AddQualityControlTemp.vue 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581
  1. <template>
  2. <div @click="closeSearch">
  3. <crumbs :title="title" :param="$route.params" linkTo="QualityControlTemp">
  4. </crumbs>
  5. <div class="contentWrapper">
  6. <div class="content">
  7. <el-form :model="form" :rules="rules" ref="form" class="selectHospital">
  8. <el-form-item label="所属医院:" prop="hospital" class="formItem">
  9. <el-select v-model="form.hospital" placeholder="请选择医院" :disabled="isEdit||isCopy" class="selectHospital" @change="changeHsopital">
  10. <el-option v-for="item in hospitalList" :key="item.id" :label="item.name" :value="item.val"></el-option>
  11. </el-select>
  12. </el-form-item>
  13. <el-form-item label="所属模块:" prop="moduleName" class="formItem">
  14. <el-select v-model="form.moduleName" placeholder="请选择所属模块" :disabled="isEdit||isCopy" class="selectModule" @change="changeHsopital">
  15. <el-option v-for="item in moduleList" :key="item.id" :label="item.name" :value="item.val"></el-option>
  16. </el-select>
  17. </el-form-item>
  18. <el-form-item label="模块类型:" prop="moduleType" class="formItem widthLarge">
  19. <el-select v-model="form.moduleType" :disabled="form.hospital==='' || form.moduleName===''" placeholder="请选择模块类型" @change="changeModuleType" class="selectModule">
  20. <el-option v-for="item in moduleTypeList" :key="item.id" :label="item.recTypeDetail" :value="item.id"></el-option>
  21. </el-select>
  22. </el-form-item>
  23. <el-form-item label="模板名称:" prop="tempName" class="formItem widthLarge">
  24. <el-input v-model="form.tempName" placeholder="请输入模板名称" disabled></el-input>
  25. </el-form-item>
  26. <el-form-item label="示例:" v-if="form.moduleType !==''" prop="example" class="formItem formExam">
  27. <span class="exampleTxt">{{form.example}}</span>
  28. <!-- <el-input v-model="form.example" disabled placeholder="示例"></el-input> -->
  29. </el-form-item>
  30. <el-form-item label="模块内容:" prop="moduleInfo" class="formItem addCon">
  31. <div class="moduleInfoItem" v-for="(item,index) in moduleInfoList">
  32. <div class="orderBox">
  33. <span class="el-icon-arrow-up order" @click="upUnit(index)"></span>
  34. <span class="el-icon-arrow-down order" @click="downUnit(index)"></span>
  35. </div>
  36. <div class="searchBox">
  37. <el-input v-model.trim="item.searchName" placeholder="搜索字段单元" @click="stopClick" @input="searchFiled(index)">
  38. </el-input>
  39. <ul v-if="searchIndex == index && item.searchResult.length > 0" class="searchResultBox">
  40. <li class="searchItem"
  41. v-for="searchItem in item.searchResult"
  42. :title="searchItem.tagName"
  43. @click="selectSearchFiled(searchItem,index)"
  44. >
  45. {{searchItem.tagName}}
  46. </li>
  47. </ul>
  48. </div>
  49. <div>
  50. <p>已选择字段:</p>
  51. <div class="selectFiledBox">
  52. <div class="orderBox">
  53. <span class="el-icon-arrow-up order" @click="upFiled(index)"></span>
  54. <span class="el-icon-arrow-down order" @click="downFiled(index)"></span>
  55. </div>
  56. <div class="selectFiled" v-for="(it,ii) in item.selectFiled">
  57. <span class="filedName" :class="{activeFiledName: item.activeIndex == ii}" @click="setActiveIndex(index,ii)">{{it.tagName}}
  58. <span class="el-icon-circle-close delFiled" @click="delSelected(ii,index)"></span>
  59. </span>
  60. </div>
  61. </div>
  62. </div>
  63. <span class="el-icon-circle-close delUnit" @click="delUnit(index)"></span>
  64. </div>
  65. <span class="addUnit" >
  66. <el-button size="small" type="primary" @click="addUnit">+单元组</el-button>
  67. </span>
  68. </el-form-item>
  69. </el-form>
  70. <el-button class="disclButn" size="small" type="primary" :disabled = 'saveDisable' @click="confirm('form')">确定</el-button>
  71. </div>
  72. </div>
  73. </div>
  74. </template>
  75. <script>
  76. import api from '@api/qualityControl.js';
  77. export default {
  78. name:"AddQualityControlTemp",
  79. data: function(){
  80. return {
  81. title: "模板维护-添加",
  82. isEdit:false,
  83. isCopy: false,
  84. saveDisable: false,
  85. form:{
  86. tempName: "",
  87. hospital:"",
  88. moduleName:"",
  89. moduleType:"",
  90. nameType:""
  91. },
  92. rules:{
  93. tempName:{ required: true, message: '请输入模块名称', trigger: ['blur', 'change']},
  94. hospital:{ required: true, message: '请选择医院', trigger: ['blur', 'change']},
  95. moduleName:{ required: true, message: '请选择所属模块', trigger: ['blur', 'change']},
  96. moduleType:{ required: true, message: '请选择模块类型 ', trigger: ['blur', 'change']},
  97. /*name:[{ required: true, message: '请输入显示名称',trigger: ['blur', 'change'] }],*/
  98. },
  99. searchIndex: -1,
  100. hospitalList:[],
  101. moduleList:[ ],
  102. moduleTypeList:[], //模块类型列表
  103. moduleInfoList:[
  104. // {
  105. // searchName:"",
  106. // activeIndex: -1,
  107. // searchResult:[
  108. // // {
  109. // // name: "4姓名"
  110. // // },
  111. // // {
  112. // // name: "5职业"
  113. // // },
  114. // // {
  115. // // name: "6年龄"
  116. // // }
  117. // ],
  118. // selectFiled:[
  119. // ]
  120. // }
  121. ]
  122. }
  123. },
  124. created(){
  125. this.getAllTypes();
  126. const {isCopy, isEdit, data } = this.$route.params
  127. if(isEdit || isCopy) {
  128. this.form.hospital = ''+data.hospitalId
  129. this.form.moduleName = ''+data.modeId
  130. if(isEdit){
  131. this.isEdit = isEdit;
  132. this.id = data.id
  133. this.title ="模板维护-修改"
  134. this.form.tempName = data.name
  135. this.getModuleTypeList().then(res =>{
  136. this.form.moduleType = data.recordModuleId
  137. this.form.example = this.moduleTypeList.find(item => item.id == this.form.moduleType).behospitalCodes
  138. })
  139. }
  140. if(isCopy){
  141. this.isEdit = isEdit;
  142. this.isCopy = isCopy
  143. this.id = ""
  144. this.title ="模板维护-复制"
  145. this.form.tempName = ""
  146. this.form.moduleType=""
  147. this.form.example=""
  148. this.getModuleTypeList()
  149. }
  150. const moduleDetail = data.moduleDetail
  151. const keysList = Object.keys(moduleDetail)
  152. for(let i = 0; i < keysList.length; i++){
  153. let selectFiled = []
  154. for(let j = 0; j < moduleDetail[keysList[i]].length; j++){
  155. const item = moduleDetail[keysList[i]][j]
  156. selectFiled.push(item.questionDTO)
  157. }
  158. this.moduleInfoList.push({
  159. searchName:"",
  160. activeIndex: -1,
  161. searchResult:[
  162. ],
  163. selectFiled:selectFiled
  164. })
  165. }
  166. }
  167. },
  168. methods:{
  169. closeSearch(){
  170. if(this.searchIndex > -1){
  171. this.moduleInfoList[this.searchIndex].searchName = ""
  172. this.moduleInfoList[this.searchIndex].searchResult=[]
  173. this.searchIndex = -1
  174. }
  175. },
  176. getAllTypes(){
  177. if(localStorage.getItem("qcModuleTypes")){
  178. this.hospitalList = JSON.parse(localStorage.getItem("qcHospitalTypes"));
  179. this.moduleList = JSON.parse(localStorage.getItem("qcModuleTypes"));
  180. return new Promise(function(resolve, reject){
  181. resolve()
  182. });
  183. }
  184. //获取枚举信息
  185. return api.getQcTypes().then((res)=>{
  186. if(res.data.code==="0"){
  187. const data = res.data.data;
  188. localStorage.setItem("qcFieldTypes",JSON.stringify(data[11]));
  189. localStorage.setItem("qcModuleTypes",JSON.stringify(data[12]));
  190. localStorage.setItem("qcHospitalTypes",JSON.stringify(data[13]));
  191. this.hospitalList = JSON.parse(localStorage.getItem("qcHospitalTypes"));
  192. this.moduleList = JSON.parse(localStorage.getItem("qcModuleTypes"));
  193. }else{
  194. this.warning("获取枚举信息失败");
  195. }
  196. });
  197. },
  198. stopClick(e){
  199. console.log('11111')
  200. // e.stopPropagation()
  201. },
  202. changeHsopital(){
  203. this.form.moduleType = ""
  204. this.getModuleTypeList()
  205. },
  206. changeModule(){
  207. this.form.moduleType = ""
  208. this.getModuleTypeList()
  209. },
  210. changeModuleType(){
  211. this.form.example = this.moduleTypeList.find(item => item.id == this.form.moduleType).behospitalCodes
  212. this.form.tempName = this.moduleTypeList.find(item => item.id == this.form.moduleType).recTypeDetail
  213. },
  214. getModuleTypeList(){
  215. this.moduleTypeList = []
  216. if(this.form.hospital === "" || this.form.moduleName===""){
  217. return
  218. }
  219. return api.getModuleTypeList({hospitalId: this.form.hospital, modeId: this.form.moduleName}).then((res) =>{
  220. if(res.data.code==="0"){
  221. const data = res.data.data;
  222. this.moduleTypeList = data
  223. }else{
  224. this.moduleTypeList=[]
  225. this.warning("获取模块类型失败");
  226. }
  227. })
  228. },
  229. addUnit(){
  230. if(!this.form.hospital){
  231. this.warning("请先选择所属医院")
  232. return
  233. }
  234. if(!this.form.tempName){
  235. this.warning("请先选择模块")
  236. return
  237. }
  238. this.moduleInfoList.push({
  239. searchName:"",
  240. activeIndex: -1,
  241. searchResult:[
  242. ],
  243. selectFiled:[
  244. ]
  245. })
  246. },
  247. searchFiled(index){
  248. this.searchIndex = index
  249. const searchName = this.moduleInfoList[index].searchName
  250. if(!searchName){
  251. return
  252. }
  253. const param = {
  254. tagName: searchName,
  255. hospitalId: this.form.hospital,
  256. modeId: [this.form.moduleName],
  257. }
  258. api.getQCName(param).then(res =>{
  259. if(res.data.code == '0'){
  260. this.moduleInfoList[index].searchResult = []
  261. this.moduleInfoList[index].searchResult.push(...res.data.data)
  262. }
  263. }).catch(e =>{
  264. console.log(e)
  265. })
  266. },
  267. selectSearchFiled(searchItem,index){
  268. this.moduleInfoList[index].selectFiled.push(searchItem)
  269. this.searchIndex = -1
  270. this.moduleInfoList[index].searchName=""
  271. this.moduleInfoList[index].searchResult = []
  272. },
  273. setActiveIndex(index, ii){
  274. let activeIndex = this.moduleInfoList[index].activeIndex
  275. if( ii === activeIndex) {
  276. this.moduleInfoList[index].activeIndex = -1
  277. } else {
  278. this.moduleInfoList[index].activeIndex = ii
  279. }
  280. },
  281. upUnit(index){
  282. if(index == 0){
  283. return
  284. }
  285. const current = this.moduleInfoList[index]
  286. const currentPre = this.moduleInfoList[index-1]
  287. this.moduleInfoList.splice(index-1,2,current,currentPre)
  288. },
  289. downUnit(index){
  290. if(index == this.moduleInfoList.length -1){
  291. return
  292. }
  293. const current = this.moduleInfoList[index]
  294. const currentNext = this.moduleInfoList[index+1]
  295. this.moduleInfoList.splice(index,2,currentNext,current)
  296. },
  297. upFiled(index){
  298. let activeIndex = this.moduleInfoList[index].activeIndex
  299. if(activeIndex == 0 || activeIndex == -1){
  300. return
  301. }
  302. const current = this.moduleInfoList[index].selectFiled[activeIndex]
  303. const currentPre = this.moduleInfoList[index].selectFiled[activeIndex-1]
  304. this.moduleInfoList[index].selectFiled.splice(activeIndex-1,2,current,currentPre)
  305. this.moduleInfoList[index].activeIndex--
  306. },
  307. downFiled(index){
  308. let activeIndex = this.moduleInfoList[index].activeIndex
  309. if(activeIndex == this.moduleInfoList[index].selectFiled.length -1 || activeIndex == -1){
  310. return
  311. }
  312. const current = this.moduleInfoList[index].selectFiled[activeIndex]
  313. const currentNext = this.moduleInfoList[index].selectFiled[activeIndex+1]
  314. this.moduleInfoList[index].selectFiled.splice(activeIndex,2,currentNext,current)
  315. this.moduleInfoList[index].activeIndex++
  316. },
  317. delSelected(ii,index){
  318. this.moduleInfoList[index].selectFiled.splice(ii,1)
  319. },
  320. delUnit(index){
  321. this.moduleInfoList.splice(index,1)
  322. },
  323. confirm(form){
  324. // this.$refs[form].validate((valid) => {
  325. // if (valid) {
  326. const {tempName,hospital,moduleName,moduleType} = this.form
  327. let moduleDetail = [], moduleInfoList = this.moduleInfoList
  328. for(let i = 0; i < moduleInfoList.length; i++){
  329. for(let j = 0; j < moduleInfoList[i].selectFiled.length; j++){
  330. let item ={
  331. groupId: i,
  332. questionId: moduleInfoList[i].selectFiled[j].id
  333. }
  334. moduleDetail.push(item)
  335. }
  336. }
  337. if(!hospital){
  338. this.warning("请选择所属医院");
  339. return
  340. }
  341. if(!moduleName){
  342. this.warning("请选择所属模块");
  343. return
  344. }
  345. if(!moduleType){
  346. this.warning("请选择模块类型");
  347. return
  348. }
  349. if(!tempName){
  350. this.warning("请输入模块名称");
  351. return
  352. }
  353. if(moduleDetail.length === 0){
  354. this.warning('请添加模块内容')
  355. return
  356. }
  357. let param = {
  358. name: tempName,
  359. modeId: moduleName,
  360. hospitalId: hospital,
  361. moduleDetail: moduleDetail,
  362. remark:'',
  363. recordModuleId:moduleType
  364. }
  365. if(this.isEdit){
  366. param = Object.assign({}, param, {id: this.id})
  367. }
  368. if(this.id && !this.isCopy){//修改
  369. this.saveDisable = true //提交保存按钮不可点击,返回结果时才可点击,防止频繁发送请求
  370. api.saveOrUpdateQCTemp(param).then((res)=>{
  371. if(res.data.code==0){
  372. this.$message({
  373. message:"修改成功",
  374. type:'success'
  375. });
  376. //返回带搜索条件的首页
  377. this.$router.push({
  378. name: 'QualityControlTemp',
  379. params: Object.assign({}, this.$route.params, {currentPage: 1})
  380. });
  381. }else{
  382. this.$message({
  383. message:res.data.msg,
  384. type:'warning'
  385. });
  386. }
  387. this.saveDisable = false
  388. })
  389. }else{//添加
  390. this.saveDisable = true; //提交保存按钮不可点击,返回结果时才可点击,防止频繁发送请求
  391. api.saveOrUpdateQCTemp(param).then((res)=>{
  392. if(res.data.code==0){
  393. this.$message({
  394. message:"添加成功",
  395. type:'success'
  396. })
  397. this.$router.push({name: 'QualityControlTemp'});
  398. }else{
  399. this.$message({
  400. message:res.data.msg,
  401. type:'warning'
  402. });
  403. }
  404. this.saveDisable = false
  405. })
  406. }
  407. // } else {
  408. // return false;
  409. // }
  410. // });
  411. },
  412. warning(msg, type,time) {
  413. this.$message({
  414. showClose: true,
  415. message: msg,
  416. type: type || 'warning',
  417. duration:time || '3000'
  418. })
  419. },
  420. }
  421. }
  422. </script>
  423. <style lang="less" scoped>
  424. .contentWrapper{
  425. padding: 50px 20px 0;
  426. }
  427. .content{
  428. background: #fff;
  429. }
  430. .formItem{
  431. /deep/.el-form-item__label{
  432. width: 150px;
  433. }
  434. }
  435. /deep/.el-form-item__content{
  436. display: inline-block;
  437. }
  438. /deep/.el-input__inner {
  439. height: 30px;
  440. line-height: 30px;
  441. // width: 200px;
  442. }
  443. /deep/.widthLarge .el-input__inner {
  444. width: 350px;
  445. }
  446. /deep/.addCon .el-form-item__label:before {
  447. content: '*';
  448. color: #f56c6c;
  449. margin-right: 4px;
  450. }
  451. .formExam{
  452. /deep/.el-form-item__content{
  453. width: calc(100% - 185px);
  454. }
  455. }
  456. .exampleTxt{
  457. display: inline-block;
  458. position: relative;
  459. width: 100%;
  460. max-height: 200px;
  461. padding: 0 20px 0 0;
  462. height: 100%;
  463. word-break: break-all;
  464. overflow-y: auto;
  465. }
  466. .moduleInfoItem{
  467. width: 500px;
  468. min-height: 200px;
  469. padding: 0 50px 0 50px;
  470. border: 1px solid #dcdfe6;
  471. border-radius: 5px;
  472. margin-bottom: 20px;
  473. position: relative;
  474. }
  475. .addUnit{
  476. display: inline-block;
  477. border: 1px solid #dcdfe6;
  478. border-radius: 5px;
  479. width: 80px;
  480. text-align: center;
  481. height: 20px;
  482. line-height: 20px;
  483. cursor: pointer;
  484. }
  485. .searchBox{
  486. width: 500px;
  487. position: relative;
  488. }
  489. .searchResultBox{
  490. position: absolute;
  491. width: 500px;
  492. box-sizing: border-box;
  493. max-height: 200px;
  494. overflow-y: auto;
  495. background: #fff;
  496. z-index: 2;
  497. border: 1px solid #48c5d7;
  498. }
  499. .searchItem{
  500. height: 40px;
  501. line-height: 40px;
  502. padding: 0 20px;
  503. cursor: pointer;
  504. overflow: hidden;
  505. white-space: nowrap;
  506. text-overflow: ellipsis;
  507. }
  508. .searchItem:hover{
  509. background-color: #F5F7FA;
  510. }
  511. .selectFiled{
  512. position: relative;
  513. }
  514. .orderBox{
  515. position: absolute;
  516. left: -50px;
  517. top: 50%;
  518. width: 50px;
  519. height: 84px;
  520. margin-top: -42px;
  521. }
  522. .selectFiledBox{
  523. position: relative;
  524. min-height: 120px;
  525. }
  526. .order{
  527. display: inline-block;
  528. width: 30px;
  529. height: 30px;
  530. font-size: 30px;
  531. margin-left: 5px;
  532. border: 1px solid #dcdfe6;
  533. cursor: pointer;
  534. }
  535. .firstItem{
  536. margin-left: 28px;
  537. }
  538. .delUnit,.delFiled{
  539. position: absolute;
  540. top: -8px;
  541. right: -6px;
  542. cursor: pointer;
  543. }
  544. .delFiled{
  545. top: -7px;
  546. right: -9px;
  547. }
  548. .filedName{
  549. position: relative;
  550. border: 1px solid #dcdfe6;
  551. border-radius: 4px;
  552. padding: 5px 10px;
  553. display: inline-block;
  554. line-height: 20px;
  555. }
  556. .activeFiledName{
  557. border: 1px solid #48C5D7;
  558. }
  559. </style>