This commit is contained in:
Your Name
2026-08-22 10:46:13 +08:00
parent c06d293424
commit 43e5411b6a
39 changed files with 1607 additions and 300 deletions
@@ -740,7 +740,9 @@ class WecomPromotionLogic
'agent_id' => $agentId,
'secret_configured' => trim((string) config('qywx_customer_acquisition.secret', '')) !== '',
'callback_ready' => $callbackTokenConfigured && $callbackAesConfigured,
'callback_url' => rtrim($domain, '/') . '/api/qywx/external-contact/notify',
// 复用自建应用现有的「API 接收消息」入口;获客助手事件与其他应用事件
// 由同一个控制器按 Event/ChangeType 分发,不需要再配置第二个回调地址。
'callback_url' => rtrim($domain, '/') . '/api/QywxExternalContactCallback/notify',
'official_doc' => 'https://developer.work.weixin.qq.com/document/path/97297',
];
}
@@ -27,7 +27,9 @@ class DesktopWorkstationLogic extends BaseLogic
{
public const CONFIG_TYPE = 'desktop_workstation';
public const PLATFORMS = ['windows_x64', 'macos_arm64', 'macos_x64'];
public const PLATFORMS = ['windows_x64', 'macos_arm64', 'macos_x64'];
public const PACKAGE_TYPES = ['archive', 'inno_setup'];
/**
* @notes 管理端读取配置(安装包地址补全域名)
@@ -76,10 +78,10 @@ class DesktopWorkstationLogic extends BaseLogic
$latest = self::normalizeVersion((string) ($config['latest_version'] ?? ''));
$minVersion = self::normalizeVersion((string) ($config['min_version'] ?? ''));
$enabled = (int) ($config['enabled'] ?? 0) === 1;
$packageKey = self::packageKey($platform, $arch);
$package = $packageKey !== ''
? self::plainPackage($config['packages'][$packageKey] ?? [])
: self::emptyPackage();
$packageKey = self::packageKey($platform, $arch);
$package = $packageKey !== ''
? self::plainPackage($config['packages'][$packageKey] ?? [], $packageKey)
: self::emptyPackage();
$canInstall = $package['url'] !== '' && $package['sha256'] !== '';
$hasUpdate = $enabled && $latest !== '' && $current !== '' && self::compareVersion($current, $latest) < 0;
$belowMin = $minVersion !== '' && $current !== '' && self::compareVersion($current, $minVersion) < 0;
@@ -186,8 +188,9 @@ class DesktopWorkstationLogic extends BaseLogic
$packages[$key] = [
'url' => (string) ($params[$key . '_url'] ?? ''),
'sha256' => (string) ($params[$key . '_sha256'] ?? ''),
'size' => $params[$key . '_size'] ?? 0,
'filename' => (string) ($params[$key . '_filename'] ?? ''),
'size' => $params[$key . '_size'] ?? 0,
'filename' => (string) ($params[$key . '_filename'] ?? ''),
'type' => (string) ($params[$key . '_type'] ?? 'archive'),
];
}
}
@@ -210,7 +213,7 @@ class DesktopWorkstationLogic extends BaseLogic
{
$packages = [];
foreach (self::PLATFORMS as $key) {
$packages[$key] = self::publicPackage($config['packages'][$key] ?? []);
$packages[$key] = self::publicPackage($config['packages'][$key] ?? [], $key);
}
$config['packages'] = $packages;
return $config;
@@ -230,8 +233,9 @@ class DesktopWorkstationLogic extends BaseLogic
$url = FileService::setFileUrl($url);
}
$sha256 = strtolower(trim((string) ($row['sha256'] ?? '')));
$filename = trim((string) ($row['filename'] ?? ''));
$size = (int) ($row['size'] ?? 0);
$filename = trim((string) ($row['filename'] ?? ''));
$size = (int) ($row['size'] ?? 0);
$type = self::normalizePackageType((string) ($row['type'] ?? ''), $key);
if ($persist) {
$filled = self::fillLocalPackageMeta($url, $sha256, $size, $filename);
$url = $filled['url'];
@@ -242,8 +246,9 @@ class DesktopWorkstationLogic extends BaseLogic
$normalized[$key] = [
'url' => $url,
'sha256' => $sha256,
'size' => max(0, $size),
'filename' => mb_substr($filename, 0, 180),
'size' => max(0, $size),
'filename' => mb_substr($filename, 0, 180),
'type' => $type,
];
}
return $normalized;
@@ -251,36 +256,52 @@ class DesktopWorkstationLogic extends BaseLogic
/**
* @param array<string, mixed> $row
* @return array{url:string,sha256:string,size:int,filename:string}
*/
private static function publicPackage(array $row): array
{
$plain = self::plainPackage($row);
* @return array{url:string,sha256:string,size:int,filename:string,type:string}
*/
private static function publicPackage(array $row, string $key): array
{
$plain = self::plainPackage($row, $key);
$plain['url'] = $plain['url'] === '' ? '' : FileService::getFileUrl($plain['url']);
return $plain;
}
/**
* @param array<string, mixed> $row
* @return array{url:string,sha256:string,size:int,filename:string}
*/
private static function plainPackage(array $row): array
{
return [
* @return array{url:string,sha256:string,size:int,filename:string,type:string}
*/
private static function plainPackage(array $row, string $key = ''): array
{
return [
'url' => trim((string) ($row['url'] ?? '')),
'sha256' => strtolower(trim((string) ($row['sha256'] ?? ''))),
'size' => max(0, (int) ($row['size'] ?? 0)),
'filename' => (string) ($row['filename'] ?? ''),
'size' => max(0, (int) ($row['size'] ?? 0)),
'filename' => (string) ($row['filename'] ?? ''),
'type' => self::normalizePackageType((string) ($row['type'] ?? ''), $key),
];
}
/**
* @return array{url:string,sha256:string,size:int,filename:string}
*/
private static function emptyPackage(): array
{
return ['url' => '', 'sha256' => '', 'size' => 0, 'filename' => ''];
}
* @return array{url:string,sha256:string,size:int,filename:string,type:string}
*/
private static function emptyPackage(): array
{
return ['url' => '', 'sha256' => '', 'size' => 0, 'filename' => '', 'type' => 'archive'];
}
public static function normalizePackageType(string $type, string $key = ''): string
{
$value = strtolower(trim($type));
if ($value === '') {
return 'archive';
}
if (!in_array($value, self::PACKAGE_TYPES, true)) {
return 'archive';
}
if ($value === 'inno_setup' && $key !== '' && $key !== 'windows_x64') {
return 'archive';
}
return $value;
}
/**
* @return array{url:string,sha256:string,size:int,filename:string}
@@ -120,14 +120,27 @@ class DesktopWorkstationValidate extends BaseValidate
unset($data);
$url = trim((string) ($row['url'] ?? ''));
$sha256 = strtolower(trim((string) ($row['sha256'] ?? '')));
$filename = trim((string) ($row['filename'] ?? ''));
$size = $row['size'] ?? 0;
$filename = trim((string) ($row['filename'] ?? ''));
$type = strtolower(trim((string) ($row['type'] ?? 'archive')));
$size = $row['size'] ?? 0;
$labels = [
'windows_x64' => 'Windows 64 位',
'macos_arm64' => 'macOS Apple 芯片',
'macos_x64' => 'macOS Intel',
];
$label = $labels[$key] ?? $key;
$label = $labels[$key] ?? $key;
if (!in_array($type, DesktopWorkstationLogic::PACKAGE_TYPES, true)) {
return $label . '安装包类型不受支持';
}
if ($type === 'inno_setup' && $key !== 'windows_x64') {
return $label . '不能使用 Windows Inno Setup 安装包';
}
if ($type === 'inno_setup' && $filename !== '' && !str_ends_with(strtolower($filename), '.exe')) {
return $label . ' Inno Setup 文件名必须以 .exe 结尾';
}
if ($type === 'inno_setup' && preg_match('#^http://#i', $url)) {
return $label . '自动安装程序必须使用 HTTPS 下载地址';
}
if ($url !== '' && !$this->isAllowedPackageUrl($url)) {
return $label . '安装包地址必须是 http(s) 链接或站内 uploads 路径';
}