chore(db): 合并数据库变更为单一全量脚本 schema_all_2026-10-11.sql

原 yxe-java/ 根目录散落 12 个 SQL 文件,同一张表的建表与加列分散在多处,
后续只改一处容易漏。合并为单文件,各变更的「用途/背景/影响/性质/配套代码」
头注与执行前后核对 SELECT 全部保留,末尾附执行记录。

涵盖:yxe_self_report(+activity_time/reject_reason)、yxe_visit_report、
yxe_visit_list(+visit_type/visit_date/submitter_name)、yxe_user_task.income、
sys_user.user_group、yxe_chronic_disease_product、transport_maintenance_*,
以及两项历史数据修正(chain_id 占位符、yxe_task.reward NULL)。

一并修复:原脚本在全新库按序执行会报错
  yxe_self_report.sql 已内联 activity_time/reject_reason,而
  yxe_self_report_add_* 两个裸 ALTER 又去 ADD 同名列
  → ERROR 1060 Duplicate column name
现全部加列改为 information_schema 判断后再 ADD,整文件可重复执行。
另为第 6/7 节补 SET @db(原先依赖第 2 节的变量,逐语句执行时会丢)。

验证(在独立临时库 yxe_schema_verify,未触碰 yaoxiaoer):
- 整文件连续执行两遍,均 exit=0,无 error / Duplicate,7 处正确跳过
- 产出结构与 yaoxiaoer 逐表 SHOW CREATE TABLE 比对,9 张表全部一致
- 另建库复现原缺陷,确认裸 ALTER 报 ERROR 1060

注:yxe_task.reward 的 NULL 修正(第 10 节)在本地库尚未执行,
    id=663 仍为 NULL;接口已因读侧兜底不再报错,如需数据一致请执行该节。
