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.
1679 lines
62 KiB
1679 lines
62 KiB
<template>
|
|
<div>
|
|
<el-card>
|
|
<div slot="header">批量预登记</div>
|
|
<div style="display: flex;margin-bottom: 10px;justify-content:space-between;">
|
|
<div></div>
|
|
<div style="display: flex;">
|
|
<div>
|
|
<a :underline="false" href="/files/单位体检人员名单导入模板.xlsx"><el-button class="btnClass">下载导入模版</el-button></a>
|
|
</div>
|
|
<div>
|
|
<el-button class="btnClass" @click="seq = 0">导入</el-button>
|
|
</div>
|
|
<div>
|
|
<el-button class="btnClass" @click="btnExport('tableData')">导入后结果状态导出</el-button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="tableData">
|
|
<el-table :data="tableData" border v-if="mode=='10'" :row-class-name="importRowClassName"
|
|
:height="window.pageHeight < 600 ? 405 : (window.pageHeight - 195)"
|
|
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 ? 405 : (window.pageHeight - 195)"
|
|
highlight-current-row size="small" >
|
|
<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>
|
|
</el-card>
|
|
|
|
<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="20">从以往体检资料中导入</el-radio>
|
|
</div>
|
|
<span slot="footer" class="dialog-footer">
|
|
<el-button type="primary" @click="btnFirst">下一步</el-button>
|
|
<el-button @click="seq = -1">关闭</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的格式必须符合一定规范,该格式的模板文件放在程序的执行目录下,文件名为:"单位体检人员名单导入模板.xls"
|
|
<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 type="primary" @click="seq--">上一步</el-button>
|
|
<el-button type="primary" @click="seq++">下一步</el-button>
|
|
<el-button @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 ref="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" id="fileNames" 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 type="primary" @click="seq--">上一步</el-button>
|
|
<el-button type="primary" @click="seq++">下一步</el-button>
|
|
<el-button @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、按住 Ctr1 或 Shift 键可进行多选,在标题列右击鼠标可设置列名,即:标题列有√;<br>
|
|
2、身份证号有值且合法时,将以身份证号为主自动换算性别、出生日期及年龄;<br>
|
|
</div>
|
|
<div style="margin: 5px 0px 0px;" @contextmenu.prevent=""> <!-- -->
|
|
<el-table :data="excelData" border ref="excelData" @header-contextmenu="headerContextmenu"
|
|
height="360" @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">
|
|
<el-button type="primary" @click="btnChoose('excelData','all')">全选</el-button>
|
|
<el-button type="primary" @click="btnChoose('excelData')" style="margin-right: 300px;">取消全选</el-button>
|
|
|
|
<el-button type="primary" @click="seq--">上一步</el-button>
|
|
<el-button type="primary" @click="seq++">下一步</el-button>
|
|
<el-button @click="seq = -1">关闭</el-button>
|
|
</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"
|
|
style="width:200px;" @change="changeCustomerOrg" filterable :filter-method="filterMethod"
|
|
:props="{ checkStrictly: true, expandTrigger: 'hover', ...customerOrg.treeprops, }"
|
|
:show-all-levels="false" 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>
|
|
<div style="display: flex;margin:20px;">
|
|
<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 type="primary" @click="seq--">上一步</el-button>
|
|
<el-button type="primary" @click="btnImport">确定导入</el-button>
|
|
<el-button @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 type="primary" @click="btnOldMan">按档案人员导入</el-button>
|
|
<el-button 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:200px;" @change="changeQueryCustomerOrg" filterable :filter-method="filterMethod"
|
|
:props="{ checkStrictly: true, expandTrigger: 'hover', ...customerOrg.treeprops, }"
|
|
:show-all-levels="false" 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 v-for="item in dict.forSex" :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 type="primary" @click="seq--">上一步</el-button>
|
|
<el-button type="primary" @click="seq++">下一步</el-button>
|
|
<el-button @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,
|
|
"organizationUnitId": "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">
|
|
<el-button type="primary" @click="btnChoose('prList','all')">全选</el-button>
|
|
<el-button type="primary" @click="btnChoose('prList')" style="margin-right: 300px;">取消全选</el-button>
|
|
|
|
<el-button type="primary" @click="seq--">上一步</el-button>
|
|
<el-button type="primary" @click="seq++">下一步</el-button>
|
|
<el-button @click="seq = -1">关闭</el-button>
|
|
</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"
|
|
style="width:200px;" @change="changeCustomerOrg" filterable :filter-method="filterMethod"
|
|
:props="{ checkStrictly: true, expandTrigger: 'hover', ...customerOrg.treeprops, }"
|
|
:show-all-levels="false" 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 type="primary" @click="seq--">上一步</el-button>
|
|
<el-button type="primary" @click="btnImportFromDataBase">确定导入</el-button>
|
|
<el-button @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>
|
|
</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 { arrayExistObj ,arrayFilter ,dddw, tcdate } from '@/utlis/proFunc';
|
|
import ElProgressOCX from "../../components/report/ElProgressOCX.vue";
|
|
|
|
|
|
export default {
|
|
components: {
|
|
ElProgressOCX,
|
|
},
|
|
data() {
|
|
return {
|
|
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开始 从数据库中导入
|
|
excelCols: [{dispLabel:'',val:'',dataLabel:''}], //excel数据列名 {dispLabel:'',val:'',dataLabel:''}
|
|
importCols:[], //实际导入的列(即有设置与 dataCols 匹配的列)
|
|
excelData: [], //excel表格数据
|
|
|
|
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:'payTypeFlag'},
|
|
],
|
|
/*
|
|
photo string
|
|
nullable: true
|
|
照片
|
|
|
|
salesman string
|
|
nullable: true
|
|
介绍人
|
|
|
|
sexHormoneTermName string
|
|
nullable: true
|
|
性激素期限
|
|
|
|
isNameHide string
|
|
nullable: true
|
|
隐藏姓名
|
|
|
|
remark string
|
|
nullable: true
|
|
备注
|
|
|
|
interposeMeasure string
|
|
nullable: true
|
|
干预措施
|
|
|
|
medicalConclusionId string($uuid)
|
|
nullable: true
|
|
体检结论
|
|
|
|
birthPlaceName string
|
|
nullable: true
|
|
出生地
|
|
*/
|
|
|
|
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() {
|
|
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,
|
|
dictInit(){
|
|
|
|
// 获取单位列表树
|
|
getapi("/api/app/customerorg/getbycodeall").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)
|
|
}
|
|
});
|
|
|
|
//性别(查询)
|
|
getapi("/api/app/for-sex").then((res) => {
|
|
if (res.code == 1) {
|
|
this.dict.forSex = res.data;
|
|
}
|
|
});
|
|
|
|
//性别(仅档案用)
|
|
getapi("/api/app/sex").then((res) => {
|
|
if (res.code == 1) {
|
|
this.dict.sex = res.data;
|
|
}
|
|
});
|
|
|
|
},
|
|
|
|
//清空进度数据数据
|
|
clearProcess(){
|
|
|
|
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").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)
|
|
}
|
|
});
|
|
},
|
|
|
|
//单位过滤 预留
|
|
filterMethod(){
|
|
|
|
},
|
|
|
|
//选择单位
|
|
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){
|
|
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:
|
|
//显示 EXCEL 导入
|
|
keys.forEach(e =>{
|
|
if(e == 'fileReadme'){
|
|
this.dialogGroup[e] = true
|
|
}else{
|
|
this.dialogGroup[e] = false
|
|
}
|
|
})
|
|
break;
|
|
case 11:
|
|
//显示 文件选择 窗口
|
|
keys.forEach(e =>{
|
|
if(e == 'fileChoose'){
|
|
this.dialogGroup[e] = true
|
|
}else{
|
|
this.dialogGroup[e] = false
|
|
}
|
|
})
|
|
break;
|
|
case 12:
|
|
// 从后面退回时,无需读数据
|
|
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:
|
|
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) => {
|
|
if(item[column.property] == '导入成功'){
|
|
success++
|
|
}else{
|
|
fail++
|
|
}
|
|
});
|
|
|
|
});
|
|
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;
|
|
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.readAsBinaryString(file);
|
|
// 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])
|
|
})
|
|
}
|
|
},
|
|
|
|
//选择要导入的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列 与 数据字段 的匹配关系
|
|
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.importing(this.dataImportOpts.startRow,this.dataImportOpts.nameType)
|
|
|
|
},
|
|
|
|
//导入进行时
|
|
// startRow : 从第几行开始导入,同名判断交互时,续接导入
|
|
// startRowNameType : 续接导入的第1行,执行 同名判断模式, 3.不提示,按新人导入
|
|
async importing(startRow,startRowNameType){
|
|
let body = {}
|
|
for(let i=startRow;i<this.excelData.length;i++){
|
|
this.elProgress.percentage = Math.floor(
|
|
((i + 1) * 100) / this.excelData.length
|
|
);
|
|
|
|
if(this.excelData[i].choosed){
|
|
body = this.excelDataToApiBody(this.excelData[i])
|
|
if(i == startRow) body.nameType = startRowNameType
|
|
if(this.choosedSameMan.patientId){
|
|
body.patientId = this.choosedSameMan.patientId
|
|
this.choosedSameMan = {} // 清除选择
|
|
}
|
|
|
|
console.log('this.excelData[i]',i,body)
|
|
try {
|
|
let res = await postapi('/api/app/patientregister/createpatientregisterexcel',body)
|
|
if(res.code != -1){
|
|
if(res.data.code == 1){
|
|
this.tableData.push(Object.assign({importState:'导入成功'},this.excelData[i]))
|
|
}else if(res.data.code == -2){
|
|
this.sameMans = res.data.details
|
|
this.dialogSameMan = true
|
|
this.dataImportOpts.startRow = i
|
|
break;
|
|
}else{
|
|
this.tableData.push(Object.assign({importState:'导入失败',importDes:res.data.msg},this.excelData[i]))
|
|
}
|
|
}else{
|
|
this.tableData.push(Object.assign({importState:'导入失败',importDes:res.message},this.excelData[i]))
|
|
}
|
|
} catch (error) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
// 结束导入
|
|
if(i == this.excelData.length - 1){
|
|
this.elProgress.display = false;
|
|
this.seq = -1
|
|
}
|
|
}
|
|
},
|
|
|
|
//将Excel的数据转换成接口的数据
|
|
excelDataToApiBody(ExcelData){
|
|
let body = {
|
|
customerOrgId:this.customerOrgIds[this.customerOrgIds.length - 1],
|
|
customerOrgRegisterId:this.customerOrgRegister.id,
|
|
organizationUnitId: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;
|
|
default:
|
|
body[e.val] = ExcelData[e.dispLabel]
|
|
break;
|
|
}
|
|
}
|
|
})
|
|
return body
|
|
},
|
|
|
|
//选中同名人员档案
|
|
rowClickSameMan(row){
|
|
this.choosedSameMan = Object.assign({},row)
|
|
},
|
|
// 同名人员,按档案人员导入
|
|
btnOldMan(){
|
|
if(!this.choosedSameMan.patientId){
|
|
this.$message.warning("请选择要导入的档案人员")
|
|
return
|
|
}
|
|
this.importing(this.dataImportOpts.startRow)
|
|
this.dialogSameMan = false
|
|
},
|
|
|
|
// 同名人员,按新人方式导入
|
|
btnNewMan(){
|
|
this.choosedSameMan = {}
|
|
this.importing(this.dataImportOpts.startRow,'3')
|
|
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.items;
|
|
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,
|
|
organizationUnitId: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",
|
|
// "organizationUnitId": "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 {
|
|
let res = await postapi('/api/app/patientregister/createpatientregisterhistory',body)
|
|
if(res.code != -1){
|
|
if(res.data.code != -1){
|
|
this.tableData.push(Object.assign({importState:'导入成功'},this.prList[i]))
|
|
}else{
|
|
this.tableData.push(Object.assign({importState:'导入失败',importDes:res.data.msg},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.css';
|
|
|
|
|
|
.btnClass{
|
|
margin-right: 10px;
|
|
}
|
|
|
|
.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;
|
|
}
|
|
|
|
</style>
|