AddTermSet.vue 15 KB

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