index.vue 25 KB

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