Ver Fonte

Merge branch 'master' of http://8.136.199.33:3000/eta_front/eta_front

Karsa há 10 meses atrás
pai
commit
10ceaa640a
59 ficheiros alterados com 3343 adições e 472 exclusões
  1. 225 0
      src/api/modules/approve.js
  2. BIN
      src/assets/img/approve_m/approve.png
  3. BIN
      src/assets/img/approve_m/future-icon.png
  4. 3 0
      src/assets/img/approve_m/future-icon.svg
  5. BIN
      src/assets/img/approve_m/passed-icon.png
  6. 10 0
      src/assets/img/approve_m/passed-icon.svg
  7. 3 0
      src/assets/img/approve_m/passed-msg.svg
  8. BIN
      src/assets/img/approve_m/passed.png
  9. BIN
      src/assets/img/approve_m/pending.png
  10. BIN
      src/assets/img/approve_m/process-icon.png
  11. 6 0
      src/assets/img/approve_m/process-icon.svg
  12. 3 0
      src/assets/img/approve_m/process-msg.svg
  13. BIN
      src/assets/img/approve_m/reject-icon.png
  14. 3 0
      src/assets/img/approve_m/reject-icon.svg
  15. 10 0
      src/assets/img/approve_m/reject-msg.svg
  16. BIN
      src/assets/img/approve_m/reject.png
  17. BIN
      src/assets/img/approve_m/return-icon.png
  18. 5 0
      src/assets/img/approve_m/return-icon.svg
  19. 3 0
      src/assets/img/approve_m/return-msg.svg
  20. BIN
      src/assets/img/approve_m/return.png
  21. BIN
      src/assets/img/approve_m/select.png
  22. BIN
      src/assets/img/approve_m/start.png
  23. 146 0
      src/components/notificationMsg.vue
  24. 65 0
      src/mixins/reportApproveConfig.js
  25. 27 0
      src/routes/modules/approveRoutes.js
  26. 12 0
      src/routes/modules/oldRoutes.js
  27. 23 3
      src/utils/buttonConfig.js
  28. 7 2
      src/views/Home.vue
  29. 386 0
      src/views/approve_manage/approveDetail.vue
  30. 194 0
      src/views/approve_manage/approveEdit.vue
  31. 311 0
      src/views/approve_manage/approveList.vue
  32. 162 0
      src/views/approve_manage/approveSetting.vue
  33. 112 0
      src/views/approve_manage/components/flowEdiotr.vue
  34. 44 0
      src/views/approve_manage/components/flowNode/addNode.vue
  35. 280 0
      src/views/approve_manage/components/flowNode/approveNode.vue
  36. 26 0
      src/views/approve_manage/components/flowNode/endNode.vue
  37. 43 0
      src/views/approve_manage/components/flowNode/startNode.vue
  38. 81 0
      src/views/approve_manage/components/rejectDialog.vue
  39. 60 0
      src/views/approve_manage/components/timeLine.vue
  40. 120 0
      src/views/approve_manage/components/timeLineItem.vue
  41. 185 0
      src/views/approve_manage/components/treeTransfer.vue
  42. 95 0
      src/views/approve_manage/config/tableConfig.js
  43. 39 0
      src/views/approve_manage/css/nodeStyle.scss
  44. 6 0
      src/views/approve_manage/css/pageStyle.scss
  45. 31 0
      src/views/approve_manage/mixins/approveMixins.js
  46. 3 4
      src/views/dataEntry_manage/databaseList.vue
  47. 3 3
      src/views/predictEdb_manage/mixins/mixin.js
  48. 0 1
      src/views/predictEdb_manage/predictEdb.vue
  49. 23 7
      src/views/report_manage/addreportNew.vue
  50. 23 7
      src/views/report_manage/editreportNew.vue
  51. 31 11
      src/views/report_manage/mixins/messagePush.js
  52. 50 15
      src/views/report_manage/reportEn/reportEditor.vue
  53. 126 94
      src/views/report_manage/reportEn/reportlist.vue
  54. 24 9
      src/views/report_manage/reportdtl.vue
  55. 129 131
      src/views/report_manage/reportlist.vue
  56. 41 16
      src/views/smartReport/editReport.vue
  57. 12 2
      src/views/smartReport/reportDetail.vue
  58. 116 166
      src/views/smartReport/reportList.vue
  59. 36 1
      src/views/system_manage/etaBaseConfig.vue

+ 225 - 0
src/api/modules/approve.js

@@ -0,0 +1,225 @@
+import http from "@/api/http.js"
+
+export const approveInterence = {
+    /**
+     * 获取审批流列表
+     * @param {Object} params 
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @param {Number} params.ReportType 报告类型:1-中文研报;2-英文研报;3-智能研报
+     * @param {Number} params.ClassifyFirstId 关联报告一级分类ID
+     * @param {Number} params.ClassifySecondId 关联报告二级分类ID
+     * @param {String} params.Keyword
+     * @param {Number} params.SortRule 排序方式: 1-正序; 2-倒序(默认)
+     * @returns 
+     */
+    getApproveFlowList(params){
+        return http.get("/report_approve/flow/list",params)
+    },
+    /**
+     * 获取报告分类树
+     * @param {Object} params 
+     * @param {Number} params.ReportApproveFlowId 审批流ID(非必填)
+     * @returns 
+     */
+    getReportClassifyTree(params){
+        return http.get("/report_approve/report/classify_tree",params)
+    },
+    /**
+     * 删除审批流
+     * @param {Object} params 
+     * @param {Number} params.ReportApproveFlowId
+     * @returns 
+     */
+    deleteApproveFlow(params){
+        return http.post("/report_approve/flow/remove",params)
+    },
+    /**
+     * 获取审批流详情
+     * @param {Object} params 
+     * @param {Number} params.ReportApproveFlowId
+     * @returns 
+     */
+    getApproveFlowDetail(params){
+        return http.get("/report_approve/flow/detail",params)
+    },
+    /**
+     * 新增审批流
+     * @param {Object} params 
+     * @param {String} params.FlowName 审批流名称
+     * @param {Number} params.ReportType 报告类型:1-中文研报;2-英文研报;3-智能研报
+     * @param {Number} params.ClassifyFirstId 一级分类ID
+     * @param {Number} params.ClassifySecondId 二级分类ID
+     * @param {Object[]} params.Nodes 审批节点
+     * @param {Number} params.Nodes[].ApproveType 审批类型:1-依次审批;2-会签;3-或签
+     * @param {Object[]} params.Nodes[].Users 审批人信息
+     * @param {String} params.Nodes[].Users[].UserType 审批人类型: user-用户; role-角色
+     * @param {Number} params.Nodes[].Users[].UserId 用户/角色ID
+     * @param {String} params.Nodes[].Users[].UserName 用户/角色姓名
+     * @param {String} params.Nodes[].Users[].Sort 依次审批时的排序
+     * @returns 
+     */
+    addNewApproveFlow(params){
+        return http.post("/report_approve/flow/add",params)
+    },
+    /**
+     * 编辑审批流
+     * @param {Object} params 
+     * @param {Number} params.ReportApproveFlowId 审批流Id
+     * 其他参数同上
+     * @returns 
+     */
+    editApproveFlow(params){
+        return http.post("/report_approve/flow/edit",params)
+    },
+
+
+    /**
+     * 获取审批列表
+     * @param {Object} params 
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @param {Number} params.ReportType 报告类型:1-中文研报;2-英文研报;3-智能研报
+     * @param {Number} params.ClassifyFirstId 报告的倒数第二级id
+     * @param {Number} params.ClassifySecondId 报告的倒数第一级id
+     * @param {String} params.Keyword
+     * @param {Number} params.SortRule 排序方式: 1-正序; 2-倒序(默认)
+     * @param {Number} params.SortField 排序字段:1-提交时间;2-处理时间;3-审批时间
+     * @param {Number} params.ListType 列表类型:1-待处理;2-已处理;3-我发起的
+     * @param {Number} params.ApproveState 审批状态:1-待审批;2-已审批/已通过;3-已驳回;4-已撤回/已撤销
+     * @param {Number} params.TimeType 时间类型:1-提交时间;2-处理时间;3-审批时间
+     * @param {String} params.StartTime 开始时间
+     * @param {String} params.EndTime 结束时间
+     * @returns 
+     */
+    getApproveList(params){
+        return http.get("/report_approve/list",params)
+    },
+    /**
+     * 获取审批详情
+     * @param {Object} params
+     * @param {Number} params.ReportApproveId
+     * @returns 
+     */
+    getApproveDetail(params){
+        return http.get("/report_approve/detail",params)
+    },
+    /**
+     * 审批消息通知
+     * @param {Object} params 
+     * @param {Number} params.PageSize
+     * @param {Number} params.CurrentIndex
+     * @returns 
+     */
+    getApproveMsgList(params){
+        return http.get("/report_approve/message/list",params)
+    },
+    /**
+     * 消息通知已读
+     * @param {Object} params 
+     * @param {Number} params.MessageId
+     * @returns 
+     */
+    readApproveMsg(params){
+        return http.post("/report_approve/message/read",params)
+    },
+    /**
+     * 撤销审批
+     * @param {Object} params 
+     * @param {Number} params.ReportApproveId
+     * @returns 
+     */
+    cancelApprove(params){
+        return http.post("/report_approve/cancel",params)
+    },
+    /**
+     * 通过审批
+     * @param {Object} params 
+     * @param {Number} params.ReportApproveId
+     * @returns 
+     */
+    passApprove(params){
+        return http.post("/report_approve/approve",params)
+    },
+    /**
+     * 驳回审批
+     * @param {Object} params 
+     * @param {Number} params.ReportApproveId
+     * @param {String} params.ApproveRemark
+     * @returns 
+     */
+    rejectApprove(params){
+        return http.post("/report_approve/refuse",params)
+    },
+    /**
+     * 校验研报分类是否有审批流
+     * @param {Object} params 
+     * @param {Number} params.ReportType 报告类型:1-中文研报;2-英文研报;3-智能研报
+     * @param {Number} params.ClassifyFirstId 倒数第二级分类的id
+     * @param {Number} params.ClassifySecondId 倒数第一级分类的id
+     * @returns 
+     */
+    checkClassifyApprove(params){
+        return http.post("/report_approve/classify/check_open",params)
+    },
+
+
+
+
+    /*------------研报审批接口----------- */
+    /**
+     * 中文研报提交审批
+     * @param {Object} params 
+     * @param {Number} params.ReportId
+     * @returns 
+     */
+    reportCnSubmit(params){
+        return http.post("/report/approve/submit",params)
+    },
+    /**
+     * 中文研报撤销审批
+     * @param {Object} params 
+     * @param {Number} params.ReportId
+     * @returns 
+     */
+    reportCnCancel(params){
+        return http.post("/report/approve/cancel",params)
+    },
+    /**
+     * 英文研报提交审批
+     * @param {Object} params 
+     * @param {Number} params.ReportId
+     * @returns 
+     */
+    reportEnSubmit(params){
+        return http.post("/english_report/approve/submit",params)
+    },
+    /**
+     * 英文研报撤销审批
+     * @param {Object} params 
+     * @param {Number} params.ReportId
+     * @returns 
+     */
+    reportEnCancel(params){
+        return http.post("/english_report/approve/cancel",params)
+    },
+    /**
+     * 智能研报提交审批
+     * @param {Object} params 
+     * @param {Number} params.ReportId
+     * @returns 
+     */
+    reportSmartSubmit(params){
+        return http.post("/smart_report/approve/submit",params)
+    },
+    /**
+     * 智能研报撤销审批
+     * @param {Object} params 
+     * @param {Number} params.ReportId
+     * @returns 
+     */
+    reportSmartCancel(params){
+        return http.post("/smart_report/approve/cancel",params)
+    },
+
+}

BIN
src/assets/img/approve_m/approve.png


BIN
src/assets/img/approve_m/future-icon.png


+ 3 - 0
src/assets/img/approve_m/future-icon.svg

@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="8" cy="8" r="7" stroke="#C0C4CC" stroke-width="2"/>
+</svg>

BIN
src/assets/img/approve_m/passed-icon.png


+ 10 - 0
src/assets/img/approve_m/passed-icon.svg

@@ -0,0 +1,10 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_2561_11064)">
+<path d="M0 8C0 3.58179 3.58179 0 8 0C12.4182 0 16 3.58179 16 8C16 12.4182 12.4182 16 8 16C3.58179 16 0 12.4182 0 8ZM6.55172 11.0411C6.65221 11.1447 6.78931 11.2048 6.9336 11.2086C7.0779 11.2123 7.2179 11.1593 7.32359 11.061L12.5661 6.18703C12.6724 6.08722 12.735 5.94935 12.7399 5.80357C12.7449 5.65779 12.692 5.51596 12.5927 5.40911C12.4934 5.30227 12.3558 5.23909 12.2101 5.2334C12.0643 5.22771 11.9222 5.27997 11.8149 5.37876L6.98483 9.9029L4.71724 7.56469C4.66696 7.51198 4.60675 7.46975 4.54006 7.44043C4.47338 7.41111 4.40155 7.39529 4.32872 7.39387C4.25589 7.39246 4.1835 7.40548 4.11573 7.43219C4.04795 7.4589 3.98614 7.49876 3.93386 7.54948C3.88157 7.6002 3.83985 7.66077 3.81109 7.7277C3.78233 7.79463 3.76712 7.86659 3.76632 7.93943C3.76552 8.01227 3.77915 8.08455 3.80642 8.15209C3.8337 8.21964 3.87408 8.28111 3.92524 8.33297L6.552 11.0411H6.55172Z" fill="#0052D9"/>
+</g>
+<defs>
+<clipPath id="clip0_2561_11064">
+<rect width="16" height="16" fill="white"/>
+</clipPath>
+</defs>
+</svg>

+ 3 - 0
src/assets/img/approve_m/passed-msg.svg

@@ -0,0 +1,3 @@
+<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M9.50115 0C4.25336 0 0 4.25284 0 9.5C0 14.7472 4.25336 19 9.50115 19C14.7489 19 19 14.7449 19 9.4977C19 4.25054 14.7444 0 9.50115 0ZM14.0439 7.59633L10.3922 11.1855L8.62384 12.9147C8.61695 12.9239 8.60776 12.933 8.59628 12.9445C8.5825 12.9583 8.56642 12.9721 8.55034 12.9859C8.44011 13.0915 8.29542 13.1489 8.14155 13.1489H8.11628C7.95552 13.1489 7.80624 13.0892 7.696 12.979C7.67992 12.9652 7.66614 12.9514 7.65236 12.9399C7.64318 12.9307 7.63629 12.9239 7.6294 12.9147L4.68053 9.96616C4.44168 9.72734 4.45775 9.32318 4.71498 9.06599C4.84588 8.9351 5.02043 8.86162 5.19727 8.86162C5.35803 8.86162 5.50731 8.92132 5.61755 9.03155L8.13006 11.5438L9.4644 10.2394L13.1183 6.65023C13.2286 6.5423 13.3756 6.48489 13.534 6.48489C13.7132 6.48489 13.89 6.56067 14.0209 6.69386C14.2735 6.95564 14.2873 7.3598 14.0439 7.59633Z" fill="#68BB8D"/>
+</svg>

BIN
src/assets/img/approve_m/passed.png


BIN
src/assets/img/approve_m/pending.png


BIN
src/assets/img/approve_m/process-icon.png


+ 6 - 0
src/assets/img/approve_m/process-icon.svg

@@ -0,0 +1,6 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="8" cy="8" r="7" fill="white" stroke="#0052D9" stroke-width="2"/>
+<circle cx="4" cy="8.5" r="1.5" fill="#0052D9"/>
+<circle cx="8" cy="8.5" r="1.5" fill="#0052D9"/>
+<circle cx="12" cy="8.5" r="1.5" fill="#0052D9"/>
+</svg>

+ 3 - 0
src/assets/img/approve_m/process-msg.svg

@@ -0,0 +1,3 @@
+<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M9.5 0C4.25327 0 0 4.25324 0 9.50002C0 12.894 1.81074 16.0301 4.75 17.7273C7.68945 19.4242 11.3107 19.4242 14.25 17.7273C17.1895 16.0303 19 12.8942 19 9.50002C19.0002 4.25343 14.7467 0 9.5 0ZM9.5 14.7779C8.91712 14.7779 8.44444 14.3053 8.44444 13.7224C8.44444 13.3454 8.64566 12.9968 8.97222 12.8083C9.29879 12.6198 9.70122 12.6198 10.0278 12.8083C10.3543 12.9968 10.5556 13.3454 10.5556 13.7224C10.5556 14.3051 10.0831 14.7779 9.5 14.7779ZM10.5556 10.5556C10.5556 11.1888 10.1333 11.6111 9.5 11.6111C8.86667 11.6111 8.44444 11.1888 8.44444 10.5556V5.27788C8.44444 4.64459 8.86667 4.22234 9.5 4.22234C10.1333 4.22234 10.5556 4.64459 10.5556 5.27788V10.5556Z" fill="#E98F36"/>
+</svg>

BIN
src/assets/img/approve_m/reject-icon.png


+ 3 - 0
src/assets/img/approve_m/reject-icon.svg

@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 7.93442C0.036889 5.7137 0.851645 3.75612 2.51279 2.18473C4.14539 0.640302 6.11295 -0.0867217 8.35598 0.00822671C10.511 0.0994046 12.3505 0.946285 13.8273 2.5179C15.3632 4.15237 16.0877 6.11726 15.9915 8.35695C15.8993 10.5061 15.0568 12.3422 13.4922 13.8175C11.8572 15.3593 9.89104 16.0873 7.6479 15.9917C5.49497 15.8998 3.6592 15.0518 2.18102 13.4843C0.735039 11.951 0.0268387 10.1078 0 7.93442ZM7.19038 7.98972C7.168 8.01406 7.15441 8.02971 7.1399 8.04434C6.69461 8.48983 6.24909 8.93521 5.80368 9.38081C5.46322 9.72142 5.12266 10.062 4.78278 10.4031C4.62677 10.5596 4.57172 10.747 4.62471 10.962C4.68981 11.2261 4.95203 11.4084 5.21859 11.3856C5.37289 11.3724 5.49612 11.3054 5.60347 11.1979C6.38351 10.4164 7.16423 9.63573 7.94484 8.85489C7.96071 8.839 7.97716 8.82392 8.01348 8.78907C8.02684 8.81352 8.03392 8.83797 8.04968 8.85374C8.82812 9.63401 9.60781 10.413 10.3861 11.1935C10.5262 11.3339 10.6882 11.4011 10.8888 11.3838C11.1686 11.3595 11.4141 11.0681 11.3896 10.7885C11.3755 10.6285 11.31 10.4993 11.1977 10.3872C10.4339 9.62464 9.6712 8.86083 8.90818 8.09747C8.80505 7.99418 8.80493 7.99429 8.90749 7.89169C9.67188 7.12696 10.4359 6.36189 11.201 5.59784C11.3367 5.46233 11.4045 5.30466 11.3859 5.11042C11.3538 4.77553 11.0216 4.53764 10.6937 4.61397C10.5534 4.64653 10.4503 4.73097 10.3522 4.82923C9.58337 5.60013 8.81316 6.36966 8.04454 7.1409C8.00776 7.17781 7.98801 7.17895 7.95055 7.14113C7.57515 6.76271 7.19781 6.38623 6.82104 6.00929C6.41195 5.60002 6.0032 5.19029 5.59353 4.78159C5.41857 4.607 5.2106 4.55181 4.9775 4.63751C4.58931 4.78021 4.47145 5.27975 4.78963 5.59499C5.46014 6.25928 6.12528 6.92918 6.79294 7.59645C6.92291 7.72659 7.0547 7.85558 7.19038 7.98972Z" fill="#AD352F"/>
+</svg>

+ 10 - 0
src/assets/img/approve_m/reject-msg.svg

@@ -0,0 +1,10 @@
+<svg width="19" height="19" viewBox="0 0 19 19" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g clip-path="url(#clip0_5316_6053)">
+<path d="M9.5 19C4.25362 19 0 14.7464 0 9.5C0 4.25362 4.25362 0 9.5 0C14.7464 0 19 4.25362 19 9.5C19 14.7464 14.7464 19 9.5 19ZM9.5 8.38058L5.57808 4.45708C5.50453 4.38405 5.41731 4.32621 5.32141 4.28688C5.2255 4.24756 5.12279 4.2275 5.01914 4.22787C4.91548 4.22824 4.81292 4.24902 4.71729 4.28903C4.62167 4.32903 4.53487 4.38749 4.46183 4.46104C4.38799 4.53391 4.32929 4.62067 4.28911 4.71631C4.24892 4.81195 4.22804 4.9146 4.22767 5.01834C4.22731 5.12209 4.24745 5.22488 4.28696 5.3208C4.32647 5.41673 4.38455 5.5039 4.45787 5.57729L8.38058 9.5L4.45708 13.4219C4.38405 13.4955 4.32621 13.5827 4.28688 13.6786C4.24756 13.7745 4.2275 13.8772 4.22787 13.9809C4.22824 14.0845 4.24902 14.1871 4.28903 14.2827C4.32903 14.3783 4.38749 14.4651 4.46104 14.5382C4.53391 14.612 4.62067 14.6707 4.71631 14.7109C4.81195 14.7511 4.9146 14.772 5.01834 14.7723C5.12209 14.7727 5.22488 14.7525 5.3208 14.713C5.41673 14.6735 5.5039 14.6154 5.57729 14.5421L9.5 10.6194L13.4219 14.5421C13.4955 14.6152 13.5827 14.673 13.6786 14.7123C13.7745 14.7517 13.8772 14.7717 13.9809 14.7713C14.0845 14.771 14.1871 14.7502 14.2827 14.7102C14.3783 14.6702 14.4651 14.6117 14.5382 14.5382C14.612 14.4653 14.6707 14.3785 14.7109 14.2829C14.7511 14.1873 14.772 14.0846 14.7723 13.9809C14.7727 13.8771 14.7525 13.7743 14.713 13.6784C14.6735 13.5825 14.6154 13.4953 14.5421 13.4219L10.6194 9.5L14.5421 5.57808C14.6152 5.50453 14.673 5.41731 14.7123 5.32141C14.7517 5.2255 14.7717 5.12279 14.7713 5.01914C14.771 4.91548 14.7502 4.81292 14.7102 4.71729C14.6702 4.62167 14.6117 4.53487 14.5382 4.46183C14.4653 4.38799 14.3785 4.32929 14.2829 4.28911C14.1873 4.24892 14.0846 4.22804 13.9809 4.22767C13.8771 4.22731 13.7743 4.24745 13.6784 4.28696C13.5825 4.32647 13.4953 4.38455 13.4219 4.45787L9.5 8.38058Z" fill="#D81E06"/>
+</g>
+<defs>
+<clipPath id="clip0_5316_6053">
+<rect width="19" height="19" fill="white"/>
+</clipPath>
+</defs>
+</svg>

BIN
src/assets/img/approve_m/reject.png


BIN
src/assets/img/approve_m/return-icon.png


+ 5 - 0
src/assets/img/approve_m/return-icon.svg

