Compare commits

...
14 Commits
Author SHA1 Message Date
Your Name 8b129b3823 更新 2026-06-15 09:12:32 +08:00
Your Name 4ba75e5a94 更新 2026-06-15 09:12:15 +08:00
Your Name 8ae5b4eead 更新 2026-06-12 18:07:21 +08:00
long e5959fd89a 1 2026-06-11 14:26:41 +08:00
Your Name 08249451a7 i
Merge branch 'master20260610'
2026-06-10 17:30:43 +08:00
Your Name 79ae055bb6 更新 2026-06-10 17:30:05 +08:00
Your Name c0cc23393e 更新 2026-06-10 15:30:38 +08:00
Your Name 470ba419e3 更新 2026-06-10 15:29:07 +08:00
Your Name 1c0cd84355 更新 2026-06-10 15:03:39 +08:00
Your Name f2e2f84e18 i
Merge branch 'master' of https://gitee.com/v_cms/zyt
2026-06-10 14:38:34 +08:00
long f7e52bcafc Merge branch '20260610-long' 2026-06-10 14:37:44 +08:00
long 2e59e883b8 订单详情优化 2026-06-10 14:37:32 +08:00
Your Name 9f1801771e 更新 2026-06-10 14:25:22 +08:00
Your Name 1adf8ccf4b 更新 2026-06-10 10:28:58 +08:00
403 changed files with 4217 additions and 2923 deletions
+2 -2
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>后台管理系统</title>
<title>中医问诊管理后台</title>
<style>
* {
margin: 0;
@@ -29,7 +29,7 @@
stroke-dasharray: 90, 150;
stroke-dashoffset: 0;
stroke-width: 2;
stroke: #4073fa;
stroke: #0EA5E9;
stroke-linecap: round;
}
+31
View File
@@ -181,6 +181,37 @@ export function commissionSettlementConfirmRevoke(params: Record<string, any>) {
return request.post({ url: '/stats.commissionSettlement/confirmRevoke', params })
}
/** 复诊接诊率(按月):当月 N 诊接诊率,部门 → 医助分组 + 合计;剔除「继承」指派 */
export function revisitRateOverview(params: { month?: string; dept_ids?: string }) {
return request.get({ url: '/stats.revisitRate/overview', params })
}
/** 复诊接诊率:部门下拉(前端组树) */
export function revisitRateDeptOptions() {
return request.get({ url: '/stats.revisitRate/deptOptions' })
}
/** 复诊接诊率:「被指派数」点击下钻(按诊单聚合明细) */
export function revisitRateAssignLines(params: {
month?: string
dept_ids?: string
assistant_id?: number
dept_id?: number
}) {
return request.get({ url: '/stats.revisitRate/assignLines', params })
}
/** 复诊接诊率:「N 诊单数」点击下钻(具体订单明细) */
export function revisitRateVisitOrderLines(params: {
month?: string
slot: number
dept_ids?: string
assistant_id?: number
dept_id?: number
}) {
return request.get({ url: '/stats.revisitRate/visitOrderLines', params })
}
/** 医助个人业绩概览 */
export function assistantPerformanceOverview(params: {
time_type?: string
+2
View File
@@ -468,6 +468,8 @@ export function prescriptionOrderAddPayOrder(params: {
pay_amount: number
pay_remark?: string
completion_request?: number
/** 创建方式:fubei 付呗(默认) / express_cod 快递代收 */
pay_create_type?: 'fubei' | 'express_cod'
}) {
return request.post({ url: '/tcm.prescriptionOrder/addPayOrder', params })
}
+15 -12
View File
@@ -1,28 +1,31 @@
const defaultSetting = {
showCrumb: true, // 是否显示面包屑
showLogo: false, // 是否显示logo
showLogo: true, // 是否显示logo
isUniqueOpened: true, //只展开一个一级菜单
sideWidth: 183, //侧边栏宽度
sideTheme: 'dark', //侧边栏主题
sideDarkColor: '#1d2124', //侧边栏深色主题颜色
sideWidth: 200, //侧边栏宽度
sideTheme: 'light', //侧边栏主题
sideDarkColor: '#0369A1', //侧边栏深色主题颜色(深天蓝)
openMultipleTabs: true, // 是否开启多标签tab栏
theme: '#4A5DFF', //主题色
successTheme: '#67c23a', //成功主题色
warningTheme: '#e6a23c', //警告主题色
dangerTheme: '#f56c6c', //危险主题色
errorTheme: '#f56c6c', //错误主题色
infoTheme: '#909399' //信息主题色
theme: '#0EA5E9', //主题色(天蓝)
successTheme: '#16A34A', //成功主题色
warningTheme: '#D97706', //警告主题色
dangerTheme: '#DC2626', //危险主题色
errorTheme: '#DC2626', //错误主题色
infoTheme: '#64748B' //信息主题色
}
/** 本地 setting 缓存结构版本。提升后仅对低于该版本的老缓存执行 SETTING_SCHEMA_MIGRATIONS */
export const SETTING_SCHEMA_VERSION = 1
export const SETTING_SCHEMA_VERSION = 4
/**
* 按版本写入 defaultSetting 中的键(老用户 localStorage 会长期盖住 config 默认值)。
* 以后若要再推一批新默认值:把 SETTING_SCHEMA_VERSION +1,并为本版本追加一条迁移键列表。
*/
export const SETTING_SCHEMA_MIGRATIONS: Record<number, (keyof typeof defaultSetting)[]> = {
1: ['sideTheme', 'sideDarkColor']
1: ['sideTheme', 'sideDarkColor'],
2: ['theme', 'successTheme', 'warningTheme', 'dangerTheme', 'errorTheme', 'infoTheme', 'sideTheme', 'sideDarkColor', 'showLogo', 'sideWidth'],
3: ['theme', 'sideTheme', 'sideDarkColor', 'sideWidth'],
4: ['theme', 'sideDarkColor']
}
export default defaultSetting
@@ -26,17 +26,19 @@ useWatchRoute((route) => {
.app-breadcrumb {
:deep(.el-breadcrumb__item) {
.el-breadcrumb__inner {
color: #303133;
color: var(--el-text-color-regular);
font-weight: 400;
transition: color 0.2s ease;
}
&:last-child .el-breadcrumb__inner {
color: var(--health-primary-dark, var(--el-color-primary));
font-weight: 500;
}
&:last-child .el-breadcrumb__inner {
color: #303133;
}
}
:deep(.el-breadcrumb__separator) {
color: #606266;
color: var(--el-text-color-secondary);
}
}
</style>
@@ -1,8 +1,14 @@
<template>
<header class="header">
<div class="navbar">
<div class="flex-1 flex">
<div class="navbar-item">
<div class="navbar-left flex-1 flex items-center min-w-0">
<side-logo
v-if="settingStore.showLogo"
class="navbar-logo shrink-0"
:show-title="!isCollapsed || isMobile"
theme="light"
/>
<div class="navbar-item shrink-0">
<el-tooltip
class="box-item"
effect="dark"
@@ -12,16 +18,19 @@
<fold />
</el-tooltip>
</div>
<div class="navbar-item">
<div class="navbar-item shrink-0">
<el-tooltip class="box-item" effect="dark" content="刷新" placement="bottom">
<refresh />
</el-tooltip>
</div>
<div class="flex items-center px-2" v-if="!isMobile && settingStore.showCrumb">
<div
class="flex items-center px-2 min-w-0"
v-if="!isMobile && settingStore.showCrumb"
>
<breadcrumb />
</div>
</div>
<div class="flex">
<div class="navbar-right flex shrink-0">
<div class="navbar-item" v-if="!isMobile">
<el-tooltip
class="box-item"
@@ -47,7 +56,6 @@
</div>
</div>
</div>
<multiple-tabs v-if="settingStore.openMultipleTabs" />
</header>
</template>
@@ -57,11 +65,11 @@ import { useFullscreen } from '@vueuse/core'
import useAppStore from '@/stores/modules/app'
import useSettingStore from '@/stores/modules/setting'
import SideLogo from '../sidebar/logo.vue'
import Setting from '../setting/index.vue'
import Breadcrumb from './breadcrumb.vue'
import Fold from './fold.vue'
import FullScreen from './full-screen.vue'
import MultipleTabs from './multiple-tabs.vue'
import Refresh from './refresh.vue'
import UserDropDown from './user-drop-down.vue'
@@ -73,11 +81,31 @@ const { isFullscreen } = useFullscreen()
</script>
<style lang="scss">
.header {
background: var(--el-bg-color);
border-bottom: 1px solid var(--health-border, var(--el-border-color-lighter));
box-shadow: 0 1px 2px rgba(15, 23, 42, 0.03);
}
.navbar {
height: var(--navbar-height);
@apply flex px-2 bg-body;
@apply flex px-4;
.navbar-logo {
margin-right: 4px;
border-bottom: none !important;
padding-right: 8px !important;
}
.navbar-item {
@apply h-full flex justify-center items-center hover:bg-page;
@apply h-10 flex justify-center items-center cursor-pointer;
min-width: 40px;
border-radius: 8px;
transition: background-color 0.2s ease;
&:hover {
background-color: var(--el-fill-color);
}
}
}
</style>
@@ -1,5 +1,5 @@
<template>
<div class="app-tabs pl-4 flex bg-body">
<div class="app-tabs flex bg-body">
<div class="flex-1 min-w-0">
<el-tabs
:model-value="currentTab"
@@ -13,7 +13,7 @@
</el-tabs>
</div>
<el-dropdown @command="handleCommand">
<span class="flex items-center px-3">
<span class="flex items-center px-3 cursor-pointer tab-dropdown">
<icon :size="16" name="el-icon-arrow-down" />
</span>
<template #dropdown>
@@ -58,9 +58,22 @@ const handleCommand = (command: any) => {
}
}
</script>
<style lang="scss" scoped>
.app-tabs {
@apply border-t border-br;
padding: 0 16px;
background: var(--el-bg-color);
border-bottom: 1px solid var(--health-border, var(--el-border-color-lighter));
.tab-dropdown {
height: 40px;
border-radius: 6px;
transition: background-color 0.2s ease;
&:hover {
background-color: var(--el-fill-color);
}
}
:deep(.el-tabs) {
height: 40px;
.el-tabs {
@@ -80,35 +93,19 @@ const handleCommand = (command: any) => {
}
&__item {
font-weight: normal;
padding: 0 15px !important;
padding: 0 16px !important;
box-sizing: border-box;
color: var(--el-text-color-secondary);
transition: color 0.2s ease;
&.is-active {
color: var(--el-text-color-primary);
background-color: var(--el-color-primary-light-9);
&::before {
content: '';
display: inline-block;
width: 6px;
height: 6px;
background-color: var(--el-color-primary);
margin-right: 6px;
border-radius: 50%;
vertical-align: 2px;
}
&::after {
position: absolute;
content: '';
display: block;
top: 0;
height: 2px;
left: 0;
width: 100%;
background-color: var(--el-color-primary);
}
color: var(--health-primary-dark, var(--el-color-primary));
font-weight: 500;
}
.is-icon-close {
color: var(--el-text-color-regular);
color: var(--el-text-color-secondary);
vertical-align: -2px;
border-radius: 50%;
transition: all 0.2s ease;
&:hover {
color: var(--color-white);
background-color: var(--el-color-danger);
@@ -116,7 +113,9 @@ const handleCommand = (command: any) => {
}
}
&__active-bar {
display: none;
height: 2px;
border-radius: 2px;
background-color: var(--health-primary, var(--el-color-primary));
}
}
}
+13 -3
View File
@@ -1,7 +1,7 @@
<template>
<main class="main-wrap h-full bg-page">
<main class="main-wrap h-full">
<el-scrollbar>
<div class="px-2 py-4">
<div class="main-content">
<router-view v-if="isRouteShow" v-slot="{ Component, route }">
<keep-alive :include="includeList" :max="20">
<component :is="Component" :key="route.fullPath" />
@@ -24,4 +24,14 @@ const isRouteShow = computed(() => appStore.isRouteShow)
const includeList = computed(() => (settingStore.openMultipleTabs ? tabsStore.getCacheTabList : []))
</script>
<style></style>
<style lang="scss" scoped>
.main-wrap {
height: 100%;
background: var(--el-bg-color);
}
.main-content {
padding: 16px 20px 24px;
min-height: 100%;
}
</style>
@@ -100,7 +100,7 @@ import theme_light from '@/assets/images/theme_white.png'
import useSettingStore from '@/stores/modules/setting'
const settingStore = useSettingStore()
const predefineColors = ref(['#409EFF', '#28C76F', '#EA5455', '#FF9F43', '#01CFE8', '#4A5DFF'])
const predefineColors = ref(['#0EA5E9', '#38BDF8', '#0284C7', '#16A34A', '#DC2626', '#0369A1'])
const sideThemeList = [
{
type: 'dark',
@@ -44,11 +44,13 @@ const handleClick = () => {
overflow: hidden;
cursor: pointer;
user-select: none;
@apply flex items-center p-2 relative;
@apply flex items-center px-3 relative;
.logo-title {
width: 70%;
position: absolute;
@apply text-xl;
@apply text-base font-medium;
color: var(--el-text-color-primary);
}
.title-width-enter-active {
@@ -67,33 +67,53 @@ const themeClass = computed(() => `theme-${props.theme}`)
&.theme-dark {
.el-menu {
:deep(.el-menu-item) {
margin: 2px 10px;
border-radius: 6px;
&.is-active {
@apply bg-primary border-primary;
background-color: rgba(255, 255, 255, 0.12);
color: #fff;
font-weight: 500;
}
}
:deep(.el-sub-menu__title) {
margin: 2px 10px;
border-radius: 6px;
}
}
:deep(.el-menu--collapse) {
.el-sub-menu.is-active .el-sub-menu__title {
@apply bg-primary #{!important};
background-color: rgba(255, 255, 255, 0.12) !important;
}
}
}
&.theme-light {
:deep(.el-menu) {
.el-menu-item {
border-color: transparent;
margin: 2px 10px;
border-radius: 6px;
color: var(--el-text-color-regular);
&.is-active {
@apply bg-primary-light-9 border-r-2 border-primary;
background-color: var(--health-primary-light, var(--el-color-primary-light-9));
color: var(--health-primary-dark, var(--el-color-primary));
font-weight: 500;
}
}
.el-sub-menu__title {
margin: 2px 10px;
border-radius: 6px;
color: var(--el-text-color-regular);
}
.el-menu-item:hover,
.el-sub-menu__title:hover {
color: var(--el-color-primary);
background-color: var(--el-fill-color);
color: var(--el-text-color-primary);
}
}
}
.el-menu {
border-right: none;
background: transparent;
padding: 10px 0;
&:not(.el-menu--collapse) {
width: var(--aside-width);
}
@@ -1,6 +1,10 @@
<template>
<div class="side" :style="sideStyle">
<side-logo v-if="settingStore.showLogo" :show-title="!isCollapsed" :theme="sideTheme" />
<side-logo
v-if="settingStore.showLogo && appStore.isMobile"
:show-title="!isCollapsed"
:theme="sideTheme"
/>
<side-menu
:routes="routes"
:is-collapsed="isCollapsed"
@@ -45,9 +49,9 @@ const sideStyle = computed(() => {
})
const menuProp = computed(() => {
return {
backgroundColor: sideTheme.value == 'dark' ? settingStore.sideDarkColor : '',
textColor: sideTheme.value == 'dark' ? 'var(--el-color-white)' : '',
activeTextColor: sideTheme.value == 'dark' ? 'var(--el-color-white)' : ''
backgroundColor: sideTheme.value == 'dark' ? settingStore.sideDarkColor : 'transparent',
textColor: sideTheme.value == 'dark' ? 'rgba(255,255,255,0.85)' : '',
activeTextColor: sideTheme.value == 'dark' ? '#ffffff' : ''
}
})
const handleSelect = () => {
@@ -60,8 +64,8 @@ const handleSelect = () => {
<style lang="scss" scoped>
.side {
position: relative;
z-index: 999;
@apply border-r border-br-light h-full flex flex-col;
background-color: var(--side-dark-color, var(--el-bg-color));
z-index: 10;
@apply h-full flex flex-col;
background-color: var(--side-dark-color, var(--health-bg-sidebar, var(--el-bg-color)));
}
</style>
+28 -9
View File
@@ -1,23 +1,42 @@
<template>
<div class="layout-default flex h-screen w-full">
<!-- shrink-0避免主内容区宽表格/图表把侧栏压缩到折叠宽度 -->
<div class="app-aside shrink-0">
<layout-sidebar />
<div class="layout-default flex flex-col h-screen w-full bg-page">
<div class="app-header shrink-0">
<layout-header />
</div>
<div class="flex-1 flex flex-col min-w-0">
<div class="app-header">
<layout-header />
<div class="layout-body flex flex-1 min-h-0">
<div class="app-aside shrink-0">
<layout-sidebar />
</div>
<div class="app-main flex-1 min-h-0">
<layout-main />
<div class="app-content flex flex-1 flex-col min-w-0 bg-body">
<multiple-tabs v-if="settingStore.openMultipleTabs" />
<div class="app-main flex-1 min-h-0">
<layout-main />
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import useSettingStore from '@/stores/modules/setting'
import LayoutHeader from './components/header/index.vue'
import MultipleTabs from './components/header/multiple-tabs.vue'
import LayoutMain from './components/main.vue'
import LayoutSidebar from './components/sidebar/index.vue'
const settingStore = useSettingStore()
</script>
<style lang="scss" scoped>
.layout-body {
flex: 1;
min-height: 0;
}
.app-content {
border-left: 1px solid var(--health-border, var(--el-border-color-lighter));
}
</style>
+34 -31
View File
@@ -1,43 +1,46 @@
:root.dark {
color-scheme: dark;
--table-header-bg-color: var(--el-bg-color);
--el-bg-color-page: #0a0a0a;
--el-bg-color: #1d2124;
--el-bg-color-overlay: #1d1e1f;
--el-text-color-primary: #e5eaf3;
--el-text-color-regular: #cfd3dc;
--el-text-color-secondary: #a3a6ad;
--el-text-color-placeholder: #8d9095;
--el-text-color-disabled: #6c6e72;
--el-border-color-darker: #636466;
--el-border-color-dark: #58585b;
--el-border-color: #4c4d4f;
--el-border-color-light: #414243;
--el-border-color-lighter: #363637;
--el-border-color-extra-light: #2b2b2c;
--el-fill-color-darker: #424243;
--el-fill-color-dark: #39393a;
--el-fill-color: #303030;
--el-fill-color-light: #262727;
--el-fill-color-lighter: #1d1d1d;
--el-fill-color-extra-light: #191919;
--table-header-bg-color: #1E293B;
--health-bg-page: #0F1419;
--health-bg-sidebar: #151B23;
--health-text-primary: #F1F5F9;
--health-text-secondary: #94A3B8;
--health-border: #334155;
--health-border-light: #1E293B;
--health-primary-light: rgba(14, 165, 233, 0.15);
--el-bg-color-page: var(--health-bg-page);
--el-bg-color: #151B23;
--el-bg-color-overlay: #1E293B;
--el-text-color-primary: var(--health-text-primary);
--el-text-color-regular: #CBD5E1;
--el-text-color-secondary: #94A3B8;
--el-text-color-placeholder: #64748B;
--el-text-color-disabled: #475569;
--el-border-color-darker: #475569;
--el-border-color-dark: #334155;
--el-border-color: #334155;
--el-border-color-light: #334155;
--el-border-color-lighter: #1E293B;
--el-border-color-extra-light: #151B23;
--el-fill-color-darker: #334155;
--el-fill-color-dark: #1E293B;
--el-fill-color: #1E293B;
--el-fill-color-light: #151B23;
--el-fill-color-lighter: #0F1419;
--el-fill-color-extra-light: #1E293B;
--el-fill-color-blank: var(--el-bg-color);
--el-mask-color: rgba(0, 0, 0, 0.8);
--el-mask-color-extra-light: rgba(0, 0, 0, 0.3);
--el-box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, 0.36), 0px 8px 20px rgba(0, 0, 0, 0.72);
--el-box-shadow-light: 0px 0px 12px rgba(0, 0, 0, 0.72);
--el-box-shadow-lighter: 0px 0px 6px rgba(0, 0, 0, 0.72);
--el-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, 0.72), 0px 12px 32px #000000,
0px 8px 16px -8px #000000 !important;
/* wangeditor主题 */
--el-mask-color: rgba(0, 0, 0, 0.72);
--el-mask-color-extra-light: rgba(0, 0, 0, 0.36);
--el-box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
--el-box-shadow-light: 0 1px 4px rgba(0, 0, 0, 0.25);
--el-box-shadow-lighter: 0 1px 2px rgba(0, 0, 0, 0.2);
--el-box-shadow-dark: 0 4px 16px rgba(0, 0, 0, 0.4);
--w-e-textarea-bg-color: var(--el-bg-color);
--w-e-textarea-color: var(--el-text-color-primary);
--w-e-textarea-border-color: var(--el-border-color);
--w-e-textarea-slight-border-color: var(--el-border-color-light);
--w-e-textarea-slight-color: var(--el-border-color);
--w-e-textarea-slight-bg-color: var(--el-bg-color-page);
/* --w-e-textarea-selected-border-color: #b4d5ff;
--w-e-textarea-handler-bg-color: #4290f7; */
--w-e-toolbar-color: var(--el-text-color-primary);
--w-e-toolbar-bg-color: var(--el-bg-color);
--w-e-toolbar-active-color: var(--el-text-color-primary);
+30 -6
View File
@@ -23,7 +23,7 @@
flex: none;
display: flex;
flex-direction: column;
border-radius: 5px;
border-radius: 8px;
&.body-padding .el-dialog__body {
padding: 0;
@@ -56,17 +56,27 @@
}
.el-table {
--el-table-header-text-color: var(--el-text-color-primary);
--el-table-header-text-color: var(--el-text-color-regular);
--el-table-header-bg-color: var(--table-header-bg-color);
--el-table-border-color: var(--health-border, var(--el-border-color-lighter));
--el-table-row-hover-bg-color: var(--el-fill-color-light);
font-size: var(--el-font-size-base);
border-radius: 8px;
overflow: hidden;
thead {
th {
font-weight: 400;
font-weight: 500;
}
}
}
.el-card {
border-radius: 8px;
border-color: var(--health-border, var(--el-border-color-lighter));
box-shadow: none;
}
.el-input-group__prepend {
background-color: var(--el-fill-color-blank);
}
@@ -78,22 +88,30 @@
.el-menu--popup-container {
&.theme-light {
.el-menu {
border-radius: 8px;
padding: 4px;
.el-menu-item {
border-radius: 6px;
&.is-active {
@apply bg-primary-light-9 border-primary border-r-2;
background-color: var(--health-primary-light, var(--el-color-primary-light-9));
color: var(--health-primary-dark, var(--el-color-primary));
font-weight: 500;
}
}
.el-menu-item:hover,
.el-sub-menu__title:hover {
color: var(--el-color-primary);
background-color: var(--el-fill-color-light);
}
}
}
&.theme-dark {
.el-menu {
border-radius: 8px;
padding: 4px;
.el-menu-item {
border-radius: 6px;
&.is-active {
@apply bg-primary;
background-color: rgba(255, 255, 255, 0.12);
}
}
}
@@ -110,6 +128,12 @@
}
}
.el-button {
border-radius: 6px;
font-weight: 500;
transition: all 0.2s ease;
}
.el-button--primary {
--el-button-hover-link-text-color: var(--el-color-primary-light-3);
}
+11
View File
@@ -1,6 +1,12 @@
@import url('https://fonts.googleapis.com/css2?family=Noto+Sans+SC:wght@300;400;500;600;700&display=swap');
body {
@apply text-base text-tx-primary overflow-hidden min-w-[375px];
font-feature-settings: 'tnum' 1;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.form-tips {
@apply text-tx-secondary text-xs leading-6 mt-1;
}
@@ -15,4 +21,9 @@ body {
/* NProgress */
#nprogress .bar {
@apply bg-primary #{!important};
height: 3px !important;
}
#nprogress .peg {
box-shadow: 0 0 8px var(--el-color-primary), 0 0 4px var(--el-color-primary) !important;
}
+40 -31
View File
@@ -1,49 +1,58 @@
:root {
--el-font-family: theme(fontFamily.sans);
--el-font-weight-primary: 400;
--el-menu-item-height: 46px;
--el-menu-item-height: 42px;
--el-menu-sub-item-height: var(--el-menu-item-height);
--el-menu-icon-width: 18px;
--aside-width: 200px;
--navbar-height: 50px;
--navbar-height: 52px;
--color-white: #ffffff;
--table-header-bg-color: #f8f8f8;
--table-header-bg-color: #F8FAFC;
--el-font-size-extra-large: 18px;
--el-menu-base-level-padding: 16px;
--el-menu-level-padding: 26px;
--el-menu-base-level-padding: 14px;
--el-menu-level-padding: 24px;
--el-font-size-large: 16px;
--el-font-size-medium: 15px;
--el-font-size-base: 14px;
--el-font-size-small: 13px;
--el-font-size-extra-small: 12px;
/* 天蓝点缀 + 中性底色(天蓝仅用于主色/激活态,不铺满全局) */
--health-primary: #0EA5E9;
--health-primary-light: #E0F2FE;
--health-primary-dark: #0284C7;
--health-bg-page: #F1F5F9;
--health-bg-sidebar: #FFFFFF;
--health-text-primary: #1E293B;
--health-text-secondary: #64748B;
--health-border: #E2E8F0;
--health-border-light: #EEF2F6;
--el-bg-color: var(--color-white);
--el-bg-color-page: #f6f6f6;
--el-bg-color-page: var(--health-bg-page);
--el-bg-color-overlay: #ffffff;
--el-text-color-primary: #333333;
--el-text-color-regular: #666666;
--el-text-color-secondary: #999999;
--el-text-color-placeholder: #a8abb2;
--el-text-color-disabled: #c0c4cc;
--el-border-color: #dcdfe6;
--el-border-color-light: #e4e7ed;
--el-border-color-lighter: #ebeef5;
--el-border-color-extra-light: #f2f2f2;
--el-border-color-dark: #d4d7de;
--el-border-color-darker: #cdd0d6;
--el-fill-color: #f0f2f5;
--el-fill-color-light: #f8f8f8;
--el-fill-color-lighter: #fafafa;
--el-fill-color-extra-light: #fafcff;
--el-fill-color-dark: #ebedf0;
--el-fill-color-darker: #e6e8eb;
--el-text-color-primary: var(--health-text-primary);
--el-text-color-regular: var(--health-text-secondary);
--el-text-color-secondary: #94A3B8;
--el-text-color-placeholder: #94A3B8;
--el-text-color-disabled: #CBD5E1;
--el-border-color: var(--health-border);
--el-border-color-light: var(--health-border);
--el-border-color-lighter: var(--health-border-light);
--el-border-color-extra-light: #F8FAFC;
--el-border-color-dark: #CBD5E1;
--el-border-color-darker: #94A3B8;
--el-fill-color: #F1F5F9;
--el-fill-color-light: #F8FAFC;
--el-fill-color-lighter: #FAFBFC;
--el-fill-color-extra-light: #F8FAFC;
--el-fill-color-dark: #E2E8F0;
--el-fill-color-darker: #CBD5E1;
--el-fill-color-blank: #ffffff;
/* 过亮会盖住抽屉/弹窗下的内容;Element Loading 与部分蒙层共用此变量 */
--el-mask-color: rgba(255, 255, 255, 0.5);
--el-mask-color-extra-light: rgba(255, 255, 255, 0.22);
-el-box-shadow: 0px 12px 32px 4px rgba(0, 0, 0, 0.04), 0px 8px 20px rgba(0, 0, 0, 0.08);
--el-box-shadow-light: 0px 0px 12px rgba(0, 0, 0, 0.12);
--el-box-shadow-lighter: 0px 0px 6px rgba(0, 0, 0, 0.12);
--el-box-shadow-dark: 0px 16px 48px 16px rgba(0, 0, 0, 0.08), 0px 12px 32px rgba(0, 0, 0, 0.12),
0px 8px 16px -8px rgba(0, 0, 0, 0.16);
--el-mask-color: rgba(255, 255, 255, 0.65);
--el-mask-color-extra-light: rgba(255, 255, 255, 0.28);
--el-box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04);
--el-box-shadow-light: 0 1px 3px rgba(15, 23, 42, 0.06);
--el-box-shadow-lighter: 0 1px 2px rgba(15, 23, 42, 0.04);
--el-box-shadow-dark: 0 4px 12px rgba(15, 23, 42, 0.08);
}
+78 -8
View File
@@ -1,14 +1,27 @@
<template>
<div class="login flex flex-col">
<div class="flex-1 flex items-center justify-center">
<div class="login-card flex rounded-md overflow-hidden">
<div class="flex-1 h-full hidden md:inline-block">
<image-contain :src="config.login_image" :width="400" height="100%" />
<div class="login-bg-decoration"></div>
<div class="flex-1 flex items-center justify-center relative z-10">
<div class="login-card flex rounded-xl overflow-hidden shadow-lg">
<div class="login-visual hidden md:flex flex-col justify-center items-center relative">
<div class="login-visual-content">
<div class="login-visual-icon">
<svg viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="20" y="8" width="8" height="32" rx="2" fill="currentColor" opacity="0.9"/>
<rect x="8" y="20" width="32" height="8" rx="2" fill="currentColor" opacity="0.9"/>
</svg>
</div>
<h2 class="login-visual-title">中医在线问诊平台</h2>
<p class="login-visual-desc">专业 · 安全 · 可信赖的医疗管理系统</p>
</div>
</div>
<div
class="login-form bg-body flex flex-col justify-center px-10 py-10 md:w-[420px] w-[380px] flex-none mx-auto"
>
<div class="text-center text-3xl font-medium mb-8">{{ config.web_name }}</div>
<div class="text-center mb-8">
<div class="login-form-badge">管理后台</div>
<div class="text-2xl font-semibold text-tx-primary mt-3">{{ config.web_name }}</div>
</div>
<!-- 企业微信自动授权中 -->
<div v-if="wxWorkAutoLogin" class="text-center py-10">
@@ -287,11 +300,68 @@ onMounted(async () => {
<style lang="scss" scoped>
.login {
background-image: url('./images/login_bg.png');
@apply min-h-screen bg-no-repeat bg-center bg-cover;
position: relative;
@apply min-h-screen overflow-hidden;
background: var(--health-bg-page, #F1F5F9);
.login-bg-decoration {
display: none;
}
.login-card {
height: auto;
min-height: 400px;
min-height: 440px;
border: 1px solid var(--health-border, var(--el-border-color-lighter));
box-shadow: var(--el-box-shadow-light);
background: var(--el-bg-color);
}
.login-visual {
width: 400px;
background: var(--el-bg-color);
color: var(--el-text-color-primary);
padding: 48px 40px;
border-right: 1px solid var(--health-border, var(--el-border-color-lighter));
.login-visual-icon {
width: 56px;
height: 56px;
border-radius: 14px;
background: var(--el-color-primary-light-9);
color: var(--el-color-primary);
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 24px;
svg {
width: 28px;
height: 28px;
}
}
.login-visual-title {
font-size: 20px;
font-weight: 600;
margin-bottom: 10px;
color: var(--el-text-color-primary);
}
.login-visual-desc {
font-size: 14px;
color: var(--el-text-color-secondary);
line-height: 1.7;
}
}
.login-form-badge {
display: inline-block;
padding: 4px 12px;
border-radius: 6px;
font-size: 12px;
font-weight: 500;
color: var(--el-color-primary);
background: var(--el-color-primary-light-9);
}
}
@@ -0,0 +1,342 @@
/**
* 处方业务订单——纯展示/格式化工具
*
* 唯一数据源:order_list.vue(处方业务订单)、PatientOrderList.vue(诊单业务订单 Tab
* 与 PrescriptionOrderDetailDrawer.vue(共享详情抽屉)共用,禁止在页面内重复定义同名函数,
* 否则两个详情页面会再次出现文案/口径漂移。
*/
/** 与诊间医助角色 ID 一致(server 角色表) */
export const TCM_ASSISTANT_ROLE_ID = 2
/** 与 server/config/project.php prescription_audit_roles 默认一致,可处方审核的角色 */
export const PRESCRIPTION_AUDIT_ROLE_IDS = [0, 3, 6]
export function formatTime(v: unknown) {
if (v === null || v === undefined || v === '') return '—'
if (typeof v === 'number' && v > 1e9 && v < 1e11) {
const d = new Date(v * 1000)
return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`
}
return String(v)
}
export function formatMoney(v: unknown) {
const n = Number(v)
if (Number.isNaN(n)) return '—'
return n.toFixed(2)
}
export function formatOrderTime(v: unknown) {
if (v === null || v === undefined || v === '') return '—'
if (typeof v === 'string' && String(v).includes('-')) return String(v)
return formatTime(v)
}
export function feeTypeText(t: number | undefined) {
const m: Record<number, string> = {
1: '挂号费',
2: '问诊费',
3: '药品费用',
4: '首付费用',
5: '尾款费用',
6: '其他费用',
7: '全部费用',
8: '驼奶费用'
}
return m[Number(t)] ?? '—'
}
export function fulfillmentText(s: number | undefined) {
const m: Record<number, string> = {
1: '待双审通过',
2: '待发货',
3: '已完成',
4: '已取消',
5: '已发货',
6: '已签收',
7: '进行中',
8: '暂不制药',
9: '拒收',
10: '退款',
11: '保留药方',
12: '制药缓发'
}
return m[Number(s)] ?? '—'
}
export function fulfillmentTagType(s: number | undefined): 'success' | 'warning' | 'danger' | 'info' | 'primary' {
const n = Number(s)
if (n === 3) return 'success'
if (n === 6) return 'success'
if (n === 5) return 'primary'
if (n === 4) return 'danger'
if (n === 2) return 'warning'
if (n === 7) return 'warning'
if (n === 8 || n === 11 || n === 12) return 'info'
if (n === 9 || n === 10) return 'danger'
return 'info'
}
export function orderStatusText(s: number | undefined) {
const m: Record<number, string> = {
1: '待支付',
2: '已支付',
3: '已取消',
4: '已退款',
5: '待审核'
}
return m[Number(s)] ?? '—'
}
export function payOrderStatusTag(s: number | undefined): 'success' | 'warning' | 'danger' | 'info' {
const n = Number(s)
if (n === 2) return 'success'
if (n === 1) return 'warning'
return 'info'
}
export function consumerRxAuditText(s: number | undefined) {
const n = Number(s)
if (n === 1) return '已通过'
if (n === 2) return '已驳回'
return '待审核'
}
export function consumerRxAuditTag(s: number | undefined): 'success' | 'warning' | 'danger' | 'info' {
const n = Number(s)
if (n === 1) return 'success'
if (n === 2) return 'danger'
return 'warning'
}
export function expressCompanyLabel(v: unknown) {
const s = String(v || '').toLowerCase()
if (s === 'sf') return '顺丰速运'
if (s === 'jd') return '京东快递'
if (s === 'jt' || s === 'jtexpress') return '极兔速递'
return '自动识别'
}
export function logActionText(act: string) {
const m: Record<string, string> = {
create: '创建',
edit: '编辑',
audit_rx_approve: '处方审核',
audit_rx_reject: '处方审核',
audit_pay_approve: '支付审核',
audit_pay_reject: '支付审核',
fill_tracking: '填快递单',
ship: '确认发货',
withdraw: '撤销',
link_pay_order: '关联支付单',
completion_request: '完单申请',
auto_complete: '自动完成',
revoke_rx_audit: '撤回处方审核',
revoke_pay_audit: '撤回支付审核',
gancao_submit: '甘草下单',
patch_rx_patient: '处方患者信息',
update_amount: '修改订单金额',
complete: '完成订单',
refund: '退款'
}
return m[act] || act
}
/** 支付单来源/方式:企微对外收款、付呗等创建链路 + 支付方式回退 */
export function formatPayOrderSource(row: { payment_method?: unknown; create_type?: unknown }) {
const createType = String(row?.create_type || '')
if (createType === 'wechat_work') return '企业微信对外收款'
if (createType === 'fubei') return '付呗'
const paymentMethod = String(row?.payment_method || '')
const methodMap: Record<string, string> = {
alipay: '支付宝',
wechat: '微信',
wechat_work: '企业微信',
fubei: '付呗',
manual: '手动确认到账'
}
if (paymentMethod && methodMap[paymentMethod]) {
return methodMap[paymentMethod]
}
return '普通订单'
}
export function normalizeBizPhone(v: unknown): string {
if (v === null || v === undefined) return ''
return String(v).replace(/\s/g, '').trim()
}
export function recipientVsPrescriptionPhoneMismatch(recipient: unknown, rxPhone: unknown): boolean {
const a = normalizeBizPhone(recipient)
const b = normalizeBizPhone(rxPhone)
if (!a || !b) return false
return a !== b
}
export function normalizeSlipHerbs(raw: unknown): Array<{ name: string; dosage: number }> {
if (!raw) return []
if (Array.isArray(raw)) {
return raw.map((x: any) => ({
name: String(x?.name ?? '').trim(),
dosage: Number(x?.dosage) || 0
}))
}
return []
}
export type SlipFormulaType = '主方' | '辅方'
export interface SlipAuxUsageForm {
dosage_amount?: number
dosage_bag_count: number
need_decoction: boolean
bags_per_dose: number
times_per_day: number
usage_days: number
}
export function normalizeSlipFormulaType(v: unknown): SlipFormulaType {
return v === '辅方' ? '辅方' : '主方'
}
export function defaultSlipAuxUsage(prescriptionType = '浓缩水丸'): SlipAuxUsageForm {
if (prescriptionType === '饮片') {
return {
dosage_amount: 50,
dosage_bag_count: 1,
need_decoction: false,
bags_per_dose: 1,
times_per_day: 3,
usage_days: 7
}
}
if (prescriptionType === '浓缩水丸') {
return {
dosage_amount: 5,
dosage_bag_count: 1,
need_decoction: false,
bags_per_dose: 1,
times_per_day: 3,
usage_days: 7
}
}
return {
dosage_amount: 1,
dosage_bag_count: 1,
need_decoction: false,
bags_per_dose: 1,
times_per_day: 3,
usage_days: 7
}
}
export function normalizeSlipAuxUsageForm(raw: unknown, prescriptionType: string): SlipAuxUsageForm {
const base = defaultSlipAuxUsage(prescriptionType)
if (!raw || typeof raw !== 'object') return { ...base }
const o = raw as Record<string, unknown>
return {
dosage_amount:
o.dosage_amount !== null && o.dosage_amount !== undefined && o.dosage_amount !== ''
? Number(o.dosage_amount)
: base.dosage_amount,
dosage_bag_count: o.dosage_bag_count != null ? Number(o.dosage_bag_count) || 1 : base.dosage_bag_count,
need_decoction: o.need_decoction === 1 || o.need_decoction === true,
bags_per_dose: o.bags_per_dose != null ? Number(o.bags_per_dose) || 1 : base.bags_per_dose,
times_per_day: o.times_per_day != null ? Number(o.times_per_day) || 3 : base.times_per_day,
usage_days: o.usage_days != null ? Number(o.usage_days) || 7 : base.usage_days
}
}
/** 是否含辅方药材(仅 formula_type=辅方;医助无药材权限时 herbs 被剥离,用后端 has_aux_formula */
export function prescriptionHasAuxFormula(rx: Record<string, unknown> | null | undefined): boolean {
if (!rx) return false
const herbs = rx.herbs
if (Array.isArray(herbs)) {
return herbs.some((h: any) => normalizeSlipFormulaType(h?.formula_type) === '辅方')
}
return Number(rx.has_aux_formula) === 1
}
/** 物流轨迹中需人工立即跟进的常见异常关键词 */
export const LOGISTICS_URGENT_KEYWORDS = [
'拒收',
'拒签',
'退件',
'客户拒收',
'拦截退回',
'退回发件',
'派件退回',
'无人签收',
'退回快件'
]
export function logisticsStringHasUrgentKeyword(s: unknown): boolean {
const t = String(s ?? '')
return LOGISTICS_URGENT_KEYWORDS.some((k) => t.includes(k))
}
export function logisticsTraceLineUrgent(context: unknown): boolean {
return logisticsStringHasUrgentKeyword(context)
}
/** 根据单次拉取的物流 payload 判断是否含拒收/退回等(详情抽屉、完成订单弹窗共用) */
export function analyzeLogisticsPayloadUrgent(p: Record<string, any> | null | undefined): {
show: boolean
keywords: string[]
lines: string[]
} {
if (!p) {
return { show: false, keywords: [], lines: [] }
}
const traces = Array.isArray(p.traces)
? (p.traces as Array<{ time?: string; context?: string }>)
: []
const chunks: string[] = []
if (p.state_text) chunks.push(String(p.state_text))
if (p.hint) chunks.push(String(p.hint))
for (const row of traces) {
if (row.context) chunks.push(String(row.context))
}
const joined = chunks.join('\n')
const keywords = LOGISTICS_URGENT_KEYWORDS.filter((k) => joined.includes(k))
if (!keywords.length) {
return { show: false, keywords: [], lines: [] }
}
const lines: string[] = []
for (const row of traces) {
const ctx = String(row.context || '')
if (logisticsStringHasUrgentKeyword(ctx)) {
lines.push(ctx)
if (lines.length >= 5) break
}
}
if (!lines.length && logisticsStringHasUrgentKeyword(p.state_text)) {
lines.push(`最新状态:${p.state_text}`)
}
if (!lines.length && logisticsStringHasUrgentKeyword(p.hint)) {
lines.push(String(p.hint))
}
return { show: true, keywords, lines }
}
/** 校验物流轨迹响应与请求上下文匹配(防止快速切换订单时旧响应串单) */
export function parseLogisticsTracePayload(
res: unknown,
expectedTrackingNumber: string,
expectedOrderId: number
): Record<string, any> | null {
const raw = (res as { data?: unknown })?.data ?? res
if (!raw || typeof raw !== 'object') return null
const payload = raw as Record<string, any>
const respNum = String(payload.tracking_number || '').trim()
if (respNum && respNum !== expectedTrackingNumber) return null
const respOrderId = Number(payload.order_id)
if (respOrderId > 0 && respOrderId !== expectedOrderId) return null
return payload
}
export function canUpdateAmount(row: { id?: number; fulfillment_status?: number } | null | undefined) {
if (!row?.id) return false
const fs = Number(row.fulfillment_status)
return fs !== 3 && fs !== 4
}
File diff suppressed because it is too large Load Diff
@@ -1998,13 +1998,14 @@
<el-form-item label="添加方式" prop="add_mode">
<el-radio-group v-model="addPayOrderForm.add_mode">
<el-radio value="create">付呗</el-radio>
<el-radio value="create_express">快递代收</el-radio>
<el-radio value="link">关联已有</el-radio>
<el-radio value="completion_only">直接完单申请</el-radio>
</el-radio-group>
</el-form-item>
<!-- 付呗手动创建支付单 -->
<template v-if="addPayOrderForm.add_mode === 'create'">
<!-- 付呗 / 快递代收手动创建支付单 -->
<template v-if="addPayOrderForm.add_mode === 'create' || addPayOrderForm.add_mode === 'create_express'">
<el-form-item label="费用类别" prop="order_type">
<el-select v-model="addPayOrderForm.order_type" class="w-full">
<el-option label="挂号费" :value="1" />
@@ -4955,10 +4956,13 @@ const addPayOrderAlertTitle = computed(() => {
if (addPayOrderForm.add_mode === 'completion_only') {
return '不创建或关联支付单,仅提交完单申请,由审核人员在支付审核时处理。'
}
if (addPayOrderForm.add_mode === 'create_express') {
return '通过快递代收创建新支付单(流转同付呗),或关联已存在但未绑定的支付单。'
}
return '可以通过付呗创建新支付单,或关联已存在但未绑定的支付单。'
})
const addPayOrderForm = reactive({
add_mode: 'create' as 'create' | 'link' | 'completion_only',
add_mode: 'create' as 'create' | 'create_express' | 'link' | 'completion_only',
order_type: 3,
pay_amount: undefined as number | undefined,
pay_remark: '',
@@ -4970,7 +4974,7 @@ const addPayOrderRules = computed<FormRules>(() => {
const rules: FormRules = {
add_mode: [{ required: true, message: '请选择添加方式', trigger: 'change' }]
}
if (addPayOrderForm.add_mode === 'create') {
if (addPayOrderForm.add_mode === 'create' || addPayOrderForm.add_mode === 'create_express') {
rules.order_type = [{ required: true, message: '请选择费用类别', trigger: 'change' }]
rules.pay_amount = [
{ required: true, message: '请输入支付金额', trigger: 'blur' },
@@ -5054,14 +5058,19 @@ async function submitAddPayOrder() {
if (addPayOrderForm.add_mode === 'completion_only') {
await prescriptionOrderRequestCompletion({ id: addPayOrderRowId.value })
feedback.msgSuccess('完单申请已提交,请等待支付审核')
} else if (addPayOrderForm.add_mode === 'create') {
//
} else if (
addPayOrderForm.add_mode === 'create' ||
addPayOrderForm.add_mode === 'create_express'
) {
// /
await prescriptionOrderAddPayOrder({
id: addPayOrderRowId.value,
order_type: addPayOrderForm.order_type,
pay_amount: addPayOrderForm.pay_amount!,
pay_remark: addPayOrderForm.pay_remark || '',
completion_request: addPayOrderForm.completion_request
completion_request: addPayOrderForm.completion_request,
pay_create_type:
addPayOrderForm.add_mode === 'create_express' ? 'express_cod' : 'fubei'
})
feedback.msgSuccess('支付单已新增,请等待审核')
} else {
+1 -1
View File
@@ -390,7 +390,7 @@
<el-tooltip placement="top" effect="dark" :show-after="200">
<template #content>
<div style="max-width: 320px; line-height: 1.7; font-size: 12px">
<b>tcm_diagnosis_assign_log</b> 行数成功指派<b>to_assistant_id &gt; 0</b>** <b>related_po_create_time</b>** 落在所选区间内与日志表快照一致诊单手动指派已写入该字段<b>被指派医助</b>归属展示部门<template v-if="tb.channel_name">
<b>tcm_diagnosis_assign_log</b> 成功指派<b>to_assistant_id &gt; 0</b><b>剔除勾选继承的指派</b><b>指派操作时间</b>落在所选区间内医助 × 诊单去重剔除已删诊单复诊接诊率页面同口径<b>被指派医助</b>归属展示部门<template v-if="tb.channel_name">
选定渠道时收窄与{{ tb.channel_name }}业绩同口径标签诊单或 channels EXISTS<br />
<b>二中心及其组织下级</b>在选定渠道下本列计 <b>0</b>
</template>
+31 -11
View File
@@ -220,7 +220,7 @@
编辑
</el-button>
<el-button
v-if="row.status === 1 || row.status === 2 || (row.status === 5 && row.payment_method === 'fubei')"
v-if="row.status === 1 || row.status === 2 || (row.status === 5 && (row.payment_method === 'fubei' || row.create_type === 'express_cod'))"
v-perms="['order.order/split']"
type="primary"
link
@@ -237,7 +237,7 @@
小程序码
</el-button>
<el-button
v-if="row.status === 1 || (row.status === 5 && row.payment_method === 'fubei')"
v-if="row.status === 1 || (row.status === 5 && (row.payment_method === 'fubei' || row.create_type === 'express_cod'))"
v-perms="['order.order/pay']"
type="success"
link
@@ -255,7 +255,7 @@
退款
</el-button>
<el-button
v-if="row.status === 1 || (row.status === 5 && row.payment_method === 'fubei')"
v-if="row.status === 1 || (row.status === 5 && (row.payment_method === 'fubei' || row.create_type === 'express_cod'))"
v-perms="['order.order/cancel']"
type="danger"
link
@@ -434,7 +434,7 @@
type="warning"
:closable="false"
class="mb-3"
title="该单为付呗·待审核,请选择实际到账方式后确认「已支付」"
title="该单为待审核(付呗/快递代收),请选择实际到账方式后确认「已支付」"
/>
<el-form-item v-if="!payForm.fubeiPendingAudit" label="支付类型" required>
<el-radio-group v-model="payForm.payType">
@@ -502,6 +502,7 @@
<el-radio label="normal">普通订单</el-radio>
<el-radio label="wechat_work">企业微信对外收款</el-radio>
<el-radio label="fubei">付呗</el-radio>
<el-radio label="express_cod">快递代收</el-radio>
</el-radio-group>
</el-form-item>
<el-alert
@@ -524,7 +525,20 @@
<template #title>付呗</template>
通过付呗收款的支付单创建后请按实际对账/审核流程在列表中处理
</el-alert>
<el-form-item v-if="createForm.createType === 'fubei'" label="支付单审核">
<el-alert
v-if="createForm.createType === 'express_cod'"
type="info"
:closable="false"
show-icon
class="mb-4"
>
<template #title>快递代收</template>
通过快递代收的支付单流转与付呗一致审核通过/确认到账后将更新为已支付
</el-alert>
<el-form-item
v-if="createForm.createType === 'fubei' || createForm.createType === 'express_cod'"
label="支付单审核"
>
<el-switch
v-model="createForm.requirePaymentSlipAudit"
active-text="申请审核"
@@ -980,8 +994,8 @@ const patientLoading = ref(false)
const patientList = ref<any[]>([])
const createForm = reactive({
createType: 'normal' as 'normal' | 'wechat_work' | 'fubei',
/** 「付呗」:开启后订单为待审核(5) */
createType: 'normal' as 'normal' | 'wechat_work' | 'fubei' | 'express_cod',
/** 「付呗」「快递代收」:开启后订单为待审核(5) */
requirePaymentSlipAudit: false,
patient_id: '',
order_type: '',
@@ -1167,13 +1181,17 @@ const submitCreateOrder = async () => {
if (createForm.createType === 'fubei') {
params.payment_channel = 'fubei'
params.require_payment_slip_audit = createForm.requirePaymentSlipAudit ? 1 : 0
} else if (createForm.createType === 'express_cod') {
params.payment_channel = 'express_cod'
params.require_payment_slip_audit = createForm.requirePaymentSlipAudit ? 1 : 0
} else {
params.payment_channel = 'normal'
params.require_payment_slip_audit = 0
}
await orderCreate(params)
const tip =
createForm.createType === 'fubei' && createForm.requirePaymentSlipAudit
(createForm.createType === 'fubei' || createForm.createType === 'express_cod') &&
createForm.requirePaymentSlipAudit
? '订单已创建,支付状态为「待审核」'
: '订单创建成功'
feedback.msgSuccess(tip)
@@ -1254,10 +1272,11 @@ const getCreateTypeText = (row: any) => {
const createTypeMap: Record<string, string> = {
normal: '普通订单',
wechat_work: '企业微信对外收款',
fubei: '付呗'
fubei: '付呗',
express_cod: '快递代收'
}
const ct = row?.create_type
if (ct === 'wechat_work' || ct === 'fubei') {
if (ct === 'wechat_work' || ct === 'fubei' || ct === 'express_cod') {
return createTypeMap[ct]
}
if (ct === 'normal' && row?.payment_method) {
@@ -1395,7 +1414,8 @@ const handleDetail = async (row: any) => {
// 支付订单
const handlePay = (row: any) => {
const fubeiPending = row.status === 5 && row.payment_method === 'fubei'
const fubeiPending =
row.status === 5 && (row.payment_method === 'fubei' || row.create_type === 'express_cod')
payForm.value = {
order_id: row.id,
order_no: row.order_no,
@@ -0,0 +1,644 @@
<template>
<div class="revisit-rate-page">
<el-card class="!border-none" shadow="never">
<el-form :inline="true" class="rate-filter-form">
<el-form-item label="统计月份">
<el-date-picker
v-model="month"
type="month"
value-format="YYYY-MM"
placeholder="选择月份"
:clearable="false"
:disabled-date="disableFutureMonth"
style="width: 160px"
@change="loadData"
/>
</el-form-item>
<el-form-item label="部门">
<el-tree-select
v-model="deptId"
:data="deptTreeOptions"
placeholder="全部部门"
clearable
filterable
check-strictly
node-key="id"
:default-expand-all="true"
:props="deptTreeProps"
style="width: 220px"
@change="loadData"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" :loading="loading" @click="loadData">查询</el-button>
<el-button :disabled="loading" @click="handleReset">重置</el-button>
</el-form-item>
<el-form-item>
<el-popover placement="bottom-start" :width="500" trigger="hover">
<template #reference>
<span class="rate-caliber-trigger">
<el-icon><InfoFilled /></el-icon>
统计口径
</span>
</template>
<div class="rate-caliber">
<p>
<b>当月被指派总数</b>当月内诊单被指派给医助按指派操作时间落月<b>剔除勾选继承的指派</b>)的诊单数医助 × 诊单去重部门行 / 合计行按诊单去重
</p>
<p>
<b>诊次 N 次下单</b>患者诊单名下计入业绩的业务订单剔除已取消 / 拒收 / 退款按下单时间升序的全局序号<b>跨月累计不重置</b> 5 月指派后旗下成交 4 单为二诊~五诊下月再成交即为六诊
</p>
<p>
<b>当月 N 诊单数</b>当月内下单且诊次为 N 的订单数归属下单时点<b>持有该患者的医助</b>指派可在往月释放后不再归属继承指派会转移持有人但不计被指派数
</p>
<p>
<b>当月 N 诊接诊率</b> = 当月 N 诊单数 ÷ 当月被指派总数往月指派当月成交会推高分子比率可能超过 100%医助当月无新指派但旗下有成交时被指派数为 0比率显示
</p>
<p>
医助按人事部门归组选定部门时含其组织下级
</p>
</div>
</el-popover>
</el-form-item>
</el-form>
</el-card>
<div class="rate-kpi-grid">
<div
v-for="card in summaryCards"
:key="card.key"
class="rate-kpi-card"
:class="{ 'is-clickable': card.clickable }"
@click="card.clickable && card.onClick && card.onClick()"
>
<div class="rate-kpi-label">{{ card.label }}</div>
<div class="rate-kpi-value">{{ card.value }}</div>
<div v-if="card.sub" class="rate-kpi-sub">{{ card.sub }}</div>
</div>
</div>
<el-card class="!border-none mt-4" shadow="never">
<template #header>
<div class="rate-card-header">
<span>部门 · 医助明细{{ monthText }}</span>
<span class="rate-card-hint">点击被指派数 / N诊单数可查看具体诊单与订单底栏合计的被指派数按诊单去重</span>
</div>
</template>
<el-table
v-loading="loading"
:data="rows"
size="small"
border
row-key="row_key"
:tree-props="{ children: 'children' }"
:default-expand-all="true"
show-summary
:summary-method="getSummaries"
>
<el-table-column label="部门 / 医助" min-width="200" fixed>
<template #default="{ row }">
<span v-if="row.is_dept" class="rate-dept-cell">
{{ row.dept_name }}
<span class="rate-dept-count">{{ row.assistant_count }} </span>
</span>
<span v-else>{{ row.assistant_name }}</span>
</template>
</el-table-column>
<el-table-column prop="assigned_count" label="当月被指派数" min-width="110" align="right">
<template #default="{ row }">
<el-link
v-if="canViewAssignLines && row.assigned_count > 0"
type="primary"
:underline="false"
@click="openAssignDetail(row)"
>
{{ row.assigned_count }}
</el-link>
<span v-else>{{ row.assigned_count }}</span>
</template>
</el-table-column>
<template v-for="slot in visitSlots" :key="slot">
<el-table-column
:prop="`visit${slot}_count`"
:label="`${slotLabel(slot)}单数`"
min-width="96"
align="right"
>
<template #header>
<span>{{ slotLabel(slot) }}单数</span>
<el-tooltip
effect="dark"
placement="top"
:content="`当月内下单、诊次为第 ${slot} 次的订单数(诊次跨月累计;归属下单时点持有患者的医助)`"
>
<el-icon class="rate-th-hint"><InfoFilled /></el-icon>
</el-tooltip>
</template>
<template #default="{ row }">
<el-link
v-if="canViewOrderLines && row[`visit${slot}_count`] > 0"
type="primary"
:underline="false"
@click="openOrderDetail(slot, row)"
>
{{ row[`visit${slot}_count`] }}
</el-link>
<span v-else>{{ row[`visit${slot}_count`] }}</span>
</template>
</el-table-column>
<el-table-column
:prop="`visit${slot}_rate`"
:label="`${slotLabel(slot)}接诊率`"
min-width="96"
align="right"
>
<template #default="{ row }">{{ formatRate(row[`visit${slot}_rate`]) }}</template>
</el-table-column>
</template>
</el-table>
</el-card>
<!-- 下钻明细 -->
<el-dialog
v-model="detailVisible"
:title="detailTitle"
width="980px"
top="6vh"
destroy-on-close
>
<el-table
v-loading="detailLoading"
:data="detailRows"
size="small"
border
stripe
max-height="60vh"
>
<template v-if="detailType === 'assign'">
<el-table-column prop="diagnosis_id" label="诊单ID" width="90" />
<el-table-column prop="patient_name" label="患者" min-width="100">
<template #default="{ row }">
<el-link
v-if="canViewPatientDetail && row.diagnosis_id"
type="primary"
:underline="false"
@click="openPatientDetail(row.diagnosis_id)"
>
{{ row.patient_name || `诊单#${row.diagnosis_id}` }}
</el-link>
<span v-else>{{ row.patient_name || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="patient_phone" label="联系电话" min-width="120">
<template #default="{ row }">{{ row.patient_phone || '—' }}</template>
</el-table-column>
<el-table-column prop="assistant_names" label="被指派医助" min-width="140" show-overflow-tooltip />
<el-table-column prop="assign_count" label="当月指派次数" width="110" align="right" />
<el-table-column prop="last_assign_time_text" label="最近指派时间" min-width="160" />
</template>
<template v-else>
<el-table-column prop="order_no" label="订单号" min-width="180" show-overflow-tooltip>
<template #default="{ row }">
<el-link
v-if="canViewOrderDetail && row.order_id"
type="primary"
:underline="false"
@click="openOrderInfo(row.order_id)"
>
{{ row.order_no || `#${row.order_id}` }}
</el-link>
<span v-else>{{ row.order_no || `#${row.order_id}` }}</span>
</template>
</el-table-column>
<el-table-column prop="diagnosis_id" label="诊单ID" width="90" />
<el-table-column prop="patient_name" label="患者" min-width="100">
<template #default="{ row }">
<el-link
v-if="canViewPatientDetail && row.diagnosis_id"
type="primary"
:underline="false"
@click="openPatientDetail(row.diagnosis_id)"
>
{{ row.patient_name || `诊单#${row.diagnosis_id}` }}
</el-link>
<span v-else>{{ row.patient_name || '' }}</span>
</template>
</el-table-column>
<el-table-column prop="amount" label="金额" width="100" align="right">
<template #default="{ row }">¥ {{ row.amount }}</template>
</el-table-column>
<el-table-column prop="create_time_text" label="下单时间" min-width="160" />
<el-table-column prop="assistant_name" label="持有医助" min-width="100" />
<el-table-column prop="creator_name" label="订单创建人" min-width="100" />
</template>
</el-table>
<div class="rate-detail-footer"> {{ detailRows.length }} </div>
</el-dialog>
<!-- 订单详情抽屉共享组件与处方订单列表详情一致只读 -->
<order-detail-drawer ref="orderDetailRef" readonly append-to-body />
<!-- 诊单患者详情编辑页只读模式 -->
<diagnosis-edit-popup ref="diagnosisEditRef" />
</div>
</template>
<script setup lang="ts" name="revisitRateStatsPage">
import { computed, defineAsyncComponent, onMounted, ref } from 'vue'
import { InfoFilled } from '@element-plus/icons-vue'
import {
revisitRateAssignLines,
revisitRateDeptOptions,
revisitRateOverview,
revisitRateVisitOrderLines
} from '@/api/stats'
import { hasPermission } from '@/utils/perm'
/** 业务订单详情抽屉(共享组件,readonly 模式,与 order_list.vue 详情同源) */
const OrderDetailDrawer = defineAsyncComponent(
() => import('@/views/consumer/prescription/components/PrescriptionOrderDetailDrawer.vue')
)
/** 诊单编辑弹窗(只读打开) */
const DiagnosisEditPopup = defineAsyncComponent(() => import('@/views/tcm/diagnosis/edit.vue'))
interface MetricPack extends Record<string, any> {
assigned_count: number
}
interface StatsRow extends MetricPack {
row_key: string
is_dept: 0 | 1
dept_id: number
dept_name: string
assistant_id?: number
assistant_name?: string
assistant_count?: number
children?: StatsRow[]
}
interface DeptTreeNode {
id: number
name: string
pid: number
children?: DeptTreeNode[]
}
const canViewAssignLines = hasPermission(['stats.revisitRate/assignLines'])
const canViewOrderLines = hasPermission(['stats.revisitRate/visitOrderLines'])
const canViewOrderDetail = hasPermission(['tcm.prescriptionOrder/detail'])
const canViewPatientDetail = hasPermission(['tcm.diagnosis/detail'])
/** 接口动态返回的诊次分档(最少 2~4,按数据扩展到五诊、六诊…) */
const visitSlots = ref<number[]>([2, 3, 4])
const cnDigits = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九', '十']
const slotLabel = (slot: number) => {
if (slot >= 2 && slot <= 10) {
return `${cnDigits[slot]}`
}
if (slot > 10 && slot < 20) {
return `${cnDigits[slot - 10]}`
}
return `${slot}`
}
const initNow = new Date()
const currentMonth = `${initNow.getFullYear()}-${String(initNow.getMonth() + 1).padStart(2, '0')}`
const month = ref<string>(currentMonth)
const deptId = ref<number | undefined>(undefined)
const loading = ref(false)
const rows = ref<StatsRow[]>([])
const total = ref<MetricPack | null>(null)
const deptTreeOptions = ref<DeptTreeNode[]>([])
const deptTreeProps = { value: 'id', label: 'name', children: 'children' }
const monthText = computed(() => {
const [y, m] = month.value.split('-')
return y && m ? `${y}${Number(m)}` : month.value
})
const formatRate = (rate: number | null | undefined) =>
rate === null || rate === undefined ? '—' : `${rate}%`
const baseQuery = () => ({
month: month.value,
dept_ids: deptId.value ? String(deptId.value) : ''
})
interface SummaryCard {
key: string
label: string
value: string
sub: string
clickable: boolean
onClick?: () => void
}
const summaryCards = computed<SummaryCard[]>(() => {
const t = total.value
const cards: SummaryCard[] = [
{
key: 'assigned',
label: '当月被指派总数',
value: t ? String(t.assigned_count) : '—',
sub: '',
clickable: !!(canViewAssignLines && t && t.assigned_count > 0),
onClick: () => openAssignDetail(null)
}
]
for (const slot of visitSlots.value) {
const cnt = t ? t[`visit${slot}_count`] : null
const rate = t ? t[`visit${slot}_rate`] : null
cards.push({
key: `visit${slot}`,
label: `当月${slotLabel(slot)}接诊率`,
value: t ? formatRate(rate) : '—',
sub: t ? `${slotLabel(slot)}下单 ${cnt}` : '',
clickable: !!(canViewOrderLines && cnt > 0),
onClick: () => openOrderDetail(slot, null)
})
}
return cards
})
/** 底栏合计:直接展示后端按诊单去重后的合计,不做各行求和 */
const getSummaries = ({ columns }: { columns: any[] }) => {
const t = total.value
return columns.map((col, index) => {
if (index === 0) {
return '合计'
}
if (!t) {
return ''
}
const prop = String(col.property || '')
if (prop === 'assigned_count') {
return String(t.assigned_count)
}
if (/^visit\d+_count$/.test(prop)) {
return String(t[prop] ?? '')
}
if (/^visit\d+_rate$/.test(prop)) {
return formatRate(t[prop])
}
return ''
})
}
const disableFutureMonth = (date: Date) => {
const now = new Date()
return date.getFullYear() * 12 + date.getMonth() > now.getFullYear() * 12 + now.getMonth()
}
const loadData = async () => {
loading.value = true
try {
const res = await revisitRateOverview(baseQuery())
rows.value = res?.rows ?? []
total.value = res?.total ?? null
if (Array.isArray(res?.slots) && res.slots.length) {
visitSlots.value = res.slots.map((s: any) => Number(s)).filter((s: number) => s >= 2)
}
if (res?.month) {
month.value = res.month
}
} finally {
loading.value = false
}
}
const buildDeptTree = (flat: Array<{ id: number; pid: number; name: string }>): DeptTreeNode[] => {
const map = new Map<number, DeptTreeNode>()
for (const d of flat) {
map.set(d.id, { ...d, children: [] })
}
const roots: DeptTreeNode[] = []
for (const d of flat) {
const node = map.get(d.id)!
if (d.pid > 0 && map.has(d.pid)) {
map.get(d.pid)!.children!.push(node)
} else {
roots.push(node)
}
}
const strip = (n: DeptTreeNode) => {
if (n.children?.length) {
n.children.forEach(strip)
} else {
delete n.children
}
}
roots.forEach(strip)
return roots
}
const loadDeptOptions = async () => {
try {
const res = await revisitRateDeptOptions()
deptTreeOptions.value = buildDeptTree(res?.rows ?? [])
} catch {
deptTreeOptions.value = []
}
}
// ── 下钻明细 ──────────────────────────────────────────
const detailVisible = ref(false)
const detailType = ref<'assign' | 'orders'>('assign')
const detailTitle = ref('')
const detailLoading = ref(false)
const detailRows = ref<any[]>([])
/** row 为 null 时表示合计(当前部门筛选范围) */
const rowScope = (row: StatsRow | null): { assistant_id?: number; dept_id?: number; label: string } => {
if (!row) {
return { label: '合计' }
}
if (row.is_dept) {
return { dept_id: row.dept_id, label: row.dept_name }
}
return { assistant_id: row.assistant_id, label: row.assistant_name || '' }
}
const openAssignDetail = async (row: StatsRow | null) => {
if (!canViewAssignLines) {
return
}
const scope = rowScope(row)
detailType.value = 'assign'
detailTitle.value = `${scope.label} · 被指派明细(${monthText.value}`
detailVisible.value = true
detailLoading.value = true
detailRows.value = []
try {
const res = await revisitRateAssignLines({
...baseQuery(),
assistant_id: scope.assistant_id,
dept_id: scope.dept_id
})
detailRows.value = res?.rows ?? []
} finally {
detailLoading.value = false
}
}
const openOrderDetail = async (slot: number, row: StatsRow | null) => {
if (!canViewOrderLines) {
return
}
const scope = rowScope(row)
detailType.value = 'orders'
detailTitle.value = `${scope.label} · ${slotLabel(slot)}订单明细(${monthText.value}`
detailVisible.value = true
detailLoading.value = true
detailRows.value = []
try {
const res = await revisitRateVisitOrderLines({
...baseQuery(),
slot,
assistant_id: scope.assistant_id,
dept_id: scope.dept_id
})
detailRows.value = res?.rows ?? []
} finally {
detailLoading.value = false
}
}
// ── 订单详情(复用处方订单列表的详情抽屉) ──────────────
const orderDetailRef = ref<{ open: (id: number) => void } | null>(null)
const openOrderInfo = (orderId: number) => {
if (!canViewOrderDetail || !orderId) {
return
}
orderDetailRef.value?.open(orderId)
}
// ── 患者(诊单)详情:诊单编辑页只读打开 ────────────────
const diagnosisEditRef = ref<{ openViewOnly: (id: number) => void } | null>(null)
const openPatientDetail = (diagnosisId: number) => {
if (!canViewPatientDetail || !diagnosisId) {
return
}
diagnosisEditRef.value?.openViewOnly(diagnosisId)
}
const handleReset = () => {
month.value = currentMonth
deptId.value = undefined
loadData()
}
onMounted(() => {
loadDeptOptions()
loadData()
})
</script>
<style lang="scss" scoped>
.revisit-rate-page {
.rate-filter-form {
:deep(.el-form-item) {
margin-bottom: 0;
}
}
.rate-caliber-trigger {
display: inline-flex;
align-items: center;
gap: 4px;
color: var(--el-text-color-secondary);
font-size: 13px;
cursor: help;
}
.rate-kpi-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 12px;
margin-top: 16px;
}
.rate-kpi-card {
background: var(--el-bg-color);
border-radius: 8px;
padding: 16px 20px;
&.is-clickable {
cursor: pointer;
transition: box-shadow 0.15s ease;
&:hover {
box-shadow: var(--el-box-shadow-light);
}
}
.rate-kpi-label {
color: var(--el-text-color-secondary);
font-size: 13px;
}
.rate-kpi-value {
margin-top: 6px;
font-size: 26px;
font-weight: 600;
color: var(--el-text-color-primary);
}
.rate-kpi-sub {
margin-top: 2px;
font-size: 12px;
color: var(--el-text-color-secondary);
}
}
.rate-card-header {
display: flex;
align-items: baseline;
gap: 10px;
.rate-card-hint {
font-size: 12px;
color: var(--el-text-color-secondary);
}
}
.rate-dept-cell {
font-weight: 600;
.rate-dept-count {
margin-left: 6px;
font-weight: 400;
font-size: 12px;
color: var(--el-text-color-secondary);
}
}
.rate-th-hint {
margin-left: 2px;
vertical-align: -2px;
color: var(--el-text-color-secondary);
cursor: help;
}
}
.rate-detail-footer {
margin-top: 10px;
text-align: right;
font-size: 12px;
color: var(--el-text-color-secondary);
}
.rate-caliber {
font-size: 13px;
line-height: 1.7;
color: var(--el-text-color-regular);
p + p {
margin-top: 6px;
}
}
</style>
@@ -56,298 +56,21 @@
</div>
</template>
<!-- 业务订单详情抽屉只读 order_list.vue 详情保持一致 -->
<el-drawer
v-model="detailVisible"
size="80%"
destroy-on-close
:close-on-click-modal="false"
append-to-body
>
<template #header>
<div class="flex items-center">
<span class="font-semibold text-lg">业务订单详情</span>
<el-tag v-if="detailData?.order_no" type="primary" effect="plain" round class="ml-3">{{ detailData.order_no }}</el-tag>
<el-tag v-if="detailData?.gancao_reciperl_order_no" type="success" effect="plain" round class="ml-2">甘草 {{ detailData.gancao_reciperl_order_no }}</el-tag>
</div>
</template>
<el-skeleton v-if="detailLoading" :rows="12" animated class="px-6 py-4" />
<div v-else-if="detailData" class="px-6 pb-6 overflow-y-auto">
<!-- 顶部数据概览 -->
<el-row :gutter="16" class="mb-5">
<el-col :xs="12" :sm="6">
<el-card shadow="never" class="border border-gray-100 bg-gray-50/50">
<div class="text-gray-500 text-xs mb-1">总金额</div>
<div class="text-red-500 font-bold text-xl">¥{{ detailData.amount }}</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="6">
<el-card shadow="never" class="border border-gray-100 bg-gray-50/50">
<div class="text-gray-500 text-xs mb-1">已付总额</div>
<div class="text-green-600 font-bold text-xl">¥{{ detailData.linked_pay_paid_total || 0 }}</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="6">
<el-card shadow="never" class="border border-gray-100 bg-gray-50/50">
<div class="text-gray-500 text-xs mb-1">需代收</div>
<div class="font-bold text-xl" :class="detailAgencyToCollect > 0 ? 'text-amber-600' : 'text-gray-500'">¥{{ formatMoney(detailAgencyToCollect) }}</div>
</el-card>
</el-col>
<el-col :xs="12" :sm="6">
<el-card shadow="never" class="border border-gray-100 bg-gray-50/50">
<div class="text-gray-500 text-xs mb-1">已付笔数</div>
<div class="text-primary font-bold text-xl">{{ detailLinkedPayOrders.length }} </div>
</el-card>
</el-col>
</el-row>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mb-4">
<!-- 左侧处方单不含测试价格改患者信息药材明细 -->
<el-card shadow="never" class="border-gray-100 h-full relative overflow-hidden">
<div v-if="detailData.prescription_audit_status === 1" class="audit-stamp stamp-pass"><div class="stamp-inner">审核通过</div></div>
<div v-if="detailData.prescription_audit_status === 2" class="audit-stamp stamp-reject"><div class="stamp-inner">已驳回</div></div>
<template #header>
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<span class="font-medium text-[15px]">处方详情</span>
<span v-if="detailData.doctor_name" class="text-xs text-gray-500">
开方人<span class="text-primary font-medium">{{ detailData.doctor_name }}</span>
</span>
</div>
<span class="text-xs text-gray-400">ID: {{ detailData.prescription_id || '—' }}</span>
</div>
</template>
<template v-if="detailPrescription">
<el-descriptions :column="2" border size="small" class="bg-white">
<el-descriptions-item label="处方编号" :span="2">{{ detailPrescription.sn || '—' }}</el-descriptions-item>
<el-descriptions-item label="患者">{{ detailPrescription.patient_name || '—' }}</el-descriptions-item>
<el-descriptions-item label="性别 / 年龄">{{ detailPrescription.gender_desc || '—' }} · {{ detailPrescription.age ?? '—' }}</el-descriptions-item>
<el-descriptions-item label="手机">
<span :class="detailRecipientRxPhoneMismatch ? 'text-red-600 font-bold' : ''">{{ detailPrescription.phone || '—' }}</span>
<el-tag v-if="detailRecipientRxPhoneMismatch" type="danger" size="small" effect="dark" class="ml-2">与订单手机不一致</el-tag>
</el-descriptions-item>
<el-descriptions-item label="处方日期">{{ detailPrescription.prescription_date || '—' }}</el-descriptions-item>
<el-descriptions-item label="医师">{{ detailPrescription.doctor_name || '—' }}</el-descriptions-item>
<el-descriptions-item label="类型">{{ detailPrescription.prescription_type || '—' }}</el-descriptions-item>
<el-descriptions-item label="临床诊断" :span="2">{{ detailPrescription.clinical_diagnosis || '—' }}</el-descriptions-item>
<el-descriptions-item label="剂数 / 用法" :span="2" v-if="showPrescriptionAuditFilter">
{{ detailData.dose_count ?? detailPrescription.dose_count ?? '' }} {{ detailData.dose_unit || '' }} ·
{{ detailPrescription.usage_instruction || detailPrescription.usage_method || '' }}
</el-descriptions-item>
<el-descriptions-item label="处方金额">
<span class="text-red-500 font-medium">¥{{ detailPrescription.amount ?? '—' }}</span>
</el-descriptions-item>
<el-descriptions-item label="消费者审核">
<el-tag :type="consumerRxAuditTag(detailPrescription.audit_status)" size="small">{{ consumerRxAuditText(detailPrescription.audit_status) }}</el-tag>
</el-descriptions-item>
<el-descriptions-item label="用量">
<template v-if="detailPrescription.dosage_amount">
{{ detailPrescription.dosage_amount }}{{ detailPrescription.dosage_unit || 'g' }}
<template v-if="detailPrescription.prescription_type === '浓缩水丸'">
· {{ Number(detailPrescription.dosage_bag_count) > 0 ? Number(detailPrescription.dosage_bag_count) : 1 }}
</template>
<span v-if="detailPrescription.prescription_type === '饮片' && detailPrescription.need_decoction !== null" class="ml-2 text-gray-500">
({{ detailPrescription.need_decoction ? '代煎' : '不代煎' }})
</span>
</template>
<template v-else></template>
</el-descriptions-item>
<el-descriptions-item label="服用方式">
<div class="flex flex-col gap-1.5 text-sm leading-relaxed">
<div>
<span class="text-gray-500">每天次数</span>
{{ detailPrescription.times_per_day ? detailPrescription.times_per_day + ' 次' : '—' }}
</div>
<div>
<span class="text-gray-500">处方开立</span>
{{ detailPrescription.usage_days != null && detailPrescription.usage_days !== '' ? detailPrescription.usage_days + ' 天' : '—' }}
</div>
<div>
<span class="text-gray-500">订单设置</span>
{{ detailData.medication_days != null && String(detailData.medication_days).trim() !== '' ? detailData.medication_days + ' 天' : '—' }}
</div>
</div>
</el-descriptions-item>
<el-descriptions-item label="状态" :span="2">
<el-tag :type="Number(detailPrescription.void_status) === 1 ? 'danger' : 'success'" size="small">{{ Number(detailPrescription.void_status) === 1 ? '已作废' : '正常' }}</el-tag>
</el-descriptions-item>
</el-descriptions>
</template>
<el-empty v-else description="无处方数据" :image-size="72" />
</el-card>
<!-- 右侧未关联 + 已关联支付单 -->
<div class="flex flex-col gap-4 h-full">
<el-card shadow="never" class="border-gray-100">
<template #header>
<div class="flex items-center justify-between">
<span class="font-medium text-[15px]">未关联的收款记录</span>
<span class="text-xs text-gray-400">本诊单下未被占用的支付单</span>
</div>
</template>
<el-table v-if="detailUnlinkedPayOrders.length" :data="detailUnlinkedPayOrders" size="small" border stripe max-height="280">
<el-table-column prop="id" label="ID" width="70" />
<el-table-column prop="order_no" label="单号" min-width="135" show-overflow-tooltip />
<el-table-column label="类型" width="90">
<template #default="{ row }">{{ row.order_type_desc || feeTypeText(row.order_type) }}</template>
</el-table-column>
<el-table-column label="金额" width="86" align="right">
<template #default="{ row }"><span class="text-red-500">¥{{ row.amount }}</span></template>
</el-table-column>
<el-table-column label="状态" width="82" align="center">
<template #default="{ row }">
<el-tag :type="payOrderStatusTag(row.status)" size="small">{{ row.status_desc || orderStatusText(row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="creator_name" label="创建人" width="80" show-overflow-tooltip />
<el-table-column label="创建时间" min-width="136">
<template #default="{ row }">{{ formatOrderTime(row.create_time) }}</template>
</el-table-column>
</el-table>
<el-empty v-else description="无未关联的收款单" :image-size="60" />
</el-card>
<el-card shadow="never" class="border-gray-100 relative overflow-hidden">
<div v-if="detailData.payment_slip_audit_status === 1" class="audit-stamp stamp-pass"><div class="stamp-inner">审核通过</div></div>
<div v-if="detailData.payment_slip_audit_status === 2" class="audit-stamp stamp-reject"><div class="stamp-inner">已驳回</div></div>
<template #header>
<div class="flex items-center gap-3">
<span class="font-medium text-[15px]">关联收款记录</span>
<span v-if="detailData.creator_name" class="text-xs text-gray-500">创建人:<span class="text-primary font-medium">{{ detailData.creator_name }}</span></span>
</div>
</template>
<el-table v-if="detailLinkedPayOrders.length" :data="detailLinkedPayOrders" size="small" border stripe max-height="280">
<el-table-column prop="id" label="ID" width="70" />
<el-table-column prop="order_no" label="单号" min-width="135" show-overflow-tooltip />
<el-table-column label="类型" width="90">
<template #default="{ row }">{{ row.order_type_desc || feeTypeText(row.order_type) }}</template>
</el-table-column>
<el-table-column label="金额" width="86" align="right">
<template #default="{ row }"><span class="text-red-500">¥{{ row.amount }}</span></template>
</el-table-column>
<el-table-column label="状态" width="82" align="center">
<template #default="{ row }">
<el-tag :type="payOrderStatusTag(row.status)" size="small">{{ row.status_desc || orderStatusText(row.status) }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="creator_name" label="创建人" width="80" show-overflow-tooltip />
<el-table-column label="创建时间" min-width="136">
<template #default="{ row }">{{ formatOrderTime(row.create_time) }}</template>
</el-table-column>
</el-table>
<el-empty v-else description="未关联收款单" :image-size="60" />
</el-card>
</div>
</div>
<!-- 履约与收货信息 -->
<el-card shadow="never" class="border-gray-100 mb-4">
<template #header><span class="font-medium text-[15px]">履约与收货信息</span></template>
<el-descriptions :column="3" border size="small">
<el-descriptions-item label="诊单ID" :span="3"><span class="font-mono">{{ detailData.diagnosis_id }}</span></el-descriptions-item>
<el-descriptions-item label="创建时间">{{ formatTime(detailData.create_time) }}</el-descriptions-item>
<el-descriptions-item label="业务订单创建人" :span="2">
<div v-if="detailData.creator_name" class="text-[13px] space-y-1">
<div><span class="font-medium text-gray-900">{{ detailData.creator_name || '—' }}</span></div>
<div v-if="detailOrderCreatorMetaLine" class="text-gray-600 text-xs">{{ detailOrderCreatorMetaLine }}</div>
</div>
<span v-else class="text-gray-400"></span>
</el-descriptions-item>
<el-descriptions-item label="创建人所属部门" :span="3">
<div v-if="detailOrderCreatorDeptBreadcrumbs.length" class="space-y-1.5">
<div v-for="(segments, idx) in detailOrderCreatorDeptBreadcrumbs" :key="idx">
<el-breadcrumb v-if="segments.length" class="text-[13px]" separator="/">
<el-breadcrumb-item v-for="(name, j) in segments" :key="j"><span class="text-gray-800">{{ name }}</span></el-breadcrumb-item>
</el-breadcrumb>
</div>
</div>
<span v-else class="text-gray-400"></span>
</el-descriptions-item>
<el-descriptions-item label="收货人">{{ detailData.recipient_name }}</el-descriptions-item>
<el-descriptions-item label="收货手机">
<span :class="detailRecipientRxPhoneMismatch ? 'text-red-600 font-bold font-mono' : 'font-mono'">{{ detailData.recipient_phone || '—' }}</span>
<el-tag v-if="detailRecipientRxPhoneMismatch" type="danger" size="small" effect="dark" class="ml-2">与处方手机不一致</el-tag>
</el-descriptions-item>
<el-descriptions-item label="收货地址">{{ detailFullAddress }}</el-descriptions-item>
<el-descriptions-item label="复诊">{{ detailData.is_follow_up ? '是' : '否' }}</el-descriptions-item>
<el-descriptions-item label="用药疗程">{{ detailData.medication_days ? detailData.medication_days + ' 天' : '—' }}</el-descriptions-item>
<el-descriptions-item label="上次医护">{{ detailData.prev_staff || '—' }}</el-descriptions-item>
<el-descriptions-item label="服务渠道">{{ detailData.service_channel || '—' }}</el-descriptions-item>
<el-descriptions-item label="服务套餐">{{ formatServicePackage(detailData.service_package) }}</el-descriptions-item>
<el-descriptions-item label="费用类别">{{ feeTypeText(detailData.fee_type) }}</el-descriptions-item>
<el-descriptions-item label="快递单号">{{ detailData.tracking_number || '—' }}</el-descriptions-item>
<el-descriptions-item label="快递公司">{{ expressCompanyLabel(detailData.express_company) }}</el-descriptions-item>
<el-descriptions-item v-perms="['tcm.prescriptionOrder/editRemarkExtra']" label="药房备注" :span="3">{{ detailData.remark_extra || '' }}</el-descriptions-item>
<el-descriptions-item label="医助备注" :span="3">{{ detailData.remark_assistant || '—' }}</el-descriptions-item>
<el-descriptions-item label="处方审核意见" :span="3">{{ detailData.prescription_audit_remark || '—' }}</el-descriptions-item>
<el-descriptions-item label="支付审核意见" :span="3">{{ detailData.payment_slip_audit_remark || '—' }}</el-descriptions-item>
</el-descriptions>
</el-card>
<!-- 物流轨迹只读 -->
<el-card v-if="String(detailData.tracking_number || '').trim()" shadow="never" class="border-gray-100 mb-4">
<template #header><span class="font-medium text-[15px]">物流轨迹</span></template>
<div class="flex flex-wrap items-center gap-3 mb-4">
<el-input v-model="logisticsTracePhoneTail" clearable maxlength="20" placeholder="收件手机" class="w-[180px]" @keyup.enter="fetchLogisticsTrace" />
<el-select v-model="detailLogisticsExpress" placeholder="承运商" style="width: 140px">
<el-option label="自动识别" value="auto" />
<el-option label="顺丰速运" value="sf" />
<el-option label="京东快递" value="jd" />
<el-option label="极兔速递" value="jt" />
</el-select>
<el-button v-perms="['tcm.prescriptionOrder/logisticsTrace']" type="primary" plain size="default" :loading="logisticsTraceLoading" @click="fetchLogisticsTrace">刷新轨迹</el-button>
</div>
<div v-if="logisticsTraceLoading && !logisticsTracePayload" class="py-6 text-center text-sm text-gray-500">正在加载物流轨迹...</div>
<div v-else-if="logisticsTracePayload" class="bg-gray-50/50 p-4 rounded-md">
<div v-if="logisticsTracePayload.state_text" class="text-sm mb-4 font-medium flex items-center gap-2">
<span class="text-gray-800">状态{{ logisticsTracePayload.state_text }}</span>
<el-tag v-if="logisticsTracePayload.carrier_label" size="small" type="info">{{ logisticsTracePayload.carrier_label }}</el-tag>
</div>
<el-timeline v-if="logisticsTraceList.length" class="mt-2 pl-2">
<el-timeline-item v-for="(t, idx) in logisticsTraceList" :key="idx" :type="idx === 0 ? 'primary' : 'info'" :hollow="idx !== 0" :timestamp="t.time" placement="top">
<span :class="idx === 0 ? 'text-gray-800 font-medium' : 'text-gray-500'">{{ t.context }}</span>
</el-timeline-item>
</el-timeline>
<el-empty v-else description="暂无轨迹节点记录" :image-size="64" />
</div>
</el-card>
<!-- 操作日志 -->
<el-card v-perms="['tcm.prescriptionOrder/logs']" shadow="never" class="border-gray-100">
<template #header><span class="font-medium text-[15px]">操作日志</span></template>
<el-timeline v-if="detailLogs.length" class="mt-2 pl-2">
<el-timeline-item v-for="(log, idx) in detailLogs" :key="log.id" :type="idx === 0 ? 'primary' : 'info'" :hollow="idx !== 0" :timestamp="formatTime(log.create_time)" placement="top">
<div class="flex items-center gap-2 mb-1">
<span class="font-medium text-[13px]">{{ log.admin_name }}</span>
<el-tag size="small" type="info">{{ logActionText(log.action) }}</el-tag>
</div>
<span :class="idx === 0 ? 'text-gray-800 font-medium' : 'text-gray-500'">{{ log.summary }}</span>
</el-timeline-item>
</el-timeline>
<el-empty v-else description="暂无操作日志" :image-size="64" />
</el-card>
</div>
</el-drawer>
<!-- 业务订单详情抽屉共享组件的 readonly 受限版展示范围由组件内 v-if="!readonly" 门控 -->
<prescription-order-detail-drawer ref="detailDrawerRef" readonly append-to-body />
</div>
</template>
<script setup lang="ts">
import { computed, watch, ref, onMounted } from 'vue'
import { computed, reactive, ref, watch } from 'vue'
import { usePaging } from '@/hooks/usePaging'
import { prescriptionOrderLists } from '@/api/tcm'
import PrescriptionOrderDetailDrawer from '@/views/consumer/prescription/components/PrescriptionOrderDetailDrawer.vue'
import {
prescriptionOrderLists,
prescriptionOrderDetail,
prescriptionOrderLogs,
prescriptionOrderLogisticsTrace,
prescriptionOrderPaidPayOrders
} from '@/api/tcm'
import { getDictData } from '@/api/app'
import { hasPermission } from '@/utils/perm'
import feedback from '@/utils/feedback'
import useUserStore from '@/stores/modules/user'
const userStore = useUserStore()
formatTime,
fulfillmentText,
fulfillmentTagType
} from '@/views/consumer/prescription/components/prescription-order-utils'
const props = defineProps<{
diagnosisId: number
@@ -379,179 +102,11 @@ const buildParams = () => {
queryParams.scene = 'diagnosis_edit'
}
/** 诊间医助角色(与 DiagnosisLists 等一致) */
const TCM_ASSISTANT_ROLE_ID = 2
/** 与 server/config/project.php prescription_audit_roles 默认一致,可处方审核的角色 */
const PRESCRIPTION_AUDIT_ROLE_IDS = [0, 3, 6]
// ─── 详情抽屉(共享组件,数据拉取/展示全部在组件内) ───
const detailDrawerRef = ref<InstanceType<typeof PrescriptionOrderDetailDrawer>>()
/**
* 是否展示「处方审核」相关字段
*/
const showPrescriptionAuditFilter = computed(() => {
const u = userStore.userInfo
if (!u || Number(u.root) === 1) return true
const ids = Array.isArray(u.role_ids) ? u.role_ids.map((n: unknown) => Number(n)) : []
if (!ids.includes(TCM_ASSISTANT_ROLE_ID)) return true
return ids.some((id) => PRESCRIPTION_AUDIT_ROLE_IDS.includes(id))
})
// ─── 详情抽屉 ───
const detailVisible = ref(false)
const detailLoading = ref(false)
const detailData = ref<any>(null)
const detailLogs = ref<any[]>([])
const detailUnlinkedPayOrders = ref<any[]>([])
const detailPrescription = computed(() => {
const p = detailData.value?.prescription
return p && typeof p === 'object' ? p : null
})
const detailLinkedPayOrders = computed(() => {
const arr = detailData.value?.linked_pay_orders
return Array.isArray(arr) ? arr : []
})
const detailAgencyToCollect = computed(() => {
const d = detailData.value
if (!d) return 0
const snap = d.agency_collect_amount
if (snap !== null && snap !== undefined && snap !== '') {
return Number(snap) || 0
}
const total = Number(d.amount) || 0
const paid = Number(d.linked_pay_paid_total) || 0
return Math.round((total - paid) * 100) / 100
})
const detailRecipientRxPhoneMismatch = computed(() => {
const rx = normalizeBizPhone(detailPrescription.value?.phone)
const biz = normalizeBizPhone(detailData.value?.recipient_phone)
if (!rx || !biz) return false
return rx !== biz
})
const detailFullAddress = computed(() => {
const d = detailData.value
if (!d) return '—'
const parts = []
if (d.shipping_province) parts.push(d.shipping_province)
if (d.shipping_city) parts.push(d.shipping_city)
if (d.shipping_district) parts.push(d.shipping_district)
if (d.shipping_address) parts.push(d.shipping_address)
return parts.length > 0 ? parts.join(' ') : '—'
})
const detailOrderCreatorMetaLine = computed(() => {
const d = detailData.value
if (!d) return ''
const account = String(d.creator_account ?? '').trim()
const mobile = String(d.creator_mobile ?? '').trim()
const parts: string[] = []
if (account) parts.push(`登录账号:${account}`)
if (mobile) parts.push(`手机:${mobile}`)
return parts.join(' · ')
})
const detailOrderCreatorDeptBreadcrumbs = computed(() => {
const raw = String(detailData.value?.order_creator_dept_path ?? detailData.value?.diagnosis_creator_dept_path ?? '').trim()
if (!raw) return [] as string[][]
return raw.split('').map((s) => s.trim()).filter(Boolean)
.map((p) => p.includes(' / ') ? p.split(' / ').map((x) => x.trim()).filter(Boolean) : p.split('/').map((x) => x.trim()).filter(Boolean))
.filter((segs) => segs.length > 0)
})
// ─── 物流轨迹 ───
const detailLogisticsExpress = ref<string>('auto')
const logisticsTraceLoading = ref(false)
const logisticsTracePayload = ref<Record<string, any> | null>(null)
const logisticsTracePhoneTail = ref('')
const logisticsTraceList = computed(() => {
const p = logisticsTracePayload.value
if (!p || !Array.isArray(p.traces)) return []
return p.traces as Array<{ time: string; context: string }>
})
async function fetchLogisticsTrace() {
const id = Number(detailData.value?.id)
if (!id) return
logisticsTraceLoading.value = true
try {
const digits = String(logisticsTracePhoneTail.value || '').replace(/\D/g, '')
const params: { id: number; express_company?: string; phone_tail?: string } = {
id,
express_company: detailLogisticsExpress.value
}
if (digits.length >= 4) params.phone_tail = digits
const res: any = await prescriptionOrderLogisticsTrace(params)
logisticsTracePayload.value = (res?.data ?? res) as Record<string, any>
} catch {
logisticsTracePayload.value = null
} finally {
logisticsTraceLoading.value = false
}
}
// ─── 打开详情 ───
async function openDetail(id: number) {
detailData.value = null
detailUnlinkedPayOrders.value = []
logisticsTracePayload.value = null
detailLogisticsExpress.value = 'auto'
logisticsTracePhoneTail.value = ''
detailLogs.value = []
detailVisible.value = true
detailLoading.value = true
try {
const res: any = await prescriptionOrderDetail({ id })
const d = res?.data ?? res ?? null
detailData.value = d
if (d) {
detailLogisticsExpress.value = String(d.express_company || 'auto') || 'auto'
const dig = String(d.recipient_phone || '').replace(/\D/g, '')
logisticsTracePhoneTail.value = dig.length >= 4 ? dig : ''
if (String(d.tracking_number || '').trim()) fetchLogisticsTrace()
fetchLogs(id)
if (d.diagnosis_id) {
loadDetailUnlinkedPayOrders(d.diagnosis_id, id, d.pay_order_ids || [])
}
}
} catch (e: any) {
feedback.msgError(e?.message || '加载详情失败')
detailVisible.value = false
} finally {
detailLoading.value = false
}
}
async function loadDetailUnlinkedPayOrders(diagnosisId: number, prescriptionOrderId: number, linkedIds: number[]) {
if (!diagnosisId) { detailUnlinkedPayOrders.value = []; return }
try {
const res: any = await prescriptionOrderPaidPayOrders({ diagnosis_id: diagnosisId, prescription_order_id: prescriptionOrderId })
const lists = res?.lists ?? res?.data?.lists ?? []
detailUnlinkedPayOrders.value = Array.isArray(lists) ? lists.filter((item: any) => !linkedIds.includes(item.id)) : []
} catch { detailUnlinkedPayOrders.value = [] }
}
function canViewPrescriptionOrderLogs() {
const p = userStore.perms || []
return p.includes('*') || p.includes('tcm.prescriptionOrder/logs')
}
async function fetchLogs(id: number) {
if (!canViewPrescriptionOrderLogs()) { detailLogs.value = []; return }
try {
const res: any = await prescriptionOrderLogs({ id })
detailLogs.value = res?.data ?? res ?? []
} catch { detailLogs.value = [] }
}
// ─── 工具函数 ───
function normalizeBizPhone(v: unknown): string {
if (v === null || v === undefined) return ''
return String(v).replace(/\s/g, '').trim()
function openDetail(id: number) {
detailDrawerRef.value?.open(id)
}
const formatAmount = (value: unknown) => {
@@ -559,126 +114,6 @@ const formatAmount = (value: unknown) => {
return Number.isFinite(n) ? n.toFixed(2) : '0.00'
}
function formatMoney(v: unknown) {
const n = Number(v)
return Number.isFinite(n) ? n.toFixed(2) : '0.00'
}
const formatTime = (value: unknown) => {
if (value === null || value === undefined || value === '') return '—'
if (typeof value === 'number' && value > 1e9 && value < 1e11) {
const d = new Date(value * 1000)
const pad = (n: number) => String(n).padStart(2, '0')
return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`
}
return String(value)
}
function formatOrderTime(v: unknown) {
if (v === null || v === undefined || v === '') return '—'
if (typeof v === 'string' && String(v).includes('-')) return String(v)
return formatTime(v)
}
function feeTypeText(t: number | undefined) {
const m: Record<number, string> = { 1: '药费', 2: '诊费', 3: '药费+诊费', 4: '其他' }
return m[Number(t)] ?? '—'
}
// 服务套餐字典选项(与 order_list.vue 数据源一致:dict 类型 server_order
const servicePackageOptions = ref<Array<{ name: string; value: string }>>([])
async function loadServicePackageOptions() {
try {
const data: any = await getDictData({ type: 'server_order' })
const list = (data?.server_order || []) as Array<{ name: string; value: string; status?: number }>
servicePackageOptions.value = list.filter((item) => item.status !== 0)
} catch {
servicePackageOptions.value = []
}
}
function formatServicePackage(value: unknown): string {
if (value === null || value === undefined || value === '') return '—'
let packages: string[] = []
if (Array.isArray(value)) {
packages = value.map((v) => String(v)).filter((v) => v !== '')
} else if (typeof value === 'string') {
packages = value.split(',').map((v) => v.trim()).filter((v) => v !== '')
}
if (packages.length === 0) return '—'
const names = packages.map((val) => {
const opt = servicePackageOptions.value.find((o) => o.value === val)
return opt ? opt.name : val
})
return names.join('、')
}
onMounted(() => {
loadServicePackageOptions()
})
function expressCompanyLabel(v: unknown) {
const s = String(v || '').toLowerCase()
if (s === 'sf') return '顺丰速运'
if (s === 'jd') return '京东快递'
if (s === 'jt' || s === 'jtexpress') return '极兔速递'
return '自动识别'
}
function consumerRxAuditText(s: number | undefined) {
const n = Number(s)
if (n === 1) return '已通过'
if (n === 2) return '已驳回'
return '待审核'
}
function consumerRxAuditTag(s: number | undefined): 'success' | 'warning' | 'danger' | 'info' {
const n = Number(s)
if (n === 1) return 'success'
if (n === 2) return 'danger'
return 'warning'
}
function payOrderStatusTag(s: number | undefined): 'success' | 'warning' | 'danger' | 'info' {
const n = Number(s)
if (n === 2) return 'success'
if (n === 1) return 'warning'
return 'info'
}
function orderStatusText(s: number | undefined) {
const m: Record<number, string> = { 0: '待支付', 1: '待支付', 2: '已支付', 3: '已取消' }
return m[Number(s)] ?? '—'
}
const fulfillmentText = (s: number | undefined) => {
const m: Record<number, string> = { 1: '待双审通过', 2: '待发货', 3: '已完成', 4: '已取消', 5: '已发货', 6: '已签收', 7: '进行中', 8: '暂不制药', 9: '拒收', 10: '退款', 11: '保留药方', 12: '制药缓发' }
return m[Number(s)] ?? '—'
}
const fulfillmentTagType = (s: number | undefined): 'success' | 'warning' | 'danger' | 'info' | 'primary' => {
const n = Number(s)
if (n === 3 || n === 6) return 'success'
if (n === 5) return 'primary'
if (n === 4 || n === 9 || n === 10) return 'danger'
if (n === 2 || n === 7) return 'warning'
if (n === 8 || n === 11 || n === 12) return 'info'
return 'info'
}
function logActionText(act: string) {
const m: Record<string, string> = {
create: '创建', edit: '编辑', audit_rx_approve: '处方审核', audit_rx_reject: '处方审核',
audit_pay_approve: '支付审核', audit_pay_reject: '支付审核', fill_tracking: '填快递单',
ship: '确认发货', withdraw: '撤销', link_pay_order: '关联支付单',
revoke_rx_audit: '撤回处方审核', revoke_pay_audit: '撤回支付审核',
gancao_submit: '甘草下单', patch_rx_patient: '处方患者信息',
update_amount: '修改订单金额', complete: '完成订单'
}
return m[act] || act
}
watch(
() => [props.diagnosisId, patientIdNum.value] as const,
() => {
@@ -699,22 +134,4 @@ defineExpose({ refresh: () => getLists() })
.po-empty-tip {
padding: 24px 0;
}
.audit-stamp {
position: absolute;
top: 12px;
right: 16px;
transform: rotate(15deg);
opacity: 0.15;
pointer-events: none;
z-index: 1;
}
.stamp-inner {
border: 3px solid currentColor;
border-radius: 8px;
padding: 4px 12px;
font-size: 18px;
font-weight: bold;
}
.stamp-pass { color: #22c55e; }
.stamp-reject { color: #ef4444; }
</style>
+8 -1
View File
@@ -77,7 +77,14 @@ module.exports = {
mask: 'var(--el-mask-color)'
},
fontFamily: {
sans: ['PingFang SC', 'Arial', 'Hiragino Sans GB', 'Microsoft YaHei', 'sans-serif']
sans: [
'Noto Sans SC',
'PingFang SC',
'Microsoft YaHei',
'Hiragino Sans GB',
'Arial',
'sans-serif'
]
},
boxShadow: {
DEFAULT: 'var(--el-box-shadow)',
File diff suppressed because one or more lines are too long
@@ -207,11 +207,17 @@ class OrderController extends BaseAdminController
$params['creator_id'] = $this->adminId;
$params['payment_channel'] = (string)$this->request->post('payment_channel', 'normal');
$params['require_payment_slip_audit'] = (int)$this->request->post('require_payment_slip_audit', 0);
// 创建方式:优先取前端透传的 create_type,否则按 payment_channel 派生(fubei→fubei,其余 normal
// 创建方式:优先取前端透传的 create_type,否则按 payment_channel 派生(fubei→fubeiexpress_cod→express_cod其余 normal
$createTypeReq = (string)$this->request->post('create_type', '');
$params['create_type'] = in_array($createTypeReq, ['normal', 'wechat_work', 'fubei'], true)
? $createTypeReq
: ($params['payment_channel'] === 'fubei' ? 'fubei' : 'normal');
if (in_array($createTypeReq, ['normal', 'wechat_work', 'fubei', 'express_cod'], true)) {
$params['create_type'] = $createTypeReq;
} elseif ($params['payment_channel'] === 'fubei') {
$params['create_type'] = 'fubei';
} elseif ($params['payment_channel'] === 'express_cod') {
$params['create_type'] = 'express_cod';
} else {
$params['create_type'] = 'normal';
}
$result = OrderLogic::create($params);
if (!$result) {
@@ -0,0 +1,51 @@
<?php
declare(strict_types=1);
namespace app\adminapi\controller\stats;
use app\adminapi\controller\BaseAdminController;
use app\adminapi\logic\stats\RevisitRateLogic;
/**
* 复诊接诊率统计(按月)
*
* - GET stats.revisitRate/overview 当月 N 诊接诊率(部门 → 医助分组 + 合计)
* - GET stats.revisitRate/deptOptions 部门下拉(前端组树)
* - GET stats.revisitRate/assignLines 「被指派数」明细(按诊单聚合)
* - GET stats.revisitRate/visitOrderLines 「N 诊单数」订单明细
*/
class RevisitRateController extends BaseAdminController
{
public function overview()
{
// 涉及指派日志 + 全量订单序列扫描,放宽执行时间兜底
@set_time_limit(120);
$params = $this->request->get();
return $this->data(RevisitRateLogic::overview($params));
}
public function deptOptions()
{
return $this->data(RevisitRateLogic::deptOptions());
}
/** 「被指派数」点击下钻:诊单维度明细 */
public function assignLines()
{
@set_time_limit(120);
$params = $this->request->get();
return $this->data(RevisitRateLogic::assignLines($params));
}
/** 「N 诊单数」点击下钻:具体订单明细 */
public function visitOrderLines()
{
@set_time_limit(120);
$params = $this->request->get();
return $this->data(RevisitRateLogic::visitOrderLines($params));
}
}
+34 -14
View File
@@ -23,9 +23,9 @@ use think\facade\Log;
class OrderLogic
{
/**
* 创建方式统一三值normal 普通订单 / wechat_work 企业微信对外收款 / fubei 付呗
* 创建方式:normal 普通订单 / wechat_work 企业微信对外收款 / fubei 付呗 / express_cod 快递代收
*/
private const CREATE_TYPES = ['normal', 'wechat_work', 'fubei'];
private const CREATE_TYPES = ['normal', 'wechat_work', 'fubei', 'express_cod'];
/**
* @notes 生成订单号
@@ -64,6 +64,15 @@ class OrderLogic
return 'normal';
}
/**
* 是否为「待审核(5)且需人工确认到账」的单:付呗(payment_method=fubei) 或 快递代收(create_type=express_cod)
*/
private static function isPendingManualAudit(Order $order): bool
{
return (string)($order->payment_method ?? '') === 'fubei'
|| (string)($order->create_type ?? '') === 'express_cod';
}
/**
* @notes 创建订单
* @param array $params
@@ -73,11 +82,16 @@ class OrderLogic
{
try {
$channel = (string)($params['payment_channel'] ?? 'normal');
if (!in_array($channel, ['normal', 'fubei'], true)) {
if (!in_array($channel, ['normal', 'fubei', 'express_cod'], true)) {
$channel = 'normal';
}
$paymentMethod = $channel === 'fubei' ? 'fubei' : null;
$createType = self::normalizeCreateType((string)($params['create_type'] ?? ''), $paymentMethod);
// 快递代收:以 express_cod 标记创建方式(与 fubei 流转一致,但 payment_method 待到账时再写)
$createTypeHint = $channel === 'express_cod' ? 'express_cod' : '';
$createType = self::normalizeCreateType(
(string)($params['create_type'] ?? $createTypeHint),
$paymentMethod
);
$requirePaymentSlipAudit = (int)($params['require_payment_slip_audit'] ?? 0) === 1;
$order = new Order();
@@ -87,10 +101,13 @@ class OrderLogic
$order->order_type = $params['order_type'];
$order->amount = $params['amount'];
$order->create_type = $createType;
// 付呗且申请审核支付单:待审核(5);否则待支付(1)
// 付呗/快递代收且申请审核支付单:待审核(5);否则待支付(1)
if ($channel === 'fubei') {
$order->payment_method = 'fubei';
$order->status = $requirePaymentSlipAudit ? 5 : 1;
} elseif ($channel === 'express_cod') {
// payment_method 留空,待人工确认到账时再写真实支付方式
$order->status = $requirePaymentSlipAudit ? 5 : 1;
} else {
$order->status = 1; // 待支付
}
@@ -387,11 +404,11 @@ class OrderLogic
}
$st = (int)$order->status;
// 1=待支付;5=待审核(付呗+申请支付单审核) 时允许录入手动到账
// 1=待支付;5=待审核(付呗/快递代收+申请支付单审核) 时允许录入手动到账
if ($st === 1) {
// 正常待支付
} elseif ($st === 5 && (string)($order->payment_method ?? '') === 'fubei') {
// 待审核的付呗单,通过人工确认后标记已支付
} elseif ($st === 5 && self::isPendingManualAudit($order)) {
// 待审核的付呗/快递代收单,通过人工确认后标记已支付
} else {
self::setError('订单状态不允许支付');
return false;
@@ -424,8 +441,8 @@ class OrderLogic
}
$st = (int)$order->status;
if ($st !== 1 && !($st === 5 && (string)($order->payment_method ?? '') === 'fubei')) {
self::setError('只有待支付或待审核(付呗)的订单才能取消');
if ($st !== 1 && !($st === 5 && self::isPendingManualAudit($order))) {
self::setError('只有待支付或待审核(付呗/快递代收)的订单才能取消');
return false;
}
@@ -509,13 +526,13 @@ class OrderLogic
}
$st = (int) $order->status;
if ($st === 5 && (string) ($order->payment_method ?? '') !== 'fubei') {
self::setError('待审核订单仅支持付呗渠道拆分');
if ($st === 5 && !self::isPendingManualAudit($order)) {
self::setError('待审核订单仅支持付呗/快递代收渠道拆分');
return false;
}
if (! in_array($st, [1, 5, 2], true)) {
self::setError('仅「待支付」「待审核(付呗)」或「已支付」的订单可拆分');
self::setError('仅「待支付」「待审核(付呗/快递代收)」或「已支付」的订单可拆分');
return false;
}
@@ -586,7 +603,10 @@ class OrderLogic
(string) ($order->remark ?? '')
);
if ($st === 5) {
$n->payment_method = 'fubei';
// 付呗子单沿用 payment_method=fubei;快递代收子单 payment_method 留空,靠 create_type 标记
if ((string) ($order->payment_method ?? '') === 'fubei') {
$n->payment_method = 'fubei';
}
$n->status = 5;
} elseif ($st === 2) {
$n->status = 2;
@@ -0,0 +1,678 @@
<?php
declare(strict_types=1);
namespace app\adminapi\logic\stats;
use think\facade\Db;
/**
* 复诊接诊率统计(按月)
*
* 口径说明:
* - 当月被指派总数 = 当月内 `tcm_diagnosis_assign_log`(按 **指派操作时间 lg.create_time** 落月,to_assistant_id>0
* **剔除勾选「继承」的指派 is_inherit=1**,诊单未删除)去重后的「医助 × 诊单」组合;
* 同一诊单当月被多次指派给同一医助只计 1 次。
* - 第 N 次下单 = 诊单(患者)名下计入业绩的业务订单(剔除履约 4/9/10、软删)按 create_time 升序的**全局**序列中第 N 笔;
* 诊次**跨月累计不重置**:例如 5 月指派后旗下成交 4 单为二诊~五诊,6 月再成交即为六诊。
* - 当月 N 诊单数 = **当月内下单**且全局序号为 N 的订单数,归属下单时点的**持有医助**——
* 按指派日志时间线取「订单时间之前最近一次指派」的 to_assistant_id(释放 to=0 即不再归属;
* 「继承」指派会转移持有人用于归属,但不计被指派数)。指派可发生在往月。
* - 当月 N 诊接诊率 = 当月 N 诊单数 ÷ 当月被指派总数;往月指派当月成交会推高分子,故比率可能超过 100%;
* 医助当月无新指派但旗下有成交时,被指派数为 0、比率显示为空。
* - 分档动态产出:N 从 2 起,至当月命中数据的最大序号(至少展示到四诊,上限 MAX_VISIT_SLOT 防御异常数据),
* 返回 `slots` 列表供前端动态渲染「五诊」「六诊」… 列。
* - 部门归类:医助按其人事部门(admin_dept 最小 dept_id)归组;部门筛选(dept_ids,含组织下级)按该归属部门过滤。
* - 部门行 / 合计行:被指派数按诊单去重(可能小于下级行相加);N 诊单数为下级行求和(每笔订单唯一归属一名医助)。
*/
class RevisitRateLogic
{
/** 至少展示到的复诊序号(二诊/三诊/四诊) */
private const MIN_VISIT_SLOT_CEILING = 4;
/** 复诊序号统计上限(防御脏数据导致列爆炸;诊次跨月累计,上限放宽) */
private const MAX_VISIT_SLOT = 50;
/** 未分配部门的占位分组 */
private const UNASSIGNED_DEPT_NAME = '未分配部门';
/**
* @param array{month?:string,dept_ids?:int[]|string} $params
*
* @return array{
* month:string,start_date:string,end_date:string,
* slots:list<int>,
* total:array<string,int|float|null>,
* rows:list<array<string,mixed>>
* }
*/
public static function overview(array $params): array
{
$ctx = self::buildStatsCore($params);
$month = $ctx['month'];
$minSlots = range(2, self::MIN_VISIT_SLOT_CEILING);
$universe = self::assistantUniverse($ctx);
if ($universe === []) {
return [
'month' => $month,
'start_date' => $ctx['startDate'],
'end_date' => $ctx['endDate'],
'slots' => $minSlots,
'total' => self::buildMetricPack(0, [], $minSlots),
'rows' => [],
];
}
// 分档:2 ~ max(4, 当月命中的最大诊次)
$maxHitSlot = 0;
foreach ($ctx['slotOrdersByAssistant'] as $slotMap) {
foreach ($slotMap as $slot => $_) {
if ((int) $slot > $maxHitSlot) {
$maxHitSlot = (int) $slot;
}
}
}
$slots = range(2, max(self::MIN_VISIT_SLOT_CEILING, $maxHitSlot));
$nameMap = Db::name('admin')
->whereIn('id', array_keys($universe))
->column('name', 'id');
// 医助行(按部门分组收集)
/** @var array<int, list<array<string, mixed>>> $assistantRowsByDept */
$assistantRowsByDept = [];
/** @var array<int, array<int, true>> $deptDiagSet 部门 => 去重被指派诊单集合 */
$deptDiagSet = [];
/** @var array<int, array<int, int>> $deptSlotCounts 部门 => [slot => 订单数] */
$deptSlotCounts = [];
/** @var array<int, true> $totalDiagSet */
$totalDiagSet = [];
/** @var array<int, int> $totalSlotCounts */
$totalSlotCounts = [];
foreach ($universe as $aid => $_) {
$deptId = (int) ($ctx['assistantDept'][$aid] ?? 0);
$diagSet = $ctx['diagsByAssistant'][$aid] ?? [];
foreach ($diagSet as $did => $_d) {
$deptDiagSet[$deptId][$did] = true;
$totalDiagSet[$did] = true;
}
$slotCounts = [];
foreach ($ctx['slotOrdersByAssistant'][$aid] ?? [] as $slot => $orders) {
$cnt = \count($orders);
$slotCounts[$slot] = $cnt;
$deptSlotCounts[$deptId][$slot] = ($deptSlotCounts[$deptId][$slot] ?? 0) + $cnt;
$totalSlotCounts[$slot] = ($totalSlotCounts[$slot] ?? 0) + $cnt;
}
$deptName = $deptId > 0
? (string) ($ctx['deptNames'][$deptId] ?? ('#' . $deptId))
: self::UNASSIGNED_DEPT_NAME;
$assistantRowsByDept[$deptId][] = [
'row_key' => 'a' . $aid,
'is_dept' => 0,
'assistant_id' => (int) $aid,
'assistant_name' => (string) ($nameMap[$aid] ?? ('#' . $aid)),
'dept_id' => $deptId,
'dept_name' => $deptName,
] + self::buildMetricPack(\count($diagSet), $slotCounts, $slots);
}
// 部门行 + 子行
$rows = [];
foreach ($assistantRowsByDept as $deptId => $children) {
usort($children, static function (array $a, array $b): int {
if ($a['assigned_count'] !== $b['assigned_count']) {
return $b['assigned_count'] <=> $a['assigned_count'];
}
return strcmp((string) $a['assistant_name'], (string) $b['assistant_name']);
});
$deptName = $deptId > 0
? (string) ($ctx['deptNames'][$deptId] ?? ('#' . $deptId))
: self::UNASSIGNED_DEPT_NAME;
$rows[] = [
'row_key' => 'd' . $deptId,
'is_dept' => 1,
'dept_id' => (int) $deptId,
'dept_name' => $deptName,
'assistant_count' => \count($children),
'children' => $children,
] + self::buildMetricPack(\count($deptDiagSet[$deptId] ?? []), $deptSlotCounts[$deptId] ?? [], $slots);
}
usort($rows, static function (array $a, array $b): int {
if ($a['assigned_count'] !== $b['assigned_count']) {
return $b['assigned_count'] <=> $a['assigned_count'];
}
return strcmp((string) $a['dept_name'], (string) $b['dept_name']);
});
return [
'month' => $month,
'start_date' => $ctx['startDate'],
'end_date' => $ctx['endDate'],
'slots' => $slots,
'total' => self::buildMetricPack(\count($totalDiagSet), $totalSlotCounts, $slots),
'rows' => $rows,
];
}
/**
* 被指派明细(按诊单聚合,与「被指派数」同口径可对账)。
* scopeassistant_id(医助行)/ dept_id(部门行,含 0=未分配部门)/ 都不传 = 当前部门筛选下合计。
*
* @param array{month?:string,dept_ids?:int[]|string,assistant_id?:int|string,dept_id?:int|string} $params
*
* @return array{month:string,count:int,rows:list<array<string,mixed>>}
*/
public static function assignLines(array $params): array
{
$ctx = self::buildStatsCore($params);
$assistantSet = self::applyRowScope($ctx, $params);
/** @var array<int, array{assistants: array<int, true>, assign_count: int, last_time: int}> $byDiag */
$byDiag = [];
foreach ($ctx['pairsRaw'] as $p) {
$aid = (int) $p['to_assistant_id'];
$did = (int) $p['diagnosis_id'];
if (!isset($assistantSet[$aid])) {
continue;
}
if (!isset($byDiag[$did])) {
$byDiag[$did] = ['assistants' => [], 'assign_count' => 0, 'last_time' => 0];
}
$byDiag[$did]['assistants'][$aid] = true;
$byDiag[$did]['assign_count']++;
$byDiag[$did]['last_time'] = max($byDiag[$did]['last_time'], (int) $p['create_time']);
}
if ($byDiag === []) {
return ['month' => $ctx['month'], 'count' => 0, 'rows' => []];
}
$diagInfo = self::fetchDiagnosisInfo(array_keys($byDiag));
$assistantIds = [];
foreach ($byDiag as $d) {
foreach ($d['assistants'] as $aid => $_) {
$assistantIds[$aid] = true;
}
}
$nameMap = Db::name('admin')
->whereIn('id', array_keys($assistantIds))
->column('name', 'id');
$rows = [];
foreach ($byDiag as $did => $d) {
$names = [];
foreach ($d['assistants'] as $aid => $_) {
$names[] = (string) ($nameMap[$aid] ?? ('#' . $aid));
}
$rows[] = [
'diagnosis_id' => (int) $did,
'patient_name' => (string) ($diagInfo[$did]['patient_name'] ?? ''),
'patient_phone' => (string) ($diagInfo[$did]['phone'] ?? ''),
'assistant_names' => implode('、', $names),
'assign_count' => (int) $d['assign_count'],
'last_assign_time' => (int) $d['last_time'],
'last_assign_time_text' => $d['last_time'] > 0 ? date('Y-m-d H:i:s', $d['last_time']) : '',
];
}
usort($rows, static fn (array $a, array $b): int => $b['last_assign_time'] <=> $a['last_assign_time']);
return ['month' => $ctx['month'], 'count' => \count($rows), 'rows' => $rows];
}
/**
* N 诊订单明细:scope 内当月下单、全局序号 = slot 的具体订单(归属持有医助),与 visit{slot}_count 同口径可对账。
*
* @param array{month?:string,slot?:int|string,dept_ids?:int[]|string,assistant_id?:int|string,dept_id?:int|string} $params
*
* @return array{month:string,slot:int,count:int,rows:list<array<string,mixed>>}
*/
public static function visitOrderLines(array $params): array
{
$slot = (int) ($params['slot'] ?? 0);
if ($slot < 2 || $slot > self::MAX_VISIT_SLOT) {
return ['month' => self::normalizeMonth((string) ($params['month'] ?? '')), 'slot' => $slot, 'count' => 0, 'rows' => []];
}
$ctx = self::buildStatsCore($params);
$assistantSet = self::applyRowScope($ctx, $params);
$orderRows = [];
foreach ($assistantSet as $aid => $_) {
foreach ($ctx['slotOrdersByAssistant'][$aid][$slot] ?? [] as $r) {
$r['holder_assistant_id'] = (int) $aid;
$orderRows[] = $r;
}
}
if ($orderRows === []) {
return ['month' => $ctx['month'], 'slot' => $slot, 'count' => 0, 'rows' => []];
}
$diagIds = array_values(array_unique(array_map(
static fn (array $r): int => (int) $r['diagnosis_id'],
$orderRows
)));
$diagInfo = self::fetchDiagnosisInfo($diagIds);
$adminIds = [];
foreach ($orderRows as $r) {
if ((int) $r['creator_id'] > 0) {
$adminIds[(int) $r['creator_id']] = true;
}
$adminIds[(int) $r['holder_assistant_id']] = true;
}
$adminNames = $adminIds !== []
? Db::name('admin')->whereIn('id', array_keys($adminIds))->column('name', 'id')
: [];
$rows = [];
foreach ($orderRows as $r) {
$did = (int) $r['diagnosis_id'];
$cid = (int) $r['creator_id'];
$hid = (int) $r['holder_assistant_id'];
$ct = (int) $r['create_time'];
$rows[] = [
'order_id' => (int) $r['id'],
'order_no' => (string) ($r['order_no'] ?? ''),
'diagnosis_id' => $did,
'patient_name' => (string) ($diagInfo[$did]['patient_name'] ?? ''),
'patient_phone' => (string) ($diagInfo[$did]['phone'] ?? ''),
'amount' => round((float) ($r['amount'] ?? 0), 2),
'create_time' => $ct,
'create_time_text' => $ct > 0 ? date('Y-m-d H:i:s', $ct) : '',
'creator_id' => $cid,
'creator_name' => $cid > 0 ? (string) ($adminNames[$cid] ?? ('#' . $cid)) : '—',
'assistant_id' => $hid,
'assistant_name' => $hid > 0 ? (string) ($adminNames[$hid] ?? ('#' . $hid)) : '—',
];
}
usort($rows, static fn (array $a, array $b): int => $b['create_time'] <=> $a['create_time']);
return ['month' => $ctx['month'], 'slot' => $slot, 'count' => \count($rows), 'rows' => $rows];
}
/**
* 部门下拉(全量未删除部门,前端组树)。
*
* @return array{rows: list<array{id:int,pid:int,name:string}>}
*/
public static function deptOptions(): array
{
$rows = Db::name('dept')
->whereNull('delete_time')
->field(['id', 'pid', 'name'])
->order('sort', 'desc')
->order('id', 'asc')
->select()
->toArray();
return [
'rows' => array_map(static fn (array $r): array => [
'id' => (int) $r['id'],
'pid' => (int) $r['pid'],
'name' => (string) $r['name'],
], $rows),
];
}
// ─────────────────────────── 内部实现 ───────────────────────────
/**
* 核心统计上下文:
* 1. 全量指派日志(≤ 月末)构建持有时间线;
* 2. 分母:当月非继承指派的「医助 × 诊单」;
* 3. 分子:曾被指派诊单的当月订单按全局序号 ≥2 归属持有医助;
* 4. 应用部门筛选(含组织下级)。
*
* @param array{month?:string,dept_ids?:int[]|string} $params
*
* @return array{
* month:string,startDate:string,endDate:string,startTs:int,endTs:int,
* pairsRaw:list<array{diagnosis_id:int,to_assistant_id:int,create_time:int}>,
* diagsByAssistant:array<int,array<int,true>>,
* slotOrdersByAssistant:array<int,array<int,list<array<string,mixed>>>>,
* assistantDept:array<int,int>,
* deptNames:array<int,string>
* }
*/
private static function buildStatsCore(array $params): array
{
$month = self::normalizeMonth((string) ($params['month'] ?? ''));
$startTs = (int) strtotime($month . '-01 00:00:00');
$endTs = (int) strtotime(date('Y-m-t', $startTs) . ' 23:59:59');
// 全量指派日志(≤ 月末,诊单未删除):含释放(to=0)与继承行,用于持有时间线
$logRows = Db::name('tcm_diagnosis_assign_log')
->alias('lg')
->join('tcm_diagnosis dg', 'dg.id = lg.diagnosis_id AND dg.delete_time IS NULL', 'INNER')
->where('lg.create_time', '<=', $endTs)
->where('lg.diagnosis_id', '>', 0)
->field(['lg.id', 'lg.diagnosis_id', 'lg.to_assistant_id', 'lg.create_time', 'lg.is_inherit'])
->order(['lg.diagnosis_id' => 'asc', 'lg.create_time' => 'asc', 'lg.id' => 'asc'])
->select()
->toArray();
/** @var array<int, list<array{t:int,to:int}>> $timeline 诊单 => 持有变更时间线(升序) */
$timeline = [];
$pairsRaw = [];
/** @var array<int, array<int, true>> $diagsByAssistant 分母:医助 => 诊单集合 */
$diagsByAssistant = [];
/** @var array<int, true> $candidateDiagSet 曾被指派(to>0,含继承)的诊单 */
$candidateDiagSet = [];
foreach ($logRows as $r) {
$did = (int) ($r['diagnosis_id'] ?? 0);
$aid = (int) ($r['to_assistant_id'] ?? 0);
$t = (int) ($r['create_time'] ?? 0);
$timeline[$did][] = ['t' => $t, 'to' => $aid];
if ($aid > 0) {
$candidateDiagSet[$did] = true;
if ((int) ($r['is_inherit'] ?? 0) === 0 && $t >= $startTs && $t <= $endTs) {
$pairsRaw[] = ['diagnosis_id' => $did, 'to_assistant_id' => $aid, 'create_time' => $t];
$diagsByAssistant[$aid][$did] = true;
}
}
}
// 分子:曾被指派诊单的当月订单(全局序号 ≥2),归属下单时点的持有医助
/** @var array<int, array<int, list<array<string, mixed>>>> $slotOrdersByAssistant */
$slotOrdersByAssistant = [];
foreach (array_chunk(array_keys($candidateDiagSet), 2000) as $chunk) {
$orderRows = self::fetchOrderSeqRows(
$chunk,
['o.id', 'o.order_no', 'o.diagnosis_id', 'o.create_time', 'o.amount', 'o.creator_id']
);
$curDid = 0;
$seq = 0;
$ptr = 0;
$holder = 0;
foreach ($orderRows as $r) {
$did = (int) ($r['diagnosis_id'] ?? 0);
if ($did <= 0) {
continue;
}
if ($did !== $curDid) {
$curDid = $did;
$seq = 0;
$ptr = 0;
$holder = 0;
}
$seq++;
$ct = (int) ($r['create_time'] ?? 0);
// 推进时间线指针:订单时间之前(含同刻)最近一次指派的持有人
$tl = $timeline[$did] ?? [];
$tlCount = \count($tl);
while ($ptr < $tlCount && $tl[$ptr]['t'] <= $ct) {
$holder = (int) $tl[$ptr]['to'];
$ptr++;
}
if ($seq < 2 || $seq > self::MAX_VISIT_SLOT) {
continue;
}
if ($ct < $startTs || $ct > $endTs) {
continue;
}
if ($holder > 0) {
$slotOrdersByAssistant[$holder][$seq][] = $r;
}
}
}
// 医助归属部门 + 部门筛选(含组织下级)
$universeIds = array_keys($diagsByAssistant + $slotOrdersByAssistant);
[$assistantDept, $deptNames] = self::buildAssistantDeptIndex($universeIds);
$deptFilterIds = self::parseDeptIds($params['dept_ids'] ?? null);
if ($deptFilterIds !== []) {
$subtreeSet = self::expandDeptSubtreeSet($deptFilterIds);
foreach ($universeIds as $aid) {
$deptId = (int) ($assistantDept[$aid] ?? 0);
if ($deptId <= 0 || !isset($subtreeSet[$deptId])) {
unset($diagsByAssistant[$aid], $slotOrdersByAssistant[$aid]);
}
}
}
return [
'month' => $month,
'startDate' => date('Y-m-d', $startTs),
'endDate' => date('Y-m-d', $endTs),
'startTs' => $startTs,
'endTs' => $endTs,
'pairsRaw' => $pairsRaw,
'diagsByAssistant' => $diagsByAssistant,
'slotOrdersByAssistant' => $slotOrdersByAssistant,
'assistantDept' => $assistantDept,
'deptNames' => $deptNames,
];
}
/**
* 统计涉及的医助全集:分母(被指派)∪ 分子(持有成交)。
*
* @param array{diagsByAssistant:array<int,array<int,true>>,slotOrdersByAssistant:array<int,array<int,list<array<string,mixed>>>>} $ctx
*
* @return array<int, true>
*/
private static function assistantUniverse(array $ctx): array
{
$set = [];
foreach (array_keys($ctx['diagsByAssistant']) as $aid) {
$set[(int) $aid] = true;
}
foreach (array_keys($ctx['slotOrdersByAssistant']) as $aid) {
$set[(int) $aid] = true;
}
return $set;
}
/**
* 行级 scopeassistant_id(医助行)优先;其次 dept_id(部门归组行,0=未分配部门);都不传 = 全部(已含部门筛选)。
*
* @return array<int, true> scope 内医助集合
*/
private static function applyRowScope(array $ctx, array $params): array
{
$assistantId = (int) ($params['assistant_id'] ?? 0);
$hasDeptScope = isset($params['dept_id']) && $params['dept_id'] !== '' && $params['dept_id'] !== null;
$deptScopeId = $hasDeptScope ? (int) $params['dept_id'] : -1;
$assistantSet = [];
foreach (self::assistantUniverse($ctx) as $aid => $_) {
if ($assistantId > 0) {
if ((int) $aid === $assistantId) {
$assistantSet[$aid] = true;
}
continue;
}
if ($hasDeptScope) {
if ((int) ($ctx['assistantDept'][$aid] ?? 0) === $deptScopeId) {
$assistantSet[$aid] = true;
}
continue;
}
$assistantSet[$aid] = true;
}
return $assistantSet;
}
/**
* 医助 → 归属部门 + 部门名称表。
*
* @param list<int> $adminIds
*
* @return array{0: array<int,int>, 1: array<int,string>}
*/
private static function buildAssistantDeptIndex(array $adminIds): array
{
if ($adminIds === []) {
return [[], []];
}
// admin_dept 为 (admin_id, dept_id) 联合主键、无自增 id;取最小 dept_id 作为归属部门保证确定性
$relRows = Db::name('admin_dept')
->whereIn('admin_id', $adminIds)
->order(['admin_id' => 'asc', 'dept_id' => 'asc'])
->field(['admin_id', 'dept_id'])
->select()
->toArray();
$deptNames = Db::name('dept')
->whereNull('delete_time')
->column('name', 'id');
$canonical = [];
foreach ($relRows as $r) {
$aid = (int) ($r['admin_id'] ?? 0);
$deptId = (int) ($r['dept_id'] ?? 0);
if ($aid <= 0 || $deptId <= 0 || isset($canonical[$aid])) {
continue;
}
if (!isset($deptNames[$deptId])) {
continue;
}
$canonical[$aid] = $deptId;
}
$names = [];
foreach ($deptNames as $id => $name) {
$names[(int) $id] = (string) $name;
}
return [$canonical, $names];
}
/**
* @param mixed $raw int[] | 逗号分隔字符串
*
* @return list<int>
*/
private static function parseDeptIds(mixed $raw): array
{
if ($raw === null || $raw === '' || $raw === []) {
return [];
}
$list = \is_array($raw) ? $raw : explode(',', (string) $raw);
return array_values(array_unique(array_filter(
array_map('intval', $list),
static fn (int $v): bool => $v > 0
)));
}
/**
* 选中部门 + 全部组织下级的 id 集合。
*
* @param list<int> $deptIds
*
* @return array<int, true>
*/
private static function expandDeptSubtreeSet(array $deptIds): array
{
$rows = Db::name('dept')
->whereNull('delete_time')
->field(['id', 'pid'])
->select()
->toArray();
$childrenByPid = [];
foreach ($rows as $r) {
$childrenByPid[(int) $r['pid']][] = (int) $r['id'];
}
$set = [];
$queue = $deptIds;
while ($queue !== []) {
$id = (int) array_shift($queue);
if ($id <= 0 || isset($set[$id])) {
continue;
}
$set[$id] = true;
foreach ($childrenByPid[$id] ?? [] as $childId) {
$queue[] = $childId;
}
}
return $set;
}
/**
* 诊单订单序列源查询(与业绩口径一致),统一排序保证序号稳定。
*
* @param list<int> $diagIds
* @param list<string> $fields
*
* @return list<array<string, mixed>>
*/
private static function fetchOrderSeqRows(array $diagIds, array $fields): array
{
$q = Db::name('tcm_prescription_order')
->alias('o')
->whereIn('o.diagnosis_id', $diagIds)
->whereNull('o.delete_time');
YejiStatsLogic::applyPrescriptionOrderNotCancelledForPerformanceQuery($q, 'o');
return $q
->field($fields)
->order(['o.diagnosis_id' => 'asc', 'o.create_time' => 'asc', 'o.id' => 'asc'])
->select()
->toArray();
}
/**
* @param list<int> $diagIds
*
* @return array<int, array{patient_name:string,phone:string}>
*/
private static function fetchDiagnosisInfo(array $diagIds): array
{
if ($diagIds === []) {
return [];
}
$rows = Db::name('tcm_diagnosis')
->whereIn('id', $diagIds)
->field(['id', 'patient_name', 'phone'])
->select()
->toArray();
$out = [];
foreach ($rows as $r) {
$out[(int) $r['id']] = [
'patient_name' => trim((string) ($r['patient_name'] ?? '')),
'phone' => trim((string) ($r['phone'] ?? '')),
];
}
return $out;
}
/**
* @param array<int, int> $slotCounts [slot => n]
* @param list<int> $slots 需输出的分档列表(保证各行键齐全)
*
* @return array<string, int|float|null>
*/
private static function buildMetricPack(int $assigned, array $slotCounts, array $slots): array
{
$pack = ['assigned_count' => $assigned];
foreach ($slots as $slot) {
$cnt = (int) ($slotCounts[$slot] ?? 0);
$pack['visit' . $slot . '_count'] = $cnt;
$pack['visit' . $slot . '_rate'] = $assigned > 0
? round($cnt / $assigned * 100, 2)
: null;
}
return $pack;
}
/** 归一化月份参数为 YYYY-MM,非法时回退当前月 */
private static function normalizeMonth(string $month): string
{
$month = trim($month);
if (preg_match('/^\d{4}-(0[1-9]|1[0-2])$/', $month) === 1) {
return $month;
}
return date('Y-m');
}
}
@@ -21,7 +21,8 @@ use think\facade\Db;
*
* - 进线数据 = 区间内 add_external_contact 事件,按接待员工(user_id) 归属部门
* · qywx.customer/todayArrival、客户列表同源事件表;选定渠道时客户须带对应企微标签(contact_tag);**二中心及其组织下级在选定渠道下进线计 0**
* - 被指派数 = 区间内 `tcm_diagnosis_assign_log` **to_assistant_id>0** **related_po_create_time>0** 并落在区间(**一律按快照字段统计**,与履约释放写入一致;诊单后台指派时会回填该字段,见 DiagnosisLogic::assign
* - 被指派数 = 区间内 `tcm_diagnosis_assign_log` **to_assistant_id>0****剔除勾选「继承」的指派 is_inherit=1**,按**指派操作时间 lg.create_time** 落区间,
* 「医助 × 诊单」去重、剔除已删诊单 —— 与「复诊接诊率」页面「当月被指派总数」完全同口径(见 RevisitRateLogic
* · **二中心及其组织下级在选定渠道下计 0**(与进线一致)
* - 复诊统计 = **名称含「二中心」的部门及其组织架构下级**:区间内业务单按患者 create_time 排序,第 1 笔不计,第 2 笔起分列「复诊2」「复诊3」…;口径同业绩单条件;按**订单创建人**所在部门在组织树内 rollup(含下级),与排行榜复诊一致
* - 已完成挂号 = status=3 挂号条数(appointment_date),列「已完成挂号」;部门归属:有效医助→接诊医生→展示行映射。
@@ -857,7 +858,7 @@ class YejiStatsLogic
? ('排行诊金 = 选定渠道「' . $channelName . '」业绩中「订单创建人 = 该医助」的部分;与部门表该渠道业绩列同口径(按订单创建人归属)。被指派数与部门表同口径。接诊率 = 诊金 ÷ 进线(元/进线)。'
. '「二中心」及其组织下级医助在该渠道下诊金、进线与被指派计 0。'
. ' 预约诊单:预约表按「预约日期」落在区间内、有效医助口径同接诊,状态含已预约/已完成/已过号(不含已取消);科室下医助全量展示。')
: '排行诊金 = 业务订单中「订单创建人 = 该医助」的金额合计;与部门表「合计业绩」同口径(按订单创建人归属)。被指派数为指派至该医助的次数。接诊率 = 诊金 ÷ 进线(元/进线;进线为 0 时为 0)。'
: '排行诊金 = 业务订单中「订单创建人 = 该医助」的金额合计;与部门表「合计业绩」同口径(按订单创建人归属)。被指派数为指派至该医助的次数(剔除勾选「继承」的指派)。接诊率 = 诊金 ÷ 进线(元/进线;进线为 0 时为 0)。'
. ' 预约诊单:预约表按「预约日期」落在区间内、有效医助口径同接诊,状态含已预约/已完成/已过号(不含已取消);科室下医助全量展示。';
$leaderboards = [];
@@ -1777,8 +1778,9 @@ class YejiStatsLogic
}
/**
* 被指派数:统计 `tcm_diagnosis_assign_log`to_assistant_id>0**** **related_po_create_time** 落入区间(须 >0
* 选定字典渠道时 INNER JOIN 诊单以满足挂号 channels EXISTStag 退化口径只过滤日志字段,不强制挂诊单
* 被指派数:统计 `tcm_diagnosis_assign_log`to_assistant_id>0**剔除勾选「继承」的指派 is_inherit=1**
* **指派操作时间 lg.create_time** 落入区间,「医助 × 诊单」去重(COUNT DISTINCT diagnosis_id)、剔除已删诊单
* 与「复诊接诊率」页面同口径。选定字典渠道时按挂号 channels EXISTS 收窄;tag 退化口径按日志字段过滤。
*
* @param array<int, int> $adminToPrimary
* @param int[]|null $tagDiagIds
@@ -1801,11 +1803,13 @@ class YejiStatsLogic
return [];
}
$diagTable = self::tableWithPrefix('tcm_diagnosis');
$query = Db::name('tcm_diagnosis_assign_log')
->alias('lg')
->where('lg.related_po_create_time', '>', 0)
->where('lg.related_po_create_time', 'between', [$startTs, $endTs])
->where('lg.to_assistant_id', '>', 0);
->join("{$diagTable} dg", 'dg.id = lg.diagnosis_id AND dg.delete_time IS NULL', 'INNER')
->where('lg.create_time', 'between', [$startTs, $endTs])
->where('lg.to_assistant_id', '>', 0)
->where('lg.is_inherit', 0);
if ($channelFilterActive) {
if ($appointmentChannelValues !== []) {
$norm = self::normalizeAppointmentChannelValues($appointmentChannelValues);
@@ -1816,8 +1820,6 @@ class YejiStatsLogic
if ($pack === null) {
return [];
}
$diagTable = self::tableWithPrefix('tcm_diagnosis');
$query->join("{$diagTable} dg", 'dg.id = lg.diagnosis_id AND dg.delete_time IS NULL', 'INNER');
$query->whereRaw($pack[0], $pack[1]);
} elseif ($tagDiagIds !== null || $tagAssistantIds !== null) {
if ($tagDiagIds !== null && $tagDiagIds === []) {
@@ -1837,7 +1839,7 @@ class YejiStatsLogic
}
}
$query->field(['lg.to_assistant_id', Db::raw('COUNT(*) AS cnt')])
$query->field(['lg.to_assistant_id', Db::raw('COUNT(DISTINCT lg.diagnosis_id) AS cnt')])
->group('lg.to_assistant_id');
$rows = $query->select()->toArray();
@@ -1869,7 +1871,7 @@ class YejiStatsLogic
}
/**
* 医助维度被指派次数:与 countDiagnosisAssignsByDept 同过滤与区间,按 to_assistant_id 汇总(供排行榜)。
* 医助维度被指派次数:与 countDiagnosisAssignsByDept 同过滤与区间(同样剔除 is_inherit=1,按 to_assistant_id 汇总(供排行榜)。
*
* @return array<int, int>
*/
@@ -1883,11 +1885,13 @@ class YejiStatsLogic
?array $dataScopeAdminIds = null,
?array $channelInfo = null
): array {
$diagTable = self::tableWithPrefix('tcm_diagnosis');
$query = Db::name('tcm_diagnosis_assign_log')
->alias('lg')
->where('lg.related_po_create_time', '>', 0)
->where('lg.related_po_create_time', 'between', [$startTs, $endTs])
->where('lg.to_assistant_id', '>', 0);
->join("{$diagTable} dg", 'dg.id = lg.diagnosis_id AND dg.delete_time IS NULL', 'INNER')
->where('lg.create_time', 'between', [$startTs, $endTs])
->where('lg.to_assistant_id', '>', 0)
->where('lg.is_inherit', 0);
if ($channelFilterActive) {
if ($appointmentChannelValues !== []) {
@@ -1899,8 +1903,6 @@ class YejiStatsLogic
if ($pack === null) {
return [];
}
$diagTable = self::tableWithPrefix('tcm_diagnosis');
$query->join("{$diagTable} dg", 'dg.id = lg.diagnosis_id AND dg.delete_time IS NULL', 'INNER');
$query->whereRaw($pack[0], $pack[1]);
} elseif ($tagDiagIds !== null || $tagAssistantIds !== null) {
if ($tagDiagIds !== null && $tagDiagIds === []) {
@@ -1920,7 +1922,7 @@ class YejiStatsLogic
}
}
$query->field(['lg.to_assistant_id', Db::raw('COUNT(*) AS cnt')])
$query->field(['lg.to_assistant_id', Db::raw('COUNT(DISTINCT lg.diagnosis_id) AS cnt')])
->group('lg.to_assistant_id');
$rows = $query->select()->toArray();
@@ -2324,7 +2324,8 @@ class PrescriptionOrderLogic
->where(function ($query) {
$query->where('payment_method', 'manual')
->whereOr('payment_method', 'fubei')
->whereOr('create_type', 'fubei');
->whereOr('create_type', 'fubei')
->whereOr('create_type', 'express_cod');
})
->update([
'status' => 5, // 待审核
@@ -2403,6 +2404,9 @@ class PrescriptionOrderLogic
$amount = round((float) ($params['pay_amount'] ?? 0), 2);
$remark = mb_substr(trim((string) ($params['pay_remark'] ?? '')), 0, 200);
$completionRequest = (int) ($params['completion_request'] ?? 0);
// 创建方式:付呗(默认) 或 快递代收(express_cod)
$payCreateType = (string) ($params['pay_create_type'] ?? 'fubei');
$isExpressCod = $payCreateType === 'express_cod';
if ($amount < 0) {
self::$error = '支付单金额不能为负数';
@@ -2417,8 +2421,13 @@ class PrescriptionOrderLogic
$payOrder->order_type = $orderType;
$payOrder->amount = $amount;
$payOrder->status = 5; // 待审核
$payOrder->payment_method = 'fubei'; // 补齐支付单按「付呗」记账
$payOrder->create_type = 'fubei';
if ($isExpressCod) {
// 快递代收:payment_method 留空,审核通过/到账后再写;用 create_type 标记
$payOrder->create_type = 'express_cod';
} else {
$payOrder->payment_method = 'fubei'; // 补齐支付单按「付呗」记账
$payOrder->create_type = 'fubei';
}
$payOrder->payment_time = null; // 审核通过后再设置支付时间
$payOrder->remark = $remark;
@@ -1 +1 @@
import r from"./error-3-P5389h.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-Ds3qCU_G.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-D49jsFPW.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-CYLw0J2V.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-DzAM_8sh.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-DM-pfG5J.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-B0jSCQ-G.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-BQ5Mf_ti.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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 +0,0 @@
import o from"./error-3-P5389h.js";import{f as r,ak as t,I as m,a as p}from"./@vue/runtime-core-C6bnekPw.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-CYLw0J2V.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};
@@ -0,0 +1 @@
import o from"./error-DzAM_8sh.js";import{f as r,ak as t,I as m,a as p}from"./@vue/runtime-core-C6bnekPw.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-BQ5Mf_ti.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{M as T,N as C,T as $,r as D,d as L,L as k}from"./element-plus-Ds3qCU_G.js";import{X as E}from"./@element-plus/icons-vue-D49jsFPW.js";import{a5 as P}from"./tcm-BqLeG7XT.js";import{f as A,w as B,ak as p,I as b,aP as F,G as h,aN as n,a as i,O as m,J as M}from"./@vue/runtime-core-C6bnekPw.js";import{Q as c}from"./@vue/shared-mAAVTE9n.js";import{y as V,n as w}from"./@vue/reactivity-DiY1c2vO.js";import{_ as K}from"./index-CYLw0J2V.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 q={class:"assign-log-panel"},z={key:1,class:"text-gray-400"},G=A({__name:"AssignLogPanel",props:{diagnosisId:{}},setup(N,{expose:v}){const _=N,d=w(!1),u=w([]);function y(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 x(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 a=new Date(t*1e3);if(Number.isNaN(a.getTime()))return"—";const r=l=>String(l).padStart(2,"0");return`${a.getFullYear()}-${r(a.getMonth()+1)}-${r(a.getDate())} ${r(a.getHours())}:${r(a.getMinutes())}:${r(a.getSeconds())}`}function f(o,e){const t=e==="from"?"from_assistant_name":"to_assistant_name",a=e==="from"?"from_assistant_id":"to_assistant_id",r=o[t];if(r!=null&&String(r).trim()!==""&&String(r)!=="—")return String(r);const l=Number(o[a]);return Number.isFinite(l)&&l>0?`ID:${l}`:"—"}const g=async()=>{if(_.diagnosisId){d.value=!0;try{const o=await P({id:_.diagnosisId}),e=Array.isArray(o)?o:[];u.value=e}catch(o){console.error(o),u.value=[]}finally{d.value=!1}}};return B(()=>_.diagnosisId,()=>{g()},{immediate:!0}),v({refresh:g}),(o,e)=>{const t=C,a=$,r=L,l=D,S=T,I=k;return p(),b("div",q,[F((p(),h(S,{data:u.value,border:"",stripe:"","empty-text":"暂无指派记录"},{default:n(()=>[i(t,{label:"操作时间",width:"175",prop:"create_time_text"}),i(t,{label:"原医助","min-width":"120"},{default:n(({row:s})=>[m(c(f(s,"from")),1)]),_:1}),i(t,{label:"新医助","min-width":"120"},{default:n(({row:s})=>[m(c(f(s,"to")),1)]),_:1}),i(t,{label:"继承",width:"72",align:"center"},{default:n(({row:s})=>[Number(s.is_inherit)===1?(p(),h(a,{key:0,type:"success",size:"small"},{default:n(()=>[...e[0]||(e[0]=[m("是",-1)])]),_:1})):(p(),b("span",z,"否"))]),_:1}),i(t,{label:"快照·业务单创建人","min-width":"130","show-overflow-tooltip":""},{default:n(({row:s})=>[m(c(y(s)),1)]),_:1}),i(t,{label:"快照·业务单创建时间",width:"190"},{header:n(()=>[e[1]||(e[1]=M("span",null,"快照·业务单创建时间",-1)),i(l,{placement:"top",content:"related_po_create_time:触发本次操作的处方业务订单 create_time;与原文助一致时表示医助创建订单时间"},{default:n(()=>[i(r,{class:"assign-log-col-hint"},{default:n(()=>[i(V(E))]),_:1})]),_:1})]),default:n(({row:s})=>[m(c(x(s)),1)]),_:1}),i(t,{label:"操作人",width:"110",prop:"operator_name"}),i(t,{label:"操作账号",width:"120",prop:"operator_account","show-overflow-tooltip":""}),i(t,{label:"IP",width:"130",prop:"ip","show-overflow-tooltip":""})]),_:1},8,["data"])),[[I,d.value]])])}}}),Ct=K(G,[["__scopeId","data-v-f670e3e6"]]);export{Ct as default};
import{M as T,N as C,T as $,d as D,f as L,L as k}from"./element-plus-DM-pfG5J.js";import{Y as E}from"./@element-plus/icons-vue-B0jSCQ-G.js";import{a5 as P}from"./tcm-DREvQype.js";import{f as A,w as B,ak as p,I as b,aP as F,G as h,aN as n,a as i,O as m,J as M}from"./@vue/runtime-core-C6bnekPw.js";import{Q as c}from"./@vue/shared-mAAVTE9n.js";import{y as V,n as w}from"./@vue/reactivity-DiY1c2vO.js";import{_ as K}from"./index-CaVLWczr.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-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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 Y={class:"assign-log-panel"},q={key:1,class:"text-gray-400"},z=A({__name:"AssignLogPanel",props:{diagnosisId:{}},setup(N,{expose:v}){const _=N,d=w(!1),u=w([]);function y(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 x(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 a=new Date(t*1e3);if(Number.isNaN(a.getTime()))return"—";const r=l=>String(l).padStart(2,"0");return`${a.getFullYear()}-${r(a.getMonth()+1)}-${r(a.getDate())} ${r(a.getHours())}:${r(a.getMinutes())}:${r(a.getSeconds())}`}function f(o,e){const t=e==="from"?"from_assistant_name":"to_assistant_name",a=e==="from"?"from_assistant_id":"to_assistant_id",r=o[t];if(r!=null&&String(r).trim()!==""&&String(r)!=="—")return String(r);const l=Number(o[a]);return Number.isFinite(l)&&l>0?`ID:${l}`:"—"}const g=async()=>{if(_.diagnosisId){d.value=!0;try{const o=await P({id:_.diagnosisId}),e=Array.isArray(o)?o:[];u.value=e}catch(o){console.error(o),u.value=[]}finally{d.value=!1}}};return B(()=>_.diagnosisId,()=>{g()},{immediate:!0}),v({refresh:g}),(o,e)=>{const t=C,a=$,r=L,l=D,S=T,I=k;return p(),b("div",Y,[F((p(),h(S,{data:u.value,border:"",stripe:"","empty-text":"暂无指派记录"},{default:n(()=>[i(t,{label:"操作时间",width:"175",prop:"create_time_text"}),i(t,{label:"原医助","min-width":"120"},{default:n(({row:s})=>[m(c(f(s,"from")),1)]),_:1}),i(t,{label:"新医助","min-width":"120"},{default:n(({row:s})=>[m(c(f(s,"to")),1)]),_:1}),i(t,{label:"继承",width:"72",align:"center"},{default:n(({row:s})=>[Number(s.is_inherit)===1?(p(),h(a,{key:0,type:"success",size:"small"},{default:n(()=>[...e[0]||(e[0]=[m("是",-1)])]),_:1})):(p(),b("span",q,"否"))]),_:1}),i(t,{label:"快照·业务单创建人","min-width":"130","show-overflow-tooltip":""},{default:n(({row:s})=>[m(c(y(s)),1)]),_:1}),i(t,{label:"快照·业务单创建时间",width:"190"},{header:n(()=>[e[1]||(e[1]=M("span",null,"快照·业务单创建时间",-1)),i(l,{placement:"top",content:"related_po_create_time:触发本次操作的处方业务订单 create_time;与原文助一致时表示医助创建订单时间"},{default:n(()=>[i(r,{class:"assign-log-col-hint"},{default:n(()=>[i(V(E))]),_:1})]),_:1})]),default:n(({row:s})=>[m(c(x(s)),1)]),_:1}),i(t,{label:"操作人",width:"110",prop:"operator_name"}),i(t,{label:"操作账号",width:"120",prop:"operator_account","show-overflow-tooltip":""}),i(t,{label:"IP",width:"130",prop:"ip","show-overflow-tooltip":""})]),_:1},8,["data"])),[[I,d.value]])])}}}),Ct=K(z,[["__scopeId","data-v-f670e3e6"]]);export{Ct as default};
@@ -1 +1 @@
import{i as L,L as T,N as V,T as D,M as z,W as M}from"./element-plus-Ds3qCU_G.js";import{ad as O}from"./tcm-BqLeG7XT.js";import{f as P,b as F,w as j,ak as a,I as n,a as i,aN as s,O as m,H as w,aP as A,G as g,F as H,J as R}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-CYLw0J2V.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-D49jsFPW.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"},W={key:0},Y={key:1,class:"text-gray-400"},q={class:"void-detail text-xs text-gray-500 mt-1"},K=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()}),j(()=>_.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})])),A((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",W,c(o.herbs.slice(0,3).map(f=>`${f.name}${f.dosage}`).join("、"))+c(o.herbs.length>3?"...":""),1)):(a(),n("span",Y,"—"))]),_: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(H,{key:0},[i(v,{type:"danger",size:"small"},{default:s(()=>[...t[1]||(t[1]=[m("已作废",-1)])]),_:1}),R("div",q,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(K,[["__scopeId","data-v-043d2738"]]);export{zt as default};
import{l as L,L as T,N as V,T as D,M as z,W as M}from"./element-plus-DM-pfG5J.js";import{ad as O}from"./tcm-DREvQype.js";import{f as P,b as F,w as j,ak as a,I as n,a as i,aN as s,O as m,H as w,aP as A,G as g,F as H,J as R}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-CaVLWczr.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-B0jSCQ-G.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-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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"},W={key:0},Y={key:1,class:"text-gray-400"},q={class:"void-detail text-xs text-gray-500 mt-1"},K=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()}),j(()=>_.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})])),A((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",W,c(o.herbs.slice(0,3).map(f=>`${f.name}${f.dosage}`).join("、"))+c(o.herbs.length>3?"...":""),1)):(a(),n("span",Y,"—"))]),_: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(H,{key:0},[i(v,{type:"danger",size:"small"},{default:s(()=>[...t[1]||(t[1]=[m("已作废",-1)])]),_:1}),R("div",q,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(K,[["__scopeId","data-v-043d2738"]]);export{zt as default};
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
import{_ as o}from"./MediaSourceSelect.vue_vue_type_script_setup_true_lang-DIj1J3Im.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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";export{o as default};
import{_ as o}from"./MediaSourceSelect.vue_vue_type_script_setup_true_lang-C3cIqxhZ.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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";export{o as default};
@@ -1 +1 @@
import{Q as g,P as V}from"./element-plus-Ds3qCU_G.js";import{f as C,ak as o,G as s,aN as v,I as p,F as h,ap as B,H as k,A as m}from"./@vue/runtime-core-C6bnekPw.js";import{y as c}from"./@vue/reactivity-DiY1c2vO.js";import{p as w,o as S}from"./@vue/shared-mAAVTE9n.js";const N=C({__name:"MediaSourceSelect",props:{modelValue:{default:""},options:{},loading:{type:Boolean,default:!1},placeholder:{default:"请选择自媒体来源"},clearable:{type:Boolean,default:!0},filterable:{type:Boolean,default:!0},allowCreate:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},selectClass:{},selectStyle:{}},emits:["update:modelValue","change","visible-change"],setup(e,{emit:i}){const u=e,n=i,d=m(()=>(u.options||[]).map(l=>typeof l=="string"?{name:l}:{name:l.name,value:l.value})),f=m(()=>d.value.some(l=>l.name===u.modelValue)),b=l=>{n("visible-change",l)};return(l,t)=>{const r=g,y=V;return o(),s(y,{"model-value":e.modelValue,placeholder:e.placeholder,clearable:e.clearable,filterable:e.filterable,"allow-create":e.allowCreate,"default-first-option":e.allowCreate,disabled:e.disabled,loading:e.loading,class:S(e.selectClass),style:w(e.selectStyle),"onUpdate:modelValue":t[0]||(t[0]=a=>n("update:modelValue",a)),onChange:t[1]||(t[1]=a=>n("change",a)),onVisibleChange:b},{default:v(()=>[(o(!0),p(h,null,B(c(d),a=>(o(),s(r,{key:a.name,label:a.name,value:a.name},null,8,["label","value"]))),128)),e.modelValue&&!c(f)?(o(),s(r,{key:`__legacy_${e.modelValue}`,label:`${e.modelValue}(已停用)`,value:e.modelValue},null,8,["label","value"])):k("",!0)]),_:1},8,["model-value","placeholder","clearable","filterable","allow-create","default-first-option","disabled","loading","class","style"])}}});export{N as _};
import{Q as g,P as V}from"./element-plus-DM-pfG5J.js";import{f as C,ak as o,G as s,aN as v,I as p,F as h,ap as B,H as k,A as m}from"./@vue/runtime-core-C6bnekPw.js";import{y as c}from"./@vue/reactivity-DiY1c2vO.js";import{p as w,o as S}from"./@vue/shared-mAAVTE9n.js";const N=C({__name:"MediaSourceSelect",props:{modelValue:{default:""},options:{},loading:{type:Boolean,default:!1},placeholder:{default:"请选择自媒体来源"},clearable:{type:Boolean,default:!0},filterable:{type:Boolean,default:!0},allowCreate:{type:Boolean,default:!1},disabled:{type:Boolean,default:!1},selectClass:{},selectStyle:{}},emits:["update:modelValue","change","visible-change"],setup(e,{emit:i}){const u=e,n=i,d=m(()=>(u.options||[]).map(l=>typeof l=="string"?{name:l}:{name:l.name,value:l.value})),f=m(()=>d.value.some(l=>l.name===u.modelValue)),b=l=>{n("visible-change",l)};return(l,t)=>{const r=g,y=V;return o(),s(y,{"model-value":e.modelValue,placeholder:e.placeholder,clearable:e.clearable,filterable:e.filterable,"allow-create":e.allowCreate,"default-first-option":e.allowCreate,disabled:e.disabled,loading:e.loading,class:S(e.selectClass),style:w(e.selectStyle),"onUpdate:modelValue":t[0]||(t[0]=a=>n("update:modelValue",a)),onChange:t[1]||(t[1]=a=>n("change",a)),onVisibleChange:b},{default:v(()=>[(o(!0),p(h,null,B(c(d),a=>(o(),s(r,{key:a.name,label:a.name,value:a.name},null,8,["label","value"]))),128)),e.modelValue&&!c(f)?(o(),s(r,{key:`__legacy_${e.modelValue}`,label:`${e.modelValue}(已停用)`,value:e.modelValue},null,8,["label","value"])):k("",!0)]),_:1},8,["model-value","placeholder","clearable","filterable","allow-create","default-first-option","disabled","loading","class","style"])}}});export{N as _};
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
import{i as se,W as ne,C as le,V as ae,v as re,d as me,a as de}from"./element-plus-Ds3qCU_G.js";import{_ as pe}from"./picker-DcVdXs-r.js";import{e as ue,c as ce,i as g,_ as ge}from"./index-CYLw0J2V.js";import{s as U}from"./@vue/runtime-dom-DDAG46FW.js";import{b as z,G as fe}from"./@element-plus/icons-vue-D49jsFPW.js";import{a as P,d as ve}from"./patient-jF4jBNUB.js";import{h as _e}from"./perm-DTInbRd6.js";import{f as ye,w as he,ak as o,I as n,G as k,aN as r,O as M,H as p,a as l,J as m,F as w,ap as E,A as ke}from"./@vue/runtime-core-C6bnekPw.js";import{n as f,y as N}from"./@vue/reactivity-DiY1c2vO.js";import{Q as T}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-wRiKfob5.js";import"./index-DQ_c_7GJ.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./index-BXes3WfF.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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 we={class:"note-timeline-wrap"},Ie={key:0,class:"timeline-actions"},Ce={class:"upload-trigger"},xe={class:"upload-trigger"},Ve={key:1,class:"note-timeline"},Ee={class:"timeline-date"},Ne={class:"timeline-body"},be={key:0,class:"timeline-content"},Se={key:1,class:"timeline-images"},Ae={key:2,class:"timeline-images"},De={key:0,class:"thumb-wrap"},Be={key:1,class:"file-wrap"},Ue=["href","title"],ze={class:"file-name"},O=8e3,Pe=ye({__name:"NoteTimeline",props:{notes:{},diagnosisId:{},readonly:{type:Boolean}},emits:["refresh"],setup(d,{emit:j}){const u=d,I=j,X=ke(()=>_e(["doctor.appointment/addDoctorNote"])),v=f(!1),C=f(""),b=f(!1),H=ue(),_=t=>H.getImageUrl(t),S=f([]),A=f([]),y=f(0),h=f(0),J=["jpg","jpeg","png","gif","bmp","webp","svg"],D=t=>{var s;const e=((s=t.split(".").pop())==null?void 0:s.toLowerCase().split("?")[0])||"";return J.includes(e)},$=t=>{var s;const e=t.split("/");return decodeURIComponent(((s=e[e.length-1])==null?void 0:s.split("?")[0])||"文件")},Q=t=>t.filter(D).map(_),Z=(t,e)=>{const s=t.filter(D),x=t[e];return s.indexOf(x)},q=t=>t?t.split(`
`).filter(Boolean):[],K=t=>{if(!u.diagnosisId)return;const e=Array.isArray(t)?t:[t];if(e.length<=y.value){y.value=e.length;return}const s=e.slice(y.value);y.value=e.length,s.length>0&&P({diagnosis_id:u.diagnosisId,tongue_images:s}).then(()=>{g.msgSuccess("舌苔照片已添加"),I("refresh")})},Y=t=>{if(!u.diagnosisId)return;const e=Array.isArray(t)?t:[t];if(e.length<=h.value){h.value=e.length;return}const s=e.slice(h.value);h.value=e.length,s.length>0&&P({diagnosis_id:u.diagnosisId,report_files:s}).then(()=>{g.msgSuccess("检查报告已添加"),I("refresh")})};he(()=>u.notes,()=>{S.value=[],A.value=[],y.value=0,h.value=0});const ee=async()=>{if(!u.diagnosisId){g.msgWarning("当前无诊单,无法添加备注");return}const t=C.value.trim();if(!t){g.msgWarning("请输入备注内容");return}b.value=!0;try{await P({diagnosis_id:u.diagnosisId,content:t}),g.msgSuccess("备注保存成功"),C.value="",v.value=!1,I("refresh")}catch(e){g.msgError((e==null?void 0:e.message)||"保存失败")}finally{b.value=!1}},B=async(t,e,s)=>{try{await de.confirm("确认删除?","提示",{type:"warning"})}catch{return}await ve({note_id:t,image_type:e,image_path:s}),g.msgSuccess("已删除"),I("refresh")};return(t,e)=>{const s=se,x=ce,F=pe,G=re,V=me,te=ne,ie=le,oe=ae;return o(),n("div",we,[!d.readonly&&d.diagnosisId?(o(),n("div",Ie,[X.value?(o(),k(s,{key:0,type:"primary",plain:"",size:"small",onClick:e[0]||(e[0]=i=>v.value=!0)},{default:r(()=>[...e[6]||(e[6]=[M(" 添加备注 ",-1)])]),_:1})):p("",!0),l(F,{modelValue:S.value,"onUpdate:modelValue":e[1]||(e[1]=i=>S.value=i),limit:99,type:"image","exclude-domain":!0,onChange:K},{upload:r(()=>[m("div",Ce,[l(x,{size:20,name:"el-icon-Plus"}),e[7]||(e[7]=m("span",null,"舌苔照片",-1))])]),_:1},8,["modelValue"]),l(F,{modelValue:A.value,"onUpdate:modelValue":e[2]||(e[2]=i=>A.value=i),limit:99,type:"file","exclude-domain":!0,onChange:Y},{upload:r(()=>[m("div",xe,[l(x,{size:20,name:"el-icon-Plus"}),e[8]||(e[8]=m("span",null,"检查报告",-1))])]),_:1},8,["modelValue"])])):p("",!0),d.notes.length?(o(),n("div",Ve,[(o(!0),n(w,null,E(d.notes,i=>{var L,R;return o(),n("div",{key:i.id,class:"timeline-node"},[e[11]||(e[11]=m("div",{class:"timeline-dot"},null,-1)),m("div",Ee,T(i.note_date),1),m("div",Ne,[i.content?(o(),n("div",be,[(o(!0),n(w,null,E(q(i.content),(a,c)=>(o(),n("div",{key:c,class:"content-line"},T(a),1))),128))])):p("",!0),(L=i.tongue_images)!=null&&L.length?(o(),n("div",Se,[e[9]||(e[9]=m("span",{class:"images-label"},"舌苔照片",-1)),(o(!0),n(w,null,E(i.tongue_images,(a,c)=>(o(),n("div",{key:c,class:"thumb-wrap"},[l(G,{src:_(a),"preview-src-list":i.tongue_images.map(_),"initial-index":c,"z-index":O,fit:"cover",class:"timeline-thumb","preview-teleported":""},null,8,["src","preview-src-list","initial-index"]),d.readonly?p("",!0):(o(),k(V,{key:0,class:"thumb-delete",onClick:U(W=>B(i.id,"tongue_images",a),["stop"])},{default:r(()=>[l(N(z))]),_:1},8,["onClick"]))]))),128))])):p("",!0),(R=i.report_files)!=null&&R.length?(o(),n("div",Ae,[e[10]||(e[10]=m("span",{class:"images-label"},"检查报告",-1)),(o(!0),n(w,null,E(i.report_files,(a,c)=>(o(),n(w,{key:c},[D(a)?(o(),n("div",De,[l(G,{src:_(a),"preview-src-list":Q(i.report_files),"initial-index":Z(i.report_files,c),"z-index":O,fit:"cover",class:"timeline-thumb","preview-teleported":""},null,8,["src","preview-src-list","initial-index"]),d.readonly?p("",!0):(o(),k(V,{key:0,class:"thumb-delete",onClick:U(W=>B(i.id,"report_files",a),["stop"])},{default:r(()=>[l(N(z))]),_:1},8,["onClick"]))])):(o(),n("div",Be,[m("a",{href:_(a),target:"_blank",class:"file-link",title:$(a)},[l(V,{size:20},{default:r(()=>[l(N(fe))]),_:1}),m("span",ze,T($(a)),1)],8,Ue),d.readonly?p("",!0):(o(),k(V,{key:0,class:"file-delete",onClick:U(W=>B(i.id,"report_files",a),["stop"])},{default:r(()=>[l(N(z))]),_:1},8,["onClick"]))]))],64))),128))])):p("",!0)])])}),128))])):p("",!0),!d.notes.length&&d.readonly?(o(),k(te,{key:2,description:"暂无备注","image-size":48})):p("",!0),l(oe,{modelValue:v.value,"onUpdate:modelValue":e[5]||(e[5]=i=>v.value=i),title:"添加备注",width:"480px","append-to-body":""},{footer:r(()=>[l(s,{onClick:e[4]||(e[4]=i=>v.value=!1)},{default:r(()=>[...e[12]||(e[12]=[M("取消",-1)])]),_:1}),l(s,{type:"primary",loading:b.value,onClick:ee},{default:r(()=>[...e[13]||(e[13]=[M("保存",-1)])]),_:1},8,["loading"])]),default:r(()=>[l(ie,{modelValue:C.value,"onUpdate:modelValue":e[3]||(e[3]=i=>C.value=i),type:"textarea",rows:4,placeholder:"输入今日备注...",maxlength:"500","show-word-limit":""},null,8,["modelValue"])]),_:1},8,["modelValue"])])}}}),Mt=ge(Pe,[["__scopeId","data-v-530ad386"]]);export{Mt as default};
import{l as se,W as ne,C as le,V as ae,e as re,f as me,a as de}from"./element-plus-DM-pfG5J.js";import{_ as pe}from"./picker-BVR108QV.js";import{e as ue,c as ce,h as g,_ as ge}from"./index-CaVLWczr.js";import{s as U}from"./@vue/runtime-dom-DDAG46FW.js";import{b as z,G as fe}from"./@element-plus/icons-vue-B0jSCQ-G.js";import{a as P,d as ve}from"./patient-3j0u_1ZH.js";import{h as _e}from"./perm-DpuQ-hbC.js";import{f as ye,w as he,ak as i,I as n,G as k,aN as r,O as M,H as p,a as l,J as m,F as w,ap as E,A as ke}from"./@vue/runtime-core-C6bnekPw.js";import{n as f,y as N}from"./@vue/reactivity-DiY1c2vO.js";import{Q as T}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-Dtw-XGAA.js";import"./index-D7o6UQWd.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./index-DXYzjdn6.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.js";import"./@vueuse/core-DfvfIixE.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-BQ5Mf_ti.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 we={class:"note-timeline-wrap"},Ie={key:0,class:"timeline-actions"},Ce={class:"upload-trigger"},xe={class:"upload-trigger"},Ve={key:1,class:"note-timeline"},Ee={class:"timeline-date"},Ne={class:"timeline-body"},be={key:0,class:"timeline-content"},Se={key:1,class:"timeline-images"},Ae={key:2,class:"timeline-images"},De={key:0,class:"thumb-wrap"},Be={key:1,class:"file-wrap"},Ue=["href","title"],ze={class:"file-name"},O=8e3,Pe=ye({__name:"NoteTimeline",props:{notes:{},diagnosisId:{},readonly:{type:Boolean}},emits:["refresh"],setup(d,{emit:j}){const u=d,I=j,X=ke(()=>_e(["doctor.appointment/addDoctorNote"])),v=f(!1),C=f(""),b=f(!1),H=ue(),_=t=>H.getImageUrl(t),S=f([]),A=f([]),y=f(0),h=f(0),J=["jpg","jpeg","png","gif","bmp","webp","svg"],D=t=>{var s;const e=((s=t.split(".").pop())==null?void 0:s.toLowerCase().split("?")[0])||"";return J.includes(e)},$=t=>{var s;const e=t.split("/");return decodeURIComponent(((s=e[e.length-1])==null?void 0:s.split("?")[0])||"文件")},Q=t=>t.filter(D).map(_),Z=(t,e)=>{const s=t.filter(D),x=t[e];return s.indexOf(x)},q=t=>t?t.split(`
`).filter(Boolean):[],K=t=>{if(!u.diagnosisId)return;const e=Array.isArray(t)?t:[t];if(e.length<=y.value){y.value=e.length;return}const s=e.slice(y.value);y.value=e.length,s.length>0&&P({diagnosis_id:u.diagnosisId,tongue_images:s}).then(()=>{g.msgSuccess("舌苔照片已添加"),I("refresh")})},Y=t=>{if(!u.diagnosisId)return;const e=Array.isArray(t)?t:[t];if(e.length<=h.value){h.value=e.length;return}const s=e.slice(h.value);h.value=e.length,s.length>0&&P({diagnosis_id:u.diagnosisId,report_files:s}).then(()=>{g.msgSuccess("检查报告已添加"),I("refresh")})};he(()=>u.notes,()=>{S.value=[],A.value=[],y.value=0,h.value=0});const ee=async()=>{if(!u.diagnosisId){g.msgWarning("当前无诊单,无法添加备注");return}const t=C.value.trim();if(!t){g.msgWarning("请输入备注内容");return}b.value=!0;try{await P({diagnosis_id:u.diagnosisId,content:t}),g.msgSuccess("备注保存成功"),C.value="",v.value=!1,I("refresh")}catch(e){g.msgError((e==null?void 0:e.message)||"保存失败")}finally{b.value=!1}},B=async(t,e,s)=>{try{await de.confirm("确认删除?","提示",{type:"warning"})}catch{return}await ve({note_id:t,image_type:e,image_path:s}),g.msgSuccess("已删除"),I("refresh")};return(t,e)=>{const s=se,x=ce,F=pe,G=re,V=me,te=ne,oe=le,ie=ae;return i(),n("div",we,[!d.readonly&&d.diagnosisId?(i(),n("div",Ie,[X.value?(i(),k(s,{key:0,type:"primary",plain:"",size:"small",onClick:e[0]||(e[0]=o=>v.value=!0)},{default:r(()=>[...e[6]||(e[6]=[M(" 添加备注 ",-1)])]),_:1})):p("",!0),l(F,{modelValue:S.value,"onUpdate:modelValue":e[1]||(e[1]=o=>S.value=o),limit:99,type:"image","exclude-domain":!0,onChange:K},{upload:r(()=>[m("div",Ce,[l(x,{size:20,name:"el-icon-Plus"}),e[7]||(e[7]=m("span",null,"舌苔照片",-1))])]),_:1},8,["modelValue"]),l(F,{modelValue:A.value,"onUpdate:modelValue":e[2]||(e[2]=o=>A.value=o),limit:99,type:"file","exclude-domain":!0,onChange:Y},{upload:r(()=>[m("div",xe,[l(x,{size:20,name:"el-icon-Plus"}),e[8]||(e[8]=m("span",null,"检查报告",-1))])]),_:1},8,["modelValue"])])):p("",!0),d.notes.length?(i(),n("div",Ve,[(i(!0),n(w,null,E(d.notes,o=>{var L,R;return i(),n("div",{key:o.id,class:"timeline-node"},[e[11]||(e[11]=m("div",{class:"timeline-dot"},null,-1)),m("div",Ee,T(o.note_date),1),m("div",Ne,[o.content?(i(),n("div",be,[(i(!0),n(w,null,E(q(o.content),(a,c)=>(i(),n("div",{key:c,class:"content-line"},T(a),1))),128))])):p("",!0),(L=o.tongue_images)!=null&&L.length?(i(),n("div",Se,[e[9]||(e[9]=m("span",{class:"images-label"},"舌苔照片",-1)),(i(!0),n(w,null,E(o.tongue_images,(a,c)=>(i(),n("div",{key:c,class:"thumb-wrap"},[l(G,{src:_(a),"preview-src-list":o.tongue_images.map(_),"initial-index":c,"z-index":O,fit:"cover",class:"timeline-thumb","preview-teleported":""},null,8,["src","preview-src-list","initial-index"]),d.readonly?p("",!0):(i(),k(V,{key:0,class:"thumb-delete",onClick:U(W=>B(o.id,"tongue_images",a),["stop"])},{default:r(()=>[l(N(z))]),_:1},8,["onClick"]))]))),128))])):p("",!0),(R=o.report_files)!=null&&R.length?(i(),n("div",Ae,[e[10]||(e[10]=m("span",{class:"images-label"},"检查报告",-1)),(i(!0),n(w,null,E(o.report_files,(a,c)=>(i(),n(w,{key:c},[D(a)?(i(),n("div",De,[l(G,{src:_(a),"preview-src-list":Q(o.report_files),"initial-index":Z(o.report_files,c),"z-index":O,fit:"cover",class:"timeline-thumb","preview-teleported":""},null,8,["src","preview-src-list","initial-index"]),d.readonly?p("",!0):(i(),k(V,{key:0,class:"thumb-delete",onClick:U(W=>B(o.id,"report_files",a),["stop"])},{default:r(()=>[l(N(z))]),_:1},8,["onClick"]))])):(i(),n("div",Be,[m("a",{href:_(a),target:"_blank",class:"file-link",title:$(a)},[l(V,{size:20},{default:r(()=>[l(N(fe))]),_:1}),m("span",ze,T($(a)),1)],8,Ue),d.readonly?p("",!0):(i(),k(V,{key:0,class:"file-delete",onClick:U(W=>B(o.id,"report_files",a),["stop"])},{default:r(()=>[l(N(z))]),_:1},8,["onClick"]))]))],64))),128))])):p("",!0)])])}),128))])):p("",!0),!d.notes.length&&d.readonly?(i(),k(te,{key:2,description:"暂无备注","image-size":48})):p("",!0),l(ie,{modelValue:v.value,"onUpdate:modelValue":e[5]||(e[5]=o=>v.value=o),title:"添加备注",width:"480px","append-to-body":""},{footer:r(()=>[l(s,{onClick:e[4]||(e[4]=o=>v.value=!1)},{default:r(()=>[...e[12]||(e[12]=[M("取消",-1)])]),_:1}),l(s,{type:"primary",loading:b.value,onClick:ee},{default:r(()=>[...e[13]||(e[13]=[M("保存",-1)])]),_:1},8,["loading"])]),default:r(()=>[l(oe,{modelValue:C.value,"onUpdate:modelValue":e[3]||(e[3]=o=>C.value=o),type:"textarea",rows:4,placeholder:"输入今日备注...",maxlength:"500","show-word-limit":""},null,8,["modelValue"])]),_:1},8,["modelValue"])])}}}),Mt=ge(Pe,[["__scopeId","data-v-530ad386"]]);export{Mt 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-CYLw0J2V.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-Ds3qCU_G.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./@element-plus/icons-vue-D49jsFPW.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 b={class:"card patient-card"},D={class:"patient-hero"},E={class:"patient-name"},G={class:"patient-meta"},H={key:0},J=w({__name:"PatientInfoCard",props:{apt:{default:()=>({})},diag:{default:()=>({})}},setup(t){return(Q,o)=>{var m,r,n,d,p,s,c,l,g,f,u,h,v,k,C;return I(),P("div",b,[o[0]||(o[0]=a("div",{class:"card-title"},"患者信息",-1)),a("div",D,[a("div",E,i(((m=t.apt)==null?void 0:m.patient_name)||"—"),1),a("div",G,[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",H,"备注:"+i(t.apt.remark),1)):N("",!0)])])])}}}),Ct=V(J,[["__scopeId","data-v-1b0de09c"]]);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-CaVLWczr.js";import"./lodash-D3kF6u-c.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.js";import"./pinia-B8cvXbiZ.js";import"./axios-C80V62Fs.js";import"./element-plus-DM-pfG5J.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./@element-plus/icons-vue-B0jSCQ-G.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"./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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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 b={class:"card patient-card"},D={class:"patient-hero"},E={class:"patient-name"},G={class:"patient-meta"},H={key:0},J=w({__name:"PatientInfoCard",props:{apt:{default:()=>({})},diag:{default:()=>({})}},setup(t){return(Q,o)=>{var m,r,n,d,p,s,c,l,g,f,u,h,v,k,C;return I(),P("div",b,[o[0]||(o[0]=a("div",{class:"card-title"},"患者信息",-1)),a("div",D,[a("div",E,i(((m=t.apt)==null?void 0:m.patient_name)||"—"),1),a("div",G,[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",H,"备注:"+i(t.apt.remark),1)):N("",!0)])])])}}}),Ct=V(J,[["__scopeId","data-v-1b0de09c"]]);export{Ct as default};
@@ -0,0 +1 @@
import{W as B,M as A,N as R,T as j,l as q,L as z}from"./element-plus-DM-pfG5J.js";import{_ as $}from"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import{u as G}from"./usePaging-VsbTxSU0.js";import{q as J}from"./tcm-DREvQype.js";import{b as M,c as Q,d as S,P as U}from"./PrescriptionOrderDetailDrawer-C6mzrFGm.js";import{f as W,w as H,as as K,ak as m,I as u,a as e,F as X,aP as b,G as h,aN as a,J as w,O as p,A as y}from"./@vue/runtime-core-C6bnekPw.js";import{y as n,a as Y,n as Z,r as tt}from"./@vue/reactivity-DiY1c2vO.js";import{Q as d}from"./@vue/shared-mAAVTE9n.js";import{_ as et}from"./index-CaVLWczr.js";import"./@vue/runtime-dom-DDAG46FW.js";import"./lodash-D3kF6u-c.js";import"./@element-plus/icons-vue-B0jSCQ-G.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-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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 ot={class:"patient-order-list"},it={key:0,class:"po-empty-tip"},at={class:"text-red-500 font-semibold"},rt={class:"flex justify-end mt-3"},st=W({__name:"PatientOrderList",props:{diagnosisId:{},patientId:{}},setup(x,{expose:k}){const c=x,_=y(()=>{const o=Number(c.patientId);return Number.isFinite(o)&&o>0?o:0}),f=y(()=>_.value>0),l=tt({}),{pager:r,getLists:g,resetPage:I}=G({fetchFun:J,params:l,size:10}),N=()=>{Object.keys(l).forEach(o=>delete l[o]),c.diagnosisId>0&&(l.context_diagnosis_id=c.diagnosisId),f.value&&(l.patient_id=_.value),l.scene="diagnosis_edit"},v=Z();function D(o){var i;(i=v.value)==null||i.open(o)}const P=o=>{const i=Number(o);return Number.isFinite(i)?i.toFixed(2):"0.00"};return H(()=>[c.diagnosisId,_.value],()=>{if(!f.value){r.lists=[],r.count=0;return}N(),I()},{immediate:!0}),k({refresh:()=>g()}),(o,i)=>{const T=B,s=R,E=j,C=q,O=A,F=$,L=K("perms"),V=z;return m(),u("div",ot,[f.value?(m(),u(X,{key:1},[b((m(),h(O,{data:n(r).lists,border:"",stripe:"","empty-text":"暂无业务订单"},{default:a(()=>[e(s,{label:"订单编号",prop:"order_no","min-width":"200","show-overflow-tooltip":""}),e(s,{label:"金额",width:"120",align:"right"},{default:a(({row:t})=>[w("span",at,"¥"+d(P(t.amount)),1)]),_:1}),e(s,{label:"医生",prop:"doctor_name",width:"110","show-overflow-tooltip":""},{default:a(({row:t})=>[p(d(t.doctor_name||"—"),1)]),_:1}),e(s,{label:"医助",prop:"assistant_name",width:"110","show-overflow-tooltip":""},{default:a(({row:t})=>[p(d(t.assistant_name||"—"),1)]),_:1}),e(s,{label:"履约状态",width:"110"},{default:a(({row:t})=>[e(E,{type:n(M)(t.fulfillment_status),size:"small",effect:"light"},{default:a(()=>[p(d(n(Q)(t.fulfillment_status)),1)]),_:2},1032,["type"])]),_:1}),e(s,{label:"创建时间","min-width":"170"},{default:a(({row:t})=>[p(d(n(S)(t.create_time)),1)]),_:1}),e(s,{label:"操作",width:"100",fixed:"right"},{default:a(({row:t})=>[b((m(),h(C,{type:"primary",link:"",onClick:nt=>D(t.id)},{default:a(()=>[...i[1]||(i[1]=[p("查看详情",-1)])]),_:1},8,["onClick"])),[[L,["tcm.prescriptionOrder/detail"]]])]),_:1})]),_:1},8,["data"])),[[V,n(r).loading]]),w("div",rt,[e(F,{modelValue:n(r),"onUpdate:modelValue":i[0]||(i[0]=t=>Y(r)?r.value=t:null),onChange:n(g)},null,8,["modelValue","onChange"])])],64)):(m(),u("div",it,[e(T,{description:"当前诊单未携带患者ID,无法列出业务订单"})])),e(U,{ref_key:"detailDrawerRef",ref:v,readonly:"","append-to-body":""},null,512)])}}}),Ht=et(st,[["__scopeId","data-v-4a0ef613"]]);export{Ht as default};
@@ -0,0 +1 @@
.patient-order-list[data-v-4a0ef613]{padding:4px 0}.po-empty-tip[data-v-4a0ef613]{padding:24px 0}
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
.patient-order-list[data-v-2e08802c]{padding:4px 0}.po-empty-tip[data-v-2e08802c]{padding:24px 0}.audit-stamp[data-v-2e08802c]{position:absolute;top:12px;right:16px;transform:rotate(15deg);opacity:.15;pointer-events:none;z-index:1}.stamp-inner[data-v-2e08802c]{border:3px solid currentColor;border-radius:8px;padding:4px 12px;font-size:18px;font-weight:700}.stamp-pass[data-v-2e08802c]{color:#22c55e}.stamp-reject[data-v-2e08802c]{color:#ef4444}
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
@charset "UTF-8";.po-detail-drawer[data-v-e14cbef6] .el-drawer__header{margin-bottom:0;padding:16px 24px;border-bottom:1px solid var(--el-border-color-lighter)}.stat-card[data-v-e14cbef6]{border-radius:8px}.stat-title[data-v-e14cbef6]{font-weight:500}.po-panel[data-v-e14cbef6]{border-radius:8px;transition:all .3s}.po-panel[data-v-e14cbef6] .el-card__header{padding:14px 16px;background-color:var(--el-bg-color-page);border-bottom:1px solid var(--el-border-color-lighter)}.po-panel[data-v-e14cbef6] .el-card__body{padding:16px}.po-desc[data-v-e14cbef6] .el-descriptions__label{width:120px;color:var(--el-text-color-regular)}.po-audit-remark[data-v-e14cbef6]{color:var(--el-color-danger);font-weight:600;white-space:pre-wrap;word-break:break-word}.audit-stamp[data-v-e14cbef6]{position:absolute;top:18px;right:-14px;width:72px;height:72px;border:3px solid currentColor;border-radius:50%;display:flex;align-items:center;justify-content:center;transform:rotate(20deg);opacity:.8;pointer-events:none;z-index:10;-webkit-user-select:none;-moz-user-select:none;user-select:none;font-weight:700;font-size:13px;letter-spacing:1px;box-shadow:inset 0 0 0 1px #ffffff80}.audit-stamp[data-v-e14cbef6]:after{content:"";position:absolute;top:4px;left:4px;right:4px;bottom:4px;border:1px double currentColor;border-radius:50%;opacity:.6}.audit-stamp .stamp-inner[data-v-e14cbef6]{text-align:center;line-height:1.1}.stamp-pass[data-v-e14cbef6]{color:var(--el-color-success)}.stamp-reject[data-v-e14cbef6]{color:var(--el-color-danger)}.po-diagnosis-creator-dept-breadcrumb[data-v-e14cbef6] .el-breadcrumb__item{display:inline-flex;float:none}.po-diagnosis-creator-dept-breadcrumb[data-v-e14cbef6] .el-breadcrumb__separator{margin:0 2px 0 4px}
@@ -1 +1 @@
import{S as L}from"./element-plus-Ds3qCU_G.js";import B from"./RecordingVideoPlayer-CqR6OAdN.js";import{e as H,_ as I}from"./index-CYLw0J2V.js";import{f as w,ak as n,I as m,J as p,F as v,G as u,aN as _,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-D49jsFPW.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 S(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 b(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(v,{key:0},[S(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:_(()=>[...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(v,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:_(()=>[k(q(b(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{S as L}from"./element-plus-DM-pfG5J.js";import B from"./RecordingVideoPlayer-Cy6aqokN.js";import{e as H,_ as I}from"./index-CaVLWczr.js";import{f as w,ak as n,I as m,J as p,F as v,G as u,aN as _,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-B0jSCQ-G.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-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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 S(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 b(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(v,{key:0},[S(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:_(()=>[...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(v,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:_(()=>[k(q(b(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,W as w}from"./element-plus-Ds3qCU_G.js";import{W as T}from"./tcm-BqLeG7XT.js";import{i as C,_ as E}from"./index-CYLw0J2V.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-D49jsFPW.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"},W={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,l as V,W as w}from"./element-plus-DM-pfG5J.js";import{W as T}from"./tcm-DREvQype.js";import{h as C,_ as E}from"./index-CaVLWczr.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-B0jSCQ-G.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-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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"},W={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",W,[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};
@@ -0,0 +1 @@
import{_ as o}from"./account-adjust.vue_vue_type_script_setup_true_lang-D5yF-zri.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-Dtw-XGAA.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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 +0,0 @@
import{_ as o}from"./account-adjust.vue_vue_type_script_setup_true_lang-DCoTQTCs.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-wRiKfob5.js";import"./index-CYLw0J2V.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-Ds3qCU_G.js";import{_ as F}from"./index-wRiKfob5.js";import{i as b}from"./index-CYLw0J2V.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-DM-pfG5J.js";import{_ as F}from"./index-Dtw-XGAA.js";import{h as b}from"./index-CaVLWczr.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
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
import{_ as o}from"./add-nav.vue_vue_type_script_setup_true_lang-DxFacXhn.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-BXes3WfF.js";import"./index-CYLw0J2V.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-UB-0VH7g.js";import"./index-wRiKfob5.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./article-DBGc93Gj.js";import"./usePaging-VsbTxSU0.js";import"./picker-DcVdXs-r.js";import"./index-DQ_c_7GJ.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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"./add-nav.vue_vue_type_script_setup_true_lang-BtFyoC78.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-DXYzjdn6.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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-GJ0IKFTv.js";import"./index-Dtw-XGAA.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./article-C_n-ZYdZ.js";import"./usePaging-VsbTxSU0.js";import"./picker-BVR108QV.js";import"./index-D7o6UQWd.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.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{C as E,B,j as C,l as N}from"./element-plus-DM-pfG5J.js";import{_ as $}from"./index-DXYzjdn6.js";import{_ as z}from"./picker-GJ0IKFTv.js";import{_ as A}from"./picker-BVR108QV.js";import{c as D,h as r}from"./index-CaVLWczr.js";import{D as I}from"./vuedraggable-5bKFmC7X.js";import{f as R,ak as p,I as j,J as l,a,aN as d,G as F,O as G,A as J}from"./@vue/runtime-core-C6bnekPw.js";import{y as c,a as L}from"./@vue/reactivity-DiY1c2vO.js";const O={class:"bg-fill-light flex items-center w-full p-4 mb-4"},P={class:"upload-btn w-[60px] h-[60px]"},S={class:"ml-3 flex-1"},T={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=J({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}`)},v=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,g=A,h=E,k=z,b=C,w=B,y=$,U=N;return p(),j("div",null,[l("div",null,[a(c(I),{class:"draggable",modelValue:c(m),"onUpdate:modelValue":e[0]||(e[0]=o=>L(m)?m.value=o:null),animation:"300",handle:".drag-move","item-key":"index"},{item:d(({element:o,index:u})=>[(p(),F(y,{class:"w-[467px]",key:u,onClose:n=>v(u)},{default:d(()=>[l("div",O,[a(g,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body",size:"60px","exclude-domain":""},{upload:d(()=>[l("div",P,[a(i,{name:"el-icon-Plus",size:20})])]),_:1},8,["modelValue","onUpdate:modelValue"]),l("div",S,[l("div",T,[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]=[G("添加",-1)])]),_:1})])])}}});export{oe as _};
@@ -1 +0,0 @@
import{C as E,B,g as C,i as N}from"./element-plus-Ds3qCU_G.js";import{_ as $}from"./index-BXes3WfF.js";import{_ as z}from"./picker-UB-0VH7g.js";import{_ as A}from"./picker-DcVdXs-r.js";import{c as D,i as r}from"./index-CYLw0J2V.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-CYLw0J2V.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-CaVLWczr.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
@@ -1 +1 @@
import{r as e}from"./index-CYLw0J2V.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-CaVLWczr.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{r as e}from"./index-CYLw0J2V.js";function r(s){return e.get({url:"/asset.AssetUser/lists",params:s})}function u(s){return e.post({url:"/asset.AssetUser/add",params:s})}function a(s){return e.post({url:"/asset.AssetUser/edit",params:s})}function i(s){return e.post({url:"/asset.AssetUser/delete",params:s})}function o(s){return e.get({url:"/asset.AssetResource/lists",params:s})}function n(s){return e.post({url:"/asset.AssetResource/add",params:s})}function A(s){return e.post({url:"/asset.AssetResource/edit",params:s})}function c(s){return e.post({url:"/asset.AssetResource/delete",params:s})}export{o as a,c as b,A as c,n as d,r as e,a as f,i as g,u as h};
import{r as e}from"./index-CaVLWczr.js";function r(s){return e.get({url:"/asset.AssetUser/lists",params:s})}function u(s){return e.post({url:"/asset.AssetUser/add",params:s})}function a(s){return e.post({url:"/asset.AssetUser/edit",params:s})}function i(s){return e.post({url:"/asset.AssetUser/delete",params:s})}function o(s){return e.get({url:"/asset.AssetResource/lists",params:s})}function n(s){return e.post({url:"/asset.AssetResource/add",params:s})}function A(s){return e.post({url:"/asset.AssetResource/edit",params:s})}function c(s){return e.post({url:"/asset.AssetResource/delete",params:s})}export{o as a,c as b,A as c,n as d,r as e,a as f,i as g,u as h};
@@ -1 +0,0 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-DcMb4onv.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-DxFacXhn.js";import"./index-BXes3WfF.js";import"./index-CYLw0J2V.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-UB-0VH7g.js";import"./index-wRiKfob5.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./article-DBGc93Gj.js";import"./usePaging-VsbTxSU0.js";import"./picker-DcVdXs-r.js";import"./index-DQ_c_7GJ.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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.vue_vue_type_script_setup_true_lang-Cl3rDtpI.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-BtFyoC78.js";import"./index-DXYzjdn6.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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-GJ0IKFTv.js";import"./index-Dtw-XGAA.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./article-C_n-ZYdZ.js";import"./usePaging-VsbTxSU0.js";import"./picker-BVR108QV.js";import"./index-D7o6UQWd.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.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.vue_vue_type_script_setup_true_lang-U4IHoVZJ.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-BtFyoC78.js";import"./index-DXYzjdn6.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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-GJ0IKFTv.js";import"./index-Dtw-XGAA.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./article-C_n-ZYdZ.js";import"./usePaging-VsbTxSU0.js";import"./picker-BVR108QV.js";import"./index-D7o6UQWd.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.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 +0,0 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-CQRXtwjJ.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-DcVdXs-r.js";import"./index-wRiKfob5.js";import"./index-CYLw0J2V.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-DQ_c_7GJ.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./index-BXes3WfF.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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{m as b,l as c,D as V}from"./element-plus-Ds3qCU_G.js";import{_ as l}from"./menu-set.vue_vue_type_script_setup_true_lang-REtTeywT.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-D49jsFPW.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-BXes3WfF.js";import"./index-CYLw0J2V.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-UB-0VH7g.js";import"./index-wRiKfob5.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./article-DBGc93Gj.js";import"./usePaging-VsbTxSU0.js";import"./picker-DcVdXs-r.js";import"./index-DQ_c_7GJ.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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{t as b,s as c,D as V}from"./element-plus-DM-pfG5J.js";import{_ as l}from"./menu-set.vue_vue_type_script_setup_true_lang-DVxv7QzP.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-B0jSCQ-G.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-DXYzjdn6.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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-GJ0IKFTv.js";import"./index-Dtw-XGAA.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./article-C_n-ZYdZ.js";import"./usePaging-VsbTxSU0.js";import"./picker-BVR108QV.js";import"./index-D7o6UQWd.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.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};
@@ -0,0 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-XBwMXD2u.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-BVR108QV.js";import"./index-Dtw-XGAA.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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-D7o6UQWd.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./index-DXYzjdn6.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.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 +0,0 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-3eudbug2.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-BXes3WfF.js";import"./index-CYLw0J2V.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-UB-0VH7g.js";import"./index-wRiKfob5.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./article-DBGc93Gj.js";import"./usePaging-VsbTxSU0.js";import"./picker-DcVdXs-r.js";import"./index-DQ_c_7GJ.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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.vue_vue_type_script_setup_true_lang-Q5tD9i__.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-DXYzjdn6.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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-GJ0IKFTv.js";import"./index-Dtw-XGAA.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./article-C_n-ZYdZ.js";import"./usePaging-VsbTxSU0.js";import"./picker-BVR108QV.js";import"./index-D7o6UQWd.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.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-CimCXKMG.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-DZ8cC-yU.js";import"./@vueuse/core-1S4fJlii.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./picker-DcVdXs-r.js";import"./index-wRiKfob5.js";import"./index-CYLw0J2V.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-DQ_c_7GJ.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./index-BXes3WfF.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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-B3hF0MFS.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-C__-n_9z.js";import"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.js";import"./picker-BVR108QV.js";import"./index-Dtw-XGAA.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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-D7o6UQWd.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./index-DXYzjdn6.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.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 +0,0 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-DdedGrqO.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-BXes3WfF.js";import"./index-CYLw0J2V.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-UB-0VH7g.js";import"./index-wRiKfob5.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./article-DBGc93Gj.js";import"./usePaging-VsbTxSU0.js";import"./picker-DcVdXs-r.js";import"./index-DQ_c_7GJ.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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-DZ8cC-yU.js";export{o as default};
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-BVj5AIjx.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-DxFacXhn.js";import"./index-BXes3WfF.js";import"./index-CYLw0J2V.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-UB-0VH7g.js";import"./index-wRiKfob5.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./article-DBGc93Gj.js";import"./usePaging-VsbTxSU0.js";import"./picker-DcVdXs-r.js";import"./index-DQ_c_7GJ.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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.vue_vue_type_script_setup_true_lang-YMWzfpr2.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-DXYzjdn6.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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-GJ0IKFTv.js";import"./index-Dtw-XGAA.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./article-C_n-ZYdZ.js";import"./usePaging-VsbTxSU0.js";import"./picker-BVR108QV.js";import"./index-D7o6UQWd.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.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-C__-n_9z.js";export{o as default};
@@ -0,0 +1 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-CtzuDUWb.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-DXYzjdn6.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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-GJ0IKFTv.js";import"./index-Dtw-XGAA.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./article-C_n-ZYdZ.js";import"./usePaging-VsbTxSU0.js";import"./picker-BVR108QV.js";import"./index-D7o6UQWd.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.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 +0,0 @@
import{_ as o}from"./attr.vue_vue_type_script_setup_true_lang-Ddj5gy6c.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-BXes3WfF.js";import"./index-CYLw0J2V.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-UB-0VH7g.js";import"./index-wRiKfob5.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./article-DBGc93Gj.js";import"./usePaging-VsbTxSU0.js";import"./picker-DcVdXs-r.js";import"./index-DQ_c_7GJ.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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 +0,0 @@
import{_ as o}from"./attr-setting.vue_vue_type_script_setup_true_lang-7deYPUyu.js";import"./element-plus-Ds3qCU_G.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-D49jsFPW.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-D5r_ao1l.js";import"./attr-DUlOXOIf.js";import"./index-BXes3WfF.js";import"./index-CYLw0J2V.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-UB-0VH7g.js";import"./index-wRiKfob5.js";import"./index.vue_vue_type_script_setup_true_lang-Ch-2CJwb.js";import"./article-DBGc93Gj.js";import"./usePaging-VsbTxSU0.js";import"./picker-DcVdXs-r.js";import"./index-DQ_c_7GJ.js";import"./index-BdBwexoG.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-C_xnWpAD.js";import"./index.vue_vue_type_script_setup_true_lang-d5pf8jrB.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-Do9pdYQV.js";import"./decoration-img-Djivcpa2.js";import"./attr.vue_vue_type_script_setup_true_lang-CQRXtwjJ.js";import"./content-BqgtYXuE.js";import"./attr.vue_vue_type_script_setup_true_lang-3eudbug2.js";import"./content.vue_vue_type_script_setup_true_lang-DlhA2sB0.js";import"./attr.vue_vue_type_script_setup_true_lang-DcMb4onv.js";import"./add-nav.vue_vue_type_script_setup_true_lang-DxFacXhn.js";import"./content-DCv905Vw.js";import"./attr.vue_vue_type_script_setup_true_lang-BVj5AIjx.js";import"./content.vue_vue_type_script_setup_true_lang-BlfTKdC3.js";import"./attr.vue_vue_type_script_setup_true_lang-DnkDutJb.js";import"./content-Bmme3Fjr.js";import"./decoration-DjJGUSst.js";import"./attr.vue_vue_type_script_setup_true_lang-CimCXKMG.js";import"./index.vue_vue_type_script_setup_true_lang-DZ8cC-yU.js";import"./content-DILoCq7p.js";import"./content.vue_vue_type_script_setup_true_lang-CDZt3905.js";import"./attr.vue_vue_type_script_setup_true_lang-ChKJn1wI.js";import"./content-ClOvIptK.js";import"./attr.vue_vue_type_script_setup_true_lang-Ddj5gy6c.js";import"./content.vue_vue_type_script_setup_true_lang-CzzmAhi9.js";import"./attr.vue_vue_type_script_setup_true_lang-9MDVGbdQ.js";import"./content-CIoGcwRX.js";export{o as default};
@@ -0,0 +1 @@
import{_ as o}from"./attr-setting.vue_vue_type_script_setup_true_lang-DVYgvQ29.js";import"./element-plus-DM-pfG5J.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-B0jSCQ-G.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-Z8yUh8iS.js";import"./attr-GSQVubKa.js";import"./index-DXYzjdn6.js";import"./index-CaVLWczr.js";import"./jspdf-BsthCvR5.js";import"./@babel/runtime-BanGtE2-.js";import"./fflate-_ayOYiT1.js";import"./vue-router-BQ5Mf_ti.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"./@vueuse/core-DfvfIixE.js";import"./@vueuse/shared-Cl3lVqjz.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-GJ0IKFTv.js";import"./index-Dtw-XGAA.js";import"./index.vue_vue_type_script_setup_true_lang-BxXLvzbM.js";import"./article-C_n-ZYdZ.js";import"./usePaging-VsbTxSU0.js";import"./picker-BVR108QV.js";import"./index-D7o6UQWd.js";import"./index-IKz52fU_.js";import"./cos-js-sdk-v5-DSMN0LUT.js";import"./file-fmh9V7UH.js";import"./index.vue_vue_type_script_setup_true_lang-ChsiNjV-.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-D37I_7zX.js";import"./decoration-img-CNI2SQzF.js";import"./attr.vue_vue_type_script_setup_true_lang-XBwMXD2u.js";import"./content-CF4EuxJf.js";import"./attr.vue_vue_type_script_setup_true_lang-Q5tD9i__.js";import"./content.vue_vue_type_script_setup_true_lang-DGXi5s9G.js";import"./attr.vue_vue_type_script_setup_true_lang-Cl3rDtpI.js";import"./add-nav.vue_vue_type_script_setup_true_lang-BtFyoC78.js";import"./content-CQatYvqb.js";import"./attr.vue_vue_type_script_setup_true_lang-U4IHoVZJ.js";import"./content.vue_vue_type_script_setup_true_lang-inZbVlkY.js";import"./attr.vue_vue_type_script_setup_true_lang-DnkDutJb.js";import"./content-slsMBNqQ.js";import"./decoration-mSWjQ76P.js";import"./attr.vue_vue_type_script_setup_true_lang-B3hF0MFS.js";import"./index.vue_vue_type_script_setup_true_lang-C__-n_9z.js";import"./content-CESu6zEn.js";import"./content.vue_vue_type_script_setup_true_lang-DP-TEpr5.js";import"./attr.vue_vue_type_script_setup_true_lang-ChKJn1wI.js";import"./content-BN54zHpU.js";import"./attr.vue_vue_type_script_setup_true_lang-CtzuDUWb.js";import"./content.vue_vue_type_script_setup_true_lang-CQ7hS9rn.js";import"./attr.vue_vue_type_script_setup_true_lang-9MDVGbdQ.js";import"./content-kr6JPixT.js";export{o as default};
@@ -1 +1 @@
import{J as y,s as g}from"./element-plus-Ds3qCU_G.js";import{e as b}from"./index-D5r_ao1l.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,v as g}from"./element-plus-DM-pfG5J.js";import{e as b}from"./index-Z8yUh8iS.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 v}from"./@vue/runtime-core-C6bnekPw.js";import{Q as k}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,k((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(v((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{J as E,B as C,G as F,I as N,C as B,D as z}from"./element-plus-Ds3qCU_G.js";import{_ as G}from"./index.vue_vue_type_script_setup_true_lang-DZ8cC-yU.js";import{_ as I}from"./picker-DcVdXs-r.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-DM-pfG5J.js";import{_ as G}from"./index.vue_vue_type_script_setup_true_lang-C__-n_9z.js";import{_ as I}from"./picker-BVR108QV.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 b,B as y,C as E,G as w,I as B,D as C}from"./element-plus-Ds3qCU_G.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-DxFacXhn.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-DM-pfG5J.js";import{_ as I}from"./add-nav.vue_vue_type_script_setup_true_lang-BtFyoC78.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 _};

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