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.

1160 lines
38 KiB

2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
  1. <template>
  2. <div style="display: flex; margin-left: 10px; margin-top: 10px;">
  3. <div style="width:220px;">
  4. <div>
  5. <span>项目类别</span>
  6. <el-cascader :options="dict.itemTypeTree" v-model="itemTypeIds" style="margin-left: 3px;width:160px;"
  7. :props="{ checkStrictly: true, expandTrigger: 'hover', ...customerOrg.treeprops, }" :show-all-levels="false"
  8. clearable filterable @change="changeItemType" size="small">
  9. </el-cascader>
  10. </div>
  11. <div class="mainareaBox">
  12. <el-table :data="asbItem"
  13. :height="(window.pageHeight > 700 ? (window.pageHeight - 440) : 260)" @row-dblclick="dbClickChoosedAsb" highlight-current-row
  14. @selection-change="handleSelectionChange" size="small" :row-class-name="handleRowClassName"
  15. @row-click="chooseAsbItem">
  16. <!--
  17. <el-table-column type="selection" align="center" width="40" />
  18. -->
  19. <el-table-column prop="displayName" label="未选组合项目" />
  20. <!--
  21. <el-table-column prop="price" label="标准价格" width="70">
  22. <template slot-scope="scope">
  23. <div style="text-align: center;">{{ scope.row.price }}</div>
  24. </template>
  25. </el-table-column>
  26. <el-table-column prop="forSexId" label="适用性别" width="70">
  27. <template slot-scope="scope">
  28. <div style="text-align: center;">{{ ldddw(dict.forSex, "id", scope.row.forSexId, "displayName") }}</div>
  29. </template>
  30. </el-table-column>
  31. -->
  32. </el-table>
  33. </div>
  34. </div>
  35. <div style="width:100px;margin-top: 70px;">
  36. <div class="btnList">
  37. <el-button type="primary" @click="addAbs(asbItemChoosed,'choosed')" style="width:90px;">添加 <i class="el-icon-arrow-right"></i>
  38. </el-button>
  39. </div>
  40. <div class="btnList">
  41. <el-button type="success" @click="addAbs(asbItemChoosed,'all')" style="width:90px;">全添加 <i class="el-icon-d-arrow-right"></i>
  42. </el-button>
  43. </div>
  44. <div class="btnList">
  45. <el-button type="warning" @click="delAbs(patientRegisterAbsChoosed,'choosed')" style="width:90px;"><i class="el-icon-arrow-left"> 移除</i>
  46. </el-button>
  47. </div>
  48. <div class="btnList">
  49. <el-button type="danger" @click="delAbs(patientRegisterAbsChoosed,'all')" style="width:90px;"><i class="el-icon-d-arrow-left"> 全移除</i>
  50. </el-button>
  51. </div>
  52. <!-- 不显示保存当已选组合有修改时失去焦点自动保存
  53. <div class="btnList">
  54. <el-button type="success" @click="onSubmit('保存')">保存 <i class="el-icon-check"></i>
  55. </el-button>
  56. </div>
  57. -->
  58. </div>
  59. <div :style="'width:' + (window.pageWidth - 110 - 20 - 230 - 100) + 'px;'">
  60. <div style="display: flex;">
  61. <div class="disTotal">
  62. <el-tooltip class="item" effect="dark" content="根据输入的折扣,自动计算折后总价" placement="top">
  63. <span>折扣 </span>
  64. </el-tooltip>
  65. <el-input style="width:55px;" v-model="discount" size="small" type="number" @input="changeAllDiscount"
  66. @focus="discountFoucs = true" @blur="discountFoucs = false" />
  67. </div>
  68. <div class="disTotal">
  69. <el-tooltip class="item" effect="dark" content="总金额即该人员此次体检实收金额,并根据此金额自动计算折扣" placement="top">
  70. <span>总金额 </span>
  71. </el-tooltip>
  72. <el-input style="width:70px;" v-model="total" size="small" type="number" @input="changeTotal" ref="total"
  73. @focus="totalFoucs = true" @blur="totalFoucs = false" />
  74. </div>
  75. <div class="disTotal">
  76. <el-select v-model="asbItemId" placeholder="快速选择组合项目" size="small"
  77. filterable :filter-method="filterMethod"
  78. clearable @clear="quickAsb = deepCopy(asbItemQuick)"
  79. @change="quickChoosedAsb" default-first-option ref="quickAsbOCX"
  80. style="width:150px;text-align: left;padding-right: 15px;">
  81. <el-option v-for="item in quickAsb" :key="item.id" :value="item.id" :label="item.displayName" />
  82. </el-select>
  83. </div>
  84. </div>
  85. <div class="mainareaBox">
  86. <el-table :data="prAsb" highlight-current-row border ref="patientRegister_patientRegisterAbs"
  87. :height="(window.pageHeight > 700 ? (window.pageHeight - 440) : 260)" width="100%" :summary-method="getSummaries"
  88. show-summary :row-class-name="handleRowClassName" @row-dblclick="removeAbs" @selection-change="selecteditems" size="small"
  89. @row-click="removeAsbItem">
  90. <!-- temporaryselection personnelUnit.nogroupselected-->
  91. <!-- 取消勾选换成选中
  92. <el-table-column type="selection" align="center"/>
  93. -->
  94. <el-table-column label="已选组合项目" min-width="120" prop="asbitemName" >
  95. <template slot-scope="scope">
  96. <div>
  97. <el-tooltip class="item" effect="dark" content="套餐/分组中包含的组合项目" placement="top">
  98. <i v-if="scope.row.groupPackageId" class="el-icon-star-on" style="font-size: 14px;color: purple;"></i>
  99. </el-tooltip>
  100. {{ scope.row.asbitemName }}
  101. </div>
  102. </template>
  103. </el-table-column>
  104. <el-table-column label="标准价格" prop="standardPrice" min-width="70" align="center" />
  105. <el-table-column label="折扣" prop="discount" min-width="60">
  106. <template slot-scope="scope">
  107. <el-input type="number" v-model="scope.row.discount" size="small" @input="changeDiscount(scope.$index)" />
  108. </template>
  109. </el-table-column>
  110. <el-table-column label="数量" prop="amount" min-width="50">
  111. <template slot-scope="scope">
  112. <el-input type="number" v-model="scope.row.amount" size="small" @input="changeDiscount(scope.$index)" />
  113. </template>
  114. </el-table-column>
  115. <el-table-column label="实收价格" prop="chargePrice" min-width="70">
  116. <template slot-scope="scope">
  117. <el-input type="number" v-model="scope.row.chargePrice" size="small"
  118. @input="changePrice(scope.$index)" /> <!--立即触发保存 @blur="onSubmit('')" -->
  119. </template>
  120. </el-table-column>
  121. <el-table-column prop="total" label="金额" min-width="70" align="center"/>
  122. <el-table-column prop="standardPrice" label="标准金额" min-width="70" v-if="false" />
  123. <el-table-column label="支付方式" prop="payTypeFlag" min-width="100">
  124. <template slot-scope="scope">
  125. <el-select v-model="scope.row.payTypeFlag" size="small">
  126. <el-option v-for="item in dict.payType" :key="item.id" :label="item.displayName" :value="item.id" />
  127. </el-select>
  128. </template>
  129. </el-table-column>
  130. <el-table-column prop="isCharge" label="收费" min-width="40" align="center">
  131. <template slot-scope="scope">
  132. <el-checkbox :value="scope.row.isCharge == 'Y'" />
  133. </template>
  134. </el-table-column>
  135. <el-table-column prop="checkCompleteFlag" label="状态" min-width="40" align="center">
  136. <template slot-scope="scope">
  137. <div>{{ dddw(dict.checkCompleteFlag, "id", scope.row.checkCompleteFlag, "displayName") }}</div>
  138. </template>
  139. </el-table-column>
  140. <el-table-column prop="isLock" label="锁" min-width="40" align="center">
  141. <template slot-scope="scope">
  142. <el-checkbox :value="scope.row.isLock == 'Y'" />
  143. </template>
  144. </el-table-column>
  145. <el-table-column prop="creatorName" label="登记人" min-width="70" align="center"></el-table-column>
  146. <el-table-column prop="creationTime" label="登记日期" win-width="90" align="center">
  147. <template slot-scope="scope">
  148. <div>{{ scope.row.creationTime ? moment(scope.row.creationTime).format('yyyy-MM-DD'):'' }}</div>
  149. </template>
  150. </el-table-column>
  151. </el-table>
  152. </div>
  153. </div>
  154. </div>
  155. </template>
  156. <script>
  157. import moment from 'moment';
  158. import { mapState, mapActions } from "vuex";
  159. import { getapi, postapi, putapi, deletapi } from "@/api/api";
  160. import { arrayFilter, arrayReduce, arrayExistObj, dddw, deepCopy, tcdate} from "../../utlis/proFunc";
  161. import proApi from "../../utlis/proApi";
  162. export default {
  163. props: ["prForm","prAsbOpraOpts","triggerHeadSave","refreshFormId"],
  164. data() {
  165. return {
  166. oldFormId:'', //配合登记人员复制新增使用
  167. itemType: [], //项目类别
  168. itemTypeIds: '', //被选中的项目类别ID
  169. asbItem:[], //左侧显示的未选组合项目
  170. asbItemAll:[], //所有未选组合项目
  171. asbItemChoosed: [], //勾选的 未选组合项目
  172. startPoint:-1,
  173. //patientRegisterAbs:[], //体检人员所选组合项目 放vuex
  174. patientRegisterAbsChoosed: [], //勾选的 体检人员所选组合项目
  175. PstartPoint:-1,
  176. //patientRegisterAbsDel: [], //体检人员 待删除的组合项目
  177. prAsb:[], //当前显示的已选组合项目(新增与编辑的在一起)
  178. prAsbDels:[], //待提交 删除的组合项目
  179. groupAsbs:[], //分组包含的项目
  180. packageAsbs:[], //套餐包含的项目
  181. asbItemId: '',
  182. discount: 100,
  183. total: 0,
  184. totalStand: 0,
  185. quickAsb: [],
  186. asbItemQuick:[],
  187. totalFoucs: false, //总价是否获取焦点
  188. discountFoucs: false, //总折扣是否获取焦点
  189. };
  190. },
  191. computed: {
  192. ...mapState(["window", "dataTransOpts", "dict", "customerOrg", "patientRegister", "personnelUnit"]),
  193. },
  194. created(){
  195. this.dictInit()
  196. },
  197. updated(){
  198. this.$nextTick(() => {
  199. this.$refs['patientRegister_patientRegisterAbs'].doLayout()
  200. })
  201. },
  202. mounted() {
  203. },
  204. methods: {
  205. ...mapActions(['getCustomerOrgGroup', 'getPatientRegisterAbs']),
  206. dddw,moment,deepCopy,
  207. // 初始化字典信息
  208. dictInit(){
  209. // 项目类别 树结构
  210. getapi("/api/app/item-type/by-code-all").then((res) => {
  211. if (res.code != -1) {
  212. this.dict.itemTypeTree = res.data;
  213. tcdate(this.dict.itemTypeTree);
  214. }
  215. });
  216. // 获取组合项目
  217. postapi('/api/app/asbitem/getasbitemlist',{isFilterActive:'Y'}).then(res =>{
  218. if(res.code != -1){
  219. this.asbItem = res.data
  220. this.asbItemAll = res.data
  221. this.asbItemQuick = res.data
  222. this.quickAsb = res.data
  223. }
  224. });
  225. },
  226. // 获取人员组合项目信息
  227. async getPrAsb(id){
  228. // debugger
  229. // 清空待删除、分组、套餐
  230. console.log('getPrAsb(id)',`getPrAsb(${id})`)
  231. this.prAsbDels = []
  232. this.groupAsbs = []
  233. this.packageAsbs = []
  234. let result = await proApi.getPrAsb(id)
  235. this.prAsb = result.data
  236. this.refreshAsbitem()
  237. },
  238. // 复制新增 拷贝明细项目
  239. async copyNew(){
  240. if(this.oldFormId){
  241. let result = await proApi.getPrAsb(this.oldFormId)
  242. this.prAsb = result.data
  243. this.prAsb.forEach(e => {
  244. e.id = '';
  245. e.patientRegisterId = '';
  246. e.isCharge = 'N';
  247. e.checkCompleteFlag = '0'
  248. e.isLock = 'N'
  249. })
  250. this.refreshAsbitem()
  251. }
  252. },
  253. // 刷新未选组合项目
  254. refreshAsbitem(){
  255. let asbItemAll = deepCopy(this.asbItemAll)
  256. arrayReduce(asbItemAll, this.prAsb, "id=asbitemId");
  257. this.changeItemType();
  258. this.asbItemQuick = deepCopy(asbItemAll);
  259. this.quickAsb = deepCopy(asbItemAll);
  260. },
  261. handleRowClassName({ row, rowIndex }) {
  262. if (row.choosed) {
  263. return 'current-row';
  264. } else {
  265. return '';
  266. }
  267. },
  268. //选择 未选的组合项目
  269. chooseAsbItem(row){
  270. this.asbItem.forEach((e,index) => {
  271. e.index = index;
  272. return e
  273. });
  274. // 按住了shift键
  275. if (this.window.shift) {
  276. //清除所有选择
  277. this.asbItem.forEach(e => {
  278. e.choosed = false;
  279. return e
  280. });
  281. if (this.startPoint == - 1) {
  282. this.asbItem[row.index].choosed = true;
  283. this.startPoint = row.index;
  284. return
  285. }
  286. if (this.startPoint > row.index) {
  287. for (let i = row.index; i <= this.startPoint; i++) {
  288. this.asbItem[i].choosed = true
  289. }
  290. } else if (this.startPoint <= row.index) {
  291. for (let i = this.startPoint; i <= row.index; i++) {
  292. this.asbItem[i].choosed = true
  293. }
  294. }
  295. return
  296. }
  297. // 按住了ctrl 键
  298. if (this.window.ctrl) {
  299. console.log('this.window.ctrl',this.window.ctrl,this.asbItem)
  300. this.asbItem[row.index].choosed = true;
  301. this.startPoint = row.index;
  302. return
  303. }
  304. // 未按住了ctrl 、shift 键
  305. //清除所有选择
  306. //console.log('清除所有选择')
  307. this.asbItem.forEach(e => {
  308. e.choosed = false;
  309. return e
  310. });
  311. this.asbItem[row.index].choosed = true;
  312. this.startPoint = row.index;
  313. },
  314. //选择 已选的组合项目
  315. removeAsbItem(row){
  316. this.prAsb.forEach((e,index) => {
  317. e.index = index;
  318. return e
  319. });
  320. // 按住了shift键
  321. if (this.window.shift) {
  322. //清除所有选择
  323. this.prAsb.forEach(e => {
  324. e.choosed = false;
  325. return e
  326. });
  327. if (this.PstartPoint == - 1) {
  328. this.prAsb[row.index].choosed = true;
  329. this.PstartPoint = row.index;
  330. return
  331. }
  332. if (this.PstartPoint > row.index) {
  333. for (let i = row.index; i <= this.PstartPoint; i++) {
  334. this.prAsb[i].choosed = true
  335. }
  336. } else if (this.PstartPoint <= row.index) {
  337. for (let i = this.PstartPoint; i <= row.index; i++) {
  338. this.prAsb[i].choosed = true
  339. }
  340. }
  341. return
  342. }
  343. // 按住了ctrl 键
  344. if (this.window.ctrl) {
  345. console.log('this.window.ctrl',this.window.ctrl,this.prAsb)
  346. this.prAsb[row.index].choosed = true;
  347. this.PstartPoint = row.index;
  348. return
  349. }
  350. // 未按住了ctrl 、shift 键
  351. //清除所有选择
  352. //console.log('清除所有选择')
  353. this.prAsb.forEach(e => {
  354. e.choosed = false;
  355. return e
  356. });
  357. this.prAsb[row.index].choosed = true;
  358. this.PstartPoint = row.index;
  359. },
  360. //更新所选组合项目
  361. async onSubmit(msg) {
  362. let ret = false
  363. ret = await this.batchAddAsb()
  364. if(!ret){
  365. if(msg) this.$message.warning(`组合项目 ${msg} 失败!`)
  366. return
  367. }
  368. ret = await this.batchDelAsb()
  369. if(!ret){
  370. if(msg) this.$message.warning(`组合项目 ${msg} 失败!`)
  371. return
  372. }
  373. ret = await this.batchEditAsb()
  374. if(!ret){
  375. if(msg) this.$message.warning(`组合项目 ${msg} 失败!`)
  376. return
  377. }
  378. console.log('this.prAsbOpraOpts.formId',this.prAsbOpraOpts.formId)
  379. if(this.prAsbOpraOpts.formId){
  380. this.refreshFormId()
  381. }else{
  382. //触发保存人员基本信息
  383. this.triggerHeadSave()
  384. this.getPrAsb(this.prForm.id)
  385. }
  386. },
  387. //未选组合项目 勾选情况
  388. handleSelectionChange(val) {
  389. // this.selecteddata = val;
  390. this.asbItemChoosed = val;
  391. //console.log(this.asbItemChoosed);
  392. },
  393. // 添加组合项目
  394. ///api/app/register-asbitem/many/3fa85f64-5717-4562-b3fc-2c963f66afa6'
  395. addAbs(asbItemChoosed,oprType) {
  396. let checked = true
  397. let payTypeFlag = '0' //默认个人支付
  398. //勾选时不需要此操作 start
  399. if(oprType && oprType == 'all'){
  400. asbItemChoosed = deepCopy(this.asbItem)
  401. }else if(oprType && oprType == 'choosed'){
  402. asbItemChoosed = []
  403. this.asbItem.forEach(e =>{
  404. if(e.choosed){
  405. asbItemChoosed.push(e)
  406. e.choosed = false
  407. }
  408. })
  409. }
  410. //勾选时不需要此操作 end
  411. if (asbItemChoosed.length < 1) {
  412. this.$message.warning("请选择要添加的组合项目")
  413. return
  414. }
  415. //性别、年龄判断
  416. // "displayName": "身高体重",
  417. // "shortName": "哈f哈",
  418. // "forSexId": "F",
  419. // "itemTypeId": "3a0b16de-75b9-c910-c61b-844709a88940",
  420. // "price": 0,
  421. console.log('asbItemChoosed.length', asbItemChoosed.length)
  422. for (let i = 0; i < asbItemChoosed.length; i++) {
  423. if (this.prForm.sexId == 'U') break //未选性别时,无需判断组合项目性别限制
  424. if (asbItemChoosed[i].forSexId == 'A') continue
  425. if (asbItemChoosed[i].forSexId != this.prForm.sexId) {
  426. this.$message.warning(`所选项目:${asbItemChoosed[i].displayName},不适合当前人员性别`)
  427. checked = false
  428. break
  429. }
  430. }
  431. //console.log(222,checked)
  432. if (!checked) return
  433. if (this.prForm.customerOrgId != this.dict.personOrgId) payTypeFlag = '1'
  434. for (let i = 0; i < asbItemChoosed.length; i++) {
  435. let pojo = {
  436. asbitemId: asbItemChoosed[i].id,
  437. asbitemName: asbItemChoosed[i].displayName,
  438. patientRegisterId: this.prForm.id,
  439. standardPrice: asbItemChoosed[i].price,
  440. chargePrice: asbItemChoosed[i].price,
  441. payTypeFlag,
  442. isCharge: "N",
  443. discount:100,
  444. amount: 1,
  445. total: asbItemChoosed[i].price,
  446. }
  447. this.prAsb.push(pojo)
  448. }
  449. this.refreshAsbitem()
  450. },
  451. //人员已选组合项目 勾选情况
  452. selecteditems(val) {
  453. this.patientRegisterAbsChoosed = val
  454. },
  455. //批量提交添加组合项目
  456. async batchAddAsb() {
  457. let ret = false
  458. let patientRegisterId = this.prForm.id || this.prAsbOpraOpts.formId
  459. if(!patientRegisterId){
  460. this.$message.warning("人员基本信息未保存");
  461. return ret
  462. }
  463. let registerAsbitems = []
  464. this.prAsb.forEach(e => {
  465. if(!e.id){
  466. registerAsbitems.push({
  467. asbitemId: e.asbitemId,
  468. patientRegisterId,
  469. standardPrice: e.standardPrice,
  470. chargePrice: e.chargePrice,
  471. payTypeFlag: e.payTypeFlag,
  472. isCharge: e.isCharge,
  473. amount: e.amount,
  474. groupPackageId: e.groupPackageId
  475. })
  476. }
  477. })
  478. if(registerAsbitems.length == 0) return true
  479. let body = {
  480. organizationUnitId:this.prForm.organizationUnitId,
  481. registerAsbitems,
  482. isAutoMerger:'Y'
  483. }
  484. try {
  485. let res = await postapi('/api/app/registerasbitem/createregisterasbitemmany', body)
  486. if(res.code != -1) ret = true
  487. } catch (error) {
  488. console.log('批量添加组合项目失败',error)
  489. }
  490. return ret
  491. },
  492. //批量提交更新组合项目
  493. async batchEditAsb() {
  494. let ret = false
  495. let body = []
  496. this.prAsb.forEach(e => {
  497. if(e.id){
  498. body.push({
  499. registerAsbitemId:e.id,
  500. input: {
  501. chargePrice: e.chargePrice,
  502. payTypeFlag: e.payTypeFlag,
  503. isCharge: e.isCharge,
  504. amount: e.amount,
  505. groupPackageId: e.groupPackageId
  506. }
  507. })
  508. }
  509. })
  510. if(body.length == 0) return true
  511. try {
  512. let res = await postapi(`/api/app/registerasbitem/updatemany`, body)
  513. if(res.code != -1) ret = true
  514. } catch (error) {
  515. console.log('批量提交更新组合项目失败',error)
  516. }
  517. return ret
  518. },
  519. //批量提交删除组合项目
  520. async batchDelAsb() {
  521. let ret = false
  522. if(this.prAsbDels.length == 0) return true
  523. let registerAsbitemIds=[]
  524. this.prAsbDels.forEach(e => {
  525. registerAsbitemIds.push(e.id)
  526. })
  527. console.log(`/api/app/registerasbitem/deletemany`, {registerAsbitemIds})
  528. try {
  529. let res = await postapi(`/api/app/registerasbitem/deletemany`, {registerAsbitemIds})
  530. if(res.code != -1) ret = true
  531. } catch (error) {
  532. console.log('批量删除组合项目失败',error)
  533. }
  534. return ret
  535. },
  536. //删除 人员已选中的组合项目
  537. ///api/app/register-asbitem/many?RegisterAsbitemIds=3fa85f64-5717-4562-b3fc-2c963f66afa6
  538. delAbs(absForDel,oprType) {
  539. let chargeComplete = ''
  540. let lfind = -1
  541. let tempRd = {}
  542. //勾选时不需要此操作 start
  543. if(oprType && oprType == 'all'){
  544. absForDel = deepCopy(this.prAsb)
  545. }else if(oprType && oprType == 'choosed'){
  546. absForDel = []
  547. this.prAsb.forEach(e =>{
  548. if(e.choosed){
  549. absForDel.push(e)
  550. e.choosed = false
  551. }
  552. })
  553. }
  554. //勾选时不需要此操作 end
  555. if (absForDel.length < 1) {
  556. this.$message.warning("请选择要移除的组合项目")
  557. return
  558. }
  559. absForDel.forEach(e => {
  560. // 如果已经收费 或 体检,则不允许删除
  561. if (e.isCharge == 'Y' || (e.checkCompleteFlag && e.checkCompleteFlag != '0')) {
  562. chargeComplete += e.asbitemName + ','
  563. }else{
  564. lfind = arrayExistObj(this.prAsb, 'asbitemId', e.asbitemId)
  565. if(lfind > -1){
  566. tempRd = Object.assign({},this.prAsb.splice(lfind,1)[0])
  567. if(e.id) this.prAsbDels.push(tempRd)
  568. }
  569. }
  570. })
  571. //刷新
  572. this.refreshAsbitem()
  573. if (chargeComplete) {
  574. this.$message({ type: "info", message: `所选项目:${chargeComplete}已收费或已检,不可删除!` });
  575. }
  576. },
  577. //双击删除已选项目
  578. removeAbs(row) {
  579. this.delAbs([row]);
  580. },
  581. //项目类别过滤 组合项目,未过滤已选择的组合项目
  582. changeItemType() {
  583. //console.log('getAsbItemByItemType', typeof this.itemTypeIds, this.itemTypeIds)
  584. let asbItemAll = deepCopy(this.asbItemAll)
  585. let lv = "";
  586. if (typeof this.itemTypeIds == "object") {
  587. if(this.itemTypeIds.length > 0) lv = this.itemTypeIds[this.itemTypeIds.length - 1];
  588. }
  589. if (lv) {
  590. this.asbItem = arrayFilter(asbItemAll, "itemTypeId", lv);
  591. } else {
  592. this.asbItem = deepCopy(asbItemAll);
  593. }
  594. arrayReduce(this.asbItem, this.prAsb, "id=asbitemId");
  595. },
  596. //选中 分组 所包含的组合项目
  597. getGroupAsbs(id){
  598. if(!id){
  599. this.groupAsbs = []
  600. this.changeGroup(id)
  601. return
  602. }
  603. getapi(`/api/app/customerorggroupdetail/getcustomerorggroupdetailinasbitem?CustomerOrgGroupId=${id}`)
  604. .then((res) => {
  605. if(res.code != -1){
  606. this.groupAsbs = res.data
  607. this.changeGroup(id)
  608. }
  609. });
  610. },
  611. //选中 套餐 所包含的组合项目
  612. getPackageAsbs(id){
  613. if(!id){
  614. this.packageAsbs = []
  615. this.changePackage(id)
  616. return
  617. }
  618. postapi('/api/app/medicalpackagedetail/getmedicalpackageinasbitem',{medicalPackageId:id})
  619. .then((res) => {
  620. if(res.code != -1){
  621. this.packageAsbs = res.data
  622. this.changePackage(id)
  623. }
  624. });
  625. },
  626. // 更换分组
  627. changeGroup(newId){
  628. //已收费项目,不更改收费方式、价格及数量,只更改分组id
  629. let payTypeFlag = '0'
  630. let lfind = -1
  631. let tempRd = {}
  632. if(!newId){
  633. this.setGroupPackageNull()
  634. return
  635. }
  636. if (this.prForm.customerOrgId != this.dict.personOrgId) payTypeFlag = '1' //单位支付
  637. for(let i = this.prAsb.length - 1;i>-1;i--){
  638. lfind = arrayExistObj(this.groupAsbs,'asbitemId',this.prAsb[i].asbitemId)
  639. if(lfind > -1){
  640. //找到了则更新此项目
  641. tempRd = Object.assign({},this.groupAsbs.splice(lfind,1)[0])
  642. this.prAsb[i].groupPackageId = newId
  643. if(this.prAsb[i].isCharge != 'Y'){
  644. this.prAsb[i].payTypeFlag = payTypeFlag
  645. this.prAsb[i].amount = tempRd.customerOrgGroupDetailAmount
  646. this.prAsb[i].standardPrice = tempRd.price
  647. this.prAsb[i].chargePrice = tempRd.customerOrgGroupDetailPrice
  648. this.prAsb[i].discount = tempRd.discount
  649. }
  650. }else{
  651. //没找到则移除此项目
  652. if(this.prAsb[i].isCharge == 'Y' || (this.prAsb[i].checkCompleteFlag && this.prAsb[i].checkCompleteFlag != '0')){
  653. this.prAsb[i].groupPackageId = null
  654. }else{
  655. tempRd = Object.assign({},this.prAsb.splice(i,1)[0])
  656. if(tempRd.id) this.prAsbDels.push(tempRd)
  657. }
  658. }
  659. }
  660. // debugger
  661. //未找到则添加(如果在待删除中找到记录,则待删除中记录移至当前显示记录中来)
  662. this.groupAsbs.forEach(e =>{
  663. lfind = arrayExistObj(this.prAsbDels,'asbitemId',e.asbitemId)
  664. if(lfind > -1){
  665. tempRd = Object.assign(this.prAsbDels.splice(lfind,1)[0],
  666. {
  667. groupPackageId:newId,
  668. standardPrice:e.price,
  669. chargePrice:e.customerOrgGroupDetailPrice,
  670. payTypeFlag,
  671. isCharge: "N",
  672. discount:e.discount,
  673. amount:e.customerOrgGroupDetailAmount,
  674. total: Math.round(e.customerOrgGroupDetailAmount * e.customerOrgGroupDetailPrice * 100)/100
  675. }
  676. )
  677. }else{
  678. tempRd = {
  679. groupPackageId:newId,
  680. asbitemId:e.asbitemId,
  681. asbitemName:e.displayName,
  682. patientRegisterId:this.prForm.id,
  683. standardPrice:e.price,
  684. chargePrice:e.customerOrgGroupDetailPrice,
  685. payTypeFlag,
  686. isCharge: "N",
  687. discount:e.discount,
  688. amount:e.customerOrgGroupDetailAmount,
  689. total: Math.round(e.customerOrgGroupDetailAmount * e.customerOrgGroupDetailPrice * 100)/100
  690. }
  691. }
  692. this.prAsb.push(tempRd)
  693. })
  694. this.refreshAsbitem()
  695. },
  696. // 更换套餐
  697. changePackage(newId){
  698. //已收费项目,不更改收费方式、价格及数量,只更改分组id
  699. let payTypeFlag = '0'
  700. let lfind = -1
  701. let tempRd = {}
  702. if(!newId){
  703. this.setGroupPackageNull()
  704. return
  705. }
  706. if (this.prForm.customerOrgId != this.dict.personOrgId) payTypeFlag = '1' //单位支付
  707. for(let i = this.prAsb.length - 1;i>-1;i--){
  708. lfind = arrayExistObj(this.packageAsbs,'id',this.prAsb[i].asbitemId)
  709. if(lfind > -1){
  710. //找到了则更新此项目
  711. tempRd = Object.assign({},this.packageAsbs.splice(lfind,1)[0])
  712. this.prAsb[i].groupPackageId = newId
  713. if(this.prAsb[i].isCharge != 'Y'){
  714. this.prAsb[i].payTypeFlag = payTypeFlag
  715. this.prAsb[i].amount = tempRd.medicalPackageDetailAmount
  716. this.prAsb[i].standardPrice = tempRd.price
  717. this.prAsb[i].chargePrice = tempRd.medicalPackageDetailPrice
  718. this.prAsb[i].discount = tempRd.discount
  719. }
  720. }else{
  721. //没找到则移除此项目
  722. if(this.prAsb[i].isCharge == 'Y' || (this.prAsb[i].checkCompleteFlag && this.prAsb[i].checkCompleteFlag != '0')){
  723. this.prAsb[i].groupPackageId = null
  724. }else{
  725. tempRd = Object.assign({},this.prAsb.splice(i,1)[0])
  726. if(tempRd.id) this.prAsbDels.push(tempRd)
  727. }
  728. }
  729. }
  730. //未找到则添加(如果在待删除中找到记录,则待删除中记录移至当前显示记录中来)
  731. this.packageAsbs.forEach(e =>{
  732. lfind = arrayExistObj(this.prAsbDels,'asbitemId',e.id)
  733. if(lfind > -1){
  734. tempRd = Object.assign(this.prAsbDels.splice(lfind,1)[0],
  735. {
  736. groupPackageId:newId,
  737. standardPrice:e.price,
  738. chargePrice:e.medicalPackageDetailPrice,
  739. payTypeFlag,
  740. isCharge: "N",
  741. discount:e.discount,
  742. amount:e.medicalPackageDetailAmount,
  743. total: Math.round(e.medicalPackageDetailAmount * e.medicalPackageDetailPrice * 100)/100
  744. }
  745. )
  746. }else{
  747. tempRd = {
  748. groupPackageId:newId,
  749. asbitemId:e.id,
  750. asbitemName:e.displayName,
  751. patientRegisterId:this.prForm.id,
  752. standardPrice:e.price,
  753. chargePrice:e.medicalPackageDetailPrice,
  754. payTypeFlag,
  755. isCharge: "N",
  756. discount:e.discount,
  757. amount:e.medicalPackageDetailAmount,
  758. total: Math.round(e.medicalPackageDetailAmount * e.medicalPackageDetailPrice * 100)/100
  759. }
  760. }
  761. this.prAsb.push(tempRd)
  762. })
  763. this.refreshAsbitem()
  764. },
  765. // 从 有分组/套餐 切换成 无分组/套餐 时
  766. setGroupPackageNull(){
  767. this.prAsb.forEach(e =>{
  768. e.groupPackageId = null
  769. })
  770. },
  771. //双击选择组合项目
  772. dbClickChoosedAsb(row) {
  773. this.addAbs([row]);
  774. },
  775. //快速选择组合项目
  776. quickChoosedAsb(v) {
  777. //远程查询时,设置了 value-key 也不管用,只能取到value console.log('quickChoosedAsb',v)
  778. let lfind = -1
  779. if (v) {
  780. lfind = arrayExistObj(this.asbItemQuick, 'id', v)
  781. if (lfind > -1) {
  782. this.addAbs([this.asbItemQuick[lfind]])
  783. }
  784. }
  785. //this.$refs['quickAsbOCX'].focus(); //asbItemId
  786. this.$nextTick(() => {
  787. this.$refs['quickAsbOCX'].blur(); //total asbItemId
  788. this.asbItemId = ''
  789. this.quickAsb = deepCopy(this.asbItemQuick)
  790. this.$refs['quickAsbOCX'].focus(); //total asbItemId
  791. });
  792. },
  793. //快速选择组合项目时,调整可按拼间简码及简称查找
  794. filterMethod(keyWords) {
  795. //console.log('filterMethod',this.asbItemQuick)
  796. if (keyWords) {
  797. this.quickAsb = [];
  798. this.asbItemQuick.forEach(item => {
  799. if (item.displayName.toLowerCase().indexOf(keyWords.toLowerCase()) > - 1
  800. || item.simpleCode.toLowerCase().indexOf(keyWords.toLowerCase()) > - 1
  801. || item.shortName.toLowerCase().indexOf(keyWords.toLowerCase()) > - 1) {
  802. this.quickAsb.push(item);
  803. }
  804. });
  805. } else {
  806. this.quickAsb = deepCopy(this.asbItemQuick);
  807. }
  808. },
  809. //修改总折扣
  810. changeAllDiscount() {
  811. if (!this.discount || this.discount == 0) return
  812. if (!this.prAsb || this.prAsb.length == 0) return
  813. this.prAsb.forEach(e => {
  814. e.discount = this.discount
  815. e.chargePrice = Math.round(e.standardPrice * this.discount) / 100
  816. e.total = Math.round(e.standardPrice * this.discount * e.amount) / 100
  817. });
  818. // this.onSubmit('')
  819. },
  820. //修改总金额
  821. changeTotal() {
  822. if (!this.total) return
  823. if (!this.prAsb || this.prAsb.length == 0) return
  824. let sumChargeDetails = Number(0) //单个标准价折后价 合计总计
  825. let qtyIsOneLast = 0 //数量为1的最后行项目,用于返写金额
  826. // console.log('this.total / this.totalStand',this.total , this.totalStand)
  827. this.discount = Math.round((100 * this.total / this.totalStand) * 100)/100
  828. this.prAsb.forEach((e, index) => {
  829. if (e.amount == 1) qtyIsOneLast = index
  830. e.discount = this.discount
  831. e.chargePrice = Math.round((e.standardPrice * this.discount / 100) * 100)/100
  832. e.total = Math.round((e.standardPrice * this.discount * e.amount / 100) * 100)/100
  833. sumChargeDetails += Math.round((e.standardPrice * this.discount * e.amount / 100) * 100)/100
  834. });
  835. // console.log('this.total - sumChargeDetails', sumChargeDetails, this.total - sumChargeDetails)
  836. //平衡金额(按总价折扣后,再根据折扣合计 会出现金额差)
  837. if (this.total != sumChargeDetails) {
  838. console.log('qtyIsOneLast',qtyIsOneLast)
  839. this.prAsb[qtyIsOneLast].total =
  840. Math.round((Number(this.prAsb[qtyIsOneLast].total) + Number(this.total) - Number(sumChargeDetails))*100)/100
  841. this.prAsb[qtyIsOneLast].chargePrice =
  842. Math.round(this.prAsb[qtyIsOneLast].total * 100 / this.prAsb[qtyIsOneLast].amount)/100
  843. if(this.prAsb[qtyIsOneLast].standardPrice != 0){
  844. this.prAsb[qtyIsOneLast].discount =
  845. Math.round(this.prAsb[qtyIsOneLast].chargePrice * 10000/this.prAsb[qtyIsOneLast].standardPrice)/100
  846. }
  847. }
  848. //this.onSubmit('')
  849. },
  850. //修改数量
  851. changeDiscount(index) {
  852. //console.log('index',index)
  853. if (!this.prAsb || this.prAsb.length == 0) return
  854. if (!this.prAsb[index].discount) return
  855. //console.log(this.prAsb[index].chargePrice,this.prAsb[index].standardPrice)
  856. this.prAsb[index].chargePrice = Math.round(this.prAsb[index].standardPrice * this.prAsb[index].discount)/100
  857. this.prAsb[index].total = this.prAsb[index].chargePrice * this.prAsb[index].amount
  858. // this.onSubmit('')
  859. },
  860. //修改单价
  861. changePrice(index) {
  862. //console.log('index',index)
  863. if (!this.prAsb || this.prAsb.length == 0) return
  864. if (!this.prAsb[index].chargePrice) return
  865. //console.log(this.prAsb[index].chargePrice,this.prAsb[index].standardPrice)
  866. this.prAsb[index].discount = Math.round(this.prAsb[index].chargePrice * 10000 / this.prAsb[index].standardPrice)/100
  867. // this.onSubmit('')
  868. },
  869. //自定义计算列
  870. getSummaries(param) {
  871. const { columns, data } = param;
  872. const sumCol = [1, 5] //需合计的列
  873. const sums = [];
  874. columns.forEach((column, index) => {
  875. //console.log('column, index,data',column, index,data)
  876. //显示合计列
  877. if (index === 0) {
  878. sums[index] = '合计';
  879. return;
  880. }
  881. //不合计的列
  882. if (sumCol.indexOf(index) == -1) {
  883. sums[index] = '';
  884. return;
  885. }
  886. sums[index] = 0
  887. data.forEach(e => {
  888. if (!isNaN(e[column.property])){
  889. if(index == 1){
  890. sums[index] += e[column.property] * e['amount']
  891. }else{
  892. sums[index] += e[column.property]
  893. }
  894. }
  895. })
  896. sums[index] = Math.round(sums[index] * 100)/100 //+ ' 元';
  897. // const values = data.map(item => Number(item[column.property]));
  898. // if (!values.every(value => isNaN(value))) {
  899. // sums[index] = values.reduce((prev, curr) => {
  900. // const value = Number(curr);
  901. // if (!isNaN(value)) {
  902. // //return prev + curr; //原始
  903. // return prev + curr; //改造
  904. // } else {
  905. // return prev;
  906. // }
  907. // }, 0);
  908. // sums[index] = sums[index].toFixed(2) + ' 元';
  909. // } else {
  910. // sums[index] = 'N/A';
  911. // }
  912. });
  913. this.totalStand = sums[1];
  914. //console.log('this.totalFoucs/this.discountFoucs',this.totalFoucs,this.discountFoucs)
  915. if (!this.totalFoucs) this.total = sums[5];
  916. if (!this.discountFoucs) this.discount = Math.round(this.total * 10000 / this.totalStand)/100;
  917. return sums;
  918. },
  919. },
  920. //监听事件
  921. watch: {
  922. // //配合复制新增使用 查询人员下的组合项目
  923. // "prForm.id":{
  924. // immediate: true, // 立即执行
  925. // // deep: true, // 深度监听复杂类型内变化
  926. // handler(newVal,oldVal){
  927. // console.log('人员登记 组合项目明细,人员id:',newVal,oldVal)
  928. // this.oldFormId = oldVal
  929. // this.getPrAsb(newVal)
  930. // // if(newVal != oldVal){
  931. // // this.getPrAsb(newVal)
  932. // // }
  933. // }
  934. // },
  935. // //人员 id 未变的情况下,亦可触发刷新组合项目
  936. // "prAsbOpraOpts.prAsbQuery":{
  937. // // immediate: true, // 立即执行
  938. // // deep: true, // 深度监听复杂类型内变化
  939. // handler(newVal,oldVal){
  940. // console.log('watch:prAsbOpraOpts.prAsbQuery:',newVal,oldVal)
  941. // if(newVal != oldVal){
  942. // this.getPrAsb(this.prForm.id)
  943. // }
  944. // }
  945. // },
  946. "dataTransOpts.refresh.register_asbitem.M":{
  947. immediate: true, // 立即执行
  948. // deep: true, // 深度监听复杂类型内变化
  949. handler(newVal,oldVal){
  950. console.log('watch: 刷新 人员登记/编辑 时的组合项目: ',this.dataTransOpts.tableS.patient_register.id)
  951. this.getPrAsb(this.dataTransOpts.tableS.patient_register.id)
  952. }
  953. },
  954. //按钮更新支付方式
  955. "prAsbOpraOpts.payTypeFlag":{
  956. // immediate: true, // 立即执行
  957. // deep: true, // 深度监听复杂类型内变化
  958. handler(newVal, oldVal) {
  959. if (newVal != oldVal && newVal != '') {
  960. this.prAsb.forEach(e =>{
  961. e.payTypeFlag = newVal;
  962. return e;
  963. });
  964. // this.onSubmit('调整支付方式');
  965. }
  966. }
  967. },
  968. //更换分组
  969. "prAsbOpraOpts.prAsbGroup":{
  970. // immediate: true, // 立即执行
  971. // deep: true, // 深度监听复杂类型内变化
  972. handler(newVal, oldVal) {
  973. if (newVal != oldVal) {
  974. this.getGroupAsbs(this.prForm.customerOrgGroupId)
  975. }
  976. }
  977. },
  978. //更换套餐
  979. "prAsbOpraOpts.prAsbPackage":{
  980. // immediate: true, // 立即执行
  981. // deep: true, // 深度监听复杂类型内变化
  982. handler(newVal, oldVal) {
  983. if (newVal != oldVal) {
  984. this.getPackageAsbs(this.prForm.medicalPackageId)
  985. }
  986. }
  987. },
  988. //复制新增 拷贝明细项目
  989. "prAsbOpraOpts.copyNew":{
  990. // immediate: true, // 立即执行
  991. // deep: true, // 深度监听复杂类型内变化
  992. handler(newVal, oldVal) {
  993. if (newVal != oldVal) {
  994. this.copyNew()
  995. }
  996. }
  997. },
  998. //体检信息保存,触发已选组合项目保存
  999. "prAsbOpraOpts.prAsbSave"(newVal, oldVal) {
  1000. console.log("patientRegister.saveTimes newVal:", newVal, " oldVal:", oldVal);
  1001. if (newVal != oldVal) {
  1002. this.onSubmit('');
  1003. }
  1004. },
  1005. },
  1006. };
  1007. </script>
  1008. <style lang="scss" scoped>
  1009. @import "../../assets/css/global_table.css";
  1010. @import "../../assets/css/global_input.css";
  1011. @import "../../assets/css/global.css";
  1012. .mainareaBox {
  1013. border: 1px solid #000;
  1014. height: v-bind("(window.pageHeight > 700 ? (window.pageHeight - 440) : 260) + 'px'");
  1015. margin-top: 5px;
  1016. }
  1017. .btnList {
  1018. margin-top: 5px;
  1019. margin-left: 5px;
  1020. margin-right: 5px;
  1021. }
  1022. .disTotal {
  1023. margin-left: 10px;
  1024. }
  1025. </style>