@@ -0,0 +1,5 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="8" cy="8" r="8" fill="#999999"/>
+<path d="M6.21355 4.34426C6.26948 4.28793 6.34477 4.255 6.42411 4.25215C6.50345 4.24931 6.5809 4.27677 6.64072 4.32896C6.70055 4.38115 6.73827 4.45416 6.74622 4.53315C6.75418 4.61214 6.73177 4.6912 6.68355 4.75426L6.65563 4.78635L5.10855 6.33301L6.65563 7.87968C6.70906 7.9331 6.74133 8.00407 6.74646 8.07945C6.75159 8.15483 6.72924 8.22951 6.68355 8.28968L6.65563 8.32176C6.60221 8.3752 6.53124 8.40746 6.45586 8.4126C6.38048 8.41773 6.3058 8.39538 6.24563 8.34968L6.21355 8.32176L4.44605 6.55385C4.39262 6.50043 4.36035 6.42946 4.35521 6.35408C4.35008 6.2787 4.37243 6.20402 4.41813 6.14385L4.44605 6.11218L6.21355 4.34426Z" fill="white" stroke="white" stroke-width="0.3"/>
+<path d="M9.25023 6.02051C9.87811 6.01989 10.4811 6.26579 10.9296 6.70528C11.378 7.14477 11.636 7.74273 11.648 8.3705C11.66 8.99827 11.4251 9.60566 10.9938 10.062C10.5625 10.5183 9.96934 10.7871 9.3419 10.8105L9.25023 10.8122H4.6669C4.58772 10.8122 4.5115 10.7821 4.45365 10.728C4.3958 10.674 4.36062 10.6 4.35522 10.521C4.34982 10.442 4.37461 10.3639 4.42458 10.3025C4.47454 10.241 4.54596 10.2009 4.6244 10.1901L4.6669 10.1872H9.25023C9.71244 10.1872 10.1563 10.0064 10.4871 9.68358C10.8179 9.36073 11.0093 8.92135 11.0205 8.45927C11.0317 7.99719 10.8618 7.54905 10.5471 7.21054C10.2323 6.87204 9.79773 6.67001 9.33606 6.64759L9.25023 6.64551H4.6669C4.58772 6.64548 4.5115 6.61541 4.45365 6.56135C4.3958 6.5073 4.36062 6.4333 4.35522 6.35431C4.34982 6.27532 4.37461 6.19722 4.42458 6.1358C4.47454 6.07438 4.54596 6.03422 4.6244 6.02343L4.6669 6.02051H9.25023Z" fill="white" stroke="white" stroke-width="0.3"/>
+</svg>

+ 3 - 0
src/assets/img/approve_m/return-msg.svg

@@ -0,0 +1,3 @@
+<svg width="20" height="18" viewBox="0 0 20 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12.6234 14.45C12.4885 14.45 12.3592 14.4018 12.2638 14.316C12.1685 14.2302 12.1149 14.1138 12.1149 13.9924C12.1149 13.871 12.1685 13.7546 12.2638 13.6688C12.3592 13.583 12.4885 13.5348 12.6234 13.5348C14.2122 13.5348 15.5047 12.3715 15.5047 10.9416C15.5047 9.51163 14.2122 8.34834 12.6234 8.34834H5.21424L8.66102 11.4501C8.75106 11.5369 8.80011 11.6518 8.79783 11.7705C8.79555 11.8893 8.74211 12.0026 8.64879 12.0865C8.55547 12.1705 8.42957 12.2185 8.29765 12.2205C8.16572 12.2225 8.0381 12.1783 7.94169 12.0972L3.26746 7.89071L7.94169 3.6839C8.03708 3.59805 8.16646 3.54982 8.30136 3.54982C8.43626 3.54982 8.56563 3.59805 8.66102 3.6839C8.7564 3.76975 8.80999 3.88618 8.80999 4.00759C8.80999 4.129 8.7564 4.24544 8.66102 4.33129L5.21424 7.43308H12.6234C14.7729 7.43308 16.5217 9.00702 16.5217 10.9416C16.5217 12.8761 14.7729 14.45 12.6234 14.45ZM10 0C4.48576 0 0 4.03749 0 9C0 13.9625 4.48576 18 10 18C15.5139 18 20 13.9625 20 9C20 4.03749 15.5139 0 10 0Z" fill="#797979"/>
+</svg>

BIN
src/assets/img/approve_m/return.png


BIN
src/assets/img/approve_m/select.png


BIN
src/assets/img/approve_m/start.png


+ 146 - 0
src/components/notificationMsg.vue

@@ -0,0 +1,146 @@
+<template>
+    <!-- 消息通知 -->
+    <el-popover
+        placement="bottom"
+        width="443"
+        trigger="click" v-model="visible">
+        <div class="notifation-wrap">
+            <!-- 防止tabs在popover前渲染,会导致tab选中状态不正确 -->
+            <el-tabs v-model="activeName" v-if="visible">
+                <el-tab-pane :label="`研报审批(${UnreadTotal})`" name="first"></el-tab-pane>
+            </el-tabs>
+            <div class="massage-list" v-if="visible">
+                <div class="message-item" :class="{'IsRead':item.IsRead}" v-for="item in msgList" :key="item.Id" @click="readMsg(item)">
+                    <span class="icon">
+                        <img :src="require(`@/assets/img/approve_m/${approveState[item.ApproveState]||'process'}-msg.svg`)" alt="">
+                    </span>
+                    <div class="info">
+                        <div class="head">
+                            <span class="title">{{item.Content}}</span>
+                            <span class="time">{{item.CreateTime}}</span>
+                        </div>
+                        <div class="content">{{item.Remark||''}}&nbsp;</div>
+                    </div>
+                </div>
+                <tableNoData v-if="!msgList.length" text="暂无消息"></tableNoData>
+            </div>
+            <el-button type="text" class="close-btn" @click="visible=false">关闭</el-button>
+        </div>
+        <span slot="reference" @click="visible = !visible" class="msg-btn">
+            <svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+                <path d="M16.7344 15.4904L15.2941 12.9564V7.84847C15.2941 5.89142 13.8231 3.77337 11.6786 2.99732C11.5741 1.96012 10.8811 1.20374 9.97287 1.20374C9.06595 1.20374 8.37036 1.96014 8.26717 2.99732C6.12392 3.77337 4.65292 5.8914 4.65292 7.84847V12.9564L3.14258 15.6146C3.04183 15.7903 3.04429 16.0054 3.14504 16.1799C3.24581 16.3544 3.43263 16.4601 3.63415 16.4601H7.22871C7.49293 17.7357 8.62233 18.6967 9.97289 18.6967C11.3247 18.6967 12.4541 17.7357 12.7171 16.4601H16.3116C16.3215 16.4601 16.3288 16.4601 16.3374 16.4601C16.6508 16.4601 16.904 16.2082 16.904 15.8948C16.904 15.7362 16.8401 15.5925 16.7344 15.4904ZM9.97287 2.33803C10.1769 2.33803 10.3415 2.49286 10.4472 2.7239C10.2899 2.70792 10.1375 2.67106 9.97287 2.67106C9.8082 2.67106 9.65583 2.70792 9.49851 2.7239C9.60422 2.49284 9.76889 2.33803 9.97287 2.33803ZM9.97287 17.5636C9.25396 17.5636 8.65303 17.1016 8.41951 16.4601H11.5262C11.2927 17.1015 10.693 17.5636 9.97287 17.5636ZM4.60745 15.3282L5.71102 13.3853C5.76015 13.3017 5.78719 13.2034 5.78719 13.1051V7.84847C5.78719 5.93934 7.57648 3.80413 9.97287 3.80413C12.3692 3.80413 14.161 5.93934 14.161 7.84847V13.1051C14.161 13.2034 14.1868 13.3017 14.2347 13.3853L15.3395 15.3282H4.60745Z" fill="currentColor"/>
+            </svg>
+            <div class="unread" v-if="UnreadTotal">{{UnreadTotal>99?'99+':UnreadTotal}}</div>
+        </span>
+    </el-popover>
+</template>
+
+<script>
+import {approveInterence} from '@/api/modules/approve.js';
+export default {
+    data() {
+        this.approveState=['','process','passed','reject','return',]
+        return {
+            activeName:'first',
+            visible:false,
+            msgList:[],
+            UnreadTotal:0
+        };
+    },
+    watch:{
+        visible(val){
+            if(val){
+                this.getMsgList()
+            }
+        }
+    },
+    methods:{
+        readMsg(msg){
+            const {ApproveState,ReportApproveId,Id} = msg
+            approveInterence.readApproveMsg({
+                MessageId:Id
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.getMsgList()
+            })
+            const type = ApproveState===1?'approve':ApproveState===4?'detail':'myself'
+            this.$router.push({
+                path:'/approveDetail',
+                query:{
+                    type,
+                    approveId:ReportApproveId
+                }
+            })
+        },
+        getMsgList(){
+            approveInterence.getApproveMsgList({
+                CurrentIndex:1,
+                PageSize:1000
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.msgList = res.Data.List||[]
+                this.UnreadTotal = res.Data.UnreadTotal||0
+            })
+        }
+    }
+};
+</script>
+
+<style lang="scss">
+.notifation-wrap{
+    position:relative;
+    .massage-list{
+        padding: 0 10px;
+        max-height: 320px;
+        overflow-y: auto;
+        .message-item{
+            cursor: pointer;
+            display: flex;
+            padding: 5px 0;
+            border-bottom: 1px solid #E4E7ED;
+            color:#333;
+            &.IsRead{
+                color:#999;
+            }
+            .icon{
+                width:40px;
+                display: flex;
+                align-items: flex-start;
+                justify-content: center;
+            }
+            .info{
+                flex:1;
+                .head{
+                    display: flex;
+                    justify-content: space-between;
+                }
+
+            }
+        }
+    }
+    .close-btn{
+        position:absolute;
+        top:0;
+        right:0;
+        box-sizing: border-box;
+    }
+}
+.msg-btn{
+    cursor: pointer;
+    display: inline-block;
+    width: 50px;
+    text-align: center;
+    position: relative;
+    .unread{
+        position: absolute;
+        width:23px;
+        height:14px;
+        color:#fff;
+        background-color:#AD352F;
+        border-radius: 40px;
+        top:-4px;
+        right:4px;
+        font-size: 12px;
+    }
+}
+</style>

+ 65 - 0
src/mixins/reportApproveConfig.js

@@ -0,0 +1,65 @@
+/*
+    研报及审批配置,涉及到:
+    智能研报
+    中文研报(除晨周报)
+    英文研报
+    审批流配置
+    审批管理
+    审批详情
+ */
+import {etaBaseConfigInterence} from '@/api/modules/etaBaseConfigApi.js';
+import {approveInterence} from '@/api/modules/approve.js';
+export default{
+    data(){
+        return{
+            ReportApproveType:'',
+            IsReportApprove:false,
+            pageLoading:false,
+            hasApproveFlow:false,
+            checkLoading:false,
+        }
+    },
+    computed:{
+        //是否开启审批流
+        isApprove(){
+            return this.IsReportApprove
+        },
+        //是否开启了ETA审批流
+        isETAApprove(){
+            return this.IsReportApprove&&this.ReportApproveType==='eta'
+        },
+        //是否开启了接口审批
+        isOtherApprove(){
+            return this.IsReportApprove&&this.ReportApproveType==='other'
+        },
+    },
+    methods:{
+        async getBaseConfig(){
+            //从基本配置中获取是否开启审批流的数据
+            this.pageLoading = true
+            const res = await etaBaseConfigInterence.getBaseConfig()
+            this.pageLoading = false
+            if(res.Ret!==200) return
+            const {IsReportApprove='',ReportApproveType=''} = res.Data
+            this.IsReportApprove = IsReportApprove==='true'?true:false,
+            this.ReportApproveType = ReportApproveType
+        },
+        //检查是否有审批流
+        checkClassifyNameArr(type=1,classify=[]){
+            this.checkLoading=true
+            let params = {
+                ReportType:type,
+                ClassifyFirstId:classify[classify.length-2]||0,
+                ClassifySecondId:classify[classify.length-1]||0,
+            }
+            approveInterence.checkClassifyApprove(params).then(res=>{
+                this.checkLoading=false
+                if(res.Ret!==200) return 
+                this.hasApproveFlow = res.Data||false
+            })
+        },
+    },
+    mounted(){
+        this.getBaseConfig()
+    }
+}

+ 27 - 0
src/routes/modules/approveRoutes.js

@@ -0,0 +1,27 @@
+const home = r => require.ensure([], () => r(require('@/views/Home.vue')), 'Home'); //主页
+export default [
+    {
+        path:'/',
+        component:home,
+        name:'审批管理',
+        hidden:false,
+        icon_path: require('@/assets/img/home/data_ic.png'),
+        children:[{
+            path:'approveList',
+            name:'审批列表',
+            component:()=>import('@/views/approve_manage/approveList.vue'),
+            hidden:false
+        },{
+            path:'approveDetail',
+            name:'审批详情',
+            component:()=>import('@/views/approve_manage/approveDetail.vue'),
+            hidden:false,
+            meta: {
+                pathFrom: "approveList",
+                pathName: "审批列表",
+                keepAlive: false,
+              },
+        }
+        ]
+    }
+]

+ 12 - 0
src/routes/modules/oldRoutes.js

@@ -323,6 +323,18 @@ export default [
         name: "外部链接配置",
         hidden: true,
       },
