index.vue 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. <template>
  2. <div class="user">
  3. <div class="content">
  4. <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row
  5. :selectConfig="selectConfig" :action-list="[
  6. ]" @get-list="getList">
  7. <template #code="{ item }">
  8. <div style="width: 100%" class="el-click" @click="lookDetails(item)">
  9. {{item.code}}
  10. </div>
  11. </template>
  12. <template #isOverdue="{item}">
  13. <div style="width: 100%">
  14. <span class="red" v-if="item.isOverdue=='1'"> 逾期 </span>
  15. </div>
  16. </template>
  17. <template #prodTag="{ item }">
  18. <div style="width: 100%">
  19. <!-- <el-icon :size="16" style="cursor:pointer;margin-right: 5px;position:relative;top:5px" color="#409EFF" @click="handleEditTag(item)">
  20. <Edit />
  21. </el-icon> -->
  22. <!-- closable @close="prodTagClose(index, item)" -->
  23. <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.prodTags" :key="index">
  24. {{ dictKeyValue(tag, contractTag) }}
  25. </el-tag>
  26. </div>
  27. </template>
  28. <template #list="{ item }">
  29. <div style="width:100%">
  30. <span v-for="(product ,index) in item.produceOrderDetailList" style="margin-right:15px">
  31. <el-popover placement="top-start" :width="400" trigger="hover">
  32. <div>
  33. <div>产品编码:{{product.productCode}}</div>
  34. <div>产品名称:{{product.productName}}</div>
  35. <div>产品尺寸:{{product.productLength}}cm*{{product.productWidth}}cm*{{product.productHeight}}cm</div>
  36. <div>产品颜色:{{product.productColor}}</div>
  37. <div>产品数量:{{product.quantity}}</div>
  38. </div>
  39. <template #reference>
  40. <el-progress type="circle" :percentage="(Number(product.finishQuantity) / Number(product.quantity))*100" width="60"
  41. :status="(Number(product.finishQuantity) / Number(product.quantity))*100 == 100 ? 'success' : ''" />
  42. </template>
  43. </el-popover>
  44. </span>
  45. </div>
  46. </template>
  47. </byTable>
  48. </div>
  49. <div class="schedule-right">
  50. <div class="schedule-top">
  51. <el-row>
  52. <!-- <el-col :span="10" style="text-align: left">
  53. <el-select v-model="status" style="width: 110px">
  54. <el-option v-for="item in tableStatus" :key="item.value" :label="item.label" :value="item.value" />
  55. </el-select>
  56. <el-button type="info" style="margin-left: 8px" @click="clickToday()" plain>今日</el-button>
  57. </el-col> -->
  58. <el-col :span="24" style="text-align: center; height: 32px; line-height: 32px">
  59. <div style="display: flex; justify-content: space-between">
  60. <el-button @click="clickToday()" plain>今日</el-button>
  61. <el-button :icon="ArrowLeftBold" @click="prevMonth()" />
  62. <span style="font-weight: 700">{{ month }}</span>
  63. <el-button :icon="ArrowRightBold" @click="nextMonth()" />
  64. </div>
  65. </el-col>
  66. <!-- <el-col :span="10" style="text-align: right">
  67. <el-button type="primary" @click="newSchedule()">新建日程</el-button>
  68. </el-col> -->
  69. </el-row>
  70. </div>
  71. <div class="schedule-bottom">
  72. <el-calendar v-model="today" ref="calendar">
  73. <template #date-cell="{ data }">
  74. <div style="text-align:center;height: 100%;">
  75. <div>
  76. {{ data.day.substr(8, 10) }}
  77. </div>
  78. <el-popover placement="left" :width="400" style="height" trigger="hover" @show="onShow(data.day)">
  79. <template #reference>
  80. <div v-if="isShow(data.day)">
  81. <div style="height:5px;margin-bottom:5px;border-radius:2px" v-for="(item,index) in judgeDay(data.day)" :key="index"
  82. :style="{ background: colorData[item]}">
  83. </div>
  84. </div>
  85. </template>
  86. <div style="height:500px;overflow:auto">
  87. <div v-for="item in showData" :key="item" style="margin-bottom:20px">
  88. <div style="display:flex">
  89. <div>颜色:</div>
  90. <div :style="{ background: colorData[item]}" style="width:20px;height:20px;border-radius:10px"></div>
  91. </div>
  92. <div>
  93. 订单号:<span v-if="rightDataObj[item]">{{rightDataObj[item]['code']}}</span>
  94. </div>
  95. <div>
  96. 产品:<span v-if="rightDataObj[item]">{{rightDataObj[item]['productName']}}</span>
  97. </div>
  98. </div>
  99. </div>
  100. </el-popover>
  101. </div>
  102. </template>
  103. </el-calendar>
  104. </div>
  105. </div>
  106. <el-dialog :title="modalType == 'add' ? '添加店铺' : '编辑店铺'" v-model="dialogVisible" width="500px" destroy-on-close>
  107. <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom" v-loading="submitLoading">
  108. </byForm>
  109. <template #footer>
  110. <el-button @click="dialogVisible = false" size="defualt">取 消</el-button>
  111. <el-button type="primary" @click="submitForm()" size="defualt" :loading="submitLoading">
  112. 确 定
  113. </el-button>
  114. </template>
  115. </el-dialog>
  116. <el-dialog :title="'投产'" v-model="productionDialog" width="500px" destroy-on-close>
  117. <byForm :formConfig="productionFormConfig" :formOption="formOption" v-model="formData.data" :rules="productionRules" ref="productionFormDom"
  118. v-loading="formLoading">
  119. </byForm>
  120. <template #footer>
  121. <el-button @click="productionDialog =false" size="default" v-debounce>取 消</el-button>
  122. <el-button @click="submitProduction" type="primary" size="default" v-debounce>提 交</el-button>
  123. </template>
  124. </el-dialog>
  125. <el-dialog :title="'确认交期'" v-model="confirmDialog" width="500px" destroy-on-close>
  126. <byForm :formConfig="confirmFormConfig" :formOption="confirmFormOption" v-model="formData.dataOne" :rules="confirmRules" ref="confirmDom"
  127. v-loading="formLoading">
  128. </byForm>
  129. <template #footer>
  130. <el-button @click="confirmDialog =false" size="default" v-debounce>取 消</el-button>
  131. <el-button @click="submitConfirm(true)" type="danger" size="default" v-debounce>驳 回</el-button>
  132. <el-button @click="submitConfirm(false)" type="primary" size="default" v-debounce>提 交</el-button>
  133. </template>
  134. </el-dialog>
  135. <el-dialog :title="'订单详情'" v-model="dialogVisible" width="90%" destroy-on-close>
  136. <byForm :formConfig="formConfig" :formOption="formOptionOne" v-model="formData.orderData" ref="formDom">
  137. <template #commodity>
  138. <div style="width: 100%">
  139. <el-table :data="formData.orderData.contractProductList" style="width: 100%; ">
  140. <el-table-column type="expand" width="50" align="center">
  141. <template #default="scope">
  142. <div style="padding-left:50px">
  143. <div style="margin-bottom:10px;">
  144. <TitleInfo content='BOM单:'></TitleInfo>
  145. </div>
  146. <el-table :data="scope.row.contractProductBomList" style="width: 100%;" border class="bom-table">
  147. <el-table-column label="图片" width="80">
  148. <template #default="{ row }">
  149. <div v-if="row.fileUrl">
  150. <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
  151. </div>
  152. <div v-else></div>
  153. </template>
  154. </el-table-column>
  155. <el-table-column prop="productCode" label="物料编码" width="190" />
  156. <el-table-column prop="productName" label="物料名称" min-width="200" />
  157. <el-table-column label="尺寸 (cm)" width="150">
  158. <template #default="{ row, $index }">
  159. <div style="width: 100%">
  160. {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
  161. </div>
  162. </template>
  163. </el-table-column>
  164. <el-table-column prop="quantity" label="数量" width="110" />
  165. <el-table-column prop="remark" label="备注" width="180" />
  166. </el-table>
  167. </div>
  168. </template>
  169. </el-table-column>
  170. <el-table-column label="商品图片" width="80">
  171. <template #default="{ row }">
  172. <div v-if="row.fileUrl">
  173. <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
  174. </div>
  175. <div v-else></div>
  176. </template>
  177. </el-table-column>
  178. <el-table-column prop="productCnName" label="商品名称" min-width="130" />
  179. <el-table-column prop="productCode" label="商品编码" width="130" />
  180. <el-table-column label="尺寸 (cm)" width="150">
  181. <template #default="{ row, $index }">
  182. <div style="width: 100%">
  183. {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
  184. </div>
  185. </template>
  186. </el-table-column>
  187. <el-table-column prop="productColor" label="颜色" width="100" />
  188. <el-table-column label="设计图稿" width="80">
  189. <template #default="{ row, $index }">
  190. <div style="width: 100%">
  191. <el-upload :action="uploadUrl" accept=".gif, .jpeg, .jpg, .png" :show-file-list="false" :data="uploadData"
  192. :before-upload="(file)=>handleBeforeUpload(file,$index)" :on-success="()=>handleSuccess($index)">
  193. <div v-loading="row.imgLoading">
  194. <img v-if="row.imageUrl" :src="row.imageUrl" class="pic" />
  195. <!-- <el-icon v-else class="avatar-uploader-icon">
  196. <Plus />
  197. </el-icon> -->
  198. </div>
  199. </el-upload>
  200. </div>
  201. </template>
  202. </el-table-column>
  203. <el-table-column label="生产源文件" width="140">
  204. <template #default="{ row, $index }">
  205. <div style="width:100%">
  206. <div v-if="row.isShowProductFile &&row.fileListOne && row.fileListOne.length > 0">
  207. <span class="el-click" @click="onPicture(row.fileListOne[0].fileUrl)">{{row.fileListOne[0].fileName}}</span>
  208. </div>
  209. <div v-else>
  210. <div v-if="row.prodFileList && row.prodFileList.length > 0">
  211. <span class="el-click" @click="onPicture(row.prodFileList[0].fileUrl)">{{row.prodFileList[0].fileName}} (定制)</span>
  212. </div>
  213. </div>
  214. </div>
  215. </template>
  216. </el-table-column>
  217. <el-table-column label="数量" width="150" prop="quantity" />
  218. <el-table-column label="备注" min-width="200" prop="remark" />
  219. </el-table>
  220. </div>
  221. </template>
  222. </byForm>
  223. <template #footer>
  224. <el-button @click="dialogVisible = false" size="defualt">取 消</el-button>
  225. </template>
  226. </el-dialog>
  227. </div>
  228. </template>
  229. <script setup>
  230. import byTable from "@/components/byTable/index";
  231. import byForm from "@/components/byForm/index";
  232. import moment from "moment";
  233. import * as date from "@/utils/date.js";
  234. import { ArrowLeftBold, ArrowRightBold } from "@element-plus/icons-vue";
  235. const { proxy } = getCurrentInstance();
  236. const contractTag = computed(
  237. () => proxy.useUserStore().allDict["contract_prod_tag"]
  238. );
  239. const companyData = ref([]);
  240. const loading = ref(false);
  241. const submitLoading = ref(false);
  242. const sourceList = ref({
  243. data: [],
  244. pagination: {
  245. total: 3,
  246. pageNum: 1,
  247. pageSize: 10,
  248. keyword: "",
  249. produceStatus: "",
  250. staDeliveryPeriod: "",
  251. endDeliveryPeriod: "",
  252. beginTime: "",
  253. endTime: "",
  254. companyId: "",
  255. isOverdue: "",
  256. },
  257. });
  258. const treeData = ref([]);
  259. const dialogVisible = ref(false);
  260. const modalType = ref("add");
  261. const status = ref("0");
  262. const today = ref(moment().format("yyyy-MM-DD"));
  263. const dateList = ref({});
  264. const month = ref(moment().format("yyyy年MM月"));
  265. const monthOne = ref(moment().format("yyyy-MM"));
  266. const calendar = ref(null);
  267. const statusData = ref([
  268. {
  269. label: "未开始",
  270. value: "0",
  271. },
  272. {
  273. label: "进行中",
  274. value: "1",
  275. },
  276. {
  277. label: "已完成",
  278. value: "2",
  279. },
  280. ]);
  281. const isOverdueData = ref([
  282. {
  283. label: "是",
  284. value: "1",
  285. },
  286. {
  287. label: "否",
  288. value: "0",
  289. },
  290. ]);
  291. const selectConfig = computed(() => [
  292. // {
  293. // label: "生产公司",
  294. // prop: "companyId",
  295. // data: companyData.value,
  296. // fn: () => {
  297. // getRightData();
  298. // },
  299. // },
  300. {
  301. label: "生产状态",
  302. prop: "produceStatus",
  303. data: statusData.value,
  304. },
  305. {
  306. label: "是否逾期",
  307. prop: "isOverdue",
  308. data: isOverdueData.value,
  309. },
  310. {
  311. type: "time",
  312. label: "交期",
  313. placeholder: "开始日期",
  314. prop: "staDeliveryPeriod",
  315. placeholderOne: "结束日期",
  316. propOne: "endDeliveryPeriod",
  317. },
  318. {
  319. type: "time",
  320. label: "下单日期",
  321. placeholder: "开始日期",
  322. prop: "beginTime",
  323. placeholderOne: "结束日期",
  324. propOne: "endTime",
  325. },
  326. ]);
  327. const config = computed(() => {
  328. return [
  329. {
  330. attrs: {
  331. label: "生产公司",
  332. prop: "companyName",
  333. width: 130,
  334. },
  335. },
  336. {
  337. attrs: {
  338. label: "订单号",
  339. slot: "code",
  340. width: 150,
  341. },
  342. },
  343. {
  344. attrs: {
  345. label: "下单时间",
  346. prop: "createTime",
  347. width: 160,
  348. },
  349. },
  350. {
  351. attrs: {
  352. label: "生产状态",
  353. prop: "produceStatus",
  354. width: 120,
  355. },
  356. render(val) {
  357. return proxy.dictValueLabel(val, statusData.value);
  358. },
  359. },
  360. {
  361. attrs: {
  362. label: "交期",
  363. prop: "deliveryPeriod",
  364. width: 160,
  365. },
  366. },
  367. {
  368. attrs: {
  369. label: "投产时间",
  370. prop: "produceTime",
  371. width: 160,
  372. },
  373. },
  374. {
  375. attrs: {
  376. label: "完工时间",
  377. prop: "finishTime",
  378. width: 160,
  379. },
  380. },
  381. {
  382. attrs: {
  383. label: "是否逾期",
  384. slot: "isOverdue",
  385. width: 80,
  386. },
  387. },
  388. {
  389. attrs: {
  390. label: "生产指示",
  391. slot: "prodTag",
  392. "min-width": 220,
  393. },
  394. },
  395. {
  396. attrs: {
  397. slot: "list",
  398. label: "产品生产进度",
  399. // prop: "name",
  400. "min-width": 300,
  401. },
  402. },
  403. {
  404. attrs: {
  405. label: "操作",
  406. width: "100",
  407. align: "center",
  408. fixed: "right",
  409. },
  410. renderHTML(row) {
  411. return [
  412. row.produceTime || !proxy.isCurrentCompanyData(row.companyId)
  413. ? {}
  414. : {
  415. attrs: {
  416. label: "投产",
  417. type: "primary",
  418. text: true,
  419. },
  420. el: "button",
  421. click() {
  422. clickDistributeProduction(row);
  423. },
  424. },
  425. row.produceTime || !proxy.isCurrentCompanyData(row.companyId)
  426. ? {}
  427. : {
  428. attrs: {
  429. label: "确认交期",
  430. type: "primary",
  431. text: true,
  432. },
  433. el: "button",
  434. click() {
  435. confirmDeliveryTime(row);
  436. },
  437. },
  438. ];
  439. },
  440. },
  441. ];
  442. });
  443. const formData = reactive({
  444. data: {},
  445. orderData: {},
  446. dataOne: {},
  447. });
  448. const formOption = reactive({
  449. inline: true,
  450. labelWidth: 100,
  451. itemWidth: 100,
  452. });
  453. const formOptionOne = reactive({
  454. inline: true,
  455. labelWidth: 100,
  456. itemWidth: 100,
  457. disabled: true,
  458. });
  459. const formDom = ref(null);
  460. const formConfig = computed(() => {
  461. return [
  462. {
  463. type: "title1",
  464. title: "基本信息",
  465. },
  466. {
  467. type: "text",
  468. prop: "code",
  469. label: "合同号:",
  470. disabled: true,
  471. isShow: formData.orderData.code ? true : false,
  472. },
  473. {
  474. type: "title1",
  475. title: "商品信息",
  476. haveLine: true,
  477. },
  478. {
  479. type: "slot",
  480. slotName: "commodity",
  481. label: "",
  482. },
  483. ];
  484. });
  485. const rules = ref({
  486. deptId: [{ required: true, message: "请选择负责部门", trigger: "change" }],
  487. name: [{ required: true, message: "请输入店铺名称", trigger: "blur" }],
  488. code: [{ required: true, message: "请输入店铺编号", trigger: "blur" }],
  489. });
  490. const getList = async (req) => {
  491. sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
  492. loading.value = true;
  493. proxy.post("/produceOrder/page", sourceList.value.pagination).then((res) => {
  494. res.rows.forEach((x) => {
  495. if (x.prodTag) {
  496. x.prodTags = x.prodTag.split(",");
  497. } else {
  498. x.prodTags = [];
  499. }
  500. });
  501. sourceList.value.data = res.rows;
  502. sourceList.value.pagination.total = res.total;
  503. setTimeout(() => {
  504. loading.value = false;
  505. }, 200);
  506. });
  507. };
  508. const openModal = () => {
  509. dialogVisible.value = true;
  510. modalType.value = "add";
  511. formData.data = {
  512. definition: "2",
  513. fileList: [],
  514. };
  515. if (currencyData.value && currencyData.value.length > 0) {
  516. formData.data.currency = currencyData.value[0].dictKey;
  517. formData.data.costCurrency = currencyData.value[0].dictKey;
  518. }
  519. };
  520. const submitForm = () => {
  521. formDom.value.handleSubmit((valid) => {
  522. submitLoading.value = true;
  523. proxy.post("/shopInfo/" + modalType.value, formData.data).then(
  524. (res) => {
  525. proxy.msgTip("操作成功", 1);
  526. dialogVisible.value = false;
  527. submitLoading.value = false;
  528. getList();
  529. },
  530. (err) => {
  531. submitLoading.value = false;
  532. }
  533. );
  534. });
  535. };
  536. const getDtl = (row) => {
  537. modalType.value = "edit";
  538. proxy.post("/shopInfo/detail", { id: row.id }).then((res) => {
  539. formData.data = res;
  540. dialogVisible.value = true;
  541. });
  542. };
  543. getList();
  544. const productionFormDom = ref(null);
  545. const productionDialog = ref(false);
  546. const formLoading = ref(false);
  547. const productionFormConfig = computed(() => [
  548. {
  549. type: "date",
  550. itemType: "datetime",
  551. label: "投产时间",
  552. prop: "produceTime",
  553. // placeholder: "合同开始时间",
  554. itemWidth: 100,
  555. clearable: true,
  556. disabledFn: (date) => {
  557. return moment(date).isBefore(moment());
  558. },
  559. },
  560. ]);
  561. const productionRules = ref({
  562. produceTime: [
  563. { required: true, message: "请选择投产时间", trigger: "change" },
  564. ],
  565. });
  566. const clickDistributeProduction = (row) => {
  567. formData.data = {
  568. id: row.id,
  569. produceTime: moment().format("yyyy-MM-DD HH:mm:ss"),
  570. };
  571. productionDialog.value = true;
  572. // proxy
  573. // .msgConfirm()
  574. // .then((res) => {
  575. // proxy.post("/produceOrder/putProduction", formData.data).then((res) => {
  576. // proxy.msgTip("操作成功");
  577. // formLoading.value = false;
  578. // productionDialog.value = false;
  579. // getList();
  580. // getRightData();
  581. // });
  582. // })
  583. // .catch((err) => {});
  584. };
  585. const submitProduction = () => {
  586. productionFormDom.value.handleSubmit(() => {
  587. formLoading.value = true;
  588. proxy.post("/produceOrder/putProduction", formData.data).then((res) => {
  589. proxy.msgTip("操作成功");
  590. formLoading.value = false;
  591. productionDialog.value = false;
  592. getList();
  593. getRightData();
  594. });
  595. });
  596. };
  597. const rightData = ref([]);
  598. const rightDataObj = ref({});
  599. const colorData = ref({});
  600. let colorList = [
  601. "#BBFF00",
  602. "#FFFF00",
  603. "#FFBB00",
  604. "#FF3333",
  605. "#D28EFF",
  606. "#CCEEFF",
  607. "#FFC8B4",
  608. "#CCDDFF",
  609. "#007799",
  610. "#550088",
  611. "#AAFFEE",
  612. "#FFB3FF",
  613. "#FFFF33",
  614. ];
  615. const getRightData = () => {
  616. proxy
  617. .post("/produceOrder/schedulingList", {
  618. beginDate: monthOne.value,
  619. companyId: sourceList.value.pagination.companyId,
  620. })
  621. .then(
  622. (res) => {
  623. rightDataObj.value = {};
  624. rightData.value = res.map((x, index) => ({
  625. ...x,
  626. produceTimeOne: x.produceTime,
  627. produceTime: x.produceTime.substr(0, 10),
  628. deliveryPeriod: x.deliveryPeriod.substr(0, 10),
  629. }));
  630. for (let i = 0; i < res.length; i++) {
  631. const ele = res[i];
  632. rightDataObj.value[ele.id] = ele;
  633. if (i <= 12) {
  634. colorData.value[ele.id] = colorList[i];
  635. } else {
  636. let index = Math.floor(i % 12);
  637. colorData.value[ele.id] = colorList[index];
  638. }
  639. }
  640. },
  641. (err) => {
  642. loading.value = false;
  643. }
  644. );
  645. };
  646. getRightData();
  647. const getBackGround = (id) => {
  648. return { background: colorData.value[id] };
  649. };
  650. const prodTagClose = (index, row) => {
  651. row.prodTags.splice(index, 1);
  652. proxy
  653. .post("/contract/updateProductionTag", {
  654. id: row.contractId,
  655. prodTag: row.prodTags.join(","),
  656. })
  657. .then((res) => {
  658. getList();
  659. });
  660. };
  661. const getDict = () => {
  662. proxy
  663. .get("/tenantDept/list", {
  664. pageNum: 1,
  665. pageSize: 9999,
  666. keyword: "",
  667. tenantId: proxy.useUserStore().user.tenantId,
  668. type: 0,
  669. })
  670. .then((res) => {
  671. companyData.value = res.data.map((x) => ({
  672. ...x,
  673. label: x.deptName,
  674. value: x.deptId,
  675. }));
  676. // treeData.value = proxy.handleTree(res.data, "deptId");
  677. });
  678. };
  679. getDict();
  680. const clickToday = () => {
  681. today.value = moment().format("yyyy-MM-DD");
  682. month.value = moment().format("yyyy年MM月");
  683. monthOne.value = moment().format("yyyy-MM");
  684. getRightData();
  685. };
  686. const isShow = (day) => {
  687. let nowDay = new Date(day + " 23:59:59").getTime();
  688. let flag = false;
  689. for (let i = 0; i < rightData.value.length; i++) {
  690. const e = rightData.value[i];
  691. let startDay = new Date(e.produceTime).getTime();
  692. let endDay = new Date(e.deliveryPeriod + " 23:59:59").getTime();
  693. if (nowDay >= startDay && nowDay <= endDay) {
  694. flag = true;
  695. break;
  696. }
  697. }
  698. return flag;
  699. };
  700. const judgeDay = (day) => {
  701. // return dateList.value[day] && dateList.value[day].length > 0;
  702. let nowDay = new Date(day + " 23:59:59").getTime();
  703. let rows = [];
  704. for (let i = 0; i < rightData.value.length; i++) {
  705. const e = rightData.value[i];
  706. let startDay = new Date(e.produceTime).getTime();
  707. let endDay = new Date(e.deliveryPeriod + " 23:59:59").getTime();
  708. if (nowDay >= startDay && nowDay <= endDay) {
  709. rows.push(e.id);
  710. }
  711. }
  712. return rows;
  713. };
  714. const showData = ref([]);
  715. const onShow = (day) => {
  716. let rows = judgeDay(day);
  717. showData.value = rows;
  718. };
  719. const getData = (id, att) => {
  720. const current = rightData.value.find((x) => x.id == id);
  721. if (current && current[att]) {
  722. return current[att];
  723. }
  724. };
  725. const selectDate = (val) => {
  726. calendar.value.selectDate(val);
  727. };
  728. const prevMonth = () => {
  729. month.value = moment(
  730. moment(month.value, "yyyy年MM月").add(-1, "month").calendar()
  731. ).format("yyyy年MM月");
  732. monthOne.value = moment(moment(month.value, "yyyy年MM月")).format("yyyy-MM");
  733. selectDate("prev-month");
  734. getRightData();
  735. };
  736. const nextMonth = () => {
  737. month.value = moment(
  738. moment(month.value, "yyyy年MM月").add(+1, "month").calendar()
  739. ).format("yyyy年MM月");
  740. monthOne.value = moment(moment(month.value, "yyyy年MM月")).format("yyyy-MM");
  741. selectDate("next-month");
  742. getRightData();
  743. };
  744. watch(
  745. () => today.value,
  746. (newValue) => {
  747. if (month.value !== moment(newValue).format("yyyy年MM月")) {
  748. month.value = moment(newValue).format("yyyy年MM月");
  749. monthOne.value = moment(moment(month.value, "yyyy年MM月")).format(
  750. "yyyy-MM"
  751. );
  752. getRightData();
  753. }
  754. }
  755. );
  756. const getFileData = () => {
  757. let ids = [];
  758. formData.orderData.contractProductList.map((x) => {
  759. // ids.push(x.productId);
  760. x.contractProductBomList.map((y) => {
  761. ids.push(y.materialId);
  762. });
  763. });
  764. ids = Array.from(new Set(ids));
  765. proxy
  766. .post("/fileInfo/getList", {
  767. businessIdList: ids,
  768. })
  769. .then((fileObj) => {
  770. formData.orderData.contractProductList.map((x) => {
  771. // if (fileObj[x.productId] && fileObj[x.productId].length > 0) {
  772. // x.fileUrl = fileObj[x.productId][0].fileUrl;
  773. // }
  774. x.contractProductBomList.map((y) => {
  775. y.fileList = fileObj[y.materialId] || [];
  776. if (y.fileList && y.fileList.length > 0) {
  777. y.fileUrl = y.fileList[0].fileUrl;
  778. }
  779. });
  780. });
  781. });
  782. };
  783. const lookDetails = (item) => {
  784. proxy.post("/contract/detail", { id: item.contractId }).then((res) => {
  785. formData.orderData = res;
  786. dialogVisible.value = true;
  787. if (
  788. formData.orderData.contractProductList &&
  789. formData.orderData.contractProductList.length > 0
  790. ) {
  791. getFileData();
  792. let ids = formData.orderData.contractProductList.map((x) => x.id);
  793. let productIds = formData.orderData.contractProductList.map(
  794. (x) => x.productId
  795. );
  796. proxy.getFileData({
  797. businessIdList: productIds,
  798. data: formData.orderData.contractProductList,
  799. att: "productId",
  800. businessType: "0",
  801. fileAtt: "productFile",
  802. filePathAtt: "fileUrl",
  803. });
  804. proxy
  805. .getFileData({
  806. businessIdList: ids,
  807. getAll: true,
  808. })
  809. .then((fileObj) => {
  810. for (
  811. let i = 0;
  812. i < formData.orderData.contractProductList.length;
  813. i++
  814. ) {
  815. const ele = formData.orderData.contractProductList[i];
  816. for (const key in fileObj) {
  817. if (
  818. ele.id == key &&
  819. fileObj[ele.id] &&
  820. fileObj[ele.id].length > 0
  821. ) {
  822. ele.fileListOne = fileObj[ele.id].filter(
  823. (x) => x.businessType == "0"
  824. );
  825. if (ele.fileListOne && ele.fileListOne.length > 0) {
  826. ele.imageUrl = ele.fileListOne[0].fileUrl;
  827. }
  828. ele.prodFileList = fileObj[ele.id]
  829. .filter((x) => x.businessType == "1")
  830. .map((x) => ({ ...x, name: x.fileName, url: x.fileUrl }));
  831. if (ele.prodFileList && ele.prodFileList.length > 0) {
  832. ele.isShowProductFile = false;
  833. } else {
  834. ele.isShowProductFile = true;
  835. }
  836. }
  837. }
  838. }
  839. });
  840. }
  841. });
  842. };
  843. const handleClickUpload = async (att, flag, index) => {
  844. let res = null;
  845. let path = "";
  846. if (flag) {
  847. proxy.msgTip("请稍后", 2);
  848. res = await proxy.post("/fileService/createTempFolder");
  849. if (res && res.path) {
  850. formData.data.contractProductList[index][att] = res.path;
  851. path = res.path;
  852. }
  853. } else {
  854. path = formData.data.contractProductList[index][att];
  855. }
  856. let a = document.createElement("a");
  857. a.href = "printer://" + "ftp://121.37.194.75/" + path + "/";
  858. a.style.display = "none";
  859. document.body.appendChild(a);
  860. a.click();
  861. document.body.removeChild(a);
  862. };
  863. const onPicture = (path) => {
  864. window.open(path, "_blank");
  865. };
  866. const confirmFormDom = ref(null);
  867. const confirmDialog = ref(false);
  868. const confirmFormOption = reactive({
  869. inline: true,
  870. labelWidth: 100,
  871. itemWidth: 100,
  872. disabled: false,
  873. });
  874. const confirmFormConfig = computed(() => [
  875. {
  876. type: "input",
  877. itemType: "textarea",
  878. label: "退回原因",
  879. prop: "aa",
  880. // placeholder: "合同开始时间",
  881. itemWidth: 100,
  882. // clearable: true,
  883. // disabledFn: (date) => {
  884. // return moment(date).isBefore(moment());
  885. // },
  886. },
  887. ]);
  888. const confirmRules = ref({});
  889. const confirmDeliveryTime = (row) => {
  890. formData.dataOne = {
  891. id: row.id,
  892. aa: "",
  893. };
  894. confirmDialog.value = true;
  895. };
  896. const submitConfirm = () => {
  897. confirmFormDom.value.handleSubmit(() => {
  898. if (!formData.dataOne.aa) {
  899. return proxy.msgTip("请填写退回原因", 2);
  900. }
  901. formLoading.value = true;
  902. proxy.post("/produceOrder/putProduction", formData.data).then((res) => {
  903. proxy.msgTip("操作成功");
  904. formLoading.value = false;
  905. confirmDialog.value = false;
  906. getList();
  907. getRightData();
  908. });
  909. });
  910. };
  911. </script>
  912. <style lang="scss" scoped>
  913. ::v-deep(.el-progress__text) {
  914. font-size: 14px !important;
  915. }
  916. .user {
  917. padding: 10px;
  918. display: flex;
  919. justify-content: space-between;
  920. .schedule-right {
  921. width: 400px;
  922. .schedule-top {
  923. width: 100%;
  924. background: #fff;
  925. padding: 20px;
  926. }
  927. .schedule-bottom {
  928. width: 100%;
  929. background: #fff;
  930. height: calc(100vh - 100px - 20px - 83px);
  931. padding: 20px;
  932. margin-top: 10px;
  933. overflow-y: auto;
  934. &::-webkit-scrollbar {
  935. width: 0px;
  936. }
  937. .line-class {
  938. height: 18px;
  939. line-height: 18px;
  940. overflow: hidden;
  941. white-space: nowrap;
  942. text-overflow: ellipsis;
  943. -o-text-overflow: ellipsis;
  944. margin: 1px 0;
  945. }
  946. }
  947. }
  948. .content {
  949. width: calc(100% - 410px);
  950. }
  951. }
  952. ::v-deep(.el-calendar__header) {
  953. display: none;
  954. }
  955. ::v-deep(.el-calendar__body) {
  956. padding: 0;
  957. }
  958. ::v-deep(.el-calendar-table .el-calendar-day) {
  959. // padding: 0;
  960. min-height: 50px;
  961. height: calc((100vh - 100px - 20px - 83px - 95px) / 5);
  962. overflow-y: hidden;
  963. }
  964. .el-icon.avatar-uploader-icon {
  965. font-size: 20px;
  966. color: #8c939d;
  967. width: 50px;
  968. height: 50px;
  969. text-align: center;
  970. border: 1px dashed var(--el-border-color);
  971. }
  972. .red {
  973. background: red;
  974. border-radius: 2px;
  975. padding: 4px;
  976. color: #fff;
  977. }
  978. </style>