diff --git a/sql/guardian_fields.sql b/sql/guardian_fields.sql new file mode 100644 index 0000000..4f60320 --- /dev/null +++ b/sql/guardian_fields.sql @@ -0,0 +1,5 @@ +-- 患者表增加监护人信息字段 +ALTER TABLE `patient` + ADD COLUMN `guardian_name` varchar(50) NOT NULL DEFAULT '' COMMENT '监护人姓名' AFTER `sign_privacy_jhr`, + ADD COLUMN `guardian_id_card` varchar(18) NOT NULL DEFAULT '' COMMENT '监护人身份证号' AFTER `guardian_name`, + ADD COLUMN `guardian_relation` varchar(20) NOT NULL DEFAULT '' COMMENT '与患者关系' AFTER `guardian_id_card`; diff --git a/src/controller/admin/patient.js b/src/controller/admin/patient.js index 0d96aca..5b15aa5 100644 --- a/src/controller/admin/patient.js +++ b/src/controller/admin/patient.js @@ -1,4 +1,5 @@ const Base = require('../base.js'); +const dayjs = require('dayjs'); module.exports = class extends Base { // 患者列表页面 @@ -122,7 +123,7 @@ module.exports = class extends Base { // 新增患者 async addAction() { const data = this.post(); - const { name, phone, id_card, gender, birth_date, province_code, city_code, district_code, address, emergency_contact, emergency_phone, tag, documents, sign_income, sign_privacy, sign_promise } = data; + const { name, phone, id_card, gender, birth_date, province_code, city_code, district_code, address, emergency_contact, emergency_phone, tag, documents, sign_income, sign_privacy, sign_promise, sign_privacy_jhr, income_amount, guardian_name, guardian_id_card, guardian_relation } = data; if (!name || !phone || !id_card || !gender || !birth_date) { return this.fail('请填写完整信息'); @@ -165,14 +166,19 @@ module.exports = class extends Base { sign_income: sign_income || '', sign_privacy: sign_privacy || '', sign_promise: sign_promise || '', - status: 0, + sign_privacy_jhr: sign_privacy_jhr || '', + income_amount: income_amount || '', + guardian_name: guardian_name || '', + guardian_id_card: guardian_id_card || '', + guardian_relation: guardian_relation || '', + status: 1, create_by: this.adminUser?.id || 0 }); - // 记录审核日志 + // 记录审核日志(后台新增直接审核通过) await this.model('patient_audit').add({ patient_id: id, - action: 'submit', + action: 'approve', operator_id: this.adminUser?.id || 0, operator_name: this.adminUser?.nickname || this.adminUser?.username || '' }); @@ -272,7 +278,7 @@ module.exports = class extends Base { // 编辑患者 async editAction() { const data = this.post(); - const { id, name, phone, id_card, gender, birth_date, province_code, city_code, district_code, address, emergency_contact, emergency_phone, tag, documents, sign_income, sign_privacy, sign_promise } = data; + const { id, name, phone, id_card, gender, birth_date, province_code, city_code, district_code, address, emergency_contact, emergency_phone, tag, documents, sign_income, sign_privacy, sign_promise, sign_privacy_jhr, income_amount, guardian_name, guardian_id_card, guardian_relation } = data; if (!id) return this.fail('参数错误'); if (!name || !phone || !id_card || !gender || !birth_date) return this.fail('请填写完整信息'); @@ -295,6 +301,11 @@ module.exports = class extends Base { sign_income: sign_income || '', sign_privacy: sign_privacy || '', sign_promise: sign_promise || '', + sign_privacy_jhr: sign_privacy_jhr || '', + income_amount: income_amount || '', + guardian_name: guardian_name || '', + guardian_id_card: guardian_id_card || '', + guardian_relation: guardian_relation || '', update_by: this.adminUser?.id || 0 }); @@ -337,7 +348,7 @@ module.exports = class extends Base { } const statusMap = { '-1': '待提交', 0: '待审核', 1: '审核通过', 2: '已驳回' }; - const header = ['ID', '姓名', '性别', '身份证', '手机号', '省份', '城市', '审核状态', '审核日期', '审核驳回原因', '瘤种']; + const header = ['ID', '姓名', '性别', '身份证', '手机号', '省份', '城市', '提交时间', '审核状态', '审核日期', '审核驳回原因', '瘤种']; const ExcelJS = require('exceljs'); const workbook = new ExcelJS.Workbook(); @@ -379,6 +390,7 @@ module.exports = class extends Base { item.phone, regionMap[item.province_code] || '', regionMap[item.city_code] || '', + item.create_time || '', statusMap[item.status] || '', audit ? (audit.create_time || '') : '', (audit && audit.action === 'reject') ? (audit.reason || '') : '', @@ -401,7 +413,8 @@ module.exports = class extends Base { }); const buffer = await workbook.xlsx.writeBuffer(); - const fileName = encodeURIComponent(`患者信息_${Date.now()}.xlsx`); + const ts = dayjs().format('YYYYMMDDHHmmss'); + const fileName = encodeURIComponent(`患者信息_${ts}.xlsx`); this.ctx.set('Content-Type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); this.ctx.set('Content-Disposition', `attachment; filename*=UTF-8''${fileName}`); diff --git a/src/controller/mp.js b/src/controller/mp.js index 0fdf43f..df3be58 100644 --- a/src/controller/mp.js +++ b/src/controller/mp.js @@ -306,6 +306,9 @@ module.exports = class extends Base { sign_privacy_jhr: patient.sign_privacy_jhr || '', sign_promise: patient.sign_promise || '', income_amount: patient.income_amount || '', + guardian_name: patient.guardian_name || '', + guardian_id_card: patient.guardian_id_card || '', + guardian_relation: patient.guardian_relation || '', status: patient.status, auth_status: patient.auth_status || 0, reject_reason: rejectReason }}); @@ -319,7 +322,7 @@ module.exports = class extends Base { async saveMyInfoAction() { const mpUser = this.mpUser; if (!mpUser) return this.json({ code: 1009, msg: '请先登录' }); - const { gender, province_code, city_code, district_code, address, emergency_contact, emergency_phone, documents, sign_income, sign_privacy, sign_privacy_jhr, sign_promise, income_amount, mp_env_version } = this.post(); + const { gender, province_code, city_code, district_code, address, emergency_contact, emergency_phone, documents, sign_income, sign_privacy, sign_privacy_jhr, sign_promise, income_amount, guardian_name, guardian_id_card, guardian_relation, mp_env_version } = this.post(); const user = await this.model('wechat_user').where({ id: mpUser.id, status: 1 }).find(); if (think.isEmpty(user) || !user.patient_id) return this.json({ code: 1, msg: '请先完成实名认证' }); if (!province_code || !city_code || !district_code) return this.json({ code: 1, msg: '请选择省市区' }); @@ -341,6 +344,9 @@ module.exports = class extends Base { sign_privacy_jhr: sign_privacy_jhr || '', sign_promise: sign_promise || '', income_amount: income_amount || null, + guardian_name: guardian_name || '', + guardian_id_card: guardian_id_card || '', + guardian_relation: guardian_relation || '', status: 0, update_time: now }); diff --git a/src/middleware/request_log.js b/src/middleware/request_log.js index 5bcc69d..7c090f9 100644 --- a/src/middleware/request_log.js +++ b/src/middleware/request_log.js @@ -3,9 +3,15 @@ const dayjs = require('dayjs'); module.exports = () => { return async (ctx, next) => { // 跳过静态资源和source map - if (ctx.path.startsWith('/static/') || ctx.path === '/favicon.ico' || ctx.path.endsWith('.map')) { + if (ctx.path.startsWith('/static/') || ctx.path === '/favicon.ico') { return next(); } + // source map / json 静态请求直接返回 404,避免 think-trace 报错 + if (ctx.path.endsWith('.map') || ctx.path.endsWith('.json')) { + ctx.status = 404; + ctx.body = ''; + return; + } const start = Date.now(); const params = { ...ctx.query, ...(ctx.request.body || {}) }; diff --git a/view/admin/patient_detail.html b/view/admin/patient_detail.html index d81e582..22e3b9b 100644 --- a/view/admin/patient_detail.html +++ b/view/admin/patient_detail.html @@ -63,6 +63,36 @@
+ 无证件儿童免冠照片 + 身份证人像面 / 国徽面照片 +
+