AddDiagBase.vue 49 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154
  1. <!-- 添加常见科室症状 -->
  2. <template>
  3. <div class="AddDiagBaseWrapper" @click="close">
  4. <crumbs
  5. :title="'诊断依据数据维护-'+titleText"
  6. class="topBack"
  7. :param="$route.params"
  8. linkTo="DiagBase"
  9. ></crumbs>
  10. <el-form ref="ruleForm" class="addDepartForm">
  11. <el-form-item class="addDiagName" label="选择添加疾病名称:" >
  12. <input class="searchInput" @focus="focuInput" type="text" v-model = "searchDiagVal">
  13. <span class="searchName" @click="searchDiag">搜索</span>
  14. <ul v-if="showDiagList&&diagList.length > 0" class="itemList diagList" ref="diagList">
  15. <li
  16. v-for="item in diagList"
  17. class="diagItem ellipsis"
  18. :title="item.name"
  19. @click="selectDiag(item)"
  20. :key="item.conceptId">
  21. {{item.name}}
  22. </li>
  23. </ul>
  24. </el-form-item>
  25. <el-form-item class="isRequired" label="已选添加疾病名称:" :class="{colorRed: !disNameExist}">
  26. {{disName}}
  27. </el-form-item>
  28. </el-form>
  29. <div class="symptomList">
  30. <p class="moduleTitle">疾病特征:</p>
  31. <p class="inpTips">序号输入规则“序号+.”后可输入的范围0~99;标准词只能有一个词;化验类型关联只能出现一个词,其他类型可以输入多个词;化验类型可输入结果列,其他类型不可输入</p>
  32. <table class="diagTable">
  33. <tr class="tableTitle">
  34. <td class="FeatureSort">排序</td>
  35. <td class="FeatureType require">类型</td>
  36. <td class="FeatureNumber require">序号</td>
  37. <td class="FeatureStand require">标准词</td>
  38. <td class="FeatureRelate">关联词</td>
  39. <td class="FeatureuniqueName">化验公表项</td>
  40. <td class="FeatureResult">结果</td>
  41. <td class="FeatureOpera"></td>
  42. </tr>
  43. <tr v-for="(item, index) in disFeatureList" :key="item.index">
  44. <td class="FeatureSort" >{{index+1}}</td>
  45. <td class="FeatureType" >
  46. <el-select size="mini" :class="{selectType: item.typeNull}" v-model.trim="item.type" placeholder="标签类型" @change="clickItem(index,'FeatureType')" clearable>
  47. <el-option v-for="item in featureTypeList" :label="item.name" :value="item.key" :key="item.key"></el-option>
  48. </el-select>
  49. </td>
  50. <td class="FeatureNumber" >
  51. <el-tooltip :disabled="!item.verifyCode&&!item.codeNull&&!item.codeError" class="item" effect="dark" :content="item.verifyCode||item.codeNull||item.codeError" placement="top">
  52. <el-input class="groupTextarea"
  53. type="textarea"
  54. :autosize="{ minRows: 1}"
  55. :class="{borderRed:item.verifyCode||item.codeNull, colorRed: item.codeError}"
  56. :title="item.code"
  57. v-model.trim="item.code"
  58. @input="handleInp(index,$event,'FeatureNumber')"
  59. @focus="clickItem(index,'FeatureNumber')">
  60. </el-input>
  61. </el-tooltip>
  62. </td>
  63. <td class="FeatureStand" >
  64. <el-tooltip :disabled="!item.verifyStandard&&!item.standardNull" class="item" effect="dark" :content="item.verifyStandard||item.standardNull" placement="top">
  65. <el-input class="groupTextarea"
  66. type="textarea"
  67. :autosize="{ minRows: 1}"
  68. :class="{borderRed:item.verifyStandard||item.standardNull}"
  69. :title="item.standard"
  70. v-model.trim="item.standard"
  71. @input="handleInp(index,$event,'FeatureStand')"
  72. @focus="clickItem(index,'FeatureStand')">
  73. </el-input>
  74. </el-tooltip>
  75. </td>
  76. <td class="FeatureRelate">
  77. <el-tooltip :disabled="!item.verifyRelation&&!item.relationNull" class="item" effect="dark" :content="item.verifyRelation||item.relationNull" placement="top">
  78. <el-input class="groupTextarea"
  79. type="textarea"
  80. :autosize="{ minRows: 1}"
  81. :class="{borderRed:item.verifyRelation|| item.relationNull}"
  82. :title="item.relation"
  83. v-model.trim="item.relation"
  84. @input="handleInp(index,$event,'FeatureRelate',item.type)"
  85. @focus="clickItem(index,'FeatureRelate')">
  86. </el-input>
  87. </el-tooltip>
  88. </td>
  89. <td class="FeatureuniqueName">
  90. <el-tooltip :disabled="!item.verifyUnique" class="item" effect="dark" :content="item.verifyUnique" placement="top">
  91. <el-input class="groupTextarea inpDisabled"
  92. type="textarea"
  93. :readonly = true
  94. :autosize="{ minRows: 1}"
  95. :class="{borderRed:item.uniqueName===null ||item.verifyUnique}"
  96. :title="item.uniqueName"
  97. v-model.trim="item.uniqueName"
  98. >
  99. </el-input>
  100. </el-tooltip>
  101. <!-- <div>{{item.uniqueName}}</div> -->
  102. </td>
  103. <td class="FeatureResult">
  104. <el-tooltip :disabled="!item.verifyResult" class="item" effect="dark" :content="item.verifyResult" placement="top">
  105. <el-input class="groupTextarea"
  106. type="textarea"
  107. :autosize="{ minRows: 1}"
  108. :readonly="item.type!=3"
  109. :class="{borderRed:item.verifyResult, inpDisabled:item.type!=3}"
  110. :title="item.midResult"
  111. v-model.trim="item.midResult"
  112. @input="handleInp(index,$event,'FeatureResult')"
  113. @focus="clickItem(index,'FeatureResult')">
  114. </el-input>
  115. </el-tooltip>
  116. </td>
  117. <td class="FeatureOpera">
  118. <el-button type="text" size="small" class="delete" @click="addItem(index, 1)"><div class="btnOpera">+</div></el-button>
  119. <el-button v-if="index !=0" type="text" size="small" class="delete" @click="delItem(index, 1)"><div class="btnOpera">-</div></el-button>
  120. </td>
  121. </tr>
  122. </table>
  123. <p class="moduleTitle">诊断公式:</p>
  124. <p class="inpTips">可输入数字(0~9);可输入规定汉字:任、一、二、三、四、五、六、七、八、九、十,其余汉字不可输入;可输入的符号:“.”、“/”、“()” “+”;确诊还可输入“拟、诊”二字;鉴别诊断的序号不可输入公式中,数据放入后该条件无效;</p>
  125. <table class="diagTable">
  126. <tr class="tableTitle">
  127. <td class="FormulaSort">排序</td>
  128. <td class="FormulaType">类型</td>
  129. <td class="FormulaNumber">公式</td>
  130. <td class="FormulaOpera"></td>
  131. </tr>
  132. <tr v-for="(item, index) in disFormulaList" :key="item.index">
  133. <td class="FormulaSort">{{index +1}}</td>
  134. <td class="FormulaType">
  135. <el-select size="mini" :class="{selectType: item.verifyType}" v-model.trim="item.type" placeholder="标签类型" @change="clickItem(index,'FormulaType')" clearable>
  136. <el-option v-for="item in formulaTypeList" :label="item.name" :value="item.key" :key="item.key"></el-option>
  137. </el-select>
  138. </td>
  139. <td class="FormulaNumber">
  140. <el-tooltip :disabled="!item.verifyFormula" class="item" effect="dark" :content="item.verifyFormula" placement="top">
  141. <el-input class="groupTextarea"
  142. type="textarea"
  143. :readonly="!item.type"
  144. :autosize="{ minRows: 1}"
  145. :class="{borderRed:item.verifyFormula,inpDisabled:!item.type}"
  146. :title="item.formula"
  147. v-model.trim="item.formula"
  148. @input="handleInp(index,$event,'FormulaNumber',item.type)"
  149. @focus="clickItem(index,'FormulaNumber')">
  150. </el-input>
  151. </el-tooltip>
  152. </td>
  153. <td class="FeatureOpera">
  154. <el-button type="text" size="small" class="delete" @click="addItem(index, 2)"><div class="btnOpera">+</div></el-button>
  155. <el-button v-if="index !=0" type="text" size="small" class="delete" @click="delItem(index, 2)"><div class="btnOpera">-</div></el-button>
  156. </td>
  157. <!-- <td class="selectedContent ">{{item.indexUnique}}</td>
  158. <td class="selectedContentGroup"><input class="groupInput" type="text" v-model="item.indexDesc" @input="handleInp(index,$event)"></td>
  159. <td class="selectedContentOpera"><el-button type="text" size="small" class="delete" @click="delSelectedIndex(item, index)">删除</el-button></td> -->
  160. </tr>
  161. </table>
  162. <div class="btn clearfix">
  163. <div class="btnBox">
  164. <!-- <el-button size="mini" @click="uploadClick">导入</el-button>
  165. <input type="file" name="uploadfile " id="upFile" @change="uploadFile($event)" accept=".csv, application/vnd.ms-excel, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet">
  166. -->
  167. <el-button
  168. type="primary"
  169. :disabled = "isReady"
  170. @click="submitForm('save')"
  171. >校验并保存数据</el-button>
  172. <el-button
  173. type="primary"
  174. :disabled = "hasQuestion == 1"
  175. @click="exportDiagnosticAll"
  176. >导出诊断依据</el-button>
  177. <el-button
  178. type="primary"
  179. :disabled = "hasQuestion == 1"
  180. @click="updateNeo"
  181. >更新图谱</el-button>
  182. </div>
  183. </div>
  184. </div>
  185. </div>
  186. </template>
  187. <script>
  188. import api from '@api/diagBase.js';
  189. import utils from '@api/utils.js';
  190. import apis from '@api/icss.js';
  191. export default {
  192. name: 'AddChronicAndIndexRelation',
  193. data() {
  194. return{
  195. id: '', //诊断id
  196. disName:'', //诊断名称
  197. modifier: '', //操作人
  198. titleText: '添加',
  199. diagList: [],
  200. featureTypeList: [],
  201. formulaTypeList: [],
  202. disFeatureList: [
  203. {
  204. type:'',
  205. code:'',
  206. standard:'',
  207. relation:'',
  208. midResult:'',
  209. formula:'',
  210. result:'',
  211. uniqueName:''
  212. }
  213. ], //疾病特征列表
  214. disFeatureListResult:[], //疾病特征列表(保存用)
  215. disFormulaList:[
  216. {
  217. type:'',
  218. code:'',
  219. standard:'',
  220. relation:'',
  221. midResult:'',
  222. result:'',
  223. formula:'',
  224. uniqueName:''
  225. }
  226. ],
  227. disFormulaListResult:[], //诊断公式列表(保存用)
  228. searchDiagVal: '',
  229. isEdit: false,
  230. saveDisable: false ,
  231. hasQuestion: 1, //是否有问题词
  232. disNameExist: true, //诊断名称是否存在
  233. hasNoUniqueName: false, //是否存在没有公表项的化验
  234. isReady:false,
  235. showDiagList: false
  236. }
  237. },
  238. created(){
  239. const userLoginDTO = JSON.parse(localStorage.getItem('userLoginDTO'))
  240. this.modifier = userLoginDTO && userLoginDTO.linkman
  241. this.getDropList()
  242. const { isEdit, data } = this.$route.params;
  243. if(isEdit) {
  244. if(isEdit) {
  245. this.isEdit = isEdit;
  246. this.titleText = '修改';
  247. this.disName = data.disName
  248. this.id = data.id
  249. this.disNameExist = data.disNameExist
  250. if(data.disFeature.length) {
  251. this.disFeatureList = data.disFeature
  252. }
  253. if(data.disformula.length) {
  254. this.disFormulaList = data.disformula
  255. }
  256. this.hasQuestion = data.hasQuestion
  257. }
  258. } else {
  259. }
  260. },
  261. watch: {
  262. // searchTagVal(newVal, preVal) {
  263. // if(newVal.trim() == ''){
  264. // this.getTagList()
  265. // }else if(newVal.trim() != preVal.trim()){
  266. // this.getTagList()
  267. // }
  268. // }
  269. },
  270. methods: {
  271. getDropList() {
  272. return apis.getKnowledgeEnums().then((res) =>{
  273. if(res.data.code === '0') {
  274. this.featureTypeList = res.data.data.diagnoseFeatureTypeEnum.filter(item => item.key != 0)
  275. this.formulaTypeList = res.data.data.diagnoseTypeEnum
  276. }
  277. })
  278. },
  279. close() {
  280. this.diagList = [];
  281. },
  282. back(){
  283. this.$router.go(-1);
  284. },
  285. searchDiag() {
  286. if(!this.searchDiagVal) {
  287. return
  288. }
  289. const param = {
  290. "name": this.searchDiagVal,
  291. }
  292. api.diagBaseIndex(param).then((res)=>{
  293. if(res.data.code === '0') {
  294. this.diagList = res.data.data
  295. this.showDiagList = true
  296. }
  297. })
  298. },
  299. selectDiag(item) {
  300. this.disName = item.name
  301. this.searchDiagVal = ''
  302. this.diagList=[]
  303. },
  304. focuInput() {
  305. this.showDiagList = false
  306. },
  307. addItem(index, type) {
  308. if(type == 1) {
  309. const item = {
  310. type:'',
  311. code:'',
  312. standard:'',
  313. relation:'',
  314. midResult:'',
  315. result:'',
  316. uniqueName:''
  317. }
  318. this.disFeatureList.splice(index+1, 0, item)
  319. }else if(type == 2) {
  320. const item = {
  321. type:'',
  322. code:'',
  323. standard:'',
  324. relation:'',
  325. midResult:'',
  326. result:'',
  327. uniqueName:''
  328. }
  329. this.disFormulaList.splice(index+1, 0, item)
  330. }
  331. },
  332. delItem(index, type) {
  333. if(type == 1) {
  334. this.disFeatureList.splice(index, 1)
  335. }else if(type == 2) {
  336. this.disFormulaList.splice(index, 1)
  337. }
  338. },
  339. //导入
  340. // uploadClick() {
  341. // let inp = document.getElementById("upFile");
  342. // inp.click();
  343. // },
  344. // uploadFile(e){
  345. // let fileInfo = e.target.files[0];
  346. // e.preventDefault();
  347. // let formData = new FormData();
  348. // formData.append('uploadfile', fileInfo);
  349. // const header = {
  350. // headers:{
  351. // 'Content-Type': 'multipart/form-data'
  352. // }
  353. // }
  354. // api.importDiagnosticBasis(formData,header).then((res)=>{
  355. //
  356. // if(res.data.code==0){
  357. // const data = res.data.data
  358. // this.warning('上传成功','success')
  359. // let feature = data.feature
  360. // let equation = data.equation
  361. // const featureList = []
  362. // const formulaList = []
  363. // if(feature&&feature.length > 0) {
  364. // for(let i = 1; i <feature.length; i++) {
  365. // const item = {}
  366. // item.type = '';
  367. // for (let j = 0; j < this.featureTypeList.length; j++) {
  368. // if(feature[i].type.indexOf(this.featureTypeList[j].name) > -1) {
  369. // item.type = this.featureTypeList[j].key
  370. // break;
  371. // }
  372. // }
  373. // item.code = feature[i].code
  374. // item.standard = feature[i].standard
  375. // item.relation = feature[i].associated
  376. // if(item.type === 4) {
  377. // item.midResult = ''
  378. // } else {
  379. // item.midResult = feature[i].midResult
  380. // }
  381. // featureList.push(item)
  382. // }
  383. // }
  384. // if(equation&&equation.length > 0) {
  385. // for(let i = 1; i <equation.length; i++) {
  386. // const item = {}
  387. // item.type = '';
  388. // for (let j = 0; j < this.formulaTypeList.length; j++) {
  389. // if(equation[i].type.indexOf(this.formulaTypeList[j].name) > -1) {
  390. // item.type = this.formulaTypeList[j].key
  391. // break;
  392. // }
  393. // }
  394. // item.formula = equation[i].associated
  395. // formulaList.push(item)
  396. // }
  397. // }
  398. // this.disFeatureList = featureList
  399. // this.disFormulaList = formulaList
  400. //
  401. // }else{
  402. // /*this.$message({
  403. // dangerouslyUseHTMLString: true,
  404. // message:res.data.msg,
  405. // type:'warning'
  406. // });*/
  407. // this.$alert(res.data.msg,'错误信息',{
  408. // dangerouslyUseHTMLString: true,
  409. // confirmButtonText: '确定',
  410. // callback: action => {
  411. // /*this.$message({
  412. // type: 'info',
  413. // message: `action: ${ action }`
  414. // });*/
  415. // }
  416. // });
  417. // }
  418. // })
  419. // //解决上传相同文件不触发change
  420. // let inp = document.getElementById("upFile");
  421. // inp.value = "";
  422. // },
  423. updateNeo() {
  424. this.submitForm('updateNeo').then(() => {
  425. if(this.hasQuestion == 0) {
  426. const param = {
  427. id: this.id,
  428. modifier: this.modifier
  429. }
  430. api.diagBaseUpdateNeo(param).then((res) => {
  431. if(res.data.code == 0) {
  432. this.warning('更新成功', 'success');
  433. } else {
  434. this.warning(res.data.msg)
  435. }
  436. })
  437. } else {
  438. this.warning('更新失败');
  439. }
  440. })
  441. // api.diagBaseUpdateNeo(param).then((res) =>{
  442. // })
  443. },
  444. exportDiagnosticAll(){
  445. this.submitForm('export').then(() => {
  446. if(this.hasQuestion == 0) {
  447. const param = {
  448. diagnoseId: this.id
  449. }
  450. api.exportDiagnosticAll(param).then((res) => {
  451. utils.downloadExportedData(res.data,'诊断依据.xls');
  452. })
  453. }else {
  454. this.warning('导出失败');
  455. }
  456. })
  457. },
  458. submitForm(type) {
  459. if(!this.disName) {
  460. this.warning('请选择诊断');
  461. return
  462. }
  463. this.disFeatureListResult = []
  464. this.disFormulaListResult = []
  465. for(let i = 0; i < this.disFeatureList.length; i++) { //如果有任意一项有值,就检测,所有项都没值,则删掉这条数据
  466. if(this.disFeatureList[i].type || this.disFeatureList[i].code || this.disFeatureList[i].standard || this.disFeatureList[i].relation || this.disFeatureList[i].midResult) {
  467. this.disFeatureListResult.push(this.disFeatureList[i])
  468. }
  469. }
  470. let disFeatureList;
  471. if(this.disFeatureListResult.length) {
  472. disFeatureList = this.disFeatureListResult;
  473. } else {
  474. disFeatureList = [
  475. {
  476. type:'',
  477. code:'',
  478. standard:'',
  479. relation:'',
  480. midResult:'',
  481. result:'',
  482. formula:'',
  483. uniqueName:''
  484. }
  485. ];
  486. }
  487. this.disFeatureList = disFeatureList
  488. // this.showDelDialog()
  489. return this.diagBaseVerifyData(type)
  490. },
  491. diagBaseVerifyData(type) {
  492. //判断诊断依据先判断化验有没有公表项
  493. const labArr= []
  494. for (let i = 0; i < this.disFeatureList.length; i++) {
  495. if(+this.disFeatureList[i].type === 3) {
  496. labArr.push({index: i, mealName: this.disFeatureList[i].standard, itemName: this.disFeatureList[i].relation, uniqueName:''})
  497. }
  498. }
  499. const loading = this.$loading({
  500. lock: true,
  501. text: 'Loading',
  502. spinner: 'el-icon-loading',
  503. background: 'rgba(0, 0, 0, 0.7)'
  504. });
  505. if(type == 'save'){
  506. this.isReady = true
  507. }
  508. if(labArr.length > 0) {
  509. this.labVerifyData(labArr, loading,type).then(() =>{
  510. if(this.hasNoUniqueName) {
  511. loading.close()
  512. return
  513. }else {
  514. this.verifyDiagBase(loading,type)
  515. }
  516. })
  517. } else {
  518. this.verifyDiagBase(loading,type)
  519. }
  520. },
  521. errorDataVerify(loading) {
  522. for(let i = 0; i < this.disFormulaList.length; i++) { //如果有任意一项有值,就检测,所有项都没值,则删掉这条数据
  523. if(this.disFormulaList[i].type || this.disFormulaList[i].formula ) {
  524. this.disFormulaListResult.push(this.disFormulaList[i])
  525. }
  526. }
  527. const disFeatureList = this.disFeatureList;
  528. const disFormulaList = this.disFormulaListResult;
  529. let codeErrorNum = 0;
  530. let errStrList = [];
  531. //必填项是否填写
  532. for(let i=0; i < disFeatureList.length; i++) {
  533. if(!disFeatureList[i].type) {
  534. disFeatureList[i].typeNull = "未选择类型"
  535. }
  536. if(!disFeatureList[i].code) {
  537. disFeatureList[i].codeNull = "未填写编码"
  538. }
  539. if(!disFeatureList[i].standard) {
  540. disFeatureList[i].standardNull = "未填写标准词"
  541. }
  542. if(!disFeatureList[i].type||!disFeatureList[i].code||!disFeatureList[i].standard) {
  543. const errStr = "第" + (i+ 1) +"行必填项未填写"
  544. errStrList.push(errStr)
  545. }
  546. let regex =new RegExp(`^${disFeatureList[i].type}\\.(0|[1-9]\\d?)$`,)
  547. if(disFeatureList[i].code &&!regex.test(disFeatureList[i].code)) { //序号和类型不匹配
  548. codeErrorNum++
  549. disFeatureList[i].codeError = "序号和类型不匹配"
  550. const errStr = "疾病特征第" + (i+ 1) +"行序号和类型不匹配"
  551. errStrList.push(errStr)
  552. } else { //序号和类型匹配但序号重复
  553. let codeArr = disFeatureList.filter(item => item.code ===disFeatureList[i].code)
  554. if(codeArr.length > 1) {
  555. codeErrorNum++
  556. disFeatureList[i].codeError = "序号重复"
  557. const errStr = "疾病特征第" + (i+ 1) +"行序号重复"
  558. errStrList.push(errStr)
  559. }
  560. }
  561. //化验项有结果则必须有关联词
  562. if(disFeatureList[i].type == '3' && disFeatureList[i].midResult && !disFeatureList[i].relation) {
  563. disFeatureList[i].relationNull = "未填写关联词"
  564. const errStr = "第" + (i+ 1) +"行化验项数据填写不完整"
  565. errStrList.push(errStr)
  566. }
  567. //导入后判断
  568. // let regexPause = new RegExp(`、`) //判断标准词是否有顿号
  569. // if(disFeatureList[i].standard &&regexPause.test(disFeatureList[i].standard)) {
  570. // disFeatureList[i].verifyStandard ='数据异常'
  571. // const errStr = "疾病特征第" + (i+ 1) +"行标准词数据异常"
  572. // errStrList.push(errStr)
  573. // }
  574. // if(disFeatureList[i].type == '3'&&regexPause.test(disFeatureList[i].relation)) {
  575. // disFeatureList[i].verifyRelation ='数据异常'
  576. // const errStr = "疾病特征第" + (i+ 1) +"行化验关联词数据异常"
  577. // errStrList.push(errStr)
  578. // }
  579. //导入后判断
  580. if(disFeatureList[i].type == '3' && !disFeatureList[i].midResult ) { //化验项下面诊断公式如果有用到,判断是否填写结果项
  581. const regex2 = new RegExp(`(?<=\\D|\\s?)${disFeatureList[i].code.replace('.','\\.')}(?=\\D|\\s?)`)
  582. // const regex2 = new RegExp(`、\\s*、{1,}`)
  583. // const regex2 = new RegExp(`([^0-9]|\\s{0,1})${disFeatureList[i].code}([^0-9]|\\s{0,1})`)
  584. let hasError = disFormulaList.find(item => {return regex2.test(item.formula)})
  585. if(hasError) {
  586. if(!disFeatureList[i].relation) {
  587. disFeatureList[i].verifyRelation = "数据异常"
  588. }
  589. disFeatureList[i].verifyResult = "数据异常"
  590. const errStr = "第" + (i+ 1) +"行化验项数据异常"
  591. errStrList.push(errStr)
  592. }
  593. }
  594. if(disFeatureList[i].type == '4' && !disFeatureList[i].relation ) { //辅检项下面诊断公式如果有用到,判断是否填写结果项(辅检结果是填在关联词列)
  595. const regex2 = new RegExp(`(?<=\\D|\\s?)${disFeatureList[i].code.replace('.','\\.')}(?=\\D|\\s?)`)
  596. let hasError = disFormulaList.find(item => {return regex2.test(item.formula)})
  597. if(hasError) {
  598. disFeatureList[i].verifyRelation = "数据异常"
  599. const errStr = "第" + (i+ 1) +"行辅捡项数据异常"
  600. errStrList.push(errStr)
  601. }
  602. }
  603. let regex1 =new RegExp(`、\\s*、{1,}|^、|、$`)
  604. if(disFeatureList[i].relation &&regex1.test(disFeatureList[i].relation)) { //不能输入连续的、,前后也不能是、
  605. disFeatureList[i].verifyRelation ='数据异常'
  606. const errStr = "疾病特征第" + (i+ 1) +"行数据异常"
  607. errStrList.push(errStr)
  608. }
  609. if(disFeatureList[i].midResult &&regex1.test(disFeatureList[i].midResult)) {
  610. disFeatureList[i].verifyResult ='数据异常'
  611. const errStr = "疾病特征第" + (i+ 1) +"行数据异常"
  612. errStrList.push(errStr)
  613. }
  614. }
  615. this.disFeatureList = JSON.parse(JSON.stringify(disFeatureList))
  616. let formulaListErrNum = 0
  617. for(let i=0; i < disFormulaList.length; i++) {
  618. if(disFormulaList[i].type&&!disFormulaList[i].formula ) {
  619. disFormulaList[i].verifyFormula = "诊断公式不能为空"
  620. formulaListErrNum++;
  621. const errStr = "诊断公式第" + (i+ 1) +"行诊断公式不能为空"
  622. errStrList.push(errStr)
  623. } else if(disFormulaList[i].formula&&!disFormulaList[i].type) {
  624. disFormulaList[i].verifyType = "诊断类型不能为空"
  625. const errStr = "诊断公式第" + (i+ 1) +"行诊断类型不能为空"
  626. errStrList.push(errStr)
  627. formulaListErrNum++;
  628. }
  629. //导入后判断
  630. // if(disFormulaList[i].type == 91) { //确诊中有没有包含其他不可输入内容
  631. // let regexDisFormula = /[^\u4EFB\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u62df\u8bca0-9\/\.+\(\)\(\)]/g
  632. // if(regexDisFormula.test(disFormulaList[i].formula)) {
  633. // disFormulaList[i].verifyFormula = "公式格式错误"
  634. // const errStr = "诊断公式第" + (i+ 1) +"行公式格式错误,"
  635. // errStrList.push(errStr)
  636. // formulaListErrNum++;
  637. // }
  638. // } else { //其他诊断中有没有包含其他不可输入内容
  639. // //计算公式只能输入以下内容: 任、一、二、三、四、五、六、七、八、九、十、0-9、/、.、(、)、(、)
  640. // let regexDisFormula = /[^\u4EFB\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u53410-9\/\.+\(\)\(\)]/g
  641. // if(regexDisFormula.test(disFormulaList[i].formula)) {
  642. // disFormulaList[i].verifyFormula = "公式格式错误"
  643. // const errStr = "诊断公式第" + (i+ 1) +"行公式格式错误"
  644. // errStrList.push(errStr)
  645. // formulaListErrNum++;
  646. // }
  647. // }
  648. //导入后判断
  649. if(disFormulaList[i].type == 91 && disFormulaList[i].formula.indexOf("拟诊") > -1) { //确诊项如果有拟诊这两个字,判断公式列表中有没有拟诊这项
  650. const noError = disFormulaList.filter(item => item.type == 92).length > 0
  651. if(!noError) {
  652. disFormulaList[i].verifyFormula = "公式格式错误"
  653. const errStr = "诊断公式第" + (i+ 1) +"行公式格式错误"
  654. errStrList.push(errStr)
  655. formulaListErrNum++;
  656. }
  657. }
  658. }
  659. if(disFormulaList.length) {
  660. this.disFormulaList = JSON.parse(JSON.stringify(disFormulaList))
  661. }
  662. let errorStr =''
  663. for(let i = 0; i <errStrList.length; i++) {
  664. errorStr += '<p>'+errStrList[i]+'</p>'
  665. }
  666. if(errStrList.length >0 ||codeErrorNum > 0 ||formulaListErrNum > 0) {
  667. this.disFeatureList = JSON.parse(JSON.stringify(disFeatureList))
  668. this.errorTips(errorStr)
  669. loading.close()
  670. return false
  671. }
  672. return true
  673. },
  674. labVerifyData(labArr, loading,type) {
  675. const labArrParam = {
  676. lisMappingSearchList : labArr
  677. }
  678. return api.getUniqueNameWithList(labArrParam).then((res) => {
  679. this.isReady=false
  680. if(res.data.code === '0') {
  681. const data = res.data.data
  682. let errorStr = ''
  683. for (let i = 0; i < data.length; i++ ) {
  684. if(!data[i].uniqueName) { //判断是否存在公表项
  685. if(!this.hasNoUniqueName) {
  686. this.hasNoUniqueName = true
  687. }
  688. errorStr +=`<p>第${+data[i].index+1}行化验公表项不存在</p>`
  689. this.disFeatureListResult[data[i].index].verifyUnique="公表项不存在"
  690. } else {
  691. this.disFeatureListResult[data[i].index].verifyUnique=""
  692. }
  693. this.disFeatureListResult[data[i].index].uniqueName = data[i].uniqueName
  694. if(data[i].uniqueName) { //有公表项和结果,则将公表项和结果拼接起来,结果用、分隔
  695. if(this.disFeatureListResult[data[i].index].midResult) {
  696. let midResult = this.disFeatureListResult[data[i].index].midResult.replace(' ', '').split('、')
  697. for (let j = 0; j < midResult.length; j++) {
  698. if(midResult[j]) {
  699. midResult[j] = data[i].uniqueName+midResult[j]
  700. }
  701. }
  702. this.disFeatureListResult[data[i].index].result = midResult.join('、')
  703. }
  704. }
  705. }
  706. if(errorStr) {
  707. this.errorTips(errorStr)
  708. }
  709. this.disFeatureList = JSON.parse(JSON.stringify(this.disFeatureListResult))
  710. this.disFeatureListResult = JSON.parse(JSON.stringify(this.disFeatureListResult))
  711. } else {
  712. this.warning(res.msg)
  713. loading.close()
  714. return
  715. }
  716. }).catch(()=>{ this.isReady=false;loading.close()})
  717. },
  718. verifyDiagBase(loading,type) {
  719. const param = {
  720. disFeature: this.disFeatureListResult,
  721. disName: this.disName,
  722. disformula: this.disFormulaListResult,
  723. id: this.id,
  724. modifier: this.modifier
  725. }
  726. const hasErrorData = this.errorDataVerify(loading)
  727. if(!hasErrorData) {
  728. return
  729. }
  730. return api.diagBaseVerifyData(param).then((res) => {
  731. if(+res.data.code === 0) {
  732. const data = res.data.data
  733. this.isReady=false
  734. if(type =='save') {
  735. if(data.hasQuestion) {
  736. this.warning('校验完成请先调整错误数据,该数据已保存')
  737. } else {
  738. this.warning('校验成功', 'success')
  739. }
  740. }
  741. this.id = data.id
  742. this.disNameExist = data.disNameExist
  743. this.disFeatureList = data.disFeature
  744. if(data.disformula.length) {
  745. this.disFormulaList = data.disformula
  746. }else {
  747. this.disFormulaList = [
  748. {
  749. type:'',
  750. code:'',
  751. standard:'',
  752. relation:'',
  753. result:'',
  754. midResult:'',
  755. formula:'',
  756. uniqueName:''
  757. }
  758. ]
  759. }
  760. this.hasQuestion = data.hasQuestion
  761. } else {
  762. this.hasQuestion = 1
  763. this.warning(res.msg)
  764. }
  765. loading.close()
  766. }).catch(()=>{ this.hasQuestion = false; this.isReady=false; loading.close()})
  767. },
  768. showConfirmDialog(msg, resolve) {
  769. this.$alert(msg, '提示', {
  770. confirmButtonText: '确定',
  771. type: 'warning'
  772. }).then(() => {
  773. resolve();
  774. }).catch(() => {});
  775. },
  776. handleInp(index,e,type,itemType){ //分组不能输入负数
  777. const value = e;
  778. if(type === 'FeatureNumber') { //序号只能输入数字和.
  779. this.$nextTick(() => {
  780. this.disFeatureList[index].code = value.replace(/[^\d.]/g,'')
  781. })
  782. } else if(type==='FeatureStand') { //标准词不能输入顿号
  783. this.$nextTick(() => {
  784. this.disFeatureList[index].standard = value.replace(/、/g,'')
  785. })
  786. // this.disFeatureList[index].standard = value.replace(/、/g,'')
  787. } else if ( type === 'FormulaNumber') {
  788. //计算公式确诊只能输入以下内容: 任、一、二、三、四、五、六、七、八、九、十、拟、诊、0-9、/、.、(、)、(、)
  789. if(itemType == 91) {
  790. this.$nextTick(() => {
  791. this.disFormulaList[index].formula = value.replace(/[^\u4EFB\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u5341\u62df\u8bca0-9\/\.+\(\)\(\)]/g,'').replace(/[\(]/g, '(').replace(/[\)]/g, ')').replace(/' '/g, '')
  792. })
  793. } else { //计算公式其他只能输入以下内容: 任、一、二、三、四、五、六、七、八、九、十、0-9、/、.、(、)、(、)
  794. //计算公式只能输入以下内容: 任、一、二、三、四、五、六、七、八、九、十、0-9、/、.、(、)、(、)
  795. this.$nextTick(() => {
  796. this.disFormulaList[index].formula = value.replace(/[^\u4EFB\u4E00\u4E8C\u4E09\u56DB\u4E94\u516D\u4E03\u516B\u4E5D\u53410-9\/\.+\(\)\(\)]/g,'').replace(/[\(]/g, '(').replace(/[\)]/g, ')').replace(/' '/g, '')
  797. })
  798. }
  799. } else if ( type === 'FeatureRelate') {
  800. if(itemType == 3) {
  801. this.$nextTick(() => {
  802. this.disFeatureList[index].relation = value.replace(/、/g,'')
  803. })
  804. }
  805. }
  806. // const item = this.selectedIndexList[index].indexDesc;
  807. // e.target.value = value.replace(/[^\d]/g,'');
  808. // this.selectedIndexList[index].indexDesc = item.replace(/[^\d]/g,'');
  809. },
  810. clickItem(index, type) {
  811. switch(type) {
  812. case 'FeatureType':
  813. this.disFeatureList[index].typeNull = ''
  814. this.disFeatureList[index].code = ''
  815. this.disFeatureList[index].standard = ''
  816. this.disFeatureList[index].relation = ''
  817. this.disFeatureList[index].midResult = ''
  818. this.disFeatureList[index].result = ''
  819. this.disFeatureList[index].formula = ''
  820. this.disFeatureList[index].uniqueName = ''
  821. return this.disFeatureList = JSON.parse(JSON.stringify(this.disFeatureList))
  822. case 'FeatureNumber':
  823. this.disFeatureList[index].codeNull = ''
  824. this.disFeatureList[index].verifyCode = ''
  825. this.disFeatureList[index].codeError = ''
  826. return this.disFeatureList = JSON.parse(JSON.stringify(this.disFeatureList))
  827. case 'FeatureStand':
  828. this.disFeatureList[index].verifyStandard =''
  829. this.disFeatureList[index].standardNull =''
  830. return this.disFeatureList = JSON.parse(JSON.stringify(this.disFeatureList))
  831. case 'FeatureRelate':
  832. this.disFeatureList[index].verifyRelation =''
  833. return this.disFeatureList = JSON.parse(JSON.stringify(this.disFeatureList))
  834. case 'FeatureResult':
  835. this.disFeatureList[index].verifyResult =''
  836. return this.disFeatureList = JSON.parse(JSON.stringify(this.disFeatureList))
  837. case 'FeatureResult':
  838. this.disFeatureList[index].verifyResult =''
  839. return this.disFeatureList = JSON.parse(JSON.stringify(this.disFeatureList))
  840. case 'FormulaType':
  841. this.disFormulaList[index].verifyType =''
  842. this.disFormulaList[index].formula =''
  843. return this.disFormulaList = JSON.parse(JSON.stringify(this.disFormulaList))
  844. case 'FormulaNumber':
  845. this.disFormulaList[index].verifyFormula =''
  846. return this.disFormulaList = JSON.parse(JSON.stringify(this.disFormulaList))
  847. }
  848. },
  849. warning(msg, type,time) {
  850. this.$message({
  851. showClose: true,
  852. message: msg,
  853. type: type || 'warning',
  854. duration:time || '3000'
  855. })
  856. },
  857. errorTips(errorStr) {
  858. this.$alert(errorStr,'错误信息',{
  859. dangerouslyUseHTMLString: true,
  860. confirmButtonText: '确定',
  861. callback: action => {
  862. /*this.$message({
  863. type: 'info',
  864. message: `action: ${ action }`
  865. });*/
  866. }
  867. });
  868. return
  869. }
  870. }
  871. }
  872. </script>
  873. <style lang="less">
  874. @import '../../less/common.less';
  875. .AddDiagBaseWrapper {
  876. color: #606266;
  877. .topBack {
  878. top: 0;
  879. }
  880. .groupTitle {
  881. background-color: #fff;
  882. height: 40px;
  883. line-height: 40px;
  884. padding-left: 20px;
  885. }
  886. .searchInput, .searchName {
  887. display: inline-block;
  888. height: 32px;
  889. line-height: 32px;
  890. border: 1px solid #a9a9a9;
  891. margin: 0px 0 0 0;
  892. padding: 0 5px;
  893. float: left;
  894. margin-top: 4px;
  895. }
  896. .isRequired .el-form-item__label::before {
  897. content: '*';
  898. color: red;
  899. }
  900. .searchName {
  901. border-left: none;
  902. cursor: pointer;
  903. font-size: 16px;
  904. padding: 0 14px;
  905. }
  906. .itemList {
  907. position: absolute;
  908. background: #fff;
  909. width: 162px;
  910. max-height: 150px;
  911. border: 1px solid #a9a9a9;
  912. left: 138px;
  913. top: 37px;
  914. z-index: 2;
  915. overflow-y: auto;
  916. }
  917. .diagItem {
  918. padding: 0 5px;
  919. height: 30px;
  920. line-height: 30px;
  921. font-size: 14px;
  922. cursor: pointer;
  923. }
  924. .diagItem:hover {
  925. background: #f5f7fa;
  926. }
  927. .addDepartForm {
  928. position: relative;
  929. background-color: #fff;
  930. padding: 20px;
  931. margin: 70px 20px 0px 20px;
  932. }
  933. .addDiagName {
  934. position: relative;
  935. }
  936. .symptomList {
  937. position: relative;
  938. background-color: #fff;
  939. padding: 20px 20px 100px 20px;
  940. margin: 0px 20px 40px 20px;
  941. min-height: 400px;
  942. }
  943. .diagTable {
  944. width: 100%;
  945. border-collapse: collapse;
  946. margin-bottom: 20px;
  947. tr {
  948. td {
  949. border: 1px solid #a9a9a9;
  950. text-align: center;
  951. }
  952. .FormulaOpera, .FeatureOpera{
  953. background: #fff;
  954. border: none;
  955. text-align: left;
  956. padding-left: 30px;
  957. }
  958. /deep/.el-textarea__inner {
  959. width: 100%;
  960. line-height: 20px;
  961. resize:none;
  962. border: none;
  963. border-radius: 0;
  964. text-align: center;
  965. }
  966. }
  967. .selectedContent {
  968. width: 25%;
  969. }
  970. .selectedContentGroup {
  971. width: 55%;
  972. }
  973. .selectedContentOpera {
  974. width: 20%;
  975. }
  976. }
  977. .groupInput {
  978. text-align: center;
  979. color: #606266;
  980. width: 80%;
  981. }
  982. .groupTextarea {
  983. text-align: center;
  984. color: #606266;
  985. width: 100%;
  986. }
  987. .btn {
  988. position: absolute;
  989. background-color: #fff;
  990. width: 100%;
  991. margin: 20px 0;
  992. height: 40px;
  993. bottom: 0px;
  994. right: 0px;
  995. .btnBox {
  996. position: absolute;
  997. right: 0px;
  998. }
  999. .el-button {
  1000. margin-right: 20px;
  1001. }
  1002. }
  1003. .tableTitle{
  1004. background: rgba(239,243,249,1);
  1005. }
  1006. .require::after{
  1007. content:"*";
  1008. color: red;
  1009. }
  1010. .borderRed {
  1011. border: 3px solid red ;
  1012. box-sizing: border-box;
  1013. }
  1014. .colorRed {
  1015. color: red;
  1016. }
  1017. .FeatureSort {
  1018. width: 5%;
  1019. }
  1020. .FeatureType {
  1021. width: 7%;
  1022. padding: 0 5px;
  1023. }
  1024. .FeatureNumber {
  1025. width: 8%;
  1026. }
  1027. .FeatureStand {
  1028. width: 25%;
  1029. }
  1030. .FeatureRelate {
  1031. width: 25%;
  1032. }
  1033. .FeatureuniqueName {
  1034. width: 10%;
  1035. }
  1036. .FeatureResult {
  1037. width: 10%;
  1038. }
  1039. .FeatureOpera{
  1040. width: 10%;
  1041. }
  1042. .FormulaSort{
  1043. width: 5%;
  1044. }
  1045. .FormulaType{
  1046. width: 7%;
  1047. padding: 0 5px;
  1048. }
  1049. .FormulaNumber{
  1050. width: 78%;
  1051. }
  1052. .FormulaOpera{
  1053. width: 10%;
  1054. }
  1055. .btnOpera {
  1056. width:16px;
  1057. height:16px;
  1058. background:rgba(176,190,197,1);
  1059. border-radius: 50%;
  1060. color: #fff;
  1061. line-height: 16px;
  1062. text-align: center;
  1063. }
  1064. /deep/.el-input--mini .el-input__inner {
  1065. width: 80px;
  1066. }
  1067. /deep/ .is-disabled {
  1068. background: #ECECEC;
  1069. color: #AAAAAA;
  1070. border: none;
  1071. }
  1072. .selectType {
  1073. input {
  1074. border: 3px solid red;
  1075. }
  1076. input:hover {
  1077. border: 3px solid red;
  1078. }
  1079. }
  1080. .moduleTitle {
  1081. margin: 0 0 10px 0;
  1082. }
  1083. .inpDisabled{
  1084. textarea {
  1085. background: #ECECEC;
  1086. color: #AAAAAA;
  1087. border: none;
  1088. cursor: not-allowed;
  1089. height: 100%;
  1090. }
  1091. }
  1092. .inpTips {
  1093. font-size: 14px;
  1094. color: red;
  1095. margin-bottom: 10px;
  1096. }
  1097. #upFile{
  1098. display: none
  1099. }
  1100. }
  1101. </style>