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.

618 lines
20 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
  1. <template>
  2. <div class="box">
  3. <div style="position: relative;">
  4. <div class="middlebox">
  5. <div class="contenttitle">
  6. 常用设置 /
  7. <span class="contenttitleBold">套餐设置</span>
  8. </div>
  9. </div>
  10. <!--套餐信息-->
  11. <div style="display: block; margin-top: 7px;margin-right: 110px;">
  12. <div style="margin-bottom: 15px;background-color: #fff;padding: 15px;border-radius: 8px;">
  13. <el-table :data="medicalPackages" ref="medicalPackages" row-key="id" :height="window.pageHeight < 600
  14. ? 210
  15. : Math.floor((window.pageHeight - 220) / 2)
  16. " highlight-current-row :row-class-name="handleRowClassName" @row-click="rowClick">
  17. <el-table-column type="index" label="序号" min-width="50" align="center" />
  18. <el-table-column prop="displayName" label="名称" min-width="150" />
  19. <el-table-column prop="price" label="价格" min-width="60" align="center" />
  20. <el-table-column prop="forSexId" label="适用性别" min-width="60" align="center">
  21. <template slot-scope="scope">
  22. {{ dddw(dict.forSex, "id", scope.row.forSexId, "displayName") }}
  23. </template>
  24. </el-table-column>
  25. <!--
  26. <el-table-column
  27. prop="maritalStatusId"
  28. label="适用婚姻状况"
  29. min-width="80"
  30. align="center"
  31. >
  32. <template slot-scope="scope">
  33. {{
  34. dddw(
  35. dict.forMaritalStatus,
  36. "id",
  37. scope.row.maritalStatusId,
  38. "displayName"
  39. )
  40. }}
  41. </template>
  42. </el-table-column>
  43. -->
  44. <el-table-column prop="isActive" label="启用" min-width="60" align="center">
  45. <template slot-scope="scope">
  46. {{ scope.row.isActive == 'Y' ? '是' : '否' }}
  47. </template>
  48. </el-table-column>
  49. <el-table-column prop="creatorName" label="创建者" min-width="60" align="center" />
  50. <el-table-column label="创建时间" min-width="150" align="center">
  51. <template slot-scope="scope">
  52. {{
  53. scope.row.creationTime
  54. ? moment(scope.row.creationTime).format("yyyy-MM-DD HH:mm:ss")
  55. : ""
  56. }}
  57. </template>
  58. </el-table-column>
  59. <el-table-column label="操作" width="40">
  60. <template>
  61. <el-tag class="move" style="
  62. cursor: move;
  63. background-color: rgb(245, 245, 245);
  64. border: none;
  65. " draggable="true">
  66. <i class="el-icon-d-caret" style="
  67. width: 1rem;
  68. height: 1rem;
  69. color: rgb(113, 113, 113);
  70. "></i>
  71. </el-tag>
  72. </template>
  73. </el-table-column>
  74. </el-table>
  75. </div>
  76. <!--套餐项目信息-->
  77. <div style="background-color: #fff; border-radius: 8px; padding: 15px;position: relative;">
  78. <MedicalPackageAsbitem :formData="form" :refreshMoney="refreshMoney" />
  79. </div>
  80. </div>
  81. <!--按钮-->
  82. <div style="margin-left: 10px; margin-top: 40px;position: absolute;top: 0;right: 0;">
  83. <div>
  84. <el-button class="commonbutton" @click="btnAdd">新增</el-button>
  85. </div>
  86. <div style="margin-top: 10px">
  87. <el-button class="commonbutton" @click="btnEdit">编辑</el-button>
  88. </div>
  89. <div style="margin-top: 10px">
  90. <el-button class="commonbutton" @click="btnDel">删除</el-button>
  91. </div>
  92. <div style="margin-top: 10px">
  93. <el-button class="commonbutton" @click="btnSetTop">置顶</el-button>
  94. </div>
  95. <div style="margin-top: 10px">
  96. <el-button class="commonbutton" @click="btnSetBottom">置低</el-button>
  97. </div>
  98. <div style="margin-top: 10px">
  99. <el-button class="commonbutton" @click="btnSort" :disabled="!isDrag">保存排序</el-button>
  100. </div>
  101. </div>
  102. </div>
  103. <!-- 新增或者编辑弹框 -->
  104. <el-dialog :title="form.id ? '编辑' : '新增'" :close-on-click-modal="false" :visible.sync="dialogVisible" width="800px">
  105. <el-form :model="form" label-width="80px" :rules="rules" ref="form">
  106. <el-row>
  107. <el-col :span="8">
  108. <el-form-item prop="displayName" label="套餐名称">
  109. <el-input v-model="form.displayName" size="small" />
  110. </el-form-item>
  111. </el-col>
  112. <el-col :span="8">
  113. <el-form-item label="金额">
  114. <el-input v-model="form.price" type="number" size="small" />
  115. </el-form-item>
  116. </el-col>
  117. <el-col :span="8">
  118. <el-form-item label="适用性别">
  119. <el-select v-model="form.forSexId" placeholder="请选择" size="small">
  120. <el-option v-for="item in dict.forSex" :key="item.id" :label="item.displayName" :value="item.id">
  121. </el-option>
  122. </el-select>
  123. </el-form-item>
  124. </el-col>
  125. <!--
  126. <el-col :span="8">
  127. <el-form-item label="婚姻状况">
  128. <el-select
  129. v-model="form.maritalStatusId"
  130. placeholder="请选择"
  131. style="width: 100%" size="small" >
  132. <el-option
  133. v-for="item in dict.forMaritalStatus"
  134. :key="item.id"
  135. :label="item.displayName"
  136. :value="item.id"
  137. >
  138. </el-option>
  139. </el-select>
  140. </el-form-item>
  141. </el-col>
  142. -->
  143. <el-col :span="8">
  144. <el-form-item label="启用" prop="isActive">
  145. <el-radio v-model="form.isActive" label="Y"></el-radio>
  146. <el-radio v-model="form.isActive" label="N"></el-radio>
  147. </el-form-item>
  148. </el-col>
  149. <el-col :span="8">
  150. <el-form-item label="备注">
  151. <el-input v-model="form.remark" size="small" />
  152. </el-form-item>
  153. </el-col>
  154. </el-row>
  155. </el-form>
  156. <span slot="footer" class="dialog-footer">
  157. <el-button @click="dialogVisible = false" class="difference">取消</el-button>
  158. <!--
  159. <el-button type="success" @click="computePrice">同比折算套餐项目价格</el-button>
  160. -->
  161. <el-button type="primary" @click="onSubmit('form')" class="commonbutton">确定</el-button>
  162. </span>
  163. </el-dialog>
  164. <!-- -->
  165. </div>
  166. </template>
  167. <script>
  168. import moment from "moment";
  169. import Sortable from "sortablejs";
  170. import { getapi, postapi, putapi, deletapi } from "@/api/api";
  171. import { mapState } from "vuex";
  172. import { dddw, deepCopy, objCopy, arrayExistObj } from "../../utlis/proFunc";
  173. import MedicalPackageAsbitem from "../../components/common/MedicalPackageAsbitem.vue";
  174. export default {
  175. components: {
  176. MedicalPackageAsbitem,
  177. },
  178. data() {
  179. return {
  180. medicalPackages: [], //套餐
  181. medicalPackageId: "", //当前选中的体检单位id
  182. customerOrgRegisterList: [], //体检次数列表
  183. customerOrgRegister: {}, //体检次数
  184. isDrag: false,
  185. form: {
  186. id: "",
  187. displayName: "",
  188. price: 0,
  189. forSexId: "A",
  190. // maritalStatusId: "A",
  191. isActive: 'Y',
  192. remark: "",
  193. },
  194. formOri: {},
  195. formInit: {},
  196. rules: {
  197. displayName: [
  198. { required: true, message: "请填写套餐名称", trigger: "blur" },
  199. ],
  200. },
  201. dialogVisible: false,
  202. };
  203. },
  204. computed: {
  205. ...mapState(["personnelUnit", "window", "dict"]),
  206. },
  207. created() {
  208. this.rowDrop();
  209. this.formInit = deepCopy(this.form);
  210. },
  211. mounted() {
  212. //获取初始数据(单位、适用性别)
  213. this.dictInit();
  214. },
  215. methods: {
  216. moment,
  217. dddw, deepCopy,
  218. //刷新套餐价格(供子组件调用)
  219. refreshMoney(formData) {
  220. //console.log('this is parent')
  221. let lfind = arrayExistObj(this.medicalPackages, 'id', formData.id)
  222. if (lfind > -1) this.medicalPackages[lfind].price = formData.price
  223. },
  224. //确定排序
  225. btnSort() {
  226. const result = [];
  227. this.medicalPackages.forEach((item, index) => {
  228. result.push({ id: item.id, displayOrder: index + 1 });
  229. });
  230. putapi("/api/app/medicalpackage/updatesortmany", {
  231. itemList: result,
  232. }).then((res) => {
  233. if (res.code != -1) {
  234. this.isDrag = false;
  235. this.$message.success('操作成功')
  236. }
  237. });
  238. },
  239. //初始化Sortable组件
  240. rowDrop() {
  241. this.$nextTick(() => {
  242. const el = document.querySelector(".el-table__body-wrapper tbody");
  243. //console.log('el0',el)
  244. const that = this;
  245. Sortable.create(el, {
  246. handle: ".move",
  247. animation: 300,
  248. //拖拽结束
  249. onEnd({ newIndex, oldIndex }) {
  250. that.isDrag = true;
  251. const currRow = that.medicalPackages.splice(oldIndex, 1)[0];
  252. that.medicalPackages.splice(newIndex, 0, currRow);
  253. },
  254. });
  255. });
  256. },
  257. //置底
  258. btnSetBottom() {
  259. if (!this.form.id) {
  260. this.$message.warning("请选择操作的数据");
  261. return
  262. }
  263. let lfind = arrayExistObj(this.medicalPackages, 'id', this.form.id)
  264. let currentRow = {}
  265. putapi(
  266. `/api/app/medicalpackage/updatemanysort?id=${this.form.id}&SortType=2`
  267. ).then((res) => {
  268. if (res.code != -1) {
  269. currentRow = this.medicalPackages.splice(lfind, 1)[0] //删除并赋值
  270. this.medicalPackages.push(currentRow)
  271. this.$refs['medicalPackages'].setCurrentRow(currentRow);
  272. this.$message.success('操作成功')
  273. }
  274. });
  275. },
  276. //置顶
  277. btnSetTop() {
  278. if (!this.form.id) {
  279. this.$message.warning("请选择操作的数据");
  280. return
  281. }
  282. let lfind = arrayExistObj(this.medicalPackages, 'id', this.form.id)
  283. let currentRow = {}
  284. putapi(
  285. `/api/app/medicalpackage/updatemanysort?id=${this.form.id}&SortType=1`
  286. ).then((res) => {
  287. if (res.code != -1) {
  288. currentRow = this.medicalPackages.splice(lfind, 1)[0]
  289. this.medicalPackages.unshift(currentRow)
  290. this.$refs['medicalPackages'].setCurrentRow(currentRow);
  291. this.$message.success('操作成功')
  292. }
  293. });
  294. },
  295. //选中颜色
  296. handleRowClassName({ row, rowIndex }) {
  297. // highLightBg 为 'selected'的高亮
  298. //console.log(rowIndex, row)
  299. //return row.highLightBg == 'selected' ? 'high-light-bg' : '';
  300. if (row.choosed) {
  301. return 'current-row';
  302. } else {
  303. return '';
  304. }
  305. },
  306. //获取初始数据
  307. dictInit() {
  308. //获取适用性别
  309. getapi("/api/app/for-sex").then((res) => {
  310. if (res.code != -1) {
  311. this.dict.forSex = res.data;
  312. }
  313. });
  314. this.getPackages()
  315. },
  316. getPackages() {
  317. // /api/app/medicalpackage/getlist
  318. postapi("/api/app/medicalpackage/getmedicalpackagelist", {}).then(res => {
  319. if (res.code != -1) {
  320. this.medicalPackages = res.data
  321. }
  322. })
  323. },
  324. //点击套餐
  325. rowClick(row) {
  326. objCopy(row, this.form);
  327. this.formOri = Object.assign({}, row)
  328. },
  329. //新增弹框
  330. btnAdd() {
  331. // if (!this.customerOrgRegister.id) {
  332. // this.$message.warning("请选择体检次数");
  333. // return;
  334. // }
  335. // if (this.customerOrgRegister.isComplete.toUpperCase() == 'Y') {
  336. // this.$message.warning("该单位体检次数已完成,不允许新增套餐");
  337. // return;
  338. // }
  339. // if (this.customerOrgRegister.isComplete.toUpperCase() == "Y") {
  340. // this.$message.warning("该单位的该次体检次数已完成,不能再添加套餐!");
  341. // return;
  342. // }
  343. this.form = deepCopy(this.formInit);
  344. // this.form.customerOrgRegisterId = this.customerOrgRegister.id;
  345. // this.form.medicalPackageId = this.medicalPackageId;
  346. this.dialogVisible = true;
  347. },
  348. //编辑弹框
  349. btnEdit() {
  350. if (!this.form.id) {
  351. this.$message.warning("请选择需要操作的数据");
  352. return;
  353. }
  354. this.dialogVisible = true;
  355. },
  356. //删除
  357. btnDel() {
  358. if (!this.form.id) {
  359. this.$message.warning("请选择需要操作的数据");
  360. return;
  361. }
  362. this.$confirm("此操作将永久删除该记录, 是否继续?", "提示", {
  363. confirmButtonText: "是",
  364. cancelButtonText: " 否 ",
  365. type: "warning",
  366. cancelButtonClass: "difference",
  367. confirmButtonClass: "commonbutton"
  368. }).then(() => {
  369. return postapi(`/api/app/medicalpackage/delete?id=${this.form.id}`);
  370. }).then((res) => {
  371. if (res.code != -1) {
  372. let lfind = arrayExistObj(
  373. this.medicalPackages,
  374. "id",
  375. this.form.id
  376. );
  377. if (lfind > -1) this.medicalPackages.splice(lfind, 1);
  378. objCopy(this.formInit, this.form)
  379. this.isDrag = false
  380. this.$message.success('删除成功')
  381. }
  382. }).catch((err) => {
  383. if (err == "cancel") {
  384. this.$message.info("已取消删除");
  385. }
  386. });
  387. },
  388. onSubmit(formName) {
  389. this.$refs[formName].validate((valid, fields) => {
  390. if (!valid) {
  391. this.$message.warning(fields[Object.keys(fields)[0]][0].message);
  392. return false;
  393. }
  394. let body = deepCopy(this.form);
  395. delete body.id;
  396. if (this.form.id) {
  397. let medicalPackageId = this.form.id
  398. let medicalPackageAsbitems = [] //分组包含的套餐
  399. //编辑
  400. postapi(`/api/app/medicalpackage/update?id=${this.form.id}`, body).then(res => {
  401. if (res.code != -1) {
  402. let lfind = arrayExistObj(
  403. this.medicalPackages,
  404. "id",
  405. this.form.id
  406. );
  407. if (lfind > -1) objCopy(this.form, this.medicalPackages[lfind]);
  408. if (this.formOri.price != this.form.price) {
  409. return postapi('/api/app/medicalpackagedetail/getmedicalpackageinasbitem', { medicalPackageId })
  410. }
  411. }
  412. }).then(res => {
  413. if (res.code != -1) {
  414. medicalPackageAsbitems = res.data;
  415. if (medicalPackageAsbitems.length < 1) {
  416. this.dialogVisible = false;
  417. this.$message.success('操作成功!')
  418. } else {
  419. let detailsBody = {
  420. medicalPackageId,
  421. details: this.madeNewPackageAsbitems(medicalPackageAsbitems, this.form.price)
  422. }
  423. return postapi('/api/app/medicalPackagedetail/createmedicalPackagedetailmany', detailsBody)
  424. }
  425. }
  426. }).then(res => {
  427. if (res.code != -1) {
  428. this.$message.success('操作成功!并自动按总价同比折算组合项目价格!')
  429. this.dialogVisible = false;
  430. // 刷新明细
  431. let id = this.form.id
  432. this.form.id = ''
  433. setTimeout(() => {
  434. this.form.id = id
  435. }, 100);
  436. }
  437. });
  438. } else {
  439. //新增
  440. postapi(
  441. "/api/app/medicalpackage/create",
  442. body
  443. ).then((res) => {
  444. if (res.code != -1) {
  445. this.form.id = res.data.id;
  446. this.medicalPackages.push(deepCopy(res.data));
  447. this.$refs['medicalPackages'].setCurrentRow(this.medicalPackages[this.medicalPackages.length - 1]);
  448. this.dialogVisible = false;
  449. this.$message.success('操作成功!')
  450. }
  451. });
  452. }
  453. });
  454. },
  455. computePrice() {
  456. if (!this.form.id) {
  457. this.$message.warning("尚未保存信息,不可执行此操作!")
  458. return
  459. }
  460. let medicalPackageId = this.form.id
  461. let medicalPackageAsbitems = [] //套餐包含的套餐
  462. postapi('/api/app/medicalPackagedetail/getmedicalPackagedetailinasbitem', { medicalPackageId })
  463. .then(res => {
  464. if (res.code != -1) {
  465. medicalPackageAsbitems = res.data;
  466. if (medicalPackageAsbitems.length < 1) {
  467. this.$message.warning("当前套餐尚未设置组合项目,不可执行此操作!")
  468. } else {
  469. let body = {
  470. medicalPackageId,
  471. details: this.madeNewPackageAsbitems(medicalPackageAsbitems, this.form.price)
  472. }
  473. return postapi('/api/app/medicalPackagedetail/createmedicalPackagedetailmany', body)
  474. }
  475. }
  476. }).then(res => {
  477. if (res.code != -1) {
  478. //console.log("操作成功");
  479. //触发套餐明细刷新
  480. this.form.id = ''
  481. //要做延时处理,否则不会触发监听
  482. setTimeout(() => {
  483. this.form.id = medicalPackageId;
  484. this.onSubmit('form')
  485. }, 100)
  486. }
  487. })
  488. },
  489. madeNewPackageAsbitems(oldPackageAsbitems, newTotal) {
  490. newTotal = Math.round(Number(newTotal) * 100) / 100
  491. let newPackageAsbitems = []
  492. let oldTotal = Number(0)
  493. oldPackageAsbitems.forEach(e => {
  494. oldTotal += Number(e.asbitemMoney) //medicalPackageDetailMoney
  495. })
  496. oldTotal = Math.round(Number(oldTotal) * 100) / 100
  497. let discount = 0
  498. if (oldTotal != 0) discount = Math.round(newTotal * 10000 / oldTotal) / 100
  499. oldTotal = Number(0)
  500. oldPackageAsbitems.forEach(e => {
  501. e.medicalPackageDetailPrice = Math.round(e.price * discount) / 100
  502. e.medicalPackageDetailMoney = Math.round(e.medicalPackageDetailPrice * e.medicalPackageDetailAmount * 100) / 100
  503. oldTotal += Number(e.medicalPackageDetailMoney)
  504. })
  505. oldTotal = Math.round(Number(oldTotal) * 100) / 100
  506. //console.log('discount,oldTotal',discount,oldTotal)
  507. let didTotal = Math.round(Number(newTotal - oldTotal) * 100) / 100
  508. if (didTotal != 0) {
  509. for (let i = 0; i < oldPackageAsbitems.length; i++) {
  510. if (oldPackageAsbitems[i].medicalPackageDetailAmount == 1) {
  511. oldPackageAsbitems[i].medicalPackageDetailPrice = Math.round((Number(oldPackageAsbitems[i].medicalPackageDetailPrice) + Number(didTotal)) * 100) / 100
  512. break
  513. }
  514. }
  515. }
  516. oldPackageAsbitems.forEach(e => {
  517. newPackageAsbitems.push({
  518. medicalPackageId: this.form.id, // e.medicalPackageId,
  519. asbitemId: e.id, // e.asbitemId
  520. price: e.medicalPackageDetailPrice,
  521. amount: e.medicalPackageDetailAmount
  522. })
  523. })
  524. return newPackageAsbitems
  525. },
  526. },
  527. };
  528. </script>
  529. <style scoped>
  530. @import "../../assets/css/global_button.css";
  531. @import "../../assets/css/global_dialog.css";
  532. @import "../../assets/css/global_table.css";
  533. @import "../../assets/css/global_form.css";
  534. @import "../../assets/css/global_input.css";
  535. @import "../../assets/css/global.css";
  536. .box {
  537. display: flex;
  538. flex-direction: column;
  539. }
  540. :deep .el-form-item {
  541. margin-bottom: 14px;
  542. }
  543. /* 去掉input textarea的手动扩张样式 */
  544. :deep(.el-textarea__inner) {
  545. resize: none;
  546. }
  547. /* el-dialog的头部样式 */
  548. :deep .el-dialog__header {
  549. padding: 11px 20px 11px;
  550. }
  551. /* el-dialog的主体样式 */
  552. :deep .el-dialog__body {
  553. padding: 0px 20px 0px;
  554. }
  555. /* el-divider样式 */
  556. :deep .el-divider--horizontal {
  557. margin: 0px 0 12px;
  558. }
  559. /* el-dialog的底部样式 */
  560. :deep .el-dialog__footer {
  561. padding: 0px 20px 14px;
  562. }
  563. </style>