123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802 |
- <template>
- <div class="user">
- <div class="content">
- <byTable :source="sourceList.data" :pagination="sourceList.pagination" :config="config" :loading="loading" highlight-current-row
- :selectConfig="selectConfig" :action-list="[
-
- ]" @get-list="getList">
- <template #code="{ item }">
- <div style="width: 100%" class="el-click" @click="lookDetails(item)">
- {{item.code}}
- </div>
- </template>
- <template #prodTag="{ item }">
- <div style="width: 100%">
- <!-- <el-icon :size="16" style="cursor:pointer;margin-right: 5px;position:relative;top:5px" color="#409EFF" @click="handleEditTag(item)">
- <Edit />
- </el-icon> -->
- <!-- closable @close="prodTagClose(index, item)" -->
- <el-tag style="margin-right: 8px" type="success" v-for="(tag, index) in item.prodTags" :key="index">
- {{ dictKeyValue(tag, contractTag) }}
- </el-tag>
- </div>
- </template>
- <template #list="{ item }">
- <div style="width:100%">
- <span v-for="(product ,index) in item.produceOrderDetailList" style="margin-right:15px">
- <el-popover placement="top-start" :width="400" trigger="hover">
- <div>
- <div>产品编码:{{product.productCode}}</div>
- <div>产品名称:{{product.productName}}</div>
- <div>产品尺寸:{{product.productLength}}cm*{{product.productWidth}}cm*{{product.productHeight}}cm</div>
- <div>产品数量:{{product.quantity}}</div>
- </div>
- <template #reference>
- <el-progress type="circle" :percentage="(Number(product.finishQuantity) / Number(product.quantity))*100" width="60"
- :status="(Number(product.finishQuantity) / Number(product.quantity))*100 == 100 ? 'success' : ''" />
- </template>
- </el-popover>
- </span>
- </div>
- </template>
- </byTable>
- </div>
- <div class="schedule-right">
- <div class="schedule-top">
- <el-row>
- <!-- <el-col :span="10" style="text-align: left">
- <el-select v-model="status" style="width: 110px">
- <el-option v-for="item in tableStatus" :key="item.value" :label="item.label" :value="item.value" />
- </el-select>
- <el-button type="info" style="margin-left: 8px" @click="clickToday()" plain>今日</el-button>
- </el-col> -->
- <el-col :span="24" style="text-align: center; height: 32px; line-height: 32px">
- <div style="display: flex; justify-content: space-between">
- <el-button @click="clickToday()" plain>今日</el-button>
- <el-button :icon="ArrowLeftBold" @click="prevMonth()" />
- <span style="font-weight: 700">{{ month }}</span>
- <el-button :icon="ArrowRightBold" @click="nextMonth()" />
- </div>
- </el-col>
- <!-- <el-col :span="10" style="text-align: right">
- <el-button type="primary" @click="newSchedule()">新建日程</el-button>
- </el-col> -->
- </el-row>
- </div>
- <div class="schedule-bottom">
- <el-calendar v-model="today" ref="calendar">
- <template #date-cell="{ data }">
- <div style="text-align:center;height: 100%;">
- <div>
- {{ data.day.substr(8, 10) }}
- </div>
- <el-popover placement="left" :width="400" trigger="hover" @show="onShow(data.day)">
- <template #reference>
- <div v-if="isShow(data.day)" style="height: calc(100% - 20px);">
- <div style="height:5px;margin-bottom:5px;border-radius:2px" v-for="(item,index) in judgeDay(data.day)" :key="index"
- :style="{ background: colorData[item]}">
- </div>
- </div>
- </template>
- <div>
- <div v-for="item in showData" :key="item" style="margin-bottom:20px">
- <div style="display:flex">
- <div>颜色:</div>
- <div :style="{ background: colorData[item]}" style="width:20px;height:20px;border-radius:10px"></div>
- </div>
- <div>
- 订单号:<span v-if="rightDataObj[item]">{{rightDataObj[item]['code']}}</span>
- </div>
- <div>
- 产品:<span v-if="rightDataObj[item]">{{rightDataObj[item]['productName']}}</span>
- </div>
- </div>
- </div>
- </el-popover>
- </div>
- </template>
- </el-calendar>
- </div>
- </div>
- <el-dialog :title="modalType == 'add' ? '添加店铺' : '编辑店铺'" v-model="dialogVisible" width="500px" destroy-on-close>
- <byForm :formConfig="formConfig" :formOption="formOption" v-model="formData.data" :rules="rules" ref="formDom" v-loading="submitLoading">
- </byForm>
- <template #footer>
- <el-button @click="dialogVisible = false" size="defualt">取 消</el-button>
- <el-button type="primary" @click="submitForm()" size="defualt" :loading="submitLoading">
- 确 定
- </el-button>
- </template>
- </el-dialog>
- <el-dialog :title="'投产'" v-model="productionDialog" width="500px" destroy-on-close>
- <byForm :formConfig="productionFormConfig" :formOption="formOption" v-model="formData.data" :rules="productionRules" ref="productionFormDom"
- v-loading="formLoading">
- </byForm>
- <template #footer>
- <el-button @click="productionDialog =false" size="default" v-debounce>取 消</el-button>
- <el-button @click="submitProduction" type="primary" size="default" v-debounce>提 交</el-button>
- </template>
- </el-dialog>
- <el-dialog :title="'订单详情'" v-model="dialogVisible" width="90%" destroy-on-close>
- <byForm :formConfig="formConfig" :formOption="formOptionOne" v-model="formData.orderData" ref="formDom">
- <template #commodity>
- <div style="width: 100%">
- <el-table :data="formData.orderData.contractProductList" style="width: 100%; ">
- <el-table-column type="expand" width="50" align="center">
- <template #default="scope">
- <div style="padding-left:50px">
- <div style="margin-bottom:10px;">
- <TitleInfo content='BOM单:'></TitleInfo>
- </div>
- <el-table :data="scope.row.contractProductBomList" style="width: 100%;" border class="bom-table">
- <el-table-column label="图片" width="80">
- <template #default="{ row }">
- <div v-if="row.fileUrl">
- <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
- </div>
- <div v-else></div>
- </template>
- </el-table-column>
- <el-table-column prop="productCode" label="物料编码" width="190" />
- <el-table-column prop="productName" label="物料名称" min-width="200" />
- <el-table-column label="尺寸 (cm)" width="150">
- <template #default="{ row, $index }">
- <div style="width: 100%">
- {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
- </div>
- </template>
- </el-table-column>
- <el-table-column prop="quantity" label="数量" width="110" />
- <el-table-column prop="remark" label="备注" width="180" />
- </el-table>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="商品图片" width="80">
- <template #default="{ row }">
- <div v-if="row.fileUrl">
- <img :src="row.fileUrl" class="pic" @click="onPicture(row.fileUrl)" />
- </div>
- <div v-else></div>
- </template>
- </el-table-column>
- <el-table-column prop="productCnName" label="商品名称" min-width="130" />
- <el-table-column prop="productCode" label="商品编码" width="130" />
- <el-table-column label="尺寸 cm*cm*cm" width="180">
- <template #default="{ row, $index }">
- <div style="width: 100%">
- {{row.productLength}} * {{row.productWidth}} * {{row.productHeight}}
- </div>
- </template>
- </el-table-column>
- <el-table-column label="设计图稿" width="80">
- <template #default="{ row, $index }">
- <div style="width: 100%">
- <el-upload action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" accept=".gif, .jpeg, .jpg, .png" :show-file-list="false"
- :data="uploadData" :before-upload="(file)=>handleBeforeUpload(file,$index)" :on-success="()=>handleSuccess($index)">
- <div v-loading="row.imgLoading">
- <img v-if="row.imageUrl" :src="row.imageUrl" class="pic" />
- <!-- <el-icon v-else class="avatar-uploader-icon">
- <Plus />
- </el-icon> -->
- </div>
- </el-upload>
- </div>
- </template>
- </el-table-column>
- <el-table-column label="生产源文件" width="140">
- <template #default="{ row, $index }">
- <span class="el-click" v-if="row.prodFilePath" @click="handleClickUpload('prodFilePath',false,$index)">点击上传 (查看)</span>
- </template>
- </el-table-column>
- <el-table-column label="数量" width="150" prop="quantity" />
- <el-table-column label="备注" min-width="200" prop="remark" />
- </el-table>
- </div>
- </template>
- </byForm>
- <template #footer>
- <el-button @click="dialogVisible = false" size="defualt">取 消</el-button>
- </template>
- </el-dialog>
- </div>
- </template>
- <script setup>
- import byTable from "@/components/byTable/index";
- import byForm from "@/components/byForm/index";
- import moment from "moment";
- import * as date from "@/utils/date.js";
- import { ArrowLeftBold, ArrowRightBold } from "@element-plus/icons-vue";
- const { proxy } = getCurrentInstance();
- const contractTag = computed(
- () => proxy.useUserStore().allDict["contract_prod_tag"]
- );
- const loading = ref(false);
- const submitLoading = ref(false);
- const sourceList = ref({
- data: [],
- pagination: {
- total: 3,
- pageNum: 1,
- pageSize: 10,
- keyword: "",
- produceStatus: "",
- staDeliveryPeriod: "",
- endDeliveryPeriod: "",
- beginTime: "",
- endTime: "",
- },
- });
- const treeData = ref([]);
- const dialogVisible = ref(false);
- const modalType = ref("add");
- const status = ref("0");
- const today = ref(moment().format("yyyy-MM-DD"));
- const dateList = ref({});
- const month = ref(moment().format("yyyy年MM月"));
- const monthOne = ref(moment().format("yyyy-MM"));
- const calendar = ref(null);
- const statusData = ref([
- {
- label: "未开始",
- value: "0",
- },
- {
- label: "进行中",
- value: "1",
- },
- {
- label: "已完成",
- value: "2",
- },
- ]);
- const selectConfig = computed(() => [
- {
- label: "生产状态",
- prop: "produceStatus",
- data: statusData.value,
- },
- {
- type: "time",
- label: "交期",
- placeholder: "开始日期",
- prop: "staDeliveryPeriod",
- placeholderOne: "结束日期",
- propOne: "endDeliveryPeriod",
- },
- {
- type: "time",
- label: "下单日期",
- placeholder: "开始日期",
- prop: "beginTime",
- placeholderOne: "结束日期",
- propOne: "endTime",
- },
- ]);
- const config = computed(() => {
- return [
- {
- attrs: {
- label: "订单号",
- slot: "code",
- width: 150,
- },
- },
- {
- attrs: {
- label: "下单时间",
- prop: "createTime",
- width: 160,
- },
- },
- {
- attrs: {
- label: "交期",
- prop: "deliveryPeriod",
- width: 160,
- },
- },
- {
- attrs: {
- label: "投产时间",
- prop: "produceTime",
- width: 160,
- },
- },
- {
- attrs: {
- label: "生产状态",
- prop: "produceStatus",
- width: 120,
- },
- render(val) {
- return proxy.dictValueLabel(val, statusData.value);
- },
- },
- {
- attrs: {
- label: "生产指示",
- slot: "prodTag",
- "min-width": 220,
- },
- },
- {
- attrs: {
- slot: "list",
- label: "产品生产进度",
- // prop: "name",
- "min-width": 300,
- },
- },
- {
- attrs: {
- label: "操作",
- width: "100",
- align: "center",
- fixed: "right",
- },
- renderHTML(row) {
- return [
- row.produceTime
- ? {}
- : {
- attrs: {
- label: "投产",
- type: "primary",
- text: true,
- },
- el: "button",
- click() {
- // proxy
- // .msgConfirm()
- // .then((res) => {
- // proxy
- // .post("/produceOrder/putProduction", {
- // id: row.id,
- // })
- // .then((res) => {
- // proxy.msgTip("操作成功", 1);
- // getList();
- // });
- // })
- // .catch((err) => {});
- clickDistributeProduction(row);
- },
- },
- ];
- },
- },
- ];
- });
- const formData = reactive({
- data: {},
- orderData: {},
- });
- const formOption = reactive({
- inline: true,
- labelWidth: 100,
- itemWidth: 100,
- });
- const formOptionOne = reactive({
- inline: true,
- labelWidth: 100,
- itemWidth: 100,
- disabled: true,
- });
- const formDom = ref(null);
- const formConfig = computed(() => {
- return [
- {
- type: "title1",
- title: "基本信息",
- },
- {
- type: "text",
- prop: "code",
- label: "合同号:",
- disabled: true,
- isShow: formData.orderData.code ? true : false,
- },
- {
- type: "title1",
- title: "商品信息",
- haveLine: true,
- },
- {
- type: "slot",
- slotName: "commodity",
- label: "",
- },
- ];
- });
- const rules = ref({
- deptId: [{ required: true, message: "请选择负责部门", trigger: "change" }],
- name: [{ required: true, message: "请输入店铺名称", trigger: "blur" }],
- code: [{ required: true, message: "请输入店铺编号", trigger: "blur" }],
- });
- const getList = async (req) => {
- sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
- loading.value = true;
- proxy.post("/produceOrder/page", sourceList.value.pagination).then((res) => {
- res.rows.forEach((x) => {
- if (x.prodTag) {
- x.prodTags = x.prodTag.split(",");
- } else {
- x.prodTags = [];
- }
- });
- sourceList.value.data = res.rows;
- sourceList.value.pagination.total = res.total;
- setTimeout(() => {
- loading.value = false;
- }, 200);
- });
- };
- const openModal = () => {
- dialogVisible.value = true;
- modalType.value = "add";
- formData.data = {
- definition: "2",
- fileList: [],
- };
- if (currencyData.value && currencyData.value.length > 0) {
- formData.data.currency = currencyData.value[0].dictKey;
- formData.data.costCurrency = currencyData.value[0].dictKey;
- }
- };
- const submitForm = () => {
- formDom.value.handleSubmit((valid) => {
- submitLoading.value = true;
- proxy.post("/shopInfo/" + modalType.value, formData.data).then(
- (res) => {
- proxy.msgTip("操作成功", 1);
- dialogVisible.value = false;
- submitLoading.value = false;
- getList();
- },
- (err) => {
- submitLoading.value = false;
- }
- );
- });
- };
- const getDtl = (row) => {
- modalType.value = "edit";
- proxy.post("/shopInfo/detail", { id: row.id }).then((res) => {
- formData.data = res;
- dialogVisible.value = true;
- });
- };
- getList();
- const productionFormDom = ref(null);
- const productionDialog = ref(false);
- const formLoading = ref(false);
- const productionFormConfig = computed(() => [
- {
- type: "date",
- itemType: "datetime",
- label: "投产时间",
- prop: "produceTime",
- // placeholder: "合同开始时间",
- itemWidth: 100,
- clearable: true,
- },
- ]);
- const productionRules = ref({
- produceTime: [
- { required: true, message: "请选择投产时间", trigger: "change" },
- ],
- });
- const clickDistributeProduction = (row) => {
- formData.data = {
- id: row.id,
- produceTime: moment().format("yyyy-MM-DD HH:mm:ss"),
- };
- productionDialog.value = true;
- };
- const submitProduction = () => {
- productionFormDom.value.handleSubmit(() => {
- formLoading.value = true;
- proxy.post("/produceOrder/putProduction", formData.data).then((res) => {
- proxy.msgTip("操作成功");
- formLoading.value = false;
- productionDialog.value = false;
- getList();
- getRightData();
- });
- });
- };
- const rightData = ref([]);
- const rightDataObj = ref({});
- const colorData = ref({});
- let colorList = [
- "#BBFF00",
- "#FFFF00",
- "#FFBB00",
- "#FF3333",
- "#D28EFF",
- "#CCEEFF",
- "#FFC8B4",
- "#CCDDFF",
- "#007799",
- "#550088",
- "#AAFFEE",
- "#FFB3FF",
- "#FFFF33",
- ];
- const getRightData = () => {
- proxy
- .post("/produceOrder/schedulingList", { beginDate: monthOne.value })
- .then(
- (res) => {
- rightDataObj.value = {};
- rightData.value = res.map((x, index) => ({
- ...x,
- produceTimeOne: x.produceTime,
- produceTime: x.produceTime.substr(0, 10),
- deliveryPeriod: x.deliveryPeriod.substr(0, 10),
- }));
- for (let i = 0; i < res.length; i++) {
- const ele = res[i];
- rightDataObj.value[ele.id] = ele;
- if (i <= 19) {
- colorData.value[ele.id] = colorList[i];
- } else {
- colorData.value[ele.id] = colorList[19 - i] || colorList[0];
- }
- }
- },
- (err) => {
- loading.value = false;
- }
- );
- };
- getRightData();
- const getBackGround = (id) => {
- return { background: colorData.value[id] };
- };
- const prodTagClose = (index, row) => {
- row.prodTags.splice(index, 1);
- proxy
- .post("/contract/updateProductionTag", {
- id: row.contractId,
- prodTag: row.prodTags.join(","),
- })
- .then((res) => {
- getList();
- });
- };
- const clickToday = () => {
- today.value = moment().format("yyyy-MM-DD");
- month.value = moment().format("yyyy年MM月");
- monthOne.value = moment().format("yyyy-MM");
- getRightData();
- };
- const isShow = (day) => {
- let nowDay = new Date(day + " 23:59:59").getTime();
- let flag = false;
- for (let i = 0; i < rightData.value.length; i++) {
- const e = rightData.value[i];
- let startDay = new Date(e.produceTime).getTime();
- let endDay = new Date(e.deliveryPeriod + " 23:59:59").getTime();
- if (nowDay >= startDay && nowDay <= endDay) {
- flag = true;
- break;
- }
- }
- return flag;
- };
- const judgeDay = (day) => {
- // return dateList.value[day] && dateList.value[day].length > 0;
- let nowDay = new Date(day + " 23:59:59").getTime();
- let rows = [];
- for (let i = 0; i < rightData.value.length; i++) {
- const e = rightData.value[i];
- let startDay = new Date(e.produceTime).getTime();
- let endDay = new Date(e.deliveryPeriod + " 23:59:59").getTime();
- if (nowDay >= startDay && nowDay <= endDay) {
- rows.push(e.id);
- }
- }
- return rows;
- };
- const showData = ref([]);
- const onShow = (day) => {
- let rows = judgeDay(day);
- showData.value = rows;
- };
- const getData = (id, att) => {
- const current = rightData.value.find((x) => x.id == id);
- if (current && current[att]) {
- return current[att];
- }
- };
- const selectDate = (val) => {
- calendar.value.selectDate(val);
- };
- const prevMonth = () => {
- month.value = moment(
- moment(month.value, "yyyy年MM月").add(-1, "month").calendar()
- ).format("yyyy年MM月");
- monthOne.value = moment(moment(month.value, "yyyy年MM月")).format("yyyy-MM");
- selectDate("prev-month");
- getRightData();
- };
- const nextMonth = () => {
- month.value = moment(
- moment(month.value, "yyyy年MM月").add(+1, "month").calendar()
- ).format("yyyy年MM月");
- monthOne.value = moment(moment(month.value, "yyyy年MM月")).format("yyyy-MM");
- selectDate("next-month");
- getRightData();
- };
- watch(
- () => today.value,
- (newValue) => {
- if (month.value !== moment(newValue).format("yyyy年MM月")) {
- month.value = moment(newValue).format("yyyy年MM月");
- monthOne.value = moment(moment(month.value, "yyyy年MM月")).format(
- "yyyy-MM"
- );
- getRightData();
- }
- }
- );
- const getFileData = () => {
- let ids = [];
- formData.orderData.contractProductList.map((x) => {
- ids.push(x.productId);
- x.contractProductBomList.map((y) => {
- ids.push(y.materialId);
- });
- });
- ids = Array.from(new Set(ids));
- proxy
- .post("/fileInfo/getList", {
- businessIdList: ids,
- })
- .then((fileObj) => {
- formData.orderData.contractProductList.map((x) => {
- if (fileObj[x.productId] && fileObj[x.productId].length > 0) {
- x.fileUrl = fileObj[x.productId][0].fileUrl;
- }
- x.contractProductBomList.map((y) => {
- y.fileList = fileObj[y.materialId] || [];
- if (y.fileList && y.fileList.length > 0) {
- y.fileUrl = y.fileList[0].fileUrl;
- }
- });
- });
- });
- };
- const lookDetails = (item) => {
- proxy.post("/contract/detail", { id: item.contractId }).then((res) => {
- formData.orderData = res;
- dialogVisible.value = true;
- if (
- formData.orderData.contractProductList &&
- formData.orderData.contractProductList.length > 0
- ) {
- getFileData();
- }
- });
- };
- const handleClickUpload = async (att, flag, index) => {
- let res = null;
- let path = "";
- if (flag) {
- proxy.msgTip("请稍后", 2);
- res = await proxy.post("/fileService/createTempFolder");
- if (res && res.path) {
- formData.data.contractProductList[index][att] = res.path;
- path = res.path;
- }
- } else {
- path = formData.data.contractProductList[index][att];
- }
- let a = document.createElement("a");
- a.href = "printer://" + "ftp://121.37.194.75/" + path + "/";
- a.style.display = "none";
- document.body.appendChild(a);
- a.click();
- document.body.removeChild(a);
- };
- </script>
- <style lang="scss" scoped>
- ::v-deep(.el-progress__text) {
- font-size: 14px !important;
- }
- .user {
- padding: 10px;
- display: flex;
- justify-content: space-between;
- .schedule-right {
- width: 400px;
- .schedule-top {
- width: 100%;
- background: #fff;
- padding: 20px;
- }
- .schedule-bottom {
- width: 100%;
- background: #fff;
- height: calc(100vh - 100px - 20px - 83px);
- padding: 20px;
- margin-top: 10px;
- overflow-y: auto;
- &::-webkit-scrollbar {
- width: 0px;
- }
- .line-class {
- height: 18px;
- line-height: 18px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- -o-text-overflow: ellipsis;
- margin: 1px 0;
- }
- }
- }
- .content {
- width: calc(100% - 410px);
- }
- }
- ::v-deep(.el-calendar__header) {
- display: none;
- }
- ::v-deep(.el-calendar__body) {
- padding: 0;
- }
- ::v-deep(.el-calendar-table .el-calendar-day) {
- // padding: 0;
- min-height: 50px;
- height: calc((100vh - 100px - 20px - 83px - 95px) / 5);
- overflow-y: hidden;
- }
- .el-icon.avatar-uploader-icon {
- font-size: 20px;
- color: #8c939d;
- width: 50px;
- height: 50px;
- text-align: center;
- border: 1px dashed var(--el-border-color);
- }
- </style>
|