+      {
+        path: "approveSetting",
+        component: () => import("@/views/approve_manage/approveSetting.vue"),
+        name: "审批流配置",
+        hidden: true,
+      },
+      {
+        path: "approveEdit",
+        component: () => import("@/views/approve_manage/approveEdit.vue"),
+        name: "编辑审批流",
+        hidden:true,
+      },
       {
         path: "dataSourceAccountList",
         component: () => import("@/views/dataSource_manage/accountList.vue"),

+ 23 - 3
src/utils/buttonConfig.js

@@ -631,7 +631,7 @@ export const baseConfigPermission = {
     etaBaseConfig_ppt:'etaBaseConfig:ppt',
     etaBaseConfig_watermark:'etaBaseConfig:watermark',
     etaBaseConfig_watermark_ybChart:'etaBaseConfig:watermark:ybChart',//如果没权限,表单不显示也不校验
-
+    etaBaseConfig_approve:'etaBaseConfig:approve',//研报审批
 }
 
 /*-----------外部链接配置-------- */
@@ -641,11 +641,30 @@ export const outlinkConfigPermission = {
     outlinkListConfig_edit:'outlinkListConfig:edit',//编辑
     outlinkListConfig_del:'outlinkListConfig:del',//删除
 }
+/*----------审批流配置----*/
+export const approveFlowPermission = {
+    reportApprove_save:'reportApprove:save',//保存
+    reportApprove_remove:'reportApprove:remove',//删除
+    reportApprove_edit:'reportApprove:edit',//编辑审批流(按钮)
+    reportApprove_add:'reportApprove:add',//添加审批流
+}
+/*
+ * --------------------------------------------------------------------------审批管理------------------------------------------------
+*/
+export const approvePermission = {
+    reportApprove_approve:'reportApprove:approve',//审批(列表中的按钮)
+    reportApprove_reject:'reportApprove:reject',//驳回(列表中的按钮)
+    reportApprove_agree:'reportApprove:agree',//通过(审批详情-通过按钮)
+    reportApprove_detail:'reportApprove:detail',//详情(列表中的按钮)
+    reportApprove_rejectreason:'reportApprove:rejectreason',//驳回理由(列表中的按钮)
+    reportApprove_return:'reportApprove:return',//返回(审批详情-返回按钮)
+    reportApprove_repeal:'reportApprove:repeal',//撤回(列表中的按钮,审批详情-撤回按钮)
+}
 
 
 //创建了新的ManageBtn记得添加到这里
 const btnMap  = {
-    reportManageBtn,enReportManageBtn,
+    reportManageBtn,enReportManageBtn,smartReportManageBtn,
     classifyBtn,enClassifyBtn,authorManage,
     enChartPermission,cloudDisk,
     pptPermission,enPPTPermission,
@@ -656,7 +675,8 @@ const btnMap  = {
     statisticPermission,stockPlantPermission,
     productPricePermission,sysDepartPermission,
     operateAuthPermission,baseConfigPermission,
-    outlinkConfigPermission
+    outlinkConfigPermission,approveFlowPermission,
+    approvePermission
 }
 
 /**

+ 7 - 2
src/views/Home.vue

@@ -248,7 +248,8 @@
                 style="width: 84px;height: 24; cursor: pointer;" />
                 </div>
               </div>
-
+               <!-- 消息通知 -->
+              <notification-msg ref="notification"/>
               <el-dropdown trigger="click" style="width:130px;">
                 <span class="el-dropdown-link userinfo-inner">
                   <img src="~@/assets/img/home/avatar.png"/>
@@ -316,13 +317,15 @@ import questionnaireDia from "../components/questionnaireDia.vue";
 import EventBus from "@/api/bus.js";
 
 import {recordActiveLoginFun,loginEndCalc} from "@/utils/TimeOnPage.js"
+import NotificationMsg from "../components/notificationMsg.vue";
 
 export default {
   components: {
     PwdDlg,
     questionMsgDia,
     questionnaireDia,
-  },
+    NotificationMsg
+},
   inject: ["reload"],
   filters: {
     formatDate(e) {
@@ -463,6 +466,7 @@ export default {
       //链接系统
       linkSystems: this.$setting.linkSystems,
       bus_code:"",
+
     };
   },
   created() {
@@ -488,6 +492,7 @@ export default {
       this.getMenuList();
     }
     this.getPublicSettings();
+    this.$refs.notification&&this.$refs.notification.getMsgList()
   },
   methods: {
     handleClickSubMenuItem(item,e){

+ 386 - 0
src/views/approve_manage/approveDetail.vue

@@ -0,0 +1,386 @@
+<template>
+    <!-- 审批详情:查看、进行审批操作 -->
+    <div class="approve-detail-wrap" v-if="isETAApprove">
+        <div class="approve-detail">
+            <div class="approve-info">
+                <span>研报名称:{{reportInfo.title||''}}</span>
+                <span>研报分类:{{reportInfo.classify||''}}</span>
+                <span style="min-width: 100px;">发起人:{{reportInfo.approver||''}}</span>
+            </div>
+            <div class="approve-content" 
+                v-loading="isLoading"
+                element-loading-text="研报加载中...">
+                <component v-if="reportInfo.reportId&&!isError"
+                    :is="reportInfo.componentName"
+                    :reportId="reportInfo.reportId"
+                    :isPreview="true"
+                    :isEn="reportInfo.type===2"
+                    @reportStartLoading="isLoading=true"
+                    @reportEndLoading="isLoading=false"
+                    @reportError="isError=true"
+                ></component>
+                <tableNoData v-if="isError" text="无法获取到报告内容,该报告可能已被删除!"></tableNoData>
+            </div>
+        </div>
+        <div class="approve-tool">
+            <div class="tool-btn">
+                <!-- 根据审批的状态决定显示 -->
+                <el-button type="danger" @click="changeApprove('reject')"
+                    v-if="formType==='approve'&&approveInfo.isCurrentApprover&&permissionBtn.isShowBtn('approvePermission','reportApprove_reject')">驳回</el-button>
+                <el-button type="primary" @click="changeApprove('pass')"
+                    v-if="formType==='approve'&&approveInfo.isCurrentApprover&&permissionBtn.isShowBtn('approvePermission','reportApprove_agree')">同意</el-button>
+                <el-button type="primary" @click="changeApprove('return')"
+                    v-if="formType==='myself'&&approveInfo.state!==4&&permissionBtn.isShowBtn('approvePermission','reportApprove_repeal')">撤销</el-button>
+                <el-button type="primary" plain @click="$router.replace(`/approveList?formType=${formType}`)">返回</el-button>
+            </div>
+            <div class="approve-timeline-wrap">
+                <p>审批流程</p>
+                <div class="timeline">
+                    <TimeLine 
+                        :TimeLineData="TimeLineData"
+                    />
+                </div>
+                <div class="approve-status" >
+                    <img :src="require(`@/assets/img/approve_m/${approveInfo.stateText||'pending'}.png`)" alt="">
+                </div>
+            </div>
+        </div>
+        <RejectDialog 
+            :isDetailDialogShow="isDetailDialogShow"
+            :isEdit="true"
+            @close="isDetailDialogShow=false;"
+            @edit="rejectApprove"
+        />
+    </div>
+    <div class="nodata-wrap approve-page-wrap" v-else>
+        <tableNoData :text="pageLoading?'':'系统暂未开通审批流程,请开启审批流程后再进行操作!'"></tableNoData>
+    </div>
+</template>
+
+<script>
+import ReportDetail from '@/views/smartReport/reportDetail.vue';
+import Reportdtl from '@/views/report_manage/reportdtl.vue'
+import TimeLine from './components/timeLine.vue';
+import RejectDialog from './components/rejectDialog.vue';
+import {approveInterence} from '@/api/modules/approve.js';
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
+
+const ApproveType = ['','依次审批','会签','或签']
+const ApproveState = ['','待审批','已同意','已驳回']
+export default {
+    mixins:[reportApproveConfig],
+    components: { RejectDialog },
+    data() {
+        return {
+            isError:false,
+            isLoading:false,
+            isDetailDialogShow:false,
+            TimeLineData:[],
+            formType:'detail',//进入审批详情的方式:approve(待处理)/detail(已处理)/myself(我发起的)
+            reportInfo:{ //报告相关信息
+                reportId:0,//研报or智能研报的报告id
+                title:'',
+                classify:'',
+                approver:'',
+                componentName:'',
+                type:0,//1中文研报 2英文研报 3智能研报
+            },
+            approveInfo:{//审批相关的信息
+                state:1,//当前审批的状态:1-待审批;2-已同意;3-已驳回;4-已撤回
+                stateText:'pending',//审批状态对应图片文字:待审批(pending),已同意(passed),已驳回(reject),已撤回(return)
+                isCurrentApprover:false,//审批进行中的节点审批人是否是当前用户,控制通过&驳回按钮显示
+            },
+        };
+    },
+    computed:{
+        UserId(){
+            return Number(localStorage.getItem("AdminId"));
+        }
+    },
+    methods: {
+        getApproveDetail(){
+            const {type,approveId} = this.$route.query
+            if(!approveId) return 
+            approveInterence.getApproveDetail({
+                ReportApproveId:Number(approveId)
+            }).then(res=>{
+                if(res.Ret!==200) return
+                //格式化时间线数据 
+                this.formatTimeLineData(res.Data)
+                const {Report={},Approve={}} = res.Data||{}
+                this.reportInfo = {
+                    reportId:Report.ReportId||0,
+                    title:Report.ReportTitle||'',
+                    classify:Report.ReportClassify||'',
+                    approver:Approve.ApplyUserName||'',
+                    componentName:Report.ReportType===3?'ReportDetail':'Reportdtl',
+                    type:Report.ReportType
+                }
+                this.formType = type||'detail'
+                this.approveInfo.state=Approve.State
+                this.approveInfo.stateText=['','pending','passed','reject','return'][Approve.State]
+            })
+        },
+        //转换接口数据
+        formatTimeLineData({Approve={},ApproveFlowNodes=[]}){
+            //发起人节点
+            const startNode = {
+                nodeType:1,
+                nodeText:'发起人:',
+                nodeStatus:'passed',
+                approveList:[{
+                    approverName:Approve.ApplyUserName||'',
+                    approveTime:Approve.CreateTime||''
+                }]
+            }
+            //排序过的审批节点,遍历
+            let currentIndex = 0
+            let Nodes = ApproveFlowNodes.map((i,index)=>{
+                //找到当前节点的index
+                if(i.ReportApproveNodeId===Approve.CurrNodeId){
+                    currentIndex = index
+                }
+                //审批节点只有一个人时不显示是什么审批流
+                const strApproveType = `(${ApproveType[i.ApproveType]})`
+                const node = {
+                    nodeType:2,
+                    nodeText:'审批人:'+i.Users.length+'人'+(i.Users.length>1?strApproveType:''),
+                    nodeStatus:i.ReportApproveNodeId===Approve.CurrNodeId?'process':'future',
+                    approveType:ApproveType[i.ApproveType]
+                }
+                const approveList = i.Users.map(u=>{
+                    const {State='',ApproveTime='',ApproveRemark=''}=u.ApproveRecord||{}
+                    return {
+                        approverName:u.UserName,
+                        approveStatus:ApproveState[State]||'',
+                        approveTime:ApproveTime,
+                        approveReason:ApproveRemark
+                    }
+                })
+                //检测当前节点的User与当前用户是否匹配 且审批需要是待审批状态
+                if(i.ReportApproveNodeId===Approve.CurrNodeId&&Approve.State===1){
+                    //当前节点的User中,有没有当前用户
+                    const hasUser = i.Users.findIndex(u=>u.UserId===this.UserId)
+                    if(hasUser!==-1){
+                        //只有依次审批需要看顺序
+                        if(i.ApproveType===1){
+                            this.approveInfo.isCurrentApprover = i.Users[hasUser].ApproveRecord?true:false
+                        }else{
+                            this.approveInfo.isCurrentApprover = true
+                        }
+                    }else{
+                        this.approveInfo.isCurrentApprover = false
+                    }
+                }
+                node.approveList = approveList
+                return node
+            })
+            //将当前节点之前的置为通过节点,当前节点之后的置为未进行节点
+            Nodes.forEach((n,index)=>{
+                if(index<currentIndex){
+                    n.nodeStatus = 'passed'
+                }
+                if(index>currentIndex){
+                    n.nodeStatus = 'future'
+                }
+            })
+
+            if(!Nodes.length){
+                this.TimeLineData = [startNode,...Nodes]
+                return
+            }
+
+            //如果当前审批是已驳回,移除当前节点后面的节点
+            if(Approve.State===3){
+                Nodes = Nodes.filter((_,index)=>index<=currentIndex)
+                Nodes[currentIndex].nodeStatus = 'reject'
+            }
+
+            //如果当前审批已撤销,移除当前节点后面的节点,在最后加上撤销节点
+            if(Approve.State===4){
+                Nodes = Nodes.filter((_,index)=>index<=currentIndex)
+                //检查最后一个节点是否有人审批
+                let hasApprove = false
+                let stateNum = 0
+                Nodes[currentIndex].approveList.forEach(u=>{
+                    if(u.approveStatus&&u.approveStatus!=='待审批'){
+                        hasApprove = true
+                    }
+                    //依次审批和会签,计算已同意的数量
+                    if(u.approveStatus==='已同意'){
+                        stateNum++
+                    }
+                    if(u.approveStatus==='已驳回'){
+                        Nodes[currentIndex].nodeStatus = 'reject'
+                    }
+                })
+                //若审批撤销,则检查当前节点是否是通过节点
+                if(Nodes[currentIndex].approveType!=='或签'&&stateNum===Nodes[currentIndex].approveList.length){
+                    Nodes[currentIndex].nodeStatus = 'passed'
+                }
+                if(Nodes[currentIndex].approveType==='或签'&&stateNum>0){
+                    Nodes[currentIndex].nodeStatus = 'passed'
+                }
+                //若没有人审批,则把这个节点删除
+                !hasApprove&&(Nodes.pop())
+                //在最后加上撤销节点
+                Nodes.push({
+                    nodeType:3,
+                    nodeText:'发起人:',
+                    nodeStatus:'return',
+                    approveList:[{
+                        approverName:(Approve.ApplyUserName||'')+'(已撤销)',
+                        approveTime:Approve.ModifyTime||''
+                    }],
+                })
+            }
+
+            //如果当前审批已同意,则最后一个节点状态改为已同意
+            if(Approve.State===2){
+                Nodes[currentIndex].nodeStatus = 'passed'
+            }
+
+            //再次遍历Nodes
+            //1.去除已同意的或签节点,没有审批的审批人状态
+            //2.去除已驳回的节点,没有参与审批的审批人的状态
+            Nodes.forEach(n=>{
+                if(n.nodeStatus==='passed'||n.nodeStatus==='reject'){
+                    n.approveList.forEach(a=>{
+                        if(a.approveStatus==='待审批'){
+                            a.approveStatus = ''
+                        }
+                    })
+                }
+            })
+
+            this.TimeLineData = [startNode,...Nodes]
+        },
+        async changeApprove(type){
+            const {approveId} = this.$route.query
+            if(!approveId) return
+            if(type==='reject'){
+                this.isDetailDialogShow = true
+                return 
+            }
+            let res = null
+            if(type==='return'){
+                res = await approveInterence.cancelApprove({
+                    ReportApproveId:Number(approveId)
+                })
+            }
+            if(type==='pass'){
+                res = await approveInterence.passApprove({
+                    ReportApproveId:Number(approveId)
+                })
+            }
+            if(res.Ret!==200) return 
+            this.$message.success(`${type==='return'?'撤销':'通过'}成功`)
+            type!=='reject'&&(this.$router.replace("/approveList"))
+        },
+        rejectApprove(reason){
+            this.isDetailDialogShow = false
+            approveInterence.rejectApprove({
+                ReportApproveId:Number(this.$route.query.approveId),
+                ApproveRemark:reason||''
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success("驳回成功")
+                this.$router.replace("/approveList")
+            })
+        }
+    },
+    mounted(){
+        this.getApproveDetail()
+    },
+    components: { TimeLine, ReportDetail, Reportdtl, RejectDialog }
+};
+</script>
+
+<style lang="scss">
+.approve-detail-wrap{
+    .approve-content{
+        .smart-report-detail{
+            .main-box{
+                width: auto;
+                box-sizing: border-box;
+                margin:0;
+                padding:10px;
+                border:none !important;
+                border-radius: 4px;
+            }
+        }
+        #reportdtl{
+            margin:0 auto;
+            padding:10px;
+            border:none !important;
+            border-radius: 4px;
+        }
+    }
+}
+</style>
+<style scoped lang="scss">
+@import url('./css/pageStyle.scss');
+.approve-detail-wrap{
+    height: calc(100vh - 120px);
+    display: flex;
+    .approve-detail,.approve-tool{
+        height: 100%;
+        box-sizing: border-box;
+    }
+    .approve-tool{
+        width:400px;
+        min-width: 360px;
+        background-color: #fff;
+        display: flex;
+        flex-direction: column;
+        overflow: hidden;
+        .tool-btn{
+            padding:20px;
+            text-align: right;
+        }
+        .approve-timeline-wrap{
+            position: relative;
+            margin-left:20px;
+            flex:1;
+            overflow-y: auto;
+            .timeline{
+                padding:20px;
+                padding-left: 0;
+            }
+            .approve-status{
+                position:absolute;
+                width:200px;
+                height:200px;
+                right:0;
+                bottom:0;
+                overflow: hidden;
+                pointer-events: none;
+                img{
+                    width:100%;
+                    height:100%;
+                }
+            }
+        }
+    }
+    .approve-detail{
+        flex: 1;
+        margin-right:20px;
+        background-color: #fff;
+        display: flex;
+        flex-direction: column;
+        .approve-info{
+            display: flex;
+            gap:60px;
+            padding:15px 20px;
+            border-bottom: 1px solid #C8CDD9;
+        }
+        .approve-content{
+            flex: 1;
+            min-width: 840px;
+            padding:20px;
+            overflow-y: auto;
+            position:relative;
+        }
+    }
+}
+</style>

+ 194 - 0
src/views/approve_manage/approveEdit.vue

@@ -0,0 +1,194 @@
+<template>
+    <!-- 添加编辑审批流 -->
+    <div class="approve-edit-wrap approve-page-wrap" v-if="isETAApprove">
+        <div class="head-box">
+            <el-form :inline="true" :model="approveForm" ref="approve-form" :rules="formRules"
+                label-width="100px" label-position="left">
+                <el-form-item label="审批流名称" prop="name">
+                    <el-input v-model="approveForm.name" :disabled="this.$route.query.flowId" placeholder="请输入审批流名称"></el-input>
+                </el-form-item>
+                <el-form-item label="关联报告" prop="classify">
+                    <el-cascader v-model="approveForm.classify"
+                        placeholder="请选择关联报告" clearable
+                        :disabled="this.$route.query.flowId"
+                        :options="classifyTree"
+                        :props="{value:'ClassifyId',label:'ClassifyName',children:'Children'}"
+                        style="margin-right: auto;margin-left: 15px;"></el-cascader>
+                </el-form-item>
+            </el-form>
+            <div class="form-btn">
+                <el-button type="primary" plain @click="$router.back()">取消</el-button>
+                <el-button v-permission="permissionBtn.approveFlowPermission.reportApprove_save"
+                    type="primary" @click="checkFlow">保存</el-button>
+            </div>
+        </div>
+        <div class="form-item" style="color:#606266;width:100px;">
+            <span style="color:#F56C6C;margin-right: 4px;">*</span>流程配置
+        </div>
+        <!-- 审批流画布 -->
+        <div class="flow-editor-wrap">
+            <FlowEdiotr
+                ref='floweditor'
+                :flowNodes="approveForm.flowNodes"
+            />
+        </div>
+    </div>
+    <div class="approve-page-wrap" v-else>
+        <tableNoData :text="pageLoading?'':'系统暂未开通审批流程,请开启审批流程后再进行操作!'"></tableNoData>
+    </div>
+</template>
+
+<script>
+import FlowEdiotr from './components/flowEdiotr';
+import {approveInterence} from '@/api/modules/approve.js';
+import approveMixins from './mixins/approveMixins';
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
+const findParentNode = (arr, id)=>{
+      // 遍历取父级code push数组
+      for (let i of arr) {
+        if (i.ClassifyId === id) {
+          return [i.ClassifyId];
+        }
+        if (i.Children) {
+          let node = findParentNode(i.Children, id);
+          if (node) {
+            return node.concat(i.ClassifyId);
+          }
+        }
+      }
+    }
+export default {
+    mixins:[approveMixins,reportApproveConfig],
+    data() {
+        return {
+            approveForm:{
+                name:'',
+                classify:'',
+                /* flowNodes:null */
+            },
+            formRules:{
+                name:[{ required: true, message: '请输入审批流名称名称', trigger: 'blur' },
+                      { max: 20, message: '长度在20个字符内', trigger: 'change' }],
+                classify:[{ required: true, message: '请选择关联报告', trigger: 'blur' },]
+            },
+
+        };
+    },
+    methods: {
+        async checkFlow(){
+            //检查name,region是否为空
+            await this.$refs["approve-form"].validate()
+            //检查审批流内容:每个审批节点是否都选择了审批人
+            const data = this.$refs.floweditor.flowData
+            if(data.length<3){
+                this.$message.warning("请添加审批节点")
+                return
+            }
+            for(let item of data){
+                if(item.nodeType===2&&!item.approvers.length){
+                    this.$message.warning("有节点未选择审批人,请检查")
+                    return
+                }
+            }
+            let Nodes = []
+            //不需要data的第一项和最后一项,其余转换为接口所需格式
+            for(let i=1;i<data.length-1;i++){
+                const Users = data[i].approvers.map((item,index)=>{
+                    return {
+                        UserType:'user',//目前只有审批节点,都是user
+                        UserId:item.ItemId,
+                        UserName:item.ItemName,
+                        Sort:data[i].ApproveType===1?index+1:0
+                    }
+                })
+                Nodes.push({
+                    ApproveType:data[i].ApproveType,
+                    Users
+                })
+            }
+            this.modifyFlow(Nodes)
+        },
+        async modifyFlow(Nodes){
+            const {name,classify} = this.approveForm
+            const params = {
+                FlowName:name,
+                ReportType:classify[0],
+                ClassifyFirstId:classify[classify.length-2]||0,
+                ClassifySecondId:classify[classify.length-1]||0,
+                Nodes
+            }
+            let res
+            const id = this.$route.query.flowId||0
+            if(id){
+                res = await approveInterence.editApproveFlow({
+                    ...params,
+                    ReportApproveFlowId:Number(id)
+                })
+            }else{
+                res = await approveInterence.addNewApproveFlow(params)
+            }
+            if(res.Ret!==200) return
+            this.$message.success(`${id?'编辑':'新增'}成功`)
+            this.$router.push('/approveSetting')
+        },
+        getFlowDetail(){
+            const id = this.$route.query.flowId||0
+            if(id){
+                approveInterence.getApproveFlowDetail({
+                    ReportApproveFlowId:Number(id)
+                }).then(res=>{
+                    if(res.Ret!==200) return 
+                    const {FlowName,ReportType,ClassifySecondId,Nodes} = res.Data||{}
+                    this.approveForm.name = FlowName||''
+                    //递归获取所有父级id
+                    const classify = this.classifyTree.find(i=>i.ClassifyId===ReportType)||{}
+                    const tempArr = findParentNode(classify.Children||[],ClassifySecondId)
+                    tempArr.push(ReportType)
+                    this.approveForm.classify = tempArr.reverse()
+                    this.approveForm.flowNodes = Nodes||[]
+                })
+            }
+        }
+    },
+    async mounted(){
+        this.getClassifyTree()
+    },
+    components: { FlowEdiotr }
+};
+</script>
+<style lang="scss">
+.approve-edit-wrap{
+    .el-form-item__content{
+        flex: 1;
+    }
+}
+</style>
+<style scoped lang="scss">
+@import url('./css/pageStyle.scss');
+.approve-edit-wrap{
+    display: flex;
+    flex-direction: column;
+    height: calc(100vh - 120px);
+    .head-box{
+        display: flex;
+        justify-content: space-between;
+        .el-form{
+            flex:1;
+            .el-input,.el-cascader{
+                min-width: 200px;
+                max-width: 420px;
+                width:100%;
+            }
+            .el-form-item{
+                width:45%;
+                display: inline-flex;
+            }
+
+        }
+    }
+    .flow-editor-wrap{
+        padding-left: 100px;
+        overflow: auto;
+    }
+}
+</style>

+ 311 - 0
src/views/approve_manage/approveList.vue

@@ -0,0 +1,311 @@
+<template>
+    <!-- 审批管理列表页 -->
+    <div class="approve-list-wrap approve-page-wrap" v-if="isETAApprove">
+        <div class="head-tab">
+            <el-tabs v-model="activeTab" @tab-click="handleClick">
+                <el-tab-pane label="待处理" name="pending"></el-tab-pane>
+                <el-tab-pane label="已处理" name="processed"></el-tab-pane>
+                <el-tab-pane label="我发起的" name="originate"></el-tab-pane>
+            </el-tabs>
+        </div>
+        <div class="approve-list">
+            <div class="select-box">
+                <el-cascader v-model="classify"
+                    placeholder="请选择关联报告" clearable
+                    :options="classifyTree"
+                    :props="{value:'ClassifyId',label:'ClassifyName',children:'Children'}"
+                    @change="handleCurrentChange(1)">
+                </el-cascader>
+                <div class="select-time-box">
+                    <el-select v-show="activeTab!=='pending'" v-model="timeType" 
+                        @change="handleCurrentChange(1)"
+                        placeholder="时间类型" style="max-width:120px;" class="custom-select">
+                        <el-option label="提交时间" :value="1" />
+                        <el-option label="处理时间" :value="2" v-if="activeTab==='processed'"/>
+                        <el-option label="审批时间" :value="3" v-if="activeTab==='originate'"/>
+                    </el-select>
+                    <div class="line" v-show="activeTab!=='pending'"></div>
+                    <el-date-picker v-model="timeDate"
+                        @change="handleCurrentChange(1)"
+                        type="daterange"
+                        value-format="yyyy-MM-dd"
+                        range-separator="至"
+                        start-placeholder="开始日期"
+                        end-placeholder="结束日期">
+                    </el-date-picker>
+                </div>
+                
+                <el-select placeholder="请选择处理状态" v-model="ApproveState" clearable v-show="activeTab!=='pending'"
+                    @change="handleCurrentChange(1)">
+                    <template v-if="activeTab==='processed'">
+                        <el-option label="已同意" :value="2" />
+                        <el-option label="已驳回" :value="3" />
+                    </template>
+                    <template v-if="activeTab==='originate'">
+                        <el-option label="待审批" :value="1" />
+                        <el-option label="已通过" :value="2" />
+                        <el-option label="已驳回" :value="3" />
+                        <el-option label="已撤销" :value="4" />
+                    </template>
+                    
+                </el-select>
+
+                <el-input v-model="keyword" prefix-icon="el-icon-search" clearable @input="handleCurrentChange(1)"
+                    placeholder="请输入报告标题" style="width:260px;margin-left: auto;"></el-input>
+            </div>
+            <div class="list-box">
+                <el-table 
+                    ref="reftable"
+                    v-loading="tableLoading"
+                    :data="tableData" 
+                    @sort-change="sortChange" border>
+                    <el-table-column
+                        v-for="item in tableColumns"
+                        :key="item.key"
+                        :label="item.label"
+                        :prop="item.key"
+                        :sortable="item.sortable"
+                        align="center"
+                    >
+                        <template slot-scope="{row}">
+                            <span v-if="item.key==='State'">
+                                {{['','待审批','已通过','已驳回','已撤销'][row.State]}}
+                            </span>
+                            <span v-else-if="item.key==='RecordState'">
+                                {{['','待审批','已同意','已驳回'][row.RecordState]}}
+                            </span>
+                            <span v-else>{{row[item.key]}}</span>
+                        </template>
+                    </el-table-column>
+                    <el-table-column label="操作" align="center">
+                        <template slot-scope="{row}">
+                            <template v-if="activeTab==='pending'">
+                                <el-button type="text" style="padding:0;" @click="toApproveDetail(row,'approve')"
+                                    v-if="permissionBtn.isShowBtn('approvePermission','reportApprove_approve')">审批</el-button>
+                            </template>
+                            <template v-if="activeTab==='processed'">
+                                <el-button type="text" style="padding:0;" @click="toApproveDetail(row,'detail')">详情</el-button>
+                                <el-button type="text" style="padding:0" @click="handleShowDetail(row)" 
+                                    v-if="row.State===3&&permissionBtn.isShowBtn('approvePermission','reportApprove_rejectreason')">驳回理由</el-button>
+                            </template>
+                            <template v-if="activeTab==='originate'">
+                                <el-button type="text" style="padding:0;" @click="toApproveDetail(row,'myself')">详情</el-button>
+                                <el-button type="text" style="padding:0;" @click="cancelApprove(row)" 
+                                    v-if="row.State!==4&&permissionBtn.isShowBtn('approvePermission','reportApprove_repeal')">撤销</el-button>
+                                <el-button type="text" style="padding:0" @click="handleShowDetail(row)" 
+                                    v-if="row.State===3&&permissionBtn.isShowBtn('approvePermission','reportApprove_rejectreason')">驳回理由</el-button>
+                            </template>
+                        </template>
+                        
+                    </el-table-column>
+                </el-table>
+            <div style="text-align:right;margin-top:20px">
+                <el-pagination 
+                        layout="total,prev,pager,next,jumper" 
+                        background 
+                        :current-page="page"
+                        @current-change="handleCurrentChange"
+                        :page-size="pageSize"
+                        :total="total"
+                        style="display: inline-block"
+                    />
+            </div>
+            </div>
+        </div>
+        <RejectDialog 
+            :isDetailDialogShow="isDetailDialogShow"
+            :isEdit="false"
+            :data="currentData"
+            @close="isDetailDialogShow=false;currentData={};"
+        />
+    </div>
+    <div class="approve-page-wrap" v-else>
+        <tableNoData :text="pageLoading?'':'系统暂未开通审批流程,请开启审批流程后再进行操作!'"></tableNoData>
+    </div>
+</template>
+
+<script>
+import RejectDialog from './components/rejectDialog.vue';
+import approveMixins from './mixins/approveMixins';
+import {approveInterence} from '@/api/modules/approve.js';
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
+import {
+        approve_pending_columns,
+        approve_processed_columns,
+        approve_originate_columns,
+    } from './config/tableConfig'
+const columnsMap = {
+    'pending':approve_pending_columns,
+    'processed':approve_processed_columns,
+    'originate':approve_originate_columns
+}
+const tabMap = {
+    'pending':1,
+    'processed':2,
+    'originate':3
+}
+export default {
+    mixins:[approveMixins,reportApproveConfig],
+    data() {
+        return {
+            activeTab: 'pending',
+            /* 筛选项 */
+            timeType:1,
+            timeDate:'',
+            ApproveState:'',
+            keyword:'',
+            classify:'',
+            /* 排序项 */
+            SortRule:0,
+            SortField:0,
+
+            tableLoading:false,
+            tableData: [],
+            tableColumns: approve_pending_columns,
+            page: 1,
+            pageSize: 10,
+            total: 0,
+
+            currentData: {},
+            isDetailDialogShow: false
+        };
+    },
+    methods: {
+        getTableData(){
+            this.tableLoading = true
+            this.tableData=[]
+            const baseParams = {
+                ListType:tabMap[this.activeTab]||0,
+                PageSize:this.pageSize,
+                CurrentIndex:this.page,
+                Keyword:this.keyword,
+            }
+            const selectParams = {
+                //关联报告
+                ReportType:this.classify[0]||0,
+                ClassifyFirstId:this.classify[this.classify.length-2]||0,
+                ClassifySecondId:this.classify[this.classify.length-1]||0,
+                //时间
+                TimeType:this.timeType,
+                StartTime:this.timeDate?this.timeDate[0]||'':'',
+                EndTime:this.timeDate?this.timeDate[1]||'':'',
+                //排序
+                SortRule:this.SortRule,
+                SortField:this.SortField,
+                //处理状态
+                ApproveState:this.ApproveState,
+            }
+            approveInterence.getApproveList({
+                ...baseParams,
+                ...selectParams
+            }).then(res=>{
+                this.tableLoading=false
+                if(res.Ret!==200) return 
+                const {List=[],Paging={}} = res.Data||{}
+                this.tableData = List||[]
+                this.total = Paging.Totals||0
+            })
+        },
+        handleCurrentChange(page) {
+            this.page = page;
+            this.getTableData()
+        },
+        sortChange({ prop, order }) {
+            this.SortRule = order==='ascending'?1:2
+            this.SortField= prop==='CreateTime'?1
+                            :prop==='HandleTime'?2:3
+            this.handleCurrentChange(1)
+        },
+        handleClick() {
+            this.timeType = 1
+            this.timeDate=''
+            this.SortField=0
+            this.SortField=0
+            this.tableColumns = columnsMap[this.activeTab];
+            this.$refs.reftable&&this.$refs.reftable.clearSort()
+            this.handleCurrentChange(1)
+        },
+        handleShowDetail(data) {
+            this.currentData = data;
+            this.isDetailDialogShow = true;
+        },
+        toApproveDetail(data,type){
+            this.$router.push({
+                path:'/approveDetail',
+                query:{
+                    type,
+                    approveId:data.ReportApproveId
+                }
+            })
+        },
+        cancelApprove(item){
+            approveInterence.cancelApprove({
+                ReportApproveId:Number(item.ReportApproveId)
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success("撤销成功")
+                this.handleCurrentChange(1)
+            })
+        },
+    },
+    mounted(){
+        this.getClassifyTree()
+        const {formType='approve'} = this.$route.query
+        const formTypeMap = {
+            'approve':'pending',
+            'detail':'processed',
+            'myself':'originate'
+        }
+        this.activeTab = formTypeMap[formType]||'pending'
+        this.getTableData()
+    },
+    components: { RejectDialog }
+};
+</script>
+
+<style lang="scss">
+.approve-list-wrap{
+    .custom-select{
+        .el-input__inner{
+            border-color: #0052D9;
+            background-color: #ECF2FE;
+            color:#0052D9;
+        }
+        .el-input__suffix{
+            color:#0052D9;
+            .el-select__caret{
+                color:#0052D9;
+            }
+        }
+        
+    }
+}
+</style>
+<style scoped lang="scss">
+@import url('./css/pageStyle.scss');
+.approve-list-wrap{
+    .head-tab{
+        margin-bottom: 5px;
+    }
+    .approve-list{
+        .select-box{
+            display: flex;
+            justify-content: space-between;
+            gap:10px;
+            .select-time-box{
+                display: flex;
+                align-items: center;
+                max-width: 380px;
+                .line{
+                    width:10px;
+                    height:1px;
+                    background-color: #C8CDD9;
+                }
+            }
+        }
+    }
+    .list-box{
+        margin-top:20px;
+    }
+}
+</style>

