123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622 |
- <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 #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="300" trigger="hover">
- <div>
- <div>产品编码:{{product.productCode}}</div>
- <div>产品名称:{{product.productName}}</div>
- <div>产品尺寸:{{product.productLength}}cm*{{product.productWidth}}cm*{{product.productHeight}}cm</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">
- <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)">
- <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>
- </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: "订单号",
- prop: "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: {},
- });
- const formOption = reactive({
- inline: true,
- labelWidth: 100,
- itemWidth: 100,
- });
- const formDom = ref(null);
- const formConfig = computed(() => {
- return [
- {
- type: "input",
- prop: "code",
- label: "店铺编号",
- itemWidth: 100,
- disabled: false,
- },
- {
- type: "input",
- prop: "name",
- label: "店铺名称",
- itemWidth: 100,
- disabled: false,
- },
- {
- type: "treeSelect",
- prop: "deptId",
- label: "负责部门",
- data: treeData.value,
- propsTreeLabel: "deptName",
- propsTreeValue: "deptId",
- itemWidth: 100,
- disabled: false,
- },
- ];
- });
- 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: "",
- };
- 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();
- });
- });
- };
- 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();
- };
- </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;
- }
- </style>
|