You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

1799 lines
69 KiB

<template>
<div>
<!--主体-->
<div>
<div class="middlebox">
<div class="contenttitle">
体检登记 /
<span class="contenttitleBold">批量预登记</span>
</div>
</div>
<div style="margin-bottom: 15px;display: flex;justify-content: space-between;
background-color: #fff;border-radius: 8px;padding: 15px;margin-top: 7px;">
<div></div>
<div style="display: flex;">
<div style="padding: 0 5px;" v-show="checkPagePriv(pagePriv.privs, '下载导入模版')">
<a :underline="false" href="/files/单位体检人员名单导入模板.xlsx"><el-button class="commonbutton"
size="small">下载导入模版</el-button></a>
</div>
<div style="padding: 0 5px;" v-show="checkPagePriv(pagePriv.privs, '下载职业病导入模版')">
<a :underline="false" href="/files/职业病体检人员名单导入模板.xlsx"><el-button class="commonbutton"
size="small" style="width:140px;">下载职业病导入模版</el-button></a>
</div>
<div style="padding: 0 5px;" v-show="checkPagePriv(pagePriv.privs, '导入')">
<el-button class="commonbutton" @click="seq = 0" size="small">导入</el-button>
</div>
<div style="padding: 0 5px;" v-show="checkPagePriv(pagePriv.privs, '导入后结果状态导出')">
<el-button class="commonbutton" @click="btnExport('tableData')" size="small"
style="width:140px;">导入后结果状态导出</el-button>
</div>
</div>
</div>
<div id="tableData" style="padding: 15px;background-color: #fff;border-radius: 8px;">
<el-table :data="tableData" v-if="mode == '10' || mode == '30'" :row-class-name="importRowClassName"
:height="window.pageHeight < 600 ? 440 : (window.pageHeight - 210)" highlight-current-row size="small"
:summary-method="getSummaries" show-summary>
<el-table-column type="index" label="序号" width="40" align="center" />
<el-table-column prop="importState" label="导入状态" min-width="80" sortable />
<el-table-column prop="importDes" label="导入描述" min-width="180" sortable />
<el-table-column v-for="(item, index) in importCols" :key="`col${index}`" :prop="item.dispLabel" align="center"
:label="item.dataLabel || item.dispLabel" min-width="100" />
</el-table>
<el-table :data="tableData" border v-if="mode == '20'" :row-class-name="importRowClassName"
:height="window.pageHeight < 600 ? 440 : (window.pageHeight - 210)" highlight-current-row size="small"
:summary-method="getSummaries" show-summary>
<el-table-column type="index" label="序号" width="40" align="center" />
<el-table-column prop="importState" label="导入状态" min-width="80" sortable />
<el-table-column prop="importDes" label="导入描述" min-width="180" sortable />
<el-table-column prop="patientNo" align="center" label="档案号" min-width="80" />
<el-table-column prop="medicalTimes" align="center" label="体检次数" min-width="80" />
<el-table-column prop="patientName" align="center" label="姓名" min-width="80" />
<el-table-column prop="sexId" align="center" label="性别" min-width="40">
<template slot-scope="scope">
<div>{{ dddw(dict.sex, "id", scope.row.sexId, "displayName") }}</div>
</template>
</el-table-column>
<el-table-column prop="birthDate" align="center" label="出生日期" min-width="80">
<template slot-scope="scope">
<div>{{ scope.row.birthDate ? moment(new Date(scope.row.birthDate)).format('yyyy-MM-DD') : '' }}</div>
</template>
</el-table-column>
<el-table-column prop="age" align="center" label="年龄" min-width="40" />
<el-table-column prop="customerOrgParentName" align="center" label="单位" min-width="150" />
<el-table-column prop="customerOrgName" align="center" label="部门" min-width="120" />
<el-table-column prop="telephone" align="center" label="电话" min-width="100" />
<el-table-column prop="mobileTelephone" align="center" label="手机" min-width="100" />
<el-table-column prop="creatorName" align="center" label="登记人员" min-width="80" />
<el-table-column prop="creationTime" align="center" label="登记日期" min-width="80">
<template slot-scope="scope">
<div>{{ scope.row.birthDate ? moment(new Date(scope.row.creationTime)).format('yyyy-MM-DD') : '' }}</div>
</template>
</el-table-column>
</el-table>
</div>
</div>
<!--弹窗-->
<div>
<el-dialog title="请选择导入方式" :visible.sync="dialogGroup.mode" width="700px" :show-close="false" :append-to-body="true"
:close-on-click-modal="false">
<div style="height:400px;margin-left: 200px;">
<br /><el-radio v-model="mode" label="10">从Excle导入</el-radio>
<br />
<br /><el-radio v-model="mode" label="30">从Excle导入(职业病)</el-radio>
<br />
<br /><el-radio v-model="mode" label="20">从以往体检资料中导入</el-radio>
</div>
<span slot="footer" class="dialog-footer">
<el-button type="primary" @click="btnFirst" class="commonbutton">下一步</el-button>
<el-button @click="seq = -1" class="commonbutton">关闭</el-button>
</span>
</el-dialog>
<el-dialog title="导入EXCEL注意事项" :visible.sync="dialogGroup.fileReadme" width="700px" :show-close="false"
:append-to-body="true" :close-on-click-modal="false">
<div style="height:400px;padding: 0 20px; ">
<br />导入Excel时,Excel的格式必须符合一定规范,该格式的模板文件可通过下载模板获取。
<br />注意事项如下:
<br />
<div style="margin-left: 25px;">1、姓名不能为空,其余数据可根据实际情况选择是否填写。
<br />2、部门、单位分组、性别、婚姻状况、人员类别、体检类别、民族必须与本软件系统中的名称完全一致。
<br />3、年龄和出生日期可以只填一栏,系统将自动对年龄和出生日期进行相互转换。
<br />4、Excel中标题列不能有单元格合并。
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="commonbutton" type="primary" @click="seq--">上一步</el-button>
<el-button class="commonbutton" type="primary" @click="seq++">下一步</el-button>
<el-button class="commonbutton" @click="seq = -1">关闭</el-button>
</span>
</el-dialog>
<el-dialog title="选择文件" :visible.sync="dialogGroup.fileChoose" width="700px" :show-close="false"
:append-to-body="true" :close-on-click-modal="false">
<div style="height:400px;padding: 0 50px; ">
<!-- webkitdirectory 选择文件属性, multiple 多选属性-->
<div><input id="fileNames" type="file" accept=".xlsx,.xls" @change="changeFileChoose" @focus="fileGetFocus" />
</div>
<div style="margin: 5px 70px;width:240px;">
<el-table :data="sheetNames" border ref="sheetNames" height="300" row-click="chooseSheetName"
highlight-current-row size="small">
<el-table-column prop="sheetName" label="Excel表单名" min-width="200" align="center" />
</el-table>
</div>
<div style="display: flex;flex-wrap: wrap;">
<span style="margin-top: 6px;">标题行: 第</span>
<el-input type="number" v-model="readDataOpts.titleRow" size="small" style="width:60px;margin: 0 5px;" />
<span style="margin-top: 6px;">行</span>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="commonbutton" type="primary" @click="seq--">上一步</el-button>
<el-button class="commonbutton" type="primary" @click="seq++">下一步</el-button>
<el-button class="commonbutton" @click="seq = -1">关闭</el-button>
</span>
</el-dialog>
<el-dialog title="选择待导入的客户信息" :visible.sync="dialogGroup.fileDataOpr" width="700px" :show-close="false"
:close-on-click-modal="false"> <!--:append-to-body="true" -->
<div style="height:400px;">
<div style="margin-top: -10px;">
1、在标题列右击鼠标可设置列名,即:标题列有 √ 的,才参与数据导入;<br>
2、身份证号有值且合法时,将以身份证号为主自动换算性别、出生日期及年龄;<br>
3、按住 Ctr1 或 Shift 键可进行多选。<br>
</div>
<div style="margin: 5px 0px 0px;" @contextmenu.prevent=""> <!-- -->
<el-table :data="excelData" border ref="excelData" @header-contextmenu="headerContextmenu" height="340"
@row-click="chooseDataImport" row-key="id" highlight-current-row size="small"
:row-class-name="handleRowClassName">
<el-table-column type="index" align="center" label="序号" min-width="40" />
<!--
<el-table-column prop="choosed" align="center" label="选中" min-width="40"/>
-->
<el-table-column v-for="(item, index) in excelCols" :key="`col_${index}`" :prop="item.dispLabel"
align="center" :label="(item.val ? '√ ' : '') + (item.dataLabel || item.dispLabel)"
:min-width="100 + index" />
</el-table>
</div>
</div>
<span slot="footer" class="dialog-footer">
<div style="display: flex;justify-content: space-between;">
<div style="display: flex;">
<el-button class="commonbutton" type="primary" @click="btnChoose('excelData', 'all')">全选</el-button>
<el-button class="commonbutton" type="primary" @click="btnChoose('excelData')">取消全选</el-button>
</div>
<div style="display: flex;">
<el-button class="commonbutton" type="primary" @click="seq--">上一步</el-button>
<el-button class="commonbutton" type="primary" @click="seq++">下一步</el-button>
<el-button class="commonbutton" @click="seq = -1">关闭</el-button>
</div>
</div>
</span>
</el-dialog>
<el-dialog title="选择单位" :visible.sync="dialogGroup.fileDataOpts" width="700px" :show-close="false"
:close-on-click-modal="false"> <!--:append-to-body="true" -->
<div style="height:400px;">
<div style="margin-top: -10px;">
选择的人员信息必须直接属于该单位或者是该单位的一级部门,如果人员信息直接属于该单位请将Exce1文件中该人员信息的部门名称设为空
</div>
<div style="display: flex;margin:20px;">
<div>
<span>体检单位:</span>
<el-cascader v-model="customerOrgIds" :options="customerOrgTree" popper-class="example" style="width:260px;"
@change="changeCustomerOrg" filterable
:props="{ checkStrictly: true, expandTrigger: 'hover', ...customerOrg.treeprops, }"
:show-all-levels="true" size="small">
</el-cascader>
</div>
<div style="margin-left: 20px">
<span>单位体检次数:</span>
<el-select v-model="customerOrgRegister" placeholder="次数" style="width: 60px; margin-left: 10px"
size="small" value-key="id">
<el-option v-for="item in customerOrgRegisterList" :key="item.id" :label="item.medicalTimes"
:value="item" />
</el-select>
</div>
</div>
<div style="display: flex;margin:20px;">
<span>相同姓名的人员:</span>
<div style="display: flex;margin-top:20px;">
<el-radio v-model="dataImportOpts.nameType" label="1">同名病人提示</el-radio>
<el-radio v-model="dataImportOpts.nameType" label="2">本单位同名提示</el-radio>
<el-radio v-model="dataImportOpts.nameType" label="3">不提示</el-radio>
</div>
</div>
<div style="display: flex;margin:20px;">
<span>登记状态:</span>
<div style="display: flex;margin-top:20px;">
<el-radio v-model="dataImportOpts.completeFlag" label="0">预登记</el-radio>
<el-radio v-model="dataImportOpts.completeFlag" label="1">正式登记</el-radio>
</div>
</div>
<!-- 2024-04-09 取消此选项 -->
<div style="display: flex;margin:20px;" v-if="false">
<span>工卡号:</span>
<div style="display: block;margin-top:20px;">
<div style="display: flex;">
<el-checkbox v-model="dataImportOpts.isAutoCreatePatientNo" />
<span style="margin-left:5px;">工卡号作为档案号</span>
</div>
<div style="display: flex;" v-if="dataImportOpts.isAutoCreatePatientNo">
<span style="margin-top:6px;">工卡号开始位置:</span>
<el-input type="number" v-model="dataImportOpts.cardStartNum" size="small"
style="width:60px;margin: 0 10px 0 0;" />
<span style="margin-top:6px;">长度:</span>
<el-input type="number" v-model="dataImportOpts.cardLength" size="small"
style="width:60px;margin: 0 10px 0 0;" />
<span style="margin-top:6px;"> 不足长度时,前面补0</span>
</div>
</div>
</div>
<div style="display: flex;margin:20px;">
<span>是否自动创建部门:</span>
<el-checkbox v-model="dataImportOpts.isAutoCreateDepartment" />
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="commonbutton" type="primary" @click="seq--">上一步</el-button>
<el-button class="commonbutton" type="primary" @click="btnImport">确定导入</el-button>
<el-button class="commonbutton" @click="seq = -1">关闭</el-button>
</span>
</el-dialog>
<el-dialog title="同名人员信息确认" :visible.sync="dialogSameMan" width="500px" :show-close="false"
:close-on-click-modal="false"> <!--:append-to-body="true" -->
<div style="margin: 5px 0px 0px;"> <!-- -->
<el-table :data="sameMans" border ref="sameMans" height="260" @row-click="rowClickSameMan" row-key="patientId"
highlight-current-row size="small">
<el-table-column type="index" align="center" label="序号" min-width="40" />
<el-table-column prop="patientNo" align="center" label="档案号" min-width="80" />
<el-table-column prop="displayName" align="center" label="姓名" min-width="80" />
<el-table-column prop="sexId" align="center" label="性别" min-width="40" />
<el-table-column prop="idNo" align="center" label="身份证号" min-width="150" />
<el-table-column prop="birthDate" align="center" label="出生日期" min-width="110" />
<el-table-column prop="telephone" align="center" label="电话" min-width="100" />
<el-table-column prop="mobileTelephone" align="center" label="手机" min-width="100" />
</el-table>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="commonbutton" type="primary" @click="btnOldMan">按档案人员导入</el-button>
<el-button class="commonbutton" type="primary" @click="btnNewMan">按新人方式导入</el-button>
</span>
</el-dialog>
<!--从历史数据库中查询导入-->
<el-dialog title="选择单位查询条件" :visible.sync="dialogGroup.query" width="700px" :show-close="false"
:close-on-click-modal="false"> <!--:append-to-body="true" -->
<div style="height:400px;">
<div style="margin-top: -10px;">
选择单位时必须选择其体检次数
</div>
<div style="display: flex;margin:20px;">
<span class="spanLeftClass">体检单位:</span>
<el-cascader v-model="query.customerOrgIds" :options="customerOrgTree" style="width:260px;"
@change="changeQueryCustomerOrg" filterable popper-class="example"
:props="{ checkStrictly: true, expandTrigger: 'hover', ...customerOrg.treeprops, }" :show-all-levels="true"
size="small">
</el-cascader>
<div style="margin-left: 20px">
<span>单位体检次数:</span>
<el-select v-model="query.customerOrgRegister" placeholder="次数" style="width: 60px; margin-left: 10px"
size="small" value-key="id">
<el-option v-for="item in query.customerOrgRegisterList" :key="item.id" :label="item.medicalTimes"
:value="item" />
</el-select>
</div>
</div>
<div style="display: flex;margin:20px;">
<span class="spanLeftClass">登记日期:</span>
<el-date-picker v-model="query.startDate" type="date" placeholder="起始日期" size="small" style="width:130px;" />
<span class="spanMidClass">至</span>
<el-date-picker v-model="query.endDate" type="date" placeholder="截止日期" size="small" style="width:130px;" />
</div>
<div style="display: flex;margin:20px;">
<span class="spanLeftClass">档案号:</span>
<el-input placeholder="起始档案号" v-model="query.patientNoStart" size="small" clearable style="width: 130px" />
<span class="spanMidClass">至</span>
<el-input placeholder="截止档案号" v-model="query.patientNoEnd" size="small" clearable style="width: 130px" />
</div>
<div style="display: flex;margin:20px;">
<span class="spanLeftClass">姓名:</span>
<el-input placeholder="姓名" v-model="query.patientName" size="small" clearable style="width: 130px" />
<span class="spanMidClass">性别:</span>
<el-select v-model="query.sexId" placeholder="请选择" style="width: 130px" size="small">
<el-option label="全部" value="A" />
<el-option v-for="item in dict.sex" :key="item.id" :label="item.displayName" :value="item.id" />
</el-select>
</div>
<div style="display: flex;margin:20px;">
<span class="spanLeftClass">状态:</span>
<el-select v-model="query.completeFlag" placeholder="请选择" clearable style="width: 130px" size="small">
<el-option v-for="item in dict.completeFlag" :key="item.id" :label="item.displayName" :value="item.id" />
</el-select>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="commonbutton" type="primary" @click="seq--">上一步</el-button>
<el-button class="commonbutton" type="primary" @click="seq++">下一步</el-button>
<el-button class="commonbutton" @click="seq = -1">关闭</el-button>
</span>
</el-dialog>
<!--选择历史档案客户信息-->
<el-dialog title="选择历史档案客户信息" :visible.sync="dialogGroup.oldMansChoose" width="700px" :show-close="false"
:close-on-click-modal="false"> <!--:append-to-body="true" -->
<div style="height:400px;">
<div style="margin-top: -10px;">
按住 Ctr1 或 Shift 键可进行多选<br>
</div>
<div style="margin: 5px 0px 0px;"> <!-- -->
<el-table :data="prList" border ref="prList" height="375" @row-click="rowClickPrList" highlight-current-row
size="small" :row-class-name="handleRowClassName">
<el-table-column type="index" align="center" label="序号" min-width="40" />
<el-table-column prop="patientNo" align="center" label="档案号" min-width="80" />
<el-table-column prop="medicalTimes" align="center" label="体检次数" min-width="80" />
<el-table-column prop="patientName" align="center" label="姓名" min-width="80" />
<el-table-column prop="sexId" align="center" label="性别" min-width="40">
<template slot-scope="scope">
<div>{{ dddw(dict.sex, "id", scope.row.sexId, "displayName") }}</div>
</template>
</el-table-column>
<el-table-column prop="birthDate" align="center" label="出生日期" min-width="80">
<template slot-scope="scope">
<div>{{ scope.row.birthDate ? moment(new Date(scope.row.birthDate)).format('yyyy-MM-DD') : '' }}</div>
</template>
</el-table-column>
<el-table-column prop="age" align="center" label="年龄" min-width="40" />
<el-table-column prop="customerOrgParentName" align="center" label="单位" min-width="150" />
<el-table-column prop="customerOrgName" align="center" label="部门" min-width="120" />
<el-table-column prop="telephone" align="center" label="电话" min-width="100" />
<el-table-column prop="mobileTelephone" align="center" label="手机" min-width="100" />
<el-table-column prop="creatorName" align="center" label="登记人员" min-width="80" />
<el-table-column prop="creationTime" align="center" label="登记日期" min-width="80">
<template slot-scope="scope">
<div>{{ scope.row.birthDate ? moment(new Date(scope.row.creationTime)).format('yyyy-MM-DD') : '' }}
</div>
</template>
</el-table-column>
<!--
"patientRegisterNo": "T4724",
"patientId": "3a0eeeeb-55b6-86d7-a578-a9c9e332e7ed",
"medicalTimes": 1,
"customerOrgId": "3a0eeeeb-5647-6fee-6052-c3c8cde65b92",
"customerOrgGroupId": "3a0e77cf-dfb7-2c35-1310-982136ca6c0c",
"medicalPackageId": null,
"patientName": "刘一",
"sexId": "M",
"birthDate": "10/1/1967",
"age": 57,
"jobCardNo": null,
"medicalCardNo": null,
"maritalStatusId": "9",
"medicalTypeId": null,
"personnelTypeId": null,
"jobPost": null,
"jobTitle": null,
"photo": null,
"salesman": null,
"sexHormoneTermId": null,
"interposeMeasure": null,
"medicalConclusionId": "00000000-0000-0000-0000-000000000000",
"reportPrintTimes": 0,
"isUpload": "N",
"completeFlag": "0",
"isMedicalStart": "N",
"medicalStartDate": "11/16/2023",
"isRecoverGuide": "N",
"summaryDate": "",
"summaryDoctor": null,
"isAudit": "N",
"auditDoctor": null,
"auditDate": "",
"isLock": "N",
"isNameHide": "N",
"isPhoneFollow": "N",
"isVip": "N",
"thirdInfo": null,
"guidePrintTimes": null,
"remark": null,
"medicalCenterId": "68f2d834-2bf0-4978-ad54-d2133c12a333",
"customerOrgRegisterId": "3a0d5dfa-3e3f-b781-6d82-779e872d1b2a",
"patientNo": "T4719",
"patientPassword": "",
"displayName": "刘一",
"nationId": null,
"birthPlaceId": null,
"idNo": null,
"postalCode": null,
"email": null,
"telephone": "15510826***",
"mobileTelephone": null,
"address": null,
"customerOrgName": "部1",
"customerOrgParentId": "3a0c5101-a6a6-e48a-36ec-33e7567a99e6",
"customerOrgParentName": "神豚集团",
"creatorName": "",
"lastModifierName": "",
"lastModificationTime": "2023-11-17T18:05:53.63381",
"lastModifierId": "3a0c4180-107c-0c89-b25b-0bd34666dcec",
"creationTime": "2023-11-17T18:05:53.633769",
"creatorId": "3a0c4180-107c-0c89-b25b-0bd34666dcec",
"id": "3a0eeeeb-565d-8a44-a2b7-a1c81cf43f2d"
-->
</el-table>
</div>
</div>
<span slot="footer" class="dialog-footer">
<div style="display: flex;justify-content: space-between;">
<div style="display: flex;">
<el-button class="commonbutton" type="primary" @click="btnChoose('prList', 'all')">全选</el-button>
<el-button class="commonbutton" type="primary" @click="btnChoose('prList')">取消全选</el-button>
</div>
<div style="display: flex;">
<el-button class="commonbutton" type="primary" @click="seq--">上一步</el-button>
<el-button class="commonbutton" type="primary" @click="seq++">下一步</el-button>
<el-button class="commonbutton" @click="seq = -1">关闭</el-button>
</div>
</div>
</span>
</el-dialog>
<el-dialog title="选择单位" :visible.sync="dialogGroup.oldMansOpts" width="700px" :show-close="false"
:close-on-click-modal="false"> <!--:append-to-body="true" -->
<div style="height:400px;">
<div style="margin-top: -10px;margin-left: 20px;">
如果是新单位或部门,选择的病人将直接导入该单位而不是其子单位
</div>
<div style="display: flex;margin:20px;">
<div style="margin:7px 0;">
<el-radio v-model="newCustomerOrgFlag" :label="false">单位或部门不变</el-radio>
<el-radio v-model="newCustomerOrgFlag" :label="true">新单位或部门</el-radio>
</div>
<div style="margin-left:5px;" v-if="newCustomerOrgFlag">
<el-cascader v-model="customerOrgIds" :options="customerOrgTree" popper-class="example" style="width:260px;"
@change="changeCustomerOrg" filterable
:props="{ checkStrictly: true, expandTrigger: 'hover', ...customerOrg.treeprops, }"
:show-all-levels="true" size="small">
</el-cascader>
</div>
</div>
<div style="margin-top: 20px;margin-left:20px;">
<span>单位体检次数:</span>
<el-select v-model="customerOrgRegister" placeholder="次数" style="width: 80px;" size="small" value-key="id">
<el-option v-for="item in customerOrgRegisterList" :key="item.id" :label="item.medicalTimes"
:value="item" />
</el-select>
</div>
<div style="margin-top: 20px;margin-left:20px;">
<span>单位体检分组:</span>
<el-select v-model="curGroup" filterable clearable value-key="id" style="width:192px;" placeholder="请选择分组"
size="small">
<el-option v-for="item in groups" :key="item.id" :label="item.displayName" :value="item" />
</el-select>
</div>
<div style="margin-top:20px;margin-left:20px;">
<span>登记状态:</span>
<el-radio v-model="dataImportOpts.completeFlag" label="0">预登记</el-radio>
<el-radio v-model="dataImportOpts.completeFlag" label="1">正式登记</el-radio>
</div>
<div style="margin-top:20px;margin-left:20px;">
<span>支付方式:</span>
<el-select v-model="payTypeFlag" placeholder="请选择" style="width: 130px" size="small">
<el-option v-for="item in dict.payType" :key="item.id" :label="item.displayName" :value="item.id" />
</el-select>
</div>
</div>
<span slot="footer" class="dialog-footer">
<el-button class="commonbutton" type="primary" @click="seq--">上一步</el-button>
<el-button class="commonbutton" type="primary" @click="btnImportFromDataBase">确定导入</el-button>
<el-button class="commonbutton" @click="seq = -1">关闭</el-button>
</span>
</el-dialog>
<!-- 通用进度条 -->
<el-dialog title="数据处理中……" :visible.sync="elProgress.display" width="700px" height="400" :show-close="false"
:close-on-click-modal="false" :append-to-body="true">
<ElProgressOCX />
</el-dialog>
</div>
</div>
</template>
<script>
import moment from "moment"
import { mapState, mapActions } from "vuex";
import { read, readFile, utils } from "xlsx";
import FileSaver from 'file-saver';
import { getapi, postapi, putapi, deletapi } from "@/api/api";
import { getPagePriv, checkPagePriv, deepCopy, arrayExistObj, arrayFilter, dddw, tcdate } from '../../utlis/proFunc';
import ElProgressOCX from "../../components/report/ElProgressOCX.vue";
export default {
components: {
ElProgressOCX,
},
data() {
return {
pagePriv: {
routeUrlorPageName: 'patientRegisterBatch', //当前页面归属路由或归属页面权限名称
privs: [] // 页面权限
},
customerOrgTree: [],
customerOrgIds: [], //选中单位节点
customerOrgRegisterList: [], //体检次数列表
customerOrgRegister: {}, //体检次数
peisid: null,
startPoint: -1, // 多选起点 -1 表示未选择
endPoint: -1, // 多选终点 -1 表示未选择
rClickRow: null, //右击的行
rClickColumn: null, //右击的列(预留)
dialogGroup: {
mode: true, //选模式 10 开始 文件导入,20开始 从数据库中导入
fileReadme: false, //导入EXCEL注意事项
fileChoose: false, //选择文件
fileDataOpr: false, //文件数据分析操作
fileDataOpts: false, //文件数据导入前参数设定
query: false, //单位查询条件
oldMansChoose: false, //选择历史数据导入
oldMansOpts: false, //历史数据导入前参数设定
},
oldSeq: -2, //旧的步骤(辅助区分上一步,下一步)
seq: 0, //当前显示窗口
mode: '10', //模式 10 开始 文件导入,20开始 从数据库中导入 ,30 开始职业病
excelCols: [{ dispLabel: '', val: '', dataLabel: '' }], //excel数据列名 {dispLabel:'',val:'',dataLabel:''}
importCols: [], //实际导入的列(即有设置与 dataCols 匹配的列)
excelData: [], //excel表格数据
choosedData: [], // 选中的待导入的数据
dataCols: [
{ dispLabel: '不设置', val: '' },
{ dispLabel: '工卡号', val: 'jobCardNo' },
{ dispLabel: '部门', val: 'departmentName' },
{ dispLabel: '分组', val: 'customerOrgGroupName' },
{ dispLabel: '姓名', val: 'patientName' },
{ dispLabel: '性别', val: 'sexName' },
{ dispLabel: '年龄', val: 'age' },
{ dispLabel: '出生日期', val: 'birthDate' },
{ dispLabel: '婚姻状况', val: 'maritalStatusName' },
{ dispLabel: '民族', val: 'nationName' },
{ dispLabel: '身份证号', val: 'idNo' },
{ dispLabel: '体检卡号', val: 'medicalCardNo' },
{ dispLabel: '电话', val: 'telephone' },
{ dispLabel: '手机', val: 'mobileTelephone' },
{ dispLabel: '电子邮件', val: 'email' },
{ dispLabel: '邮编', val: 'postalCode' },
{ dispLabel: '地址', val: 'address' },
{ dispLabel: '职务', val: 'jobPost' },
{ dispLabel: '职称', val: 'jobTitle' },
{ dispLabel: '人员类别', val: 'personnelTypeName' },
{ dispLabel: '体检类别', val: 'medicalTypeName' },
{ dispLabel: '工种', val: 'jobType' },
{ dispLabel: '检查类别', val: 'ocCheckTypeName' },
{ dispLabel: '接害因素', val: 'poisons' },
{ dispLabel: '备注', val: 'remark' },
{ dispLabel: '介绍人', val: 'salesman' },
{ dispLabel: '支付方式', val: 'payTypeFlag' },
],
masterCols:{}, // 批量导入必填的项目
tableData: [], //导入数据状态显示
workBook: null, //EXCEL 工作薄
sheetNames: [], //EXCEL 工作薄中的表单 {sheetName:}
readDataOpts: {
file: '', //选中的文件名
sheetNameChoosed: '', //当前选中的表格
titleRow: 1, //标题行
},
readDataOptsInit: {},
dataImportOpts: {
customerOrgId: '', //单位ID
nameType: '2', //同名病人处理(1.同名病人提示,只要存在同名就提示 2.本单位同名提示,单位内部同名就提示 3.不提示,所有数据创建)
completeFlag: '0', //完成标志 0:预登记 1:未检 2:部份已检 3:已总检 默认未检
isAutoCreateDepartment: true, // 是否自动创建部门 Y N( N:按名字查找部门,如果未找到就提示 Y:未找到就创建)
isAutoCreatePatientNo: false, // 工卡号作为档案号 Y/N (根据工卡号生成,可以指定起始位置跟位数)
cardStartNum: 1,
cardLength: 6,
startRow: 0, //从 excelData 的第几行开始导入
},
dataImportOptsInit: {},
dialogSameMan: false, //同名人员确认窗口
sameMans: [], //同名人员列表
choosedSameMan: {}, // 当前选中同名人员信息
query: { //单位查询条件
customerOrgIds: [],
customerOrgId: '',
customerOrgRegisterList: [],
customerOrgRegister: {},
customerOrgRegisterId: '',
startDate: null,
endDate: null,
startPatientNo: '',
endPatientNo: '',
patientName: '',
sexId: 'A',
completeFlag: '',
},
prList: [], //查询出符合条件的历史档案人员信息
groups: [], //体检分组列表
curGroup: null, //当前选中要导入的分组 {}
newCustomerOrgFlag: false, // [false]单位或部门不变 or [true]新单位或部门
payTypeFlag: '1', // 默认单位
};
},
//组件创建完成,一般页面初始布局放在这里
created() {
//获取用户当前页面的权限
let userPriv = window.sessionStorage.getItem('userPriv')
if (userPriv) this.pagePriv.privs = deepCopy(getPagePriv(this.pagePriv.routeUrlorPageName))
if (!checkPagePriv(this.pagePriv.privs, '导入')) this.seq = -1
this.peisid = window.sessionStorage.getItem('peisid');
if (!this.peisid || this.peisid == 'null') {
this.seq = -1
}
this.readDataOptsInit = Object.assign({}, this.readDataOpts)
this.dataImportOptsInit = Object.assign({}, this.dataImportOpts)
},
//页面挂载完成,一般页面渲染数据放在这里
mounted() {
this.dictInit()
},
computed: {
...mapState(["window", "dict", "elProgress", "patientRegister", "customerOrg"]),
},
methods: {
dddw, moment, checkPagePriv,
dictInit() {
// 获取单位列表树
this.getCustomerOrgTree()
//性别(查询 仅档案用)
getapi("/api/app/sex").then((res) => {
if (res.code == 1) {
this.dict.sex = res.data;
}
});
// 获取系统参数 -- 人员登记必填列
postapi('/api/app/SysParmValue/GetSysParmValueBySysParmId', { sysParmId: 'patient_register_required_field' })
.then(res => {
if (res.code > -1) {
try {
this.masterCols = JSON.parse(res.data)
} catch (error) {
console.error(error)
}
}
})
.finally(() => {
this.masterCols.patientName = "姓名"
})
},
//清空进度数据数据
clearProcess() {
let elo = document.getElementById('fileNames')
if(elo) elo.value = ''; // 清空选择的文件
this.workBook = null //EXCEL 工作薄
this.sheetNames = [] //EXCEL 工作薄中的表单 {sheetName:}
this.readDataOpts = Object.assign({}, this.readDataOptsInit)
this.dataImportOpts = Object.assign({}, this.dataImportOptsInit)
this.customerOrgIds = [] //选中单位节点
this.customerOrgRegisterList = [] //体检次数列表
this.customerOrgRegister = {} //体检次数
this.startPoint = -1 // 多选起点 -1 表示未选择
this.endPoint = -1 // 多选终点 -1 表示未选择
},
// 获取单位列表树
getCustomerOrgTree() {
getapi("/api/app/customerorg/getbycodeall?IsHidePerson=1").then((res) => {
// console.log("res.data", res.data);
if (res.code != -1) {
this.customerOrgTree = res.data;
let lfind = arrayExistObj(this.customerOrgTree, 'id', this.dict.personOrgId)
if (lfind > -1) this.customerOrgTree.splice(lfind, 1)
tcdate(this.customerOrgTree)
}
});
},
//选择单位
changeCustomerOrg(v) {
this.chooseCustomerOrg(v)
},
//选择单位查询条件
changeQueryCustomerOrg(v) {
this.chooseCustomerOrg(v, 'query')
},
chooseCustomerOrg(v, obj) {
let id = ''
if (typeof v == 'string') {
id = v
} else {
id = v[0]
}
getapi(
`/api/app/customerorgregister/getlistincustomerorgid?CustomerOrgId=${id}`
).then((res) => {
if (res.code != -1) {
if (obj == 'query') {
this.query.customerOrgRegisterList = res.data
if (this.query.customerOrgRegisterList.length > 0) {
this.query.customerOrgRegister = this.query.customerOrgRegisterList[this.query.customerOrgRegisterList.length - 1];
} else {
this.query.customerOrgRegister = {};
// this.customerOrgGroups = [];
}
}
this.customerOrgRegisterList = arrayFilter(res.data, 'isComplete', 'N') //不显示已完成的体检次数
if (this.customerOrgRegisterList.length > 0) {
this.customerOrgRegister = this.customerOrgRegisterList[this.customerOrgRegisterList.length - 1];
// this.getCustomerOrgGroup(this.customerOrgRegister.id);
} else {
this.customerOrgRegister = {};
// this.customerOrgGroups = [];
}
}
});
},
//第一次点下一步
btnFirst() {
if (!this.peisid || this.peisid == 'null') {
this.$message.warning("该用户未选归属体检中心,不能执行此操作!");
return
}
this.seq = parseInt(this.mode)
},
// 导入过程 上一步,下一步
async btnProcess(seq) {
let keys = Object.keys(this.dialogGroup)
let count = 0 //选中待导入的人员数
if (seq == 9 || seq == 29) {
this.workBook = null
this.sheetNameChoosed = ''
seq = 0
}
if (seq == 19) seq = 0
// console.log('keys',keys)
switch (seq) {
case -1:
//关闭所有弹窗
keys.forEach(e => {
this.dialogGroup[e] = false
})
this.clearProcess()
break;
case 0:
//显示 选择导入方式
keys.forEach(e => {
if (e == 'mode') {
this.dialogGroup[e] = true
} else {
this.dialogGroup[e] = false
}
})
this.excelCols = []
this.tableData = []
this.prList = []
this.startPoint = -1 // 多选起点 -1 表示未选择
this.endPoint = -1 // 多选终点 -1 表示未选择
break;
case 10:
case 30:
//显示 EXCEL 导入
keys.forEach(e => {
if (e == 'fileReadme') {
this.dialogGroup[e] = true
} else {
this.dialogGroup[e] = false
}
})
break;
case 11:
case 31:
//显示 文件选择 窗口
keys.forEach(e => {
if (e == 'fileChoose') {
this.dialogGroup[e] = true
} else {
this.dialogGroup[e] = false
}
})
break;
case 12:
case 32:
// 从后面退回时,无需读数据
if (this.oldSeq < seq) {
if (!this.readData()) {
this.seq--
break;
}
}
//显示 数据分析操作 窗口
keys.forEach(e => {
if (e == 'fileDataOpr') {
this.dialogGroup[e] = true
} else {
this.dialogGroup[e] = false
}
})
break;
case 13:
case 33:
count = 0
this.excelData.forEach(e => {
if (e.choosed) count++
})
if (count == 0) {
this.$message.warning("未选中要导入的记录")
this.seq--
break;
}
//显示 文件数据导入前参数设定 窗口
keys.forEach(e => {
if (e == 'fileDataOpts') {
this.dialogGroup[e] = true
} else {
this.dialogGroup[e] = false
}
})
break;
case 20:
//显示 单位查询条件 导入
keys.forEach(e => {
if (e == 'query') {
this.dialogGroup[e] = true
} else {
this.dialogGroup[e] = false
}
})
break;
case 21:
//显示 选择要导入的 档案人员
if (this.oldSeq < seq) {
if (!await this.getPrList()) {
console.log('this.seq break', this.seq)
this.seq--
break
}
}
keys.forEach(e => {
if (e == 'oldMansChoose') {
this.dialogGroup[e] = true
} else {
this.dialogGroup[e] = false
}
})
break;
case 22:
//显示 选择新的体检单位及分组
count = 0
this.prList.forEach(e => {
if (e.choosed) count++
})
if (count == 0) {
this.$message.warning("未选中要导入的记录")
this.seq--
break;
}
keys.forEach(e => {
if (e == 'oldMansOpts') {
this.dialogGroup[e] = true
} else {
this.dialogGroup[e] = false
}
})
break;
default:
break;
}
},
//导入完后,导入状态显示
importRowClassName({ row, rowIndex }) {
if (row.importState == '导入失败') {
return "danger";
} else {
return "";
}
},
//多选 颜色标记
handleRowClassName({ row, rowIndex }) {
if (row.choosed) {
return "current-row";
} else {
return "";
}
},
// 导入完后,状态统计
getSummaries(param) {
const { columns, data } = param;
const sumCol = [2]; //需合计的列
const sums = [];
let success = 0, fail = 0;
columns.forEach((column, index) => {
//显示合计列
if (index === 1) {
sums[index] = "导入合计";
return;
}
//不合计的列
if (sumCol.indexOf(index) == -1) {
sums[index] = "";
return;
}
data.forEach((item) => {
console.log('item,column.property',item,column.property)
if (item[column.property]) {
fail++
} else {
success++
}
});
});
sums[2] = `成功:${success} 条,失败:${fail} 条。`
return sums;
},
//清除所选文件
fileGetFocus(e) {
console.log('fileGetFocus(e)', e)
e.value = '' //未起作用的
// e.target.files = []
},
// 获取选择的文件
changeFileChoose(e) {
if (e.target.files.length <= 0) return;
// console.log('file',e.target.files[0])
this.readDataOpts.file = e.target.files[0];
// 调用导入Excel文件的方法
// File {name: 'vulkan-1.dll',
// console.log('file',file,file.type)
let fileName = this.readDataOpts.file.name.split('.')
let fileNameExt = fileName[fileName.length - 1].toLowerCase()
if (fileNameExt != 'xls' && fileNameExt != 'xlsx') {
this.$message.warning("你选的文件可能不是标准的Excel文件!")
}
this.readFile(this.readDataOpts.file);
},
//sheetjs 读取文件
readFile(file) {
const reader = new FileReader();
// reader.readAsArrayBuffer(file);
// 定义读取文件
reader.onload = (e) => {
let data = e.target.result;
// let typedArray = new Uint8Array(data);
// var workBook = read(typedArray,{type:'array'})
// this.workBook = read(data,{type:'binary',cellDates:true}) //日期将转成 标准 日期格式,显示会 undefined
this.workBook = read(data, { type: 'binary' })
// var workBook = readFile(file); //后端读法
this.sheetNames = []
this.workBook.SheetNames.forEach(e => {
this.sheetNames.push({ sheetName: e })
})
this.$nextTick(() => {
this.$refs['sheetNames'].setCurrentRow(this.sheetNames[0]);
this.chooseSheetName(this.sheetNames[0])
})
}
// 错误处理
reader.onerror = function (event) {
// 读取失败时执行的代码
console.error("File could not be read!" + event.target.error);
};
reader.readAsBinaryString(file);
},
//选择要导入的Excel表单名
chooseSheetName(row) {
this.readDataOpts.sheetNameChoosed = row.sheetName
},
//读取数据
readData() {
let ret = 1
if (!this.readDataOpts.file || !this.workBook || !this.readDataOpts.sheetNameChoosed) {
this.$message.warning("请选择文件及要导入的表格")
return 0
}
if (this.readDataOpts.titleRow <= 0) {
this.$message.warning("标题行不能小于1")
return 0
}
let worksheet = this.workBook.Sheets[this.readDataOpts.sheetNameChoosed];
//分析标题信息
let head = utils.sheet_to_json(worksheet, { header: 1 });
this.excelCols = []
head[this.readDataOpts.titleRow - 1].forEach(e => {
let lfind = arrayExistObj(this.dataCols, 'dispTitle', e), val = '', dataLabel = '';
if (lfind > -1) {
val = this.dataCols[lfind].val
dataLabel = this.dataCols[lfind].dataLabel
}
this.excelCols.push({
dispLabel: e,
val,
dataLabel
})
})
//console.log('head,',head,this.excelCols)
this.excelData = utils.sheet_to_json(worksheet, { raw: false, range: this.readDataOpts.titleRow - 1 }); //raw:false,range:1 从第1行开始读取
this.excelData.forEach((e, index) => {
e.choosed = false;
e.index = index;
e.id = 'excelData' + index;
});
//console.log('this.excelCols',this.excelCols)
// console.log('sheet_to_json excelData',this.excelData)
// 导入后,批量分析Excel列 与 数据字段 的匹配关系
this.parseExcelData()
return ret
},
//选择要导入的数据
chooseDataImport(row) {
// console.log("this.excelData",this.excelData);
// 按住了shift键
if (this.window.shift) {
//清除所有选择
this.excelData.forEach((e, index) => {
e.choosed = false;
e.index = index;
});
if (this.startPoint == -1) {
this.excelData[row.index].choosed = true;
this.startPoint = row.index;
} else {
if (this.startPoint > row.index) {
for (let i = row.index; i <= this.startPoint; i++) {
this.excelData[i].choosed = true;
}
} else if (this.startPoint <= row.index) {
for (let i = this.startPoint; i <= row.index; i++) {
this.excelData[i].choosed = true;
}
}
}
} else if (this.window.ctrl) { // 按住了ctrl 键
this.excelData[row.index].choosed = true;
if (this.startPoint == -1) {
this.startPoint = row.index;
}
} else {
// 未按住了ctrl 、shift 键
//清除所有选择
console.log("清除所有选择");
this.excelData.forEach((e, index) => {
e.choosed = false;
e.index = index;
});
// console.log(this.excelData,row.index);
// console.log(this.excelData[row.index].choosed);
this.excelData[row.index].choosed = true;
this.startPoint = row.index;
}
},
// 全选(取消全选)
btnChoose(refName, type) {
let choosed = false
if (type && type == 'all') {
choosed = true
}
this[refName].forEach(e => {
e.choosed = choosed
if (choosed) {
this.$refs[refName].setCurrentRow(e)
}
})
if (!choosed) {
this.$refs[refName].setCurrentRow()
}
},
//右击标题
headerContextmenu(column, event) {
let chooseCol = column.minWidth - 100
let items = [] //菜单
this.dataCols.forEach(e => {
items.push({
label: e.dispLabel,
onClick: () => {
this.setColumn(chooseCol, e)
},
})
})
//右击显示的菜单
this.$contextmenu({
items,
event,
//x: event.clientX,
//y: event.clientY,
customClass: "custom-class",
zIndex: 30000, //够大再能在最上面显示
minWidth: 80,
height: 20
});
return false;
},
//设置真实数据字段列
setColumn(oldColNum, newColObj) {
// console.log('oldColNum,newColObj',oldColNum,newColObj)
//如果数据字段已设置过,则将之前设置的先清空
if (newColObj.dispLabel != "不设置") {
let lfind = arrayExistObj(this.excelCols, 'dataLabel', newColObj.dispLabel)
if (lfind > -1) {
this.excelCols[lfind].dataLabel = ''
this.excelCols[lfind].val = ''
}
}
this.excelCols[oldColNum].dataLabel = newColObj.dispLabel
this.excelCols[oldColNum].val = newColObj.val
// console.log('newColObj.val',newColObj.val)
let tempDate = ''
if (newColObj.val == 'birthDate') {
this.excelData.forEach(e => {
tempDate = e[this.excelCols[oldColNum].dispLabel]
// console.log('birthDate',tempDate)
e[this.excelCols[oldColNum].dispLabel] = tempDate ? moment(new Date(tempDate)).format('yyyy-MM-DD') : ''
})
}
},
// 选择EXCEL文件后,批量分析Excel列 与 数据字段 的匹配关系
parseExcelData() {
let lfind = -1
this.excelCols.forEach((e, i) => {
lfind = arrayExistObj(this.dataCols, 'dispLabel', e.dispLabel)
if (lfind > -1) this.setColumn(i, this.dataCols[lfind])
});
},
// 确定导入数据库
btnImport() {
if (!this.customerOrgIds || this.customerOrgIds.length == 0) {
this.$message.warning("请选择单位")
return
}
if (!this.customerOrgRegister || !this.customerOrgRegister.id) {
this.$message.warning("请选择单位体检次数")
return
}
this.elProgress.display = true;
this.elProgress.percentage = 0;
this.importCols = []
this.excelCols.forEach(e => {
if (e.val) {
this.importCols.push(e)
}
})
this.tableData = [] // 记录导入后结果状态
this.choosedData = [] //选中待导入的数据
this.excelData.forEach(e => {
if (e.choosed) this.choosedData.push(e)
});
//导入进行中
this.importing(this.dataImportOpts.startRow, this.dataImportOpts.nameType)
// 开始导入时,清除选择的 文件
document.getElementById('fileNames').value = '';
},
// 导入必填项验证
checkValide(body){
let msg = ''
// patientName,personnelTypeName,medicalTypeName,salesman
let keys = Object.keys(this.masterCols)
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
switch (key) {
case 'patientName':
case 'name':
if(!body.patientName) msg = this.masterCols[key] + ' 未填值'
break;
case 'medicalTypeId': //体检类别
if(!body.medicalTypeName) msg = this.masterCols[key] + ' 未填值'
break;
case 'personnelTypeId': //人员类别
if(!body.personnelTypeName) msg = this.masterCols[key] + ' 未填值'
break;
case 'salesman': //介绍人
if(!body.salesman) msg = this.masterCols[key] + ' 未填值'
break;
default:
break;
}
if(msg) break;
}
return msg
},
//导入进行时
// startRow : 从第几行开始导入,同名判断交互时,续接导入
// startRowNameType : 续接导入的第1行,执行 同名判断模式, 3.不提示,按新人导入(前端不用管)
async importing(startRow, startRowNameType) {
let body = {}
for (let i = startRow; i < this.choosedData.length; i++) {
this.elProgress.percentage = Math.floor(
((i + 1) * 100) / this.choosedData.length
);
// 将Excel的数据转换成接口的数据
body = this.excelDataToApiBody(this.choosedData[i])
if (i == startRow) body.nameType = startRowNameType
console.log(`this.choosedData[${i}],startRowNameType,body`)
// 判断是否必填:
let msg = this.checkValide(body)
if(msg){
this.tableData.push(Object.assign({ importState: '导入失败', importDes: msg }, this.choosedData[i]))
}else{
try {
// 同一人判断
if (this.choosedSameMan.patientNo) {
// 上一次循环已经判断是否同一人,此次循环不需再判断了
if (this.choosedSameMan.patientNo == '$newPatient$') {
body.nameType = '3'
} else {
body.patientNo = this.choosedSameMan.patientNo
}
} else if (startRowNameType != '3') {
let result = await this.isSamePatient(startRowNameType, body)
if (result.isContinue) {
if (result.err) {
this.tableData.push(Object.assign({ importState: '导入失败', importDes: result.err }, this.choosedData[i]))
}
} else {
this.dataImportOpts.startRow = i
break; // 跳出循环,重新从 i 开执行 this.importing
}
}
// 旧接口:/api/app/patientregister/createpatientregisterexcel
let res = await postapi('/api/app/patientregister/CreatePatientRegisterFromExcel', body)
this.choosedSameMan = {} // 清除选择同一人员的记录
if (res.code >= 0) {
this.tableData.push(Object.assign({ importState: '导入成功' }, this.choosedData[i]))
} else {
this.tableData.push(Object.assign({ importState: '导入失败', importDes: res.message }, this.choosedData[i]))
}
} catch (error) {
this.tableData.push(Object.assign({ importState: '导入失败', importDes: `${error}` }, this.choosedData[i]))
}
}
// 结束导入
if (i == this.choosedData.length - 1) {
this.elProgress.display = false;
this.seq = -1
}
}
},
// 同一人判断
async isSamePatient(startRowNameType, body) {
console.log('isSamePatient', startRowNameType, body)
let result = {
isContinue: true,
err: ''
}
let res
if (body.idNo) {
try {
res = await postapi('/api/app/patient/GetByIdNo', { idNo: body.idNo })
if (res.code < 0) {
result.err = `身份证号查重错误,原因:${res.message}`
return result
} else if (res.code == 1) {
body.patientNo = res.data.patientNo
return result
}
} catch (error) {
result.err = `身份证号查重错误,原因:${error}`
return result
}
}
// 没有身份证号或身份证号未找到同名人员时,按姓名查重
let url, localBody = {
customerOrgId: body.customerOrgId,
name: body.patientName
}
switch (startRowNameType) {
case '1':
case '2':
if (startRowNameType == '1') url = '/api/app/patientregister/GetSameNamePatient'
if (startRowNameType == '2') url = '/api/app/patientregister/GetCustomerOrgSameNamePatient'
res = await postapi(url, localBody)
if (res.code >= 0) {
if (res.data.length > 0) {
result.isContinue = false
this.sameMans = res.data
this.dialogSameMan = true
}
} else {
result.err = `${startRowNameType == '2' ? '同单位内' : ''}同名查重错误,原因:${res.message}`
}
break;
default:
break;
}
return result
// if (this.choosedSameMan.patientNo) {
// body.patientNo = this.choosedSameMan.patientNo
// // body.patientId = this.choosedSameMan.patientId
// this.choosedSameMan = {} // 清除选择人员
// }
// try {
// switch (key) {
// case value:
// break;
// default:
// break;
// }
// { dispLabel: '姓名', val: 'patientName' },
// { dispLabel: '性别', val: 'sexName' },
// { dispLabel: '年龄', val: 'age' },
// { dispLabel: '出生日期', val: 'birthDate' },
// { dispLabel: '婚姻状况', val: 'maritalStatusName' },
// { dispLabel: '民族', val: 'nationName' },
// { dispLabel: '身份证号', val: 'idNo' },
},
//将Excel的数据转换成接口的数据
excelDataToApiBody(ExcelData) {
let body = {
customerOrgId: this.customerOrgIds[this.customerOrgIds.length - 1],
customerOrgRegisterId: this.customerOrgRegister.id,
medicalCenterId: this.peisid,
nameType: this.dataImportOpts.nameType,
completeFlag: this.dataImportOpts.completeFlag,
isAutoCreateDepartment: this.dataImportOpts.isAutoCreateDepartment ? 'Y' : 'N',
isAutoCreatePatientNo: this.dataImportOpts.isAutoCreatePatientNo ? 'Y' : 'N',
cardStartNum: this.dataImportOpts.cardStartNum,
cardLength: this.dataImportOpts.cardLength
}
this.excelCols.forEach(e => {
if (e.val) {
switch (e.val) {
case 'age':
if (ExcelData[e.dispLabel]) body[e.val] = parseInt(ExcelData[e.dispLabel])
break;
// case 'birthDate':
// if(ExcelData[e.dispLabel]) body[e.val] = moment(new Date(ExcelData[e.dispLabel])).format('yyyy-MM-DD')
// break;
case 'poisons':
if (ExcelData[e.dispLabel]) body[e.val] = ExcelData[e.dispLabel].replaceAll(",", ",").split(",")
break;
default:
body[e.val] = ExcelData[e.dispLabel]
break;
}
}
})
if(this.seq > 30){
body.isOccupationalDisease = 'Y'
body.isDefaultMedicalType = 'Y'
}
return body
},
//选中同名人员档案
rowClickSameMan(row) {
this.choosedSameMan = deepCopy(row)
},
// 同名人员,按档案人员导入
btnOldMan() {
if (!this.choosedSameMan.patientNo) {
this.$message.warning("请选择要导入的档案人员")
return
}
this.importing(this.dataImportOpts.startRow, this.dataImportOpts.nameType)
this.dialogSameMan = false
},
// 同名人员,按新人方式导入
btnNewMan() {
this.choosedSameMan = { patientNo: '$newPatient$' } // 约定按新人导入
this.importing(this.dataImportOpts.startRow, this.dataImportOpts.nameType)
this.dialogSameMan = false
},
// 查询档案人员
async getPrList() {
let ret = false
if (!this.query.customerOrgIds || this.query.customerOrgIds.length == 0) {
this.$message.warning("请选择单位或部门")
return false
}
if (!this.query.customerOrgRegister || !this.query.customerOrgRegister.id) {
this.$message.warning("请选择单位体检次数")
return false
}
this.query.customerOrgId = this.query.customerOrgIds[this.query.customerOrgIds.length - 1]
this.query.customerOrgRegisterId = this.query.customerOrgRegister.id
let body = Object.assign({}, this.query)
delete body.customerOrgIds
delete body.customerOrgRegister
delete body.customerOrgRegisterList
if (!body.completeFlag) delete body.completeFlag
if (!body.patientName) delete body.patientName
if (!body.startPatientNo && !body.endPatientNo) {
delete body.startPatientNo
delete body.endPatientNo
} else if (!body.startPatientNo) {
this.$message.warning("请填写起始档案号")
return false
} else if (!body.endPatientNo) {
this.$message.warning("请填写截止档案号")
return false
}
if (!body.startDate && !body.endDate) {
delete body.startDate
delete body.endDate
} else if (!body.startDate) {
this.$message.warning("请填写起始登记日期")
return false
} else if (!body.endDate) {
this.$message.warning("请填写截止登记日期")
return false
} else {
body.startDate = moment(new Date(body.startDate)).format('yyyy-MM-DD')
body.endDate = moment(new Date(body.endDate)).format('yyyy-MM-DD')
}
const loading = this.$loading({
lock: true,
text: "Loading",
spinner: "el-icon-loading",
background: "rgba(0, 0, 0, 0.7)",
});
try {
let res = await postapi('/api/patientregister/getpatientregisterimportlist', body)
if (res.code != -1) {
this.prList = res.data
if (res.data.length == 0) {
this.$message.warning("没有符合条件的数据")
} else {
ret = true
}
}
} catch (error) {
//
}
loading.close()
return ret
},
//选择要导入的数据
rowClickPrList(row) {
// console.log("this.excelData",this.excelData);
// 按住了shift键
if (this.window.shift) {
//清除所有选择
this.prList.forEach((e, index) => {
e.choosed = false;
e.index = index;
});
if (this.startPoint == -1) {
this.prList[row.index].choosed = true;
this.startPoint = row.index;
} else {
if (this.startPoint > row.index) {
for (let i = row.index; i <= this.startPoint; i++) {
this.prList[i].choosed = true;
}
} else if (this.startPoint <= row.index) {
for (let i = this.startPoint; i <= row.index; i++) {
this.prList[i].choosed = true;
}
}
}
} else if (this.window.ctrl) { // 按住了ctrl 键
this.prList[row.index].choosed = true;
if (this.startPoint == -1) {
this.startPoint = row.index;
}
} else {
// 未按住了ctrl 、shift 键
//清除所有选择
console.log("清除所有选择");
this.prList.forEach((e, index) => {
e.choosed = false;
e.index = index;
});
// console.log(this.excelData,row.index);
// console.log(this.excelData[row.index].choosed);
this.prList[row.index].choosed = true;
this.startPoint = row.index;
}
},
//获取分组
getGroups(customerOrgRegisterId) {
///api/app/customerorggroup/getlistinfilter?CustomerOrgRegisterId=3fa85f64-5717-4562-b3fc-2c963f66afa6
getapi(`/api/app/customerorggroup/getlistinfilter?CustomerOrgRegisterId=${customerOrgRegisterId}`).then(res => {
if (res.code != - 1) {
this.groups = res.data;
this.curGroup = null //清除已选分组
}
})
},
//确定从档案中导入数据
async btnImportFromDataBase() {
let customerOrgIds = []
let customerOrgId = ""
if (this.newCustomerOrgFlag) {
customerOrgIds = this.customerOrgIds
} else {
customerOrgIds = this.query.customerOrgIds
}
if (customerOrgIds && customerOrgIds.length > 0) customerOrgId = customerOrgIds[customerOrgIds.length - 1]
if (!customerOrgId) {
this.$message.warning("请选择新导入的体检单位或部门")
return
}
if (!this.curGroup || !this.customerOrgRegister) {
this.$message.warning("请选择新导入的体检次数与分组")
return
}
let body = {
customerOrgRegisterId: this.customerOrgRegister.id,
customerOrgGroupId: this.curGroup.id,
completeFlag: this.dataImportOpts.completeFlag,
payTypeFlag: this.payTypeFlag,
medicalCenterId: this.peisid,
}
//{
// "patientRegisterId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
// "customerOrgId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
// "customerOrgRegisterId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
// "customerOrgGroupId": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
// "completeFlag": "string",
// "payTypeFlag": "string",
// "medicalCenterId": "3fa85f64-5717-4562-b3fc-2c963f66afa6"
// }
this.elProgress.display = true
this.elProgress.percentage = 0
for (let i = 0; i < this.prList.length; i++) {
this.elProgress.percentage = Math.floor(((i + 1) * 100) / this.prList.length);
if (!this.prList[i].choosed) continue
body.patientRegisterId = this.prList[i].id
body.customerOrgId = this.newCustomerOrgFlag ? customerOrgId : this.prList[i].customerOrgId
try {
// 旧接口:/api/app/patientregister/createpatientregisterhistory
let res = await postapi('/api/app/patientregister/CreatePatientRegisterFromHistory', body)
if (res.code >= 0) {
this.tableData.push(Object.assign({ importState: '导入成功' }, this.prList[i]))
} else {
this.tableData.push(Object.assign({ importState: '导入失败', importDes: res.message }, this.prList[i]))
}
} catch (error) {
this.tableData.push(Object.assign({ importState: '导入失败', importDes: res.message }, this.prList[i]))
}
}
this.elProgress.display = false
this.seq = -1
},
//通用导出
btnExport(elId) {
let table = document.getElementById(elId);
let tableData = table.innerHTML
let fileName = moment(new Date()).format('yyyyMMDDHHmmss') + '.xls'
let blob = new Blob([tableData], { type: "text/plain;charset=utf-8" });
FileSaver.saveAs(blob, fileName);
},
},
watch: {
"seq": {
immediate: true, // 立即执行
// // deep: true, // 深度监听复杂类型内变化
handler(newVal, oldVal) {
console.log('watch:seq:', newVal, oldVal)
if (!oldVal && oldVal != 0) {
this.oldSeq = -2
} else {
this.oldSeq = oldVal
}
if (newVal != oldVal) {
this.btnProcess(newVal);
}
}
},
"readDataOpts.titleRow": {
// immediate: true, // 立即执行
// deep: true, // 深度监听复杂类型内变化
handler(newVal, oldVal) {
console.log('watch:readDataOpts.titleRow:', newVal, oldVal)
if (newVal && newVal != oldVal) {
if (this.seq == 11) this.readData()
}
}
},
//所选体检次数改变时,自动获取登记日期
"query.customerOrgRegister.id": {
// immediate: true, // 立即执行
// deep: true, // 深度监听复杂类型内变化
handler(newVal, oldVal) {
if (newVal && newVal != oldVal) {
this.query.startDate = new Date(this.query.customerOrgRegister.beginTime)
this.query.endDate = this.query.customerOrgRegister.isComplete == 'N' ? new Date() : new Date(this.query.customerOrgRegister.endTime)
}
}
},
//选体检新体检次数改变时,获取分组数据
"customerOrgRegister.id": {
// immediate: true, // 立即执行
// deep: true, // 深度监听复杂类型内变化
handler(newVal, oldVal) {
if (newVal && newVal != oldVal) {
this.getGroups(newVal)
}
}
},
},
};
</script>
<style scoped>
@import '../../assets/css/global_button.css';
@import '../../assets/css/global_card.css';
@import '../../assets/css/global_dialog.css';
@import '../../assets/css/global_form.css';
@import '../../assets/css/global_input.css';
@import '../../assets/css/global_table.css';
@import '../../assets/css/global_menu.css';
@import '../../assets/css/global.css';
.spanLeftClass {
margin-top: 6px;
width: 70px;
}
.spanMidClass {
text-align: center;
margin-top: 6px;
width: 50px;
}
/* type=number 显示微调按钮 */
::v-deep input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: button !important;
margin: 0 -12px 0 0 !important;
}
::v-deep .el-table__header th {
font-family: "Microsoft YaHei";
}
</style>