docClassifyManage.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. <!--
  2. 表格树形数据拖拽 本来使用el-table和sortablejs 但是奇怪的判断导致前端无法做跨级拖拽的限制。
  3. 得由后端来限制,固使用drag-tree-table 但是这个插件构造比较简单,不是用table标签实现的
  4. 如果产品要实现el-table上面的功能,需要自定义,有更好的方法,还请通知一声。
  5. -->
  6. <template>
  7. <div class="doc-classifyMana-container">
  8. <div class="doc-classifyMana-top-zone">
  9. <el-button type="primary" @click="addClassify">添加分类</el-button>
  10. <el-input placeholder="分类名称" v-model="queryParams.KeyWord" @input="getclassifyData" clearable
  11. style="width:500px;margin-left: 20px;">
  12. <i slot="prefix" class="el-input__icon el-icon-search"></i>
  13. </el-input>
  14. </div>
  15. <!-- <el-table style="border:1px solid #eaeaea;" ref="classifyTableRef"
  16. :data="classifyList" :row-class-name="tableRowClassName" row-key="id" :tree-props="{children:'child'}">
  17. <el-table-column prop="text" label="一级分类">
  18. <template slot-scope="scope">
  19. <span>{{scope.row.level==1?scope.row.text:''}}</span>
  20. </template>
  21. </el-table-column>
  22. <el-table-column prop="text" label="二级分类">
  23. <template slot-scope="scope">
  24. <span>{{scope.row.level==2?scope.row.text:''}}</span>
  25. </template>
  26. </el-table-column>
  27. <el-table-column prop="text" label="三级分类">
  28. <template slot-scope="scope">
  29. <span>{{scope.row.level==3?scope.row.text:''}}</span>
  30. </template>
  31. </el-table-column>
  32. <el-table-column label="操作" align="center">
  33. <template slot-scope="scope">
  34. <div class="table-button">
  35. <span @click="configItem(scope.row)">权限配置</span>
  36. <span @click="edititem(scope.row)">编辑</span>
  37. <span @click="checkdeleteitem(scope.row)" style="margin-right: 0;color: #F56C6C;">删除</span>
  38. </div>
  39. </template>
  40. </el-table-column>
  41. </el-table> -->
  42. <dragTreeTable ref="dragTreeTableRef" :beforeDragOver="beforeDrag"
  43. :data="treeData" :onDrag="onTreeDataChange"
  44. hightRowChange resize border >
  45. <!-- onlySameLevelCanDrag -->
  46. </dragTreeTable>
  47. <!-- 添加分类弹窗 -->
  48. <el-dialog :title="dialogTitle" :visible.sync="showAddClassifyDia" width="625px"
  49. append-to-body :close-on-click-modal="false" @close="resetForm">
  50. <div style="display: flex;flex-direction: column; align-items: center;margin-bottom: 35px;">
  51. <el-form :model="classifyForm" ref="classifyFormRef" label-width="80px">
  52. <el-form-item label="上级目录" prop="ParentId">
  53. <el-cascader v-model="classifyForm.ParentId" :options="noLevelThreeList" @change="selectParentId"
  54. placeholder="请选择上级目录(不选默认添加的是一级分类)" ref="parentIdCascaderRef"
  55. :props="{ value:'ClassifyId',label:'ClassifyName',children:'Children',checkStrictly:true,emitPath:false,disabled:'Disabled'}"
  56. class="lastCatalogCascader" :disabled="this.dialogTitle.indexOf('编辑分类')!=-1" />
  57. </el-form-item>
  58. <el-form-item label="分类名称" prop="HelpDocClassifyName" :rules="{required:true,message:'分类名称不能为空',trigger:'blur'}">
  59. <el-input v-model="classifyForm.HelpDocClassifyName" placeholder="请输入分类名称" style="width: 337px;"
  60. maxlength="10"></el-input>
  61. </el-form-item>
  62. </el-form>
  63. <div style="margin-top: 40px;">
  64. <el-button type="primary" style="width:120px;margin-right:10px" @click="classifySave" size="medium">保存</el-button>
  65. <el-button style="width:120px;" @click="showAddClassifyDia=false" size="medium">取消</el-button>
  66. </div>
  67. </div>
  68. </el-dialog>
  69. <!-- 设置权限弹窗 -->
  70. <el-dialog :title="dialogTitle" :visible.sync="showPermissionDia" width="625px"
  71. append-to-body :close-on-click-modal="false" @close="resetPermissonForm">
  72. <div style="display: flex;flex-direction: column; align-items: center;margin-bottom: 35px;">
  73. <el-form :model="permissionForm" ref="permissionFormRef" label-width="80px">
  74. <el-form-item label="可见权限" prop="merchantIds">
  75. <el-select v-model="permissionForm.merchantIds" placeholder="请选择商家"
  76. multiple style="width: 337px;" collapse-tags clearable filterable >
  77. <el-option :label="item.BusinessName" :value="item.EtaBusinessId"
  78. v-for="item in merchantList" :key="item.merchantId"></el-option>
  79. </el-select>
  80. </el-form-item>
  81. </el-form>
  82. <div style="margin-top: 40px;">
  83. <el-button type="primary" style="width:120px;margin-right:10px" @click="configSave" size="medium">保存</el-button>
  84. <el-button style="width:120px;" @click="showPermissionDia=false" size="medium">取消</el-button>
  85. </div>
  86. </div>
  87. </el-dialog>
  88. </div>
  89. </template>
  90. <script>
  91. // import Sortable from "sortablejs";
  92. import {assistanceDocInterence,businessCustomInterence} from "@/api/api.js"
  93. import dragTreeTable from "drag-tree-table";
  94. export default {
  95. name:"docClassifyManage",
  96. components:{dragTreeTable},
  97. data() {
  98. // 表格头设置
  99. this.tableHeadList=[
  100. {
  101. type:"selection",
  102. title: '一级分类',
  103. field: 'ClassifyName',
  104. flex:1,
  105. align: 'center',
  106. formatter: (item) => {
  107. return item.Level==1?item.ClassifyName:""
  108. }
  109. },
  110. {
  111. title: '二级分类',
  112. field: 'ClassifyName',
  113. // width: 200,
  114. flex:1,
  115. align: 'center',
  116. formatter: (item) => {
  117. return item.Level==2?item.ClassifyName:""
  118. }
  119. },
  120. {
  121. title: '三级分类',
  122. field: 'ClassifyName',
  123. // width: 200,
  124. flex:1,
  125. align: 'center',
  126. formatter: (item) => {
  127. return item.Level==3?item.ClassifyName:""
  128. }
  129. },
  130. {
  131. type: 'action',
  132. title: '操作',
  133. width: 260,
  134. // flex:1,
  135. align: 'center',
  136. actions:[
  137. {
  138. text: '权限配置',
  139. onclick: (item) => {
  140. // item是当前行的数据
  141. this.configClassify(item)
  142. },
  143. formatter: (item) => {
  144. return '<span class="table-button">权限配置</span>'
  145. }
  146. },
  147. {
  148. text: '编辑',
  149. onclick: (item) => {
  150. this.editClassify(item)
  151. },
  152. formatter: (item) => {
  153. return '<span class="table-button">编辑</span>'
  154. }
  155. },
  156. {
  157. text: '删除',
  158. onclick: (item) => {
  159. this.deleteClassify(item)
  160. },
  161. formatter: (item) => {
  162. return '<span class="table-button" style="margin-right: 0;color: #F56C6C;">删除</span>'
  163. }
  164. }
  165. ]
  166. }
  167. ]
  168. // 自定义字段替换
  169. this.custom_field={
  170. id: 'ClassifyId',
  171. order: 'Sort',
  172. lists: 'Children',
  173. parent_id: 'ParentId'
  174. }
  175. return {
  176. queryParams:{
  177. KeyWord:''
  178. },
  179. treeData:{
  180. columns:this.tableHeadList,
  181. lists:[],
  182. custom_field:this.custom_field
  183. },
  184. // 没有三级分类的分类数组,用于添加
  185. noLevelThreeList:[],
  186. // // 扁平化之后的数据
  187. // classifyListFlat:[],
  188. dialogTitle:"",
  189. showAddClassifyDia:false,
  190. classifyForm:{
  191. ParentId:0,
  192. HelpDocClassifyName:'',
  193. Level:0,
  194. },
  195. merchantList:[],
  196. showPermissionDia:false,
  197. permissionForm:{
  198. HelpDocClassifyId:0,
  199. merchantIds:[]
  200. },
  201. }
  202. },
  203. created(){
  204. this.getmerchantList()
  205. this.getclassifyData()
  206. },
  207. mounted(){
  208. this.$nextTick(()=>{
  209. // this.tableDropSet()
  210. })
  211. },
  212. methods: {
  213. getmerchantList(){
  214. businessCustomInterence.getBusinessList({PageSize:9999999,CurrentIndex:1}).then(res=>{
  215. if(res.Ret == 200){
  216. this.merchantList = res.Data.List||[]
  217. }
  218. })
  219. },
  220. getclassifyData(){
  221. assistanceDocInterence.getAssistanceClassifyList(this.queryParams).then(res=>{
  222. if(res.Ret == 200){
  223. this.treeData.lists = res.Data?res.Data.AllNodes||[]:[]
  224. this.noLevelThreeList = res.Data?res.Data.TwoLevelNodes||[]:[]
  225. this.treeData.lists.map(list=> {
  226. // 一级展开
  227. list.open=true
  228. })
  229. // console.log(this.treeData.lists);
  230. }
  231. })
  232. },
  233. // tableRowClassName({row,rowIndex}) {
  234. // if( row.child && row.child.length>0 ){
  235. // return 'has-child-row';
  236. // }else{
  237. // return '';
  238. // }
  239. // },
  240. beforeDrag(dragItem,effectItem,type){
  241. if(type=='center'){
  242. // 放里面
  243. if((dragItem.Level-1)!=effectItem.Level) return false
  244. }else{
  245. //不放里面
  246. if(dragItem.Level!=effectItem.Level) return false
  247. }
  248. // return false
  249. },
  250. onTreeDataChange(list,dragItem){
  251. // console.log(list,dragItem,'arguments');
  252. // list - 拖拽后的数据 dragItem-拖拽的项
  253. let ClassifyId,PrevClassifyId,NextClassifyId,ParentClassifyId=0
  254. // 在拖拽后的数据中找到拖拽项对应的位置
  255. const findDraggedItem=(list)=>{
  256. let itemIndex = list.findIndex(it => it.ClassifyId == dragItem.ClassifyId)
  257. if(itemIndex!=-1){
  258. if(itemIndex==0){
  259. PrevClassifyId=0
  260. }else{
  261. PrevClassifyId = list[itemIndex-1].ClassifyId
  262. }
  263. if(itemIndex==(list.length-1)){
  264. NextClassifyId=0
  265. }else{
  266. NextClassifyId = list[itemIndex+1].ClassifyId
  267. }
  268. ClassifyId = dragItem.ClassifyId
  269. ParentClassifyId = dragItem.ParentId
  270. console.log({
  271. ClassifyId,ParentClassifyId,PrevClassifyId,NextClassifyId
  272. });
  273. assistanceDocInterence.moveAssistanceClassify({
  274. ClassifyId,ParentClassifyId,PrevClassifyId,NextClassifyId
  275. }).then(res=>{
  276. if(res.Ret == 200){
  277. this.$message.success("移动分类成功")
  278. this.getclassifyData()
  279. }
  280. })
  281. }else{
  282. list.map(li => {
  283. li.Children && li.Children.length>0 && findDraggedItem(li.Children)
  284. })
  285. }
  286. }
  287. findDraggedItem(list)
  288. },
  289. // tableDropSet(){
  290. // const tbody = this.$refs.classifyTableRef.$el.querySelector(
  291. // ".el-table__body-wrapper > table > tbody"
  292. // );
  293. // const _this = this;
  294. // Sortable.create(tbody, {
  295. // animation: 150,
  296. // onStart(evt){
  297. // if(_this.classifyListFlat && _this.classifyListFlat.length>0){
  298. // return
  299. // }else{
  300. // _this.flatClassifyList(_this.classifyList,0)
  301. // }
  302. // console.log(_this.classifyListFlat);
  303. // },
  304. // onEnd({ newIndex, oldIndex }) {
  305. // console.log({ newIndex, oldIndex });
  306. // if(newIndex == oldIndex) return
  307. // const oldRow = _this.classifyListFlat[oldIndex]
  308. // const newRow = _this.classifyListFlat[newIndex]
  309. // console.log(oldRow,newRow);
  310. // _this.$message.success("拖拽成功")
  311. // _this.getclassifyData()
  312. // },
  313. // onMove({ dragged, related }){
  314. // console.log(dragged.rowIndex, related.rowIndex);
  315. // const oldRow = _this.classifyListFlat[dragged.rowIndex]
  316. // const newRow = _this.classifyListFlat[related.rowIndex]
  317. // console.log(oldRow.level,newRow.level);
  318. // if (oldRow.level !== newRow.level) {
  319. // return false // 不允许不同级的拖动
  320. // }
  321. // }
  322. // });
  323. // },
  324. // flatClassifyList(list,parentId){
  325. // for (let i = 0; i < list.length; i++) {
  326. // const element = list[i];
  327. // const lastElementId = i==0?0:list[i-1].id
  328. // const nextElementId = i==(list.length-1)?0:list[i+1].id
  329. // this.classifyListFlat.push({id:element.id,lastElementId,nextElementId,parentId,level:element.level})
  330. // if(element.child && element.child.length>0){
  331. // this.flatClassifyList(element.child,element.id)
  332. // }
  333. // }
  334. // },
  335. // 添加分类
  336. addClassify(){
  337. this.dialogTitle="添加分类"
  338. this.showAddClassifyDia=true
  339. },
  340. // 编辑分类
  341. editClassify(item){
  342. this.classifyForm={
  343. ParentId:item.ParentId,
  344. HelpDocClassifyId:item.ClassifyId,
  345. HelpDocClassifyName:item.ClassifyName
  346. }
  347. this.dialogTitle="编辑分类"
  348. this.showAddClassifyDia=true
  349. },
  350. selectParentId(value){
  351. this.classifyForm.Level = this.$refs.parentIdCascaderRef.getCheckedNodes()[0].data.Level
  352. },
  353. deleteClassify(item){
  354. this.$confirm('是否确认删除?', '提示', {
  355. confirmButtonText: '确定',
  356. cancelButtonText: '取消',
  357. type: 'warning',
  358. }).then(() => {
  359. assistanceDocInterence.deleteAssistanceClassify({ClassifyId:item.ClassifyId}).then(res=>{
  360. if(res.Ret == 200){
  361. this.$message.success("删除分类成功")
  362. this.getclassifyData()
  363. }
  364. })
  365. }).catch(()=>{})
  366. },
  367. // 保存
  368. classifySave(){
  369. this.$refs.classifyFormRef.validate(valid=>{
  370. if(valid){
  371. console.log(this.classifyForm);
  372. if(this.classifyForm.HelpDocClassifyId){
  373. //编辑
  374. assistanceDocInterence.editAssistanceClassify(this.classifyForm).then(res=>{
  375. if(res.Ret == 200){
  376. this.$message.success(this.dialogTitle+"成功")
  377. this.showAddClassifyDia=false
  378. this.resetForm()
  379. this.getclassifyData()
  380. }
  381. })
  382. }else{
  383. //新增
  384. assistanceDocInterence.addAssistanceClassify({...this.classifyForm}).then(res=>{
  385. if(res.Ret == 200){
  386. this.$message.success(this.dialogTitle+"成功")
  387. this.showAddClassifyDia=false
  388. this.resetForm()
  389. this.getclassifyData()
  390. }
  391. })
  392. }
  393. }
  394. })
  395. },
  396. resetForm(){
  397. this.classifyForm={
  398. ParentId:0,
  399. HelpDocClassifyName:'',
  400. Level:0
  401. }
  402. this.$refs.classifyFormRef.clearValidate()
  403. },
  404. //权限配置
  405. configClassify(row){
  406. this.permissionForm={
  407. HelpDocClassifyId:row.ClassifyId,
  408. merchantIds:row.VisibleBusinessIds?row.VisibleBusinessIds.split(',').map(element => {
  409. return parseInt(element)
  410. }):[]
  411. }
  412. // console.log(this.permissionForm.merchantIds);
  413. this.dialogTitle="设置权限"
  414. this.showPermissionDia=true
  415. },
  416. resetPermissonForm(){
  417. this.permissionForm={
  418. HelpDocClassifyId:0,
  419. merchantIds:[]
  420. }
  421. this.$refs.permissionFormRef.clearValidate()
  422. },
  423. configSave(){
  424. assistanceDocInterence.editAssistanceClassifyVisible({
  425. HelpDocClassifyId:this.permissionForm.HelpDocClassifyId,
  426. VisibleBusinessIds:this.permissionForm.merchantIds.join(',')
  427. }).then(res=>{
  428. if(res.Ret == 200){
  429. this.$message.success("设置成功")
  430. this.showPermissionDia=false
  431. this.resetPermissonForm()
  432. this.getclassifyData()
  433. }
  434. })
  435. }
  436. },
  437. }
  438. </script>
  439. <style lang="scss" scoped>
  440. .doc-classifyMana-container{
  441. background-color: white;
  442. min-height: calc(100vh - 110px);
  443. padding: 30px;
  444. box-sizing: border-box;
  445. border: solid 1px #ECECEC;
  446. .doc-classifyMana-top-zone{
  447. display: flex;
  448. align-items: flex-start;
  449. justify-content: space-between;
  450. margin-bottom: 20px;
  451. }
  452. }
  453. </style>
  454. <style lang="scss">
  455. .lastCatalogCascader{
  456. width: 337px;
  457. .el-input{
  458. width: 337px;
  459. }
  460. }
  461. .has-child-row {
  462. background-color: #f2f6fa!important;
  463. }
  464. .table-button{
  465. color:#4099ef;
  466. cursor: pointer;
  467. margin-right: 10px;
  468. }
  469. </style>