+ 162 - 0
src/views/approve_manage/approveSetting.vue

@@ -0,0 +1,162 @@
+<template>
+    <!-- 审批流配置列表 -->
+    <div class="approve-setting-wrap approve-page-wrap" v-if="isETAApprove">
+        <div class="head-box">
+            <el-button v-permission="permissionBtn.approveFlowPermission.reportApprove_add"
+                type="primary" @click="$router.push('/approveEdit')">添加审批流</el-button>
+            <el-cascader v-model="classify"
+                placeholder="请选择关联报告" clearable
+                :options="classifyTree"
+                :props="{value:'ClassifyId',label:'ClassifyName',children:'Children'}"
+                @change="handleSearchChange"
+                style="margin-right: auto;margin-left: 15px;"></el-cascader>
+            <el-input v-model="Keyword" @input="handleCurrentChange(1)"
+                placeholder="请输入审批流名称" prefix-icon="el-icon-search" clearable style="width:260px;"></el-input>
+        </div>
+        <div class="list-box">
+            <el-table :data="tableData" @sort-change="sortChange" border>
+                <el-table-column
+                    v-for="item in tableColumns"
+                    :key="item.key"
+                    :label="item.label"
+                    :prop="item.key"
+                    :sortable="item.sortable"
+                    align="center"
+                ></el-table-column>
+                <el-table-column label="操作" align="center">
+                    <template slot-scope="{row}">
+                        <el-button v-permission="permissionBtn.approveFlowPermission.reportApprove_edit"
+                            type="text" style="padding:0;" @click="handleEditFlow(row)">编辑</el-button>
+                        <el-button v-permission="permissionBtn.approveFlowPermission.reportApprove_remove"
+                            type="text" style="padding:0;color:red;" @click="handleDeleteFlow(row)">删除</el-button>
+                    </template>
+                    
+                </el-table-column>
+            </el-table>
+            <div style="text-align:right;margin-top:20px">
+                <el-pagination 
+                        layout="total,prev,pager,next,jumper" 
+                        background 
+                        :current-page="page"
+                        @current-change="handleCurrentChange"
+                        :page-size="pageSize"
+                        :total="total"
+                        style="display: inline-block"
+                    />
+            </div>
+        </div>
+    </div>
+    <div class="approve-page-wrap" v-else>
+        <tableNoData :text="pageLoading?'':'系统暂未开通审批流程,请开启审批流程后再进行操作!'"></tableNoData>
+    </div>
+</template>
+
+<script>
+import {approveInterence} from '@/api/modules/approve.js'
+import approveMixins from './mixins/approveMixins';
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
+export default {
+    mixins:[approveMixins,reportApproveConfig],
+    data() {
+        return {
+            /* 列表筛选项 */
+            ClassifyFirstId:0,//研报倒数第二级分类id
+            ClassifySecondId:0,//研报最后一级分类id
+            ReportType:0,//研报类型 1-中文研报;2-英文研报;3-智能研报
+            SortRule:0,//排序规则:1-正序; 2-倒序(默认)
+            Keyword:'',
+            classify:'',
+
+            tableData:[],
+            tableColumns:[{
+                label:'审批流名称',
+                key:'FlowName'
+            },{
+                label:'关联报告',
+                key:'ReportClassify'
+            },{
+                label:'创建时间',
+                key:'CreateTime',
+                sortable:'custom'
+            }],
+            page:1,
+            pageSize:10,
+            total:0,
+        };
+    },
+    methods: {
+        handleCurrentChange(page){
+            this.page = page
+            this.getTableData()
+        },
+        handleSearchChange(){
+            this.ReportType = this.classify[0]||0
+            this.ClassifySecondId = this.classify[this.classify.length-1]||0
+            if(this.classify.length>=3){
+                this.ClassifyFirstId = this.classify[this.classify.length-2]||0
+            }else{
+                this.ClassifyFirstId = 0
+            }
+            this.handleCurrentChange(1)
+        },
+        sortChange({prop,order}){
+            this.SortRule = order==='ascending'?1:2
+            this.handleCurrentChange(1)
+        },
+        getTableData(){
+            approveInterence.getApproveFlowList({
+                PageSize:this.pageSize,
+                CurrentIndex:this.page,
+                ReportType:this.ReportType,
+                ClassifyFirstId:this.ClassifyFirstId,
+                ClassifySecondId:this.ClassifySecondId,
+                Keyword:this.Keyword,
+                SortRule:this.SortRule
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                const {List=[],Paging={}} = res.Data||{}
+                this.tableData = List||[]
+                this.total = Paging.Totals||0
+            })
+        },
+        handleEditFlow(item){
+            this.$router.push({
+                path:'/approveEdit',
+                query:{
+                    flowId:item.ReportApproveFlowId
+                }
+            })
+        },
+        handleDeleteFlow(item){
+            this.$confirm("删除后不可恢复,确认删除吗?","提示",{
+                type:"warning"
+            }).then(()=>{
+                approveInterence.deleteApproveFlow({
+                    ReportApproveFlowId:item.ReportApproveFlowId
+                }).then(res=>{
+                    if(res.Ret!==200) return 
+                    this.$message.success("删除成功")
+                    this.handleCurrentChange(1)
+                })
+            }).catch(()=>{})
+        }
+    },
+    mounted(){
+        this.getClassifyTree()
+        this.getTableData()
+    },
+};
+</script>
+
+<style scoped lang="scss">
+@import url('./css/pageStyle.scss');
+.approve-setting-wrap{
+    .head-box{
+        display: flex;
+        justify-content: space-between;
+    }
+    .list-box{
+        margin-top:30px;
+    }
+}
+</style>

+ 112 - 0
src/views/approve_manage/components/flowEdiotr.vue

@@ -0,0 +1,112 @@
+<template>
+    <!-- 审批流内容 -->
+    <div class="flow-editor">
+        <span class="circle-point"></span>
+        <span class="circle-point end"></span>
+        <component v-for="(node,index) in flowData" :key="index"
+            :is="node.nodeName"
+            :flowNode="{...node,...{index}}"
+            @addNode="addFlowNode"
+            @editNode="editFlowNode"
+            @removeNode="removeNode">
+        </component>
+    </div>
+</template>
+
+<script>
+import StartNode from './flowNode/startNode.vue';
+import AddNode from './flowNode/addNode.vue';
+import ApproveNode from './flowNode/approveNode.vue';
+import EndNode from './flowNode/endNode.vue';
+export default {
+    props:{
+        flowNodes:{ //审批流原数据,只包含审批节点
+            type:Array,
+            default:[]
+        }
+    },
+    data() {
+        return {
+            flowData:[{
+                nodeType: 1,
+                nodeName: 'StartNode',
+            },{
+                nodeType:3,
+                nodeName:'EndNode'
+            }]
+        };
+    },
+    watch:{
+        flowNodes(val){
+            this.initFlowData()
+        }
+    },
+    methods: {
+        initFlowData(){
+            const approveData = this.flowNodes.map(n=>{
+                const approvers = n.Users.map(i=>{
+                    return {
+                        ItemId:i.UserId,
+                        ItemName:i.UserName
+                    }
+                })
+                return {
+                    ...n,
+                    nodeType:2,
+                    nodeName:'ApproveNode',
+                    approvers
+                }
+            })
+            this.flowData.splice(1,0,...approveData)
+        },
+        addFlowNode(node){
+            const {prevNode} = node
+            delete node.prevNode
+            const {index} = prevNode
+            this.flowData.splice(index+1,0,node)
+        },
+        removeNode(node){
+            const {index} = node
+            this.flowData.splice(index,1)
+        },
+        editFlowNode(node){
+            const {index} = node
+            this.flowData.splice(index,1,node)
+        }
+    },
+    mounted(){
+        //this.initFlowData()
+    },
+    components: { StartNode,AddNode,ApproveNode,EndNode }
+};
+</script>
+
+<style scoped lang="scss">
+@import url('../css/nodeStyle.scss');
+.flow-editor{
+    margin-left: 20px;
+    position:relative;
+    .circle-point{
+            position:absolute;
+            top:0;
+            left:-22px;
+            width:6px;
+            height:6px;
+            border-radius: 50%;
+            background-color: #0052D9;
+            &.end{
+                top:auto;
+                bottom:0;
+            }
+        }
+        &::before{
+            content: '';
+            top:0;
+            left:-20px;
+            bottom: 0;
+            width:2px;
+            background-color: #0052D9;
+            position: absolute;
+        }
+}
+</style>

+ 44 - 0
src/views/approve_manage/components/flowNode/addNode.vue

@@ -0,0 +1,44 @@
+<template>
+    <div class="add-node-wrap">
+        <div class="add-btn" @click="handleAddApprove">
+            <span> <i class="el-icon-circle-plus-outline"></i></span>
+            <span>添加审批人</span>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props:["node"],
+    data() {
+        return {
+            visible:false,
+        };
+    },
+    methods: {
+        handleAddApprove(){
+            this.visible = false
+            const data = {
+                nodeType:2,
+                ApproveType:1,
+                nodeName:'ApproveNode',
+                approvers:[],
+                prevNode:this.node
+            }
+            this.$emit("addNode",data)
+        }
+    },
+};
+</script>
+
+<style scoped lang="scss">
+.add-node-wrap{
+    margin: 20px 0;
+    .add-btn{
+        user-select: none;
+        cursor: pointer;
+        color:#0052D9;
+        display: inline-block;
+    }
+}
+</style>

+ 280 - 0
src/views/approve_manage/components/flowNode/approveNode.vue

@@ -0,0 +1,280 @@
+<template>
+    <div class="approve-node-wrap node-wrap">
+        <div class="node-content">
+            <div class="head">
+                <span class="icon"></span>
+                <span class="name">审核人</span>
+                <span class="icon-btn" @click="removeNode"><i class="el-icon-close"></i></span>
+            </div>
+            <div class="content" @click="showDrawer">
+                <ul class="approver-list" v-if="flowNode.approvers.length">
+                    <li class="list-item" v-for="(item,index) in flowNode.approvers" :key="item.ItemId">
+                        {{item.ItemName}}{{index===flowNode.approvers.length-1?'':'、'}}
+                    </li>
+                </ul>
+                <span v-else style="color:#0052D9;display: flex;align-items: center;">
+                    <img src="~@/assets/img/approve_m/select.png">
+                    请选择审批人
+                </span>
+            </div>
+        </div>
+        <AddNode :node="flowNode" v-on="$listeners"/>
+        <el-drawer
+            direction="rtl"
+            :visible.sync="drawerShow"
+            :withHeader="true"
+            :modal-append-to-body="false"
+            >
+            <div class="approve-drawer-wrap">
+                <div class="header">
+                    <p>审批人设置</p>
+                    <span class="close-icon" @click="drawerShow=false" style="cursor: pointer;"><i class="el-icon-close"></i></span>
+                </div>
+                <div class="drawer-content">
+                    <div class="block">
+                        <p>选择审批人</p>
+                        <div class="choose-box">
+                            <el-radio v-model="block1" :label="1">指定人员</el-radio>
+                            <el-button @click="chooseDialogShow=true" type="primary">
+                                <i class="el-icon-circle-plus-outline" style="margin-right: 5px;"></i>
+                                选择人员
+                            </el-button>
+                        </div>
+                        <draggable 
+                            v-model="choosedList"
+                            animation="300"
+                            tag="ul"
+                            class="approve-list">
+                            <li class="list-item" v-for="item in choosedList" :key="item.ItemId">
+                                <span class="name">{{item.ItemName}}</span>
+                                <span class="icon-btn">
+                                    <i class="el-icon-close" @click.stop="removeChoosedItem(item)"></i>
+                                </span>
+                            </li>
+                        </draggable>
+                    </div>
+                    <div class="line"></div>
+                    <div class="block" style="margin-top:30px;">
+                        <p>多人审批时</p>
+                        <el-radio-group v-model="approveType">
+                            <el-radio :label="1">
+                                依次审批
+                                <el-tooltip effect="dark" placement="top" content="多个审批人依次进行审批;只有当所有审批人同意,该节点才能通过;按选择顺序审批" >
+                                    <span class="hint-text">
+                                        <i class="el-icon-info"></i>
+                                    </span>
+                                </el-tooltip>
+                            </el-radio>
+                            <el-radio :label="2">
+                                会签(须所有审批人同意)
+                                <el-tooltip effect="dark" placement="top" content="所有审批人同意,该节点才能通过;审批无先后顺序" >
+                                    <span class="hint-text">
+                                        <i class="el-icon-info"></i>
+                                    </span>
+                                </el-tooltip>
+                            </el-radio>
+                            <el-radio :label="3">
+                                或签(一名审批人同意或拒绝即可)
+                                <el-tooltip effect="dark" placement="top" content="任意一名审批人同意,该节点即通过;审批无先后顺序" >
+                                    <span class="hint-text">
+                                        <i class="el-icon-info"></i>
+                                    </span>
+                                </el-tooltip>
+                            </el-radio>
+                        </el-radio-group>
+                    </div>
+                </div>
+                <div class="drawer-btn">
+                    <el-button type="primary" plain @click="drawerShow=false">取消</el-button>
+                    <el-button type="primary" @click="editApproveNode">确认</el-button>
+                </div>
+            </div>
+        </el-drawer>
+        <!-- 选择人员弹窗 -->
+        <el-dialog 
+            title="选择人员"
+            width="600px"
+            :visible.sync="chooseDialogShow"
+            :modal-append-to-body="false"
+            :append-to-body="false"
+            @close="chooseDialogShow=false"
+        >
+            <div class="dialog-wrap">
+                <TreeTransfer 
+                    ref="tree-trans"
+                    :defaultList="choosedList"
+                    :chooseDialogShow="chooseDialogShow"
+                />
+            </div>
+            <div class="dialog-btn">
+                <el-button type="primary" plain @click="chooseDialogShow=false">取消</el-button>
+                <el-button type="primary" @click="getChoosedList">确认</el-button>
+            </div>
+        </el-dialog>
+    </div>
+</template>
+
+<script>
+import TreeTransfer from '../treeTransfer';
+import draggable from 'vuedraggable';
+import AddNode from './addNode';
+export default {
+    props:{
+        flowNode:{
+            type:Object,
+            default:{}
+        }
+    },
+    data() {
+        return {
+            drawerShow: false,
+            block1: 1,
+            approveType: 1,
+            chooseDialogShow: false,
+            choosedList:[]
+        };
+    },
+    watch:{
+        drawerShow(val){
+            if(val){
+                this.choosedList = _.cloneDeep(this.flowNode.approvers||[])
+                this.approveType = this.flowNode.ApproveType
+            }
+        }
+    },
+    methods: {
+        removeNode() {
+            this.$emit('removeNode', this.flowNode);
+        },
+        showDrawer() {
+            this.drawerShow = true;
+        },
+        getChoosedList(){
+            if(!this.$refs["tree-trans"].choosedList.length){
+                this.$message.warning("请至少选择一人")
+                return
+            }
+            this.choosedList = _.cloneDeep(this.$refs["tree-trans"].choosedList)||[]
+            this.chooseDialogShow = false
+        },
+        removeChoosedItem(item){
+            const index = this.choosedList.findIndex(i=>i.ItemId===item.ItemId)
+            index!==-1&&this.choosedList.splice(index,1)
+        },
+        editApproveNode(){
+            const node = _.cloneDeep(this.flowNode)
+            node.approvers = _.cloneDeep(this.choosedList)
+            node.ApproveType = this.approveType
+            this.$emit('editNode',node)
+            this.drawerShow = false
+        },
+    },
+    components: { TreeTransfer, draggable, AddNode }
+};
+</script>
+
+<style lang="scss">
+.approve-node-wrap{
+    .el-drawer__body{
+        overflow: hidden;
+    }
+    #el-drawer__title{ //drawer弹出时会自动聚焦第一个元素,设置无内容的title清除聚焦状态
+        height:0px;
+        margin:0px;
+        padding:0px;
+    }
+    .dialog-btn{
+        margin-top:60px;
+        padding-bottom: 40px;
+        text-align: center;
+    }
+}
+</style>
+<style scoped lang="scss">
+.approve-node-wrap{
+    .head{
+        background-color: #0052D9;
+        .icon{
+            background-image: url('~@/assets/img/approve_m/approve.png');
+        }
+        .icon-btn{
+            font-size: 20px;
+        }
+    }
+    .content{
+        .approver-list{
+            color:#0052D9;
+            display: flex;
+            align-items: center;
+            flex-wrap: wrap;
+        }
+    }
+    .approve-drawer-wrap{
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+        overflow: hidden;
+        .header{
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            /* font-weight: bold; */
+            font-size: 18px;
+            height:35px;
+            padding:20px;
+            border-bottom: 1px solid #C8CDD9;
+        }
+        .drawer-content{
+            flex:1;
+            overflow-y: auto;
+            box-sizing: border-box;
+            padding:30px;
+            .block{
+                min-height: 340px;
+                .choose-box{
+                    margin-top: 20px;
+                    display: flex;
+                    justify-content: space-between;
+                    align-items: center;
+                }
+            }
+            .line{
+                margin:0 -30px;
+                height: 1px;
+                background-color:#C8CDD9;
+            }
+            .approve-list{
+                margin-top: 10px;
+                display: flex;
+                flex-wrap: wrap;
+                gap:10px;
+                .list-item{
+                    cursor: move;
+                    padding:8px;
+                    border-radius: 4px;
+                    border:1px solid #C8CDD9;
+                    .icon-btn{
+                        cursor: pointer;
+                    }
+                }
+            }
+            .el-radio-group{
+                margin-top: 20px;
+                .el-radio{
+                    display: block;
+                    margin-bottom: 10px;
+                    .hint-text{
+                        color:#C0C4CC;
+                    }
+
+                }
+            }
+        }
+        .drawer-btn{
+            text-align: center;
+            margin:10px;
+        }
+    }
+    
+}
+</style>

+ 26 - 0
src/views/approve_manage/components/flowNode/endNode.vue

@@ -0,0 +1,26 @@
+<template>
+    <div class="end-node-wrap node-wrap">
+        <div class="end-content">流程结束</div>
+    </div>
+</template>
+
+<script>
+export default {
+    data() {
+        return {
+
+        };
+    },
+    methods: {
+
+    },
+};
+</script>
+
+<style scoped lang="scss">
+.end-node-wrap{
+    .end-content{
+        color:#C0C4CC;
+    }
+}
+</style>

+ 43 - 0
src/views/approve_manage/components/flowNode/startNode.vue

@@ -0,0 +1,43 @@
+<template>
+    <div class="start-node-wrap node-wrap">
+        <div class="node-content">
+            <div class="head">
+                <span class="icon"></span>
+                <p class="name">发起人</p>
+            </div>
+            <div class="content">所有人</div>
+        </div>
+        <AddNode :node="flowNode" v-on="$listeners"/>
+    </div>
+</template>
+
+<script>
+import AddNode from './addNode.vue';
+export default {
+    components: { AddNode},
+    props:{
+        flowNode:{
+            type:Object,
+            default:{}
+        }
+    },
+    data() {
+        return {};
+    },
+    methods: {},
+};
+</script>
+
+<style scoped lang="scss">
+.start-node-wrap{
+    .head{
+        background-color: #ECF2FE;
+        .name{
+            color:#0052D9;
+        }
+        .icon{
+            background-image: url('~@/assets/img/approve_m/start.png');
+        }
+    }
+}
+</style>

+ 81 - 0
src/views/approve_manage/components/rejectDialog.vue

@@ -0,0 +1,81 @@
+<template>
+    <el-dialog custom-class="approve-reject-dialog"
+        title="审批驳回"
+        :visible.sync="isDetailDialogShow"
+        :close-on-click-modal="false"
+        :modal-append-to-body="false"
+        @close="$emit('close')"
+        width="692px"
+        v-dialogDrag
+        center
+    >
+        <div class="dialog-content-wrap">
+            <el-input type="textarea" v-model="content" :disabled="!isEdit" :rows="10" :placeholder="isEdit?'请输入驳回理由':'无'"></el-input>
+        </div>
+        <div class="dialog-btn-wrap">
+            
+            <template v-if="isEdit">
+                <el-button @click="$emit('close')">取消</el-button>
+                <el-button type="primary" @click="handleConfirm">确认</el-button>
+            </template>
+            <el-button v-else @click="$emit('close')">知道了</el-button>
+        </div>
+    </el-dialog>
+</template>
+
+<script>
+export default {
+    props:{
+        isDetailDialogShow:{
+            type:Boolean,
+            default:false
+        },
+        isEdit:{
+            type:Boolean,
+            default:true
+        },
+        data:{
+            type:Object,
+            default:()=>{return{}}
+        }
+    },
+    watch:{
+        isDetailDialogShow(val){
+            if(val){
+                this.content = this.data.ApproveRemark||''
+            }
+        }
+    },
+    data() {
+        return {
+            content:''
+        };
+    },
+    methods: {
+        handleConfirm(){
+            /* if(!this.content.length){
+                this.$message.warning("请输入驳回理由")
+                return
+            } */
+            this.$emit('edit',this.content)
+        }
+    },
+};
+</script>
+
+<style lang="scss">
+.approve-reject-dialog{
+    .dialog-content-wrap{
+        .el-textarea{
+            textarea{
+                resize: none !important;
+            }
+        }
+    }
+    .dialog-btn-wrap{
+        text-align: center;
+        margin-top: 20px;
+        padding-bottom: 25px;
+    }
+}
+</style>

+ 60 - 0
src/views/approve_manage/components/timeLine.vue

@@ -0,0 +1,60 @@
+<template>
+    <div class="time-line-wrap">
+        <ul>
+            <li v-for="(node,index) in TimeLineData" :key="index">
+                <TimeLineItem :node="node" :isLast="index===TimeLineData.length-1"/>
+            </li>
+        </ul>
+    </div>
+</template>
+
+<script>
+import TimeLineItem from './timeLineItem.vue';
+export default {
+    components:{TimeLineItem},
+    props:{
+        TimeLineData:{
+            type:Array
+        }
+    },
+    data() {
+        return {
+            //时间线数据格式
+            mockTimeLine:[
+                {
+                    nodeType:1,
+                    nodeText:'发起人:',
+                    approveList:[{
+                        approverName:'张三',
+                        approveTime:'2023-10-10 10:10:10'
+                    }],
+                    nodeStatus:'passed',//passed节点已通过,return节点已撤回,reject节点已驳回,future节点未进行到
+                },{
+                    nodeType:2,
+                    nodeText:'审批人:', //需要拼接成 审批人:2人(会签)
+                    nodeStatus:'process',//节点正在进行中
+                    approveType:'会签',
+                    approveList:[//参与审批的人员
+                        {
+                            approverName:'李四',
+                            approveTime:'2023-10-10 10:15:10',
+                            approveStatus:'已同意'
+                        },{
+                            approverName:'王五',
+                            approveTime:'2023-10-10 10:22:00',
+                            approveStatus:'已驳回',
+                            approveReason:'就是驳回'
+                        }
+                    ]
+                }
+            ]
+        };
+    },
+    methods: {
+
+    },
+};
+</script>
+
+<style scoped lang="scss">
+</style>

