3 changed files with 542 additions and 1 deletions
@ -0,0 +1,534 @@ |
|||
<template> |
|||
<div> |
|||
<div class="middlebox"> |
|||
<div class="contenttitle"> |
|||
体检查询 / |
|||
<span class="contenttitleBold">营业额统计(体检中心)</span> |
|||
</div> |
|||
</div> |
|||
<div style=" |
|||
display: flex; |
|||
justify-content: space-between; |
|||
padding: 10px; |
|||
background-color: #fff; |
|||
border-radius: 8px; |
|||
margin-bottom: 10px; |
|||
"> |
|||
|
|||
<div style="display: flex;flex-wrap: wrap;height: 32px;align-items: center;"> |
|||
<div class="query"> |
|||
<el-select v-model="query.dateType" placeholder="请选择" style="width: 80px" size="small"> |
|||
<el-option label="登记日期" :value="'1'" /> |
|||
<el-option label="体检日期" :value="'2'" /> |
|||
<el-option label="总检日期" :value="'3'" /> |
|||
<el-option label="收费日期" :value="'6'" /> |
|||
</el-select> |
|||
<!-- dateType 1 登记,2 体检,3 总检日期--> |
|||
<el-date-picker v-model="query.startDate" type="date" placeholder="起始日期" size="small" style="width: 90px" |
|||
value-format="yyyy-MM-dd" :picker-options="pickerOptions" /> |
|||
<span class="spanClass">至</span> |
|||
<el-date-picker v-model="query.endDate" type="date" placeholder="截止日期" size="small" style="width: 90px" |
|||
value-format="yyyy-MM-dd" :picker-options="pickerOptions" /> |
|||
</div> |
|||
<div class="query"> |
|||
<span class="spanClass">体检单位</span> |
|||
<el-select v-model="query.customerOrgIds" placeholder="请选择体检单位" :filter-method="filterMethod" |
|||
default-first-option clearable filterable style="margin-left: 10px;width: 300px;" size="small" multiple |
|||
collapse-tags> |
|||
<el-option v-for="item in customerOrg" :key="item.id" :label="item.displayName" :value="item.id"> |
|||
{{ item.displayName }} |
|||
</el-option> |
|||
</el-select> |
|||
</div> |
|||
<div class="query"> |
|||
<span class="spanClass">含预登记</span> |
|||
<el-checkbox v-model="query.isPreRegistration" true-label="Y" false-label="N" /> |
|||
</div> |
|||
<div class="query"> |
|||
<span class="spanClass">体检类别</span> |
|||
<el-select v-model="query.medicalTypeIds" placeholder="请选择体检类别" :filter-method="filterMethodM" |
|||
default-first-option clearable filterable style="margin-left: 10px;width: 200px;" size="small" multiple |
|||
collapse-tags> |
|||
<el-option v-for="item in medicalType" :key="item.id" :label="item.displayName" :value="item.id"> |
|||
{{ item.displayName }} |
|||
</el-option> |
|||
</el-select> |
|||
</div> |
|||
<div class="query"> |
|||
<span class="spanClass">人员类别</span> |
|||
<el-select v-model="query.personnelTypeIds" placeholder="请选择人员类别" :filter-method="filterMethodP" |
|||
default-first-option clearable filterable style="margin-left: 10px;width: 200px;" size="small" multiple |
|||
collapse-tags> |
|||
<el-option v-for="item in personnelType" :key="item.id" :label="item.displayName" :value="item.id"> |
|||
{{ item.displayName }} |
|||
</el-option> |
|||
</el-select> |
|||
</div> |
|||
<div class="query"> |
|||
<span class="spanClass">业务员</span> |
|||
<el-select v-model="query.salesmans" placeholder="请输入业务员姓名" default-first-option clearable filterable |
|||
style="margin-left: 10px" size="small" multiple collapse-tags> |
|||
<el-option v-for="item in dictSalesman" :key="item.id" :label="item.surname" :value="item.surname" /> |
|||
</el-select> |
|||
</div> |
|||
<div class="query"> |
|||
<span class="spanClass">科室</span> |
|||
<el-select v-model="query.itemTypeIds" placeholder="请选择科室" default-first-option clearable filterable |
|||
style="margin-left: 10px;width: 300px;" size="small" multiple collapse-tags> |
|||
<el-option v-for="item in dict.itemTypeTree" :key="item.id" :label="item.displayName" :value="item.id"> |
|||
{{ item.displayName }} |
|||
</el-option> |
|||
</el-select> |
|||
</div> |
|||
</div> |
|||
|
|||
<div style="display: block;width: 110px;"> |
|||
<div> |
|||
<el-button type="primary" class="commonbutton" @click="btnQuery" size="small">查询</el-button> |
|||
</div> |
|||
<div style="margin-top: 5px;"> |
|||
<el-button class="commonbutton" @click="btnExport('tableData')" size="small">导出</el-button> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div id="tableData"> |
|||
<div v-show="false">{{ queryCondition }}</div> |
|||
<el-table :data="tableDataTrans" border style="width: 100%" highlight-current-row :span-method="spanMethod"> |
|||
<el-table-column prop="itemTypeName" label="科室" min-width="120"></el-table-column> |
|||
<el-table-column prop="asbitemName" label="组合项目" min-width="180"></el-table-column> |
|||
<el-table-column v-for="(col, index) in asyncCols" :key="index" :label="col" min-width="80" align="center"> |
|||
<el-table-column :prop="`${col}_djrs`" label="登记人数" min-width="80" align="center"></el-table-column> |
|||
<el-table-column :prop="`${col}_yjrs`" label="已检人数" min-width="80" align="center"></el-table-column> |
|||
<el-table-column :prop="`${col}_bzje`" label="标准金额" min-width="80" align="center"></el-table-column> |
|||
<el-table-column :prop="`${col}_ysje`" label="应收金额" min-width="80" align="center"></el-table-column> |
|||
<el-table-column :prop="`${col}_ssje`" label="实收金额" min-width="80" align="center"></el-table-column> |
|||
</el-table-column> |
|||
<el-table-column label="汇总" min-width="180"> |
|||
<el-table-column prop="djrs" label="登记人数" min-width="80" align="center"></el-table-column> |
|||
<el-table-column prop="yjrs" label="已检人数" min-width="80" align="center"></el-table-column> |
|||
<el-table-column prop="bzje" label="标准金额" min-width="80" align="center"></el-table-column> |
|||
<el-table-column prop="ysje" label="应收金额" min-width="80" align="center"></el-table-column> |
|||
<el-table-column prop="ssje" label="实收金额" min-width="80" align="center"></el-table-column> |
|||
</el-table-column> |
|||
</el-table> |
|||
</div> |
|||
</div> |
|||
</template> |
|||
<script> |
|||
import { mapState } from "vuex"; |
|||
import { getapi, postapi, putapi, deletapi } from "@/api/api"; |
|||
import { deepCopy, dddw, arrayExistObj } from "../../utlis/proFunc"; |
|||
import CusOrgOCX from "./CusOrgOCX.vue"; |
|||
import { UTable, UTableColumn } from "umy-ui"; |
|||
import moment from "moment"; |
|||
import FileSaver from "file-saver"; |
|||
|
|||
export default { |
|||
components: { |
|||
CusOrgOCX, UTable, UTableColumn |
|||
}, |
|||
props: ["orgEnable"], |
|||
data() { |
|||
return { |
|||
dialogVisible: false, |
|||
local: { |
|||
completeFlag: [], |
|||
}, |
|||
|
|||
customerOrg: [], |
|||
customerOrgAll: [], |
|||
medicalType: [], |
|||
personnelType: [], |
|||
dictSalesman: [], |
|||
|
|||
query: { |
|||
dateType: "1", |
|||
startDate: "", |
|||
endDate: "", |
|||
customerOrgIds: [], |
|||
medicalTypeIds: [], |
|||
personnelTypeIds: [], |
|||
salesmans: [], |
|||
|
|||
// isMedicalTypeId: 'Y', |
|||
isPreRegistration: "N", |
|||
itemTypeIds: [], |
|||
}, |
|||
|
|||
tableData: [ |
|||
{ |
|||
itemTypeName: 'CT', |
|||
itemDetails: [ |
|||
{ |
|||
asbitemName: '胸部CT', djrs: 4, yjrs: 2, bzje: 6, ysje: 8, ssje: 10, |
|||
details: [ |
|||
{ org: 'C座', djrs: 3, yjrs: 2, bzje: 3, ysje: 4, ssje: 6 }, |
|||
{ org: 'B座', djrs: 1, yjrs: 0, bzje: 3, ysje: 4, ssje: 2 } |
|||
] |
|||
}, |
|||
{ |
|||
asbitemName: '头部CT', djrs: 2, yjrs: 1, bzje: 3, ysje: 4, ssje: 5, |
|||
details: [ |
|||
{ org: 'C座', djrs: 2, yjrs: 1, bzje: 3, ysje: 4, ssje: 5 }, |
|||
{ org: 'B座', djrs: 0, yjrs: 0, bzje: 0, ysje: 0, ssje: 0 } |
|||
] |
|||
} |
|||
] |
|||
} |
|||
], //原始数据 |
|||
asyncCols:['C座','B座'], // 动态体检中心 |
|||
tableDataTrans: [], //转换后数据 |
|||
}; |
|||
}, |
|||
|
|||
created() { |
|||
try { |
|||
let LocalConfig = JSON.parse( |
|||
window.localStorage.getItem("LocalConfig") || null |
|||
); |
|||
if (LocalConfig?.normal?.maxResultCount) { |
|||
this.loadOpts.maxResultCount = LocalConfig.normal.maxResultCount; |
|||
} |
|||
} catch (error) { |
|||
console.log('window.localStorage.getItem("LocalConfig")', error); |
|||
} |
|||
|
|||
this.loadOptsInit = Object.assign({}, this.loadOpts); |
|||
}, |
|||
|
|||
//挂载完成 |
|||
mounted() { |
|||
this.dictInit(); |
|||
}, |
|||
|
|||
updated() { |
|||
// this.$nextTick(() => { |
|||
// this.$refs["refTable"].doLayout(); |
|||
// }); |
|||
}, |
|||
|
|||
computed: { |
|||
...mapState(["pickerOptions", "window", "dict", "patientRegister", "report"]), |
|||
// 返回查询条件 |
|||
queryCondition() { |
|||
let ret = '', sp = '' |
|||
let lfind = 0 |
|||
switch (this.query.dateType) { |
|||
case '2': |
|||
ret = '体检日期' |
|||
break; |
|||
case '3': |
|||
ret = '总检日期' |
|||
break; |
|||
case '6': |
|||
ret = '收费日期' |
|||
break; |
|||
default: |
|||
ret = '登记日期' |
|||
break; |
|||
} |
|||
if (this.query.startDate) { |
|||
ret += ":" + this.query.startDate + '--' |
|||
} else { |
|||
ret += ": ≤ " |
|||
} |
|||
if (this.query.endDate) { |
|||
ret += this.query.endDate |
|||
} else { |
|||
ret += moment(new Date()).format('yyyy-MM-DD') |
|||
} |
|||
if (this.query.medicalTypeIds.length > 0) { |
|||
ret += ' 体检类别:' |
|||
this.query.medicalTypeIds.forEach((e, i) => { |
|||
if (i == 0) { |
|||
sp = '' |
|||
} else { |
|||
sp = '、' |
|||
} |
|||
lfind = arrayExistObj(this.dict.medicalType, 'id', e) |
|||
if (lfind > -1) ret += sp + this.dict.medicalType[lfind].displayName |
|||
}); |
|||
} |
|||
if (this.query.personnelTypeIds.length > 0) { |
|||
ret += ' 人员类别:' |
|||
this.query.personnelTypeIds.forEach((e, i) => { |
|||
if (i == 0) { |
|||
sp = '' |
|||
} else { |
|||
sp = '、' |
|||
} |
|||
lfind = arrayExistObj(this.dict.personnelType, 'id', e) |
|||
if (lfind > -1) ret += sp + this.dict.personnelType[lfind].displayName |
|||
}); |
|||
} |
|||
return ret |
|||
} |
|||
}, |
|||
methods: { |
|||
dddw, |
|||
/** |
|||
* Element UI 表格合并方法 |
|||
* @param {Object} params - { row, column, rowIndex, columnIndex } |
|||
* @returns {Array} [rowspan, colspan] |
|||
*/ |
|||
spanMethod({ row, column, rowIndex, columnIndex }) { |
|||
if (columnIndex === 0) { |
|||
const currentName = row.itemTypeName; |
|||
const prevRow = this.tableDataTrans[rowIndex - 1]; |
|||
if (prevRow && prevRow.itemTypeName === currentName) { |
|||
return [0, 0]; |
|||
} else { |
|||
let rowspan = 1; |
|||
for (let i = rowIndex + 1; i < this.tableDataTrans.length; i++) { |
|||
if (this.tableDataTrans[i].itemTypeName === currentName) rowspan++; |
|||
else break; |
|||
} |
|||
return [rowspan, 1]; |
|||
} |
|||
} |
|||
return [1, 1]; |
|||
}, |
|||
|
|||
//获取初始数据 |
|||
dictInit() { |
|||
let today = moment(new Date()).format("YYYY-MM-DD"); |
|||
this.query.startDate = today; |
|||
this.query.endDate = today; |
|||
|
|||
//获取单位列表 |
|||
getapi("/api/app/customer-org/parent-all").then((res) => { |
|||
if (res.code != -1) { |
|||
this.customerOrgAll = res.data; |
|||
this.customerOrg = deepCopy(this.customerOrgAll); |
|||
} |
|||
}); |
|||
|
|||
//体检类别 |
|||
getapi("/api/app/medical-type/in-filter").then((res) => { |
|||
if (res.code > -1) { |
|||
this.dict.medicalType = res.data; |
|||
this.medicalType = res.data; |
|||
} |
|||
}); |
|||
|
|||
//人员类别 |
|||
getapi("/api/app/personnel-type/in-filter").then((res) => { |
|||
if (res.code == 1) { |
|||
this.dict.personnelType = res.data; |
|||
this.personnelType = res.data; |
|||
} |
|||
}); |
|||
|
|||
// 业务员 { |
|||
postapi('/api/identity/users/GetUserListBySaleRole') |
|||
.then(res => { |
|||
if (res.code > -1) { |
|||
this.dictSalesman = res.data |
|||
} |
|||
}) |
|||
|
|||
// 项目类别 树结构 |
|||
getapi("/api/app/item-type/by-code-all").then((res) => { |
|||
if (res.code != -1) { |
|||
this.dict.itemTypeTree = res.data; |
|||
} |
|||
}); |
|||
|
|||
}, |
|||
|
|||
//通用导出 |
|||
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); |
|||
}, |
|||
|
|||
// 单位过滤 |
|||
filterMethod(keyWords) { |
|||
if (keyWords) { |
|||
this.customerOrg = []; |
|||
this.customerOrgAll.forEach((item) => { |
|||
if ( |
|||
item.displayName.toLowerCase().indexOf(keyWords.toLowerCase()) > -1 || |
|||
item.simpleCode.toLowerCase().indexOf(keyWords.toLowerCase()) > -1 |
|||
// || item.shortName.toLowerCase().indexOf(keyWords.toLowerCase()) > - 1 |
|||
) { |
|||
this.customerOrg.push(item); |
|||
} |
|||
}); |
|||
} else { |
|||
this.customerOrg = deepCopy(this.customerOrgAll); |
|||
} |
|||
}, |
|||
|
|||
// 体检类别过滤 |
|||
filterMethodM(keyWords) { |
|||
if (keyWords) { |
|||
this.medicalType = []; |
|||
this.dict.medicalType.forEach((item) => { |
|||
if ( |
|||
item.displayName.toLowerCase().indexOf(keyWords.toLowerCase()) > -1 |
|||
) { |
|||
this.medicalType.push(item); |
|||
} |
|||
}); |
|||
} else { |
|||
this.medicalType = deepCopy(this.dict.medicalType); |
|||
} |
|||
}, |
|||
|
|||
// 人员类别过滤 |
|||
filterMethodP(keyWords) { |
|||
if (keyWords) { |
|||
this.personnelType = []; |
|||
this.dict.personnelType.forEach((item) => { |
|||
if ( |
|||
item.displayName.toLowerCase().indexOf(keyWords.toLowerCase()) > -1 |
|||
// || item.shortName.toLowerCase().indexOf(keyWords.toLowerCase()) > - 1 |
|||
) { |
|||
this.personnelType.push(item); |
|||
} |
|||
}); |
|||
} else { |
|||
this.personnelType = deepCopy(this.dict.personnelType); |
|||
} |
|||
}, |
|||
|
|||
|
|||
// 按钮查询 |
|||
btnQuery() { |
|||
this.tableData = [] |
|||
this.loadOpts = Object.assign({}, this.loadOptsInit) |
|||
this.queryEvent() |
|||
}, |
|||
|
|||
// 触发滚动 |
|||
scrollQuery(scroll, event) { |
|||
// 是否拉到底部 |
|||
if (!scroll.judgeFlse) return; |
|||
|
|||
if (this.scolling) return |
|||
|
|||
// this.dom = document.getElementById("refTable") |
|||
// this.dom = this.$refs["refTable"].bodyWrapper; |
|||
// console.log('this.dom', this.dom) |
|||
|
|||
// this.dom.addEventListener('scroll', () => { |
|||
// // // console.log('scrollTop',this.dom.scrollTop,'clientHeight',this.dom.clientHeight,'scrollHeight',this.dom.scrollHeight); |
|||
// if (this.dom.scrollTop + this.dom.clientHeight + 20 > this.dom.scrollHeight) { |
|||
// this.scolling = false |
|||
// }else{ |
|||
// this.scolling = true |
|||
// } |
|||
// }) |
|||
|
|||
// if (this.scolling) return |
|||
this.loadOpts.skipCount++ |
|||
if ( |
|||
this.loadOpts.skipCount != 0 && |
|||
this.loadOpts.skipCount * this.loadOpts.maxResultCount >= |
|||
this.loadOpts.totalCount |
|||
) { |
|||
// this.$message.warning({ showClose: true, message: '没有可拉取的数据了' }) |
|||
return; |
|||
} |
|||
|
|||
this.scolling = true |
|||
this.queryEvent() |
|||
.finally(() => { |
|||
this.scolling = false |
|||
}) |
|||
|
|||
}, |
|||
|
|||
// 查询事件 |
|||
queryEvent() { |
|||
return new Promise((resolve, reject) => { |
|||
let body = Object.assign({}, this.query, this.loadOpts) |
|||
if (this.query.patientRegisterNo) { |
|||
body = { patientRegisterNo: this.query.patientRegisterNo } |
|||
} else if (this.query.patientNo) { |
|||
body = { patientNo: this.query.patientNo } |
|||
} else { |
|||
delete body.patientRegisterNo |
|||
delete body.patientNo |
|||
if (!body.startDate) body.startDate = '1900-01-01' |
|||
if (!body.endDate) body.endDate = moment(new Date()).format('yyyy-MM-DD') |
|||
} |
|||
postapi("/api/app/CustomerReport/GetCustomerOrgPhysicalExaminationDetailStatistics", body) |
|||
.then(res => { |
|||
if (res.code > -1) { |
|||
this.loadOpts.totalCount = res.data.totalCount |
|||
let arrs = [].concat(res.data.items); |
|||
arrs.forEach(e => { |
|||
e.groupPack = e.customerOrgGroupName || e.medicalPackageName |
|||
e.deptName = (e.customerOrgName == e.departmentName ? '' : e.departmentName) |
|||
e.birthDate = e?.birthDate.substring(0, 10) || e.birthDate |
|||
e.medicalStartDate = e?.medicalStartDate.substring(0, 10) || e.medicalStartDate |
|||
}); |
|||
this.tableData = [].concat(this.tableData, arrs) |
|||
this.getSummaries() |
|||
} |
|||
}) |
|||
.finally(() => { |
|||
resolve() |
|||
}); |
|||
}) |
|||
}, |
|||
|
|||
//合计 |
|||
getSummaries() { |
|||
this.loadOpts.standardAmount = 0 |
|||
this.loadOpts.receivableAmount = 0 |
|||
this.loadOpts.chargeAmount = 0 |
|||
this.tableData.forEach(e => { |
|||
this.loadOpts.standardAmount = Number(this.loadOpts.standardAmount) + Number(e.standardAmount) |
|||
this.loadOpts.receivableAmount = Number(this.loadOpts.receivableAmount) + Number(e.receivableAmount) |
|||
this.loadOpts.chargeAmount = Number(this.loadOpts.chargeAmount) + Number(e.chargeAmount) |
|||
}); |
|||
this.loadOpts.standardAmount = Math.round(this.loadOpts.standardAmount * 100) / 100 |
|||
this.loadOpts.receivableAmount = Math.round(this.loadOpts.receivableAmount * 100) / 100 |
|||
this.loadOpts.chargeAmount = Math.round(this.loadOpts.chargeAmount * 100) / 100 |
|||
}, |
|||
}, |
|||
}; |
|||
</script> |
|||
<style scoped> |
|||
@import "../../assets/css/global.css"; |
|||
@import "../../assets/css/global_font.css"; |
|||
|
|||
::v-deep .el-input__inner { |
|||
/*text-align: center;*/ |
|||
padding-left: 5px; |
|||
padding-right: 15px; |
|||
} |
|||
|
|||
::v-deep .el-input__icon { |
|||
width: 15px; |
|||
/* 输入框下拉箭头或清除图标 默认 25 */ |
|||
} |
|||
|
|||
::v-deep .el-input-group__append { |
|||
padding: 0 5px; |
|||
/* 控件默认 0 20px;*/ |
|||
} |
|||
|
|||
::v-deep .el-icon-search:before { |
|||
color: #00f; |
|||
} |
|||
|
|||
.query { |
|||
margin-left: 5px; |
|||
margin-bottom: 5px; |
|||
font-size: 14px; |
|||
color: #232748; |
|||
font-weight: 400; |
|||
font-family: "NotoSansSC-Regular"; |
|||
} |
|||
|
|||
.spanClass { |
|||
padding: 0 2px 0 0; |
|||
} |
|||
</style> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue