AddQualityControlTemp.vue 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563
  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.moduleName){
  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(moduleDetail.length === 0){
  338. this.warning('请添加模块内容')
  339. return
  340. }
  341. let param = {
  342. name: tempName,
  343. modeId: moduleName,
  344. hospitalId: hospital,
  345. moduleDetail: moduleDetail,
  346. remark:'',
  347. recordModuleId:moduleType
  348. }
  349. if(this.isEdit){
  350. param = Object.assign({}, param, {id: this.id})
  351. }
  352. if(this.id && !this.isCopy){//修改
  353. this.saveDisable = true //提交保存按钮不可点击,返回结果时才可点击,防止频繁发送请求
  354. api.saveOrUpdateQCTemp(param).then((res)=>{
  355. if(res.data.code==0){
  356. this.$message({
  357. message:"修改成功",
  358. type:'success'
  359. });
  360. //返回带搜索条件的首页
  361. this.$router.push({
  362. name: 'QualityControlTemp',
  363. params: Object.assign({}, this.$route.params, {currentPage: 1})
  364. });
  365. }else{
  366. this.$message({
  367. message:res.data.msg,
  368. type:'warning'
  369. });
  370. }
  371. this.saveDisable = false
  372. })
  373. }else{//添加
  374. this.saveDisable = true; //提交保存按钮不可点击,返回结果时才可点击,防止频繁发送请求
  375. api.saveOrUpdateQCTemp(param).then((res)=>{
  376. if(res.data.code==0){
  377. this.$message({
  378. message:"添加成功",
  379. type:'success'
  380. })
  381. this.$router.push({name: 'QualityControlTemp'});
  382. }else{
  383. this.$message({
  384. message:res.data.msg,
  385. type:'warning'
  386. });
  387. }
  388. this.saveDisable = false
  389. })
  390. }
  391. } else {
  392. return false;
  393. }
  394. });
  395. },
  396. warning(msg, type,time) {
  397. this.$message({
  398. showClose: true,
  399. message: msg,
  400. type: type || 'warning',
  401. duration:time || '3000'
  402. })
  403. },
  404. }
  405. }
  406. </script>
  407. <style lang="less" scoped>
  408. .contentWrapper{
  409. padding: 50px 20px 0;
  410. }
  411. .content{
  412. background: #fff;
  413. }
  414. .formItem{
  415. /deep/.el-form-item__label{
  416. width: 150px;
  417. }
  418. }
  419. /deep/.el-form-item__content{
  420. display: inline-block;
  421. }
  422. /deep/.el-input__inner {
  423. height: 30px;
  424. line-height: 30px;
  425. width: 200px;
  426. }
  427. /deep/.widthLarge .el-input__inner {
  428. width: 350px;
  429. }
  430. /deep/.addCon .el-form-item__label:before {
  431. content: '*';
  432. color: #f56c6c;
  433. margin-right: 4px;
  434. }
  435. .formExam{
  436. /deep/.el-form-item__content{
  437. width: calc(100% - 185px);
  438. }
  439. }
  440. .exampleTxt{
  441. display: inline-block;
  442. position: relative;
  443. width: 100%;
  444. max-height: 200px;
  445. padding: 0 20px 0 0;
  446. height: 100%;
  447. word-break: break-all;
  448. overflow-y: auto;
  449. }
  450. .moduleInfoItem{
  451. width: 500px;
  452. min-height: 200px;
  453. padding: 0 50px 0 50px;
  454. border: 1px solid #dcdfe6;
  455. border-radius: 5px;
  456. margin-bottom: 20px;
  457. position: relative;
  458. }
  459. .addUnit{
  460. display: inline-block;
  461. border: 1px solid #dcdfe6;
  462. border-radius: 5px;
  463. width: 80px;
  464. text-align: center;
  465. height: 20px;
  466. line-height: 20px;
  467. cursor: pointer;
  468. }
  469. .searchBox{
  470. width: 200px;
  471. position: relative;
  472. }
  473. .searchResultBox{
  474. position: absolute;
  475. width: 200px;
  476. box-sizing: border-box;
  477. max-height: 200px;
  478. overflow-y: auto;
  479. background: #fff;
  480. z-index: 2;
  481. border: 1px solid #48c5d7;
  482. }
  483. .searchItem{
  484. height: 40px;
  485. line-height: 40px;
  486. padding: 0 20px;
  487. cursor: pointer;
  488. overflow: hidden;
  489. white-space: nowrap;
  490. text-overflow: ellipsis;
  491. }
  492. .searchItem:hover{
  493. background-color: #F5F7FA;
  494. }
  495. .selectFiled{
  496. position: relative;
  497. }
  498. .orderBox{
  499. position: absolute;
  500. left: -50px;
  501. top: 50%;
  502. width: 50px;
  503. height: 84px;
  504. margin-top: -42px;
  505. }
  506. .selectFiledBox{
  507. position: relative;
  508. min-height: 120px;
  509. }
  510. .order{
  511. display: inline-block;
  512. width: 30px;
  513. height: 30px;
  514. font-size: 30px;
  515. margin-left: 5px;
  516. border: 1px solid #dcdfe6;
  517. cursor: pointer;
  518. }
  519. .firstItem{
  520. margin-left: 28px;
  521. }
  522. .delUnit,.delFiled{
  523. position: absolute;
  524. top: -8px;
  525. right: -6px;
  526. cursor: pointer;
  527. }
  528. .delFiled{
  529. top: -7px;
  530. right: -9px;
  531. }
  532. .filedName{
  533. position: relative;
  534. border: 1px solid #dcdfe6;
  535. border-radius: 4px;
  536. padding: 5px 10px;
  537. display: inline-block;
  538. line-height: 20px;
  539. }
  540. .activeFiledName{
  541. border: 1px solid #48C5D7;
  542. }
  543. </style>