|
|
|
@ -15,6 +15,9 @@ |
|
|
|
: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="150"/> |
|
|
|
<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> |
|
|
|
</div> |
|
|
|
</el-card> |
|
|
|
@ -23,8 +26,8 @@ |
|
|
|
:append-to-body="true" :close-on-click-modal="false"> |
|
|
|
<div style="height:300px;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> |
|
|
|
<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> |
|
|
|
@ -55,6 +58,18 @@ |
|
|
|
:append-to-body="true" :close-on-click-modal="false"> |
|
|
|
<div style="height:300px;padding: 0 50px; "> |
|
|
|
<div><input type="file" accept=".xlsx,.xls" @change="changeFileChoose" /></div> |
|
|
|
<div style="margin: 5px 70px;width:240px;"> |
|
|
|
<el-table :data="sheetNames" border ref="sheetNames" |
|
|
|
height="240" 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 type="primary" @click="seq--">上一步</el-button> |
|
|
|
@ -62,105 +77,321 @@ |
|
|
|
<el-button @click="seq = -1">关闭</el-button> |
|
|
|
</span> |
|
|
|
</el-dialog> |
|
|
|
|
|
|
|
<el-dialog title="选择待导入的客户信息" :visible.sync="dialogGroup.fileDataOpr" width="600px" :show-close="false" |
|
|
|
:close-on-click-modal="false"> <!--:append-to-body="true" --> |
|
|
|
<div style="height:300px;"> |
|
|
|
<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="260" @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('all')">全选</el-button> |
|
|
|
<el-button type="primary" @click="btnChoose" style="margin-right: 200px;">取消全选</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="600px" :show-close="false" |
|
|
|
:close-on-click-modal="false"> <!--:append-to-body="true" --> |
|
|
|
<div style="height:300px;"> |
|
|
|
<div style="margin-top: -10px;"> |
|
|
|
选择的人员信息必须直接属于该单位或者是该单位的一级部门,如果人员信息直接属于该单位请将Exce1文件中该人员信息的部门名称设为空 |
|
|
|
</div> |
|
|
|
<div style="display: flex;margin:10px;"> |
|
|
|
<div> |
|
|
|
<span>体检单位:</span> |
|
|
|
<el-cascader v-model="customerOrgIds" :options="customerOrgTree" |
|
|
|
style="width:150px;" @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:10px;"> |
|
|
|
<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:10px;"> |
|
|
|
<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:10px;"> |
|
|
|
<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;"> |
|
|
|
<span style="margin-top:6px;">工卡号开始位置:</span> |
|
|
|
<el-input type="number" v-model="dataImportOpts.cardStartNum" size="small" style="width:100px;margin: 0 10px 0 0;"/> |
|
|
|
<span style="margin-top:6px;">长度:</span> |
|
|
|
<el-input type="number" v-model="dataImportOpts.cardLength" size="small" style="width:100px;margin: 0 10px 0 0;"/> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
</div> |
|
|
|
<div style="display: flex;margin:10px;"> |
|
|
|
<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="elProgress.display" |
|
|
|
width="600px" |
|
|
|
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 ExcelJS from "exceljs"; |
|
|
|
import { read,readFile, utils } from "xlsx"; |
|
|
|
|
|
|
|
import { getapi, postapi, putapi, deletapi } from "@/api/api"; |
|
|
|
import { arrayExistObj ,arrayFilter ,tcdate } from '@/utlis/proFunc'; |
|
|
|
import ElProgressOCX from "../../components/report/ElProgressOCX.vue"; |
|
|
|
|
|
|
|
|
|
|
|
export default { |
|
|
|
components: { |
|
|
|
|
|
|
|
ElProgressOCX, |
|
|
|
}, |
|
|
|
data() { |
|
|
|
return { |
|
|
|
return { |
|
|
|
customerOrgTree:[], |
|
|
|
customerOrgIds:[], //选中单位节点 |
|
|
|
customerOrgRegisterList: [], //体检次数列表 |
|
|
|
customerOrgRegister: {}, //体检次数 |
|
|
|
|
|
|
|
peisid:null, |
|
|
|
startPoint: -1, // 多选起点 -1 表示选择 |
|
|
|
endPoint: -1, // 多选终点 -1 表示选择 |
|
|
|
rClickRow: null, //右击的行 |
|
|
|
rClickColumn: null, //右击的列(预留) |
|
|
|
|
|
|
|
dialogGroup:{ |
|
|
|
mode:true, //选模式 10 开始 文件导入,20开始 从数据库中导入 |
|
|
|
fileReadme:false, |
|
|
|
fileChoose:false, |
|
|
|
fileDataChoose:false, |
|
|
|
fileDataOption:false, |
|
|
|
fileReadme:false, //导入EXCEL注意事项 |
|
|
|
fileChoose:false, //选择文件 |
|
|
|
fileDataOpr:false, //文件数据分析操作 |
|
|
|
fileDataOpts:false, //文件数据导入前参数设定 |
|
|
|
}, |
|
|
|
seq: 0, //当前显示窗口 |
|
|
|
mode: '10', //模式 10 开始 文件导入,20开始 从数据库中导入 |
|
|
|
excelCols: [{label:'',val:''}], //excel数据列名 |
|
|
|
excelData: [], //excel表格数据 |
|
|
|
excelCols: [{dispLabel:'',val:'',dataLabel:''}], //excel数据列名 {dispLabel:'',val:'',dataLabel:''} |
|
|
|
importCols:[], //实际导入的列(即有设置与 dataCols 匹配的列) |
|
|
|
excelData: [], //excel表格数据 |
|
|
|
|
|
|
|
dataCols:[ |
|
|
|
{label:'不设置',val:'noSet'}, |
|
|
|
{label:'工卡号',val:'noSet'}, |
|
|
|
{label:'部门',val:'noSet'}, |
|
|
|
{label:'姓名',val:'noSet'}, |
|
|
|
{label:'性别',val:'noSet'}, |
|
|
|
{label:'不设置',val:'noSet'}, |
|
|
|
{label:'工卡号',val:'noSet'}, |
|
|
|
{label:'部门',val:'noSet'}, |
|
|
|
{label:'姓名',val:'noSet'}, |
|
|
|
{label:'性别',val:'noSet'}, |
|
|
|
{label:'年龄',val:'noSet'}, |
|
|
|
{label:'出生日期',val:'noSet'}, |
|
|
|
{label:'婚姻状况',val:'noSet'}, |
|
|
|
{label:'民族',val:'noSet'}, |
|
|
|
{label:'身份证号',val:'noSet'}, |
|
|
|
{label:'电话',val:'noSet'}, |
|
|
|
{label:'手机',val:'noSet'}, |
|
|
|
{label:'电子邮件',val:'noSet'}, |
|
|
|
{label:'邮编',val:'noSet'}, |
|
|
|
{label:'地址',val:'noSet'}, |
|
|
|
{label:'人员类别',val:'noSet'}, |
|
|
|
{label:'体检类别',val:'noSet'}, |
|
|
|
{label:'支付方式',val:'noSet'}, |
|
|
|
{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 工作薄中的表单 |
|
|
|
sheetNames:[], //EXCEL 工作薄中的表单 {sheetName:} |
|
|
|
readDataOpts:{ |
|
|
|
sheetNameChoosed:'', //当前选中的表格 |
|
|
|
titleRow:1, //标题行 |
|
|
|
dataRow:2, //读取开始数据行 |
|
|
|
titleRow:1, //标题行 |
|
|
|
}, |
|
|
|
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:0, |
|
|
|
cardLength:6 |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
}, |
|
|
|
|
|
|
|
//组件创建完成,一般页面初始布局放在这里 |
|
|
|
created() { |
|
|
|
|
|
|
|
this.peisid = window.sessionStorage.getItem('peisid'); |
|
|
|
if(!this.peisid || this.peisid == 'null'){ |
|
|
|
this.seq = -1 |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
//页面挂载完成,一般页面渲染数据放在这里 |
|
|
|
mounted() { |
|
|
|
|
|
|
|
this.getCustomerOrgTree() |
|
|
|
}, |
|
|
|
|
|
|
|
computed: { |
|
|
|
...mapState(["window", "dict", "patientRegister", "customerOrg"]), |
|
|
|
...mapState(["window", "dict", "elProgress", "patientRegister", "customerOrg"]), |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
methods: { |
|
|
|
|
|
|
|
// 获取单位列表树 |
|
|
|
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) { |
|
|
|
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) { |
|
|
|
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 = []; |
|
|
|
} |
|
|
|
// objCopy(this.formInit,this.form) |
|
|
|
} |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
//第一次点下一步 |
|
|
|
btnFirst() { |
|
|
|
if(!this.peisid || this.peisid == 'null'){ |
|
|
|
this.$message.warning("该用户未选归属体检中心,不能执行此操作!"); |
|
|
|
return |
|
|
|
} |
|
|
|
this.seq = parseInt(this.mode) |
|
|
|
}, |
|
|
|
|
|
|
|
//下一步 |
|
|
|
btnNext() { |
|
|
|
if(this.seq == 0) return; |
|
|
|
this.seq++; |
|
|
|
this.setDialogDisp(); |
|
|
|
}, |
|
|
|
|
|
|
|
btnImport(seq){ |
|
|
|
// 导入过程 上一步,下一步 |
|
|
|
btnProcess(seq){ |
|
|
|
let keys = Object.keys(this.dialogGroup) |
|
|
|
|
|
|
|
if(seq == 9){ |
|
|
|
@ -179,7 +410,7 @@ export default { |
|
|
|
}) |
|
|
|
break; |
|
|
|
case 0: |
|
|
|
//关闭所有弹窗 |
|
|
|
//显示 选择导入方式 |
|
|
|
keys.forEach(e =>{ |
|
|
|
if(e == 'mode'){ |
|
|
|
this.dialogGroup[e] = true |
|
|
|
@ -189,7 +420,7 @@ export default { |
|
|
|
}) |
|
|
|
break; |
|
|
|
case 10: |
|
|
|
//关闭所有弹窗 |
|
|
|
//显示 EXCEL 导入 |
|
|
|
keys.forEach(e =>{ |
|
|
|
if(e == 'fileReadme'){ |
|
|
|
this.dialogGroup[e] = true |
|
|
|
@ -199,7 +430,7 @@ export default { |
|
|
|
}) |
|
|
|
break; |
|
|
|
case 11: |
|
|
|
//关闭所有弹窗 |
|
|
|
//显示 文件选择 窗口 |
|
|
|
keys.forEach(e =>{ |
|
|
|
if(e == 'fileChoose'){ |
|
|
|
this.dialogGroup[e] = true |
|
|
|
@ -208,6 +439,44 @@ export default { |
|
|
|
} |
|
|
|
}) |
|
|
|
break; |
|
|
|
case 12: |
|
|
|
// 从后面退回时,无需读数据 |
|
|
|
if(this.excelData.length == 0){ |
|
|
|
if(!this.readData()){ |
|
|
|
this.seq-- |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
//显示 数据分析操作 窗口 |
|
|
|
keys.forEach(e =>{ |
|
|
|
if(e == 'fileDataOpr'){ |
|
|
|
this.dialogGroup[e] = true |
|
|
|
}else{ |
|
|
|
this.dialogGroup[e] = false |
|
|
|
} |
|
|
|
}) |
|
|
|
break; |
|
|
|
case 13: |
|
|
|
let 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; |
|
|
|
default: |
|
|
|
|
|
|
|
break; |
|
|
|
@ -215,16 +484,13 @@ export default { |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
//显示数据 |
|
|
|
setDialogDisp(){ |
|
|
|
this.dialogGroup.forEach((item,index) =>{ |
|
|
|
if(index == this.seq){ |
|
|
|
item = true; |
|
|
|
}else{ |
|
|
|
item = false; |
|
|
|
} |
|
|
|
return item; |
|
|
|
}); |
|
|
|
//多选 颜色标记 |
|
|
|
handleRowClassName({ row, rowIndex }) { |
|
|
|
if (row.choosed) { |
|
|
|
return "current-row"; |
|
|
|
} else { |
|
|
|
return ""; |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
changeFileChoose(e) { |
|
|
|
@ -244,136 +510,269 @@ export default { |
|
|
|
let data = e.target.result; |
|
|
|
// let typedArray = new Uint8Array(data); |
|
|
|
// var workBook = read(typedArray,{type:'array'}) |
|
|
|
this.workBook = read(data,{type:'binary',cellDates:true}) |
|
|
|
// 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]) |
|
|
|
}) |
|
|
|
this.sheetNames = this.workBook.SheetNames |
|
|
|
console.log('workBook',workBook) |
|
|
|
var sheet_name_list = workBook.SheetNames; |
|
|
|
sheet_name_list.forEach(function(e,index) { |
|
|
|
var worksheet = workBook.Sheets[e]; |
|
|
|
console.log(e,index,worksheet) |
|
|
|
let jsonData = utils.sheet_to_json(worksheet,{header:1}) //raw:false,range:1 从第几行开始读取 |
|
|
|
console.log('jsonData',jsonData) |
|
|
|
utils.sheet_to_formulae() |
|
|
|
/* DO SOMETHING WITH worksheet HERE */ |
|
|
|
}); |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
//选择要导入的Excel表单名 |
|
|
|
chooseSheetName(row){ |
|
|
|
this.readDataOpts.sheetNameChoosed = row.sheetName |
|
|
|
}, |
|
|
|
|
|
|
|
//读取数据 |
|
|
|
readData(){ |
|
|
|
let ret = 1 |
|
|
|
if(!this.workBook || !this.readDataOpts.sheetNameChoosed){ |
|
|
|
this.$message.warning("请选择文件及要导入的表格") |
|
|
|
return |
|
|
|
return 0 |
|
|
|
} |
|
|
|
|
|
|
|
if(this.readDataOpts.titleRow <= 0){ |
|
|
|
this.$message.warning("标题行不能小于1") |
|
|
|
return |
|
|
|
} |
|
|
|
if(this.readDataOpts.dataRowRow <= 0){ |
|
|
|
this.$message.warning("数据行不能小于2") |
|
|
|
return |
|
|
|
return 0 |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let worksheet = this.workBook.Sheets[this.readDataOpts.sheetNameChoosed]; |
|
|
|
let temp |
|
|
|
let worksheet = this.workBook.Sheets[this.readDataOpts.sheetNameChoosed]; |
|
|
|
|
|
|
|
// = utils.sheet_to_json(worksheet,{header:1}) //raw:false,range:1 从第几行开始读取 |
|
|
|
//分析标题信息 |
|
|
|
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 |
|
|
|
}) |
|
|
|
}) |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//导入ExcelFile 的数据 |
|
|
|
importExcelFile(file) { |
|
|
|
// 按住了shift键 |
|
|
|
if (this.window.shift) { |
|
|
|
//清除所有选择 |
|
|
|
this.excelData.forEach((e,index) => { |
|
|
|
e.choosed = false; |
|
|
|
e.index = index; |
|
|
|
}); |
|
|
|
|
|
|
|
// 创建一个工作簿 |
|
|
|
const workbook = new ExcelJS.Workbook(); |
|
|
|
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); |
|
|
|
|
|
|
|
console.log('workbook',workbook) |
|
|
|
// 读取Excel文件 |
|
|
|
const reader = new FileReader(); |
|
|
|
this.excelData[row.index].choosed = true; |
|
|
|
this.startPoint = row.index; |
|
|
|
} |
|
|
|
}, |
|
|
|
|
|
|
|
reader.onload = () => { |
|
|
|
const buffer = reader.result; |
|
|
|
const typedArray = new Uint8Array(buffer); |
|
|
|
// 全选(取消全选) |
|
|
|
btnChoose(type){ |
|
|
|
let choosed = false |
|
|
|
if(type && type == 'all'){ |
|
|
|
choosed = true |
|
|
|
} |
|
|
|
this.excelData.forEach(e =>{ |
|
|
|
e.choosed = choosed |
|
|
|
if(choosed){ |
|
|
|
this.$refs['excelData'].setCurrentRow(e) |
|
|
|
} |
|
|
|
}) |
|
|
|
|
|
|
|
//application/vnd.ms-excel |
|
|
|
const blob = new Blob([typedArray], { |
|
|
|
//type xlsx:application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, xls:application/vnd.ms-excel |
|
|
|
type: file.type, |
|
|
|
}); |
|
|
|
if(!choosed){ |
|
|
|
this.$refs['excelData'].setCurrentRow() |
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
// 从Blob中读取Excel文件 |
|
|
|
workbook.xlsx.load(blob).then((wb) => { |
|
|
|
console.log('wb',wb); |
|
|
|
// 获取第一个工作表 |
|
|
|
const worksheet = wb.getWorksheet(1); |
|
|
|
console.log('worksheet',worksheet); |
|
|
|
// 处理Excel文件内容 |
|
|
|
worksheet.eachRow((row, rowNumber) => { |
|
|
|
console.log(row.values); |
|
|
|
this.excelData.push(row.values); |
|
|
|
|
|
|
|
// console.log(`第${row.rowNumber}行的数据:${row.rowData}`); |
|
|
|
}); |
|
|
|
}); |
|
|
|
}; |
|
|
|
reader.readAsArrayBuffer(file); |
|
|
|
//右击标题 |
|
|
|
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; |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//导入后数据分析 |
|
|
|
parseexcelData(startRow) { |
|
|
|
if (!this.excelData || this.excelData.length == 0) return; |
|
|
|
let cols = []; |
|
|
|
let record = {}; |
|
|
|
this.excelData.forEach((item, index) => { |
|
|
|
console.log(index, item); |
|
|
|
if (index == startRow - 2) { |
|
|
|
item.forEach((e, i) => { |
|
|
|
console.log("e", i, e); |
|
|
|
if (i > 0) { |
|
|
|
if (e) { |
|
|
|
this.tableDataCol.push({ excelCol: e, apiCol: "", label: e }); |
|
|
|
cols.push(e); |
|
|
|
} else { |
|
|
|
this.tableDataCol.push({ |
|
|
|
excelCol: `第${Number(i) + 1}列`, |
|
|
|
apiCol: "", |
|
|
|
lebel: `第${Number(i) + 1}列`, |
|
|
|
}); |
|
|
|
cols.push(`第${Number(i) + 1}列`); |
|
|
|
} |
|
|
|
} |
|
|
|
}); |
|
|
|
} else if (index > startRow - 2) { |
|
|
|
for (let i = 0; i < item.length; i++) { |
|
|
|
if (i > 0) { |
|
|
|
console.log("cols[i]", i, cols[i - 1]); |
|
|
|
if (item[i]) { |
|
|
|
record[cols[i - 1]] = item[i]; |
|
|
|
} else { |
|
|
|
record[cols[i - 1]] = null; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
this.tableData.push({ ...record }); |
|
|
|
//设置真实数据字段列 |
|
|
|
setColumn(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 |
|
|
|
}, |
|
|
|
|
|
|
|
// 导入后,批量分析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]) |
|
|
|
}); |
|
|
|
}, |
|
|
|
|
|
|
|
// console.log("tableDataCol", this.tableDataCol); |
|
|
|
// console.log("tableData", this.tableData); |
|
|
|
// 确定导入数据库 |
|
|
|
async btnImport(){ |
|
|
|
if(!this.customerOrgIds || this.customerOrgIds.length == 0){ |
|
|
|
this.$message.warning("请选择单位") |
|
|
|
return |
|
|
|
} |
|
|
|
if(!this.customerOrgRegister || !this.customerOrgRegister.id){ |
|
|
|
this.$message.warning("请选择单位体检次数") |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
let body = {} |
|
|
|
this.elProgress.display = true; |
|
|
|
this.elProgress.percentage = 0; |
|
|
|
|
|
|
|
this.tableData = [] |
|
|
|
for(let i=0;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]) |
|
|
|
console.log('this.excelData[i]',i,body) |
|
|
|
try { |
|
|
|
let res = await postapi('/api/app/patientregister/createpatientregisterexcel',body) |
|
|
|
if(res.code != -1){ |
|
|
|
this.tableData.push(Object.assign({importState:'导入成功'},this.excelData[i])) |
|
|
|
}else{ |
|
|
|
this.tableData.push(Object.assign({importState:`导入失败,原因:${res.message}`},this.excelData[i])) |
|
|
|
} |
|
|
|
} catch (error) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
this.elProgress.display = false; |
|
|
|
this.seq = -1 |
|
|
|
this.importCols = [] |
|
|
|
this.excelCols.forEach(e =>{ |
|
|
|
if(e.val){ |
|
|
|
this.importCols.push(e) |
|
|
|
} |
|
|
|
}) |
|
|
|
}, |
|
|
|
|
|
|
|
//将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 |
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
@ -384,7 +783,7 @@ export default { |
|
|
|
handler(newVal,oldVal){ |
|
|
|
console.log('watch:seq:',newVal,oldVal) |
|
|
|
if(newVal != oldVal){ |
|
|
|
this.btnImport(newVal); |
|
|
|
this.btnProcess(newVal); |
|
|
|
} |
|
|
|
} |
|
|
|
}, |
|
|
|
@ -398,10 +797,11 @@ export default { |
|
|
|
@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_input.css'; */ |
|
|
|
@import '../../assets/css/global_table.css'; |
|
|
|
@import '../../assets/css/global.css'; |
|
|
|
|
|
|
|
|
|
|
|
.btnClass{ |
|
|
|
margin-right: 10px; |
|
|
|
} |
|
|
|
|