index.vue 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851
  1. <template>
  2. <div class="processApproval" ref="processApprovalDom">
  3. <div class="left-card">
  4. <div class="top">
  5. <div class="commons-title title">
  6. {{ getFlowName() }}
  7. </div>
  8. <div class="line"></div>
  9. <!-- 报价单 -->
  10. <template v-if="flowForm.flowKey == 'sale_quotation_flow'">
  11. <!-- <PriceSheetEHSD ref="makeDom" :queryData="queryData.data"></PriceSheetEHSD> -->
  12. <PriceSheet ref="makeDom" :queryData="queryData.data"></PriceSheet>
  13. </template>
  14. <template v-if="flowForm.flowKey == 'discuss_price_flow'">
  15. <DiscussPrice ref="makeDom" :queryData="queryData.data"></DiscussPrice>
  16. </template>
  17. <template v-if="flowForm.flowKey == 'sales_outbound_approved_flow'">
  18. <SalesOutBound ref="makeDom" :queryData="queryData.data"></SalesOutBound>
  19. </template>
  20. <!-- 销售订单 -->
  21. <Contract ref="makeDom" :queryData="queryData.data" v-else-if="flowForm.flowKey == 'contract_flow' || flowForm.flowKey == 'sample_flow'">
  22. </Contract>
  23. <!-- 销售合同变更 -->
  24. <ContractChange ref="makeDom" :queryData="queryData.data"
  25. v-else-if="flowForm.flowKey == 'contract_update_flow' || flowForm.flowKey == 'sample_update_flow' "></ContractChange>
  26. <!-- 售后 -->
  27. <AfterSales ref="makeDom" :queryData="queryData.data" v-else-if="flowForm.flowKey == 'after_sales_flow'">
  28. </AfterSales>
  29. <!-- 申购 -->
  30. <Subscribe ref="makeDom" :queryData="queryData.data" v-else-if="flowForm.flowKey == 'subscribe_flow'"></Subscribe>
  31. <!-- 采购 -->
  32. <Purchase ref="makeDom" :queryData="queryData.data" v-else-if="flowForm.flowKey == 'purchase_flow'"> </Purchase>
  33. <!-- 采购变更 -->
  34. <PurchaseChange ref="makeDom" :queryData="queryData.data" v-else-if="flowForm.flowKey == 'purchase_update_flow'"> </PurchaseChange>
  35. <!-- 采购付款 -->
  36. <PurchasePayment ref="makeDom" v-else-if="flowForm.flowKey == 'pay_flow'" :queryData="queryData.data"></PurchasePayment>
  37. <!-- 请款 -->
  38. <SendFunds ref="makeDom" v-else-if="flowForm.flowKey == 'account_request_funds_flow'" :queryData="queryData.data"></SendFunds>
  39. <ReturnGood ref="makeDom" v-else-if="flowForm.flowKey == 'purchase_back_flow'" :queryData="queryData.data"></ReturnGood>
  40. <!-- 取消到账认领 -->
  41. <!-- <CancelClaim ref="makeDom" v-else-if="flowForm.flowKey == 'claim_del_flow'" :queryData="queryData.data"></CancelClaim> -->
  42. </div>
  43. </div>
  44. <div class="right-card">
  45. <el-tabs v-model="activeName" class="demo-tabs">
  46. <el-tab-pane label="处理意见" name="first" v-if="isShowSubmitDom">
  47. <div style="overflow: auto; height: calc(100vh - 200px)">
  48. <div style="padding-bottom:50px" v-if="showChart">
  49. <div style="margin-bottom:10px;">
  50. <TitleInfo :content="'利润预算波动'"></TitleInfo>
  51. </div>
  52. <div ref="chartDom" style="height:150px"></div>
  53. </div>
  54. <div style="margin-bottom:10px">
  55. <TitleInfo :content="'办理'"></TitleInfo>
  56. </div>
  57. <el-form :model="flowForm" :rules="flowRules" ref="flowFormDom" label-position="top">
  58. <el-form-item prop="remark" label-width="0px" label="">
  59. <el-input type="textarea" placeholder="请输入" :rows="3" v-model="flowForm.remark">
  60. </el-input>
  61. </el-form-item>
  62. <el-form-item prop="remark" label="">
  63. <div style="width:100%">
  64. <el-upload v-model:fileList="flowForm.fileList" drag :action="uploadUrl" :data="uploadData" multiple :before-upload="uploadFile"
  65. :on-success="handleSuccess" :on-preview="onPreviewFile">
  66. <el-icon class="el-icon--upload"><upload-filled /></el-icon>
  67. <div class="el-upload__text">
  68. 点击或拖拽上传附件
  69. </div>
  70. </el-upload>
  71. </div>
  72. </el-form-item>
  73. <el-form-item>
  74. <div style="text-align:center;width:100%">
  75. <el-button type="primary" v-if="approvalRecordData.buttonInfoList.length == 0" @click="handleSubmit"
  76. :loading="btnLoading">提交</el-button>
  77. <el-button type="primary" v-if="
  78. approvalRecordData.buttonInfoList.length == 0 &&
  79. StagFlowKey.includes(flowForm.flowKey)
  80. " @click="handleSubmitStag" :loading="btnLoading">暂存</el-button>
  81. <div v-else>
  82. <!-- 按钮长度小于2 -->
  83. <template v-for="(item,index) in approvalRecordData.buttonInfoList" :key="item.type">
  84. <el-button type="primary" :loading="btnLoading" @click="handleSubmit(item.type)" style="margin-bottom:10px"
  85. v-if="index<2">{{ item.name }}</el-button>
  86. </template>
  87. <!-- 大于等于2 -->
  88. <template v-if="approvalRecordData.buttonInfoList.length>2">
  89. <el-popover placement="bottom-start" title="" :width="120" trigger="hover">
  90. <div style="text-align:center;width:100%">
  91. <div v-for="(item,index) in approvalRecordData.buttonInfoList" :key="item.type" style="text-align:center;width:100%">
  92. <el-button type="primary" :loading="btnLoading" @click="handleSubmit(item.type)" style="margin-bottom:10px"
  93. v-if="index>=2">
  94. {{ item.name }}</el-button>
  95. </div>
  96. </div>
  97. <template #reference>
  98. <el-button type="primary" style="margin-bottom:10px;">更多</el-button>
  99. </template>
  100. </el-popover>
  101. </template>
  102. </div>
  103. </div>
  104. </el-form-item>
  105. </el-form>
  106. </div>
  107. </el-tab-pane>
  108. <el-tab-pane label="审批记录" name="second">
  109. <ul class="flow-chart" ref="flowChartDom">
  110. <li v-for="item in recordList" :key="item.id" :class="
  111. !route.query.id
  112. ? ''
  113. : item.status == 2
  114. ? 'flow-orange'
  115. : item.status == 3 && !route.query.id
  116. ? 'flow-orange'
  117. : item.status == 3 && route.query.id
  118. ? 'flow-grey'
  119. : ''
  120. ">
  121. <div class="left-icon">
  122. <i class="iconfont icon-iconm_daick"></i>
  123. <i class="iconfont icon-icomx_quertj1 right-btm-status"></i>
  124. </div>
  125. <div class="right-conetnt">
  126. <div class="name">{{ item.nodeName }}</div>
  127. <div class="remark">
  128. <div class="label">
  129. <span v-if="item.status != 3">办理人:</span>{{ item.processedUser
  130. }}<span class="time">{{ item.processedDate }}</span>
  131. </div>
  132. {{ item.remark }}
  133. <div v-for="j in fileObj[item.flowExampleDetailId]" v-if="fileObj[item.flowExampleDetailId]">
  134. <a @click="proxy.download(j.fileUrl, j.fileName)" style="color: #409eff; line-height: 30px">{{ j.fileName }}</a>
  135. </div>
  136. </div>
  137. </div>
  138. <div class="line"></div>
  139. </li>
  140. </ul>
  141. </el-tab-pane>
  142. <!-- <el-tab-pane label="决策辅助" name="three" v-if="auxiliaryData.length > 0">
  143. <div style="overflow: auto; height: calc(100vh - 200px)">
  144. <auxiliary :data="auxiliaryData"></auxiliary>
  145. </div>
  146. </el-tab-pane> -->
  147. </el-tabs>
  148. </div>
  149. <el-dialog :title="dialogTitle" width="400" v-model="dialogVisible" v-if="dialogVisible" :before-close="handleNextClose" :show-close="true"
  150. :close-on-click-modal="false" :close-on-press-escape="false">
  151. <el-form :model="flowForm">
  152. <el-form-item label="处理人" v-if="nextHandleUser && nextHandleUser.length>0">
  153. <el-select v-model="flowForm.handleUserId" placeholder="请选择" filterable style="width: 100%">
  154. <el-option v-for="item in nextHandleUser" :label="item.nickName" :value="item.userId">
  155. </el-option>
  156. </el-select>
  157. </el-form-item>
  158. <el-form-item label="退回节点" v-if="flowDefinitionNodeList && flowDefinitionNodeList.length>0">
  159. <el-select v-model="flowForm.handleNodeId" placeholder="请选择" filterable style="width: 100%">
  160. <el-option v-for="item in flowDefinitionNodeList" :label="item.nodeName" :value="item.id">
  161. </el-option>
  162. </el-select>
  163. </el-form-item>
  164. <el-form-item>
  165. <div style="width: 100%; text-align: center">
  166. <el-button type="primary" @click="handleSelectUser">提交</el-button>
  167. </div>
  168. </el-form-item>
  169. </el-form>
  170. </el-dialog>
  171. </div>
  172. </template>
  173. <script setup name="ProcessApproval">
  174. import useTagsViewStore from "@/store/modules/tagsView.js";
  175. import { useRouter, useRoute } from "vue-router";
  176. import PriceSheet from "@/components/process/SF/PriceSheet";
  177. import DiscussPrice from "@/components/process/SF/DiscussPrice";
  178. import SalesOutBound from "@/components/process/SF/SalesOutBound";
  179. import Contract from "@/components/process/SF/Contract";
  180. import ContractChange from "@/components/process/SF/ContractChange";
  181. import AfterSales from "@/components/process/SF/AfterSales";
  182. import Subscribe from "@/components/process/SF/Subscribe";
  183. import Purchase from "@/components/process/SF/Purchase";
  184. import PurchaseChange from "@/components/process/SF/PurchaseChange";
  185. import ReturnGood from "@/components/process/SF/ReturnGood";
  186. import PurchasePayment from "@/components/process/PurchasePayment";
  187. import SendFunds from "@/components/process/SendFunds";
  188. // 消息提示
  189. import { ElMessage, ElMessageBox } from "element-plus";
  190. //决策辅助
  191. import auxiliary from "./auxiliary";
  192. import useUserStore from "@/store/modules/user";
  193. const userInfo = useUserStore();
  194. import $bus from "@/bus/index.js";
  195. import * as echarts from "echarts";
  196. import TitleInfo from "@/components/TitleInfo/index.vue";
  197. const router = useRouter();
  198. const route = useRoute();
  199. // 传参
  200. const props = defineProps({
  201. query: Object,
  202. });
  203. const StagFlowKey = ref(["contract_flow"]);
  204. // tab切换逻辑
  205. const activeName = ref("first");
  206. let auxiliaryData = ref([]);
  207. const getAuxiliaryData = (data) => {
  208. auxiliaryData.value = data;
  209. };
  210. const btnLoading = ref(false);
  211. // 意见表单
  212. const flowForm = reactive({
  213. flowKey: "",
  214. handleUserId: "",
  215. remark: "",
  216. data: {},
  217. fileList: [],
  218. });
  219. const uploadData = ref({});
  220. const flowRules = reactive({
  221. // remark: [{ required: true, message: "请输入处理意见", trigger: "blur" }],
  222. });
  223. //组件实例
  224. const { proxy } = getCurrentInstance();
  225. const makeDom = ref(null);
  226. const flowFormDom = ref(null);
  227. let dialogVisible = ref(false);
  228. const dialogTitle = ref("");
  229. const nextHandleUser = ref([]);
  230. const flowDefinitionNodeList = ref([]);
  231. const handleType = ref(null);
  232. const handleSelectUser = () => {
  233. if (nextHandleUser.value && nextHandleUser.value.length > 0) {
  234. if (!flowForm.handleUserId) {
  235. return ElMessage({
  236. message: "请选择下一节点处理人!",
  237. type: "info",
  238. });
  239. }
  240. }
  241. if (flowDefinitionNodeList.value && flowDefinitionNodeList.value.length > 0) {
  242. if (!flowForm.handleNodeId) {
  243. return ElMessage({
  244. message: "请选择要退回的节点!",
  245. type: "info",
  246. });
  247. }
  248. }
  249. handleSubmit(handleType.value);
  250. };
  251. const handleResult = (res) => {
  252. if (
  253. (res.userList == null && res.success) ||
  254. (res.flowDefinitionNodeList == null && res.success)
  255. ) {
  256. skipPage();
  257. } else if (res.userList && res.userList.length > 0) {
  258. flowDefinitionNodeList.value = [];
  259. dialogTitle.value = "下一处理人";
  260. dialogVisible.value = true;
  261. nextHandleUser.value = res.userList;
  262. } else if (
  263. res.flowDefinitionNodeList &&
  264. res.flowDefinitionNodeList.length > 0
  265. ) {
  266. nextHandleUser.value = [];
  267. dialogTitle.value = "退回到指定节点";
  268. dialogVisible.value = true;
  269. flowDefinitionNodeList.value = res.flowDefinitionNodeList;
  270. } else {
  271. return ElMessage({
  272. message: "请联系管理员!",
  273. type: "info",
  274. });
  275. }
  276. };
  277. const uploadFile = async (file) => {
  278. const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });
  279. uploadData.value = res.uploadBody;
  280. file.id = res.id;
  281. file.fileName = res.fileName;
  282. file.fileUrl = res.fileUrl;
  283. file.uploadState = true;
  284. return true;
  285. };
  286. const handleSuccess = (any, UploadFile) => {
  287. UploadFile.raw.uploadState = false;
  288. };
  289. const onPreviewFile = (file) => {
  290. window.open(file.raw.fileUrl, "_blank");
  291. };
  292. const handleNextClose = () => {
  293. btnLoading.value = false;
  294. dialogVisible.value = false;
  295. };
  296. // 提交逻辑
  297. const handleSubmit = async (_type) => {
  298. handleType.value = _type ? _type : undefined;
  299. try {
  300. // 调用发起组件的提交事件
  301. const flag = await makeDom.value.handleSubmit();
  302. if (flag) {
  303. flowFormDom.value.validate((valid) => {
  304. btnLoading.value = true;
  305. if (valid) {
  306. const data = { ...makeDom.value.getFormData() };
  307. flowForm.fileList = flowForm.fileList.map((item) => {
  308. return {
  309. ...item,
  310. ...item.raw,
  311. };
  312. });
  313. if (route.query.processType == 10 || route.query.processType == 30) {
  314. // if (_type && _type == 1) {
  315. // proxy
  316. // .post("/flowExample/setStartData", {
  317. // exampleId: route.query.id,
  318. // startData: data,
  319. // })
  320. // .then();
  321. // }
  322. proxy
  323. .post("/flowProcess/jump", {
  324. ...flowForm,
  325. data,
  326. handleType: _type,
  327. version: route.query.version,
  328. flowId: route.query.id,
  329. skipSetData: true,
  330. })
  331. .then(
  332. (res) => {
  333. handleResult(res);
  334. },
  335. (err) => {
  336. btnLoading.value = false;
  337. }
  338. );
  339. return;
  340. } else {
  341. proxy
  342. .post("/flowProcess/initiate", {
  343. ...flowForm,
  344. data,
  345. skipSetData: true,
  346. })
  347. .then(
  348. (res) => {
  349. handleResult(res);
  350. },
  351. (err) => {
  352. btnLoading.value = false;
  353. }
  354. );
  355. }
  356. }
  357. });
  358. }
  359. } catch (err) {
  360. console.log("数据未填完整!", err);
  361. }
  362. };
  363. // 暂存
  364. const handleSubmitStag = async (_type) => {
  365. try {
  366. // 调用发起组件的提交事件
  367. const flag = await makeDom.value.handleSubmit(true);
  368. if (flag) {
  369. flowFormDom.value.validate((valid) => {
  370. btnLoading.value = true;
  371. if (valid) {
  372. const data = { ...makeDom.value.getFormData() };
  373. flowForm.fileList = flowForm.fileList.map((item) => {
  374. return {
  375. ...item,
  376. ...item.raw,
  377. };
  378. });
  379. if (flowForm.flowKey == "contract_flow") {
  380. proxy.post("/contract/add", data).then(
  381. (res) => {
  382. skipPage();
  383. },
  384. (err) => {
  385. btnLoading.value = false;
  386. }
  387. );
  388. } else if (flowForm.flowKey == "subscribe_flow") {
  389. proxy.post("/contract/add", data).then(
  390. (res) => {
  391. skipPage();
  392. },
  393. (err) => {
  394. btnLoading.value = false;
  395. }
  396. );
  397. }
  398. }
  399. });
  400. }
  401. } catch (err) {
  402. console.log("数据未填完整!", err);
  403. }
  404. };
  405. // 页面跳转
  406. const skipPage = () => {
  407. let pageObj = {
  408. subscribe_flow: "Subscribe",
  409. contract_flow: "Contract",
  410. contract_update_flow: "Contract",
  411. sample_flow: "ContractSample",
  412. sample_update_flow: "ContractSample",
  413. sale_quotation_flow: "Quotation",
  414. purchase_update_flow: "Purchased",
  415. purchase_flow: "Purchase",
  416. pay_flow: "Payment",
  417. purchase_back_flow: "ReturnGood",
  418. discuss_price_flow: "PriceSheetEHSD",
  419. after_sales_flow: "AfterSales",
  420. sales_outbound_approved_flow: "Contract",
  421. };
  422. const useTagsStore = useTagsViewStore();
  423. useTagsStore.delVisitedView(router.currentRoute.value);
  424. if (route.query.processType) {
  425. router.replace({
  426. name: "Backlog",
  427. });
  428. } else {
  429. proxy.msgTip("操作成功");
  430. router.replace({
  431. name: pageObj[route.query.flowKey],
  432. });
  433. }
  434. $bus.emit("refreshTableData");
  435. };
  436. let queryData = reactive({
  437. data: {},
  438. });
  439. // 记录
  440. const recordList = ref([]);
  441. const fileIds = ref([]);
  442. const fileObj = ref({});
  443. const approvalRecordData = ref({
  444. buttonInfoList: [],
  445. });
  446. const getRecords = (_id) => {
  447. if (_id) {
  448. proxy
  449. .post("/flowExample/getApprovalRecord", {
  450. id: _id,
  451. })
  452. .then((res) => {
  453. recordList.value = res.recordList;
  454. queryData.data.recordList = res.recordList;
  455. approvalRecordData.value = res;
  456. fileIds.value = res.recordList.map((item) => {
  457. return item.flowExampleDetailId;
  458. });
  459. proxy
  460. .post("fileInfo/getList", { businessIdList: fileIds.value })
  461. .then((res2) => {
  462. fileObj.value = res2;
  463. });
  464. });
  465. } else {
  466. proxy
  467. .post("/flowExample/getFlowNode", {
  468. flowKey: flowForm.flowKey,
  469. })
  470. .then((res) => {
  471. recordList.value = res;
  472. });
  473. }
  474. };
  475. const isShowSubmitDom = ref(true);
  476. const chartDom = ref(null);
  477. const chartData = ref([]);
  478. let myChart = null;
  479. const optionTwo = reactive({
  480. data: {
  481. tooltip: {
  482. trigger: "axis",
  483. },
  484. // legend: {
  485. // data: ["价格"],
  486. // },
  487. grid: {
  488. left: "3%",
  489. right: "6%",
  490. top: "10%",
  491. bottom: "3%",
  492. containLabel: true,
  493. },
  494. tooltip: {
  495. show: true,
  496. trigger: "axis",
  497. // 格式化函数
  498. // valueFormatter: (val) => {
  499. // return val + "aaa";
  500. // },
  501. formatter: (params, ticket, callback) => {
  502. return `
  503. ${params[0].axisValue}
  504. <br/>
  505. ${params[0].seriesName}:${params[0].data}
  506. <br/> 销售合同金额:${
  507. chartData.value[params[0].dataIndex].contractCurrency
  508. } ${chartData.value[params[0].dataIndex].contractAmount}
  509. <br/> 采购合同金额:CNY ${
  510. chartData.value[params[0].dataIndex].purchaseAmount
  511. }`;
  512. },
  513. textStyle: {
  514. fontSize: 12,
  515. },
  516. },
  517. // toolbox: {
  518. // feature: {
  519. // saveAsImage: {},
  520. // },
  521. // },
  522. xAxis: {
  523. type: "category",
  524. boundaryGap: false,
  525. data: [],
  526. },
  527. yAxis: {
  528. type: "value",
  529. },
  530. series: [
  531. {
  532. name: "毛利",
  533. type: "line",
  534. data: [],
  535. },
  536. ],
  537. },
  538. });
  539. const showChart = ref(false);
  540. onMounted(async () => {
  541. // 路由进入
  542. if (route.query && route.query.flowKey) {
  543. //processType 10 为修改 20为查看 30回退发起
  544. if (route.query.processType == 20) {
  545. activeName.value = "second";
  546. isShowSubmitDom.value = false;
  547. }
  548. if (
  549. route.query.processType == 10 ||
  550. route.query.processType == 20 ||
  551. route.query.processType == 30
  552. ) {
  553. // await proxy
  554. // .post("/flowProcess/getStartData", { flowId: route.query.id })
  555. // .then((res) => {
  556. // queryData.data = { ...res };
  557. // });
  558. } else {
  559. queryData.data = { ...route.query };
  560. }
  561. flowForm.flowKey = route.query.flowKey;
  562. flowForm.submitType = route.query.submitType;
  563. getRecords(route.query.id);
  564. }
  565. $bus.on("getGrossData", (data) => {
  566. if (route.query.processType == 10 || route.query.processType == 30) {
  567. showChart.value = true;
  568. }
  569. nextTick(() => {
  570. if (data && data.length > 1 && showChart.value) {
  571. myChart = echarts.init(chartDom.value);
  572. window.addEventListener("resize", () => {
  573. myChart.resize();
  574. });
  575. chartData.value = data;
  576. // chartData.value = data.slice(1, data.length);
  577. optionTwo.data.xAxis.data = chartData.value.map((item) => {
  578. return item.createTime.slice(0, 10);
  579. });
  580. optionTwo.data.series[0].data = chartData.value.map((item) => {
  581. return item.gross;
  582. });
  583. myChart.setOption(optionTwo.data);
  584. myChart.resize();
  585. } else {
  586. showChart.value = false;
  587. }
  588. });
  589. });
  590. });
  591. onBeforeUnmount(() => {
  592. // 取消订阅特定事件
  593. $bus.off("getGrossData");
  594. });
  595. watch(
  596. () => props.query,
  597. () => {
  598. if (props.query) {
  599. if (props.query.processType == 20) {
  600. isShowSubmitDom.value = false;
  601. activeName.value = "second";
  602. }
  603. if (
  604. props.query.processType == 10 ||
  605. props.query.processType == 20 ||
  606. props.query.processType == 30
  607. ) {
  608. queryData.data = { ...props.query };
  609. } else {
  610. queryData.data = { ...props.query };
  611. }
  612. flowForm.flowKey = props.query.flowKey;
  613. flowForm.submitType = props.query.submitType;
  614. getRecords(props.query.id);
  615. }
  616. },
  617. {
  618. deep: true,
  619. immediate: true,
  620. }
  621. );
  622. const getFlowName = () => {
  623. let name = "流程(审批)";
  624. if (route.query && route.query.flowName) {
  625. name = route.query.flowName;
  626. } else if (props.query && props.query.flowName) {
  627. name = props.query.flowName;
  628. }
  629. return name;
  630. };
  631. // 动态计算高度
  632. const processApprovalDom = ref(null);
  633. const flowChartDom = ref(null);
  634. const getTableHeight = () => {
  635. if (route.query.currentContractId) {
  636. processApprovalDom.value.style.height = window.innerHeight - 160 + "px";
  637. flowChartDom.value.style.height = window.innerHeight - 250 + "px";
  638. } else {
  639. processApprovalDom.value.style.height = window.innerHeight - 100 + "px";
  640. flowChartDom.value.style.height = window.innerHeight - 210 + "px";
  641. }
  642. };
  643. onMounted(() => {
  644. getTableHeight();
  645. });
  646. window.addEventListener("resize", () => {
  647. getTableHeight();
  648. });
  649. </script>
  650. <style lang="scss" scoped>
  651. .processApproval {
  652. display: flex;
  653. justify-content: space-between;
  654. padding: 10px;
  655. // height: calc(100vh - 100px);
  656. .left-card {
  657. // background: #fff;
  658. border-radius: 4px;
  659. // padding: 20px;
  660. // flex: 1;
  661. width: calc(100% - 350px - 10px);
  662. margin-right: 10px;
  663. display: flex;
  664. flex-direction: column;
  665. .top {
  666. /* 宽度和高度 */
  667. flex: 1;
  668. overflow-y: auto;
  669. background: #fff;
  670. padding: 20px 20px 0px 20px;
  671. .line {
  672. border-bottom: 1px solid #ddd;
  673. margin-bottom: 20px;
  674. }
  675. }
  676. .bottom {
  677. margin-top: 10px;
  678. height: 220px;
  679. background: #fff;
  680. padding: 20px 20px 0px 20px;
  681. overflow: auto;
  682. }
  683. }
  684. .right-card {
  685. background: #fff;
  686. border-radius: 4px;
  687. // padding: 0 20px 20px;
  688. padding: 0 20px 5px;
  689. width: 350px;
  690. box-sizing: border-box;
  691. .flow-chart {
  692. overflow: auto;
  693. height: calc(100vh - 200px);
  694. padding: 0;
  695. margin: 0;
  696. li {
  697. margin: 0;
  698. padding: 0 0 20px;
  699. list-style: none;
  700. display: flex;
  701. justify-content: space-between;
  702. position: relative;
  703. .right-conetnt {
  704. flex: 1;
  705. .name {
  706. font-size: 12px;
  707. color: #39c55a;
  708. margin-bottom: 10px;
  709. span {
  710. color: #999;
  711. }
  712. }
  713. .time {
  714. float: right;
  715. }
  716. .remark {
  717. padding: 10px;
  718. color: #666666;
  719. font-size: 12px;
  720. background: #f1f1f1;
  721. border-radius: 2px;
  722. .label {
  723. color: #999;
  724. margin-bottom: 10px;
  725. }
  726. }
  727. }
  728. .left-icon {
  729. width: 40px;
  730. height: 40px;
  731. text-align: center;
  732. line-height: 40px;
  733. background: #0084ff;
  734. border-radius: 10px;
  735. color: #fff;
  736. font-size: 20px;
  737. position: relative;
  738. margin-right: 27px;
  739. z-index: 2;
  740. .right-btm-status {
  741. position: absolute;
  742. bottom: 0px;
  743. right: -10px;
  744. height: 20px;
  745. width: 20px;
  746. line-height: 16px;
  747. border-radius: 10px;
  748. background: #39c55a;
  749. border: 2px solid #fff;
  750. font-size: 12px;
  751. box-sizing: border-box;
  752. }
  753. }
  754. }
  755. li::before {
  756. content: "";
  757. position: absolute;
  758. top: 0;
  759. left: 20px;
  760. width: 2px;
  761. height: 100%;
  762. background: #ddd;
  763. z-index: 1;
  764. }
  765. li:last-child::before {
  766. display: none;
  767. }
  768. .flow-orange {
  769. .right-btm-status {
  770. background: #ff9a00 !important;
  771. }
  772. .name {
  773. color: #ff9a00 !important;
  774. }
  775. .left-icon {
  776. background: #ff9a00 !important;
  777. }
  778. }
  779. .flow-grey {
  780. .right-btm-status {
  781. background: #999 !important;
  782. }
  783. .name {
  784. color: #999 !important;
  785. }
  786. .left-icon {
  787. background: #999 !important;
  788. }
  789. }
  790. .flow-red {
  791. .right-btm-status {
  792. background: #ff4d4f !important;
  793. }
  794. .name {
  795. color: #ff4d4f !important;
  796. }
  797. .left-icon {
  798. background: #ff4d4f !important;
  799. }
  800. }
  801. }
  802. }
  803. }
  804. :deep(.el-upload-dragger .el-icon--upload) {
  805. margin-bottom: 0px;
  806. font-size: 40px;
  807. }
  808. :deep(.el-upload-dragger) {
  809. padding: 0px !important;
  810. }
  811. </style>