From 486acc465d75543b327715fa4647120fa6045fd2 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 1 Sep 2026 17:18:42 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/src/api/file.ts | 7 +- admin/src/components/upload/index.vue | 31 +++++-- admin/src/utils/oss-direct-upload.ts | 58 +++++++++---- .../setting/desktop_workstation/index.vue | 11 ++- app/src/doctor_workstation/__init__.py | 2 +- .../adminapi/controller/UploadController.php | 30 ++++++- .../common/service/DirectUploadService.php | 84 +++++++++++++++++-- .../common/service/storage/engine/Qcloud.php | 22 +++-- .../DesktopWorkstationUpdateContractTest.php | 68 +++++++++++++-- 9 files changed, 262 insertions(+), 51 deletions(-) diff --git a/admin/src/api/file.ts b/admin/src/api/file.ts index 2d60dd2c1..9f81ff782 100644 --- a/admin/src/api/file.ts +++ b/admin/src/api/file.ts @@ -100,6 +100,7 @@ export interface OssCredentialsResponse { host?: string cdn_domain?: string key_prefix?: string + object_key?: string max_size?: number duration?: number expired_time?: number @@ -111,8 +112,10 @@ export interface OssCredentialsResponse { } } +export type OssDirectUploadType = 'video' | 'voice' | 'desktop_package' + /** 申请 STS 临时凭证 */ -export function getOssCredentials(params: { type: 'video' }) { +export function getOssCredentials(params: { type: OssDirectUploadType; name?: string }) { return request.post({ url: '/upload/ossCredentials', params @@ -121,7 +124,7 @@ export function getOssCredentials(params: { type: 'video' }) { /** 直传完成回执:写 file 表 + HEAD 校验 */ export function confirmOssUpload(params: { - type: 'video' + type: OssDirectUploadType key: string name: string size: number diff --git a/admin/src/components/upload/index.vue b/admin/src/components/upload/index.vue index eead4783d..98b3a5b62 100644 --- a/admin/src/components/upload/index.vue +++ b/admin/src/components/upload/index.vue @@ -51,8 +51,10 @@ import useAppStore from '@/stores/modules/app' import useUserStore from '@/stores/modules/user' import feedback from '@/utils/feedback' import { + DirectUploadApiError, DirectUploadFallbackError, - uploadVideoDirectToCos + uploadDirectToCos, + type DirectUploadType } from '@/utils/oss-direct-upload' export default defineComponent({ @@ -83,7 +85,7 @@ export default defineComponent({ type: Boolean, default: false }, - // 视频直传到 OSS(绕开服务器中转,仅 type=video 生效) + // 直传到对象存储,绕开服务器中转 direct: { type: Boolean, default: false @@ -102,8 +104,10 @@ export default defineComponent({ const visible = ref(false) const fileList = ref([]) - // 仅 video/voice + direct 时才接管 http-request - const useDirect = computed(() => props.direct && ['video', 'voice'].includes(props.type)) + const directTypes: DirectUploadType[] = ['video', 'voice', 'desktop_package'] + const useDirect = computed( + () => props.direct && directTypes.includes(props.type as DirectUploadType) + ) const handleProgress = () => { visible.value = true @@ -131,7 +135,10 @@ export default defineComponent({ fileList.value = [] emit('allSuccess') } - feedback.msgError(`${file.name}文件上传失败`) + if (!(event instanceof DirectUploadApiError)) { + const message = event instanceof Error ? event.message : '' + feedback.msgError(message || `${file.name}文件上传失败`) + } uploadRefs.value?.abort(file) visible.value = false emit('change', file) @@ -153,18 +160,20 @@ export default defineComponent({ return '.wmv,.avi,.mpg,.mpeg,.3gp,.mov,.mp4,.flv,.rmvb,.mkv' case 'voice': return '.mp3,.wav,.wma,.m4a,.aac,.amr' + case 'desktop_package': + return '.exe,.zip' default: return '*' } }) - // 走 COS 直传:成功时模拟老接口的响应 envelope,失败/降级时回到默认 XHR + // 走 COS 直传:成功时模拟老接口的响应 envelope const httpRequest = async (options: UploadRequestOptions) => { visible.value = true try { - const data = await uploadVideoDirectToCos({ + const data = await uploadDirectToCos({ file: options.file, - type: props.type as any, + type: props.type as DirectUploadType, cid: Number((options.data as any)?.cid ?? 0), onProgress(info) { // 触发 ElUpload 内部进度(保持与默认上传一致的体验) @@ -178,6 +187,12 @@ export default defineComponent({ ;(options as any).onSuccess?.({ code: RequestCodeEnum.SUCCESS, msg: 'ok', data }) } catch (err: any) { if (err instanceof DirectUploadFallbackError) { + if (props.type === 'desktop_package') { + ;(options as any).onError?.( + new Error('当前未启用腾讯云 COS,安装包无法直传,请配置 COS 后重试') + ) + return + } feedback.msgWarning('当前存储不支持直传,已切换为普通上传') await defaultXhrUpload(options) return diff --git a/admin/src/utils/oss-direct-upload.ts b/admin/src/utils/oss-direct-upload.ts index 90637d1f1..1cd284624 100644 --- a/admin/src/utils/oss-direct-upload.ts +++ b/admin/src/utils/oss-direct-upload.ts @@ -3,10 +3,11 @@ import COS from 'cos-js-sdk-v5' import { confirmOssUpload, getOssCredentials, - type OssCredentialsResponse + type OssCredentialsResponse, + type OssDirectUploadType } from '@/api/file' -export type DirectUploadType = 'video' +export type DirectUploadType = OssDirectUploadType export interface DirectUploadProgress { /** 0-100 */ @@ -37,8 +38,17 @@ export interface DirectUploadOptions { const SLICE_SIZE = 5 * 1024 * 1024 // 5MB const ASYNC_LIMIT = 3 +async function callDirectUploadApi(request: () => Promise): Promise { + try { + return await request() + } catch (error) { + // request 拦截器已经展示过接口/网络错误,上传组件只负责收口失败状态 + throw new DirectUploadApiError(error) + } +} + function buildKey(prefix: string, file: File): string { - const ext = (file.name.split('.').pop() || 'mp4').toLowerCase() + const ext = (file.name.split('.').pop() || 'bin').toLowerCase() const ts = Date.now() const rand = Math.random().toString(36).slice(2, 10) return `${prefix}${ts}-${rand}.${ext}` @@ -48,8 +58,13 @@ function buildKey(prefix: string, file: File): string { * 直传到腾讯云 COS(含 STS 凭证申请、分片上传、回执) * 不支持降级 / fallback=true 时抛错,由调用方决定走老链路。 */ -export async function uploadVideoDirectToCos(options: DirectUploadOptions): Promise { - const credentials: OssCredentialsResponse = await getOssCredentials({ type: options.type }) +export async function uploadDirectToCos(options: DirectUploadOptions): Promise { + const credentials: OssCredentialsResponse = await callDirectUploadApi(() => + getOssCredentials({ + type: options.type, + name: options.file.name + }) + ) if (credentials.fallback) { const handled = options.onFallback?.(credentials.provider) ?? false @@ -66,7 +81,7 @@ export async function uploadVideoDirectToCos(options: DirectUploadOptions): Prom if (credentials.max_size && options.file.size > credentials.max_size) { const mb = Math.round(credentials.max_size / 1024 / 1024) - throw new Error(`视频体积超出上限(${mb}MB)`) + throw new Error(`文件体积超出上限(${mb}MB)`) } const cred = credentials.credentials @@ -85,7 +100,7 @@ export async function uploadVideoDirectToCos(options: DirectUploadOptions): Prom } }) - const key = buildKey(credentials.key_prefix, options.file) + const key = credentials.object_key || buildKey(credentials.key_prefix, options.file) await new Promise((resolve, reject) => { cos.uploadFile( @@ -117,14 +132,16 @@ export async function uploadVideoDirectToCos(options: DirectUploadOptions): Prom ) }) - const confirmed = await confirmOssUpload({ - type: options.type, - key, - name: options.file.name, - size: options.file.size, - content_type: options.file.type || '', - cid: options.cid ?? 0 - }) + const confirmed = await callDirectUploadApi(() => + confirmOssUpload({ + type: options.type, + key, + name: options.file.name, + size: options.file.size, + content_type: options.file.type || '', + cid: options.cid ?? 0 + }) + ) options.onProgress?.({ percent: 100, loaded: options.file.size, total: options.file.size, speed: 0 }) @@ -140,3 +157,14 @@ export class DirectUploadFallbackError extends Error { this.provider = provider } } + +/** 请求层已经展示过错误,避免 ElUpload 再弹一条通用失败提示。 */ +export class DirectUploadApiError extends Error { + readonly originalError: unknown + + constructor(error: unknown) { + super('') + this.name = 'DirectUploadApiError' + this.originalError = error + } +} diff --git a/admin/src/views/setting/desktop_workstation/index.vue b/admin/src/views/setting/desktop_workstation/index.vue index 09842a9e9..9ab6cfa69 100644 --- a/admin/src/views/setting/desktop_workstation/index.vue +++ b/admin/src/views/setting/desktop_workstation/index.vue @@ -16,7 +16,8 @@ 一键打包 产物一致的安装包,并填入打包目录中的 SHA-256。Windows 推荐使用 Setup.exe,用户点击“立即更新”后会自动安装并重启;macOS 继续使用 ZIP。 - 安装包通常超过 200MB,优先传到对象存储 / CDN 后粘贴地址。 + 安装包通常超过 200MB,本页上传按钮会直传到已配置的腾讯云 COS;也可以 + 自行上传到其他对象存储 / CDN 后粘贴地址。
升级策略
@@ -125,7 +126,9 @@
选择安装包并上传
- 仅建议上传较小的包。大文件请先传到对象存储,再把地址和 SHA-256 - 填到上方。Windows 自动安装程序必须使用 HTTPS 地址并开启证书校验。 + 安装包将分片直传腾讯云 COS,不经过业务服务器(支持 EXE / ZIP,最大 + 2GB)。Windows 自动安装程序必须使用 HTTPS 地址并开启证书校验。
diff --git a/app/src/doctor_workstation/__init__.py b/app/src/doctor_workstation/__init__.py index 99be554e4..a33caea94 100644 --- a/app/src/doctor_workstation/__init__.py +++ b/app/src/doctor_workstation/__init__.py @@ -3,7 +3,7 @@ __all__ = ["DEBUG_MODE", "ONLINE_API_BASE_URL", "__version__"] # Single source of truth for runtime, package, installer, and executable versions. -__version__ = "1.2.0" +__version__ = "1.4.0" # 调试模式开启时,登录页显示“演示模式”和“服务器设置”。 # 正式发布请保持 False;此时程序只使用下面配置的线上域名。 diff --git a/server/app/adminapi/controller/UploadController.php b/server/app/adminapi/controller/UploadController.php index 643e79638..939a43443 100755 --- a/server/app/adminapi/controller/UploadController.php +++ b/server/app/adminapi/controller/UploadController.php @@ -15,6 +15,7 @@ namespace app\adminapi\controller; +use app\common\cache\AdminAuthCache; use app\common\service\DirectUploadService; use app\common\service\UploadService; use Exception; @@ -86,7 +87,12 @@ class UploadController extends BaseAdminController { $type = trim((string)$this->request->post('type', 'video')); try { - $result = DirectUploadService::issueCredentials($type); + $this->assertDirectUploadPermission($type); + $result = DirectUploadService::issueCredentials( + $type, + $this->adminId, + trim((string)$this->request->post('name', '')) + ); return $this->success('ok', $result); } catch (Exception $e) { return $this->fail($e->getMessage()); @@ -100,8 +106,10 @@ class UploadController extends BaseAdminController public function ossConfirm() { try { + $type = trim((string)$this->request->post('type', 'video')); + $this->assertDirectUploadPermission($type); $result = DirectUploadService::confirm([ - 'type' => trim((string)$this->request->post('type', 'video')), + 'type' => $type, 'key' => trim((string)$this->request->post('key', '')), 'name' => trim((string)$this->request->post('name', '')), 'size' => (int)$this->request->post('size', 0), @@ -115,4 +123,22 @@ class UploadController extends BaseAdminController } } + /** + * 安装包属于发布能力,不能沿用普通素材上传的“登录即放行”。 + * @throws Exception + */ + private function assertDirectUploadPermission(string $type): void + { + if ($type !== DirectUploadService::TYPE_DESKTOP_PACKAGE + || (int)($this->adminInfo['root'] ?? 0) === 1) { + return; + } + + $permissions = (new AdminAuthCache($this->adminId))->getAdminUri() ?? []; + $permissions = array_map('strtolower', $permissions); + if (!in_array('setting.desktop_workstation/setconfig', $permissions, true)) { + throw new Exception('权限不足,无法上传医生工作站安装包'); + } + } + } diff --git a/server/app/common/service/DirectUploadService.php b/server/app/common/service/DirectUploadService.php index cbe991bd9..e31a0ffc8 100755 --- a/server/app/common/service/DirectUploadService.php +++ b/server/app/common/service/DirectUploadService.php @@ -20,6 +20,7 @@ class DirectUploadService /** 视频允许的扩展名(沿用 config/project.file_video) */ public const TYPE_VIDEO = 'video'; public const TYPE_VOICE = 'voice'; + public const TYPE_DESKTOP_PACKAGE = 'desktop_package'; /** 默认凭证有效期 30 分钟 */ public const DEFAULT_DURATION = 1800; @@ -28,6 +29,7 @@ class DirectUploadService private const MAX_SIZE = [ self::TYPE_VIDEO => 2 * 1024 * 1024 * 1024, // 2GB self::TYPE_VOICE => 500 * 1024 * 1024, // 500MB + self::TYPE_DESKTOP_PACKAGE => 2 * 1024 * 1024 * 1024, // 2GB ]; /** @@ -36,7 +38,7 @@ class DirectUploadService * @return array * @throws Exception */ - public static function issueCredentials(string $type): array + public static function issueCredentials(string $type, int $adminId = 0, string $name = ''): array { if (!isset(self::MAX_SIZE[$type])) { throw new Exception('不支持的上传类型: ' . $type); @@ -54,9 +56,27 @@ class DirectUploadService throw new Exception('腾讯云 COS 配置不完整'); } - $keyPrefix = self::buildKeyPrefix($type); + $keyPrefix = self::buildKeyPrefix($type, $adminId); + $objectKey = ''; + // 兼容前后端错峰发布:旧 uploader 只传 type,不传 name。 + // 新 uploader 仍使用更严格的单对象授权;旧版则限制在当前管理员当天目录, + // 并在 confirm 阶段校验文件名、扩展名与实际对象。 + if ($type === self::TYPE_DESKTOP_PACKAGE && trim($name) !== '') { + $extension = strtolower((string)pathinfo($name, PATHINFO_EXTENSION)); + $objectKey = $keyPrefix + . (int)round(microtime(true) * 1000) + . '-' + . bin2hex(random_bytes(8)) + . ($extension !== '' ? '.' . $extension : ''); + self::validateFileExtension($type, $objectKey, $name); + } $engine = new QcloudEngine($storageConfig); - $sts = $engine->getStsCredentials($keyPrefix, self::MAX_SIZE[$type], self::DEFAULT_DURATION); + $sts = $engine->getStsCredentials( + $objectKey !== '' ? $objectKey : $keyPrefix, + self::MAX_SIZE[$type], + self::DEFAULT_DURATION, + $objectKey !== '' + ); return [ 'provider' => 'qcloud', @@ -66,6 +86,7 @@ class DirectUploadService 'host' => $sts['host'], 'cdn_domain' => rtrim((string)($storageConfig['domain'] ?? ''), '/'), 'key_prefix' => $keyPrefix, + 'object_key' => $objectKey, 'max_size' => self::MAX_SIZE[$type], 'duration' => self::DEFAULT_DURATION, 'expired_time' => $sts['expiredTime'], @@ -93,8 +114,7 @@ class DirectUploadService } $key = ltrim((string)($params['key'] ?? ''), '/'); - $allowedPrefix = self::buildKeyPrefix($type); - if ($key === '' || strpos($key, $allowedPrefix) !== 0) { + if (!self::isAllowedObjectKey($type, $key, (int)($params['admin_id'] ?? 0))) { throw new Exception('对象 Key 非法'); } @@ -112,6 +132,7 @@ class DirectUploadService if ($name === '') { $name = basename($key); } + self::validateFileExtension($type, $key, $name); if (strlen($name) > 128) { $name = substr($name, 0, 123) . substr($name, -5); } @@ -137,9 +158,16 @@ class DirectUploadService ]; } - private static function buildKeyPrefix(string $type): string + private static function buildKeyPrefix(string $type, int $adminId = 0): string { - return 'uploads/' . $type . '/' . date('Ymd') . '/'; + $prefix = 'uploads/' . $type . '/'; + if ($type === self::TYPE_DESKTOP_PACKAGE) { + if ($adminId <= 0) { + throw new Exception('安装包上传账号无效'); + } + $prefix .= $adminId . '/'; + } + return $prefix . date('Ymd') . '/'; } private static function resolveFileType(string $type): int @@ -150,4 +178,46 @@ class DirectUploadService default => FileEnum::FILE_TYPE, }; } + + /** + * 桌面安装包是可执行文件,只允许发布流程所需的 EXE / ZIP。 + */ + private static function validateFileExtension(string $type, string $key, string $name): void + { + if ($type !== self::TYPE_DESKTOP_PACKAGE) { + return; + } + + $nameExtension = strtolower((string)pathinfo($name, PATHINFO_EXTENSION)); + $keyExtension = strtolower((string)pathinfo($key, PATHINFO_EXTENSION)); + $allowedExtensions = ['exe', 'zip']; + if (!in_array($nameExtension, $allowedExtensions, true) + || $nameExtension !== $keyExtension) { + throw new Exception('桌面安装包仅支持 EXE 或 ZIP 文件'); + } + } + + /** + * 安装包 Key 绑定上传管理员,并兼容跨午夜完成的上传。 + */ + private static function isAllowedObjectKey(string $type, string $key, int $adminId): bool + { + if ($key === '') { + return false; + } + if ($type !== self::TYPE_DESKTOP_PACKAGE) { + return strpos($key, self::buildKeyPrefix($type)) === 0; + } + if ($adminId <= 0) { + return false; + } + + $ownerPrefix = 'uploads/' . self::TYPE_DESKTOP_PACKAGE . '/' . $adminId . '/'; + if (strpos($key, $ownerPrefix) !== 0) { + return false; + } + $date = substr($key, strlen($ownerPrefix), 8); + return in_array($date, [date('Ymd'), date('Ymd', time() - 86400)], true) + && substr($key, strlen($ownerPrefix) + 8, 1) === '/'; + } } diff --git a/server/app/common/service/storage/engine/Qcloud.php b/server/app/common/service/storage/engine/Qcloud.php index d57250a7f..d79724382 100755 --- a/server/app/common/service/storage/engine/Qcloud.php +++ b/server/app/common/service/storage/engine/Qcloud.php @@ -116,13 +116,19 @@ class Qcloud extends Server /** * @notes 获取 STS 临时凭证(用于浏览器直传) - * @param string $keyPrefix 资源前缀,如 uploads/video/20260508/ + * @param string $keyScope 资源前缀或完整对象 Key * @param int $maxSizeBytes 单文件大小上限(字节) * @param int $durationSeconds 凭证有效期(秒) + * @param bool $exactObject 是否只授权单个对象 Key * @return array {credentials, expiredTime, requestId} * @throws Exception */ - public function getStsCredentials(string $keyPrefix, int $maxSizeBytes, int $durationSeconds = 1800): array + public function getStsCredentials( + string $keyScope, + int $maxSizeBytes, + int $durationSeconds = 1800, + bool $exactObject = false + ): array { $bucket = $this->config['bucket']; // bucket 形如 likeadmin-1300000000,appId 即末段 @@ -137,15 +143,19 @@ class Qcloud extends Server $shortBucket = substr($bucket, 0, strrpos($bucket, '-')); $region = $this->config['region']; - $prefix = ltrim($keyPrefix, '/'); - if ($prefix === '' || substr($prefix, -1) !== '/') { - $prefix = $prefix . '/'; + $scope = ltrim($keyScope, '/'); + if ($scope === '') { + throw new Exception('COS 授权对象不能为空'); + } + if (!$exactObject && substr($scope, -1) !== '/') { + $scope .= '/'; } $duration = max(900, min($durationSeconds, 7200)); // 自行构造 policy:对象级写动作收紧 + bucket 级 ListMultipartUploads(cos-js-sdk-v5 续传探测必需) - $objectArn = sprintf('qcs::cos:%s:uid/%s:%s/%s*', $region, $appId, $bucket, $prefix); + $objectResource = $exactObject ? $scope : $scope . '*'; + $objectArn = sprintf('qcs::cos:%s:uid/%s:%s/%s', $region, $appId, $bucket, $objectResource); $bucketArn = sprintf('qcs::cos:%s:uid/%s:%s/*', $region, $appId, $bucket); $policy = [ diff --git a/server/tests/DesktopWorkstationUpdateContractTest.php b/server/tests/DesktopWorkstationUpdateContractTest.php index 68ffa0f0b..f9ffb2f4e 100644 --- a/server/tests/DesktopWorkstationUpdateContractTest.php +++ b/server/tests/DesktopWorkstationUpdateContractTest.php @@ -4,7 +4,8 @@ declare(strict_types=1); require dirname(__DIR__) . '/vendor/autoload.php'; -use app\adminapi\logic\setting\DesktopWorkstationLogic; +use app\adminapi\logic\setting\DesktopWorkstationLogic; +use app\common\service\DirectUploadService; function desktopUpdateExpect(bool $condition, string $message): void { @@ -92,14 +93,69 @@ desktopUpdateExpect( $adminView = file_get_contents(dirname(__DIR__, 2) . '/admin/src/views/setting/desktop_workstation/index.vue'); desktopUpdateExpect(is_string($adminView), 'admin view source is readable'); -desktopUpdateExpect( +desktopUpdateExpect( str_contains($adminView, 'setting.desktop_workstation/setConfig') && str_contains($adminView, 'force_update') - && str_contains($adminView, 'inno_setup'), - 'admin page can save force-update and Inno Setup configuration' + && str_contains($adminView, 'inno_setup') + && str_contains($adminView, 'type="desktop_package"') + && str_contains($adminView, 'direct'), + 'admin page saves update settings and sends installers through direct upload' ); - -$migration = file_get_contents( + +$directUploadReflection = new ReflectionClass(DirectUploadService::class); +$validateExtension = $directUploadReflection->getMethod('validateFileExtension'); +$validateExtension->invoke( + null, + DirectUploadService::TYPE_DESKTOP_PACKAGE, + 'uploads/desktop_package/7/' . date('Ymd') . '/package.exe', + 'DoctorWorkstation.EXE' +); +$invalidExtensionRejected = false; +try { + $validateExtension->invoke( + null, + DirectUploadService::TYPE_DESKTOP_PACKAGE, + 'uploads/desktop_package/7/' . date('Ymd') . '/package.php', + 'package.php' + ); +} catch (Throwable $e) { + $invalidExtensionRejected = true; +} +desktopUpdateExpect($invalidExtensionRejected, 'desktop direct upload rejects non-EXE/ZIP files'); + +$validateObjectKey = $directUploadReflection->getMethod('isAllowedObjectKey'); +$ownedKey = 'uploads/desktop_package/7/' . date('Ymd') . '/package.exe'; +desktopUpdateExpect( + $validateObjectKey->invoke(null, DirectUploadService::TYPE_DESKTOP_PACKAGE, $ownedKey, 7) === true + && $validateObjectKey->invoke(null, DirectUploadService::TYPE_DESKTOP_PACKAGE, $ownedKey, 8) === false, + 'desktop package keys are bound to the issuing admin' +); + +$uploadController = file_get_contents(dirname(__DIR__) . '/app/adminapi/controller/UploadController.php'); +$qcloudEngine = file_get_contents(dirname(__DIR__) . '/app/common/service/storage/engine/Qcloud.php'); +$directUploadService = file_get_contents( + dirname(__DIR__) . '/app/common/service/DirectUploadService.php' +); +desktopUpdateExpect( + is_string($uploadController) + && str_contains($uploadController, 'assertDirectUploadPermission') + && str_contains($uploadController, 'setting.desktop_workstation/setconfig'), + 'desktop package credentials and confirmation require publish permission' +); +desktopUpdateExpect( + is_string($qcloudEngine) + && str_contains($qcloudEngine, 'bool $exactObject = false') + && str_contains($qcloudEngine, '$exactObject ? $scope : $scope .'), + 'COS credentials can be restricted to one server-issued object key' +); +desktopUpdateExpect( + is_string($directUploadService) + && str_contains($directUploadService, "trim(\$name) !== ''") + && str_contains($directUploadService, '$objectKey !== \'\''), + 'desktop credentials remain compatible with uploaders that do not send a filename' +); + +$migration = file_get_contents( dirname(__DIR__) . '/sql/1.9.20260821/add_desktop_workstation_update_menu.sql' ); desktopUpdateExpect(is_string($migration), 'menu migration is readable'); From 58ffde808f5f9a2c22ad8a8c7f322b08406ea456 Mon Sep 17 00:00:00 2001 From: Your Name Date: Tue, 1 Sep 2026 17:49:29 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- admin/src/views/order/index.vue | 88 +++++++++++++++++-- admin/tsconfig.tsbuildinfo | 2 +- .../controller/order/OrderController.php | 4 +- .../app/adminapi/logic/order/OrderLogic.php | 32 +++++++ .../adminapi/validate/order/OrderValidate.php | 7 +- .../{403-CtdR6W2l.js => 403-BmLGKk7A.js} | 2 +- .../{404-CXFa7py3.js => 404-CmorDS9I.js} | 2 +- ....js => AppointmentRecordPanel-BpH__D9N.js} | 2 +- ...BJqJNEtv.js => AssignLogPanel-DMXc8Jqu.js} | 2 +- ...s => AssistantWatchCallDialog-BqtcnHW7.js} | 2 +- ...MVExjrX.js => BloodRecordList-DTMeNv6F.js} | 2 +- ...xSFvwQC.js => CallRecordPanel-ZONGPWXz.js} | 2 +- ...BLtWH42F.js => CaseRecordList-CL7Kp6AB.js} | 2 +- ...ix-CyosaMyV.js => DailyMatrix-D01fgjtP.js} | 2 +- ...9_uHk.js => DiagnosisTodoList-xS02xWPz.js} | 2 +- ...BGqliNYm.js => DietRecordList-C9fLdJrg.js} | 2 +- ...ULsr.js => ExerciseRecordList-CvmKVQcK.js} | 2 +- ...ancaoSubmissionReconcileButton-DG0nuCy2.js | 1 - ...ancaoSubmissionReconcileButton-DrJpChfz.js | 1 + ...e_type_script_setup_true_lang-BftoD0d7.js} | 2 +- ...2PSWO.js => ImChatRecordPanel-BlkJJW_C.js} | 2 +- ...-Blhw3brs.js => MessageBubble-B5BsnFAs.js} | 2 +- ...e-DKHSaTnS.js => NoteTimeline-wNJ-rZy1.js} | 2 +- ...AIJtIvu.js => OrderActionHost-D73bqFMW.js} | 2 +- ...nel-DzCf0lfm.js => OrderPanel-DgNymLix.js} | 2 +- ...el-BJ9vKOZj.js => PaibanPanel-BTEE_UUk.js} | 2 +- ...juuNi0D.js => PatientCaseCard-NxgOrpCM.js} | 2 +- ...H5SNzTt.js => PatientInfoCard-D5uw3qNu.js} | 2 +- ...XyX-J1.js => PatientOrderList-CSsHGOMg.js} | 2 +- ...criptionAiBatchGenerateDialog-B-IEFevM.js} | 2 +- ...=> PrescriptionAiReportDialog-CCdOg7ZY.js} | 2 +- ...PrescriptionOrderDetailDrawer-B_2wN6Ii.js} | 2 +- ...-Bp7xfqwl.js => ProgressPanel-DBVRvrQ9.js} | 2 +- ...js => PromotionAutomationForm-BXs5CP3m.js} | 2 +- ....js => RecordingPlaybackBlock-CmnTchSD.js} | 2 +- ...jw.js => RecordingVideoPlayer-CR4Pj59Y.js} | 2 +- ...anel-B4JzYDcv.js => SendPanel-BgqrvafY.js} | 2 +- ...Ds9UAziv.js => TrackingMatrix-BTeLttMt.js} | 2 +- ...nB.js => TrackingNoteTimeline-D8entDIu.js} | 2 +- ...=> WecomFloatingWidgetBuilder-H2GVpZS9.js} | 2 +- ...Pe.js => WelcomeMessageEditor-DU7sC9wU.js} | 2 +- .../admin/assets/account-adjust-BQTUUVRb.js | 1 - .../admin/assets/account-adjust-CXxGZv7i.js | 1 + ...e_type_script_setup_true_lang-CYtMLkFm.js} | 2 +- ...t-C4m8qYkN.js => account_cost-CDzLKn8m.js} | 2 +- .../{add-Gu66mkdw.js => add-BvP9GbDo.js} | 2 +- .../public/admin/assets/add-nav-BDin2PpE.js | 1 + .../public/admin/assets/add-nav-D7rLIffq.js | 1 - ...e_type_script_setup_true_lang-BRpnt2eu.js} | 2 +- .../{admin-ChXgJQ5G.js => admin-DwnCzeVZ.js} | 2 +- ...nt-zTo2RqT9.js => appointment-BEsZkoeX.js} | 2 +- ...rticle-Cu5yzLRi.js => article-D3zonLOQ.js} | 2 +- .../{asset-B2iLP5lJ.js => asset-D_ZwIjus.js} | 2 +- .../{attr-C57oQ8cq.js => attr-37BbNTQY.js} | 2 +- server/public/admin/assets/attr-B3poZnXc.js | 1 + server/public/admin/assets/attr-BVNi28ly.js | 1 + server/public/admin/assets/attr-BoawLJZX.js | 1 + server/public/admin/assets/attr-ByaCyTPj.js | 1 - server/public/admin/assets/attr-CMrm-DSv.js | 1 - .../{attr-rlv01xAn.js => attr-CWiMQaRC.js} | 2 +- server/public/admin/assets/attr-Cn4VQoWB.js | 1 + server/public/admin/assets/attr-CwE1nJyu.js | 1 - server/public/admin/assets/attr-D4tNr3SV.js | 1 - server/public/admin/assets/attr-DFZZwPjZ.js | 1 - server/public/admin/assets/attr-DKl8I92I.js | 1 + server/public/admin/assets/attr-DpmlKg-8.js | 1 + server/public/admin/assets/attr-MCgScSMl.js | 1 + server/public/admin/assets/attr-OcAk4MZZ.js | 1 - server/public/admin/assets/attr-aC8tJyH9.js | 1 - .../admin/assets/attr-setting-NSizJDtk.js | 1 + .../admin/assets/attr-setting-k7posH2Y.js | 1 - ...e_type_script_setup_true_lang-B-f0b3rG.js} | 2 +- ...e_type_script_setup_true_lang-BrNS2ps-.js} | 2 +- ...e_type_script_setup_true_lang-CATWtHib.js} | 2 +- ...e_type_script_setup_true_lang-CKteeFgv.js} | 2 +- ...e_type_script_setup_true_lang-CkKLqcSB.js} | 2 +- ...e_type_script_setup_true_lang-DoWm5gA7.js} | 2 +- ...e_type_script_setup_true_lang-DseAJCCV.js} | 2 +- ...e_type_script_setup_true_lang-mooesuD5.js} | 2 +- server/public/admin/assets/auth-BlESbXb9.js | 1 + server/public/admin/assets/auth-CESdQlQD.js | 1 - ...e_type_script_setup_true_lang-AQ4_bAhe.js} | 2 +- ...DL5YJLN.js => balance_details-Cr7ZUPxv.js} | 2 +- ...NRSijL.js => bind-work-wechat-Dg0ap0Ef.js} | 2 +- .../{cache-9M5LCxnE.js => cache-BgfOe8T_.js} | 2 +- ...tBWH34K.js => change-password-C46iFdxM.js} | 2 +- .../{code-CaYOWymS.js => code-DNIhtABi.js} | 2 +- .../admin/assets/code-preview-B1NJP23z.js | 1 - .../admin/assets/code-preview-RJcnpzk5.js | 1 + ...e_type_script_setup_true_lang-CRW3XgSs.js} | 2 +- ...X.js => commission-settlement-Ba0rN1JT.js} | 2 +- ...{config-D3etBTYC.js => config-CVDJcIrk.js} | 2 +- ...sumer-RNmfwlCf.js => consumer-CuRvN66O.js} | 2 +- .../public/admin/assets/content-6NQb9fPh.js | 1 - .../public/admin/assets/content-B9sQ5ebX.js | 1 - ...ontent-BypteVIU.js => content-BTKWe1Z5.js} | 2 +- .../public/admin/assets/content-BhhhXtGi.js | 1 + ...ontent-CcP_0nbo.js => content-BpKeA_ag.js} | 2 +- .../public/admin/assets/content-CDaFLLpk.js | 1 + .../public/admin/assets/content-CZhOpWVD.js | 1 - ...ontent-C87VwXzh.js => content-CpbkN2kw.js} | 2 +- .../public/admin/assets/content-D1KvtwNt.js | 1 + ...ontent-CPAKwgni.js => content-D1ij9T2f.js} | 2 +- ...ontent-CFWygn2e.js => content-D1r1vbY9.js} | 2 +- ...ontent-B7cQuIwl.js => content-DFD7Fvvr.js} | 2 +- .../public/admin/assets/content-D_SXu5io.js | 1 - ...ontent-CqjH9rbN.js => content-HKhGJAox.js} | 2 +- ...ontent-D1UpIOe_.js => content-HN9yJedS.js} | 2 +- .../public/admin/assets/content-LA105ak9.js | 1 - .../public/admin/assets/content-lxqjEjid.js | 1 + .../public/admin/assets/content-zynEdjJM.js | 1 + ...e_type_script_setup_true_lang-4xOoG6gL.js} | 2 +- ...e_type_script_setup_true_lang-BdL5caX-.js} | 2 +- ...e_type_script_setup_true_lang-CmpqhioD.js} | 2 +- ...e_type_script_setup_true_lang-Cu2kG1Y2.js} | 2 +- ...e_type_script_setup_true_lang-h3Bp18Pd.js} | 2 +- .../public/admin/assets/cost-edit-DU2ac9RQ.js | 1 + .../public/admin/assets/cost-edit-eteZY1-Z.js | 1 - ...e_type_script_setup_true_lang-pSKxrmjL.js} | 2 +- .../admin/assets/data-table-CSKxrtmg.js | 1 - .../admin/assets/data-table-gbxPyRId.js | 1 + ...e_type_script_setup_true_lang-BZ1Q2f6Y.js} | 2 +- ...jpQ962yE.js => decoration-img-Do-2aqVt.js} | 2 +- ...ion-WmZwV1l6.js => decoration-knxy2eJf.js} | 2 +- ...-C0s8MlWW.js => default_reply-BXZmmklG.js} | 2 +- ...ent-CICDmn1H.js => department-gRRYxP3x.js} | 2 +- ...ji-DKrWlrKg.js => dept-tongji-DXWAi3Ff.js} | 2 +- ...{detail-Cgvp-_PL.js => detail-DKUoQk_D.js} | 2 +- ...{detail-M0gHlgVc.js => detail-xgWfI8Le.js} | 2 +- .../{dict-8-SPyWb_.js => dict-CZJyZkTT.js} | 2 +- ...{doctor-CqioGk2D.js => doctor-BZ-6as6e.js} | 2 +- server/public/admin/assets/edit-3bdey74N.js | 1 - server/public/admin/assets/edit-8H2NhPo5.js | 1 - server/public/admin/assets/edit-B1eZmWqP.js | 1 - .../{edit-BzrSb_V-.js => edit-BAQcgf6y.js} | 2 +- server/public/admin/assets/edit-BDvvA_gT.js | 1 + server/public/admin/assets/edit-BEOCSxrJ.js | 1 + server/public/admin/assets/edit-BL6-9qZ2.js | 1 + .../{edit-BBYrKOeZ.js => edit-BX51An5D.js} | 2 +- server/public/admin/assets/edit-B_wGlDhL.js | 1 - server/public/admin/assets/edit-BaB4QDHq.js | 1 - .../{edit-_A3kcUPH.js => edit-BwxqNdrV.js} | 2 +- server/public/admin/assets/edit-C5DDVcvS.js | 1 + .../{edit-DVQrgsMJ.js => edit-C5ML-lKb.js} | 2 +- server/public/admin/assets/edit-CEuRjNQ2.js | 1 + server/public/admin/assets/edit-CPPUlBVk.js | 1 + server/public/admin/assets/edit-CWpJeocW.js | 1 - .../{edit-C96_xkzc.js => edit-C_RwJBv2.js} | 2 +- server/public/admin/assets/edit-D1SoOzTa.js | 1 + .../{edit-B2UjXNUY.js => edit-DC5hUyyD.js} | 2 +- server/public/admin/assets/edit-DEUGz5U-.js | 1 - .../{edit-C0ag41Ju.js => edit-DI3F_G6T.js} | 2 +- server/public/admin/assets/edit-DKo3eb_i.js | 1 + server/public/admin/assets/edit-DKradhBd.js | 1 + server/public/admin/assets/edit-DPJC6Ado.js | 1 - .../{edit-o0GZ5HGe.js => edit-DShP9dbK.js} | 2 +- server/public/admin/assets/edit-DiVLx7h4.js | 1 + server/public/admin/assets/edit-DnpPtN-o.js | 1 - server/public/admin/assets/edit-E56wgM9X.js | 1 - server/public/admin/assets/edit-ckLJqch4.js | 1 - server/public/admin/assets/edit-dgTxXsf8.js | 1 + .../{edit-vUeq2SpE.js => edit-mLRg8Zlj.js} | 2 +- ...e_type_script_setup_true_lang-BXsrwL-Y.js} | 2 +- ...e_type_script_setup_true_lang-BhmDUUmH.js} | 2 +- ...e_type_script_setup_true_lang-D4NnUw3A.js} | 2 +- ...e_type_script_setup_true_lang-DBR4r8G6.js} | 2 +- ...e_type_script_setup_true_lang-DK-bk5jR.js} | 2 +- ...e_type_script_setup_true_lang-DP2Xlmdd.js} | 2 +- ...e_type_script_setup_true_lang-DtuVPyoN.js} | 2 +- ...e_type_script_setup_true_lang-VIhBpqn6.js} | 2 +- ...e_type_script_setup_true_lang-mUGc9CZB.js} | 2 +- ...e_type_script_setup_true_lang-qSAWp6mZ.js} | 2 +- ...e_name_articleColumnEdit_lang-BfaQQnZn.js} | 2 +- ...nt-CfdO0qds.js => environment-BUXc3V6G.js} | 2 +- .../{error-CMCHDzcN.js => error-6FP48E5B.js} | 2 +- .../{fans-DGCEKtNc.js => fans-BF_y35sQ.js} | 2 +- .../{file-DgCzlv_t.js => file-C9QmA6nu.js} | 2 +- .../{file-BSLutQ6Q.js => file-D4bvhnm2.js} | 2 +- ...{filing-JOen2IS2.js => filing-D60SpNy7.js} | 2 +- ...inance-DO6FzBk8.js => finance-Bka0H2CZ.js} | 2 +- ...it-Dq0_NqQZ.js => first_visit-D3BuRLUy.js} | 2 +- ...y-86RSqA7j.js => follow_reply-CbFkHmug.js} | 2 +- ...e_type_script_setup_true_lang-DRLRiIzH.js} | 2 +- ...{guahao-CDxq4uNv.js => guahao-BrgoBdcV.js} | 2 +- .../assets/{h5-mdvy1Cpg.js => h5-CPFFKjD5.js} | 2 +- .../assets/{h5-95av_p9T.js => h5-Dhl-4jmv.js} | 2 +- .../{icon-iGDIM6R8.js => icon-Bs5SgeQr.js} | 2 +- .../{index-BVwnd8A7.js => index--A3zwFrX.js} | 2 +- .../{index-DzgMnFVr.js => index-B2jtx2bf.js} | 2 +- .../{index-C7M1esnu.js => index-B533BOtK.js} | 4 +- .../{index-tC3jtUZm.js => index-B8ivRMOh.js} | 2 +- .../{index-Jnm6fRWA.js => index-BH-dg4ug.js} | 2 +- server/public/admin/assets/index-BLSe8mr1.js | 1 - .../{index-CAx_1v6P.js => index-BWkxbE1a.js} | 2 +- .../{index-BDuLlk_N.js => index-Bah7OLZ8.js} | 2 +- .../{index-DwwGc2F3.js => index-BbIFSx8E.js} | 2 +- .../{index-DPZ9o5-u.js => index-BbV-V8PG.js} | 2 +- .../{index-CGyV7ceF.js => index-Be8yEUiM.js} | 2 +- .../{index-D8sN2TCt.js => index-BnBKFySM.js} | 4 +- .../{index-yyAKDqe8.js => index-BydY8kCU.js} | 4 +- .../{index-DA1PdhTS.js => index-ByuNO7XH.js} | 2 +- .../{index-DTw-4ccp.js => index-C5jCku85.js} | 2 +- .../{index-lSQE6iRL.js => index-C7JYrbNs.js} | 2 +- .../{index-DlFTAv1E.js => index-C7ZmxV-F.js} | 2 +- .../{index-C0NzaaDf.js => index-C7vAYfs5.js} | 2 +- .../{index-CT9QYsp5.js => index-CLDsuxxQ.js} | 2 +- .../{index-vSvUBdqb.js => index-CMRA3PuU.js} | 2 +- server/public/admin/assets/index-CWGYoexO.css | 1 - .../{index-BvJKY-U8.js => index-CYYHkN3d.js} | 2 +- .../{index-CxN7cX60.js => index-CZl-VQtd.js} | 2 +- .../{index-Dlm_Ud7P.js => index-CbdrpUUq.js} | 4 +- .../{index-Boj89U8p.js => index-CfZ4aqc0.js} | 2 +- .../{index-B3SE_zRo.js => index-Ch5_JdNF.js} | 2 +- .../{index-ATVwjEyz.js => index-CjDFDDim.js} | 2 +- .../{index-BVA_6cp6.js => index-Cohei6LU.js} | 4 +- .../{index-BBQfJsGy.js => index-CqlL8qOd.js} | 2 +- .../{index-Ho7YRaEv.js => index-Cw7jeHt_.js} | 2 +- server/public/admin/assets/index-D161q69e.css | 1 + server/public/admin/assets/index-D5ha4AI8.js | 1 + .../{index-CDzrObNE.js => index-DA2AflTP.js} | 2 +- .../{index-CK4OHxfK.js => index-DAqCCRRG.js} | 2 +- .../{index-BWpENAYd.js => index-DDTQj9el.js} | 2 +- .../{index-A0QOtr2T.js => index-DEw2EmBw.js} | 2 +- .../{index-ciItWuER.js => index-DNIZ2L1-.js} | 2 +- .../{index-Cv4PBRwN.js => index-DNqjqay5.js} | 2 +- .../{index-UZLFPeoq.js => index-DVelW5J4.js} | 2 +- .../{index-CZ8VhsQ7.js => index-DWyJ4XiR.js} | 2 +- .../{index-DSQ4trbC.js => index-DXF3nun7.js} | 4 +- .../{index-CHE1S1if.js => index-Dadt1zx4.js} | 2 +- .../{index-nGT57_mw.js => index-DbqxaR5x.js} | 2 +- .../{index-DOtR0ony.js => index-De_Ggygg.js} | 2 +- .../{index-gRG9ukFs.js => index-DlN9NhXT.js} | 2 +- .../{index-CzENQZ3e.js => index-DsBo-4fn.js} | 2 +- .../{index-BSeLizHq.js => index-DussDQHo.js} | 2 +- .../{index-BI2Ucjvd.js => index-DyOJaJ6j.js} | 4 +- server/public/admin/assets/index-Ikjyl3zK.js | 1 - server/public/admin/assets/index-KBVowiPJ.js | 1 + .../{index-D826NRqd.js => index-S1gTXaZW.js} | 2 +- .../{index-BI2XUhVK.js => index-U4zTCoJm.js} | 2 +- .../{index-BogfzvkW.js => index-UhFJ9RCI.js} | 2 +- server/public/admin/assets/index-WVdL8TUb.js | 1 + .../{index-Dmtv7rWH.js => index-fNGMMQD2.js} | 2 +- .../{index-DcKx5Zv3.js => index-gBZ7-66e.js} | 2 +- .../{index-BOjQQyiz.js => index-jWJrM75h.js} | 2 +- .../{index-CKgzsHFk.js => index-jc3ZzON2.js} | 2 +- .../{index-DKcacmwz.js => index-oKlQecaT.js} | 2 +- server/public/admin/assets/index-qgB-gudq.js | 1 - .../{index-XOp1oFjn.js => index-s5WLt4CF.js} | 2 +- .../{index-BWW_kssV.js => index-uLhETmFw.js} | 2 +- .../{index-C-fg9mUq.js => index-yHj7SKQ4.js} | 2 +- ...e_type_script_setup_true_lang-CGi6SiYS.js} | 2 +- ...e_vue_type_style_index_0_lang-B11qapSk.js} | 2 +- ...ex_h5-CedwFVOM.js => index_h5-ClXAKosm.js} | 4 +- ...on-1N9FIumN.js => information-D7X5sCiB.js} | 2 +- ...ournal-CTuTL0Qa.js => journal-EvYmBZCT.js} | 2 +- ...-CD4NFRIN.js => keyword_reply-C6VRoxHN.js} | 2 +- .../{link-Cywy8iKO.js => link-D6EvD4j5.js} | 2 +- .../{list-DNaVQUWi.js => list-DI2sw77y.js} | 2 +- .../{list-CFn08t8a.js => list-q_ueKYBM.js} | 4 +- ...ist_h5-lelkA1zL.js => list_h5-DHGwRgIv.js} | 4 +- .../{login-HSmCf0WN.js => login-oyiRFxGF.js} | 2 +- ...CSdqbOWO.js => login_register-BsJQglAy.js} | 2 +- ...icine-D4PSMk_C.js => medicine-CeuSH5P5.js} | 2 +- ...icine-BGoWrHZQ.js => medicine-D-dCqQ1G.js} | 2 +- .../{menu-B-eJPkns.js => menu-DJZiNDpA.js} | 2 +- .../{menu-Csbwqclt.js => menu-DqrBSnXV.js} | 2 +- .../{menu-C8pkmrPP.js => menu-dCURUr4D.js} | 2 +- .../public/admin/assets/menu-set-CyZvHnam.js | 1 + .../public/admin/assets/menu-set-yB78RNPw.js | 1 - ...e_type_script_setup_true_lang-BrpZ1Esn.js} | 2 +- ...essage-DOXWICw4.js => message-DeCY9DIY.js} | 2 +- ...e-DWeFqNLW.js => mobile-style-BJPx8XWE.js} | 2 +- ...e_type_script_setup_true_lang-BSb-ymoZ.js} | 2 +- ...{mubiao-CtR36119.js => mubiao-43Kytdl3.js} | 2 +- ...83Ci7g.js => mubiao-dept-card-CJtS9jzd.js} | 2 +- ...8o5qYa.js => mubiao-dept-node-o0cVTBTl.js} | 2 +- ...a-attr-SNi4vyVH.js => oa-attr-DvLS-UHJ.js} | 2 +- .../admin/assets/oa-menu-form-COdaICdr.js | 1 + .../admin/assets/oa-menu-form-DVM0KTgi.js | 1 - .../assets/oa-menu-form-edit-CAb91-T_.js | 1 + .../assets/oa-menu-form-edit-WgxROdzR.js | 1 - ...e_type_script_setup_true_lang-CAMxOlcL.js} | 2 +- ...e_type_script_setup_true_lang-BLW7ceyF.js} | 2 +- ...phone-N644Zi_s.js => oa-phone-CjkbdX_m.js} | 2 +- ...g-DCc7YH8s.js => open_setting-DzfaF8EB.js} | 2 +- .../{order-DsXbJQv_.js => order-DIocapO1.js} | 2 +- ...ist-DUjvHQvE.js => order_list-C2mJT1SM.js} | 4 +- ...-CT50l9ao.js => order_list_h5-CNoDPTO-.js} | 4 +- ...rflow-BSo7-beH.js => overflow-kDTId0qf.js} | 2 +- ...{paiban-DjBHNMk3.js => paiban-C3uz7VzV.js} | 2 +- ...atient-gF122Y6k.js => patient-CpnWapWy.js} | 2 +- ...l-C6DjYsI8.js => patient-call-D0xnxSZh.js} | 2 +- .../{pay-Delv8P2f.js => pay-Bd1XnIo1.js} | 2 +- .../assets/{pc-Bk3Tvw-v.js => pc-DrP4iNoM.js} | 2 +- ...ils-CZzxPWD5.js => pc_details-uy34b2Ox.js} | 2 +- .../{perm-CZKo0Mmn.js => perm-BD9k-zw8.js} | 2 +- ...{picker-BbcA6kuc.js => picker-CE0Pfmrv.js} | 2 +- ...{picker-BAOfQDdS.js => picker-uz8umsna.js} | 2 +- ...e_type_script_setup_true_lang-Bwi0xWhY.js} | 2 +- .../{post-CBTOaewL.js => post-yTL8VCEj.js} | 2 +- ...Xjv.js => prescription-drawer-BEcSwJC_.js} | 2 +- ...review-CyivopeO.js => preview-D4bEHEV9.js} | 2 +- ...-pc-BLPQL8hC.js => preview-pc-baMk5AhO.js} | 2 +- ...gress-C6qeH9_p.js => progress-KzU3n1Kq.js} | 2 +- ...tocol-BwVn3JpF.js => protocol-CrgGcoSJ.js} | 2 +- .../{qywx-CWcOh1sT.js => qywx-DxG0aKr4.js} | 2 +- ...donly-BxbRUmFO.js => readonly-CjOt1Tys.js} | 2 +- ...VY6cYD3.js => recharge_record-DfhUk4mU.js} | 2 +- .../admin/assets/refund-log-BoUviBhs.js | 1 + .../admin/assets/refund-log-eqJV4vY4.js | 1 - ...e_type_script_setup_true_lang-CLIzXwvi.js} | 2 +- ...-Byyslm3j.js => refund_record-CYo_3Kmf.js} | 2 +- .../admin/assets/relations-add-CJI8OwDQ.js | 1 + .../admin/assets/relations-add-UmSg4hJ8.js | 1 - ...e_type_script_setup_true_lang-BgIUlPoE.js} | 2 +- ...text-bYrWm5Ub.js => rich_text-DKxI42Fn.js} | 2 +- .../{role-CjKcg2Ub.js => role-DNZbmMPj.js} | 2 +- ...{roster-CwrIEDV5.js => roster-DXfqVXnY.js} | 2 +- ...YD6ura.js => self_input_stats-BirdNTvT.js} | 2 +- ...etting-CJnDPoQO.js => setting-DddIw5eD.js} | 2 +- .../{setup-BWQ3-7cU.js => setup-B4FPVb57.js} | 2 +- ...ics-U30bkxFR.js => statistics-CpEVS-Pr.js} | 2 +- .../{stats-Cf3aMyps.js => stats-DQjWWEKm.js} | 2 +- .../{style-CQHYfs7y.js => style-5q5EFKBp.js} | 2 +- ...{tabbar-BgxPit7U.js => tabbar-B_cnHFD1.js} | 2 +- .../{tcm-DE5Wfo6u.js => tcm-D7a_LLlo.js} | 2 +- ...r-Bl4xeUlD.js => theme-picker-mZj-_qpf.js} | 2 +- ...{tongji-BJPHDF40.js => tongji-C1wqmUBv.js} | 2 +- ...{upload-lQxejo5B.js => upload-9CT7wPz8.js} | 2 +- ...q0Ye1fLv.js => useDictOptions-DY-li7cm.js} | 2 +- ...7qYs3.js => useListTimeFilter-D7kvnLOg.js} | 2 +- ..._.js => useMediaSourceOptions-Cmz-rAmo.js} | 2 +- ...nuOa-DFeb4XYQ.js => useMenuOa-DfImeyDg.js} | 2 +- .../{user-OOQ8OY_S.js => user-2uu4SLqW.js} | 2 +- .../{weapp-DbJ0f5Xu.js => weapp-CcUHTdmz.js} | 2 +- .../{weapp-DZYH4ck5.js => weapp-Fk8BaeDS.js} | 2 +- ...ebsite-vHPbcRar.js => website-BRLSpcLf.js} | 2 +- .../{wx_oa-3hSYRsew.js => wx_oa-lHYBBign.js} | 2 +- .../public/admin/assets/yeji-edit-CVBd3ZUy.js | 1 + .../public/admin/assets/yeji-edit-DIYLvmQy.js | 1 - ...e_type_script_setup_true_lang-idiS46qx.js} | 2 +- .../{yeji-BCGpE7SW.js => yeji-zWKsvP2S.js} | 2 +- server/public/admin/index.html | 2 +- server/tests/OrderEditTimeContractTest.php | 88 +++++++++++++++++++ 344 files changed, 520 insertions(+), 319 deletions(-) rename server/public/admin/assets/{403-CtdR6W2l.js => 403-BmLGKk7A.js} (75%) rename server/public/admin/assets/{404-CXFa7py3.js => 404-CmorDS9I.js} (58%) rename server/public/admin/assets/{AppointmentRecordPanel-BWwjr2Td.js => AppointmentRecordPanel-BpH__D9N.js} (96%) rename server/public/admin/assets/{AssignLogPanel-BJqJNEtv.js => AssignLogPanel-DMXc8Jqu.js} (97%) rename server/public/admin/assets/{AssistantWatchCallDialog-CWA9HZCR.js => AssistantWatchCallDialog-BqtcnHW7.js} (96%) rename server/public/admin/assets/{BloodRecordList-OMVExjrX.js => BloodRecordList-DTMeNv6F.js} (98%) rename server/public/admin/assets/{CallRecordPanel-DxSFvwQC.js => CallRecordPanel-ZONGPWXz.js} (93%) rename server/public/admin/assets/{CaseRecordList-BLtWH42F.js => CaseRecordList-CL7Kp6AB.js} (95%) rename server/public/admin/assets/{DailyMatrix-CyosaMyV.js => DailyMatrix-D01fgjtP.js} (98%) rename server/public/admin/assets/{DiagnosisTodoList-Bve9_uHk.js => DiagnosisTodoList-xS02xWPz.js} (97%) rename server/public/admin/assets/{DietRecordList-BGqliNYm.js => DietRecordList-C9fLdJrg.js} (93%) rename server/public/admin/assets/{ExerciseRecordList-Ho4xULsr.js => ExerciseRecordList-CvmKVQcK.js} (94%) delete mode 100644 server/public/admin/assets/GancaoSubmissionReconcileButton-DG0nuCy2.js create mode 100644 server/public/admin/assets/GancaoSubmissionReconcileButton-DrJpChfz.js rename server/public/admin/assets/{GancaoSubmissionReconcileButton.vue_vue_type_script_setup_true_lang-3HAp0vZ1.js => GancaoSubmissionReconcileButton.vue_vue_type_script_setup_true_lang-BftoD0d7.js} (96%) rename server/public/admin/assets/{ImChatRecordPanel-BPt2PSWO.js => ImChatRecordPanel-BlkJJW_C.js} (97%) rename server/public/admin/assets/{MessageBubble-Blhw3brs.js => MessageBubble-B5BsnFAs.js} (98%) rename server/public/admin/assets/{NoteTimeline-DKHSaTnS.js => NoteTimeline-wNJ-rZy1.js} (94%) rename server/public/admin/assets/{OrderActionHost-DAIJtIvu.js => OrderActionHost-D73bqFMW.js} (98%) rename server/public/admin/assets/{OrderPanel-DzCf0lfm.js => OrderPanel-DgNymLix.js} (96%) rename server/public/admin/assets/{PaibanPanel-BJ9vKOZj.js => PaibanPanel-BTEE_UUk.js} (97%) rename server/public/admin/assets/{PatientCaseCard-DjuuNi0D.js => PatientCaseCard-NxgOrpCM.js} (98%) rename server/public/admin/assets/{PatientInfoCard-CH5SNzTt.js => PatientInfoCard-D5uw3qNu.js} (96%) rename server/public/admin/assets/{PatientOrderList-BVXyX-J1.js => PatientOrderList-CSsHGOMg.js} (96%) rename server/public/admin/assets/{PrescriptionAiBatchGenerateDialog-BjmI-O2T.js => PrescriptionAiBatchGenerateDialog-B-IEFevM.js} (99%) rename server/public/admin/assets/{PrescriptionAiReportDialog-COSWV6J7.js => PrescriptionAiReportDialog-CCdOg7ZY.js} (99%) rename server/public/admin/assets/{PrescriptionOrderDetailDrawer-DKHZSM3G.js => PrescriptionOrderDetailDrawer-B_2wN6Ii.js} (99%) rename server/public/admin/assets/{ProgressPanel-Bp7xfqwl.js => ProgressPanel-DBVRvrQ9.js} (98%) rename server/public/admin/assets/{PromotionAutomationForm-KEn9fnx9.js => PromotionAutomationForm-BXs5CP3m.js} (98%) rename server/public/admin/assets/{RecordingPlaybackBlock-EOaWFCvB.js => RecordingPlaybackBlock-CmnTchSD.js} (94%) rename server/public/admin/assets/{RecordingVideoPlayer-CBiSJJjw.js => RecordingVideoPlayer-CR4Pj59Y.js} (98%) rename server/public/admin/assets/{SendPanel-B4JzYDcv.js => SendPanel-BgqrvafY.js} (99%) rename server/public/admin/assets/{TrackingMatrix-Ds9UAziv.js => TrackingMatrix-BTeLttMt.js} (99%) rename server/public/admin/assets/{TrackingNoteTimeline-DImZbQnB.js => TrackingNoteTimeline-D8entDIu.js} (93%) rename server/public/admin/assets/{WecomFloatingWidgetBuilder-BDkf_18P.js => WecomFloatingWidgetBuilder-H2GVpZS9.js} (99%) rename server/public/admin/assets/{WelcomeMessageEditor-C4MvGiPe.js => WelcomeMessageEditor-DU7sC9wU.js} (99%) delete mode 100644 server/public/admin/assets/account-adjust-BQTUUVRb.js create mode 100644 server/public/admin/assets/account-adjust-CXxGZv7i.js rename server/public/admin/assets/{account-adjust.vue_vue_type_script_setup_true_lang-1tNuVJCo.js => account-adjust.vue_vue_type_script_setup_true_lang-CYtMLkFm.js} (94%) rename server/public/admin/assets/{account_cost-C4m8qYkN.js => account_cost-CDzLKn8m.js} (94%) rename server/public/admin/assets/{add-Gu66mkdw.js => add-BvP9GbDo.js} (99%) create mode 100644 server/public/admin/assets/add-nav-BDin2PpE.js delete mode 100644 server/public/admin/assets/add-nav-D7rLIffq.js rename server/public/admin/assets/{add-nav.vue_vue_type_script_setup_true_lang-CWR6_Pss.js => add-nav.vue_vue_type_script_setup_true_lang-BRpnt2eu.js} (92%) rename server/public/admin/assets/{admin-ChXgJQ5G.js => admin-DwnCzeVZ.js} (84%) rename server/public/admin/assets/{appointment-zTo2RqT9.js => appointment-BEsZkoeX.js} (97%) rename server/public/admin/assets/{article-Cu5yzLRi.js => article-D3zonLOQ.js} (93%) rename server/public/admin/assets/{asset-B2iLP5lJ.js => asset-D_ZwIjus.js} (90%) rename server/public/admin/assets/{attr-C57oQ8cq.js => attr-37BbNTQY.js} (74%) create mode 100644 server/public/admin/assets/attr-B3poZnXc.js create mode 100644 server/public/admin/assets/attr-BVNi28ly.js create mode 100644 server/public/admin/assets/attr-BoawLJZX.js delete mode 100644 server/public/admin/assets/attr-ByaCyTPj.js delete mode 100644 server/public/admin/assets/attr-CMrm-DSv.js rename server/public/admin/assets/{attr-rlv01xAn.js => attr-CWiMQaRC.js} (92%) create mode 100644 server/public/admin/assets/attr-Cn4VQoWB.js delete mode 100644 server/public/admin/assets/attr-CwE1nJyu.js delete mode 100644 server/public/admin/assets/attr-D4tNr3SV.js delete mode 100644 server/public/admin/assets/attr-DFZZwPjZ.js create mode 100644 server/public/admin/assets/attr-DKl8I92I.js create mode 100644 server/public/admin/assets/attr-DpmlKg-8.js create mode 100644 server/public/admin/assets/attr-MCgScSMl.js delete mode 100644 server/public/admin/assets/attr-OcAk4MZZ.js delete mode 100644 server/public/admin/assets/attr-aC8tJyH9.js create mode 100644 server/public/admin/assets/attr-setting-NSizJDtk.js delete mode 100644 server/public/admin/assets/attr-setting-k7posH2Y.js rename server/public/admin/assets/{attr-setting.vue_vue_type_script_setup_true_lang-BV5Kr0G_.js => attr-setting.vue_vue_type_script_setup_true_lang-B-f0b3rG.js} (94%) rename server/public/admin/assets/{attr.vue_vue_type_script_setup_true_lang-RGK71_GJ.js => attr.vue_vue_type_script_setup_true_lang-BrNS2ps-.js} (91%) rename server/public/admin/assets/{attr.vue_vue_type_script_setup_true_lang-CdxoGwgl.js => attr.vue_vue_type_script_setup_true_lang-CATWtHib.js} (93%) rename server/public/admin/assets/{attr.vue_vue_type_script_setup_true_lang-u4o_m7kt.js => attr.vue_vue_type_script_setup_true_lang-CKteeFgv.js} (95%) rename server/public/admin/assets/{attr.vue_vue_type_script_setup_true_lang-Cg44HydJ.js => attr.vue_vue_type_script_setup_true_lang-CkKLqcSB.js} (96%) rename server/public/admin/assets/{attr.vue_vue_type_script_setup_true_lang-CPzfaJDP.js => attr.vue_vue_type_script_setup_true_lang-DoWm5gA7.js} (96%) rename server/public/admin/assets/{attr.vue_vue_type_script_setup_true_lang-Bp-mV46k.js => attr.vue_vue_type_script_setup_true_lang-DseAJCCV.js} (96%) rename server/public/admin/assets/{attr.vue_vue_type_script_setup_true_lang-B3OEm7iz.js => attr.vue_vue_type_script_setup_true_lang-mooesuD5.js} (96%) create mode 100644 server/public/admin/assets/auth-BlESbXb9.js delete mode 100644 server/public/admin/assets/auth-CESdQlQD.js rename server/public/admin/assets/{auth.vue_vue_type_script_setup_true_lang-jtFw75zX.js => auth.vue_vue_type_script_setup_true_lang-AQ4_bAhe.js} (92%) rename server/public/admin/assets/{balance_details-CDL5YJLN.js => balance_details-Cr7ZUPxv.js} (94%) rename server/public/admin/assets/{bind-work-wechat-CxNRSijL.js => bind-work-wechat-Dg0ap0Ef.js} (97%) rename server/public/admin/assets/{cache-9M5LCxnE.js => cache-BgfOe8T_.js} (94%) rename server/public/admin/assets/{change-password-qtBWH34K.js => change-password-C46iFdxM.js} (95%) rename server/public/admin/assets/{code-CaYOWymS.js => code-DNIhtABi.js} (92%) delete mode 100644 server/public/admin/assets/code-preview-B1NJP23z.js create mode 100644 server/public/admin/assets/code-preview-RJcnpzk5.js rename server/public/admin/assets/{code-preview.vue_vue_type_script_setup_true_lang-DUs78PfX.js => code-preview.vue_vue_type_script_setup_true_lang-CRW3XgSs.js} (95%) rename server/public/admin/assets/{commission-settlement-CwVxh19X.js => commission-settlement-Ba0rN1JT.js} (99%) rename server/public/admin/assets/{config-D3etBTYC.js => config-CVDJcIrk.js} (94%) rename server/public/admin/assets/{consumer-RNmfwlCf.js => consumer-CuRvN66O.js} (81%) delete mode 100644 server/public/admin/assets/content-6NQb9fPh.js delete mode 100644 server/public/admin/assets/content-B9sQ5ebX.js rename server/public/admin/assets/{content-BypteVIU.js => content-BTKWe1Z5.js} (90%) create mode 100644 server/public/admin/assets/content-BhhhXtGi.js rename server/public/admin/assets/{content-CcP_0nbo.js => content-BpKeA_ag.js} (84%) create mode 100644 server/public/admin/assets/content-CDaFLLpk.js delete mode 100644 server/public/admin/assets/content-CZhOpWVD.js rename server/public/admin/assets/{content-C87VwXzh.js => content-CpbkN2kw.js} (85%) create mode 100644 server/public/admin/assets/content-D1KvtwNt.js rename server/public/admin/assets/{content-CPAKwgni.js => content-D1ij9T2f.js} (90%) rename server/public/admin/assets/{content-CFWygn2e.js => content-D1r1vbY9.js} (90%) rename server/public/admin/assets/{content-B7cQuIwl.js => content-DFD7Fvvr.js} (69%) delete mode 100644 server/public/admin/assets/content-D_SXu5io.js rename server/public/admin/assets/{content-CqjH9rbN.js => content-HKhGJAox.js} (86%) rename server/public/admin/assets/{content-D1UpIOe_.js => content-HN9yJedS.js} (90%) delete mode 100644 server/public/admin/assets/content-LA105ak9.js create mode 100644 server/public/admin/assets/content-lxqjEjid.js create mode 100644 server/public/admin/assets/content-zynEdjJM.js rename server/public/admin/assets/{content.vue_vue_type_script_setup_true_lang-uKSsEXIj.js => content.vue_vue_type_script_setup_true_lang-4xOoG6gL.js} (90%) rename server/public/admin/assets/{content.vue_vue_type_script_setup_true_lang-DVY7e7kv.js => content.vue_vue_type_script_setup_true_lang-BdL5caX-.js} (90%) rename server/public/admin/assets/{content.vue_vue_type_script_setup_true_lang-foMFOzn5.js => content.vue_vue_type_script_setup_true_lang-CmpqhioD.js} (89%) rename server/public/admin/assets/{content.vue_vue_type_script_setup_true_lang-CkqaiKg0.js => content.vue_vue_type_script_setup_true_lang-Cu2kG1Y2.js} (92%) rename server/public/admin/assets/{content.vue_vue_type_script_setup_true_lang-BWyBDECY.js => content.vue_vue_type_script_setup_true_lang-h3Bp18Pd.js} (88%) create mode 100644 server/public/admin/assets/cost-edit-DU2ac9RQ.js delete mode 100644 server/public/admin/assets/cost-edit-eteZY1-Z.js rename server/public/admin/assets/{cost-edit.vue_vue_type_script_setup_true_lang-BGyNX0C4.js => cost-edit.vue_vue_type_script_setup_true_lang-pSKxrmjL.js} (95%) delete mode 100644 server/public/admin/assets/data-table-CSKxrtmg.js create mode 100644 server/public/admin/assets/data-table-gbxPyRId.js rename server/public/admin/assets/{data-table.vue_vue_type_script_setup_true_lang-DmdHTjkI.js => data-table.vue_vue_type_script_setup_true_lang-BZ1Q2f6Y.js} (92%) rename server/public/admin/assets/{decoration-img-jpQ962yE.js => decoration-img-Do-2aqVt.js} (92%) rename server/public/admin/assets/{decoration-WmZwV1l6.js => decoration-knxy2eJf.js} (87%) rename server/public/admin/assets/{default_reply-C0s8MlWW.js => default_reply-BXZmmklG.js} (91%) rename server/public/admin/assets/{department-CICDmn1H.js => department-gRRYxP3x.js} (86%) rename server/public/admin/assets/{dept-tongji-DKrWlrKg.js => dept-tongji-DXWAi3Ff.js} (97%) rename server/public/admin/assets/{detail-Cgvp-_PL.js => detail-DKUoQk_D.js} (93%) rename server/public/admin/assets/{detail-M0gHlgVc.js => detail-xgWfI8Le.js} (95%) rename server/public/admin/assets/{dict-8-SPyWb_.js => dict-CZJyZkTT.js} (92%) rename server/public/admin/assets/{doctor-CqioGk2D.js => doctor-BZ-6as6e.js} (95%) delete mode 100644 server/public/admin/assets/edit-3bdey74N.js delete mode 100644 server/public/admin/assets/edit-8H2NhPo5.js delete mode 100644 server/public/admin/assets/edit-B1eZmWqP.js rename server/public/admin/assets/{edit-BzrSb_V-.js => edit-BAQcgf6y.js} (95%) create mode 100644 server/public/admin/assets/edit-BDvvA_gT.js create mode 100644 server/public/admin/assets/edit-BEOCSxrJ.js create mode 100644 server/public/admin/assets/edit-BL6-9qZ2.js rename server/public/admin/assets/{edit-BBYrKOeZ.js => edit-BX51An5D.js} (94%) delete mode 100644 server/public/admin/assets/edit-B_wGlDhL.js delete mode 100644 server/public/admin/assets/edit-BaB4QDHq.js rename server/public/admin/assets/{edit-_A3kcUPH.js => edit-BwxqNdrV.js} (96%) create mode 100644 server/public/admin/assets/edit-C5DDVcvS.js rename server/public/admin/assets/{edit-DVQrgsMJ.js => edit-C5ML-lKb.js} (96%) create mode 100644 server/public/admin/assets/edit-CEuRjNQ2.js create mode 100644 server/public/admin/assets/edit-CPPUlBVk.js delete mode 100644 server/public/admin/assets/edit-CWpJeocW.js rename server/public/admin/assets/{edit-C96_xkzc.js => edit-C_RwJBv2.js} (96%) create mode 100644 server/public/admin/assets/edit-D1SoOzTa.js rename server/public/admin/assets/{edit-B2UjXNUY.js => edit-DC5hUyyD.js} (95%) delete mode 100644 server/public/admin/assets/edit-DEUGz5U-.js rename server/public/admin/assets/{edit-C0ag41Ju.js => edit-DI3F_G6T.js} (94%) create mode 100644 server/public/admin/assets/edit-DKo3eb_i.js create mode 100644 server/public/admin/assets/edit-DKradhBd.js delete mode 100644 server/public/admin/assets/edit-DPJC6Ado.js rename server/public/admin/assets/{edit-o0GZ5HGe.js => edit-DShP9dbK.js} (97%) create mode 100644 server/public/admin/assets/edit-DiVLx7h4.js delete mode 100644 server/public/admin/assets/edit-DnpPtN-o.js delete mode 100644 server/public/admin/assets/edit-E56wgM9X.js delete mode 100644 server/public/admin/assets/edit-ckLJqch4.js create mode 100644 server/public/admin/assets/edit-dgTxXsf8.js rename server/public/admin/assets/{edit-vUeq2SpE.js => edit-mLRg8Zlj.js} (89%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_lang-lgkHYHs8.js => edit.vue_vue_type_script_setup_true_lang-BXsrwL-Y.js} (97%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_lang-CgRuR__C.js => edit.vue_vue_type_script_setup_true_lang-BhmDUUmH.js} (97%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_lang-CjNyADYX.js => edit.vue_vue_type_script_setup_true_lang-D4NnUw3A.js} (94%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_lang-DF4flQdk.js => edit.vue_vue_type_script_setup_true_lang-DBR4r8G6.js} (94%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_lang-DV7z1Uj3.js => edit.vue_vue_type_script_setup_true_lang-DK-bk5jR.js} (98%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_lang-BzMFszkq.js => edit.vue_vue_type_script_setup_true_lang-DP2Xlmdd.js} (97%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_lang-3QPUkJoq.js => edit.vue_vue_type_script_setup_true_lang-DtuVPyoN.js} (93%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_lang-UeMFutFG.js => edit.vue_vue_type_script_setup_true_lang-VIhBpqn6.js} (97%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_lang-B1jEngmN.js => edit.vue_vue_type_script_setup_true_lang-mUGc9CZB.js} (93%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_lang-CApaxj9z.js => edit.vue_vue_type_script_setup_true_lang-qSAWp6mZ.js} (94%) rename server/public/admin/assets/{edit.vue_vue_type_script_setup_true_name_articleColumnEdit_lang-Hs5Pxchq.js => edit.vue_vue_type_script_setup_true_name_articleColumnEdit_lang-BfaQQnZn.js} (96%) rename server/public/admin/assets/{environment-CfdO0qds.js => environment-BUXc3V6G.js} (96%) rename server/public/admin/assets/{error-CMCHDzcN.js => error-6FP48E5B.js} (92%) rename server/public/admin/assets/{fans-DGCEKtNc.js => fans-BF_y35sQ.js} (89%) rename server/public/admin/assets/{file-DgCzlv_t.js => file-C9QmA6nu.js} (90%) rename server/public/admin/assets/{file-BSLutQ6Q.js => file-D4bvhnm2.js} (95%) rename server/public/admin/assets/{filing-JOen2IS2.js => filing-D60SpNy7.js} (88%) rename server/public/admin/assets/{finance-DO6FzBk8.js => finance-Bka0H2CZ.js} (95%) rename server/public/admin/assets/{first_visit-Dq0_NqQZ.js => first_visit-D3BuRLUy.js} (98%) rename server/public/admin/assets/{follow_reply-86RSqA7j.js => follow_reply-CbFkHmug.js} (91%) rename server/public/admin/assets/{footer.vue_vue_type_script_setup_true_lang-DduXUdph.js => footer.vue_vue_type_script_setup_true_lang-DRLRiIzH.js} (87%) rename server/public/admin/assets/{guahao-CDxq4uNv.js => guahao-BrgoBdcV.js} (98%) rename server/public/admin/assets/{h5-mdvy1Cpg.js => h5-CPFFKjD5.js} (94%) rename server/public/admin/assets/{h5-95av_p9T.js => h5-Dhl-4jmv.js} (99%) rename server/public/admin/assets/{icon-iGDIM6R8.js => icon-Bs5SgeQr.js} (94%) rename server/public/admin/assets/{index-BVwnd8A7.js => index--A3zwFrX.js} (99%) rename server/public/admin/assets/{index-DzgMnFVr.js => index-B2jtx2bf.js} (95%) rename server/public/admin/assets/{index-C7M1esnu.js => index-B533BOtK.js} (89%) rename server/public/admin/assets/{index-tC3jtUZm.js => index-B8ivRMOh.js} (92%) rename server/public/admin/assets/{index-Jnm6fRWA.js => index-BH-dg4ug.js} (88%) delete mode 100644 server/public/admin/assets/index-BLSe8mr1.js rename server/public/admin/assets/{index-CAx_1v6P.js => index-BWkxbE1a.js} (94%) rename server/public/admin/assets/{index-BDuLlk_N.js => index-Bah7OLZ8.js} (99%) rename server/public/admin/assets/{index-DwwGc2F3.js => index-BbIFSx8E.js} (95%) rename server/public/admin/assets/{index-DPZ9o5-u.js => index-BbV-V8PG.js} (99%) rename server/public/admin/assets/{index-CGyV7ceF.js => index-Be8yEUiM.js} (84%) rename server/public/admin/assets/{index-D8sN2TCt.js => index-BnBKFySM.js} (93%) rename server/public/admin/assets/{index-yyAKDqe8.js => index-BydY8kCU.js} (95%) rename server/public/admin/assets/{index-DA1PdhTS.js => index-ByuNO7XH.js} (81%) rename server/public/admin/assets/{index-DTw-4ccp.js => index-C5jCku85.js} (99%) rename server/public/admin/assets/{index-lSQE6iRL.js => index-C7JYrbNs.js} (95%) rename server/public/admin/assets/{index-DlFTAv1E.js => index-C7ZmxV-F.js} (97%) rename server/public/admin/assets/{index-C0NzaaDf.js => index-C7vAYfs5.js} (92%) rename server/public/admin/assets/{index-CT9QYsp5.js => index-CLDsuxxQ.js} (99%) rename server/public/admin/assets/{index-vSvUBdqb.js => index-CMRA3PuU.js} (97%) delete mode 100644 server/public/admin/assets/index-CWGYoexO.css rename server/public/admin/assets/{index-BvJKY-U8.js => index-CYYHkN3d.js} (98%) rename server/public/admin/assets/{index-CxN7cX60.js => index-CZl-VQtd.js} (99%) rename server/public/admin/assets/{index-Dlm_Ud7P.js => index-CbdrpUUq.js} (97%) rename server/public/admin/assets/{index-Boj89U8p.js => index-CfZ4aqc0.js} (95%) rename server/public/admin/assets/{index-B3SE_zRo.js => index-Ch5_JdNF.js} (58%) rename server/public/admin/assets/{index-ATVwjEyz.js => index-CjDFDDim.js} (90%) rename server/public/admin/assets/{index-BVA_6cp6.js => index-Cohei6LU.js} (87%) rename server/public/admin/assets/{index-BBQfJsGy.js => index-CqlL8qOd.js} (91%) rename server/public/admin/assets/{index-Ho7YRaEv.js => index-Cw7jeHt_.js} (98%) create mode 100644 server/public/admin/assets/index-D161q69e.css create mode 100644 server/public/admin/assets/index-D5ha4AI8.js rename server/public/admin/assets/{index-CDzrObNE.js => index-DA2AflTP.js} (89%) rename server/public/admin/assets/{index-CK4OHxfK.js => index-DAqCCRRG.js} (74%) rename server/public/admin/assets/{index-BWpENAYd.js => index-DDTQj9el.js} (87%) rename server/public/admin/assets/{index-A0QOtr2T.js => index-DEw2EmBw.js} (99%) rename server/public/admin/assets/{index-ciItWuER.js => index-DNIZ2L1-.js} (99%) rename server/public/admin/assets/{index-Cv4PBRwN.js => index-DNqjqay5.js} (96%) rename server/public/admin/assets/{index-UZLFPeoq.js => index-DVelW5J4.js} (92%) rename server/public/admin/assets/{index-CZ8VhsQ7.js => index-DWyJ4XiR.js} (99%) rename server/public/admin/assets/{index-DSQ4trbC.js => index-DXF3nun7.js} (84%) rename server/public/admin/assets/{index-CHE1S1if.js => index-Dadt1zx4.js} (94%) rename server/public/admin/assets/{index-nGT57_mw.js => index-DbqxaR5x.js} (99%) rename server/public/admin/assets/{index-DOtR0ony.js => index-De_Ggygg.js} (98%) rename server/public/admin/assets/{index-gRG9ukFs.js => index-DlN9NhXT.js} (86%) rename server/public/admin/assets/{index-CzENQZ3e.js => index-DsBo-4fn.js} (99%) rename server/public/admin/assets/{index-BSeLizHq.js => index-DussDQHo.js} (96%) rename server/public/admin/assets/{index-BI2Ucjvd.js => index-DyOJaJ6j.js} (89%) delete mode 100644 server/public/admin/assets/index-Ikjyl3zK.js create mode 100644 server/public/admin/assets/index-KBVowiPJ.js rename server/public/admin/assets/{index-D826NRqd.js => index-S1gTXaZW.js} (90%) rename server/public/admin/assets/{index-BI2XUhVK.js => index-U4zTCoJm.js} (93%) rename server/public/admin/assets/{index-BogfzvkW.js => index-UhFJ9RCI.js} (93%) create mode 100644 server/public/admin/assets/index-WVdL8TUb.js rename server/public/admin/assets/{index-Dmtv7rWH.js => index-fNGMMQD2.js} (98%) rename server/public/admin/assets/{index-DcKx5Zv3.js => index-gBZ7-66e.js} (93%) rename server/public/admin/assets/{index-BOjQQyiz.js => index-jWJrM75h.js} (99%) rename server/public/admin/assets/{index-CKgzsHFk.js => index-jc3ZzON2.js} (88%) rename server/public/admin/assets/{index-DKcacmwz.js => index-oKlQecaT.js} (98%) delete mode 100644 server/public/admin/assets/index-qgB-gudq.js rename server/public/admin/assets/{index-XOp1oFjn.js => index-s5WLt4CF.js} (78%) rename server/public/admin/assets/{index-BWW_kssV.js => index-uLhETmFw.js} (93%) rename server/public/admin/assets/{index-C-fg9mUq.js => index-yHj7SKQ4.js} (96%) rename server/public/admin/assets/{index.vue_vue_type_script_setup_true_lang-DRmqxZlC.js => index.vue_vue_type_script_setup_true_lang-CGi6SiYS.js} (98%) rename server/public/admin/assets/{index.vue_vue_type_style_index_0_lang-CQoGbDFs.js => index.vue_vue_type_style_index_0_lang-B11qapSk.js} (91%) rename server/public/admin/assets/{index_h5-CedwFVOM.js => index_h5-ClXAKosm.js} (93%) rename server/public/admin/assets/{information-1N9FIumN.js => information-D7X5sCiB.js} (92%) rename server/public/admin/assets/{journal-CTuTL0Qa.js => journal-EvYmBZCT.js} (94%) rename server/public/admin/assets/{keyword_reply-CD4NFRIN.js => keyword_reply-C6VRoxHN.js} (91%) rename server/public/admin/assets/{link-Cywy8iKO.js => link-D6EvD4j5.js} (70%) rename server/public/admin/assets/{list-DNaVQUWi.js => list-DI2sw77y.js} (96%) rename server/public/admin/assets/{list-CFn08t8a.js => list-q_ueKYBM.js} (93%) rename server/public/admin/assets/{list_h5-lelkA1zL.js => list_h5-DHGwRgIv.js} (92%) rename server/public/admin/assets/{login-HSmCf0WN.js => login-oyiRFxGF.js} (97%) rename server/public/admin/assets/{login_register-CSdqbOWO.js => login_register-BsJQglAy.js} (97%) rename server/public/admin/assets/{medicine-D4PSMk_C.js => medicine-CeuSH5P5.js} (81%) rename server/public/admin/assets/{medicine-BGoWrHZQ.js => medicine-D-dCqQ1G.js} (98%) rename server/public/admin/assets/{menu-B-eJPkns.js => menu-DJZiNDpA.js} (71%) rename server/public/admin/assets/{menu-Csbwqclt.js => menu-DqrBSnXV.js} (91%) rename server/public/admin/assets/{menu-C8pkmrPP.js => menu-dCURUr4D.js} (86%) create mode 100644 server/public/admin/assets/menu-set-CyZvHnam.js delete mode 100644 server/public/admin/assets/menu-set-yB78RNPw.js rename server/public/admin/assets/{menu-set.vue_vue_type_script_setup_true_lang-B3X7Pnx0.js => menu-set.vue_vue_type_script_setup_true_lang-BrpZ1Esn.js} (94%) rename server/public/admin/assets/{message-DOXWICw4.js => message-DeCY9DIY.js} (87%) rename server/public/admin/assets/{mobile-style-DWeFqNLW.js => mobile-style-BJPx8XWE.js} (50%) rename server/public/admin/assets/{mobile-style.vue_vue_type_script_setup_true_lang-CuN-qVrx.js => mobile-style.vue_vue_type_script_setup_true_lang-BSb-ymoZ.js} (97%) rename server/public/admin/assets/{mubiao-CtR36119.js => mubiao-43Kytdl3.js} (97%) rename server/public/admin/assets/{mubiao-dept-card-Dm83Ci7g.js => mubiao-dept-card-CJtS9jzd.js} (98%) rename server/public/admin/assets/{mubiao-dept-node-Dg8o5qYa.js => mubiao-dept-node-o0cVTBTl.js} (97%) rename server/public/admin/assets/{oa-attr-SNi4vyVH.js => oa-attr-DvLS-UHJ.js} (84%) create mode 100644 server/public/admin/assets/oa-menu-form-COdaICdr.js delete mode 100644 server/public/admin/assets/oa-menu-form-DVM0KTgi.js create mode 100644 server/public/admin/assets/oa-menu-form-edit-CAb91-T_.js delete mode 100644 server/public/admin/assets/oa-menu-form-edit-WgxROdzR.js rename server/public/admin/assets/{oa-menu-form-edit.vue_vue_type_script_setup_true_lang-BU0lQ2rg.js => oa-menu-form-edit.vue_vue_type_script_setup_true_lang-CAMxOlcL.js} (90%) rename server/public/admin/assets/{oa-menu-form.vue_vue_type_script_setup_true_lang-B2-C723X.js => oa-menu-form.vue_vue_type_script_setup_true_lang-BLW7ceyF.js} (97%) rename server/public/admin/assets/{oa-phone-N644Zi_s.js => oa-phone-CjkbdX_m.js} (91%) rename server/public/admin/assets/{open_setting-DCc7YH8s.js => open_setting-DzfaF8EB.js} (93%) rename server/public/admin/assets/{order-DsXbJQv_.js => order-DIocapO1.js} (96%) rename server/public/admin/assets/{order_list-DUjvHQvE.js => order_list-C2mJT1SM.js} (98%) rename server/public/admin/assets/{order_list_h5-CT50l9ao.js => order_list_h5-CNoDPTO-.js} (98%) rename server/public/admin/assets/{overflow-BSo7-beH.js => overflow-kDTId0qf.js} (87%) rename server/public/admin/assets/{paiban-DjBHNMk3.js => paiban-C3uz7VzV.js} (95%) rename server/public/admin/assets/{patient-gF122Y6k.js => patient-CpnWapWy.js} (88%) rename server/public/admin/assets/{patient-call-C6DjYsI8.js => patient-call-D0xnxSZh.js} (98%) rename server/public/admin/assets/{pay-Delv8P2f.js => pay-Bd1XnIo1.js} (85%) rename server/public/admin/assets/{pc-Bk3Tvw-v.js => pc-DrP4iNoM.js} (95%) rename server/public/admin/assets/{pc_details-CZzxPWD5.js => pc_details-uy34b2Ox.js} (50%) rename server/public/admin/assets/{perm-CZKo0Mmn.js => perm-BD9k-zw8.js} (67%) rename server/public/admin/assets/{picker-BbcA6kuc.js => picker-CE0Pfmrv.js} (98%) rename server/public/admin/assets/{picker-BAOfQDdS.js => picker-uz8umsna.js} (95%) rename server/public/admin/assets/{picker.vue_vue_type_script_setup_true_lang-DVRJp74q.js => picker.vue_vue_type_script_setup_true_lang-Bwi0xWhY.js} (97%) rename server/public/admin/assets/{post-CBTOaewL.js => post-yTL8VCEj.js} (86%) rename server/public/admin/assets/{prescription-drawer-TD_YhXjv.js => prescription-drawer-BEcSwJC_.js} (98%) rename server/public/admin/assets/{preview-CyivopeO.js => preview-D4bEHEV9.js} (61%) rename server/public/admin/assets/{preview-pc-BLPQL8hC.js => preview-pc-baMk5AhO.js} (59%) rename server/public/admin/assets/{progress-C6qeH9_p.js => progress-KzU3n1Kq.js} (98%) rename server/public/admin/assets/{protocol-BwVn3JpF.js => protocol-CrgGcoSJ.js} (89%) rename server/public/admin/assets/{qywx-CWcOh1sT.js => qywx-DxG0aKr4.js} (99%) rename server/public/admin/assets/{readonly-BxbRUmFO.js => readonly-CjOt1Tys.js} (82%) rename server/public/admin/assets/{recharge_record-CVY6cYD3.js => recharge_record-DfhUk4mU.js} (92%) create mode 100644 server/public/admin/assets/refund-log-BoUviBhs.js delete mode 100644 server/public/admin/assets/refund-log-eqJV4vY4.js rename server/public/admin/assets/{refund-log.vue_vue_type_script_setup_true_lang-CGanx4Ad.js => refund-log.vue_vue_type_script_setup_true_lang-CLIzXwvi.js} (96%) rename server/public/admin/assets/{refund_record-Byyslm3j.js => refund_record-CYo_3Kmf.js} (96%) create mode 100644 server/public/admin/assets/relations-add-CJI8OwDQ.js delete mode 100644 server/public/admin/assets/relations-add-UmSg4hJ8.js rename server/public/admin/assets/{relations-add.vue_vue_type_script_setup_true_lang-DQpJL7Qk.js => relations-add.vue_vue_type_script_setup_true_lang-BgIUlPoE.js} (95%) rename server/public/admin/assets/{rich_text-bYrWm5Ub.js => rich_text-DKxI42Fn.js} (70%) rename server/public/admin/assets/{role-CjKcg2Ub.js => role-DNZbmMPj.js} (83%) rename server/public/admin/assets/{roster-CwrIEDV5.js => roster-DXfqVXnY.js} (99%) rename server/public/admin/assets/{self_input_stats-k9YD6ura.js => self_input_stats-BirdNTvT.js} (91%) rename server/public/admin/assets/{setting-CJnDPoQO.js => setting-DddIw5eD.js} (93%) rename server/public/admin/assets/{setup-BWQ3-7cU.js => setup-B4FPVb57.js} (78%) rename server/public/admin/assets/{statistics-U30bkxFR.js => statistics-CpEVS-Pr.js} (88%) rename server/public/admin/assets/{stats-Cf3aMyps.js => stats-DQjWWEKm.js} (97%) rename server/public/admin/assets/{style-CQHYfs7y.js => style-5q5EFKBp.js} (84%) rename server/public/admin/assets/{tabbar-BgxPit7U.js => tabbar-B_cnHFD1.js} (73%) rename server/public/admin/assets/{tcm-DE5Wfo6u.js => tcm-D7a_LLlo.js} (99%) rename server/public/admin/assets/{theme-picker-Bl4xeUlD.js => theme-picker-mZj-_qpf.js} (93%) rename server/public/admin/assets/{tongji-BJPHDF40.js => tongji-C1wqmUBv.js} (97%) rename server/public/admin/assets/{upload-lQxejo5B.js => upload-9CT7wPz8.js} (90%) rename server/public/admin/assets/{useDictOptions-q0Ye1fLv.js => useDictOptions-DY-li7cm.js} (84%) rename server/public/admin/assets/{useListTimeFilter-Bux7qYs3.js => useListTimeFilter-D7kvnLOg.js} (98%) rename server/public/admin/assets/{useMediaSourceOptions-B2W31OQ_.js => useMediaSourceOptions-Cmz-rAmo.js} (90%) rename server/public/admin/assets/{useMenuOa-DFeb4XYQ.js => useMenuOa-DfImeyDg.js} (92%) rename server/public/admin/assets/{user-OOQ8OY_S.js => user-2uu4SLqW.js} (82%) rename server/public/admin/assets/{weapp-DbJ0f5Xu.js => weapp-CcUHTdmz.js} (93%) rename server/public/admin/assets/{weapp-DZYH4ck5.js => weapp-Fk8BaeDS.js} (68%) rename server/public/admin/assets/{website-vHPbcRar.js => website-BRLSpcLf.js} (91%) rename server/public/admin/assets/{wx_oa-3hSYRsew.js => wx_oa-lHYBBign.js} (93%) create mode 100644 server/public/admin/assets/yeji-edit-CVBd3ZUy.js delete mode 100644 server/public/admin/assets/yeji-edit-DIYLvmQy.js rename server/public/admin/assets/{yeji-edit.vue_vue_type_script_setup_true_lang-DbSiGPBE.js => yeji-edit.vue_vue_type_script_setup_true_lang-idiS46qx.js} (98%) rename server/public/admin/assets/{yeji-BCGpE7SW.js => yeji-zWKsvP2S.js} (99%) create mode 100644 server/tests/OrderEditTimeContractTest.php diff --git a/admin/src/views/order/index.vue b/admin/src/views/order/index.vue index 0a882618e..d71c8bd3e 100644 --- a/admin/src/views/order/index.vue +++ b/admin/src/views/order/index.vue @@ -677,6 +677,28 @@ + + + + + +