AddPlan.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644
  1. <template>
  2. <el-scrollbar style="height: 100%" ref="elscrollbar">
  3. <div class="AddPlanWrapper clearfix" @click="close">
  4. <crumbs
  5. :title="isEdit ? '电子病历方案配置-修改方案' : '电子病历方案配置-添加方案'"
  6. class="topBack"
  7. :param="$route.params"
  8. linkTo="Plan"
  9. ></crumbs>
  10. <div class="AddPlanBox">
  11. <el-row :gutter="20">
  12. <el-col :span="16">
  13. <el-form ref="form" :model="form" label-width="80px" :rules="rules">
  14. <el-form-item label="方案名称" prop="planName">
  15. <el-input v-model="form.planName" placeholder="2-30位,可输入汉字、字母、数字和下划线"></el-input>
  16. </el-form-item>
  17. <el-form-item label="方案编码" prop="planCode">
  18. <el-input v-model="form.planCode" placeholder="4-15位,可输入字母、数字和下划线"></el-input>
  19. </el-form-item>
  20. <el-form-item label="方案配置">
  21. <ul>
  22. <li>
  23. <div class="title">
  24. <div class="handleIcon" @click="openPlanItems">
  25. <img
  26. src="../../../images/multi.png"
  27. alt="辅助信息"
  28. :class="{'open' : isOpenCloseItems}"
  29. />
  30. </div>
  31. <h4>辅助信息</h4>
  32. <div class="titlwSwitch">
  33. <el-switch
  34. v-model="switchSubStatus"
  35. :active-value="1"
  36. :inactive-value="0"
  37. active-color="#4BC4D7"
  38. inactive-color="#BBBBBB"
  39. ></el-switch>
  40. <span class="titlwSwitchStatus">{{switchSubStatus === 1 ? '启用中' : '未启用'}}</span>
  41. </div>
  42. </div>
  43. <transition name="plus-icon">
  44. <div v-if="isOpenCloseItems">
  45. <ul class="sub" v-for="(item,index) in planDefaultList" :key="item.id">
  46. <li class="planItem">
  47. <div class="sort">
  48. <div class="top">
  49. <img
  50. :src="isTopLight !== index ? require('../../../images/icon_default_top.png') : require('../../../images/icon_hover_top.png')"
  51. alt="上升"
  52. v-if="index !== 0"
  53. @click="sortPlan(item,index,'top')"
  54. @mouseover="handleMouseEnter1(index)"
  55. @mouseleave="handleMouseLeave1(index)"
  56. />
  57. </div>
  58. <div class="down">
  59. <img
  60. :src="isDownLight !== index ? require('../../../images/icon_default_down.png') : require('../../../images/icon_hover_down.png')"
  61. alt="下降"
  62. v-if="index !== planDefaultList.length - 1"
  63. @click="sortPlan(item,index,'down')"
  64. @mouseover="handleMouseEnter(index)"
  65. @mouseleave="handleMouseLeave(index)"
  66. />
  67. </div>
  68. </div>
  69. <div class="openOrClose">
  70. <span class="planInfo">{{item.name}}</span>
  71. <div class="switch">
  72. <el-switch
  73. v-model="item.status"
  74. :active-value="1"
  75. :inactive-value="0"
  76. active-color="#4BC4D7"
  77. inactive-color="#BBBBBB"
  78. ></el-switch>
  79. </div>
  80. <span class="planStatus">{{item.status === 1 ? '启用中' : '未启用'}}</span>
  81. </div>
  82. <div class="showNum" v-if="item.number">
  83. <span style="marginRight:8px;">默认显示个数</span>
  84. <el-select
  85. v-model="item.number"
  86. placeholder="请选择"
  87. size="small"
  88. :disabled="item.status !== 1 ? true: false"
  89. >
  90. <el-option label="1" value="1"></el-option>
  91. <el-option label="2" value="2"></el-option>
  92. <el-option label="3" value="3"></el-option>
  93. <el-option label="4" value="4"></el-option>
  94. <el-option label="5" value="5"></el-option>
  95. <el-option label="6" value="6"></el-option>
  96. </el-select>
  97. </div>
  98. </li>
  99. </ul>
  100. </div>
  101. </transition>
  102. </li>
  103. <li>
  104. <div class="title">
  105. <div class="handleIcon">
  106. <img src="../../../images/multi.png" alt="医学知识" />
  107. </div>
  108. <h4>医学知识</h4>
  109. <div class="titlwSwitch">
  110. <el-switch
  111. v-model="switchMedStatus"
  112. :active-value="1"
  113. :inactive-value="0"
  114. active-color="#4BC4D7"
  115. inactive-color="#BBBBBB"
  116. ></el-switch>
  117. <span class="titlwSwitchStatus">{{switchMedStatus === 1 ? '启用中' : '未启用'}}</span>
  118. </div>
  119. </div>
  120. </li>
  121. <li>
  122. <div class="title">
  123. <div class="handleIcon">
  124. <img src="../../../images/multi.png" alt="医学知识" />
  125. </div>
  126. <h4>随访计划</h4>
  127. <div class="titlwSwitch">
  128. <el-switch
  129. v-model="switchFollowStatus"
  130. :active-value="1"
  131. :inactive-value="0"
  132. active-color="#4BC4D7"
  133. inactive-color="#BBBBBB"
  134. ></el-switch>
  135. <span class="titlwSwitchStatus">{{switchFollowStatus === 1 ? '启用中' : '未启用'}}</span>
  136. </div>
  137. </div>
  138. </li>
  139. </ul>
  140. </el-form-item>
  141. <el-form-item>
  142. <el-button type="primary" @click="onSubmit" :disabled="saveDisable">确定</el-button>
  143. </el-form-item>
  144. </el-form>
  145. </el-col>
  146. </el-row>
  147. </div>
  148. </div>
  149. </el-scrollbar>
  150. </template>
  151. <script>
  152. import api from '@api/cdss.js';
  153. export default {
  154. name: 'AddPlan',
  155. data() {
  156. var numreg = /^[a-zA-Z0-9_\u4e00-\u9fa5]+$/;
  157. var numreg1 = /^[0-9a-zA-Z_]{1,}$/;
  158. var validatePass = (rule, value, callback) => {
  159. if (!numreg.test(value)) {
  160. callback(new Error('汉字、字母、数字和下划线'));
  161. } else {
  162. callback();
  163. }
  164. };
  165. var validatePass1 = (rule, value, callback) => {
  166. if (!numreg1.test(value)) {
  167. callback(new Error('字母、数字和下划线'));
  168. } else {
  169. callback();
  170. }
  171. };
  172. return {
  173. form: {
  174. planName: '',
  175. planCode: ''
  176. },
  177. saveDisable: false, //保存按钮禁止点击
  178. rules: {
  179. planName: [
  180. { required: true, message: '方案名称不能为空', trigger: 'change' },
  181. { min: 2, max: 30, message: '长度2-30位', trigger: 'blur' },
  182. { required: true, validator: validatePass, trigger: 'blur' }
  183. ],
  184. planCode: [
  185. { required: true, message: '方案编码不能为空', trigger: 'change' },
  186. { min: 4, max: 15, message: '长度4-15位', trigger: 'blur' },
  187. { required: true, validator: validatePass1, trigger: 'blur' }
  188. ]
  189. },
  190. planDefaultList: [],
  191. hospitalId: '',
  192. isEdit: false, // 是否处于编辑页面 false--新增 true--编辑
  193. switchSubStatus: 0, // 辅助信息
  194. switchMedStatus: 0, // 医学知识
  195. switchFollowStatus: 0, //随访计划
  196. isOpenCloseItems: true, // 是否展开方案配置项
  197. isDownLight: -1,
  198. isTopLight: -1,
  199. flag: 1,
  200. editCount: -1, // 页面会否被编辑 >0被编辑 =0 未编辑
  201. isSaveSuccess: false // 是否保存成功
  202. };
  203. },
  204. beforeRouteLeave(to, from, next) {
  205. if (
  206. (this.editCount > 2 && !this.isSaveSuccess && this.isEdit) ||
  207. (this.editCount > 1 && !this.isSaveSuccess && !this.isEdit)
  208. ) {
  209. // console.log('页面被编辑了');
  210. this.$confirm('还有未保存的内容,确定要退出当前页面吗?', '提示', {
  211. confirmButtonText: '确定',
  212. cancelButtonText: '取消',
  213. cancelButtonClass: 'leaveBtn',
  214. customClass: 'leaveBox',
  215. type: 'warning'
  216. })
  217. .then(() => {
  218. next();
  219. })
  220. .catch(() => {});
  221. } else {
  222. next();
  223. }
  224. },
  225. watch: {
  226. form: {
  227. handler(newName, oldName) {
  228. this.editCount++;
  229. },
  230. deep: true
  231. // immediate: true
  232. },
  233. planDefaultList: {
  234. handler(newName, oldName) {
  235. // console.log(newName,'newName');
  236. // console.log(oldName,'oldName');
  237. this.editCount++;
  238. },
  239. deep: true,
  240. immediate: true
  241. }
  242. },
  243. async created() {
  244. const { isEdit, data } = this.$route.params;
  245. // console.log(data, '编辑页传递的data');
  246. let res = await api.getHospitalInfo(); // 同步获取医院信息
  247. this.hospitalId = res.data.data.id;
  248. if (isEdit) {
  249. // 编辑页面
  250. this.isEdit = true;
  251. let params = {
  252. hospitalId: res.data.data.id,
  253. id: data.id
  254. };
  255. this._getPlanInfoIds(params);
  256. } else {
  257. // 新增页面
  258. this._getDefaultPlans(); // 获取默认配置信息
  259. }
  260. },
  261. methods: {
  262. close() {},
  263. // 方案配置排序
  264. sortPlan(item, index, type) {
  265. // console.log('排序', item, index, type);
  266. let tempList = [...this.planDefaultList];
  267. if (type === 'down') {
  268. // 降序
  269. let plan = tempList.find(item => {
  270. return item.orderNo === index + 1;
  271. });
  272. let tempPlan = { ...plan };
  273. let planNext = tempList.find(item => {
  274. return item.orderNo === index + 2;
  275. });
  276. let tempPlanNext = { ...planNext };
  277. plan = tempPlanNext;
  278. plan.orderNo -= 1;
  279. planNext = tempPlan;
  280. planNext.orderNo += 1;
  281. let arr = tempList.map((i, idx) => {
  282. if (idx === index) {
  283. return { ...plan };
  284. } else if (idx === index + 1) {
  285. return { ...planNext };
  286. } else {
  287. return i;
  288. }
  289. });
  290. this.planDefaultList = [...arr];
  291. } else {
  292. // 升序
  293. let plan = tempList.find(item => {
  294. return item.orderNo === index + 1;
  295. });
  296. let tempPlan = { ...plan };
  297. let planPre = tempList.find(item => {
  298. return item.orderNo === index;
  299. });
  300. let tempPlanPre = { ...planPre };
  301. plan = tempPlanPre;
  302. plan.orderNo += 1;
  303. planPre = tempPlan;
  304. planPre.orderNo -= 1;
  305. let arr = tempList.map((i, idx) => {
  306. if (idx === index) {
  307. return { ...plan };
  308. } else if (idx === index - 1) {
  309. return { ...planPre };
  310. } else {
  311. return i;
  312. }
  313. });
  314. this.planDefaultList = [...arr];
  315. }
  316. },
  317. // 展开列表项
  318. openPlanItems() {
  319. this.isOpenCloseItems = !this.isOpenCloseItems;
  320. },
  321. // 鼠标移入
  322. handleMouseEnter(index) {
  323. this.isDownLight = index;
  324. },
  325. // 鼠标移除
  326. handleMouseLeave(index) {
  327. this.isDownLight = -1;
  328. },
  329. // 鼠标移入
  330. handleMouseEnter1(index) {
  331. this.isTopLight = index;
  332. },
  333. // 鼠标移除
  334. handleMouseLeave1(index) {
  335. this.isTopLight = -1;
  336. },
  337. // 获取默认方案配置
  338. _getDefaultPlans() {
  339. api.getDefaultPlans().then(res => {
  340. // console.log(res, '获取默认的方案配置');
  341. if (res.data.code === '0') {
  342. this.planDefaultList =
  343. res.data.data &&
  344. res.data.data.planDetailDefault.length !== 0 &&
  345. res.data.data.planDetailDefault[0].planDetails;
  346. this.switchSubStatus =
  347. res.data.data &&
  348. res.data.data.planDetailDefault.length !== 0 &&
  349. res.data.data.planDetailDefault[0].status;
  350. this.switchMedStatus =
  351. res.data.data &&
  352. res.data.data.planDetailDefault.length !== 0 &&
  353. res.data.data.planDetailDefault[1].status;
  354. this.switchFollowStatus =
  355. res.data.data &&
  356. res.data.data.planDetailDefault.length !== 0 &&
  357. res.data.data.planDetailDefault[2].status;
  358. }
  359. });
  360. },
  361. // 编辑页面 根据id获取方案配置
  362. async _getPlanInfoIds(params) {
  363. // 先获取默认的所有方案
  364. let tempArr = [];
  365. let newPlan = [];
  366. let res = await api.getDefaultPlans();
  367. if (res.data.code === '0') {
  368. tempArr =
  369. res.data.data &&
  370. res.data.data.planDetailDefault.length !== 0 &&
  371. res.data.data.planDetailDefault[0].planDetails;
  372. }
  373. let res1 = await api.getPlanInfoIds(params);
  374. if (res1.data.code === '0') {
  375. newPlan = res1.data.data[0].sysSetInfo[0].planDetails;
  376. this.form.planName = res1.data.data[0].planName;
  377. this.form.planCode = res1.data.data[0].planCode;
  378. this.switchSubStatus = res1.data.data[0].sysSetInfo[0].status;
  379. this.switchMedStatus = res1.data.data[0].sysSetInfo[1].status;
  380. this.switchFollowStatus = res1.data.data[0].sysSetInfo[2].status;
  381. // this.planDefaultList = res1.data.data[0].sysSetInfo[0].planDetails;
  382. }
  383. let arr = [];
  384. let arrTemp = [];
  385. let arrTemp1 = []; // 不同index
  386. for (var i = 0; i < tempArr.length; i++) {
  387. arrTemp.push(i);
  388. }
  389. for (var i = 0; i < tempArr.length; i++) {
  390. for (var j = 0; j < newPlan.length; j++) {
  391. if (tempArr[i].code === newPlan[j].code) {
  392. arr.push(i);
  393. }
  394. }
  395. }
  396. arrTemp1 = arr
  397. .filter(x => arrTemp.indexOf(x) == -1)
  398. .concat(arrTemp.filter(x => arr.indexOf(x) == -1));
  399. let endArr = [...newPlan];
  400. for (var j = 0; j < arrTemp1.length; j++) {
  401. let temp = tempArr[arrTemp1[j]];
  402. temp.orderNo = arr.length + j + 1;
  403. temp.status = 0;
  404. endArr.push(temp);
  405. }
  406. // console.log(endArr,'-=-=-=-=-=');
  407. this.planDefaultList = endArr;
  408. },
  409. // format处理细项数据
  410. handleSendData() {
  411. let TempPlanDetail = [];
  412. TempPlanDetail = this.planDefaultList.map((item, index) => {
  413. return {
  414. code: item.code,
  415. hospitalId: this.hospitalId,
  416. name: item.name,
  417. number: item.number,
  418. orderNo: item.orderNo,
  419. planId: item.planId,
  420. remark: item.remark,
  421. status: item.status,
  422. value: item.value
  423. };
  424. });
  425. return TempPlanDetail;
  426. // console.log(TempPlanDetail, 'TempPlanDetail');
  427. },
  428. // 处理保存活动信息参数
  429. _getParams() {
  430. let params = {
  431. hospitalId: this.hospitalId,
  432. planCode: this.form.planCode,
  433. planDetailParent: [
  434. {
  435. code: 'auxiliary',
  436. hospitalId: this.hospitalId,
  437. name: '辅助信息',
  438. number: 0,
  439. orderNo: 1,
  440. planDetailSub: this.handleSendData(),
  441. status: this.switchSubStatus
  442. },
  443. {
  444. code: 'medical',
  445. hospitalId: this.hospitalId,
  446. name: '医学知识',
  447. orderNo: 3,
  448. planDetailSub: [{}],
  449. status: this.switchMedStatus
  450. },
  451. {
  452. code: 'followup',
  453. hospitalId: this.hospitalId,
  454. name: '随访计划',
  455. orderNo: 4,
  456. planDetailSub: [{}],
  457. status: this.switchFollowStatus
  458. }
  459. ], // 方案配置信息
  460. planName: this.form.planName,
  461. planStatus: 1 // 1 启用 默认启用
  462. };
  463. if (this.isEdit) {
  464. // 编辑状态,需要额外添加ID
  465. const { data } = this.$route.params;
  466. params = { ...params, id: data.id };
  467. }
  468. return params;
  469. },
  470. onSubmit() {
  471. this.$refs.form.validate(valid => {
  472. if (valid) {
  473. this.saveDisable = true;
  474. let params = this._getParams();
  475. api.savePlanInfoDatas(params).then(res => {
  476. if (res.data.code === '0') {
  477. this.$message({
  478. showClose: true,
  479. message: '保存成功',
  480. type: 'success',
  481. duration: 1000
  482. });
  483. this.isSaveSuccess = true; // 保存成功,可正常退出
  484. this.$router.push({
  485. name: 'Plan',
  486. params: Object.assign({}, this.$route.params, {
  487. currentPage: 1
  488. })
  489. });
  490. } else if (res.data.code === '00020007') {
  491. // 方案名/方案编码已存在
  492. this.$message({
  493. showClose: true,
  494. message: res.data.msg,
  495. type: 'error',
  496. duration: 1000
  497. });
  498. }
  499. this.saveDisable = false;
  500. });
  501. } else {
  502. this.saveDisable = false;
  503. var div = this.$refs['elscrollbar'].$refs['wrap'];
  504. this.$nextTick(() => {
  505. div.scrollTop = 0;
  506. });
  507. return false;
  508. }
  509. });
  510. }
  511. }
  512. };
  513. </script>
  514. <style lang="less" scoped>
  515. .AddPlanWrapper {
  516. min-width: 940px;
  517. .AddPlanBox {
  518. padding: 20px 60px 120px 60px;
  519. margin: 70px 20px 0 20px;
  520. background: #fff;
  521. }
  522. color: #606266;
  523. .topBack {
  524. top: 0;
  525. }
  526. .title {
  527. background-color: #f2f2f2;
  528. display: flex;
  529. .handleIcon {
  530. width: 30px;
  531. cursor: pointer;
  532. height: 40px;
  533. display: flex;
  534. justify-content: center;
  535. align-items: center;
  536. img {
  537. width: 20px;
  538. height: 20px;
  539. }
  540. .open {
  541. transform: rotate(180deg);
  542. }
  543. .close {
  544. transform: rotate(0deg);
  545. }
  546. }
  547. .titlwSwitch {
  548. width: 120px;
  549. }
  550. h4 {
  551. flex: 1;
  552. }
  553. .titlwSwitchStatus {
  554. margin-left: 16px;
  555. }
  556. }
  557. .sub {
  558. .planItem {
  559. display: flex;
  560. .sort {
  561. width: 60px;
  562. display: flex;
  563. .top {
  564. display: flex;
  565. justify-content: center;
  566. align-items: center;
  567. width: 30px;
  568. cursor: pointer;
  569. img {
  570. width: 10px;
  571. height: 14px;
  572. }
  573. }
  574. .down {
  575. width: 30px;
  576. cursor: pointer;
  577. display: flex;
  578. justify-content: center;
  579. align-items: center;
  580. img {
  581. width: 10px;
  582. height: 14px;
  583. }
  584. }
  585. }
  586. .openOrClose {
  587. display: flex;
  588. flex: 1;
  589. .planInfo {
  590. width: 140px;
  591. }
  592. .switch {
  593. }
  594. .planStatus {
  595. margin-left: 16px;
  596. }
  597. }
  598. .showNum {
  599. display: flex;
  600. width: 160px;
  601. /deep/.el-input--small {
  602. width: 60px;
  603. }
  604. }
  605. }
  606. }
  607. .el-button {
  608. float: right;
  609. }
  610. .plus-icon-enter-active {
  611. transition: all 0.8s;
  612. }
  613. .plus-icon-enter {
  614. opacity: 0;
  615. margin-top: 12px;
  616. }
  617. .plus-icon-leave-active {
  618. transition: all 0.8s;
  619. }
  620. .plus-icon-leave-active {
  621. opacity: 0;
  622. margin-top: 12px;
  623. }
  624. }
  625. .leaveBox {
  626. /deep/ .leaveBtn {
  627. // margin-right: 46px;
  628. background-color: #d7d7d7 !important;
  629. border-color: transparent;
  630. }
  631. }
  632. </style>