index.vue 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096
  1. <template>
  2. <div class="app-container ">
  3. <div class="stat-warp">
  4. <div style="margin-bottom:15px">
  5. <TitleInfo :content="'工作事项'"></TitleInfo>
  6. </div>
  7. <ul>
  8. <li class="theme1" @click="toUrl(1)">
  9. <div class="num">{{ toBeProcessedData.total }}</div>
  10. <div class="label">待审批</div>
  11. <div class="icon-box">
  12. <i class="icon iconfont icon-iconm_waixht"></i>
  13. </div>
  14. </li>
  15. <li class="theme2" @click="toUrl(2)">
  16. <div class="num">{{ allData[0].total }}</div>
  17. <div class="label">待报价</div>
  18. <div class="icon-box">
  19. <svg-icon :icon-class="'baojia'" className="svg-class1" />
  20. </div>
  21. </li>
  22. <li class="theme3" @click="toUrl(3)">
  23. <div class="num">{{ allData[1].total }}</div>
  24. <div class="label">待投产</div>
  25. <div class="icon-box">
  26. <svg-icon :icon-class="'touchang'" className="svg-class" />
  27. </div>
  28. </li>
  29. <li class="theme4" @click="toUrl(4)">
  30. <div class="num">{{ allData[2].total }}</div>
  31. <div class="label">待入库</div>
  32. <div class="icon-box">
  33. <svg-icon :icon-class="'ruku'" className="svg-class1" />
  34. </div>
  35. </li>
  36. <li class="theme5" @click="toUrl(5)">
  37. <div class="num">{{ allData[3].total }}</div>
  38. <div class="label">待出库</div>
  39. <div class="icon-box">
  40. <svg-icon :icon-class="'chuku'" className="svg-class1" />
  41. </div>
  42. </li>
  43. <!-- <li class="theme6" @click="toUrl(6)" v-if="useUserStore().user.companyId =='100'">
  44. <div class="num">{{ allData[4].total }}</div>
  45. <div class="label">待认领</div>
  46. <div class="icon-box">
  47. <svg-icon :icon-class="'renling'" className="svg-class1" />
  48. </div>
  49. </li> -->
  50. <li class="theme6" @click="toUrl(6)">
  51. <div class="num">{{ allData[5].total }}</div>
  52. <div class="label">库存预警</div>
  53. <div class="icon-box">
  54. <svg-icon :icon-class="'kucun'" className="svg-class1" />
  55. </div>
  56. </li>
  57. </ul>
  58. <div class="table-card">
  59. <el-card style="width:32%">
  60. <TitleInfo :content="'待审批'"></TitleInfo>
  61. <el-table :data="toBeProcessedData.rows" style="width: 100%" :height="tableHeight">
  62. <el-table-column prop="title" label="流程标题" />
  63. <el-table-column label="操作" width="60" align="right">
  64. <template #default="{row,$index}">
  65. <div style="width:100%">
  66. <el-button type="primary" link style="font-size:12px" @click="pushProcessApproval(row)">办理</el-button>
  67. </div>
  68. </template>
  69. </el-table-column>
  70. </el-table>
  71. </el-card>
  72. <el-card style="width:32%">
  73. <TitleInfo :content="'待报价'"></TitleInfo>
  74. <el-table :data="allData[0].rows" style="width: 100%" :height="tableHeight">
  75. <el-table-column prop="code" label="报价单号">
  76. <template #default="{row,$index}">
  77. <div style="width:100%">
  78. <span class="el-click" @click="handleOpenDetail(row)">{{row.code}}</span>
  79. </div>
  80. </template>
  81. </el-table-column>
  82. <el-table-column prop="amount" label="报价金额" width="110" />
  83. </el-table>
  84. </el-card>
  85. <el-card style="width:32%">
  86. <TitleInfo :content="'待投产'"></TitleInfo>
  87. <el-table :data="allData[1].rows" style="width: 100%" :height="tableHeight">
  88. <el-table-column prop="code" label="订单号">
  89. <template #default="{row,$index}">
  90. <div style="width:100%">
  91. <span class="el-click" @click="lookDetails(row)">{{row.code}}</span>
  92. </div>
  93. </template>
  94. </el-table-column>
  95. <el-table-column prop="deliveryPeriod" label="交期" width="150" />
  96. </el-table>
  97. </el-card>
  98. </div>
  99. <div class="table-card ">
  100. <el-card style="width:32%">
  101. <TitleInfo :content="'待入库'"></TitleInfo>
  102. <el-table :data="allData[2].rows" style="width: 100%" :height="tableHeight">
  103. <el-table-column prop="productName" label="产品名称" />
  104. <el-table-column prop="quantity" label="数量" width="100" />
  105. </el-table>
  106. </el-card>
  107. <el-card style="width:32%">
  108. <TitleInfo :content="'待出库'"></TitleInfo>
  109. <el-table :data="allData[3].rows" style="width: 100%" :height="tableHeight">
  110. <el-table-column prop="productName" label="产品名称" />
  111. <el-table-column prop="quantity" label="数量" width="100" />
  112. </el-table>
  113. </el-card>
  114. <!-- <el-card style="width:32%" v-if="useUserStore().user.companyId =='100'">
  115. <TitleInfo :content="'待认领'"></TitleInfo>
  116. <el-table :data="allData[4].rows" style="width: 100%" :height="tableHeight">
  117. <el-table-column prop="accountManagementName" label="账户名称" />
  118. <el-table-column prop="amount" label="到账金额" width="100" />
  119. <el-table-column prop="transactionTime" label="到账时间" width="150" />
  120. </el-table>
  121. </el-card> -->
  122. <el-card style="width:32%">
  123. <TitleInfo :content="'库存预警'"></TitleInfo>
  124. <el-table :data="allData[5].rows" style="width: 100%" :height="tableHeight">
  125. <el-table-column prop="productCode" label="产品编码" />
  126. <el-table-column prop="productName" label="产品名称" />
  127. <el-table-column prop="stockThreshold" label="安全库存" width="100" />
  128. <el-table-column prop="quantity" label="当前库存" width="100" />
  129. </el-table>
  130. </el-card>
  131. </div>
  132. </div>
  133. <div class="table-warp">
  134. <div style="margin-bottom:15px">
  135. <TitleInfo :content="'监控告警'"></TitleInfo>
  136. </div>
  137. <el-card style="margin-bottom:20px">
  138. <TitleInfo :content="'逾期生产订单'+` (${allData[6].total})`"></TitleInfo>
  139. <el-table :data="allData[6].rows" style="width: 100%" :height="tableHeightOne">
  140. <el-table-column prop="code" label="订单号">
  141. <template #default="{row,$index}">
  142. <div style="width:100%">
  143. <span class="el-click" @click="lookDetails(row)">{{row.code}}</span>
  144. </div>
  145. </template>
  146. </el-table-column>
  147. <el-table-column prop="deliveryPeriod" label="交期" width="150" />
  148. </el-table>
  149. </el-card>
  150. <el-card style="margin-bottom:20px">
  151. <TitleInfo :content="'报损情况(近30天)'"></TitleInfo>
  152. <div class="baosun">
  153. <div class="theme2 q" @click="toUrl(7)">
  154. <span class="label">报损</span>
  155. <span class="num">{{ reportLossesData.replenishSumQuantity }}</span>
  156. </div>
  157. <div class="theme3 q" @click="toUrl(7)">
  158. <span class="label">丢件</span>
  159. <span class="num">{{ reportLossesData.lossSumQuantity }}</span>
  160. </div>
  161. </div>
  162. </el-card>
  163. <el-card>
  164. <TitleInfo :content="'设备运行情况'"></TitleInfo>
  165. <div style="display:flex;align-items:center">
  166. <div style="width:100px;font-size:12px">
  167. 设备名称:设备1 <br><br> 当天标刻数量:10<br><br>在线工作时长(分钟):1000
  168. </div>
  169. <div style="height:190px;width:calc(100% - 100px)" ref="pie_1"></div>
  170. </div>
  171. </el-card>
  172. </div>
  173. <el-dialog v-if="detailDialog" v-model="detailDialog" title="报价详情" width="90%" append-to-body>
  174. <PriceSheetDetailList :rowData="detailRowData" dataType="1" @changeLeftData="changeLeftData"></PriceSheetDetailList>
  175. </el-dialog>
  176. <el-dialog :title="'查看'" v-model="dialogVisible" width="90%" destroy-on-close>
  177. <el-tabs v-model="activeName" type="card" class="demo-tabs" @tab-change="handleTabChange">
  178. <el-tab-pane label="订单详情" name="1">
  179. </el-tab-pane>
  180. <el-tab-pane label="物料结存" name="2">
  181. </el-tab-pane>
  182. </el-tabs>
  183. <byForm :formConfig="formConfig" :formOption="formOptionOne" v-model="formData.orderData" ref="formDom">
  184. <template #commodity>
  185. <div style="width: 100%">
  186. <el-table :data="formData.orderData.contractProductList" style="width: 100%; ">
  187. <el-table-column type="expand" width="50" align="center">
  188. <template #default="scope">
  189. <div style="padding-left:50px">
  190. <div style="margin-bottom:10px;">
  191. <TitleInfo content='BOM单:'></TitleInfo>
  192. </div>
  193. <el-table :data="scope.row.contractProductBomList" style="width: 100%;" border class="bom-table">
  194. <el-table-column label="图片" width="80">
  195. <template #default="{ row }">
  196. <div v-if="row.fileUrl">
  197. <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
  198. </div>
  199. <div v-else></div>
  200. </template>
  201. </el-table-column>
  202. <el-table-column prop="productCode" label="物料编码" width="190" />
  203. <el-table-column prop="productName" label="物料名称" min-width="200" />
  204. <el-table-column label="规格尺寸 (cm)" width="150">
  205. <template #default="{ row, $index }">
  206. <div style="width: 100%">
  207. {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
  208. </div>
  209. </template>
  210. </el-table-column>
  211. <el-table-column prop="quantity" label="数量" width="110" />
  212. <el-table-column prop="remark" label="备注" width="180" />
  213. </el-table>
  214. </div>
  215. </template>
  216. </el-table-column>
  217. <el-table-column label="商品图片" width="80">
  218. <template #default="{ row }">
  219. <div v-if="row.fileUrl">
  220. <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
  221. </div>
  222. <div v-else></div>
  223. </template>
  224. </el-table-column>
  225. <el-table-column prop="productCnName" label="商品名称" min-width="130" />
  226. <el-table-column prop="productCode" label="商品编码" width="130" />
  227. <el-table-column label="规格尺寸 (cm)" width="150">
  228. <template #default="{ row, $index }">
  229. <div style="width: 100%">
  230. {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
  231. </div>
  232. </template>
  233. </el-table-column>
  234. <el-table-column prop="productColor" label="颜色" width="100" />
  235. <!-- <el-table-column label="设计图稿" width="80">
  236. <template #default="{ row, $index }">
  237. <div style="width: 100%">
  238. <el-upload :action="uploadUrl" accept=".gif, .jpeg, .jpg, .png" :show-file-list="false" :data="uploadData"
  239. :before-upload="(file)=>handleBeforeUpload(file,$index)" :on-success="()=>handleSuccess($index)">
  240. <div v-loading="row.imgLoading">
  241. <img v-if="row.imageUrl" :src="row.imageUrl" class="pic" />
  242. </div>
  243. </el-upload>
  244. </div>
  245. </template>
  246. </el-table-column> -->
  247. <el-table-column label="生产plt文件" width="140">
  248. <template #default="{ row, $index }">
  249. <div style="width:100%">
  250. <div v-if="row.isShowProductFile &&row.fileListOne && row.fileListOne.length > 0">
  251. <span class="el-click" @click="onPicture(row.fileListOne[0].fileUrl)">{{row.fileListOne[0].fileName}}</span>
  252. </div>
  253. <div v-else>
  254. <div v-if="row.prodFileList && row.prodFileList.length > 0">
  255. <span class="el-click" @click="onPicture(row.prodFileList[0].fileUrl)">{{row.prodFileList[0].fileName}} (定制)</span>
  256. </div>
  257. </div>
  258. </div>
  259. </template>
  260. </el-table-column>
  261. <el-table-column label="数量" width="150" prop="quantity" />
  262. <el-table-column label="备注" min-width="200" prop="remark" />
  263. </el-table>
  264. </div>
  265. </template>
  266. <template #commodityOne>
  267. <div style="width: 100%">
  268. <el-table :data="formData.orderData.materialList" style="width: 100%; ">
  269. <el-table-column label="物料图片" width="80">
  270. <template #default="{ row }">
  271. <div v-if="row.fileUrl">
  272. <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
  273. </div>
  274. <div v-else></div>
  275. </template>
  276. </el-table-column>
  277. <el-table-column prop="materialCode" label="物料编码" width="200" />
  278. <el-table-column prop="materialName" label="物料名称" min-width="150" />
  279. <el-table-column prop="quantity" label="应发数量" width="150" />
  280. <el-table-column prop="unclaimedQuantity" label="未领数量" width="150" />
  281. <el-table-column prop="receivedQuantity" label="已领数量" width="150" />
  282. <el-table-column prop="workshopInventoryQuantity" label="车间结存" width="150">
  283. <template #default="{ row, $index }">
  284. <div style="color:red">
  285. {{row.workshopInventoryQuantity}}
  286. </div>
  287. </template>
  288. </el-table-column>
  289. <el-table-column prop="purchaseTransitQuantity" label="采购在途" width="100" />
  290. </el-table>
  291. </div>
  292. </template>
  293. </byForm>
  294. <template #footer>
  295. <el-button @click="dialogVisible = false" size="defualt">取 消</el-button>
  296. </template>
  297. </el-dialog>
  298. </div>
  299. </template>
  300. <script setup name="Index">
  301. import { createApp, onMounted, ref } from "vue";
  302. import byTableDemo from "../components/byTable/demo";
  303. import html2canvas from "html2canvas";
  304. import JsPDF from "jspdf";
  305. import * as echarts from "echarts";
  306. import PriceSheetDetailList from "@/views/EHSD/saleContract/PriceSheetDetailList";
  307. import byForm from "@/components/byForm/index";
  308. const { proxy } = getCurrentInstance();
  309. const tableHeight = ref(0);
  310. const tableHeightOne = ref(0);
  311. const getTableHeight = () => {
  312. tableHeight.value = (window.innerHeight - 390) / 2;
  313. tableHeightOne.value = window.innerHeight - 610;
  314. };
  315. getTableHeight();
  316. window.addEventListener("resize", () => {
  317. getTableHeight();
  318. });
  319. function goTarget(url) {
  320. window.open(url, "__blank");
  321. }
  322. const toBeProcessedData = ref({
  323. total: 0,
  324. rows: [],
  325. });
  326. const allData = ref({
  327. 0: {
  328. total: 0,
  329. rows: [],
  330. },
  331. 1: { total: 0, rows: [] },
  332. 2: { total: 0, rows: [] },
  333. 3: { total: 0, rows: [] },
  334. 4: { total: 0, rows: [] },
  335. 5: { total: 0, rows: [] },
  336. 6: { total: 0, rows: [] },
  337. });
  338. const reportLossesData = ref({});
  339. const pushProcessApproval = (row) => {
  340. if (row.status != 1 && row.status != 0) {
  341. proxy.$router.push({
  342. path: "/platform_manage/process/processApproval",
  343. query: {
  344. flowKey: row.flowKey,
  345. id: row.id,
  346. processType: 20,
  347. version: row.version,
  348. businessId: row.businessId,
  349. submitType: "10",
  350. },
  351. });
  352. return;
  353. }
  354. proxy.post("flowExample/getApprovalRecord", { id: row.id }).then((res) => {
  355. if (res.recordList.length > 0) {
  356. let data = res.recordList.filter((item) => item.status === 2);
  357. let nodeType = 0;
  358. if (data && data.length > 0) {
  359. nodeType = data[0].nodeType;
  360. }
  361. proxy.$router.push({
  362. path: "/platform_manage/process/processApproval",
  363. query: {
  364. flowKey: row.flowKey,
  365. id: row.id,
  366. processType: nodeType == 1 ? 30 : 10,
  367. businessId: row.businessId,
  368. },
  369. });
  370. }
  371. });
  372. };
  373. const pushProcessApprovalOne = (row) => {
  374. proxy.$router.push({
  375. path: "/platform_manage/process/processApproval",
  376. query: {
  377. flowKey: row.flowKey,
  378. id: row.id,
  379. processType: 20,
  380. version: row.version,
  381. businessId: row.businessId,
  382. submitType: "10",
  383. },
  384. });
  385. return;
  386. };
  387. const getData = () => {
  388. proxy
  389. .post("/flowExample/getToBeProcessedPage", {
  390. pageNum: 1,
  391. pageSize: 5,
  392. })
  393. .then((res) => {
  394. toBeProcessedData.value = res;
  395. });
  396. // 待报价
  397. proxy
  398. .post("/saleQuotation/page", {
  399. pageNum: 1,
  400. pageSize: 5,
  401. isEstimate: proxy.useUserStore().user.companyId == "100" ? "" : "1",
  402. })
  403. .then((res) => {
  404. allData.value[0] = res;
  405. });
  406. // 待投产
  407. proxy
  408. .post("/produceOrder/page", {
  409. pageNum: 1,
  410. pageSize: 5,
  411. isProduce: "0",
  412. })
  413. .then((res) => {
  414. allData.value[1] = res;
  415. });
  416. // 待入库
  417. proxy
  418. .post("/stockWaitDetails/page", {
  419. pageNum: 1,
  420. pageSize: 5,
  421. type: 1,
  422. })
  423. .then((res) => {
  424. allData.value[2] = res;
  425. });
  426. // 待出库
  427. proxy
  428. .post("/stockWaitDetails/page", {
  429. pageNum: 1,
  430. pageSize: 5,
  431. type: 2,
  432. })
  433. .then((res) => {
  434. allData.value[3] = res;
  435. });
  436. // 待认领
  437. proxy
  438. .post("/sale/accountRunningWater/page", {
  439. pageNum: 1,
  440. pageSize: 5,
  441. isClaim: "0,2",
  442. dataType: "1",
  443. })
  444. .then((res) => {
  445. allData.value[4] = res;
  446. });
  447. // 库存预警
  448. proxy
  449. .post("/stock/stockWarningPage", {
  450. pageNum: 1,
  451. pageSize: 5,
  452. })
  453. .then((res) => {
  454. allData.value[5] = res;
  455. });
  456. // 逾期生产订单
  457. proxy
  458. .post("/produceOrder/page", {
  459. pageNum: 1,
  460. pageSize: 10,
  461. isOverdue: "1",
  462. })
  463. .then((res) => {
  464. allData.value[6] = res;
  465. });
  466. // 补单统计
  467. proxy.post("/reportLossesDetails/lossesStatistics").then((res) => {
  468. reportLossesData.value = res;
  469. });
  470. };
  471. const toUrl = (att) => {
  472. //获取name为name的路由的基础信息
  473. // const route = proxy.$router.resolve({ name: name, params: {} });
  474. let pageObj = {
  475. 1: "Backlog",
  476. 2:
  477. proxy.useUserStore().user.companyId == "100"
  478. ? "PriceSheetEHSD"
  479. : "PriceSheetEstimate",
  480. 3: "ProductionOrder",
  481. 4: "WaitingForStorage",
  482. 5: "WaitingForDelivery",
  483. 6: "Claim",
  484. 7: "InventoryInquiry",
  485. };
  486. proxy.$router.push({
  487. name: pageObj[att],
  488. });
  489. };
  490. getData();
  491. // ​
  492. const getOption = () => {
  493. return {
  494. title: {
  495. show: true,
  496. text: "",
  497. bottom: "0%",
  498. left: "center",
  499. textStyle: {
  500. color: "#fff",
  501. fontSize: 12,
  502. fontWeight: 400,
  503. },
  504. },
  505. tooltip: {
  506. trigger: "item",
  507. },
  508. grid: {
  509. show: false,
  510. bottom: 0,
  511. },
  512. // legend: {
  513. // top: "0%",
  514. // left: "center",
  515. // },
  516. series: [
  517. {
  518. name: "设备1",
  519. type: "pie",
  520. // center: ["50%", "50%"],
  521. radius: ["45%", "75%"],
  522. top: "0%",
  523. bottom: "0%",
  524. avoidLabelOverlap: false,
  525. label: {
  526. show: false,
  527. position: "center",
  528. },
  529. emphasis: {
  530. label: {
  531. show: true,
  532. fontSize: 14,
  533. fontWeight: "bold",
  534. color: "#fff",
  535. },
  536. },
  537. labelLine: {
  538. show: false,
  539. },
  540. data: [
  541. {
  542. value: 1000,
  543. name: "工作时长",
  544. itemStyle: {
  545. color: "#F9CB19",
  546. },
  547. },
  548. {
  549. value: 440,
  550. name: "",
  551. itemStyle: {
  552. color: "#268EFF",
  553. },
  554. },
  555. ],
  556. },
  557. ],
  558. };
  559. };
  560. const pie_1 = ref(null);
  561. let pie_1Chart = null;
  562. let option1 = {};
  563. onMounted(() => {
  564. option1 = getOption();
  565. pie_1Chart = echarts.init(pie_1.value);
  566. window.addEventListener("resize", () => {
  567. pie_1Chart.resize();
  568. });
  569. pie_1Chart.setOption(option1);
  570. pie_1Chart.resize();
  571. });
  572. const detailDialog = ref(false);
  573. const detailRowData = ref({});
  574. const handleOpenDetail = (item) => {
  575. detailRowData.value = item;
  576. detailDialog.value = true;
  577. };
  578. const handleOpenOrderDetail = (row) => {
  579. proxy.$router.push({
  580. path: "/platform_manage/process/processApproval",
  581. query: {
  582. flowKey: "contract_flow",
  583. id: row.flowId || "",
  584. processType: 20,
  585. businessId: row.contractId,
  586. },
  587. });
  588. };
  589. const formData = reactive({
  590. data: {},
  591. orderData: {},
  592. });
  593. const formOptionOne = reactive({
  594. inline: true,
  595. labelWidth: 100,
  596. itemWidth: 100,
  597. disabled: true,
  598. });
  599. const dialogVisible = ref(false);
  600. const formDom = ref(null);
  601. const formConfig = computed(() => {
  602. return [
  603. {
  604. type: "title1",
  605. title: "基本信息",
  606. isShow: activeName.value == "1",
  607. },
  608. {
  609. type: "text",
  610. prop: "code",
  611. label: "合同号:",
  612. disabled: true,
  613. isShow: formData.orderData.code && activeName.value == "1" ? true : false,
  614. },
  615. {
  616. type: "title1",
  617. title: "商品信息",
  618. haveLine: true,
  619. isShow: activeName.value == "1",
  620. },
  621. {
  622. type: "slot",
  623. slotName: "commodity",
  624. label: "",
  625. isShow: activeName.value == "1",
  626. },
  627. {
  628. type: "title1",
  629. title: "物料结存",
  630. haveLine: false,
  631. isShow: activeName.value == "2",
  632. },
  633. {
  634. type: "slot",
  635. slotName: "commodityOne",
  636. label: "",
  637. isShow: activeName.value == "2",
  638. },
  639. ];
  640. });
  641. const getFileData = () => {
  642. let ids = [];
  643. formData.orderData.contractProductList.map((x) => {
  644. // ids.push(x.productId);
  645. x.contractProductBomList.map((y) => {
  646. ids.push(y.materialId);
  647. });
  648. });
  649. ids = Array.from(new Set(ids));
  650. proxy
  651. .post("/fileInfo/getList", {
  652. businessIdList: ids,
  653. })
  654. .then((fileObj) => {
  655. formData.orderData.contractProductList.map((x) => {
  656. // if (fileObj[x.productId] && fileObj[x.productId].length > 0) {
  657. // x.fileUrl = fileObj[x.productId][0].fileUrl;
  658. // }
  659. x.contractProductBomList.map((y) => {
  660. y.fileList = fileObj[y.materialId] || [];
  661. if (y.fileList && y.fileList.length > 0) {
  662. y.fileUrl = y.fileList[0].fileUrl;
  663. }
  664. });
  665. });
  666. });
  667. };
  668. const activeName = ref("1");
  669. const lookDetails = (item) => {
  670. activeName.value = "1";
  671. proxy.post("/contract/detail", { id: item.contractId }).then(async (res) => {
  672. formData.orderData = res;
  673. dialogVisible.value = true;
  674. proxy
  675. .post("/produceOrder/materialBalanceList", { id: item.id })
  676. .then((sonRes) => {
  677. formData.orderData.materialList = sonRes;
  678. if (sonRes && sonRes.length > 0) {
  679. let ids = sonRes.map((x) => x.materialId);
  680. proxy.getFileData({
  681. businessIdList: ids,
  682. data: formData.orderData.materialList,
  683. att: "materialId",
  684. businessType: "0",
  685. fileAtt: "fileList",
  686. filePathAtt: "fileUrl",
  687. });
  688. }
  689. });
  690. if (
  691. formData.orderData.contractProductList &&
  692. formData.orderData.contractProductList.length > 0
  693. ) {
  694. getFileData();
  695. let ids = formData.orderData.contractProductList.map((x) => x.id);
  696. let productIds = formData.orderData.contractProductList.map(
  697. (x) => x.productId
  698. );
  699. const productAllFile = await proxy.getFileData({
  700. businessIdList: productIds,
  701. getAll: true,
  702. });
  703. for (let i = 0; i < formData.orderData.contractProductList.length; i++) {
  704. const ele = formData.orderData.contractProductList[i];
  705. for (const key in productAllFile) {
  706. if (
  707. ele.productId == key &&
  708. productAllFile[ele.productId] &&
  709. productAllFile[ele.productId].length > 0
  710. ) {
  711. ele.productFile = productAllFile[ele.productId].filter(
  712. (x) => x.businessType == "0"
  713. );
  714. if (ele.productFile && ele.productFile.length > 0) {
  715. ele.fileUrl = ele.productFile[0].fileUrl;
  716. }
  717. break;
  718. }
  719. }
  720. }
  721. proxy
  722. .getFileData({
  723. businessIdList: ids,
  724. getAll: true,
  725. })
  726. .then((fileObj) => {
  727. if (fileObj && Object.keys(fileObj).length > 0) {
  728. for (
  729. let i = 0;
  730. i < formData.orderData.contractProductList.length;
  731. i++
  732. ) {
  733. const ele = formData.orderData.contractProductList[i];
  734. for (const key in fileObj) {
  735. if (
  736. ele.id == key &&
  737. fileObj[ele.id] &&
  738. fileObj[ele.id].length > 0
  739. ) {
  740. let imageUrlList = fileObj[ele.id].filter(
  741. (x) => x.businessType == "0"
  742. );
  743. if (imageUrlList && imageUrlList.length > 0) {
  744. ele.imageUrl = imageUrlList[0].fileUrl;
  745. }
  746. ele.prodFileList = fileObj[ele.id]
  747. .filter((x) => x.businessType == "1")
  748. .map((x) => ({ ...x, name: x.fileName, url: x.fileUrl }));
  749. if (ele.prodFileList && ele.prodFileList.length > 0) {
  750. ele.isShowProductFile = false;
  751. } else {
  752. ele.isShowProductFile = true;
  753. if (productAllFile[ele.productId]) {
  754. ele.fileListOne = productAllFile[ele.productId].filter(
  755. (x) => x.businessType == "2"
  756. );
  757. }
  758. }
  759. }
  760. }
  761. }
  762. } else {
  763. for (
  764. let i = 0;
  765. i < formData.orderData.contractProductList.length;
  766. i++
  767. ) {
  768. const ele = formData.orderData.contractProductList[i];
  769. ele.isShowProductFile = true;
  770. for (const key in productAllFile) {
  771. if (
  772. ele.productId == key &&
  773. productAllFile[ele.productId] &&
  774. productAllFile[ele.productId].length > 0
  775. ) {
  776. ele.fileListOne = productAllFile[ele.productId].filter(
  777. (x) => x.businessType == "2"
  778. );
  779. break;
  780. }
  781. }
  782. }
  783. }
  784. });
  785. }
  786. });
  787. };
  788. </script>
  789. <style scoped lang="scss">
  790. .app-container {
  791. display: flex;
  792. width: 100vw;
  793. padding: 10px;
  794. font-size: 14px !important;
  795. // height: 100%;
  796. .announcement {
  797. padding: 0;
  798. margin: 0;
  799. li {
  800. list-style: none;
  801. border-radius: 2px;
  802. padding: 14px 20px;
  803. background: #eeeeee;
  804. margin-bottom: 10px;
  805. font-size: 14px;
  806. cursor: pointer;
  807. .time {
  808. color: #999;
  809. }
  810. .content {
  811. margin-top: 10px;
  812. color: #333;
  813. }
  814. }
  815. li:hover {
  816. background: #eff6ff;
  817. }
  818. }
  819. .table-warp {
  820. width: 400px;
  821. //页面全屏,占据剩下的位置
  822. height: calc(100vh - 120px);
  823. background: #fff;
  824. padding: 10px;
  825. // border-radius: 5px;
  826. .baosun {
  827. display: flex;
  828. justify-content: space-between;
  829. margin-top: 15px;
  830. .q {
  831. padding: 10px;
  832. min-width: 150px;
  833. display: flex;
  834. cursor: pointer;
  835. justify-content: space-between;
  836. border-radius: 10px;
  837. .num {
  838. font-size: 20px;
  839. font-weight: 700;
  840. }
  841. }
  842. .theme2 {
  843. background: linear-gradient(180deg, #eae8fb 0%, #ded9ff 100%);
  844. }
  845. //#FFF1E1 #FF9315
  846. .theme3 {
  847. background: #fff1e1;
  848. }
  849. }
  850. .card {
  851. height: calc(50% - 10px);
  852. background: #fff;
  853. float: left;
  854. border-radius: 5px;
  855. padding: 20px;
  856. overflow-y: auto;
  857. }
  858. .odd {
  859. width: calc(66.5% - 10px);
  860. }
  861. .even {
  862. margin-left: 10px;
  863. width: 33.5%;
  864. }
  865. // .card:nth-child(2n + 1) {
  866. // margin-right: 20px;
  867. // }
  868. .card:nth-child(1) {
  869. margin-bottom: 10px;
  870. }
  871. .card:nth-child(2) {
  872. margin-bottom: 10px;
  873. }
  874. }
  875. .stat-warp {
  876. width: calc(100% - 400px - 10px);
  877. height: calc(100vh - 120px);
  878. margin-right: 10px;
  879. // margin-bottom: 10px;
  880. background: #fff;
  881. padding: 10px;
  882. // padding: 20px;
  883. // overflow: hidden;
  884. // position: relative;
  885. // border-radius: 5px;
  886. .title {
  887. height: 60px;
  888. select {
  889. height: 60px;
  890. border: none;
  891. outline: none;
  892. -webkit-appearance: none;
  893. appearance: none;
  894. font-size: 14px;
  895. font-weight: bold;
  896. background: url("@/assets/images/sanjiao.png") no-repeat right center;
  897. padding-right: 20px;
  898. }
  899. div {
  900. height: 60px;
  901. font-size: 14px;
  902. font-weight: bold;
  903. line-height: 60px;
  904. }
  905. }
  906. ul {
  907. padding: 0;
  908. // overflow: hidden;
  909. margin: 0;
  910. display: flex;
  911. width: 100%;
  912. flex-wrap: nowrap;
  913. overflow: hidden;
  914. justify-content: space-between;
  915. li {
  916. flex: 1;
  917. list-style: none;
  918. min-width: 150px;
  919. box-sizing: border-box;
  920. margin-right: 20px;
  921. background: linear-gradient(360deg, #c7e3fe 0%, #dfecff 100%);
  922. // float: left;
  923. // overflow: hidden;
  924. padding: 10px;
  925. color: #333333;
  926. position: relative;
  927. border-radius: 10px;
  928. cursor: pointer;
  929. .label {
  930. font-size: 14px;
  931. margin-top: 10px;
  932. }
  933. .label::before {
  934. // width: 10px;
  935. // height: 10px;
  936. // content: '';
  937. // border-radius: 50%;
  938. // background: #0084ff;
  939. // display: inline-block;
  940. // margin-right: 10px;
  941. }
  942. .num {
  943. font-size: 24px;
  944. font-weight: bold;
  945. }
  946. .icon-box {
  947. position: absolute;
  948. height: 40px;
  949. width: 40px;
  950. right: 20px;
  951. top: 20px;
  952. background: #fff;
  953. border-radius: 10px;
  954. text-align: center;
  955. line-height: 40px;
  956. i {
  957. font-size: 20px;
  958. color: #0084ff;
  959. }
  960. }
  961. }
  962. //#F5F3FF #9E64ED
  963. .theme2 {
  964. background: linear-gradient(180deg, #eae8fb 0%, #ded9ff 100%);
  965. .label::before {
  966. background: #7566f0;
  967. }
  968. .icon-box i {
  969. color: #7566f0;
  970. }
  971. }
  972. //#FFF1E1 #FF9315
  973. .theme3 {
  974. background: #fff1e1;
  975. .label::before {
  976. background: #ff9315;
  977. }
  978. .icon-box i {
  979. color: #ff9315;
  980. }
  981. }
  982. //#E2FBE8 #39C55A
  983. .theme4 {
  984. background: #e2fbe8;
  985. .label::before {
  986. background: #39c55a;
  987. }
  988. }
  989. .theme5 {
  990. background: #ffebe9;
  991. .label::before {
  992. background: #f94539;
  993. }
  994. }
  995. .theme6 {
  996. background: #e4f9f9;
  997. .label::before {
  998. background: #53cbcb;
  999. }
  1000. }
  1001. .multi-data {
  1002. .label::before {
  1003. display: none;
  1004. }
  1005. .label {
  1006. font-size: 14px;
  1007. font-weight: bold;
  1008. color: #333;
  1009. margin-bottom: 8px;
  1010. }
  1011. .num-warp {
  1012. overflow: hidden;
  1013. .num-box {
  1014. float: left;
  1015. min-width: 80px;
  1016. margin-right: 20px;
  1017. .num-small {
  1018. font-size: 16px;
  1019. font-weight: bold;
  1020. margin-bottom: 8px;
  1021. }
  1022. .label-small {
  1023. color: #666;
  1024. font-size: 14px;
  1025. }
  1026. }
  1027. }
  1028. }
  1029. }
  1030. }
  1031. .table-card {
  1032. display: flex;
  1033. justify-content: space-between;
  1034. margin-top: 20px;
  1035. }
  1036. }
  1037. :deep(
  1038. .el-table .el-table__header-wrapper th,
  1039. .el-table .el-table__fixed-header-wrapper th
  1040. ) {
  1041. height: auto !important;
  1042. }
  1043. .svg-class {
  1044. font-size: 16px;
  1045. }
  1046. .svg-class1 {
  1047. font-size: 19px;
  1048. margin-top: 10px;
  1049. }
  1050. :deep(.el-table .cell) {
  1051. font-size: 12px !important;
  1052. line-height: 24px !important;
  1053. }
  1054. </style>