+ 120 - 0
src/views/approve_manage/components/timeLineItem.vue

@@ -0,0 +1,120 @@
+<template>
+    <div class="item-wrap">
+        <div class="icon-wrap">
+            <div :class="['icon',node.nodeStatus]">
+                <img :src="require(`@/assets/img/approve_m/${node.nodeStatus}-icon.svg`)" alt="">
+            </div>
+            <div :class="['line',isLast?'last':'',node.nodeStatus]"></div>
+        </div>
+        <div class="info-wrap">
+            <!-- 发起人或审批人 -->
+            <div class="normal-text">
+                <p>{{node.nodeText}}</p>
+            </div>
+            <ul class="approve-list">
+                <li v-for="(item,itemIndex) in node.approveList" :key="itemIndex">
+                    <div class="approve-item-wrap">
+                        <!-- 审批人(审批状态) 审批时间-->
+                        <div class="normal-text">
+                            <p :class="{'passed':item.approveStatus==='已同意'}">{{item.approverName}} <span v-if="item.approveStatus">{{'('+item.approveStatus+')'}}</span> </p>
+                            <span class="time">{{item.approveTime||''}}</span>
+                        </div>
+                        <!-- 驳回理由 -->
+                        <div class="approve-reason" v-if="item.approveReason">
+                            驳回理由:{{item.approveReason}}
+                        </div>
+                    </div>
+                </li>
+            </ul>
+        </div>
+    </div>
+</template>
+
+<script>
+export default {
+    props:{
+        node:{
+            type:Object,
+            default:{}
+        },
+        isLast:{
+            type:Boolean,
+            default:false
+        }
+    },
+    data() {
+        return {
+
+        };
+    },
+    methods: {
+
+    },
+};
+</script>
+
+<style scoped lang="scss">
+.item-wrap{
+    display: flex;
+    width:100%;
+    .icon-wrap{
+        width:25px;
+        /* border:1px solid black; */
+        position:relative;
+        .icon,.line{
+            position:absolute;
+            left:50%;
+            transform: translateX(-50%);
+        }
+        .icon{
+            width:16px;
+            height:16px;
+            border-radius: 50%;
+            background-color: #fff;
+            overflow: hidden;
+            img{
+                width:100%;
+                height:100%;
+            }
+        }
+        .line{
+            top:16px;
+            width:1px;
+            height:calc(100% - 16px);
+            background-color: gray;
+            &.passed{
+                background-color: #0052D9;
+            }
+            &.last{
+                background-color: transparent;
+            }
+        }
+    }
+    .info-wrap{
+        flex:1;
+        margin-left: 15px;
+        margin-bottom: 20px;
+        .approve-list{
+            .approve-item-wrap{
+                .normal-text{
+                    display: flex;
+                    justify-content: space-between;
+                    margin-bottom: 10px;
+                    color:gray;
+                    &.passed{
+                        color:#0052D9;
+                    }
+                }
+                .approve-reason{
+                   /*  margin-left: -40px; */
+                    padding:10px;
+                    /* padding-left: 40px; */
+                    color:#AD352F;
+                    background-color: #FFF0ED;
+                }
+            }
+        }
+        
+    }
+}
+</style>

+ 185 - 0
src/views/approve_manage/components/treeTransfer.vue

@@ -0,0 +1,185 @@
+<template>
+    <!-- 选择审批人组件 -->
+    <div class="tree-transfer">
+        <div class="before-transfer transfer">
+            <div class="search">
+                <el-input placeholder="搜索" suffix-icon="el-icon-search" style="width:100%;"
+                    v-model="searchText" @input="$refs['trans-tree'].filter(searchText)"></el-input>
+            </div>
+            <div class="content">
+                <el-tree 
+                    node-key="ItemId"
+                    ref="trans-tree"
+                    show-checkbox
+                    :data="treeData"
+                    :props="{
+                        label:'ItemName',
+                        children:'Children'
+                    }"
+                    :filter-node-method="filterNode"
+                    @check="SetCheckedNode"
+                ></el-tree>
+            </div>
+        </div>
+        <div class="after-transfer transfer">
+            <div class="head">
+                <span>已选{{choosedList.length}}项</span>
+                <span class="btn-text delete" @click="clearnItem">清空</span>
+            </div>
+            <draggable 
+                v-model="choosedList"
+                animation="300"
+                tag="ul"
+                class="content">
+                <li class="list-item" v-for="item in choosedList" :key="item.ItemId">
+                    <span class="name">{{item.ItemName}}</span>
+                    <span class="icon-btn" style="color:#C0C4CC;">
+                        <i class="el-icon-close" @click.stop="removeItem(item)"></i>
+                    </span>
+                </li>
+            </draggable>
+        </div>
+    </div>
+</template>
+
+<script>
+import { dataAuthInterface } from "@/api/api.js";
+import draggable from 'vuedraggable';
+export default {
+    components:{draggable},
+    props:{
+        defaultList:{
+            type:Array,
+            default:[]
+        },
+        chooseDialogShow:{
+            type:Boolean,
+            default:false
+        }
+    },
+    data() {
+        return {
+            totalNum:0,
+            treeData:[],
+            searchText:'',
+            choosedList:[]
+        };
+    },
+    watch:{
+        chooseDialogShow:{
+            handler(val){
+                if(val){
+                    this.searchText=''
+                    this.getTreeData()
+                }
+            },
+            immediate:true
+        }
+    },
+    methods: {
+        getTreeData(){
+            ///datamanage/manual/sysuser/search?KeyWord= ,要用新接口再换
+            dataAuthInterface.userSearch({
+                KeyWord: ''
+            }).then(res => {
+                if(res.Ret === 200) {
+                    this.treeData = res.Data||[];
+                }
+                this.$nextTick(()=>{
+                    const keys = this.defaultList.map(i=>{
+                        return i.ItemId
+                    })
+                    this.$refs["trans-tree"].setCheckedKeys(keys)
+                    this.choosedList = _.cloneDeep(this.defaultList)
+                })
+            })
+        },
+        filterNode(value,data){
+            if(!value) return true
+            return data.ItemName.indexOf(value)!==-1
+        },
+        SetCheckedNode(data,{checkedNodes}){
+            if(!this.choosedList.length){
+                 //只获取人员
+                this.choosedList = checkedNodes.filter(i=>{
+                    if(i.ItemId<10000&&!i.Children)
+                        return i
+                })
+            }else{
+                //遍历 filterArr choosedList里没有的,push进去
+                const filterArr = checkedNodes.filter(i=>{
+                    if(i.ItemId<10000&&!i.Children)
+                        return i
+                })
+                filterArr.forEach(i=>{
+                    const index = this.choosedList.findIndex(item=>i.ItemId===item.ItemId)
+                    if(index===-1){this.choosedList.push(i)}
+                })
+                //遍历choosedList,filterArr里没有的,删除
+                const tempArr = _.cloneDeep(this.choosedList)
+                tempArr.forEach(i=>{
+                    const checkIndex = filterArr.findIndex(item=>item.ItemId===i.ItemId)
+                    if(checkIndex===-1){
+                        const index = this.choosedList.findIndex(item=>item.ItemId===i.ItemId)
+                        index!==-1&&this.choosedList.splice(index,1)
+                    }
+                })
+            }
+        },
+        removeItem(item){
+            const {ItemId} = item
+            this.$refs["trans-tree"].setChecked(ItemId,false,false)
+            const index = this.choosedList.findIndex(i=>i.ItemId===ItemId)
+            index!==-1&&this.choosedList.splice(index,1)
+        },
+        clearnItem(){
+            this.$refs["trans-tree"].setCheckedKeys([])
+            this.choosedList = []
+        },
+    },
+    mounted(){
+        //this.getTreeData()
+    }
+};
+</script>
+
+<style scoped lang="scss">
+.tree-transfer{
+    display: flex;
+    align-items: center;
+    gap:12px;
+    .transfer{
+        display: flex;
+        flex-direction: column;
+        width:254px;
+        height: 400px;
+        border:1px solid #DCDCDC;
+        border-radius: 6px;
+        padding:8px;
+        .head,.search,.content{
+            padding:10px;
+        }
+        .head{
+            display: flex;
+            justify-content: space-between;
+            .btn-text{
+                cursor: pointer;
+                &.delete{
+                    color:red;
+                }
+            }
+        }
+        .content{
+            flex:1;
+            overflow-y: scroll;
+            margin-bottom: 10px;
+            .list-item{
+                cursor: pointer;
+                padding:6px 0;
+                display: flex;
+                justify-content: space-between;
+            }
+        }
+    }
+}
+</style>

+ 95 - 0
src/views/approve_manage/config/tableConfig.js

@@ -0,0 +1,95 @@
+//审批管理-待处理
+export const approve_pending_columns = [
+    {
+        key:'ReportTitle',
+        label:'报告标题'
+    },{
+        key:'ReportClassify',
+        label:'关联报告'
+    },{
+        key:'ApplyUserName',
+        label:'提交人'
+    },{
+        key:'CreateTime',
+        label:'提交时间',
+        sortable:'custom'
+    },{
+        key:'RecordState',
+        label:'审批状态',
+    }
+]
+export const appreve_pending_status = [
+    {
+        type:1,
+        label:'待审批'
+    }
+]
+//审批管理-已处理
+export const approve_processed_columns=[
+    {
+        key:'ReportTitle',
+        label:'报告标题'
+    },{
+        key:'ReportClassify',
+        label:'关联报告'
+    },{
+        key:'ApplyUserName',
+        label:'提交人'
+    },{
+        key:'CreateTime',
+        label:'提交时间',
+        sortable:'custom'
+    },{
+        key:'HandleTime',
+        label:'处理时间',
+        sortable:'custom'
+    },{
+        key:'RecordState',
+        label:'处理结果',
+    }
+]
+export const approve_processed_status = [
+    {
+        type:1,
+        label:'已同意'
+    },{
+        type:2,
+        label:'已驳回'
+    }
+]
+//审批管理-我发起的
+export const approve_originate_columns=[
+    {
+        key:'ReportTitle',
+        label:'报告标题'
+    },{
+        key:'ReportClassify',
+        label:'关联报告'
+    },{
+        key:'CreateTime',
+        label:'提交时间',
+        sortable:'custom'
+    },{
+        key:'ApproveTime',
+        label:'审批时间',
+        sortable:'custom'
+    },{
+        key:'State',
+        label:'审批状态',
+    }
+]
+export const approve_originate_status=[
+    {
+        type:1,
+        label:'待审批'
+    },{
+        type:2,
+        label:'已通过'
+    },{
+        type:3,
+        label:'已驳回'
+    },{
+        type:4,
+        label:'已撤销'
+    }
+]

+ 39 - 0
src/views/approve_manage/css/nodeStyle.scss

@@ -0,0 +1,39 @@
+.node-wrap{
+    display: flex;
+    flex-direction: column;
+    /* align-items: center; */
+    .node-content{
+        overflow: hidden;
+        cursor: pointer;
+        border-radius: 4px;
+        width:300px;
+        min-height: 100px;
+        background-color: #fff;
+        border:1px solid #0052D9;
+        .head{
+            user-select: none;
+            color:#fff;
+            height:35px;
+            display: flex;
+            align-items: center;
+            padding: 5px;
+            justify-content: space-between;
+            border-bottom: 1px solid #0052D9;
+            .name{
+                margin-left: 5px;
+                margin-right: auto;
+            }
+            .icon{
+                display: inline-block;
+                width:20px;
+                height:20px;
+            }
+        }
+        .content{
+            padding:5px;
+        }
+    }
+    div{
+        box-sizing: border-box;
+    }
+}

+ 6 - 0
src/views/approve_manage/css/pageStyle.scss

@@ -0,0 +1,6 @@
+.approve-page-wrap{
+    min-height: calc(100vh - 120px);
+    background-color: #fff;
+    box-sizing: border-box;
+    padding:30px;
+}

+ 31 - 0
src/views/approve_manage/mixins/approveMixins.js

@@ -0,0 +1,31 @@
+import {approveInterence} from '@/api/modules/approve.js'
+const filterNodes = (arr,hasDisabled)=>{
+    arr.length &&arr.forEach((item) => {
+        hasDisabled&&(item.disabled = item.HasFlow)
+        item.Children.length && filterNodes(item.Children,hasDisabled);
+        if (!item.Children.length) {
+            delete item.Children;
+        }
+    })
+}
+
+export default{
+    data(){
+        return {
+            classifyTree:[],
+        }
+    },
+    methods:{
+        getClassifyTree(){
+            approveInterence.getReportClassifyTree().then(res=>{
+                if(res.Ret!==200) return 
+                this.classifyTree = res.Data||[]
+                const hasDisabled = window.location.pathname.startsWith('/approveEdit')
+                filterNodes(this.classifyTree,hasDisabled)
+                if(this.getFlowDetail){
+                    this.getFlowDetail()
+                }
+            })
+        },
+    }
+}

+ 3 - 4
src/views/dataEntry_manage/databaseList.vue

@@ -88,7 +88,6 @@
 						@node-drag-end="dropMouseLeave"
 						@node-drag-leave="dropMouseLeave"
 						@node-drag-enter="dropMouseOver"
-						@node-drag-over="dropMouseOver"
 					>
 						<span
 							class="custom-tree-node"
