| | |
| | | |
| | | <el-tabs v-model="mainTab" type="border-card"> |
| | | <el-tab-pane label="档案详情" name="detail"> |
| | | <div v-if="archive.subType === 'pregnancy'" class="page-title">孕妇首诊信息登记</div> |
| | | <!-- 患者基本信息 --> |
| | | <el-card class="info-card" shadow="never"> |
| | | <div slot="header" class="card-header"><span>患者基本信息</span></div> |
| | |
| | | <el-col :span="8"><el-form-item label="诊断名称"><el-input v-model="pregForm.firstVisit.diagname" class="w-full" /></el-form-item></el-col> |
| | | <el-col :span="16"><el-form-item label="居住地址"><el-input v-model="pregForm.firstVisit.address" class="w-full" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="末次月经"><el-date-picker v-model="pregForm.firstVisit.lmp" value-format="yyyy-MM-dd" class="w-md" @change="onLmpChange" /></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | </div> |
| | | |
| | |
| | | <el-col :span="8"> |
| | | <div class="cascade-col"> |
| | | <div class="cascade-label">具体情况</div> |
| | | <el-checkbox-group v-model="pregForm.pregnancy.details" :disabled="!pregForm.pregnancy.status"> |
| | | <el-checkbox v-for="d in pregnancySubOptions" :key="d" :label="d">{{ d }}</el-checkbox> |
| | | <el-checkbox-group v-model="pregForm.pregnancy.details" @change="onDetailsChange"> |
| | | <el-checkbox v-for="d in PREGNANCY_DETAIL_OPTIONS" :key="d" :label="d">{{ d }}</el-checkbox> |
| | | </el-checkbox-group> |
| | | <div v-if="!pregForm.pregnancy.status" class="cascade-empty">请先选择妊娠情况</div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="cascade-col"> |
| | | <div class="cascade-label">处理建议</div> |
| | | <el-checkbox-group v-model="pregForm.pregnancy.hint" :disabled="!pregForm.pregnancy.status"> |
| | | <el-checkbox-group v-model="pregForm.pregnancy.hint" :disabled="!pregForm.pregnancy.details.length" @change="onHintChange"> |
| | | <el-checkbox v-for="h in pregnancyHintOptions" :key="h" :label="h">{{ h }}</el-checkbox> |
| | | </el-checkbox-group> |
| | | <div v-if="!pregForm.pregnancy.status" class="cascade-empty">请先选择妊娠情况</div> |
| | | <div v-if="!pregForm.pregnancy.details.length" class="cascade-empty">请先选择具体情况</div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | |
| | | <el-col :span="8"><el-form-item label="预产期"><el-date-picker v-model="pregForm.registration.edd" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="记录者"><el-input v-model="pregForm.registration.recorder" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item v-if="pregForm.registration.isRegistered === '否'" label="未建档原因"> |
| | | <el-input v-model="pregForm.registration.unregisteredReason" type="textarea" :rows="2" class="w-lg" /> |
| | | <el-form-item v-if="pregForm.registration.isRegistered === '否'" label="未建册原因"> |
| | | <el-checkbox-group v-model="pregForm.registration.unregisteredReasons"> |
| | | <el-checkbox v-for="r in UNREGISTERED_REASONS" :key="r" :label="r">{{ r }}</el-checkbox> |
| | | </el-checkbox-group> |
| | | <el-input |
| | | v-if="pregForm.registration.unregisteredReasons.includes('其他特殊因素')" |
| | | v-model="pregForm.registration.unregisteredReasonOther" |
| | | type="textarea" |
| | | :rows="2" |
| | | class="w-lg" |
| | | style="margin-top:8px" |
| | | placeholder="请填写其他特殊因素" |
| | | /> |
| | | </el-form-item> |
| | | </el-form> |
| | | </el-card> |
| | |
| | | </el-form> |
| | | </el-card> |
| | | |
| | | <!-- ===== 孕妇随访:早孕随访表 + 评分表(选中「经咨询指导后继续妊娠并在产科建档」后出现) ===== --> |
| | | <template v-if="archive.subType === 'pregnancy' && showFollowUp"> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>早孕随访表</span></div> |
| | | <el-form :model="pregForm.earlyFollow" label-width="140px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="姓名"><el-input v-model="pregForm.earlyFollow.name" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="年龄"><el-input v-model="pregForm.earlyFollow.age" class="w-xs" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="就诊号"><el-input v-model="pregForm.earlyFollow.visitNo" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="联系方式(微信)"><el-input v-model="pregForm.earlyFollow.wechat" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="户籍"><el-input v-model="pregForm.earlyFollow.household" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="孕产史"><el-input v-model="pregForm.earlyFollow.gravidaPara" placeholder="G_P_" class="w-xs" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="婚姻状况"> |
| | | <el-select v-model="pregForm.earlyFollow.maritalStatus" class="w-sm"> |
| | | <el-option label="未婚" value="未婚" /><el-option label="已婚" value="已婚" /><el-option label="不详" value="不详" /> |
| | | </el-select> |
| | | </el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="建表日期"><el-date-picker v-model="pregForm.earlyFollow.buildDate" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="预产期"><el-date-picker v-model="pregForm.earlyFollow.edd" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item label="计划流产主要原因(可多选)"> |
| | | <el-checkbox-group v-model="pregForm.earlyFollow.abortionReasons"> |
| | | <el-checkbox label="已有多孩" /><el-checkbox label="经济因素" /><el-checkbox label="药物暴露" /> |
| | | <el-checkbox label="未达结婚年龄" /><el-checkbox label="身体因素" /><el-checkbox label="家庭支持不足" /> |
| | | <el-checkbox label="自身不愿生育" /><el-checkbox label="其他" /> |
| | | </el-checkbox-group> |
| | | <el-input v-if="pregForm.earlyFollow.abortionReasons.includes('其他')" v-model="pregForm.earlyFollow.otherReason" placeholder="其他原因" class="w-md" style="margin-top:8px" /> |
| | | </el-form-item> |
| | | <el-form-item label="继续妊娠"> |
| | | <el-radio-group v-model="pregForm.earlyFollow.continuePregnancy"> |
| | | <el-radio label="是">是</el-radio><el-radio label="否">否</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="16"><el-form-item label="早孕建册单位"><el-input v-model="pregForm.earlyFollow.registrationUnit" class="w-full" /></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <div class="sub-section"> |
| | | <div class="sub-title">辅导内容</div> |
| | | <el-table :data="pregForm.counseling" border size="small"> |
| | | <el-table-column label="辅导次数" width="120" align="center"> |
| | | <template slot-scope="scope">{{ ['第一次辅导','第二次辅导','第三次辅导','第四次辅导'][scope.$index] }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="辅导日期" width="160" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-date-picker v-if="editing" v-model="scope.row.date" value-format="yyyy-MM-dd" size="small" style="width:100%" /> |
| | | <span v-else>{{ scope.row.date || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="辅导内容" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-input v-if="editing" v-model="scope.row.content" size="small" /> |
| | | <span v-else>{{ scope.row.content || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="辅导人员" width="140" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-input v-if="editing" v-model="scope.row.person" size="small" /> |
| | | <span v-else>{{ scope.row.person || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <div class="sub-section"> |
| | | <div class="sub-title">评分表</div> |
| | | <el-form :model="pregForm.score" label-width="140px" size="small" :disabled="!editing" inline> |
| | | <el-form-item label="评分总分"><el-input-number v-model="pregForm.score.total" :controls="false" style="width:140px" /></el-form-item> |
| | | <el-form-item label="评估结果"><el-input v-model="pregForm.score.result" class="w-lg" /></el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </el-card> |
| | | |
| | | <!-- 随访周期 --> |
| | | <!-- 随访周期(无论是否建立早孕随访表均显示) --> |
| | | <template v-if="archive.subType === 'pregnancy'"> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>随访周期</span></div> |
| | | <EditableTable :data.sync="pregForm.followupCycle" :editing="editing" :columns="followupColumns" /> |
| | | </el-card> |
| | | |
| | | <!-- 当前患者随访记录表 --> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>当前患者随访记录表</span></div> |
| | | <el-table :data="currentFollowRecords" border size="small"> |
| | | <el-table-column type="index" label="序号" width="60" align="center" /> |
| | | <el-table-column prop="planDate" label="拟随访日期" width="130" align="center" /> |
| | | <el-table-column prop="status" label="状况" width="100" align="center" /> |
| | | <el-table-column prop="method" label="随访方式" width="110" align="center" /> |
| | | <el-table-column prop="situation" label="随访情况" align="center" show-overflow-tooltip /> |
| | | <el-table-column prop="followDate" label="随访日期" width="130" align="center" /> |
| | | <el-table-column prop="staff" label="随访人员" width="110" align="center" /> |
| | | </el-table> |
| | | <EditableTable |
| | | :data.sync="pregForm.followupCycle" |
| | | :editing="editing" |
| | | :columns="followupColumns" |
| | | auto-seq="seq" |
| | | /> |
| | | </el-card> |
| | | </template> |
| | | |
| | |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="改良Kupperman评分标准表" name="kupperman"> |
| | | <el-form :model="form.kupperman" label-width="160px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"><el-col :span="8"><el-form-item label="评估日期"><el-date-picker v-model="form.kupperman.date" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col></el-row> |
| | | <KuppermanScoreTable v-model="form.kupperman" :editing="editing" /> |
| | | </el-form> |
| | | <KuppermanScoreTable v-model="form.kupperman" :patient="patientInfo" :editing="editing" /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="更年期评分量表(MRS)" name="mrs"> |
| | | <el-form :model="form.mrs" label-width="160px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"><el-col :span="8"><el-form-item label="评估日期"><el-date-picker v-model="form.mrs.date" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col></el-row> |
| | | <MRSScoreTable v-model="form.mrs" :editing="editing" /> |
| | | </el-form> |
| | | <MRSScoreTable v-model="form.mrs" :patient="patientInfo" :editing="editing" /> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="匹兹堡睡眠质量评分量表(PSQI)" name="psqi"> |
| | | <el-form :model="form.psqi" label-width="160px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"><el-col :span="8"><el-form-item label="评估日期"><el-date-picker v-model="form.psqi.date" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col></el-row> |
| | | <PSQIScoreTable v-model="form.psqi" :editing="editing" /> |
| | | </el-form> |
| | | <PSQIScoreTable v-model="form.psqi" :patient="patientInfo" :editing="editing" /> |
| | | </el-tab-pane> |
| | | </el-tabs> |
| | | </el-card> |
| | | </template> |
| | | </el-tab-pane> |
| | | |
| | | <!-- ===== 早孕随访表(独立 tab,选中「继续妊娠并在产科建档」并确认后显示) ===== --> |
| | | <el-tab-pane v-if="archive.subType === 'pregnancy' && showFollowUp" label="早孕随访表" name="followup"> |
| | | <el-card class="info-card" shadow="never" style="margin-top:14px"> |
| | | <div slot="header" class="card-header"><span>早孕随访表</span></div> |
| | | <el-form :model="pregForm.earlyFollow" label-width="140px" size="small" :disabled="!editing"> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="姓名"><el-input v-model="pregForm.earlyFollow.name" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="年龄"><el-input v-model="pregForm.earlyFollow.age" class="w-xs" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="就诊号"><el-input v-model="pregForm.earlyFollow.visitNo" class="w-sm" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="联系方式(微信)"><el-input v-model="pregForm.earlyFollow.wechat" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="户籍"><el-input v-model="pregForm.earlyFollow.household" class="w-sm" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="孕产史"><el-input v-model="pregForm.earlyFollow.gravidaPara" placeholder="G_P_" class="w-xs" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="8"><el-form-item label="婚姻状况"> |
| | | <el-select v-model="pregForm.earlyFollow.maritalStatus" class="w-sm"> |
| | | <el-option label="未婚" value="未婚" /><el-option label="已婚" value="已婚" /><el-option label="不详" value="不详" /> |
| | | </el-select> |
| | | </el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="建表日期"><el-date-picker v-model="pregForm.earlyFollow.buildDate" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | <el-col :span="8"><el-form-item label="预产期"><el-date-picker v-model="pregForm.earlyFollow.edd" value-format="yyyy-MM-dd" class="w-md" /></el-form-item></el-col> |
| | | </el-row> |
| | | <el-form-item label="计划流产主要原因(可多选)"> |
| | | <el-checkbox-group v-model="pregForm.earlyFollow.abortionReasons"> |
| | | <el-checkbox label="已有多孩" /><el-checkbox label="经济因素" /><el-checkbox label="药物暴露" /> |
| | | <el-checkbox label="未达结婚年龄" /><el-checkbox label="身体因素" /><el-checkbox label="家庭支持不足" /> |
| | | <el-checkbox label="自身不愿生育" /><el-checkbox label="其他" /> |
| | | </el-checkbox-group> |
| | | <el-input v-if="pregForm.earlyFollow.abortionReasons.includes('其他')" v-model="pregForm.earlyFollow.otherReason" placeholder="其他原因" class="w-md" style="margin-top:8px" /> |
| | | </el-form-item> |
| | | <el-form-item label="继续妊娠"> |
| | | <el-radio-group v-model="pregForm.earlyFollow.continuePregnancy"> |
| | | <el-radio label="是">是</el-radio><el-radio label="否">否</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-row :gutter="20"> |
| | | <el-col :span="16"><el-form-item label="早孕建册单位"><el-input v-model="pregForm.earlyFollow.registrationUnit" class="w-full" /></el-form-item></el-col> |
| | | </el-row> |
| | | </el-form> |
| | | |
| | | <div class="sub-section"> |
| | | <div class="sub-title">辅导内容</div> |
| | | <el-table :data="pregForm.counseling" border size="small"> |
| | | <el-table-column label="辅导次数" width="120" align="center"> |
| | | <template slot-scope="scope">{{ ['第一次辅导','第二次辅导','第三次辅导','第四次辅导'][scope.$index] }}</template> |
| | | </el-table-column> |
| | | <el-table-column label="辅导日期" width="160" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-date-picker v-if="editing" v-model="scope.row.date" value-format="yyyy-MM-dd" size="small" style="width:100%" /> |
| | | <span v-else>{{ scope.row.date || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="辅导内容" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-input v-if="editing" v-model="scope.row.content" size="small" /> |
| | | <span v-else>{{ scope.row.content || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="辅导人员" width="140" align="center"> |
| | | <template slot-scope="scope"> |
| | | <el-input v-if="editing" v-model="scope.row.person" size="small" /> |
| | | <span v-else>{{ scope.row.person || '-' }}</span> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | </div> |
| | | |
| | | <div class="sub-section"> |
| | | <div class="sub-title">评分表</div> |
| | | <el-form :model="pregForm.score" label-width="140px" size="small" :disabled="!editing" inline> |
| | | <el-form-item label="评分总分"><el-input-number v-model="pregForm.score.total" :controls="false" style="width:140px" /></el-form-item> |
| | | <el-form-item label="评估结果"><el-input v-model="pregForm.score.result" class="w-lg" /></el-form-item> |
| | | </el-form> |
| | | </div> |
| | | </el-card> |
| | | </el-tab-pane> |
| | | |
| | | <el-tab-pane label="服务记录" name="service"> |
| | |
| | | import KuppermanScoreTable from "./KuppermanScoreTable.vue"; |
| | | import MRSScoreTable from "./MRSScoreTable.vue"; |
| | | import PSQIScoreTable from "./PSQIScoreTable.vue"; |
| | | import { loadArchives, saveArchives } from "../types"; |
| | | import { getArchive, saveArchive, closeArchive, calcAge } from "../apiAdapter"; |
| | | |
| | | const PREGNANCY_OPTIONS = { |
| | | planBirth: { label: "首诊拟生育", details: ["先兆流产"], hints: ["医学处置后继续妊娠并在产科建档"] }, |
| | |
| | | planAbortion: { label: "首诊拟人工流产", details: ["药物流产", "手术流产"], hints: ["经咨询指导后继续妊娠并在产科建档"] }, |
| | | }; |
| | | |
| | | // 妊娠情况-具体情况全量选项(不再随妊娠情况变化) |
| | | const PREGNANCY_DETAIL_OPTIONS = ["先兆流产", "自然流产", "胚胎停育", "药物流产", "手术流产"]; |
| | | |
| | | // 具体情况 → 处理建议 映射(处理建议可选项随所选具体情况变动) |
| | | const PREGNANCY_DETAIL_HINTS = { |
| | | "先兆流产": ["医学处置后继续妊娠并在产科建档"], |
| | | "自然流产": ["为女性再次妊娠提供备孕指导"], |
| | | "胚胎停育": ["为女性再次妊娠提供备孕指导"], |
| | | "药物流产": ["经咨询指导后继续妊娠并在产科建档"], |
| | | "手术流产": ["经咨询指导后继续妊娠并在产科建档"], |
| | | }; |
| | | |
| | | // 是否建册=否 时的未建册原因(可多选,最后一项“其他特殊因素”可补充输入) |
| | | const UNREGISTERED_REASONS = [ |
| | | "拟终止妊娠,不建册", |
| | | "妊娠异常:胚胎停育、异位妊娠、难免流产、自然流产", |
| | | "先兆流产,病情不稳定,暂缓建册", |
| | | "合并内外科基础疾病,评估暂不宜继续妊娠", |
| | | "患者个人及家庭因素,暂不建册", |
| | | "档案与就诊流转因素:已在外院建册或要求回属地管辖地建册", |
| | | "其他特殊因素", |
| | | ]; |
| | | |
| | | export default { |
| | | name: "MaternalHealthArchiveDetail", |
| | | components: { InfoField, EditableTable, ServiceRecords, KuppermanScoreTable, MRSScoreTable, PSQIScoreTable }, |
| | | data() { |
| | | return { |
| | | PREGNANCY_OPTIONS, |
| | | PREGNANCY_OPTIONS, PREGNANCY_DETAIL_OPTIONS, PREGNANCY_DETAIL_HINTS, UNREGISTERED_REASONS, |
| | | loading: false, archive: null, editing: true, activeTab: "sysQ", mainTab: "detail", |
| | | followupColumns: [ |
| | | { prop: "seq", label: "序号", width: 60 }, |
| | | { prop: "planDate", label: "拟随访日期", width: 130, type: "date" }, |
| | | { prop: "status", label: "状况", width: 100, type: "select", options: ["已完成", "未完成"] }, |
| | | { prop: "planDate", label: "拟随访日期", width: 180, type: "date" }, |
| | | // 新增一行时状况默认「未完成」,序号由 EditableTable 的 auto-seq 自动填充 |
| | | { prop: "status", label: "状况", width: 130, type: "select", options: ["已完成", "未完成"], default: "未完成" }, |
| | | { prop: "method", label: "随访方式", width: 110 }, |
| | | { prop: "situation", label: "随访情况", minWidth: 160 }, |
| | | { prop: "followDate", label: "随访日期", width: 130, type: "date" }, |
| | | { prop: "staff", label: "随访人员", width: 110 }, |
| | | ], |
| | | pregForm: { |
| | | firstVisit: { visitNo: "", selfPhone: "", wardName: "", contactPhone: "", idcardno: "", address: "", diagname: "", firstDoctor: "" }, |
| | | firstVisit: { visitNo: "", selfPhone: "", wardName: "", contactPhone: "", idcardno: "", address: "", diagname: "", firstDoctor: "", lmp: "" }, |
| | | pregnancy: { status: "", details: [], hint: [] }, |
| | | earlyFollow: { name: "", age: "", visitNo: "", wechat: "", household: "", gravidaPara: "", maritalStatus: "", buildDate: "", abortionReasons: [], otherReason: "", continuePregnancy: "", edd: "", registrationUnit: "" }, |
| | | counseling: [ |
| | |
| | | { date: "", content: "", person: "" }, { date: "", content: "", person: "" }, |
| | | ], |
| | | score: { total: null, result: "" }, |
| | | registration: { isRegistered: "", unregisteredReason: "", edd: "", recorder: "" }, |
| | | registration: { isRegistered: "", unregisteredReasons: [], unregisteredReasonOther: "", edd: "", recorder: "" }, |
| | | followupCycle: [], |
| | | showFollowUp: false, |
| | | }, |
| | | form: { |
| | | menoSysQ: { date:"", age:null, menstruation:"", lmp:"", menopauseAge:null, hotFlash:0, insomnia:0, mood:0, fatigue:0, jointPain:0, palpitation:0, dryness:0, libido:0, otherSymptoms:"", advice:"", doctor:"" }, |
| | | mhtFirst: { date:"", chiefComplaint:"", menopauseYears:null, height:null, weight:null, bmi:null, bloodPressure:"", glucose:null, lipid:"", pastHistory:"", gynExam:"", breastExam:"", auxExam:"", mhtPlan:"", doctor:"" }, |
| | | mhtFollow: { date:"", compliance:"良好", symptomImprove:"部分", sideEffect:"", bleeding:"无", weight:null, bloodPressure:"", reExamResult:"", planAdjust:"", nextVisit:"", doctor:"" }, |
| | | kupperman: { date:"", 潮热出汗:0,感觉异常:0,失眠:0,情绪波动:0,抑郁:0,眩晕:0,疲乏:0,关节痛:0,头痛:0,心悸:0,皮肤蚁走感:0,性生活:0,泌尿系感染:0 }, |
| | | mrs: { date:"" }, |
| | | psqi: { date:"" }, |
| | | kupperman: { date:"", evaluator:"", kup_0:0,kup_1:0,kup_2:0,kup_3:0,kup_4:0,kup_5:0,kup_6:0,kup_7:0,kup_8:0,kup_9:0,kup_10:0,kup_11:0,kup_12:0 }, |
| | | mrs: { date:"", evaluator:"", mrs_0:0,mrs_1:0,mrs_2:0,mrs_3:0,mrs_4:0,mrs_5:0,mrs_6:0,mrs_7:0,mrs_8:0,mrs_9:0,mrs_10:0 }, |
| | | psqi: { date:"", evaluator:"", q1BedTime:"", q2Latency:0, q3WakeTime:"", q4Hours:null, q5a:0,q5b:0,q5c:0,q5d:0,q5e:0,q5f:0,q5g:0,q5h:0,q5i:0,q5j:0, q6Quality:0, q7Medication:0, q8Sleepy:0, q9Energy:0 }, |
| | | }, |
| | | }; |
| | | }, |
| | | computed: { |
| | | sourceLabel() { const m={standalone:"独立建档",outpatient:"门诊记录",inpatient:"在院记录"}; return m[this.archive?.sourcePage]||this.archive?.sourcePage||"-"; }, |
| | | pregnancySubOptions() { |
| | | const opt = PREGNANCY_OPTIONS[this.pregForm.pregnancy.status]; |
| | | return opt ? opt.details : []; |
| | | // 量表纸质表表头所用的患者基本信息 |
| | | patientInfo() { |
| | | const a = this.archive || {}; |
| | | return { |
| | | name: a.patname || "", |
| | | // 与项目统一约定一致:sex == 1 为男,其余为女 |
| | | sex: a.sex === undefined || a.sex === null || a.sex === "" ? "" : a.sex == 1 ? "男" : "女", |
| | | age: a.age || "", |
| | | dept: a.deptname || "", |
| | | diagnosis: a.diagname || "", |
| | | }; |
| | | }, |
| | | pregnancyHintOptions() { |
| | | const opt = PREGNANCY_OPTIONS[this.pregForm.pregnancy.status]; |
| | | return opt ? opt.hints : []; |
| | | // 处理建议可选项随所选「具体情况」变动 |
| | | const set = {}; |
| | | (this.pregForm.pregnancy.details || []).forEach((d) => { |
| | | (PREGNANCY_DETAIL_HINTS[d] || []).forEach((h) => { set[h] = true; }); |
| | | }); |
| | | return Object.keys(set); |
| | | }, |
| | | showFollowUp() { |
| | | return this.pregForm.pregnancy.status === "planAbortion" && |
| | | this.pregForm.pregnancy.hint.includes("经咨询指导后继续妊娠并在产科建档"); |
| | | return !!this.pregForm.showFollowUp; |
| | | }, |
| | | currentFollowRecords() { |
| | | return (this.pregForm.followupCycle || []).filter((r) => r.status === "已完成"); |
| | | }, |
| | | }, |
| | | watch: { |
| | | // 身份证号填完整后,自动把出生日期与年龄补上(只补空字段) |
| | | "archive.idcardno"(val) { this.fillBirthdayFromIdcard(val); }, |
| | | "pregForm.firstVisit.idcardno"(val) { this.fillBirthdayFromIdcard(val); }, |
| | | }, |
| | | created() { |
| | | const id = this.$route.query.id; |
| | | if (id) this.loadArchive(id, this.$route.query.edit == 1); |
| | | const typeKey = this.$route.query.type; |
| | | // detailId:详情表主键。后端列表接口暂未返回,先按路由参数透传,未来可直接拼上 |
| | | if (id) this.loadArchive(id, typeKey, this.$route.query.edit == 1, this.$route.query.detailId); |
| | | }, |
| | | methods: { |
| | | loadArchive(id, autoEdit) { |
| | | this.loading = true; |
| | | this.archive = loadArchives().find((item) => item.id === id) || null; |
| | | if (this.archive) { |
| | | if (this.archive.subType === "pregnancy") { |
| | | if (this.archive.pregFormData) { |
| | | const saved = JSON.parse(JSON.stringify(this.archive.pregFormData)); |
| | | this.pregForm = Object.assign({}, this.pregForm, saved); |
| | | if (!this.pregForm.pregnancy) this.pregForm.pregnancy = { status: "", details: [], hint: [] }; |
| | | } |
| | | } else if (this.archive.subType === "menopause") { |
| | | if (this.archive.formData) { |
| | | Object.keys(this.form).forEach((k) => { |
| | | if (this.archive.formData[k]) Object.assign(this.form[k], this.archive.formData[k]); |
| | | }); |
| | | } |
| | | } |
| | | /** |
| | | * 从身份证号解析出生日期 yyyy-MM-dd |
| | | * 18 位:第 7-14 位是 yyyyMMdd;15 位老身份证:第 7-12 位是 yyMMdd,前面补 19 |
| | | * 格式不对或日期不存在(如 20260231)返回空 |
| | | */ |
| | | parseIdcardBirth(id) { |
| | | if (!id) return ""; |
| | | const s = String(id).trim().toUpperCase(); |
| | | let y, m, d; |
| | | if (/^\d{17}[\dX]$/.test(s)) { |
| | | y = s.substring(6, 10); m = s.substring(10, 12); d = s.substring(12, 14); |
| | | } else if (/^\d{15}$/.test(s)) { |
| | | y = "19" + s.substring(6, 8); m = s.substring(8, 10); d = s.substring(10, 12); |
| | | } else { |
| | | return ""; |
| | | } |
| | | if (autoEdit) this.editing = true; |
| | | this.loading = false; |
| | | const pad = (n) => String(n).padStart(2, "0"); |
| | | const dt = new Date(Number(y), Number(m) - 1, Number(d)); |
| | | if (isNaN(dt.getTime())) return ""; |
| | | // 拒绝 2 月 31 日这类不存在的日期 |
| | | if (dt.getFullYear() !== Number(y) || pad(dt.getMonth() + 1) !== m || pad(dt.getDate()) !== d) return ""; |
| | | return y + "-" + m + "-" + d; |
| | | }, |
| | | /** 身份证合法时补齐出生日期与年龄,已经有值的字段不动 */ |
| | | fillBirthdayFromIdcard(id) { |
| | | if (!this.archive) return; |
| | | const birth = this.parseIdcardBirth(id); |
| | | if (!birth) return; |
| | | if (!this.archive.birthday) this.archive.birthday = birth; |
| | | if (!this.archive.age) this.archive.age = calcAge(birth); |
| | | }, |
| | | loadArchive(id, typeKey, autoEdit, detailId) { |
| | | this.loading = true; |
| | | getArchive(typeKey, id, detailId) |
| | | .then((archive) => { |
| | | this.archive = archive || null; |
| | | if (this.archive) { |
| | | if (this.archive.subType === "pregnancy") { |
| | | if (this.archive.pregFormData) { |
| | | const saved = JSON.parse(JSON.stringify(this.archive.pregFormData)); |
| | | this.pregForm = Object.assign({}, this.pregForm, saved); |
| | | if (!this.pregForm.pregnancy) this.pregForm.pregnancy = { status: "", details: [], hint: [] }; |
| | | if (!this.pregForm.registration) this.pregForm.registration = { isRegistered: "", unregisteredReasons: [], unregisteredReasonOther: "", edd: "", recorder: "" }; |
| | | if (!Array.isArray(this.pregForm.registration.unregisteredReasons)) this.pregForm.registration.unregisteredReasons = []; |
| | | // 末次月经:从病历/档案自动抓取,并自动计算预产期 |
| | | if (!this.pregForm.firstVisit.lmp && this.archive.lmp) { |
| | | this.pregForm.firstVisit.lmp = this.archive.lmp; |
| | | if (!this.pregForm.registration.edd) this.pregForm.registration.edd = this.calcEdd(this.archive.lmp); |
| | | } |
| | | if (!saved.hasOwnProperty("showFollowUp")) { |
| | | // 兼容旧数据:已有早孕随访表内容则默认显示 |
| | | const ef = saved.earlyFollow || {}; |
| | | this.pregForm.showFollowUp = !!(ef.name || ef.visitNo || ef.buildDate || ef.edd); |
| | | } |
| | | } |
| | | } else if (this.archive.subType === "menopause") { |
| | | if (this.archive.formData) { |
| | | Object.keys(this.form).forEach((k) => { |
| | | if (this.archive.formData[k]) Object.assign(this.form[k], this.archive.formData[k]); |
| | | }); |
| | | } |
| | | } |
| | | } |
| | | if (autoEdit) this.editing = true; |
| | | }) |
| | | .catch(() => { this.archive = null; }) |
| | | .finally(() => { this.loading = false; }); |
| | | }, |
| | | onPregnancyStatusChange() { |
| | | this.pregForm.pregnancy.details = []; |
| | | this.pregForm.pregnancy.hint = []; |
| | | const opt = PREGNANCY_OPTIONS[this.pregForm.pregnancy.status]; |
| | | if (this.archive) this.archive.pregnancyStatus = opt ? opt.label : ""; |
| | | }, |
| | | onDetailsChange() { |
| | | // 处理建议随具体情况变动,剔除已不再适用的已选项 |
| | | const valid = this.pregnancyHintOptions; |
| | | this.pregForm.pregnancy.hint = (this.pregForm.pregnancy.hint || []).filter((h) => valid.includes(h)); |
| | | }, |
| | | calcEdd(lmp) { |
| | | if (!lmp) return ""; |
| | | const d = new Date(String(lmp).replace(/-/g, "/")); |
| | | if (isNaN(d.getTime())) return ""; |
| | | const m = d.getMonth() + 1; // 1-12 |
| | | let y = d.getFullYear(); |
| | | // 末次月经:月份>3 减3(跨年),≤3 加9;日期+7 |
| | | const eddMonth = m > 3 ? m - 3 : m + 9; |
| | | if (m > 3) y += 1; |
| | | const edd = new Date(y, eddMonth - 1, d.getDate() + 7); |
| | | const pad = (n) => String(n).padStart(2, "0"); |
| | | return edd.getFullYear() + "-" + pad(edd.getMonth() + 1) + "-" + pad(edd.getDate()); |
| | | }, |
| | | onLmpChange(val) { |
| | | this.pregForm.registration.edd = this.calcEdd(val); |
| | | }, |
| | | hasFollowupHint(hints) { |
| | | return (hints || []).some((h) => h && h.indexOf("继续妊娠并在产科建档") > -1); |
| | | }, |
| | | onHintChange(val) { |
| | | if (this.hasFollowupHint(val) && !this.pregForm.showFollowUp) { |
| | | this.$modal.confirm("是否创建早孕随访表?").then(() => { |
| | | this.pregForm.showFollowUp = true; |
| | | // 新建随访表时把档案里已有的基础信息带过来,避免重复录入 |
| | | this.fillEarlyFollowDefaults(); |
| | | this.$message.success("已创建早孕随访表"); |
| | | }).catch(() => {}); |
| | | } |
| | | }, |
| | | /** |
| | | * 用档案信息预填早孕随访表的基础字段 |
| | | * 只填空字段,不覆盖用户已经填过的内容 |
| | | */ |
| | | fillEarlyFollowDefaults() { |
| | | const a = this.archive || {}; |
| | | if (!this.pregForm.earlyFollow) { |
| | | this.pregForm.earlyFollow = { name: "", age: "", visitNo: "", wechat: "", household: "", gravidaPara: "", maritalStatus: "", buildDate: "", abortionReasons: [], otherReason: "", continuePregnancy: "", edd: "", registrationUnit: "" }; |
| | | } |
| | | const ef = this.pregForm.earlyFollow; |
| | | const put = (key, val) => { |
| | | if (val === undefined || val === null || val === "") return; |
| | | if (ef[key] === undefined || ef[key] === null || ef[key] === "") ef[key] = val; |
| | | }; |
| | | put("name", a.patname); // 姓名 |
| | | put("age", a.age); // 年龄(由出生日期推算) |
| | | put("visitNo", a.outhospno || a.serialnum); // 就诊号(门诊号 / 流水号) |
| | | put("edd", this.pregForm.registration && this.pregForm.registration.edd); // 预产期(档案里已按末次月经算好) |
| | | put("buildDate", this.todayStr()); // 建表日期默认今天 |
| | | }, |
| | | /** 今天 yyyy-MM-dd */ |
| | | todayStr() { |
| | | const d = new Date(); |
| | | const pad = (n) => String(n).padStart(2, "0"); |
| | | return d.getFullYear() + "-" + pad(d.getMonth() + 1) + "-" + pad(d.getDate()); |
| | | }, |
| | | toggleEdit() { |
| | | if (this.editing) { |
| | | // 先把页面表单回填到档案对象,再整体提交 |
| | | if (this.archive.subType === "pregnancy") this.archive.pregFormData = JSON.parse(JSON.stringify(this.pregForm)); |
| | | if (this.archive.subType === "menopause") this.archive.formData = JSON.parse(JSON.stringify(this.form)); |
| | | this.archive.updateTime = new Date().toISOString().replace("T", " ").substring(0, 19); |
| | | const all = loadArchives(); |
| | | const idx = all.findIndex((item) => item.id === this.archive.id); |
| | | if (idx >= 0) all[idx] = JSON.parse(JSON.stringify(this.archive)); |
| | | saveArchives(all); |
| | | this.$message.success("保存成功"); |
| | | this.loading = true; |
| | | saveArchive(this.archive) |
| | | .then(() => { |
| | | this.$message.success("保存成功"); |
| | | this.editing = false; |
| | | }) |
| | | .catch(() => {}) |
| | | .finally(() => { this.loading = false; }); |
| | | return; |
| | | } |
| | | this.editing = !this.editing; |
| | | this.editing = true; |
| | | }, |
| | | handleCloseCase() { |
| | | this.$modal.confirm("确认将该档案结案?结案后可在列表页查看结案状态。").then(() => { |
| | | this.archive.closeStatus = 1; |
| | | this.archive.updateTime = new Date().toISOString().replace("T", " ").substring(0, 19); |
| | | const all = loadArchives(); |
| | | const idx = all.findIndex((item) => item.id === this.archive.id); |
| | | if (idx >= 0) all[idx] = JSON.parse(JSON.stringify(this.archive)); |
| | | saveArchives(all); |
| | | this.$message.success("已结案"); |
| | | this.loading = true; |
| | | return closeArchive(this.archive) |
| | | .then(() => { |
| | | this.archive.closeStatus = 1; |
| | | this.$message.success("已结案"); |
| | | }) |
| | | .catch(() => {}) |
| | | .finally(() => { this.loading = false; }); |
| | | }).catch(() => {}); |
| | | }, |
| | | }, |
| | |
| | | .info-card { margin-bottom: 0; } |
| | | .card-header { display: flex; justify-content: space-between; align-items: center; font-size: 16px; font-weight: 600; } |
| | | .header-sub { font-size: 13px; color: #909399; font-weight: normal; } |
| | | .page-title { |
| | | margin: 0 0 14px; |
| | | padding-left: 12px; |
| | | font-size: 17px; |
| | | font-weight: 600; |
| | | color: #303133; |
| | | border-left: 4px solid $primary; |
| | | } |
| | | .empty-wrap { text-align: center; padding: 100px 0; color: #c0c4cc; font-size: 16px; } |
| | | |
| | | // 蓝色分割线 + 小标题 |