AddTermSet.vue 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559
  1. <style lang="less" scoped>
  2. // @import "../../less/admin.less";
  3. #AddRuleContent {
  4. width: 100%;
  5. min-width: 1000px;
  6. padding: 20px;
  7. padding-top: 50px;
  8. padding-bottom: 0;
  9. box-sizing: border-box;
  10. .form {
  11. width: 100%;
  12. }
  13. .remark {
  14. font-size: 14px;
  15. color: #606266;
  16. position: relative;
  17. left: 34px;
  18. top: -10px;
  19. padding-right: 30px;
  20. }
  21. .left_header {
  22. display: flex;
  23. justify-content: space-between;
  24. .tips {
  25. margin-top: 15px;
  26. }
  27. .inp {
  28. width: 280px;
  29. /deep/.el-input__inner {
  30. height: 30px;
  31. margin-top: 10px;
  32. }
  33. }
  34. }
  35. .table_form {
  36. width: 100%;
  37. box-sizing: border-box;
  38. background: #fff;
  39. padding: 20px;
  40. padding-bottom: 0;
  41. display: flex;
  42. flex-wrap: wrap;
  43. }
  44. .table_content {
  45. min-height: 200px;
  46. height: calc(100vh - 264px);
  47. margin-top: 10px;
  48. display: flex;
  49. justify-content: space-between;
  50. .table_left {
  51. flex: 1;
  52. margin-right: 10px;
  53. background: #ffffff;
  54. padding: 0 50px;
  55. .left_box {
  56. margin: 30px 0;
  57. overflow: hidden;
  58. overflow-y: auto;
  59. height: calc(100vh - 410px);
  60. }
  61. .tabs {
  62. float: left;
  63. max-width: 49%;
  64. min-width: 49%;
  65. }
  66. .form_btn {
  67. display: flex;
  68. justify-content: flex-end;
  69. }
  70. }
  71. .table_right {
  72. width: 300px;
  73. background: #ffffff;
  74. }
  75. }
  76. /deep/.el-select-dropdown__item.hover,
  77. .el-select-dropdown__item:hover {
  78. color: #48c5d7;
  79. }
  80. /deep/ .el-form--inline .el-form-item__label {
  81. font-size: 14px;
  82. color: #606266;
  83. }
  84. /deep/ .el-input--mini .el-input__inner,
  85. .el-select {
  86. width: 100%;
  87. font-size: 14px;
  88. }
  89. /deep/ .el-form-item.is-success .el-input__inner,
  90. .el-form-item.is-success .el-textarea__inner {
  91. border-color: #c9c9c9 !important;
  92. }
  93. /deep/ .el-form-item.is-success .el-textarea__inner {
  94. border-color: #c9c9c9 !important;
  95. }
  96. /deep/ .el-form-item.is-success .el-textarea__inner {
  97. border-color: #c9c9c9 !important;
  98. }
  99. .conceptSearch {
  100. width: 100%;
  101. text-align: center;
  102. z-index: 2;
  103. padding: 30px;
  104. box-sizing: border-box;
  105. .conceptTitle {
  106. width: 100%;
  107. text-align: center;
  108. padding: 20px 0;
  109. }
  110. .searchText {
  111. padding: 0 35px 0 15px;
  112. width: 100%;
  113. height: 34px;
  114. border: 1px solid #c9c9c9;
  115. box-sizing: border-box;
  116. }
  117. .conceptList {
  118. min-height: 200px;
  119. max-height: 300px;
  120. margin: -2px auto 0;
  121. border: 1px solid #e1dfdf;
  122. overflow: hidden;
  123. overflow-y: auto;
  124. }
  125. .conceptItem {
  126. height: 34px;
  127. line-height: 34px;
  128. text-align: left;
  129. padding: 0 15px;
  130. cursor: pointer;
  131. }
  132. .conceptItem:hover {
  133. background: #f5f7fa;
  134. }
  135. .searchWrap {
  136. position: relative;
  137. .search {
  138. position: absolute;
  139. right: 7px;
  140. top: 8px;
  141. }
  142. }
  143. }
  144. .noresult {
  145. padding: 20px 0;
  146. color: #ccc;
  147. }
  148. }
  149. </style>
  150. <template>
  151. <div>
  152. <crumbs :title="title" :param="$route.params" linkTo="TermSet"></crumbs>
  153. <div id="AddRuleContent">
  154. <div class="table_form">
  155. <el-form
  156. size="mini"
  157. :inline="true"
  158. class="demo-form-inline form"
  159. :model="form"
  160. :rules="rules"
  161. >
  162. <el-form-item label-width="130px" label="术语集合类型:" prop="collectionLibType">
  163. <el-select
  164. v-model="form.collectionLibType"
  165. placeholder="请选择"
  166. @change="getConceptLibType"
  167. :disabled="sign==2?true:false"
  168. :title="form.collectionLibName"
  169. >
  170. <el-option
  171. v-for="item in ruleTypeList"
  172. :key="item.val"
  173. :label="item.name"
  174. :value="item.val"
  175. ></el-option>
  176. </el-select>
  177. </el-form-item>
  178. <!-- 规则术语类型: -->
  179. <el-form-item label-width="130px" label="术语集合名称:" prop="collectionLibName">
  180. <el-select
  181. clearable
  182. remote
  183. filterable
  184. v-model.trim="form.collectionLibName"
  185. placeholder="请输入"
  186. :remote-method="searchLibName"
  187. @change="getCollectionLib"
  188. :disabled="sign==2?true:false"
  189. value-key="conceptId"
  190. :title="form.collectionLibName"
  191. >
  192. <el-option
  193. v-for="item in ruleTermTypeList"
  194. :key="item.conceptId"
  195. :label="item.conceptName"
  196. :value="item.conceptName"
  197. ></el-option>
  198. </el-select>
  199. </el-form-item>
  200. </el-form>
  201. <div class="remark">说明:{{form.collectionRemark}}</div>
  202. </div>
  203. <div class="table_content" v-if="onshow">
  204. <div class="table_left">
  205. <div class="left_header">
  206. <h4 class="tips">关联的术语({{form.concepts.length}})</h4>
  207. <el-input v-model="searchtext" @input="searchList" placeholder="请搜索" class="inp"></el-input>
  208. </div>
  209. <div class="left_box">
  210. <el-table
  211. v-if="firstList.length>0"
  212. :data="firstList"
  213. border
  214. class="tabs"
  215. :header-row-style="{height:'40px'}"
  216. :header-cell-style="{height:'40px',padding:'0',background:'#f7f7f7'}"
  217. >
  218. <el-table-column prop="conceptLibName" :show-overflow-tooltip="true" label="术语名称"></el-table-column>
  219. <el-table-column label="操作" fixed="right">
  220. <template slot-scope="scope">
  221. <el-button
  222. type="text"
  223. size="small"
  224. class="delete"
  225. @click="showDelDialog(scope.row)"
  226. >移除</el-button>
  227. </template>
  228. </el-table-column>
  229. </el-table>
  230. <el-table
  231. v-if="lastList.length>0"
  232. :data="lastList"
  233. border
  234. class="tabs"
  235. :header-row-style="{height:'40px'}"
  236. :header-cell-style="{height:'40px',padding:'0',background:'#f7f7f7'}"
  237. >
  238. <el-table-column prop="conceptLibName" :show-overflow-tooltip="true" label="术语名称"></el-table-column>
  239. <el-table-column label="操作" fixed="right">
  240. <template slot-scope="scope">
  241. <el-button
  242. type="text"
  243. size="small"
  244. class="delete"
  245. @click="showDelDialog(scope.row)"
  246. >移除</el-button>
  247. </template>
  248. </el-table-column>
  249. </el-table>
  250. </div>
  251. <div class="form_btn">
  252. <el-button type="primary" size="medium " @click="saveSet">确定</el-button>
  253. </div>
  254. </div>
  255. <div class="table_right">
  256. <div class="conceptSearch" ref="conceptSearch">
  257. <h4 class="conceptTitle">添加关联术语</h4>
  258. <p class="searchWrap">
  259. <img class="search" src="../../images/search.png" alt="搜索" />
  260. <input
  261. v-model.trim="conceptText"
  262. @input="searchConcept"
  263. type="text"
  264. ref="conceptInput"
  265. class="searchText"
  266. placeholder="请输入关键词搜索"
  267. />
  268. </p>
  269. <ul class="conceptList" ref="conceptList">
  270. <li
  271. v-for="item in conceptList"
  272. class="conceptItem ellipsis"
  273. :title="item.conceptName"
  274. @click="selectConcept(item)"
  275. :key="item.conceptId"
  276. >{{item.conceptName}}</li>
  277. <li class="noresult" v-if="conceptList.length==0">暂无结果~</li>
  278. </ul>
  279. </div>
  280. </div>
  281. </div>
  282. </div>
  283. </div>
  284. </template>
  285. <script type="text/javascript">
  286. import api from '@api/knowledgeLib.js';
  287. import AddNewRuleTable from './AddNewRuleTable';
  288. export default {
  289. name: 'AddRule',
  290. data() {
  291. return {
  292. title: '术语集合内容维护-添加',
  293. ruleTypeList: [],
  294. ruleTermTypeList: [],
  295. conceptList: [],
  296. conceptText: '',
  297. excludedConceptIds: [],
  298. type: [],
  299. firstList: [],
  300. lastList: [],
  301. sign: 1,
  302. searchtext: '',
  303. len: null,
  304. form: {
  305. collectionLibType: '',
  306. collectionLibName: '',
  307. concepts: [],
  308. conceptLibType: '',
  309. collectionRemark: '',
  310. collectionId: ''
  311. },
  312. whether: false,
  313. editCount: -1, // 页面会否被编辑 >0被编辑 =0 未编辑
  314. startCount: -1,
  315. isSaveSuccess: false, // 是否保存成功
  316. rules: {
  317. collectionLibType: [
  318. { required: true, message: '请选择术语集合类型', trigger: 'change' }
  319. ],
  320. collectionLibName: [
  321. { required: true, message: '请选择术语集合名称', trigger: 'change' }
  322. ]
  323. }
  324. };
  325. },
  326. created() {
  327. this.getDict();
  328. const param = this.$route.params;
  329. let info = param.data;
  330. if (info) {
  331. this.title = '术语集合内容维护-' + '修改';
  332. this.form.collectionLibType = JSON.stringify(info.collectionLibType);
  333. this.form.collectionLibName = info.collectionLibName;
  334. this.form.concepts = info.concepts;
  335. this.form.conceptLibType = info.concepts[0].conceptLibType;
  336. this.form.collectionId = info.collectionId;
  337. this.form.collectionRemark = info.collectionRemark;
  338. this.sign = 2;
  339. this.$nextTick(() => {
  340. this.getList(this.form.concepts);
  341. this.getIds(this.form.concepts);
  342. this.searchConcept();
  343. });
  344. }
  345. setTimeout(() => {
  346. this.startCount = this.editCount;
  347. }, 500);
  348. },
  349. methods: {
  350. getDict() {
  351. api
  352. .zskgetDict()
  353. .then(res => {
  354. if (res.data.code == '0') {
  355. const data = res.data.data;
  356. this.ruleTypeList = data[63];
  357. this.type = data[61];
  358. }
  359. })
  360. .catch(error => {
  361. console.log(error);
  362. });
  363. },
  364. //过滤集合id
  365. getIds(arr) {
  366. arr.forEach((item, index) => {
  367. this.excludedConceptIds.push(item.conceptId);
  368. });
  369. },
  370. //获取术语集合名称
  371. searchLibName(val) {
  372. api
  373. .getSearchConcept({
  374. excludedConceptIds: [0],
  375. libType: this.form.collectionLibType,
  376. name: val
  377. })
  378. .then(res => {
  379. if (res.data.code == '0') {
  380. const data = res.data.data;
  381. this.ruleTermTypeList = data;
  382. }
  383. })
  384. .catch(error => {
  385. console.log(error);
  386. });
  387. },
  388. searchList(val) {
  389. let concepts = JSON.parse(JSON.stringify(this.form.concepts));
  390. let str = '.*' + val + '.*';
  391. let reg = new RegExp(str);
  392. let arr = [];
  393. //通过附加信息查询
  394. for (var i = 0; i < concepts.length; i++) {
  395. if (reg.test(concepts[i].conceptLibName)) {
  396. arr.push(concepts[i]);
  397. }
  398. }
  399. this.getList(arr);
  400. },
  401. getCollectionLib(newValue) {
  402. this.ruleTermTypeList.forEach(item => {
  403. if (newValue == item.conceptName) {
  404. // this.form.collectionLibName = item.conceptName;
  405. this.form.collectionId = item.conceptId;
  406. this.form.collectionRemark = item.remark;
  407. }
  408. });
  409. },
  410. // 基础术语
  411. async searchConcept() {
  412. this.whether = true;
  413. const params = {
  414. typeId: this.form.conceptLibType,
  415. name: this.conceptText,
  416. excludedConceptIds: this.excludedConceptIds
  417. };
  418. const data = await api.getTreeSearchList(params);
  419. if (data.data.code == '0') {
  420. this.conceptList = data.data.data;
  421. this.whether = false;
  422. }
  423. },
  424. // 选择基础术语
  425. selectConcept(item) {
  426. if (this.whether) {
  427. return;
  428. }
  429. let concepts = {
  430. conceptId: item.conceptId,
  431. conceptLibType: item.conceptNameType,
  432. conceptLibName: item.conceptName
  433. };
  434. this.excludedConceptIds.push(item.conceptId);
  435. this.form.concepts.push(concepts);
  436. this.getList(this.form.concepts);
  437. this.$nextTick(() => {
  438. setTimeout(() => {
  439. this.searchConcept();
  440. }, 150);
  441. });
  442. },
  443. // 切换术语类型
  444. getConceptLibType() {
  445. this.type.forEach(it => {
  446. let id = it.val.split('-');
  447. if (this.form.collectionLibType == id[0]) {
  448. this.form.conceptLibType = id[2];
  449. }
  450. });
  451. this.clearData();
  452. },
  453. // 移除术语
  454. showDelDialog(row) {
  455. this.form.concepts.forEach((item, index) => {
  456. if (item.conceptId == row.conceptId) {
  457. this.form.concepts.splice(index, 1);
  458. this.excludedConceptIds.splice(index, 1);
  459. }
  460. });
  461. this.searchConcept();
  462. if (this.searchtext != '') {
  463. this.searchList(this.searchtext);
  464. } else {
  465. this.getList(this.form.concepts);
  466. }
  467. },
  468. getchk(num) {
  469. return num % 2 == 0 ? '偶数' : '奇数'; //判断是否能整除2
  470. },
  471. getList(arr) {
  472. this.firstList = [];
  473. this.lastList = [];
  474. arr.forEach((item, index) => {
  475. if (this.getchk(index) == '偶数') {
  476. this.firstList.push(item);
  477. } else {
  478. this.lastList.push(item);
  479. }
  480. });
  481. },
  482. saveSet() {
  483. let params = {
  484. ...this.form,
  485. relationId: 0
  486. };
  487. api.saveOrUpdateRecord(params).then(res => {
  488. if (res.data.code == 0) {
  489. this.$message({
  490. message: '操作成功',
  491. type: 'success'
  492. });
  493. this.isSaveSuccess = true;
  494. this.$router.push({
  495. name: 'TermSet',
  496. params: Object.assign({}, this.$route.params, { currentPage: 1 })
  497. });
  498. } else {
  499. this.$message({
  500. message: res.data.msg,
  501. type: 'warning'
  502. });
  503. }
  504. });
  505. },
  506. clearData() {
  507. this.form.collectionLibName = '';
  508. this.conceptText = '';
  509. this.ruleTermTypeList = [];
  510. this.form.concepts = [];
  511. this.getList(this.form.concepts);
  512. this.searchConcept();
  513. }
  514. },
  515. watch: {
  516. form: {
  517. handler(newName, oldName) {
  518. this.editCount++;
  519. },
  520. deep: true,
  521. immediate: true
  522. }
  523. },
  524. beforeRouteLeave(to, from, next) {
  525. if (
  526. this.startCount !== this.editCount &&
  527. this.form.concepts.length > 0 &&
  528. !this.isSaveSuccess
  529. ) {
  530. this.$alert('还有未保存的内容,确定要退出当前页面吗?', '提示', {
  531. confirmButtonText: '确定',
  532. // cancelButtonText: '取消',
  533. // cancelButtonClass: 'leaveBtn',
  534. // customClass: 'leaveBox',
  535. type: 'warning'
  536. })
  537. .then(() => {
  538. next();
  539. })
  540. .catch(() => {});
  541. } else {
  542. next();
  543. }
  544. },
  545. computed: {
  546. onshow() {
  547. return (
  548. this.form.collectionLibType != '' && this.form.collectionLibName != ''
  549. );
  550. }
  551. }
  552. };
  553. </script>