knowledgeClassList.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. <template>
  2. <rx-layout>
  3. <div slot="center" style>
  4. <rx-fit>
  5. <div slot="toolheader" border="false" foldbtn="false">
  6. <breadcrumb firstLevel="知识仓库管理" lastLevel="知识分类" />
  7. <div class="mainContent">
  8. <div class="body">
  9. <div class="content">
  10. <a-form ref="searchForm" layout="inline" style="display:flex;flex-wrap:wrap;">
  11. <!-- <div style="width:80%;display:flex;flex-wrap:wrap;">
  12. <a-form-item
  13. style="width:300px;margin: 5px 40px 5px 0;"
  14. label="分类名称"
  15. name="name">
  16. <a-input v-model="queryParam.name" placeholder="请输入"/>
  17. </a-form-item>
  18. </div> -->
  19. <a-form-item
  20. class="form-item-style"
  21. label="分类名称"
  22. name="name">
  23. <a-input class="set-input" v-model="queryParam.name" placeholder="请输入"/>
  24. </a-form-item>
  25. <div style="display:flex;justify-content:flex-end;margin-top: 8px;">
  26. <a-button @click="handleResetClick">重置</a-button>
  27. <a-button type="primary" @click="handleSearchClick">查询</a-button>
  28. </div>
  29. </a-form>
  30. <rx-button alias="classificationAdd" :butn-icon="'none'" @click="handleAddClassClick">新增分类</rx-button>
  31. </div>
  32. </div>
  33. </div>
  34. </div>
  35. <rx-grid
  36. ref="classifyRef"
  37. class="table-style"
  38. style="background: #fff"
  39. :columns="columns"
  40. :url="api.findAllKnowledgeCategory"
  41. :queryParam="queryParam"
  42. data-field="result.data"
  43. :defaultPageSize="10"
  44. :heightAuto="true"
  45. :pageSizeOptions="['10','20','30','40']"
  46. idField="pkId"
  47. >
  48. <template slot="name" slot-scope="{text}">
  49. <div style="white-space: pre-line">{{ text }}</div>
  50. </template>
  51. <template slot="action" slot-scope="{text,record,index}">
  52. <rx-button class="clearBtn" alias="classificationEdit" :butn-icon="'none'" v-if="record.isSys != 1" @click="handleUpdateClassifyClick(record)">编辑</rx-button>
  53. <rx-button class="clearBtn" alias="classificationLook" :butn-icon="'none'" @click="handleJumpKnowledgeManage(record)">查看知识</rx-button>
  54. <template v-if="isShowButton">
  55. <rx-button v-if="index != (getDataLength(record) - 1)" class="clearBtn" alias="classificationRise" :butn-icon="'none'" @click="handleActionClick(record,false)">下降</rx-button>
  56. <rx-button v-if="index != 0" class="clearBtn" alias="classificationRise" :butn-icon="'none'" @click="handleActionClick(record,true)">上升</rx-button>
  57. </template>
  58. <rx-button class="clearBtn" alias="classificationDel" :butn-icon="'none'" v-if="record.isSys != 1" @click="handleDeleteClick(record)">删除</rx-button>
  59. </template>
  60. </rx-grid>
  61. </rx-fit>
  62. <a-modal v-model="knowledgeShow"
  63. :title="title"
  64. centered
  65. okText="保存"
  66. @ok="handleOk"
  67. :confirmLoading="saveLoading"
  68. @cancel="handleCancel">
  69. <a-form ref="classRef" :model="classForm" layout="inline" :label-col="{ span: 4 }">
  70. <a-form-item label="分类名称" prop="name">
  71. <a-input v-model="classForm.name" :maxLength="10" placeholder="请输入" />
  72. </a-form-item>
  73. <a-form-item label="上级分类" prop="parent" v-if="chooseLevel != 1">
  74. <a-cascader v-model="classForm.parent"
  75. ref="cascader"
  76. :options="classifyLevelList"
  77. :fieldNames="{ label: 'name', value: 'pkId', children: 'children' }"
  78. placeholder="请选择上级分类,创建一级分类无需选择"
  79. :changeOnSelect="changeOnSelect" />
  80. </a-form-item>
  81. <a-form-item label="排序" prop="sort">
  82. <div style="width:40%">
  83. <a-input-number v-model="classForm.sort" :min="0" />
  84. </div>
  85. </a-form-item>
  86. </a-form>
  87. </a-modal>
  88. </div>
  89. </rx-layout>
  90. </template>
  91. <script>
  92. import breadcrumb from '../components/breadcrumb.vue'
  93. import api from '@/api/knowledge/classify'
  94. import classApi from '@/api/knowledge/classify'
  95. import { getCategoryId } from '../aJs/getClassifyTree'
  96. import mixin from "../aMixin/mixin"
  97. const classifyMixin = new mixin('classify')
  98. export default {
  99. components: {
  100. breadcrumb
  101. },
  102. mixins: [ classifyMixin ],
  103. data() {
  104. return {
  105. api,
  106. saveLoading: false,
  107. title: '',
  108. knowledgeShow: false,
  109. queryParam: {
  110. name: ''
  111. },
  112. columns:[
  113. {
  114. title: 'ID',
  115. dataIndex: 'pkId',
  116. align: 'center'
  117. },
  118. {
  119. title: '分类名称',
  120. dataIndex: 'name',
  121. // align: 'center',
  122. scopedSlots: {customRender: 'name'}
  123. },
  124. {
  125. title: '操作人',
  126. dataIndex: 'operatorName',
  127. align: 'center'
  128. },
  129. {
  130. title: '操作时间',
  131. dataIndex: 'updateTime',
  132. align: 'center'
  133. },
  134. {
  135. title: '操作',
  136. dataIndex: 'action',
  137. // align: 'center',
  138. scopedSlots: {customRender: 'action'},
  139. width: 250
  140. }
  141. ],
  142. classForm: {
  143. pkId: '',
  144. name: '',
  145. parent: [],
  146. sort: 0
  147. },
  148. // 所有分类数据
  149. classifyList: [],
  150. // 编辑时不同等级的分类数据
  151. classifyLevelList: [],
  152. // 显示上升下降按钮
  153. isShowButton: true,
  154. // 选中的分类等级
  155. chooseLevel: 0,
  156. changeOnSelect: true
  157. }
  158. },
  159. computed: {
  160. getDataLength() {
  161. return function(record) {
  162. if(record.level == 1) {
  163. return this.$refs.classifyRef.getData().length
  164. } else if(record.level == 2) {
  165. let levelTwo = this.$refs.classifyRef.getData().find(item => item.pkId == record.parent)
  166. if(levelTwo.children) {
  167. return levelTwo.children.length
  168. } else {
  169. return 0
  170. }
  171. } else {
  172. for(let i of this.$refs.classifyRef.getData()) {
  173. if(i.children) {
  174. for(let j of i.children) {
  175. if(j.pkId == record.parent) {
  176. if(j.children) {
  177. return j.children.length
  178. } else {
  179. return 0
  180. }
  181. }
  182. }
  183. }
  184. }
  185. }
  186. }
  187. }
  188. },
  189. created() {
  190. this.init()
  191. },
  192. methods: {
  193. async init() {
  194. let res = await classApi.getAllByCategoryId()
  195. this.classifyList = this.getData(res.data.children)
  196. this.classifyLevelList = JSON.parse(JSON.stringify(this.classifyList))
  197. },
  198. // 格式化数据 disabled 编辑三分类时,只有一级分类没有二级分类,则不可选一级分类
  199. getData(data,disabled = false) {
  200. data.forEach((element) => {
  201. if(element.children && element.children.length > 0 && element.level == 2) {
  202. this.getData(element.children)
  203. } else {
  204. if(disabled && element.level == 2) {
  205. element.disabled = true
  206. }
  207. delete element.children
  208. }
  209. })
  210. return data
  211. },
  212. // 搜索
  213. handleSearchClick() {
  214. this.isShowButton = this.queryParam.name ? false : true
  215. this.reloadTable()
  216. },
  217. handleAddClassClick() {
  218. this.title ='新增分类'
  219. this.chooseLevel = 0
  220. this.changeOnSelect = true
  221. this.init()
  222. this.knowledgeShow = true
  223. },
  224. // 编辑页面显示
  225. async handleUpdateClassifyClick(record) {
  226. this.title = '编辑分类'
  227. this.chooseLevel = record.level
  228. this.changeOnSelect = false
  229. if(record.level == 2) {
  230. this.classifyLevelList = JSON.parse(JSON.stringify(this.classifyList))
  231. this.classifyLevelList.forEach(element => {
  232. if(element.level == 2) {
  233. delete element.children
  234. }
  235. })
  236. }
  237. if(record.level == 3) {
  238. this.classifyLevelList = this.getData(JSON.parse(JSON.stringify(this.classifyList)), true)
  239. }
  240. let res = await this.api.findAllParentByCategoryId(record.pkId)
  241. let gategoryId
  242. if(!res.data.parents) {
  243. gategoryId = []
  244. } else {
  245. gategoryId = getCategoryId(res.data.parents)
  246. }
  247. this.classForm = {
  248. pkId: record.pkId,
  249. name: record.name,
  250. parent: gategoryId,
  251. sort: record.sort
  252. }
  253. this.knowledgeShow = true
  254. },
  255. async handleOk() {
  256. if(!this.classForm.name) {
  257. this.$message.error("请输入分类名称");
  258. return
  259. }
  260. if((this.chooseLevel == 2 || this.chooseLevel == 3) && !this.classForm.parent.length) {
  261. this.$message.error("请选择上级分类");
  262. return
  263. }
  264. this.saveLoading = true
  265. let parentId = this.classForm.parent
  266. let res = await this.api.save({...this.classForm, parent: parentId.length ? parentId.reverse()[0] : null})
  267. if(res.code == 200) {
  268. this.reloadTable()
  269. this.handleCancel()
  270. this.saveLoading = false
  271. }
  272. },
  273. handleCancel() {
  274. this.knowledgeShow = false
  275. this.classForm = Object.assign({},this.$options.data().classForm)
  276. },
  277. handleJumpKnowledgeManage(record) {
  278. this.$router.push({
  279. path: '/knowledge/knowledgeManageList',
  280. query: {pkId: record.pkId}
  281. })
  282. },
  283. // 重新加载表格
  284. reloadTable() {
  285. this.$refs.classifyRef.loadData()
  286. }
  287. }
  288. }
  289. </script>
  290. <style lang="less" scoped>
  291. @gary: #f8f8f8;
  292. @white: #fff;
  293. .rx-fit {
  294. padding: 40px!important;
  295. background: @gary;
  296. overflow-y: auto!important;
  297. display: block!important;
  298. .fit-header {
  299. .mainContent {
  300. width: 100%;
  301. .body {
  302. background: @white;
  303. padding: 10px 20px;
  304. .content {
  305. background: @white;
  306. button:first-child {
  307. margin-right: 20px;
  308. }
  309. >button {
  310. margin: 10px;
  311. margin-left: 0;
  312. }
  313. }
  314. }
  315. }
  316. }
  317. .table-style {
  318. padding: 20px;
  319. min-height: 400px;
  320. .clearBtn {
  321. background: none;
  322. color: #3294F7;
  323. text-shadow: none;
  324. padding: 0px 6px;
  325. border: none;
  326. box-shadow: none;
  327. }
  328. }
  329. }
  330. .show-other{
  331. width: 100%;
  332. animation:show-other-search 0.8s;
  333. }
  334. .form-item-style {
  335. margin: 5px 20px 5px 0;
  336. }
  337. .set-input {
  338. width:180px;
  339. }
  340. @keyframes show-other-search{
  341. 0%{opacity:0;}
  342. 50%{opacity:0.8;}
  343. 100%{opacity: 1;}
  344. }
  345. </style>
  346. <style scoped>
  347. /deep/ .divdefault {
  348. position: inherit!important;
  349. }
  350. /deep/ .ant-table-row-expand-icon{
  351. position: relative;
  352. z-index: 100;
  353. }
  354. /deep/.ant-btn > .anticon + span {
  355. margin-left: 0;
  356. }
  357. /deep/.ant-table-thead > tr > th {
  358. text-align: center;
  359. height: 54px;
  360. }
  361. /deep/ .ant-table-tbody > tr > td {
  362. height: 54px;
  363. }
  364. /deep/ .ant-form{
  365. padding: 0;
  366. }
  367. /deep/ .gridContent{
  368. border: none;
  369. }
  370. /deep/ .gridContent .ant-table-content .ant-table-tbody>tr>td:nth-child(2) {
  371. padding-left: 60px!important;
  372. }
  373. </style>