feat(config): 按业务模块拆分 Mock 开关
用 VITE_MOCK_* 系列环境变量替换全局 VITE_USE_MOCK,各模块独立控制演示数据 启用,并新增 src/utils/mock-flags.ts 统一解析缺省值。文档库关闭演示库时 如实提示接口待接入,避免静默沿用本地数据或覆盖已保存内容。
This commit is contained in:
@@ -1,4 +1,15 @@
|
||||
VITE_APP_NAME=medical-sign-clinical
|
||||
VITE_API_BASE_URL=/api
|
||||
# 联调默认走真实后端;仅在演示原型时改为 true。
|
||||
VITE_USE_MOCK=false
|
||||
|
||||
# Mock 开关:按业务模块(对齐侧边栏菜单)独立控制,取值只认 true / false。
|
||||
# 留空或注释掉即使用该模块的缺省值,缺省值以 src/utils/mock-flags.ts 为准,
|
||||
# 目前是「签署工作台 + 文档库走演示数据,其余模块走真实接口」。
|
||||
# 只有想让某个模块偏离缺省时才需要在这里(或本地 .env.*.local)显式声明。
|
||||
# VITE_MOCK_WORKBENCH_HOME=false
|
||||
# VITE_MOCK_SIGNING=true
|
||||
# VITE_MOCK_DOCUMENTS=true
|
||||
# VITE_MOCK_DOCUMENT_PERMISSIONS=false
|
||||
# VITE_MOCK_REPORTS=false
|
||||
# VITE_MOCK_USERS=false
|
||||
# VITE_MOCK_ORGANIZATION=false
|
||||
# VITE_MOCK_SETTINGS=false
|
||||
|
||||
@@ -86,7 +86,7 @@ TanStack Vue Query、PDF 预览、报表图表、自动化测试和签字板适
|
||||
|
||||
已完成 Vite 基础初始化、路由、Pinia、原型主题 CSS、登录页、首页、签署工作台第一版 Mock 和文档库管理页面。登录、首页统计、签署工作台的患者/就诊/模板/任务/审计、签署文件下载、短信重发、模板创建/版本工作流、用户组织查询与用户创建编辑,以及按模板维护文档权限已经接入 MEDISIGN 后端;系统设置仍保留 Mock,真实签字板/线上签名回调和打印服务仍需设备或后端能力。
|
||||
|
||||
自测与演示:`VITE_USE_MOCK=true` 时,文档库和签署任务的演示数据会镜像到 localStorage(见 `utils/mock-storage.ts`),刷新页面后仍可继续,不必每次重建文书、重发签署;文档库页头的「重置演示数据」可清空这些本地数据回到初始状态。持久化只针对演示数据,不涉及登录态与真实患者信息。
|
||||
自测与演示:开启 `VITE_MOCK_DOCUMENTS` / `VITE_MOCK_SIGNING`(两者缺省即为开启)时,文档库和签署任务的演示数据会镜像到 localStorage(见 `utils/mock-storage.ts`),刷新页面后仍可继续,不必每次重建文书、重发签署;文档库页头的「重置演示数据」可清空这些本地数据回到初始状态。持久化只针对演示数据,不涉及登录态与真实患者信息。
|
||||
|
||||
## 当前路由结构
|
||||
|
||||
@@ -193,6 +193,6 @@ API 请求和响应类型按业务域放在 `api/workbench/types.ts`、`api/mana
|
||||
|
||||
开发环境默认使用 `/api` 作为同源接口前缀,Vite 会将 `/api` 转发到 `https://ipad.shenynet.com`,因此浏览器不会直接跨域请求后端。代理配置位于 `vite.config.ts`,不改写 `/api/v1/...` 路径。修改代理或环境变量后需要重启 Vite 开发服务。
|
||||
|
||||
生产环境不会使用 Vite 的开发代理,需要在 Nginx 或其他网关中配置同样的 `/api` 反向代理。文档权限和用户权限相关管理接口默认调用真实后端,仅在显式设置 `VITE_USE_MOCK=true` 时使用 Mock 数据。使用本地开发代理时,`VITE_API_BASE_URL` 应填写 `/api`;如果改为直连后端,则需要后端配置允许当前前端源的 CORS。
|
||||
生产环境不会使用 Vite 的开发代理,需要在 Nginx 或其他网关中配置同样的 `/api` 反向代理。Mock 开关按业务模块(对齐菜单)拆分,缺省只有文档库和签署工作台使用演示数据,其余模块直接调用真实后端;各开关的环境变量名与缺省值见 `src/utils/mock-flags.ts`,需要临时切换时在本地 `.env.*.local` 里覆盖即可。使用本地开发代理时,`VITE_API_BASE_URL` 应填写 `/api`;如果改为直连后端,则需要后端配置允许当前前端源的 CORS。
|
||||
|
||||
当前尚未接入的签署能力包括手写板设备桥接、线上签署页面/签名回调和打印服务。签署投递、一次性 Token 消费和真实 PNG 上传 API 已完成封装,但页面不能用 Canvas 演示数据冒充真实签名;需要接入设备适配器或患者 H5 回调后再启用。短信初次发送接口需要完整手机号,而患者查询只返回脱敏手机号,因此真实模式会要求当前操作人员确认完整投递地址;生产环境也可以改为由后端根据患者 ID 解析投递地址。需要演示完整交互时再设置 `VITE_USE_MOCK=true`。
|
||||
当前尚未接入的签署能力包括手写板设备桥接、线上签署页面/签名回调和打印服务。签署投递、一次性 Token 消费和真实 PNG 上传 API 已完成封装,但页面不能用 Canvas 演示数据冒充真实签名;需要接入设备适配器或患者 H5 回调后再启用。短信初次发送接口需要完整手机号,而患者查询只返回脱敏手机号,因此真实模式会要求当前操作人员确认完整投递地址;生产环境也可以改为由后端根据患者 ID 解析投递地址。签署工作台缺省即使用演示数据(`VITE_MOCK_SIGNING`),需要走真实投递时把它设为 `false`。
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
## 当前核验结论
|
||||
|
||||
文档权限页面仅在显式设置 `VITE_USE_MOCK=true` 时使用演示数据;未设置该变量或设置为其他值时,页面调用真实权限接口。修改环境变量后需要重启 Vite。
|
||||
文档权限页面仅在显式设置 `VITE_MOCK_DOCUMENT_PERMISSIONS=true` 时使用演示数据;未设置该变量或设为 `false` 时,页面调用真实权限接口。该开关缺省关闭。修改环境变量后需要重启 Vite。
|
||||
|
||||
本轮新增接口已覆盖当前文档权限页面的后端缺口,暂无阻断前端接入的缺失接口。跨模板矩阵查询最多支持 100 个模板,批量保存最多支持 200 项;页面当前采用“模板选择 + 当前模板矩阵”的交互,没有臆造跨模板对比表。
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
- 明细由 tasks 服务端分页返回;
|
||||
- 院区、科室和模板分类由 options 返回;
|
||||
- 导出改为服务端异步任务,完成后下载文件;
|
||||
- VITE_USE_MOCK 非 false 时仍保留原有 Mock 演示数据。
|
||||
- 打开 `VITE_MOCK_REPORTS` 时仍保留原有 Mock 演示数据;该开关缺省关闭,报表默认走服务端报表接口。
|
||||
|
||||
## 2. 接入矩阵
|
||||
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
真实接口模式:
|
||||
|
||||
```bash
|
||||
VITE_USE_MOCK=false npm run dev
|
||||
VITE_MOCK_USERS=false npm run dev
|
||||
```
|
||||
|
||||
至少验证以下场景:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
> 事实基准:用户于 2026-09-02 导出的 default_OpenAPI.json,OpenAPI 3.1.0,MEDISIGN 患者电子签 API v1。
|
||||
>
|
||||
> 接入状态:当 VITE_USE_MOCK=false 时,首页已接入 GET /api/v1/workbench/overview。
|
||||
> 接入状态:首页缺省(`VITE_MOCK_WORKBENCH_HOME` 未开启)已接入 GET /api/v1/workbench/overview。
|
||||
|
||||
## 1. 核验结论
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { unwrapApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
import type { ApiResponse, PageResult } from '@/types/common'
|
||||
|
||||
@@ -11,7 +12,8 @@ import type {
|
||||
BackendPage,
|
||||
} from './types'
|
||||
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK !== 'false'
|
||||
// 审计日志当前只用于签署留痕,跟随签署工作台的开关;后续有独立页面时再拆出来。
|
||||
const useMockData = mockFlags.signing
|
||||
|
||||
function formatDateTime(value: string) {
|
||||
const date = new Date(value)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { unwrapApiResponse, unwrapNullableApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
import type { ApiResponse, PageResult } from '@/types/common'
|
||||
|
||||
@@ -30,8 +31,7 @@ import type {
|
||||
UpdateRolePermissionPolicyRequest,
|
||||
} from './types'
|
||||
|
||||
// 仅显式开启 VITE_USE_MOCK=true 时使用演示数据,避免联调环境因未注入变量而误入 Mock 分支。
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK === 'true'
|
||||
const useMockData = mockFlags.documentPermissions
|
||||
|
||||
export const isPermissionMockEnabled = useMockData
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import axios from 'axios'
|
||||
|
||||
import { unwrapApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
import type { ApiResponse, PageResult } from '@/types/common'
|
||||
|
||||
@@ -17,8 +18,7 @@ import type {
|
||||
TemplateVersionResponseDto,
|
||||
} from './types'
|
||||
|
||||
// 仅显式开启 VITE_USE_MOCK=true 时使用演示数据,避免联调环境因未注入变量而误入 Mock 分支。
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK === 'true'
|
||||
const useMockData = mockFlags.documents
|
||||
|
||||
export const isDocumentMockEnabled = useMockData
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { unwrapApiResponse, unwrapNullableApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
import type { ApiResponse, PageResult } from '@/types/common'
|
||||
|
||||
@@ -13,8 +14,7 @@ import type {
|
||||
UpdateDepartmentRequest,
|
||||
} from './types'
|
||||
|
||||
// 仅显式开启 VITE_USE_MOCK=true 时使用演示数据,避免联调环境因未注入变量而误入 Mock 分支。
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK === 'true'
|
||||
const useMockData = mockFlags.organization
|
||||
|
||||
function getRecords(data: BackendCollection<OrganizationResponseDto>) {
|
||||
return Array.isArray(data) ? data : (data.records ?? data.items ?? data.content ?? [])
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import axios from 'axios'
|
||||
|
||||
import { unwrapApiResponse, unwrapNullableApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
import type { ApiResponse, PageResult } from '@/types/common'
|
||||
|
||||
@@ -14,8 +15,7 @@ import type {
|
||||
UpdateApiPermissionRequest,
|
||||
} from './types'
|
||||
|
||||
// 仅显式开启 VITE_USE_MOCK=true 时使用演示权限目录。
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK === 'true'
|
||||
const useMockData = mockFlags.users
|
||||
|
||||
export const isApiPermissionMockEnabled = useMockData
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { unwrapApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
import type { ApiResponse } from '@/types/common'
|
||||
|
||||
@@ -13,7 +14,7 @@ import type {
|
||||
ReportTasksQueryDto,
|
||||
} from './types'
|
||||
|
||||
export const isReportsMockEnabled = import.meta.env.VITE_USE_MOCK !== 'false'
|
||||
export const isReportsMockEnabled = mockFlags.reports
|
||||
|
||||
function compactQuery(values: object) {
|
||||
return Object.fromEntries(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { unwrapApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
import type { ApiResponse } from '@/types/common'
|
||||
|
||||
@@ -14,8 +15,7 @@ import type {
|
||||
UpdateRoleRequest,
|
||||
} from './types'
|
||||
|
||||
// 仅显式开启 VITE_USE_MOCK=true 时使用演示数据,避免联调环境因未注入变量而误入 Mock 分支。
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK === 'true'
|
||||
const useMockData = mockFlags.users
|
||||
|
||||
const fallbackColors = ['#6b5bd2', '#0e6e8c', '#0f9d6c', '#d9821f', '#c65d5d']
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
|
||||
import type { SystemSettingsResponse, UpdateSystemSettingsRequest } from './types'
|
||||
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK !== 'false'
|
||||
const useMockData = mockFlags.settings
|
||||
|
||||
const mockSettings: SystemSettingsResponse = {
|
||||
sections: [
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import axios from 'axios'
|
||||
|
||||
import { unwrapApiResponse, unwrapNullableApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
import type { ApiResponse, PageResult } from '@/types/common'
|
||||
|
||||
@@ -22,8 +23,7 @@ import type {
|
||||
UserRolesUpdateRequest,
|
||||
} from './types'
|
||||
|
||||
// 仅显式开启 VITE_USE_MOCK=true 时使用演示数据,避免联调环境因未注入变量而误入 Mock 分支。
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK === 'true'
|
||||
const useMockData = mockFlags.users
|
||||
|
||||
export const isUserMockEnabled = useMockData
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import axios from 'axios'
|
||||
|
||||
import { unwrapApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
|
||||
import type {
|
||||
@@ -11,7 +12,7 @@ import type {
|
||||
SigningArtifact,
|
||||
} from './types'
|
||||
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK !== 'false'
|
||||
const useMockData = mockFlags.signing
|
||||
|
||||
type ArtifactCollection = SignArtifactResponseDto[] | ApiPageResponse<SignArtifactResponseDto>
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { getCampuses } from '@/api/management/organization'
|
||||
import { unwrapApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { request } from '@/utils/request'
|
||||
import type { ApiResponse } from '@/types/common'
|
||||
|
||||
@@ -18,7 +19,8 @@ import type {
|
||||
WorkbenchTodoTask,
|
||||
WorkbenchTrendPoint,
|
||||
} from './types'
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK !== 'false'
|
||||
|
||||
const useMockData = mockFlags.workbenchHome
|
||||
|
||||
interface MockCampusOverview {
|
||||
summary: WorkbenchOverviewResponse['summary']
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import axios from 'axios'
|
||||
|
||||
import { unwrapApiResponse } from '@/utils/api-response'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { readLocalSigningTemplates } from '@/utils/mock-document-library'
|
||||
import { MOCK_STORAGE_KEYS, readMockState, writeMockState } from '@/utils/mock-storage'
|
||||
import { request } from '@/utils/request'
|
||||
@@ -35,7 +36,7 @@ import type {
|
||||
VisitType,
|
||||
} from './types'
|
||||
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK !== 'false'
|
||||
const useMockData = mockFlags.signing
|
||||
|
||||
const mockPatients: PatientProfile[] = [
|
||||
{
|
||||
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
/// <reference types="vite/client" />
|
||||
|
||||
interface ImportMetaEnv {
|
||||
readonly VITE_APP_NAME: string
|
||||
readonly VITE_API_BASE_URL: string
|
||||
|
||||
/**
|
||||
* 各业务模块的 Mock 开关,取值只认 'true' / 'false',留空即使用模块缺省值。
|
||||
* 缺省值与各开关的含义见 src/utils/mock-flags.ts。
|
||||
*/
|
||||
readonly VITE_MOCK_WORKBENCH_HOME?: string
|
||||
readonly VITE_MOCK_SIGNING?: string
|
||||
readonly VITE_MOCK_DOCUMENTS?: string
|
||||
readonly VITE_MOCK_DOCUMENT_PERMISSIONS?: string
|
||||
readonly VITE_MOCK_REPORTS?: string
|
||||
readonly VITE_MOCK_USERS?: string
|
||||
readonly VITE_MOCK_ORGANIZATION?: string
|
||||
readonly VITE_MOCK_SETTINGS?: string
|
||||
}
|
||||
@@ -2,12 +2,12 @@ import { computed, ref } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
import { getCampuses } from '@/api/management/organization'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import type { CampusRecord } from '@/api/management/types'
|
||||
import type { WorkbenchCampus } from '@/api/workbench/types'
|
||||
|
||||
// 仅显式开启 VITE_USE_MOCK=true 时使用演示院区,避免真实接口联调时把 mock UUID
|
||||
// 作为 campusId 发给后端。
|
||||
const useMockData = import.meta.env.VITE_USE_MOCK === 'true'
|
||||
// 演示院区跟随组织数据开关:开着会把 mock 的 campusId 一并发给真实接口。
|
||||
const useMockData = mockFlags.organization
|
||||
|
||||
const mockCampusRecords: CampusRecord[] = [
|
||||
{ id: 'mock-campus-main', code: 'MAIN', name: '本部院区', status: 'ENABLED', sortNo: 1 },
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/**
|
||||
* Mock 开关:按业务模块(对齐侧边栏菜单)独立控制。
|
||||
*
|
||||
* 背景:早期只有一个全局 VITE_USE_MOCK,一开全开、一关全关,而且各 API 文件的
|
||||
* 默认值约定还不一致(有的 `!== 'false'` 默认开,有的 `=== 'true'` 默认关)。
|
||||
* 文档库与签署工作台还依赖演示数据,其余模块已经接了真实接口,混在一起就只能整体
|
||||
* 切换,联调时很容易把真实接口的页面也带进 Mock 分支。
|
||||
*
|
||||
* 现在的约定:
|
||||
* - 每个模块读自己的环境变量,缺省值就是「这个模块默认要不要用演示数据」;
|
||||
* - 环境变量没配、或值不是 true / false 时一律用缺省值,联调环境不会被本地 .env 残留影响;
|
||||
* - 开关粒度对齐菜单,不按 API 文件拆。同一个菜单下的多个 API 模块共用一个开关,
|
||||
* 例如签署工作台同时覆盖签署任务与签署产物。
|
||||
*/
|
||||
|
||||
/** 环境变量未配置(或值不是 true / false)时按缺省值处理 */
|
||||
function resolveMockFlag(raw: string | undefined, fallback: boolean): boolean {
|
||||
if (raw === 'true') {
|
||||
return true
|
||||
}
|
||||
|
||||
if (raw === 'false') {
|
||||
return false
|
||||
}
|
||||
|
||||
return fallback
|
||||
}
|
||||
|
||||
export const mockFlags = {
|
||||
/** 首页:工作台概览、待办与趋势 */
|
||||
workbenchHome: resolveMockFlag(import.meta.env.VITE_MOCK_WORKBENCH_HOME, false),
|
||||
/** 签署工作台:签署任务、签署产物,以及仅用于签署留痕的审计日志 */
|
||||
signing: resolveMockFlag(import.meta.env.VITE_MOCK_SIGNING, true),
|
||||
/** 文档库管理:文书库与文书模板接口 */
|
||||
documents: resolveMockFlag(import.meta.env.VITE_MOCK_DOCUMENTS, true),
|
||||
/** 文档权限:模板权限配置与权限矩阵 */
|
||||
documentPermissions: resolveMockFlag(import.meta.env.VITE_MOCK_DOCUMENT_PERMISSIONS, false),
|
||||
/** 报表分析 */
|
||||
reports: resolveMockFlag(import.meta.env.VITE_MOCK_REPORTS, false),
|
||||
/** 用户与权限:用户、角色、接口权限目录 */
|
||||
users: resolveMockFlag(import.meta.env.VITE_MOCK_USERS, false),
|
||||
/**
|
||||
* 组织基础数据:院区与科室。
|
||||
* 不单独对应某个菜单,而是被首页、签署工作台、用户与权限和应用级院区选择器共用,
|
||||
* 所以独立成一个开关;开着会把演示院区的 UUID 一并发给真实接口。
|
||||
*/
|
||||
organization: resolveMockFlag(import.meta.env.VITE_MOCK_ORGANIZATION, false),
|
||||
/**
|
||||
* 系统设置。注意:系统设置页面目前直接用页面内的演示数据渲染,还没有消费
|
||||
* api/management/settings.ts,所以这个开关暂时只作用于该 API 模块。
|
||||
*/
|
||||
settings: resolveMockFlag(import.meta.env.VITE_MOCK_SETTINGS, false),
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import { useRouter } from 'vue-router'
|
||||
import NewSigningTaskDialog from '@/components/signing/NewSigningTaskDialog.vue'
|
||||
import type { SigningTaskRecord, SigningTemplate } from '@/api/workbench/types'
|
||||
import type { CampusRecord, DepartmentRecord } from '@/api/management/types'
|
||||
import { mockFlags } from '@/utils/mock-flags'
|
||||
import { clearMockState } from '@/utils/mock-storage'
|
||||
|
||||
import DocumentFilterTabs from './components/DocumentFilterTabs.vue'
|
||||
@@ -25,9 +26,13 @@ import type {
|
||||
|
||||
// 原型阶段:文档库数据与文书内容全部来自本地真实附件(mock.ts + contents.ts),暂不调用后端接口。
|
||||
// 后续接入时,仅需将 loadLibrary / saveTemplate / handleWorkflow 中的本地数据操作替换为文档模板接口。
|
||||
// 是否使用本地演示库由 VITE_MOCK_DOCUMENTS 控制,缺省开启。
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const useMockLibrary = mockFlags.documents
|
||||
/** 关掉演示库后,文书库本应改由模板接口提供,但该路径尚未实现:如实提示,不静默沿用本地数据 */
|
||||
const apiLibraryPending = ref(false)
|
||||
const library = ref<DocumentDepartment[]>([])
|
||||
const selectedTemplate = ref<DocumentTemplate | null>(null)
|
||||
const signingTemplate = ref<SigningTemplate | null>(null)
|
||||
@@ -114,11 +119,26 @@ function cloneLibrary(source: DocumentDepartment[]): DocumentDepartment[] {
|
||||
}
|
||||
|
||||
function loadLibrary() {
|
||||
if (!useMockLibrary) {
|
||||
library.value = []
|
||||
apiLibraryPending.value = true
|
||||
return
|
||||
}
|
||||
|
||||
library.value = cloneLibrary(loadDocumentLibrary())
|
||||
}
|
||||
|
||||
// 演示数据落本地:刷新后文书库还在,不用每次重新建文书
|
||||
watch(library, (value) => saveDocumentLibrary(value), { deep: true })
|
||||
// 演示数据落本地:刷新后文书库还在,不用每次重新建文书。
|
||||
// 关闭演示库时不写本地,否则会把之前保存的演示文书覆盖成空库。
|
||||
watch(
|
||||
library,
|
||||
(value) => {
|
||||
if (useMockLibrary) {
|
||||
saveDocumentLibrary(value)
|
||||
}
|
||||
},
|
||||
{ deep: true },
|
||||
)
|
||||
|
||||
function handlePreview(template: DocumentTemplate) {
|
||||
selectedTemplate.value = template
|
||||
@@ -323,7 +343,12 @@ onMounted(loadLibrary)
|
||||
:statuses="statusTabs"
|
||||
/>
|
||||
|
||||
<div v-if="filteredTemplates.length" class="template-grid">
|
||||
<p v-if="apiLibraryPending" class="library-pending">
|
||||
已关闭本地演示库(VITE_MOCK_DOCUMENTS=false),但文档库尚未接入模板接口,暂时无法展示文书。
|
||||
改回 VITE_MOCK_DOCUMENTS=true 可继续使用演示库。
|
||||
</p>
|
||||
|
||||
<div v-else-if="filteredTemplates.length" class="template-grid">
|
||||
<DocumentTemplateCard
|
||||
v-for="template in filteredTemplates"
|
||||
:key="template.id"
|
||||
@@ -391,6 +416,17 @@ onMounted(loadLibrary)
|
||||
gap: 16px;
|
||||
}
|
||||
|
||||
.library-pending {
|
||||
padding: 16px 20px;
|
||||
margin: 0 0 16px;
|
||||
color: var(--warn);
|
||||
font-size: 13px;
|
||||
line-height: 1.7;
|
||||
background: var(--card);
|
||||
border: 1px solid var(--line);
|
||||
border-radius: var(--r);
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
padding: 56px 24px;
|
||||
color: var(--mut);
|
||||
|
||||
@@ -408,7 +408,7 @@ function showImportMessage() {
|
||||
}
|
||||
|
||||
if (isUserMockEnabled) {
|
||||
ElMessage.info('批量导入需要切换到真实接口模式(VITE_USE_MOCK=false)')
|
||||
ElMessage.info('批量导入需要切换到真实接口模式(VITE_MOCK_USERS=false)')
|
||||
return
|
||||
}
|
||||
|
||||
@@ -467,7 +467,7 @@ function resetPassword(user: UserTableRow) {
|
||||
}
|
||||
|
||||
if (isUserMockEnabled) {
|
||||
ElMessage.info('密码重置需要切换到真实接口模式(VITE_USE_MOCK=false)')
|
||||
ElMessage.info('密码重置需要切换到真实接口模式(VITE_MOCK_USERS=false)')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user