classifylistV2.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  1. <template>
  2. <div class="classify-page">
  3. <div class="top-wrap">
  4. <div class="type-box">
  5. <!-- 中文分类 -->
  6. <div class="item active"
  7. v-permission="[
  8. permissionBtn.classifyBtn.classifyList_cnClassify,
  9. permissionBtn.enClassifyBtn.classifyList_enClassify,
  10. 'and'
  11. ]">
  12. {{ $t('ReportManage.CategoryList.chinese_tabs') }}
  13. </div>
  14. <!-- 英文分类 -->
  15. <div class="item" @click="$emit('typeChange','2')" style="margin-left: 20px;"
  16. v-permission="permissionBtn.enClassifyBtn.classifyList_enClassify">
  17. {{ $t('ReportManage.CategoryList.english_tabs') }}
  18. </div>
  19. </div>
  20. <div style="display:flex;padding:10px;gap:10px">
  21. <!-- 添加分类 -->
  22. <el-button
  23. type="primary"
  24. @click="addClassify"
  25. v-permission="permissionBtn.classifyBtn.classifyList_cnClassify_classifyAdd"
  26. >
  27. {{$t('ReportManage.CategoryList.add_category')}}
  28. </el-button>
  29. <el-input :placeholder="$t('ReportManage.CategoryList.category_name')" v-model="searchVal" style="max-width: 262px;" @change="getList" clearable>
  30. <i slot="prefix" class="el-input__icon el-icon-search"></i>
  31. </el-input>
  32. </div>
  33. </div>
  34. <div class="content-box">
  35. <el-tree
  36. :data="list"
  37. node-key="Id"
  38. :props="{
  39. label: 'ClassifyName',
  40. children: 'Child'
  41. }"
  42. check-strictly
  43. :empty-text="$t('Common.no_classify_msg')"
  44. draggable
  45. indent='76'
  46. :allow-drop="canDropHandle"
  47. @node-drop="dropOverHandle"
  48. >
  49. <div
  50. class="classify-item-wrap"
  51. slot-scope="{ data }"
  52. >
  53. <div>
  54. <span
  55. :class="['tag', data.Enabled==1?'open':'close']"
  56. @click.stop="handleEnableSet(data)">
  57. {{data.Enabled==1?$t('Common.enable'):$t('Common.disable')}}
  58. </span>
  59. <span>{{data.ClassifyName}}</span>
  60. </div>
  61. <div class="opt-box">
  62. <!-- 章节设置 -->
  63. <span class="editsty"
  64. v-if="!data.Child || (data.Child&&!data.Child.length)"
  65. @click="chapterSetting(data)"
  66. v-permission="permissionBtn.classifyBtn.classifyList_cnClassify_chapterSetting">
  67. {{ $t('ReportManage.CategoryList.section_settings') }}
  68. </span>
  69. <el-button type="text" style="color:#f00" @click.stop="handleDel(data)" v-permission="permissionBtn.classifyBtn.classifyList_cnClassify_delete">删除</el-button>
  70. <img class="icon-drag" src="~@/assets/img/data_m/move_ico2.png" alt="">
  71. <img class="icon-set" src="~@/assets/img/icons/variety_set.png" alt="" @click.stop="handleEdit(data)" v-permission="permissionBtn.classifyBtn.classifyList_cnClassify_classifyEdit">
  72. </div>
  73. </div>
  74. </el-tree>
  75. </div>
  76. <!-- 分类弹窗 -->
  77. <m-dialog
  78. :title="classifyForm.classify_id?$t('ReportManage.CategoryList.edit_category'):$t('ReportManage.CategoryList.add_category')"
  79. :show.sync="classifyForm.show"
  80. v-if="classifyForm.show"
  81. width="650px"
  82. >
  83. <div style="padding-left: 50px">
  84. <el-form
  85. :model="classifyForm"
  86. :rules="formRules"
  87. ref="formRef"
  88. hide-required-asterisk
  89. label-width="auto">
  90. <!-- 分类名称 -->
  91. <el-form-item prop="classify_name" :label="$t('ReportManage.CategoryList.category_name')">
  92. <el-input
  93. type="text"
  94. v-model="classifyForm.classify_name"
  95. :placeholder="$t('ReportManage.CategoryList.category_name_hint')"
  96. style="width:400px;"
  97. />
  98. </el-form-item>
  99. <!-- 上级分类 -->
  100. <el-form-item prop="parent_id" :label="$t('ReportManage.CategoryList.parent_category')">
  101. <el-cascader
  102. v-model="classifyForm.parent_id"
  103. :options="classifyparentArr"
  104. :disabled="classifyForm.classify_id"
  105. style="width:400px;"
  106. ref="classifyRef"
  107. :props="{
  108. checkStrictly: true,
  109. value: 'Id',
  110. label: 'ClassifyName',
  111. children:'Child',
  112. emitPath:false
  113. }"
  114. clearable
  115. @change="changeClassify"
  116. >
  117. </el-cascader>
  118. </el-form-item>
  119. <!-- 报告类型 -->
  120. <el-form-item prop="reportType" label="报告类型">
  121. <template slot="label">
  122. <span>报告类型</span>
  123. <el-tooltip content="研报对应研报中心可选分类,PPT对应PPT中心可选分类">
  124. <i class="el-icon-warning"/>
  125. </el-tooltip>
  126. </template>
  127. <el-select v-model="classifyForm.reportType" style="width:400px" :disabled="classifyForm.classify_id||classifyForm.parent_id">
  128. <el-option label="研报" :value="1"/>
  129. <el-option label="PPT" :value="2"/>
  130. </el-select>
  131. </el-form-item>
  132. <!-- 报告提醒 -->
  133. <el-form-item prop="warnTime" label="报告提醒">
  134. <template slot="label">
  135. <span>报告提醒</span>
  136. <el-tooltip content="开启后,指定的报告编辑人将在课题结束前定时收到写报告提醒">
  137. <i class="el-icon-warning"/>
  138. </el-tooltip>
  139. </template>
  140. <el-switch
  141. v-model="classifyForm.isReportWarn"
  142. :active-value="1"
  143. :inactive-value="0"
  144. />
  145. <el-time-picker
  146. v-if="classifyForm.isReportWarn"
  147. v-model="classifyForm.warnTime"
  148. value-format="HH:mm:ss"
  149. style="width:120px;margin-left:20px"
  150. >
  151. </el-time-picker>
  152. </el-form-item>
  153. </el-form>
  154. <div v-html="tips" style="color:#999;"></div>
  155. </div>
  156. <div slot="footer" style="margin-top: 20px;">
  157. <el-button
  158. @click="cancelClassify"
  159. style="width: 132px; height: 40px"
  160. >{{ $t('Dialog.cancel_btn') }}</el-button>
  161. <el-button
  162. @click="setClassifyHandle"
  163. type="primary"
  164. style="width: 132px; height: 40px"
  165. >{{ $t('Dialog.confirm_save_btn') }}</el-button>
  166. </div>
  167. </m-dialog>
  168. <!-- 转移报告弹窗 -->
  169. <m-dialog
  170. title="分类报告转移"
  171. :show.sync="isTransferReport"
  172. width="650px"
  173. >
  174. <div>
  175. <el-form
  176. :model="transferForm"
  177. hide-required-asterisk
  178. label-width="auto"
  179. >
  180. <el-form-item prop="classify_name" label="原分类">
  181. <el-cascader
  182. v-model="transferForm.oldClassify"
  183. @change="filterChange"
  184. :options="classifyparentArr"
  185. clearable
  186. placeholder="请选择分类"
  187. style="width:100%;"
  188. ></el-cascader>
  189. </el-form-item>
  190. <!-- 上级分类 -->
  191. <el-form-item prop="parent_id" label="转移至分类">
  192. <el-cascader
  193. v-model="transferForm.newClassify"
  194. @change="filterChange"
  195. :options="classifyparentArr"
  196. clearable
  197. placeholder="请选择分类"
  198. style="width:100%;"
  199. ></el-cascader>
  200. </el-form-item>
  201. </el-form>
  202. </div>
  203. <div slot="footer" style="margin-top: 20px;">
  204. <el-button
  205. @click="isTransferReport=false"
  206. style="width: 132px; height: 40px"
  207. >{{ $t('Dialog.cancel_btn') }}</el-button>
  208. <el-button
  209. @click="handleSaveTransferReport"
  210. type="primary"
  211. style="width: 132px; height: 40px"
  212. >{{ $t('Dialog.confirm_save_btn') }}</el-button>
  213. </div>
  214. </m-dialog>
  215. </div>
  216. </template>
  217. <script>
  218. import mDialog from '@/components/mDialog.vue';
  219. import { classifylist,classifyparent,classifyadd,classifyedit,classifydelete } from 'api/api.js';
  220. import {classifyPermissionInterface} from '@/api/modules/classifyApi.js'
  221. export default {
  222. components:{mDialog},
  223. computed: {
  224. canSetPermission() {
  225. /* 编辑最小级分类可设置品种 新增分类可设置跑品种 */
  226. if(!this.permissionBtn.classifyBtn.classifyList_cnClassify_connect_variety) return false
  227. if(this.classifyForm.classify_id) {
  228. return this.classifyForm.isLastLevel?true:false
  229. }else {
  230. return true
  231. }
  232. }
  233. },
  234. data() {
  235. return {
  236. typeVal:1,
  237. searchVal:'',
  238. list:[],
  239. classifyForm:{
  240. show:false,
  241. classify_id:0,
  242. classify_name:"",
  243. parent_id: 0,
  244. variety:'',//关联的品种
  245. reportType: 1,
  246. isReportWarn: 0,
  247. warnTime:'09:00:00'
  248. },
  249. formRules: {
  250. classify_name: [{ required:true,message:this.$t('ReportManage.CategoryList.category_name_hint'),trigger:'blur'}]
  251. },
  252. classifyparentArr:[],
  253. reportVarietyList:[],//中文品种列表
  254. /* 转移报告弹窗 */
  255. isTransferReport: false,
  256. transferForm: {},
  257. tips: `注:若上级分类已关联报告,则新建的第一个子分类默认继承上级分类(父分类)关联的报告。`
  258. }
  259. },
  260. mounted(){
  261. this.getList()
  262. },
  263. methods: {
  264. /* 报告转移 */
  265. transferReport() {
  266. this.isTransferReport = true;
  267. this.transferForm = {
  268. oldClassify: '',
  269. newClassify: ''
  270. }
  271. },
  272. handleSaveTransferReport() {
  273. },
  274. async getList(type){
  275. const res=await classifylist({
  276. KeyWord:this.searchVal,
  277. })
  278. if(res.Ret===200){
  279. this.list=res.Data.List||[]
  280. this.classifyparentArr=_.cloneDeep(this.list)
  281. this.filterNodes(this.classifyparentArr)
  282. }
  283. },
  284. /* 添加分类默认关联父级品种 */
  285. async changeClassify(id) {
  286. let item = this.$refs.classifyRef.getCheckedNodes(true)
  287. console.log(item)
  288. if(item&&item[0]) {
  289. this.classifyForm.reportType = item[0].data.ClassifyType
  290. }
  291. },
  292. // 去设置章节
  293. chapterSetting(row){
  294. this.$router.push({path:'chapterSetting',query:{ id:row.Id,classifyName: row.ClassifyName }})
  295. },
  296. filterNodes(arr) {
  297. arr.length && arr.forEach(item => {
  298. item.Child && item.Child.length && this.filterNodes(item.Child)
  299. if(!item.Child || (item.Child&&!item.Child.length) || item.Level===2) {
  300. delete item.Child
  301. }
  302. })
  303. },
  304. async addClassify(){
  305. this.classifyForm={
  306. show:true,
  307. classify_id:0,
  308. classify_name:"",
  309. parent_id: 0,
  310. variety:'',//关联的品种
  311. reportType: 1,
  312. isReportWarn: 0,
  313. warnTime:'09:00:00'
  314. }
  315. },
  316. async handleEdit(item){
  317. console.log(item)
  318. this.classifyForm={
  319. show:true,
  320. classify_id:item.Id,
  321. classify_name:item.ClassifyName,
  322. parent_id: item.ParentId,
  323. isLastLevel: !item.Child,
  324. reportType: item.ClassifyType,
  325. isReportWarn: item.IsRemind,
  326. warnTime: item.RemindTime
  327. }
  328. },
  329. async setClassifyHandle(){
  330. await this.$refs.formRef.validate();
  331. const { classify_name,parent_id,classify_id,reportType,isReportWarn,warnTime } = this.classifyForm;
  332. let params = {
  333. ClassifyName: classify_name,
  334. ParentId: parent_id,
  335. ClassifyType: reportType,
  336. IsRemind: isReportWarn,
  337. RemindTime: warnTime
  338. }
  339. const { Ret,Msg } = classify_id
  340. ? await classifyedit({...params,ClassifyId: classify_id})
  341. : await classifyadd(params)
  342. if(Ret !== 200) return
  343. //this.$message.success(Msg)
  344. this.$message.success(
  345. classify_id
  346. ?this.$t('ReportManage.CategoryList.modification_successful')
  347. :this.$t('ReportManage.CategoryList.addition_successful')
  348. )
  349. this.cancelClassify();
  350. this.getList();
  351. },
  352. /* 取消 */
  353. cancelClassify() {
  354. this.$refs.formRef.resetFields();
  355. this.classifyForm.show = false;
  356. },
  357. /* 删除分类 */
  358. async handleDel(item) {
  359. await this.$confirm('分类删除后不可恢复,是否确认删除?', '提示', {
  360. type: 'warning'
  361. })
  362. const res = await classifydelete({ClassifyId:item.ClassifyId})
  363. if(res.Ret!==200) return
  364. this.$message.success('删除成功')
  365. this.getList()
  366. },
  367. //启用\禁用设置
  368. handleEnableSet(item){
  369. // 判断权限
  370. const {classifyBtn,checkPermissionBtn} = this.permissionBtn
  371. if(!checkPermissionBtn(classifyBtn.classifyList_cnClassify_enable)) return
  372. classifyPermissionInterface.enableSet({
  373. ClassifyId:item.Id,
  374. Enabled:item.Enabled==1?0:1
  375. }).then(res=>{
  376. if(res.Ret===200){
  377. //设置成功
  378. this.$message.success(this.$t('ReportManage.CategoryList.setup_successful'))
  379. this.getList()
  380. }
  381. })
  382. },
  383. //控制只能同级拖动
  384. canDropHandle(draggingNode, dropNode, type){
  385. if(type==='inner') return false //禁止向内部拖动
  386. if(draggingNode.level!=dropNode.level) return false
  387. if(draggingNode.data.ParentId!=dropNode.data.ParentId) return false
  388. return true
  389. },
  390. //拖动结束
  391. dropOverHandle(b,a,i,e) {
  392. // 被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置
  393. const classifyId=b.data.Id
  394. let list=a.parent.childNodes;
  395. let PrevClassifyId=0,NextClassifyId=0,targetIndex=0;
  396. list.forEach((item,index) => {
  397. if(item.data.Id===classifyId){
  398. targetIndex=index
  399. }
  400. });
  401. if(targetIndex===0){
  402. NextClassifyId=list[1].data.Id
  403. }else if(targetIndex===list.length-1){
  404. PrevClassifyId=list[list.length-1].data.Id
  405. }else{
  406. PrevClassifyId=list[targetIndex-1].data.Id
  407. NextClassifyId=list[targetIndex+1].data.Id
  408. }
  409. const params={
  410. ClassifyId:classifyId,
  411. PrevClassifyId,
  412. NextClassifyId
  413. }
  414. console.log(params);
  415. classifyPermissionInterface.moveSort(params).then(res=>{
  416. if(res.Ret===200){
  417. this.$message.success(this.$t('ReportManage.CategoryList.move_successful'))
  418. }else{
  419. this.getList()
  420. }
  421. })
  422. },
  423. },
  424. }
  425. </script>
  426. <style lang="scss">
  427. .el-cascader .el-input{
  428. width: 100%;
  429. }
  430. .classify-page{
  431. .content-box{
  432. .el-tree-node__content{
  433. height: fit-content;
  434. padding-top: 10px;
  435. padding-bottom: 10px;
  436. border-bottom: 1px solid #C8CDD9;
  437. }
  438. }
  439. }
  440. </style>
  441. <style lang="scss" scoped>
  442. .top-wrap{
  443. display: flex;
  444. justify-content: space-between;
  445. background: #FFFFFF;
  446. border-radius: 4px;
  447. .type-box{
  448. display: flex;
  449. .item{
  450. position: relative;
  451. cursor: pointer;
  452. color: #666;
  453. min-width: 88px;
  454. line-height: 60px;
  455. text-align: center;
  456. }
  457. .active{
  458. color: #0052D9;
  459. &::after{
  460. content: '';
  461. display: block;
  462. width: 100%;
  463. height: 2px;
  464. position: absolute;
  465. bottom: 0px;
  466. left: 0;
  467. background-color: #0052D9;
  468. }
  469. }
  470. }
  471. }
  472. .content-box{
  473. padding: 20px;
  474. margin-top: 20px;
  475. height: calc(100vh - 230px);
  476. overflow-y: auto;
  477. background-color: #FFFFFF;
  478. .classify-item-wrap{
  479. flex: 1;
  480. padding-right: 20px;
  481. display: flex;
  482. justify-content: space-between;
  483. align-items: center;
  484. .tag{
  485. display: inline-block;
  486. min-width: 76px;
  487. line-height: 30px;
  488. text-align: center;
  489. &.open{
  490. background-color: #ECF2FE;
  491. color: #0052D9;
  492. }
  493. &.close{
  494. background-color: #0052D9;
  495. color: #fff;
  496. }
  497. }
  498. .opt-box{
  499. display: flex;
  500. align-items: center;
  501. gap: 10px;
  502. .icon-drag,.icon-set{
  503. width: 16px;
  504. height: 16px;
  505. margin-left: 10px;
  506. }
  507. }
  508. }
  509. }
  510. </style>