classifylistV2.vue 20 KB

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