first commit

This commit is contained in:
Your Name
2026-09-08 11:40:15 +08:00
commit a5353f7eb5
9568 changed files with 1646214 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
-- 音视频权限拒绝日志表
CREATE TABLE IF NOT EXISTS `zyt_av_permission_log` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`patient_id` varchar(64) NOT NULL DEFAULT '' COMMENT '患者IDpatient_xxx格式)',
`doctor_id` varchar(64) NOT NULL DEFAULT '' COMMENT '医生IDdoctor_xxx格式)',
`denied_scope` varchar(32) NOT NULL DEFAULT '' COMMENT '被拒绝的权限 scopecamera/record',
`scene` varchar(32) NOT NULL DEFAULT '' COMMENT '触发场景(makeCall / incoming',
`action` varchar(16) NOT NULL DEFAULT 'cancel' COMMENT '用户行为:cancel=取消 / open_setting=去设置',
`wx_version` varchar(32) NOT NULL DEFAULT '' COMMENT '微信基础库版本',
`create_time` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间(Unix秒)',
PRIMARY KEY (`id`),
KEY `idx_patient` (`patient_id`),
KEY `idx_doctor` (`doctor_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='音视频权限拒绝行为日志';
@@ -0,0 +1,21 @@
-- 诊单查看记录表
CREATE TABLE IF NOT EXISTS `la_diagnosis_view_records` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` int(11) NOT NULL DEFAULT '0' COMMENT '查看用户ID',
`diagnosis_id` int(11) NOT NULL DEFAULT '0' COMMENT '诊单ID',
`patient_id` int(11) NOT NULL DEFAULT '0' COMMENT '患者ID',
`share_user_id` int(11) NOT NULL DEFAULT '0' COMMENT '分享用户ID',
`view_count` int(11) NOT NULL DEFAULT '1' COMMENT '查看次数',
`first_view_time` int(11) NOT NULL DEFAULT '0' COMMENT '首次查看时间',
`last_view_time` int(11) NOT NULL DEFAULT '0' COMMENT '最后查看时间',
`is_confirmed` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已确认 0-未确认 1-已确认',
`confirmed_time` int(11) NOT NULL DEFAULT '0' COMMENT '确认时间',
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
`delete_time` int(11) DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
KEY `idx_user_diagnosis` (`user_id`, `diagnosis_id`),
KEY `idx_diagnosis` (`diagnosis_id`),
KEY `idx_patient` (`patient_id`),
KEY `idx_share_user` (`share_user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='诊单查看记录表';
@@ -0,0 +1,69 @@
<?php
use think\migration\Migrator;
use think\migration\Migration;
class CreateOrderTables extends Migration
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.io/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* log all of them to the migrations log:
*
* createTable
* renameTable
* addColumn
* addCustomColumn
* renameColumn
* addIndex
* addForeignKey
* addTimestamps
* update
* delete
* dropTable
* truncateTable
* addSoftDelete
*/
public function change()
{
// 订单表
$table = $this->table('la_order', ['engine' => 'InnoDB', 'collation' => 'utf8mb4_unicode_ci', 'comment' => '订单表']);
$table->addColumn('order_no', 'string', ['limit' => 50, 'comment' => '订单号'])
->addColumn('patient_id', 'integer', ['comment' => '患者ID'])
->addColumn('creator_id', 'integer', ['comment' => '创建人ID(推广ID'])
->addColumn('order_type', 'tinyinteger', ['comment' => '订单类型 1-挂号费 2-问诊费 3-药品费用'])
->addColumn('amount', 'decimal', ['precision' => 10, 'scale' => 2, 'comment' => '订单金额'])
->addColumn('status', 'tinyinteger', ['default' => 1, 'comment' => '订单状态 1-待支付 2-已支付 3-已取消 4-已退款'])
->addColumn('payment_method', 'string', ['limit' => 20, 'null' => true, 'comment' => '支付方式 alipay-支付宝 wechat-微信 bank-银行卡'])
->addColumn('payment_time', 'datetime', ['null' => true, 'comment' => '支付时间'])
->addColumn('remark', 'string', ['limit' => 500, 'default' => '', 'comment' => '备注'])
->addColumn('create_time', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间'])
->addColumn('update_time', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'update' => 'CURRENT_TIMESTAMP', 'comment' => '更新时间'])
->addColumn('delete_time', 'datetime', ['null' => true, 'comment' => '删除时间'])
->addIndex(['order_no'], ['unique' => true])
->addIndex(['patient_id'])
->addIndex(['creator_id'])
->addIndex(['status'])
->addIndex(['create_time'])
->create();
// 订单详情表
$table = $this->table('la_order_detail', ['engine' => 'InnoDB', 'collation' => 'utf8mb4_unicode_ci', 'comment' => '订单详情表']);
$table->addColumn('order_id', 'integer', ['comment' => '订单ID'])
->addColumn('related_type', 'string', ['limit' => 20, 'comment' => '关联类型 appointment-挂号 diagnosis-问诊 medicine-药品'])
->addColumn('related_id', 'integer', ['comment' => '关联ID'])
->addColumn('quantity', 'integer', ['default' => 1, 'comment' => '数量'])
->addColumn('unit_price', 'decimal', ['precision' => 10, 'scale' => 2, 'comment' => '单价'])
->addColumn('total_price', 'decimal', ['precision' => 10, 'scale' => 2, 'comment' => '总价'])
->addColumn('create_time', 'datetime', ['default' => 'CURRENT_TIMESTAMP', 'comment' => '创建时间'])
->addIndex(['order_id'])
->addIndex(['related_type', 'related_id'])
->create();
}
}
@@ -0,0 +1,3 @@
-- 预约表:渠道来源(字典 type_value = channels
ALTER TABLE `zyt_doctor_appointment`
ADD COLUMN `channel_source` varchar(64) NOT NULL DEFAULT '' COMMENT '渠道来源(字典channels)' AFTER `remark`;
@@ -0,0 +1,18 @@
-- 医生排班:一条记录 = 一段连续可挂号时间(支持同日多段、白班/夜班)
-- 表前缀默认 zyt_,与 config/database.php 中 prefix 一致
ALTER TABLE `zyt_doctor_roster`
ADD COLUMN `start_time` varchar(5) DEFAULT NULL COMMENT '接诊开始 HH:mm' AFTER `period`,
ADD COLUMN `end_time` varchar(5) DEFAULT NULL COMMENT '接诊结束 HH:mm' AFTER `start_time`,
ADD COLUMN `shift_type` varchar(20) DEFAULT NULL COMMENT 'day白班/night夜班' AFTER `end_time`,
ADD COLUMN `slot_minutes` smallint unsigned NOT NULL DEFAULT 15 COMMENT '号源间隔分钟' AFTER `shift_type`;
-- 历史数据:按原上午/下午补全时间
UPDATE `zyt_doctor_roster` SET `start_time`='09:00', `end_time`='12:00' WHERE `period`='morning' AND (`start_time` IS NULL OR `start_time`='');
UPDATE `zyt_doctor_roster` SET `start_time`='14:00', `end_time`='18:00' WHERE `period`='afternoon' AND (`start_time` IS NULL OR `start_time`='');
-- 原唯一键限制「每天仅上午+下午」,需改为按时段区分
ALTER TABLE `zyt_doctor_roster` DROP INDEX `uk_doctor_date_period`;
-- 防止同一天重复录入完全相同的时间段(含软删字段,与 ThinkPHP 软删一致)
ALTER TABLE `zyt_doctor_roster` ADD UNIQUE KEY `uk_doctor_date_segment` (`doctor_id`,`date`,`start_time`,`end_time`,`delete_time`);
@@ -0,0 +1,3 @@
-- 药材库:拼音首字母连写,供列表检索(如 甘草 -> gc)
ALTER TABLE `zyt_doctor_medicine`
ADD COLUMN `name_pinyin_abbr` varchar(64) NOT NULL DEFAULT '' COMMENT '名称拼音首字母(小写连写)' AFTER `name`;
@@ -0,0 +1,16 @@
<?php
use think\migration\Migrator;
use think\migration\Migration;
class AddOrderTradeNo extends Migration
{
public function change()
{
$table = $this->table('la_order');
if (!$table->hasColumn('trade_no')) {
$table->addColumn('trade_no', 'string', ['limit' => 64, 'null' => true, 'comment' => '支付平台交易号', 'after' => 'payment_time'])
->update();
}
}
}
@@ -0,0 +1,20 @@
<?php
use think\migration\Migrator;
use think\migration\Migration;
class AddOrderWechatPayeePayer extends Migration
{
public function change()
{
$table = $this->table('la_order');
if (!$table->hasColumn('payee_userid')) {
$table->addColumn('payee_userid', 'string', ['limit' => 64, 'null' => true, 'comment' => '收款人企业微信userid', 'after' => 'creator_id'])
->update();
}
if (!$table->hasColumn('payer_external_userid')) {
$table->addColumn('payer_external_userid', 'string', ['limit' => 128, 'null' => true, 'comment' => '付款人企业微信客户external_userid', 'after' => 'payee_userid'])
->update();
}
}
}
@@ -0,0 +1,17 @@
<?php
use think\migration\Migrator;
use think\migration\Migration;
/**
* 企业微信直接收款时自动创建订单,patient_id 可为空(待关联患者)
*/
class AllowOrderPatientNull extends Migration
{
public function change()
{
$this->table('la_order')
->changeColumn('patient_id', 'integer', ['null' => true, 'comment' => '患者ID(诊单ID),空表示待关联'])
->update();
}
}
@@ -0,0 +1,2 @@
-- 处方表增加详细病历字段(每次开方保存一份诊单快照)
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `case_record` longtext DEFAULT NULL COMMENT '详细病历(诊单快照JSON' AFTER `clinical_diagnosis`;
@@ -0,0 +1,29 @@
-- 挂号单状态自动更新 - MySQL 事件(可选,需开启 event_scheduler
-- 表名请根据实际前缀修改(如 zyt_doctor_appointment、la_doctor_appointment
-- 创建事件:每10分钟执行一次
-- SET GLOBAL event_scheduler = ON; -- 需先开启事件调度器
DELIMITER $$
DROP EVENT IF EXISTS evt_update_appointment_status$$
CREATE EVENT evt_update_appointment_status
ON SCHEDULE EVERY 10 MINUTE
DO
BEGIN
-- 1. 超过8小时 -> 已取消(status=2)
UPDATE zyt_doctor_appointment
SET status = 2, update_time = UNIX_TIMESTAMP()
WHERE status = 1
AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) <= DATE_SUB(NOW(), INTERVAL 8 HOUR);
-- 2. 已过时间但未超8小时 -> 已过号(status=4)
UPDATE zyt_doctor_appointment
SET status = 4, update_time = UNIX_TIMESTAMP()
WHERE status = 1
AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) < NOW()
AND CONCAT(appointment_date, ' ', IFNULL(appointment_time, '00:00:00')) > DATE_SUB(NOW(), INTERVAL 8 HOUR);
END$$
DELIMITER ;
@@ -0,0 +1,3 @@
-- 诊单:在用药物(患者当前服用的西药/中成药等)
ALTER TABLE `zyt_tcm_diagnosis`
ADD COLUMN `current_medications` varchar(2000) NOT NULL DEFAULT '' COMMENT '在用药物' AFTER `remark`;
@@ -0,0 +1,5 @@
-- 问题:UNIQUE(doctor_id, appointment_date, appointment_time, status) 允许「一条已预约 + 一条已取消」
-- 同一时段若先后有两名患者预约并取消,第二条 UPDATE status=2 会与第一条已取消行唯一键冲突(1062)。
-- 解决:去掉该唯一索引;「档期仅一条已预约」由 AppointmentLogic::create 中 status=1 存在性检查保证。
ALTER TABLE `zyt_doctor_appointment` DROP INDEX `unique_appointment`;
ALTER TABLE `zyt_doctor_appointment` ADD KEY `idx_doctor_date_time_status` (`doctor_id`, `appointment_date`, `appointment_time`, `status`);
@@ -0,0 +1,8 @@
-- 处方:指定角色可见(非共享时除创建者外,所列角色用户也可查看);审核状态与审核信息
ALTER TABLE `zyt_tcm_prescription`
ADD COLUMN `visible_role_ids` varchar(500) NOT NULL DEFAULT '' COMMENT '额外可见角色ID,逗号分隔,与创建者/共享并列' AFTER `is_shared`,
ADD COLUMN `audit_status` tinyint(1) NOT NULL DEFAULT 1 COMMENT '审核:0待审核 1已通过 2已驳回(同时作废)' AFTER `visible_role_ids`,
ADD COLUMN `audit_time` int(10) unsigned DEFAULT NULL COMMENT '审核时间' AFTER `audit_status`,
ADD COLUMN `audit_by` int(11) unsigned DEFAULT NULL COMMENT '审核人ID' AFTER `audit_time`,
ADD COLUMN `audit_by_name` varchar(50) NOT NULL DEFAULT '' COMMENT '审核人姓名' AFTER `audit_by`,
ADD COLUMN `audit_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '审核意见' AFTER `audit_by_name`;
@@ -0,0 +1,15 @@
-- 诊单指派医助操作记录(单次指派一条,批量指派为多条)
CREATE TABLE IF NOT EXISTS `zyt_tcm_diagnosis_assign_log` (
`id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`diagnosis_id` int unsigned NOT NULL DEFAULT 0 COMMENT '诊单ID',
`from_assistant_id` int unsigned NOT NULL DEFAULT 0 COMMENT '原医助管理员ID0表示未指派',
`to_assistant_id` int unsigned NOT NULL DEFAULT 0 COMMENT '新医助管理员ID',
`operator_admin_id` int unsigned NOT NULL DEFAULT 0 COMMENT '操作人管理员ID',
`operator_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人姓名',
`operator_account` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人账号',
`ip` varchar(45) NOT NULL DEFAULT '' COMMENT '操作IP',
`create_time` int unsigned NOT NULL DEFAULT 0 COMMENT '操作时间',
PRIMARY KEY (`id`),
KEY `idx_diagnosis_id` (`diagnosis_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='诊单指派医助操作记录';
@@ -0,0 +1,3 @@
-- 发现糖尿病患病史:支持文字描述(如半年、1年)或纯数字
ALTER TABLE `zyt_tcm_diagnosis`
MODIFY COLUMN `diabetes_discovery_year` varchar(50) DEFAULT NULL COMMENT '发现糖尿病患病史(如:半年、1年、或纯数字年数)';
@@ -0,0 +1,4 @@
-- 处方表:关联诊单所属医助(admin.id),便于统计「这张处方对应哪位医助的患者」
ALTER TABLE `zyt_tcm_prescription`
ADD COLUMN `assistant_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '诊单医助(admin id)0=无' AFTER `creator_id`,
ADD KEY `idx_assistant` (`assistant_id`);
@@ -0,0 +1,35 @@
-- 处方业务订单(履约/双审流程),与支付单表 zyt_order 分离
CREATE TABLE IF NOT EXISTS `zyt_tcm_prescription_order` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`order_no` varchar(50) NOT NULL COMMENT '业务订单号',
`prescription_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '消费者处方ID',
`diagnosis_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '诊单ID',
`creator_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '创建人管理员ID',
`recipient_name` varchar(50) NOT NULL DEFAULT '' COMMENT '收货人',
`recipient_phone` varchar(20) NOT NULL DEFAULT '' COMMENT '收货手机',
`shipping_address` varchar(500) NOT NULL DEFAULT '' COMMENT '收货地址',
`is_follow_up` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '是否复诊 0否1是',
`medication_days` int(11) DEFAULT NULL COMMENT '用药疗程(天)',
`prev_staff` varchar(100) NOT NULL DEFAULT '' COMMENT '上次医生/医助',
`service_channel` varchar(100) NOT NULL DEFAULT '' COMMENT '服务渠道',
`service_package` varchar(100) NOT NULL DEFAULT '' COMMENT '服务套餐',
`tracking_number` varchar(80) NOT NULL DEFAULT '' COMMENT '快递单号',
`fee_type` tinyint(2) unsigned NOT NULL DEFAULT 3 COMMENT '费用类别 1挂号2问诊3药品4首付5尾款6其他7全部',
`amount` decimal(10,2) NOT NULL DEFAULT 0.00 COMMENT '业务订单金额',
`internal_cost` decimal(10,2) DEFAULT NULL COMMENT '内部成本(财务可见)',
`remark_extra` varchar(500) NOT NULL DEFAULT '' COMMENT '备注补充',
`linked_pay_order_id` int(11) unsigned DEFAULT NULL COMMENT '关联支付单 zyt_order.id',
`prescription_audit_status` tinyint(2) unsigned NOT NULL DEFAULT 0 COMMENT '处方审核 0待审1通过2驳回',
`prescription_audit_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '处方审核意见',
`payment_slip_audit_status` tinyint(2) unsigned NOT NULL DEFAULT 0 COMMENT '支付单审核 0待审1通过2驳回',
`payment_slip_audit_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '支付单审核意见',
`fulfillment_status` tinyint(2) unsigned NOT NULL DEFAULT 1 COMMENT '1待双审通过 2履约中 3已完成 4已取消',
`create_time` int(10) unsigned NOT NULL DEFAULT 0,
`update_time` int(10) unsigned NOT NULL DEFAULT 0,
`delete_time` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_order_no` (`order_no`),
KEY `idx_prescription_id` (`prescription_id`),
KEY `idx_diagnosis_id` (`diagnosis_id`),
KEY `idx_creator_id` (`creator_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='处方业务订单(非支付单)';
@@ -0,0 +1,93 @@
-- 处方业务订单:后台菜单与接口权限(zyt_system_menu
-- 执行前请确认表前缀为 zyt_;若库中已有相同 perms 的行请跳过或删除重复项。
-- 菜单挂在「消费者处方」同级目录下(与 consumer/prescription/index 共用父级 pid
SET @rx_pid := (
SELECT pid FROM zyt_system_menu
WHERE type = 'C'
AND (
component = 'consumer/prescription/index'
OR component LIKE '%consumer/prescription/index%'
)
LIMIT 1
);
SET @rx_pid := IFNULL(@rx_pid, 0);
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
@rx_pid, 'C', '处方业务订单', 'local-icon-dingdan', 48,
'tcm.prescriptionOrder/lists', 'consumer/prescription_order', 'consumer/prescription/order_list',
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'tcm.prescriptionOrder/lists');
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', '详情', '', 1, 'tcm.prescriptionOrder/detail', '', '',
'', '', 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/detail');
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', '创建', '', 2, 'tcm.prescriptionOrder/create', '', '',
'', '', 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/create');
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', '编辑', '', 3, 'tcm.prescriptionOrder/edit', '', '',
'', '', 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/edit');
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', '修改快递单号', '', 31, 'tcm.prescriptionOrder/ddcode', '', '',
'', '', 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/ddcode');
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', '处方审核', '', 4, 'tcm.prescriptionOrder/auditPrescription', '', '',
'', '', 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/auditPrescription');
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', '支付单审核', '', 5, 'tcm.prescriptionOrder/auditPayment', '', '',
'', '', 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/auditPayment');
@@ -0,0 +1,4 @@
-- 业务订单审核意见(已建表可执行;若列已存在会报错,可忽略或手动删重跑)
ALTER TABLE `zyt_tcm_prescription_order`
ADD COLUMN `prescription_audit_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '处方审核意见' AFTER `prescription_audit_status`,
ADD COLUMN `payment_slip_audit_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '支付单审核意见' AFTER `payment_slip_audit_status`;
@@ -0,0 +1,24 @@
-- 处方业务订单:撤回、拉取可关联已支付单(权限节点)
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', '撤回订单', '', 6, 'tcm.prescriptionOrder/withdraw', '', '',
'', '', 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/withdraw');
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', '可关联支付单', '', 7, 'tcm.prescriptionOrder/paidPayOrders', '', '',
'', '', 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/paidPayOrders');
@@ -0,0 +1,16 @@
-- 处方业务订单 ↔ 支付单(zyt_order) 多对多关联
CREATE TABLE IF NOT EXISTS `zyt_tcm_prescription_order_pay_order` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`prescription_order_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '业务订单ID',
`pay_order_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT 'zyt_order.id,已支付',
`create_time` int(10) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_po_pay` (`prescription_order_id`,`pay_order_id`),
KEY `idx_pay_order` (`pay_order_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='业务订单关联支付单';
-- 历史单条关联字段迁入关联表(幂等:忽略重复)
INSERT IGNORE INTO `zyt_tcm_prescription_order_pay_order` (`prescription_order_id`, `pay_order_id`, `create_time`)
SELECT `id`, `linked_pay_order_id`, UNIX_TIMESTAMP()
FROM `zyt_tcm_prescription_order`
WHERE `linked_pay_order_id` IS NOT NULL AND `linked_pay_order_id` > 0 AND `delete_time` IS NULL;
@@ -0,0 +1,3 @@
-- 业务订单:快递公司(顺丰/京东/自动),用于物流轨迹查询
ALTER TABLE `zyt_tcm_prescription_order`
ADD COLUMN `express_company` varchar(20) NOT NULL DEFAULT '' COMMENT '快递公司 sf=顺丰 jd=京东 auto=自动' AFTER `tracking_number`;
@@ -0,0 +1,13 @@
-- 处方业务订单:物流轨迹查询权限
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', '物流轨迹', '', 8, 'tcm.prescriptionOrder/logisticsTrace', '', '',
'', '', 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/logisticsTrace');
@@ -0,0 +1,13 @@
-- 处方业务订单详情:查看处方药材明细(无此权限时接口不返回 herbs)
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', '药材明细', '', 9, 'tcm.prescriptionOrder/viewRxHerbs', '', '',
'', '', 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/viewRxHerbs');
@@ -0,0 +1,7 @@
-- 甘草订单状态回调:增加回调状态、流程、药房、备注字段
ALTER TABLE `zyt_tcm_prescription_order`
ADD COLUMN `gancao_order_state` smallint(6) NOT NULL DEFAULT 0 COMMENT '甘草订单状态 10审核中 11审核通过 110制作中 20物流中 30完成 90拦截 91撤单 92驳回' AFTER `gancao_submit_time`,
ADD COLUMN `gancao_flow_name` varchar(100) NOT NULL DEFAULT '' COMMENT '甘草当前加工流名(回调ext.flow_name' AFTER `gancao_order_state`,
ADD COLUMN `gancao_supplier` varchar(100) NOT NULL DEFAULT '' COMMENT '甘草制作药房(回调ext.supplier' AFTER `gancao_flow_name`,
ADD COLUMN `gancao_shipping_name` varchar(50) NOT NULL DEFAULT '' COMMENT '甘草物流商名称(回调ext.shipping_name' AFTER `gancao_supplier`,
ADD COLUMN `gancao_remark` varchar(500) NOT NULL DEFAULT '' COMMENT '甘草回调备注(拦截/撤单/驳回原因等)' AFTER `gancao_shipping_name`;
@@ -0,0 +1,17 @@
-- 甘草药管家处方单号回写 + 菜单权限
ALTER TABLE `zyt_tcm_prescription_order`
ADD COLUMN `gancao_reciperl_order_no` varchar(32) NOT NULL DEFAULT '' COMMENT '甘草处方订单号 recipel_order_no' AFTER `remark_extra`,
ADD COLUMN `gancao_submit_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '提交甘草成功时间戳' AFTER `gancao_reciperl_order_no`;
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', '上传甘草药方', '', 9, 'tcm.prescriptionOrder/submitGancaoRecipel', '', '',
'', '', 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/submitGancaoRecipel');
@@ -0,0 +1,105 @@
-- 企业微信 员工↔客户 消息收发相关表
-- 1) 会话索引(员工 userid × 客户 external_userid × 群 roomid 三元组,用于前端会话列表)
-- 2) 消息归档(会话存档 SDK 拉取落库;msgid 唯一,支持撤回更新)
-- 3) 消息归档附件(大型媒体独立存储,按需下载到本地/对象存储)
-- 4) 发消息任务(企业群发 add_msg_template 一次投递记录 + 每客户明细)
CREATE TABLE IF NOT EXISTS `zyt_qywx_msg_session` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`staff_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '企微员工 userid',
`external_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '客户 external_userid;群聊时为 roomid 对应的主联系客户,可留空',
`roomid` varchar(64) NOT NULL DEFAULT '' COMMENT '企微群聊 roomid;单聊为空',
`session_type` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '1=单聊 2=群聊',
`last_msg_id` varchar(64) NOT NULL DEFAULT '' COMMENT '最近一条归档消息 msgid(来自会话存档)',
`last_msg_seq` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '最近一条归档消息 seq',
`last_msg_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '最近一条归档消息 Unix 秒',
`last_msg_type` varchar(32) NOT NULL DEFAULT '' COMMENT '最近一条消息类型',
`last_msg_summary` varchar(512) NOT NULL DEFAULT '' COMMENT '最近一条消息摘要(纯文本,用于列表)',
`unread_staff` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '员工侧未读(后台管理员打开会话后清零)',
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
`update_time` int(11) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_session` (`staff_userid`,`external_userid`,`roomid`),
KEY `idx_staff_time` (`staff_userid`,`last_msg_time`),
KEY `idx_ext_time` (`external_userid`,`last_msg_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微消息会话索引';
CREATE TABLE IF NOT EXISTS `zyt_qywx_msg_archive` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`msgid` varchar(64) NOT NULL DEFAULT '' COMMENT '企微会话存档 msgid,官方唯一键',
`seq` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '拉取 seq(单调递增,断点续拉)',
`action` varchar(16) NOT NULL DEFAULT 'send' COMMENT 'send/recall/switch',
`from_user` varchar(64) NOT NULL DEFAULT '' COMMENT '发送方 userid / external_userid',
`from_type` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '0=未知 1=员工 2=客户',
`to_list` text COMMENT '接收方列表 JSON(单聊通常仅 1 个)',
`roomid` varchar(64) NOT NULL DEFAULT '' COMMENT '群 roomid,单聊为空',
`msgtype` varchar(32) NOT NULL DEFAULT '' COMMENT 'text/image/voice/video/file/link/location/emotion/chatrecord/markdown/news/meeting/calendar/mixed/weapp/voip_doc_share/...',
`content` mediumtext COMMENT '文本/卡片摘要(mixed/chatrecord 会序列化 JSON',
`media_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'sdkfileid:作为 GetMediaData 入参',
`md5sum` varchar(64) NOT NULL DEFAULT '' COMMENT '企微下发的 md5sum',
`file_name` varchar(512) NOT NULL DEFAULT '' COMMENT '原始文件名',
`file_size` bigint(20) unsigned NOT NULL DEFAULT 0 COMMENT '字节',
`file_ext` varchar(32) NOT NULL DEFAULT '' COMMENT '扩展名',
`play_length` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '语音/视频时长 秒',
`raw` mediumtext COMMENT '解密后的原始 JSON,兜底',
`send_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '消息时间 Unix 秒',
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
`update_time` int(11) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_msgid` (`msgid`),
KEY `idx_seq` (`seq`),
KEY `idx_room_time` (`roomid`,`send_time`),
KEY `idx_from_time` (`from_user`,`send_time`),
KEY `idx_send_time` (`send_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微会话存档消息';
CREATE TABLE IF NOT EXISTS `zyt_qywx_msg_archive_media` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`msgid` varchar(64) NOT NULL DEFAULT '' COMMENT '关联 zyt_qywx_msg_archive.msgid',
`sdkfileid` varchar(128) NOT NULL DEFAULT '',
`status` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '0=待下载 1=成功 2=失败',
`retry_count` int(11) unsigned NOT NULL DEFAULT 0,
`file_path` varchar(1024) NOT NULL DEFAULT '' COMMENT '本地/对象存储相对路径',
`file_url` varchar(1024) NOT NULL DEFAULT '' COMMENT '可公网访问的地址(如已迁 CDN',
`file_size` bigint(20) unsigned NOT NULL DEFAULT 0,
`md5sum` varchar(64) NOT NULL DEFAULT '',
`error` varchar(512) NOT NULL DEFAULT '',
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
`update_time` int(11) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_msg_sdk` (`msgid`,`sdkfileid`),
KEY `idx_status` (`status`,`retry_count`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微会话存档消息媒介文件';
CREATE TABLE IF NOT EXISTS `zyt_qywx_msg_send_task` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`admin_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '后台发起人 admin id',
`sender_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '代发员工 useridadd_msg_template 的 sender',
`external_userids` text COMMENT '目标客户 external_userid JSON 数组',
`chat_type` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '1=single 2=group(对应企微 chat_type',
`msg_payload` mediumtext COMMENT '消息体 JSON(含 text/image/video/file/link/miniprogram 任意组合)',
`msg_template_id` varchar(64) NOT NULL DEFAULT '' COMMENT '企微返回 msgid(提醒员工确认发送的 ID)',
`fail_list` text COMMENT '企微返回的 fail_list',
`status` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '0=待提交 1=已提交等待员工确认 2=已确认发送 3=失败',
`error` varchar(512) NOT NULL DEFAULT '',
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
`update_time` int(11) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_sender_time` (`sender_userid`,`create_time`),
KEY `idx_template` (`msg_template_id`),
KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微员工代发消息任务';
-- 断点续拉游标(seq 持久化;一行一条,按 staff_userid 维度)
CREATE TABLE IF NOT EXISTS `zyt_qywx_msg_archive_cursor` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`cursor_key` varchar(64) NOT NULL DEFAULT '' COMMENT '默认 global;如需按员工分片则存 staff_userid',
`seq` bigint(20) unsigned NOT NULL DEFAULT 0,
`last_pull_time` int(11) unsigned NOT NULL DEFAULT 0,
`last_pull_count` int(11) unsigned NOT NULL DEFAULT 0,
`last_error` varchar(512) NOT NULL DEFAULT '',
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
`update_time` int(11) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_cursor_key` (`cursor_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微会话存档拉取游标';
@@ -0,0 +1,13 @@
-- 支付单(zyt_order)后台操作日志:操作人、动作、时间
CREATE TABLE IF NOT EXISTS `zyt_order_action_log` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`order_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT 'zyt_order.id',
`admin_id` int(11) unsigned NOT NULL DEFAULT 0,
`admin_name` varchar(64) NOT NULL DEFAULT '' COMMENT '操作人姓名快照',
`action` varchar(32) NOT NULL DEFAULT '' COMMENT '动作码',
`summary` varchar(500) NOT NULL DEFAULT '' COMMENT '补充说明',
`create_time` int(11) unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
KEY `idx_order_id` (`order_id`),
KEY `idx_admin_id_time` (`admin_id`, `create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='支付单操作日志';
@@ -0,0 +1,5 @@
-- 诊单编辑页:查看完整手机号(无此权限时仅脱敏,需点击展开)
-- 将按钮挂在「中医诊单」菜单下(perms = tcm.diagnosis/lists);若库中结构不同请改 pid。
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 `id`, 'A', '手机号明文', '', 21, 'tcm.diagnosis/phonePlain', '', '', '', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM `zyt_system_menu` WHERE `perms` = 'tcm.diagnosis/lists' LIMIT 1;
@@ -0,0 +1,3 @@
-- 处方:系统代开标记(如医生在挂号列表点「完成」后自动生成、无药材配方)
ALTER TABLE `zyt_tcm_prescription`
ADD COLUMN `is_system_auto` tinyint(1) UNSIGNED NOT NULL DEFAULT 0 COMMENT '系统代开:1=完成挂号等自动生成' AFTER `is_shared`;
@@ -0,0 +1,3 @@
-- 已改为仅更新「创建人 creator_id」,不再使用 assistant_id 列;若已执行过 add 脚本可执行本脚本清理
-- 若表上无此列,执行会报错,可忽略或先 SHOW COLUMNS 确认
ALTER TABLE `zyt_order` DROP INDEX `idx_assistant_id`, DROP COLUMN `assistant_id`;
@@ -0,0 +1,5 @@
-- 支付单指派医助:后台批量指派、列表筛选
-- 表前缀 zyt_ 与 .env 中 PREFIX 一致
ALTER TABLE `zyt_order`
ADD COLUMN `assistant_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '指派医助 la_admin.id0=未指派' AFTER `creator_id`,
ADD KEY `idx_assistant_id` (`assistant_id`);
@@ -0,0 +1,13 @@
-- 处方业务订单:查看「操作日志」区块与 /tcm.prescriptionOrder/logs 接口
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', '操作日志', '', 9, 'tcm.prescriptionOrder/logs', '', '',
'', '', 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/logs');
@@ -0,0 +1,29 @@
CREATE TABLE IF NOT EXISTS `zyt_qywx_media_channel` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`channel_code` varchar(80) NOT NULL DEFAULT '' COMMENT '渠道编码:由 tag_id 或 tag_name 生成',
`channel_name` varchar(100) NOT NULL DEFAULT '' COMMENT '渠道名称(展示名)',
`source_tag_id` varchar(64) NOT NULL DEFAULT '' COMMENT '企微标签ID',
`source_tag_name` varchar(100) NOT NULL DEFAULT '' COMMENT '企微标签名',
`source_group_name` varchar(100) NOT NULL DEFAULT '' COMMENT '企微标签组名',
`tag_uniq_key` varchar(120) NOT NULL DEFAULT '' COMMENT '标签唯一键:优先 tag_id,否则 tag_name 哈希',
`status` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '状态:1=启用',
`last_seen_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '最近扫描命中时间',
`create_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_channel_code` (`channel_code`),
UNIQUE KEY `uk_tag_uniq_key` (`tag_uniq_key`),
KEY `idx_status` (`status`),
KEY `idx_last_seen_time` (`last_seen_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企微渠道标签源表';
ALTER TABLE `zyt_account_cost`
ADD COLUMN `media_channel_code` varchar(80) NOT NULL DEFAULT '' COMMENT '渠道编码' AFTER `cost_date`,
ADD COLUMN `media_channel_name` varchar(100) NOT NULL DEFAULT '' COMMENT '渠道名称' AFTER `media_channel_code`,
ADD COLUMN `dept_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '绑定部门ID' AFTER `media_channel_name`,
ADD COLUMN `dept_name` varchar(100) NOT NULL DEFAULT '' COMMENT '绑定部门名称' AFTER `dept_id`;
ALTER TABLE `zyt_account_cost`
DROP INDEX `uk_cost_date`,
ADD UNIQUE KEY `uk_cost_date_channel_dept` (`cost_date`, `media_channel_code`, `dept_id`),
ADD KEY `idx_cost_date_channel_dept` (`cost_date`, `media_channel_code`, `dept_id`);
@@ -0,0 +1,9 @@
-- 角色表新增数据范围(数据隔离)字段
-- 1=全部数据(免隔离,root 默认全部)
-- 2=本部门及子部门(按 admin_dept 关联 + dept 树的后代汇总可见 admin_id
-- 3=仅本部门
-- 4=仅本人
-- 迁移后保持旧行为:所有现有角色默认 1(全部),需要管理员按需逐角色改为 2/3/4 激活隔离
ALTER TABLE `zyt_system_role`
ADD COLUMN `data_scope` tinyint(1) NOT NULL DEFAULT 1
COMMENT '数据范围:1全部 2本部门及下级 3仅本部门 4仅本人' AFTER `sort`;
@@ -0,0 +1,7 @@
-- 二诊医助:新指派患者已读标记
ALTER TABLE `zyt_tcm_diagnosis`
ADD COLUMN `assign_read_at` int(10) unsigned DEFAULT NULL
COMMENT '医助查看指派时间戳,NULL 未读(新指派红旗)' AFTER `assistant_id`;
-- 已有数据标记为已读,避免全部显示红旗
UPDATE `zyt_tcm_diagnosis` SET `assign_read_at` = UNIX_TIMESTAMP() WHERE `assistant_id` > 0;
@@ -0,0 +1,13 @@
-- 支付单:设置/取消豁免权(权限节点)
SET @order_menu_id := (SELECT id FROM zyt_system_menu WHERE perms = 'order.order/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
@order_menu_id, 'A', '设置豁免权', '', 0, 'order.order/setExempt', '', '',
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @order_menu_id IS NOT NULL
AND NOT EXISTS (SELECT 1 FROM zyt_system_menu WHERE perms = 'order.order/setExempt');
@@ -0,0 +1,3 @@
ALTER TABLE `zyt_order`
ADD COLUMN `is_exempt` tinyint(1) unsigned NOT NULL DEFAULT 0
COMMENT '豁免权:1=关联此单时跳过定金门槛校验' AFTER `status`;
@@ -0,0 +1,168 @@
-- 处方库 AI 双模型解释:持久化表 + 读取/刷新/编辑三个独立 API 权限。
-- 三个 perms 必须与 PrescriptionLibraryController action 一一对应,否则
-- AuthMiddleware 会把未注册 URI 当作无需鉴权的普通接口直接放行。
CREATE TABLE IF NOT EXISTS `zyt_prescription_library_ai_report` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '报告ID',
`prescription_id` int unsigned NOT NULL COMMENT '处方库ID',
`model_key` varchar(32) NOT NULL COMMENT '服务端模型配置键:qwen/openai',
`model_name` varchar(100) NOT NULL DEFAULT '' COMMENT '生成时实际模型名称',
`model_label` varchar(50) NOT NULL DEFAULT '' COMMENT '模型展示名',
`report_content` mediumtext NOT NULL COMMENT '报告原始内容',
`message_id` varchar(191) NOT NULL DEFAULT '' COMMENT 'Dify message_id',
`prompt_version` varchar(50) NOT NULL DEFAULT '' COMMENT '提示词版本',
`prescription_fingerprint` char(64) NOT NULL DEFAULT '' COMMENT '生成时处方内容SHA-256',
`generated_by` int unsigned NOT NULL DEFAULT 0 COMMENT '最近生成管理员ID',
`generated_time` int unsigned NOT NULL DEFAULT 0 COMMENT '最近生成时间',
`edited_by` int unsigned NOT NULL DEFAULT 0 COMMENT '最近人工编辑管理员ID',
`edited_time` int unsigned NOT NULL DEFAULT 0 COMMENT '最近人工编辑时间',
`create_time` int unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int unsigned NOT NULL DEFAULT 0 COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_prescription_model` (`prescription_id`, `model_key`),
KEY `idx_generated_by_time` (`generated_by`, `generated_time`),
KEY `idx_edited_by_time` (`edited_by`, `edited_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='处方库AI解释报告';
START TRANSACTION;
SET @prescription_library_menu_id := (
SELECT `id`
FROM `zyt_system_menu`
WHERE `type` = 'C'
AND (
`component` = 'consumer/prescription/list'
OR `component` LIKE '%consumer/prescription/list%'
)
ORDER BY `id`
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
COALESCE(@prescription_library_menu_id, 0), 'A', '查看AI解释', '', 51,
'tcm.prescriptionLibrary/aiReports', '', '',
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE NOT EXISTS (
SELECT 1 FROM `zyt_system_menu`
WHERE `perms` = 'tcm.prescriptionLibrary/aiReports'
);
-- 刷新报告:固定同时生成 qwen/openai,不接受前端模型配置。
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
COALESCE(@prescription_library_menu_id, 0), 'A', '刷新AI解释', '', 52,
'tcm.prescriptionLibrary/generateAiReports', '', '',
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE NOT EXISTS (
SELECT 1 FROM `zyt_system_menu`
WHERE `perms` = 'tcm.prescriptionLibrary/generateAiReports'
);
-- 批量生成前只读发现:仅返回当前数据范围内完全没有报告的处方,不调用模型。
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
COALESCE(@prescription_library_menu_id, 0), 'A', '查询待生成AI解释', '', 54,
'tcm.prescriptionLibrary/missingAiReports', '', '',
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE NOT EXISTS (
SELECT 1 FROM `zyt_system_menu`
WHERE `perms` = 'tcm.prescriptionLibrary/missingAiReports'
);
-- 人工编辑必须是独立权限,不能依赖刷新权限隐式放行。
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
COALESCE(@prescription_library_menu_id, 0), 'A', '编辑AI解释', '', 53,
'tcm.prescriptionLibrary/editAiReport', '', '',
'', '', 0, 1, 0, UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE NOT EXISTS (
SELECT 1 FROM `zyt_system_menu`
WHERE `perms` = 'tcm.prescriptionLibrary/editAiReport'
);
SET @prescription_ai_read_menu_id := (
SELECT `id` FROM `zyt_system_menu`
WHERE `perms` = 'tcm.prescriptionLibrary/aiReports'
ORDER BY `id` LIMIT 1
);
SET @prescription_ai_refresh_menu_id := (
SELECT `id` FROM `zyt_system_menu`
WHERE `perms` = 'tcm.prescriptionLibrary/generateAiReports'
ORDER BY `id` LIMIT 1
);
SET @prescription_ai_missing_menu_id := (
SELECT `id` FROM `zyt_system_menu`
WHERE `perms` = 'tcm.prescriptionLibrary/missingAiReports'
ORDER BY `id` LIMIT 1
);
SET @prescription_ai_edit_menu_id := (
SELECT `id` FROM `zyt_system_menu`
WHERE `perms` = 'tcm.prescriptionLibrary/editAiReport'
ORDER BY `id` LIMIT 1
);
-- 已能查看处方库/处方的角色继承“读取已保存报告”。
INSERT IGNORE INTO `zyt_system_role_menu` (`role_id`, `menu_id`)
SELECT DISTINCT `role_menu`.`role_id`, @prescription_ai_read_menu_id
FROM `zyt_system_role_menu` AS `role_menu`
INNER JOIN `zyt_system_menu` AS `menu` ON `menu`.`id` = `role_menu`.`menu_id`
WHERE @prescription_ai_read_menu_id IS NOT NULL
AND (
`menu`.`perms` IN (
'tcm.prescriptionLibrary/lists',
'tcm.prescriptionLibrary/detail',
'tcm.prescriptionLibrary/aiReport',
'wcf.prescription/lists',
'wcf.prescription/read'
)
OR `menu`.`id` = @prescription_library_menu_id
);
-- 保持现有 AI 生成能力:能读取 AI 报告的角色默认继承刷新权限,之后可独立撤销。
INSERT IGNORE INTO `zyt_system_role_menu` (`role_id`, `menu_id`)
SELECT `role_id`, @prescription_ai_refresh_menu_id
FROM `zyt_system_role_menu`
WHERE @prescription_ai_read_menu_id IS NOT NULL
AND @prescription_ai_refresh_menu_id IS NOT NULL
AND `menu_id` = @prescription_ai_read_menu_id;
-- 能刷新单处方 AI 报告的角色继承批量发现权限;接口本身仍独立鉴权。
INSERT IGNORE INTO `zyt_system_role_menu` (`role_id`, `menu_id`)
SELECT `role_id`, @prescription_ai_missing_menu_id
FROM `zyt_system_role_menu`
WHERE @prescription_ai_refresh_menu_id IS NOT NULL
AND @prescription_ai_missing_menu_id IS NOT NULL
AND `menu_id` = @prescription_ai_refresh_menu_id;
-- 编辑仅继承给已有处方库编辑能力的角色,权限项本身仍可独立配置。
INSERT IGNORE INTO `zyt_system_role_menu` (`role_id`, `menu_id`)
SELECT DISTINCT `role_menu`.`role_id`, @prescription_ai_edit_menu_id
FROM `zyt_system_role_menu` AS `role_menu`
INNER JOIN `zyt_system_menu` AS `menu` ON `menu`.`id` = `role_menu`.`menu_id`
WHERE @prescription_ai_edit_menu_id IS NOT NULL
AND (
`menu`.`perms` IN (
'tcm.prescriptionLibrary/edit',
'wcf.prescription/edit'
)
);
COMMIT;
@@ -0,0 +1,27 @@
-- 医生工作站视频接通后的实时录音转写。
-- 转写摘要固化到每条通话记录,分段表用唯一键保证 WebChannel 重试幂等。
ALTER TABLE `zyt_tcm_call_record`
ADD COLUMN `transcription_session_id` varchar(128) NOT NULL DEFAULT '' COMMENT '实时转写会话ID',
ADD COLUMN `transcription_language` varchar(32) NOT NULL DEFAULT '' COMMENT '转写源语言',
ADD COLUMN `transcription_status` varchar(16) NOT NULL DEFAULT '' COMMENT 'running/completed/partial/failed',
ADD COLUMN `transcription_segment_count` int unsigned NOT NULL DEFAULT 0 COMMENT '已持久化完成分段数',
ADD COLUMN `transcript_text` longtext NULL COMMENT '按时间和说话人生成的面诊对话文字',
ADD COLUMN `transcription_started_at` int unsigned NOT NULL DEFAULT 0 COMMENT '转写开始Unix时间',
ADD COLUMN `transcription_finished_at` int unsigned NOT NULL DEFAULT 0 COMMENT '转写完成Unix时间';
CREATE TABLE IF NOT EXISTS `zyt_tcm_call_transcript_segment` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '分段ID',
`call_record_id` int unsigned NOT NULL COMMENT '通话记录ID',
`transcription_session_id` varchar(128) NOT NULL COMMENT '实时转写会话ID',
`segment_id` varchar(160) NOT NULL COMMENT '腾讯云完成分段ID',
`speaker_user_id` varchar(160) NOT NULL DEFAULT '' COMMENT '说话人TRTC用户ID',
`speaker_role` varchar(20) NOT NULL DEFAULT 'unknown' COMMENT 'doctor/patient/unknown',
`timestamp_ms` bigint unsigned NOT NULL DEFAULT 0 COMMENT '分段时间戳(毫秒)',
`text` text NOT NULL COMMENT '完成分段文字,最多4000字符',
`create_time` int unsigned NOT NULL DEFAULT 0,
`update_time` int unsigned NOT NULL DEFAULT 0,
PRIMARY KEY (`id`),
UNIQUE KEY `uk_call_session_segment` (`call_record_id`, `transcription_session_id`, `segment_id`),
KEY `idx_call_session_time` (`call_record_id`, `transcription_session_id`, `timestamp_ms`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='视频面诊实时转写完成分段';
@@ -0,0 +1,89 @@
-- 实时转写接口继承现有“1v1通话”权限,避免未注册 action 被默认放行。
START TRANSACTION;
SET @video_call_menu_id := (
SELECT `id`
FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/video-call'
ORDER BY `id`
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 @video_call_menu_id, 'A', '启动通话转写', '', 1,
'tcm.diagnosis/startCallTranscription', '', '', '', '', 0, 1, 0,
UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @video_call_menu_id IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/startCallTranscription'
);
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 @video_call_menu_id, 'A', '保存通话转写分段', '', 2,
'tcm.diagnosis/upsertCallTranscriptSegments', '', '', '', '', 0, 1, 0,
UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @video_call_menu_id IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/upsertCallTranscriptSegments'
);
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 @video_call_menu_id, 'A', '完成通话转写', '', 3,
'tcm.diagnosis/finishCallTranscription', '', '', '', '', 0, 1, 0,
UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE @video_call_menu_id IS NOT NULL
AND NOT EXISTS (
SELECT 1 FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/finishCallTranscription'
);
SET @transcription_start_menu_id := (
SELECT `id` FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/startCallTranscription'
ORDER BY `id` LIMIT 1
);
SET @transcription_segment_menu_id := (
SELECT `id` FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/upsertCallTranscriptSegments'
ORDER BY `id` LIMIT 1
);
SET @transcription_finish_menu_id := (
SELECT `id` FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/finishCallTranscription'
ORDER BY `id` LIMIT 1
);
INSERT IGNORE INTO `zyt_system_role_menu` (`role_id`, `menu_id`)
SELECT `role_id`, @transcription_start_menu_id
FROM `zyt_system_role_menu`
WHERE `menu_id` = @video_call_menu_id
AND @transcription_start_menu_id IS NOT NULL;
INSERT IGNORE INTO `zyt_system_role_menu` (`role_id`, `menu_id`)
SELECT `role_id`, @transcription_segment_menu_id
FROM `zyt_system_role_menu`
WHERE `menu_id` = @video_call_menu_id
AND @transcription_segment_menu_id IS NOT NULL;
INSERT IGNORE INTO `zyt_system_role_menu` (`role_id`, `menu_id`)
SELECT `role_id`, @transcription_finish_menu_id
FROM `zyt_system_role_menu`
WHERE `menu_id` = @video_call_menu_id
AND @transcription_finish_menu_id IS NOT NULL;
COMMIT;
@@ -0,0 +1,107 @@
-- 患者级 AI 诊断报告:不可变生成快照 + 两个独立接口权限。
-- 重要:本表故意不设置 (patient_id, model_key) 唯一键;每次生成必须 INSERT,历史绝不覆盖。
CREATE TABLE IF NOT EXISTS `zyt_patient_ai_report` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '患者AI报告快照ID',
`patient_id` int unsigned NOT NULL COMMENT '稳定患者ID(tcm_diagnosis.patient_id)',
`diagnosis_id` int unsigned DEFAULT NULL COMMENT '生成时数据域内最新诊单ID',
`model_key` varchar(32) NOT NULL COMMENT '服务端模型配置键(qwen/openai)',
`model_name` varchar(100) NOT NULL DEFAULT '' COMMENT '生成时实际模型名称快照',
`model_label` varchar(50) NOT NULL DEFAULT '' COMMENT '模型展示名快照',
`report_json` longtext NOT NULL COMMENT '结构化报告JSON',
`diagnosis` mediumtext NOT NULL COMMENT '结构化诊断分析',
`risk_assessment_json` text NOT NULL COMMENT '风险评估JSON数组',
`treatment_advice` mediumtext NOT NULL COMMENT '治疗与复核建议',
`disclaimer` varchar(255) NOT NULL DEFAULT '' COMMENT '固定医疗免责声明',
`source_snapshot` longtext NOT NULL COMMENT '生成时结构化来源快照JSON,仅服务端保存',
`source_summary_json` text NOT NULL COMMENT '用于历史列表的非原文来源计数摘要JSON',
`source_diagnosis_ids_json` text NOT NULL COMMENT '生成时全部来源诊单ID集合,用于历史行级权限复核',
`source_hash` char(64) NOT NULL COMMENT '规范化来源快照SHA-256',
`prompt_version` varchar(64) NOT NULL DEFAULT '' COMMENT '服务端提示词版本',
`message_id` varchar(191) NOT NULL DEFAULT '' COMMENT '上游消息ID,仅用于服务端审计',
`generated_at` int unsigned NOT NULL COMMENT '模型生成Unix时间',
`admin_id` int unsigned NOT NULL DEFAULT 0 COMMENT '发起生成的管理员ID',
`department_id` int unsigned NOT NULL DEFAULT 0 COMMENT '生成时首个所属部门ID快照',
`department_name` varchar(100) NOT NULL DEFAULT '' COMMENT '生成时首个所属部门名称快照',
`department_snapshot_json` text NOT NULL COMMENT '生成时全部所属部门JSON快照',
`created_at` int unsigned NOT NULL COMMENT '记录创建Unix时间',
PRIMARY KEY (`id`),
KEY `idx_patient_generated` (`patient_id`, `generated_at`, `id`),
KEY `idx_patient_model_generated` (`patient_id`, `model_key`, `generated_at`, `id`),
KEY `idx_diagnosis` (`diagnosis_id`),
KEY `idx_admin_generated` (`admin_id`, `generated_at`),
KEY `idx_department_generated` (`department_id`, `generated_at`),
KEY `idx_source_hash` (`source_hash`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='患者级AI诊断报告不可变快照';
SET @patient_ai_parent_id := (
SELECT `id`
FROM `zyt_system_menu`
WHERE `type` = 'C'
AND `perms` IN ('tcm.diagnosis/lists', 'doctor.appointment/lists')
ORDER BY FIELD(`perms`, 'tcm.diagnosis/lists', 'doctor.appointment/lists'), `id`
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
COALESCE(@patient_ai_parent_id, 0), 'A', '查看患者AI诊断报告', '', 66,
'tcm.diagnosis/patientAiReports', '', '', '', '', 0, 1, 0,
UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE NOT EXISTS (
SELECT 1 FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/patientAiReports'
);
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
COALESCE(@patient_ai_parent_id, 0), 'A', '生成患者AI诊断报告', '', 67,
'tcm.diagnosis/generatePatientAiReport', '', '', '', '', 0, 1, 0,
UNIX_TIMESTAMP(), UNIX_TIMESTAMP()
FROM DUAL
WHERE NOT EXISTS (
SELECT 1 FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/generatePatientAiReport'
);
SET @patient_ai_read_id := (
SELECT `id` FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/patientAiReports'
ORDER BY `id` LIMIT 1
);
SET @patient_ai_generate_id := (
SELECT `id` FROM `zyt_system_menu`
WHERE `perms` = 'tcm.diagnosis/generatePatientAiReport'
ORDER BY `id` LIMIT 1
);
-- 已能查看诊单/旧诊单AI报告的角色继承患者报告读取权限;之后仍可在角色菜单中单独撤销。
INSERT IGNORE INTO `zyt_system_role_menu` (`role_id`, `menu_id`)
SELECT DISTINCT `rm`.`role_id`, @patient_ai_read_id
FROM `zyt_system_role_menu` AS `rm`
INNER JOIN `zyt_system_menu` AS `m` ON `m`.`id` = `rm`.`menu_id`
WHERE @patient_ai_read_id IS NOT NULL
AND `m`.`perms` IN (
'tcm.diagnosis/lists',
'tcm.diagnosis/detail',
'tcm.diagnosis/readonlyDetail',
'tcm.diagnosis/aiReports'
);
-- 生成是独立能力,只从原有AI生成/结构化分析能力继承,不因能查看诊单而自动开放。
INSERT IGNORE INTO `zyt_system_role_menu` (`role_id`, `menu_id`)
SELECT DISTINCT `rm`.`role_id`, @patient_ai_generate_id
FROM `zyt_system_role_menu` AS `rm`
INNER JOIN `zyt_system_menu` AS `m` ON `m`.`id` = `rm`.`menu_id`
WHERE @patient_ai_generate_id IS NOT NULL
AND `m`.`perms` IN (
'tcm.diagnosis/generateAiReports',
'tcm.diagnosis/aiAnalysis'
);
@@ -0,0 +1,5 @@
-- 添加主诉相关字段到诊单表
ALTER TABLE `zyt_tcm_diagnosis`
ADD COLUMN `diabetes_discovery_year` int(3) DEFAULT NULL COMMENT '发现糖尿病就患病史(年)' AFTER `diabetes_type`,
ADD COLUMN `local_hospital_diagnosis` varchar(255) DEFAULT '' COMMENT '当地医院诊断结果(多选,逗号分隔)' AFTER `diabetes_discovery_year`,
ADD COLUMN `local_hospital_name` varchar(255) DEFAULT '' COMMENT '当地就诊医院名称' AFTER `local_hospital_diagnosis`;
@@ -0,0 +1,24 @@
-- 为管理员表添加医生相关字段
-- 执行时间:请根据实际情况修改
-- 添加基本信息字段
ALTER TABLE `zyt_admin`
ADD COLUMN `gender` tinyint(1) DEFAULT 1 COMMENT '性别:1=男,2=女' AFTER `name`,
ADD COLUMN `age` int(3) DEFAULT NULL COMMENT '年龄' AFTER `gender`,
ADD COLUMN `phone` varchar(20) DEFAULT NULL COMMENT '手机号' AFTER `age`;
-- 添加专业信息字段
ALTER TABLE `zyt_admin`
ADD COLUMN `title` varchar(50) DEFAULT NULL COMMENT '职称' AFTER `phone`,
ADD COLUMN `department` varchar(100) DEFAULT NULL COMMENT '所属科室' AFTER `title`,
ADD COLUMN `specialty` text DEFAULT NULL COMMENT '擅长领域' AFTER `department`;
-- 添加履历信息字段
ALTER TABLE `zyt_admin`
ADD COLUMN `education` text DEFAULT NULL COMMENT '教育背景' AFTER `specialty`,
ADD COLUMN `experience` text DEFAULT NULL COMMENT '工作经历' AFTER `education`,
ADD COLUMN `honors` text DEFAULT NULL COMMENT '荣誉资质' AFTER `experience`;
-- 添加索引
ALTER TABLE `zyt_admin` ADD INDEX `idx_phone` (`phone`);
ALTER TABLE `zyt_admin` ADD INDEX `idx_gender` (`gender`);
@@ -0,0 +1,2 @@
-- 处方单增加医师电子签名字段
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `doctor_signature` longtext DEFAULT NULL COMMENT '医师电子签名(base64)' AFTER `doctor_name`;
@@ -0,0 +1,2 @@
-- 处方剂量单位(剂、丸、袋、盒等)
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `dose_unit` varchar(20) NOT NULL DEFAULT '' COMMENT '剂量单位:剂、丸、袋、盒、瓶、膏、贴、包、片、粒' AFTER `dose_count`;
@@ -0,0 +1,4 @@
-- 企微侧「首次添加为外部联系人」时间:follow_user[].createtime 的最小值(同步时写入)
ALTER TABLE `zyt_qywx_external_contact`
ADD COLUMN `external_first_add_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '企微侧首次添加外部联系人时间(Unix秒)' AFTER `follow_admin_ids`,
ADD KEY `idx_external_first_add_time` (`external_first_add_time`);
@@ -0,0 +1,4 @@
-- 企微客户跟进人:解析 follow_user.userid 后匹配 zyt_admin.work_wechat_userid,写入后台管理员 id 列表(JSON 数组)
-- 使用可空列:兼容各 MySQL 版本向已有数据表加 TEXT 列;同步与接口均按空视为 []
ALTER TABLE `zyt_qywx_external_contact`
ADD COLUMN `follow_admin_ids` text NULL COMMENT '跟进人对应后台管理员ID列表JSON' AFTER `follow_users`;
@@ -0,0 +1,5 @@
-- 订单表增加收款人、付款人字段(企业微信对外收款同步用)
-- 将 zyt_ 替换为你的表前缀(.env 中 PREFIX
ALTER TABLE `zyt_order` ADD COLUMN `payee_userid` VARCHAR(64) NULL COMMENT '收款人企业微信userid' AFTER `creator_id`;
ALTER TABLE `zyt_order` ADD COLUMN `payer_external_userid` VARCHAR(128) NULL COMMENT '付款人企业微信客户external_userid' AFTER `payee_userid`;
@@ -0,0 +1,6 @@
-- 为诊单表添加舌苔照片和检查报告字段
ALTER TABLE `tcm_diagnosis` ADD COLUMN `tongue_photo` VARCHAR(500) COMMENT '舌苔照片URL' AFTER `tongue_coating`;
ALTER TABLE `tcm_diagnosis` ADD COLUMN `examination_report` LONGTEXT COMMENT '检查报告图片URL列表(逗号分隔)' AFTER `tongue_photo`;
-- 添加索引以提高查询性能
ALTER TABLE `tcm_diagnosis` ADD INDEX `idx_tongue_photo` (`tongue_photo`);
@@ -0,0 +1,11 @@
-- 处方增加共享字段
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `is_shared` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否共享:0-不共享(仅自己可见) 1-共享(所有人可见)' AFTER `template_id`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `prescription_name` varchar(100) NOT NULL DEFAULT '' COMMENT '处方名称' AFTER `sn`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `usage_days` int(11) NOT NULL DEFAULT 7 COMMENT '服用天数' AFTER `dose_unit`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `usage_time` varchar(50) NOT NULL DEFAULT '饭前' COMMENT '服用时间:饭前、饭后、饭中、空腹、睡前、晨起、随时' AFTER `usage_days`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `usage_way` varchar(50) NOT NULL DEFAULT '温水送服' COMMENT '服用方式:温水送服、开水冲服、黄酒送服等' AFTER `usage_time`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `dietary_taboo` varchar(200) NOT NULL DEFAULT '' COMMENT '忌口(逗号分隔):辛辣食物、生冷食物、油腻食物等' AFTER `usage_way`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `usage_notes` varchar(200) NOT NULL DEFAULT '' COMMENT '其他服用说明' AFTER `dietary_taboo`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `prescription_type` varchar(50) NOT NULL DEFAULT '浓缩水丸' COMMENT '处方类型:浓缩水丸、饮片、颗粒、丸剂、散剂等' AFTER `prescription_name`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `tongue_image` varchar(255) NOT NULL DEFAULT '' COMMENT '舌象图片' AFTER `tongue`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `pulse_condition` varchar(100) NOT NULL DEFAULT '' COMMENT '脉象详情' AFTER `pulse`;
@@ -0,0 +1,81 @@
-- 处方增加共享字段(安全版本 - 字段存在则跳过)
-- 1. 处方名称
SET @col_exists = 0;
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'zyt_tcm_prescription' AND COLUMN_NAME = 'prescription_name';
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `prescription_name` varchar(100) NOT NULL DEFAULT "" COMMENT "处方名称" AFTER `sn`', 'SELECT "prescription_name already exists"');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 2. 处方类型
SET @col_exists = 0;
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'zyt_tcm_prescription' AND COLUMN_NAME = 'prescription_type';
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `prescription_type` varchar(50) NOT NULL DEFAULT "浓缩水丸" COMMENT "处方类型:浓缩水丸、饮片、颗粒、丸剂、散剂等" AFTER `prescription_name`', 'SELECT "prescription_type already exists"');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 3. 舌象图片
SET @col_exists = 0;
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'zyt_tcm_prescription' AND COLUMN_NAME = 'tongue_image';
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `tongue_image` varchar(255) NOT NULL DEFAULT "" COMMENT "舌象图片" AFTER `tongue`', 'SELECT "tongue_image already exists"');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 4. 脉象详情
SET @col_exists = 0;
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'zyt_tcm_prescription' AND COLUMN_NAME = 'pulse_condition';
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `pulse_condition` varchar(100) NOT NULL DEFAULT "" COMMENT "脉象详情" AFTER `pulse`', 'SELECT "pulse_condition already exists"');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 5. 服用天数
SET @col_exists = 0;
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'zyt_tcm_prescription' AND COLUMN_NAME = 'usage_days';
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `usage_days` int(11) NOT NULL DEFAULT 7 COMMENT "服用天数" AFTER `dose_unit`', 'SELECT "usage_days already exists"');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 6. 服用时间
SET @col_exists = 0;
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'zyt_tcm_prescription' AND COLUMN_NAME = 'usage_time';
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `usage_time` varchar(50) NOT NULL DEFAULT "饭前" COMMENT "服用时间:饭前、饭后、饭中、空腹、睡前、晨起、随时" AFTER `usage_instruction`', 'SELECT "usage_time already exists"');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 7. 服用方式
SET @col_exists = 0;
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'zyt_tcm_prescription' AND COLUMN_NAME = 'usage_way';
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `usage_way` varchar(50) NOT NULL DEFAULT "温水送服" COMMENT "服用方式:温水送服、开水冲服、黄酒送服等" AFTER `usage_time`', 'SELECT "usage_way already exists"');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 8. 忌口
SET @col_exists = 0;
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'zyt_tcm_prescription' AND COLUMN_NAME = 'dietary_taboo';
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `dietary_taboo` varchar(200) NOT NULL DEFAULT "" COMMENT "忌口(逗号分隔):辛辣食物、生冷食物、油腻食物等" AFTER `usage_way`', 'SELECT "dietary_taboo already exists"');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 9. 其他服用说明
SET @col_exists = 0;
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'zyt_tcm_prescription' AND COLUMN_NAME = 'usage_notes';
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `usage_notes` varchar(200) NOT NULL DEFAULT "" COMMENT "其他服用说明" AFTER `dietary_taboo`', 'SELECT "usage_notes already exists"');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 10. 是否共享
SET @col_exists = 0;
SELECT COUNT(*) INTO @col_exists FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'zyt_tcm_prescription' AND COLUMN_NAME = 'is_shared';
SET @sql = IF(@col_exists = 0, 'ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `is_shared` tinyint(1) NOT NULL DEFAULT 0 COMMENT "是否共享:0-不共享(仅自己可见) 1-共享(所有人可见)" AFTER `template_id`', 'SELECT "is_shared already exists"');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
@@ -0,0 +1,12 @@
-- 添加生命体征、地区和婚姻状态字段到诊断表
ALTER TABLE `zyt_tcm_diagnosis` ADD COLUMN `marital_status` tinyint(1) DEFAULT NULL COMMENT '婚姻状态:0-未婚 1-已婚 2-离异' AFTER `age`;
ALTER TABLE `zyt_tcm_diagnosis` ADD COLUMN `height` int(3) DEFAULT NULL COMMENT '身高(cm)' AFTER `marital_status`;
ALTER TABLE `zyt_tcm_diagnosis` ADD COLUMN `weight` decimal(5,2) DEFAULT NULL COMMENT '体重(kg)' AFTER `height`;
ALTER TABLE `zyt_tcm_diagnosis` ADD COLUMN `region` varchar(100) DEFAULT '' COMMENT '地区' AFTER `weight`;
ALTER TABLE `zyt_tcm_diagnosis` ADD COLUMN `systolic_pressure` int(3) DEFAULT NULL COMMENT '收缩压(mmHg)' AFTER `region`;
ALTER TABLE `zyt_tcm_diagnosis` ADD COLUMN `diastolic_pressure` int(3) DEFAULT NULL COMMENT '舒张压(mmHg)' AFTER `systolic_pressure`;
ALTER TABLE `zyt_tcm_diagnosis` ADD COLUMN `fasting_blood_sugar` decimal(5,2) DEFAULT NULL COMMENT '空腹血糖(mmol/L)' AFTER `diastolic_pressure`;
-- 添加索引以提高查询性能
ALTER TABLE `zyt_tcm_diagnosis` ADD KEY `idx_region` (`region`);
ALTER TABLE `zyt_tcm_diagnosis` ADD KEY `idx_marital_status` (`marital_status`);
@@ -0,0 +1,5 @@
-- 处方作废字段
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `void_status` tinyint(1) NOT NULL DEFAULT 0 COMMENT '作废状态:0-正常 1-已作废' AFTER `doctor_signature`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `void_time` int(10) unsigned DEFAULT NULL COMMENT '作废时间' AFTER `void_status`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `void_by` int(11) unsigned DEFAULT NULL COMMENT '作废操作人ID' AFTER `void_time`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `void_by_name` varchar(50) DEFAULT '' COMMENT '作废操作人姓名' AFTER `void_by`;
@@ -0,0 +1,4 @@
-- 给管理员表增加企业微信UserId字段,用于企业微信授权登录匹配
ALTER TABLE `zyt_admin`
ADD COLUMN `work_wechat_userid` varchar(64) DEFAULT '' COMMENT '企业微信UserId' AFTER `multipoint_login`,
ADD INDEX `idx_work_wechat_userid` (`work_wechat_userid`);
@@ -0,0 +1,154 @@
-- ============================================
-- 物流追踪系统数据库表
-- ============================================
-- 1. 物流订单表(主表)
CREATE TABLE IF NOT EXISTS `zyt_express_tracking` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`order_id` int(11) NOT NULL DEFAULT '0' COMMENT '关联订单IDprescription_order表)',
`order_type` varchar(50) NOT NULL DEFAULT 'prescription' COMMENT '订单类型',
`tracking_number` varchar(80) NOT NULL DEFAULT '' COMMENT '快递单号',
`express_company` varchar(50) NOT NULL DEFAULT 'auto' COMMENT '快递公司编码',
`express_company_name` varchar(100) NOT NULL DEFAULT '' COMMENT '快递公司名称',
`recipient_phone` varchar(20) NOT NULL DEFAULT '' COMMENT '收件人手机号',
`recipient_name` varchar(100) NOT NULL DEFAULT '' COMMENT '收件人姓名',
`recipient_address` varchar(500) NOT NULL DEFAULT '' COMMENT '收件地址',
-- 物流状态
`current_state` varchar(10) NOT NULL DEFAULT '0' COMMENT '当前物流状态:0在途,1揽收,2疑难,3签收,4退签,5派件,6退回,7转投,8清关,10待清关,11清关中,12已清关,13清关异常,14拒签',
`current_state_text` varchar(50) NOT NULL DEFAULT '' COMMENT '当前状态文本',
`is_signed` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已签收:0否,1是',
`sign_time` int(11) NOT NULL DEFAULT '0' COMMENT '签收时间',
-- 最新轨迹
`latest_trace_time` varchar(50) NOT NULL DEFAULT '' COMMENT '最新轨迹时间',
`latest_trace_context` varchar(500) NOT NULL DEFAULT '' COMMENT '最新轨迹内容',
`latest_location` varchar(200) NOT NULL DEFAULT '' COMMENT '最新位置',
-- 查询信息
`last_query_time` int(11) NOT NULL DEFAULT '0' COMMENT '最后查询时间',
`query_count` int(11) NOT NULL DEFAULT '0' COMMENT '查询次数',
`data_source` varchar(50) NOT NULL DEFAULT '' COMMENT '数据来源:kuaidi100/official',
-- 预计信息
`estimated_arrival_time` varchar(50) NOT NULL DEFAULT '' COMMENT '预计到达时间',
`total_time` varchar(50) NOT NULL DEFAULT '' COMMENT '总耗时',
`remain_time` varchar(50) NOT NULL DEFAULT '' COMMENT '剩余时间',
-- 自动更新控制
`auto_update` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否自动更新:0否,1是',
`update_interval` int(11) NOT NULL DEFAULT '1800' COMMENT '更新间隔(秒),默认30分钟',
`next_update_time` int(11) NOT NULL DEFAULT '0' COMMENT '下次更新时间',
-- 通知设置
`notify_on_sign` tinyint(1) NOT NULL DEFAULT '1' COMMENT '签收时通知:0否,1是',
`notify_on_problem` tinyint(1) NOT NULL DEFAULT '1' COMMENT '异常时通知:0否,1是',
`notified_states` varchar(500) NOT NULL DEFAULT '' COMMENT '已通知的状态(JSON数组)',
-- 扩展信息
`route_info` text COMMENT '路由信息(JSON',
`extra_data` text COMMENT '扩展数据(JSON',
-- 时间戳
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',
`delete_time` int(11) DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_tracking_number` (`tracking_number`),
KEY `idx_order_id` (`order_id`),
KEY `idx_state` (`current_state`),
KEY `idx_auto_update` (`auto_update`, `next_update_time`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流追踪主表';
-- 2. 物流轨迹明细表
CREATE TABLE IF NOT EXISTS `zyt_express_trace` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tracking_id` int(11) NOT NULL DEFAULT '0' COMMENT '关联tracking表ID',
`tracking_number` varchar(80) NOT NULL DEFAULT '' COMMENT '快递单号(冗余,便于查询)',
-- 轨迹信息
`trace_time` varchar(50) NOT NULL DEFAULT '' COMMENT '轨迹时间',
`trace_time_stamp` int(11) NOT NULL DEFAULT '0' COMMENT '轨迹时间戳',
`trace_context` varchar(1000) NOT NULL DEFAULT '' COMMENT '轨迹内容',
-- 状态信息
`status` varchar(50) NOT NULL DEFAULT '' COMMENT '物流状态名称',
`status_code` varchar(10) NOT NULL DEFAULT '' COMMENT '物流状态码',
-- 位置信息
`location` varchar(200) NOT NULL DEFAULT '' COMMENT '当前位置',
`area_code` varchar(50) NOT NULL DEFAULT '' COMMENT '行政区域编码',
`area_name` varchar(200) NOT NULL DEFAULT '' COMMENT '行政区域名称',
`area_center` varchar(100) NOT NULL DEFAULT '' COMMENT '区域中心坐标',
-- 扩展信息
`extra_data` text COMMENT '扩展数据(JSON',
-- 时间戳
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_tracking_id` (`tracking_id`),
KEY `idx_tracking_number` (`tracking_number`),
KEY `idx_trace_time_stamp` (`trace_time_stamp`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流轨迹明细表';
-- 3. 物流状态变更记录表
CREATE TABLE IF NOT EXISTS `zyt_express_state_log` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tracking_id` int(11) NOT NULL DEFAULT '0' COMMENT '关联tracking表ID',
`tracking_number` varchar(80) NOT NULL DEFAULT '' COMMENT '快递单号',
-- 状态变更
`old_state` varchar(10) NOT NULL DEFAULT '' COMMENT '旧状态',
`old_state_text` varchar(50) NOT NULL DEFAULT '' COMMENT '旧状态文本',
`new_state` varchar(10) NOT NULL DEFAULT '' COMMENT '新状态',
`new_state_text` varchar(50) NOT NULL DEFAULT '' COMMENT '新状态文本',
-- 变更信息
`change_time` int(11) NOT NULL DEFAULT '0' COMMENT '变更时间',
`change_reason` varchar(500) NOT NULL DEFAULT '' COMMENT '变更原因(最新轨迹内容)',
-- 通知信息
`is_notified` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否已通知:0否,1是',
`notify_time` int(11) NOT NULL DEFAULT '0' COMMENT '通知时间',
`notify_result` varchar(500) NOT NULL DEFAULT '' COMMENT '通知结果',
-- 时间戳
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_tracking_id` (`tracking_id`),
KEY `idx_tracking_number` (`tracking_number`),
KEY `idx_change_time` (`change_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流状态变更记录表';
-- 4. 物流查询日志表
CREATE TABLE IF NOT EXISTS `zyt_express_query_log` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`tracking_number` varchar(80) NOT NULL DEFAULT '' COMMENT '快递单号',
`express_company` varchar(50) NOT NULL DEFAULT '' COMMENT '快递公司编码',
-- 查询信息
`query_type` varchar(50) NOT NULL DEFAULT 'manual' COMMENT '查询类型:manual手动,auto自动',
`query_source` varchar(50) NOT NULL DEFAULT '' COMMENT '查询来源:kuaidi100/official',
`query_time` int(11) NOT NULL DEFAULT '0' COMMENT '查询时间',
-- 查询结果
`is_success` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否成功:0否,1是',
`error_code` varchar(50) NOT NULL DEFAULT '' COMMENT '错误码',
`error_message` varchar(500) NOT NULL DEFAULT '' COMMENT '错误信息',
-- 响应信息
`response_time` int(11) NOT NULL DEFAULT '0' COMMENT '响应时间(毫秒)',
`trace_count` int(11) NOT NULL DEFAULT '0' COMMENT '轨迹数量',
-- 时间戳
`create_time` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_tracking_number` (`tracking_number`),
KEY `idx_query_time` (`query_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='物流查询日志表';
@@ -0,0 +1,40 @@
-- 粉丝表
CREATE TABLE IF NOT EXISTS `zyt_fan` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL DEFAULT '' COMMENT '姓名',
`phone` varchar(20) NOT NULL DEFAULT '' COMMENT '手机号',
`id_card` varchar(18) NOT NULL DEFAULT '' COMMENT '身份证号码',
`age` tinyint(3) unsigned NOT NULL DEFAULT 0 COMMENT '年龄',
`gender` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '性别: 0=未知 1=男 2=女',
`remark` varchar(500) NOT NULL DEFAULT '' COMMENT '备注',
`creator_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '创建人ID',
`creator_name` varchar(50) NOT NULL DEFAULT '' COMMENT '创建人名称',
`status` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '状态: 0=禁用 1=启用',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(10) unsigned DEFAULT NULL COMMENT '修改时间',
`delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
KEY `idx_phone` (`phone`),
KEY `idx_id_card` (`id_card`),
KEY `idx_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='粉丝表';
-- 粉丝回访记录表
CREATE TABLE IF NOT EXISTS `zyt_fan_visit_record` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`fan_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '关联粉丝ID',
`visit_type` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '回访类型: 1=电话 2=微信 3=短信 4=上门 5=其他',
`visit_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '回访时间',
`content` text COMMENT '回访内容',
`result` varchar(500) NOT NULL DEFAULT '' COMMENT '回访结果',
`next_visit_time` int(10) unsigned DEFAULT NULL COMMENT '下次回访时间',
`operator_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '操作人ID',
`operator_name` varchar(50) NOT NULL DEFAULT '' COMMENT '操作人名称',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(10) unsigned DEFAULT NULL COMMENT '修改时间',
`delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
KEY `idx_fan_id` (`fan_id`),
KEY `idx_visit_time` (`visit_time`),
KEY `idx_operator_id` (`operator_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='粉丝回访记录表';
@@ -0,0 +1,17 @@
-- 处方库表
CREATE TABLE IF NOT EXISTS `zyt_prescription_library` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`prescription_name` varchar(100) NOT NULL DEFAULT '' COMMENT '处方名称',
`formula_type` varchar(20) NOT NULL DEFAULT '主方' COMMENT '处方类型:主方、辅方',
`herbs` text COMMENT '药材列表JSON[{name, dosage}]',
`is_public` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否公开:0-仅自己可见 1-所有人可见',
`creator_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建人ID',
`creator_name` varchar(50) NOT NULL DEFAULT '' COMMENT '创建人姓名',
`create_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
`delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
KEY `idx_creator` (`creator_id`),
KEY `idx_is_public` (`is_public`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='处方库表';
@@ -0,0 +1,42 @@
-- 企业微信外部联系人(客户)表
CREATE TABLE IF NOT EXISTS `zyt_qywx_external_contact` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`external_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '外部联系人ID',
`name` varchar(64) NOT NULL DEFAULT '' COMMENT '客户名称',
`avatar` varchar(255) NOT NULL DEFAULT '' COMMENT '头像URL',
`type` tinyint(1) unsigned NOT NULL DEFAULT 1 COMMENT '类型:1=微信用户,2=企业微信用户',
`gender` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '性别:0=未知,1=男,2=女',
`unionid` varchar(64) NOT NULL DEFAULT '' COMMENT '微信unionid',
`position` varchar(64) NOT NULL DEFAULT '' COMMENT '职位',
`corp_name` varchar(128) NOT NULL DEFAULT '' COMMENT '企业名称',
`corp_full_name` varchar(255) NOT NULL DEFAULT '' COMMENT '企业全称',
`external_profile` text COMMENT '外部联系人扩展信息JSON',
`follow_users` text COMMENT '跟进人列表JSON',
`follow_admin_ids` text NULL COMMENT '跟进人对应后台管理员ID列表JSON',
`external_first_add_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '企微侧首次添加外部联系人时间(Unix秒)',
`create_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '添加时间',
`update_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '更新时间',
`delete_time` int(11) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_external_userid` (`external_userid`),
KEY `idx_name` (`name`),
KEY `idx_unionid` (`unionid`),
KEY `idx_external_first_add_time` (`external_first_add_time`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业微信外部联系人表';
-- 企业微信同步设置表
CREATE TABLE IF NOT EXISTS `zyt_qywx_sync_settings` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`setting_key` varchar(64) NOT NULL DEFAULT '' COMMENT '设置键',
`setting_value` text COMMENT '设置值JSON',
`create_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_setting_key` (`setting_key`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业微信同步设置表';
-- 插入默认同步设置
INSERT INTO `zyt_qywx_sync_settings` (`setting_key`, `setting_value`, `create_time`, `update_time`)
VALUES ('customer_sync', '{"auto_sync":false,"interval":3600,"last_sync_time":0,"sync_status":"idle"}', UNIX_TIMESTAMP(), UNIX_TIMESTAMP())
ON DUPLICATE KEY UPDATE `update_time` = UNIX_TIMESTAMP();
@@ -0,0 +1,22 @@
-- 企业微信「客户联系」事件流水表
-- 用途:
-- 1) 记录每一次 change_external_contact 推送,用于"今天进来多少人(=add_external_contact 次数)"等精确统计;
-- 2) 独立于 zyt_qywx_external_contact(会被软删/UPSERT 覆盖),保证统计零误差;
-- 3) 企微对非 2xx 响应最多重试 3 次,(change_type, user_id, external_userid, event_time) 唯一键保证幂等。
CREATE TABLE IF NOT EXISTS `zyt_qywx_external_contact_event` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`change_type` varchar(32) NOT NULL DEFAULT '' COMMENT 'change_external_contact 下的子类型,如 add_external_contact/del_external_contact/del_follow_user/transfer_fail 等',
`user_id` varchar(64) NOT NULL DEFAULT '' COMMENT '企业员工 userid(可能为空)',
`external_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '外部联系人 external_userid(可能为空,如渠道活码尚未产生客户)',
`state` varchar(128) NOT NULL DEFAULT '' COMMENT '企微 State(推广渠道自定义参数),用于分渠道统计',
`fail_reason` varchar(64) NOT NULL DEFAULT '' COMMENT 'transfer_fail 等事件的失败原因',
`welcome_code` tinyint(1) unsigned NOT NULL DEFAULT 0 COMMENT '是否带欢迎码(1=带;不落 code 原文以免泄漏)',
`event_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '企微 CreateTime(事件发生时间戳,秒)',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '本地入库时间(秒)',
`raw` text DEFAULT NULL COMMENT '事件原文 JSON(调试用,可定期清理)',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_change_user_ext_time` (`change_type`, `user_id`, `external_userid`, `event_time`),
KEY `idx_change_time` (`change_type`, `event_time`),
KEY `idx_event_time` (`event_time`),
KEY `idx_state` (`state`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业微信外部联系人事件流水(用于进入计数)';
@@ -0,0 +1,27 @@
-- 诊单腾讯云 IM 单聊消息归档(定时从 admin_getroammsg 同步,突破云端约 7 天漫游限制)
-- 执行前请确认库名与表前缀(默认前缀 zyt_)
CREATE TABLE IF NOT EXISTS `zyt_tcm_im_chat_message` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
`diagnosis_id` int unsigned NOT NULL DEFAULT 0 COMMENT '诊单ID',
`patient_id` int unsigned NOT NULL DEFAULT 0 COMMENT '患者ID(冗余,便于按患者维度排查/统计)',
`msg_id` varchar(160) NOT NULL DEFAULT '' COMMENT '业务唯一键:MsgSeq_MsgRandom_From_Account',
`from_account` varchar(64) NOT NULL DEFAULT '' COMMENT '发送方 IM UserID',
`to_account` varchar(64) NOT NULL DEFAULT '' COMMENT '接收方 IM UserID',
`msg_time` int unsigned NOT NULL DEFAULT 0 COMMENT '消息时间 Unix 时间戳',
`is_from_doctor` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '是否医生/医助侧发送',
`msg_type` varchar(32) NOT NULL DEFAULT '' COMMENT 'text/image/file/sound/video/custom/...',
`text` mediumtext COMMENT '文本或自定义消息 Data',
`image_url` varchar(1024) NOT NULL DEFAULT '' COMMENT '图片 URL',
`file_url` varchar(1024) NOT NULL DEFAULT '' COMMENT '文件/语音/视频 URL',
`file_name` varchar(512) NOT NULL DEFAULT '' COMMENT '文件名',
`raw_elem_type` varchar(64) NOT NULL DEFAULT '' COMMENT 'TIM 元素类型',
`from_staff_name` varchar(64) NOT NULL DEFAULT '' COMMENT '医生侧姓名快照',
`doctor_peer_account` varchar(64) NOT NULL DEFAULT '' COMMENT '拉取会话时使用的医生侧账号 doctor_*',
`create_time` int unsigned NOT NULL DEFAULT 0 COMMENT '入库时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_msg_id` (`msg_id`),
KEY `idx_diagnosis_time` (`diagnosis_id`,`msg_time`),
KEY `idx_patient_time` (`patient_id`,`msg_time`),
KEY `idx_msg_time` (`msg_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='诊单IM聊天记录归档';
@@ -0,0 +1,38 @@
-- 中医处方单表
CREATE TABLE IF NOT EXISTS `zyt_tcm_prescription` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`sn` varchar(50) NOT NULL DEFAULT '' COMMENT '处方编号',
`diagnosis_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '诊单ID',
`appointment_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '预约ID',
`patient_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '患者ID',
`patient_name` varchar(50) NOT NULL DEFAULT '' COMMENT '患者姓名',
`gender` tinyint(1) NOT NULL DEFAULT '0' COMMENT '性别:0-女 1-男',
`age` int(3) NOT NULL DEFAULT '0' COMMENT '年龄',
`phone` varchar(20) DEFAULT '' COMMENT '电话',
`visit_no` varchar(50) DEFAULT '' COMMENT '门诊号',
`prescription_date` date DEFAULT NULL COMMENT '处方日期',
`pulse` varchar(100) DEFAULT '' COMMENT '脉象',
`tongue` varchar(100) DEFAULT '' COMMENT '舌象',
`clinical_diagnosis` varchar(500) DEFAULT '' COMMENT '临床诊断',
`herbs` text COMMENT '中药列表JSON[{name, dosage}]',
`dose_count` int(11) NOT NULL DEFAULT '1' COMMENT '剂数',
`usage_instruction` varchar(200) DEFAULT '水煎服一日二次' COMMENT '用法',
`amount` decimal(10,2) NOT NULL DEFAULT '0.00' COMMENT '金额',
`doctor_name` varchar(50) DEFAULT '' COMMENT '医师姓名',
`template_id` int(11) unsigned DEFAULT '0' COMMENT '模板ID',
`creator_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '创建人ID',
`create_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '创建时间',
`update_time` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '更新时间',
`delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_sn` (`sn`),
KEY `idx_diagnosis` (`diagnosis_id`),
KEY `idx_appointment` (`appointment_id`),
KEY `idx_patient` (`patient_id`),
KEY `idx_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='中医处方单表';
-- 处方增加共享字段
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `is_shared` tinyint(1) NOT NULL DEFAULT 0 COMMENT '是否共享:0-不共享(仅自己可见) 1-共享(所有人可见)' AFTER `template_id`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `prescription_name` varchar(100) NOT NULL DEFAULT '' COMMENT '处方名称' AFTER `sn`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `usage_days` int(11) NOT NULL DEFAULT 7 COMMENT '服用天数' AFTER `dose_unit`;
ALTER TABLE `zyt_tcm_prescription` ADD COLUMN `usage_method` varchar(200) NOT NULL DEFAULT '' COMMENT '服用说明' AFTER `usage_days`;
@@ -0,0 +1,27 @@
-- 企业微信聊天记录表(关联诊单/患者,记录企业微信沟通内容)
CREATE TABLE IF NOT EXISTS `zyt_wechat_chat_record` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`diagnosis_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '关联诊单ID',
`patient_id` int(11) unsigned NOT NULL DEFAULT 0 COMMENT '关联患者ID',
`staff_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '企业微信成员UserId',
`staff_name` varchar(64) NOT NULL DEFAULT '' COMMENT '成员名称',
`external_userid` varchar(64) NOT NULL DEFAULT '' COMMENT '客户的企业微信external_userid',
`external_name` varchar(128) NOT NULL DEFAULT '' COMMENT '客户名称',
`msg_type` varchar(20) NOT NULL DEFAULT 'text' COMMENT '消息类型: text/image/file/link/note',
`content` text COMMENT '消息内容/摘要',
`media_url` varchar(500) NOT NULL DEFAULT '' COMMENT '媒体文件URL(图片/文件)',
`chat_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '聊天时间戳',
`direction` tinyint(1) NOT NULL DEFAULT 0 COMMENT '方向: 0=员工发出 1=客户发出',
`create_time` int(10) unsigned NOT NULL DEFAULT 0 COMMENT '创建时间',
`update_time` int(10) unsigned DEFAULT NULL COMMENT '修改时间',
`delete_time` int(10) unsigned DEFAULT NULL COMMENT '删除时间',
PRIMARY KEY (`id`),
KEY `idx_diagnosis_id` (`diagnosis_id`),
KEY `idx_patient_id` (`patient_id`),
KEY `idx_staff_userid` (`staff_userid`),
KEY `idx_chat_time` (`chat_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='企业微信聊天记录';
-- 给患者诊单表增加企业微信外部联系人ID(用于自动匹配)
ALTER TABLE `zyt_diagnosis`
ADD COLUMN `external_userid` varchar(64) DEFAULT '' COMMENT '企业微信外部联系人ID' AFTER `assistant_id`;
@@ -0,0 +1,18 @@
-- 回滚:删除管理员表的医生相关字段
-- 警告:执行此脚本将删除这些字段的所有数据
-- 删除索引
ALTER TABLE `zyt_admin` DROP INDEX `idx_phone`;
ALTER TABLE `zyt_admin` DROP INDEX `idx_gender`;
-- 删除字段
ALTER TABLE `zyt_admin`
DROP COLUMN `gender`,
DROP COLUMN `age`,
DROP COLUMN `phone`,
DROP COLUMN `title`,
DROP COLUMN `department`,
DROP COLUMN `specialty`,
DROP COLUMN `education`,
DROP COLUMN `experience`,
DROP COLUMN `honors`;
@@ -0,0 +1,62 @@
-- =====================================================
-- 同步现有订单的快递单号到物流追踪表
-- =====================================================
-- 执行时间:2026-04-07
-- 说明:将 zyt_tcm_prescription_order 表中已有的快递单号同步到 zyt_express_tracking 表
-- =====================================================
-- 插入现有订单的快递单号到物流追踪表
-- 只插入有快递单号且不为空的订单
INSERT INTO `zyt_express_tracking` (
`order_id`,
`order_type`,
`tracking_number`,
`express_company`,
`recipient_phone`,
`recipient_name`,
`recipient_address`,
`auto_update`,
`update_interval`,
`next_update_time`,
`create_time`,
`update_time`
)
SELECT
o.`id` AS `order_id`,
'prescription' AS `order_type`,
o.`tracking_number`,
CASE
WHEN o.`express_company` = '' OR o.`express_company` IS NULL THEN 'auto'
ELSE o.`express_company`
END AS `express_company`,
o.`recipient_phone`,
o.`recipient_name`,
o.`shipping_address` AS `recipient_address`,
1 AS `auto_update`,
600 AS `update_interval`,
UNIX_TIMESTAMP() AS `next_update_time`,
UNIX_TIMESTAMP() AS `create_time`,
UNIX_TIMESTAMP() AS `update_time`
FROM `zyt_tcm_prescription_order` o
WHERE o.`tracking_number` IS NOT NULL
AND o.`tracking_number` != ''
AND o.`delete_time` IS NULL
AND NOT EXISTS (
-- 避免重复插入
SELECT 1 FROM `zyt_express_tracking` t
WHERE t.`tracking_number` = o.`tracking_number`
);
-- 显示同步结果
SELECT
COUNT(*) AS '已同步的快递单号数量'
FROM `zyt_express_tracking`
WHERE `delete_time` IS NULL;
-- 显示待更新的快递单号(未签收的)
SELECT
COUNT(*) AS '待自动更新的快递单号数量'
FROM `zyt_express_tracking`
WHERE `auto_update` = 1
AND `is_signed` = 0
AND `delete_time` IS NULL;