@@ -1422,8 +1421,8 @@ export default {
 				}
 			}else{//拖动的是目录
 				// console.log(dropNode.level,draggingNode.level);
-				//目录只能拖动到层级比他大的里面去
-				if(dropNode.level<draggingNode.level||(dropNode.level===draggingNode.level&&type!=='inner')){
+				//目录层级不能改变
+				if((dropNode.level+1==draggingNode.level&&type==='inner'&&!dropNode.data.EdbCode)||(dropNode.level===draggingNode.level&&type!=='inner')){
 					canDrop=true
 				}
 			}
@@ -1509,7 +1508,7 @@ export default {
 			// console.log(e.layerY);
 			
 			// 被拖拽节点对应的 Node、所进入节点对应的 Node、event
-			if((node1.level>node2.level||(node1.data.EdbInfoId>0&&!node2.data.EdbInfoId)) && (e.target.childNodes[0].className.includes('el-tree-node__content') 
+			if(!node2.data.EdbInfoId&&(node1.level>node2.level||(node1.data.EdbInfoId>0&&!node2.data.EdbInfoId)) && (e.target.childNodes[0].className.includes('el-tree-node__content') 
 			|| e.target.className.includes('el-tree-node__content'))) {
 				// console.log(e.target.childNodes[0])
 				e.target.childNodes[0].className.includes('el-tree-node__content') 

+ 3 - 3
src/views/predictEdb_manage/mixins/mixin.js

@@ -182,7 +182,7 @@ export default {
     /* 拖拽覆盖添加背景色 */
     dropMouseOver(node1, node2, e) {
       // 被拖拽节点对应的 Node、所进入节点对应的 Node、event
-			if((node1.level>node2.level||(node1.data.EdbInfoId>0&&!node2.data.EdbInfoId)) && (e.target.childNodes[0].className.includes('el-tree-node__content') 
+			if(!node2.data.EdbInfoId&&(node1.level>node2.level||(node1.data.EdbInfoId>0&&!node2.data.EdbInfoId)) && (e.target.childNodes[0].className.includes('el-tree-node__content') 
 			|| e.target.className.includes('el-tree-node__content'))) {
 				// console.log(e.target.childNodes[0])
 				e.target.childNodes[0].className.includes('el-tree-node__content') 
@@ -236,8 +236,8 @@ export default {
 				}
 			}else{//拖动的是目录
 				// console.log(dropNode.level,draggingNode.level);
-				//目录只能拖动到层级比他大的里面去
-				if(dropNode.level<draggingNode.level||(dropNode.level===draggingNode.level&&type!=='inner')){
+				//目录层级不能改变
+				if((dropNode.level+1==draggingNode.level&&type==='inner'&&!dropNode.data.EdbCode)||(dropNode.level===draggingNode.level&&type!=='inner')){
 					canDrop=true
 				}
 			}

+ 0 - 1
src/views/predictEdb_manage/predictEdb.vue

@@ -69,7 +69,6 @@
 						@node-drag-end="dropMouseLeave"
 						@node-drag-leave="dropMouseLeave"
 						@node-drag-enter="dropMouseOver"
-						@node-drag-over="dropMouseOver"
 					>
 						<span class="custom-tree-node" slot-scope="{ node, data }">
 							<el-input

+ 23 - 7
src/views/report_manage/addreportNew.vue

@@ -17,7 +17,8 @@
 			></froala>
 		</div>
 		<div id="rightitems" v-show="isRightFormShow">
-			<div
+			<!-- 通过接口判断是否走审批流,按钮显示的不一致,干脆判断完成再显示所有按钮-->
+			<div v-if="!pageLoading"
 				style="
 					text-align: right;
 					padding: 0px 0 15px 0;
@@ -50,23 +51,27 @@
 					>存草稿</el-button
 				>
 				<!--不走审批流-->
-				<template v-if="!isApprove">
+				<template v-if="!isApprove||!hasApproveFlow">
 					<el-button v-permission="permissionBtn.reportManageBtn.reportManage_publish"
 						type="primary"
 						size="medium"
+						:disabled="checkLoading"
 						@click.native="clickreportadd('dsfb')"
 						>定时发布</el-button
 					>
-					<el-button
+					<el-button v-permission="permissionBtn.reportManageBtn.reportManage_publish"
 						type="primary"
 						size="medium"
+						:disabled="checkLoading"
 						@click.native="clickreportadd('fb')"
 						:loading="isPublishloading"
 						>发布</el-button
 					>
 				</template>
-				<template v-if="isApprove">
-					<el-button type="primary" size="medium" @click="clickreportadd('fb')">提交</el-button>
+				<template v-if="isApprove&&hasApproveFlow">
+					<el-button v-permission="permissionBtn.reportManageBtn.reportManage_publish"
+						:disabled="checkLoading"
+						type="primary" size="medium" @click="clickreportadd('submit')">提交</el-button>
 				</template>
 			</div>
 			<div
@@ -368,10 +373,11 @@ import VueFroala from 'vue-froala-wysiwyg';
 import urlSlug from 'url-slug';
 import mixinMsg from './mixins/messagePush'
 import reportMixin from './mixins/reportMixin';
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
 import importMyChart from './components/importMyChart.vue'
 import importSemantics from './components/importSemantics.vue';
 export default {
-	mixins:[mixinMsg,reportMixin],
+	mixins:[mixinMsg,reportMixin,reportApproveConfig],
 	data() {
 		var that = this;
 		return {
@@ -507,6 +513,10 @@ export default {
 						frequency: res.Data.Frequency,
 						content: res.Data.Content,
 					};
+					let classify = this.aeForm.classifynameArr.map(i=>{
+						return JSON.parse(i).v||0
+					})
+					this.checkClassifyNameArr(1,classify)
 				}
 			});
 		},
@@ -518,6 +528,12 @@ export default {
 			});
 		},
 		userclassidreportdetail() {
+			//检查classifynameArr是否有审批流
+			let classify = this.aeForm.classifynameArr.map(i=>{
+				return JSON.parse(i).v||0
+			})
+			this.checkClassifyNameArr(1,classify)
+
 			if (this.aeForm.add_type == 1) {
 				if (this.aeForm.classifynameArr.length == 2) {
 					this.aeForm.title = JSON.parse(this.aeForm.classifynameArr[1]).l;
@@ -612,7 +628,7 @@ export default {
 				window.open(href, '_blank');
 				return false;
 			}
-			if (tp == 'fb') {
+			if (tp == 'fb'||tp == 'submit') {
 				this.isPublishloading = true;
 			}
 			const isPost = this.permissionBtn.checkPermissionBtn(this.permissionBtn.reportManageBtn.reportManage_sendMsg)&&(!this.isApprove)

+ 23 - 7
src/views/report_manage/editreportNew.vue

@@ -17,7 +17,8 @@
 			></froala>
 		</div>
 		<div id="rightitems" v-show="isRightFormShow">
-			<div
+			<!-- 通过接口判断是否走审批流,按钮显示的不一致,干脆判断完成再显示所有按钮-->
+			<div v-if="!pageLoading"
 				style="
 					text-align: right;
 					padding: 0px 0 15px 0;
@@ -50,23 +51,27 @@
 					>存草稿</el-button
 				>
 				<!--不走审批流-->
-				<template v-if="!isApprove">
+				<template v-if="!isApprove||!hasApproveFlow">
 					<el-button v-permission="permissionBtn.reportManageBtn.reportManage_publish"
 						type="primary"
 						size="medium"
+						:disabled="checkLoading"
 						@click.native="clickreportadd('dsfb')"
 						>定时发布</el-button
 					>
-					<el-button
+					<el-button v-permission="permissionBtn.reportManageBtn.reportManage_publish"
 						type="primary"
 						size="medium"
+						:disabled="checkLoading"
 						@click.native="clickreportadd('fb')"
 						:loading="isPublishloading"
 						>发布</el-button
 					>
 				</template>
-				<template v-if="isApprove">
-					<el-button type="primary" size="medium" @click="clickreportadd('fb')">提交</el-button>
+				<template v-if="isApprove&&hasApproveFlow">
+					<el-button v-permission="permissionBtn.reportManageBtn.reportManage_publish"
+						:disabled="checkLoading"
+						type="primary" size="medium" @click="clickreportadd('submit')">提交</el-button>
 				</template>
 			</div>
 			<div
@@ -364,10 +369,11 @@ import urlSlug from 'url-slug';
 import http from '@/api/http.js';
 import mixinMsg from './mixins/messagePush'
 import reportMixin from './mixins/reportMixin';
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
 import importMyChart from './components/importMyChart.vue'
 import importSemantics from './components/importSemantics.vue';
 export default {
-	mixins:[mixinMsg,reportMixin],
+	mixins:[mixinMsg,reportMixin,reportApproveConfig],
 	data() {
 		var that = this;
 		return {
@@ -486,6 +492,12 @@ export default {
 			// }
 		},
 		userclassidreportdetail() {
+			//检查classifynameArr是否有审批流
+			let classify = this.aeForm.classifynameArr.map(i=>{
+				return JSON.parse(i).v||0
+			})
+			this.checkClassifyNameArr(1,classify)
+
 			if (this.aeForm.add_type == 1) {
 				if (this.aeForm.classifynameArr.length == 2) {
 					this.aeForm.title = JSON.parse(this.aeForm.classifynameArr[1]).l;
@@ -587,6 +599,8 @@ export default {
 					if(data.PrePublishTime){
 						this.taskTime=data.PrePublishTime
 					}
+					let classify = [data.ClassifyIdFirst,data.ClassifyIdSecond]
+					this.checkClassifyNameArr(1,classify)
 				}
 			});
 		},
@@ -639,9 +653,11 @@ export default {
 				window.open(href, '_blank');
 				return false;
 			}
+			if(tp=='fb'||tp=='submit'){
+				this.isPublishloading = true;
+			}
 			const isPost = this.permissionBtn.checkPermissionBtn(this.permissionBtn.reportManageBtn.reportManage_sendMsg)&&(!this.isApprove)
 			if (tp == 'fb') {
-				this.isPublishloading = true;
 				// 判断是否要推送客群
 				let hasTel=0
 				if(this.aeForm.classifynameArr.length == 2){

+ 31 - 11
src/views/report_manage/mixins/messagePush.js

@@ -1,23 +1,14 @@
 import { reportadd, reportedit, messagePushPost,dataBaseInterface,reportMessageSend } from "@/api/api.js";
+import {approveInterence} from '@/api/modules/approve.js';
 import * as sheetInterface from '@/api/modules/sheetApi.js';
 import { getUrlParams } from '@/utils/common'
 export default {
   data() {
     return {
       isMessagePost: false,
-      //isApprove:false,//是否走审批流
-      isRightFormShow:true
+      isRightFormShow:true,
     };
   },
-  computed:{
-    //是否开启审批流,若开启,发布相关按钮,筛选项改变
-    isApprove(){
-        const type = this.$setting.dynamicOutLinks.ApprovalFlow ||
-                     this.$store.state.dynamicOutLinks.ApprovalFlow ||
-                     JSON.parse(localStorage.getItem('dynamicOutLinks')).ApprovalFlow||''
-        return ['1','3'].includes(type)
-    }
-  },
   methods: {
     reporteditMsg(params2, tp) {
       reportedit(params2).then(async (res) => {
@@ -46,6 +37,8 @@ export default {
           } else if(tp=='dsfb'){
             this.showDSFB=true
             // this.$router.push({path:'/reportlist'});
+          }else if(tp=='submit'){
+            this.handleSubmitReport(res.Data.ReportId)
           }
         }
       });
@@ -78,6 +71,8 @@ export default {
           } else if(tp=='dsfb'){
             this.showDSFB=true
             // this.$router.push({path:'/reportlist'});
+          }else if(tp=='submit'){
+            this.handleSubmitReport(res.Data.ReportId)
           }
           //已经添加过报告
           this.isAddEnter = true;
@@ -151,5 +146,30 @@ export default {
           }
       }
     },1000),
+    //展示提交审批弹窗
+    handleSubmitReport(id){
+        this.submitId = id
+        this.$confirm("是否确认提交该报告进入审批流程?","提示",{
+            confirmButtonText:'确定',
+            cancelButtonText:'取消',
+            type:'warning',
+        }).then(()=>{
+            this.submitReport("submit")
+        })
+        
+    },
+    //提交审批
+    submitReport(type){
+        /* if(type==='submit'){ */
+            approveInterence.reportCnSubmit({
+                ReportId:Number(this.submitId)
+            }).then(res=>{
+                if(res.Ret!==200) return
+                this.$message.success("提交成功")
+                this.isPublishloading = false;
+                this.$router.push({ path: '/reportlist' });
+            })
+        /* } */
+    }
   },
 };

+ 50 - 15
src/views/report_manage/reportEn/reportEditor.vue

@@ -31,7 +31,7 @@
     </div>
 		
 		<div id="rightitems" v-show="isRightFormShow">
-			<div
+			<div v-if="!pageLoading"
 				style="
 					text-align: right;
 					padding: 0px 0 15px 0;
@@ -63,19 +63,28 @@
 					@click.native="clickreportadd('cg')"
 					>存草稿</el-button
 				>
-				<el-button v-permission="permissionBtn.enReportManageBtn.enReport_publish"
-					type="primary"
-					size="medium"
-					@click.native="clickreportadd('dsfb')"
-					>定时发布</el-button
-				>
-				<el-button
-					type="primary"
-					size="medium"
-					@click.native="clickreportadd('fb')"
-					:loading="isPublishloading"
-					>发布</el-button
-				>
+				<template v-if="!isApprove||!hasApproveFlow">
+					<el-button v-permission="permissionBtn.enReportManageBtn.enReport_publish"
+						type="primary"
+						size="medium"
+						:disabled="checkLoading"
+						@click.native="clickreportadd('dsfb')"
+						>定时发布</el-button
+					>
+					<el-button v-permission="permissionBtn.enReportManageBtn.enReport_publish"
+						type="primary"
+						size="medium"
+						:disabled="checkLoading"
+						@click.native="clickreportadd('fb')"
+						:loading="isPublishloading"
+						>发布</el-button
+					>
+				</template>
+				<template v-if="isApprove&&hasApproveFlow">
+					<el-button v-permission="permissionBtn.enReportManageBtn.enReport_publish"
+						:disabled="checkLoading"
+						type="primary" size="medium" @click="clickreportadd('submit')">提交</el-button>
+				</template>
 			</div>
 			<div
 				style="margin: 0px 0 0 20px;padding: 10px 20px;box-sizing: border-box;background: #fff;border: 1px solid #3464e0;"
@@ -371,14 +380,16 @@ import {
 } from 'api/api.js';
 import {authorEn} from '@/api/modules/reportAuthorApi.js';
 import * as reportEnInterface from '@/api/modules/reportEnApi';
+import {approveInterence} from '@/api/modules/approve.js';
 import http from '@/api/http.js';
 import mixinMsg from '../mixins/messagePush'
 import reportMixin from '../mixins/reportMixin';
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
 import importMyChart from '../components/importMyChart.vue'
 import setEnNameDia from '@/views/dataEntry_manage/components/setEnNameDia.vue'
 import importSemantics from '../components/importSemantics.vue';
 export default {
-	mixins:[mixinMsg,reportMixin],
+	mixins:[mixinMsg,reportMixin,reportApproveConfig],
 	data() {
 		return {
 			//批量导入图表
@@ -574,6 +585,11 @@ export default {
 		},
 
 		userclassidreportdetail() {
+			//检查classifynameArr是否有审批流
+			let classify = this.aeForm.classifynameArr.map(i=>{
+				return JSON.parse(i).v||0
+			})
+			this.checkClassifyNameArr(2,classify)
 			// console.log(this.aeForm.classifynameArr,'this.aeForm.classifynameArr');
 			if (this.aeForm.add_type == 1) {
 				if (this.aeForm.classifynameArr.length == 3) {
@@ -672,6 +688,8 @@ export default {
 					if(data.PrePublishTime){
 						this.taskTime=data.PrePublishTime
 					}
+					let classify = [data.ClassifyIdRoot,data.ClassifyIdFirst,data.ClassifyIdSecond]
+					this.checkClassifyNameArr(2,classify)
 				}
 			});
 		},
@@ -754,6 +772,8 @@ export default {
 				}else if(tp==='dsfb'){
 					//定时发布
 					this.showDSFB=true
+				}else if(tp==='submit'){
+					this.submitReport()
 				}
 			// if (tp == 'yl') { //预览
 			// 	sessionStorage.setItem('reportdtl', JSON.stringify(params));
@@ -767,6 +787,21 @@ export default {
 			// 	this.reporteditMsg(params,tp)
 			// }
 		},
+		submitReport(){
+			this.$confirm("是否确认提交该报告进入审批流程?","提示",{
+				confirmButtonText:'确定',
+				cancelButtonText:'取消',
+				type:'warning',
+			}).then(()=>{
+				approveInterence.reportEnSubmit({
+					ReportId:Number(this.report_id)
+				}).then(res=>{
+					if(res.Ret!==200) return
+					this.$message.success("提交成功")
+					this.$router.push({ path: '/reportEnList' });
+				})
+			})
+		},
 
 		publishreport(id) {
 			//发布报告

+ 126 - 94
src/views/report_manage/reportEn/reportlist.vue

@@ -39,6 +39,7 @@
                             style="width:100%;"
                         >
                             <el-option label="发布时间" value="publish_time"></el-option>
+                            <el-option label="审批时间" value="approve_time"></el-option>
                             <el-option label="更新时间" value="modify_time"></el-option>
                         </el-select>
                     </div>
@@ -75,8 +76,12 @@
                             clearable
                             style="width:100%;"
                         >
+                            <el-option label="未发布" :value="1" v-if="!isOtherApprove"></el-option>
                             <el-option label="已发布" :value="2"></el-option>
-                            <el-option label="未发布" :value="1"></el-option>
+                            <el-option label="待提交" :value="3" v-if="isApprove"></el-option>
+                            <el-option label="待审批" :value="4" v-if="isApprove"></el-option>
+                            <el-option label="已驳回" :value="5"></el-option>
+                            <el-option label="已通过" :value="6"></el-option>
                         </el-select>
                     </div>
                     <div class="select-item">
@@ -100,17 +105,6 @@
                 </div>
             </el-popover>
           </el-form-item>
-          <!-- <el-form-item label="">
-            <el-select
-              v-model="searchform.timeType"
-              placeholder="选择时间类型"
-              size="medium"
-              style="width:110px"
-            >
-              <el-option label="发布时间" value="publish_time"></el-option>
-              <el-option label="更新时间" value="modify_time"></el-option>
-            </el-select>
-          </el-form-item> -->
           <el-form-item label="">
             <el-date-picker
               v-model="searchform.dateValue"
@@ -124,56 +118,6 @@
               style="width: 280px"
             ></el-date-picker>
           </el-form-item>
-          <!-- <el-form-item label="">
-            <el-select
-              v-model="searchform.frequency"
-              placeholder="更新频度筛选"
-              size="medium"
-              clearable
-              style="width: 140px"
-            >
-              <el-option v-for="item in frequencyArr" :key="item" :label="item" :value="item"></el-option>
-            </el-select>
-          </el-form-item> -->
-          <!-- <el-form-item label="">
-            <el-cascader
-              :options="optionsArr"
-              :props="{
-                value:'Id',
-                label:'ClassifyName',
-                children:'Child'
-              }"
-              v-model="searchform.classifynameArr"
-              clearable
-              placeholder="类型筛选"
-              size="medium"
-            ></el-cascader>
-          </el-form-item> -->
-          <!-- <el-form-item label="">
-            <el-select
-              v-model.number="searchform.publishState"
-              placeholder="发布筛选"
-              size="medium"
-              clearable
-              style="width: 140px"
-            >
-              <el-option label="已发布" :value="2"></el-option>
-              <el-option label="未发布" :value="1"></el-option>
-            </el-select>
-          </el-form-item> -->
-          <!-- <el-form-item label="">
-            <el-select
-              v-permission="permissionBtn.enReportManageBtn.enReport_sendEmail"
-              v-model.number="searchform.EmailState"
-              placeholder="群发状态筛选"
-              size="medium"
-              clearable
-              style="width: 140px"
-            >
-              <el-option label="未群发邮件" :value="1"></el-option>
-              <el-option label="已群发邮件" :value="2"></el-option>
-            </el-select>
-          </el-form-item> -->
           <el-form-item style="margin-left:auto;">
             <el-input
               placeholder="标题 / 创建人"
@@ -213,6 +157,9 @@
                 <i class="el-icon-warning"/>
               </el-tooltip>
             </span>
+            <span v-else-if="item.key==='PublishTime'">
+                发布/审批时间
+            </span>
             <span v-else>{{ item.label }}</span>
           </template>	
 					<template slot-scope="{row}">
@@ -225,7 +172,12 @@
                 <!-- <span v-if="row.ClassifyNameSecond">/ {{row.ClassifyNameSecond}}</span> -->
               </span>
               <span v-else-if="item.key==='State'" :style="row.State===2 && 'color:#46C371;'">
-                {{row.State===2 ? '已发布' : '未发布'}}
+                <span v-if="row.State == '1'">未发布</span>
+                <span v-if="row.State == '2'">已发布</span>
+                <span v-if="row.State == '3'">待提交</span>
+                <span v-if="row.State == '4'">待审批</span>
+                <span v-if="row.State == '5'">已驳回</span>
+                <span v-if="row.State == '6'">已通过</span>
               </span>
               <span v-else-if="item.key==='Stage'">第{{row.Stage}}期</span>
               <span v-else-if="item.key==='Pv'" style="cursor:pointer; color:#4099ef;" >
@@ -234,40 +186,86 @@
                 <span v-if="row.Pv" style="color:#333">{{row.Pv}}</span>
               </span>
               <span v-else-if="item.key==='PublishTime'">
-                <span>{{row.PrePublishTime?row.PrePublishTime:row.PublishTime}}</span>
-                <svg v-if="row.PrePublishTime&&row.State===1" width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
-                  <path d="M15.2002 8C15.2002 4.13401 12.0662 1 8.20019 1C4.3342 1 1.20019 4.13401 1.2002 8C1.2002 11.866 4.3342 15 8.2002 15C12.0662 15 15.2002 11.866 15.2002 8ZM5.2002 10L5.2002 9L8.17491 9L11.2002 4.5L11.9073 5.20711L8.58912 10L5.2002 10Z" fill="#0052D9"/>
-                </svg>
+                <template v-if="[1,2].includes(row.State)">
+                    <span>{{row.PrePublishTime?row.PrePublishTime:row.PublishTime}}</span>
+                    <svg v-if="row.PrePublishTime&&row.State===1" width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+                        <path d="M15.2002 8C15.2002 4.13401 12.0662 1 8.20019 1C4.3342 1 1.20019 4.13401 1.2002 8C1.2002 11.866 4.3342 15 8.2002 15C12.0662 15 15.2002 11.866 15.2002 8ZM5.2002 10L5.2002 9L8.17491 9L11.2002 4.5L11.9073 5.20711L8.58912 10L5.2002 10Z" fill="#0052D9"/>
+                    </svg>
+                </template>
+                <template v-else>
+                    <span>{{row.ApproveTime}}</span>
+                </template>
+                
+                
               </span>
 
               <span v-else-if="item.key==='handle'">
-                <template v-if="row.State===1">
-                    <span class="editsty" v-permission="permissionBtn.enReportManageBtn.enReport_publish"
-                        @click="reportHandle(row,'publish')" v-if="row.CanEdit">发布</span>
-                    <span v-permission="permissionBtn.enReportManageBtn.enReport_reportEdit"
-                        class="editsty" @click="reportHandle(row,'edit')" v-if="row.CanEdit">编辑</span>
-                  <!-- <span class="editsty" @click="reportHandle(row,'editing')" v-else>{{row.Editor||''}}编辑中...</span> -->
-                  <span v-permission="permissionBtn.enReportManageBtn.enReport_reportEdit"
-                    class="editsty" @click="reportHandle(row,'edit')" v-else>{{row.Editor||''}}编辑中...</span>
-                  <span v-permission="permissionBtn.enReportManageBtn.enReport_reportDel"
-                    class="deletesty" @click="reportHandle(row,'del')" v-if="row.CanEdit">删除</span>
-                </template>
-                <template v-else>
-                    <span v-if="permissionBtn.checkPermissionBtn(permissionBtn.enReportManageBtn.enReport_cancelPublish)"
-                        @click="reportHandle(row,'cancelPublish')" class="deletesty">取消发布</span>
-                    <span v-if="row.EmailState===0&&row.EmailAuth&&permissionBtn.checkPermissionBtn(permissionBtn.enReportManageBtn.enReport_sendEmail)"
-                        class="editsty copylink" @click="reportHandle(row,'sendEmail')">群发邮件</span>
+                    <!-- 操作:未发布——发布、编辑、删除
+                    已发布——取消发布、群发邮件/群发日志
+                    待提交——提交、编辑、删除
+                    待审批——撤销
+                    已通过——撤销、群发邮件/群发日志
+                    已驳回——撤销 -->
+                    <template v-if="[1,3].includes(row.State)">
+                        <span class="editsty" @click="reportHandle(row,'publish')" v-if="row.CanEdit&&row.State===1
+                                &&permissionBtn.isShowBtn('enReportManageBtn','enReport_publish')">发布</span>
+                        <span class="editsty" @click="handleSubmitReport(row)" v-if="row.CanEdit&&row.State===3
+                                &&permissionBtn.isShowBtn('enReportManageBtn','enReport_publish')">提交</span>
+                        <span v-permission="permissionBtn.enReportManageBtn.enReport_reportEdit" class="editsty"
+                            @click="reportHandle(row,'edit')" v-if="row.CanEdit">编辑</span>
+                        <span v-permission="permissionBtn.enReportManageBtn.enReport_reportEdit" class="editsty"
+                            @click="reportHandle(row,'edit')" v-else>{{row.Editor||''}}编辑中...</span>
+                        <span v-permission="permissionBtn.enReportManageBtn.enReport_reportDel" class="deletesty"
+                            @click="reportHandle(row,'del')" v-if="row.CanEdit">删除</span>
+                    </template>
+                    <template v-if="[2,6].includes(row.State)">
+                        <span
+                            v-if="permissionBtn.isShowBtn('enReportManageBtn','enReport_cancelPublish')&&row.State===2"
+                            @click="reportHandle(row,'cancelPublish')" class="deletesty">撤销</span><!-- 取消发布 -->
+                        <span
+                            v-if="permissionBtn.isShowBtn('enReportManageBtn','enReport_cancelPublish')&&row.State===6"
+                            @click="cancelApprove(row)" class="deletesty">撤销</span>
+                        <span
+                            v-if="row.EmailState===0&&row.EmailAuth&&permissionBtn.checkPermissionBtn(permissionBtn.enReportManageBtn.enReport_sendEmail)"
+                            class="editsty copylink" @click="reportHandle(row,'sendEmail')">群发邮件</span>
+
+                        <span class="editsty copylink"
+                            v-if="row.EmailState===1&&row.EmailAuth&&permissionBtn.checkPermissionBtn(permissionBtn.enReportManageBtn.enReport_sendEmail)"
+                            @click="reportHandle(row,'view-log')" style="position: relative;">
+                            群发日志
+                            <span class="warn-tag" v-if="row.EmailHasFail"></span>
+                        </span>
+                    </template>
+                    <template v-if="[4,5].includes(row.State)">
+                        <span v-if="permissionBtn.isShowBtn('enReportManageBtn','enReport_cancelPublish')"
+                            @click="cancelApprove(row)" class="deletesty">撤销</span>
+                    </template>
+
+                  <!-- <template v-if="row.State===1">
+                      <span class="editsty" v-permission="permissionBtn.enReportManageBtn.enReport_publish"
+                          @click="reportHandle(row,'publish')" v-if="row.CanEdit">发布</span>
+                      <span v-permission="permissionBtn.enReportManageBtn.enReport_reportEdit" class="editsty"
+                          @click="reportHandle(row,'edit')" v-if="row.CanEdit">编辑</span>
+                      <span v-permission="permissionBtn.enReportManageBtn.enReport_reportEdit" class="editsty"
+                          @click="reportHandle(row,'edit')" v-else>{{row.Editor||''}}编辑中...</span>
+                      <span v-permission="permissionBtn.enReportManageBtn.enReport_reportDel" class="deletesty"
+                          @click="reportHandle(row,'del')" v-if="row.CanEdit">删除</span>
+                  </template>
+                  <template v-else>
+                      <span
+                          v-if="permissionBtn.checkPermissionBtn(permissionBtn.enReportManageBtn.enReport_cancelPublish)"
+                          @click="reportHandle(row,'cancelPublish')" class="deletesty">取消发布</span>
+                      <span
+                          v-if="row.EmailState===0&&row.EmailAuth&&permissionBtn.checkPermissionBtn(permissionBtn.enReportManageBtn.enReport_sendEmail)"
+                          class="editsty copylink" @click="reportHandle(row,'sendEmail')">群发邮件</span>
 
-                  <span
-                    class="editsty copylink" 
-                    v-if="row.EmailState===1&&row.EmailAuth&&permissionBtn.checkPermissionBtn(permissionBtn.enReportManageBtn.enReport_sendEmail)" 
-                    @click="reportHandle(row,'view-log')"
-                    style="position: relative;"
-                  >
-                    群发日志 
-                    <span class="warn-tag" v-if="row.EmailHasFail"></span>
-                  </span>
-								</template>
+                      <span class="editsty copylink"
+                          v-if="row.EmailState===1&&row.EmailAuth&&permissionBtn.checkPermissionBtn(permissionBtn.enReportManageBtn.enReport_sendEmail)"
+                          @click="reportHandle(row,'view-log')" style="position: relative;">
+                          群发日志
+                          <span class="warn-tag" v-if="row.EmailHasFail"></span>
+                      </span>
+                  </template> -->
               </span>
 
 							<span v-else>{{ row[item.key] || '' }}</span>
@@ -456,9 +454,12 @@
 <script>
 import * as reportEnInterface from '@/api/modules/reportEnApi';
 import {strategyReportInterence,reportVarietyENInterence,customInterence} from '@/api/api.js'
+import {approveInterence} from '@/api/modules/approve.js';
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
 import mPage from '@/components/mPage.vue';
 import strategyReportEdit from '../components/strategyReportEdit.vue'
 export default {
+  mixins:[reportApproveConfig],
   watch: {
     searchform: {
       handler() {
@@ -533,7 +534,7 @@ export default {
             minwidthsty: 100
         },
         {
-            label: '发布状态',
+            label: '状态',
             key: 'State',
         },
         {
@@ -675,6 +676,37 @@ export default {
 
       handleMap[key](row);
     },
+    /* 提交报告 */
+    handleSubmitReport(row){
+        this.$confirm("是否确认提交该报告进入审批流程?","提示",{
+            confirmButtonText:'确定',
+            cancelButtonText:'取消',
+            type:'warning',
+        }).then(()=>{
+            approveInterence.reportEnSubmit({
+                ReportId:Number(row.Id)
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success("提交成功")
+                this.getTableData()
+            })
+        })
+    },
+    //撤销提交报告
+    cancelApprove(item){
+        this.$confirm("确定要撤销审批吗?","提示",{
+            confirmButtonText:'确定',
+            cancelButtonText:'取消'
+        }).then(()=>{
+            approveInterence.reportEnCancel({
+                ReportId:Number(item.Id)
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success("撤销成功")
+                this.getTableData()
+            })
+        })
+    },
 
     /* 发布报告 */
     publishReport(item) {

+ 24 - 9
src/views/report_manage/reportdtl.vue

@@ -7,7 +7,7 @@
 		</div>
 		
 		<!-- 英文版摘要+overview -->
-		<div id="abstract-en" v-if="$route.query.fromPage=='en'">
+		<div id="abstract-en" v-if="$route.query.fromPage=='en'||isEn">
 			<div 
 				class="abstract" 
 				:style="{borderBottom:reportInfo.Overview?'1px solid #C1C1C1':'none',paddingBottom:reportInfo.Overview?'20px':'0'}"
@@ -31,7 +31,7 @@
 			</div>
 		</div>
 		<div id="abstract" v-else>
-		  <div>{{$route.query.fromPage=='en'?'Abstract':'摘要'}}:{{reportInfo.Abstract}}</div>
+		  <div>{{($route.query.fromPage=='en'||isEn)?'Abstract':'摘要'}}:{{reportInfo.Abstract}}</div>
 		</div>
 		<div id="resetsty" style="padding:30px; box-sizing:border-box; overflow:hidden;">
 			<block v-if="reportInfo.ChapterType=='day'||reportInfo.ChapterType=='week'">
@@ -95,6 +95,16 @@
 				return str
 			}
 		},
+		props:{
+			reportId:{ //审批详情-预览报告
+				type:Number,
+				default:0
+			},
+			isEn:{
+				type:Boolean,
+				default:false
+			}
+		},
 		data() {
 			return {
 				id:parseInt(this.$route.query.id),
@@ -110,7 +120,7 @@
 			vueQr
 		},
 		mounted() {
-			if(this.$route.query.id) {
+			if(this.$route.query.id||this.reportId) {
 				this.getreportdetail();
 			}else {
 				let reportdtl=sessionStorage.getItem('reportdtl') || false;
@@ -136,15 +146,20 @@
 			},
 			async getreportdetail(){
 				let res
-				if(this.$route.query.fromPage == 'en'){
-					res=await reportEnInterface.reportDetail({ReportId:parseInt(this.id)})
+				let reportId = this.id||this.reportId
+				this.$emit("reportStartLoading")
+				if((this.$route.query.fromPage == 'en'||this.isEn)){
+					res=await reportEnInterface.reportDetail({ReportId:parseInt(reportId)})
 				}else if(this.$route.query.fromPage == 'strategyReport'){
-					res=await strategyReportInterence.getReportDetail({Id:parseInt(this.id)})
+					res=await strategyReportInterence.getReportDetail({Id:parseInt(reportId)})
 				}else{
-					res=await reportdetail({ReportId:parseInt(this.id)})
+					res=await reportdetail({ReportId:parseInt(reportId)})
+				}
+				this.$emit("reportEndLoading")
+				if( res.Ret!==200 ){
+					this.$emit("reportError")
+					return 
 				}
-
-				if( res.Ret!==200 )return
 
 				this.reportInfo=res.Data;
 				this.isshow=true;

+ 129 - 131
src/views/report_manage/reportlist.vue

@@ -49,7 +49,8 @@
                             style="width:100%;"
                             @change="search"
                         >
-                            <el-option :label="isApprove?'审批时间':'发布时间'" value="publish_time"></el-option>
+                            <el-option label="发布时间" value="publish_time"></el-option>
+                            <el-option label="审批时间" value="approve_time"></el-option>
                             <el-option label="更新时间" value="modify_time"></el-option>
                         </el-select>
                     </div>
@@ -82,20 +83,7 @@
                             style="width:100%;"
                         ></el-cascader>
                     </div>
-                    <div class="select-item" v-if="!isApprove">
-                        <el-select 
-                            v-model.number="searchform.publishState"
-                            placeholder="发布筛选"
-                            size="medium"
-                            clearable
-                            style="width:100%;"
-                            @change="search"
-                        >
-                            <el-option label="已发布" :value="2"></el-option>
-                            <el-option label="未发布" :value="1"></el-option>
-                        </el-select>
-                    </div>
-                    <div class="select-item" v-if="isApprove">
+                    <div class="select-item">
                         <el-select
                             v-model.number="searchform.publishState"
                             placeholder="状态筛选"
@@ -104,10 +92,12 @@
                             style="width:100%;"
                             @change="search"
                         >
-                            <el-option label="待提交" :value="1"></el-option>
-                            <el-option label="待审批" :value="2"></el-option>
-                            <el-option label="已审批" :value="4"></el-option>
-                            <el-option label="已驳回" :value="3"></el-option>
+                            <el-option label="未发布" :value="1" v-if="!isOtherApprove"></el-option>
+                            <el-option label="已发布" :value="2"></el-option>
+                            <el-option label="待提交" :value="3" v-if="isApprove"></el-option>
+                            <el-option label="待审批" :value="4" v-if="isApprove"></el-option>
+                            <el-option label="已驳回" :value="5"></el-option>
+                            <el-option label="已通过" :value="6"></el-option>
                         </el-select>
                     </div>
                     <div class="select-item">
@@ -227,24 +217,18 @@
             align="center"
             min-width="100"
           ></el-table-column>
-          <el-table-column label="发布状态" align="center" v-if="!isApprove">
-            <template slot-scope="scope">
-              <span v-if="scope.row.State == '2'" style="color: #46c371"
-                >已发布</span
-              >
-              <span v-if="scope.row.State == '1'">未发布</span>
-            </template>
-          </el-table-column>
           <el-table-column label="状态" align="center" v-if="isApprove">
             <template slot-scope="scope">
-                <span v-if="scope.row.State == '1'">待提交</span>
-                <span v-if="scope.row.State == '2'">待审批</span>
-                <span v-if="scope.row.State == '4'">已审批</span>
-                <span v-if="scope.row.State == '3'">已驳回</span>
+                <span v-if="scope.row.State == '1'">未发布</span>
+                <span v-if="scope.row.State == '2'">已发布</span>
+                <span v-if="scope.row.State == '3'">待提交</span>
+                <span v-if="scope.row.State == '4'">待审批</span>
+                <span v-if="scope.row.State == '5'">已驳回</span>
+                <span v-if="scope.row.State == '6'">已通过</span>
             </template>
           </el-table-column>
 
-          <el-table-column
+          <!-- <el-table-column
             v-if="!isApprove"
             prop="PublishTime"
             label="发布时间"
@@ -261,14 +245,27 @@
           </el-table-column>
           <el-table-column
             v-if="isApprove"
-            prop="PublishTime"
+            prop="ApproveTime"
             label="审批时间"
             min-width="124"
             align="center"
             :formatter="formatterColumn"
           >
             <template slot-scope="scope">
-                <span>{{scope.row.PrePublishTime?scope.row.PrePublishTime:scope.row.PublishTime|formatTime}}</span>
+                <span>{{scope.row.ApproveTime|formatTime}}</span>
+            </template>
+          </el-table-column> -->
+          <el-table-column prop="PublishTime" label="发布/审批时间" min-width="124" align="center">
+            <template slot-scope="scope">
+                <template v-if="[1,2].includes(scope.row.State)">
+                    <span>{{scope.row.PrePublishTime?scope.row.PrePublishTime:scope.row.PublishTime|formatTime}}</span>
+                    <svg style="position: relative;top:2px" v-if="scope.row.PrePublishTime&&scope.row.State == '1'" width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+                        <path d="M15.2002 8C15.2002 4.13401 12.0662 1 8.20019 1C4.3342 1 1.20019 4.13401 1.2002 8C1.2002 11.866 4.3342 15 8.2002 15C12.0662 15 15.2002 11.866 15.2002 8ZM5.2002 10L5.2002 9L8.17491 9L11.2002 4.5L11.9073 5.20711L8.58912 10L5.2002 10Z" fill="#0052D9"/>
+                    </svg>
+                </template>
+                <template v-else>
+                    <span>{{scope.row.ApproveTime|formatTime}}</span>
+                </template>
             </template>
           </el-table-column>
 
@@ -314,96 +311,62 @@
           <el-table-column label="操作" align="center" min-width="130" fixed="right">
             <template slot-scope="scope">
               <div class="opt-btns">
-                <!--不走审批流的按钮-->
-                <template v-if="!isApprove">
-                    <template v-if="scope.row.State == 1">
-                        <span v-permission="permissionBtn.reportManageBtn.reportManage_publish" class="editsty"
-                            @click="publishreport(scope.row)" v-if="scope.row.CanEdit">发布</span>
-                        <span v-permission="permissionBtn.reportManageBtn.reportManage_reportEdit" class="editsty"
-                            @click="editreport(scope.row, 'edit')" v-if="scope.row.CanEdit">编辑</span>
-                        <span v-permission="permissionBtn.reportManageBtn.reportManage_reportEdit" class="editsty"
-                            @click="editreport(scope.row, 'editing')" v-else>{{ scope.row.Editor || "" }}编辑中...</span>
-                        <span v-permission="permissionBtn.reportManageBtn.reportManage_reportDel" class="deletesty"
-                            @click="deleteitem(scope.row)" v-if="scope.row.CanEdit">删除</span>
-                    </template>
-                    <template v-if="scope.row.State == 2">
-                        <span
-                            v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_cancelPublish)"
-                            @click="canclepublish(scope.row)" style="color: red; cursor: pointer">取消发布</span>
-                        <span
-                            v-if="scope.row.MsgIsSend == 0 && permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_sendMsg)"
-                            style="color: #4099ef; cursor: pointer" @click="messageSend(scope.row)">推送消息</span>
-                        <span
-                            v-else-if="scope.row.MsgIsSend != 0&&permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_sendMsg)"
-                            style="color: red">已推送消息</span>
-                    </template>
-                    <span style="color: #46c371; cursor: pointer"
-                        v-if="!['晨报', '周报'].includes(scope.row.ClassifyNameFirst)&&permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_audioUpload)"
-                        @click="openupload(scope.row.Id)">音频上传</span>
-                    <a v-permission="permissionBtn.reportManageBtn.reportManage_audioDownload"
-                        :href="hostapi + '?ReportId=' + parseInt(scope.row.Id)" v-if="
-                        scope.row.VideoUrl &&
-                        !['晨报', '周报'].includes(scope.row.ClassifyNameFirst)
-                    " :download="scope.row.VideoName" style="cursor: pointer; color: #4099ef">音频下载</a>
-                    <span v-permission="permissionBtn.reportManageBtn.reportManage_audioDownload"
-                        style="cursor: pointer; color: #4099ef" v-if="
-                        ['晨报', '周报'].includes(scope.row.ClassifyNameFirst) &&
-                        scope.row.ChapterVideoList.length > 0
-                    " @click="handleShowDownloadAudio(scope.row)">音频下载</span>
+                <!-- 操作:未发布——发布、编辑、删除
+                    已发布——取消发布、推送消息/已推送消息
+                    待提交——提交、编辑、删除
+                    待审批——撤销
+                    已通过——撤销、推送消息/已推送消息
+                    已驳回——撤销 
+                -->
+                <!-- 未发布,待提交 -->
+                <template v-if="[1,3].includes(scope.row.State)">
+                    <span class="editsty" @click="publishreport(scope.row)"
+                        v-if="scope.row.CanEdit&&scope.row.State===1
+                            &&permissionBtn.isShowBtn('reportManageBtn','reportManage_publish')"
+                    >发布</span>
+                    <span class="editsty" @click="handleSubmitReport(scope.row)"
+                        v-if="scope.row.CanEdit&&scope.row.State===3
+                            &&permissionBtn.isShowBtn('reportManageBtn','reportManage_publish')"
+                    >提交</span>
+                    <span v-permission="permissionBtn.reportManageBtn.reportManage_reportEdit" class="editsty"
+                        @click="editreport(scope.row, 'edit')" v-if="scope.row.CanEdit">编辑</span>
+                    <span v-permission="permissionBtn.reportManageBtn.reportManage_reportEdit" class="editsty"
+                        @click="editreport(scope.row, 'editing')" v-else>{{ scope.row.Editor || "" }}编辑中...</span>
+                    <span v-permission="permissionBtn.reportManageBtn.reportManage_reportDel" class="deletesty"
+                        @click="deleteitem(scope.row)" v-if="scope.row.CanEdit">删除</span>
                 </template>
-                <!--走审批流的按钮,权限与原先按钮对应-->
-                <template v-if="isApprove">
-                    <!--待提交-->
-                    <template v-if="scope.row.State===1">
-                        <span v-permission="permissionBtn.reportManageBtn.reportManage_publish"
-                            @click="publishreport(scope.row)"
-                            class="editsty">提交</span>
-                        <span v-permission="permissionBtn.reportManageBtn.reportManage_reportEdit" class="editsty"
-                            @click="editreport(scope.row, 'edit')" v-if="scope.row.CanEdit">编辑</span>
-                        <span v-permission="permissionBtn.reportManageBtn.reportManage_reportEdit" class="editsty"
-                            @click="editreport(scope.row, 'editing')" v-else>{{ scope.row.Editor || "" }}编辑中...</span>
-                        <span v-permission="permissionBtn.reportManageBtn.reportManage_reportDel" class="deletesty"
-                            @click="deleteitem(scope.row)" v-if="scope.row.CanEdit">删除</span>
-                    </template>
-                    <!--已提交(待审批,已审批)-->
-                    <template v-if="[2,4].includes(scope.row.State)">
-                        <span
-                            v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_cancelPublish)"
-                            @click="canclepublish(scope.row)"
-                            class="editsty">撤销</span>
-                        <template v-if="scope.row.State!==2">
-                            <span
-                                v-if="scope.row.MsgIsSend == 0 && permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_sendMsg)"
-                                style="color: #4099ef; cursor: pointer" @click="messageSend(scope.row)">推送消息</span>
-                            <span
-                                v-else-if="scope.row.MsgIsSend != 0&&permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_sendMsg)"
-                                style="color: red">已推送消息</span>
-                        </template>
-                    </template>
-
-                    <!--已驳回则只显示撤销按钮-->
-                    <template v-if="scope.row.State===3">
-                        <span v-permission="permissionBtn.reportManageBtn.reportManage_publish"
-                            @click="canclepublish(scope.row)"
-                            class="editsty">撤销</span>
-                    </template>
-                    <!--音频上传/下载 按原先逻辑-->
-                    <template v-if="scope.row.State!==3">
-                        <span style="color: #46c371; cursor: pointer"
-                            v-if="!['晨报', '周报'].includes(scope.row.ClassifyNameFirst)&&permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_audioUpload)"
-                            @click="openupload(scope.row.Id)">音频上传</span>
-                        <a v-permission="permissionBtn.reportManageBtn.reportManage_audioDownload"
-                            :href="hostapi + '?ReportId=' + parseInt(scope.row.Id)" v-if="
-                            scope.row.VideoUrl &&
-                            !['晨报', '周报'].includes(scope.row.ClassifyNameFirst)
-                        " :download="scope.row.VideoName" style="cursor: pointer; color: #4099ef">音频下载</a>
-                        <span v-permission="permissionBtn.reportManageBtn.reportManage_audioDownload"
-                            style="cursor: pointer; color: #4099ef" v-if="
-                            ['晨报', '周报'].includes(scope.row.ClassifyNameFirst) &&
-                            scope.row.ChapterVideoList.length > 0
-                        " @click="handleShowDownloadAudio(scope.row)">音频下载</span>
-                    </template>
+                <!-- 已发布,已通过 -->
+                <template v-if="[2,6].includes(scope.row.State)">
+                    <span v-if="scope.row.State===2&&permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_cancelPublish)"
+                        @click="canclepublish(scope.row)" style="color: red; cursor: pointer">撤销</span><!-- 取消发布 -->
+                    <span v-if="scope.row.State===6&&permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_cancelPublish)"
+                        @click="cancelReport(scope.row)" style="color: red; cursor: pointer">撤销</span>
+                    <span
+                        v-if="scope.row.MsgIsSend == 0 && permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_sendMsg)"
+                        style="color: #4099ef; cursor: pointer" @click="messageSend(scope.row)">推送消息</span>
+                    <span
+                        v-else-if="scope.row.MsgIsSend != 0&&permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_sendMsg)"
+                        style="color: red">已推送消息</span>
+                </template>
+                <!-- 待审批,已驳回 -->
+                <template v-if="[4,5].includes(scope.row.State)">
+                    <span v-if="permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_cancelPublish)"
+                        @click="cancelReport(scope.row)" style="color: red; cursor: pointer">撤销</span>
                 </template>
+                <!-- 音频上传和下载,跟State无关 -->
+                <span style="color: #46c371; cursor: pointer"
+                    v-if="!['晨报', '周报'].includes(scope.row.ClassifyNameFirst)&&permissionBtn.checkPermissionBtn(permissionBtn.reportManageBtn.reportManage_audioUpload)"
+                    @click="openupload(scope.row.Id)">音频上传</span>
+                <a v-permission="permissionBtn.reportManageBtn.reportManage_audioDownload"
+                    :href="hostapi + '?ReportId=' + parseInt(scope.row.Id)" v-if="
+                    scope.row.VideoUrl &&
+                    !['晨报', '周报'].includes(scope.row.ClassifyNameFirst)
+                " :download="scope.row.VideoName" style="cursor: pointer; color: #4099ef">音频下载</a>
+                <span v-permission="permissionBtn.reportManageBtn.reportManage_audioDownload"
+                    style="cursor: pointer; color: #4099ef" v-if="
+                    ['晨报', '周报'].includes(scope.row.ClassifyNameFirst) &&
+                    scope.row.ChapterVideoList.length > 0
+                " @click="handleShowDownloadAudio(scope.row)">音频下载</span>
               </div>
             </template>
           </el-table-column>
@@ -638,7 +601,10 @@ import {
   reportMessageSend,
   weekReportValidAudio,
 } from "api/api.js";
+import {approveInterence} from '@/api/modules/approve.js';
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
 export default {
+  mixins:[reportApproveConfig],
   computed: {
     exportUrlDl() {
       let url = this.exportUrl;
@@ -672,13 +638,6 @@ export default {
     hasUV(){
       return this.permissionBtn.checkPermissionBtn(this.permissionBtn.reportManageBtn.reportManage_reportList_uv)
     },
-    //是否开启审批流,若开启,发布相关按钮,筛选项改变
-    isApprove(){
-        const type = this.$setting.dynamicOutLinks.ApprovalFlow ||
-                     this.$store.state.dynamicOutLinks.ApprovalFlow ||
-                     JSON.parse(localStorage.getItem('dynamicOutLinks')).ApprovalFlow||''
-        return ['1','3'].includes(type)
-    }
   },
   data() {
     return {
@@ -725,9 +684,9 @@ export default {
       showPublish: false,
       isDSFB:false,//是否为定时发布
       tableKey:0,
-      selectNum:1
+      selectNum:1,
 
-      //isApprove:false,//是否开启审批流,若开启,发布相关按钮,筛选项改变
+      submitId:0,//当前选择的报告id
     };
   },
   mounted() {
@@ -1065,6 +1024,45 @@ export default {
       this.batches = [];
       this.showPublish = false;
     },
+    //提交报告
+    handleSubmitReport(item){
+        this.submitId = item.Id
+        this.$confirm("是否确认提交该报告进入审批流程?","提示",{
+            confirmButtonText:'确定',
+            cancelButtonText:'取消',
+            type:'warning',
+        }).then(()=>{
+            this.submitReport("submit")
+        })
+        
+    },
+    submitReport(type){
+        //both:提交&推送
+        /* if(type==='submit'){ */
+            approveInterence.reportCnSubmit({
+                ReportId:Number(this.submitId)
+            }).then(res=>{
+                if(res.Ret!==200) return
+                this.$message.success("提交成功")
+                this.getlist()
+            })
+        /* } */
+    },
+    //撤销提交报告
+    cancelReport(item){
+        this.$confirm("确定要撤销审批吗?","提示",{
+            confirmButtonText:'确定',
+            cancelButtonText:'取消'
+        }).then(()=>{
+            approveInterence.reportCnCancel({
+                ReportId:Number(item.Id)
+            }).then(res=>{
+                if(res.Ret!==200) return 
+                this.$message.success("撤销成功")
+                this.getlist()
+            })
+        })
+    },
 
     selectchange(val) {
       //多选操作

+ 41 - 16
src/views/smartReport/editReport.vue

@@ -20,18 +20,21 @@
                     <img src="~@/assets/img/smartReport/icon01.png" alt="">
                     <span>存草稿</span>
                 </li>
-                <template v-if="!isApprove">
-                    <li class="action-item" @click="handlePublishOpt('dsfb')">
+                <template v-if="!isApprove||!hasApproveFlow">
+                    <li class="action-item" :class="{'disabled':checkLoading}"
+                        @click="handlePublishOpt('dsfb')">
                         <img src="~@/assets/img/smartReport/icon01.png" alt="">
                         <span>定时发布</span>
                     </li>
-                    <li class="action-item" @click="handlePublishOpt('fb')">
+                    <li class="action-item" :class="{'disabled':checkLoading}"
+                        @click="handlePublishOpt('fb')">
                         <img src="~@/assets/img/smartReport/icon01.png" alt="">
                         <span>发布</span>
                     </li>
                 </template>
-                <template v-if="isApprove">
-                    <li class="action-item" @click="handlePublishOpt('fb')">
+                <template v-if="isApprove&&hasApproveFlow">
+                    <li class="action-item" :class="{'disabled':checkLoading}"
+                        @click="handlePublishOpt('submit')">
                         <img src="~@/assets/img/smartReport/icon01.png" alt="">
                         <span>提交</span>
                     </li>
@@ -240,14 +243,17 @@ import ETASheet from './components/ETASheet.vue'
 import { getPublicSettingsApi } from '@/api/modules/oldApi';
 import { dataBaseInterface } from "@/api/api.js";
 import {apiSmartReport}  from '@/api/modules/smartReport'
+import {approveInterence} from '@/api/modules/approve.js';
 import BaseInfo from './components/BaseInfo.vue'
 import StatisticAnalysis from './components/StatisticAnalysis.vue'
 import ETAPriceChart from './components/ETAPriceChart.vue'
 import ETASandBox from './components/ETASandBox.vue'
 import SemanticAnalysis from './components/SemanticAnalysis.vue'
 import { getUrlParams } from '@/utils/common'
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
 import ImgSource from './components/ImgSource.vue'
 export default {
+    mixins:[reportApproveConfig],
     name:"smartReportEdit",
     components: {
         draggable,
@@ -290,15 +296,6 @@ export default {
             deep:true
         }
     },
-    computed:{
-        //是否开启审批流,若开启,发布相关按钮,筛选项改变
-        isApprove(){
-            const type = this.$setting.dynamicOutLinks.ApprovalFlow ||
-                        this.$store.state.dynamicOutLinks.ApprovalFlow ||
-                        JSON.parse(localStorage.getItem('dynamicOutLinks')).ApprovalFlow||''
-            return ['2','3'].includes(type)
-        }
-    },
     data() {
         return {
             reportInfo:null,
@@ -804,6 +801,10 @@ export default {
                 CanvasColor:this.bgColor
             }
             console.log(params);
+            //检查classifynameArr是否有审批流
+            let classify = [e.ClassifyIdFirst,e.ClassifyIdSecond]
+            this.checkClassifyNameArr(3,classify)
+
             apiSmartReport.reportEdit({...params}).then(res=>{
                 if(res.Ret===200){
                     this.$message.success('保存成功')
@@ -837,6 +838,8 @@ export default {
                     this.$nextTick(()=>{
                         this.contentChange=false
                     })
+                    let classify = [res.Data.ClassifyIdFirst,res.Data.ClassifyIdSecond]
+                    this.checkClassifyNameArr(3,classify)
                 }
             })
         },
@@ -924,10 +927,11 @@ export default {
                 return
             }
             // 发布
-            if(this.isApprove){
-                this.reportPublish({sendMsg:false})
+            if(type==='submit'){
+                this.submitReport()
                 return
             }
+            //截止至ETA1.3.8 智能研报无推送模板消息,所有的reportInfo.MsgIsSend都为1
             if(this.reportInfo.MsgIsSend==1){//该报告已经推送过模板消息
                 this.reportPublish({sendMsg:false})
             }else{
@@ -960,6 +964,22 @@ export default {
                 )
             }
         },
+        //提交报告
+        submitReport(){
+            this.$confirm("是否确认提交该报告进入审批流程?","提示",{
+                confirmButtonText:'确定',
+                cancelButtonText:'取消',
+                type:'warning',
+            }).then(()=>{
+                approveInterence.reportSmartSubmit({
+                    ReportId:Number(this.$route.query.id)
+                }).then(res=>{
+                    if(res.Ret!==200) return 
+                    this.$message.success("提交成功")
+                    this.$router.replace({ path: '/smartReportList' });
+                })
+            })
+        },
 
         // 定时发布报告
         async handleSetReportPrepublish(){
@@ -1180,6 +1200,11 @@ div{
                 &:last-child{
                     border-right: none;
                 }
+                &.disabled{
+                    pointer-events: none;
+                    cursor: not-allowed;
+                    color:#999;
+                }
             }
         }
     }

+ 12 - 2
src/views/smartReport/reportDetail.vue

@@ -10,7 +10,7 @@
             </div> -->
             <div class="html-wrap" v-html="content"></div>
         </div>
-        <div class="right-opt-box" v-if="$route.query.type!=='preview'">
+        <div class="right-opt-box" v-if="$route.query.type!=='preview'&&!reportId">
             <div 
                 class="item copy" 
                 v-if="linkUrl" 
@@ -73,6 +73,12 @@ export default {
             return ['2','3'].includes(type)
         }
     },
+    props:{
+        reportId:{//审批详情-预览报告
+            type:Number,
+            default:0
+        }
+    },
     data() {
         return {
             reportInfo:null,
@@ -87,11 +93,13 @@ export default {
     methods: {
         // 获取报告详情
         getReportDetail(){
-            const id=this.$route.query.id||0
+            const id=this.$route.query.id||this.reportId||0
             if(!id) return
+            this.$emit("reportStartLoading")
             apiSmartReport.reportDetail({
                 SmartReportId:Number(id)
             }).then(res=>{
+                this.$emit("reportEndLoading")
                 if(res.Ret===200){
                     this.reportInfo=res.Data
                     if(this.$route.query.type==='preview'){
@@ -99,6 +107,8 @@ export default {
                     }else{
                         this.content=res.Data.Content
                     }
+                }else{
+                    this.$emit("reportError")
                 }
             })
         },

+ 116 - 166
src/views/smartReport/reportList.vue

@@ -29,7 +29,8 @@
                                     style="width:100%"
                                     @change="search"
                                     >
-                                    <el-option :label="isApprove?'审批时间':'发布时间'" value="publish_time"></el-option>
+                                    <el-option label="发布时间" value="publish_time"></el-option>
+                                    <el-option label="审批时间" value="approve_time"></el-option>
                                     <el-option label="更新时间" value="modify_time"></el-option>
                                 </el-select>
                             </div>
@@ -62,20 +63,7 @@
                                     style="width:100%;"
                                 />
                             </div>
-                            <div class="select-item" v-if="!isApprove">
-                                <el-select
-                                    v-model.number="searchform.publishState"
-                                    placeholder="发布筛选"
-                                    size="medium"
-                                    clearable
-                                    style="width:100%;"
-                                    @change="search"
-                                >
-                                    <el-option label="已发布" :value="2"></el-option>
-                                    <el-option label="未发布" :value="1"></el-option>
-                                </el-select>
-                            </div>
-                            <div class="select-item" v-if="isApprove">
+                            <div class="select-item">
                                 <el-select
                                     v-model.number="searchform.publishState"
                                     placeholder="状态筛选"
@@ -84,10 +72,12 @@
                                     style="width:100%;"
                                     @change="search"
                                 >
-                                    <el-option label="待提交" :value="1"></el-option>
-                                    <el-option label="待审批" :value="2"></el-option>
-                                    <el-option label="已审批" :value="4"></el-option>
-                                    <el-option label="已驳回" :value="3"></el-option>
+                                    <el-option label="未发布" :value="1" v-if="!isOtherApprove"></el-option>
+                                    <el-option label="已发布" :value="2"></el-option>
+                                    <el-option label="待提交" :value="3" v-if="isApprove"></el-option>
+                                    <el-option label="待审批" :value="4" v-if="isApprove"></el-option>
+                                    <el-option label="已驳回" :value="5"></el-option>
+                                    <el-option label="已通过" :value="6"></el-option>
                                 </el-select>
                             </div>
                         </div>
@@ -112,20 +102,6 @@
                         style="width: 280px"
                     />
                 </el-form-item>
-                <!-- <el-form-item label="">
-                    <el-select
-                        v-permission="permissionBtn.smartReportManageBtn.reportManage_reportList_sendTime"
-                        @change="search"
-                        v-model.number="searchform.msgIsSend"
-                        placeholder="推送消息状态"
-                        size="medium"
-                        clearable
-                        style="width: 140px"
-                    >
-                        <el-option label="未推送消息" :value="1"></el-option>
-                        <el-option label="已推送消息" :value="2"></el-option>
-                    </el-select>
-                </el-form-item> -->
                 <el-form-item style="flex:1;text-align:right;">
                     <el-input
                         @input="search"
@@ -207,23 +183,17 @@
                     align="center"
                     min-width="100"
                 ></el-table-column>
-                <el-table-column label="发布状态" align="center" v-if="!isApprove">
-                    <template slot-scope="scope">
-                    <span v-if="scope.row.State == '2'" style="color: #46c371"
-                        >已发布</span
-                    >
-                    <span v-if="scope.row.State == '1'">未发布</span>
-                    </template>
-                </el-table-column>
-                <el-table-column label="状态" align="center" v-if="isApprove">
+                <el-table-column label="状态" align="center">
                     <template slot-scope="scope">
-                        <span v-if="scope.row.State == '1'">待提交</span>
-                        <span v-if="scope.row.State == '2'">待审批</span>
-                        <span v-if="scope.row.State == '4'">已审批</span>
-                        <span v-if="scope.row.State == '3'">已驳回</span>
+                        <span v-if="scope.row.State == '1'">未发布</span>
+                        <span v-if="scope.row.State == '2'">已发布</span>
+                        <span v-if="scope.row.State == '3'">待提交</span>
+                        <span v-if="scope.row.State == '4'">待审批</span>
+                        <span v-if="scope.row.State == '5'">已驳回</span>
+                        <span v-if="scope.row.State == '6'">已通过</span>
                     </template>
                 </el-table-column>
-                <el-table-column v-if="!isApprove"
+                <!-- <el-table-column v-if="!isApprove"
                     prop="PublishTime"
                     label="发布时间"
                     min-width="124"
@@ -239,26 +209,29 @@
                 </el-table-column>
                 <el-table-column
                     v-if="isApprove"
-                    prop="PublishTime"
+                    prop="ApproveTime"
                     label="审批时间"
                     min-width="124"
                     align="center"
                     :formatter="formatterColumn"
                 >
                     <template slot-scope="scope">
-                        <span>{{scope.row.PrePublishTime?scope.row.PrePublishTime:scope.row.PublishTime|formatTime}}</span>
+                        <span>{{scope.row.ApproveTime|formatTime}}</span>
                     </template>
-                </el-table-column>
-                <!-- <el-table-column v-if="permissionBtn.checkPermissionBtn(permissionBtn.smartReportManageBtn.reportManage_reportList_sendTime)"
-                    prop="MsgSendTime"
-                    label="报告推送时间"
-                    min-width="124"
-                    align="center"
-                >
-                    <template slot-scope="scope">{{
-                    scope.row.MsgSendTime | formatTime
-                    }}</template>
                 </el-table-column> -->
+                <el-table-column prop="PublishTime" label="发布/审批时间" min-width="124" align="center">
+                <template slot-scope="scope">
+                    <template v-if="[1,2].includes(scope.row.State)">
+                        <span>{{scope.row.PrePublishTime?scope.row.PrePublishTime:scope.row.PublishTime|formatTime}}</span>
+                        <svg style="position: relative;top:2px" v-if="scope.row.PrePublishTime&&scope.row.State == '1'" width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+                            <path d="M15.2002 8C15.2002 4.13401 12.0662 1 8.20019 1C4.3342 1 1.20019 4.13401 1.2002 8C1.2002 11.866 4.3342 15 8.2002 15C12.0662 15 15.2002 11.866 15.2002 8ZM5.2002 10L5.2002 9L8.17491 9L11.2002 4.5L11.9073 5.20711L8.58912 10L5.2002 10Z" fill="#0052D9"/>
+                        </svg>
+                    </template>
+                    <template v-else>
+                        <span>{{scope.row.ApproveTime|formatTime}}</span>
+                    </template>
+                </template>
+            </el-table-column>
                 <el-table-column
                     prop="ContentModifyTime"
                     label="更新时间"
@@ -285,109 +258,59 @@
                 <el-table-column label="操作" align="center" min-width="130" fixed="right">
                     <template slot-scope="scope">
                     <div class="opt-btns">
-                        <!-- 不走审批流的按钮 -->
-                        <template v-if="!isApprove">
-                            <template v-if="scope.row.State == 1">
-                                <span v-permission="permissionBtn.smartReportManageBtn.reportManage_publish"
-                                    class="editsty" @click="handlePublishReportOpt(scope.row)"
-                                    v-if="scope.row.CanEdit">发布</span>
-                                <span v-permission="permissionBtn.smartReportManageBtn.reportManage_reportEdit"
-                                    class="editsty" @click="editreport(scope.row, 'edit')"
-                                    v-if="scope.row.CanEdit">编辑</span>
-                                <span v-permission="permissionBtn.smartReportManageBtn.reportManage_reportEdit"
-                                    class="editsty" @click="editreport(scope.row, 'editing')"
-                                    v-else>{{ scope.row.Editor || "" }}编辑中...</span>
-                                <span v-permission="permissionBtn.smartReportManageBtn.reportManage_reportDel"
-                                    class="deletesty" @click="handleDelReport(scope.row)"
-                                    v-if="scope.row.CanEdit">删除</span>
-                            </template>
-                            <template v-if="scope.row.State == 2">
-                                <span
-                                    v-if="permissionBtn.checkPermissionBtn(permissionBtn.smartReportManageBtn.reportManage_cancelPublish)"
-                                    @click="handleReportPublishCancel(scope.row)"
-                                    style="color: red; cursor: pointer"
-                                >取消发布</span>
-                                <span
-                                    v-if="scope.row.DetailImgUrl"
-                                    v-permission="permissionBtn.smartReportManageBtn.reportManage_exportImg"
-                                    @click="handleDownReportImg(scope.row.DetailImgUrl,scope.row.Title)"
-                                    style="cursor: pointer; color: #4099ef;display:inline-block"
-                                >图片下载</span>
-                                <!-- <span
-                            v-if="scope.row.MsgIsSend == 0 && permissionBtn.checkPermissionBtn(permissionBtn.smartReportManageBtn.reportManage_sendMsg)"
-                            style="color: #4099ef; cursor: pointer"
-                            @click="handleSendMsg(scope.row)"
-                            >推送消息</span
-                        >
-                        <span v-else-if="scope.row.MsgIsSend != 0&&permissionBtn.checkPermissionBtn(permissionBtn.smartReportManageBtn.reportManage_sendMsg)"
-                            style="color: red">已推送消息</span> -->
-                            </template>
-                            <span style="color: #46c371; cursor: pointer;display:inline-block"
-                                v-if="permissionBtn.checkPermissionBtn(permissionBtn.smartReportManageBtn.reportManage_audioUpload)"
-                                @click="openupload(scope.row.SmartReportId)">音频上传</span>
-                            <span style="cursor: pointer; color: #4099ef;display:inline-block"
-                                v-permission="permissionBtn.smartReportManageBtn.reportManage_audioDownload"
-                                v-if="scope.row.VideoUrl" @click="handleDownloadVoice(scope.row)">
-                                音频下载
-                            </span>
-                            <!-- <a
-                                v-permission="permissionBtn.smartReportManageBtn.reportManage_audioDownload"
-                                :href="scope.row.VideoUrl"
-                                v-if="scope.row.VideoUrl"
-                                :download="scope.row.VideoName"
-                                style="cursor: pointer; color: #4099ef"
-                                >音频下载</a
-                                > -->
+                        <!-- 操作:
+                            已发布——取消发布、下载图片
+                            未发布——发布、编辑、删除
+                            待提交——提交、编辑、删除
+                            待审批——撤销
+                            已通过——撤销、下载图片、
+                            已驳回——撤销 -->
+                        <!-- 未发布,待提交 -->
+                        <template v-if="[1,3].includes(scope.row.State)">
+                            <span v-permission="permissionBtn.smartReportManageBtn.reportManage_publish"
+                                class="editsty" @click="handlePublishReportOpt(scope.row)"
+                                v-if="scope.row.CanEdit&&scope.row.State===1">发布</span>
+                            <span v-permission="permissionBtn.smartReportManageBtn.reportManage_publish"
+                                class="editsty" @click="handleSubmitReport(scope.row)"
+                                v-if="scope.row.CanEdit&&scope.row.State===3">提交</span>
+                            <span v-permission="permissionBtn.smartReportManageBtn.reportManage_reportEdit"
+                                class="editsty" @click="editreport(scope.row, 'edit')"
+                                v-if="scope.row.CanEdit">编辑</span>
+                            <span v-permission="permissionBtn.smartReportManageBtn.reportManage_reportEdit"
+                                class="editsty" @click="editreport(scope.row, 'editing')"
+                                v-else>{{ scope.row.Editor || "" }}编辑中...</span>
+                            <span v-permission="permissionBtn.smartReportManageBtn.reportManage_reportDel"
+                                class="deletesty" @click="handleDelReport(scope.row)"
+                                v-if="scope.row.CanEdit">删除</span>
                         </template>
-                        <!-- 走审批流的按钮 -->
-                        <template v-if="isApprove">
-                            <!-- 待提交 -->
-                            <template v-if="scope.row.State == 1">
-                                <span v-permission="permissionBtn.smartReportManageBtn.reportManage_publish"
-                                    class="editsty" @click="handlePublishReportOpt(scope.row)"
-                                    v-if="scope.row.CanEdit">提交</span>
-                                <span v-permission="permissionBtn.smartReportManageBtn.reportManage_reportEdit"
-                                    class="editsty" @click="editreport(scope.row, 'edit')"
-                                    v-if="scope.row.CanEdit">编辑</span>
-                                <span v-permission="permissionBtn.smartReportManageBtn.reportManage_reportEdit"
-                                    class="editsty" @click="editreport(scope.row, 'editing')"
-                                    v-else>{{ scope.row.Editor || "" }}编辑中...</span>
-                                <span v-permission="permissionBtn.smartReportManageBtn.reportManage_reportDel"
-                                    class="deletesty" @click="handleDelReport(scope.row)"
-                                    v-if="scope.row.CanEdit">删除</span>
-                            </template>
-                            <!--已提交(待审批,已审批)-->
-                            <template v-if="[2,4].includes(scope.row.State)">
-                                <span
-                                    v-if="permissionBtn.checkPermissionBtn(permissionBtn.smartReportManageBtn.reportManage_cancelPublish)"
-                                    @click="handleReportPublishCancel(scope.row)"
-                                    style="color: red; cursor: pointer">撤销
-                                </span>
-                                <span
-                                    v-if="scope.row.DetailImgUrl&&scope.row.State===4"
-                                    v-permission="permissionBtn.smartReportManageBtn.reportManage_reportView_exportImg"
-                                    @click="handleDownReportImg(scope.row.DetailImgUrl,scope.row.Title)"
-                                    style="cursor: pointer; color: #4099ef;display:inline-block"
-                                >图片下载</span>
-                            </template>
-                             <!--已驳回则只显示撤销按钮-->
-                            <template v-if="scope.row.State===3">
-                                <span v-permission="permissionBtn.smartReportManageBtn.reportManage_publish"
+                        <!-- 已发布,已通过 -->
+                        <template v-if="[2,6].includes(scope.row.State)">
+                            <span v-if="permissionBtn.isShowBtn('smartReportManageBtn','reportManage_cancelPublish')&&scope.row.State===2"
                                 @click="handleReportPublishCancel(scope.row)"
-                                    class="editsty">撤销</span>
-                            </template>
-                            <!--音频上传/下载 按原先逻辑-->
-                            <template v-if="scope.row.State!==3">
-                                <span style="color: #46c371; cursor: pointer;display:inline-block"
-                                    v-if="permissionBtn.checkPermissionBtn(permissionBtn.smartReportManageBtn.reportManage_audioUpload)"
-                                    @click="openupload(scope.row.SmartReportId)">音频上传</span>
-                                <span style="cursor: pointer; color: #4099ef;display:inline-block"
-                                    v-permission="permissionBtn.smartReportManageBtn.reportManage_audioDownload"
-                                    v-if="scope.row.VideoUrl" @click="handleDownloadVoice(scope.row)">
-                                    音频下载
-                                </span>
-                            </template>
+                                style="color: red; cursor: pointer">撤销</span><!-- 取消发布 -->
+                            <span v-if="permissionBtn.isShowBtn('smartReportManageBtn','reportManage_cancelPublish')&&scope.row.State===6"
+                                @click="cancelReport(scope.row)"
+                                style="color: red; cursor: pointer">撤销</span>
+                            <span v-if="scope.row.DetailImgUrl"
+                                v-permission="permissionBtn.smartReportManageBtn.reportManage_reportView_exportImg"
+                                @click="handleDownReportImg(scope.row.DetailImgUrl,scope.row.Title)"
+                                style="cursor: pointer; color: #4099ef;display:inline-block">图片下载</span>
                         </template>
+                        <!-- 待审批,已驳回 -->
+                        <template v-if="[4,5].includes(scope.row.State)">
+                            <span v-if="permissionBtn.isShowBtn('smartReportManageBtn','reportManage_cancelPublish')"
+                                @click="cancelReport(scope.row)"
+                                style="color: red; cursor: pointer">撤销</span>
+                        </template>
+                        <!-- 音频上传、下载,与状态无关 -->
+                        <span style="color: #46c371; cursor: pointer;display:inline-block"
+                            v-if="permissionBtn.checkPermissionBtn(permissionBtn.smartReportManageBtn.reportManage_audioUpload)"
+                            @click="openupload(scope.row.SmartReportId)">音频上传</span>
+                        <span style="cursor: pointer; color: #4099ef;display:inline-block"
+                            v-permission="permissionBtn.smartReportManageBtn.reportManage_audioDownload"
+                            v-if="scope.row.VideoUrl" @click="handleDownloadVoice(scope.row)">
+                            音频下载
+                        </span>
                     </div>
                     </template>
                 </el-table-column>
@@ -522,8 +445,11 @@
 <script>
 import { voiceupload } from "api/api.js";
 import {apiSmartReport}  from '@/api/modules/smartReport'
+import {approveInterence} from '@/api/modules/approve.js';
+import reportApproveConfig from "@/mixins/reportApproveConfig.js"
 import BaseInfo from './components/BaseInfo.vue'
 export default {
+    mixins:[reportApproveConfig],
     components:{BaseInfo},
     computed:{
         Role() {
@@ -534,13 +460,6 @@ export default {
         hasUV(){
             return this.permissionBtn.checkPermissionBtn(this.permissionBtn.smartReportManageBtn.reportManage_reportList_uv)
         },
-        //是否开启审批流,若开启,发布相关按钮,筛选项改变
-        isApprove(){
-            const type = this.$setting.dynamicOutLinks.ApprovalFlow ||
-                        this.$store.state.dynamicOutLinks.ApprovalFlow ||
-                        JSON.parse(localStorage.getItem('dynamicOutLinks')).ApprovalFlow||''
-            return ['2','3'].includes(type)
-        }
     },
     data() {
         return {
@@ -685,6 +604,37 @@ export default {
             this.isDSFB=false
             this.showPublish=false
         },
+        //提交报告
+        handleSubmitReport(item){
+            this.$confirm("是否确认提交该报告进入审批流程?","提示",{
+                confirmButtonText:'确定',
+                cancelButtonText:'取消',
+                type:'warning',
+            }).then(()=>{
+                approveInterence.reportSmartSubmit({
+                    ReportId:Number(item.SmartReportId)
+                }).then(res=>{
+                    if(res.Ret!==200) return 
+                    this.$message.success("提交成功")
+                    this.getReportList()
+                })
+            })
+        },
+        cancelReport(item){
+            this.$confirm("确定要撤销审批吗?","提示",{
+                confirmButtonText:'确定',
+                cancelButtonText:'取消',
+                type:'warning',
+            }).then(()=>{
+                approveInterence.reportSmartCancel({
+                    ReportId:Number(item.SmartReportId)
+                }).then(res=>{
+                    if(res.Ret!==200) return 
+                    this.$message.success("撤销成功")
+                    this.getReportList()
+                })
+            })
+        },
 
         //编辑报告
         async editreport(item, type){

+ 36 - 1
src/views/system_manage/etaBaseConfig.vue

@@ -142,6 +142,28 @@
                             </el-form-item>
                         </template>
                     </div>
+                    <!-- 研报审批 -->
+                    <div v-if="isShowApprove">
+                        <div style="width:100%;margin-bottom: 20px;">
+                            <span style="color:#606266;">研报审批</span> 
+                            <el-switch v-model="approve"></el-switch>
+                        </div>
+                        <div class="side" v-if="approve">
+                            <el-form-item label="" prop="ReportApproveType">
+                                <el-radio-group v-model="formData.ReportApproveType">
+                                    <el-radio label="eta">ETA内部审批</el-radio>
+                                    <el-radio label="other">
+                                        <span>第三方审批</span>
+                                        <el-tooltip effect="dark" placement="top" content="中文研报(智能研报/研报列表)通过API接口对接第三方审批系统" >
+                                            <span class="hint-text">
+                                                <i class="el-icon-warning-outline"></i>
+                                            </span>
+                                        </el-tooltip>
+                                    </el-radio>
+                                </el-radio-group>
+                            </el-form-item>
+                        </div>
+                    </div>
                 </div>
                 <div class="side">
                     <el-form-item label="中文研报分享抬头" prop="H5ShareName">
@@ -314,6 +336,7 @@ export default {
             /* base config */
             checkList:[],//水印应用
             Iflytek:false,//是否启用科大讯飞服务
+            approve:false,//是否开启研报审批
             formData: {
                 Disclaimer: '',//免责声明
                 CompanyName:'',//公司名称
@@ -347,6 +370,9 @@ export default {
 
                 WatermarkReport:false,//研报分享水印
 
+                IsReportApprove:false,//是否开启研报审批
+                ReportApproveType:'eta',//研报审批选项
+
             },//表单预设值
             rules: {
                 Disclaimer:[{ required: true, message: '请输入免责声明', trigger: 'blur' }],
@@ -445,6 +471,12 @@ export default {
                     this.permissionBtn.baseConfigPermission.etaBaseConfig_xunfei
                 )
         },
+        //是否显示研报审批相关表单项
+        isShowApprove(){
+            return this.permissionBtn.checkPermissionBtn(
+                this.permissionBtn.baseConfigPermission.etaBaseConfig_approve
+            )
+        },
         //是否显示中文PPT相关的表单项
         isShowPPT(){
             return this.permissionBtn.checkPermissionBtn(
@@ -530,11 +562,13 @@ export default {
             });
             //获取WatermarkChart的值,赋值checkList
             //获取UseXf的值,赋值Iflytek
+            //获取IsReportApprove的值,赋值approve
             etaBaseConfigInterence.getBaseConfig().then(res=>{
                 if(res.Ret!==200) return 
-                const {WatermarkChart='',UseXf='',CnPptCoverImgs='',EnPptCoverImgs=''} = res.Data
+                const {WatermarkChart='',UseXf='',IsReportApprove='',CnPptCoverImgs='',EnPptCoverImgs=''} = res.Data
                 this.checkList = WatermarkChart==='true'?['研报图表']:[]
                 this.Iflytek = UseXf==='true'?true:false
+                this.approve = IsReportApprove==='true'?true:false
                 if(res.Data){
                     // this.$set(this,'formData',res.Data)
                     this.formData = {...this.formData,...res.Data}
@@ -583,6 +617,7 @@ export default {
                     this.formData.LoginEmailTemplateContent = this.formData.LoginEmailTemplateContent.replace(/<p data-f-id=\"pbf\".*?<\/p>/g, "");
                     this.formData.WatermarkChart = ''+(this.checkList.includes('研报图表')?true:false)
                     this.formData.UseXf = ''+(this.Iflytek?true:false)
+                    this.formData.IsReportApprove = ''+(this.approve?true:false)
                     const CnPptCoverImgs = this.formData.CnPptCoverImgs.join(',')
                     const EnPptCoverImgs = this.formData.EnPptCoverImgs.join(',')
                     //通过验证后,提交数据前