Compare commits

..
Author SHA1 Message Date
Your Name 86903cdb59 更新 2026-05-16 15:50:06 +08:00
Your Name 7ba9dabdb4 更新 2026-05-14 16:26:27 +08:00
Your Name 611f3dcd5c Merge branch 'master' of https://gitee.com/v_cms/zyt 2026-05-14 16:23:52 +08:00
Your Name d3388b160e 更新 2026-05-14 16:23:29 +08:00
long f83d4c06cb Merge branch 'long-20260514' 2026-05-14 16:22:38 +08:00
long 4941ea3e21 Update DailyMatrix.vue
更新血糖折线图显示
2026-05-14 15:54:30 +08:00
Your Name e35696e153 更新 2026-05-14 15:34:28 +08:00
Your Name e1df584ed5 更新 2026-05-14 11:25:48 +08:00
Your Name 928f75e016 更新 2026-05-14 11:00:56 +08:00
Your Name 37fa160c24 更新 2026-05-13 17:23:29 +08:00
Your Name 0eaacbb4ce 更新 2026-05-13 16:54:54 +08:00
326 changed files with 4920 additions and 898 deletions
+10
View File
@@ -66,6 +66,16 @@ export function appointmentLists(params: any) {
return request.get({ url: '/doctor.appointment/lists', params }) return request.get({ url: '/doctor.appointment/lists', params })
} }
/** 后台编辑挂号(预约日期/时段/类型/状态/备注/医助) */
export function appointmentAdminEdit(params: any) {
return request.post({ url: '/doctor.appointment/edit', params })
}
/** 批量修改挂号渠道来源(与 edit 共用 doctor.appointment/edit 权限) */
export function appointmentBatchEditChannel(params: any) {
return request.post({ url: '/doctor.appointment/batchEditChannel', params })
}
// 获取挂号详情 // 获取挂号详情
export function appointmentDetail(params: any) { export function appointmentDetail(params: any) {
return request.get({ url: '/doctor.appointment/detail', params }) return request.get({ url: '/doctor.appointment/detail', params })
+20 -1
View File
@@ -110,6 +110,13 @@ const COMMISSION_SETTLEMENT_TIMEOUT_MS = 120000
/** 提成结算业绩(独立于业绩看板 yejiStats) */ /** 提成结算业绩(独立于业绩看板 yejiStats) */
export function commissionSettlementOverview(params: { export function commissionSettlementOverview(params: {
settlement_month: string settlement_month: string
/** 与 tcm.prescriptionOrder/lists 同源:create_time between */
start_time?: string
end_time?: string
/** 默认 3=履约完成,与列表 fulfillment_status 一致 */
fulfillment_status?: number
/** 传 1 时仅统计 is_system_auto=1;显式时段下默认不传(含手动) */
require_system_auto_prescription?: 0 | 1
dept_ids?: number[] | string dept_ids?: number[] | string
channel_code?: string channel_code?: string
}) { }) {
@@ -127,14 +134,21 @@ export function commissionSettlementChannelOptions() {
return request.get({ url: '/stats.commissionSettlement/channelOptions' }) return request.get({ url: '/stats.commissionSettlement/channelOptions' })
} }
/** 提成核对:订单明细分页 bucket: 空|current|deferred */ /** 提成核对:订单明细分页 bucket: 空|current|deferredappt_channel_value 可与 assistant_id/doctor_id 组合(0=未匹配挂号渠道) */
export function commissionSettlementOrderLines(params: { export function commissionSettlementOrderLines(params: {
settlement_month: string settlement_month: string
start_time?: string
end_time?: string
fulfillment_status?: number
require_system_auto_prescription?: 0 | 1
dept_ids?: number[] | string dept_ids?: number[] | string
channel_code?: string channel_code?: string
page?: number page?: number
page_size?: number page_size?: number
bucket?: string bucket?: string
assistant_id?: number
doctor_id?: number
appt_channel_value?: number
}) { }) {
return request.get( return request.get(
{ url: '/stats.commissionSettlement/orderLines', params, timeout: COMMISSION_SETTLEMENT_TIMEOUT_MS }, { url: '/stats.commissionSettlement/orderLines', params, timeout: COMMISSION_SETTLEMENT_TIMEOUT_MS },
@@ -160,3 +174,8 @@ export function commissionSettlementConfirmFinalize(params: Record<string, any>)
{ ignoreCancelToken: true } { ignoreCancelToken: true }
) )
} }
/** 撤回「确定本期业绩」:清除顺延结转,状态变为可再次核对/确定 */
export function commissionSettlementConfirmRevoke(params: Record<string, any>) {
return request.post({ url: '/stats.commissionSettlement/confirmRevoke', params })
}
+5
View File
@@ -363,6 +363,11 @@ export function prescriptionOrderLists(params: any) {
return request.get({ url: '/tcm.prescriptionOrder/lists', params }) return request.get({ url: '/tcm.prescriptionOrder/lists', params })
} }
/** 处方业务订单导出(export=1 预估条数,export=2 下载 Excel */
export function prescriptionOrderExport(params: any) {
return request.get({ url: '/tcm.prescriptionOrder/export', params })
}
/** /**
* 诊单下可关联的支付单(已支付 zyt_order;已占用且未撤回的会排除;编辑时传 prescription_order_id 保留当前单已选)。 * 诊单下可关联的支付单(已支付 zyt_order;已占用且未撤回的会排除;编辑时传 prescription_order_id 保留当前单已选)。
* 服务端仅返回创建时间在 2026-04-20(含)之后的支付单;编辑时本单已关联的旧单仍会出现在列表中。 * 服务端仅返回创建时间在 2026-04-20(含)之后的支付单;编辑时本单已关联的旧单仍会出现在列表中。
@@ -13,6 +13,7 @@
<el-button>导出</el-button> <el-button>导出</el-button>
</template> </template>
<div> <div>
<p v-if="props.exportHint" class="text-sm text-gray-500 mb-3 leading-relaxed">{{ props.exportHint }}</p>
<el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules"> <el-form ref="formRef" :model="formData" label-width="120px" :rules="formRules">
<el-form-item label="数据量:"> <el-form-item label="数据量:">
预计导出{{ exportData.count }}条数据 {{ exportData.sum_page }}每页{{ 预计导出{{ exportData.count }}条数据 {{ exportData.sum_page }}每页{{
@@ -79,6 +80,11 @@ const props = defineProps({
fetchFun: { fetchFun: {
type: Function, type: Function,
required: true required: true
},
/** 可选:导出弹窗内提示文案(如说明与列表筛选一致) */
exportHint: {
type: String,
default: ''
} }
}) })
const popupRef = shallowRef<InstanceType<typeof Popup>>() const popupRef = shallowRef<InstanceType<typeof Popup>>()
@@ -0,0 +1,582 @@
<template>
<div class="guahao-list">
<el-card class="!border-none" shadow="never">
<el-form class="mb-[-16px]" :model="queryParams" :inline="true" @submit.prevent>
<el-form-item label="预约日期">
<daterange-picker
v-model:startTime="queryParams.start_date"
v-model:endTime="queryParams.end_date"
/>
</el-form-item>
<el-form-item label="患者姓名">
<el-input
v-model="queryParams.patient_name"
placeholder="模糊搜索"
clearable
class="!w-[160px]"
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="医生">
<el-input
v-model="queryParams.doctor_name"
placeholder="模糊搜索"
clearable
class="!w-[140px]"
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="医助">
<el-select
v-model="queryParams.assistant_id"
placeholder="全部"
clearable
filterable
class="!w-[180px]"
>
<el-option
v-for="a in assistantOptions"
:key="a.id"
:label="a.name + (a.account ? ` (${a.account})` : '')"
:value="a.id"
/>
</el-select>
</el-form-item>
<el-form-item label="状态">
<el-select v-model="queryParams.status" placeholder="全部" clearable class="!w-[130px]">
<el-option label="已预约" :value="1" />
<el-option label="已取消" :value="2" />
<el-option label="已完成" :value="3" />
<el-option label="已过号" :value="4" />
</el-select>
</el-form-item>
<el-form-item label="渠道">
<el-select
v-model="queryParams.channel_source"
placeholder="全部"
clearable
filterable
class="!w-[200px]"
>
<el-option
v-for="item in channelOptions"
:key="String(item.value)"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetFilter">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div class="flex flex-wrap items-center gap-3 mb-4">
<el-button
v-perms="['doctor.appointment/edit']"
type="primary"
:disabled="selectedRows.length === 0"
@click="openBatchChannelDialog"
>
批量修改渠道
</el-button>
<span v-if="selectedRows.length > 0" class="text-sm text-gray-500">
已选 {{ selectedRows.length }}
</span>
</div>
<el-table
ref="tableRef"
v-loading="pager.loading"
row-key="id"
:data="pager.lists"
size="large"
stripe
@selection-change="onSelectionChange"
>
<el-table-column type="selection" width="48" align="center" reserve-selection />
<el-table-column label="ID" prop="id" width="72" align="center" />
<el-table-column label="诊单/患者" min-width="140">
<template #default="{ row }">
<div class="text-sm">
<div class="font-medium">{{ row.patient_name || '—' }}</div>
<div class="text-gray-500">{{ maskPhone(row.patient_phone) }}</div>
<div class="text-xs text-gray-400">诊单 #{{ row.diagnosis_id ?? row.patient_id }}</div>
</div>
</template>
</el-table-column>
<el-table-column label="医生" prop="doctor_name" width="100" show-overflow-tooltip />
<el-table-column label="医助" prop="assistant_name" width="100" show-overflow-tooltip />
<el-table-column label="预约时间" min-width="128">
<template #default="{ row }">
<div>{{ row.appointment_date }}</div>
<div class="text-gray-500">{{ formatHm(row.appointment_time) }} · {{ row.period_desc }}</div>
</template>
</el-table-column>
<el-table-column label="类型" prop="appointment_type_desc" width="100" />
<el-table-column label="渠道" min-width="130" show-overflow-tooltip>
<template #default="{ row }">
<div class="text-sm">{{ row.channel_source_desc || '—' }}</div>
<div v-if="row.channel_source_detail" class="text-xs text-gray-400 truncate">
{{ row.channel_source_detail }}
</div>
</template>
</el-table-column>
<el-table-column label="状态" width="96" align="center">
<template #default="{ row }">
<el-tag
:type="
row.status === 1 ? 'success' : row.status === 2 ? 'info' : row.status === 3 ? 'primary' : 'danger'
"
size="small"
effect="light"
>
{{ row.status_desc }}
</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" min-width="120" show-overflow-tooltip />
<el-table-column label="操作" width="100" fixed="right" align="center">
<template #default="{ row }">
<el-button v-perms="['doctor.appointment/edit']" type="primary" link @click="openEdit(row)">
编辑
</el-button>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<el-dialog v-model="editVisible" title="编辑挂号" width="560px" destroy-on-close @closed="resetEditForm">
<el-form :model="editForm" label-width="96px">
<el-form-item label="预约日期" required>
<el-date-picker
v-model="editForm.appointment_date"
type="date"
value-format="YYYY-MM-DD"
placeholder="选择日期"
class="!w-full"
/>
</el-form-item>
<el-form-item label="预约时间" required>
<el-time-picker
v-model="editForm.appointment_time"
format="HH:mm"
value-format="HH:mm"
placeholder="时间"
class="!w-full"
/>
</el-form-item>
<el-form-item label="时段" required>
<el-radio-group v-model="editForm.period">
<el-radio-button label="morning">上午</el-radio-button>
<el-radio-button label="afternoon">下午</el-radio-button>
<el-radio-button label="all">全天</el-radio-button>
</el-radio-group>
</el-form-item>
<el-form-item label="问诊类型" required>
<el-select v-model="editForm.appointment_type" class="!w-full">
<el-option label="视频问诊" value="video" />
<el-option label="图文问诊" value="text" />
<el-option label="电话问诊" value="phone" />
</el-select>
</el-form-item>
<el-form-item label="渠道来源" required>
<el-select
v-model="editForm.channel_source"
placeholder="请选择渠道来源"
filterable
class="!w-full"
@change="onChannelSourceChange"
>
<el-option
v-for="item in channelOptions"
:key="String(item.value)"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item v-if="needsChannelSourceDetail" label="自媒体补充" required>
<el-input
v-model="editForm.channel_source_detail"
maxlength="128"
show-word-limit
placeholder="请输入自媒体相关补充内容"
clearable
class="!w-full"
/>
</el-form-item>
<el-form-item label="状态" required>
<el-select v-model="editForm.status" class="!w-full">
<el-option label="已预约" :value="1" />
<el-option label="已取消" :value="2" />
<el-option label="已完成" :value="3" />
<el-option label="已过号" :value="4" />
</el-select>
</el-form-item>
<el-form-item label="挂号医助">
<el-select
v-model="editForm.assistant_id"
placeholder="不修改可留空"
clearable
filterable
class="!w-full"
>
<el-option
v-for="a in assistantOptions"
:key="a.id"
:label="a.name + (a.account ? ` (${a.account})` : '')"
:value="a.id"
/>
</el-select>
</el-form-item>
<el-form-item label="备注">
<el-input v-model="editForm.remark" type="textarea" :rows="3" maxlength="500" show-word-limit />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="editVisible = false">取消</el-button>
<el-button type="primary" :loading="editSaving" @click="submitEdit">保存</el-button>
</template>
</el-dialog>
<el-dialog
v-model="batchChannelVisible"
title="批量修改渠道"
width="520px"
destroy-on-close
@closed="resetBatchChannelForm"
>
<p class="text-sm text-gray-600 mb-4">将对已选 {{ selectedRows.length }} 条挂号写入同一渠道来源仅改渠道不改其它字段</p>
<el-form :model="batchChannelForm" label-width="96px">
<el-form-item label="渠道来源" required>
<el-select
v-model="batchChannelForm.channel_source"
placeholder="请选择渠道来源"
filterable
class="!w-full"
@change="onBatchChannelSourceChange"
>
<el-option
v-for="item in channelOptions"
:key="String(item.value)"
:label="item.name"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item v-if="needsBatchChannelSourceDetail" label="自媒体补充" required>
<el-input
v-model="batchChannelForm.channel_source_detail"
maxlength="128"
show-word-limit
placeholder="请输入自媒体相关补充内容"
clearable
class="!w-full"
/>
</el-form-item>
</el-form>
<template #footer>
<el-button @click="batchChannelVisible = false">取消</el-button>
<el-button type="primary" :loading="batchChannelSaving" @click="submitBatchChannel">确定</el-button>
</template>
</el-dialog>
</div>
</template>
<script lang="ts" setup name="consumerPrescriptionGuahao">
import DaterangePicker from '@/components/daterange-picker/index.vue'
import { getDictData } from '@/api/app'
import { appointmentAdminEdit, appointmentBatchEditChannel, appointmentLists } from '@/api/doctor'
import { getAssistants } from '@/api/tcm'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
const queryParams = reactive({
start_date: '',
end_date: '',
patient_name: '',
doctor_name: '',
assistant_id: undefined as number | undefined,
status: '' as number | '',
channel_source: '' as string
})
const queryInit = {
start_date: '',
end_date: '',
patient_name: '',
doctor_name: '',
assistant_id: undefined as number | undefined,
status: '' as number | '',
channel_source: ''
}
const { pager, getLists, resetPage } = usePaging({
fetchFun: appointmentLists,
params: queryParams
})
const assistantOptions = ref<Array<{ id: number; name: string; account?: string }>>([])
const tableRef = ref<{ clearSelection?: () => void } | null>(null)
const selectedRows = ref<Record<string, unknown>[]>([])
function onSelectionChange(rows: Record<string, unknown>[]) {
selectedRows.value = rows
}
/** 与诊单预约弹窗一致:这些字典 name 需填「自媒体补充」 */
const CHANNEL_NAMES_REQUIRING_SELF_MEDIA_DETAIL = new Set([
'自媒体4H',
'自媒体3Q',
'自媒体3H',
'自媒体2H',
'自媒体2Q'
])
function channelNameRequiresSelfMediaDetail(name: string) {
return CHANNEL_NAMES_REQUIRING_SELF_MEDIA_DETAIL.has(String(name ?? '').trim())
}
const channelOptions = ref<Array<{ name: string; value: string }>>([])
const selectedChannelDictName = computed(() => {
const v = editForm.channel_source
if (v === '' || v == null) return ''
const row = channelOptions.value.find((item: { value: string }) => String(item.value) === String(v))
return row ? String(row.name ?? '').trim() : ''
})
const needsChannelSourceDetail = computed(() => channelNameRequiresSelfMediaDetail(selectedChannelDictName.value))
const batchSelectedChannelDictName = computed(() => {
const v = batchChannelForm.channel_source
if (v === '' || v == null) return ''
const row = channelOptions.value.find((item: { value: string }) => String(item.value) === String(v))
return row ? String(row.name ?? '').trim() : ''
})
const needsBatchChannelSourceDetail = computed(() =>
channelNameRequiresSelfMediaDetail(batchSelectedChannelDictName.value)
)
function onBatchChannelSourceChange(val: string) {
const row = channelOptions.value.find((item: { value: string }) => String(item.value) === String(val))
const name = row ? String(row.name ?? '').trim() : ''
if (!channelNameRequiresSelfMediaDetail(name)) {
batchChannelForm.channel_source_detail = ''
}
}
const batchChannelVisible = ref(false)
const batchChannelSaving = ref(false)
const batchChannelForm = reactive({
channel_source: '' as string,
channel_source_detail: '' as string
})
function openBatchChannelDialog() {
if (selectedRows.value.length === 0) {
feedback.msgWarning('请先勾选挂号记录')
return
}
batchChannelForm.channel_source = ''
batchChannelForm.channel_source_detail = ''
batchChannelVisible.value = true
}
function resetBatchChannelForm() {
batchChannelForm.channel_source = ''
batchChannelForm.channel_source_detail = ''
}
async function submitBatchChannel() {
if (selectedRows.value.length === 0) {
feedback.msgWarning('请先勾选挂号记录')
return
}
if (!batchChannelForm.channel_source) {
feedback.msgError('请选择渠道来源')
return
}
if (needsBatchChannelSourceDetail.value && !batchChannelForm.channel_source_detail.trim()) {
feedback.msgError('请填写自媒体补充说明')
return
}
batchChannelSaving.value = true
try {
const ids = selectedRows.value.map((r) => Number(r.id))
await appointmentBatchEditChannel({
ids,
channel_source: batchChannelForm.channel_source,
channel_source_detail: batchChannelForm.channel_source_detail.trim()
})
feedback.msgSuccess('批量修改成功')
batchChannelVisible.value = false
tableRef.value?.clearSelection?.()
selectedRows.value = []
getLists()
} finally {
batchChannelSaving.value = false
}
}
function onChannelSourceChange(val: string) {
const row = channelOptions.value.find((item: { value: string }) => String(item.value) === String(val))
const name = row ? String(row.name ?? '').trim() : ''
if (!channelNameRequiresSelfMediaDetail(name)) {
editForm.channel_source_detail = ''
}
}
const editVisible = ref(false)
const editSaving = ref(false)
const editForm = reactive({
id: 0,
appointment_date: '',
appointment_time: '' as string,
period: 'morning' as 'morning' | 'afternoon' | 'all',
appointment_type: 'video',
status: 1,
remark: '',
assistant_id: undefined as number | undefined,
channel_source: '' as string,
channel_source_detail: '' as string
})
function maskPhone(phone?: string) {
const p = String(phone || '')
if (p.length >= 11) {
return p.slice(0, 3) + '****' + p.slice(-4)
}
return p || '—'
}
function formatHm(t?: string) {
const s = String(t || '')
return s.length >= 5 ? s.slice(0, 5) : s || '—'
}
function resetFilter() {
Object.assign(queryParams, queryInit)
resetPage()
}
function rowPeriod(row: Record<string, unknown>): 'morning' | 'afternoon' | 'all' {
const v = String(row.period ?? row.type ?? 'morning')
if (v === 'afternoon' || v === 'all') {
return v
}
return 'morning'
}
async function loadAssistants() {
try {
const res: any = await getAssistants()
assistantOptions.value = res?.lists ?? res ?? []
} catch {
assistantOptions.value = []
}
}
async function loadChannelOptions() {
try {
const data: any = await getDictData({ type: 'channels' })
const rows = (data?.channels || []).filter((row: { status?: number }) => row.status !== 0)
rows.sort((a: { sort?: number; id?: number }, b: { sort?: number; id?: number }) => {
const ds = Number(b?.sort ?? 0) - Number(a?.sort ?? 0)
if (ds !== 0) return ds
return Number(b?.id ?? 0) - Number(a?.id ?? 0)
})
channelOptions.value = rows
} catch {
channelOptions.value = []
}
}
function openEdit(row: Record<string, unknown>) {
editForm.id = Number(row.id)
editForm.appointment_date = String(row.appointment_date || '')
editForm.appointment_time = formatHm(String(row.appointment_time || ''))
editForm.period = rowPeriod(row)
editForm.appointment_type = String(row.appointment_type || 'video')
editForm.status = Number(row.status)
editForm.remark = String(row.remark || '')
const raw = row.appointment_assistant_id
editForm.assistant_id =
raw !== undefined && raw !== null && raw !== '' ? Number(raw) : undefined
editForm.channel_source = String(row.channel_source ?? row.channels ?? '')
editForm.channel_source_detail = String(row.channel_source_detail ?? '')
editVisible.value = true
}
function resetEditForm() {
editForm.id = 0
editForm.appointment_date = ''
editForm.appointment_time = ''
editForm.period = 'morning'
editForm.appointment_type = 'video'
editForm.status = 1
editForm.remark = ''
editForm.assistant_id = undefined
editForm.channel_source = ''
editForm.channel_source_detail = ''
}
async function submitEdit() {
if (!editForm.appointment_date) {
feedback.msgError('请选择预约日期')
return
}
if (!editForm.appointment_time) {
feedback.msgError('请选择预约时间')
return
}
if (!editForm.channel_source) {
feedback.msgError('请选择渠道来源')
return
}
if (needsChannelSourceDetail.value && !editForm.channel_source_detail.trim()) {
feedback.msgError('请填写自媒体补充说明')
return
}
editSaving.value = true
try {
const payload: Record<string, unknown> = {
id: editForm.id,
appointment_date: editForm.appointment_date,
appointment_time: editForm.appointment_time,
period: editForm.period,
appointment_type: editForm.appointment_type,
status: editForm.status,
remark: editForm.remark,
assistant_id: editForm.assistant_id ?? '',
channel_source: editForm.channel_source,
channel_source_detail: editForm.channel_source_detail.trim()
}
await appointmentAdminEdit(payload)
feedback.msgSuccess('保存成功')
editVisible.value = false
getLists()
} finally {
editSaving.value = false
}
}
onMounted(() => {
loadAssistants()
loadChannelOptions()
})
onActivated(() => {
getLists()
})
getLists()
</script>
@@ -548,12 +548,20 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="患者姓名" prop="patient_name"> <el-form-item label="患者姓名" prop="patient_name">
<el-input v-model="editForm.patient_name" placeholder="请输入患者姓名" /> <el-input
v-model="editForm.patient_name"
placeholder="请输入患者姓名"
:disabled="editMode === 'edit'"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
<el-form-item label="门诊号" prop="visit_no"> <el-form-item label="门诊号" prop="visit_no">
<el-input v-model="editForm.visit_no" placeholder="自动生成或手动输入" /> <el-input
v-model="editForm.visit_no"
placeholder="自动生成或手动输入"
:disabled="editMode === 'edit'"
/>
</el-form-item> </el-form-item>
</el-col> </el-col>
</el-row> </el-row>
@@ -263,9 +263,22 @@
/> />
</el-select> </el-select>
</el-form-item> </el-form-item>
<el-form-item class="w-[160px]" label="服务渠道">
<el-select v-model="queryParams.service_channel" clearable placeholder="全部" class="!w-full">
<el-option label="未指派" value="0" />
</el-select>
</el-form-item>
<el-form-item> <el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button> <el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="handleReset">重置</el-button> <el-button @click="handleReset">重置</el-button>
<export-data
v-perms="['tcm.prescriptionOrder/export']"
class="ml-2.5"
:fetch-fun="prescriptionOrderExport"
:params="prescriptionOrderExportParams"
:page-size="pager.size"
export-hint="导出范围与上方筛选一致(履约状态、创建时间及其他条件均会生效)。含「自媒体渠道(挂号渠道来源)」:按诊单关联患者取最近一条挂号的渠道字典与细分。"
/>
</el-form-item> </el-form-item>
</el-form> </el-form>
</el-card> </el-card>
@@ -1369,7 +1382,7 @@
<!-- 编辑分步向导与创建业务订单弹窗统一 --> <!-- 编辑分步向导与创建业务订单弹窗统一 -->
<el-dialog <el-dialog
v-model="editVisible" v-model="editVisible"
title="编辑业务订单" :title="editGancaoLogisticsOnlyMode ? '修改物流信息(甘草订单)' : '编辑业务订单'"
width="940px" width="940px"
top="4vh" top="4vh"
:close-on-click-modal="false" :close-on-click-modal="false"
@@ -1392,18 +1405,33 @@
</el-tooltip> </el-tooltip>
</div> </div>
<el-steps <el-alert
:active="editOrderStep" v-if="editGancaoLogisticsOnlyMode"
finish-status="success" type="info"
align-center :closable="false"
class="create-order-steps" show-icon
class="mb-4"
title="订单已提交甘草,仅可修改快递单号与承运商;地址、金额等变更请先走取消流程。"
> >
<el-step title="患者与收货" description="诊单与物流地址" /> <template v-if="editGancaoDisplayNo" #default>
<el-step title="服务与支付单" description="套餐与关联收款" /> <div class="text-sm text-gray-700 mt-1">甘草处方单号{{ editGancaoDisplayNo }}</div>
<el-step title="金额与确认" description="费用与备注" /> </template>
</el-steps> </el-alert>
<p class="create-order-step-lead">{{ editOrderStepLead }}</p> <template v-if="!editGancaoLogisticsOnlyMode">
<el-steps
:active="editOrderStep"
finish-status="success"
align-center
class="create-order-steps"
>
<el-step title="患者与收货" description="诊单与物流地址" />
<el-step title="服务与支付单" description="套餐与关联收款" />
<el-step title="金额与确认" description="费用与备注" />
</el-steps>
<p class="create-order-step-lead">{{ editOrderStepLead }}</p>
</template>
<el-form <el-form
ref="editFormRef" ref="editFormRef"
@@ -1412,6 +1440,24 @@
label-width="108px" label-width="108px"
class="create-order-form" class="create-order-form"
> >
<template v-if="editGancaoLogisticsOnlyMode">
<el-row :gutter="20">
<el-col :span="24">
<el-form-item label="物流设置">
<div class="flex gap-2 w-full">
<el-select v-model="editForm.express_company" placeholder="承运商" class="w-[140px] shrink-0">
<el-option label="自动识别" value="auto" />
<el-option label="顺丰速运" value="sf" />
<el-option label="京东快递" value="jd" />
<el-option label="极兔速递" value="jt" />
</el-select>
<el-input v-model="editForm.tracking_number" maxlength="80" placeholder="快递单号" class="flex-1 min-w-0" />
</div>
</el-form-item>
</el-col>
</el-row>
</template>
<template v-if="!editGancaoLogisticsOnlyMode">
<div v-show="editOrderStep === 0" class="create-order-step-panel"> <div v-show="editOrderStep === 0" class="create-order-step-panel">
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
@@ -1558,7 +1604,17 @@
<el-row :gutter="20"> <el-row :gutter="20">
<el-col :span="12"> <el-col :span="12">
<el-form-item label="服务渠道"> <el-form-item label="服务渠道">
<el-input v-model="editForm.service_channel" placeholder="可选" maxlength="100" /> <el-select
v-model="editForm.service_channel"
class="w-full"
filterable
allow-create
default-first-option
clearable
placeholder="可选或自定义输入"
>
<el-option label="未指派" value="0" />
</el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">
@@ -1735,12 +1791,13 @@
</el-col> </el-col>
</el-row> </el-row>
</div> </div>
</template>
</el-form> </el-form>
</div> </div>
<template #footer> <template #footer>
<div class="create-order-footer"> <div class="create-order-footer">
<div class="create-order-footer__hint"> <div v-if="!editGancaoLogisticsOnlyMode" class="create-order-footer__hint">
<span class="create-order-footer__step"> {{ editOrderStep + 1 }} / 3 </span> <span class="create-order-footer__step"> {{ editOrderStep + 1 }} / 3 </span>
<span v-if="editOrderStep === 2 && editDepositMin > 0" class="create-order-footer__warn"> <span v-if="editOrderStep === 2 && editDepositMin > 0" class="create-order-footer__warn">
订单金额与关联支付单合计须 ¥{{ formatMoney(editDepositMin) }} 订单金额与关联支付单合计须 ¥{{ formatMoney(editDepositMin) }}
@@ -1748,17 +1805,19 @@
</div> </div>
<div class="create-order-footer__actions"> <div class="create-order-footer__actions">
<el-button size="large" @click="editVisible = false">取消</el-button> <el-button size="large" @click="editVisible = false">取消</el-button>
<el-button v-if="editOrderStep > 0" size="large" @click="goEditOrderPrevStep">上一步</el-button> <template v-if="!editGancaoLogisticsOnlyMode">
<el-button v-if="editOrderStep > 0" size="large" @click="goEditOrderPrevStep">上一步</el-button>
<el-button
v-if="editOrderStep < 2"
type="primary"
size="large"
@click="goEditOrderNextStep"
>
下一步
</el-button>
</template>
<el-button <el-button
v-if="editOrderStep < 2" v-if="editGancaoLogisticsOnlyMode || editOrderStep === 2"
type="primary"
size="large"
@click="goEditOrderNextStep"
>
下一步
</el-button>
<el-button
v-if="editOrderStep === 2"
type="primary" type="primary"
size="large" size="large"
:loading="editSaving" :loading="editSaving"
@@ -2505,6 +2564,7 @@ import {
prescriptionOrderDetail, prescriptionOrderDetail,
prescriptionOrderEdit, prescriptionOrderEdit,
prescriptionOrderLists, prescriptionOrderLists,
prescriptionOrderExport,
prescriptionOrderPaidPayOrders, prescriptionOrderPaidPayOrders,
prescriptionOrderWithdraw, prescriptionOrderWithdraw,
prescriptionOrderLogisticsTrace, prescriptionOrderLogisticsTrace,
@@ -2789,6 +2849,8 @@ const queryParams = reactive({
payment_slip_audit_status: '' as number | '', payment_slip_audit_status: '' as number | '',
/** 供货方式:甘草(已传甘草药方单号)/ 自营(无甘草单号) */ /** 供货方式:甘草(已传甘草药方单号)/ 自营(无甘草单号) */
supply_mode: '' as '' | 'gancao' | 'self', supply_mode: '' as '' | 'gancao' | 'self',
/** 服务渠道:'' 不限;'0' 未指派(库内 '' 或 '0' */
service_channel: '' as '' | '0',
/** 列表排除履约已取消(4):重点看板「待处方审核」等用 */ /** 列表排除履约已取消(4):重点看板「待处方审核」等用 */
exclude_fulfillment_cancelled: 0 as number exclude_fulfillment_cancelled: 0 as number
}) })
@@ -2853,21 +2915,35 @@ function handleFocusBoardSearch(key: 'pendingRx' | 'pendingPay' | 'pendingShip'
resetPage() resetPage()
} }
async function fetchLists(params: Record<string, unknown>) { function normalizePrescriptionOrderListQuery(params: Record<string, unknown>): Record<string, unknown> {
const p: Record<string, unknown> = { ...params } const p: Record<string, unknown> = { ...params }
if (p.prescription_id === '' || p.prescription_id === undefined) { if (p.prescription_id === '' || p.prescription_id === undefined) {
delete p.prescription_id delete p.prescription_id
} else { } else {
p.prescription_id = Number(p.prescription_id) p.prescription_id = Number(p.prescription_id)
} }
if (p.fulfillment_status === '' || p.fulfillment_status === undefined) { if (p.fulfillment_status === '' || p.fulfillment_status === undefined || p.fulfillment_status === null) {
delete p.fulfillment_status delete p.fulfillment_status
} else {
p.fulfillment_status = Number(p.fulfillment_status)
} }
if (p.prescription_audit_status === '' || p.prescription_audit_status === undefined) { if (
p.prescription_audit_status === '' ||
p.prescription_audit_status === undefined ||
p.prescription_audit_status === null
) {
delete p.prescription_audit_status delete p.prescription_audit_status
} else {
p.prescription_audit_status = Number(p.prescription_audit_status)
} }
if (p.payment_slip_audit_status === '' || p.payment_slip_audit_status === undefined) { if (
p.payment_slip_audit_status === '' ||
p.payment_slip_audit_status === undefined ||
p.payment_slip_audit_status === null
) {
delete p.payment_slip_audit_status delete p.payment_slip_audit_status
} else {
p.payment_slip_audit_status = Number(p.payment_slip_audit_status)
} }
if (!p.supply_mode || p.supply_mode === '') { if (!p.supply_mode || p.supply_mode === '') {
delete p.supply_mode delete p.supply_mode
@@ -2891,12 +2967,17 @@ async function fetchLists(params: Record<string, unknown>) {
if (!String(p.patient_keyword || '').trim()) delete p.patient_keyword if (!String(p.patient_keyword || '').trim()) delete p.patient_keyword
if (!String(p.express_keyword || '').trim()) delete p.express_keyword if (!String(p.express_keyword || '').trim()) delete p.express_keyword
if (!p.express_company || p.express_company === '') delete p.express_company if (!p.express_company || p.express_company === '') delete p.express_company
if (p.service_channel === '' || p.service_channel === undefined || p.service_channel === null) {
delete p.service_channel
} else {
p.service_channel = String(p.service_channel).trim()
if (p.service_channel === '') delete p.service_channel
}
if (Number(p.exclude_fulfillment_cancelled) !== 1) delete p.exclude_fulfillment_cancelled if (Number(p.exclude_fulfillment_cancelled) !== 1) delete p.exclude_fulfillment_cancelled
if (!String(p.start_time || '').trim() || !String(p.end_time || '').trim()) { if (!String(p.start_time || '').trim() || !String(p.end_time || '').trim()) {
delete p.start_time delete p.start_time
delete p.end_time delete p.end_time
} else { } else {
// 00:00:00
const st = String(p.start_time || '').trim() const st = String(p.start_time || '').trim()
const et = String(p.end_time || '').trim() const et = String(p.end_time || '').trim()
if (/^\d{4}-\d{2}-\d{2}$/.test(st) && /^\d{4}-\d{2}-\d{2}$/.test(et)) { if (/^\d{4}-\d{2}-\d{2}$/.test(st) && /^\d{4}-\d{2}-\d{2}$/.test(et)) {
@@ -2904,9 +2985,16 @@ async function fetchLists(params: Record<string, unknown>) {
p.end_time = `${et} 23:59:59` p.end_time = `${et} 23:59:59`
} }
} }
return p
}
async function fetchLists(params: Record<string, unknown>) {
const p = normalizePrescriptionOrderListQuery({ ...params })
return prescriptionOrderLists(p) return prescriptionOrderLists(p)
} }
const prescriptionOrderExportParams = computed(() => normalizePrescriptionOrderListQuery({ ...queryParams }))
const { pager, getLists, resetPage, resetParams } = usePaging({ const { pager, getLists, resetPage, resetParams } = usePaging({
fetchFun: fetchLists, fetchFun: fetchLists,
params: queryParams params: queryParams
@@ -3102,6 +3190,7 @@ function handleReset() {
queryParams.prescription_audit_status = '' queryParams.prescription_audit_status = ''
queryParams.payment_slip_audit_status = '' queryParams.payment_slip_audit_status = ''
queryParams.supply_mode = '' queryParams.supply_mode = ''
queryParams.service_channel = ''
queryParams.exclude_fulfillment_cancelled = 0 queryParams.exclude_fulfillment_cancelled = 0
resetParams() resetParams()
} }
@@ -3205,14 +3294,21 @@ function canEditRow(row: {
gancao_reciperl_order_no?: string | null gancao_reciperl_order_no?: string | null
gancao_submit_time?: number | null gancao_submit_time?: number | null
}) { }) {
// (5)(6)(3)(4)
const fs = Number(row.fulfillment_status) const fs = Number(row.fulfillment_status)
if (fs !== 1 && fs !== 2) return false // (3)(4)
// > 0 if (fs === 3 || fs === 4) return false
const gcNo = String(row.gancao_reciperl_order_no || '').trim() const gcNo = String(row.gancao_reciperl_order_no || '').trim()
const gcTime = Number(row.gancao_submit_time || 0) const gcTime = Number(row.gancao_submit_time || 0)
if (gcNo !== '' || gcTime > 0) return false const gcLocked = gcNo !== '' || gcTime > 0
return true
// /// 6 edit
if (gcLocked) {
return [1, 2, 5, 7].includes(fs)
}
// (1)(2)
return fs === 1 || fs === 2
} }
function canRxAudit(row: { prescription_audit_status?: number; fulfillment_status?: number }) { function canRxAudit(row: { prescription_audit_status?: number; fulfillment_status?: number }) {
@@ -3281,9 +3377,8 @@ function canCompleteRow(row: { fulfillment_status?: number; payment_slip_audit_s
} }
function canQuickTrackRow(row: { fulfillment_status?: number }) { function canQuickTrackRow(row: { fulfillment_status?: number }) {
// (5) / (6) 使 // (5) (6)
const fs = Number(row.fulfillment_status) return Number(row.fulfillment_status) === 5
return fs === 5 || fs === 6
} }
function canUpdateAmount(row: { id?: number; fulfillment_status?: number } | null | undefined) { function canUpdateAmount(row: { id?: number; fulfillment_status?: number } | null | undefined) {
@@ -3919,6 +4014,10 @@ const editSaving = ref(false)
const editOrderStep = ref(0) const editOrderStep = ref(0)
/** 顶部「关联处方」卡片数据(来自业务订单详情中的 prescription */ /** 顶部「关联处方」卡片数据(来自业务订单详情中的 prescription */
const editOrderPrescription = ref<Record<string, any> | null>(null) const editOrderPrescription = ref<Record<string, any> | null>(null)
/** 甘草 SCM 已提交:弹窗仅展示并提交快递单号与承运商 */
const editGancaoLogisticsOnlyMode = ref(false)
/** 用于提示文案展示甘草处方单号 */
const editGancaoDisplayNo = ref('')
const editOrderStepLead = computed(() => { const editOrderStepLead = computed(() => {
const texts = [ const texts = [
@@ -4097,6 +4196,8 @@ const editRules = computed<FormRules>(() => {
function resetEditOrderDialog() { function resetEditOrderDialog() {
editOrderStep.value = 0 editOrderStep.value = 0
editOrderPrescription.value = null editOrderPrescription.value = null
editGancaoLogisticsOnlyMode.value = false
editGancaoDisplayNo.value = ''
editFormRef.value?.clearValidate() editFormRef.value?.clearValidate()
} }
@@ -4216,7 +4317,12 @@ async function openEdit(row: { id: number }) {
editForm.pay_order_ids = Array.isArray(pids) ? pids.map((x: unknown) => Number(x)).filter((n) => !Number.isNaN(n)) : [] editForm.pay_order_ids = Array.isArray(pids) ? pids.map((x: unknown) => Number(x)).filter((n) => !Number.isNaN(n)) : []
editForm.internal_cost = editForm.internal_cost =
d.internal_cost != null && d.internal_cost !== '' ? Number(d.internal_cost) : undefined d.internal_cost != null && d.internal_cost !== '' ? Number(d.internal_cost) : undefined
const gcNo = String(d.gancao_reciperl_order_no || '').trim()
const gcTime = Number(d.gancao_submit_time || 0)
editGancaoLogisticsOnlyMode.value = gcNo !== '' || gcTime > 0
editGancaoDisplayNo.value = gcNo || ''
await loadEditPaidOrders(editForm.diagnosis_id, editForm.id) await loadEditPaidOrders(editForm.diagnosis_id, editForm.id)
// BUG FIX: NextTick // BUG FIX: NextTick
@@ -4232,8 +4338,14 @@ async function openEdit(row: { id: number }) {
} }
async function submitEdit() { async function submitEdit() {
if (!editFormRef.value || editOrderStep.value !== 2) return if (!editFormRef.value) return
await editFormRef.value.validate() const gancaoLogisticsOnly = editGancaoLogisticsOnlyMode.value
if (!gancaoLogisticsOnly && editOrderStep.value !== 2) return
if (!gancaoLogisticsOnly) {
await editFormRef.value.validate()
} else {
editFormRef.value.clearValidate()
}
editSaving.value = true editSaving.value = true
try { try {
const payload: Record<string, unknown> = { const payload: Record<string, unknown> = {
@@ -4435,6 +4547,61 @@ async function testGancaoPreviewFromDetail() {
if (d && d.success) { if (d && d.success) {
gancaoPreviewData.value = d gancaoPreviewData.value = d
gancaoPreviewDrawerVisible.value = true gancaoPreviewDrawerVisible.value = true
// ( + + ) internal_cost canViewInternalCost
if (canViewFinanceFields() && d.fee) {
const internalTotal = calculateTotalFee(d.fee)
try {
const resDetail: any = await prescriptionOrderDetail({ id: detailData.value.id })
const od = resDetail?.data ?? resDetail
if (od?.id) {
const pkgRaw = od.service_package
const servicePackageStr = Array.isArray(pkgRaw)
? pkgRaw.join(',')
: String(pkgRaw || '')
await prescriptionOrderEdit({
id: od.id,
recipient_name: od.recipient_name || '',
recipient_phone: od.recipient_phone || '',
shipping_province: od.shipping_province || '',
shipping_city: od.shipping_city || '',
shipping_district: od.shipping_district || '',
shipping_address: od.shipping_address || '',
is_follow_up: od.is_follow_up ? 1 : 0,
medication_days:
od.medication_days != null && String(od.medication_days).trim() !== ''
? od.medication_days
: '',
dose_unit: od.dose_unit || '剂',
dose_count: od.dose_count > 0 ? od.dose_count : 1,
prev_staff: od.prev_staff || '',
service_channel: od.service_channel || '',
service_package: servicePackageStr,
express_company: od.express_company || 'auto',
tracking_number: od.tracking_number || '',
fee_type: Number(od.fee_type) || 3,
amount: Number(od.amount) || 0,
remark_extra: od.remark_extra || '',
remark_assistant: od.remark_assistant || '',
internal_cost: internalTotal,
pay_order_ids: Array.isArray(od.pay_order_ids) ? od.pay_order_ids : []
})
feedback.msgSuccess('内部成本已按预报价总计更新')
getLists()
if (detailVisible.value && Number(detailData.value?.id) === Number(od.id)) {
try {
const r: any = await prescriptionOrderDetail({ id: od.id })
const nd = r?.data ?? r ?? null
if (nd) detailData.value = nd
} catch {
detailData.value = { ...detailData.value, internal_cost: internalTotal }
}
}
}
} catch {
/* 拦截器已提示;仍保留抽屉中的预报价结果 */
}
}
//feedback.msgSuccess('') //feedback.msgSuccess('')
} else { } else {
// feedback.msgError(d?.error || '') // feedback.msgError(d?.error || '')
@@ -4550,8 +4717,8 @@ async function submitQuickTrack() {
if (nd) detailData.value = nd if (nd) detailData.value = nd
} catch { /* 静默 */ } } catch { /* 静默 */ }
} }
// // (2)(5)/(6)
if (canShipRow({ fulfillment_status: 2, tracking_number: quickTrackForm.tracking_number })) { if (canShipRow({ fulfillment_status: Number(d.fulfillment_status) })) {
try { try {
await ElMessageBox.confirm( await ElMessageBox.confirm(
`快递单号「${quickTrackForm.tracking_number}」已保存,是否立即确认发货?`, `快递单号「${quickTrackForm.tracking_number}」已保存,是否立即确认发货?`,
@@ -3052,14 +3052,18 @@ function canEditRow(row: {
gancao_reciperl_order_no?: string | null gancao_reciperl_order_no?: string | null
gancao_submit_time?: number | null gancao_submit_time?: number | null
}) { }) {
// (5)(6)(3)(4)
const fs = Number(row.fulfillment_status) const fs = Number(row.fulfillment_status)
if (fs !== 1 && fs !== 2) return false if (fs === 3 || fs === 4) return false
// > 0
const gcNo = String(row.gancao_reciperl_order_no || '').trim() const gcNo = String(row.gancao_reciperl_order_no || '').trim()
const gcTime = Number(row.gancao_submit_time || 0) const gcTime = Number(row.gancao_submit_time || 0)
if (gcNo !== '' || gcTime > 0) return false const gcLocked = gcNo !== '' || gcTime > 0
return true
if (gcLocked) {
return [1, 2, 5, 7].includes(fs)
}
return fs === 1 || fs === 2
} }
function canRxAudit(row: { prescription_audit_status?: number; fulfillment_status?: number }) { function canRxAudit(row: { prescription_audit_status?: number; fulfillment_status?: number }) {
@@ -3128,9 +3132,7 @@ function canCompleteRow(row: { fulfillment_status?: number; payment_slip_audit_s
} }
function canQuickTrackRow(row: { fulfillment_status?: number }) { function canQuickTrackRow(row: { fulfillment_status?: number }) {
// (5) / (6) 使 return Number(row.fulfillment_status) === 5
const fs = Number(row.fulfillment_status)
return fs === 5 || fs === 6
} }
function canUploadGancaoRow(row: { function canUploadGancaoRow(row: {
@@ -4312,8 +4314,8 @@ async function submitQuickTrack() {
if (nd) detailData.value = nd if (nd) detailData.value = nd
} catch { /* 静默 */ } } catch { /* 静默 */ }
} }
// // (2)(5)/(6)
if (canShipRow({ fulfillment_status: 2, tracking_number: quickTrackForm.tracking_number })) { if (canShipRow({ fulfillment_status: Number(d.fulfillment_status) })) {
try { try {
await ElMessageBox.confirm( await ElMessageBox.confirm(
`快递单号「${quickTrackForm.tracking_number}」已保存,是否立即确认发货?`, `快递单号「${quickTrackForm.tracking_number}」已保存,是否立即确认发货?`,
+347 -37
View File
@@ -9,7 +9,11 @@
</span> </span>
<h1 class="cs-masthead__title">提成结算业绩</h1> <h1 class="cs-masthead__title">提成结算业绩</h1>
<p class="cs-masthead__desc"> <p class="cs-masthead__desc">
系统代开处方对应的已完成业务订单按结算月 7 日截止拆分本期提成与顺延下期可按部门汇总或下发至业绩归属医助与处方开方医生 订单池默认与<strong>处方订单列表</strong>同源<strong>创建时间 start_timeend_time</strong> +
<strong>fulfillment_status</strong>默认完成态 3账号<strong>列表可见性数据域</strong>一并生效
选结算月<strong>仍可</strong>套用物流签收<strong></strong>尾款支付<strong>均须在</strong><strong>结算月 7 24 </strong>拆分本期提成 / 顺延下期
仅有签收在范围内尾款晚于截止仍会顺延
展示部门渠道下拉与列表不同勾选后会与列表<strong>计数不同</strong>
</p> </p>
</div> </div>
<dl v-if="meta.settlement_month || meta.cutoff_end" class="cs-masthead__stats"> <dl v-if="meta.settlement_month || meta.cutoff_end" class="cs-masthead__stats">
@@ -17,9 +21,9 @@
<dt class="cs-stat__label">结算月</dt> <dt class="cs-stat__label">结算月</dt>
<dd class="cs-stat__value">{{ meta.settlement_month || settlementMonth }}</dd> <dd class="cs-stat__value">{{ meta.settlement_month || settlementMonth }}</dd>
</div> </div>
<div v-if="meta.order_month" class="cs-stat"> <div v-if="meta.order_month || meta.order_start_time" class="cs-stat">
<dt class="cs-stat__label">订单创建月</dt> <dt class="cs-stat__label">订单时间窗</dt>
<dd class="cs-stat__value">{{ meta.order_month }}</dd> <dd class="cs-stat__value cs-stat__value--xs">{{ orderWindowLabel }}</dd>
</div> </div>
<div v-if="meta.cutoff_end" class="cs-stat"> <div v-if="meta.cutoff_end" class="cs-stat">
<dt class="cs-stat__label">截止时刻</dt> <dt class="cs-stat__label">截止时刻</dt>
@@ -42,6 +46,21 @@
class="filter-month" class="filter-month"
/> />
</div> </div>
<div class="filter-field filter-field--rangewrap">
<span class="lbl">订单创建</span>
<el-date-picker
v-model="orderTimeRange"
type="datetimerange"
value-format="YYYY-MM-DD HH:mm:ss"
range-separator=""
start-placeholder="列表 start_time"
end-placeholder="列表 end_time"
class="filter-datetimerange"
/>
<el-checkbox v-model="requireSystemAutoOnly" class="filter-sa-check">
仅系统代开处方
</el-checkbox>
</div>
<div class="filter-field"> <div class="filter-field">
<span class="lbl">渠道来源</span> <span class="lbl">渠道来源</span>
<el-select <el-select
@@ -117,17 +136,26 @@
<div class="cs-alert__body"> <div class="cs-alert__body">
<p v-if="meta.rule_note">{{ meta.rule_note }}</p> <p v-if="meta.rule_note">{{ meta.rule_note }}</p>
<p v-else> <p v-else>
订单创建月为<strong>结算月的上一自然月</strong><strong>系统代开处方</strong>完成挂号等自动生成对应的<strong>履约已完成</strong>业务订单 请选择结算月并设置<strong>订单创建时间范围</strong>与处方订单列表 URL 参数
<strong>签收</strong>时间取物流签收时间<strong>尾款支付</strong>取关联支付单已支付时间优先尾款/全部费用类型 <code>start_time</code>/<code>end_time</code>/<code>fulfillment_status</code>
签收与尾款均在<strong>结算月 7 24:00 </strong>完成的计入本期提成其余计入顺延下期 一致切换结算月会自动带出<strong>上一自然月整段</strong>作为默认时段可按业务修改例如 2026-04-0204-30
仅系统代开处方勾选后与列表在未限制开方类型时的条数会不一致
</p> </p>
<p v-if="meta.cutoff_end" class="cs-alert__meta"> <p v-if="meta.cutoff_end" class="cs-alert__meta">
当前结算月<strong>{{ meta.settlement_month }}</strong> 当前结算月<strong>{{ meta.settlement_month }}</strong>
· 订单创建月<strong>{{ meta.order_month }}</strong> · 订单时间<strong>{{ orderWindowLabel }}</strong>
· 履约状态<strong>{{ meta.fulfillment_status ?? 3 }}</strong>
· 截止时刻<strong>{{ meta.cutoff_end }}</strong> · 截止时刻<strong>{{ meta.cutoff_end }}</strong>
<template v-if="meta.channel_name"> <template v-if="meta.channel_name">
· 渠道<strong>{{ meta.channel_name }}</strong> · 渠道<strong>{{ meta.channel_name }}</strong>
</template> </template>
<template v-if="meta.settlement_month">
· 处方池<strong>{{
meta.require_system_auto_prescription ? '仅系统代开' : '含手动与系统'
}}</strong>
<template v-if="meta.explicit_order_time_window">
· 列表对齐<strong></strong></template>
</template>
</p> </p>
</div> </div>
</el-alert> </el-alert>
@@ -136,27 +164,43 @@
<div class="cs-reconcile"> <div class="cs-reconcile">
<div class="cs-reconcile__head"> <div class="cs-reconcile__head">
<div class="cs-reconcile__tags"> <div class="cs-reconcile__tags">
<el-tag v-if="confirmInfo?.status === 1" type="success" effect="dark">已确定业绩</el-tag> <el-tag v-if="settlementConfirmedLocked" type="success" effect="dark">已确定业绩</el-tag>
<el-tag v-else type="warning" effect="plain">待确定业绩</el-tag> <el-tag v-else-if="confirmInfo?.status === 2" type="warning" effect="plain">已撤回确定</el-tag>
<el-tag v-else type="info" effect="plain">待确定业绩</el-tag>
<span <span
v-if="confirmInfo?.status === 1 && confirmInfo.confirmed_at_text" v-if="settlementConfirmedLocked && confirmInfo?.confirmed_at_text"
class="cs-reconcile__meta" class="cs-reconcile__meta"
> >
{{ confirmInfo.confirmed_admin_name || '—' }} · {{ confirmInfo.confirmed_at_text }} {{ confirmInfo.confirmed_admin_name || '—' }} · {{ confirmInfo.confirmed_at_text }}
</span> </span>
<span
v-else-if="confirmInfo?.status === 2 && confirmInfo.revoked_at_text"
class="cs-reconcile__meta"
>
撤回{{ confirmInfo.revoked_admin_name || '—' }} · {{ confirmInfo.revoked_at_text }}
</span>
</div> </div>
<div class="cs-reconcile__toolbar"> <div class="cs-reconcile__toolbar">
<el-button type="primary" plain @click="openReconcileDialog">业绩明细核对</el-button> <el-button type="primary" plain @click="openReconcileDialog">业绩明细核对</el-button>
<el-button :disabled="confirmInfo?.status === 1 || reconcileSaving" @click="handleSaveReconcile"> <el-button :disabled="settlementConfirmedLocked || reconcileSaving" @click="handleSaveReconcile">
保存核对备注 保存核对备注
</el-button> </el-button>
<el-button <el-button
type="warning" type="warning"
:disabled="confirmInfo?.status === 1 || confirmSubmitting" :disabled="settlementConfirmedLocked || confirmSubmitting"
@click="handleConfirmFinalize" @click="handleConfirmFinalize"
> >
确定本期业绩 确定本期业绩
</el-button> </el-button>
<el-button
v-if="settlementConfirmedLocked"
type="danger"
plain
:loading="confirmRevoking"
@click="handleConfirmRevoke"
>
撤回确定
</el-button>
</div> </div>
</div> </div>
<el-input <el-input
@@ -166,7 +210,7 @@
maxlength="500" maxlength="500"
show-word-limit show-word-limit
placeholder="核对备注(可与财务线下对齐后填写;确定业绩前可反复保存)" placeholder="核对备注(可与财务线下对齐后填写;确定业绩前可反复保存)"
:disabled="confirmInfo?.status === 1" :disabled="settlementConfirmedLocked"
class="cs-reconcile__note" class="cs-reconcile__note"
/> />
<p v-if="Number(totalAgg.carry_in_order_count) > 0" class="cs-reconcile__carry"> <p v-if="Number(totalAgg.carry_in_order_count) > 0" class="cs-reconcile__carry">
@@ -245,6 +289,8 @@
按诊单业绩归属医助 <strong>×</strong> 挂号渠道doctor_appointment.channels拆分到行 按诊单业绩归属医助 <strong>×</strong> 挂号渠道doctor_appointment.channels拆分到行
<strong>复诊2复诊3自媒体1等保持各自独立</strong>未关联挂号统一归到未匹配挂号渠道 <strong>复诊2复诊3自媒体1等保持各自独立</strong>未关联挂号统一归到未匹配挂号渠道
同一医助多行<strong>自动合并医助 / 归属中心单元格</strong>顺延汇入为上期结转进入本期订单池的单数 同一医助多行<strong>自动合并医助 / 归属中心单元格</strong>顺延汇入为上期结转进入本期订单池的单数
<strong>展示部门</strong>有勾选时本表仅列出<strong>可归入该部门上下文</strong>的业绩医助与人事部门落在所选部门范围内的账号一致
<strong>点击挂号渠道</strong>查看该行对应的业务订单明细与上方部门筛选一致
</span> </span>
</div> </div>
<el-table <el-table
@@ -264,9 +310,10 @@
<template #default="{ row }"> <template #default="{ row }">
<el-tag <el-tag
size="small" size="small"
class="cs-channel-tag" class="cs-channel-tag cs-channel-tag--clickable"
:class="channelTagClass(row.appt_channel_name)" :class="channelTagClass(row.appt_channel_name)"
effect="plain" effect="plain"
@click.stop="openOrdersForAssistantChannel(row)"
> >
{{ row.appt_channel_name }} {{ row.appt_channel_name }}
</el-tag> </el-tag>
@@ -293,6 +340,8 @@
<span class="cs-table-head__hint"> <span class="cs-table-head__hint">
按处方创建账号开方人 <strong>×</strong> 挂号渠道拆分 按处方创建账号开方人 <strong>×</strong> 挂号渠道拆分
可与医助维度交叉核对同一医生多行自动合并医生 / 归属中心单元格 可与医助维度交叉核对同一医生多行自动合并医生 / 归属中心单元格
<strong>展示部门</strong>有勾选时与医助表相同仅统计<strong>该部门上下文内</strong>订单对应的开方医生
<strong>点击挂号渠道</strong>查看该行对应的业务订单明细
</span> </span>
</div> </div>
<el-table <el-table
@@ -312,9 +361,10 @@
<template #default="{ row }"> <template #default="{ row }">
<el-tag <el-tag
size="small" size="small"
class="cs-channel-tag" class="cs-channel-tag cs-channel-tag--clickable"
:class="channelTagClass(row.appt_channel_name)" :class="channelTagClass(row.appt_channel_name)"
effect="plain" effect="plain"
@click.stop="openOrdersForDoctorChannel(row)"
> >
{{ row.appt_channel_name }} {{ row.appt_channel_name }}
</el-tag> </el-tag>
@@ -341,7 +391,7 @@
<el-dialog <el-dialog
v-model="reconcileDialogVisible" v-model="reconcileDialogVisible"
title="业绩明细核对" title="业绩明细核对"
width="1040px" width="1280px"
destroy-on-close destroy-on-close
class="cs-dialog" class="cs-dialog"
@open="onReconcileDialogOpen" @open="onReconcileDialogOpen"
@@ -354,7 +404,26 @@
</el-radio-group> </el-radio-group>
</div> </div>
<el-table v-loading="linesLoading" :data="linesRows" border stripe size="small" max-height="440"> <el-table v-loading="linesLoading" :data="linesRows" border stripe size="small" max-height="440">
<el-table-column prop="order_no" label="业务订单号" min-width="116" show-overflow-tooltip /> <el-table-column prop="order_no" label="业务订单号" min-width="128" show-overflow-tooltip />
<el-table-column label="快递单号" min-width="132" show-overflow-tooltip>
<template #default="{ row }">{{ row.tracking_number || '—' }}</template>
</el-table-column>
<el-table-column label="挂号日期" min-width="124" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.appointment_date_text || '—' }}</span>
<el-tag
v-if="row.appointment_status && Number(row.appointment_status) !== 3"
class="cs-tag-appt-muted"
type="info"
size="small"
effect="plain"
>未完结挂号</el-tag
>
</template>
</el-table-column>
<el-table-column label="挂号渠道" min-width="124" show-overflow-tooltip>
<template #default="{ row }">{{ row.appt_channel_name || '—' }}</template>
</el-table-column>
<el-table-column prop="assistant_name" label="业绩医助" min-width="100" show-overflow-tooltip /> <el-table-column prop="assistant_name" label="业绩医助" min-width="100" show-overflow-tooltip />
<el-table-column prop="doctor_name" label="开方医生" min-width="100" show-overflow-tooltip /> <el-table-column prop="doctor_name" label="开方医生" min-width="100" show-overflow-tooltip />
<el-table-column prop="primary_dept_name" label="归属部门" min-width="100" show-overflow-tooltip /> <el-table-column prop="primary_dept_name" label="归属部门" min-width="100" show-overflow-tooltip />
@@ -373,8 +442,20 @@
<span v-else class="cs-muted"></span> <span v-else class="cs-muted"></span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="sign_time_text" label="签收时间" min-width="152" show-overflow-tooltip /> <el-table-column label="顺延说明" min-width="200" show-overflow-tooltip>
<el-table-column prop="pay_time_text" label="尾款支付" min-width="152" show-overflow-tooltip /> <template #default="{ row }">
<span v-if="row.bucket === 'deferred' && row.bucket_defer_text" class="cs-muted">{{
row.bucket_defer_text
}}</span>
<span v-else class="cs-muted"></span>
</template>
</el-table-column>
<el-table-column label="物流签收" min-width="152" show-overflow-tooltip>
<template #default="{ row }">{{ row.sign_time_text || '—' }}</template>
</el-table-column>
<el-table-column prop="pay_time_text" label="尾款支付" min-width="152" show-overflow-tooltip>
<template #default="{ row }">{{ row.pay_time_text || '—' }}</template>
</el-table-column>
<el-table-column prop="create_time_text" label="订单创建" width="152" /> <el-table-column prop="create_time_text" label="订单创建" width="152" />
</el-table> </el-table>
<div class="cs-dialog__pager"> <div class="cs-dialog__pager">
@@ -390,8 +471,8 @@
<el-dialog <el-dialog
v-model="leafOrdersVisible" v-model="leafOrdersVisible"
:title="leafOrdersDept ? `已完成业绩订单 · ${leafOrdersDept.name}` : '已完成业绩订单'" :title="leafOrdersDialogTitle"
width="1040px" width="1280px"
destroy-on-close destroy-on-close
class="cs-dialog" class="cs-dialog"
> >
@@ -403,12 +484,33 @@
</el-radio-group> </el-radio-group>
<span class="cs-dialog__hint"> <span class="cs-dialog__hint">
结算月<strong>{{ meta.settlement_month || settlementMonth }}</strong> 结算月<strong>{{ meta.settlement_month || settlementMonth }}</strong>
<template v-if="meta.order_month"> · 订单创建月<strong>{{ meta.order_month }}</strong></template> <template v-if="orderWindowLabel && orderWindowLabel !== '—'"
> · 订单创建<strong>{{ orderWindowLabel }}</strong></template
>
<template v-if="meta.channel_name"> · 渠道<strong>{{ meta.channel_name }}</strong></template> <template v-if="meta.channel_name"> · 渠道<strong>{{ meta.channel_name }}</strong></template>
</span> </span>
</div> </div>
<el-table v-loading="leafOrdersLoading" :data="leafOrdersRows" border stripe size="small" max-height="440"> <el-table v-loading="leafOrdersLoading" :data="leafOrdersRows" border stripe size="small" max-height="440">
<el-table-column prop="order_no" label="业务订单号" min-width="116" show-overflow-tooltip /> <el-table-column prop="order_no" label="业务订单号" min-width="128" show-overflow-tooltip />
<el-table-column label="快递单号" min-width="132" show-overflow-tooltip>
<template #default="{ row }">{{ row.tracking_number || '—' }}</template>
</el-table-column>
<el-table-column label="挂号日期" min-width="124" show-overflow-tooltip>
<template #default="{ row }">
<span>{{ row.appointment_date_text || '—' }}</span>
<el-tag
v-if="row.appointment_status && Number(row.appointment_status) !== 3"
class="cs-tag-appt-muted"
type="info"
size="small"
effect="plain"
>未完结挂号</el-tag
>
</template>
</el-table-column>
<el-table-column label="挂号渠道" min-width="124" show-overflow-tooltip>
<template #default="{ row }">{{ row.appt_channel_name || '—' }}</template>
</el-table-column>
<el-table-column prop="assistant_name" label="业绩医助" min-width="100" show-overflow-tooltip /> <el-table-column prop="assistant_name" label="业绩医助" min-width="100" show-overflow-tooltip />
<el-table-column prop="doctor_name" label="开方医生" min-width="100" show-overflow-tooltip /> <el-table-column prop="doctor_name" label="开方医生" min-width="100" show-overflow-tooltip />
<el-table-column prop="primary_dept_name" label="归属部门" min-width="120" show-overflow-tooltip /> <el-table-column prop="primary_dept_name" label="归属部门" min-width="120" show-overflow-tooltip />
@@ -427,8 +529,20 @@
<span v-else class="cs-muted"></span> <span v-else class="cs-muted"></span>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="sign_time_text" label="签收时间" min-width="152" show-overflow-tooltip /> <el-table-column label="顺延说明" min-width="200" show-overflow-tooltip>
<el-table-column prop="pay_time_text" label="尾款支付" min-width="152" show-overflow-tooltip /> <template #default="{ row }">
<span v-if="row.bucket === 'deferred' && row.bucket_defer_text" class="cs-muted">{{
row.bucket_defer_text
}}</span>
<span v-else class="cs-muted"></span>
</template>
</el-table-column>
<el-table-column label="物流签收" min-width="152" show-overflow-tooltip>
<template #default="{ row }">{{ row.sign_time_text || '—' }}</template>
</el-table-column>
<el-table-column prop="pay_time_text" label="尾款支付" min-width="152" show-overflow-tooltip>
<template #default="{ row }">{{ row.pay_time_text || '—' }}</template>
</el-table-column>
<el-table-column prop="create_time_text" label="订单创建" width="152" /> <el-table-column prop="create_time_text" label="订单创建" width="152" />
</el-table> </el-table>
<div class="cs-dialog__pager"> <div class="cs-dialog__pager">
@@ -445,12 +559,13 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onMounted, reactive, ref } from 'vue' import { computed, onMounted, reactive, ref, watch } from 'vue'
import { ArrowRight, ArrowUp, RefreshRight, Search, Tickets } from '@element-plus/icons-vue' import { ArrowRight, ArrowUp, RefreshRight, Search, Tickets } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus' import { ElMessage, ElMessageBox } from 'element-plus'
import { import {
commissionSettlementChannelOptions, commissionSettlementChannelOptions,
commissionSettlementConfirmFinalize, commissionSettlementConfirmFinalize,
commissionSettlementConfirmRevoke,
commissionSettlementDeptOptions, commissionSettlementDeptOptions,
commissionSettlementOrderLines, commissionSettlementOrderLines,
commissionSettlementOverview, commissionSettlementOverview,
@@ -565,6 +680,16 @@ interface CsDoctorRow {
deferred_period_amount: number deferred_period_amount: number
} }
type LeafOrderDrillDept = { mode: 'dept'; dept_id: number; dept_name: string }
type LeafOrderDrillChannel = {
mode: 'channel'
title: string
assistant_id?: number
doctor_id?: number
appt_channel_value: number
}
type LeafOrderDrill = LeafOrderDrillDept | LeafOrderDrillChannel
interface CsAssistChannelRow extends CsAssistRow { interface CsAssistChannelRow extends CsAssistRow {
appt_channel_value: number appt_channel_value: number
appt_channel_name: string appt_channel_name: string
@@ -584,7 +709,27 @@ function defaultSettlementMonth(): string {
return `${y}-${m}` return `${y}-${m}`
} }
function pad2(n: number): string {
return String(n).padStart(2, '0')
}
function formatDateTime(d: Date): string {
return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())} ${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}`
}
/** 订单池默认:结算月「上一自然月」整段(与未传 start/end 的后端行为一致) */
function defaultOrderTimeRangeForSettlementMonth(sm: string): [string, string] {
const m = /^(\d{4})-(\d{2})$/.exec(sm)
const y = m ? parseInt(m[1], 10) : new Date().getFullYear()
const monthNum = m ? parseInt(m[2], 10) : new Date().getMonth() + 1
const start = new Date(y, monthNum - 2, 1, 0, 0, 0)
const end = new Date(y, monthNum - 1, 0, 23, 59, 59)
return [formatDateTime(start), formatDateTime(end)]
}
const settlementMonth = ref<string>(defaultSettlementMonth()) const settlementMonth = ref<string>(defaultSettlementMonth())
const orderTimeRange = ref<[string, string] | null>(defaultOrderTimeRangeForSettlementMonth(settlementMonth.value))
const requireSystemAutoOnly = ref(false)
const loading = ref(false) const loading = ref(false)
const deptOptions = ref<DeptOption[]>([]) const deptOptions = ref<DeptOption[]>([])
const deptOptionsLoading = ref(false) const deptOptionsLoading = ref(false)
@@ -612,9 +757,14 @@ const totalAgg = ref<{
const meta = reactive({ const meta = reactive({
settlement_month: '', settlement_month: '',
order_month: '', order_month: '',
order_start_time: '',
order_end_time: '',
fulfillment_status: 3,
explicit_order_time_window: false,
cutoff_end: '', cutoff_end: '',
rule_note: '', rule_note: '',
channel_name: '', channel_name: '',
require_system_auto_prescription: false,
}) })
const confirmInfo = ref<{ const confirmInfo = ref<{
@@ -622,10 +772,17 @@ const confirmInfo = ref<{
reconcile_note?: string reconcile_note?: string
confirmed_admin_name?: string confirmed_admin_name?: string
confirmed_at_text?: string confirmed_at_text?: string
revoked_admin_name?: string
revoked_at_text?: string
is_confirmed_locked?: boolean
} | null>(null) } | null>(null)
const reconcileNote = ref('') const reconcileNote = ref('')
const reconcileSaving = ref(false) const reconcileSaving = ref(false)
const confirmSubmitting = ref(false) const confirmSubmitting = ref(false)
const confirmRevoking = ref(false)
/** 仅 status=1 时锁定,禁止保存备注 / 重复确定;status=2 已撤回可再操作 */
const settlementConfirmedLocked = computed(() => Number(confirmInfo.value?.status) === 1)
const reconcileDialogVisible = ref(false) const reconcileDialogVisible = ref(false)
const linesLoading = ref(false) const linesLoading = ref(false)
@@ -636,7 +793,7 @@ const linesPage = ref(1)
const linesPageSize = ref(20) const linesPageSize = ref(20)
const leafOrdersVisible = ref(false) const leafOrdersVisible = ref(false)
const leafOrdersDept = ref<{ id: number; name: string } | null>(null) const leafOrderDrill = ref<LeafOrderDrill | null>(null)
const leafOrdersBucket = ref<string>('all') const leafOrdersBucket = ref<string>('all')
const leafOrdersRows = ref<Record<string, any>[]>([]) const leafOrdersRows = ref<Record<string, any>[]>([])
const leafOrdersTotal = ref(0) const leafOrdersTotal = ref(0)
@@ -644,6 +801,20 @@ const leafOrdersPage = ref(1)
const leafOrdersPageSize = ref(20) const leafOrdersPageSize = ref(20)
const leafOrdersLoading = ref(false) const leafOrdersLoading = ref(false)
const leafOrdersDialogTitle = computed(() => {
const d = leafOrderDrill.value
if (!d) return '已完成业绩订单'
if (d.mode === 'dept') return `已完成业绩订单 · ${d.dept_name}`
return d.title
})
const orderWindowLabel = computed(() => {
if (meta.order_start_time && meta.order_end_time) {
return `${meta.order_start_time}${meta.order_end_time}`
}
return meta.order_month || '—'
})
const deptChildrenMap = computed(() => { const deptChildrenMap = computed(() => {
const map = new Map<number, number[]>() const map = new Map<number, number[]>()
for (const d of deptOptions.value) { for (const d of deptOptions.value) {
@@ -718,7 +889,45 @@ function openOrderLinesForDept(deptId: number, deptName: string) {
ElMessage.warning('请选择结算月') ElMessage.warning('请选择结算月')
return return
} }
leafOrdersDept.value = { id: deptId, name: deptName } leafOrderDrill.value = { mode: 'dept', dept_id: deptId, dept_name: deptName }
leafOrdersBucket.value = 'all'
leafOrdersPage.value = 1
leafOrdersRows.value = []
leafOrdersTotal.value = 0
leafOrdersVisible.value = true
loadLeafOrders(1)
}
function openOrdersForAssistantChannel(row: CsAssistChannelRow) {
if (!settlementMonth.value) {
ElMessage.warning('请选择结算月')
return
}
leafOrderDrill.value = {
mode: 'channel',
title: `业务订单 · ${row.appt_channel_name} · 医助 ${row.assistant_name}`,
assistant_id: row.assistant_id,
appt_channel_value: Number(row.appt_channel_value ?? 0),
}
leafOrdersBucket.value = 'all'
leafOrdersPage.value = 1
leafOrdersRows.value = []
leafOrdersTotal.value = 0
leafOrdersVisible.value = true
loadLeafOrders(1)
}
function openOrdersForDoctorChannel(row: CsDoctorChannelRow) {
if (!settlementMonth.value) {
ElMessage.warning('请选择结算月')
return
}
leafOrderDrill.value = {
mode: 'channel',
title: `业务订单 · ${row.appt_channel_name} · 医生 ${row.doctor_name}`,
doctor_id: row.doctor_id,
appt_channel_value: Number(row.appt_channel_value ?? 0),
}
leafOrdersBucket.value = 'all' leafOrdersBucket.value = 'all'
leafOrdersPage.value = 1 leafOrdersPage.value = 1
leafOrdersRows.value = [] leafOrdersRows.value = []
@@ -728,18 +937,30 @@ function openOrderLinesForDept(deptId: number, deptName: string) {
} }
async function loadLeafOrders(page: number) { async function loadLeafOrders(page: number) {
if (!settlementMonth.value || !leafOrdersDept.value) return if (!settlementMonth.value || !leafOrderDrill.value) return
leafOrdersLoading.value = true leafOrdersLoading.value = true
leafOrdersPage.value = page leafOrdersPage.value = page
try { try {
const d = leafOrderDrill.value
const p: Record<string, any> = { const p: Record<string, any> = {
settlement_month: settlementMonth.value, settlement_month: settlementMonth.value,
dept_ids: String(leafOrdersDept.value.id),
page, page,
page_size: leafOrdersPageSize.value, page_size: leafOrdersPageSize.value,
} }
if (selectedChannel.value) { if (d.mode === 'dept') {
p.channel_code = selectedChannel.value p.dept_ids = String(d.dept_id)
if (selectedChannel.value) {
p.channel_code = selectedChannel.value
}
} else {
Object.assign(p, buildQueryParams())
p.appt_channel_value = d.appt_channel_value
if (d.assistant_id != null) {
p.assistant_id = d.assistant_id
}
if (d.doctor_id != null) {
p.doctor_id = d.doctor_id
}
} }
if (leafOrdersBucket.value && leafOrdersBucket.value !== 'all') { if (leafOrdersBucket.value && leafOrdersBucket.value !== 'all') {
p.bucket = leafOrdersBucket.value p.bucket = leafOrdersBucket.value
@@ -796,6 +1017,11 @@ async function loadOverview() {
ElMessage.warning('请选择结算月') ElMessage.warning('请选择结算月')
return return
} }
const ot = orderTimeRange.value
if (!ot || !ot[0] || !ot[1]) {
ElMessage.warning('请设置订单创建时间范围')
return
}
loading.value = true loading.value = true
try { try {
const res: any = await commissionSettlementOverview(buildQueryParams() as any) const res: any = await commissionSettlementOverview(buildQueryParams() as any)
@@ -807,9 +1033,21 @@ async function loadOverview() {
totalAgg.value = res?.total || {} totalAgg.value = res?.total || {}
meta.settlement_month = res?.settlement_month || sm meta.settlement_month = res?.settlement_month || sm
meta.order_month = res?.order_month || '' meta.order_month = res?.order_month || ''
meta.order_start_time = res?.order_start_time ? String(res.order_start_time) : ''
meta.order_end_time = res?.order_end_time ? String(res.order_end_time) : ''
meta.fulfillment_status =
res?.fulfillment_status != null ? Number(res.fulfillment_status) : 3
meta.explicit_order_time_window =
typeof res?.explicit_order_time_window === 'boolean'
? res.explicit_order_time_window
: !!(meta.order_start_time && meta.order_end_time)
meta.cutoff_end = res?.cutoff_end || '' meta.cutoff_end = res?.cutoff_end || ''
meta.rule_note = res?.rule_note || '' meta.rule_note = res?.rule_note || ''
meta.channel_name = res?.channel_name || '' meta.channel_name = res?.channel_name || ''
meta.require_system_auto_prescription =
typeof res?.require_system_auto_prescription === 'boolean'
? res.require_system_auto_prescription
: false
confirmInfo.value = res?.confirm ?? null confirmInfo.value = res?.confirm ?? null
reconcileNote.value = reconcileNote.value =
res?.confirm?.reconcile_note != null ? String(res.confirm.reconcile_note) : '' res?.confirm?.reconcile_note != null ? String(res.confirm.reconcile_note) : ''
@@ -829,7 +1067,18 @@ async function loadOverview() {
function buildQueryParams(): Record<string, any> { function buildQueryParams(): Record<string, any> {
const sm = settlementMonth.value const sm = settlementMonth.value
const p: Record<string, any> = { settlement_month: sm } const p: Record<string, any> = {
settlement_month: sm,
fulfillment_status: 3,
}
const ot = orderTimeRange.value
if (ot && ot[0] && ot[1]) {
p.start_time = ot[0]
p.end_time = ot[1]
}
if (requireSystemAutoOnly.value) {
p.require_system_auto_prescription = 1
}
if (selectedDeptIds.value.length > 0) { if (selectedDeptIds.value.length > 0) {
p.dept_ids = selectedDeptIds.value.join(',') p.dept_ids = selectedDeptIds.value.join(',')
} }
@@ -882,8 +1131,8 @@ async function handleSaveReconcile() {
ElMessage.warning('请选择结算月') ElMessage.warning('请选择结算月')
return return
} }
if (confirmInfo.value?.status === 1) { if (settlementConfirmedLocked.value) {
ElMessage.warning('已确定业绩不可修改备注') ElMessage.warning('已确定业绩不可修改备注;请先撤回确定')
return return
} }
reconcileSaving.value = true reconcileSaving.value = true
@@ -908,7 +1157,7 @@ async function handleConfirmFinalize() {
} }
try { try {
await ElMessageBox.confirm( await ElMessageBox.confirm(
'确定后将为「顺延下期」订单写入结转记录下一结算月在相同渠道与部门筛选下自动并入统计。确定后不可在线撤销,请与财务对后再操作。', '确定后将为「顺延下期」订单写入结转记录下一结算月在相同渠道与部门筛选下自动并入统计。确定后仍可「撤回确定」以清除结转并重新核对(与财务对后再操作。',
'确定本期业绩', '确定本期业绩',
{ {
confirmButtonText: '确定', confirmButtonText: '确定',
@@ -936,8 +1185,40 @@ async function handleConfirmFinalize() {
} }
} }
async function handleConfirmRevoke() {
if (!settlementMonth.value) {
ElMessage.warning('请选择结算月')
return
}
try {
await ElMessageBox.confirm(
'将撤回本次「确定业绩」状态,并删除已写入的顺延结转记录(下期将不再汇入这些单)。确定后继续?',
'撤回确定业绩',
{
confirmButtonText: '撤回',
cancelButtonText: '取消',
type: 'warning',
}
)
} catch {
return
}
confirmRevoking.value = true
try {
await commissionSettlementConfirmRevoke(buildQueryParams() as any)
ElMessage.success('已撤回确定;可重新保存备注并再次确定本期业绩')
await loadOverview()
} catch (e: any) {
ElMessage.error(e?.msg || e?.message || '撤回失败')
} finally {
confirmRevoking.value = false
}
}
function handleReset() { function handleReset() {
settlementMonth.value = defaultSettlementMonth() settlementMonth.value = defaultSettlementMonth()
orderTimeRange.value = defaultOrderTimeRangeForSettlementMonth(settlementMonth.value)
requireSystemAutoOnly.value = false
selectedDeptIds.value = [] selectedDeptIds.value = []
selectedChannel.value = '' selectedChannel.value = ''
loadOverview() loadOverview()
@@ -1053,6 +1334,12 @@ function getSummaries(param: { columns: Array<{ property?: string }>; data: CsRo
return sums return sums
} }
watch(settlementMonth, (v) => {
if (v) {
orderTimeRange.value = defaultOrderTimeRangeForSettlementMonth(v)
}
})
onMounted(async () => { onMounted(async () => {
await Promise.all([loadDeptOptions(), loadChannelOptions()]) await Promise.all([loadDeptOptions(), loadChannelOptions()])
await loadOverview() await loadOverview()
@@ -1249,7 +1536,24 @@ onMounted(async () => {
flex: 1 1 280px; flex: 1 1 280px;
min-width: 240px; min-width: 240px;
} }
.filter-field--rangewrap {
flex: 1 1 440px;
min-width: 300px;
}
.filter-month { width: 168px; } .filter-month { width: 168px; }
.filter-datetimerange {
width: 100%;
max-width: 520px;
}
.filter-sa-check {
margin-top: 6px;
font-weight: 500;
color: var(--cs-text);
}
.cs-tag-appt-muted {
margin-left: 6px;
vertical-align: middle;
}
.filter-select--channel { width: 220px; } .filter-select--channel { width: 220px; }
.filter-dept-tree-select { width: 100%; min-width: 240px; } .filter-dept-tree-select { width: 100%; min-width: 240px; }
.filter-actions { .filter-actions {
@@ -1581,6 +1885,12 @@ onMounted(async () => {
border-color: #cbd5e1 !important; border-color: #cbd5e1 !important;
color: #64748b !important; color: #64748b !important;
} }
&--clickable {
cursor: pointer;
&:hover {
filter: brightness(0.96);
}
}
&--neutral { &--neutral {
background: #f0fdfa !important; background: #f0fdfa !important;
border-color: #99f6e4 !important; border-color: #99f6e4 !important;
File diff suppressed because it is too large Load Diff
@@ -53,7 +53,7 @@
> >
<el-option <el-option
v-for="item in channelOptions" v-for="item in channelOptions"
:key="item.value" :key="String(item.value)"
:label="item.name" :label="item.name"
:value="item.value" :value="item.value"
/> />
@@ -470,7 +470,11 @@ const loadChannelOptions = async () => {
if (ds !== 0) return ds if (ds !== 0) return ds
return Number(b?.id ?? 0) - Number(a?.id ?? 0) return Number(b?.id ?? 0) - Number(a?.id ?? 0)
}) })
channelOptions.value = rows // 统一为字符串,避免字典 value 为数字时 el-select 与表单校验不一致导致看似选了但实际未绑定
channelOptions.value = rows.map((row: any) => ({
...row,
value: row?.value != null && row.value !== '' ? String(row.value) : ''
}))
} catch (e) { } catch (e) {
console.error('加载渠道来源失败:', e) console.error('加载渠道来源失败:', e)
channelOptions.value = [] channelOptions.value = []
@@ -693,7 +697,7 @@ const handleConfirm = async () => {
appointment_time: form.appointmentTime, appointment_time: form.appointmentTime,
appointment_type: form.appointmentType, appointment_type: form.appointmentType,
remark: form.remark, remark: form.remark,
channel_source: form.channel_source, channel_source: String(form.channel_source ?? ''),
channel_source_detail: form.channel_source_detail.trim() channel_source_detail: form.channel_source_detail.trim()
} }
@@ -683,7 +683,7 @@ const bloodTrendOption = computed(() => ({
name: '空腹血糖', name: '空腹血糖',
type: 'line', type: 'line',
smooth: true, smooth: true,
connectNulls: false, connectNulls: true,
data: bloodTrendSeries.value.fasting, data: bloodTrendSeries.value.fasting,
symbolSize: 7, symbolSize: 7,
itemStyle: { itemStyle: {
@@ -698,7 +698,7 @@ const bloodTrendOption = computed(() => ({
name: '餐后血糖', name: '餐后血糖',
type: 'line', type: 'line',
smooth: true, smooth: true,
connectNulls: false, connectNulls: true,
data: bloodTrendSeries.value.postprandial, data: bloodTrendSeries.value.postprandial,
symbolSize: 7, symbolSize: 7,
itemStyle: { itemStyle: {
@@ -719,7 +719,8 @@ function formatColumnDate(date: string) {
function parseTrendNumber(value: unknown): number | null { function parseTrendNumber(value: unknown): number | null {
if (value === '' || value == null) return null if (value === '' || value == null) return null
const parsed = Number(value) const parsed = Number(value)
return Number.isFinite(parsed) ? parsed : null if (!Number.isFinite(parsed) || parsed === 0) return null
return parsed
} }
function getCell(metric: string, date: string): { value: string; isHigh: boolean; hasRecord: boolean } { function getCell(metric: string, date: string): { value: string; isHigh: boolean; hasRecord: boolean } {
File diff suppressed because one or more lines are too long
@@ -64,6 +64,40 @@ class AppointmentController extends BaseAdminController
return $this->dataLists(new AppointmentLists()); return $this->dataLists(new AppointmentLists());
} }
/**
* 后台编辑挂号记录(消费者处方-挂号列表等,perms: doctor.appointment/edit
*/
public function edit()
{
$params = (new AppointmentValidate())->post()->goCheck('adminEdit');
$post = $this->request->post();
if (array_key_exists('assistant_id', $post)) {
$params['assistant_id'] = $post['assistant_id'];
}
$result = AppointmentLogic::adminEdit($params, $this->adminId, $this->adminInfo);
if ($result === false) {
return $this->fail(AppointmentLogic::getError());
}
return $this->success('保存成功');
}
/** 批量修改挂号渠道来源(消费者处方-挂号列表) */
public function batchEditChannel()
{
$params = (new AppointmentValidate())->post()->goCheck('batchEditChannel');
$post = $this->request->post();
if (\array_key_exists('channel_source_detail', $post)) {
$params['channel_source_detail'] = $post['channel_source_detail'];
}
$result = AppointmentLogic::adminBatchEditChannel($params, $this->adminId, $this->adminInfo);
if ($result === false) {
return $this->fail(AppointmentLogic::getError());
}
return $this->success((string) ($result['msg'] ?? '操作成功'), $result);
}
/** /**
* @notes 预约详情 * @notes 预约详情
* @return \think\response\Json * @return \think\response\Json
@@ -32,6 +32,8 @@ use app\adminapi\logic\stats\YejiStatsLogic;
* - POST stats.commissionSettlement/confirmFinalize * - POST stats.commissionSettlement/confirmFinalize
* - POST stats.commissionSettlement/confirmRevoke
* - GET stats.commissionSettlement/deptOptions * - GET stats.commissionSettlement/deptOptions
* - GET stats.commissionSettlement/channelOptions * - GET stats.commissionSettlement/channelOptions
@@ -106,6 +108,16 @@ class CommissionSettlementController extends BaseAdminController
public function confirmRevoke()
{
return $this->data(YejiStatsLogic::commissionSettlementConfirmRevoke($this->request->post(), $this->adminId, $this->adminInfo));
}
public function deptOptions() public function deptOptions()
{ {
@@ -20,6 +20,14 @@ class PrescriptionOrderController extends BaseAdminController
return $this->dataLists(new PrescriptionOrderLists()); return $this->dataLists(new PrescriptionOrderLists());
} }
/**
* 处方业务订单导出(与 lists 相同筛选条件,Excel;参数 export=1 预估 export=2 下载)
*/
public function export()
{
return $this->dataLists(new PrescriptionOrderLists());
}
/** /**
* 指定诊单下可关联的支付单(待支付/已支付,创建/编辑业务订单时多选关联) * 指定诊单下可关联的支付单(待支付/已支付,创建/编辑业务订单时多选关联)
*/ */
@@ -109,17 +109,30 @@ class AuthMiddleware
*/ */
private function matchPermissionAlias(string $accessUri, array $adminUris): bool private function matchPermissionAlias(string $accessUri, array $adminUris): bool
{ {
if (!in_array('tcm.diagnosis/dailyrecord', $adminUris, true)) { if (in_array('tcm.diagnosis/dailyrecord', $adminUris, true)
return false; && in_array($accessUri, [
'tcm.diagnosistodo/lists',
'tcm.diagnosistodo/add',
'tcm.diagnosistodo/cancel',
'tcm.diagnosis/trackingnotes',
'tcm.diagnosis/addtrackingnote',
], true)) {
return true;
} }
return in_array($accessUri, [ // 导出与列表共用 PrescriptionOrderLists 数据域;角色漏勾「导出订单」子权限时仍返回 权限不足
'tcm.diagnosistodo/lists', if ($accessUri === 'tcm.prescriptionorder/export'
'tcm.diagnosistodo/add', && in_array('tcm.prescriptionorder/lists', $adminUris, true)) {
'tcm.diagnosistodo/cancel', return true;
'tcm.diagnosis/trackingnotes', }
'tcm.diagnosis/addtrackingnote',
], true); // 挂号列表批量改渠道:与单条编辑同一数据域,复用 doctor.appointment/edit
if ($accessUri === 'doctor.appointment/batcheditchannel'
&& in_array('doctor.appointment/edit', $adminUris, true)) {
return true;
}
return false;
} }
/** /**
@@ -28,12 +28,9 @@ abstract class BaseAdminDataLists extends BaseDataLists
protected array $adminInfo; protected array $adminInfo;
protected int $adminId; protected int $adminId;
public function __construct() protected function initAdminIdentity(): void
{ {
parent::__construct();
$this->adminInfo = $this->request->adminInfo; $this->adminInfo = $this->request->adminInfo;
$this->adminId = $this->request->adminId; $this->adminId = $this->request->adminId;
} }
} }
@@ -7,9 +7,11 @@ use app\common\model\DiagnosisViewRecord;
use app\common\model\doctor\Appointment; use app\common\model\doctor\Appointment;
use app\common\model\tcm\Prescription; use app\common\model\tcm\Prescription;
use app\common\model\auth\AdminRole; use app\common\model\auth\AdminRole;
use app\common\model\dict\DictData;
use app\common\lists\ListsExtendInterface; use app\common\lists\ListsExtendInterface;
use app\common\lists\ListsSearchInterface; use app\common\lists\ListsSearchInterface;
use app\common\lists\Traits\HasDataScopeFilter; use app\common\lists\Traits\HasDataScopeFilter;
use think\facade\Db;
/** /**
* 医生预约列表 * 医生预约列表
@@ -56,6 +58,63 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
$inList = implode(',', $ids); $inList = implode(',', $ids);
$query->whereRaw("(a.doctor_id IN ({$inList}) OR u.assistant_id IN ({$inList}))"); $query->whereRaw("(a.doctor_id IN ({$inList}) OR u.assistant_id IN ({$inList}))");
} }
/**
* 按医助筛选:诊单指派医助或挂号记录上的医助任一命中即可
*
* @param mixed $query
*/
private function applyAssistantIdFilter($query): void
{
$aid = (int) ($this->params['assistant_id'] ?? 0);
if ($aid <= 0) {
return;
}
$query->where(function ($q) use ($aid): void {
$q->where('u.assistant_id', $aid)->whereOr('a.assistant_id', $aid);
});
}
/**
* 渠道筛选:与 AppointmentLogic 一致,兼容仅有 channel_source、仅有 channels、或两者皆有的表结构
*
* @param mixed $query
*/
private function applyChannelSourceFilter($query, string $chFilter): void
{
if ($chFilter === '') {
return;
}
$tblFields = Db::name('doctor_appointment')->getTableFields();
$cols = \is_array($tblFields) ? $tblFields : [];
$hasChannelSource = \in_array('channel_source', $cols, true);
$hasChannels = \in_array('channels', $cols, true);
if (!$hasChannelSource && !$hasChannels) {
return;
}
$query->where(function ($q) use ($chFilter, $hasChannelSource, $hasChannels): void {
if ($hasChannelSource && $hasChannels) {
$q->where('a.channel_source', '=', $chFilter)
->whereOr('a.channels', '=', $chFilter);
if (is_numeric($chFilter)) {
$q->whereOr('a.channels', '=', (int) $chFilter);
}
return;
}
if ($hasChannelSource) {
$q->where('a.channel_source', '=', $chFilter);
return;
}
$q->where('a.channels', '=', $chFilter);
if (is_numeric($chFilter)) {
$q->whereOr('a.channels', '=', (int) $chFilter);
}
});
}
/** /**
* @notes 设置搜索条件 * @notes 设置搜索条件
* @return array * @return array
@@ -89,6 +148,9 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
$this->searchWhere[] = ['a.status', '=', $this->params['status']]; $this->searchWhere[] = ['a.status', '=', $this->params['status']];
} }
// 渠道字典 value(命中 channel_source 或 legacy channels
$chFilter = isset($this->params['channel_source']) ? trim((string) $this->params['channel_source']) : '';
// 处理日期范围搜索 // 处理日期范围搜索
if (!empty($this->params['start_date']) && !empty($this->params['end_date'])) { if (!empty($this->params['start_date']) && !empty($this->params['end_date'])) {
$this->searchWhere[] = ['a.appointment_date', 'between', [$this->params['start_date'], $this->params['end_date']]]; $this->searchWhere[] = ['a.appointment_date', 'between', [$this->params['start_date'], $this->params['end_date']]];
@@ -122,11 +184,15 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
->leftJoin('tcm_diagnosis u', 'a.patient_id = u.id') ->leftJoin('tcm_diagnosis u', 'a.patient_id = u.id')
->leftJoin('admin ad', 'a.doctor_id = ad.id') ->leftJoin('admin ad', 'a.doctor_id = ad.id')
->leftJoin('admin asst', 'u.assistant_id = asst.id') ->leftJoin('admin asst', 'u.assistant_id = asst.id')
->field('a.*, u.patient_name as patient_name, u.phone as patient_phone, u.gender as gender, u.age as age, u.weight as weight, u.height as height, u.assistant_id as assistant_id, ad.name as doctor_name, asst.name as assistant_name, u.id as diagnosis_id'); ->field('a.*, u.patient_name as patient_name, u.phone as patient_phone, u.gender as gender, u.age as age, u.weight as weight, u.height as height, u.assistant_id as assistant_id, ad.name as doctor_name, asst.name as assistant_name, u.id as diagnosis_id, a.assistant_id as appointment_assistant_id');
if ($this->searchWhere !== []) { if ($this->searchWhere !== []) {
$query->where($this->searchWhere); $query->where($this->searchWhere);
} }
$this->applyAssistantIdFilter($query);
$this->applyChannelSourceFilter($query, $chFilter);
// 是否确认诊单:1=已确认 0=未确认 // 是否确认诊单:1=已确认 0=未确认
if (isset($this->params['diagnosis_confirmed']) && $this->params['diagnosis_confirmed'] !== '') { if (isset($this->params['diagnosis_confirmed']) && $this->params['diagnosis_confirmed'] !== '') {
$confirmed = (int)$this->params['diagnosis_confirmed']; $confirmed = (int)$this->params['diagnosis_confirmed'];
@@ -212,6 +278,9 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
} }
} }
} }
$channelNameByValue = DictData::where('type_value', 'channels')->column('name', 'value');
foreach ($lists as &$item) { foreach ($lists as &$item) {
$statusMap = [ $statusMap = [
1 => '已预约', 1 => '已预约',
@@ -228,6 +297,24 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
]; ];
$item['appointment_type_desc'] = $typeMap[$item['appointment_type']] ?? '未知'; $item['appointment_type_desc'] = $typeMap[$item['appointment_type']] ?? '未知';
$periodRaw = (string) ($item['period'] ?? ($item['type'] ?? ''));
$periodMap = [
'morning' => '上午',
'afternoon' => '下午',
'all' => '全天',
];
$item['period_desc'] = $periodMap[$periodRaw] ?? ($periodRaw !== '' ? $periodRaw : '—');
$srcKey = trim((string) ($item['channel_source'] ?? ''));
if ($srcKey === '' && isset($item['channels']) && $item['channels'] !== '' && $item['channels'] !== null) {
$srcKey = trim((string) $item['channels']);
}
if ($srcKey !== '') {
$item['channel_source_desc'] = (string) ($channelNameByValue[$srcKey] ?? $channelNameByValue[(string) (int) $srcKey] ?? $srcKey);
} else {
$item['channel_source_desc'] = '—';
}
$item['diagnosis_confirmed'] = isset($confirmedMap[$item['diagnosis_id'] ?? 0]) ? 1 : 0; $item['diagnosis_confirmed'] = isset($confirmedMap[$item['diagnosis_id'] ?? 0]) ? 1 : 0;
$item['has_prescription'] = isset($prescribedDiagnosisIds[$item['diagnosis_id'] ?? 0]) ? 1 : 0; $item['has_prescription'] = isset($prescribedDiagnosisIds[$item['diagnosis_id'] ?? 0]) ? 1 : 0;
@@ -267,6 +354,7 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
if ($applyStatusFilter && isset($this->params['status']) && $this->params['status'] !== '') { if ($applyStatusFilter && isset($this->params['status']) && $this->params['status'] !== '') {
$query->where('a.status', '=', $this->params['status']); $query->where('a.status', '=', $this->params['status']);
} }
$chFilter = isset($this->params['channel_source']) ? trim((string) $this->params['channel_source']) : '';
if (!empty($this->params['start_date']) && !empty($this->params['end_date'])) { if (!empty($this->params['start_date']) && !empty($this->params['end_date'])) {
$query->whereBetween('a.appointment_date', [$this->params['start_date'], $this->params['end_date']]); $query->whereBetween('a.appointment_date', [$this->params['start_date'], $this->params['end_date']]);
} elseif (!empty($this->params['start_date'])) { } elseif (!empty($this->params['start_date'])) {
@@ -283,6 +371,10 @@ class AppointmentLists extends BaseAdminDataLists implements ListsSearchInterfac
$query->where('a.doctor_id', '=', (int) $this->params['doctor_id']); $query->where('a.doctor_id', '=', (int) $this->params['doctor_id']);
} }
$this->applyAssistantIdFilter($query);
$this->applyChannelSourceFilter($query, $chFilter);
if ((int) ($this->params['exclude_cancelled'] ?? 0) === 1) { if ((int) ($this->params['exclude_cancelled'] ?? 0) === 1) {
$sf = $this->params['status'] ?? ''; $sf = $this->params['status'] ?? '';
if ($sf === '' || (int) $sf !== 2) { if ($sf === '' || (int) $sf !== 2) {
@@ -8,6 +8,8 @@ use app\adminapi\lists\BaseAdminDataLists;
use app\adminapi\logic\dept\DeptLogic; use app\adminapi\logic\dept\DeptLogic;
use app\adminapi\logic\stats\YejiStatsLogic; use app\adminapi\logic\stats\YejiStatsLogic;
use app\adminapi\logic\tcm\PrescriptionOrderLogic; use app\adminapi\logic\tcm\PrescriptionOrderLogic;
use app\common\enum\ExportEnum;
use app\common\lists\ListsExcelInterface;
use app\common\lists\ListsExtendInterface; use app\common\lists\ListsExtendInterface;
use app\common\lists\ListsSearchInterface; use app\common\lists\ListsSearchInterface;
use app\common\lists\Traits\HasDataScopeFilter; use app\common\lists\Traits\HasDataScopeFilter;
@@ -23,7 +25,7 @@ use think\facade\Config;
use think\facade\Db; use think\facade\Db;
use think\db\Query; use think\db\Query;
class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchInterface, ListsExtendInterface class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchInterface, ListsExtendInterface, ListsExcelInterface
{ {
use HasDataScopeFilter; use HasDataScopeFilter;
@@ -102,6 +104,7 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
$this->applyPatientIdFilter($query); $this->applyPatientIdFilter($query);
$this->applyExpressCompanyFilter($query); $this->applyExpressCompanyFilter($query);
$this->applyExpressKeywordFilter($query); $this->applyExpressKeywordFilter($query);
$this->applyServiceChannelFilter($query);
$this->applySupplyModeFilter($query); $this->applySupplyModeFilter($query);
if (!$this->shouldBypassListVisibilityForDiagnosisEdit()) { if (!$this->shouldBypassListVisibilityForDiagnosisEdit()) {
$this->applyCreatorOrOwnPrescriptionVisibility($query); $this->applyCreatorOrOwnPrescriptionVisibility($query);
@@ -198,6 +201,24 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
$query->whereRaw("(($po) OR ($et))"); $query->whereRaw("(($po) OR ($et))");
} }
/**
* 服务渠道:未指派传 service_channel=0 时命中「空串」或「0」(varchar)
*/
private function applyServiceChannelFilter(Query $query): void
{
$raw = $this->params['service_channel'] ?? '';
if ($raw === '' || $raw === null) {
return;
}
$v = trim((string) $raw);
if ($v === '0') {
$query->whereRaw("(TRIM(IFNULL(`service_channel`,'')) = '' OR `service_channel` = '0')");
return;
}
$query->where('service_channel', '=', $v);
}
/** /**
* 供货方式:甘草(已上传甘草药方单号)/ 自营(无甘草单号,走药房直发等) * 供货方式:甘草(已上传甘草药方单号)/ 自营(无甘草单号,走药房直发等)
* *
@@ -558,6 +579,10 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
PrescriptionOrderLogic::appendLinkedAppointmentsToListRows($lists, $this->params); PrescriptionOrderLogic::appendLinkedAppointmentsToListRows($lists, $this->params);
} }
if ((int) $this->export === ExportEnum::EXPORT) {
PrescriptionOrderLogic::appendPrescriptionOrderListExportRows($lists, $this->adminInfo);
}
return $lists; return $lists;
} }
@@ -601,6 +626,40 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
return $base; return $base;
} }
public function setFileName(): string
{
return '处方业务订单';
}
public function setExcelFields(): array
{
return [
'export_fulfillment_status_text' => '履约状态',
'export_order_time' => '创建时间',
'doctor_name' => '医生姓名',
'export_patient_name' => '患者姓名',
'export_patient_gender' => '性别',
'export_patient_age' => '年龄',
'export_patient_phone' => '手机号',
'assistant_name' => '医助名字',
'export_center_label' => '一中心还是二中心',
'export_assistant_dept' => '医助部门',
'export_channel' => '渠道',
'export_guahao_channel_source' => '自媒体渠道(挂号渠道来源)',
'export_medication_form' => '药品形态',
'export_medication_days' => '天数',
'export_amount' => '总金额',
'export_paid_amount' => '已付金额',
'export_agency_collect' => '代收金额',
'export_tracking_number' => '快递单号',
'export_supply_mode' => '甘草还是自营',
'export_gancao_prescription_cost' => '处方成本',
'export_first_visit_assistant' => '初诊医助',
'export_rx_audit_time' => '审核时间',
'export_rx_auditor' => '审核人',
];
}
/** /**
* 业绩看板侧栏专用:约诊/接诊条数,与 YejiStatsLogic::applyConsultFiltersAlignedWithAppointmentLists 同口径 * 业绩看板侧栏专用:约诊/接诊条数,与 YejiStatsLogic::applyConsultFiltersAlignedWithAppointmentLists 同口径
* doctor_appointment.status=3appointment_date 落入区间,有效医助 COALESCE(挂号.assistant_id,诊单.assistant_id))。 * doctor_appointment.status=3appointment_date 落入区间,有效医助 COALESCE(挂号.assistant_id,诊单.assistant_id))。
@@ -9,6 +9,8 @@ use app\common\service\doctor\RosterSegmentService;
use app\common\model\tcm\Diagnosis; use app\common\model\tcm\Diagnosis;
use app\common\model\tcm\DiagnosisGuahaoLog; use app\common\model\tcm\DiagnosisGuahaoLog;
use app\common\model\auth\Admin; use app\common\model\auth\Admin;
use app\common\model\auth\AdminRole;
use app\common\service\DataScope\DataScopeService;
use app\api\logic\ChatNotifyLogic; use app\api\logic\ChatNotifyLogic;
use app\adminapi\logic\tcm\PrescriptionLogic; use app\adminapi\logic\tcm\PrescriptionLogic;
use app\adminapi\logic\tcm\DiagnosisLogic; use app\adminapi\logic\tcm\DiagnosisLogic;
@@ -42,6 +44,61 @@ class AppointmentLogic extends BaseLogic
return in_array($name, self::CHANNEL_NAMES_REQUIRING_SOURCE_DETAIL, true); return in_array($name, self::CHANNEL_NAMES_REQUIRING_SOURCE_DETAIL, true);
} }
/**
* @param array<int|string, mixed> $cols Db::name('doctor_appointment')->getTableFields()
*/
private static function assertAppointmentChannelWritable(array $cols, string $chSrc): ?string
{
$hasChannelSource = in_array('channel_source', $cols, true);
$hasChannels = in_array('channels', $cols, true);
if (!$hasChannelSource && !$hasChannels) {
return '挂号表缺少渠道字段(channel_source 或 channels),无法保存渠道来源';
}
if (!$hasChannelSource && $hasChannels && $chSrc !== '' && !is_numeric($chSrc)) {
return '当前挂号表仅有数值型渠道字段 channels,无法写入该渠道;请在数据库增加 channel_source 列';
}
return null;
}
/**
* @param array<string, mixed> $row
* @param array<int|string, mixed> $cols
*/
private static function mergeAppointmentChannelIntoRow(array &$row, array $cols, string $chSrc, string $chDetail): void
{
$hasChannelSource = in_array('channel_source', $cols, true);
$hasChannelDetail = in_array('channel_source_detail', $cols, true);
$hasChannels = in_array('channels', $cols, true);
if ($hasChannelSource) {
$row['channel_source'] = $chSrc;
}
if ($hasChannelDetail) {
$row['channel_source_detail'] = $chDetail;
}
if ($hasChannels && is_numeric($chSrc)) {
$row['channels'] = (int) $chSrc;
}
}
/**
* @param array<string, mixed> $row
* @param array<int|string, mixed> $cols
*
* @return array<string, mixed>
*/
private static function filterAppointmentRowByExistingColumns(array $row, array $cols): array
{
$out = [];
foreach ($row as $k => $v) {
if (in_array((string) $k, $cols, true)) {
$out[$k] = $v;
}
}
return $out;
}
/** /**
* @notes 获取可用时间段 * @notes 获取可用时间段
* @param array $params * @param array $params
@@ -262,25 +319,49 @@ class AppointmentLogic extends BaseLogic
} }
} }
$data = [ $cols = Db::name('doctor_appointment')->getTableFields();
'patient_id' => $params['patient_id'], $cols = is_array($cols) ? $cols : [];
'assistant_id'=>$params['assistant_id'], $channelErr = self::assertAppointmentChannelWritable($cols, $chSrc);
'doctor_id' => $params['doctor_id'], if ($channelErr !== null) {
'roster_id' => 0, // 不再关联排班表 self::setError($channelErr);
Db::rollback();
return false;
}
$insert = [
'patient_id' => (int) $params['patient_id'],
'doctor_id' => (int) $params['doctor_id'],
'appointment_date' => $params['appointment_date'], 'appointment_date' => $params['appointment_date'],
'period' => $params['period'] ?? 'all',
'appointment_time' => $appointmentTime, 'appointment_time' => $appointmentTime,
'appointment_type' => $params['appointment_type'] ?? 'video', 'appointment_type' => $params['appointment_type'] ?? 'video',
'remark' => $params['remark'] ?? '', 'remark' => $params['remark'] ?? '',
// 表字段为 channel_source(与字典 type_value=channels 的 value 一致);勿再写入不存在的 channels 列
'channel_source' => $chSrc,
'channel_source_detail' => $chDetail,
'status' => 1, 'status' => 1,
'create_time' => time(), 'create_time' => time(),
'update_time' => time(), 'update_time' => time(),
]; ];
if (in_array('roster_id', $cols, true)) {
$insert['roster_id'] = 0;
}
if (in_array('assistant_id', $cols, true)) {
$insert['assistant_id'] = (int) ($params['assistant_id'] ?? 0);
}
$periodVal = $params['period'] ?? 'all';
if (in_array('period', $cols, true)) {
$insert['period'] = $periodVal;
} elseif (in_array('type', $cols, true)) {
$insert['type'] = $periodVal;
}
self::mergeAppointmentChannelIntoRow($insert, $cols, $chSrc, $chDetail);
$appointment = Appointment::create($data); $insert = self::filterAppointmentRowByExistingColumns($insert, $cols);
$newId = (int) Db::name('doctor_appointment')->insertGetId($insert);
if ($newId <= 0) {
self::setError('预约创建失败');
Db::rollback();
return false;
}
Db::commit(); Db::commit();
@@ -288,21 +369,21 @@ class AppointmentLogic extends BaseLogic
$hm = substr((string) $appointmentTime, 0, 5); $hm = substr((string) $appointmentTime, 0, 5);
$summary = sprintf( $summary = sprintf(
'挂号 #%d:医生「%s」,%s %s', '挂号 #%d:医生「%s」,%s %s',
(int) $appointment->id, $newId,
$doctorName !== '' ? $doctorName : ('ID:' . (int) $params['doctor_id']), $doctorName !== '' ? $doctorName : ('ID:' . (int) $params['doctor_id']),
(string) $params['appointment_date'], (string) $params['appointment_date'],
$hm $hm
); );
self::appendDiagnosisGuahaoLog( self::appendDiagnosisGuahaoLog(
(int) $params['patient_id'], (int) $params['patient_id'],
(int) $appointment->id, $newId,
$operatorAdminId, $operatorAdminId,
$operatorAdminInfo, $operatorAdminInfo,
'create', 'create',
$summary $summary
); );
return ['id' => $appointment->id]; return ['id' => $newId];
} catch (\Exception $e) { } catch (\Exception $e) {
Db::rollback(); Db::rollback();
self::setError($e->getMessage()); self::setError($e->getMessage());
@@ -497,11 +578,14 @@ class AppointmentLogic extends BaseLogic
// 面诊结束:通知对应医助(从诊单 assistant_id 获取) // 面诊结束:通知对应医助(从诊单 assistant_id 获取)
try { try {
$diagnosis = Diagnosis::where('id', $appointment->patient_id)->find(); $diagnosis = Diagnosis::where('id', $appointment->patient_id)->find();
if ($diagnosis && !empty($diagnosis->assistant_id)) { if ($diagnosis && !empty($diagnosis->assistant_id)) {
$assistantId = (int) $diagnosis->assistant_id; $assistantId = (int) $diagnosis->assistant_id;
$patientName = $diagnosis->patient_name ?? '患者'; $patientName = $diagnosis->patient_name ?? '患者';
$doctor = Admin::where('id', $appointment->doctor_id)->find(); $doctor = Admin::where('id', $appointment->doctor_id)->find();
$doctorName = $doctor ? $doctor->name : '医生'; $doctorName = $doctor ? $doctor->name : '医生';
ChatNotifyLogic::addConsultationCompleteNotify( ChatNotifyLogic::addConsultationCompleteNotify(
$assistantId, $assistantId,
$patientName, $patientName,
@@ -787,6 +871,368 @@ class AppointmentLogic extends BaseLogic
} }
} }
/**
* 与 AppointmentLists 一致的可见性(不含 progress_board / diag_scope_relax
*/
private static function appointmentRowManageableByAdmin(
Appointment $appointment,
?Diagnosis $diag,
int $adminId,
array $adminInfo
): bool {
$roleIds = array_map('intval', AdminRole::where('admin_id', $adminId)->column('role_id'));
if (in_array(1, $roleIds, true) && (int) $appointment->doctor_id !== $adminId) {
return false;
}
if (in_array(2, $roleIds, true)) {
$asst = $diag ? (int) $diag->assistant_id : 0;
if ($asst !== $adminId) {
return false;
}
}
if (!DataScopeService::isEnabled()) {
return true;
}
$ids = DataScopeService::getVisibleAdminIds($adminId, $adminInfo);
if ($ids === []) {
return false;
}
if ($ids === null) {
return true;
}
$docId = (int) $appointment->doctor_id;
$asstId = $diag ? (int) $diag->assistant_id : 0;
return in_array($docId, $ids, true)
|| ($asstId > 0 && in_array($asstId, $ids, true));
}
/**
* 后台编辑挂号(预约日期/时段/类型/状态/备注/医助)
*
* @param array<string, mixed> $params
*/
public static function adminEdit(array $params, int $adminId, array $adminInfo): bool
{
try {
$id = (int) ($params['id'] ?? 0);
if ($id <= 0) {
self::setError('参数错误');
return false;
}
$appointment = Appointment::findOrEmpty($id);
if ($appointment->isEmpty()) {
self::setError('预约记录不存在');
return false;
}
$diag = Diagnosis::where('id', (int) $appointment->patient_id)->whereNull('delete_time')->find();
if (!self::appointmentRowManageableByAdmin($appointment, $diag ?: null, $adminId, $adminInfo)) {
self::setError('无权限编辑');
return false;
}
$period = trim((string) ($params['period'] ?? ''));
if (!in_array($period, ['morning', 'afternoon', 'all'], true)) {
self::setError('时段无效');
return false;
}
$appointmentDate = trim((string) ($params['appointment_date'] ?? ''));
if ($appointmentDate === '') {
self::setError('预约日期不能为空');
return false;
}
$rawTime = trim((string) ($params['appointment_time'] ?? ''));
if ($rawTime === '') {
self::setError('预约时间不能为空');
return false;
}
$appointmentTime = strlen($rawTime) === 5 ? $rawTime . ':00' : $rawTime;
$status = (int) ($params['status'] ?? 0);
if ($status < 1 || $status > 4) {
self::setError('状态无效');
return false;
}
$appointmentType = trim((string) ($params['appointment_type'] ?? ''));
if (!in_array($appointmentType, ['video', 'text', 'phone'], true)) {
self::setError('预约类型无效');
return false;
}
$remark = isset($params['remark']) ? trim((string) $params['remark']) : '';
if (mb_strlen($remark) > 500) {
self::setError('备注过长');
return false;
}
$chSrc = trim((string) ($params['channel_source'] ?? ''));
if ($chSrc === '') {
self::setError('请选择渠道来源');
return false;
}
$chDetail = trim((string) ($params['channel_source_detail'] ?? ''));
$channelDictName = trim((string) (DictData::where('type_value', 'channels')
->where('value', $chSrc)
->value('name') ?? ''));
if ($channelDictName !== '' && self::channelDictNameRequiresSourceDetail($channelDictName)) {
if ($chDetail === '') {
self::setError('请填写自媒体渠道补充信息');
return false;
}
}
if (mb_strlen($chDetail) > 128) {
self::setError('渠道补充说明过长');
return false;
}
$postAssistant = array_key_exists('assistant_id', $params);
$assistantId = null;
if ($postAssistant) {
$assistantRaw = $params['assistant_id'];
if ($assistantRaw !== null && $assistantRaw !== '') {
$aid = (int) $assistantRaw;
$assistantId = $aid > 0 ? $aid : null;
}
}
$patientId = (int) $appointment->patient_id;
$doctorId = (int) $appointment->doctor_id;
if (in_array($status, [1, 4], true)) {
$patientDup = Appointment::where('patient_id', $patientId)
->where('appointment_date', $appointmentDate)
->whereIn('status', [1, 4])
->where('id', '<>', $id)
->find();
if ($patientDup) {
self::setError('该诊单在所选日期已有其他有效挂号(已预约/已过号)');
return false;
}
}
if ($status === 1) {
$slotDup = Appointment::where('doctor_id', $doctorId)
->where('appointment_date', $appointmentDate)
->where('appointment_time', $appointmentTime)
->where('status', 1)
->where('id', '<>', $id)
->find();
if ($slotDup) {
self::setError('该医生在所选时段已被占用');
return false;
}
}
$beforeDate = (string) ($appointment->appointment_date ?? '');
$beforeTimeRaw = (string) ($appointment->appointment_time ?? '');
$beforeHm = strlen($beforeTimeRaw) >= 5 ? substr($beforeTimeRaw, 0, 5) : $beforeTimeRaw;
$snap = $appointment->toArray();
$beforePeriod = (string) ($snap['period'] ?? $snap['type'] ?? '');
$beforeStatus = (int) $appointment->status;
$tblFields = Db::name('doctor_appointment')->getTableFields();
$cols = is_array($tblFields) ? $tblFields : [];
$channelErr = self::assertAppointmentChannelWritable($cols, $chSrc);
if ($channelErr !== null) {
self::setError($channelErr);
return false;
}
Db::startTrans();
$saveData = [
'appointment_date' => $appointmentDate,
'appointment_time' => $appointmentTime,
'appointment_type' => $appointmentType,
'status' => $status,
'remark' => $remark,
'update_time' => time(),
];
if (in_array('assistant_id', $cols, true) && $postAssistant) {
$saveData['assistant_id'] = $assistantId;
}
if (in_array('period', $cols, true)) {
$saveData['period'] = $period;
} elseif (in_array('type', $cols, true)) {
$saveData['type'] = $period;
}
self::mergeAppointmentChannelIntoRow($saveData, $cols, $chSrc, $chDetail);
Db::name('doctor_appointment')->where('id', $id)->update($saveData);
Db::commit();
$hm = substr($appointmentTime, 0, 5);
$summary = sprintf(
'后台修改挂号 #%d:日期 %s %s→%s %s,时段 %s→%s,状态 %d→%d',
$id,
$beforeDate,
$beforeHm,
$appointmentDate,
$hm,
$beforePeriod !== '' ? $beforePeriod : '—',
$period,
$beforeStatus,
$status
);
self::appendDiagnosisGuahaoLog($patientId, $id, $adminId, $adminInfo, 'admin_edit', $summary);
return true;
} catch (\Throwable $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
/**
* 后台批量修改挂号渠道(仅渠道号与可选补充)
*
* @param array<string, mixed> $params
* @return array{updated:int}|false
*/
public static function adminBatchEditChannel(array $params, int $adminId, array $adminInfo)
{
try {
$idsRaw = $params['ids'] ?? [];
if (!\is_array($idsRaw) || $idsRaw === []) {
self::setError('请选择要修改的挂号记录');
return false;
}
$ids = [];
foreach ($idsRaw as $raw) {
$id = (int) $raw;
if ($id > 0) {
$ids[$id] = $id;
}
}
$ids = array_values($ids);
$maxBatch = 300;
if (\count($ids) === 0) {
self::setError('预约ID无效');
return false;
}
if (\count($ids) > $maxBatch) {
self::setError('单次最多修改 ' . $maxBatch . ' 条挂号');
return false;
}
$chSrc = trim((string) ($params['channel_source'] ?? ''));
if ($chSrc === '') {
self::setError('请选择渠道来源');
return false;
}
$chDetail = isset($params['channel_source_detail']) ? trim((string) $params['channel_source_detail']) : '';
$channelDictName = trim((string) (DictData::where('type_value', 'channels')
->where('value', $chSrc)
->value('name') ?? ''));
if ($channelDictName !== '' && self::channelDictNameRequiresSourceDetail($channelDictName)) {
if ($chDetail === '') {
self::setError('请填写自媒体渠道补充信息');
return false;
}
}
if (mb_strlen($chDetail) > 128) {
self::setError('渠道补充说明过长');
return false;
}
$tblFields = Db::name('doctor_appointment')->getTableFields();
$cols = \is_array($tblFields) ? $tblFields : [];
$channelErr = self::assertAppointmentChannelWritable($cols, $chSrc);
if ($channelErr !== null) {
self::setError($channelErr);
return false;
}
Db::startTrans();
$updated = 0;
foreach ($ids as $id) {
$appointment = Appointment::findOrEmpty((int) $id);
if ($appointment->isEmpty()) {
Db::rollback();
self::setError('预约记录不存在(ID ' . $id . '');
return false;
}
$diag = Diagnosis::where('id', (int) $appointment->patient_id)->whereNull('delete_time')->find();
if (!self::appointmentRowManageableByAdmin($appointment, $diag ?: null, $adminId, $adminInfo)) {
Db::rollback();
self::setError('无权限修改挂号 #' . $id);
return false;
}
$saveData = [
'update_time' => time(),
];
self::mergeAppointmentChannelIntoRow($saveData, $cols, $chSrc, $chDetail);
$saveData = self::filterAppointmentRowByExistingColumns($saveData, $cols);
Db::name('doctor_appointment')->where('id', $id)->update($saveData);
$patientId = (int) $appointment->patient_id;
self::appendDiagnosisGuahaoLog(
$patientId,
(int) $id,
$adminId,
$adminInfo,
'admin_batch_channel',
sprintf('批量修改挂号 #%d:渠道设为 %s', $id, $chSrc !== '' ? $chSrc : '—')
);
++$updated;
}
Db::commit();
return [
'updated' => $updated,
'msg' => sprintf('已更新 %d 条挂号渠道', $updated),
];
} catch (\Throwable $e) {
Db::rollback();
self::setError($e->getMessage());
return false;
}
}
/** /**
* 诊单列表维度:记录谁在后台发起挂号 / 取消挂号(写入失败不影响主流程) * 诊单列表维度:记录谁在后台发起挂号 / 取消挂号(写入失败不影响主流程)
*/ */
@@ -5,12 +5,15 @@ declare(strict_types=1);
namespace app\adminapi\logic\stats; namespace app\adminapi\logic\stats;
use app\adminapi\logic\dept\DeptLogic; use app\adminapi\logic\dept\DeptLogic;
use app\adminapi\logic\tcm\PrescriptionOrderLogic;
use app\common\model\auth\AdminDept; use app\common\model\auth\AdminDept;
use app\common\model\tcm\Diagnosis; use app\common\model\tcm\Diagnosis;
use app\common\model\tcm\PrescriptionOrder; use app\common\model\tcm\PrescriptionOrder;
use app\common\service\DataScope\DataScopeService; use app\common\service\DataScope\DataScopeService;
use app\common\service\ExpressTrackingService;
use app\common\service\qywx\MediaChannelService; use app\common\service\qywx\MediaChannelService;
use think\db\Query; use think\db\Query;
use think\facade\Config;
use think\facade\Db; use think\facade\Db;
/** /**
@@ -183,21 +186,95 @@ class YejiStatsLogic
} }
} }
$c['adminToPrimary'] = $filtered; $c['adminToPrimary'] = $filtered;
$allowedPrimaries = array_values(array_unique(array_values($filtered))); $primariesFiltered = array_values(array_unique(array_filter(array_values($filtered), static fn (int $v): bool => $v > 0)));
if ($allowedPrimaries === []) { if ($primariesFiltered === []) {
$c['tableRowDeptIds'] = [];
return;
}
$tableRowDeptIdsSrc = array_values(array_map('intval', $c['tableRowDeptIds'] ?? []));
$deptById = isset($c['deptById']) && \is_array($c['deptById']) ? $c['deptById'] : [];
$visibleAdminIds = array_map('intval', array_keys($filtered));
/** 与折叠业绩到表格行同源:SELF/本部门 等场景下台账锚点为父「中心」、表格仅有子行为时不能用 id 精确交集 */
$keepFlip = [];
if ($tableRowDeptIdsSrc !== [] && $deptById !== [] && $visibleAdminIds !== []) {
$mapped = self::batchMapPerformanceAdminsToTableDept($visibleAdminIds, $tableRowDeptIdsSrc, $deptById);
foreach ($mapped as $__tid) {
$t = (int) $__tid;
if ($t > 0) {
$keepFlip[$t] = true;
}
}
}
if ($keepFlip === [] && $tableRowDeptIdsSrc !== [] && $deptById !== []) {
foreach ($primariesFiltered as $p) {
foreach ($tableRowDeptIdsSrc as $tid) {
if ($tid <= 0) {
continue;
}
if (self::yejiDeptOnPathBetween($tid, $p, $deptById)) {
$keepFlip[$tid] = true;
}
}
}
}
if ($keepFlip === []) {
$c['tableRowDeptIds'] = []; $c['tableRowDeptIds'] = [];
return; return;
} }
$allowFlip = array_flip($allowedPrimaries);
$c['tableRowDeptIds'] = array_values(array_filter( $c['tableRowDeptIds'] = array_values(array_filter(
$c['tableRowDeptIds'], $tableRowDeptIdsSrc,
static function (int $did) use ($allowFlip): bool { static function (int $did) use ($keepFlip): bool {
return $did > 0 && isset($allowFlip[$did]); return $did > 0 && isset($keepFlip[$did]);
} }
)); ));
} }
/**
* 任一部门是否为另一部门的上级(ancestor 祖先、descendant 沿 pid 上移可遇到 ancestor)。
*/
private static function yejiDeptIsAncestorOfDept(int $ancestorId, int $descendantId, array $deptById): bool
{
if ($ancestorId <= 0 || $descendantId <= 0) {
return false;
}
$cur = $descendantId;
for ($i = 0; $i < 64; $i++) {
if ($cur === $ancestorId) {
return true;
}
if (!isset($deptById[$cur])) {
return false;
}
$cur = (int) ($deptById[$cur]['pid'] ?? 0);
if ($cur <= 0) {
return false;
}
}
return false;
}
/**
* 表格行 dept 与台账 primary 是否应对齐到同一 subtree(任一为另一祖先)。
*
* @param array<int, array<string, mixed>> $deptById
*/
private static function yejiDeptOnPathBetween(int $tableRowDeptId, int $ledgerPrimaryDeptId, array $deptById): bool
{
if ($tableRowDeptId <= 0 || $ledgerPrimaryDeptId <= 0) {
return false;
}
if ($tableRowDeptId === $ledgerPrimaryDeptId) {
return true;
}
return self::yejiDeptIsAncestorOfDept($tableRowDeptId, $ledgerPrimaryDeptId, $deptById)
|| self::yejiDeptIsAncestorOfDept($ledgerPrimaryDeptId, $tableRowDeptId, $deptById);
}
/** /**
* 与业绩看板相同的日期、部门树、渠道、标签与数据范围上下文,供医生日统计等复用。 * 与业绩看板相同的日期、部门树、渠道、标签与数据范围上下文,供医生日统计等复用。
* *
@@ -5043,15 +5120,22 @@ class YejiStatsLogic
return null; return null;
} }
$r = is_array($row) ? $row : $row->toArray(); $r = is_array($row) ? $row : $row->toArray();
$st = (int) ($r['status'] ?? 0);
return [ return [
'status' => (int) ($r['status'] ?? 0), 'status' => $st,
'reconcile_note' => (string) ($r['reconcile_note'] ?? ''), 'reconcile_note' => (string) ($r['reconcile_note'] ?? ''),
'confirmed_admin_id' => (int) ($r['confirmed_admin_id'] ?? 0), 'confirmed_admin_id' => (int) ($r['confirmed_admin_id'] ?? 0),
'confirmed_admin_name' => (string) ($r['confirmed_admin_name'] ?? ''), 'confirmed_admin_name' => (string) ($r['confirmed_admin_name'] ?? ''),
'confirmed_at' => (int) ($r['confirmed_at'] ?? 0), 'confirmed_at' => (int) ($r['confirmed_at'] ?? 0),
'confirmed_at_text' => !empty($r['confirmed_at']) ? date('Y-m-d H:i:s', (int) $r['confirmed_at']) : '', 'confirmed_at_text' => !empty($r['confirmed_at']) ? date('Y-m-d H:i:s', (int) $r['confirmed_at']) : '',
'totals_json' => (string) ($r['totals_json'] ?? ''), 'totals_json' => (string) ($r['totals_json'] ?? ''),
'revoked_at' => (int) ($r['revoked_at'] ?? 0),
'revoked_admin_id' => (int) ($r['revoked_admin_id'] ?? 0),
'revoked_admin_name' => (string) ($r['revoked_admin_name'] ?? ''),
'revoked_at_text' => !empty($r['revoked_at']) ? date('Y-m-d H:i:s', (int) $r['revoked_at']) : '',
// 仅 status=1 锁定,禁止重复确定;status=2 已撤回可再核对/确定
'is_confirmed_locked' => $st === 1,
]; ];
} }
@@ -5071,11 +5155,54 @@ class YejiStatsLogic
} }
$prevMonthAnchor = strtotime('-1 month', $anchor); $prevMonthAnchor = strtotime('-1 month', $anchor);
$orderCreateStartTs = (int) strtotime(date('Y-m-01 00:00:00', $prevMonthAnchor)); if ($prevMonthAnchor === false) {
$orderCreateEndTs = (int) strtotime(date('Y-m-t 23:59:59', $prevMonthAnchor)); throw new \think\Exception('结算月日期无效');
}
$stRaw = trim((string) ($params['start_time'] ?? ''));
$etRaw = trim((string) ($params['end_time'] ?? ''));
$explicitOrderTimeWindow = ($stRaw !== '' && $etRaw !== '');
if ($explicitOrderTimeWindow) {
$t0 = strtotime($stRaw);
$t1 = strtotime($etRaw);
if ($t0 === false || $t1 === false) {
throw new \think\Exception('订单创建时间 start_time / end_time 无效,请与处方订单列表一致传入(如 2026-04-02 00:00:00');
}
$orderCreateStartTs = (int) $t0;
$orderCreateEndTs = (int) $t1;
if ($orderCreateStartTs > $orderCreateEndTs) {
throw new \think\Exception('订单开始时间不能晚于结束时间');
}
$orderMonthLabel = date('Y-m-d H:i:s', $orderCreateStartTs) . ' ' . date('Y-m-d H:i:s', $orderCreateEndTs);
} else {
$orderCreateStartTs = (int) strtotime(date('Y-m-01 00:00:00', $prevMonthAnchor));
$orderCreateEndTs = (int) strtotime(date('Y-m-t 23:59:59', $prevMonthAnchor));
$orderMonthLabel = date('Y-m', $prevMonthAnchor);
}
$cutoffTs = (int) strtotime(date('Y-m-07 23:59:59', $anchor)); $cutoffTs = (int) strtotime(date('Y-m-07 23:59:59', $anchor));
$orderMonthLabel = date('Y-m', $prevMonthAnchor); $fulfillmentStatus = (int) ($params['fulfillment_status'] ?? 3);
if ($fulfillmentStatus < 0) {
$fulfillmentStatus = 3;
}
if ($explicitOrderTimeWindow) {
if (array_key_exists('require_system_auto_prescription', $params)) {
$v = $params['require_system_auto_prescription'];
$requireSystemAutoEffective = $v === true || $v === 1 || $v === '1';
} else {
$requireSystemAutoEffective = false;
}
$applyListSqlVisibility = true;
$skipPhpDataScopeAttributionFilter = true;
} else {
$requireSystemAutoEffective = (bool) Config::get('project.commission_settlement.require_system_auto_prescription', true);
$applyListSqlVisibility = false;
$skipPhpDataScopeAttributionFilter = false;
}
$ctxParams = array_merge($params, [ $ctxParams = array_merge($params, [
'start_date' => date('Y-m-d', $orderCreateStartTs), 'start_date' => date('Y-m-d', $orderCreateStartTs),
'end_date' => date('Y-m-d', $orderCreateEndTs), 'end_date' => date('Y-m-d', $orderCreateEndTs),
@@ -5094,12 +5221,19 @@ class YejiStatsLogic
$rxTable = self::tableWithPrefix('tcm_prescription'); $rxTable = self::tableWithPrefix('tcm_prescription');
$att = self::sqlPerformanceAttributionAdminExpr(); $att = self::sqlPerformanceAttributionAdminExpr();
$assistAttributionRestrictSelfId = 0;
if ($viewerAdminId > 0 && PrescriptionOrderLogic::statsRestrictedToOwnAssistantPerformanceDomain($viewerAdminInfo)) {
$assistAttributionRestrictSelfId = $viewerAdminId;
}
return [ return [
'monthRaw' => $monthRaw, 'monthRaw' => $monthRaw,
'cutoffTs' => $cutoffTs, 'cutoffTs' => $cutoffTs,
'orderCreateStartTs' => $orderCreateStartTs, 'orderCreateStartTs' => $orderCreateStartTs,
'orderCreateEndTs' => $orderCreateEndTs, 'orderCreateEndTs' => $orderCreateEndTs,
'orderMonthLabel' => $orderMonthLabel, 'orderMonthLabel' => $orderMonthLabel,
'orderStartTimeText' => date('Y-m-d H:i:s', $orderCreateStartTs),
'orderEndTimeText' => date('Y-m-d H:i:s', $orderCreateEndTs),
'nextSettlementMonth' => self::commissionSettlementNextMonth($monthRaw), 'nextSettlementMonth' => self::commissionSettlementNextMonth($monthRaw),
'deptKey' => $deptKey, 'deptKey' => $deptKey,
'scopeChannelCode' => $scopeChannelCode, 'scopeChannelCode' => $scopeChannelCode,
@@ -5111,6 +5245,15 @@ class YejiStatsLogic
'diagTable' => $diagTable, 'diagTable' => $diagTable,
'rxTable' => $rxTable, 'rxTable' => $rxTable,
'att' => $att, 'att' => $att,
'assistAttributionRestrictSelfId' => $assistAttributionRestrictSelfId,
'fulfillmentStatus' => $fulfillmentStatus,
'explicitOrderTimeWindow' => $explicitOrderTimeWindow,
'requireSystemAutoEffective' => $requireSystemAutoEffective,
'applyListSqlVisibility' => $applyListSqlVisibility,
'skipPhpDataScopeAttributionFilter' => $skipPhpDataScopeAttributionFilter,
'viewerAdminId' => $viewerAdminId,
'viewerAdminInfo' => $viewerAdminInfo,
'commissionRequestParams' => $params,
]; ];
} }
@@ -5178,6 +5321,45 @@ class YejiStatsLogic
return $out; return $out;
} }
/**
* 诊单关联挂号摘要展示:优先 status=3(已完成),否则取该诊单维度下最近一条挂号(patient_id=诊单 id)。
* doctor_appointment.patient_id 与诊单主键对齐,见 DiagnosisLists。
*
* @param int[] $diagnosisIds
*
* @return array<int, array{appointment_id: int, channels: int, appointment_date: string, appointment_status: int}> diagnosis_id => 摘要
*/
private static function commissionSettlementDiagnosisLatestCompletedAppointment(array $diagnosisIds): array
{
$ids = array_values(array_unique(array_filter(array_map('intval', $diagnosisIds), static fn (int $x): bool => $x > 0)));
if ($ids === []) {
return [];
}
$rows = Db::name('doctor_appointment')
->whereIn('patient_id', $ids)
->orderRaw('`patient_id` asc, (case when `status` = 3 then 1 else 0 end) desc, `id` desc')
->field(['id', 'patient_id', 'channels', 'appointment_date', 'status'])
->select()
->toArray();
$out = [];
foreach ($rows as $r) {
$dg = (int) ($r['patient_id'] ?? 0);
if ($dg <= 0 || isset($out[$dg])) {
continue;
}
$out[$dg] = [
'appointment_id' => (int) ($r['id'] ?? 0),
'channels' => (int) ($r['channels'] ?? 0),
'appointment_date' => trim((string) ($r['appointment_date'] ?? '')),
'appointment_status' => (int) ($r['status'] ?? 0),
];
}
return $out;
}
/** /**
* 挂号字典 channelsvalue(int) => name(string)。仅取本次涉及到的 value 集合,减少 dict 全量读取。 * 挂号字典 channelsvalue(int) => name(string)。仅取本次涉及到的 value 集合,减少 dict 全量读取。
* *
@@ -5230,16 +5412,91 @@ class YejiStatsLogic
} }
/** /**
* 签收 / 尾款时间:对物流与支付关联做 GROUP BY 后 LEFT JOIN,避免 SELECT 中逐行相关子查询导致 overview 超时。 * 「本期提成 / 顺延下期」单笔判定(与 overview / orderLines / 确定结转一致)。
*
* @return array{eligible: bool, defer_code: string, defer_text: string}
*/
private static function commissionSettlementBucketEligible(int $signTs, int $payTs, int $cutoffTs): array
{
$deadlineText = date('Y-m-d H:i:s', $cutoffTs);
if ($signTs <= 0) {
return [
'eligible' => false,
'defer_code' => 'missing_sign',
'defer_text' => '库内无有效物流签收时间(轨迹未入库或运单号与物流主表不匹配)',
];
}
if ($payTs <= 0) {
return [
'eligible' => false,
'defer_code' => 'missing_pay',
'defer_text' => '无已支付关联单或未能解析尾款支付时间',
];
}
if ($signTs > $cutoffTs) {
return [
'eligible' => false,
'defer_code' => 'sign_after_cutoff',
'defer_text' => '物流签收晚于结算截止(' . $deadlineText . '',
];
}
if ($payTs > $cutoffTs) {
return [
'eligible' => false,
'defer_code' => 'pay_after_cutoff',
'defer_text' => '尾款支付(' . date('Y-m-d H:i:s', $payTs) . ')晚于结算截止(' . $deadlineText . '),仅此一项也会导致顺延',
];
}
return ['eligible' => true, 'defer_code' => '', 'defer_text' => ''];
}
/**
* 签收 / 尾款时间:对物流与支付关联做 GROUP BY LEFT JOIN。
* 签收时间不仅用 express_tracking.sign_time:历史数据或部分同步路径下 sign_time 仍为 0
* express_trace 已有「签收」语义轨迹(与 logisticsTrace 展示同源),此处用轨迹时间戳回填,避免误算为「无签收」而全部顺延。
*/ */
private static function commissionSettlementAttachExpressPayAggregates(Query $query): void private static function commissionSettlementAttachExpressPayAggregates(Query $query): void
{ {
$etTable = self::tableWithPrefix('express_tracking'); $etTable = self::tableWithPrefix('express_tracking');
$traceTable = self::tableWithPrefix('express_trace');
$linkTbl = self::tableWithPrefix('tcm_prescription_order_pay_order'); $linkTbl = self::tableWithPrefix('tcm_prescription_order_pay_order');
$payTbl = self::tableWithPrefix('order'); $payTbl = self::tableWithPrefix('order');
$etAggSql = "(SELECT et.order_id, MAX(et.sign_time) AS cs_sign_ts FROM {$etTable} et " // 单条物流记录上的「有效签收时间戳」:sign_time > 0 优先;否则签收类轨迹;再否则主表已签收/已标记签收时用最新轨迹时间兜底
. "WHERE et.order_type = 'prescription' AND et.delete_time IS NULL GROUP BY et.order_id) cs_et_sig"; $sigTraceCond = "`tr_sig`.`status_code` IN ('3','301','302','304') OR `tr_sig`.`status` LIKE '%签收%' "
. "OR `tr_sig`.`trace_context` LIKE '%签收%' OR `tr_sig`.`trace_context` LIKE '%妥投%' "
. "OR `tr_sig`.`trace_context` LIKE '%已送达%' OR `tr_sig`.`trace_context` LIKE '%本人签收%'";
$rowSignExpr = 'GREATEST('
. 'IF(IFNULL(`et`.`sign_time`, 0) > 0, `et`.`sign_time`, 0), '
. 'IFNULL((SELECT MAX(`tr_sig`.`trace_time_stamp`) FROM `' . $traceTable . '` `tr_sig` '
. 'WHERE `tr_sig`.`tracking_id` = `et`.`id` AND IFNULL(`tr_sig`.`trace_time_stamp`, 0) > 0 AND ('
. $sigTraceCond
. ')), 0), '
. 'IF((`et`.`current_state` = \'3\' OR IFNULL(`et`.`is_signed`, 0) = 1), '
. 'IFNULL((SELECT MAX(`tr_any`.`trace_time_stamp`) FROM `' . $traceTable . '` `tr_any` '
. 'WHERE `tr_any`.`tracking_id` = `et`.`id` AND IFNULL(`tr_any`.`trace_time_stamp`, 0) > 0), 0), '
. '0)'
. ')';
$poTable = self::tableWithPrefix('tcm_prescription_order');
// tracking_numberTRIM 避免空格导致匹配失败;collation 统一避免 HY000 1267
$trackingJoinOn =
'TRIM(`po`.`tracking_number`) COLLATE utf8mb4_unicode_ci = TRIM(`et`.`tracking_number`) COLLATE utf8mb4_unicode_ci';
// 与 ExpressTrackingService::getDetailByTrackingNumber 一致:按单号可查即应能统计签收;勿再依赖 et.order_type(历史数据可能空串/未回写)。
// 口径一:express_tracking.order_id 指向处方业务单(用业务单表限定,而非 et.order_type 字符串)。
// 口径二:order_id 未绑定或漂移时,用处方单运单号与物流主表 TRIM 后等值关联。
$etAggSql = '(SELECT `u`.`order_id`, MAX(`u`.`cs_row_sign`) AS `cs_sign_ts` FROM ('
. 'SELECT `et`.`order_id` AS `order_id`, ' . $rowSignExpr . ' AS `cs_row_sign` FROM `' . $etTable . '` `et` '
. 'INNER JOIN `' . $poTable . '` `po_by_id` ON `po_by_id`.`id` = `et`.`order_id` AND `po_by_id`.`delete_time` IS NULL '
. 'WHERE `et`.`delete_time` IS NULL AND IFNULL(`et`.`order_id`, 0) > 0 '
. 'UNION ALL '
. 'SELECT `po`.`id` AS `order_id`, ' . $rowSignExpr . ' AS `cs_row_sign` FROM `' . $etTable . '` `et` '
. 'INNER JOIN `' . $poTable . '` `po` ON ' . $trackingJoinOn
. " AND LENGTH(TRIM(IFNULL(`po`.`tracking_number`, ''))) > 0 "
. ' AND `po`.`delete_time` IS NULL '
. 'WHERE `et`.`delete_time` IS NULL'
. ') AS `u` GROUP BY `u`.`order_id`) `cs_et_sig`';
$payAggSql = "(SELECT l.prescription_order_id AS cs_pay_oid, " $payAggSql = "(SELECT l.prescription_order_id AS cs_pay_oid, "
. 'MAX(CASE WHEN pay.order_type IN (5, 7) THEN UNIX_TIMESTAMP(pay.payment_time) END) AS cs_pay_tail_ts, ' . 'MAX(CASE WHEN pay.order_type IN (5, 7) THEN UNIX_TIMESTAMP(pay.payment_time) END) AS cs_pay_tail_ts, '
@@ -5273,16 +5530,27 @@ class YejiStatsLogic
$rxTable = $pack['rxTable']; $rxTable = $pack['rxTable'];
$att = $pack['att']; $att = $pack['att'];
$requireSa = !empty($pack['requireSystemAutoEffective']);
$fulfillmentStatus = (int) ($pack['fulfillmentStatus'] ?? 3);
$rxJoinCond = 'rx.id = o.prescription_id AND rx.delete_time IS NULL';
if ($requireSa) {
$rxJoinCond .= ' AND IFNULL(rx.is_system_auto, 0) = 1';
}
$query = Db::name('tcm_prescription_order') $query = Db::name('tcm_prescription_order')
->alias('o') ->alias('o')
->join("{$diagTable} dg", 'dg.id = o.diagnosis_id AND dg.delete_time IS NULL', 'INNER') ->join("{$diagTable} dg", 'dg.id = o.diagnosis_id AND dg.delete_time IS NULL', 'INNER');
->join("{$rxTable} rx", 'rx.id = o.prescription_id AND rx.delete_time IS NULL AND IFNULL(rx.is_system_auto, 0) = 1', 'INNER'); if ($requireSa) {
$query->join("{$rxTable} rx", $rxJoinCond, 'INNER');
} else {
$query->join("{$rxTable} rx", $rxJoinCond, 'LEFT');
}
self::commissionSettlementAttachExpressPayAggregates($query); self::commissionSettlementAttachExpressPayAggregates($query);
$query->whereNull('o.delete_time') $query->whereNull('o.delete_time')
->where('o.fulfillment_status', 3) ->where('o.fulfillment_status', $fulfillmentStatus)
->where('o.diagnosis_id', '>', 0) ->where('o.diagnosis_id', '>', 0);
->whereRaw("({$att}) > 0", []);
$query->where(function ($qq) use ($pack) { $query->where(function ($qq) use ($pack) {
$qq->whereBetween('o.create_time', [$pack['orderCreateStartTs'], $pack['orderCreateEndTs']]); $qq->whereBetween('o.create_time', [$pack['orderCreateStartTs'], $pack['orderCreateEndTs']]);
@@ -5295,6 +5563,24 @@ class YejiStatsLogic
self::applyCommissionSettlementChannelFilter($query, $c); self::applyCommissionSettlementChannelFilter($query, $c);
$viewerAdminId = (int) ($pack['viewerAdminId'] ?? 0);
$viewerAdminInfo = $pack['viewerAdminInfo'] ?? [];
if (!empty($pack['applyListSqlVisibility']) && $viewerAdminId > 0 && \is_array($viewerAdminInfo)) {
$reqParams = $pack['commissionRequestParams'] ?? [];
PrescriptionOrderLogic::applyPrescriptionOrderListAccessForCommissionQuery(
$query,
'o',
$viewerAdminId,
$viewerAdminInfo,
\is_array($reqParams) ? $reqParams : []
);
}
$selfAid = (int) ($pack['assistAttributionRestrictSelfId'] ?? 0);
if ($selfAid > 0) {
$query->whereRaw("({$att}) = ?", [$selfAid]);
}
return $query; return $query;
} }
@@ -5303,9 +5589,9 @@ class YejiStatsLogic
* *
* 规则摘要: * 规则摘要:
* - 订单池:结算月上一自然月内创建;关联处方 is_system_auto=1(系统代开);履约已完成 fulfillment_status=3;未软删。 * - 订单池:结算月上一自然月内创建;关联处方 is_system_auto=1(系统代开);履约已完成 fulfillment_status=3;未软删。
* - 签收时间:express_tracking.order_type=prescription 下 MAX(sign_time)。 * - 签收时间:express_tracking 与处方单关联(order_id 命中业务单 **** 运单号 TRIM 后一致);sign_time / express_trace 轨迹回填,与 logisticsTrace(getDetailByTrackingNumber) 同源,不依赖 et.order_type 字符串(历史数据可能未写入)。
* - 尾款支付时间:关联支付单 status=2,优先 order_type∈(5,7),否则回退为任意已支付关联单的 MAX(payment_time) * - 尾款支付时间:关联支付单 status=2,优先 order_type∈(5,7),否则回退为任意已支付关联单的 MAX(payment_time)
* - 计入本期:签收与尾款时间均已成立且不晚于结算月 7 日 23:59:59。 * - 计入本期:签收与尾款时间均已成立,且**两者均**不晚于结算月 7 23:59:59(仅签收在截止前但尾款更晚→仍顺延)。
* - 其余已完成单计入「顺延下期」(含签收或支付缺失、或晚于截止)。 * - 其余已完成单计入「顺延下期」(含签收或支付缺失、或晚于截止)。
* *
* @param array{settlement_month?: string, dept_ids?: int[]|string, channel_code?: string, tag_id?: string} $params * @param array{settlement_month?: string, dept_ids?: int[]|string, channel_code?: string, tag_id?: string} $params
@@ -5326,6 +5612,9 @@ class YejiStatsLogic
$confirm = self::commissionSettlementGetConfirmRow($monthRaw, $pack['scopeChannelCode'], $pack['deptKey']); $confirm = self::commissionSettlementGetConfirmRow($monthRaw, $pack['scopeChannelCode'], $pack['deptKey']);
$requireSysAutoPo = !empty($pack['requireSystemAutoEffective']);
$explicitOrderTimeWindow = !empty($pack['explicitOrderTimeWindow']);
$emptyTotal = [ $emptyTotal = [
'completed_order_count' => 0, 'completed_order_count' => 0,
'completed_order_amount' => 0.0, 'completed_order_amount' => 0.0,
@@ -5337,22 +5626,30 @@ class YejiStatsLogic
]; ];
if ($tableRowDeptIds === [] || $adminToPrimary === []) { if ($tableRowDeptIds === [] || $adminToPrimary === []) {
$ruleLegacy = '订单创建月为结算月上一个月的自然月整段;或未传 start/end 时为整月时间段。签收与尾款均在结算月 7 日前完成的计入本期,否则顺延。上期「确定业绩」产生的顺延订单会并入本期。';
$ruleAligned = '传 start_time+end_time 时订单池与处方订单列表一致(创建时间与 fulfillment_status);默认含手动与系统处方,可见性与列表同源。结转与签收/尾款截止日期规则同上。';
return [ return [
'settlement_month' => $monthRaw, 'settlement_month' => $monthRaw,
'order_month' => $orderMonthLabel, 'order_month' => $orderMonthLabel,
'cutoff_end' => date('Y-m-d H:i:s', $cutoffTs), 'order_start_time' => $pack['orderStartTimeText'],
'rule_note' => '订单创建月为结算月的上一自然月;统计系统代开处方对应的已完成业务订单;签收与尾款均在结算月 7 日 24 点前完成的金额计入本期提成,否则计入顺延下期。上期「确定业绩」写入的顺延订单会在本期并入统计。', 'order_end_time' => $pack['orderEndTimeText'],
'channel_code' => $c['channelCode'], 'fulfillment_status' => $pack['fulfillmentStatus'],
'channel_name' => $c['channelInfo'] ? (string) $c['channelInfo']['channel_name'] : '', 'explicit_order_time_window' => $explicitOrderTimeWindow,
'scope_dept_ids_key' => $pack['deptKey'], 'cutoff_end' => date('Y-m-d H:i:s', $cutoffTs),
'carry_in_order_count' => 0, 'rule_note' => $explicitOrderTimeWindow ? $ruleAligned : $ruleLegacy,
'confirm' => $confirm, 'channel_code' => $c['channelCode'],
'rows' => [], 'channel_name' => $c['channelInfo'] ? (string) $c['channelInfo']['channel_name'] : '',
'assistant_rows' => [], 'scope_dept_ids_key' => $pack['deptKey'],
'doctor_rows' => [], 'carry_in_order_count' => 0,
'assistant_channel_rows' => [], 'confirm' => $confirm,
'doctor_channel_rows' => [], 'rows' => [],
'total' => $emptyTotal, 'assistant_rows' => [],
'doctor_rows' => [],
'assistant_channel_rows' => [],
'doctor_channel_rows' => [],
'total' => $emptyTotal,
'require_system_auto_prescription' => $requireSysAutoPo,
]; ];
} }
@@ -5366,6 +5663,9 @@ class YejiStatsLogic
'o.diagnosis_id', 'o.diagnosis_id',
'o.create_time', 'o.create_time',
'o.amount', 'o.amount',
'o.tracking_number',
'o.express_company',
'o.recipient_phone',
Db::raw("({$att}) AS assistant_id"), Db::raw("({$att}) AS assistant_id"),
Db::raw('IFNULL(rx.creator_id, 0) AS doctor_id'), Db::raw('IFNULL(rx.creator_id, 0) AS doctor_id'),
], $signPayFields))->select()->toArray(); ], $signPayFields))->select()->toArray();
@@ -5412,17 +5712,49 @@ class YejiStatsLogic
$doctorChDefCnt = []; $doctorChDefCnt = [];
$doctorChCarry = []; $doctorChCarry = [];
$assistScopeFlip = null;
if (!empty($c['dataScopeRestricted'])
&& isset($c['dataScopeVisibleAdminIds'])
&& $c['dataScopeVisibleAdminIds'] !== []) {
$assistScopeFlip = array_flip(array_map('intval', $c['dataScopeVisibleAdminIds']));
}
$selfOnlyAttributionAid = (int) ($pack['assistAttributionRestrictSelfId'] ?? 0);
if ($selfOnlyAttributionAid > 0) {
$assistScopeFlip = [$selfOnlyAttributionAid => true];
}
$skipPhpDs = !empty($pack['skipPhpDataScopeAttributionFilter']);
foreach ($rowsRaw as $r) { foreach ($rowsRaw as $r) {
$aid = (int) ($r['assistant_id'] ?? 0);
if (!$skipPhpDs && $assistScopeFlip !== null && ($aid <= 0 || !isset($assistScopeFlip[$aid]))) {
continue;
}
// 展示部门有勾选时:只统计可归入当前部门上下文(adminToPrimary)的医助,与部门汇总口径一致;否则「按医助下发」会混入部门外的业绩医助。
if (!empty($c['explicitDeptFilter']) && ($aid <= 0 || !isset($adminToPrimary[$aid]))) {
continue;
}
$oid = (int) ($r['id'] ?? 0); $oid = (int) ($r['id'] ?? 0);
$isCarry = $oid > 0 && isset($carryFlip[$oid]); $isCarry = $oid > 0 && isset($carryFlip[$oid]);
if ($isCarry) { if ($isCarry) {
$carryInCnt++; $carryInCnt++;
} }
$aid = (int) ($r['assistant_id'] ?? 0);
$doctorId = (int) ($r['doctor_id'] ?? 0); $doctorId = (int) ($r['doctor_id'] ?? 0);
$signTs = (int) ($r['sign_ts'] ?? 0); $signTs = (int) ($r['sign_ts'] ?? 0);
$payTs = (int) ($r['pay_ts'] ?? 0); $payTs = (int) ($r['pay_ts'] ?? 0);
if ($signTs <= 0) {
$tn0 = trim((string) ($r['tracking_number'] ?? ''));
if ($tn0 !== '') {
$signTs = ExpressTrackingService::resolveSignUnixTimeForCommission(
$tn0,
(string) ($r['express_company'] ?? 'auto'),
(string) ($r['recipient_phone'] ?? ''),
true
);
}
}
$amt = round((float) ($r['amount'] ?? 0), 2); $amt = round((float) ($r['amount'] ?? 0), 2);
$dgId = (int) ($r['diagnosis_id'] ?? 0); $dgId = (int) ($r['diagnosis_id'] ?? 0);
$apCh = (int) ($diagToApptChannel[$dgId] ?? 0); $apCh = (int) ($diagToApptChannel[$dgId] ?? 0);
@@ -5434,7 +5766,7 @@ class YejiStatsLogic
$totAgg[$aid] = ($totAgg[$aid] ?? 0.0) + $amt; $totAgg[$aid] = ($totAgg[$aid] ?? 0.0) + $amt;
$cntByAsst[$aid] = ($cntByAsst[$aid] ?? 0) + 1; $cntByAsst[$aid] = ($cntByAsst[$aid] ?? 0) + 1;
$eligible = $signTs > 0 && $payTs > 0 && $signTs <= $cutoffTs && $payTs <= $cutoffTs; $eligible = self::commissionSettlementBucketEligible($signTs, $payTs, $cutoffTs)['eligible'];
if ($eligible) { if ($eligible) {
$curAgg[$aid] = ($curAgg[$aid] ?? 0.0) + $amt; $curAgg[$aid] = ($curAgg[$aid] ?? 0.0) + $amt;
$curCntByAsst[$aid] = ($curCntByAsst[$aid] ?? 0) + 1; $curCntByAsst[$aid] = ($curCntByAsst[$aid] ?? 0) + 1;
@@ -5710,22 +6042,42 @@ class YejiStatsLogic
return ($b['completed_order_amount'] ?? 0) <=> ($a['completed_order_amount'] ?? 0); return ($b['completed_order_amount'] ?? 0) <=> ($a['completed_order_amount'] ?? 0);
}); });
if ($explicitOrderTimeWindow) {
$ruleNoteFull = '订单池与「处方订单列表」对齐:create_time 介于 start_timeend_time(与列表 between_time 同源),'
. ('fulfillment_status=' . (string) (int) ($pack['fulfillmentStatus'] ?? 3) . '。')
. ($requireSysAutoPo
? '当前已开启仅统计关联处方 is_system_auto=1(系统代开)的订单;与未限制开方类型的列表条数可能不一致。'
: '未限制仅系统代开处方(含手动),与列表在同一时段、同一状态下条数应一致(另受本页展示部门/渠道筛选影响)。')
. ' 签收与尾款时间不晚于结算月 7 日 24 点的计入「本期提成」,其余计入「顺延下期」。'
. '上期同渠道同部门范围内「确定业绩」产生的顺延订单并入本期。'
. '「按医助」「按医生」拆分按 (人 × 挂号渠道):挂号渠道取最新已完成挂号 channels;未关联展示为「未匹配挂号渠道」。';
} else {
$ruleNoteFull = ($requireSysAutoPo
? '订单创建月为结算月的上一自然月;仅统计系统代开处方(is_system_auto=1)对应的履约已完成(默认 fulfillment_status=3)业务订单。 '
: '订单创建月为结算月的上一自然月;当前配置同时包含手动与系统代开关联处方(订单池更接近列表;财务请确认口径)。 ')
. '签收时间取物流签收最大值;尾款取关联支付单已支付时间(优先尾款/全部)。签收与尾款均不晚于结算月 7 日 24 点计入「本期提成」,其余计入「顺延下期」。结转规则同上。';
}
return [ return [
'settlement_month' => $monthRaw, 'settlement_month' => $monthRaw,
'order_month' => $orderMonthLabel, 'order_month' => $orderMonthLabel,
'cutoff_end' => date('Y-m-d H:i:s', $cutoffTs), 'order_start_time' => $pack['orderStartTimeText'],
'rule_note' => '订单创建月为结算月的上一自然月;仅统计系统代开处方(is_system_auto=1)对应的履约已完成业务订单。签收时间取物流表签收时间最大值;尾款时间取关联支付单已支付记录(优先类型为尾款/全部)。签收与尾款均不晚于结算月 7 日 24 点的计入「本期提成」,其余已完成订单计入「顺延下期」。上期同渠道同部门范围内「确定业绩」产生的顺延订单,会计入本期订单池。「按医助下发」「按医生下发」按 (人 × 挂号渠道) 拆分;挂号渠道取该订单对应诊单的最新已完成挂号 doctor_appointment.channelsdict_data type_value=channels),如「复诊2」「自媒体1」等保持各自独立一行,未关联挂号统一展示为「未匹配挂号渠道」。', 'order_end_time' => $pack['orderEndTimeText'],
'channel_code' => $c['channelCode'], 'fulfillment_status' => $pack['fulfillmentStatus'],
'channel_name' => $c['channelInfo'] ? (string) $c['channelInfo']['channel_name'] : '', 'explicit_order_time_window' => $explicitOrderTimeWindow,
'scope_dept_ids_key' => $pack['deptKey'], 'cutoff_end' => date('Y-m-d H:i:s', $cutoffTs),
'carry_in_order_count' => $carryInCnt, 'rule_note' => $ruleNoteFull,
'confirm' => $confirm, 'channel_code' => $c['channelCode'],
'rows' => $rows, 'channel_name' => $c['channelInfo'] ? (string) $c['channelInfo']['channel_name'] : '',
'assistant_rows' => $assistantRows, 'scope_dept_ids_key' => $pack['deptKey'],
'doctor_rows' => $doctorRows, 'carry_in_order_count' => $carryInCnt,
'assistant_channel_rows' => $assistantChannelRows, 'confirm' => $confirm,
'doctor_channel_rows' => $doctorChannelRows, 'rows' => $rows,
'total' => [ 'assistant_rows' => $assistantRows,
'doctor_rows' => $doctorRows,
'assistant_channel_rows' => $assistantChannelRows,
'doctor_channel_rows' => $doctorChannelRows,
'total' => [
'completed_order_count' => $sumCompletedCnt, 'completed_order_count' => $sumCompletedCnt,
'completed_order_amount' => round($sumCompletedAmt, 2), 'completed_order_amount' => round($sumCompletedAmt, 2),
'current_period_count' => $sumCurCnt, 'current_period_count' => $sumCurCnt,
@@ -5734,13 +6086,14 @@ class YejiStatsLogic
'deferred_period_amount' => round($sumDefAmt, 2), 'deferred_period_amount' => round($sumDefAmt, 2),
'carry_in_order_count' => $carryInCnt, 'carry_in_order_count' => $carryInCnt,
], ],
'require_system_auto_prescription' => $requireSysAutoPo,
]; ];
} }
/** /**
* 提成核对:订单明细(分页)。 * 提成核对:订单明细(分页)。
* *
* @param array{settlement_month?: string, dept_ids?: int[]|string, channel_code?: string, page?: int|string, page_size?: int|string, bucket?: string} $params bucket: 空|current|deferred * @param array{settlement_month?: string, dept_ids?: int[]|string, channel_code?: string, page?: int|string, page_size?: int|string, bucket?: string, assistant_id?: int|string, doctor_id?: int|string, appt_channel_value?: int|string|null} $params bucket: |current|deferredappt_channel_value 与其它筛选同时传递时一并生效(含 0=未匹配挂号渠道)
* *
* @return array<string, mixed> * @return array<string, mixed>
*/ */
@@ -5756,11 +6109,31 @@ class YejiStatsLogic
$bucket = trim((string) ($params['bucket'] ?? '')); $bucket = trim((string) ($params['bucket'] ?? ''));
$page = max(1, (int) ($params['page'] ?? 1)); $page = max(1, (int) ($params['page'] ?? 1));
$pageSize = min(100, max(10, (int) ($params['page_size'] ?? 20))); $pageSize = min(100, max(10, (int) ($params['page_size'] ?? 20)));
$filterAssistantId = max(0, (int) ($params['assistant_id'] ?? 0));
$filterDoctorId = max(0, (int) ($params['doctor_id'] ?? 0));
$filterApptChannelActive = array_key_exists('appt_channel_value', $params)
&& $params['appt_channel_value'] !== null
&& $params['appt_channel_value'] !== '';
$filterApptChannelVal = $filterApptChannelActive ? (int) $params['appt_channel_value'] : null;
if ($tableRowDeptIds === [] || $adminToPrimary === []) { if ($tableRowDeptIds === [] || $adminToPrimary === []) {
return ['list' => [], 'count' => 0, 'page' => $page, 'page_size' => $pageSize]; return ['list' => [], 'count' => 0, 'page' => $page, 'page_size' => $pageSize];
} }
$cPack = $pack['c'];
$linesAssistScopeFlip = null;
if (!empty($cPack['dataScopeRestricted'])
&& isset($cPack['dataScopeVisibleAdminIds'])
&& $cPack['dataScopeVisibleAdminIds'] !== []) {
$linesAssistScopeFlip = array_flip(array_map('intval', $cPack['dataScopeVisibleAdminIds']));
}
$linesSelfAid = (int) ($pack['assistAttributionRestrictSelfId'] ?? 0);
if ($linesSelfAid > 0) {
$linesAssistScopeFlip = [$linesSelfAid => true];
}
$linesSkipPhpDs = !empty($pack['skipPhpDataScopeAttributionFilter']);
$query = self::commissionSettlementBuildFilteredOrderQuery($pack); $query = self::commissionSettlementBuildFilteredOrderQuery($pack);
$att = $pack['att']; $att = $pack['att'];
$signPayFields = self::commissionSettlementSignPayFieldRawList(); $signPayFields = self::commissionSettlementSignPayFieldRawList();
@@ -5768,6 +6141,9 @@ class YejiStatsLogic
$baseRows = $query->field(array_merge([ $baseRows = $query->field(array_merge([
'o.id', 'o.id',
'o.order_no', 'o.order_no',
'o.tracking_number',
'o.express_company',
'o.recipient_phone',
'o.diagnosis_id', 'o.diagnosis_id',
'o.create_time', 'o.create_time',
'o.amount', 'o.amount',
@@ -5775,11 +6151,59 @@ class YejiStatsLogic
Db::raw('IFNULL(rx.creator_id, 0) AS doctor_id'), Db::raw('IFNULL(rx.creator_id, 0) AS doctor_id'),
], $signPayFields))->order('o.id', 'desc')->select()->toArray(); ], $signPayFields))->order('o.id', 'desc')->select()->toArray();
$diagIdSet = [];
foreach ($baseRows as $r) {
$dg = (int) ($r['diagnosis_id'] ?? 0);
if ($dg > 0) {
$diagIdSet[$dg] = true;
}
}
$diagKeys = array_keys($diagIdSet);
$diagToApptChannel = self::commissionSettlementDiagnosisLatestApptChannel($diagKeys);
$diagToApptDetail = self::commissionSettlementDiagnosisLatestCompletedAppointment($diagKeys);
$chValsForDict = [];
foreach ($diagToApptChannel as $v) {
$chValsForDict[] = (int) $v;
}
foreach ($diagToApptDetail as $drow) {
$chValsForDict[] = (int) ($drow['channels'] ?? 0);
}
$apptChannelsDictMap = self::commissionSettlementApptChannelsDictMap($chValsForDict);
$mapped = []; $mapped = [];
foreach ($baseRows as $r) { foreach ($baseRows as $r) {
$dgId = (int) ($r['diagnosis_id'] ?? 0);
$apCh = (int) ($diagToApptChannel[$dgId] ?? 0);
if ($filterApptChannelActive && $apCh !== (int) $filterApptChannelVal) {
continue;
}
$preAid = (int) ($r['assistant_id'] ?? 0);
if (!$linesSkipPhpDs && $linesAssistScopeFlip !== null && ($preAid <= 0 || !isset($linesAssistScopeFlip[$preAid]))) {
continue;
}
if (!empty($cPack['explicitDeptFilter']) && ($preAid <= 0 || !isset($adminToPrimary[$preAid]))) {
continue;
}
$preDoctorId = (int) ($r['doctor_id'] ?? 0);
if ($filterAssistantId > 0 && $preAid !== $filterAssistantId) {
continue;
}
if ($filterDoctorId > 0 && $preDoctorId !== $filterDoctorId) {
continue;
}
$signTs = (int) ($r['sign_ts'] ?? 0); $signTs = (int) ($r['sign_ts'] ?? 0);
$payTs = (int) ($r['pay_ts'] ?? 0); $payTs = (int) ($r['pay_ts'] ?? 0);
$eligible = $signTs > 0 && $payTs > 0 && $signTs <= $cutoffTs && $payTs <= $cutoffTs; $tnForSig = trim((string) ($r['tracking_number'] ?? ''));
if ($signTs <= 0 && $tnForSig !== '') {
$signTs = ExpressTrackingService::resolveSignUnixTimeForCommission(
$tnForSig,
(string) ($r['express_company'] ?? 'auto'),
(string) ($r['recipient_phone'] ?? ''),
true
);
}
$bucketMeta = self::commissionSettlementBucketEligible($signTs, $payTs, $cutoffTs);
$eligible = $bucketMeta['eligible'];
$b = $eligible ? 'current' : 'deferred'; $b = $eligible ? 'current' : 'deferred';
if ($bucket === 'current' && $b !== 'current') { if ($bucket === 'current' && $b !== 'current') {
continue; continue;
@@ -5788,8 +6212,16 @@ class YejiStatsLogic
continue; continue;
} }
$oid = (int) ($r['id'] ?? 0); $oid = (int) ($r['id'] ?? 0);
$aid = (int) ($r['assistant_id'] ?? 0); $aid = $preAid;
$doctorId = (int) ($r['doctor_id'] ?? 0); $doctorId = $preDoctorId;
$apDet = $diagToApptDetail[$dgId] ?? null;
$chForLabel = \is_array($apDet) ? (int) ($apDet['channels'] ?? 0) : 0;
if ($chForLabel <= 0) {
$chForLabel = (int) ($diagToApptChannel[$dgId] ?? 0);
}
$apptDateRaw = \is_array($apDet) ? trim((string) ($apDet['appointment_date'] ?? '')) : '';
$apptStatus = \is_array($apDet) ? (int) ($apDet['appointment_status'] ?? 0) : 0;
$trackingNo = trim((string) ($r['tracking_number'] ?? ''));
$foldRows = [['assistant_id' => $aid, 'cnt' => 1]]; $foldRows = [['assistant_id' => $aid, 'cnt' => 1]];
$byDept = self::foldPerformanceRowsToDeptByTable($foldRows, $adminToPrimary, $tableRowDeptIds, $deptById, 'cnt'); $byDept = self::foldPerformanceRowsToDeptByTable($foldRows, $adminToPrimary, $tableRowDeptIds, $deptById, 'cnt');
$primaryDeptId = 0; $primaryDeptId = 0;
@@ -5801,6 +6233,8 @@ class YejiStatsLogic
$mapped[] = [ $mapped[] = [
'id' => $oid, 'id' => $oid,
'order_no' => (string) ($r['order_no'] ?? ''), 'order_no' => (string) ($r['order_no'] ?? ''),
'tracking_number' => $trackingNo,
'express_company' => trim((string) ($r['express_company'] ?? '')),
'diagnosis_id' => (int) ($r['diagnosis_id'] ?? 0), 'diagnosis_id' => (int) ($r['diagnosis_id'] ?? 0),
'amount' => round((float) ($r['amount'] ?? 0), 2), 'amount' => round((float) ($r['amount'] ?? 0), 2),
'create_time' => (int) ($r['create_time'] ?? 0), 'create_time' => (int) ($r['create_time'] ?? 0),
@@ -5814,9 +6248,17 @@ class YejiStatsLogic
'assistant_name' => '', 'assistant_name' => '',
'doctor_name' => '', 'doctor_name' => '',
'bucket' => $b, 'bucket' => $b,
'bucket_defer_code' => $eligible ? '' : (string) ($bucketMeta['defer_code'] ?? ''),
'bucket_defer_text' => $eligible ? '' : (string) ($bucketMeta['defer_text'] ?? ''),
'is_carry_in' => $oid > 0 && isset($carryFlip[$oid]) ? 1 : 0, 'is_carry_in' => $oid > 0 && isset($carryFlip[$oid]) ? 1 : 0,
'primary_dept_id' => $primaryDeptId, 'primary_dept_id' => $primaryDeptId,
'primary_dept_name' => $primaryDeptId > 0 ? self::formatYejiDeptRowDisplayName($primaryDeptId, $deptById) : '', 'primary_dept_name' => $primaryDeptId > 0 ? self::formatYejiDeptRowDisplayName($primaryDeptId, $deptById) : '',
'appointment_id' => \is_array($apDet) ? (int) ($apDet['appointment_id'] ?? 0) : 0,
'appointment_date' => $apptDateRaw,
'appointment_date_text' => $apptDateRaw !== '' ? $apptDateRaw : '',
'appointment_status' => $apptStatus,
'appt_channel_value' => $chForLabel,
'appt_channel_name' => self::commissionSettlementApptChannelLabel($chForLabel, $apptChannelsDictMap),
]; ];
} }
@@ -5894,7 +6336,7 @@ class YejiStatsLogic
if ($exists) { if ($exists) {
$ex = is_array($exists) ? $exists : $exists->toArray(); $ex = is_array($exists) ? $exists : $exists->toArray();
if ((int) ($ex['status'] ?? 0) === 1) { if ((int) ($ex['status'] ?? 0) === 1) {
throw new \think\Exception('已确定业绩的记录不可修改核对备注,如需更正请联系管理员处理数据'); throw new \think\Exception('当前为「已确定业绩」锁定状态,不可修改备注;请先「撤回确定」后再编辑');
} }
Db::name('commission_settlement_confirm')->where('id', (int) $ex['id'])->update([ Db::name('commission_settlement_confirm')->where('id', (int) $ex['id'])->update([
'reconcile_note' => $note, 'reconcile_note' => $note,
@@ -5960,6 +6402,9 @@ class YejiStatsLogic
$rowsRaw = $query->field(array_merge([ $rowsRaw = $query->field(array_merge([
'o.id', 'o.id',
'o.create_time', 'o.create_time',
'o.tracking_number',
'o.express_company',
'o.recipient_phone',
Db::raw("({$att}) AS assistant_id"), Db::raw("({$att}) AS assistant_id"),
], $signPayFields))->select()->toArray(); ], $signPayFields))->select()->toArray();
@@ -5967,8 +6412,18 @@ class YejiStatsLogic
foreach ($rowsRaw as $r) { foreach ($rowsRaw as $r) {
$signTs = (int) ($r['sign_ts'] ?? 0); $signTs = (int) ($r['sign_ts'] ?? 0);
$payTs = (int) ($r['pay_ts'] ?? 0); $payTs = (int) ($r['pay_ts'] ?? 0);
$eligible = $signTs > 0 && $payTs > 0 && $signTs <= $cutoffTs && $payTs <= $cutoffTs; if ($signTs <= 0) {
if (!$eligible) { $tn0 = trim((string) ($r['tracking_number'] ?? ''));
if ($tn0 !== '') {
$signTs = ExpressTrackingService::resolveSignUnixTimeForCommission(
$tn0,
(string) ($r['express_company'] ?? 'auto'),
(string) ($r['recipient_phone'] ?? ''),
true
);
}
}
if (!self::commissionSettlementBucketEligible($signTs, $payTs, $cutoffTs)['eligible']) {
$deferredIds[] = (int) ($r['id'] ?? 0); $deferredIds[] = (int) ($r['id'] ?? 0);
} }
} }
@@ -6022,6 +6477,9 @@ class YejiStatsLogic
'confirmed_admin_id' => $viewerAdminId, 'confirmed_admin_id' => $viewerAdminId,
'confirmed_admin_name' => mb_substr($adminName, 0, 64), 'confirmed_admin_name' => mb_substr($adminName, 0, 64),
'confirmed_at' => $t, 'confirmed_at' => $t,
'revoked_at' => 0,
'revoked_admin_id' => 0,
'revoked_admin_name' => '',
'update_time' => $t, 'update_time' => $t,
]); ]);
} else { } else {
@@ -6035,6 +6493,9 @@ class YejiStatsLogic
'confirmed_admin_id' => $viewerAdminId, 'confirmed_admin_id' => $viewerAdminId,
'confirmed_admin_name' => mb_substr($adminName, 0, 64), 'confirmed_admin_name' => mb_substr($adminName, 0, 64),
'confirmed_at' => $t, 'confirmed_at' => $t,
'revoked_at' => 0,
'revoked_admin_id' => 0,
'revoked_admin_name' => '',
'create_time' => $t, 'create_time' => $t,
'update_time' => $t, 'update_time' => $t,
]); ]);
@@ -6052,4 +6513,65 @@ class YejiStatsLogic
'deferred_carry_count' => count($deferredIds), 'deferred_carry_count' => count($deferredIds),
]; ];
} }
/**
* 撤回「确定本期业绩」:status 1→2,并删除本 scope 下因该次确定写入的顺延结转,避免下期重复汇入。
* status=1 时可撤回;撤回后可再次保存备注并重新确定(仍受 uk_scope 唯一行约束)。
*
* @param array{settlement_month?: string, dept_ids?: int[]|string, channel_code?: string} $params
*
* @return array{ok: bool}
*/
public static function commissionSettlementConfirmRevoke(array $params, int $viewerAdminId = 0, array $viewerAdminInfo = []): array
{
if ($viewerAdminId <= 0) {
throw new \think\Exception('未登录');
}
$pack = self::commissionSettlementResolveBasePack($params, $viewerAdminId, $viewerAdminInfo);
$tableRowDeptIds = $pack['tableRowDeptIds'];
$adminToPrimary = $pack['adminToPrimary'];
if ($tableRowDeptIds === [] || $adminToPrimary === []) {
throw new \think\Exception('当前账号无可操作的展示部门');
}
$exists = Db::name('commission_settlement_confirm')
->where('settlement_month', $pack['monthRaw'])
->where('scope_channel_code', $pack['scopeChannelCode'])
->where('scope_dept_ids_key', $pack['deptKey'])
->find();
if (!$exists) {
throw new \think\Exception('当前筛选下无核对记录,无需撤回');
}
$ex = is_array($exists) ? $exists : $exists->toArray();
if ((int) ($ex['status'] ?? 0) !== 1) {
throw new \think\Exception('仅「已确定业绩」状态可撤回;当前为草稿、或已撤回状态');
}
$adminName = (string) (Db::name('admin')->where('id', $viewerAdminId)->whereNull('delete_time')->value('name') ?: '');
$t = time();
Db::startTrans();
try {
Db::name('commission_settlement_carry')
->where('source_settlement_month', $pack['monthRaw'])
->where('scope_channel_code', $pack['scopeChannelCode'])
->where('scope_dept_ids_key', $pack['deptKey'])
->delete();
Db::name('commission_settlement_confirm')->where('id', (int) $ex['id'])->update([
'status' => 2,
'revoked_at' => $t,
'revoked_admin_id' => $viewerAdminId,
'revoked_admin_name' => mb_substr($adminName, 0, 64),
'update_time' => $t,
]);
Db::commit();
} catch (\Throwable $e) {
Db::rollback();
throw $e;
}
return ['ok' => true];
}
} }
@@ -773,6 +773,7 @@ class PrescriptionLogic
} }
$diagnosisId = (int) ($appointment->patient_id ?? 0); $diagnosisId = (int) ($appointment->patient_id ?? 0);
if ($diagnosisId <= 0) { if ($diagnosisId <= 0) {
Log::info('createSystemAutoFromCompletedAppointment: no diagnosis (patient_id), skip appt=' . $appointmentId); Log::info('createSystemAutoFromCompletedAppointment: no diagnosis (patient_id), skip appt=' . $appointmentId);
@@ -826,6 +827,18 @@ class PrescriptionLogic
$visitNo = '1K' . str_pad((string) $diagnosisId, 8, '0', STR_PAD_LEFT); $visitNo = '1K' . str_pad((string) $diagnosisId, 8, '0', STR_PAD_LEFT);
$herbs = []; $herbs = [];
/** 与手动开方一致:存一份当前诊单详情快照(/admin 开方时用 tcmDiagnosisDetail → 同源 DiagnosisLogic::detail */
$caseSnapshot = [];
try {
$snap = DiagnosisLogic::detail(['id' => $diagnosisId]);
$caseSnapshot = is_array($snap) ? $snap : [];
} catch (\Throwable $e) {
Log::warning(
'createSystemAutoFromCompletedAppointment: case_record snapshot failed diagnosis='
. $diagnosisId . ' ' . $e->getMessage()
);
}
$data = [ $data = [
'sn' => $sn, 'sn' => $sn,
@@ -850,7 +863,7 @@ class PrescriptionLogic
'tongue' => (string) ($diagnosis->tongue ?? ''), 'tongue' => (string) ($diagnosis->tongue ?? ''),
'tongue_image' => '', 'tongue_image' => '',
'clinical_diagnosis' => $clinical, 'clinical_diagnosis' => $clinical,
'case_record' => [], 'case_record' => $caseSnapshot,
'herbs' => $herbs, 'herbs' => $herbs,
'dose_count' => 1, 'dose_count' => 1,
'dose_unit' => '剂', 'dose_unit' => '剂',
@@ -876,7 +889,7 @@ class PrescriptionLogic
'creator_id' => $doctorId, 'creator_id' => $doctorId,
'assistant_id' => $assistantIdForRx, 'assistant_id' => $assistantIdForRx,
]; ];
$prescription = new Prescription(); $prescription = new Prescription();
$prescription->save($data); $prescription->save($data);
@@ -14,11 +14,13 @@ use app\common\model\tcm\Prescription;
use app\common\model\tcm\PrescriptionOrder; use app\common\model\tcm\PrescriptionOrder;
use app\common\model\tcm\PrescriptionOrderLog; use app\common\model\tcm\PrescriptionOrderLog;
use app\common\model\tcm\PrescriptionOrderPayOrder; use app\common\model\tcm\PrescriptionOrderPayOrder;
use app\common\model\dict\DictData;
use app\common\model\doctor\Appointment; use app\common\model\doctor\Appointment;
use app\common\model\auth\Admin; use app\common\model\auth\Admin;
use app\common\service\DataScope\DataScopeService; use app\common\service\DataScope\DataScopeService;
use app\common\service\ExpressTrackService; use app\common\service\ExpressTrackService;
use app\common\service\gancao\GancaoScmRecipelService; use app\common\service\gancao\GancaoScmRecipelService;
use think\db\Query;
use think\facade\Config; use think\facade\Config;
use think\facade\Db; use think\facade\Db;
use think\facade\Log; use think\facade\Log;
@@ -268,6 +270,166 @@ class PrescriptionOrderLogic
return self::roleIntersect($adminInfo, $allow); return self::roleIntersect($adminInfo, $allow);
} }
/**
* 与业务订单列表金额统计一致:命中「统计医助」角色且非农单支付审核档时,业务侧按「仅限本人关联诊单的业绩域」收口。
* 提成结算等对业绩归因 SQL 收窄时需与之对齐。
*/
public static function statsRestrictedToOwnAssistantPerformanceDomain(array $adminInfo): bool
{
if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
return false;
}
if (self::canViewOrderListStatsAllScope($adminInfo)) {
return false;
}
$assistantRid = (int) Config::get('project.prescription_order_stats_assistant_role_id', 2);
return $assistantRid > 0 && self::roleIntersect($adminInfo, [$assistantRid]);
}
/**
* 提成结算等与列表对齐:按开方医生 / 诊单医助 ∪ 订单创建人 筛选(与 PrescriptionOrderLists::applyDoctorAssistantFilters 在非业绩抽屉场景一致)。
*
* @param array<string, mixed> $params
*/
public static function applyCommissionOrderDoctorAssistantFilters(Query $query, string $alias, array $params): void
{
if (isset($params['doctor_id']) && (int) $params['doctor_id'] > 0) {
$doctorId = (int) $params['doctor_id'];
$rxTbl = (new Prescription())->getTable();
$query->whereExists(
"SELECT 1 FROM `{$rxTbl}` rx WHERE rx.`id` = `{$alias}`.`prescription_id` "
. "AND rx.`delete_time` IS NULL AND rx.`creator_id` = {$doctorId}"
);
}
if (isset($params['assistant_id']) && (int) $params['assistant_id'] > 0) {
$assistantId = (int) $params['assistant_id'];
$diagTbl = (new Diagnosis())->getTable();
$query->where(function ($q) use ($alias, $diagTbl, $assistantId): void {
$q->where("{$alias}.creator_id", $assistantId);
$q->whereOrRaw(
"EXISTS (SELECT 1 FROM `{$diagTbl}` dg WHERE dg.`id` = `{$alias}`.`diagnosis_id`"
. " AND dg.`delete_time` IS NULL AND dg.`assistant_id` = {$assistantId})"
);
});
}
}
/**
* 与处方订单列表 HasDataScopeFilter + applyCreatorOrOwnPrescriptionVisibility 等价;主业务订单别名 $alias。
*
* @param array<string, mixed> $params 可含 assistant_id(显式收窄时校验数据域)
*/
public static function applyPrescriptionOrderListAccessForCommissionQuery(
Query $query,
string $alias,
int $viewerAdminId,
array $viewerAdminInfo,
array $params = []
): void {
if ($viewerAdminId <= 0) {
return;
}
self::applyCommissionOrderDoctorAssistantFilters($query, $alias, $params);
if (self::canSeeAllPrescriptionOrders($viewerAdminInfo)) {
self::applyCommissionOrderDataScope($query, $alias, $viewerAdminId, $viewerAdminInfo);
return;
}
$rxTbl = (new Prescription())->getTable();
$diagTbl = (new Diagnosis())->getTable();
$explicitAssistant = (int) ($params['assistant_id'] ?? 0);
$allowExplicitAssistantVisibility = false;
if ($explicitAssistant > 0) {
if (!DataScopeService::isEnabled()) {
$allowExplicitAssistantVisibility = true;
} else {
$visibleIds = DataScopeService::getVisibleAdminIds($viewerAdminId, $viewerAdminInfo);
if ($visibleIds === null || in_array($explicitAssistant, $visibleIds, true)) {
$allowExplicitAssistantVisibility = true;
}
}
}
$query->where(function ($q) use (
$alias,
$rxTbl,
$diagTbl,
$viewerAdminId,
$explicitAssistant,
$allowExplicitAssistantVisibility,
$viewerAdminInfo
): void {
if (self::canViewOrdersForOwnPrescription($viewerAdminInfo)) {
$q->where(function ($qq) use ($alias, $rxTbl, $diagTbl, $viewerAdminId): void {
$qq->where("{$alias}.creator_id", $viewerAdminId);
$qq->whereOrRaw(
"EXISTS (SELECT 1 FROM `{$rxTbl}` rx WHERE rx.`id` = `{$alias}`.`prescription_id`"
. " AND rx.`delete_time` IS NULL AND rx.`creator_id` = {$viewerAdminId})"
);
$qq->whereOrRaw(
"EXISTS (SELECT 1 FROM `{$diagTbl}` dg WHERE dg.`id` = `{$alias}`.`diagnosis_id`"
. " AND dg.`delete_time` IS NULL AND dg.`assistant_id` = {$viewerAdminId})"
);
});
} else {
$q->where(function ($qq) use ($alias, $diagTbl, $viewerAdminId): void {
$qq->where("{$alias}.creator_id", $viewerAdminId);
$qq->whereOrRaw(
"EXISTS (SELECT 1 FROM `{$diagTbl}` dg WHERE dg.`id` = `{$alias}`.`diagnosis_id`"
. " AND dg.`delete_time` IS NULL AND dg.`assistant_id` = {$viewerAdminId})"
);
});
}
if ($allowExplicitAssistantVisibility) {
$q->whereOr("{$alias}.creator_id", $explicitAssistant);
$q->whereOrRaw(
"EXISTS (SELECT 1 FROM `{$diagTbl}` dg WHERE dg.`id` = `{$alias}`.`diagnosis_id`"
. " AND dg.`delete_time` IS NULL AND dg.`assistant_id` = {$explicitAssistant})"
);
}
});
self::applyCommissionOrderDataScope($query, $alias, $viewerAdminId, $viewerAdminInfo);
}
/**
* 列表数据域:创建人 ∈ 可见 或 诊单医助 ∈ 可见。
*/
private static function applyCommissionOrderDataScope(
Query $query,
string $alias,
int $viewerAdminId,
array $viewerAdminInfo
): void {
if (!DataScopeService::isEnabled()) {
return;
}
$ids = DataScopeService::getVisibleAdminIds($viewerAdminId, $viewerAdminInfo);
if ($ids === null) {
return;
}
if ($ids === []) {
$query->whereRaw('0 = 1');
return;
}
$diagTbl = (new Diagnosis())->getTable();
$inList = implode(',', array_map('intval', $ids));
$query->where(function ($q) use ($alias, $diagTbl, $inList): void {
$q->whereIn("{$alias}.creator_id", explode(',', $inList));
$q->whereOrRaw(
"EXISTS (SELECT 1 FROM `{$diagTbl}` dg WHERE dg.`id` = `{$alias}`.`diagnosis_id` "
. "AND dg.`delete_time` IS NULL AND dg.`assistant_id` IN ({$inList}))"
);
});
}
/** /**
* @param array<string,mixed> $row * @param array<string,mixed> $row
*/ */
@@ -1280,16 +1442,16 @@ class PrescriptionOrderLogic
return false; return false;
} }
// 已成功提交甘草 SCM(生成了甘草处方单号 或 submit_time>0),再改本地信息会与甘草侧不一致,禁止编辑 if ($fs === 6) {
self::$error = '已签收订单不可修改快递单号';
return false;
}
// 已成功提交甘草 SCM:仅允许更新快递单号与承运商(与甘草侧地址/药方等仍以取消流程为准)
$gcOrderNo = trim((string) $order->gancao_reciperl_order_no); $gcOrderNo = trim((string) $order->gancao_reciperl_order_no);
$gcSubmitTime = (int) $order->gancao_submit_time; $gcSubmitTime = (int) $order->gancao_submit_time;
if ($gcOrderNo !== '' || $gcSubmitTime > 0) { if ($gcOrderNo !== '' || $gcSubmitTime > 0) {
self::$error = sprintf( return self::editGancaoLogisticsOnly($order, $params, $adminId, $adminInfo);
'订单已提交甘草(处方单号:%s),不可再编辑;如需修改请先走取消流程',
$gcOrderNo !== '' ? $gcOrderNo : '—'
);
return false;
} }
$medDays = $params['medication_days'] ?? null; $medDays = $params['medication_days'] ?? null;
@@ -1423,6 +1585,47 @@ class PrescriptionOrderLogic
return $out; return $out;
} }
/**
* 甘草已提交后仅更新物流字段(tracking_number、express_company),忽略金额/地址等其它请求参数。
*
* @param array<string,mixed> $params
* @return array<string,mixed>|false
*/
private static function editGancaoLogisticsOnly(
PrescriptionOrder $order,
array $params,
int $adminId,
array $adminInfo
) {
$order->tracking_number = mb_substr(trim((string) ($params['tracking_number'] ?? '')), 0, 80);
if (array_key_exists('express_company', $params)) {
$order->express_company = self::normalizeExpressCompany($params['express_company']);
}
try {
$order->save();
} catch (\Throwable $e) {
self::$error = $e->getMessage();
return false;
}
self::writeLog(
(int) $order->id,
$adminId,
$adminInfo,
'edit',
'甘草订单已提交,仅更新快递信息(单号/承运商)'
);
$out = $order->toArray();
self::maskInternalCostIfNeeded($out, $adminInfo);
self::maskRemarkExtraIfNeeded($out, $adminInfo);
self::attachLinkedPayOrders($out);
return $out;
}
/** /**
* 确认发货:更新快递信息并将 fulfillment_status 从 2(履约中)推进到 5(已发货) * 确认发货:更新快递信息并将 fulfillment_status 从 2(履约中)推进到 5(已发货)
* *
@@ -2263,7 +2466,7 @@ class PrescriptionOrderLogic
return $out; return $out;
} }
private static function fulfillmentStatusLabel(int $fs): string public static function fulfillmentStatusLabel(int $fs): string
{ {
$m = [ $m = [
1 => '待双审通过', 1 => '待双审通过',
@@ -2283,6 +2486,301 @@ class PrescriptionOrderLogic
return $m[$fs] ?? ('状态' . (string) $fs); return $m[$fs] ?? ('状态' . (string) $fs);
} }
/**
* 导出用:诊单医助在 admin_dept 中的部门路径(多部门「;」、路径内「 / 」)
*/
public static function formatAssistantDeptPathForExport(int $assistantAdminId): string
{
if ($assistantAdminId <= 0) {
return '';
}
$deptIds = Db::name('admin_dept')->where('admin_id', $assistantAdminId)->column('dept_id');
$pathSegments = [];
foreach ($deptIds as $did) {
$p = self::buildDeptPath((int) $did);
if ($p !== '') {
$pathSegments[] = $p;
}
}
$pathSegments = array_values(array_unique($pathSegments));
return $pathSegments === [] ? '' : implode('', $pathSegments);
}
/**
* 导出用:药品形态(丸剂 / 饮片+代煎|自煎等)
*
* @param array<string, mixed> $rx
*/
public static function formatMedicationFormForExport(array $rx): string
{
$type = trim((string) ($rx['prescription_type'] ?? ''));
if ($type === '') {
return '';
}
if ($type === '饮片') {
$nd = (int) ($rx['need_decoction'] ?? 0);
return $type . ($nd === 1 ? '(代煎)' : '(自煎)');
}
return $type;
}
/**
* 导出列:挂号表渠道来源展示(与 AppointmentLists channel_source_desc 同字典口径)
*
* @param array<string, mixed> $apRow doctor_appointment 一行
* @param array<string, string> $channelNameByValue DictData channels value=>name
*/
private static function formatGuahaoChannelSourceForExport(array $apRow, array $channelNameByValue): string
{
$srcKey = trim((string) ($apRow['channel_source'] ?? ''));
if ($srcKey === '' && isset($apRow['channels']) && $apRow['channels'] !== '' && $apRow['channels'] !== null) {
$srcKey = trim((string) $apRow['channels']);
}
$label = '';
if ($srcKey !== '') {
$label = (string) ($channelNameByValue[$srcKey] ?? $channelNameByValue[(string) (int) $srcKey] ?? $srcKey);
}
$detail = trim((string) ($apRow['channel_source_detail'] ?? ''));
if ($label === '' && $detail === '') {
return '';
}
if ($detail !== '') {
return $label !== '' ? "{$label}{$detail}" : $detail;
}
return $label;
}
/**
* 挂号表渠道相关列是否存在(未加 channel_source 的老库仅查 channels 或整列留空)
*
* @return array{channel_source: bool, channel_source_detail: bool, channels: bool}
*/
private static function doctorAppointmentChannelColumnsForExport(): array
{
$out = [
'channel_source' => false,
'channel_source_detail' => false,
'channels' => false,
];
try {
$cols = Db::name('doctor_appointment')->getTableFields();
if (!is_array($cols)) {
return $out;
}
foreach (array_keys($out) as $k) {
$out[$k] = in_array($k, $cols, true);
}
} catch (\Throwable) {
// keep false
}
return $out;
}
/**
* 业务订单列表导出:写入与 PrescriptionOrderLists::setExcelFields 对应的字段(export=2 时由列表类调用)
*
* @param array<int, array<string, mixed>> $lists
*/
public static function appendPrescriptionOrderListExportRows(array &$lists, array $adminInfo): void
{
if ($lists === []) {
return;
}
$diagIds = [];
$rxIds = [];
$poIds = [];
foreach ($lists as $row) {
$poIds[] = (int) ($row['id'] ?? 0);
$d = (int) ($row['diagnosis_id'] ?? 0);
if ($d > 0) {
$diagIds[$d] = true;
}
$r = (int) ($row['prescription_id'] ?? 0);
if ($r > 0) {
$rxIds[$r] = true;
}
}
$poIds = array_values(array_filter(array_unique($poIds), static fn (int $id): bool => $id > 0));
$diagIdList = array_keys($diagIds);
$rxIdList = array_keys($rxIds);
$diagById = [];
if ($diagIdList !== []) {
$diagRows = Diagnosis::whereIn('id', $diagIdList)->whereNull('delete_time')
->field(['id', 'patient_name', 'gender', 'age', 'phone', 'assistant_id'])
->select()
->toArray();
foreach ($diagRows as $dr) {
$diagById[(int) $dr['id']] = $dr;
}
}
/** 诊单 ID => 该患者最近一条挂号(按预约日、id 倒序),用于导出「挂号渠道来源」 */
$apptChannelByDiagId = [];
$channelNameByValue = [];
$chCols = self::doctorAppointmentChannelColumnsForExport();
$needGuahaoChannel = $chCols['channel_source'] || $chCols['channels'] || $chCols['channel_source_detail'];
if ($diagIdList !== [] && $needGuahaoChannel) {
$selectFields = ['patient_id', 'appointment_date', 'id'];
if ($chCols['channel_source']) {
$selectFields[] = 'channel_source';
}
if ($chCols['channel_source_detail']) {
$selectFields[] = 'channel_source_detail';
}
if ($chCols['channels']) {
$selectFields[] = 'channels';
}
$apptRows = Appointment::whereIn('patient_id', $diagIdList)
->field($selectFields)
->order('appointment_date', 'desc')
->order('id', 'desc')
->select()
->toArray();
foreach ($apptRows as $ar) {
$p = (int) ($ar['patient_id'] ?? 0);
if ($p > 0 && !isset($apptChannelByDiagId[$p])) {
$apptChannelByDiagId[$p] = $ar;
}
}
if ($chCols['channel_source'] || $chCols['channels']) {
$channelNameByValue = DictData::where('type_value', 'channels')->column('name', 'value');
}
}
$rxById = [];
if ($rxIdList !== []) {
$rxRows = Prescription::whereIn('id', $rxIdList)->whereNull('delete_time')
->field(['id', 'prescription_type', 'need_decoction', 'dose_unit'])
->select()
->toArray();
foreach ($rxRows as $xr) {
$rxById[(int) $xr['id']] = $xr;
}
}
$logRows = PrescriptionOrderLog::whereIn('prescription_order_id', $poIds)
->whereIn('action', ['audit_rx_approve', 'audit_rx_reject', 'revoke_rx_audit'])
->field(['prescription_order_id', 'id', 'action', 'admin_name', 'create_time'])
->order('id', 'asc')
->select()
->toArray();
$auditEffectiveByPo = [];
foreach ($logRows as $lg) {
$pid = (int) ($lg['prescription_order_id'] ?? 0);
if ($pid <= 0) {
continue;
}
$act = (string) ($lg['action'] ?? '');
if ($act === 'revoke_rx_audit') {
$auditEffectiveByPo[$pid] = null;
continue;
}
if ($act === 'audit_rx_approve' || $act === 'audit_rx_reject') {
$auditEffectiveByPo[$pid] = $lg;
}
}
$assistantDeptCache = [];
foreach ($lists as &$item) {
$poId = (int) ($item['id'] ?? 0);
$fs = (int) ($item['fulfillment_status'] ?? 0);
$item['export_fulfillment_status_text'] = self::fulfillmentStatusLabel($fs);
$ct = (int) ($item['create_time'] ?? 0);
$item['export_order_time'] = $ct > 0 ? date('Y-m-d H:i:s', $ct) : '';
$diagId = (int) ($item['diagnosis_id'] ?? 0);
$dg = $diagById[$diagId] ?? null;
$item['export_patient_name'] = \is_array($dg) ? (string) ($dg['patient_name'] ?? '') : '';
if (\is_array($dg)) {
$g = (int) ($dg['gender'] ?? 0);
$item['export_patient_gender'] = $g === 1 ? '男' : '女';
$item['export_patient_age'] = (string) ($dg['age'] ?? '');
$item['export_patient_phone'] = (string) ($dg['phone'] ?? '');
$astId = (int) ($dg['assistant_id'] ?? 0);
if ($astId > 0) {
if (!isset($assistantDeptCache[$astId])) {
$assistantDeptCache[$astId] = self::formatAssistantDeptPathForExport($astId);
}
$item['export_assistant_dept'] = $assistantDeptCache[$astId];
} else {
$item['export_assistant_dept'] = '';
}
} else {
$item['export_patient_gender'] = '';
$item['export_patient_age'] = '';
$item['export_patient_phone'] = '';
$item['export_assistant_dept'] = '';
}
$rxId = (int) ($item['prescription_id'] ?? 0);
$rx = $rxById[$rxId] ?? [];
$item['export_medication_form'] = self::formatMedicationFormForExport(\is_array($rx) ? $rx : []);
$item['export_channel'] = (string) ($item['service_channel'] ?? '');
$apCh = $apptChannelByDiagId[$diagId] ?? null;
$item['export_guahao_channel_source'] = \is_array($apCh)
? self::formatGuahaoChannelSourceForExport($apCh, $channelNameByValue)
: '';
$md = $item['medication_days'] ?? null;
$item['export_medication_days'] = $md !== null && $md !== '' ? (string) $md : '';
$amt = round((float) ($item['amount'] ?? 0), 2);
$paid = round((float) ($item['linked_pay_paid_total'] ?? 0), 2);
$item['export_amount'] = number_format($amt, 2, '.', '');
$item['export_paid_amount'] = number_format($paid, 2, '.', '');
$item['export_agency_collect'] = number_format(round($amt - $paid, 2), 2, '.', '');
$item['export_tracking_number'] = (string) ($item['tracking_number'] ?? '');
$isGc = trim((string) ($item['gancao_reciperl_order_no'] ?? '')) !== '';
$item['export_supply_mode'] = $isGc ? '甘草' : '自营';
// 「处方成本」列:与列表/详情一致,取订单 internal_cost(含「测试价格」预报价写入;甘草/自营均导出)
if (self::canViewInternalCost($adminInfo)) {
$rawCost = $item['internal_cost'] ?? null;
$item['export_gancao_prescription_cost'] = $rawCost !== null && $rawCost !== ''
? number_format(round((float) $rawCost, 2), 2, '.', '')
: '';
} else {
$item['export_gancao_prescription_cost'] = '';
}
$isFu = (int) ($item['is_follow_up'] ?? 0) === 1;
$item['export_first_visit_assistant'] = $isFu ? (string) ($item['prev_staff'] ?? '') : '';
$hit = (int) ($item['po_assign_snapshot_hit'] ?? 0);
$rel = (int) ($item['po_assign_is_release'] ?? 0);
$er = (int) ($item['po_assign_to_er_center'] ?? 0);
if ($hit !== 1) {
$item['export_center_label'] = '—';
} elseif ($rel === 1) {
$item['export_center_label'] = '已释放';
} elseif ($er === 1) {
$item['export_center_label'] = '二中心';
} else {
$item['export_center_label'] = '一中心';
}
$paSt = (int) ($item['prescription_audit_status'] ?? 0);
$aud = $auditEffectiveByPo[$poId] ?? null;
if (($paSt === 1 || $paSt === 2) && \is_array($aud)) {
$at = (int) ($aud['create_time'] ?? 0);
$item['export_rx_audit_time'] = $at > 0 ? date('Y-m-d H:i:s', $at) : '';
$item['export_rx_auditor'] = (string) ($aud['admin_name'] ?? '');
} else {
$item['export_rx_audit_time'] = '';
$item['export_rx_auditor'] = '';
}
}
unset($item);
}
/** /**
* 完成订单时把关联诊单的 assistant_id 清空,让患者回到「待分配」状态 * 完成订单时把关联诊单的 assistant_id 清空,让患者回到「待分配」状态
* 仅当该患者没有其它进行中的处方订单且无指派日志时才清空,避免误覆盖 * 仅当该患者没有其它进行中的处方订单且无指派日志时才清空,避免误覆盖
@@ -21,11 +21,14 @@ class AppointmentValidate extends BaseValidate
'doctor_id' => 'require|integer', 'doctor_id' => 'require|integer',
'diagnosis_id' => 'require|integer', 'diagnosis_id' => 'require|integer',
'appointment_date' => 'require|date', 'appointment_date' => 'require|date',
'period' => 'in:morning,afternoon,all',
'appointment_time' => 'require', 'appointment_time' => 'require',
'appointment_type' => 'in:video,text,phone', 'period' => 'in:morning,afternoon,all',
'appointment_type' => 'require|in:video,text,phone',
'status' => 'require|integer|between:1,4',
'remark' => 'max:500',
'channel_source' => 'require', 'channel_source' => 'require',
'channel_source_detail' => 'max:128', 'channel_source_detail' => 'max:128',
'ids' => 'require|array',
'note_id' => 'require|integer', 'note_id' => 'require|integer',
'image_type' => 'require|in:tongue_images,report_files', 'image_type' => 'require|in:tongue_images,report_files',
'image_path' => 'require', 'image_path' => 'require',
@@ -41,11 +44,15 @@ class AppointmentValidate extends BaseValidate
'doctor_id' => '医生ID', 'doctor_id' => '医生ID',
'diagnosis_id' => '诊单ID', 'diagnosis_id' => '诊单ID',
'appointment_date' => '预约日期', 'appointment_date' => '预约日期',
'period' => '时段',
'appointment_time' => '预约时间', 'appointment_time' => '预约时间',
'period' => '时段',
'appointment_type' => '预约类型', 'appointment_type' => '预约类型',
'status' => '状态',
'remark' => '备注',
'assistant_id' => '医助',
'channel_source' => '渠道来源', 'channel_source' => '渠道来源',
'channel_source_detail' => '渠道补充说明', 'channel_source_detail' => '渠道补充说明',
'ids' => '预约ID列表',
]; ];
/** /**
@@ -125,4 +132,28 @@ class AppointmentValidate extends BaseValidate
{ {
return $this->only(['note_id', 'image_type', 'image_path']); return $this->only(['note_id', 'image_type', 'image_path']);
} }
/**
* 后台挂号编辑(消费者处方-挂号列表等)
*/
public function sceneAdminEdit()
{
return $this->only([
'id',
'appointment_date',
'appointment_time',
'period',
'appointment_type',
'status',
'remark',
'channel_source',
'channel_source_detail',
]);
}
/** 批量修改挂号渠道(权限同 doctor.appointment/edit */
public function sceneBatchEditChannel()
{
return $this->only(['ids', 'channel_source', 'channel_source_detail']);
}
} }
@@ -392,7 +392,7 @@ class GancaoCallbackController extends BaseApiController
$nu = (string) ($ext['nu'] ?? ''); $nu = (string) ($ext['nu'] ?? '');
$supplier = (string) ($ext['supplier'] ?? ''); $supplier = (string) ($ext['supplier'] ?? '');
if ($nu !== '') { if ($nu !== '' && trim((string) ($order->tracking_number ?? '')) === '') {
$order->tracking_number = mb_substr($nu, 0, 80); $order->tracking_number = mb_substr($nu, 0, 80);
} }
if ($shippingName !== '') { if ($shippingName !== '') {
@@ -0,0 +1,279 @@
<?php
declare(strict_types=1);
namespace app\command;
use app\adminapi\logic\tcm\PrescriptionOrderLogic;
use app\common\model\tcm\PrescriptionOrder;
use app\common\model\tcm\PrescriptionOrderLog;
use app\common\service\gancao\GancaoScmRecipelService;
use think\console\Command;
use think\console\Input;
use think\console\input\Option;
use think\console\Output;
/**
* 历史 internal_cost 回填:对每条业务订单调用甘草预下单(CTM_PREVIEW),
* 将返回 fee 的「药材成本 + 制作费 + 物流费」合计写入 zyt_tcm_prescription_order.internal_cost。
*
* php think tcm:backfill-internal-cost --dry-run
* php think tcm:backfill-internal-cost --limit=30 --sleep-ms=400
* php think tcm:backfill-internal-cost --order-id=123
* php think tcm:backfill-internal-cost --force
* php think tcm:backfill-internal-cost --null-or-zero --min-id=1000
* php think tcm:backfill-internal-cost --fulfillment-status=5,6,3
*
* 履约状态代码(fulfillment_status):1待双审通过 2待发货 3已完成 4已取消 5已发货 6已签收
* 7进行中 8暂不制药 9拒收 10退款 11保留药方 12制药缓发
*
* 说明:使用 root 上下文仅用于绕过后台「谁能看哪张处方/订单」校验;不落管理员登录态。
* 甘草未配置、药材无法匹配、规则拦截、缺药等会跳过并在末尾汇总。
*/
class TcmBackfillPrescriptionOrderInternalCost extends Command
{
protected function configure(): void
{
$this->setName('tcm:backfill-internal-cost')
->setDescription('批量用甘草预报价回填处方业务订单 internal_cost')
->addOption('dry-run', null, Option::VALUE_NONE, '只演练不写库')
->addOption('limit', 'l', Option::VALUE_OPTIONAL, '最多处理条数', 100)
->addOption('order-id', null, Option::VALUE_OPTIONAL, '仅处理指定 prescription_order.id', null)
->addOption('force', 'f', Option::VALUE_NONE, '覆盖已有 internal_cost(默认只填 NULL')
->addOption('null-or-zero', null, Option::VALUE_NONE, '与默认一致且同时处理 internal_cost=0 的行(仍可用 --force 覆盖任意值)')
->addOption('min-id', null, Option::VALUE_OPTIONAL, '仅 id>=该值', null)
->addOption('max-id', null, Option::VALUE_OPTIONAL, '仅 id<=该值', null)
->addOption(
'fulfillment-status',
null,
Option::VALUE_OPTIONAL,
'仅处理指定履约状态,逗号分隔数字,如 5,6,3=已发货/已签收/已完成;不传则不限',
null
)
->addOption('sleep-ms', null, Option::VALUE_OPTIONAL, '每条成功调用后休眠毫秒,减轻开放平台压力', 250)
->addOption('detail', 'd', Option::VALUE_NONE, '打印每条明细');
}
/**
* @return array{admin_id:int, root:int, name:string, role_id:int[]}
*/
private static function cliAdminInfo(): array
{
return [
'admin_id' => 0,
'root' => 1,
'name' => 'CLI-internal-cost',
'role_id' => [],
];
}
/**
* @param array<string, mixed> $fee
*/
private static function totalFeeFromPreview(array $fee): float
{
$m = (float) ($fee['m_cost'] ?? 0);
$p = (float) ($fee['proces_cost'] ?? 0);
$l = (float) ($fee['lis_cost'] ?? 0);
return round($m + $p + $l, 2);
}
/**
* 解析 CLI 传入的履约状态列表(112,与 PrescriptionOrderLogic::fulfillmentStatusLabel 一致)
*
* @return int[] 去重后的状态码;$raw 非空但解析不到合法值时返回 null 表示调用方应报错
*/
private static function parseFulfillmentStatusOption(?string $raw): ?array
{
if ($raw === null) {
return [];
}
$raw = trim($raw);
if ($raw === '') {
return [];
}
$seen = [];
foreach (explode(',', $raw) as $part) {
$n = (int) trim($part);
if ($n >= 1 && $n <= 12) {
$seen[$n] = true;
}
}
$ids = array_keys($seen);
sort($ids);
return $ids !== [] ? $ids : null;
}
protected function execute(Input $input, Output $output): int
{
$dryRun = (bool) $input->getOption('dry-run');
$verbose = (bool) $input->getOption('detail');
$force = (bool) $input->getOption('force');
$nullOrZero = (bool) $input->getOption('null-or-zero');
$limit = max(1, (int) $input->getOption('limit'));
$sleepMs = max(0, (int) $input->getOption('sleep-ms'));
$onlyOrderId = $input->getOption('order-id');
$onlyOrderId = $onlyOrderId !== null && $onlyOrderId !== '' ? (int) $onlyOrderId : null;
$minId = $input->getOption('min-id');
$minId = $minId !== null && $minId !== '' ? (int) $minId : null;
$maxId = $input->getOption('max-id');
$maxId = $maxId !== null && $maxId !== '' ? (int) $maxId : null;
$fsRaw = $input->getOption('fulfillment-status');
$fsRaw = $fsRaw !== null ? (string) $fsRaw : null;
$fulfillmentStatuses = self::parseFulfillmentStatusOption($fsRaw);
if ($fulfillmentStatuses === null) {
$output->error('--fulfillment-status 格式无效,请传入 1–12 的数字,英文逗号分隔,例如:5,6,3');
return 1;
}
$adminInfo = self::cliAdminInfo();
$adminId = 0;
$output->writeln('========================================');
$output->writeln('批量回填 internal_cost(甘草 CTM_PREVIEW');
$output->writeln('========================================');
if (!GancaoScmRecipelService::isConfigured()) {
$output->error('甘草 SCM 未配置:' . GancaoScmRecipelService::whyNotConfigured());
return 1;
}
$q = PrescriptionOrder::whereNull('delete_time')->where('prescription_id', '>', 0)->order('id', 'asc');
if ($fulfillmentStatuses !== []) {
$q->whereIn('fulfillment_status', $fulfillmentStatuses);
}
if ($onlyOrderId !== null && $onlyOrderId > 0) {
$q->where('id', $onlyOrderId);
} else {
if (!$force) {
if ($nullOrZero) {
$q->whereRaw('(internal_cost IS NULL OR internal_cost = 0)');
} else {
$q->whereNull('internal_cost');
}
}
if ($minId !== null && $minId > 0) {
$q->where('id', '>=', $minId);
}
if ($maxId !== null && $maxId > 0) {
$q->where('id', '<=', $maxId);
}
$q->limit($limit);
}
$rows = $q->field(['id', 'order_no', 'dose_count', 'medication_days', 'internal_cost', 'fulfillment_status'])->select()->toArray();
if ($rows === []) {
$output->warning('没有符合条件的订单。');
return 0;
}
$fsLabel = '';
if ($fulfillmentStatuses !== []) {
$parts = [];
foreach ($fulfillmentStatuses as $code) {
$parts[] = (string) $code . '=' . PrescriptionOrderLogic::fulfillmentStatusLabel((int) $code);
}
$fsLabel = ' fulfillment-status=[' . implode(',', $parts) . ']';
}
$output->writeln(sprintf(
'待处理 %d 条(dry-run=%s force=%s sleep-ms=%d%s',
count($rows),
$dryRun ? 'yes' : 'no',
$force ? 'yes' : 'no',
$sleepMs,
$fsLabel
));
$ok = 0;
$fail = 0;
$skipped = 0;
$reasons = [];
foreach ($rows as $row) {
$id = (int) ($row['id'] ?? 0);
if ($id <= 0) {
continue;
}
if (!$force && !$nullOrZero && $row['internal_cost'] !== null && $row['internal_cost'] !== '') {
$skipped++;
continue;
}
$params = [];
$dc = (int) ($row['dose_count'] ?? 0);
if ($dc > 0) {
$params['dose_count'] = $dc;
}
$md = $row['medication_days'] ?? null;
if ($md !== null && $md !== '' && (int) $md > 0) {
$params['medication_days'] = (int) $md;
}
$ret = PrescriptionOrderLogic::previewGancaoRecipel($id, $adminId, $adminInfo, $params);
if ($ret === false) {
$fail++;
$err = PrescriptionOrderLogic::getError();
$reasons[$err] = ($reasons[$err] ?? 0) + 1;
if ($verbose) {
$output->writeln("<error>#{$id} 失败:{$err}</error>");
}
continue;
}
$fee = is_array($ret['fee'] ?? null) ? $ret['fee'] : [];
$total = self::totalFeeFromPreview($fee);
if ($verbose) {
$ono = (string) ($row['order_no'] ?? '');
$fs = (int) ($row['fulfillment_status'] ?? 0);
$fst = PrescriptionOrderLogic::fulfillmentStatusLabel($fs);
$output->writeln(sprintf('#%d %s [%s] → internal_cost=%.2f', $id, $ono, $fst, $total));
}
if (!$dryRun) {
PrescriptionOrder::where('id', $id)->whereNull('delete_time')->update([
'internal_cost' => $total,
]);
$log = new PrescriptionOrderLog();
$log->prescription_order_id = $id;
$log->admin_id = 0;
$log->admin_name = 'CLI';
$log->action = 'cli_backfill_internal_cost';
$log->summary = mb_substr(sprintf('甘草预报价回填 internal_cost=%.2f', $total), 0, 500);
$log->create_time = time();
try {
$log->save();
} catch (\Throwable $e) {
// 忽略
}
}
$ok++;
if ($sleepMs > 0 && !$dryRun) {
usleep($sleepMs * 1000);
}
}
$output->writeln('');
$output->writeln(sprintf('完成:成功 %d,失败 %d,跳过 %d', $ok, $fail, $skipped));
if ($reasons !== []) {
$output->writeln('失败原因统计:');
foreach ($reasons as $msg => $cnt) {
$output->writeln(' [' . $cnt . 'x] ' . $msg);
}
}
return $fail > 0 ? 2 : 0;
}
}
@@ -58,6 +58,12 @@ abstract class BaseDataLists implements ListsInterface
public string $export; public string $export;
/**
* 管理端列表:在 request 就绪后写入 adminId/adminInfo(见 BaseAdminDataLists
*/
protected function initAdminIdentity(): void
{
}
public function __construct() public function __construct()
{ {
@@ -66,6 +72,8 @@ abstract class BaseDataLists implements ListsInterface
//请求参数设置 //请求参数设置
$this->request = request(); $this->request = request();
// admin 列表子类在 initExport 中可能触发 count/lists,须先于 initPage/initExport 写入身份
$this->initAdminIdentity();
$this->params = $this->request->param(); $this->params = $this->request->param();
//分页初始化 //分页初始化
@@ -862,4 +862,237 @@ class ExpressTrackingService
return $data; return $data;
} }
/**
* PrescriptionOrderLogic::logisticsTrace 一致:优先库表 express_tracking + express_trace
* 库内算不出签收时(或库无记录),可选走快递100(与详情「刷新轨迹」同源)。
*
* 提成结算 orderLines 等对 SQL JOIN 无法覆盖「仅 API 有轨迹」的运单做补算。
*
* @param bool $queryKuaidiWhenDbUnusable true 时与 logisticsTrace 完全同路径;false 时仅数据库推导(overview 大批量避免 HTTP
*/
public static function resolveSignUnixTimeForCommission(
string $trackingNumber,
string $expressCompany,
string $recipientPhone,
bool $queryKuaidiWhenDbUnusable = true
): int {
$num = trim($trackingNumber);
if ($num === '') {
return 0;
}
$cacheKey = $num . '|' . ($queryKuaidiWhenDbUnusable ? '1' : '0');
static $memo = [];
if (isset($memo[$cacheKey])) {
return $memo[$cacheKey];
}
$detail = self::loadTrackingDetailNormalized($num);
if (is_array($detail)) {
$fromDb = self::effectiveSignUnixFromTrackingDetail($detail);
if ($fromDb > 0) {
$memo[$cacheKey] = $fromDb;
return $fromDb;
}
}
if (!$queryKuaidiWhenDbUnusable) {
$memo[$cacheKey] = 0;
return 0;
}
$ec = strtolower(trim($expressCompany));
if ($ec === '') {
$ec = 'auto';
}
$api = ExpressTrackService::query($ec, $num, $recipientPhone, '');
$fromApi = self::effectiveSignUnixFromKuaidiPayload($api);
$memo[$cacheKey] = $fromApi;
return $fromApi;
}
/**
* 单号精确匹配失败时尝试 TRIM(TrackingNumber)(历史数据首尾空格)。
*
* @return array<string, mixed>|null
*/
private static function loadTrackingDetailNormalized(string $trackingNumber): ?array
{
$n = trim($trackingNumber);
if ($n === '') {
return null;
}
$first = self::getDetailByTrackingNumber($n);
if ($first !== null) {
return $first;
}
$tracking = ExpressTracking::with(['traces' => function ($query) {
$query->order('trace_time_stamp', 'desc');
}])
->whereRaw('TRIM(`tracking_number`) = ?', [$n])
->whereNull('delete_time')
->find();
if (!$tracking) {
return null;
}
$data = $tracking->toArray();
$data['traces'] = $tracking->traces ? $tracking->traces->toArray() : [];
return $data;
}
/**
* YejiStatsLogic 物流子查询中每条 express_tracking GREATEST 语义对齐。
*
* @param array<string, mixed> $detail getDetail* / loadTrackingDetailNormalized 结果
*/
private static function effectiveSignUnixFromTrackingDetail(array $detail): int
{
$a = (int) ($detail['sign_time'] ?? 0);
$traces = $detail['traces'] ?? [];
if (!is_array($traces)) {
$traces = [];
}
$b = 0;
foreach ($traces as $tr) {
if (!is_array($tr)) {
continue;
}
if (!self::dbTraceRowLooksSigned($tr)) {
continue;
}
$ts = self::traceRowToUnix($tr);
if ($ts > 0) {
$b = max($b, $ts);
}
}
$c = 0;
$stateOk = ((string) ($detail['current_state'] ?? '') === ExpressTracking::STATE_SIGNED
|| (int) ($detail['is_signed'] ?? 0) === 1);
if ($stateOk) {
foreach ($traces as $tr) {
if (!is_array($tr)) {
continue;
}
$ts = self::traceRowToUnix($tr);
if ($ts > 0) {
$c = max($c, $ts);
}
}
}
return max($a, $b, $c);
}
/**
* @param array<string, mixed> $tr express_trace
*/
private static function dbTraceRowLooksSigned(array $tr): bool
{
$code = (string) ($tr['status_code'] ?? '');
if (in_array($code, ['3', '301', '302', '304'], true)) {
return true;
}
$st = (string) ($tr['status'] ?? '');
$ctx = (string) ($tr['trace_context'] ?? '');
$hay = $st . ' ' . $ctx;
foreach (['签收', '妥投', '已送达', '本人签收'] as $k) {
if (mb_stripos($hay, $k) !== false) {
return true;
}
}
return false;
}
/**
* @param array<string, mixed> $tr
*/
private static function traceRowToUnix(array $tr): int
{
$ts = (int) ($tr['trace_time_stamp'] ?? 0);
if ($ts > 0) {
return $ts;
}
$raw = trim((string) ($tr['trace_time'] ?? ''));
if ($raw === '') {
return 0;
}
$p = strtotime($raw);
return $p !== false ? (int) $p : 0;
}
/**
* @param array<string, mixed> $api ExpressTrackService::query 返回值
*/
private static function effectiveSignUnixFromKuaidiPayload(array $api): int
{
$traces = $api['traces'] ?? [];
if (!is_array($traces) || $traces === []) {
return 0;
}
$state = (string) ($api['state'] ?? '');
$best = 0;
foreach ($traces as $row) {
if (!is_array($row)) {
continue;
}
$tstr = (string) ($row['time'] ?? '');
$ctx = (string) ($row['context'] ?? '');
$p = strtotime($tstr);
$ts = $p !== false ? (int) $p : 0;
if ($ts <= 0) {
continue;
}
$signedLike = self::plainContextLooksSigned($ctx);
if ($signedLike) {
$best = max($best, $ts);
}
}
if ($best > 0) {
return $best;
}
if ($state === '3') {
foreach ($traces as $row) {
if (!is_array($row)) {
continue;
}
$tstr = (string) ($row['time'] ?? '');
$p = strtotime($tstr);
$ts = $p !== false ? (int) $p : 0;
if ($ts > 0) {
$best = max($best, $ts);
}
}
}
return $best;
}
private static function plainContextLooksSigned(string $context): bool
{
foreach (['签收', '妥投', '已送达', '本人签收', '快件已送达'] as $k) {
if (mb_stripos($context, $k) !== false) {
return true;
}
}
return false;
}
} }
+22
View File
@@ -21,6 +21,7 @@ use app\common\enum\ExportEnum;
use app\common\lists\BaseDataLists; use app\common\lists\BaseDataLists;
use app\common\lists\ListsExcelInterface; use app\common\lists\ListsExcelInterface;
use app\common\lists\ListsExtendInterface; use app\common\lists\ListsExtendInterface;
use think\facade\Config;
use think\Response; use think\Response;
use think\response\Json; use think\response\Json;
use think\exception\HttpResponseException; use think\exception\HttpResponseException;
@@ -120,12 +121,16 @@ class JsonService
{ {
//获取导出信息 //获取导出信息
if ($lists->export == ExportEnum::INFO && $lists instanceof ListsExcelInterface) { if ($lists->export == ExportEnum::INFO && $lists instanceof ListsExcelInterface) {
self::relaxLimitsForExcelExport();
return self::data($lists->excelInfo()); return self::data($lists->excelInfo());
} }
//获取导出文件的下载链接 //获取导出文件的下载链接
if ($lists->export == ExportEnum::EXPORT && $lists instanceof ListsExcelInterface) { if ($lists->export == ExportEnum::EXPORT && $lists instanceof ListsExcelInterface) {
self::relaxLimitsForExcelExport();
$exportDownloadUrl = $lists->createExcel($lists->setExcelFields(), $lists->lists()); $exportDownloadUrl = $lists->createExcel($lists->setExcelFields(), $lists->lists());
return self::success('', ['url' => $exportDownloadUrl], 2); return self::success('', ['url' => $exportDownloadUrl], 2);
} }
@@ -141,4 +146,21 @@ class JsonService
} }
return self::success('', $data, 1, 0); return self::success('', $data, 1, 0);
} }
/**
* Excel 导出:拉数 + PhpSpreadsheet 易超过默认 max_execution_time=30
*/
private static function relaxLimitsForExcelExport(): void
{
@set_time_limit(0);
$max = Config::get('project.lists.export_max_execution_time', 600);
$max = is_numeric($max) ? (int) $max : 600;
if ($max > 0) {
@ini_set('max_execution_time', (string) $max);
}
$mem = Config::get('project.lists.export_memory_limit', '512M');
if (is_string($mem) && $mem !== '') {
@ini_set('memory_limit', $mem);
}
}
} }
+2
View File
@@ -32,6 +32,8 @@ return [
'qywx:sync-msg-archive' => 'app\\command\\QywxSyncMsgArchive', 'qywx:sync-msg-archive' => 'app\\command\\QywxSyncMsgArchive',
// 甘草订单物流路由同步(GET_TASK_ROUTE_LIST // 甘草订单物流路由同步(GET_TASK_ROUTE_LIST
'gancao:sync-logistics' => 'app\\command\\GancaoSyncLogisticsRoute', 'gancao:sync-logistics' => 'app\\command\\GancaoSyncLogisticsRoute',
// 历史 internal_cost:批量甘草预报价回填(CTM_PREVIEW
'tcm:backfill-internal-cost' => 'app\\command\\TcmBackfillPrescriptionOrderInternalCost',
// 迁移诊单图片到医生备注表 // 迁移诊单图片到医生备注表
'migrate:images-to-doctor-note' => 'app\\command\\MigrateImagesToDoctorNote', 'migrate:images-to-doctor-note' => 'app\\command\\MigrateImagesToDoctorNote',
// 诊单待办事项:扫描到点的待执行项并向创建人发送企业微信消息 // 诊单待办事项:扫描到点的待执行项并向创建人发送企业微信消息
+13
View File
@@ -47,6 +47,9 @@ return [
'lists' => [ 'lists' => [
'page_size_max' => 25000,//列表页查询数量限制(列表页每页数量、导出每页数量) 'page_size_max' => 25000,//列表页查询数量限制(列表页每页数量、导出每页数量)
'page_size' => 25, //默认每页数量 'page_size' => 25, //默认每页数量
/** Excel 导出:接口内放宽 PHP 限制(JsonService::relaxLimitsForExcelExport */
'export_max_execution_time' => 600,
'export_memory_limit' => '512M',
], ],
// 各种默认图片 // 各种默认图片
@@ -137,6 +140,16 @@ return [
'exempt_roles' => [], 'exempt_roles' => [],
], ],
/*
* 提成结算 stats.commissionSettlementYejiStatsLogic
* require_system_auto_prescriptiontrue(默认)仅系统代开口径(is_system_auto=1),常与订单列表「全部已完成」条数不一致。
* false 时与列表一致纳入手动开方单(仍需履约完成、业绩归因等其它条件)。
* .env 可选:commission_settlement.require_system_auto = 1|0 ,未配置时读本项。
*/
'commission_settlement' => [
'require_system_auto_prescription' => (int) env('commission_settlement.require_system_auto', 1) === 1,
],
// 腾讯云实时音视频(TRTC)配置 // 腾讯云实时音视频(TRTC)配置
'trtc' => [ 'trtc' => [
'sdkAppId' => (int)env('trtc.sdk_app_id', 1600127710), 'sdkAppId' => (int)env('trtc.sdk_app_id', 1600127710),
@@ -1 +1 @@
import r from"./error-B0nGVLsS.js";import{f as p,ak as i,I as m,a as e,aN as s,J as o}from"./@vue/runtime-core-C6bnekPw.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-QlpZ4wdW.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const a="/admin/assets/no_perms-jDxcYpYC.png",n={class:"error404"},W=p({__name:"403",setup(c){return(_,t)=>(i(),m("div",n,[e(r,{code:"403",title:"您的账号权限不足,请联系管理员添加权限!","show-btn":!1},{content:s(()=>[...t[0]||(t[0]=[o("div",{class:"flex justify-center"},[o("img",{class:"w-[150px] h-[150px]",src:a,alt:""})],-1)])]),_:1})]))}});export{W as default}; import r from"./error-Drkso1hy.js";import{f as p,ak as i,I as m,a as e,aN as s,J as o}from"./@vue/runtime-core-C6bnekPw.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-QlpZ4wdW.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const a="/admin/assets/no_perms-jDxcYpYC.png",n={class:"error404"},W=p({__name:"403",setup(c){return(_,t)=>(i(),m("div",n,[e(r,{code:"403",title:"您的账号权限不足,请联系管理员添加权限!","show-btn":!1},{content:s(()=>[...t[0]||(t[0]=[o("div",{class:"flex justify-center"},[o("img",{class:"w-[150px] h-[150px]",src:a,alt:""})],-1)])]),_:1})]))}});export{W as default};
@@ -1 +1 @@
import o from"./error-B0nGVLsS.js";import{f as r,ak as t,I as m,a as p}from"./@vue/runtime-core-C6bnekPw.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-QlpZ4wdW.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const i={class:"error404"},T=r({__name:"404",setup(e){return(a,s)=>(t(),m("div",i,[p(o,{code:"404",title:"哎呀,出错了!您访问的页面不存在…"})]))}});export{T as default}; import o from"./error-Drkso1hy.js";import{f as r,ak as t,I as m,a as p}from"./@vue/runtime-core-C6bnekPw.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./vue-router-QlpZ4wdW.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const i={class:"error404"},T=r({__name:"404",setup(e){return(a,s)=>(t(),m("div",i,[p(o,{code:"404",title:"哎呀,出错了!您访问的页面不存在…"})]))}});export{T as default};
@@ -1 +1 @@
import{M as x,N as y,r as I,d as $,L as C}from"./element-plus-BhlMEThZ.js";import{a8 as D}from"./@element-plus/icons-vue-ouZ25BHH.js";import{$ as L}from"./tcm-DNvmHkGt.js";import{f as T,w as P,ak as g,I as A,aP as E,G as k,aN as n,a,O as m,J as B}from"./@vue/runtime-core-C6bnekPw.js";import{Q as p}from"./@vue/shared-mAAVTE9n.js";import{y as F,n as b}from"./@vue/reactivity-DiY1c2vO.js";import{_ as M}from"./index-WGeajlD5.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const V={class:"assign-log-panel"},K=T({__name:"AssignLogPanel",props:{diagnosisId:{}},setup(h,{expose:w}){const c=h,d=b(!1),_=b([]);function v(o){const e=o.related_po_creator_name;if(e!=null&&String(e).trim()!=="")return String(e);const t=Number(o.related_po_creator_id);return Number.isFinite(t)&&t>0?`ID:${t}`:"—"}function N(o){const e=o.related_po_create_time_text;if(e!=null&&String(e).trim()!=="")return String(e);const t=Number(o.related_po_create_time);if(!Number.isFinite(t)||t<=0)return"—";const i=new Date(t*1e3);if(Number.isNaN(i.getTime()))return"—";const r=s=>String(s).padStart(2,"0");return`${i.getFullYear()}-${r(i.getMonth()+1)}-${r(i.getDate())} ${r(i.getHours())}:${r(i.getMinutes())}:${r(i.getSeconds())}`}function u(o,e){const t=e==="from"?"from_assistant_name":"to_assistant_name",i=e==="from"?"from_assistant_id":"to_assistant_id",r=o[t];if(r!=null&&String(r).trim()!==""&&String(r)!=="—")return String(r);const s=Number(o[i]);return Number.isFinite(s)&&s>0?`ID:${s}`:"—"}const f=async()=>{if(c.diagnosisId){d.value=!0;try{const o=await L({id:c.diagnosisId}),e=Array.isArray(o)?o:[];_.value=e}catch(o){console.error(o),_.value=[]}finally{d.value=!1}}};return P(()=>c.diagnosisId,()=>{f()},{immediate:!0}),w({refresh:f}),(o,e)=>{const t=y,i=$,r=I,s=x,S=C;return g(),A("div",V,[E((g(),k(s,{data:_.value,border:"",stripe:"","empty-text":"暂无指派记录"},{default:n(()=>[a(t,{label:"操作时间",width:"175",prop:"create_time_text"}),a(t,{label:"原医助","min-width":"120"},{default:n(({row:l})=>[m(p(u(l,"from")),1)]),_:1}),a(t,{label:"新医助","min-width":"120"},{default:n(({row:l})=>[m(p(u(l,"to")),1)]),_:1}),a(t,{label:"快照·业务单创建人","min-width":"130","show-overflow-tooltip":""},{default:n(({row:l})=>[m(p(v(l)),1)]),_:1}),a(t,{label:"快照·业务单创建时间",width:"190"},{header:n(()=>[e[0]||(e[0]=B("span",null,"快照·业务单创建时间",-1)),a(r,{placement:"top",content:"related_po_create_time:触发本次操作的处方业务订单 create_time;与原文助一致时表示医助创建订单时间"},{default:n(()=>[a(i,{class:"assign-log-col-hint"},{default:n(()=>[a(F(D))]),_:1})]),_:1})]),default:n(({row:l})=>[m(p(N(l)),1)]),_:1}),a(t,{label:"操作人",width:"110",prop:"operator_name"}),a(t,{label:"操作账号",width:"120",prop:"operator_account","show-overflow-tooltip":""}),a(t,{label:"IP",width:"130",prop:"ip","show-overflow-tooltip":""})]),_:1},8,["data"])),[[S,d.value]])])}}}),yt=M(K,[["__scopeId","data-v-5465d5eb"]]);export{yt as default}; import{M as x,N as y,r as I,d as C,L as $}from"./element-plus-DFTWCWyi.js";import{W as D}from"./@element-plus/icons-vue-HOEUG8sr.js";import{a0 as L}from"./tcm-FwHxrTHD.js";import{f as T,w as P,ak as g,I as A,aP as E,G as k,aN as n,a,O as m,J as B}from"./@vue/runtime-core-C6bnekPw.js";import{Q as p}from"./@vue/shared-mAAVTE9n.js";import{y as F,n as b}from"./@vue/reactivity-DiY1c2vO.js";import{_ as M}from"./index-3gMrVgPp.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const V={class:"assign-log-panel"},K=T({__name:"AssignLogPanel",props:{diagnosisId:{}},setup(h,{expose:w}){const c=h,d=b(!1),_=b([]);function v(o){const e=o.related_po_creator_name;if(e!=null&&String(e).trim()!=="")return String(e);const t=Number(o.related_po_creator_id);return Number.isFinite(t)&&t>0?`ID:${t}`:"—"}function N(o){const e=o.related_po_create_time_text;if(e!=null&&String(e).trim()!=="")return String(e);const t=Number(o.related_po_create_time);if(!Number.isFinite(t)||t<=0)return"—";const i=new Date(t*1e3);if(Number.isNaN(i.getTime()))return"—";const r=s=>String(s).padStart(2,"0");return`${i.getFullYear()}-${r(i.getMonth()+1)}-${r(i.getDate())} ${r(i.getHours())}:${r(i.getMinutes())}:${r(i.getSeconds())}`}function u(o,e){const t=e==="from"?"from_assistant_name":"to_assistant_name",i=e==="from"?"from_assistant_id":"to_assistant_id",r=o[t];if(r!=null&&String(r).trim()!==""&&String(r)!=="—")return String(r);const s=Number(o[i]);return Number.isFinite(s)&&s>0?`ID:${s}`:"—"}const f=async()=>{if(c.diagnosisId){d.value=!0;try{const o=await L({id:c.diagnosisId}),e=Array.isArray(o)?o:[];_.value=e}catch(o){console.error(o),_.value=[]}finally{d.value=!1}}};return P(()=>c.diagnosisId,()=>{f()},{immediate:!0}),w({refresh:f}),(o,e)=>{const t=y,i=C,r=I,s=x,S=$;return g(),A("div",V,[E((g(),k(s,{data:_.value,border:"",stripe:"","empty-text":"暂无指派记录"},{default:n(()=>[a(t,{label:"操作时间",width:"175",prop:"create_time_text"}),a(t,{label:"原医助","min-width":"120"},{default:n(({row:l})=>[m(p(u(l,"from")),1)]),_:1}),a(t,{label:"新医助","min-width":"120"},{default:n(({row:l})=>[m(p(u(l,"to")),1)]),_:1}),a(t,{label:"快照·业务单创建人","min-width":"130","show-overflow-tooltip":""},{default:n(({row:l})=>[m(p(v(l)),1)]),_:1}),a(t,{label:"快照·业务单创建时间",width:"190"},{header:n(()=>[e[0]||(e[0]=B("span",null,"快照·业务单创建时间",-1)),a(r,{placement:"top",content:"related_po_create_time:触发本次操作的处方业务订单 create_time;与原文助一致时表示医助创建订单时间"},{default:n(()=>[a(i,{class:"assign-log-col-hint"},{default:n(()=>[a(F(D))]),_:1})]),_:1})]),default:n(({row:l})=>[m(p(N(l)),1)]),_:1}),a(t,{label:"操作人",width:"110",prop:"operator_name"}),a(t,{label:"操作账号",width:"120",prop:"operator_account","show-overflow-tooltip":""}),a(t,{label:"IP",width:"130",prop:"ip","show-overflow-tooltip":""})]),_:1},8,["data"])),[[S,d.value]])])}}}),yt=M(K,[["__scopeId","data-v-5465d5eb"]]);export{yt as default};
@@ -1 +1 @@
import{i as L,L as T,N as V,T as D,M as z,R as M}from"./element-plus-BhlMEThZ.js";import{a7 as O}from"./tcm-DNvmHkGt.js";import{f as P,b as F,w as R,ak as a,I as n,a as i,aN as s,O as m,H as w,aP as j,G as g,F as A,J as H}from"./@vue/runtime-core-C6bnekPw.js";import{y as d,n as k}from"./@vue/reactivity-DiY1c2vO.js";import{Q as c}from"./@vue/shared-mAAVTE9n.js";import{_ as G}from"./index-WGeajlD5.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const J={class:"case-record-list"},Q={key:0,class:"mb-3 flex justify-end"},Y={key:0},q={key:1,class:"text-gray-400"},K={class:"void-detail text-xs text-gray-500 mt-1"},U=P({__name:"CaseRecordList",props:{diagnosisId:{type:Number,default:0},readOnly:{type:Boolean,default:!1}},emits:["view","openPrescription"],setup(y,{expose:x,emit:C}){const _=y,h=C,l=k([]),p=k(!1),u=async()=>{if(_.diagnosisId){p.value=!0;try{const e=await O({diagnosis_id:_.diagnosisId});l.value=Array.isArray(e)?e:[]}catch(e){console.error("获取病历记录失败:",e),l.value=[]}finally{p.value=!1}}},S=e=>{if(!e)return"";const t=new Date(e*1e3);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`},$=e=>{h("view",e)},B=()=>{h("openPrescription")};return F(()=>{u()}),R(()=>_.diagnosisId,()=>{u()}),x({refresh:u}),(e,t)=>{const b=L,r=V,v=D,E=z,N=M,I=T;return a(),n("div",J,[y.readOnly?w("",!0):(a(),n("div",Q,[i(b,{type:"primary",size:"small",onClick:B},{default:s(()=>[...t[0]||(t[0]=[m("开方",-1)])]),_:1})])),j((a(),g(E,{data:d(l),border:""},{default:s(()=>[i(r,{prop:"prescription_date",label:"就诊日期",width:"120"}),i(r,{prop:"visit_no",label:"门诊号",width:"120"}),i(r,{prop:"clinical_diagnosis",label:"临床诊断","min-width":"160","show-overflow-tooltip":""}),i(r,{label:"处方摘要","min-width":"180"},{default:s(({row:o})=>[o.herbs&&o.herbs.length?(a(),n("span",Y,c(o.herbs.slice(0,3).map(f=>`${f.name}${f.dosage}`).join("、"))+c(o.herbs.length>3?"...":""),1)):(a(),n("span",q,"—"))]),_:1}),i(r,{prop:"doctor_name",label:"医师",width:"90","show-overflow-tooltip":""}),i(r,{label:"状态",width:"140",align:"center"},{default:s(({row:o})=>[o.void_status===1?(a(),n(A,{key:0},[i(v,{type:"danger",size:"small"},{default:s(()=>[...t[1]||(t[1]=[m("已作废",-1)])]),_:1}),H("div",K,c(o.void_by_name||"—")+" "+c(S(o.void_time)),1)],64)):(a(),g(v,{key:1,type:"success",size:"small"},{default:s(()=>[...t[2]||(t[2]=[m("正常",-1)])]),_:1}))]),_:1}),i(r,{label:"操作",width:"120",fixed:"right"},{default:s(({row:o})=>[i(b,{link:"",type:"primary",size:"small",onClick:f=>$(o)},{default:s(()=>[...t[3]||(t[3]=[m(" 查看 ",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["data"])),[[I,d(p)]]),!d(p)&&d(l).length===0?(a(),g(N,{key:1,description:"暂无病历记录,开方后会自动显示",class:"mt-4"})):w("",!0)])}}}),zt=G(U,[["__scopeId","data-v-043d2738"]]);export{zt as default}; import{i as L,L as T,N as V,T as D,M as z,R as M}from"./element-plus-DFTWCWyi.js";import{a8 as O}from"./tcm-FwHxrTHD.js";import{f as P,b as F,w as R,ak as a,I as n,a as i,aN as s,O as m,H as w,aP as j,G as g,F as A,J as H}from"./@vue/runtime-core-C6bnekPw.js";import{y as d,n as k}from"./@vue/reactivity-DiY1c2vO.js";import{Q as c}from"./@vue/shared-mAAVTE9n.js";import{_ as G}from"./index-3gMrVgPp.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const J={class:"case-record-list"},Q={key:0,class:"mb-3 flex justify-end"},Y={key:0},q={key:1,class:"text-gray-400"},K={class:"void-detail text-xs text-gray-500 mt-1"},U=P({__name:"CaseRecordList",props:{diagnosisId:{type:Number,default:0},readOnly:{type:Boolean,default:!1}},emits:["view","openPrescription"],setup(y,{expose:x,emit:C}){const _=y,h=C,l=k([]),p=k(!1),u=async()=>{if(_.diagnosisId){p.value=!0;try{const e=await O({diagnosis_id:_.diagnosisId});l.value=Array.isArray(e)?e:[]}catch(e){console.error("获取病历记录失败:",e),l.value=[]}finally{p.value=!1}}},S=e=>{if(!e)return"";const t=new Date(e*1e3);return`${t.getFullYear()}-${String(t.getMonth()+1).padStart(2,"0")}-${String(t.getDate()).padStart(2,"0")} ${String(t.getHours()).padStart(2,"0")}:${String(t.getMinutes()).padStart(2,"0")}`},$=e=>{h("view",e)},B=()=>{h("openPrescription")};return F(()=>{u()}),R(()=>_.diagnosisId,()=>{u()}),x({refresh:u}),(e,t)=>{const b=L,r=V,v=D,E=z,N=M,I=T;return a(),n("div",J,[y.readOnly?w("",!0):(a(),n("div",Q,[i(b,{type:"primary",size:"small",onClick:B},{default:s(()=>[...t[0]||(t[0]=[m("开方",-1)])]),_:1})])),j((a(),g(E,{data:d(l),border:""},{default:s(()=>[i(r,{prop:"prescription_date",label:"就诊日期",width:"120"}),i(r,{prop:"visit_no",label:"门诊号",width:"120"}),i(r,{prop:"clinical_diagnosis",label:"临床诊断","min-width":"160","show-overflow-tooltip":""}),i(r,{label:"处方摘要","min-width":"180"},{default:s(({row:o})=>[o.herbs&&o.herbs.length?(a(),n("span",Y,c(o.herbs.slice(0,3).map(f=>`${f.name}${f.dosage}`).join("、"))+c(o.herbs.length>3?"...":""),1)):(a(),n("span",q,"—"))]),_:1}),i(r,{prop:"doctor_name",label:"医师",width:"90","show-overflow-tooltip":""}),i(r,{label:"状态",width:"140",align:"center"},{default:s(({row:o})=>[o.void_status===1?(a(),n(A,{key:0},[i(v,{type:"danger",size:"small"},{default:s(()=>[...t[1]||(t[1]=[m("已作废",-1)])]),_:1}),H("div",K,c(o.void_by_name||"—")+" "+c(S(o.void_time)),1)],64)):(a(),g(v,{key:1,type:"success",size:"small"},{default:s(()=>[...t[2]||(t[2]=[m("正常",-1)])]),_:1}))]),_:1}),i(r,{label:"操作",width:"120",fixed:"right"},{default:s(({row:o})=>[i(b,{link:"",type:"primary",size:"small",onClick:f=>$(o)},{default:s(()=>[...t[3]||(t[3]=[m(" 查看 ",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["data"])),[[I,d(p)]]),!d(p)&&d(l).length===0?(a(),g(N,{key:1,description:"暂无病历记录,开方后会自动显示",class:"mt-4"})):w("",!0)])}}}),zt=G(U,[["__scopeId","data-v-043d2738"]]);export{zt as default};
@@ -0,0 +1 @@
.daily-matrix[data-v-3f89758f]{padding:16px}.daily-matrix__toolbar[data-v-3f89758f]{display:flex;justify-content:space-between;gap:12px;align-items:center;flex-wrap:wrap;margin-bottom:12px}.daily-matrix__toolbar-left[data-v-3f89758f],.daily-matrix__toolbar-right[data-v-3f89758f]{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.daily-matrix__table[data-v-3f89758f],.daily-matrix__table-wrap[data-v-3f89758f]{width:100%}.daily-matrix__chart[data-v-3f89758f]{margin-top:16px;padding:16px 18px;border:1px solid var(--el-border-color-lighter);border-radius:10px;background:linear-gradient(180deg,#fff,#f8fafc)}.daily-matrix__chart-canvas[data-v-3f89758f]{height:280px;width:100%}.daily-matrix__cell[data-v-3f89758f]{min-height:32px;display:inline-flex;align-items:center;justify-content:center;gap:2px;width:100%;color:var(--el-text-color-regular)}.daily-matrix__cell.is-clickable[data-v-3f89758f]{cursor:pointer}.daily-matrix__cell.is-empty[data-v-3f89758f]{color:var(--el-text-color-placeholder)}.daily-matrix__cell.is-high[data-v-3f89758f]{color:#dc2626;font-weight:700}.daily-matrix__cell-up[data-v-3f89758f]{color:#dc2626;font-size:13px}.daily-matrix__todo[data-v-3f89758f]{margin-top:16px}.daily-matrix__section-title[data-v-3f89758f]{font-size:14px;font-weight:600;margin-bottom:12px;color:var(--el-text-color-primary)}.daily-matrix__tracking-existing[data-v-3f89758f]{width:100%;max-height:180px;overflow:auto;padding:8px 10px;border:1px solid var(--el-border-color);border-radius:6px;background:var(--el-fill-color-light)}.daily-matrix__tracking-line[data-v-3f89758f]{font-size:12.5px;line-height:1.6;color:var(--el-text-color-regular);word-break:break-word}.daily-matrix__tracking-preview[data-v-3f89758f]{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;width:100%;text-align:left}.daily-matrix__tracking-tooltip[data-v-3f89758f]{max-width:320px}.daily-matrix__tracking-tooltip-line[data-v-3f89758f]{font-size:12.5px;line-height:1.6;word-break:break-word}@media(max-width:768px){.daily-matrix[data-v-3f89758f],.daily-matrix__chart[data-v-3f89758f]{padding:12px}.daily-matrix__chart-canvas[data-v-3f89758f]{height:240px}}
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.daily-matrix[data-v-8849b23d]{padding:16px}.daily-matrix__toolbar[data-v-8849b23d]{display:flex;justify-content:space-between;gap:12px;align-items:center;flex-wrap:wrap;margin-bottom:12px}.daily-matrix__toolbar-left[data-v-8849b23d],.daily-matrix__toolbar-right[data-v-8849b23d]{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.daily-matrix__table[data-v-8849b23d],.daily-matrix__table-wrap[data-v-8849b23d]{width:100%}.daily-matrix__chart[data-v-8849b23d]{margin-top:16px;padding:16px 18px;border:1px solid var(--el-border-color-lighter);border-radius:10px;background:linear-gradient(180deg,#fff,#f8fafc)}.daily-matrix__chart-canvas[data-v-8849b23d]{height:280px;width:100%}.daily-matrix__cell[data-v-8849b23d]{min-height:32px;display:inline-flex;align-items:center;justify-content:center;gap:2px;width:100%;color:var(--el-text-color-regular)}.daily-matrix__cell.is-clickable[data-v-8849b23d]{cursor:pointer}.daily-matrix__cell.is-empty[data-v-8849b23d]{color:var(--el-text-color-placeholder)}.daily-matrix__cell.is-high[data-v-8849b23d]{color:#dc2626;font-weight:700}.daily-matrix__cell-up[data-v-8849b23d]{color:#dc2626;font-size:13px}.daily-matrix__todo[data-v-8849b23d]{margin-top:16px}.daily-matrix__section-title[data-v-8849b23d]{font-size:14px;font-weight:600;margin-bottom:12px;color:var(--el-text-color-primary)}.daily-matrix__tracking-existing[data-v-8849b23d]{width:100%;max-height:180px;overflow:auto;padding:8px 10px;border:1px solid var(--el-border-color);border-radius:6px;background:var(--el-fill-color-light)}.daily-matrix__tracking-line[data-v-8849b23d]{font-size:12.5px;line-height:1.6;color:var(--el-text-color-regular);word-break:break-word}.daily-matrix__tracking-preview[data-v-8849b23d]{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:12px;width:100%;text-align:left}.daily-matrix__tracking-tooltip[data-v-8849b23d]{max-width:320px}.daily-matrix__tracking-tooltip-line[data-v-8849b23d]{font-size:12.5px;line-height:1.6;word-break:break-word}@media(max-width:768px){.daily-matrix[data-v-8849b23d],.daily-matrix__chart[data-v-8849b23d]{padding:12px}.daily-matrix__chart-canvas[data-v-8849b23d]{height:240px}}
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
import{R as W,v as Z,d as q,a as K}from"./element-plus-BhlMEThZ.js";import{_ as Y}from"./picker-ChJwUkIc.js";import{e as ee,c as te,i as S,_ as ie}from"./index-WGeajlD5.js";import{s as A}from"./@vue/runtime-dom-DDAG46FW.js";import{b as B,G as se}from"./@element-plus/icons-vue-ouZ25BHH.js";import{d as oe,a as R}from"./patient-BG1gG9yF.js";import{f as ne,w as re,ak as i,I as n,a as l,aN as c,J as a,H as d,F as v,ap as k,G as I}from"./@vue/runtime-core-C6bnekPw.js";import{n as w,y as C}from"./@vue/reactivity-DiY1c2vO.js";import{Q as z}from"./@vue/shared-mAAVTE9n.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./lodash-D3kF6u-c.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-CgbeKU6K.js";import"./index-B5BEu-2e.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./index-EG3kZkys.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./usePaging-VsbTxSU0.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const le={class:"note-timeline-wrap"},ae={key:0,class:"timeline-actions"},me={class:"upload-trigger"},de={class:"upload-trigger"},pe={key:1,class:"note-timeline"},ce={class:"timeline-date"},ue={class:"timeline-body"},ge={key:0,class:"timeline-content"},_e={key:1,class:"timeline-images"},fe={key:2,class:"timeline-images"},ve={key:0,class:"thumb-wrap"},he={key:1,class:"file-wrap"},ye=["href","title"],ke={class:"file-name"},T=8e3,Ie=ne({__name:"NoteTimeline",props:{notes:{},diagnosisId:{},readonly:{type:Boolean}},emits:["refresh"],setup(m,{emit:G}){const u=m,b=G,L=ee(),g=t=>L.getImageUrl(t),x=w([]),E=w([]),_=w(0),f=w(0),$=["jpg","jpeg","png","gif","bmp","webp","svg"],N=t=>{var s;const e=((s=t.split(".").pop())==null?void 0:s.toLowerCase().split("?")[0])||"";return $.includes(e)},M=t=>{var s;const e=t.split("/");return decodeURIComponent(((s=e[e.length-1])==null?void 0:s.split("?")[0])||"文件")},j=t=>t.filter(N).map(g),O=(t,e)=>{const s=t.filter(N),h=t[e];return s.indexOf(h)},X=t=>t?t.split(` import{R as W,v as Z,d as q,a as K}from"./element-plus-DFTWCWyi.js";import{_ as Y}from"./picker-C4e9dvGe.js";import{e as ee,c as te,i as S,_ as ie}from"./index-3gMrVgPp.js";import{s as A}from"./@vue/runtime-dom-DDAG46FW.js";import{b as B,G as se}from"./@element-plus/icons-vue-HOEUG8sr.js";import{d as oe,a as R}from"./patient-5oeg5KQT.js";import{f as ne,w as re,ak as i,I as n,a as l,aN as c,J as a,H as d,F as v,ap as k,G as I}from"./@vue/runtime-core-C6bnekPw.js";import{n as w,y as C}from"./@vue/reactivity-DiY1c2vO.js";import{Q as z}from"./@vue/shared-mAAVTE9n.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./lodash-D3kF6u-c.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-CICkVesR.js";import"./index-B8fzRqRH.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./index-DZ0cpdk5.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./usePaging-VsbTxSU0.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const le={class:"note-timeline-wrap"},ae={key:0,class:"timeline-actions"},me={class:"upload-trigger"},de={class:"upload-trigger"},pe={key:1,class:"note-timeline"},ce={class:"timeline-date"},ue={class:"timeline-body"},ge={key:0,class:"timeline-content"},_e={key:1,class:"timeline-images"},fe={key:2,class:"timeline-images"},ve={key:0,class:"thumb-wrap"},he={key:1,class:"file-wrap"},ye=["href","title"],ke={class:"file-name"},T=8e3,Ie=ne({__name:"NoteTimeline",props:{notes:{},diagnosisId:{},readonly:{type:Boolean}},emits:["refresh"],setup(m,{emit:G}){const u=m,b=G,L=ee(),g=t=>L.getImageUrl(t),x=w([]),E=w([]),_=w(0),f=w(0),$=["jpg","jpeg","png","gif","bmp","webp","svg"],N=t=>{var s;const e=((s=t.split(".").pop())==null?void 0:s.toLowerCase().split("?")[0])||"";return $.includes(e)},M=t=>{var s;const e=t.split("/");return decodeURIComponent(((s=e[e.length-1])==null?void 0:s.split("?")[0])||"文件")},j=t=>t.filter(N).map(g),O=(t,e)=>{const s=t.filter(N),h=t[e];return s.indexOf(h)},X=t=>t?t.split(`
`).filter(Boolean):[],H=t=>{if(!u.diagnosisId)return;const e=Array.isArray(t)?t:[t];if(e.length<=_.value){_.value=e.length;return}const s=e.slice(_.value);_.value=e.length,s.length>0&&R({diagnosis_id:u.diagnosisId,tongue_images:s}).then(()=>{S.msgSuccess("舌苔照片已添加"),b("refresh")})},J=t=>{if(!u.diagnosisId)return;const e=Array.isArray(t)?t:[t];if(e.length<=f.value){f.value=e.length;return}const s=e.slice(f.value);f.value=e.length,s.length>0&&R({diagnosis_id:u.diagnosisId,report_files:s}).then(()=>{S.msgSuccess("检查报告已添加"),b("refresh")})};re(()=>u.notes,()=>{x.value=[],E.value=[],_.value=0,f.value=0});const V=async(t,e,s)=>{try{await K.confirm("确认删除?","提示",{type:"warning"})}catch{return}await oe({note_id:t,image_type:e,image_path:s}),S.msgSuccess("已删除"),b("refresh")};return(t,e)=>{const s=te,h=Y,U=Z,y=q,Q=W;return i(),n("div",le,[!m.readonly&&m.diagnosisId?(i(),n("div",ae,[l(h,{modelValue:x.value,"onUpdate:modelValue":e[0]||(e[0]=o=>x.value=o),limit:99,type:"image","exclude-domain":!0,onChange:H},{upload:c(()=>[a("div",me,[l(s,{size:20,name:"el-icon-Plus"}),e[2]||(e[2]=a("span",null,"舌苔照片",-1))])]),_:1},8,["modelValue"]),l(h,{modelValue:E.value,"onUpdate:modelValue":e[1]||(e[1]=o=>E.value=o),limit:99,type:"file","exclude-domain":!0,onChange:J},{upload:c(()=>[a("div",de,[l(s,{size:20,name:"el-icon-Plus"}),e[3]||(e[3]=a("span",null,"检查报告",-1))])]),_:1},8,["modelValue"])])):d("",!0),m.notes.length?(i(),n("div",pe,[(i(!0),n(v,null,k(m.notes,o=>{var D,F;return i(),n("div",{key:o.id,class:"timeline-node"},[e[6]||(e[6]=a("div",{class:"timeline-dot"},null,-1)),a("div",ce,z(o.note_date),1),a("div",ue,[o.content?(i(),n("div",ge,[(i(!0),n(v,null,k(X(o.content),(r,p)=>(i(),n("div",{key:p,class:"content-line"},z(r),1))),128))])):d("",!0),(D=o.tongue_images)!=null&&D.length?(i(),n("div",_e,[e[4]||(e[4]=a("span",{class:"images-label"},"舌苔照片",-1)),(i(!0),n(v,null,k(o.tongue_images,(r,p)=>(i(),n("div",{key:p,class:"thumb-wrap"},[l(U,{src:g(r),"preview-src-list":o.tongue_images.map(g),"initial-index":p,"z-index":T,fit:"cover",class:"timeline-thumb","preview-teleported":""},null,8,["src","preview-src-list","initial-index"]),m.readonly?d("",!0):(i(),I(y,{key:0,class:"thumb-delete",onClick:A(P=>V(o.id,"tongue_images",r),["stop"])},{default:c(()=>[l(C(B))]),_:1},8,["onClick"]))]))),128))])):d("",!0),(F=o.report_files)!=null&&F.length?(i(),n("div",fe,[e[5]||(e[5]=a("span",{class:"images-label"},"检查报告",-1)),(i(!0),n(v,null,k(o.report_files,(r,p)=>(i(),n(v,{key:p},[N(r)?(i(),n("div",ve,[l(U,{src:g(r),"preview-src-list":j(o.report_files),"initial-index":O(o.report_files,p),"z-index":T,fit:"cover",class:"timeline-thumb","preview-teleported":""},null,8,["src","preview-src-list","initial-index"]),m.readonly?d("",!0):(i(),I(y,{key:0,class:"thumb-delete",onClick:A(P=>V(o.id,"report_files",r),["stop"])},{default:c(()=>[l(C(B))]),_:1},8,["onClick"]))])):(i(),n("div",he,[a("a",{href:g(r),target:"_blank",class:"file-link",title:M(r)},[l(y,{size:20},{default:c(()=>[l(C(se))]),_:1}),a("span",ke,z(M(r)),1)],8,ye),m.readonly?d("",!0):(i(),I(y,{key:0,class:"file-delete",onClick:A(P=>V(o.id,"report_files",r),["stop"])},{default:c(()=>[l(C(B))]),_:1},8,["onClick"]))]))],64))),128))])):d("",!0)])])}),128))])):d("",!0),!m.notes.length&&m.readonly?(i(),I(Q,{key:2,description:"暂无备注","image-size":48})):d("",!0)])}}}),It=ie(Ie,[["__scopeId","data-v-f77bb3f4"]]);export{It as default}; `).filter(Boolean):[],H=t=>{if(!u.diagnosisId)return;const e=Array.isArray(t)?t:[t];if(e.length<=_.value){_.value=e.length;return}const s=e.slice(_.value);_.value=e.length,s.length>0&&R({diagnosis_id:u.diagnosisId,tongue_images:s}).then(()=>{S.msgSuccess("舌苔照片已添加"),b("refresh")})},J=t=>{if(!u.diagnosisId)return;const e=Array.isArray(t)?t:[t];if(e.length<=f.value){f.value=e.length;return}const s=e.slice(f.value);f.value=e.length,s.length>0&&R({diagnosis_id:u.diagnosisId,report_files:s}).then(()=>{S.msgSuccess("检查报告已添加"),b("refresh")})};re(()=>u.notes,()=>{x.value=[],E.value=[],_.value=0,f.value=0});const V=async(t,e,s)=>{try{await K.confirm("确认删除?","提示",{type:"warning"})}catch{return}await oe({note_id:t,image_type:e,image_path:s}),S.msgSuccess("已删除"),b("refresh")};return(t,e)=>{const s=te,h=Y,U=Z,y=q,Q=W;return i(),n("div",le,[!m.readonly&&m.diagnosisId?(i(),n("div",ae,[l(h,{modelValue:x.value,"onUpdate:modelValue":e[0]||(e[0]=o=>x.value=o),limit:99,type:"image","exclude-domain":!0,onChange:H},{upload:c(()=>[a("div",me,[l(s,{size:20,name:"el-icon-Plus"}),e[2]||(e[2]=a("span",null,"舌苔照片",-1))])]),_:1},8,["modelValue"]),l(h,{modelValue:E.value,"onUpdate:modelValue":e[1]||(e[1]=o=>E.value=o),limit:99,type:"file","exclude-domain":!0,onChange:J},{upload:c(()=>[a("div",de,[l(s,{size:20,name:"el-icon-Plus"}),e[3]||(e[3]=a("span",null,"检查报告",-1))])]),_:1},8,["modelValue"])])):d("",!0),m.notes.length?(i(),n("div",pe,[(i(!0),n(v,null,k(m.notes,o=>{var D,F;return i(),n("div",{key:o.id,class:"timeline-node"},[e[6]||(e[6]=a("div",{class:"timeline-dot"},null,-1)),a("div",ce,z(o.note_date),1),a("div",ue,[o.content?(i(),n("div",ge,[(i(!0),n(v,null,k(X(o.content),(r,p)=>(i(),n("div",{key:p,class:"content-line"},z(r),1))),128))])):d("",!0),(D=o.tongue_images)!=null&&D.length?(i(),n("div",_e,[e[4]||(e[4]=a("span",{class:"images-label"},"舌苔照片",-1)),(i(!0),n(v,null,k(o.tongue_images,(r,p)=>(i(),n("div",{key:p,class:"thumb-wrap"},[l(U,{src:g(r),"preview-src-list":o.tongue_images.map(g),"initial-index":p,"z-index":T,fit:"cover",class:"timeline-thumb","preview-teleported":""},null,8,["src","preview-src-list","initial-index"]),m.readonly?d("",!0):(i(),I(y,{key:0,class:"thumb-delete",onClick:A(P=>V(o.id,"tongue_images",r),["stop"])},{default:c(()=>[l(C(B))]),_:1},8,["onClick"]))]))),128))])):d("",!0),(F=o.report_files)!=null&&F.length?(i(),n("div",fe,[e[5]||(e[5]=a("span",{class:"images-label"},"检查报告",-1)),(i(!0),n(v,null,k(o.report_files,(r,p)=>(i(),n(v,{key:p},[N(r)?(i(),n("div",ve,[l(U,{src:g(r),"preview-src-list":j(o.report_files),"initial-index":O(o.report_files,p),"z-index":T,fit:"cover",class:"timeline-thumb","preview-teleported":""},null,8,["src","preview-src-list","initial-index"]),m.readonly?d("",!0):(i(),I(y,{key:0,class:"thumb-delete",onClick:A(P=>V(o.id,"report_files",r),["stop"])},{default:c(()=>[l(C(B))]),_:1},8,["onClick"]))])):(i(),n("div",he,[a("a",{href:g(r),target:"_blank",class:"file-link",title:M(r)},[l(y,{size:20},{default:c(()=>[l(C(se))]),_:1}),a("span",ke,z(M(r)),1)],8,ye),m.readonly?d("",!0):(i(),I(y,{key:0,class:"file-delete",onClick:A(P=>V(o.id,"report_files",r),["stop"])},{default:c(()=>[l(C(B))]),_:1},8,["onClick"]))]))],64))),128))])):d("",!0)])])}),128))])):d("",!0),!m.notes.length&&m.readonly?(i(),I(Q,{key:2,description:"暂无备注","image-size":48})):d("",!0)])}}}),It=ie(Ie,[["__scopeId","data-v-f77bb3f4"]]);export{It as default};
@@ -1 +1 @@
import{m as x,f as y,a as B}from"./diag-display-DCz_VAqj.js";import{f as w,ak as I,I as P,J as a,H as N}from"./@vue/runtime-core-C6bnekPw.js";import{Q as i}from"./@vue/shared-mAAVTE9n.js";import{y as e}from"./@vue/reactivity-DiY1c2vO.js";import{_ as V}from"./index-WGeajlD5.js";import"./lodash-D3kF6u-c.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const D={class:"card patient-card"},E={class:"patient-hero"},G={class:"patient-name"},H={class:"patient-meta"},J={key:0},Q=w({__name:"PatientInfoCard",props:{apt:{default:()=>({})},diag:{default:()=>({})}},setup(t){return(S,o)=>{var m,r,n,d,p,s,c,l,g,f,u,h,v,k,C;return I(),P("div",D,[o[0]||(o[0]=a("div",{class:"card-title"},"患者信息",-1)),a("div",E,[a("div",G,i(((m=t.apt)==null?void 0:m.patient_name)||"—"),1),a("div",H,[a("div",null,i(e(x)((r=t.apt)==null?void 0:r.patient_phone))+" · "+i(e(y)((n=t.diag)==null?void 0:n.gender))+" · "+i(((d=t.diag)==null?void 0:d.age)!=null?t.diag.age+"岁":"—"),1),a("div",null,i((p=t.diag)!=null&&p.height?t.diag.height+"cm":"—")+" / "+i((s=t.diag)!=null&&s.weight?t.diag.weight+"kg":"—")+" · "+i(((c=t.diag)==null?void 0:c.region)||"—"),1),a("div",null," 预约:"+i((l=t.apt)==null?void 0:l.appointment_date)+" "+i((g=t.apt)==null?void 0:g.appointment_time)+" · "+i(e(B)((f=t.apt)==null?void 0:f.period)),1),a("div",null,"医生:"+i(((u=t.apt)==null?void 0:u.doctor_name)||"—")+" 医助:"+i(((h=t.apt)==null?void 0:h.assistant_name)||"—"),1),a("div",null," 状态:"+i(((v=t.apt)==null?void 0:v.status_desc)||"—")+" · "+i((k=t.apt)!=null&&k.has_prescription?"已开方":"未开方"),1),(C=t.apt)!=null&&C.remark?(I(),P("div",J,"备注:"+i(t.apt.remark),1)):N("",!0)])])])}}}),Ct=V(Q,[["__scopeId","data-v-e3476da5"]]);export{Ct as default}; import{m as x,f as y,a as B}from"./diag-display-DCz_VAqj.js";import{f as w,ak as I,I as P,J as a,H as N}from"./@vue/runtime-core-C6bnekPw.js";import{Q as i}from"./@vue/shared-mAAVTE9n.js";import{y as e}from"./@vue/reactivity-DiY1c2vO.js";import{_ as V}from"./index-3gMrVgPp.js";import"./lodash-D3kF6u-c.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const D={class:"card patient-card"},E={class:"patient-hero"},G={class:"patient-name"},H={class:"patient-meta"},J={key:0},Q=w({__name:"PatientInfoCard",props:{apt:{default:()=>({})},diag:{default:()=>({})}},setup(t){return(S,o)=>{var m,r,n,d,p,s,c,l,g,f,u,h,v,k,C;return I(),P("div",D,[o[0]||(o[0]=a("div",{class:"card-title"},"患者信息",-1)),a("div",E,[a("div",G,i(((m=t.apt)==null?void 0:m.patient_name)||"—"),1),a("div",H,[a("div",null,i(e(x)((r=t.apt)==null?void 0:r.patient_phone))+" · "+i(e(y)((n=t.diag)==null?void 0:n.gender))+" · "+i(((d=t.diag)==null?void 0:d.age)!=null?t.diag.age+"岁":"—"),1),a("div",null,i((p=t.diag)!=null&&p.height?t.diag.height+"cm":"—")+" / "+i((s=t.diag)!=null&&s.weight?t.diag.weight+"kg":"—")+" · "+i(((c=t.diag)==null?void 0:c.region)||"—"),1),a("div",null," 预约:"+i((l=t.apt)==null?void 0:l.appointment_date)+" "+i((g=t.apt)==null?void 0:g.appointment_time)+" · "+i(e(B)((f=t.apt)==null?void 0:f.period)),1),a("div",null,"医生:"+i(((u=t.apt)==null?void 0:u.doctor_name)||"—")+" 医助:"+i(((h=t.apt)==null?void 0:h.assistant_name)||"—"),1),a("div",null," 状态:"+i(((v=t.apt)==null?void 0:v.status_desc)||"—")+" · "+i((k=t.apt)!=null&&k.has_prescription?"已开方":"未开方"),1),(C=t.apt)!=null&&C.remark?(I(),P("div",J,"备注:"+i(t.apt.remark),1)):N("",!0)])])])}}}),Ct=V(Q,[["__scopeId","data-v-e3476da5"]]);export{Ct as default};
@@ -1 +1 @@
import{_ as L}from"./element-plus-BhlMEThZ.js";import B from"./RecordingVideoPlayer-DWTE4RFi.js";import{e as H,_ as I}from"./index-WGeajlD5.js";import{f as w,ak as n,I as m,J as p,F as _,G as u,aN as v,O as k,H as y,ap as R,A as d}from"./@vue/runtime-core-C6bnekPw.js";import{Q as q}from"./@vue/shared-mAAVTE9n.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const C={key:0,class:"recording-list"},N={class:"recording-item"},P={key:1,class:"recording-alternates"},V={class:"recording-alternates__links"},A={key:1,class:"text-gray-400"},E=w({__name:"RecordingPlaybackBlock",props:{recordId:{},urls:{}},setup(c){const $=c,h=H(),l=d(()=>{const e=$.urls||[],t=new Set,r=[];for(const s of e){const o=String(s??"").trim();!o||t.has(o)||(t.add(o),r.push(o))}return r}),a=d(()=>{const e=l.value;if(!e.length)return null;const t=e.find(i=>/\.mp4(\?|#|$)/i.test(i));if(t)return t;const r=e.find(i=>/\.m3u8(\?|#|$)/i.test(i)&&/vod-qcloud\.com/i.test(i));if(r)return r;const s=e.find(i=>/\.m3u8(\?|#|$)/i.test(i)&&/\.cos\.[^/]+\.myqcloud\.com/i.test(i));if(s)return s;const o=e.find(i=>/\.m3u8(\?|#|$)/i.test(i));return o||e[0]}),f=d(()=>{const e=l.value,t=a.value;return t?e.filter(r=>r!==t):e.slice(1)});function b(e){if(!e||typeof e!="string")return!1;const t=e.trim();return/^https?:\/\//i.test(t)?/\.(mp4|webm|ogg|mov|mkv|m4v|m3u8)(\?|#|$)/i.test(t):/\.(mp4|webm|ogg|mov|mkv|m4v|m3u8)(\?|#|$)/i.test(t)||t.startsWith("/uploads/")}function g(e){return h.getImageUrl(String(e||"").trim())}function S(e,t){const r=e.trim();return/\.mp4(\?|#|$)/i.test(r)?`MP4 ${t+1}`:/vod-qcloud\.com/i.test(r)&&/\.m3u8/i.test(r)?`点播 ${t+1}`:/\.cos\.[^/]+\.myqcloud\.com/i.test(r)&&/\.m3u8/i.test(r)?`COS HLS ${t+1}`:/\.m3u8/i.test(r)?`HLS ${t+1}`:`链接 ${t+1}`}return(e,t)=>{const r=L;return l.value.length?(n(),m("div",C,[p("div",N,[a.value?(n(),m(_,{key:0},[b(a.value)?(n(),u(B,{key:`${c.recordId}-${a.value}`,src:a.value},null,8,["src"])):(n(),u(r,{key:1,href:g(a.value),target:"_blank",type:"primary"},{default:v(()=>[...t[0]||(t[0]=[k(" 打开回放 ",-1)])]),_:1},8,["href"]))],64)):y("",!0),f.value.length?(n(),m("div",P,[t[1]||(t[1]=p("span",{class:"recording-alternates__label"},"备用地址",-1)),p("div",V,[(n(!0),m(_,null,R(f.value,(s,o)=>(n(),u(r,{key:`${c.recordId}-alt-${o}-${s.slice(-32)}`,href:g(s),target:"_blank",type:"primary",class:"recording-alternates__link"},{default:v(()=>[k(q(S(s,o)),1)]),_:2},1032,["href"]))),128))])])):y("",!0)])])):(n(),m("span",A,"暂无"))}}}),ht=I(E,[["__scopeId","data-v-d67b2e91"]]);export{ht as default}; import{_ as L}from"./element-plus-DFTWCWyi.js";import B from"./RecordingVideoPlayer-DNu6oAB9.js";import{e as H,_ as I}from"./index-3gMrVgPp.js";import{f as w,ak as n,I as m,J as p,F as _,G as u,aN as v,O as k,H as y,ap as R,A as d}from"./@vue/runtime-core-C6bnekPw.js";import{Q as q}from"./@vue/shared-mAAVTE9n.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const C={key:0,class:"recording-list"},N={class:"recording-item"},P={key:1,class:"recording-alternates"},V={class:"recording-alternates__links"},A={key:1,class:"text-gray-400"},E=w({__name:"RecordingPlaybackBlock",props:{recordId:{},urls:{}},setup(c){const $=c,h=H(),l=d(()=>{const e=$.urls||[],t=new Set,r=[];for(const s of e){const o=String(s??"").trim();!o||t.has(o)||(t.add(o),r.push(o))}return r}),a=d(()=>{const e=l.value;if(!e.length)return null;const t=e.find(i=>/\.mp4(\?|#|$)/i.test(i));if(t)return t;const r=e.find(i=>/\.m3u8(\?|#|$)/i.test(i)&&/vod-qcloud\.com/i.test(i));if(r)return r;const s=e.find(i=>/\.m3u8(\?|#|$)/i.test(i)&&/\.cos\.[^/]+\.myqcloud\.com/i.test(i));if(s)return s;const o=e.find(i=>/\.m3u8(\?|#|$)/i.test(i));return o||e[0]}),f=d(()=>{const e=l.value,t=a.value;return t?e.filter(r=>r!==t):e.slice(1)});function b(e){if(!e||typeof e!="string")return!1;const t=e.trim();return/^https?:\/\//i.test(t)?/\.(mp4|webm|ogg|mov|mkv|m4v|m3u8)(\?|#|$)/i.test(t):/\.(mp4|webm|ogg|mov|mkv|m4v|m3u8)(\?|#|$)/i.test(t)||t.startsWith("/uploads/")}function g(e){return h.getImageUrl(String(e||"").trim())}function S(e,t){const r=e.trim();return/\.mp4(\?|#|$)/i.test(r)?`MP4 ${t+1}`:/vod-qcloud\.com/i.test(r)&&/\.m3u8/i.test(r)?`点播 ${t+1}`:/\.cos\.[^/]+\.myqcloud\.com/i.test(r)&&/\.m3u8/i.test(r)?`COS HLS ${t+1}`:/\.m3u8/i.test(r)?`HLS ${t+1}`:`链接 ${t+1}`}return(e,t)=>{const r=L;return l.value.length?(n(),m("div",C,[p("div",N,[a.value?(n(),m(_,{key:0},[b(a.value)?(n(),u(B,{key:`${c.recordId}-${a.value}`,src:a.value},null,8,["src"])):(n(),u(r,{key:1,href:g(a.value),target:"_blank",type:"primary"},{default:v(()=>[...t[0]||(t[0]=[k(" 打开回放 ",-1)])]),_:1},8,["href"]))],64)):y("",!0),f.value.length?(n(),m("div",P,[t[1]||(t[1]=p("span",{class:"recording-alternates__label"},"备用地址",-1)),p("div",V,[(n(!0),m(_,null,R(f.value,(s,o)=>(n(),u(r,{key:`${c.recordId}-alt-${o}-${s.slice(-32)}`,href:g(s),target:"_blank",type:"primary",class:"recording-alternates__link"},{default:v(()=>[k(q(S(s,o)),1)]),_:2},1032,["href"]))),128))])])):y("",!0)])])):(n(),m("span",A,"暂无"))}}}),ht=I(E,[["__scopeId","data-v-d67b2e91"]]);export{ht as default};
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
import{C as I,i as V,R as w}from"./element-plus-BhlMEThZ.js";import{Q as T}from"./tcm-DNvmHkGt.js";import{i as C,_ as E}from"./index-WGeajlD5.js";import{f as z,ak as t,I as e,a as p,J as l,aN as H,O as S,H as m,F as c,ap as u,G as F}from"./@vue/runtime-core-C6bnekPw.js";import{Q as f}from"./@vue/shared-mAAVTE9n.js";import{n as g}from"./@vue/reactivity-DiY1c2vO.js";/* empty css */import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const L={class:"tracking-timeline-wrap"},M={key:0,class:"timeline-input"},Q={class:"input-actions"},A={key:1,class:"tracking-timeline"},D={class:"timeline-date"},G={class:"timeline-body"},J={key:0,class:"timeline-content"},O=z({__name:"TrackingNoteTimeline",props:{notes:{},diagnosisId:{},readonly:{type:Boolean}},emits:["refresh"],setup(i,{emit:v}){const d=i,y=v,r=g(""),a=g(!1),_=o=>o?o.split(` import{C as I,i as V,R as w}from"./element-plus-DFTWCWyi.js";import{R as T}from"./tcm-FwHxrTHD.js";import{i as C,_ as E}from"./index-3gMrVgPp.js";import{f as z,ak as t,I as e,a as p,J as l,aN as H,O as S,H as m,F as c,ap as u,G as F}from"./@vue/runtime-core-C6bnekPw.js";import{Q as f}from"./@vue/shared-mAAVTE9n.js";import{n as g}from"./@vue/reactivity-DiY1c2vO.js";/* empty css */import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const L={class:"tracking-timeline-wrap"},M={key:0,class:"timeline-input"},R={class:"input-actions"},A={key:1,class:"tracking-timeline"},D={class:"timeline-date"},G={class:"timeline-body"},J={key:0,class:"timeline-content"},O=z({__name:"TrackingNoteTimeline",props:{notes:{},diagnosisId:{},readonly:{type:Boolean}},emits:["refresh"],setup(i,{emit:v}){const d=i,y=v,r=g(""),a=g(!1),_=o=>o?o.split(`
`).filter(Boolean):[],k=async()=>{if(!d.diagnosisId)return;const o=r.value.trim();if(o){a.value=!0;try{await T({diagnosis_id:d.diagnosisId,tracking_content:o}),C.msgSuccess("已添加"),r.value="",y("refresh")}finally{a.value=!1}}};return(o,n)=>{const h=I,b=V,N=w;return t(),e("div",L,[!i.readonly&&i.diagnosisId?(t(),e("div",M,[p(h,{modelValue:r.value,"onUpdate:modelValue":n[0]||(n[0]=s=>r.value=s),type:"textarea",rows:2,placeholder:"输入跟踪备注,回车换行;保存后将以「[HH:MM] 内容」追加到当天记录",maxlength:"1000","show-word-limit":"",resize:"none",disabled:a.value},null,8,["modelValue","disabled"]),l("div",Q,[p(b,{type:"primary",size:"small",loading:a.value,disabled:!r.value.trim(),onClick:k},{default:H(()=>[...n[1]||(n[1]=[S(" 添加 ",-1)])]),_:1},8,["loading","disabled"])])])):m("",!0),i.notes.length?(t(),e("div",A,[(t(!0),e(c,null,u(i.notes,s=>(t(),e("div",{key:s.id,class:"timeline-node"},[n[2]||(n[2]=l("div",{class:"timeline-dot"},null,-1)),l("div",D,f(s.note_date),1),l("div",G,[s.content?(t(),e("div",J,[(t(!0),e(c,null,u(_(s.content),(x,B)=>(t(),e("div",{key:B,class:"content-line"},f(x),1))),128))])):m("",!0)])]))),128))])):m("",!0),!i.notes.length&&i.readonly?(t(),F(N,{key:2,description:"暂无跟踪备注","image-size":48})):m("",!0)])}}}),Tt=E(O,[["__scopeId","data-v-82b635bd"]]);export{Tt as default}; `).filter(Boolean):[],k=async()=>{if(!d.diagnosisId)return;const o=r.value.trim();if(o){a.value=!0;try{await T({diagnosis_id:d.diagnosisId,tracking_content:o}),C.msgSuccess("已添加"),r.value="",y("refresh")}finally{a.value=!1}}};return(o,n)=>{const h=I,b=V,N=w;return t(),e("div",L,[!i.readonly&&i.diagnosisId?(t(),e("div",M,[p(h,{modelValue:r.value,"onUpdate:modelValue":n[0]||(n[0]=s=>r.value=s),type:"textarea",rows:2,placeholder:"输入跟踪备注,回车换行;保存后将以「[HH:MM] 内容」追加到当天记录",maxlength:"1000","show-word-limit":"",resize:"none",disabled:a.value},null,8,["modelValue","disabled"]),l("div",R,[p(b,{type:"primary",size:"small",loading:a.value,disabled:!r.value.trim(),onClick:k},{default:H(()=>[...n[1]||(n[1]=[S(" 添加 ",-1)])]),_:1},8,["loading","disabled"])])])):m("",!0),i.notes.length?(t(),e("div",A,[(t(!0),e(c,null,u(i.notes,s=>(t(),e("div",{key:s.id,class:"timeline-node"},[n[2]||(n[2]=l("div",{class:"timeline-dot"},null,-1)),l("div",D,f(s.note_date),1),l("div",G,[s.content?(t(),e("div",J,[(t(!0),e(c,null,u(_(s.content),(x,B)=>(t(),e("div",{key:B,class:"content-line"},f(x),1))),128))])):m("",!0)])]))),128))])):m("",!0),!i.notes.length&&i.readonly?(t(),F(N,{key:2,description:"暂无跟踪备注","image-size":48})):m("",!0)])}}}),Tt=E(O,[["__scopeId","data-v-82b635bd"]]);export{Tt as default};
@@ -1 +1 @@
import{_ as o}from"./account-adjust.vue_vue_type_script_setup_true_lang-DnPFkfbx.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-CgbeKU6K.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";export{o as default}; import{_ as o}from"./account-adjust.vue_vue_type_script_setup_true_lang-CP4l28D8.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-CICkVesR.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";export{o as default};
@@ -1 +1 @@
import{D as h,B as q,G as B,I,C as D}from"./element-plus-BhlMEThZ.js";import{_ as F}from"./index-CgbeKU6K.js";import{i as b}from"./index-WGeajlD5.js";import{f as G,w,ak as j,G as S,aN as r,J as U,a,O as u,A}from"./@vue/runtime-core-C6bnekPw.js";import{y as n,q as y,r as J}from"./@vue/reactivity-DiY1c2vO.js";import{Q as k}from"./@vue/shared-mAAVTE9n.js";const M={class:"pr-8"},L=G({__name:"account-adjust",props:{show:{type:Boolean,required:!0},value:{type:[Number,String],required:!0}},emits:["update:show","confirm"],setup(d,{emit:V}){const s=y(),i=d,f=V,o=J({action:1,num:"",remark:""}),m=y(),c=A(()=>Number(i.value)+Number(o.num)*(o.action==1?1:-1)),R={num:[{required:!0,message:"请输入调整的金额"}]},g=e=>{if(e.includes("-"))return b.msgError("请输入正整数");o.num=e},x=async()=>{var e;await((e=s.value)==null?void 0:e.validate()),f("confirm",o)},C=()=>{var e;f("update:show",!1),(e=s.value)==null||e.resetFields()};return w(()=>i.show,e=>{var t,l;e?(t=m.value)==null||t.open():(l=m.value)==null||l.close()}),w(c,e=>{e<0&&(b.msgError("调整后余额需大于0"),o.num="")}),(e,t)=>{const l=q,_=I,E=B,v=D,N=h;return j(),S(F,{ref_key:"popupRef",ref:m,title:"余额调整",width:"500px",onConfirm:x,async:!0,onClose:C},{default:r(()=>[U("div",M,[a(N,{ref_key:"formRef",ref:s,model:n(o),"label-width":"120px",rules:R},{default:r(()=>[a(l,{label:"当前余额"},{default:r(()=>[u("¥ "+k(d.value),1)]),_:1}),a(l,{label:"余额增减",required:"",prop:"action"},{default:r(()=>[a(E,{modelValue:n(o).action,"onUpdate:modelValue":t[0]||(t[0]=p=>n(o).action=p)},{default:r(()=>[a(_,{value:1},{default:r(()=>[...t[2]||(t[2]=[u("增加余额",-1)])]),_:1}),a(_,{value:2},{default:r(()=>[...t[3]||(t[3]=[u("扣减余额",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),a(l,{label:"调整余额",prop:"num"},{default:r(()=>[a(v,{"model-value":n(o).num,placeholder:"请输入调整的金额",type:"number",onInput:g},null,8,["model-value"])]),_:1}),a(l,{label:"调整后余额"},{default:r(()=>[u(" ¥ "+k(n(c)),1)]),_:1}),a(l,{label:"备注",prop:"remark"},{default:r(()=>[a(v,{modelValue:n(o).remark,"onUpdate:modelValue":t[1]||(t[1]=p=>n(o).remark=p),type:"textarea",rows:4},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])])]),_:1},512)}}});export{L as _}; import{D as h,B as q,G as B,I,C as D}from"./element-plus-DFTWCWyi.js";import{_ as F}from"./index-CICkVesR.js";import{i as b}from"./index-3gMrVgPp.js";import{f as G,w,ak as j,G as S,aN as r,J as U,a,O as u,A}from"./@vue/runtime-core-C6bnekPw.js";import{y as n,q as y,r as J}from"./@vue/reactivity-DiY1c2vO.js";import{Q as k}from"./@vue/shared-mAAVTE9n.js";const M={class:"pr-8"},L=G({__name:"account-adjust",props:{show:{type:Boolean,required:!0},value:{type:[Number,String],required:!0}},emits:["update:show","confirm"],setup(d,{emit:V}){const s=y(),i=d,f=V,o=J({action:1,num:"",remark:""}),m=y(),c=A(()=>Number(i.value)+Number(o.num)*(o.action==1?1:-1)),R={num:[{required:!0,message:"请输入调整的金额"}]},g=e=>{if(e.includes("-"))return b.msgError("请输入正整数");o.num=e},x=async()=>{var e;await((e=s.value)==null?void 0:e.validate()),f("confirm",o)},C=()=>{var e;f("update:show",!1),(e=s.value)==null||e.resetFields()};return w(()=>i.show,e=>{var t,l;e?(t=m.value)==null||t.open():(l=m.value)==null||l.close()}),w(c,e=>{e<0&&(b.msgError("调整后余额需大于0"),o.num="")}),(e,t)=>{const l=q,_=I,E=B,v=D,N=h;return j(),S(F,{ref_key:"popupRef",ref:m,title:"余额调整",width:"500px",onConfirm:x,async:!0,onClose:C},{default:r(()=>[U("div",M,[a(N,{ref_key:"formRef",ref:s,model:n(o),"label-width":"120px",rules:R},{default:r(()=>[a(l,{label:"当前余额"},{default:r(()=>[u("¥ "+k(d.value),1)]),_:1}),a(l,{label:"余额增减",required:"",prop:"action"},{default:r(()=>[a(E,{modelValue:n(o).action,"onUpdate:modelValue":t[0]||(t[0]=p=>n(o).action=p)},{default:r(()=>[a(_,{value:1},{default:r(()=>[...t[2]||(t[2]=[u("增加余额",-1)])]),_:1}),a(_,{value:2},{default:r(()=>[...t[3]||(t[3]=[u("扣减余额",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),a(l,{label:"调整余额",prop:"num"},{default:r(()=>[a(v,{"model-value":n(o).num,placeholder:"请输入调整的金额",type:"number",onInput:g},null,8,["model-value"])]),_:1}),a(l,{label:"调整后余额"},{default:r(()=>[u(" ¥ "+k(n(c)),1)]),_:1}),a(l,{label:"备注",prop:"remark"},{default:r(()=>[a(v,{modelValue:n(o).remark,"onUpdate:modelValue":t[1]||(t[1]=p=>n(o).remark=p),type:"textarea",rows:4},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])])]),_:1},512)}}});export{L as _};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as o}from"./add-nav.vue_vue_type_script_setup_true_lang-DoaKouJ5.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-EG3kZkys.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-CqvZAHDk.js";import"./index-CgbeKU6K.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./article-B0vJLMlu.js";import"./usePaging-VsbTxSU0.js";import"./picker-ChJwUkIc.js";import"./index-B5BEu-2e.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default}; import{_ as o}from"./add-nav.vue_vue_type_script_setup_true_lang-CFFk8uqz.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DZ0cpdk5.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-B4tRYcnk.js";import"./index-CICkVesR.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./article-BAOzVJEM.js";import"./usePaging-VsbTxSU0.js";import"./picker-C4e9dvGe.js";import"./index-B8fzRqRH.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
@@ -1 +1 @@
import{C as E,B,g as C,i as N}from"./element-plus-BhlMEThZ.js";import{_ as $}from"./index-EG3kZkys.js";import{_ as z}from"./picker-CqvZAHDk.js";import{_ as A}from"./picker-ChJwUkIc.js";import{c as D,i as r}from"./index-WGeajlD5.js";import{D as I}from"./vuedraggable-5bKFmC7X.js";import{f as R,ak as p,I as F,J as l,a,aN as d,G,O as J,A as L}from"./@vue/runtime-core-C6bnekPw.js";import{y as c,a as O}from"./@vue/reactivity-DiY1c2vO.js";const P={class:"bg-fill-light flex items-center w-full p-4 mb-4"},S={class:"upload-btn w-[60px] h-[60px]"},T={class:"ml-3 flex-1"},j={class:"flex items-center"},q={class:"flex items-center mt-[18px]"},H={class:"flex-1 flex items-center"},K={class:"drag-move cursor-move ml-auto"},oe=R({__name:"add-nav",props:{modelValue:{type:Array,default:()=>[]},max:{type:Number,default:100},min:{type:Number,default:1}},emits:["update:modelValue"],setup(_,{emit:f}){const t=_,V=f,m=L({get(){return t.modelValue},set(s){V("update:modelValue",s)}}),x=()=>{var s;((s=t.modelValue)==null?void 0:s.length)<t.max?m.value.push({image:"",name:"导航名称",link:{},is_show:"1"}):r.msgError(`最多添加${t.max}`)},g=s=>{var e;if(((e=t.modelValue)==null?void 0:e.length)<=t.min)return r.msgError(`最少保留${t.min}`);m.value.splice(s,1)};return(s,e)=>{const i=D,v=A,h=E,k=z,b=C,w=B,y=$,U=N;return p(),F("div",null,[l("div",null,[a(c(I),{class:"draggable",modelValue:c(m),"onUpdate:modelValue":e[0]||(e[0]=o=>O(m)?m.value=o:null),animation:"300",handle:".drag-move","item-key":"index"},{item:d(({element:o,index:u})=>[(p(),G(y,{class:"w-[467px]",key:u,onClose:n=>g(u)},{default:d(()=>[l("div",P,[a(v,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body",size:"60px","exclude-domain":""},{upload:d(()=>[l("div",S,[a(i,{name:"el-icon-Plus",size:20})])]),_:1},8,["modelValue","onUpdate:modelValue"]),l("div",T,[l("div",j,[e[1]||(e[1]=l("span",{class:"text-tx-regular flex-none mr-3"},"名称",-1)),a(h,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),l("div",q,[e[2]||(e[2]=l("span",{class:"text-tx-regular flex-none mr-3"},"链接",-1)),a(k,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),a(w,{label:"是否显示",class:"mt-[18px]"},{default:d(()=>[l("div",H,[a(b,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),l("div",K,[a(i,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),l("div",null,[a(U,{type:"primary",onClick:x},{default:d(()=>[...e[3]||(e[3]=[J("添加",-1)])]),_:1})])])}}});export{oe as _}; import{C as E,B,g as C,i as N}from"./element-plus-DFTWCWyi.js";import{_ as $}from"./index-DZ0cpdk5.js";import{_ as z}from"./picker-B4tRYcnk.js";import{_ as A}from"./picker-C4e9dvGe.js";import{c as D,i as r}from"./index-3gMrVgPp.js";import{D as I}from"./vuedraggable-5bKFmC7X.js";import{f as R,ak as p,I as F,J as l,a,aN as d,G,O as J,A as L}from"./@vue/runtime-core-C6bnekPw.js";import{y as c,a as O}from"./@vue/reactivity-DiY1c2vO.js";const P={class:"bg-fill-light flex items-center w-full p-4 mb-4"},S={class:"upload-btn w-[60px] h-[60px]"},T={class:"ml-3 flex-1"},j={class:"flex items-center"},q={class:"flex items-center mt-[18px]"},H={class:"flex-1 flex items-center"},K={class:"drag-move cursor-move ml-auto"},oe=R({__name:"add-nav",props:{modelValue:{type:Array,default:()=>[]},max:{type:Number,default:100},min:{type:Number,default:1}},emits:["update:modelValue"],setup(_,{emit:f}){const t=_,V=f,m=L({get(){return t.modelValue},set(s){V("update:modelValue",s)}}),x=()=>{var s;((s=t.modelValue)==null?void 0:s.length)<t.max?m.value.push({image:"",name:"导航名称",link:{},is_show:"1"}):r.msgError(`最多添加${t.max}`)},g=s=>{var e;if(((e=t.modelValue)==null?void 0:e.length)<=t.min)return r.msgError(`最少保留${t.min}`);m.value.splice(s,1)};return(s,e)=>{const i=D,v=A,h=E,k=z,b=C,w=B,y=$,U=N;return p(),F("div",null,[l("div",null,[a(c(I),{class:"draggable",modelValue:c(m),"onUpdate:modelValue":e[0]||(e[0]=o=>O(m)?m.value=o:null),animation:"300",handle:".drag-move","item-key":"index"},{item:d(({element:o,index:u})=>[(p(),G(y,{class:"w-[467px]",key:u,onClose:n=>g(u)},{default:d(()=>[l("div",P,[a(v,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body",size:"60px","exclude-domain":""},{upload:d(()=>[l("div",S,[a(i,{name:"el-icon-Plus",size:20})])]),_:1},8,["modelValue","onUpdate:modelValue"]),l("div",T,[l("div",j,[e[1]||(e[1]=l("span",{class:"text-tx-regular flex-none mr-3"},"名称",-1)),a(h,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),l("div",q,[e[2]||(e[2]=l("span",{class:"text-tx-regular flex-none mr-3"},"链接",-1)),a(k,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),a(w,{label:"是否显示",class:"mt-[18px]"},{default:d(()=>[l("div",H,[a(b,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),l("div",K,[a(i,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),l("div",null,[a(U,{type:"primary",onClick:x},{default:d(()=>[...e[3]||(e[3]=[J("添加",-1)])]),_:1})])])}}});export{oe as _};
@@ -1 +1 @@
import{r as n}from"./index-WGeajlD5.js";function e(t){return n.get({url:"/auth.admin/lists",params:t},{ignoreCancelToken:!0})}function i(t){return n.post({url:"/auth.admin/add",params:t})}function r(t){return n.post({url:"/auth.admin/edit",params:t})}function u(t){return n.post({url:"/auth.admin/delete",params:t})}function d(t){return n.get({url:"/auth.admin/detail",params:t})}export{e as a,r as b,u as c,i as d,d as e}; import{r as n}from"./index-3gMrVgPp.js";function e(t){return n.get({url:"/auth.admin/lists",params:t},{ignoreCancelToken:!0})}function i(t){return n.post({url:"/auth.admin/add",params:t})}function r(t){return n.post({url:"/auth.admin/edit",params:t})}function u(t){return n.post({url:"/auth.admin/delete",params:t})}function d(t){return n.get({url:"/auth.admin/detail",params:t})}export{e as a,r as b,u as c,i as d,d as e};
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
.today-block-alert[data-v-dbfff1e8]{margin-bottom:16px}.appointment-form[data-v-dbfff1e8] .el-form-item__label{font-weight:500}.appointment-form .channel-source-select[data-v-dbfff1e8]{width:100%;max-width:360px}.doctor-list[data-v-dbfff1e8]{display:flex;flex-wrap:wrap;gap:12px}.doctor-list .doctor-radio[data-v-dbfff1e8]{margin-right:0}.doctor-list .doctor-radio[data-v-dbfff1e8] .el-radio__label{display:flex;align-items:center}.appointment-time-container[data-v-dbfff1e8]{width:100%}.date-selector[data-v-dbfff1e8]{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:20px}.date-selector .date-button[data-v-dbfff1e8]{min-width:130px;height:40px;font-size:14px;border-radius:8px;transition:all .2s}.date-selector .date-button[data-v-dbfff1e8]:hover{transform:translateY(-2px);box-shadow:0 2px 8px #0000001a}.time-slots-container[data-v-dbfff1e8]{background-color:#f8f9fa;border-radius:8px;padding:16px}.time-slots-header[data-v-dbfff1e8]{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.time-slots-header .header-title[data-v-dbfff1e8]{font-size:15px;font-weight:600;color:#303133}.time-slots-grid[data-v-dbfff1e8]{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:10px;max-height:450px;overflow-y:auto;padding:2px}.time-slots-grid[data-v-dbfff1e8]::-webkit-scrollbar{width:6px}.time-slots-grid[data-v-dbfff1e8]::-webkit-scrollbar-thumb{background-color:#dcdfe6;border-radius:3px}.time-slots-grid[data-v-dbfff1e8]::-webkit-scrollbar-thumb:hover{background-color:#c0c4cc}.time-slots-grid .time-slot-item[data-v-dbfff1e8]{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0 8px;border:2px solid #e4e7ed;border-radius:8px;cursor:pointer;transition:all .2s;background-color:#fff;min-height:70px}.time-slots-grid .time-slot-item .slot-time[data-v-dbfff1e8]{font-size:15px;font-weight:600;color:#303133;margin-bottom:6px}.time-slots-grid .time-slot-item .slot-status[data-v-dbfff1e8]{font-size:12px;color:#909399;padding:0 8px;border-radius:4px;background-color:#f4f4f5}.time-slots-grid .time-slot-item .slot-status.status-available[data-v-dbfff1e8]{color:#67c23a;background-color:#f0f9ff}.time-slots-grid .time-slot-item.available[data-v-dbfff1e8]{border-color:#e4e7ed}.time-slots-grid .time-slot-item.available[data-v-dbfff1e8]:hover{border-color:#409eff;background-color:#ecf5ff;transform:translateY(-2px);box-shadow:0 4px 12px #409eff26}.time-slots-grid .time-slot-item.unavailable[data-v-dbfff1e8]{background-color:#f5f7fa;border-color:#e4e7ed;cursor:not-allowed;opacity:.6}.time-slots-grid .time-slot-item.unavailable .slot-time[data-v-dbfff1e8]{color:#c0c4cc}.time-slots-grid .time-slot-item.unavailable .slot-status[data-v-dbfff1e8]{color:#c0c4cc;background-color:#f5f7fa}.time-slots-grid .time-slot-item.unavailable[data-v-dbfff1e8]:hover{transform:none;box-shadow:none}.time-slots-grid .time-slot-item.selected[data-v-dbfff1e8]{border-color:#409eff;background:linear-gradient(135deg,#409eff,#66b1ff);box-shadow:0 4px 12px #409eff4d}.time-slots-grid .time-slot-item.selected .slot-time[data-v-dbfff1e8]{color:#fff}.time-slots-grid .time-slot-item.selected .slot-status[data-v-dbfff1e8]{color:#fff;background-color:#fff3}[data-v-dbfff1e8] .el-radio-group{display:flex;flex-wrap:wrap;gap:12px}[data-v-dbfff1e8] .el-radio{margin-right:0}.drawer-footer[data-v-dbfff1e8]{display:flex;justify-content:flex-end;gap:12px;padding:12px 0}
@@ -1 +0,0 @@
.today-block-alert[data-v-0586cc07]{margin-bottom:16px}.appointment-form[data-v-0586cc07] .el-form-item__label{font-weight:500}.appointment-form .channel-source-select[data-v-0586cc07]{width:100%;max-width:360px}.doctor-list[data-v-0586cc07]{display:flex;flex-wrap:wrap;gap:12px}.doctor-list .doctor-radio[data-v-0586cc07]{margin-right:0}.doctor-list .doctor-radio[data-v-0586cc07] .el-radio__label{display:flex;align-items:center}.appointment-time-container[data-v-0586cc07]{width:100%}.date-selector[data-v-0586cc07]{display:flex;gap:10px;flex-wrap:wrap;margin-bottom:20px}.date-selector .date-button[data-v-0586cc07]{min-width:130px;height:40px;font-size:14px;border-radius:8px;transition:all .2s}.date-selector .date-button[data-v-0586cc07]:hover{transform:translateY(-2px);box-shadow:0 2px 8px #0000001a}.time-slots-container[data-v-0586cc07]{background-color:#f8f9fa;border-radius:8px;padding:16px}.time-slots-header[data-v-0586cc07]{display:flex;justify-content:space-between;align-items:center;margin-bottom:16px}.time-slots-header .header-title[data-v-0586cc07]{font-size:15px;font-weight:600;color:#303133}.time-slots-grid[data-v-0586cc07]{display:grid;grid-template-columns:repeat(auto-fill,minmax(110px,1fr));gap:10px;max-height:450px;overflow-y:auto;padding:2px}.time-slots-grid[data-v-0586cc07]::-webkit-scrollbar{width:6px}.time-slots-grid[data-v-0586cc07]::-webkit-scrollbar-thumb{background-color:#dcdfe6;border-radius:3px}.time-slots-grid[data-v-0586cc07]::-webkit-scrollbar-thumb:hover{background-color:#c0c4cc}.time-slots-grid .time-slot-item[data-v-0586cc07]{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:0 8px;border:2px solid #e4e7ed;border-radius:8px;cursor:pointer;transition:all .2s;background-color:#fff;min-height:70px}.time-slots-grid .time-slot-item .slot-time[data-v-0586cc07]{font-size:15px;font-weight:600;color:#303133;margin-bottom:6px}.time-slots-grid .time-slot-item .slot-status[data-v-0586cc07]{font-size:12px;color:#909399;padding:0 8px;border-radius:4px;background-color:#f4f4f5}.time-slots-grid .time-slot-item .slot-status.status-available[data-v-0586cc07]{color:#67c23a;background-color:#f0f9ff}.time-slots-grid .time-slot-item.available[data-v-0586cc07]{border-color:#e4e7ed}.time-slots-grid .time-slot-item.available[data-v-0586cc07]:hover{border-color:#409eff;background-color:#ecf5ff;transform:translateY(-2px);box-shadow:0 4px 12px #409eff26}.time-slots-grid .time-slot-item.unavailable[data-v-0586cc07]{background-color:#f5f7fa;border-color:#e4e7ed;cursor:not-allowed;opacity:.6}.time-slots-grid .time-slot-item.unavailable .slot-time[data-v-0586cc07]{color:#c0c4cc}.time-slots-grid .time-slot-item.unavailable .slot-status[data-v-0586cc07]{color:#c0c4cc;background-color:#f5f7fa}.time-slots-grid .time-slot-item.unavailable[data-v-0586cc07]:hover{transform:none;box-shadow:none}.time-slots-grid .time-slot-item.selected[data-v-0586cc07]{border-color:#409eff;background:linear-gradient(135deg,#409eff,#66b1ff);box-shadow:0 4px 12px #409eff4d}.time-slots-grid .time-slot-item.selected .slot-time[data-v-0586cc07]{color:#fff}.time-slots-grid .time-slot-item.selected .slot-status[data-v-0586cc07]{color:#fff;background-color:#fff3}[data-v-0586cc07] .el-radio-group{display:flex;flex-wrap:wrap;gap:12px}[data-v-0586cc07] .el-radio{margin-right:0}.drawer-footer[data-v-0586cc07]{display:flex;justify-content:flex-end;gap:12px;padding:12px 0}
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{r as e}from"./index-WGeajlD5.js";function a(t){return e.get({url:"/article.articleCate/lists",params:t})}function l(t){return e.get({url:"/article.articleCate/all",params:t})}function i(t){return e.post({url:"/article.articleCate/add",params:t})}function c(t){return e.post({url:"/article.articleCate/edit",params:t})}function u(t){return e.post({url:"/article.articleCate/delete",params:t})}function n(t){return e.get({url:"/article.articleCate/detail",params:t})}function s(t){return e.post({url:"/article.articleCate/updateStatus",params:t})}function o(t){return e.get({url:"/article.article/lists",params:t})}function d(t){return e.post({url:"/article.article/add",params:t})}function f(t){return e.post({url:"/article.article/edit",params:t})}function C(t){return e.post({url:"/article.article/delete",params:t})}function p(t){return e.get({url:"/article.article/detail",params:t})}function g(t){return e.post({url:"/article.article/updateStatus",params:t})}export{a,u as b,s as c,c as d,i as e,n as f,p as g,f as h,d as i,l as j,o as k,g as l,C as m}; import{r as e}from"./index-3gMrVgPp.js";function a(t){return e.get({url:"/article.articleCate/lists",params:t})}function l(t){return e.get({url:"/article.articleCate/all",params:t})}function i(t){return e.post({url:"/article.articleCate/add",params:t})}function c(t){return e.post({url:"/article.articleCate/edit",params:t})}function u(t){return e.post({url:"/article.articleCate/delete",params:t})}function n(t){return e.get({url:"/article.articleCate/detail",params:t})}function s(t){return e.post({url:"/article.articleCate/updateStatus",params:t})}function o(t){return e.get({url:"/article.article/lists",params:t})}function d(t){return e.post({url:"/article.article/add",params:t})}function f(t){return e.post({url:"/article.article/edit",params:t})}function C(t){return e.post({url:"/article.article/delete",params:t})}function p(t){return e.get({url:"/article.article/detail",params:t})}function g(t){return e.post({url:"/article.article/updateStatus",params:t})}export{a,u as b,s as c,c as d,i as e,n as f,p as g,f as h,d as i,l as j,o as k,g as l,C as m};
@@ -1 +1 @@
import{m as b,l as c,D as V}from"./element-plus-BhlMEThZ.js";import{_ as l}from"./menu-set.vue_vue_type_script_setup_true_lang-DczS9hZJ.js";import{f as v,ak as x,I as k,J as E,a as o,aN as e,F as g,A as w}from"./@vue/runtime-core-C6bnekPw.js";import{y as r}from"./@vue/reactivity-DiY1c2vO.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-EG3kZkys.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-CqvZAHDk.js";import"./index-CgbeKU6K.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./article-B0vJLMlu.js";import"./usePaging-VsbTxSU0.js";import"./picker-ChJwUkIc.js";import"./index-B5BEu-2e.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";const Bt=v({__name:"attr",props:{modelValue:{type:Object,default:()=>({nav:[],menu:{}})}},emits:["update:modelValue"],setup(n,{emit:s}){const u=n,d=s,m=w({get(){return u.modelValue},set(i){d("update:modelValue",i)}});return(i,t)=>{const a=c,f=b,_=V;return x(),k(g,null,[t[2]||(t[2]=E("div",{class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2"}," pc导航设置 ",-1)),o(_,{class:"mt-4","label-width":"70px"},{default:e(()=>[o(f,{"model-value":"nav"},{default:e(()=>[o(a,{label:"主导航设置",name:"nav"},{default:e(()=>[o(l,{modelValue:r(m).nav,"onUpdate:modelValue":t[0]||(t[0]=p=>r(m).nav=p)},null,8,["modelValue"])]),_:1}),o(a,{label:"菜单设置",name:"menu"},{default:e(()=>[o(l,{modelValue:r(m).menu,"onUpdate:modelValue":t[1]||(t[1]=p=>r(m).menu=p)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})],64)}}});export{Bt as default}; import{m as b,l as c,D as V}from"./element-plus-DFTWCWyi.js";import{_ as l}from"./menu-set.vue_vue_type_script_setup_true_lang-C2G8lz5r.js";import{f as v,ak as x,I as k,J as E,a as o,aN as e,F as g,A as w}from"./@vue/runtime-core-C6bnekPw.js";import{y as r}from"./@vue/reactivity-DiY1c2vO.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DZ0cpdk5.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-B4tRYcnk.js";import"./index-CICkVesR.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./article-BAOzVJEM.js";import"./usePaging-VsbTxSU0.js";import"./picker-C4e9dvGe.js";import"./index-B8fzRqRH.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";const Bt=v({__name:"attr",props:{modelValue:{type:Object,default:()=>({nav:[],menu:{}})}},emits:["update:modelValue"],setup(n,{emit:s}){const u=n,d=s,m=w({get(){return u.modelValue},set(i){d("update:modelValue",i)}});return(i,t)=>{const a=c,f=b,_=V;return x(),k(g,null,[t[2]||(t[2]=E("div",{class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2"}," pc导航设置 ",-1)),o(_,{class:"mt-4","label-width":"70px"},{default:e(()=>[o(f,{"model-value":"nav"},{default:e(()=>[o(a,{label:"主导航设置",name:"nav"},{default:e(()=>[o(l,{modelValue:r(m).nav,"onUpdate:modelValue":t[0]||(t[0]=p=>r(m).nav=p)},null,8,["modelValue"])]),_:1}),o(a,{label:"菜单设置",name:"menu"},{default:e(()=>[o(l,{modelValue:r(m).menu,"onUpdate:modelValue":t[1]||(t[1]=p=>r(m).menu=p)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})],64)}}});export{Bt as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-BeYayLpN.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-DoaKouJ5.js";import"./index-EG3kZkys.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-CqvZAHDk.js";import"./index-CgbeKU6K.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./article-B0vJLMlu.js";import"./usePaging-VsbTxSU0.js";import"./picker-ChJwUkIc.js";import"./index-B5BEu-2e.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-C8Xjq8fP.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-CFFk8uqz.js";import"./index-DZ0cpdk5.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-B4tRYcnk.js";import"./index-CICkVesR.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./article-BAOzVJEM.js";import"./usePaging-VsbTxSU0.js";import"./picker-C4e9dvGe.js";import"./index-B8fzRqRH.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-C8zKp0iH.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-EG3kZkys.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-CqvZAHDk.js";import"./index-CgbeKU6K.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./article-B0vJLMlu.js";import"./usePaging-VsbTxSU0.js";import"./picker-ChJwUkIc.js";import"./index-B5BEu-2e.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-Cc2WhLSx.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DZ0cpdk5.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-B4tRYcnk.js";import"./index-CICkVesR.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./article-BAOzVJEM.js";import"./usePaging-VsbTxSU0.js";import"./picker-C4e9dvGe.js";import"./index-B8fzRqRH.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-DLX7Bkcw.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-DoaKouJ5.js";import"./index-EG3kZkys.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-CqvZAHDk.js";import"./index-CgbeKU6K.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./article-B0vJLMlu.js";import"./usePaging-VsbTxSU0.js";import"./picker-ChJwUkIc.js";import"./index-B5BEu-2e.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-DFGf9uAL.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./add-nav.vue_vue_type_script_setup_true_lang-CFFk8uqz.js";import"./index-DZ0cpdk5.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-B4tRYcnk.js";import"./index-CICkVesR.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./article-BAOzVJEM.js";import"./usePaging-VsbTxSU0.js";import"./picker-C4e9dvGe.js";import"./index-B8fzRqRH.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-OoA4Xdeb.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-EG3kZkys.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-CqvZAHDk.js";import"./index-CgbeKU6K.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./article-B0vJLMlu.js";import"./usePaging-VsbTxSU0.js";import"./picker-ChJwUkIc.js";import"./index-B5BEu-2e.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";import"./index.vue_vue_type_script_setup_true_lang-Cc4XuxK2.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-GR4QA_cF.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DZ0cpdk5.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-B4tRYcnk.js";import"./index-CICkVesR.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./article-BAOzVJEM.js";import"./usePaging-VsbTxSU0.js";import"./picker-C4e9dvGe.js";import"./index-B8fzRqRH.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";import"./index.vue_vue_type_script_setup_true_lang-3vCdLVB9.js";export{o as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-fyxAx4v9.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./picker-ChJwUkIc.js";import"./index-CgbeKU6K.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./index-B5BEu-2e.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./index-EG3kZkys.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./usePaging-VsbTxSU0.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-B1MycmMF.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./picker-C4e9dvGe.js";import"./index-CICkVesR.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./index-B8fzRqRH.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./index-DZ0cpdk5.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./usePaging-VsbTxSU0.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-D40iDxQn.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-EG3kZkys.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-CqvZAHDk.js";import"./index-CgbeKU6K.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./article-B0vJLMlu.js";import"./usePaging-VsbTxSU0.js";import"./picker-ChJwUkIc.js";import"./index-B5BEu-2e.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-D9FBD5zP.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-DZ0cpdk5.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-B4tRYcnk.js";import"./index-CICkVesR.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./article-BAOzVJEM.js";import"./usePaging-VsbTxSU0.js";import"./picker-C4e9dvGe.js";import"./index-B8fzRqRH.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
@@ -0,0 +1 @@
import{_ as o}from"./attr-setting.vue_vue_type_script_setup_true_lang-DBG3xOmU.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-Bn5GtvFe.js";import"./attr-CdvqfETs.js";import"./index-DZ0cpdk5.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-B4tRYcnk.js";import"./index-CICkVesR.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./article-BAOzVJEM.js";import"./usePaging-VsbTxSU0.js";import"./picker-C4e9dvGe.js";import"./index-B8fzRqRH.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";import"./content.vue_vue_type_script_setup_true_lang-DX8I8qt1.js";import"./decoration-img-D9TT1t4P.js";import"./attr.vue_vue_type_script_setup_true_lang-B1MycmMF.js";import"./content-D87Vyb_K.js";import"./attr.vue_vue_type_script_setup_true_lang-D9FBD5zP.js";import"./content.vue_vue_type_script_setup_true_lang-BJ9m72NM.js";import"./attr.vue_vue_type_script_setup_true_lang-C8Xjq8fP.js";import"./add-nav.vue_vue_type_script_setup_true_lang-CFFk8uqz.js";import"./content-CT-IOUMn.js";import"./attr.vue_vue_type_script_setup_true_lang-DFGf9uAL.js";import"./content.vue_vue_type_script_setup_true_lang-BDgU8eD6.js";import"./attr.vue_vue_type_script_setup_true_lang-DnkDutJb.js";import"./content-C4GYg1-J.js";import"./decoration-CcVPP3F0.js";import"./attr.vue_vue_type_script_setup_true_lang-D920s4vb.js";import"./index.vue_vue_type_script_setup_true_lang-3vCdLVB9.js";import"./content-BDJ-3Oo2.js";import"./content.vue_vue_type_script_setup_true_lang-DrTey1mi.js";import"./attr.vue_vue_type_script_setup_true_lang-ChKJn1wI.js";import"./content-iFQ7_n9O.js";import"./attr.vue_vue_type_script_setup_true_lang-Cc2WhLSx.js";import"./content.vue_vue_type_script_setup_true_lang-BEXpY337.js";import"./attr.vue_vue_type_script_setup_true_lang-9MDVGbdQ.js";import"./content-BNJH0A6g.js";export{o as default};
@@ -1 +0,0 @@
import{_ as o}from"./attr-setting.vue_vue_type_script_setup_true_lang-CtdOUhBl.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-FZAPJPVx.js";import"./attr-CMxTlG1F.js";import"./index-EG3kZkys.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./picker-CqvZAHDk.js";import"./index-CgbeKU6K.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./article-B0vJLMlu.js";import"./usePaging-VsbTxSU0.js";import"./picker-ChJwUkIc.js";import"./index-B5BEu-2e.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";import"./content.vue_vue_type_script_setup_true_lang-BJrtWBvr.js";import"./decoration-img-fq9C1rE-.js";import"./attr.vue_vue_type_script_setup_true_lang-fyxAx4v9.js";import"./content-DkrZqAgv.js";import"./attr.vue_vue_type_script_setup_true_lang-D40iDxQn.js";import"./content.vue_vue_type_script_setup_true_lang-BbhECIBb.js";import"./attr.vue_vue_type_script_setup_true_lang-BeYayLpN.js";import"./add-nav.vue_vue_type_script_setup_true_lang-DoaKouJ5.js";import"./content-Di7_mIq8.js";import"./attr.vue_vue_type_script_setup_true_lang-DLX7Bkcw.js";import"./content.vue_vue_type_script_setup_true_lang-C3ii9RjK.js";import"./attr.vue_vue_type_script_setup_true_lang-DnkDutJb.js";import"./content-CQ1MSlnv.js";import"./decoration-Chu7a66w.js";import"./attr.vue_vue_type_script_setup_true_lang-BCceAe1Z.js";import"./index.vue_vue_type_script_setup_true_lang-Cc4XuxK2.js";import"./content-CNtNRtZj.js";import"./content.vue_vue_type_script_setup_true_lang-ClhpAPU9.js";import"./attr.vue_vue_type_script_setup_true_lang-ChKJn1wI.js";import"./content-CFxt_S62.js";import"./attr.vue_vue_type_script_setup_true_lang-C8zKp0iH.js";import"./content.vue_vue_type_script_setup_true_lang-DyyrVmQQ.js";import"./attr.vue_vue_type_script_setup_true_lang-9MDVGbdQ.js";import"./content-eEXCq2Xh.js";export{o as default};
@@ -1 +1 @@
import{J as y,s as g}from"./element-plus-BhlMEThZ.js";import{e as b}from"./index-FZAPJPVx.js";import{f as x,ak as o,I as _,a as r,aN as c,J as h,G as i,K as w,at as k}from"./@vue/runtime-core-C6bnekPw.js";import{Q as v}from"./@vue/shared-mAAVTE9n.js";import{y as C}from"./@vue/reactivity-DiY1c2vO.js";const B={class:"pages-setting"},E={class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2 text-xl font-medium"},V=x({__name:"attr-setting",props:{widget:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(e,{emit:m}){const d=m,p=a=>{d("update:content",a)};return(a,N)=>{const f=y,u=g;return o(),_("div",B,[r(f,{shadow:"never",class:"!border-none flex"},{default:c(()=>{var t;return[h("div",E,v((t=e.widget)==null?void 0:t.title),1)]}),_:1}),r(u,{class:"w-full",style:{height:"calc(100% - 60px)"}},{default:c(()=>{var t,n,s,l;return[(o(),i(w,null,[(o(),i(k((n=C(b)[(t=e.widget)==null?void 0:t.name])==null?void 0:n.attr),{content:(s=e.widget)==null?void 0:s.content,styles:(l=e.widget)==null?void 0:l.styles,type:e.type,"onUpdate:content":p},null,40,["content","styles","type"]))],1024))]}),_:1})])}}});export{V as _}; import{J as y,s as g}from"./element-plus-DFTWCWyi.js";import{e as b}from"./index-Bn5GtvFe.js";import{f as x,ak as o,I as _,a as r,aN as c,J as h,G as i,K as w,at as k}from"./@vue/runtime-core-C6bnekPw.js";import{Q as v}from"./@vue/shared-mAAVTE9n.js";import{y as C}from"./@vue/reactivity-DiY1c2vO.js";const B={class:"pages-setting"},E={class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2 text-xl font-medium"},V=x({__name:"attr-setting",props:{widget:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(e,{emit:m}){const d=m,p=a=>{d("update:content",a)};return(a,N)=>{const f=y,u=g;return o(),_("div",B,[r(f,{shadow:"never",class:"!border-none flex"},{default:c(()=>{var t;return[h("div",E,v((t=e.widget)==null?void 0:t.title),1)]}),_:1}),r(u,{class:"w-full",style:{height:"calc(100% - 60px)"}},{default:c(()=>{var t,n,s,l;return[(o(),i(w,null,[(o(),i(k((n=C(b)[(t=e.widget)==null?void 0:t.name])==null?void 0:n.attr),{content:(s=e.widget)==null?void 0:s.content,styles:(l=e.widget)==null?void 0:l.styles,type:e.type,"onUpdate:content":p},null,40,["content","styles","type"]))],1024))]}),_:1})])}}});export{V as _};
@@ -1 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-BCceAe1Z.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index.vue_vue_type_script_setup_true_lang-Cc4XuxK2.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./picker-ChJwUkIc.js";import"./index-CgbeKU6K.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./index-B5BEu-2e.js";import"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import"./index-EG3kZkys.js";import"./index-DZaM0Cil.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C-kxKruc.js";import"./index.vue_vue_type_script_setup_true_lang-yV8imoKs.js";import"./usePaging-VsbTxSU0.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default}; import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-D920s4vb.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index.vue_vue_type_script_setup_true_lang-3vCdLVB9.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./picker-C4e9dvGe.js";import"./index-CICkVesR.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./index-B8fzRqRH.js";import"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import"./index-DZ0cpdk5.js";import"./index-B_l0oBGM.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-CDsvlnsR.js";import"./index.vue_vue_type_script_setup_true_lang-x0oL2ShL.js";import"./usePaging-VsbTxSU0.js";import"./vuedraggable-5bKFmC7X.js";import"./vue-BVs68q8v.js";import"./@vue/compiler-dom-CqayqxS7.js";import"./@vue/compiler-core-CvbQOXIO.js";import"./sortablejs-dsEAUXlE.js";export{o as default};
@@ -1 +1 @@
import{J as V,B as w,C as x,D as b}from"./element-plus-BhlMEThZ.js";import{_ as g}from"./picker-ChJwUkIc.js";import{f as k,ak as E,I as U,a as e,aN as n,J as y,A as B}from"./@vue/runtime-core-C6bnekPw.js";import{y as o}from"./@vue/reactivity-DiY1c2vO.js";const j=k({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:r}){const p=r,i=u,l=B({get:()=>i.content,set:d=>{p("update:content",d)}});return(d,t)=>{const s=x,m=w,_=g,c=V,f=b;return E(),U("div",null,[e(f,{"label-width":"90px",size:"large","label-position":"top"},{default:n(()=>[e(c,{shadow:"never",class:"!border-none flex mt-2"},{default:n(()=>[e(m,{label:"平台名称"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).title,"onUpdate:modelValue":t[0]||(t[0]=a=>o(l).title=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"客服二维码"},{default:n(()=>[y("div",null,[e(_,{modelValue:o(l).qrcode,"onUpdate:modelValue":t[1]||(t[1]=a=>o(l).qrcode=a),"exclude-domain":""},null,8,["modelValue"])])]),_:1}),e(m,{label:"备注"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).remark,"onUpdate:modelValue":t[2]||(t[2]=a=>o(l).remark=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"联系电话"},{default:n(()=>[e(s,{class:"w-[400px]",modelValue:o(l).mobile,"onUpdate:modelValue":t[3]||(t[3]=a=>o(l).mobile=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"服务时间"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).time,"onUpdate:modelValue":t[4]||(t[4]=a=>o(l).time=a)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})])}}});export{j as _}; import{J as V,B as w,C as x,D as b}from"./element-plus-DFTWCWyi.js";import{_ as g}from"./picker-C4e9dvGe.js";import{f as k,ak as E,I as U,a as e,aN as n,J as y,A as B}from"./@vue/runtime-core-C6bnekPw.js";import{y as o}from"./@vue/reactivity-DiY1c2vO.js";const j=k({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:r}){const p=r,i=u,l=B({get:()=>i.content,set:d=>{p("update:content",d)}});return(d,t)=>{const s=x,m=w,_=g,c=V,f=b;return E(),U("div",null,[e(f,{"label-width":"90px",size:"large","label-position":"top"},{default:n(()=>[e(c,{shadow:"never",class:"!border-none flex mt-2"},{default:n(()=>[e(m,{label:"平台名称"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).title,"onUpdate:modelValue":t[0]||(t[0]=a=>o(l).title=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"客服二维码"},{default:n(()=>[y("div",null,[e(_,{modelValue:o(l).qrcode,"onUpdate:modelValue":t[1]||(t[1]=a=>o(l).qrcode=a),"exclude-domain":""},null,8,["modelValue"])])]),_:1}),e(m,{label:"备注"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).remark,"onUpdate:modelValue":t[2]||(t[2]=a=>o(l).remark=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"联系电话"},{default:n(()=>[e(s,{class:"w-[400px]",modelValue:o(l).mobile,"onUpdate:modelValue":t[3]||(t[3]=a=>o(l).mobile=a)},null,8,["modelValue"])]),_:1}),e(m,{label:"服务时间"},{default:n(()=>[e(s,{class:"w-[400px]","show-word-limit":"",maxlength:"20",modelValue:o(l).time,"onUpdate:modelValue":t[4]||(t[4]=a=>o(l).time=a)},null,8,["modelValue"])]),_:1})]),_:1})]),_:1})])}}});export{j as _};
@@ -1 +1 @@
import{J as b,B as y,C as E,G as w,I as B,D as C}from"./element-plus-BhlMEThZ.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-DoaKouJ5.js";import{f as N,ak as k,I as O,a as t,aN as o,J as a,O as u,A as U}from"./@vue/runtime-core-C6bnekPw.js";import{y as s}from"./@vue/reactivity-DiY1c2vO.js";const g={class:"flex-1"},J=N({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(p,{emit:i}){const f=i,_=p,l=U({get:()=>_.content,set:m=>{f("update:content",m)}});return(m,e)=>{const x=E,c=y,d=b,r=B,v=w,V=C;return k(),O("div",null,[t(V,{"label-width":"70px"},{default:o(()=>[t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[t(c,{label:"标题"},{default:o(()=>[t(x,{class:"w-[396px]",modelValue:s(l).title,"onUpdate:modelValue":e[0]||(e[0]=n=>s(l).title=n)},null,8,["modelValue"])]),_:1})]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[5]||(e[5]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),t(v,{modelValue:s(l).style,"onUpdate:modelValue":e[1]||(e[1]=n=>s(l).style=n)},{default:o(()=>[t(r,{value:1},{default:o(()=>[...e[3]||(e[3]=[u("横排",-1)])]),_:1}),t(r,{value:2},{default:o(()=>[...e[4]||(e[4]=[u("竖排",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"菜单"),a("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),a("div",g,[t(I,{modelValue:s(l).data,"onUpdate:modelValue":e[2]||(e[2]=n=>s(l).data=n)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{J as _}; import{J as b,B as y,C as E,G as w,I as B,D as C}from"./element-plus-DFTWCWyi.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-CFFk8uqz.js";import{f as N,ak as k,I as O,a as t,aN as o,J as a,O as u,A as U}from"./@vue/runtime-core-C6bnekPw.js";import{y as s}from"./@vue/reactivity-DiY1c2vO.js";const g={class:"flex-1"},J=N({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(p,{emit:i}){const f=i,_=p,l=U({get:()=>_.content,set:m=>{f("update:content",m)}});return(m,e)=>{const x=E,c=y,d=b,r=B,v=w,V=C;return k(),O("div",null,[t(V,{"label-width":"70px"},{default:o(()=>[t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[t(c,{label:"标题"},{default:o(()=>[t(x,{class:"w-[396px]",modelValue:s(l).title,"onUpdate:modelValue":e[0]||(e[0]=n=>s(l).title=n)},null,8,["modelValue"])]),_:1})]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[5]||(e[5]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),t(v,{modelValue:s(l).style,"onUpdate:modelValue":e[1]||(e[1]=n=>s(l).style=n)},{default:o(()=>[t(r,{value:1},{default:o(()=>[...e[3]||(e[3]=[u("横排",-1)])]),_:1}),t(r,{value:2},{default:o(()=>[...e[4]||(e[4]=[u("竖排",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),t(d,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=a("div",{class:"flex items-end mb-4"},[a("div",{class:"text-base text-[#101010] font-medium"},"菜单"),a("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),a("div",g,[t(I,{modelValue:s(l).data,"onUpdate:modelValue":e[2]||(e[2]=n=>s(l).data=n)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{J as _};
@@ -1 +1 @@
import{J as I,B as O,C as j,g as A,i as F,D as J}from"./element-plus-BhlMEThZ.js";import{_ as z}from"./index-EG3kZkys.js";import{c as G,i as g}from"./index-WGeajlD5.js";import{_ as H}from"./picker-CqvZAHDk.js";import{_ as R}from"./picker-ChJwUkIc.js";import{D as S}from"./vuedraggable-5bKFmC7X.js";import{k as v}from"./lodash-es-C2A-Pj28.js";import{f as T,ak as _,I as h,a as t,aN as a,J as s,G as q,O as K,H as L,A as M}from"./@vue/runtime-core-C6bnekPw.js";import{y as p}from"./@vue/reactivity-DiY1c2vO.js";const P={class:"bg-fill-light flex items-center w-full p-4 mt-4"},Q={class:"ml-3 flex-1"},W={class:"flex-1 flex items-center"},X={class:"drag-move cursor-move ml-auto"},Y={key:0,class:"mt-4"},r=5,ce=T({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:k}){const d=k,m=u,f=M({get:()=>m.content,set:l=>{d("update:content",l)}}),b=()=>{var l;if(((l=m.content.data)==null?void 0:l.length)<r){const e=v(m.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),d("update:content",e)}else g.msgError(`最多添加${r}张图片`)},w=l=>{var c;if(((c=m.content.data)==null?void 0:c.length)<=1)return g.msgError("最少保留一张图片");const e=v(m.content);e.data.splice(l,1),d("update:content",e)};return(l,e)=>{const c=R,y=j,i=O,E=H,U=A,C=G,B=z,D=F,N=I,$=J;return _(),h("div",null,[t($,{"label-width":"70px"},{default:a(()=>[t(N,{shadow:"never",class:"!border-none flex mt-2"},{default:a(()=>{var x;return[e[2]||(e[2]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单"),s("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),t(p(S),{class:"draggable",modelValue:p(f).data,"onUpdate:modelValue":e[0]||(e[0]=o=>p(f).data=o),animation:"300",handle:".drag-move","item-key":"index"},{item:a(({element:o,index:V})=>[(_(),q(B,{key:V,onClose:n=>w(V),class:"w-[467px]"},{default:a(()=>[s("div",P,[t(c,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),s("div",Q,[t(i,{label:"图片名称"},{default:a(()=>[t(y,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{class:"mt-[18px]",label:"图片链接"},{default:a(()=>[t(E,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{label:"是否显示",class:"mt-[18px]"},{default:a(()=>[s("div",W,[t(U,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),s("div",X,[t(C,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"]),((x=u.content.data)==null?void 0:x.length)<r?(_(),h("div",Y,[t(D,{class:"w-full",type:"primary",onClick:b},{default:a(()=>[...e[1]||(e[1]=[K("添加图片",-1)])]),_:1})])):L("",!0)]}),_:1})]),_:1})])}}});export{ce as _}; import{J as I,B as O,C as j,g as A,i as F,D as J}from"./element-plus-DFTWCWyi.js";import{_ as z}from"./index-DZ0cpdk5.js";import{c as G,i as g}from"./index-3gMrVgPp.js";import{_ as H}from"./picker-B4tRYcnk.js";import{_ as R}from"./picker-C4e9dvGe.js";import{D as S}from"./vuedraggable-5bKFmC7X.js";import{k as v}from"./lodash-es-C2A-Pj28.js";import{f as T,ak as _,I as h,a as t,aN as a,J as s,G as q,O as K,H as L,A as M}from"./@vue/runtime-core-C6bnekPw.js";import{y as p}from"./@vue/reactivity-DiY1c2vO.js";const P={class:"bg-fill-light flex items-center w-full p-4 mt-4"},Q={class:"ml-3 flex-1"},W={class:"flex-1 flex items-center"},X={class:"drag-move cursor-move ml-auto"},Y={key:0,class:"mt-4"},r=5,ce=T({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(u,{emit:k}){const d=k,m=u,f=M({get:()=>m.content,set:l=>{d("update:content",l)}}),b=()=>{var l;if(((l=m.content.data)==null?void 0:l.length)<r){const e=v(m.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),d("update:content",e)}else g.msgError(`最多添加${r}张图片`)},w=l=>{var c;if(((c=m.content.data)==null?void 0:c.length)<=1)return g.msgError("最少保留一张图片");const e=v(m.content);e.data.splice(l,1),d("update:content",e)};return(l,e)=>{const c=R,y=j,i=O,E=H,U=A,C=G,B=z,D=F,N=I,$=J;return _(),h("div",null,[t($,{"label-width":"70px"},{default:a(()=>[t(N,{shadow:"never",class:"!border-none flex mt-2"},{default:a(()=>{var x;return[e[2]||(e[2]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单"),s("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),t(p(S),{class:"draggable",modelValue:p(f).data,"onUpdate:modelValue":e[0]||(e[0]=o=>p(f).data=o),animation:"300",handle:".drag-move","item-key":"index"},{item:a(({element:o,index:V})=>[(_(),q(B,{key:V,onClose:n=>w(V),class:"w-[467px]"},{default:a(()=>[s("div",P,[t(c,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),s("div",Q,[t(i,{label:"图片名称"},{default:a(()=>[t(y,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"请输入名称"},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{class:"mt-[18px]",label:"图片链接"},{default:a(()=>[t(E,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])]),_:2},1024),t(i,{label:"是否显示",class:"mt-[18px]"},{default:a(()=>[s("div",W,[t(U,{modelValue:o.is_show,"onUpdate:modelValue":n=>o.is_show=n,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),s("div",X,[t(C,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"]),((x=u.content.data)==null?void 0:x.length)<r?(_(),h("div",Y,[t(D,{class:"w-full",type:"primary",onClick:b},{default:a(()=>[...e[1]||(e[1]=[K("添加图片",-1)])]),_:1})])):L("",!0)]}),_:1})]),_:1})])}}});export{ce as _};
@@ -1 +1 @@
import{J as E,B as C,G as F,I as N,C as B,D as z}from"./element-plus-BhlMEThZ.js";import{_ as G}from"./index.vue_vue_type_script_setup_true_lang-Cc4XuxK2.js";import{_ as I}from"./picker-ChJwUkIc.js";import{f as O,ak as r,G as s,aN as t,a as l,O as p,H as i,J as y,A as j}from"./@vue/runtime-core-C6bnekPw.js";import{y as a}from"./@vue/reactivity-DiY1c2vO.js";const T=O({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(m,{emit:g}){const b=g,x=m,o=j({get:()=>x.content,set:_=>{b("update:content",_)}});return(_,e)=>{const u=N,f=F,d=C,k=B,V=I,v=G,U=E,w=z;return r(),s(w,{ref:"form","label-width":"80px",size:"large"},{default:t(()=>[l(U,{shadow:"never",class:"!border-none flex mt-2"},{default:t(()=>[l(d,{label:"页面标题"},{default:t(()=>[l(f,{modelValue:a(o).title_type,"onUpdate:modelValue":e[0]||(e[0]=n=>a(o).title_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[7]||(e[7]=[p("文字",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[8]||(e[8]=[p("图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.title_type==1?(r(),s(d,{key:0},{default:t(()=>[l(k,{modelValue:a(o).title,"onUpdate:modelValue":e[1]||(e[1]=n=>a(o).title=n),maxlength:"8","show-word-limit":"",class:"w-[300px]",placeholder:"请输入页面标题"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.title_type==2?(r(),s(d,{key:1},{default:t(()=>[l(V,{modelValue:a(o).title_img,"onUpdate:modelValue":e[2]||(e[2]=n=>a(o).title_img=n),limit:1,size:"100px"},null,8,["modelValue"]),e[9]||(e[9]=y("div",{class:"form-tips"},"建议图片尺寸:300px*40px",-1))]),_:1})):i("",!0),m.content.title_type==1?(r(),s(d,{key:2,label:"文字颜色"},{default:t(()=>[l(f,{modelValue:a(o).text_color,"onUpdate:modelValue":e[3]||(e[3]=n=>a(o).text_color=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[10]||(e[10]=[p("白色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[11]||(e[11]=[p("黑色",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1})):i("",!0),l(d,{label:"页面背景"},{default:t(()=>[l(f,{modelValue:a(o).bg_type,"onUpdate:modelValue":e[4]||(e[4]=n=>a(o).bg_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[12]||(e[12]=[p("背景颜色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[13]||(e[13]=[p("背景图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.bg_type==1?(r(),s(d,{key:3},{default:t(()=>[l(v,{modelValue:a(o).bg_color,"onUpdate:modelValue":e[5]||(e[5]=n=>a(o).bg_color=n),"reset-color":"#F5F5F5"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.bg_type==2?(r(),s(d,{key:4},{default:t(()=>[l(V,{modelValue:a(o).bg_image,"onUpdate:modelValue":e[6]||(e[6]=n=>a(o).bg_image=n),limit:1,size:"100px"},null,8,["modelValue"]),e[14]||(e[14]=y("div",{class:"form-tips"},"建议图片尺寸:750px*高度不限",-1))]),_:1})):i("",!0)]),_:1})]),_:1},512)}}});export{T as _}; import{J as E,B as C,G as F,I as N,C as B,D as z}from"./element-plus-DFTWCWyi.js";import{_ as G}from"./index.vue_vue_type_script_setup_true_lang-3vCdLVB9.js";import{_ as I}from"./picker-C4e9dvGe.js";import{f as O,ak as r,G as s,aN as t,a as l,O as p,H as i,J as y,A as j}from"./@vue/runtime-core-C6bnekPw.js";import{y as a}from"./@vue/reactivity-DiY1c2vO.js";const T=O({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(m,{emit:g}){const b=g,x=m,o=j({get:()=>x.content,set:_=>{b("update:content",_)}});return(_,e)=>{const u=N,f=F,d=C,k=B,V=I,v=G,U=E,w=z;return r(),s(w,{ref:"form","label-width":"80px",size:"large"},{default:t(()=>[l(U,{shadow:"never",class:"!border-none flex mt-2"},{default:t(()=>[l(d,{label:"页面标题"},{default:t(()=>[l(f,{modelValue:a(o).title_type,"onUpdate:modelValue":e[0]||(e[0]=n=>a(o).title_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[7]||(e[7]=[p("文字",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[8]||(e[8]=[p("图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.title_type==1?(r(),s(d,{key:0},{default:t(()=>[l(k,{modelValue:a(o).title,"onUpdate:modelValue":e[1]||(e[1]=n=>a(o).title=n),maxlength:"8","show-word-limit":"",class:"w-[300px]",placeholder:"请输入页面标题"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.title_type==2?(r(),s(d,{key:1},{default:t(()=>[l(V,{modelValue:a(o).title_img,"onUpdate:modelValue":e[2]||(e[2]=n=>a(o).title_img=n),limit:1,size:"100px"},null,8,["modelValue"]),e[9]||(e[9]=y("div",{class:"form-tips"},"建议图片尺寸:300px*40px",-1))]),_:1})):i("",!0),m.content.title_type==1?(r(),s(d,{key:2,label:"文字颜色"},{default:t(()=>[l(f,{modelValue:a(o).text_color,"onUpdate:modelValue":e[3]||(e[3]=n=>a(o).text_color=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[10]||(e[10]=[p("白色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[11]||(e[11]=[p("黑色",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1})):i("",!0),l(d,{label:"页面背景"},{default:t(()=>[l(f,{modelValue:a(o).bg_type,"onUpdate:modelValue":e[4]||(e[4]=n=>a(o).bg_type=n)},{default:t(()=>[l(u,{value:"1"},{default:t(()=>[...e[12]||(e[12]=[p("背景颜色",-1)])]),_:1}),l(u,{value:"2"},{default:t(()=>[...e[13]||(e[13]=[p("背景图片",-1)])]),_:1})]),_:1},8,["modelValue"])]),_:1}),m.content.bg_type==1?(r(),s(d,{key:3},{default:t(()=>[l(v,{modelValue:a(o).bg_color,"onUpdate:modelValue":e[5]||(e[5]=n=>a(o).bg_color=n),"reset-color":"#F5F5F5"},null,8,["modelValue"])]),_:1})):i("",!0),m.content.bg_type==2?(r(),s(d,{key:4},{default:t(()=>[l(V,{modelValue:a(o).bg_image,"onUpdate:modelValue":e[6]||(e[6]=n=>a(o).bg_image=n),limit:1,size:"100px"},null,8,["modelValue"]),e[14]||(e[14]=y("div",{class:"form-tips"},"建议图片尺寸:750px*高度不限",-1))]),_:1})):i("",!0)]),_:1})]),_:1},512)}}});export{T as _};
@@ -1 +1 @@
import{J as j,B as A,C as F,g as J,i as S,D as z}from"./element-plus-BhlMEThZ.js";import{_ as G}from"./index-EG3kZkys.js";import{c as H,i as k}from"./index-WGeajlD5.js";import{_ as R}from"./picker-CqvZAHDk.js";import{_ as T}from"./picker-ChJwUkIc.js";import{D as q}from"./vuedraggable-5bKFmC7X.js";import{k as v}from"./lodash-es-C2A-Pj28.js";import{f as K,ak as d,I as b,a as o,aN as s,J as n,G as u,H as r,O as L,A as M}from"./@vue/runtime-core-C6bnekPw.js";import{y as _}from"./@vue/reactivity-DiY1c2vO.js";const P={class:"flex-1"},Q={class:"bg-fill-light w-full p-4 mt-4"},W={class:"flex-1"},X={class:"flex-1 flex items-center"},Y={class:"drag-move cursor-move ml-auto"},Z={key:0,class:"mt-4"},f=5,me=K({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(m,{emit:y}){const p=y,c=m,g=M({get:()=>c.content,set:a=>{p("update:content",a)}}),w=()=>{var a;if(((a=c.content.data)==null?void 0:a.length)<f){const e=v(c.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),p("update:content",e)}else k.msgError(`最多添加${f}张图片`)},E=a=>{var i;if(((i=c.content.data)==null?void 0:i.length)<=1)return k.msgError("最少保留一张图片");const e=v(c.content);e.data.splice(a,1),p("update:content",e)};return(a,e)=>{const i=T,U=R,C=F,h=A,B=J,D=H,N=G,$=S,I=j,O=z;return d(),b("div",null,[o(O,{"label-width":"70px"},{default:s(()=>[o(I,{shadow:"never",class:"!border-none flex mt-2"},{default:s(()=>{var x;return[e[2]||(e[2]=n("div",{class:"flex items-end"},[n("div",{class:"text-base text-[#101010] font-medium"},"图片设置"),n("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),n("div",P,[o(_(q),{class:"draggable",modelValue:_(g).data,"onUpdate:modelValue":e[0]||(e[0]=t=>_(g).data=t),animation:"300",handle:".drag-move"},{item:s(({element:t,index:V})=>[(d(),u(N,{key:V,onClose:l=>E(V),class:"w-full"},{default:s(()=>[n("div",Q,[o(i,{width:"396px",height:"196px",modelValue:t.image,"onUpdate:modelValue":l=>t.image=l,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),n("div",W,[o(h,{class:"mt-[18px]",label:"图片链接"},{default:s(()=>[m.type=="mobile"?(d(),u(U,{key:0,modelValue:t.link,"onUpdate:modelValue":l=>t.link=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0),m.type=="pc"?(d(),u(C,{key:1,placeholder:"请输入链接",modelValue:t.link.path,"onUpdate:modelValue":l=>t.link.path=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0)]),_:2},1024),o(h,{label:"是否显示",class:"mt-[18px] !mb-0"},{default:s(()=>[n("div",X,[o(B,{modelValue:t.is_show,"onUpdate:modelValue":l=>t.is_show=l,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),n("div",Y,[o(D,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),((x=m.content.data)==null?void 0:x.length)<f?(d(),b("div",Z,[o($,{class:"w-full",type:"primary",onClick:w},{default:s(()=>[...e[1]||(e[1]=[L("添加图片",-1)])]),_:1})])):r("",!0)]}),_:1})]),_:1})])}}});export{me as _}; import{J as j,B as A,C as F,g as J,i as S,D as z}from"./element-plus-DFTWCWyi.js";import{_ as G}from"./index-DZ0cpdk5.js";import{c as H,i as k}from"./index-3gMrVgPp.js";import{_ as R}from"./picker-B4tRYcnk.js";import{_ as T}from"./picker-C4e9dvGe.js";import{D as q}from"./vuedraggable-5bKFmC7X.js";import{k as v}from"./lodash-es-C2A-Pj28.js";import{f as K,ak as d,I as b,a as o,aN as s,J as n,G as u,H as r,O as L,A as M}from"./@vue/runtime-core-C6bnekPw.js";import{y as _}from"./@vue/reactivity-DiY1c2vO.js";const P={class:"flex-1"},Q={class:"bg-fill-light w-full p-4 mt-4"},W={class:"flex-1"},X={class:"flex-1 flex items-center"},Y={class:"drag-move cursor-move ml-auto"},Z={key:0,class:"mt-4"},f=5,me=K({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})},type:{type:String,default:"mobile"}},emits:["update:content"],setup(m,{emit:y}){const p=y,c=m,g=M({get:()=>c.content,set:a=>{p("update:content",a)}}),w=()=>{var a;if(((a=c.content.data)==null?void 0:a.length)<f){const e=v(c.content);e.data.push({is_show:"1",image:"",name:"",link:{}}),p("update:content",e)}else k.msgError(`最多添加${f}张图片`)},E=a=>{var i;if(((i=c.content.data)==null?void 0:i.length)<=1)return k.msgError("最少保留一张图片");const e=v(c.content);e.data.splice(a,1),p("update:content",e)};return(a,e)=>{const i=T,U=R,C=F,h=A,B=J,D=H,N=G,$=S,I=j,O=z;return d(),b("div",null,[o(O,{"label-width":"70px"},{default:s(()=>[o(I,{shadow:"never",class:"!border-none flex mt-2"},{default:s(()=>{var x;return[e[2]||(e[2]=n("div",{class:"flex items-end"},[n("div",{class:"text-base text-[#101010] font-medium"},"图片设置"),n("div",{class:"text-xs text-tx-secondary ml-2"}," 最多添加5张,建议图片尺寸:750px*200px ")],-1)),n("div",P,[o(_(q),{class:"draggable",modelValue:_(g).data,"onUpdate:modelValue":e[0]||(e[0]=t=>_(g).data=t),animation:"300",handle:".drag-move"},{item:s(({element:t,index:V})=>[(d(),u(N,{key:V,onClose:l=>E(V),class:"w-full"},{default:s(()=>[n("div",Q,[o(i,{width:"396px",height:"196px",modelValue:t.image,"onUpdate:modelValue":l=>t.image=l,"upload-class":"bg-body","exclude-domain":""},null,8,["modelValue","onUpdate:modelValue"]),n("div",W,[o(h,{class:"mt-[18px]",label:"图片链接"},{default:s(()=>[m.type=="mobile"?(d(),u(U,{key:0,modelValue:t.link,"onUpdate:modelValue":l=>t.link=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0),m.type=="pc"?(d(),u(C,{key:1,placeholder:"请输入链接",modelValue:t.link.path,"onUpdate:modelValue":l=>t.link.path=l},null,8,["modelValue","onUpdate:modelValue"])):r("",!0)]),_:2},1024),o(h,{label:"是否显示",class:"mt-[18px] !mb-0"},{default:s(()=>[n("div",X,[o(B,{modelValue:t.is_show,"onUpdate:modelValue":l=>t.is_show=l,"active-value":"1","inactive-value":"0"},null,8,["modelValue","onUpdate:modelValue"]),n("div",Y,[o(D,{name:"el-icon-Rank",size:"18"})])])]),_:2},1024)])])]),_:2},1032,["onClose"]))]),_:1},8,["modelValue"])]),((x=m.content.data)==null?void 0:x.length)<f?(d(),b("div",Z,[o($,{class:"w-full",type:"primary",onClick:w},{default:s(()=>[...e[1]||(e[1]=[L("添加图片",-1)])]),_:1})])):r("",!0)]}),_:1})]),_:1})])}}});export{me as _};
@@ -1 +1 @@
import{J as B,G as F,I as N,B as O,P as U,Q as g,D as C}from"./element-plus-BhlMEThZ.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-DoaKouJ5.js";import{f as j,ak as d,I as m,a as l,aN as o,J as s,O as x,F as c,ap as v,A as D}from"./@vue/runtime-core-C6bnekPw.js";import{y as n}from"./@vue/reactivity-DiY1c2vO.js";const G={class:"flex-1 mt-4"},P=j({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(V,{emit:b}){const y=b,w=V,a=D({get:()=>w.content,set:u=>{y("update:content",u)}});return(u,e)=>{const r=N,E=F,p=g,i=U,_=O,f=B,k=C;return d(),m("div",null,[l(k,{"label-width":"70px"},{default:o(()=>[l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),l(E,{modelValue:n(a).style,"onUpdate:modelValue":e[0]||(e[0]=t=>n(a).style=t)},{default:o(()=>[l(r,{value:1},{default:o(()=>[...e[4]||(e[4]=[x("固定显示",-1)])]),_:1}),l(r,{value:2},{default:o(()=>[...e[5]||(e[5]=[x("分页滑动",-1)])]),_:1})]),_:1},8,["modelValue"]),l(_,{label:"每行数量",class:"mt-4"},{default:o(()=>[l(i,{modelValue:n(a).per_line,"onUpdate:modelValue":e[1]||(e[1]=t=>n(a).per_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(5,t=>l(p,{key:t,label:t+"个",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1}),l(_,{label:"显示行数"},{default:o(()=>[l(i,{modelValue:n(a).show_line,"onUpdate:modelValue":e[2]||(e[2]=t=>n(a).show_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(2,t=>l(p,{key:t,label:t+"行",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1})]),_:1}),l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[7]||(e[7]=s("div",{class:"flex items-end"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单设置"),s("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),s("div",G,[l(I,{modelValue:n(a).data,"onUpdate:modelValue":e[3]||(e[3]=t=>n(a).data=t)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{P as _}; import{J as B,G as F,I as N,B as O,P as U,Q as g,D as C}from"./element-plus-DFTWCWyi.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-CFFk8uqz.js";import{f as j,ak as d,I as m,a as l,aN as o,J as s,O as x,F as c,ap as v,A as D}from"./@vue/runtime-core-C6bnekPw.js";import{y as n}from"./@vue/reactivity-DiY1c2vO.js";const G={class:"flex-1 mt-4"},P=j({__name:"attr",props:{content:{type:Object,default:()=>({})},styles:{type:Object,default:()=>({})}},emits:["update:content"],setup(V,{emit:b}){const y=b,w=V,a=D({get:()=>w.content,set:u=>{y("update:content",u)}});return(u,e)=>{const r=N,E=F,p=g,i=U,_=O,f=B,k=C;return d(),m("div",null,[l(k,{"label-width":"70px"},{default:o(()=>[l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[6]||(e[6]=s("div",{class:"flex items-end mb-4"},[s("div",{class:"text-base text-[#101010] font-medium"},"展示样式")],-1)),l(E,{modelValue:n(a).style,"onUpdate:modelValue":e[0]||(e[0]=t=>n(a).style=t)},{default:o(()=>[l(r,{value:1},{default:o(()=>[...e[4]||(e[4]=[x("固定显示",-1)])]),_:1}),l(r,{value:2},{default:o(()=>[...e[5]||(e[5]=[x("分页滑动",-1)])]),_:1})]),_:1},8,["modelValue"]),l(_,{label:"每行数量",class:"mt-4"},{default:o(()=>[l(i,{modelValue:n(a).per_line,"onUpdate:modelValue":e[1]||(e[1]=t=>n(a).per_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(5,t=>l(p,{key:t,label:t+"个",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1}),l(_,{label:"显示行数"},{default:o(()=>[l(i,{modelValue:n(a).show_line,"onUpdate:modelValue":e[2]||(e[2]=t=>n(a).show_line=t),style:{width:"300px"}},{default:o(()=>[(d(),m(c,null,v(2,t=>l(p,{key:t,label:t+"行",value:t},null,8,["label","value"])),64))]),_:1},8,["modelValue"])]),_:1})]),_:1}),l(f,{shadow:"never",class:"!border-none flex mt-2"},{default:o(()=>[e[7]||(e[7]=s("div",{class:"flex items-end"},[s("div",{class:"text-base text-[#101010] font-medium"},"菜单设置"),s("div",{class:"text-xs text-tx-secondary ml-2"},"建议图片尺寸:100px*100px")],-1)),s("div",G,[l(I,{modelValue:n(a).data,"onUpdate:modelValue":e[3]||(e[3]=t=>n(a).data=t)},null,8,["modelValue"])])]),_:1})]),_:1})])}}});export{P as _};
@@ -1 +1 @@
import{_ as o}from"./auth.vue_vue_type_script_setup_true_lang-CkortvX5.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./menu-DZMc1hcQ.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./role-DXkM_hVH.js";import"./index-CgbeKU6K.js";export{o as default}; import{_ as o}from"./auth.vue_vue_type_script_setup_true_lang-DEGXli-7.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./menu-CvNSzpcw.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";import"./role-CW3bIpHR.js";import"./index-CICkVesR.js";export{o as default};
@@ -1 +1 @@
import{D as I,s as G,B as J,H as M,Z as O,L as P}from"./element-plus-BhlMEThZ.js";import{m as U}from"./menu-DZMc1hcQ.js";import{a as Z}from"./role-DXkM_hVH.js";import{_ as j}from"./index-CgbeKU6K.js";import{x as z}from"./index-WGeajlD5.js";import{f as Q,ak as k,I as W,a as l,aN as d,aP as X,G as Y,J as y,n as x}from"./@vue/runtime-core-C6bnekPw.js";import{y as c,a as $,q as f,n as r,r as ee}from"./@vue/reactivity-DiY1c2vO.js";const te={class:"edit-popup"},de=Q({__name:"auth",emits:["success","close"],setup(ae,{expose:C,emit:g}){const _=g,o=f(),h=f(),u=f(),b=r(!1),i=r(!0),m=r(!1),v=r([]),p=r([]),s=ee({id:"",name:"",desc:"",sort:0,data_scope:1,menu_id:[]}),E={name:[{required:!0,message:"请输入名称",trigger:["blur"]}]},w=()=>{m.value=!0,U().then(e=>{p.value=e,v.value=z(e),x(()=>{A()}),m.value=!1})},R=()=>{var a,n;const e=(a=o.value)==null?void 0:a.getCheckedKeys(),t=(n=o.value)==null?void 0:n.getHalfCheckedKeys();return e==null||e.unshift.apply(e,t),e},A=()=>{s.menu_id.forEach(e=>{x(()=>{var t;(t=o.value)==null||t.setChecked(e,!0,!1)})})},D=e=>{const t=p.value;for(let a=0;a<t.length;a++)o.value.store.nodesMap[t[a].id].expanded=e},K=e=>{var t,a;e?(t=o.value)==null||t.setCheckedKeys(v.value.map(n=>n.id)):(a=o.value)==null||a.setCheckedKeys([])},B=async()=>{var e,t;await((e=h.value)==null?void 0:e.validate()),s.menu_id=R(),await Z(s),(t=u.value)==null||t.close(),_("success")},V=()=>{_("close")},S=()=>{var e;(e=u.value)==null||e.open()},T=async e=>{for(const t in s)e[t]!=null&&e[t]!=null&&(s[t]=e[t])};return w(),C({open:S,setFormData:T}),(e,t)=>{const a=M,n=O,F=J,L=G,N=I,q=P;return k(),W("div",te,[l(j,{ref_key:"popupRef",ref:u,title:"分配权限",async:!0,width:"550px",onConfirm:B,onClose:V},{default:d(()=>[X((k(),Y(N,{class:"ls-form",ref_key:"formRef",ref:h,rules:E,model:c(s),"label-width":"60px"},{default:d(()=>[l(L,{class:"h-[400px] sm:h-[600px]"},{default:d(()=>[l(F,{label:"权限",prop:"menu_id"},{default:d(()=>[y("div",null,[l(a,{label:"展开/折叠",onChange:D}),l(a,{label:"全选/不全选",onChange:K}),l(a,{modelValue:c(i),"onUpdate:modelValue":t[0]||(t[0]=H=>$(i)?i.value=H:null),label:"父子联动"},null,8,["modelValue"]),y("div",null,[l(n,{ref_key:"treeRef",ref:o,data:c(p),props:{label:"name",children:"children"},"check-strictly":!c(i),"node-key":"id","default-expand-all":c(b),"show-checkbox":""},null,8,["data","check-strictly","default-expand-all"])])])]),_:1})]),_:1})]),_:1},8,["model"])),[[q,c(m)]])]),_:1},512)])}}});export{de as _}; import{D as I,s as G,B as J,H as M,Z as O,L as P}from"./element-plus-DFTWCWyi.js";import{m as U}from"./menu-CvNSzpcw.js";import{a as Z}from"./role-CW3bIpHR.js";import{_ as j}from"./index-CICkVesR.js";import{x as z}from"./index-3gMrVgPp.js";import{f as Q,ak as k,I as W,a as l,aN as d,aP as X,G as Y,J as y,n as x}from"./@vue/runtime-core-C6bnekPw.js";import{y as c,a as $,q as f,n as r,r as ee}from"./@vue/reactivity-DiY1c2vO.js";const te={class:"edit-popup"},de=Q({__name:"auth",emits:["success","close"],setup(ae,{expose:C,emit:g}){const _=g,o=f(),h=f(),u=f(),b=r(!1),i=r(!0),m=r(!1),v=r([]),p=r([]),s=ee({id:"",name:"",desc:"",sort:0,data_scope:1,menu_id:[]}),E={name:[{required:!0,message:"请输入名称",trigger:["blur"]}]},w=()=>{m.value=!0,U().then(e=>{p.value=e,v.value=z(e),x(()=>{A()}),m.value=!1})},R=()=>{var a,n;const e=(a=o.value)==null?void 0:a.getCheckedKeys(),t=(n=o.value)==null?void 0:n.getHalfCheckedKeys();return e==null||e.unshift.apply(e,t),e},A=()=>{s.menu_id.forEach(e=>{x(()=>{var t;(t=o.value)==null||t.setChecked(e,!0,!1)})})},D=e=>{const t=p.value;for(let a=0;a<t.length;a++)o.value.store.nodesMap[t[a].id].expanded=e},K=e=>{var t,a;e?(t=o.value)==null||t.setCheckedKeys(v.value.map(n=>n.id)):(a=o.value)==null||a.setCheckedKeys([])},B=async()=>{var e,t;await((e=h.value)==null?void 0:e.validate()),s.menu_id=R(),await Z(s),(t=u.value)==null||t.close(),_("success")},V=()=>{_("close")},S=()=>{var e;(e=u.value)==null||e.open()},T=async e=>{for(const t in s)e[t]!=null&&e[t]!=null&&(s[t]=e[t])};return w(),C({open:S,setFormData:T}),(e,t)=>{const a=M,n=O,F=J,L=G,N=I,q=P;return k(),W("div",te,[l(j,{ref_key:"popupRef",ref:u,title:"分配权限",async:!0,width:"550px",onConfirm:B,onClose:V},{default:d(()=>[X((k(),Y(N,{class:"ls-form",ref_key:"formRef",ref:h,rules:E,model:c(s),"label-width":"60px"},{default:d(()=>[l(L,{class:"h-[400px] sm:h-[600px]"},{default:d(()=>[l(F,{label:"权限",prop:"menu_id"},{default:d(()=>[y("div",null,[l(a,{label:"展开/折叠",onChange:D}),l(a,{label:"全选/不全选",onChange:K}),l(a,{modelValue:c(i),"onUpdate:modelValue":t[0]||(t[0]=H=>$(i)?i.value=H:null),label:"父子联动"},null,8,["modelValue"]),y("div",null,[l(n,{ref_key:"treeRef",ref:o,data:c(p),props:{label:"name",children:"children"},"check-strictly":!c(i),"node-key":"id","default-expand-all":c(b),"show-checkbox":""},null,8,["data","check-strictly","default-expand-all"])])])]),_:1})]),_:1})]),_:1},8,["model"])),[[q,c(m)]])]),_:1},512)])}}});export{de as _};
@@ -1 +1 @@
import{K as L,D as N,B as K,C as I,P as O,Q as z,i as J,J as Q,M as R,N as S,L as $}from"./element-plus-BhlMEThZ.js";import{_ as j}from"./index.vue_vue_type_script_setup_true_lang-BV5h5xGw.js";import{h as q}from"./index-WGeajlD5.js";import{_ as A}from"./index.vue_vue_type_script_setup_true_lang-fpoITlFG.js";import{w as G}from"./@vue/runtime-dom-DDAG46FW.js";import{g as M,h as H}from"./finance-D4tuF6N5.js";import{u as W}from"./useDictOptions-DCfbzBsR.js";import{u as X}from"./usePaging-VsbTxSU0.js";import{f as v,ak as s,I as h,a as e,aN as n,F as Y,ap as Z,G as w,O as p,aP as ee,J as _}from"./@vue/runtime-core-C6bnekPw.js";import{y as o,a as te,r as oe}from"./@vue/reactivity-DiY1c2vO.js";import{Q as y,o as ae}from"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./lodash-D3kF6u-c.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const ne={class:"flex items-center"},le={class:"flex justify-end mt-4"},ie=v({name:"balanceDetail"}),Xe=v({...ie,setup(re){const l=oe({user_info:"",change_type:"",start_time:"",end_time:""}),{pager:r,getLists:d,resetPage:c,resetParams:C}=X({fetchFun:M,params:l}),{optionsData:x}=W({change_type:{api:H}});return d(),(me,a)=>{const V=L,E=I,m=K,u=z,T=O,k=A,f=J,B=N,g=Q,i=S,D=q,P=R,U=j,F=$;return s(),h("div",null,[e(g,{class:"!border-none",shadow:"never"},{default:n(()=>[e(V,{type:"warning",title:"温馨提示:用户账户变动记录",closable:!1,"show-icon":""}),e(B,{ref:"formRef",class:"mb-[-16px] mt-[16px]",model:o(l),inline:!0},{default:n(()=>[e(m,{class:"w-[280px]",label:"用户信息"},{default:n(()=>[e(E,{modelValue:o(l).user_info,"onUpdate:modelValue":a[0]||(a[0]=t=>o(l).user_info=t),placeholder:"请输入用户账号/昵称/手机号",clearable:"",onKeyup:G(o(c),["enter"])},null,8,["modelValue","onKeyup"])]),_:1}),e(m,{class:"w-[280px]",label:"变动类型"},{default:n(()=>[e(T,{modelValue:o(l).change_type,"onUpdate:modelValue":a[1]||(a[1]=t=>o(l).change_type=t)},{default:n(()=>[e(u,{label:"全部",value:""}),(s(!0),h(Y,null,Z(o(x).change_type,(t,b)=>(s(),w(u,{key:b,label:t,value:b},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),e(m,{label:"记录时间"},{default:n(()=>[e(k,{startTime:o(l).start_time,"onUpdate:startTime":a[2]||(a[2]=t=>o(l).start_time=t),endTime:o(l).end_time,"onUpdate:endTime":a[3]||(a[3]=t=>o(l).end_time=t)},null,8,["startTime","endTime"])]),_:1}),e(m,null,{default:n(()=>[e(f,{type:"primary",onClick:o(c)},{default:n(()=>[...a[5]||(a[5]=[p("查询",-1)])]),_:1},8,["onClick"]),e(f,{onClick:o(C)},{default:n(()=>[...a[6]||(a[6]=[p("重置",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["model"])]),_:1}),e(g,{class:"!border-none mt-4",shadow:"never"},{default:n(()=>[ee((s(),w(P,{size:"large",data:o(r).lists},{default:n(()=>[e(i,{label:"用户账号",prop:"account","min-width":"100"}),e(i,{label:"用户昵称","min-width":"160"},{default:n(({row:t})=>[_("div",ne,[e(D,{class:"flex-none mr-2",src:t.avatar,width:40,height:40,"preview-teleported":"",fit:"contain"},null,8,["src"]),p(" "+y(t.nickname),1)])]),_:1}),e(i,{label:"手机号码",prop:"mobile","min-width":"100"}),e(i,{label:"变动金额",prop:"change_amount","min-width":"100"},{default:n(({row:t})=>[_("span",{class:ae({"text-error":t.action==2})},y(t.change_amount),3)]),_:1}),e(i,{label:"剩余金额",prop:"left_amount","min-width":"100"}),e(i,{label:"变动类型",prop:"change_type_desc","min-width":"120"}),e(i,{label:"来源单号",prop:"source_sn","min-width":"100"}),e(i,{label:"记录时间",prop:"create_time","min-width":"120"})]),_:1},8,["data"])),[[F,o(r).loading]]),_("div",le,[e(U,{modelValue:o(r),"onUpdate:modelValue":a[4]||(a[4]=t=>te(r)?r.value=t:null),onChange:o(d)},null,8,["modelValue","onChange"])])]),_:1})])}}});export{Xe as default}; import{K as L,D as N,B as K,C as I,P as O,Q as z,i as J,J as Q,M as R,N as S,L as $}from"./element-plus-DFTWCWyi.js";import{_ as j}from"./index.vue_vue_type_script_setup_true_lang-CcvIuIWy.js";import{h as q}from"./index-3gMrVgPp.js";import{_ as A}from"./index.vue_vue_type_script_setup_true_lang-DPC_NOWM.js";import{w as G}from"./@vue/runtime-dom-DDAG46FW.js";import{g as M,h as H}from"./finance-DT6A6QwQ.js";import{u as W}from"./useDictOptions-CLpU8GHI.js";import{u as X}from"./usePaging-VsbTxSU0.js";import{f as v,ak as s,I as h,a as e,aN as n,F as Y,ap as Z,G as w,O as p,aP as ee,J as _}from"./@vue/runtime-core-C6bnekPw.js";import{y as o,a as te,r as oe}from"./@vue/reactivity-DiY1c2vO.js";import{Q as y,o as ae}from"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./lodash-D3kF6u-c.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const ne={class:"flex items-center"},le={class:"flex justify-end mt-4"},ie=v({name:"balanceDetail"}),Xe=v({...ie,setup(re){const l=oe({user_info:"",change_type:"",start_time:"",end_time:""}),{pager:r,getLists:d,resetPage:c,resetParams:C}=X({fetchFun:M,params:l}),{optionsData:x}=W({change_type:{api:H}});return d(),(me,a)=>{const V=L,E=I,m=K,u=z,T=O,k=A,f=J,B=N,g=Q,i=S,D=q,P=R,U=j,F=$;return s(),h("div",null,[e(g,{class:"!border-none",shadow:"never"},{default:n(()=>[e(V,{type:"warning",title:"温馨提示:用户账户变动记录",closable:!1,"show-icon":""}),e(B,{ref:"formRef",class:"mb-[-16px] mt-[16px]",model:o(l),inline:!0},{default:n(()=>[e(m,{class:"w-[280px]",label:"用户信息"},{default:n(()=>[e(E,{modelValue:o(l).user_info,"onUpdate:modelValue":a[0]||(a[0]=t=>o(l).user_info=t),placeholder:"请输入用户账号/昵称/手机号",clearable:"",onKeyup:G(o(c),["enter"])},null,8,["modelValue","onKeyup"])]),_:1}),e(m,{class:"w-[280px]",label:"变动类型"},{default:n(()=>[e(T,{modelValue:o(l).change_type,"onUpdate:modelValue":a[1]||(a[1]=t=>o(l).change_type=t)},{default:n(()=>[e(u,{label:"全部",value:""}),(s(!0),h(Y,null,Z(o(x).change_type,(t,b)=>(s(),w(u,{key:b,label:t,value:b},null,8,["label","value"]))),128))]),_:1},8,["modelValue"])]),_:1}),e(m,{label:"记录时间"},{default:n(()=>[e(k,{startTime:o(l).start_time,"onUpdate:startTime":a[2]||(a[2]=t=>o(l).start_time=t),endTime:o(l).end_time,"onUpdate:endTime":a[3]||(a[3]=t=>o(l).end_time=t)},null,8,["startTime","endTime"])]),_:1}),e(m,null,{default:n(()=>[e(f,{type:"primary",onClick:o(c)},{default:n(()=>[...a[5]||(a[5]=[p("查询",-1)])]),_:1},8,["onClick"]),e(f,{onClick:o(C)},{default:n(()=>[...a[6]||(a[6]=[p("重置",-1)])]),_:1},8,["onClick"])]),_:1})]),_:1},8,["model"])]),_:1}),e(g,{class:"!border-none mt-4",shadow:"never"},{default:n(()=>[ee((s(),w(P,{size:"large",data:o(r).lists},{default:n(()=>[e(i,{label:"用户账号",prop:"account","min-width":"100"}),e(i,{label:"用户昵称","min-width":"160"},{default:n(({row:t})=>[_("div",ne,[e(D,{class:"flex-none mr-2",src:t.avatar,width:40,height:40,"preview-teleported":"",fit:"contain"},null,8,["src"]),p(" "+y(t.nickname),1)])]),_:1}),e(i,{label:"手机号码",prop:"mobile","min-width":"100"}),e(i,{label:"变动金额",prop:"change_amount","min-width":"100"},{default:n(({row:t})=>[_("span",{class:ae({"text-error":t.action==2})},y(t.change_amount),3)]),_:1}),e(i,{label:"剩余金额",prop:"left_amount","min-width":"100"}),e(i,{label:"变动类型",prop:"change_type_desc","min-width":"120"}),e(i,{label:"来源单号",prop:"source_sn","min-width":"100"}),e(i,{label:"记录时间",prop:"create_time","min-width":"120"})]),_:1},8,["data"])),[[F,o(r).loading]]),_("div",le,[e(U,{modelValue:o(r),"onUpdate:modelValue":a[4]||(a[4]=t=>te(r)?r.value=t:null),onChange:o(d)},null,8,["modelValue","onChange"])])]),_:1})])}}});export{Xe as default};
@@ -1 +1 @@
import{K as c,J as _,M as d,N as f,i as u}from"./element-plus-BhlMEThZ.js";import{i as h,B as b}from"./index-WGeajlD5.js";import{f as i,ak as w,I as C,a as t,aN as o,O as k}from"./@vue/runtime-core-C6bnekPw.js";import{y,n as E}from"./@vue/reactivity-DiY1c2vO.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const x={class:"cache"},B=i({name:"cache"}),st=i({...B,setup(N){const m=E([{content:"系统缓存",desc:"系统运行过程中产生的各类缓存数据"}]),n=async()=>{await h.confirm("确认清除系统缓存?"),await b(),window.location.reload()};return(g,r)=>{const p=c,a=_,e=f,l=u,s=d;return w(),C("div",x,[t(a,{class:"!border-none",shadow:"never"},{default:o(()=>[t(p,{type:"warning",title:"温馨提示:管理系统运行过程中产生的缓存",closable:!1,"show-icon":""})]),_:1}),t(a,{class:"!border-none mt-4",shadow:"never"},{default:o(()=>[t(s,{data:y(m),size:"large"},{default:o(()=>[t(e,{label:"管理内容",prop:"content","min-width":"130"}),t(e,{label:"内容说明",prop:"desc","min-width":"180"}),t(e,{label:"操作",width:"130",fixed:"right"},{default:o(()=>[t(l,{type:"primary",link:"",onClick:n},{default:o(()=>[...r[0]||(r[0]=[k("清除系统缓存",-1)])]),_:1})]),_:1})]),_:1},8,["data"])]),_:1})])}}});export{st as default}; import{K as c,J as _,M as d,N as f,i as u}from"./element-plus-DFTWCWyi.js";import{i as h,B as b}from"./index-3gMrVgPp.js";import{f as i,ak as w,I as C,a as t,aN as o,O as k}from"./@vue/runtime-core-C6bnekPw.js";import{y,n as E}from"./@vue/reactivity-DiY1c2vO.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const x={class:"cache"},B=i({name:"cache"}),st=i({...B,setup(N){const m=E([{content:"系统缓存",desc:"系统运行过程中产生的各类缓存数据"}]),n=async()=>{await h.confirm("确认清除系统缓存?"),await b(),window.location.reload()};return(g,r)=>{const p=c,a=_,e=f,l=u,s=d;return w(),C("div",x,[t(a,{class:"!border-none",shadow:"never"},{default:o(()=>[t(p,{type:"warning",title:"温馨提示:管理系统运行过程中产生的缓存",closable:!1,"show-icon":""})]),_:1}),t(a,{class:"!border-none mt-4",shadow:"never"},{default:o(()=>[t(s,{data:y(m),size:"large"},{default:o(()=>[t(e,{label:"管理内容",prop:"content","min-width":"130"}),t(e,{label:"内容说明",prop:"desc","min-width":"180"}),t(e,{label:"操作",width:"130",fixed:"right"},{default:o(()=>[t(l,{type:"primary",link:"",onClick:n},{default:o(()=>[...r[0]||(r[0]=[k("清除系统缓存",-1)])]),_:1})]),_:1})]),_:1},8,["data"])]),_:1})])}}});export{st as default};
@@ -1 +1 @@
import{E as p,B as b,C as v,D as E,i as h}from"./element-plus-BhlMEThZ.js";import{u as V,g as C,P,c as B,d as F,_ as I}from"./index-WGeajlD5.js";import{w as L}from"./@vue/runtime-dom-DDAG46FW.js";import{u as N}from"./useLockFn-X4Qce5KO.js";import{_ as z}from"./footer.vue_vue_type_script_setup_true_lang-K_mZhWVZ.js";import{a as R}from"./vue-router-QlpZ4wdW.js";import{f as S,b as q,ak as U,I as D,J as i,a as s,aN as t,O as K}from"./@vue/runtime-core-C6bnekPw.js";import{y as u,q as M,r as O}from"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const T={class:"change-password flex flex-col"},$={class:"flex-1 flex items-center justify-center"},j={class:"change-password-card bg-body rounded-md px-10 py-10 w-[480px]"},G=S({__name:"change-password",setup(J){const n=M(),_=R(),d=V();q(()=>{C()||(p.error("请先登录"),_.push(P.LOGIN))});const e=O({password:"",password_confirm:""}),w={password:[{required:!0,message:"请输入新密码",trigger:"blur"},{min:6,message:"密码长度不能少于6位",trigger:"blur"}],password_confirm:[{required:!0,validator:(a,o,r)=>{o===""?r(new Error("请再次输入密码")):o!==e.password?r(new Error("两次输入的密码不一致")):r()},trigger:"blur"}]},l=async()=>{var a;await((a=n.value)==null?void 0:a.validate());try{await F({password:e.password,password_confirm:e.password_confirm}),p.success("密码修改成功,请重新登录"),d.isPaw=1,await d.logout()}catch(o){p.error((o==null?void 0:o.msg)||(o==null?void 0:o.message)||"密码修改失败")}},{isLock:g,lockFn:x}=N(l);return(a,o)=>{const r=B,c=v,f=b,y=E,k=h;return U(),D("div",T,[i("div",$,[i("div",j,[o[3]||(o[3]=i("div",{class:"text-center text-2xl font-medium mb-2"},"首次登录",-1)),o[4]||(o[4]=i("div",{class:"text-center text-gray-500 text-sm mb-8"},"为了您的账号安全,请修改初始密码",-1)),s(y,{ref_key:"formRef",ref:n,model:e,size:"large",rules:w},{default:t(()=>[s(f,{prop:"password"},{default:t(()=>[s(c,{modelValue:e.password,"onUpdate:modelValue":o[0]||(o[0]=m=>e.password=m),type:"password","show-password":"",placeholder:"请输入新密码"},{prepend:t(()=>[s(r,{name:"el-icon-Lock",size:"16"})]),_:1},8,["modelValue"])]),_:1}),s(f,{prop:"password_confirm"},{default:t(()=>[s(c,{modelValue:e.password_confirm,"onUpdate:modelValue":o[1]||(o[1]=m=>e.password_confirm=m),type:"password","show-password":"",placeholder:"请再次输入新密码",onKeyup:L(l,["enter"])},{prepend:t(()=>[s(r,{name:"el-icon-Lock",size:"16"})]),_:1},8,["modelValue"])]),_:1})]),_:1},8,["model"]),s(k,{type:"primary",size:"large",loading:u(g),onClick:u(x),class:"w-full"},{default:t(()=>[...o[2]||(o[2]=[K(" 确认修改 ",-1)])]),_:1},8,["loading","onClick"])])]),s(z)])}}}),Ro=I(G,[["__scopeId","data-v-bbd4ab41"]]);export{Ro as default}; import{E as p,B as b,C as v,D as E,i as h}from"./element-plus-DFTWCWyi.js";import{u as V,g as C,P,c as B,d as F,_ as I}from"./index-3gMrVgPp.js";import{w as L}from"./@vue/runtime-dom-DDAG46FW.js";import{u as N}from"./useLockFn-X4Qce5KO.js";import{_ as z}from"./footer.vue_vue_type_script_setup_true_lang-C8LDVEj8.js";import{a as R}from"./vue-router-QlpZ4wdW.js";import{f as S,b as q,ak as U,I as D,J as i,a as s,aN as t,O as K}from"./@vue/runtime-core-C6bnekPw.js";import{y as u,q as M,r as O}from"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";const T={class:"change-password flex flex-col"},$={class:"flex-1 flex items-center justify-center"},j={class:"change-password-card bg-body rounded-md px-10 py-10 w-[480px]"},G=S({__name:"change-password",setup(J){const n=M(),_=R(),d=V();q(()=>{C()||(p.error("请先登录"),_.push(P.LOGIN))});const e=O({password:"",password_confirm:""}),w={password:[{required:!0,message:"请输入新密码",trigger:"blur"},{min:6,message:"密码长度不能少于6位",trigger:"blur"}],password_confirm:[{required:!0,validator:(a,o,r)=>{o===""?r(new Error("请再次输入密码")):o!==e.password?r(new Error("两次输入的密码不一致")):r()},trigger:"blur"}]},l=async()=>{var a;await((a=n.value)==null?void 0:a.validate());try{await F({password:e.password,password_confirm:e.password_confirm}),p.success("密码修改成功,请重新登录"),d.isPaw=1,await d.logout()}catch(o){p.error((o==null?void 0:o.msg)||(o==null?void 0:o.message)||"密码修改失败")}},{isLock:g,lockFn:x}=N(l);return(a,o)=>{const r=B,c=v,f=b,y=E,k=h;return U(),D("div",T,[i("div",$,[i("div",j,[o[3]||(o[3]=i("div",{class:"text-center text-2xl font-medium mb-2"},"首次登录",-1)),o[4]||(o[4]=i("div",{class:"text-center text-gray-500 text-sm mb-8"},"为了您的账号安全,请修改初始密码",-1)),s(y,{ref_key:"formRef",ref:n,model:e,size:"large",rules:w},{default:t(()=>[s(f,{prop:"password"},{default:t(()=>[s(c,{modelValue:e.password,"onUpdate:modelValue":o[0]||(o[0]=m=>e.password=m),type:"password","show-password":"",placeholder:"请输入新密码"},{prepend:t(()=>[s(r,{name:"el-icon-Lock",size:"16"})]),_:1},8,["modelValue"])]),_:1}),s(f,{prop:"password_confirm"},{default:t(()=>[s(c,{modelValue:e.password_confirm,"onUpdate:modelValue":o[1]||(o[1]=m=>e.password_confirm=m),type:"password","show-password":"",placeholder:"请再次输入新密码",onKeyup:L(l,["enter"])},{prepend:t(()=>[s(r,{name:"el-icon-Lock",size:"16"})]),_:1},8,["modelValue"])]),_:1})]),_:1},8,["model"]),s(k,{type:"primary",size:"large",loading:u(g),onClick:u(x),class:"w-full"},{default:t(()=>[...o[2]||(o[2]=[K(" 确认修改 ",-1)])]),_:1},8,["loading","onClick"])])]),s(z)])}}}),Ro=I(G,[["__scopeId","data-v-bbd4ab41"]]);export{Ro as default};
@@ -1 +1 @@
import{r as t}from"./index-WGeajlD5.js";function o(e){return t.get({url:"/tools.generator/generateTable",params:e})}function n(e){return t.get({url:"/tools.generator/dataTable",params:e})}function a(e){return t.post({url:"/tools.generator/selectTable",params:e})}function l(e){return t.get({url:"/tools.generator/detail",params:e})}function s(e){return t.post({url:"/tools.generator/syncColumn",params:e})}function u(e){return t.post({url:"/tools.generator/delete",params:e})}function g(e){return t.post({url:"/tools.generator/edit",params:e})}function i(e){return t.post({url:"/tools.generator/preview",params:e})}function c(e){return t.post({url:"/tools.generator/generate",params:e})}function f(){return t.get({url:"/tools.generator/getModels"})}export{f as a,o as b,u as c,i as d,c as e,n as f,g,a as h,s,l as t}; import{r as t}from"./index-3gMrVgPp.js";function o(e){return t.get({url:"/tools.generator/generateTable",params:e})}function n(e){return t.get({url:"/tools.generator/dataTable",params:e})}function a(e){return t.post({url:"/tools.generator/selectTable",params:e})}function l(e){return t.get({url:"/tools.generator/detail",params:e})}function s(e){return t.post({url:"/tools.generator/syncColumn",params:e})}function u(e){return t.post({url:"/tools.generator/delete",params:e})}function g(e){return t.post({url:"/tools.generator/edit",params:e})}function i(e){return t.post({url:"/tools.generator/preview",params:e})}function c(e){return t.post({url:"/tools.generator/generate",params:e})}function f(){return t.get({url:"/tools.generator/getModels"})}export{f as a,o as b,u as c,i as d,c as e,n as f,g,a as h,s,l as t};
@@ -1 +1 @@
import{_ as o}from"./code-preview.vue_vue_type_script_setup_true_lang-CkC3yGlQ.js";import"./element-plus-BhlMEThZ.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-ouZ25BHH.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-WGeajlD5.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";export{o as default}; import{_ as o}from"./code-preview.vue_vue_type_script_setup_true_lang-SrzZFBF1.js";import"./element-plus-DFTWCWyi.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@vue/runtime-core-C6bnekPw.js";import"./@vue/reactivity-DiY1c2vO.js";import"./@vue/shared-mAAVTE9n.js";import"./@element-plus/icons-vue-HOEUG8sr.js";import"./lodash-es-C2A-Pj28.js";import"./@popperjs/core-C5az9QE8.js";import"./dayjs-DG77mNTn.js";import"./@ctrl/tinycolor-BuyEbX8F.js";import"./async-validator-CFA_igpM.js";import"./normalize-wheel-es-BQoi3Ox2.js";import"./index-3gMrVgPp.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-QlpZ4wdW.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./css-color-function-DI01JAaZ.js";import"./balanced-match-BdS7OldZ.js";import"./color-B2zxaWkI.js";import"./clone-DBZ6_OiU.js";import"./color-convert-OrFsTA_V.js";import"./color-name-Dju3oUBS.js";import"./color-string-pUQDDJII.js";import"./ms-CzQ2E3wO.js";import"./vue-clipboard3-DByT_rEQ.js";import"./clipboard-CHgxszqY.js";import"./echarts-CNLwa9wG.js";import"./tslib-BDyQ-Jie.js";import"./zrender-DRNXw7y3.js";import"./highlight.js-Bxt7hFFy.js";import"./@highlightjs/vue-plugin-C4onkBvW.js";export{o as default};
@@ -1 +1 @@
import{m as B,l as N,s as T,i as $,V as j}from"./element-plus-BhlMEThZ.js";import{c as D,i as d}from"./index-WGeajlD5.js";import{u as F}from"./vue-clipboard3-DByT_rEQ.js";import{f as S,ar as U,ak as c,I as i,a as t,aN as a,F as A,ap as G,G as I,J as u,O as J,A as L}from"./@vue/runtime-core-C6bnekPw.js";import{a as p,y as _,n as O}from"./@vue/reactivity-DiY1c2vO.js";const P={class:"code-preview"},R={class:"flex",style:{height:"50vh"}},W=S({__name:"code-preview",props:{modelValue:{type:Boolean},code:{}},emits:["update:modelValue"],setup(r,{emit:f}){const V=r,b=f,{toClipboard:g}=F(),n=O("index0"),h=async l=>{try{await g(l),d.msgSuccess("复制成功")}catch{d.msgError("复制失败")}},s=L({get(){return V.modelValue},set(l){b("update:modelValue",l)}});return(l,e)=>{const v=U("highlightjs"),y=T,k=D,C=$,x=N,E=B,w=j;return c(),i("div",P,[t(w,{modelValue:_(s),"onUpdate:modelValue":e[1]||(e[1]=o=>p(s)?s.value=o:null),width:"900px",title:"代码预览"},{default:a(()=>[t(E,{modelValue:_(n),"onUpdate:modelValue":e[0]||(e[0]=o=>p(n)?n.value=o:null)},{default:a(()=>[(c(!0),i(A,null,G(r.code,(o,m)=>(c(),I(x,{label:o.name,name:`index${m}`,key:m},{default:a(()=>[u("div",R,[t(y,{class:"flex-1"},{default:a(()=>[t(v,{autodetect:"",code:o.content},null,8,["code"])]),_:2},1024),u("div",null,[t(C,{onClick:q=>h(o.content),type:"primary",link:""},{icon:a(()=>[t(k,{name:"el-icon-CopyDocument"})]),default:a(()=>[e[2]||(e[2]=J(" 复制 ",-1))]),_:1},8,["onClick"])])])]),_:2},1032,["label","name"]))),128))]),_:1},8,["modelValue"])]),_:1},8,["modelValue"])])}}});export{W as _}; import{m as B,l as N,s as T,i as $,V as j}from"./element-plus-DFTWCWyi.js";import{c as D,i as d}from"./index-3gMrVgPp.js";import{u as F}from"./vue-clipboard3-DByT_rEQ.js";import{f as S,ar as U,ak as c,I as i,a as t,aN as a,F as A,ap as G,G as I,J as u,O as J,A as L}from"./@vue/runtime-core-C6bnekPw.js";import{a as p,y as _,n as O}from"./@vue/reactivity-DiY1c2vO.js";const P={class:"code-preview"},R={class:"flex",style:{height:"50vh"}},W=S({__name:"code-preview",props:{modelValue:{type:Boolean},code:{}},emits:["update:modelValue"],setup(r,{emit:f}){const V=r,b=f,{toClipboard:g}=F(),n=O("index0"),h=async l=>{try{await g(l),d.msgSuccess("复制成功")}catch{d.msgError("复制失败")}},s=L({get(){return V.modelValue},set(l){b("update:modelValue",l)}});return(l,e)=>{const v=U("highlightjs"),y=T,k=D,C=$,x=N,E=B,w=j;return c(),i("div",P,[t(w,{modelValue:_(s),"onUpdate:modelValue":e[1]||(e[1]=o=>p(s)?s.value=o:null),width:"900px",title:"代码预览"},{default:a(()=>[t(E,{modelValue:_(n),"onUpdate:modelValue":e[0]||(e[0]=o=>p(n)?n.value=o:null)},{default:a(()=>[(c(!0),i(A,null,G(r.code,(o,m)=>(c(),I(x,{label:o.name,name:`index${m}`,key:m},{default:a(()=>[u("div",R,[t(y,{class:"flex-1"},{default:a(()=>[t(v,{autodetect:"",code:o.content},null,8,["code"])]),_:2},1024),u("div",null,[t(C,{onClick:q=>h(o.content),type:"primary",link:""},{icon:a(()=>[t(k,{name:"el-icon-CopyDocument"})]),default:a(()=>[e[2]||(e[2]=J(" 复制 ",-1))]),_:1},8,["onClick"])])])]),_:2},1032,["label","name"]))),128))]),_:1},8,["modelValue"])]),_:1},8,["modelValue"])])}}});export{W as _};
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More