更新
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export interface PrescriptionAiVisibilityConfig {
|
||||
role_ids: number[]
|
||||
admin_ids: number[]
|
||||
}
|
||||
|
||||
export interface PrescriptionAiVisibilityOptions {
|
||||
roles: { id: number; name: string }[]
|
||||
admins: { id: number; name: string; account: string }[]
|
||||
}
|
||||
|
||||
export interface PrescriptionAiCapabilities {
|
||||
agreement_visible: boolean
|
||||
can_manage_visibility: boolean
|
||||
}
|
||||
|
||||
// A failed or malformed read must never become an empty policy that can be saved.
|
||||
function readVisibilityConfig(value: unknown): PrescriptionAiVisibilityConfig {
|
||||
const config = value as Partial<PrescriptionAiVisibilityConfig> | null
|
||||
const validIds = (ids: unknown): ids is number[] =>
|
||||
Array.isArray(ids) && ids.every((id) => Number.isSafeInteger(id) && id > 0)
|
||||
if (!config || !validIds(config.role_ids) || !validIds(config.admin_ids)) {
|
||||
throw new Error('可见范围配置响应格式不正确')
|
||||
}
|
||||
return { role_ids: [...config.role_ids], admin_ids: [...config.admin_ids] }
|
||||
}
|
||||
|
||||
export async function getPrescriptionAiVisibilityConfig() {
|
||||
const data = await request.get({ url: '/tcm.prescriptionAi/getVisibilityConfig' })
|
||||
return readVisibilityConfig(data)
|
||||
}
|
||||
|
||||
export async function setPrescriptionAiVisibilityConfig(params: PrescriptionAiVisibilityConfig) {
|
||||
const data = await request.post({ url: '/tcm.prescriptionAi/setVisibilityConfig', params })
|
||||
return readVisibilityConfig(data)
|
||||
}
|
||||
|
||||
export function getPrescriptionAiVisibilityOptions() {
|
||||
return request.get({
|
||||
url: '/tcm.prescriptionAi/visibilityOptions'
|
||||
}) as Promise<PrescriptionAiVisibilityOptions>
|
||||
}
|
||||
|
||||
export function getPrescriptionAiCapabilities() {
|
||||
return request.get({
|
||||
url: '/tcm.prescriptionAi/capabilities'
|
||||
}) as Promise<PrescriptionAiCapabilities>
|
||||
}
|
||||
@@ -490,8 +490,10 @@ export function prescriptionOrderPatchPrescriptionUsage(params: {
|
||||
times_per_day: number
|
||||
usage_days: number
|
||||
medication_days: number
|
||||
dosage_bag_count?: number
|
||||
aux_times_per_day?: number
|
||||
aux_usage_days?: number
|
||||
aux_dosage_bag_count?: number
|
||||
}) {
|
||||
return request.post({ url: '/tcm.prescriptionOrder/patchPrescriptionUsage', params })
|
||||
}
|
||||
|
||||
@@ -312,6 +312,17 @@
|
||||
{{ detailPrescription.dosage_amount }}{{ detailPrescription.dosage_unit || 'g' }}
|
||||
<template v-if="detailPrescription.prescription_type === '浓缩水丸'">
|
||||
· {{ Number(detailPrescription.dosage_bag_count) > 0 ? Number(detailPrescription.dosage_bag_count) : 1 }}袋
|
||||
<el-button
|
||||
v-if="!readonly && detailData.prescription_id && !String(detailData.prescription_detail_error || '').trim()"
|
||||
v-perms="['tcm.prescriptionOrder/patchPrescriptionUsage']"
|
||||
type="primary"
|
||||
size="small"
|
||||
link
|
||||
class="ml-2"
|
||||
@click="openPatchUsageDialog"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
</template>
|
||||
<span v-if="detailPrescription.prescription_type === '饮片' && detailPrescription.need_decoction !== null" class="ml-2 text-gray-500">
|
||||
({{ detailPrescription.need_decoction ? '代煎' : '不代煎' }})
|
||||
@@ -325,6 +336,17 @@
|
||||
{{ detailAuxUsage.dosage_amount }}{{ detailPrescription.dosage_unit || 'g' }}
|
||||
<template v-if="detailPrescription.prescription_type === '浓缩水丸'">
|
||||
· {{ Number(detailAuxUsage.dosage_bag_count) > 0 ? Number(detailAuxUsage.dosage_bag_count) : 1 }}袋
|
||||
<el-button
|
||||
v-if="!readonly && detailData.prescription_id && !String(detailData.prescription_detail_error || '').trim()"
|
||||
v-perms="['tcm.prescriptionOrder/patchPrescriptionUsage']"
|
||||
type="primary"
|
||||
size="small"
|
||||
link
|
||||
class="ml-2"
|
||||
@click="openPatchUsageDialog"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
</template>
|
||||
<span v-if="detailPrescription.prescription_type === '饮片'" class="ml-2 text-gray-500">
|
||||
({{ detailAuxUsage.need_decoction ? '代煎' : '不代煎' }})
|
||||
@@ -943,6 +965,15 @@
|
||||
label-width="108px"
|
||||
>
|
||||
<div v-if="detailHasAuxHerbs" class="text-xs font-medium text-gray-500 mb-3">主方</div>
|
||||
<el-form-item
|
||||
v-if="detailPrescription?.prescription_type === '浓缩水丸'"
|
||||
label="每次袋数"
|
||||
prop="dosage_bag_count"
|
||||
>
|
||||
<el-select v-model="patchUsageForm.dosage_bag_count" class="w-full">
|
||||
<el-option v-for="count in 5" :key="count" :label="`${count}袋`" :value="count" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="每天次数" prop="times_per_day">
|
||||
<el-input-number
|
||||
v-model="patchUsageForm.times_per_day"
|
||||
@@ -968,6 +999,15 @@
|
||||
</el-form-item>
|
||||
<template v-if="detailHasAuxHerbs">
|
||||
<div class="text-xs font-medium text-gray-500 mb-3 mt-2 pt-2 border-t border-gray-100">辅方</div>
|
||||
<el-form-item
|
||||
v-if="detailPrescription?.prescription_type === '浓缩水丸'"
|
||||
label="每次袋数"
|
||||
prop="aux_dosage_bag_count"
|
||||
>
|
||||
<el-select v-model="patchUsageForm.aux_dosage_bag_count" class="w-full">
|
||||
<el-option v-for="count in 5" :key="count" :label="`${count}袋`" :value="count" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="每天次数" prop="aux_times_per_day">
|
||||
<el-input-number
|
||||
v-model="patchUsageForm.aux_times_per_day"
|
||||
@@ -1432,10 +1472,12 @@ const patchUsageVisible = ref(false)
|
||||
const patchUsageSaving = ref(false)
|
||||
const patchUsageFormRef = ref<FormInstance>()
|
||||
const patchUsageForm = reactive({
|
||||
dosage_bag_count: 1 as number | undefined,
|
||||
times_per_day: 3 as number | undefined,
|
||||
usage_days: 7 as number | undefined,
|
||||
aux_times_per_day: 3 as number | undefined,
|
||||
aux_usage_days: 7 as number | undefined,
|
||||
aux_dosage_bag_count: 1 as number | undefined,
|
||||
medication_days: undefined as number | undefined
|
||||
})
|
||||
const patchUsageRules = computed<FormRules>(() => {
|
||||
@@ -1444,9 +1486,15 @@ const patchUsageRules = computed<FormRules>(() => {
|
||||
usage_days: [{ required: true, message: '请填写主方开立天数', trigger: 'change' }],
|
||||
medication_days: [{ required: true, message: '请填写订单服用天数', trigger: 'change' }]
|
||||
}
|
||||
if (detailPrescription.value?.prescription_type === '浓缩水丸') {
|
||||
rules.dosage_bag_count = [{ required: true, message: '请选择主方每次袋数', trigger: 'change' }]
|
||||
}
|
||||
if (detailHasAuxHerbs.value) {
|
||||
rules.aux_times_per_day = [{ required: true, message: '请填写辅方每天次数', trigger: 'change' }]
|
||||
rules.aux_usage_days = [{ required: true, message: '请填写辅方开立天数', trigger: 'change' }]
|
||||
if (detailPrescription.value?.prescription_type === '浓缩水丸') {
|
||||
rules.aux_dosage_bag_count = [{ required: true, message: '请选择辅方每次袋数', trigger: 'change' }]
|
||||
}
|
||||
}
|
||||
return rules
|
||||
})
|
||||
@@ -1459,6 +1507,7 @@ function openPatchUsageDialog() {
|
||||
return
|
||||
}
|
||||
const aux = detailAuxUsage.value
|
||||
patchUsageForm.dosage_bag_count = Number(rx.dosage_bag_count) > 0 ? Number(rx.dosage_bag_count) : 1
|
||||
patchUsageForm.times_per_day =
|
||||
Number(rx.times_per_day) > 0 ? Number(rx.times_per_day) : 3
|
||||
patchUsageForm.usage_days =
|
||||
@@ -1468,16 +1517,20 @@ function openPatchUsageDialog() {
|
||||
patchUsageForm.aux_usage_days =
|
||||
aux && Number(aux.usage_days) > 0 ? Number(aux.usage_days) : 7
|
||||
const md = Number(ord.medication_days)
|
||||
patchUsageForm.aux_dosage_bag_count =
|
||||
aux && Number(aux.dosage_bag_count) > 0 ? Number(aux.dosage_bag_count) : 1
|
||||
patchUsageForm.medication_days = md > 0 ? md : Number(rx.usage_days) > 0 ? Number(rx.usage_days) : 7
|
||||
patchUsageVisible.value = true
|
||||
nextTick(() => patchUsageFormRef.value?.clearValidate())
|
||||
}
|
||||
|
||||
function resetPatchUsageForm() {
|
||||
patchUsageForm.dosage_bag_count = 1
|
||||
patchUsageForm.times_per_day = 3
|
||||
patchUsageForm.usage_days = 7
|
||||
patchUsageForm.aux_times_per_day = 3
|
||||
patchUsageForm.aux_usage_days = 7
|
||||
patchUsageForm.aux_dosage_bag_count = 1
|
||||
patchUsageForm.medication_days = undefined
|
||||
}
|
||||
|
||||
@@ -1498,17 +1551,25 @@ async function submitPatchUsage() {
|
||||
times_per_day: number
|
||||
usage_days: number
|
||||
medication_days: number
|
||||
dosage_bag_count?: number
|
||||
aux_times_per_day?: number
|
||||
aux_usage_days?: number
|
||||
aux_dosage_bag_count?: number
|
||||
} = {
|
||||
id: ordId,
|
||||
times_per_day: Number(patchUsageForm.times_per_day),
|
||||
usage_days: Number(patchUsageForm.usage_days),
|
||||
medication_days: Number(patchUsageForm.medication_days)
|
||||
}
|
||||
if (detailPrescription.value?.prescription_type === '浓缩水丸') {
|
||||
payload.dosage_bag_count = Number(patchUsageForm.dosage_bag_count)
|
||||
}
|
||||
if (detailHasAuxHerbs.value) {
|
||||
payload.aux_times_per_day = Number(patchUsageForm.aux_times_per_day)
|
||||
payload.aux_usage_days = Number(patchUsageForm.aux_usage_days)
|
||||
if (detailPrescription.value?.prescription_type === '浓缩水丸') {
|
||||
payload.aux_dosage_bag_count = Number(patchUsageForm.aux_dosage_bag_count)
|
||||
}
|
||||
}
|
||||
await prescriptionOrderPatchPrescriptionUsage(payload)
|
||||
feedback.msgSuccess('保存成功')
|
||||
@@ -1763,7 +1824,7 @@ async function refresh() {
|
||||
detailLogisticsExpress.value = String(d.express_company || 'auto') || 'auto'
|
||||
void fetchLogisticsTrace()
|
||||
}
|
||||
if (props.loadRelatedData) void fetchLogs(id)
|
||||
if (props.loadRelatedData) await fetchLogs(id)
|
||||
const diagId = d.diagnosis_id
|
||||
if (props.loadRelatedData && diagId) {
|
||||
void loadDetailUnlinkedPayOrders(diagId, id, d.pay_order_ids || [])
|
||||
|
||||
@@ -883,6 +883,17 @@
|
||||
{{ detailPrescription.dosage_amount }}{{ detailPrescription.dosage_unit || 'g' }}
|
||||
<template v-if="detailPrescription.prescription_type === '浓缩水丸'">
|
||||
· {{ Number(detailPrescription.dosage_bag_count) > 0 ? Number(detailPrescription.dosage_bag_count) : 1 }}袋
|
||||
<el-button
|
||||
v-if="detailData.prescription_id && !String(detailData.prescription_detail_error || '').trim()"
|
||||
v-perms="['tcm.prescriptionOrder/patchPrescriptionUsage']"
|
||||
type="primary"
|
||||
size="small"
|
||||
link
|
||||
class="ml-2"
|
||||
@click="openPatchUsageDialog"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
</template>
|
||||
<span v-if="detailPrescription.prescription_type === '饮片' && detailPrescription.need_decoction !== null" class="ml-2 text-gray-500">
|
||||
({{ detailPrescription.need_decoction ? '代煎' : '不代煎' }})
|
||||
@@ -896,6 +907,17 @@
|
||||
{{ detailAuxUsage.dosage_amount }}{{ detailPrescription.dosage_unit || 'g' }}
|
||||
<template v-if="detailPrescription.prescription_type === '浓缩水丸'">
|
||||
· {{ Number(detailAuxUsage.dosage_bag_count) > 0 ? Number(detailAuxUsage.dosage_bag_count) : 1 }}袋
|
||||
<el-button
|
||||
v-if="detailData.prescription_id && !String(detailData.prescription_detail_error || '').trim()"
|
||||
v-perms="['tcm.prescriptionOrder/patchPrescriptionUsage']"
|
||||
type="primary"
|
||||
size="small"
|
||||
link
|
||||
class="ml-2"
|
||||
@click="openPatchUsageDialog"
|
||||
>
|
||||
修改
|
||||
</el-button>
|
||||
</template>
|
||||
<span v-if="detailPrescription.prescription_type === '饮片'" class="ml-2 text-gray-500">
|
||||
({{ detailAuxUsage.need_decoction ? '代煎' : '不代煎' }})
|
||||
@@ -2261,6 +2283,15 @@
|
||||
label-width="96px"
|
||||
>
|
||||
<div v-if="detailHasAuxHerbs" class="text-xs font-medium text-gray-500 mb-3">主方</div>
|
||||
<el-form-item
|
||||
v-if="detailPrescription?.prescription_type === '浓缩水丸'"
|
||||
label="每次袋数"
|
||||
prop="dosage_bag_count"
|
||||
>
|
||||
<el-select v-model="patchUsageForm.dosage_bag_count" class="w-full">
|
||||
<el-option v-for="count in 5" :key="count" :label="`${count}袋`" :value="count" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="每天次数" prop="times_per_day">
|
||||
<el-input-number
|
||||
v-model="patchUsageForm.times_per_day"
|
||||
@@ -2286,6 +2317,15 @@
|
||||
</el-form-item>
|
||||
<template v-if="detailHasAuxHerbs">
|
||||
<div class="text-xs font-medium text-gray-500 mb-3 mt-2 pt-2 border-t border-gray-100">辅方</div>
|
||||
<el-form-item
|
||||
v-if="detailPrescription?.prescription_type === '浓缩水丸'"
|
||||
label="每次袋数"
|
||||
prop="aux_dosage_bag_count"
|
||||
>
|
||||
<el-select v-model="patchUsageForm.aux_dosage_bag_count" class="w-full">
|
||||
<el-option v-for="count in 5" :key="count" :label="`${count}袋`" :value="count" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="每天次数" prop="aux_times_per_day">
|
||||
<el-input-number
|
||||
v-model="patchUsageForm.aux_times_per_day"
|
||||
@@ -3954,10 +3994,12 @@ const patchUsageVisible = ref(false)
|
||||
const patchUsageSaving = ref(false)
|
||||
const patchUsageFormRef = ref<FormInstance>()
|
||||
const patchUsageForm = reactive({
|
||||
dosage_bag_count: 1 as number | undefined,
|
||||
times_per_day: 3 as number | undefined,
|
||||
usage_days: 7 as number | undefined,
|
||||
aux_times_per_day: 3 as number | undefined,
|
||||
aux_usage_days: 7 as number | undefined,
|
||||
aux_dosage_bag_count: 1 as number | undefined,
|
||||
medication_days: undefined as number | undefined
|
||||
})
|
||||
const patchUsageRules = computed<FormRules>(() => {
|
||||
@@ -3966,9 +4008,15 @@ const patchUsageRules = computed<FormRules>(() => {
|
||||
usage_days: [{ required: true, message: '请填写主方开立天数', trigger: 'change' }],
|
||||
medication_days: [{ required: true, message: '请填写订单服用天数', trigger: 'change' }]
|
||||
}
|
||||
if (detailPrescription.value?.prescription_type === '浓缩水丸') {
|
||||
rules.dosage_bag_count = [{ required: true, message: '请选择主方每次袋数', trigger: 'change' }]
|
||||
}
|
||||
if (detailHasAuxHerbs.value) {
|
||||
rules.aux_times_per_day = [{ required: true, message: '请填写辅方每天次数', trigger: 'change' }]
|
||||
rules.aux_usage_days = [{ required: true, message: '请填写辅方开立天数', trigger: 'change' }]
|
||||
if (detailPrescription.value?.prescription_type === '浓缩水丸') {
|
||||
rules.aux_dosage_bag_count = [{ required: true, message: '请选择辅方每次袋数', trigger: 'change' }]
|
||||
}
|
||||
}
|
||||
return rules
|
||||
})
|
||||
@@ -3981,6 +4029,7 @@ function openPatchUsageDialog() {
|
||||
return
|
||||
}
|
||||
const aux = detailAuxUsage.value
|
||||
patchUsageForm.dosage_bag_count = Number(rx.dosage_bag_count) > 0 ? Number(rx.dosage_bag_count) : 1
|
||||
patchUsageForm.times_per_day =
|
||||
Number(rx.times_per_day) > 0 ? Number(rx.times_per_day) : 3
|
||||
patchUsageForm.usage_days =
|
||||
@@ -3990,16 +4039,20 @@ function openPatchUsageDialog() {
|
||||
patchUsageForm.aux_usage_days =
|
||||
aux && Number(aux.usage_days) > 0 ? Number(aux.usage_days) : 7
|
||||
const md = Number(ord.medication_days)
|
||||
patchUsageForm.aux_dosage_bag_count =
|
||||
aux && Number(aux.dosage_bag_count) > 0 ? Number(aux.dosage_bag_count) : 1
|
||||
patchUsageForm.medication_days = md > 0 ? md : Number(rx.usage_days) > 0 ? Number(rx.usage_days) : 7
|
||||
patchUsageVisible.value = true
|
||||
nextTick(() => patchUsageFormRef.value?.clearValidate())
|
||||
}
|
||||
|
||||
function resetPatchUsageForm() {
|
||||
patchUsageForm.dosage_bag_count = 1
|
||||
patchUsageForm.times_per_day = 3
|
||||
patchUsageForm.usage_days = 7
|
||||
patchUsageForm.aux_times_per_day = 3
|
||||
patchUsageForm.aux_usage_days = 7
|
||||
patchUsageForm.aux_dosage_bag_count = 1
|
||||
patchUsageForm.medication_days = undefined
|
||||
}
|
||||
|
||||
@@ -4020,17 +4073,25 @@ async function submitPatchUsage() {
|
||||
times_per_day: number
|
||||
usage_days: number
|
||||
medication_days: number
|
||||
dosage_bag_count?: number
|
||||
aux_times_per_day?: number
|
||||
aux_usage_days?: number
|
||||
aux_dosage_bag_count?: number
|
||||
} = {
|
||||
id: ordId,
|
||||
times_per_day: Number(patchUsageForm.times_per_day),
|
||||
usage_days: Number(patchUsageForm.usage_days),
|
||||
medication_days: Number(patchUsageForm.medication_days)
|
||||
}
|
||||
if (detailPrescription.value?.prescription_type === '浓缩水丸') {
|
||||
payload.dosage_bag_count = Number(patchUsageForm.dosage_bag_count)
|
||||
}
|
||||
if (detailHasAuxHerbs.value) {
|
||||
payload.aux_times_per_day = Number(patchUsageForm.aux_times_per_day)
|
||||
payload.aux_usage_days = Number(patchUsageForm.aux_usage_days)
|
||||
if (detailPrescription.value?.prescription_type === '浓缩水丸') {
|
||||
payload.aux_dosage_bag_count = Number(patchUsageForm.aux_dosage_bag_count)
|
||||
}
|
||||
}
|
||||
await prescriptionOrderPatchPrescriptionUsage(payload)
|
||||
feedback.msgSuccess('保存成功')
|
||||
|
||||
@@ -0,0 +1,227 @@
|
||||
<template>
|
||||
<div class="prescription-ai-visibility">
|
||||
<el-card v-loading="loading" shadow="never" class="!border-none">
|
||||
<div class="text-xl font-medium mb-[20px]">处方 AI 一致度可见范围</div>
|
||||
<el-alert type="info" :closable="false" show-icon class="mb-5">
|
||||
<template #title>指定用户组或用户可查看一致度</template>
|
||||
<div class="leading-6">
|
||||
用户命中任一指定系统角色,或被单独指定,即可查看桌面端“与 AI
|
||||
一致度”、逐味对照和一致度统计。AI
|
||||
报告继续按原有权限开放,已有报告不受影响,患者与处方的数据范围保持原有规则。
|
||||
</div>
|
||||
</el-alert>
|
||||
|
||||
<el-alert
|
||||
v-if="loadError"
|
||||
:title="loadError"
|
||||
type="error"
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb-5"
|
||||
/>
|
||||
<div v-if="loading" role="status" class="mb-5">正在读取当前可见范围…</div>
|
||||
|
||||
<el-form
|
||||
v-if="hasLoaded"
|
||||
class="ls-form"
|
||||
:model="formData"
|
||||
:disabled="!ready || loading || saving"
|
||||
label-width="140px"
|
||||
>
|
||||
<el-form-item label="指定用户组" prop="role_ids">
|
||||
<div class="w-full max-w-[640px]">
|
||||
<el-select
|
||||
v-model="formData.role_ids"
|
||||
class="w-full"
|
||||
multiple
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择系统角色,可搜索角色名称"
|
||||
>
|
||||
<el-option
|
||||
v-for="role in roleOptions"
|
||||
:key="role.id"
|
||||
:label="role.name"
|
||||
:value="role.id"
|
||||
/>
|
||||
</el-select>
|
||||
<div class="form-tips">账号拥有任一指定角色即可命中。</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="指定用户" prop="admin_ids">
|
||||
<div class="w-full max-w-[640px]">
|
||||
<el-select
|
||||
v-model="formData.admin_ids"
|
||||
class="w-full"
|
||||
multiple
|
||||
filterable
|
||||
clearable
|
||||
placeholder="请选择用户,可搜索姓名或账号"
|
||||
>
|
||||
<el-option
|
||||
v-for="admin in adminOptions"
|
||||
:key="admin.id"
|
||||
:label="admin.label"
|
||||
:value="admin.id"
|
||||
/>
|
||||
</el-select>
|
||||
<div class="form-tips">
|
||||
单独指定的用户无需同时命中用户组。当前不在可选列表中的已配置 ID
|
||||
会保留,移除后保存才会取消该项授权。
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
<el-form-item label="生效规则">
|
||||
<div>
|
||||
<div class="leading-6">指定用户组与指定用户按“或”生效。</div>
|
||||
<div class="form-tips">
|
||||
两项均为空时,所有账号(包括超级管理员)均隐藏一致度、对照与统计。
|
||||
拥有本页管理权限不自动获得一致度查看权,超级管理员也需命中上述名单。
|
||||
</div>
|
||||
</div>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-alert
|
||||
v-if="ready && !formData.role_ids.length && !formData.admin_ids.length"
|
||||
title="当前选择为空:保存后所有账号将隐藏一致度、对照与统计,AI 报告仍保留。"
|
||||
type="warning"
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb-5"
|
||||
/>
|
||||
<el-alert
|
||||
v-if="saveError"
|
||||
:title="saveError"
|
||||
type="error"
|
||||
:closable="false"
|
||||
show-icon
|
||||
class="mb-5"
|
||||
/>
|
||||
<el-button :disabled="loading || saving" @click="loadConfig">
|
||||
{{ loadError ? '重试加载' : '重新加载' }}
|
||||
</el-button>
|
||||
</el-card>
|
||||
|
||||
<footer-btns v-if="canManage">
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="saving"
|
||||
:disabled="!ready || loading || saving"
|
||||
@click="handleSubmit"
|
||||
>
|
||||
{{ saving ? '正在保存' : '保存' }}
|
||||
</el-button>
|
||||
</footer-btns>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts" name="prescriptionAiVisibility">
|
||||
import { computed, reactive, ref } from 'vue'
|
||||
|
||||
import type {
|
||||
PrescriptionAiVisibilityConfig,
|
||||
PrescriptionAiVisibilityOptions
|
||||
} from '@/api/setting/prescription_ai_visibility'
|
||||
import {
|
||||
getPrescriptionAiCapabilities,
|
||||
getPrescriptionAiVisibilityConfig,
|
||||
getPrescriptionAiVisibilityOptions,
|
||||
setPrescriptionAiVisibilityConfig
|
||||
} from '@/api/setting/prescription_ai_visibility'
|
||||
import feedback from '@/utils/feedback'
|
||||
|
||||
const loading = ref(false)
|
||||
const saving = ref(false)
|
||||
const ready = ref(false)
|
||||
const hasLoaded = ref(false)
|
||||
const canManage = ref(false)
|
||||
const loadError = ref('')
|
||||
const saveError = ref('')
|
||||
const formData = reactive<PrescriptionAiVisibilityConfig>({ role_ids: [], admin_ids: [] })
|
||||
const optionsData = reactive<PrescriptionAiVisibilityOptions>({ roles: [], admins: [] })
|
||||
|
||||
const roleOptions = computed(() => {
|
||||
const options = new Map(optionsData.roles.map((role) => [role.id, role]))
|
||||
for (const id of formData.role_ids) {
|
||||
if (!options.has(id)) {
|
||||
options.set(id, { id, name: `已配置角色 #${id}(当前不在可选列表)` })
|
||||
}
|
||||
}
|
||||
return [...options.values()]
|
||||
})
|
||||
|
||||
const adminOptions = computed(() => {
|
||||
const options = new Map(
|
||||
optionsData.admins.map((admin) => [
|
||||
admin.id,
|
||||
{ id: admin.id, label: `${admin.name || `用户 #${admin.id}`}(${admin.account})` }
|
||||
])
|
||||
)
|
||||
for (const id of formData.admin_ids) {
|
||||
if (!options.has(id)) {
|
||||
options.set(id, { id, label: `已配置用户 #${id}(当前不在可选列表)` })
|
||||
}
|
||||
}
|
||||
return [...options.values()]
|
||||
})
|
||||
|
||||
const assignConfig = (config: PrescriptionAiVisibilityConfig) => {
|
||||
formData.role_ids = [...config.role_ids]
|
||||
formData.admin_ids = [...config.admin_ids]
|
||||
}
|
||||
|
||||
const loadConfig = async () => {
|
||||
if (loading.value || saving.value) return
|
||||
loading.value = true
|
||||
ready.value = false
|
||||
canManage.value = false
|
||||
loadError.value = ''
|
||||
saveError.value = ''
|
||||
try {
|
||||
const capabilities = await getPrescriptionAiCapabilities()
|
||||
if (capabilities.can_manage_visibility !== true) {
|
||||
loadError.value = '当前账号无权管理处方 AI 一致度可见范围。'
|
||||
return
|
||||
}
|
||||
canManage.value = true
|
||||
const [config, options] = await Promise.all([
|
||||
getPrescriptionAiVisibilityConfig(),
|
||||
getPrescriptionAiVisibilityOptions()
|
||||
])
|
||||
if (!Array.isArray(options?.roles) || !Array.isArray(options?.admins)) {
|
||||
throw new Error('可选用户组或用户响应格式不正确')
|
||||
}
|
||||
// Apply both responses together; an incomplete load cannot overwrite the current policy.
|
||||
assignConfig(config)
|
||||
optionsData.roles = options.roles
|
||||
optionsData.admins = options.admins
|
||||
hasLoaded.value = true
|
||||
ready.value = true
|
||||
} catch {
|
||||
loadError.value = '可见范围加载失败,尚未读取完整配置。请重试加载后再保存。'
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleSubmit = async () => {
|
||||
if (!ready.value || !canManage.value || loading.value || saving.value) return
|
||||
saving.value = true
|
||||
saveError.value = ''
|
||||
try {
|
||||
const config = await setPrescriptionAiVisibilityConfig({
|
||||
role_ids: [...formData.role_ids],
|
||||
admin_ids: [...formData.admin_ids]
|
||||
})
|
||||
assignConfig(config)
|
||||
feedback.msgSuccess('可见范围已保存')
|
||||
} catch {
|
||||
saveError.value = '保存结果未确认,当前选择已保留。请重试保存,或重新加载以确认服务端策略。'
|
||||
} finally {
|
||||
saving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
void loadConfig()
|
||||
</script>
|
||||
Reference in New Issue
Block a user