chore: prepare anxinyan release

This commit is contained in:
wushumin
2026-05-25 14:53:59 +08:00
parent 21360a6a2c
commit fa8c9015d9
26 changed files with 2124 additions and 120 deletions

View File

@@ -8,6 +8,8 @@ use support\think\Db;
class SystemConfigsController
{
private const H5_OAUTH_REDIRECT_HASH_PATH = '/#/pages/auth/login';
public function index(Request $request)
{
$this->bootstrapDefaults();
@@ -23,6 +25,7 @@ class SystemConfigsController
foreach ($configs as $item) {
$configMap[$item['config_group'] . '.' . $item['config_key']] = $item['config_value'] ?? '';
}
$this->applyDerivedConfigValues($configMap);
$groups = [];
foreach ($this->definitions() as $groupCode => $group) {
@@ -38,6 +41,7 @@ class SystemConfigsController
'placeholder' => $item['placeholder'],
'remark' => $item['remark'],
'is_secret' => (bool)$item['is_secret'],
'read_only' => (bool)($item['read_only'] ?? false),
'options' => $item['options'] ?? [],
'visible_when' => $item['visible_when'] ?? null,
'value' => $configMap[$groupCode . '.' . $item['config_key']] ?? '',
@@ -74,6 +78,7 @@ class SystemConfigsController
}
}
$submittedConfigKeys = [];
foreach ($items as $item) {
if (!is_array($item)) {
continue;
@@ -87,6 +92,18 @@ class SystemConfigsController
}
$configValueMap[$mapKey] = (string)($item['config_value'] ?? '');
$submittedConfigKeys[$mapKey] = [
'config_group' => $groupCode,
'config_key' => $configKey,
];
}
$this->applyDerivedConfigValues($configValueMap);
if (isset($submittedConfigKeys['h5.page_base_url']) || isset($submittedConfigKeys['h5.oauth_redirect_url'])) {
$submittedConfigKeys['h5.oauth_redirect_url'] = [
'config_group' => 'h5',
'config_key' => 'oauth_redirect_url',
];
}
try {
@@ -99,14 +116,10 @@ class SystemConfigsController
Db::startTrans();
try {
foreach ($items as $item) {
if (!is_array($item)) {
continue;
}
$groupCode = trim((string)($item['config_group'] ?? ''));
$configKey = trim((string)($item['config_key'] ?? ''));
$configValue = (string)($item['config_value'] ?? '');
foreach ($submittedConfigKeys as $mapKey => $configMeta) {
$groupCode = $configMeta['config_group'];
$configKey = $configMeta['config_key'];
$configValue = (string)($configValueMap[$mapKey] ?? '');
$mapKey = $groupCode . '.' . $configKey;
if ($groupCode === '' || $configKey === '' || !isset($allowedMap[$mapKey])) {
@@ -405,8 +418,8 @@ class SystemConfigsController
'items' => [
['config_key' => 'app_id', 'title' => 'H5 AppID', 'field_type' => 'text', 'placeholder' => '请输入 H5 AppID', 'remark' => '用于 H5 登录与开放平台接入', 'is_secret' => false],
['config_key' => 'app_secret', 'title' => 'H5 AppSecret', 'field_type' => 'password', 'placeholder' => '请输入 H5 AppSecret', 'remark' => '请妥善保管,仅后台可见', 'is_secret' => true],
['config_key' => 'oauth_redirect_url', 'title' => '授权回调地址', 'field_type' => 'text', 'placeholder' => '请输入 H5 授权回调地址', 'remark' => '用于 H5 登录或支付回调', 'is_secret' => false],
['config_key' => 'page_base_url', 'title' => 'H5 页面根地址', 'field_type' => 'text', 'placeholder' => '例如 https://m.anxinyan.com', 'remark' => '用于生成扫码查看报告和验真页的完整 H5 链接', 'is_secret' => false],
['config_key' => 'oauth_redirect_url', 'title' => '授权回调地址', 'field_type' => 'text', 'placeholder' => '保存 H5 页面根地址后自动生成', 'remark' => ' H5 页面根地址自动拼接,无需手动填写。', 'is_secret' => false, 'read_only' => true],
['config_key' => 'page_base_url', 'title' => 'H5 页面根地址', 'field_type' => 'text', 'placeholder' => '例如 https://m.anxinjianyan.com', 'remark' => '用于生成扫码查看报告和验真页的完整 H5 链接', 'is_secret' => false],
],
],
'payment' => [
@@ -501,4 +514,38 @@ class SystemConfigsController
throw new \RuntimeException('当前已切换为七牛云存储,请至少填写公开访问域名或七牛公网访问域名');
}
}
private function applyDerivedConfigValues(array &$configValueMap): void
{
$configValueMap['h5.oauth_redirect_url'] = $this->buildH5OAuthRedirectUrl((string)($configValueMap['h5.page_base_url'] ?? ''));
}
private function buildH5OAuthRedirectUrl(string $pageBaseUrl): string
{
$baseUrl = $this->normalizeH5PageBaseUrl($pageBaseUrl);
if ($baseUrl === '') {
return '';
}
return $baseUrl . self::H5_OAUTH_REDIRECT_HASH_PATH;
}
private function normalizeH5PageBaseUrl(string $value): string
{
$baseUrl = trim($value);
if ($baseUrl === '') {
return '';
}
$hashPos = strpos($baseUrl, '#');
if ($hashPos !== false) {
$baseUrl = substr($baseUrl, 0, $hashPos);
}
if (!preg_match('/^https?:\/\//i', $baseUrl)) {
$baseUrl = 'https://' . ltrim($baseUrl, '/');
}
return rtrim($baseUrl, '/');
}
}

View File

@@ -66,6 +66,59 @@ class AuthController
}
}
public function wechatConfig(Request $request)
{
try {
$payload = (new AppAuthService())->wechatConfig();
return api_success($payload);
} catch (\Throwable $e) {
return api_error('微信授权配置获取失败', 500, [
'detail' => $e->getMessage(),
]);
}
}
public function wechatExchange(Request $request)
{
$code = trim((string)$request->input('code', ''));
$state = trim((string)$request->input('state', ''));
if ($code === '') {
return api_error('微信授权 code 不能为空', 422);
}
try {
$payload = (new AppAuthService())->exchangeWechatCode($code, $state, $request);
return api_success($payload, ($payload['status'] ?? '') === 'need_bind' ? '请绑定手机号' : '登录成功');
} catch (\RuntimeException $e) {
return api_error($e->getMessage(), 422);
} catch (\Throwable $e) {
return api_error('微信授权登录失败', 500, [
'detail' => $e->getMessage(),
]);
}
}
public function wechatBindMobile(Request $request)
{
$bindTicket = trim((string)$request->input('bind_ticket', ''));
$mobile = trim((string)$request->input('mobile', ''));
$code = trim((string)$request->input('code', ''));
if ($bindTicket === '' || $mobile === '' || $code === '') {
return api_error('微信绑定凭证、手机号和验证码不能为空', 422);
}
try {
$payload = (new AppAuthService())->bindWechatMobile($bindTicket, $mobile, $code, $request);
return api_success($payload, '绑定成功');
} catch (\RuntimeException $e) {
return api_error($e->getMessage(), 422);
} catch (\Throwable $e) {
return api_error('微信绑定手机号失败', 500, [
'detail' => $e->getMessage(),
]);
}
}
public function me(Request $request)
{
$userInfo = (new AppAuthService())->current($request);

View File

@@ -104,7 +104,13 @@ class ReportsController
'valuation_snapshot' => $this->decodeJsonField($content['valuation_snapshot_json'] ?? null),
'risk_notice_text' => ($content['risk_notice_text'] ?? '') !== '' ? $content['risk_notice_text'] : $defaultRiskNotice,
];
$productDisplay = $this->buildProductDisplay($reportData, $payload['product_snapshot'], $payload['result_snapshot'], $payload['valuation_snapshot']);
$productDisplay = $this->buildProductDisplay(
$reportData,
$payload['product_snapshot'],
$payload['result_snapshot'],
$payload['valuation_snapshot'],
$payload['appraisal_snapshot']
);
$reportMedia = [
'images' => $this->filterAssetsByType($evidenceAttachments, 'image'),
];
@@ -118,7 +124,12 @@ class ReportsController
)
: ['visible' => false, 'nodes' => []];
$traceInfo['visible'] = $traceInfoVisible;
$pdfUrl = $this->ensurePdfFile($request, $reportData, $content ?: [], $verify ?: [], $productDisplay, $reportMedia);
$pdfProductDisplay = $productDisplay;
$pdfProductDisplay['items'] = array_values(array_filter(
$productDisplay['items'] ?? [],
fn (array $item) => ($item['label'] ?? '') !== '服务类型'
));
$pdfUrl = $this->ensurePdfFile($request, $reportData, $content ?: [], $verify ?: [], $pdfProductDisplay, $reportMedia);
return api_success([
'report_header' => [
@@ -128,6 +139,7 @@ class ReportsController
'report_title' => $reportData['report_title'],
'report_status' => $reportData['report_status'],
'service_provider' => $reportData['service_provider'],
'service_provider_text' => $this->serviceProviderText((string)$reportData['service_provider']),
'institution_name' => $this->displayInstitutionName((string)$reportData['service_provider']),
'publish_time' => $reportData['publish_time'],
'zhongjian_report_no' => (string)($reportData['zhongjian_report_no'] ?? ''),
@@ -283,7 +295,7 @@ class ReportsController
$generator = new ReportPdfGenerator();
$pdfBinary = $generator->generate([
'report_title' => $report['report_title'] ?? '鉴定报告',
'service_provider_text' => ($report['service_provider'] ?? 'anxinyan') === 'zhongjian' ? '中检鉴定' : '实物鉴定',
'service_provider_text' => $this->serviceProviderText((string)($report['service_provider'] ?? 'anxinyan')),
'institution_name' => $this->displayInstitutionName((string)($report['service_provider'] ?? 'anxinyan')),
'report_no' => $report['report_no'] ?? '',
'publish_time' => $publishTime,
@@ -322,7 +334,7 @@ class ReportsController
return $this->storage()->publicUrl($request, $relativePath);
}
private function buildProductDisplay(array $report, array $productInfo, array $resultInfo, array $valuationInfo = []): array
private function buildProductDisplay(array $report, array $productInfo, array $resultInfo, array $valuationInfo = [], array $appraisalInfo = []): array
{
$items = [];
$this->appendDisplayItem(
@@ -363,6 +375,16 @@ class ReportsController
);
}
$this->appendDisplayItem(
$items,
'服务类型',
$this->serviceProviderText((string)($report['service_provider'] ?? 'anxinyan'))
);
$appraiserName = $this->textValue($appraisalInfo['appraiser_name'] ?? '')
?: $this->textValue($appraisalInfo['reviewer_name'] ?? '')
?: $this->textValue($report['report_entry_admin_name'] ?? '');
$this->appendDisplayItem($items, '鉴定师', $appraiserName);
$conditionGrade = $this->textValue($valuationInfo['condition_grade'] ?? '');
$conditionDesc = $this->textValue($valuationInfo['condition_desc'] ?? '');
if ($conditionGrade !== '' || $conditionDesc !== '') {
@@ -654,6 +676,11 @@ class ReportsController
return trim((string)($value ?? ''));
}
private function serviceProviderText(string $serviceProvider): string
{
return $serviceProvider === 'zhongjian' ? '中检鉴定' : '实物鉴定';
}
private function displayInstitutionName(string $serviceProvider): string
{
return $serviceProvider === 'zhongjian' ? '中检鉴定中心' : '安心检验';