This commit is contained in:
2026-10-11 22:58:04 +08:00
parent eff7ba2340
commit 1c431c6899
13 changed files with 610 additions and 343 deletions
@@ -1,42 +0,0 @@
-- 用途:修正 yxe_self_report.chain_id 中残留的位置型占位符(chain_0、chain_3、chain_6 …)
-- 日期:2026-10-11
-- 背景:前端 normalizeMerchantChain 在接口未返回 chainId 时会回退成 `chain_${index}`,
-- 该值经审核端 saveMerchantEdit 写入 chain_id 落库。而按连锁筛选走的是等值匹配
-- (YxeSelfReportMapper.xml: a.chain_id = #{param.chainId}),占位符导致这些记录
-- 在按连锁筛选时被永久漏掉。本系统没有连锁表,chain 名称即事实上的连锁标识
-- (连锁字典 sys_dict_data.dict_id=175 的 dict_data_code 同样是连锁名)。
-- 影响:5 行(chain_6 -> 老百姓 3 行;chain_3 -> 百姓人家 2 行)
-- 性质:幂等,可重复执行;以 chain_name 为准回填 chain_id
-- 配套代码:MerchantServiceImpl.groupByChain 返回稳定 chainId;
-- AuditSelfReportItem.vue 兜底链改用连锁名并在写入前拦截 chain_ 前缀
-- 执行前核对(应为 5 行)
SELECT id, chain_id, chain_name
FROM yxe_self_report
WHERE chain_id REGEXP '^chain_[0-9]+$'
ORDER BY id;
-- 修正
UPDATE yxe_self_report
SET chain_id = chain_name
WHERE chain_id REGEXP '^chain_[0-9]+$'
AND chain_name IS NOT NULL
AND chain_name <> '';
-- 执行后核对(remaining_placeholder 与 mismatch 均应为 0)
SELECT SUM(chain_id REGEXP '^chain_[0-9]+$') AS remaining_placeholder,
SUM(chain_id <> chain_name) AS mismatch,
COUNT(*) AS total
FROM yxe_self_report;
-- ============================================================
-- 执行记录
-- ============================================================
-- 2026-10-11 本地开发库(127.0.0.1:3306/yaoxiaoer,root)
-- 执行结果:受影响 5 行
-- 执行后核对:remaining_placeholder = 0,mismatch = 0
-- 功能验证:按连锁筛选命中数
-- chainId=老百姓 279 -> 282(找回 id 119、130、169)
-- chainId=百姓人家 174 -> 176(找回 id 138、139)
--
-- 生产库:尚未执行。需经确认后按同一条语句复核执行。
-49
View File
@@ -1,49 +0,0 @@
-- 用途:把 yxe_task.reward 为 NULL 的历史脏数据规范化为 0,消除业绩统计接口的空指针隐患
-- 日期:2026-10-11
-- 背景:小程序 pages/performance/index 页面请求的 /yxe-user-task/userRank 与 /yxe-task/data
-- 同时返回 {"code":1,"message":"操作失败","error":"java.lang.NullPointerException"},
-- 页面「我的完成进度/完成率」与人员排行榜全部空白。
-- 根因:yxe_task.reward 为 NULL 的任务被计入完成数后执行
-- BigDecimal.ZERO.add(task.getReward())
-- → BigDecimal.add(null) 抛 NPE,整个接口失败。
-- 本库命中数据为 yxe_task.id=663(title='测试手动',status=2 已完成,
-- 其 yxe_user_task.id=630 / user_id=875 的 status=2)。注意任务状态为 2 的只有这 1 条,
-- 但它足以让「全量排行榜」接口整体失败——userRank 不传 name 时遍历全部用户。
-- 影响:1 行
-- 性质:幂等,可重复执行;只处理 status 已完成但仍为 NULL 的奖励金额
-- 配套代码:
-- 1) 读侧兜底:YxeTaskController#data、YxeUserTaskController#userRank
-- 对 reward 做 nullToZero,接口不再报错;
-- 2) 写侧堵源:YxeTaskController#save / #saveBatch 在新增时把缺失的 reward 兜底为 0,
-- 不再产生新的 NULL 脏数据。
-- 注意 #update / #updateBatch **刻意不补默认值**:二者是部分更新语义
-- (MyBatis-Plus 默认 NOT_NULL 策略),null 表示“本次不修改该字段”,
-- 若在那里兜底会把任务原有奖金静默清零,直接影响用户实得收益。
-- 3) 回归测试:src/test/java/com/gxwebsoft/yxe/controller/TaskRewardNullSafetyTest.java
-- 说明:本脚本属于「历史数据规范化」。即使不执行,接口也已不再报错(读侧兜底),
-- 但金额会按 0 计;执行后数据本身也归于一致。
-- 执行前核对:先看清 NULL 分布在哪些任务、是否已有人完成任务
SELECT t.id AS task_id,
t.title,
t.status AS task_status,
t.reward,
COUNT(ut.id) AS user_task_cnt,
SUM(ut.status = 2) AS completed_cnt
FROM yxe_task t
LEFT JOIN yxe_user_task ut ON ut.task_id = t.id
WHERE t.reward IS NULL
GROUP BY t.id, t.title, t.status, t.reward
ORDER BY t.id;
-- 变更:仅规范化「已完成/进行中」且 reward 为 NULL 的任务,避免影响尚未开始的任务
UPDATE yxe_task
SET reward = 0.00
WHERE reward IS NULL
AND status IN (1, 2);
-- 执行后核对(remaining_null 应为 0)
SELECT SUM(reward IS NULL) AS remaining_null,
SUM(reward IS NULL AND status IN (1, 2)) AS remaining_null_active,
COUNT(*) AS total
FROM yxe_task;
+610
View File
@@ -0,0 +1,610 @@
-- ============================================================================
-- yxe 库结构与数据修正 —— 全量累计脚本
-- ============================================================================
-- 用途:yxe 业务库(yaoxiaoer)的建表 / 加列 / 历史数据修正,汇总为一个可整
-- 文件重复执行的脚本,供新环境初始化与生产库复核执行。
-- 日期:2026-10-11
-- 背景:原先这些变更散落在 yxe-java/ 根目录的 12 个独立 SQL 文件中,同一张表
-- 的建表与加列分散在多处,后续维护容易只改一处;本次合并为单文件,
-- 原文件内容完整保留在本文件对应分节中。
--
-- 由以下 12 个文件合并而来(合并后原文件删除,历史可经 git log 追溯):
-- yxe_self_report.sql
-- yxe_self_report_add_activity_time.sql
-- yxe_self_report_add_reject_reason.sql
-- yxe_visit_report.sql (2026-10-11 新增)
-- yxe_visit_list_add_visit_form_fields_2026-10-11.sql(2026-10-11 新增)
-- yxe_user_task_add_income.sql
-- yxe_chronic_disease_product.sql
-- sys_user_add_user_group.sql
-- transport_maintenance_plan.sql
-- transport_maintenance_record.sql
-- fix_self_report_chain_id_placeholder_2026-10-11.sql(2026-10-11 数据修正)
-- fix_task_reward_null_npe_2026-10-11.sql (2026-10-11 数据修正)
--
-- 性质:整体幂等,可整文件重复执行。
-- 建表用 CREATE TABLE IF NOT EXISTS;加列统一走 information_schema 判断后
-- 再 ADD(原先部分 ALTER 是裸语句,重复执行或与建表语句叠加时会报
-- Duplicate column name,本次一并改为条件执行);数据修正限定条件,
-- 重复执行不改变结果。
--
-- 执行顺序:按本文件自上而下执行即可。分节顺序已考虑依赖:
-- 先建表/加列(第 1–8 节),最后做历史数据修正(第 9–10 节)。
-- 注意第 1 节的建表已内联 activity_time / reject_reason,
-- 第 2–3 节的加列会自动跳过(已存在)。
--
-- 配套代码(各变更的详细说明见对应分节):
-- yxe-java YxeSelfReport* / YxeVisitReport* / YxeVisitList* / YxeTask* /
-- YxeUserTask* / YxeChronicDiseaseProduct* 及对应 Controller
-- yxe-mp packageUser/self-report/*、pages/visit/index、pages/audit/index
-- yxe-admin src/api/yxe/*、src/views/yxe/*
-- ============================================================================
-- ############################################################################
-- 1. yxe_self_report —— 自主填报(驻店填报)建表
-- ############################################################################
-- 用途:自主填报(2026-10 起对外称「驻店填报」)主表
-- 背景:自主填报功能的原始建表语句;后续新增的 activity_time / reject_reason
-- 两列已内联到本建表语句中(见下方列定义),因此第 2–3 节的加列在
-- 新库上会走「已存在则跳过」分支。
-- 影响:新库建表 0 行;已存在的库不做任何改动。
-- 性质:幂等(CREATE TABLE IF NOT EXISTS)。
-- 配套代码:YxeSelfReport 实体与 YxeSelfReportController 全套。
-- 执行前核对(应为 0,即表不存在)
SELECT COUNT(*) AS table_exists
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_self_report';
CREATE TABLE IF NOT EXISTS `yxe_self_report` (
`id` int NOT NULL AUTO_INCREMENT,
`user_id` int DEFAULT NULL COMMENT '提交人ID',
`merchant_id` int DEFAULT NULL COMMENT '门店ID',
`merchant_name` varchar(255) DEFAULT NULL COMMENT '门店名称',
`chain_id` varchar(64) DEFAULT NULL COMMENT '连锁ID',
`chain_name` varchar(255) DEFAULT NULL COMMENT '连锁名称',
`date` varchar(32) DEFAULT NULL COMMENT '填报日期',
`activity_time` varchar(32) DEFAULT NULL COMMENT '活动时间',
`reward` decimal(10,2) DEFAULT NULL COMMENT '奖金金额',
`image` longtext COMMENT '全部图片集合',
`clock_photos` longtext COMMENT '上下班打卡图',
`booth_photos` longtext COMMENT '门头摆台照',
`sales_groups` longtext COMMENT '销量填写JSON',
`receipt_photo` longtext COMMENT '小票图',
`summary` longtext COMMENT '活动小结',
`rating` varchar(32) DEFAULT NULL COMMENT '门店评分',
`lat` varchar(64) DEFAULT NULL COMMENT '纬度',
`lng` varchar(64) DEFAULT NULL COMMENT '经度',
`location` varchar(500) DEFAULT NULL COMMENT '定位地址',
`sort_number` int DEFAULT 0 COMMENT '排序',
`comments` varchar(500) DEFAULT NULL COMMENT '备注',
`status` tinyint DEFAULT 0 COMMENT '状态:0待审核,1通过,2拒绝',
`reject_reason` varchar(500) DEFAULT NULL COMMENT '驳回原因',
`deleted` tinyint DEFAULT 0 COMMENT '逻辑删除',
`tenant_id` int DEFAULT 10325 COMMENT '租户ID',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_yxe_self_report_user_id` (`user_id`),
KEY `idx_yxe_self_report_merchant_id` (`merchant_id`),
KEY `idx_yxe_self_report_status` (`status`),
KEY `idx_yxe_self_report_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='自主填报';
-- 执行后核对(应返回 1 行,且列/注释符合预期)
SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_COMMENT, ORDINAL_POSITION
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_self_report'
ORDER BY ORDINAL_POSITION;
-- ############################################################################
-- 2. yxe_self_report —— 新增 activity_time(活动时间)
-- ############################################################################
-- 用途:自主填报新增「活动时间」
-- 背景:申报活动时间需要与填报日期(date)区分开,单独一列留存。
-- 注意:该列已内联进第 1 节的建表语句,本节的加列在新库上会跳过,
-- 保留此节是为兼容「先有旧表、后加列」的存量库。
-- 影响:ALTER 本身 0 行;存量数据该列为 NULL,不做回填。
-- 性质:幂等(information_schema 判断列是否存在后 ADD)。
-- 配套代码:YxeSelfReport.activityTime、yxe-mp create.vue 活动日期选择器。
-- 执行前核对(应为 0,即列不存在)
SELECT COUNT(*) AS col_exists
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_self_report'
AND COLUMN_NAME = 'activity_time';
SET @db := DATABASE();
SET @sql := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'yxe_self_report' AND COLUMN_NAME = 'activity_time') = 0,
'ALTER TABLE `yxe_self_report` ADD COLUMN `activity_time` varchar(32) DEFAULT NULL COMMENT ''活动时间'' AFTER `date`',
'SELECT ''yxe_self_report.activity_time already exists'' AS skipped'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- ############################################################################
-- 3. yxe_self_report —— 新增 reject_reason(驳回原因)
-- ############################################################################
-- 用途:自主填报新增「驳回原因」
-- 背景:审核端驳回后需要把原因回传给提交人,并在重新提交时展示。
-- 注意:该列已内联进第 1 节的建表语句,本节同样是为存量库兼容保留。
-- 影响:ALTER 本身 0 行;存量数据该列为 NULL。
-- 性质:幂等(information_schema 判断列是否存在后 ADD)。
-- 配套代码:YxeSelfReport.rejectReason、YxeSelfReportController#resubmit。
-- 执行前核对(应为 0,即列不存在)
SELECT COUNT(*) AS col_exists
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_self_report'
AND COLUMN_NAME = 'reject_reason';
SET @sql := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'yxe_self_report' AND COLUMN_NAME = 'reject_reason') = 0,
'ALTER TABLE `yxe_self_report` ADD COLUMN `reject_reason` varchar(500) DEFAULT NULL COMMENT ''驳回原因'' AFTER `status`',
'SELECT ''yxe_self_report.reject_reason already exists'' AS skipped'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 执行后核对(第 2–3 节合计应为 2 行)
SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_COMMENT, ORDINAL_POSITION
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_self_report'
AND COLUMN_NAME IN ('activity_time', 'reject_reason')
ORDER BY ORDINAL_POSITION;
-- ############################################################################
-- 4. yxe_visit_report —— 跑店填报建表
-- ############################################################################
-- 用途:新增 yxe_visit_report 表(跑店填报)
-- 背景:甲方要求把「自主填报」拆成「驻店填报 / 跑店填报」两种类型:
-- 1) 原自主填报页改为「驻店填报」,数据仍存 yxe_self_report,不动;
-- 2) 新增「跑店填报」,填报内容为「巡店列表(多门店,每条含门店/定位/打卡照片)
-- + 活动小结」。
-- 巡店列表是「一次填报多家门店」的数组结构,yxe_self_report 既没有多门店
-- 字段,也没有区分驻店/跑店类型的字段;本次选择新建独立表,避免污染既有
-- 历史数据与既有审核/导出逻辑。
-- 影响:新建空表,0 行业务数据;不改动 yxe_self_report 任何结构。
-- 性质:幂等(CREATE TABLE IF NOT EXISTS)。
-- 配套代码:
-- yxe-java YxeVisitReport.java / YxeVisitReportParam.java / YxeVisitReportMapper.java
-- / YxeVisitReportMapper.xml / YxeVisitReportService(+Impl)
-- / YxeVisitReportController.java
-- yxe-mp packageUser/self-report/select.vue(选择填报类型)
-- packageUser/self-report/visit.vue(跑店填报)
-- packageUser/self-report/records.vue(填报记录加类型切换)
-- pages/audit/index.vue(药审核加跑店填报类型)
-- yxe-admin src/api/yxe/yxeVisitReport/*、src/views/yxe/yxeSelfReport/*(类型筛选与跑店详情)
-- 执行前核对(应为 0,即表不存在)
SELECT COUNT(*) AS table_exists
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_visit_report';
-- 变更:建表(已存在则跳过)
CREATE TABLE IF NOT EXISTS `yxe_visit_report` (
`id` int NOT NULL AUTO_INCREMENT,
`user_id` int DEFAULT NULL COMMENT '提交人ID',
`store_count` int DEFAULT 0 COMMENT '巡店门店数',
`store_list` longtext COMMENT '巡店列表JSON(门店/定位/打卡照片)',
`image` longtext COMMENT '全部图片集合',
`summary` longtext COMMENT '活动小结',
`reward` decimal(10,2) DEFAULT NULL COMMENT '奖金金额(审核时填写)',
`lat` varchar(64) DEFAULT NULL COMMENT '纬度(整单,取首条门店)',
`lng` varchar(64) DEFAULT NULL COMMENT '经度(整单,取首条门店)',
`location` varchar(500) DEFAULT NULL COMMENT '定位地址(整单,取首条门店)',
`sort_number` int DEFAULT 0 COMMENT '排序',
`comments` varchar(500) DEFAULT NULL COMMENT '备注',
`status` tinyint DEFAULT 0 COMMENT '状态:0待审核,1通过,2拒绝',
`reject_reason` varchar(500) DEFAULT NULL COMMENT '驳回原因',
`deleted` tinyint DEFAULT 0 COMMENT '逻辑删除',
`tenant_id` int DEFAULT 10325 COMMENT '租户ID',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_yxe_visit_report_user_id` (`user_id`),
KEY `idx_yxe_visit_report_status` (`status`),
KEY `idx_yxe_visit_report_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='跑店填报';
-- 执行后核对(应返回 18 行,且列/注释符合预期)
SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_COMMENT, ORDINAL_POSITION
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_visit_report'
ORDER BY ORDINAL_POSITION;
-- ############################################################################
-- 5. yxe_visit_list —— 新增客户拜访表单字段
-- ############################################################################
-- 用途:yxe_visit_list 表新增客户拜访表单字段(拜访对象类型、拜访日期、提交人姓名)
-- 背景:小程序 pages/visit/index 按「客户拜访」新原型重构为多卡片表单:
-- 1) 新增「拜访对象 - 类型」(地点 / 门店经理 / 其他);
-- 2) 新增「拜访信息 - 拜访日期」,默认当天;
-- 3) 新增「我的信息 - 姓名」,进页面自动带出账号 real_name,仍允许修改,
-- 因此与 sys_user.real_name 可能不一致,需要独立字段留痕。
-- 三项均为本次新增,历史记录该字段为空(前端展示为 "-")。
-- 影响:ALTER 语句本身 0 行;已有历史数据新增列为 NULL,不做回填。
-- 性质:幂等(通过 information_schema 判断列是否存在后再 ADD)。
-- 配套代码:
-- yxe-java YxeVisitList.java / YxeVisitListParam.java / YxeVisitListMapper.xml
-- / YxeVisitListController.java(导出表头)
-- yxe-mp pages/visit/index.vue
-- yxe-admin src/api/yxe/yxeVisitList/model、列表列、详情、编辑弹窗
-- 备注:本列注释在源码中已由「门店/门店经理/其他」改为「地点/门店经理/其他」。
-- 对**已存在该列**的库(列已建、注释仍是旧值),本节按幂等设计跳过,
-- 不会修正注释;如需同步注释,另行执行:
-- ALTER TABLE `yxe_visit_list` MODIFY COLUMN `visit_type` varchar(16)
-- DEFAULT NULL COMMENT '拜访对象类型: 地点/门店经理/其他';
-- 新库建列时直接用下面语句,注释即为新值。
-- 执行前核对(应为 0 行,即三列均不存在)
SELECT COLUMN_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_visit_list'
AND COLUMN_NAME IN ('visit_type', 'visit_date', 'submitter_name');
-- 变更:按列分别判断,已存在则跳过
SET @db := DATABASE();
SET @sql := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'yxe_visit_list' AND COLUMN_NAME = 'visit_type') = 0,
'ALTER TABLE `yxe_visit_list` ADD COLUMN `visit_type` varchar(16) DEFAULT NULL COMMENT ''拜访对象类型: 地点/门店经理/其他'' AFTER `name`',
'SELECT ''visit_type already exists'' AS skipped'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'yxe_visit_list' AND COLUMN_NAME = 'visit_date') = 0,
'ALTER TABLE `yxe_visit_list` ADD COLUMN `visit_date` varchar(32) DEFAULT NULL COMMENT ''拜访日期'' AFTER `visit_type`',
'SELECT ''visit_date already exists'' AS skipped'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'yxe_visit_list' AND COLUMN_NAME = 'submitter_name') = 0,
'ALTER TABLE `yxe_visit_list` ADD COLUMN `submitter_name` varchar(64) DEFAULT NULL COMMENT ''提交人姓名(拜访人自填)'' AFTER `visit_date`',
'SELECT ''submitter_name already exists'' AS skipped'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 执行后核对(应为 3 行,且类型/注释符合预期)
SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_COMMENT, ORDINAL_POSITION
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_visit_list'
AND COLUMN_NAME IN ('visit_type', 'visit_date', 'submitter_name')
ORDER BY ORDINAL_POSITION;
-- ############################################################################
-- 6. yxe_user_task —— 新增 income(任务收入)
-- ############################################################################
-- 用途:用户任务新增「任务收入」
-- 背景:任务完成后的收入需要单独留存,便于业绩统计与提成核算。
-- 影响:ALTER 本身 0 行;存量数据该列为 NULL,不做回填。
-- 性质:幂等(information_schema 判断列是否存在后 ADD)。
-- 配套代码:YxeUserTask.income、yxe-mp pages/bonus/index。
-- 执行前核对(应为 0,即列不存在)
SELECT COUNT(*) AS col_exists
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_user_task'
AND COLUMN_NAME = 'income';
SET @db := DATABASE();
SET @sql := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'yxe_user_task' AND COLUMN_NAME = 'income') = 0,
'ALTER TABLE `yxe_user_task` ADD COLUMN `income` decimal(10, 2) NULL DEFAULT NULL COMMENT ''任务收入'' AFTER `chain`',
'SELECT ''yxe_user_task.income already exists'' AS skipped'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 执行后核对(应为 1 行)
SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_COMMENT, ORDINAL_POSITION
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_user_task'
AND COLUMN_NAME = 'income';
-- ############################################################################
-- 7. sys_user —— 新增 user_group(用户分组)
-- ############################################################################
-- 用途:系统用户新增「用户分组」
-- 背景:审核与导出需要按用户分组筛选(yxe_self_report / yxe_visit_report 的
-- userGroup 查询条件即走本列)。
-- 影响:ALTER 本身 0 行;存量用户该列为 NULL。
-- 性质:幂等(information_schema 判断列是否存在后 ADD)。
-- 配套代码:YxeSelfReportMapper.xml / YxeVisitReportMapper.xml 的 userGroup 条件、
-- yxe-admin 自主填报列表「用户分组」筛选项。
-- 执行前核对(应为 0,即列不存在)
SELECT COUNT(*) AS col_exists
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'sys_user'
AND COLUMN_NAME = 'user_group';
SET @db := DATABASE();
SET @sql := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'sys_user' AND COLUMN_NAME = 'user_group') = 0,
'ALTER TABLE sys_user ADD COLUMN user_group VARCHAR(50) NULL COMMENT ''用户分组'' AFTER user_level',
'SELECT ''sys_user.user_group already exists'' AS skipped'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 执行后核对(应为 1 行)
SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_COMMENT, ORDINAL_POSITION
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'sys_user'
AND COLUMN_NAME = 'user_group';
-- ############################################################################
-- 8. 其余建表:慢病产品 / 运输保养 / 运输维修
-- ############################################################################
-- === 8.1 yxe_chronic_disease_product —— 慢病产品管理 =========================
-- 用途:慢病产品基础资料(连锁 / 产品名 / 规格粒数 / 每日用量 / 每盒天数等)
-- 影响:新库建表 0 行。
-- 性质:幂等(CREATE TABLE IF NOT EXISTS)。
CREATE TABLE IF NOT EXISTS `yxe_chronic_disease_product` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`chain` varchar(100) NOT NULL COMMENT '连锁',
`product_name` varchar(100) NOT NULL COMMENT '产品名',
`spec_count` decimal(10,2) NOT NULL COMMENT '规格粒/片',
`daily_usage_count` decimal(10,2) NOT NULL COMMENT '说明书每天使用/次',
`dosage_per_time` decimal(10,2) NOT NULL COMMENT '每次几粒/片',
`box_usage_days` decimal(10,2) DEFAULT NULL COMMENT '1盒服用几天',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态, 0禁用, 1启用',
`deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除, 0否, 1是',
`tenant_id` int DEFAULT NULL COMMENT '租户id',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
KEY `idx_ycdp_product_name` (`product_name`),
KEY `idx_ycdp_chain` (`chain`),
KEY `idx_ycdp_deleted` (`deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='慢病产品管理';
-- === 8.2 transport_maintenance_plan —— 保养记录 ============================
-- 用途:车辆/船舶保养记录
-- 影响:新库建表 0 行。
-- 性质:幂等(CREATE TABLE IF NOT EXISTS)。
CREATE TABLE IF NOT EXISTS `transport_maintenance_plan` (
`maintenance_plan_id` int NOT NULL AUTO_INCREMENT COMMENT '保养记录ID',
`vehicle_type` varchar(10) NOT NULL COMMENT '车船类型: 车辆, 船舶',
`vehicle_no` varchar(30) NOT NULL COMMENT '车牌号/船号',
`maintainer` varchar(20) DEFAULT NULL COMMENT '保养人',
`maintenance_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '保养时间',
`mileage` decimal(12,2) DEFAULT NULL COMMENT '里程/航程数',
`mileage_unit` varchar(10) DEFAULT NULL COMMENT '里程/航程单位: 公里, 海里',
`maintenance_item` varchar(100) DEFAULT NULL COMMENT '保养项目',
`cost` decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT '费用',
`store_name` varchar(50) DEFAULT NULL COMMENT '店名',
`contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`address` varchar(100) DEFAULT NULL COMMENT '地址',
`next_maintenance_time` datetime DEFAULT NULL COMMENT '下次保养时间',
`next_maintenance_mileage` decimal(12,2) DEFAULT NULL COMMENT '下次保养里程/航程',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`attachments` longtext COMMENT '附件, JSON或逗号分隔文件地址',
`sort_number` int NOT NULL DEFAULT 0 COMMENT '排序(数字越小越靠前)',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态, 0正常, 1禁用',
`deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除, 0否, 1是',
`user_id` int DEFAULT NULL COMMENT '创建人ID',
`organization_id` int DEFAULT NULL COMMENT '组织ID',
`tenant_id` int DEFAULT 10325 COMMENT '租户ID',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`maintenance_plan_id`),
KEY `idx_tmp_vehicle_type` (`vehicle_type`),
KEY `idx_tmp_vehicle_no` (`vehicle_no`),
KEY `idx_tmp_maintenance_time` (`maintenance_time`),
KEY `idx_tmp_next_maintenance_time` (`next_maintenance_time`),
KEY `idx_tmp_organization_id` (`organization_id`),
KEY `idx_tmp_tenant_id` (`tenant_id`),
KEY `idx_tmp_deleted` (`deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='保养记录';
-- === 8.3 transport_maintenance_record —— 维修记录 ==========================
-- 用途:车辆/船舶维修记录
-- 影响:新库建表 0 行。
-- 性质:幂等(CREATE TABLE IF NOT EXISTS)。
CREATE TABLE IF NOT EXISTS `transport_maintenance_record` (
`maintenance_record_id` int NOT NULL AUTO_INCREMENT COMMENT '维修记录ID',
`vehicle_type` varchar(10) NOT NULL COMMENT '车船类型: 车辆, 船舶',
`vehicle_no` varchar(30) NOT NULL COMMENT '车牌号/船号',
`maintainer` varchar(20) DEFAULT NULL COMMENT '维修人',
`maintenance_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '维修时间',
`location` varchar(100) DEFAULT NULL COMMENT '维修位置',
`replaced_part` varchar(200) DEFAULT NULL COMMENT '更换零件',
`cost` decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT '费用',
`company` varchar(50) DEFAULT NULL COMMENT '维修单位',
`contact` varchar(20) DEFAULT NULL COMMENT '联系方式',
`address` varchar(100) DEFAULT NULL COMMENT '地址',
`factory_time` datetime DEFAULT NULL COMMENT '出厂时间',
`mileage` decimal(12,2) DEFAULT NULL COMMENT '里程/航程数',
`mileage_unit` varchar(10) DEFAULT NULL COMMENT '里程/航程单位: 公里, 海里',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`attachments` longtext COMMENT '附件, JSON或逗号分隔文件地址',
`sort_number` int NOT NULL DEFAULT 0 COMMENT '排序(数字越小越靠前)',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态, 0正常, 1禁用',
`deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除, 0否, 1是',
`user_id` int DEFAULT NULL COMMENT '创建人ID',
`organization_id` int DEFAULT NULL COMMENT '组织ID',
`tenant_id` int DEFAULT 10325 COMMENT '租户ID',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`maintenance_record_id`),
KEY `idx_tmr_vehicle_type` (`vehicle_type`),
KEY `idx_tmr_vehicle_no` (`vehicle_no`),
KEY `idx_tmr_maintenance_time` (`maintenance_time`),
KEY `idx_tmr_factory_time` (`factory_time`),
KEY `idx_tmr_organization_id` (`organization_id`),
KEY `idx_tmr_tenant_id` (`tenant_id`),
KEY `idx_tmr_deleted` (`deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='维修记录';
-- 执行后核对(三张表应各返回 1 行)
SELECT TABLE_NAME, TABLE_COMMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME IN ('yxe_chronic_disease_product',
'transport_maintenance_plan',
'transport_maintenance_record')
ORDER BY TABLE_NAME;
-- ############################################################################
-- 9. 数据修正:yxe_self_report.chain_id 残留位置型占位符
-- ############################################################################
-- 用途:修正 yxe_self_report.chain_id 中残留的位置型占位符(chain_0、chain_3、chain_6 …)
-- 背景:前端 normalizeMerchantChain 在接口未返回 chainId 时会回退成 `chain_${index}`,
-- 该值经审核端 saveMerchantEdit 写入 chain_id 落库。而按连锁筛选走的是等值匹配
-- (YxeSelfReportMapper.xml: a.chain_id = #{param.chainId}),占位符导致这些记录
-- 在按连锁筛选时被永久漏掉。本系统没有连锁表,chain 名称即事实上的连锁标识
-- (连锁字典 sys_dict_data.dict_id=175 的 dict_data_code 同样是连锁名)。
-- 影响:本次实际 5 行(chain_6 -> 老百姓 3 行;chain_3 -> 百姓人家 2 行)。
-- 可重复执行:修正后不再匹配 WHERE 条件,无副作用。
-- 性质:幂等(以 chain_name 为准回填 chain_id,限定 REGEXP 占位符)。
-- 配套代码:MerchantServiceImpl.groupByChain 返回稳定 chainId;
-- AuditSelfReportItem.vue 兜底链改用连锁名并在写入前拦截 chain_ 前缀。
-- 执行前核对(本地库曾为 5 行;执行后应为 0 行)
SELECT id, chain_id, chain_name
FROM yxe_self_report
WHERE chain_id REGEXP '^chain_[0-9]+$'
ORDER BY id;
-- 修正
UPDATE yxe_self_report
SET chain_id = chain_name
WHERE chain_id REGEXP '^chain_[0-9]+$'
AND chain_name IS NOT NULL
AND chain_name <> '';
-- 执行后核对(remaining_placeholder 与 mismatch 均应为 0)
SELECT SUM(chain_id REGEXP '^chain_[0-9]+$') AS remaining_placeholder,
SUM(chain_id <> chain_name) AS mismatch,
COUNT(*) AS total
FROM yxe_self_report;
-- ############################################################################
-- 10. 数据修正:yxe_task.reward 为 NULL 的历史脏数据
-- ############################################################################
-- 用途:把 yxe_task.reward 为 NULL 的历史脏数据规范化为 0,消除业绩统计接口的空指针隐患
-- 背景:小程序 pages/performance/index 页面请求的 /yxe-user-task/userRank 与 /yxe-task/data
-- 同时返回 {"code":1,"message":"操作失败","error":"java.lang.NullPointerException"},
-- 页面「我的完成进度/完成率」与人员排行榜全部空白。
-- 根因:yxe_task.reward 为 NULL 的任务被计入完成数后执行
-- BigDecimal.ZERO.add(task.getReward())
-- → BigDecimal.add(null) 抛 NPE,整个接口失败。
-- 本库命中数据为 yxe_task.id=663(title='测试手动',status=2 已完成,
-- 其 yxe_user_task.id=630 / user_id=875 的 status=2)。注意任务状态为 2 的只有这 1 条,
-- 但它足以让「全量排行榜」接口整体失败——userRank 不传 name 时遍历全部用户。
-- 影响:1 行。
-- 性质:幂等(重复执行时 WHERE 不再命中)。
-- 配套代码:
-- 1) 读侧兜底:YxeTaskController#data、YxeUserTaskController#userRank
-- 对 reward 做 nullToZero,接口不再报错;
-- 2) 写侧堵源:YxeTaskController#save / #saveBatch 在新增时把缺失的 reward 兜底为 0,
-- 不再产生新的 NULL 脏数据。
-- 注意 #update / #updateBatch **刻意不补默认值**:二者是部分更新语义
-- (MyBatis-Plus 默认 NOT_NULL 策略),null 表示“本次不修改该字段”,
-- 若在那里兜底会把任务原有奖金静默清零,直接影响用户实得收益。
-- 3) 回归测试:src/test/java/com/gxwebsoft/yxe/controller/TaskRewardNullSafetyTest.java
-- 说明:本脚本属于「历史数据规范化」。即使不执行,接口也已不再报错(读侧兜底),
-- 但金额会按 0 计;执行后数据本身也归于一致。
-- 执行前核对:先看清 NULL 分布在哪些任务、是否已有人完成任务
SELECT t.id AS task_id,
t.title,
t.status AS task_status,
t.reward,
COUNT(ut.id) AS user_task_cnt,
SUM(ut.status = 2) AS completed_cnt
FROM yxe_task t
LEFT JOIN yxe_user_task ut ON ut.task_id = t.id
WHERE t.reward IS NULL
GROUP BY t.id, t.title, t.status, t.reward
ORDER BY t.id;
-- 变更:仅规范化「已完成/进行中」且 reward 为 NULL 的任务,避免影响尚未开始的任务
UPDATE yxe_task
SET reward = 0.00
WHERE reward IS NULL
AND status IN (1, 2);
-- 执行后核对(remaining_null 应为 0)
SELECT SUM(reward IS NULL) AS remaining_null,
SUM(reward IS NULL AND status IN (1, 2)) AS remaining_null_active,
COUNT(*) AS total
FROM yxe_task;
-- ============================================================================
-- 执行记录
-- ============================================================================
-- 2026-10-11 本地开发库(127.0.0.1:3306/yaoxiaoer,root)
-- 第 1 节 yxe_self_report 建表 —— 表已存在,跳过
-- 第 2 节 activity_time —— 列已存在,跳过
-- 第 3 节 reject_reason —— 列已存在,跳过
-- 第 4 节 yxe_visit_report 建表 —— 已执行(18 列,0 行业务数据)
-- 第 5 节 yxe_visit_list 三列 —— 三列均已存在(visit_type/visit_date/submitter_name)
-- 第 6 节 yxe_user_task.income —— 列已存在,跳过
-- 第 7 节 sys_user.user_group —— 列已存在,跳过
-- 第 8 节 三张建表 —— 三表均已存在,跳过
-- 第 9 节 chain_id 占位符修正 —— 已执行:受影响 5 行;
-- 执行后 remaining_placeholder = 0,mismatch = 0
-- 功能验证:按连锁筛选命中数
-- chainId=老百姓 279 -> 282(找回 id 119、130、169)
-- chainId=百姓人家 174 -> 176(找回 id 138、139)
-- 第 10 节 yxe_task.reward 规范化 —— **尚未执行**:本地库仍有
-- yxe_task.id=663(title='测试手动',status=2)reward 为 NULL。
-- 接口已因读侧兜底不再报错,但金额按 0 计;如需数据一致请执行本节。
--
-- 生产库:尚未执行。需经确认后按本文件自上而下复核执行。
--
-- 备注(第 5 节):yxe_visit_list.visit_type 列的注释在本地库仍是旧值
-- 「拜访对象类型: 门店/门店经理/其他」,与源码中的新值「地点/...」不一致。
-- 因该列已存在,第 5 节按幂等设计跳过,不会修正注释;如需同步,见第 5 节备注。
-- ============================================================================
-2
View File
@@ -1,2 +0,0 @@
ALTER TABLE sys_user
ADD COLUMN user_group VARCHAR(50) NULL COMMENT '用户分组' AFTER user_level;
-34
View File
@@ -1,34 +0,0 @@
CREATE TABLE IF NOT EXISTS `transport_maintenance_plan` (
`maintenance_plan_id` int NOT NULL AUTO_INCREMENT COMMENT '保养记录ID',
`vehicle_type` varchar(10) NOT NULL COMMENT '车船类型: 车辆, 船舶',
`vehicle_no` varchar(30) NOT NULL COMMENT '车牌号/船号',
`maintainer` varchar(20) DEFAULT NULL COMMENT '保养人',
`maintenance_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '保养时间',
`mileage` decimal(12,2) DEFAULT NULL COMMENT '里程/航程数',
`mileage_unit` varchar(10) DEFAULT NULL COMMENT '里程/航程单位: 公里, 海里',
`maintenance_item` varchar(100) DEFAULT NULL COMMENT '保养项目',
`cost` decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT '费用',
`store_name` varchar(50) DEFAULT NULL COMMENT '店名',
`contact_phone` varchar(20) DEFAULT NULL COMMENT '联系电话',
`address` varchar(100) DEFAULT NULL COMMENT '地址',
`next_maintenance_time` datetime DEFAULT NULL COMMENT '下次保养时间',
`next_maintenance_mileage` decimal(12,2) DEFAULT NULL COMMENT '下次保养里程/航程',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`attachments` longtext COMMENT '附件, JSON或逗号分隔文件地址',
`sort_number` int NOT NULL DEFAULT 0 COMMENT '排序(数字越小越靠前)',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态, 0正常, 1禁用',
`deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除, 0否, 1是',
`user_id` int DEFAULT NULL COMMENT '创建人ID',
`organization_id` int DEFAULT NULL COMMENT '组织ID',
`tenant_id` int DEFAULT 10325 COMMENT '租户ID',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`maintenance_plan_id`),
KEY `idx_tmp_vehicle_type` (`vehicle_type`),
KEY `idx_tmp_vehicle_no` (`vehicle_no`),
KEY `idx_tmp_maintenance_time` (`maintenance_time`),
KEY `idx_tmp_next_maintenance_time` (`next_maintenance_time`),
KEY `idx_tmp_organization_id` (`organization_id`),
KEY `idx_tmp_tenant_id` (`tenant_id`),
KEY `idx_tmp_deleted` (`deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='保养记录';
-34
View File
@@ -1,34 +0,0 @@
CREATE TABLE IF NOT EXISTS `transport_maintenance_record` (
`maintenance_record_id` int NOT NULL AUTO_INCREMENT COMMENT '维修记录ID',
`vehicle_type` varchar(10) NOT NULL COMMENT '车船类型: 车辆, 船舶',
`vehicle_no` varchar(30) NOT NULL COMMENT '车牌号/船号',
`maintainer` varchar(20) DEFAULT NULL COMMENT '维修人',
`maintenance_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '维修时间',
`location` varchar(100) DEFAULT NULL COMMENT '维修位置',
`replaced_part` varchar(200) DEFAULT NULL COMMENT '更换零件',
`cost` decimal(12,2) NOT NULL DEFAULT 0.00 COMMENT '费用',
`company` varchar(50) DEFAULT NULL COMMENT '维修单位',
`contact` varchar(20) DEFAULT NULL COMMENT '联系方式',
`address` varchar(100) DEFAULT NULL COMMENT '地址',
`factory_time` datetime DEFAULT NULL COMMENT '出厂时间',
`mileage` decimal(12,2) DEFAULT NULL COMMENT '里程/航程数',
`mileage_unit` varchar(10) DEFAULT NULL COMMENT '里程/航程单位: 公里, 海里',
`remark` varchar(500) DEFAULT NULL COMMENT '备注',
`attachments` longtext COMMENT '附件, JSON或逗号分隔文件地址',
`sort_number` int NOT NULL DEFAULT 0 COMMENT '排序(数字越小越靠前)',
`status` tinyint NOT NULL DEFAULT 0 COMMENT '状态, 0正常, 1禁用',
`deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除, 0否, 1是',
`user_id` int DEFAULT NULL COMMENT '创建人ID',
`organization_id` int DEFAULT NULL COMMENT '组织ID',
`tenant_id` int DEFAULT 10325 COMMENT '租户ID',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`maintenance_record_id`),
KEY `idx_tmr_vehicle_type` (`vehicle_type`),
KEY `idx_tmr_vehicle_no` (`vehicle_no`),
KEY `idx_tmr_maintenance_time` (`maintenance_time`),
KEY `idx_tmr_factory_time` (`factory_time`),
KEY `idx_tmr_organization_id` (`organization_id`),
KEY `idx_tmr_tenant_id` (`tenant_id`),
KEY `idx_tmr_deleted` (`deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='维修记录';
-18
View File
@@ -1,18 +0,0 @@
CREATE TABLE IF NOT EXISTS `yxe_chronic_disease_product` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`chain` varchar(100) NOT NULL COMMENT '连锁',
`product_name` varchar(100) NOT NULL COMMENT '产品名',
`spec_count` decimal(10,2) NOT NULL COMMENT '规格粒/片',
`daily_usage_count` decimal(10,2) NOT NULL COMMENT '说明书每天使用/次',
`dosage_per_time` decimal(10,2) NOT NULL COMMENT '每次几粒/片',
`box_usage_days` decimal(10,2) DEFAULT NULL COMMENT '1盒服用几天',
`status` tinyint NOT NULL DEFAULT 1 COMMENT '状态, 0禁用, 1启用',
`deleted` tinyint NOT NULL DEFAULT 0 COMMENT '是否删除, 0否, 1是',
`tenant_id` int DEFAULT NULL COMMENT '租户id',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`id`),
KEY `idx_ycdp_product_name` (`product_name`),
KEY `idx_ycdp_chain` (`chain`),
KEY `idx_ycdp_deleted` (`deleted`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='慢病产品管理';
-34
View File
@@ -1,34 +0,0 @@
CREATE TABLE IF NOT EXISTS `yxe_self_report` (
`id` int NOT NULL AUTO_INCREMENT,
`user_id` int DEFAULT NULL COMMENT '提交人ID',
`merchant_id` int DEFAULT NULL COMMENT '门店ID',
`merchant_name` varchar(255) DEFAULT NULL COMMENT '门店名称',
`chain_id` varchar(64) DEFAULT NULL COMMENT '连锁ID',
`chain_name` varchar(255) DEFAULT NULL COMMENT '连锁名称',
`date` varchar(32) DEFAULT NULL COMMENT '填报日期',
`activity_time` varchar(32) DEFAULT NULL COMMENT '活动时间',
`reward` decimal(10,2) DEFAULT NULL COMMENT '奖金金额',
`image` longtext COMMENT '全部图片集合',
`clock_photos` longtext COMMENT '上下班打卡图',
`booth_photos` longtext COMMENT '门头摆台照',
`sales_groups` longtext COMMENT '销量填写JSON',
`receipt_photo` longtext COMMENT '小票图',
`summary` longtext COMMENT '活动小结',
`rating` varchar(32) DEFAULT NULL COMMENT '门店评分',
`lat` varchar(64) DEFAULT NULL COMMENT '纬度',
`lng` varchar(64) DEFAULT NULL COMMENT '经度',
`location` varchar(500) DEFAULT NULL COMMENT '定位地址',
`sort_number` int DEFAULT 0 COMMENT '排序',
`comments` varchar(500) DEFAULT NULL COMMENT '备注',
`status` tinyint DEFAULT 0 COMMENT '状态:0待审核,1通过,2拒绝',
`reject_reason` varchar(500) DEFAULT NULL COMMENT '驳回原因',
`deleted` tinyint DEFAULT 0 COMMENT '逻辑删除',
`tenant_id` int DEFAULT 10325 COMMENT '租户ID',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_yxe_self_report_user_id` (`user_id`),
KEY `idx_yxe_self_report_merchant_id` (`merchant_id`),
KEY `idx_yxe_self_report_status` (`status`),
KEY `idx_yxe_self_report_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='自主填报';
-2
View File
@@ -1,2 +0,0 @@
ALTER TABLE `yxe_self_report`
ADD COLUMN `activity_time` varchar(32) DEFAULT NULL COMMENT '活动时间' AFTER `date`;
-2
View File
@@ -1,2 +0,0 @@
ALTER TABLE `yxe_self_report`
ADD COLUMN `reject_reason` varchar(500) DEFAULT NULL COMMENT '驳回原因' AFTER `status`;
-2
View File
@@ -1,2 +0,0 @@
ALTER TABLE `yxe_user_task`
ADD COLUMN `income` decimal(10, 2) NULL DEFAULT NULL COMMENT '任务收入' AFTER `chain`;
@@ -1,63 +0,0 @@
-- 用途:yxe_visit_list 表新增客户拜访表单字段(拜访对象类型、拜访日期、提交人姓名)
-- 日期:2026-10-11
-- 背景:小程序 pages/visit/index 按「客户拜访」新原型重构为多卡片表单:
-- 1) 新增「拜访对象 - 类型」(地点 / 门店经理 / 其他);
-- 2) 新增「拜访信息 - 拜访日期」,默认当天;
-- 3) 新增「我的信息 - 姓名」,进页面自动带出账号 real_name,仍允许修改,
-- 因此与 sys_user.real_name 可能不一致,需要独立字段留痕。
-- 三项均为本次新增,历史记录该字段为空(前端展示为 "-")。
-- 影响:ALTER 语句本身 0 行;已有历史数据新增列为 NULL,不做回填。
-- 性质:幂等,可重复执行(通过 information_schema 判断列是否存在后再 ADD)
-- 配套代码:
-- yxe-java YxeVisitList.java / YxeVisitListParam.java / YxeVisitListMapper.xml
-- / YxeVisitListController.java(导出表头)
-- yxe-mp pages/visit/index.vue
-- yxe-admin src/api/yxe/yxeVisitList/model、列表列、详情、编辑弹窗
-- 执行前核对(应为 0 行,即三列均不存在)
SELECT COLUMN_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_visit_list'
AND COLUMN_NAME IN ('visit_type', 'visit_date', 'submitter_name');
-- 变更:按列分别判断,已存在则跳过
SET @db := DATABASE();
SET @sql := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'yxe_visit_list' AND COLUMN_NAME = 'visit_type') = 0,
'ALTER TABLE `yxe_visit_list` ADD COLUMN `visit_type` varchar(16) DEFAULT NULL COMMENT ''拜访对象类型: 地点/门店经理/其他'' AFTER `name`',
'SELECT ''visit_type already exists'' AS skipped'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'yxe_visit_list' AND COLUMN_NAME = 'visit_date') = 0,
'ALTER TABLE `yxe_visit_list` ADD COLUMN `visit_date` varchar(32) DEFAULT NULL COMMENT ''拜访日期'' AFTER `visit_type`',
'SELECT ''visit_date already exists'' AS skipped'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @sql := IF(
(SELECT COUNT(*) FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = @db AND TABLE_NAME = 'yxe_visit_list' AND COLUMN_NAME = 'submitter_name') = 0,
'ALTER TABLE `yxe_visit_list` ADD COLUMN `submitter_name` varchar(64) DEFAULT NULL COMMENT ''提交人姓名(拜访人自填)'' AFTER `visit_date`',
'SELECT ''submitter_name already exists'' AS skipped'
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
-- 执行后核对(应为 3 行,且类型/注释符合预期)
SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_COMMENT, ORDINAL_POSITION
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_visit_list'
AND COLUMN_NAME IN ('visit_type', 'visit_date', 'submitter_name')
ORDER BY ORDINAL_POSITION;
-61
View File
@@ -1,61 +0,0 @@
-- 用途:新增 yxe_visit_report 表(跑店填报)
-- 日期:2026-10-11
-- 背景:甲方要求把「自主填报」拆成「驻店填报 / 跑店填报」两种类型:
-- 1) 原自主填报页改为「驻店填报」,数据仍存 yxe_self_report,不动;
-- 2) 新增「跑店填报」,填报内容为「巡店列表(多门店,每条含门店/定位/打卡照片)+ 活动小结」。
-- 巡店列表是「一次填报多家门店」的数组结构,yxe_self_report 既没有多门店字段,
-- 也没有区分驻店/跑店类型的字段;本次选择新建独立表,避免污染既有 928 条历史数据
-- 与既有审核/导出逻辑。
-- 影响:新建空表,0 行业务数据;不改动 yxe_self_report 任何结构。
-- 性质:幂等,可重复执行(CREATE TABLE IF NOT EXISTS)。
-- 配套代码:
-- yxe-java YxeVisitReport.java / YxeVisitReportParam.java / YxeVisitReportMapper.java
-- / YxeVisitReportMapper.xml / YxeVisitReportService(+Impl)
-- / YxeVisitReportController.java
-- yxe-mp packageUser/self-report/select.vue(选择填报类型)
-- packageUser/self-report/visit.vue(跑店填报)
-- packageUser/self-report/records.vue(填报记录加类型切换)
-- pages/audit/index.vue(药审核加跑店填报类型)
-- yxe-admin src/api/yxe/yxeVisitReport/*、src/views/yxe/yxeSelfReport/*(类型筛选与跑店详情)
-- 执行前核对(应为 0,即表不存在)
SELECT COUNT(*) AS table_exists
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_visit_report';
-- 变更:建表(已存在则跳过)
CREATE TABLE IF NOT EXISTS `yxe_visit_report` (
`id` int NOT NULL AUTO_INCREMENT,
`user_id` int DEFAULT NULL COMMENT '提交人ID',
`store_count` int DEFAULT 0 COMMENT '巡店门店数',
`store_list` longtext COMMENT '巡店列表JSON(门店/定位/打卡照片)',
`image` longtext COMMENT '全部图片集合',
`summary` longtext COMMENT '活动小结',
`reward` decimal(10,2) DEFAULT NULL COMMENT '奖金金额(审核时填写)',
`lat` varchar(64) DEFAULT NULL COMMENT '纬度(整单,取首条门店)',
`lng` varchar(64) DEFAULT NULL COMMENT '经度(整单,取首条门店)',
`location` varchar(500) DEFAULT NULL COMMENT '定位地址(整单,取首条门店)',
`sort_number` int DEFAULT 0 COMMENT '排序',
`comments` varchar(500) DEFAULT NULL COMMENT '备注',
`status` tinyint DEFAULT 0 COMMENT '状态:0待审核,1通过,2拒绝',
`reject_reason` varchar(500) DEFAULT NULL COMMENT '驳回原因',
`deleted` tinyint DEFAULT 0 COMMENT '逻辑删除',
`tenant_id` int DEFAULT 10325 COMMENT '租户ID',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_yxe_visit_report_user_id` (`user_id`),
KEY `idx_yxe_visit_report_status` (`status`),
KEY `idx_yxe_visit_report_create_time` (`create_time`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='跑店填报';
-- 执行后核对(应返回 1 行,且列/注释符合预期)
SELECT COLUMN_NAME, COLUMN_TYPE, IS_NULLABLE, COLUMN_COMMENT, ORDINAL_POSITION
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'yxe_visit_report'
ORDER BY ORDINAL_POSITION;
-- 执行后核对(应为 0,跑店填报为新建功能,无历史数据)
SELECT COUNT(*) AS row_count FROM `yxe_visit_report`;