index.vue 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <template>
  2. <!-- 审批详情 -->
  3. <view class="approval-detail">
  4. <view class="main">
  5. <view class="header">
  6. <view class="title-box">
  7. <text class="originator">{{ detailInfo.createName }}</text>
  8. <text :style="{ color: statusColor }" class="approvedBy">
  9. {{ proStatus }}
  10. </text>
  11. </view>
  12. <image class="status-icon" :src="statusIcon"></image>
  13. </view>
  14. <!-- 表单信息 -->
  15. <fmInfo :content="content"></fmInfo>
  16. <!-- 流程图 -->
  17. <detailFlowChart :proNodes="proNodes"></detailFlowChart>
  18. <!-- 审批mdl-form -->
  19. <approval-fm
  20. @reload="getDetailData"
  21. :rId="id"
  22. :isShow.sync="isShow"
  23. ></approval-fm>
  24. <!-- 撤销原因mdl -->
  25. <revokeFm
  26. :id="detailInfo.id"
  27. :showRevoke.sync="showRevoke"
  28. ></revokeFm>
  29. </view>
  30. <view class="footer">
  31. <!-- tabs我审批&&当前登录人的审批状态为true--显示审批按钮 -->
  32. <c-button
  33. v-if="type === 1 && detailInfo.audit"
  34. @click="isShow = true"
  35. type="primary"
  36. >
  37. 审批
  38. </c-button>
  39. <!--tabs我发起--待审批可修改-->
  40. <template v-else-if="type === 0">
  41. <view
  42. v-if="detailInfo.status === 0"
  43. @click="updatePro"
  44. class="update-btn"
  45. >
  46. 修改
  47. </view>
  48. <!-- 0: '待审批',1: '已归档',4: '审批中',-->
  49. <view
  50. v-if="[0, 1, 4].includes(detailInfo.status)"
  51. class="revoke-btn"
  52. @click="openMdl"
  53. >
  54. 撤销
  55. </view>
  56. <!--tabs我发起--2已撤销/3已驳回,后可再次提交 -->
  57. <c-button
  58. v-if="[2, 3].includes(detailInfo.status)"
  59. type="primary"
  60. >
  61. 再次提交
  62. </c-button>
  63. </template>
  64. </view>
  65. </view>
  66. </template>
  67. <script>
  68. import fmInfo from './fmInfo.vue';
  69. import detailFlowChart from './detailFlowChart.vue';
  70. import { details, revoke } from '@/api/approval';
  71. import ApprovalFm from '@/pages/waitHandle/approvalDetail/approvalFm.vue';
  72. import processStatus from '@/utils/types/processStatus.js';
  73. import nodeStatus from '@/utils/types/nodeStatus.js';
  74. import revokeFm from './revokeFm.vue'; // 撤销原因
  75. export default {
  76. name: 'approvalDetail',
  77. components: {
  78. ApprovalFm,
  79. fmInfo,
  80. detailFlowChart,
  81. revokeFm,
  82. },
  83. data() {
  84. return {
  85. showRevoke: false, // 撤销原因
  86. type: undefined, // 0我发起,1我审批,2抄送人
  87. approvedItem: {}, // 找出流程中到谁审批
  88. isShow: false,
  89. id: undefined,
  90. detailInfo: {},
  91. };
  92. },
  93. computed: {
  94. proStatus() {
  95. const approvedItem = this.approvedItem;
  96. const { status } = this.detailInfo;
  97. if (status === 0 && approvedItem) {
  98. // 流程状态:待审批,取节点的状态
  99. const nStatus = nodeStatus[approvedItem.status] || '';
  100. const uName = approvedItem.userName || '';
  101. return uName + nStatus; //审批人name+节点状态
  102. }
  103. return processStatus[status] || ''; // 流程的状态
  104. },
  105. statusColor() {
  106. const { status } = this.detailInfo;
  107. const colors = {
  108. 0: '#FF9935', // '待审批'
  109. 1: '#11C59D', // '已归档'
  110. 2: '#436FF6', // '已撤销'
  111. 3: '#FF5E59', // '已驳回'
  112. 4: '#FF9935', // '审批中'
  113. };
  114. return colors[status || 0];
  115. },
  116. statusIcon() {
  117. const { status } = this.detailInfo;
  118. const icons = {
  119. 0: 'sqz', // '待审批'
  120. 1: 'ygd', // '已归档'
  121. 2: 'ycx', // '已撤销'
  122. 3: 'ybh', // '已驳回'
  123. 4: 'sqz', // '审批中'
  124. };
  125. const iconName = icons[status || 0];
  126. return require(`@/static/images/approval/${iconName}.png`);
  127. },
  128. proNodes() {
  129. return this.detailInfo.nodes || [];
  130. },
  131. content() {
  132. const { detailInfo } = this;
  133. if (!detailInfo || !detailInfo.content) {
  134. return {};
  135. }
  136. return JSON.parse(detailInfo.content);
  137. },
  138. },
  139. onLoad(params) {
  140. this.id = +params.id;
  141. this.type = +params.type; // 0我发起,1我审批,2抄送人
  142. this.getDetailData();
  143. },
  144. methods: {
  145. async revokeProcess() {
  146. // 撤销原因只有要再走流程的才填
  147. const { processType, status } = this.detailInfo; // status流程状态
  148. if (processType === 3 && status === 1) {
  149. // 请假在归档状态时撤销---查看详情---提交时填写撤销原因
  150. this.showRevoke = true;
  151. return;
  152. }
  153. try {
  154. uni.$c.loading();
  155. await revoke({ id: this.detailInfo.id });
  156. uni.$c.toast('撤销成功');
  157. uni.hideLoading();
  158. } catch (e) {
  159. uni.hideLoading();
  160. throw new Error(e);
  161. }
  162. },
  163. openMdl() {
  164. // 撤销流程
  165. uni.showModal({
  166. title: '提示',
  167. content: '确认撤销吗?',
  168. success: (res) => {
  169. if (res.confirm) {
  170. this.revokeProcess(); // 撤销
  171. }
  172. },
  173. });
  174. },
  175. updatePro() {
  176. // 修改流程
  177. uni.$u.route('pages/approval/index', {
  178. type: this.detailInfo.processType,
  179. });
  180. },
  181. handleApproval() {},
  182. async getDetailData() {
  183. try {
  184. uni.$c.loading();
  185. const { data } = await details(this.id);
  186. this.detailInfo = data || {};
  187. const nodes = data.nodes || [];
  188. const curArr = nodes.find((item) => item.current)?.list || [];
  189. this.approvedItem = curArr.find((item) => item.status === 0); // 找出流程中到谁审批
  190. uni.hideLoading();
  191. } catch (e) {
  192. uni.hideLoading();
  193. throw new Error(e);
  194. }
  195. },
  196. },
  197. };
  198. </script>
  199. <style scoped lang="scss">
  200. .approval-detail {
  201. display: flex;
  202. flex-direction: column;
  203. .main {
  204. flex: 1;
  205. padding: 28rpx;
  206. overflow-y: auto;
  207. .header {
  208. min-height: 68px;
  209. padding: 28rpx;
  210. position: relative;
  211. background-color: #fff;
  212. border-radius: $bd-radius;
  213. .title-box {
  214. display: flex;
  215. flex-direction: column;
  216. .originator {
  217. font-size: 13px;
  218. color: #333333;
  219. }
  220. .approvedBy {
  221. font-size: 12px;
  222. color: #ff9935;
  223. margin-top: 24rpx;
  224. }
  225. }
  226. .status-icon {
  227. position: absolute;
  228. top: 10rpx;
  229. right: 20rpx;
  230. width: 66px;
  231. height: 61px;
  232. }
  233. }
  234. }
  235. .footer {
  236. display: flex;
  237. margin-bottom: 20rpx;
  238. .update-btn {
  239. flex: 1;
  240. text-align: center;
  241. background: #e3eafe;
  242. height: 38px;
  243. line-height: 38px;
  244. color: #436ff6;
  245. font-size: 14px;
  246. border-top-width: 2px;
  247. border-top-style: solid;
  248. border-top-color: #436ff6;
  249. }
  250. .revoke-btn {
  251. flex: 1;
  252. text-align: center;
  253. background: #ffe7e6;
  254. height: 38px;
  255. line-height: 38px;
  256. color: #ff5e59;
  257. font-size: 14px;
  258. border-top-width: 2px;
  259. border-top-style: solid;
  260. border-top-color: #ff5e59;
  261. }
  262. }
  263. }
  264. </style>