detail.vue 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486
  1. <template>
  2. <view class="content">
  3. <view class="title"> 项目详情 </view>
  4. <view class="main">
  5. <view class="list">
  6. <view class="detail">
  7. <span class="subTitle">项目名称:</span>
  8. <span class="detailContent">{{ currentProject.project_name }}</span>
  9. </view>
  10. <view class="detail" v-if="currentProject.TypeInfo">
  11. <span class="subTitle">项目类别:</span>
  12. <span class="detailContent">{{ currentProject.TypeInfo.name }}</span>
  13. </view>
  14. <view class="detail" v-if="currentProject.IndustryInfo">
  15. <span class="subTitle">行业名称:</span>
  16. <span class="detailContent">
  17. {{ currentProject.IndustryInfo.name }}
  18. </span>
  19. </view>
  20. <view class="detail">
  21. <span class="subTitle">流程:</span>
  22. <span class="detailContent">{{ currentProject.FlowInfo.name }}</span>
  23. </view>
  24. <view class="detail">
  25. <span class="subTitle">状态:</span>
  26. <span class="detailContent">
  27. {{ status[currentProject.project_status] }}
  28. </span>
  29. </view>
  30. <view class="detail">
  31. <span class="subTitle">节点:</span>
  32. <span class="detailContent">
  33. {{ `${currentProject.NodeInfo.node}(` }}
  34. <span v-if="currentProject.audit_status == 0">待提交</span>
  35. <span
  36. v-if="currentProject.audit_status == 1"
  37. :style="{ color: '#1890ff' }"
  38. >
  39. 审核中
  40. </span>
  41. <span
  42. v-if="currentProject.audit_status == 2"
  43. :style="{ color: '#f5222d' }"
  44. >
  45. 审核拒绝
  46. </span>
  47. <span
  48. v-if="currentProject.audit_status == 3"
  49. :style="{ color: '#a0d911' }"
  50. >
  51. 审核通过
  52. </span>
  53. <span>)</span>
  54. </span>
  55. </view>
  56. <view class="detail" v-if="currentProject.audit_status == 2">
  57. <span class="subTitle">拒绝原因:</span>
  58. <span class="detailContent">
  59. {{ currentProject.audit_comment }}
  60. </span>
  61. </view>
  62. <view class="detail" v-if="currentProject.location">
  63. <span class="subTitle">项目地区:</span>
  64. <span class="detailContent">
  65. {{ `${currentProject.location}(${currentProject.location_code})` }}
  66. </span>
  67. </view>
  68. <view class="detail" v-if="currentProject.name">
  69. <span class="subTitle">项目简称:</span>
  70. <span class="detailContent">{{ currentProject.name }}</span>
  71. </view>
  72. <view class="detail" v-if="currentProject.version">
  73. <span class="subTitle">项目批次:</span>
  74. <span class="detailContent">{{ currentProject.version }}期</span>
  75. </view>
  76. <view class="detail" v-if="currentProject.AuthorUser">
  77. <span class="subTitle">创建人:</span>
  78. <span class="detailContent">{{
  79. currentProject.AuthorUser.CName
  80. }}</span>
  81. </view>
  82. <view class="detail" v-if="currentProject.AuthorDepInfo">
  83. <span class="subTitle">所属部门:</span>
  84. <span class="detailContent">
  85. {{ currentProject.AuthorDepInfo.Name }}
  86. </span>
  87. </view>
  88. <view class="detail">
  89. <span class="subTitle">项目编号:</span>
  90. <span class="detailContent">
  91. {{ currentProject.project_full_code }}
  92. </span>
  93. </view>
  94. </view>
  95. <view class="title">审核详情 </view>
  96. <view class="list">
  97. <uni-steps
  98. :options="nodeList.list"
  99. :active="nodeList.currentIndex"
  100. direction="column"
  101. />
  102. </view>
  103. <uni-card title="操作" v-if="!this.auth">
  104. <view class="editBtns" slot="actions">
  105. <view class="edit" v-if="canEdit(0)" @click="onEdit()">编辑</view>
  106. <view class="edit" v-if="canEdit(0)" @click="onDelete()">删除</view>
  107. <view class="edit" v-if="canEdit(0)" @click="onSubmitAuth()">
  108. 提交审核
  109. </view>
  110. <view class="edit" v-if="canEdit(1)" @click="onMember()"
  111. >成员管理
  112. </view>
  113. <view class="edit" v-if="canEdit(2)" @click="onExecute()">
  114. 转执行
  115. </view>
  116. <view class="edit" v-if="canEdit(3)" @click="onWarranty()">
  117. 转质保
  118. </view>
  119. <view class="edit" v-if="canEdit(3)" @click="onOperate()">
  120. 转运营
  121. </view>
  122. </view>
  123. </uni-card>
  124. </view>
  125. <view class="group" v-if="this.auth && canAuth()">
  126. <button @click="onHandleAudit(0)" class="commit">审核拒绝</button>
  127. <button @click="onHandleAudit(1)" type="primary" class="commit">
  128. 审核通过
  129. </button>
  130. </view>
  131. </view>
  132. </template>
  133. <script>
  134. import { mapState } from "vuex";
  135. import {
  136. queryFlow,
  137. deleteApproval,
  138. submitAudit,
  139. queryUserDetail,
  140. authApproval,
  141. } from "@/services/project";
  142. export default {
  143. data() {
  144. return {
  145. auth: false,
  146. status: ["售前", "转执行", "转运营", "转质保"],
  147. flowList: [],
  148. depRole: [],
  149. user: {},
  150. };
  151. },
  152. computed: {
  153. ...mapState(["currentProject"]),
  154. nodeList() {
  155. if (!this.flowList) return [];
  156. let flowInfo = this.flowList.find(
  157. (item) => item.id == this.currentProject.flow_id
  158. );
  159. if (!flowInfo) return [];
  160. let currentIndex = flowInfo.Nodes.findIndex(
  161. (item) => item.id == this.currentProject.node_id
  162. );
  163. return {
  164. currentIndex,
  165. list: flowInfo.Nodes.map((item) => ({
  166. title: item.node,
  167. desc: `审批人:${this.getAudits(item)}`,
  168. })),
  169. };
  170. },
  171. },
  172. onLoad(options) {
  173. this.auth = Boolean(options.auth);
  174. this.init();
  175. },
  176. methods: {
  177. async init() {
  178. this.user = uni.getStorageSync("user");
  179. let res;
  180. res = await queryFlow();
  181. this.flowList = res.data;
  182. res = await queryUserDetail(this.user);
  183. let depId = this.user.DepId;
  184. let dep = res.data.Dep.find((item) => item.ID == depId);
  185. this.depRole = dep.Role;
  186. },
  187. canAuth() {
  188. let { NodeInfo, audit_status, project_status } = this.currentProject;
  189. if (!NodeInfo || this.flowList.length == 0 || this.depRole.length == 0)
  190. return false;
  191. if (audit_status != 1) return false;
  192. if (project_status == 2)
  193. return this.currentProject.opt_manager_id == this.user.ID;
  194. if (project_status == 3)
  195. return this.currentProject.wty_manager_id == this.user.ID;
  196. let flow = this.flowList.find((item) => item.id == NodeInfo.flow_id);
  197. if (!flow) return false;
  198. let { NodeAudits } = flow.Nodes.find((item) => item.id == NodeInfo.id);
  199. const role = this.depRole.find((item) =>
  200. NodeAudits.find((audit) => audit.audit_role == item.ID)
  201. );
  202. return Boolean(role);
  203. },
  204. onHandleAudit(value) {
  205. if (value) {
  206. uni.showModal({
  207. title: "审批通过",
  208. content: "是否确认通过审批",
  209. confirmText: "通过",
  210. success: async (res) => {
  211. if (res.confirm) {
  212. let payload = {
  213. id: this.currentProject.id,
  214. project_full_code: this.currentProject.project_full_code,
  215. flow_id: this.currentProject.flow_id,
  216. node_id: this.currentProject.node_id,
  217. audit_status: 3,
  218. audit_comment: "",
  219. };
  220. await authApproval(payload);
  221. uni.showToast({
  222. title: "审核成功",
  223. });
  224. setTimeout(function () {
  225. uni.hideToast();
  226. uni.navigateTo({
  227. url: "./auth",
  228. });
  229. }, 1800);
  230. }
  231. },
  232. });
  233. // } else console.log("审核拒绝");
  234. } else {
  235. uni.showModal({
  236. title: "是否确认拒绝",
  237. content: "拒绝理由",
  238. editable: true,
  239. success: async (res) => {
  240. if (res.confirm) {
  241. let payload = {
  242. id: this.currentProject.id,
  243. project_full_code: this.currentProject.project_full_code,
  244. flow_id: this.currentProject.flow_id,
  245. node_id: this.currentProject.node_id,
  246. audit_status: 2,
  247. audit_comment: res.content,
  248. };
  249. await authApproval(payload);
  250. uni.showToast({
  251. title: "已拒绝",
  252. });
  253. setTimeout(function () {
  254. uni.hideToast();
  255. uni.navigateTo({
  256. url: "./auth",
  257. });
  258. }, 1800);
  259. }
  260. },
  261. });
  262. }
  263. },
  264. getAudits(nodeInfo) {
  265. switch (nodeInfo.id) {
  266. case 11:
  267. return "执行项目经理";
  268. case 12:
  269. return "运营经理";
  270. case 13:
  271. return "执行项目经理";
  272. case 14:
  273. return "质保经理";
  274. default:
  275. return (nodeInfo.NodeAudits || [])
  276. .map((item) => item.AuthorRoleInfo.Name)
  277. .join(",");
  278. }
  279. },
  280. canEdit(index) {
  281. let {
  282. audit_status,
  283. project_status,
  284. author,
  285. LeaderId,
  286. opt_manager_id,
  287. wty_manager_id,
  288. } = this.currentProject;
  289. //audit_status: 0未提审1审核中2审核拒绝3审核通过
  290. //project_status: 0售前1执行2转运营3转质保
  291. switch (index) {
  292. //编辑删除提审
  293. case 0:
  294. //售前阶段,未提审/审核被拒,创建人/管理员
  295. return (
  296. project_status == 0 &&
  297. (audit_status == 0 || audit_status == 2) &&
  298. (this.user.ID == author || this.user.IsSuper)
  299. );
  300. //成员管理
  301. case 1:
  302. //售前/执行/运营/质保,审核通过,项目经理/管理员
  303. let manager;
  304. switch (project_status) {
  305. case 0:
  306. manager = author;
  307. break;
  308. case 1:
  309. manager = LeaderId;
  310. break;
  311. case 2:
  312. manager = opt_manager_id;
  313. break;
  314. case 3:
  315. manager = wty_manager_id;
  316. break;
  317. }
  318. return (
  319. audit_status == 3 && (this.user.ID == manager || this.user.IsSuper)
  320. );
  321. //转执行
  322. case 2:
  323. //售前,审核通过,售前经理/管理员
  324. return (
  325. project_status == 0 &&
  326. audit_status == 3 &&
  327. (this.user.ID == author || this.user.IsSuper)
  328. );
  329. //转质保运营
  330. case 3:
  331. //执行,审核通过,执行经理/管理员
  332. return (
  333. project_status == 1 &&
  334. audit_status == 3 &&
  335. (this.user.ID == LeaderId || this.user.IsSuper)
  336. );
  337. }
  338. },
  339. onEdit() {
  340. uni.navigateTo({
  341. url: `./add?project_id=${this.currentProject.id}`,
  342. });
  343. },
  344. onDelete() {
  345. uni.showModal({
  346. title: "删除项目",
  347. content: "是否确认删除该项目",
  348. confirmText: "删除",
  349. confirmColor: "#ff7875",
  350. success: async (res) => {
  351. if (res.confirm) {
  352. await deleteApproval(this.currentProject);
  353. uni.showToast({
  354. title: "删除成功",
  355. });
  356. setTimeout(function () {
  357. uni.hideToast();
  358. uni.navigateTo({
  359. url: "./list",
  360. });
  361. }, 1800);
  362. }
  363. },
  364. });
  365. },
  366. onSubmitAuth() {
  367. uni.showModal({
  368. title: "提交审核",
  369. content: "是否确认提交审核",
  370. confirmText: "提审",
  371. success: async (res) => {
  372. if (res.confirm) {
  373. let payload = {
  374. id: this.currentProject.id,
  375. flow_id: this.currentProject.flow_id,
  376. node_id: this.currentProject.node_id,
  377. };
  378. console.log(payload);
  379. await submitAudit(payload);
  380. uni.showToast({
  381. title: "提审成功",
  382. });
  383. setTimeout(function () {
  384. uni.hideToast();
  385. uni.navigateTo({
  386. url: "./list",
  387. });
  388. }, 1800);
  389. }
  390. },
  391. });
  392. },
  393. onMember() {
  394. uni.navigateTo({
  395. url: "./member",
  396. });
  397. },
  398. onExecute() {
  399. return;
  400. },
  401. onWarranty() {
  402. return;
  403. },
  404. onOperate() {
  405. return;
  406. },
  407. },
  408. };
  409. </script>
  410. <style lang="less" scoped>
  411. .content {
  412. display: flex;
  413. flex-wrap: wrap;
  414. }
  415. .main {
  416. width: 100%;
  417. padding-bottom: 60px;
  418. }
  419. .title {
  420. width: 100%;
  421. padding: 0 20px 20px 20px;
  422. font: 24px bold;
  423. }
  424. .list {
  425. margin: 0 10% 20px 10%;
  426. }
  427. .detail {
  428. width: 100%;
  429. padding: 15px 0;
  430. font-size: 18px;
  431. display: flex;
  432. justify-items: space-between;
  433. .subTitle {
  434. width: 30%;
  435. }
  436. .detailContent {
  437. width: 70%;
  438. }
  439. }
  440. ::v-deep {
  441. .uni-steps__column-title {
  442. font-size: 18px;
  443. line-height: 24px;
  444. }
  445. .uni-steps__column-desc {
  446. font-size: 14px;
  447. line-height: 18px;
  448. }
  449. }
  450. .editBtns {
  451. display: flex;
  452. justify-content: space-around;
  453. flex-wrap: wrap;
  454. margin: 0 5%;
  455. .edit {
  456. width: 30%;
  457. margin-bottom: 20px;
  458. font-size: 16px;
  459. text-align: center;
  460. }
  461. }
  462. .group {
  463. width: 100%;
  464. display: flex;
  465. position: fixed;
  466. flex-wrap: wrap;
  467. justify-content: flex-start;
  468. bottom: 0;
  469. left: 0;
  470. .commit {
  471. width: 50%;
  472. border-radius: 0;
  473. margin: inherit;
  474. }
  475. }
  476. </style>