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.

407 lines
14 KiB

3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
  1. <template>
  2. <div>
  3. <div class="middlebox">
  4. <div class="contenttitle">
  5. 体检查询 /
  6. <span class="contenttitleBold">营业额统计实收</span>
  7. </div>
  8. </div>
  9. <div
  10. style="display: flex;justify-content: space-between; padding: 10px;background-color: #fff;border-radius: 8px;margin-bottom: 10px;">
  11. <div style="display:block;">
  12. <div style="display: flex;flex-wrap: wrap;height: 32px;align-items: center;">
  13. <div class="query">
  14. <el-select v-model="query.dateType" placeholder="请选择" style="width: 80px" size="small" disabled>
  15. <el-option label="登记日期" :value="'1'" />
  16. <el-option label="体检日期" :value="'2'" />
  17. <el-option label="总检日期" :value="'3'" />
  18. <el-option label="收费日期" :value="'6'" />
  19. </el-select>
  20. <!-- dateType 1 登记2 体检3 总检日期-->
  21. <el-date-picker v-model="query.startDate" type="date" placeholder="起始日期" size="small" style="width:90px;"
  22. value-format="yyyy-MM-dd" :picker-options="pickerOptions" />
  23. <span class="spanClass"></span>
  24. <el-date-picker v-model="query.endDate" type="date" placeholder="截止日期" size="small" style="width:90px;"
  25. value-format="yyyy-MM-dd" :picker-options="pickerOptions" />
  26. </div>
  27. <div class="query">
  28. <span class="spanClass">体检单位</span>
  29. <el-select v-model="query.customerOrgIds" placeholder="请选择体检单位" :filter-method="filterMethod"
  30. default-first-option clearable filterable style="margin-left: 10px;width:300px;" size="small" multiple
  31. collapse-tags>
  32. <el-option v-for="item in customerOrg" :key="item.id" :label="item.displayName" :value="item.id">
  33. {{ item.displayName }}
  34. </el-option>
  35. </el-select>
  36. </div>
  37. <div class="query">
  38. <span class="spanClass">含预登记</span>
  39. <el-checkbox v-model="query.isPreRegistration" true-label="Y" false-label="N" />
  40. </div>
  41. <div class="query">
  42. <span class="spanClass">含子单位</span>
  43. <el-checkbox v-model="query.isChild" true-label="Y" false-label="N" @change="btnQuery" />
  44. </div>
  45. <div class="query">
  46. <span class="spanClass">单位次数</span>
  47. <el-checkbox v-model="query.isCustomerOrgRegister" true-label="Y" false-label="N" @change="btnQuery" />
  48. </div>
  49. </div>
  50. <div style="display: flex;flex-wrap: wrap;margin-top: 2px; height: 32px;align-items: center;">
  51. <div class="query">
  52. <span class="spanClass">体检类别</span>
  53. <el-select v-model="query.medicalTypeIds" placeholder="请选择体检类别" :filter-method="filterMethod"
  54. default-first-option clearable filterable style="margin-left: 10px;width:200px;" size="small" multiple
  55. collapse-tags>
  56. <el-option v-for="item in medicalType" :key="item.id" :label="item.displayName" :value="item.id">
  57. {{ item.displayName }}
  58. </el-option>
  59. </el-select>
  60. </div>
  61. <div class="query">
  62. <span class="spanClass">人员类别</span>
  63. <el-select v-model="query.personnelTypeIds" placeholder="请选择人员类别" :filter-method="filterMethod"
  64. default-first-option clearable filterable style="margin-left: 10px;width:200px;" size="small" multiple
  65. collapse-tags>
  66. <el-option v-for="item in personnelType" :key="item.id" :label="item.displayName" :value="item.id">
  67. {{ item.displayName }}
  68. </el-option>
  69. </el-select>
  70. </div>
  71. <div class="query">
  72. <span class="spanClass">业务员</span>
  73. <el-select v-model="query.salesmans" placeholder="请输入业务员姓名" default-first-option clearable filterable
  74. style="margin-left: 10px" size="small" multiple collapse-tags>
  75. <el-option v-for="item in dictSalesman" :key="item.id" :label="item.surname" :value="item.surname" />
  76. </el-select>
  77. </div>
  78. <div class="query">
  79. <span>支付方式</span>
  80. <el-select v-model="query.payModeIds" placeholder="请选择" style="margin-left: 10px" filterable clearable
  81. size="small" multiple collapse-tags>
  82. <el-option v-for="item in dict.payMode" :key="item.id" :label="item.displayName" :value="item.id" />
  83. </el-select>
  84. </div>
  85. </div>
  86. </div>
  87. <div style="display: block;width: 110px;">
  88. <div>
  89. <el-button type="primary" class="commonbutton" @click="btnQuery" size="small">查询</el-button>
  90. </div>
  91. <div style="margin-top: 5px;">
  92. <el-button class="commonbutton" @click="btnExport('tableData')" size="small">导出</el-button>
  93. </div>
  94. </div>
  95. </div>
  96. <div id="tableData">
  97. <el-table :data="tableData" border :height="window.pageHeight - 192" highlight-current-row size="small"
  98. row-key="id" :summary-method="getSummaries" show-summary ref="refTable">
  99. <el-table-column type="index" label="序号" width="50" align="center" />
  100. <el-table-column prop="customerOrgName" label="单位名称" min-width="240" />
  101. <el-table-column v-if="query.isCustomerOrgRegister == 'Y' ? true : false" prop="medicalTimes" label="单位次数"
  102. min-width="80" align="center" />
  103. <el-table-column label="收款" align="center">
  104. <el-table-column prop="chargeCount" label="人数" min-width="80" align="center" />
  105. <el-table-column prop="chargeTotal" label="金额" min-width="80" align="center" />
  106. </el-table-column>
  107. <el-table-column label="退款" min-width="80" align="center">
  108. <el-table-column prop="refundCount" label="人数" min-width="80" align="center" />
  109. <el-table-column prop="refundTotal" label="金额" min-width="80" align="center" />
  110. </el-table-column>
  111. <el-table-column label="营收金额" min-width="80" align="center">
  112. <el-table-column prop="turnoverTotal" label="汇总" min-width="80" align="center" />
  113. <el-table-column v-for="(col, index) in asyncCols" :key="index" :prop="col" :label="col" min-width="80"
  114. align="center">
  115. <template slot-scope="scope">
  116. <el-tooltip class="item" :content="`收款:${scope.row[col + '_p']} 退款:${scope.row[col + '_b']}`"
  117. placement="top">
  118. <div v-if="scope.row[col] != 0 ? true : false">{{ scope.row[col] }}</div>
  119. </el-tooltip>
  120. </template>
  121. </el-table-column>
  122. </el-table-column>
  123. </el-table>
  124. </div>
  125. </div>
  126. </template>
  127. <script>
  128. import { mapState } from "vuex";
  129. import { getapi, postapi, putapi, deletapi } from "@/api/api";
  130. import { deepCopy } from "../../utlis/proFunc"
  131. import CusOrgOCX from "./CusOrgOCX.vue"
  132. import moment from "moment";
  133. import FileSaver from 'file-saver';
  134. export default {
  135. components: {
  136. CusOrgOCX,
  137. },
  138. props: ["orgEnable"],
  139. data() {
  140. return {
  141. dialogVisible: false,
  142. local: {
  143. completeFlag: []
  144. },
  145. customerOrg: [],
  146. customerOrgAll: [],
  147. medicalType: [],
  148. personnelType: [],
  149. dictSalesman: [],
  150. query: {
  151. dateType: '6',
  152. startDate: '',
  153. endDate: '',
  154. customerOrgIds: [],
  155. medicalTypeIds: [],
  156. personnelTypeIds: [],
  157. salesmans: [],
  158. payModeIds: [],
  159. // isMedicalTypeId: 'Y',
  160. isPreRegistration: 'N',
  161. isChild: 'Y',
  162. isCustomerOrgRegister: 'N', // 是否显示单位体检次数
  163. },
  164. tableData: [],
  165. asyncCols: [], // 动态列
  166. };
  167. },
  168. created() {
  169. },
  170. //挂载完成
  171. mounted() {
  172. this.dictInit()
  173. },
  174. updated() {
  175. this.$nextTick(() => {
  176. this.$refs['refTable'].doLayout()
  177. })
  178. },
  179. computed: {
  180. ...mapState(["pickerOptions", "window", "dict", "patientRegister", "report"]),
  181. },
  182. methods: {
  183. //获取初始数据
  184. dictInit() {
  185. let today = moment(new Date()).format("YYYY-MM-DD")
  186. this.query.startDate = today
  187. this.query.endDate = today
  188. //获取单位列表
  189. getapi("/api/app/customer-org/parent-all").then((res) => {
  190. if (res.code != -1) {
  191. this.customerOrgAll = res.data;
  192. this.customerOrg = deepCopy(this.customerOrgAll);
  193. }
  194. });
  195. //体检类别
  196. getapi("/api/app/medical-type/in-filter").then((res) => {
  197. if (res.code > -1) {
  198. this.dict.medicalType = res.data;
  199. this.medicalType = res.data
  200. }
  201. });
  202. //人员类别
  203. getapi("/api/app/personnel-type/in-filter").then((res) => {
  204. if (res.code == 1) {
  205. this.dict.personnelType = res.data;
  206. this.personnelType = res.data;
  207. }
  208. });
  209. // 业务员 {
  210. postapi('/api/identity/users/GetUserListBySaleRole')
  211. .then(res => {
  212. if (res.code > -1) {
  213. this.dictSalesman = res.data
  214. }
  215. })
  216. //支付方式
  217. getapi("/api/app/pay-mode").then((res) => {
  218. if (res.code == 1) {
  219. this.dict.payMode = res.data;
  220. }
  221. });
  222. },
  223. //通用导出
  224. btnExport(elId) {
  225. let table = document.getElementById(elId);
  226. let tableData = table.innerHTML
  227. let fileName = moment(new Date()).format('yyyyMMDDHHmmss') + '.xls'
  228. let blob = new Blob([tableData], { type: "text/plain;charset=utf-8" });
  229. FileSaver.saveAs(blob, fileName);
  230. },
  231. // 单位过滤
  232. filterMethod(keyWords) {
  233. if (keyWords) {
  234. this.customerOrg = [];
  235. this.customerOrgAll.forEach((item) => {
  236. if (
  237. item.displayName.toLowerCase().indexOf(keyWords.toLowerCase()) > -1 ||
  238. item.simpleCode.toLowerCase().indexOf(keyWords.toLowerCase()) > -1
  239. // || item.shortName.toLowerCase().indexOf(keyWords.toLowerCase()) > - 1
  240. ) {
  241. this.customerOrg.push(item);
  242. }
  243. });
  244. } else {
  245. this.customerOrg = deepCopy(this.customerOrgAll);
  246. }
  247. },
  248. // 查询
  249. btnQuery() {
  250. //let body = deepCopy(this.query)
  251. postapi("/api/app/CustomerReport/GetCustomerOrgAmountReceivedStatistics", this.query).then(res => {
  252. if (res.code > -1) {
  253. // 动态生成新的显示数据
  254. this.makeDispData(res.data)
  255. }
  256. })
  257. },
  258. // 动态生成新的显示数据
  259. makeDispData(orgData) {
  260. this.tableData = []
  261. this.asyncCols = []
  262. // 没有数据返回
  263. if (!(Array.isArray(orgData) && orgData.length > 0)) return
  264. orgData.forEach(e => {
  265. if (this.query.isChild == 'Y') {
  266. e.customerOrgName = (e.customerOrgName == e.departmentName ? e.customerOrgName : e.customerOrgName + '--' + e.departmentName)
  267. }
  268. e.chargeTotal = 0
  269. e.refundTotal = 0
  270. e.feeDetail.forEach(c => {
  271. e.chargeTotal = Number(e.chargeTotal) + Number(c.chargeMoney)
  272. e.refundTotal = Number(e.refundTotal) + Number(c.refundMoney)
  273. if (!this.asyncCols.includes(c.payModeName)) {
  274. this.asyncCols.push(c.payModeName)
  275. }
  276. e[c.payModeName] = Math.round((Number(c.chargeMoney) + Number(c.refundMoney)) * 100) / 100
  277. e[c.payModeName + '_p'] = c.chargeMoney // 收
  278. e[c.payModeName + '_b'] = c.refundMoney // 退
  279. });
  280. e.chargeTotal = Math.round(e.chargeTotal * 100) / 100
  281. e.refundTotal = Math.round(e.refundTotal * 100) / 100
  282. e.turnoverTotal = Math.round((Number(e.chargeTotal) + Number(e.refundTotal)) * 100) / 100
  283. this.tableData.push(e)
  284. });
  285. this.tableData.forEach(e => {
  286. this.asyncCols.forEach(col => {
  287. if (!e[col]) {
  288. e[col] = 0
  289. }
  290. });
  291. });
  292. // console.log('this.tableData',this.tableData)
  293. // console.log('this.asyncCols',this.asyncCols)
  294. },
  295. //合计
  296. getSummaries(param) {
  297. // console.log('getSummaries param', param)
  298. // if(!param){
  299. // param = {
  300. // columns:[{}, {}, {}, {}, {}, {}, {property: 'asbitemMoney'},{property: 'customerOrgGroupDetailMoney'}],
  301. // data:this.customerOrgGroupAsbitems
  302. // }
  303. // }
  304. const { columns, data } = param;
  305. let count = 7, sumCol = [] //需合计的列
  306. const sums = [];
  307. if (this.query.isCustomerOrgRegister == 'Y') {
  308. sumCol = [2, 3, 4, 5, 6, 7]
  309. count = 8
  310. } else {
  311. sumCol = [2, 3, 4, 5, 6]
  312. }
  313. this.asyncCols.forEach(() => {
  314. sumCol.push(count++)
  315. });
  316. console.log('sumCol', sumCol)
  317. columns.forEach((column, index) => {
  318. console.log('column.property, index,data', column.property, index, data)
  319. //显示合计列
  320. if (index === 1) {
  321. sums[index] = '合计';
  322. return;
  323. }
  324. //不合计的列
  325. if (sumCol.indexOf(index) == -1) {
  326. sums[index] = '';
  327. return;
  328. }
  329. sums[index] = 0
  330. data.forEach(e => {
  331. if (!isNaN(e[column.property])) sums[index] += Number(e[column.property])// * e['amount']
  332. })
  333. sums[index] = sums[index].toFixed(2) //+ ' 元';
  334. });
  335. // this.groupPrice = sums[7];
  336. // console.log('getSummaries',sums)
  337. // if (!this.totalFoucs) this.total = sums[5];
  338. // if (!this.discountFoucs) this.discount = Number(this.total * 100 / this.totalStand).toFixed(2);
  339. return sums;
  340. },
  341. },
  342. };
  343. </script>
  344. <style scoped>
  345. @import '../../assets/css/global.css';
  346. @import '../../assets/css/global_font.css';
  347. ::v-deep .el-input__inner {
  348. /*text-align: center;*/
  349. padding-left: 5px;
  350. padding-right: 15px;
  351. }
  352. ::v-deep .el-input__icon {
  353. width: 15px;
  354. /* 输入框下拉箭头或清除图标 默认 25 */
  355. }
  356. ::v-deep .el-input-group__append {
  357. padding: 0 5px;
  358. /* 控件默认 0 20px;*/
  359. }
  360. ::v-deep .el-icon-search:before {
  361. color: #00F;
  362. }
  363. .query {
  364. margin-left: 10px;
  365. font-size: 14px;
  366. color: #232748;
  367. font-weight: 400;
  368. font-family: "NotoSansSC-Regular";
  369. }
  370. .spanClass {
  371. padding: 0 2px 0 0;
  372. }
  373. </style>