更新
This commit is contained in:
@@ -0,0 +1,592 @@
|
||||
<template>
|
||||
<div class="dept-card" :class="{ 'dept-card--saved': allSaved, 'dept-card--empty': isEmpty }">
|
||||
|
||||
<!-- 面包屑路径(仅钻取卡显示) -->
|
||||
<div v-if="!isRoot && breadcrumb" class="dept-card__crumb">
|
||||
<span
|
||||
v-for="(seg, i) in breadcrumb"
|
||||
:key="i"
|
||||
class="crumb-seg"
|
||||
>
|
||||
<span class="crumb-seg__text">{{ seg }}</span>
|
||||
<el-icon v-if="i < breadcrumb.length - 1" class="crumb-sep"><ArrowRight /></el-icon>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- 卡片头 -->
|
||||
<div class="dept-card__header">
|
||||
<div class="dept-card__avatar" :style="{ background: avatarBg }">
|
||||
{{ node.dept_name.slice(0, 1) }}
|
||||
</div>
|
||||
<div class="dept-card__meta">
|
||||
<div class="dept-card__name">{{ node.dept_name }}</div>
|
||||
<div v-if="node.children?.length" class="dept-card__sub-count">
|
||||
{{ node.children.length }} 个子部门
|
||||
<span v-if="childTotal > 0" class="dept-card__sub-total">· ¥{{ formatMoneyShort(childTotal) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dept-card__actions">
|
||||
<span v-if="node.target_id" class="status-badge status-badge--saved">已保存</span>
|
||||
<span v-else class="status-badge status-badge--new">未设置</span>
|
||||
<!-- 钻取卡才有关闭按钮 -->
|
||||
<button v-if="!isRoot" class="close-btn" title="关闭此卡片" @click="emit('close')">
|
||||
<el-icon><Close /></el-icon>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 当前部门输入 -->
|
||||
<div class="dept-card__body">
|
||||
<div class="field-row">
|
||||
<div class="field-block">
|
||||
<label class="field-block__label">目标金额</label>
|
||||
<el-input-number
|
||||
v-model="node.target_amount"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:step="1000"
|
||||
controls-position="right"
|
||||
placeholder="0.00"
|
||||
class="field-block__input"
|
||||
/>
|
||||
<span v-if="node.target_amount > 0" class="field-block__hint">
|
||||
¥ {{ formatMoney(node.target_amount) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="field-block field-block--remark">
|
||||
<label class="field-block__label">备注</label>
|
||||
<el-input
|
||||
v-model="node.remark"
|
||||
maxlength="255"
|
||||
placeholder="备注(选填)"
|
||||
clearable
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 子部门列表 -->
|
||||
<template v-if="node.children?.length">
|
||||
<div class="child-header">
|
||||
<span class="child-header__title">子部门</span>
|
||||
<span class="child-header__count">{{ node.children.length }}</span>
|
||||
</div>
|
||||
<div class="child-list">
|
||||
<div
|
||||
v-for="child in node.children"
|
||||
:key="child.dept_id"
|
||||
class="child-row"
|
||||
:class="{ 'child-row--active': drilledId === child.dept_id }"
|
||||
>
|
||||
<div class="child-row__name-wrap">
|
||||
<div class="child-row__dot" />
|
||||
<span class="child-row__name">{{ child.dept_name }}</span>
|
||||
<el-tag
|
||||
v-if="child.target_id"
|
||||
size="small" type="success" effect="plain" round
|
||||
class="child-row__tag"
|
||||
>已保存</el-tag>
|
||||
</div>
|
||||
|
||||
<div class="child-row__inputs">
|
||||
<el-input-number
|
||||
v-model="child.target_amount"
|
||||
:min="0"
|
||||
:precision="2"
|
||||
:step="1000"
|
||||
controls-position="right"
|
||||
placeholder="0.00"
|
||||
class="child-row__amount"
|
||||
/>
|
||||
<el-input
|
||||
v-model="child.remark"
|
||||
maxlength="255"
|
||||
placeholder="备注"
|
||||
clearable
|
||||
size="small"
|
||||
class="child-row__remark"
|
||||
/>
|
||||
<!-- 子部门若有下级,显示子树合计 + 钻取按钮 -->
|
||||
<template v-if="child.children?.length">
|
||||
<span
|
||||
v-if="subtreeSum(child) > 0"
|
||||
class="child-subtree-total"
|
||||
:title="`「${child.dept_name}」含下级合计`"
|
||||
>
|
||||
={{ formatMoneyShort(subtreeSum(child)) }}
|
||||
</span>
|
||||
<button
|
||||
class="drill-btn"
|
||||
:class="{ 'drill-btn--active': drilledId === child.dept_id }"
|
||||
:title="`展开「${child.dept_name}」的 ${child.children.length} 个子部门`"
|
||||
@click="emit('drill-in', child)"
|
||||
>
|
||||
<el-icon><ArrowRight /></el-icon>
|
||||
<span>{{ child.children.length }}</span>
|
||||
</button>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 底部合计 -->
|
||||
<div class="dept-card__footer">
|
||||
<span class="dept-card__footer-label">本卡合计</span>
|
||||
<span class="dept-card__footer-total" :class="{ 'is-nonzero': cardTotal > 0 }">
|
||||
¥ {{ formatMoney(cardTotal) }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { computed } from 'vue'
|
||||
import { ArrowRight, Close } from '@element-plus/icons-vue'
|
||||
import type { DeptTargetRow } from './mubiao-dept-node.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
node: DeptTargetRow
|
||||
isRoot: boolean
|
||||
drilledId: number | null
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'drill-in', node: DeptTargetRow): void
|
||||
(e: 'close'): void
|
||||
}>()
|
||||
|
||||
// 递归求一个节点的整棵子树金额合计(含自身)
|
||||
function subtreeSum(node: DeptTargetRow): number {
|
||||
let s = Number(node.target_amount ?? 0)
|
||||
if (node.children?.length) {
|
||||
for (const c of node.children) s += subtreeSum(c)
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
const childTotal = computed(() => {
|
||||
if (!props.node.children?.length) return 0
|
||||
return props.node.children.reduce((s, c) => s + subtreeSum(c), 0)
|
||||
})
|
||||
|
||||
const cardTotal = computed(() => Number(props.node.target_amount ?? 0) + childTotal.value)
|
||||
const isEmpty = computed(() => cardTotal.value === 0)
|
||||
const allSaved = computed(() => {
|
||||
if (!props.node.target_id) return false
|
||||
if (!props.node.children?.length) return true
|
||||
return props.node.children.every(c => c.target_id > 0)
|
||||
})
|
||||
|
||||
// 面包屑:从 dept_path 中提取,去掉最后一段(就是自己的名字)
|
||||
const breadcrumb = computed(() => {
|
||||
if (!props.node.dept_path) return null
|
||||
const segs = props.node.dept_path.split(/\s*\/\s*/).filter(Boolean)
|
||||
return segs.length > 1 ? segs : null
|
||||
})
|
||||
|
||||
// 根据名称哈希生成确定性渐变
|
||||
const avatarBg = computed(() => {
|
||||
const palettes = [
|
||||
'linear-gradient(135deg,#667eea,#764ba2)',
|
||||
'linear-gradient(135deg,#f093fb,#f5576c)',
|
||||
'linear-gradient(135deg,#4facfe,#00f2fe)',
|
||||
'linear-gradient(135deg,#43e97b,#38f9d7)',
|
||||
'linear-gradient(135deg,#fa709a,#fee140)',
|
||||
'linear-gradient(135deg,#30cfd0,#330867)',
|
||||
'linear-gradient(135deg,#a18cd1,#fbc2eb)',
|
||||
'linear-gradient(135deg,#fccb90,#d57eeb)',
|
||||
'linear-gradient(135deg,#e0c3fc,#8ec5fc)',
|
||||
'linear-gradient(135deg,#f6d365,#fda085)',
|
||||
]
|
||||
let hash = 0
|
||||
for (let i = 0; i < props.node.dept_name.length; i++) {
|
||||
hash = (hash * 31 + props.node.dept_name.charCodeAt(i)) & 0xffff
|
||||
}
|
||||
return palettes[hash % palettes.length]
|
||||
})
|
||||
|
||||
function formatMoney(v: number): string {
|
||||
return Number(v || 0).toLocaleString('zh-CN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
|
||||
}
|
||||
|
||||
function formatMoneyShort(v: number): string {
|
||||
if (v >= 10000) return (v / 10000).toFixed(1) + 'w'
|
||||
return v.toLocaleString('zh-CN', { maximumFractionDigits: 0 })
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.dept-card {
|
||||
background: var(--el-bg-color);
|
||||
border: 1px solid var(--el-border-color-lighter);
|
||||
border-radius: 14px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
||||
transition: box-shadow 0.2s ease, transform 0.15s ease;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.09);
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
&--saved {
|
||||
border-color: color-mix(in srgb, #67c23a 30%, var(--el-border-color-lighter));
|
||||
}
|
||||
|
||||
&--empty {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── 面包屑 ── */
|
||||
.dept-card__crumb {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
gap: 2px;
|
||||
padding: 8px 14px 0;
|
||||
font-size: 11px;
|
||||
|
||||
.crumb-seg {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
|
||||
&__text {
|
||||
color: var(--el-text-color-placeholder);
|
||||
|
||||
&:last-child {
|
||||
color: var(--el-color-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.crumb-sep {
|
||||
font-size: 10px;
|
||||
color: var(--el-border-color-darker);
|
||||
}
|
||||
}
|
||||
|
||||
/* ── 卡片头 ── */
|
||||
.dept-card__header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
padding: 14px 14px 12px;
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
background: linear-gradient(180deg, var(--el-fill-color-extra-light), var(--el-bg-color));
|
||||
}
|
||||
|
||||
.dept-card__avatar {
|
||||
width: 38px;
|
||||
height: 38px;
|
||||
border-radius: 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 15px;
|
||||
font-weight: 800;
|
||||
color: #fff;
|
||||
flex-shrink: 0;
|
||||
box-shadow: 0 3px 8px rgba(0, 0, 0, 0.18);
|
||||
}
|
||||
|
||||
.dept-card__meta {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.dept-card__name {
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
color: var(--el-text-color-primary);
|
||||
line-height: 1.3;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.dept-card__sub-count {
|
||||
font-size: 11.5px;
|
||||
color: var(--el-text-color-placeholder);
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.dept-card__sub-total {
|
||||
color: var(--el-color-primary);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.dept-card__actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
all: unset;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 6px;
|
||||
color: var(--el-text-color-placeholder);
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, color 0.15s;
|
||||
|
||||
&:hover {
|
||||
background: var(--el-fill-color);
|
||||
color: var(--el-color-danger);
|
||||
}
|
||||
|
||||
.el-icon { font-size: 13px; }
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 3px 9px;
|
||||
border-radius: 999px;
|
||||
font-size: 11px;
|
||||
font-weight: 600;
|
||||
|
||||
&--saved {
|
||||
background: color-mix(in srgb, #67c23a 12%, transparent);
|
||||
color: #529b2e;
|
||||
border: 1px solid color-mix(in srgb, #67c23a 28%, transparent);
|
||||
}
|
||||
|
||||
&--new {
|
||||
background: var(--el-fill-color);
|
||||
color: var(--el-text-color-placeholder);
|
||||
border: 1px solid var(--el-border-color-lighter);
|
||||
}
|
||||
}
|
||||
|
||||
/* ── 主体输入 ── */
|
||||
.dept-card__body {
|
||||
padding: 14px;
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
}
|
||||
|
||||
.field-row {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.field-block {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 5px;
|
||||
|
||||
&__label {
|
||||
font-size: 10.5px;
|
||||
font-weight: 700;
|
||||
color: var(--el-text-color-secondary);
|
||||
letter-spacing: 0.07em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
&__input {
|
||||
width: 100%;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&__hint {
|
||||
font-size: 11px;
|
||||
color: var(--el-text-color-placeholder);
|
||||
margin-top: -2px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ── 子部门区 ── */
|
||||
.child-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 8px 14px;
|
||||
background: var(--el-fill-color-extra-light);
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
|
||||
&__title {
|
||||
font-size: 11px;
|
||||
font-weight: 700;
|
||||
color: var(--el-text-color-secondary);
|
||||
letter-spacing: 0.07em;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
&__count {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
min-width: 18px;
|
||||
height: 18px;
|
||||
padding: 0 5px;
|
||||
border-radius: 999px;
|
||||
font-size: 10px;
|
||||
font-weight: 700;
|
||||
background: var(--el-color-primary-light-8);
|
||||
color: var(--el-color-primary);
|
||||
}
|
||||
}
|
||||
|
||||
.child-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.child-row {
|
||||
padding: 9px 14px;
|
||||
border-bottom: 1px solid var(--el-border-color-lighter);
|
||||
transition: background 0.12s;
|
||||
|
||||
&:last-child { border-bottom: none; }
|
||||
|
||||
&:hover { background: var(--el-fill-color-extra-light); }
|
||||
|
||||
&--active {
|
||||
background: color-mix(in srgb, var(--el-color-primary) 5%, var(--el-bg-color)) !important;
|
||||
border-left: 2px solid var(--el-color-primary-light-4);
|
||||
}
|
||||
|
||||
&__name-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 7px;
|
||||
margin-bottom: 7px;
|
||||
}
|
||||
|
||||
&__dot {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
background: var(--el-color-primary-light-4);
|
||||
flex-shrink: 0;
|
||||
box-shadow: 0 0 0 2px color-mix(in srgb, var(--el-color-primary) 15%, transparent);
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: var(--el-text-color-primary);
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&__tag { flex-shrink: 0; }
|
||||
|
||||
&__inputs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
&__amount {
|
||||
flex: 0 0 150px;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
border-radius: 7px;
|
||||
}
|
||||
}
|
||||
|
||||
&__remark {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
:deep(.el-input__wrapper) {
|
||||
border-radius: 7px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 子树合计标签 */
|
||||
.child-subtree-total {
|
||||
flex-shrink: 0;
|
||||
font-size: 11.5px;
|
||||
font-weight: 700;
|
||||
color: var(--el-color-primary);
|
||||
white-space: nowrap;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
|
||||
/* 钻取按钮 */
|
||||
.drill-btn {
|
||||
all: unset;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 3px;
|
||||
flex-shrink: 0;
|
||||
padding: 5px 10px;
|
||||
border-radius: 7px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: var(--el-color-primary);
|
||||
background: var(--el-color-primary-light-9);
|
||||
border: 1px solid var(--el-color-primary-light-7);
|
||||
cursor: pointer;
|
||||
transition: background 0.15s, box-shadow 0.15s, transform 0.1s;
|
||||
|
||||
&:hover {
|
||||
background: var(--el-color-primary-light-8);
|
||||
box-shadow: 0 2px 6px color-mix(in srgb, var(--el-color-primary) 20%, transparent);
|
||||
transform: translateX(1px);
|
||||
}
|
||||
|
||||
&--active {
|
||||
background: var(--el-color-primary);
|
||||
color: #fff;
|
||||
border-color: var(--el-color-primary);
|
||||
box-shadow: 0 2px 8px color-mix(in srgb, var(--el-color-primary) 35%, transparent);
|
||||
}
|
||||
|
||||
.el-icon {
|
||||
font-size: 12px;
|
||||
transition: transform 0.15s;
|
||||
}
|
||||
|
||||
&:hover .el-icon { transform: translateX(2px); }
|
||||
}
|
||||
|
||||
/* ── 底部 ── */
|
||||
.dept-card__footer {
|
||||
margin-top: auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 10px 14px;
|
||||
background: var(--el-fill-color-extra-light);
|
||||
border-top: 1px solid var(--el-border-color-lighter);
|
||||
}
|
||||
|
||||
.dept-card__footer-label {
|
||||
font-size: 11.5px;
|
||||
color: var(--el-text-color-placeholder);
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.dept-card__footer-total {
|
||||
font-size: 15px;
|
||||
font-weight: 800;
|
||||
color: var(--el-text-color-placeholder);
|
||||
letter-spacing: -0.02em;
|
||||
transition: color 0.2s;
|
||||
|
||||
&.is-nonzero { color: var(--el-color-primary); }
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace app\common\model\tcm;
|
||||
|
||||
use app\common\model\BaseModel;
|
||||
|
||||
/**
|
||||
* 诊单挂号 / 取消挂号操作日志(后台)
|
||||
*/
|
||||
class DiagnosisGuahaoLog extends BaseModel
|
||||
{
|
||||
protected $name = 'tcm_diagnosis_guahao_log';
|
||||
|
||||
protected $autoWriteTimestamp = false;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
-- 中医诊单:查看挂号/取消挂号操作日志 API 权限
|
||||
SET @diag_menu_id := (SELECT id FROM zyt_system_menu WHERE perms = 'tcm.diagnosis/lists' LIMIT 1);
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@diag_menu_id, 'A', '挂号操作日志', '', 53,
|
||||
'tcm.diagnosis/guahaoLogList', '', '',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE @diag_menu_id IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.diagnosis/guahaoLogList');
|
||||
@@ -0,0 +1,16 @@
|
||||
-- 处方业务订单:接口权限「修改关联处方患者姓名/手机」
|
||||
-- 执行前确认表前缀为 zyt_;若已有相同 perms 则跳过。
|
||||
|
||||
SET @po_menu_id := (SELECT id FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/lists' LIMIT 1);
|
||||
|
||||
INSERT INTO zyt_system_menu (
|
||||
pid, type, name, icon, sort, perms, paths, component,
|
||||
selected, params, is_cache, is_show, is_disable, create_time, update_time
|
||||
)
|
||||
SELECT
|
||||
@po_menu_id, 'A', '修改处方患者信息', '', 52,
|
||||
'tcm.prescriptionOrder/patchPrescriptionPatient', '', '',
|
||||
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
|
||||
FROM DUAL
|
||||
WHERE @po_menu_id IS NOT NULL
|
||||
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/patchPrescriptionPatient');
|
||||
@@ -0,0 +1,16 @@
|
||||
-- 诊单挂号 / 取消挂号操作日志(谁在何时操作)
|
||||
-- 执行前确认表前缀为 zyt_
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `zyt_tcm_diagnosis_guahao_log` (
|
||||
`id` int unsigned NOT NULL AUTO_INCREMENT,
|
||||
`diagnosis_id` int unsigned NOT NULL DEFAULT '0' COMMENT '诊单 id(doctor_appointment.patient_id)',
|
||||
`appointment_id` int unsigned NOT NULL DEFAULT '0' COMMENT '挂号记录 id',
|
||||
`admin_id` int unsigned NOT NULL DEFAULT '0' COMMENT '操作人管理员 id',
|
||||
`admin_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人姓名',
|
||||
`action` varchar(32) NOT NULL DEFAULT '' COMMENT 'create=挂号 cancel=取消挂号',
|
||||
`summary` varchar(500) NOT NULL DEFAULT '' COMMENT '摘要',
|
||||
`create_time` int unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_diagnosis_id` (`diagnosis_id`),
|
||||
KEY `idx_create_time` (`create_time`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='诊单挂号操作日志';
|
||||
Reference in New Issue
Block a user