瀏覽代碼

新需求

cz 1 年之前
父節點
當前提交
226cf9be5c

+ 10 - 1
src/components/product/SelectProduct.vue

@@ -108,8 +108,13 @@ import { ElMessage, ElMessageBox } from "element-plus";
 import byTable from "@/components/byTable/index";
 import byForm from "@/components/byForm/index";
 import treeList from "@/components/product/treeList";
-
 import { computed, defineComponent, ref } from "vue";
+const props = defineProps({
+  isTechnology: {
+    type: String,
+    default: "",
+  },
+});
 const loading = ref(false);
 const submitLoading = ref(false);
 const sourceList = ref({
@@ -122,6 +127,7 @@ const sourceList = ref({
     productClassifyId: "",
     keyword: "",
     definition: "1",
+    isTechnology: "",
   },
 });
 let dialogVisible = ref(false);
@@ -430,6 +436,9 @@ const getDtl = (row) => {
   });
 };
 getTreeList();
+if (props.isTechnology) {
+  sourceList.value.pagination.isTechnology = props.isTechnology;
+}
 getList();
 const handleBeforeUpload = async (file) => {
   const res = await proxy.post("/fileInfo/getSing", { fileName: file.name });

+ 337 - 0
src/views/JXSK/production/forward/index.vue

@@ -0,0 +1,337 @@
+<template>
+  <div class="tenant">
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{}"
+        :action-list="[]"
+        @get-list="getList"
+      >
+      </byTable>
+    </div>
+    <el-dialog
+      :title="'任务流转'"
+      v-model="dialogVisible"
+      width="700"
+      v-loading="loading"
+      destroy-on-close
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+        <template #file>
+          <div>aa</div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm(true)"
+          size="large"
+          :loading="submitLoading"
+        >
+          提 交
+        </el-button>
+        <el-button
+          type="danger"
+          @click="submitForm()"
+          size="large"
+          :loading="submitLoading"
+        >
+          退 回
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+  },
+});
+const dialogVisible = ref(false);
+const modalType = ref("add");
+const rules = ref({
+  workOrderId: [{ required: true, message: "请选择工单", trigger: "change" }],
+  startDate: [
+    { required: true, message: "请选择计划开始时间", trigger: "change" },
+  ],
+  stopDate: [
+    { required: true, message: "请选择计划结束时间", trigger: "change" },
+  ],
+  quantity: [{ required: true, message: "请输入计划数量", trigger: "blur" }],
+});
+const workOrderData = ref([]);
+const workOrderDataOne = ref([]);
+
+const statusData = ref([
+  {
+    label: "未开始",
+    value: "0",
+  },
+  {
+    label: "进行中",
+    value: "1",
+  },
+  {
+    label: "完成",
+    value: "2",
+  },
+]);
+
+const selectConfig = reactive([]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "产品名称",
+        prop: "productName",
+      },
+    },
+    {
+      attrs: {
+        label: "产品SN",
+        prop: "productSn",
+      },
+    },
+
+    {
+      attrs: {
+        label: "当前工序",
+        prop: "productionProcessesName",
+      },
+    },
+    {
+      attrs: {
+        label: "下一工序",
+        prop: "nextProductionProcessesName",
+      },
+    },
+
+    {
+      attrs: {
+        label: "操作",
+        width: "80",
+        align: "center",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "查看",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtl(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const formData = reactive({
+  data: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      itemType: "text",
+      prop: "productName",
+      label: "产品名称",
+      disabled: true,
+      style: {
+        width: "50%",
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "productSn",
+      label: "产品SN",
+      disabled: true,
+      style: {
+        width: "50%",
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "productionProcessesName",
+      label: "当前工序",
+      disabled: true,
+      style: {
+        width: "50%",
+      },
+    },
+    {
+      type: "slot",
+      slotName: "file",
+      label: "工序图纸",
+    },
+    {
+      type: "title",
+      title: "任务流转",
+      isShow: submitType.value == "10",
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "nextProductionProcessesName",
+      label: "目标工序",
+      disabled: true,
+      style: {
+        width: "50%",
+      },
+      isShow: submitType.value == "10",
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/productionTaskDetail/circulationPage", sourceList.value.pagination)
+    .then((message) => {
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+
+const submitForm = (flag) => {
+  if (flag) {
+    if (submitType.value == "10") {
+      const data = {
+        id: formData.data.id,
+        receivedUserId: formData.data.receivedUserId,
+      };
+      proxy.post("/productionTaskDetail/circulation", data).then(
+        (res) => {
+          ElMessage({
+            message: "操作成功",
+            type: "success",
+          });
+          dialogVisible.value = false;
+          submitLoading.value = false;
+          getList();
+        },
+        (err) => {
+          submitLoading.value = false;
+          return ElMessage({
+            message: err.message,
+            type: "info",
+          });
+        }
+      );
+    } else {
+      proxy
+        .post("/productionTaskDetail/productStorage", { id: formData.data.id })
+        .then(
+          (res) => {
+            ElMessage({
+              message: "操作成功",
+              type: "success",
+            });
+            dialogVisible.value = false;
+            submitLoading.value = false;
+            getList();
+          },
+          (err) => {
+            submitLoading.value = false;
+            return ElMessage({
+              message: err.message,
+              type: "info",
+            });
+          }
+        );
+    }
+  } else {
+    ElMessageBox.confirm(`你确定退回当前任务吗?`, "提示", {
+      confirmButtonText: "确定",
+      cancelButtonText: "取消",
+      type: "warning",
+    }).then(() => {
+      proxy
+        .post("/productionTaskDetail/revokeTask", { id: formData.data.id })
+        .then(
+          (res) => {
+            ElMessage({
+              message: "退回成功",
+              type: "success",
+            });
+            dialogVisible.value = false;
+            submitLoading.value = false;
+            getList();
+          },
+          (err) => {
+            submitLoading.value = false;
+            return ElMessage({
+              message: err.message,
+              type: "info",
+            });
+          }
+        );
+    });
+  }
+};
+const submitType = ref("");
+const getDtl = (row) => {
+  if (
+    row.nextProductionProcessesId == "" ||
+    row.nextProductionProcessesId == "-1"
+  ) {
+    submitType.value = "20";
+  } else {
+    submitType.value = "10";
+  }
+  formOption.disabled = true;
+  formData.data = { ...row };
+  dialogVisible.value = true;
+};
+
+getList();
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+</style>

+ 373 - 0
src/views/JXSK/production/plan/index.vue

@@ -0,0 +1,373 @@
+<template>
+  <div class="tenant">
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          select: select,
+        }"
+        :action-list="[
+          {
+            text: '添加计划',
+            action: () => openModal('add'),
+          },
+        ]"
+        @get-list="getList"
+      >
+      </byTable>
+    </div>
+    <el-dialog
+      :title="modalType == 'add' ? '添加计划' : '查看计划'"
+      v-model="dialogVisible"
+      width="700"
+      v-loading="loading"
+      destroy-on-close
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+        <template #list>
+          <div style="width: 100%">
+            <el-table :data="formData.data.productionTaskList">
+              <el-table-column prop="quantity" label="任务数量" />
+              <el-table-column prop="personLiableName" label="负责人" />
+              <el-table-column
+                prop="status"
+                label="完成状态"
+                :formatter="(row) => dictValueLabel(row.status, statusData)"
+              />
+            </el-table>
+          </div>
+        </template>
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm()"
+          size="large"
+          :loading="submitLoading"
+          v-if="modalType == 'add'"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+  },
+});
+const dialogVisible = ref(false);
+const modalType = ref("add");
+const rules = ref({
+  workOrderId: [{ required: true, message: "请选择工单", trigger: "change" }],
+  startDate: [
+    { required: true, message: "请选择计划开始时间", trigger: "change" },
+  ],
+  stopDate: [
+    { required: true, message: "请选择计划结束时间", trigger: "change" },
+  ],
+  quantity: [{ required: true, message: "请输入计划数量", trigger: "blur" }],
+});
+const workOrderData = ref([]);
+const workOrderDataOne = ref([]);
+
+const statusData = ref([
+  {
+    label: "未开始",
+    value: "0",
+  },
+  {
+    label: "进行中",
+    value: "1",
+  },
+  {
+    label: "完成",
+    value: "2",
+  },
+]);
+
+const selectConfig = reactive([
+  {
+    label: "计划状态",
+    prop: "status",
+    data: statusData.value,
+  },
+]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "工单单号",
+        prop: "workOrderCode",
+      },
+    },
+    {
+      attrs: {
+        label: "计划单号",
+        prop: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "计划开始时间",
+        prop: "startDate",
+      },
+    },
+    {
+      attrs: {
+        label: "计划结束时间",
+        prop: "stopDate",
+      },
+    },
+    {
+      attrs: {
+        label: "产品名称",
+        prop: "productName",
+      },
+    },
+
+    {
+      attrs: {
+        label: "计划数量",
+        prop: "quantity",
+      },
+    },
+
+    {
+      attrs: {
+        label: "计划状态",
+        prop: "status",
+      },
+      render(status) {
+        return proxy.dictValueLabel(status, statusData.value);
+      },
+    },
+
+    {
+      attrs: {
+        label: "操作",
+        width: "80",
+        align: "center",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "查看",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtl(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const formData = reactive({
+  data: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "select",
+      prop: "workOrderId",
+      label: "工单",
+      required: true,
+      filterable: true,
+      data:
+        modalType.value == "add" ? workOrderData.value : workOrderDataOne.value,
+      fn: (val) => {
+        changeFn(val);
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "productName",
+      label: "产品名称",
+      disabled: true,
+      style: {
+        width: "25%",
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "waitQuantity",
+      label: "待排程数量",
+      disabled: true,
+      style: {
+        width: "25%",
+      },
+      isShow: modalType.value == "add",
+    },
+    {
+      type: "date",
+      itemType: "date",
+      prop: "startDate",
+      label: "计划开始时间",
+      required: true,
+    },
+    {
+      type: "date",
+      itemType: "date",
+      prop: "stopDate",
+      label: "计划结束时间",
+      required: true,
+    },
+    {
+      type: "number",
+      prop: "quantity",
+      label: "计划数量",
+      precision: 0,
+      min: 0,
+      controls: false,
+    },
+    {
+      type: "slot",
+      slotName: "list",
+      label: "生产任务",
+      isShow: modalType.value != "add",
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/productionPlan/page", sourceList.value.pagination)
+    .then((message) => {
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+const openModal = () => {
+  dialogVisible.value = true;
+  modalType.value = "add";
+  formOption.disabled = false;
+  formData.data = {};
+};
+
+const submitForm = () => {
+  byform.value.handleSubmit(() => {
+    if (Number(formData.data.quantity) > Number(formData.data.waitQuantity)) {
+      return ElMessage({
+        message: "计划数量不可大于待排程数量",
+        type: "info",
+      });
+    }
+    if (proxy.compareTime(formData.data.startDate, formData.data.stopDate)) {
+      return ElMessage({
+        message: "时间选择存在问题",
+        type: "info",
+      });
+    }
+    submitLoading.value = true;
+    proxy.post("/productionPlan/add", formData.data).then(
+      () => {
+        ElMessage({
+          message: "添加成功",
+          type: "success",
+        });
+        dialogVisible.value = false;
+        submitLoading.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        submitLoading.value = false;
+      }
+    );
+  });
+};
+const getDtl = (row) => {
+  modalType.value = "detail";
+  formOption.disabled = true;
+  proxy.post("/productionPlan/detail", { id: row.id }).then((res) => {
+    formData.data = res;
+    changeFn(formData.data.workOrderId);
+    dialogVisible.value = true;
+  });
+};
+
+const getDict = () => {
+  proxy
+    .post("/workOrder/page", { pageNum: 1, pageSize: 9999, isRemaining: "1" })
+    .then((res) => {
+      workOrderData.value = res.rows.map((x) => ({
+        label: x.code,
+        value: x.id,
+        ...x,
+      }));
+    });
+  proxy.post("/workOrder/page", { pageNum: 1, pageSize: 9999 }).then((res) => {
+    workOrderDataOne.value = res.rows.map((x) => ({
+      label: x.code,
+      value: x.id,
+      ...x,
+    }));
+  });
+};
+getDict();
+getList();
+
+const changeFn = (val) => {
+  const current =
+    modalType.value == "add"
+      ? workOrderData.value.find((x) => x.value == val)
+      : workOrderDataOne.value.find((x) => x.value == val);
+  if (current) {
+    formData.data.productName = current.productName;
+    formData.data.waitQuantity = current.remainingQuantity;
+  }
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+</style>

+ 331 - 0
src/views/JXSK/production/receive/index.vue

@@ -0,0 +1,331 @@
+<template>
+  <div class="tenant">
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{}"
+        :action-list="[]"
+        @get-list="getList"
+      >
+      </byTable>
+    </div>
+    <el-dialog
+      :title="'任务接收'"
+      v-model="dialogVisible"
+      width="700"
+      v-loading="loading"
+      destroy-on-close
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+      >
+      </byForm>
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm(true)"
+          size="large"
+          :loading="submitLoading"
+        >
+          提 交
+        </el-button>
+        <el-button
+          type="danger"
+          @click="submitForm()"
+          size="large"
+          :loading="submitLoading"
+          v-if="otherBtn"
+        >
+          退 回
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+  },
+});
+const dialogVisible = ref(false);
+const modalType = ref("add");
+const rules = ref({
+  workOrderId: [{ required: true, message: "请选择工单", trigger: "change" }],
+  startDate: [
+    { required: true, message: "请选择计划开始时间", trigger: "change" },
+  ],
+  stopDate: [
+    { required: true, message: "请选择计划结束时间", trigger: "change" },
+  ],
+  quantity: [{ required: true, message: "请输入计划数量", trigger: "blur" }],
+});
+const workOrderData = ref([]);
+const workOrderDataOne = ref([]);
+
+const statusData = ref([
+  {
+    label: "未开始",
+    value: "0",
+  },
+  {
+    label: "进行中",
+    value: "1",
+  },
+  {
+    label: "完成",
+    value: "2",
+  },
+]);
+
+const selectConfig = reactive([]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "产品名称",
+        prop: "productName",
+      },
+    },
+    {
+      attrs: {
+        label: "产品SN",
+        prop: "productSn",
+      },
+    },
+
+    {
+      attrs: {
+        label: "当前工序",
+        prop: "productionProcessesName",
+      },
+    },
+    {
+      attrs: {
+        label: "前道工序",
+        prop: "previousProcessesName",
+      },
+    },
+
+    {
+      attrs: {
+        label: "操作",
+        width: "80",
+        align: "center",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "查看",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtl(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const formData = reactive({
+  data: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "input",
+      itemType: "text",
+      prop: "productName",
+      label: "产品名称",
+      disabled: true,
+      style: {
+        width: "50%",
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "productSn",
+      label: "产品SN",
+      disabled: true,
+      style: {
+        width: "50%",
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "productionProcessesName",
+      label: "当前工序",
+      disabled: true,
+      style: {
+        width: "50%",
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "previousProcessesName",
+      label: "前道工序",
+      disabled: true,
+      style: {
+        width: "50%",
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "circulationUserName",
+      label: "流转人",
+      disabled: true,
+      style: {
+        width: "50%",
+      },
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/productionTaskDetail/receivePage", sourceList.value.pagination)
+    .then((message) => {
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+const submitApi = () => {
+  proxy.post("/productionTaskDetail/receive", { id: formData.data.id }).then(
+    (res) => {
+      ElMessage({
+        message: "操作成功",
+        type: "success",
+      });
+      dialogVisible.value = false;
+      submitLoading.value = false;
+      getList();
+    },
+    (err) => {
+      submitLoading.value = false;
+      return ElMessage({
+        message: err.message,
+        type: "info",
+      });
+    }
+  );
+};
+const submitForm = (flag) => {
+  if (flag) {
+    proxy
+      .post("/productionTaskDetail/haveTaskCount", {
+        productionProcessesId: formData.data.productionProcessesId,
+      })
+      .then((res) => {
+        if (res && Number(res) > 0) {
+          ElMessageBox.confirm(
+            `你当前还有进行中的任务尚未提交,确认接收新任务吗?`,
+            "提示",
+            {
+              confirmButtonText: "确定",
+              cancelButtonText: "取消",
+              type: "warning",
+            }
+          ).then(() => {
+            ElMessageBox.confirm(
+              `你当前还有进行中的任务尚未提交,确认接收新任务吗?`,
+              "提示",
+              {
+                confirmButtonText: "确定",
+                cancelButtonText: "取消",
+                type: "warning",
+              }
+            ).then(() => {
+              submitApi();
+            });
+          });
+        } else {
+          submitApi();
+        }
+      });
+  } else {
+    proxy
+      .post("/productionTaskDetail/rejection", { id: formData.data.id })
+      .then(
+        (res) => {
+          ElMessage({
+            message: "退回成功",
+            type: "success",
+          });
+          dialogVisible.value = false;
+          submitLoading.value = false;
+          getList();
+        },
+        (err) => {
+          submitLoading.value = false;
+          return ElMessage({
+            message: err.message,
+            type: "info",
+          });
+        }
+      );
+  }
+};
+const submitType = ref("");
+const otherBtn = ref(true);
+const getDtl = (row) => {
+  if (!row.productionProcessesName) {
+    otherBtn.value = false;
+  } else {
+    otherBtn.value = true;
+  }
+  formOption.disabled = true;
+  formData.data = { ...row };
+  dialogVisible.value = true;
+};
+
+getList();
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+</style>

+ 515 - 0
src/views/JXSK/production/task/index.vue

@@ -0,0 +1,515 @@
+<template>
+  <div class="tenant">
+    <div class="content">
+      <byTable
+        :source="sourceList.data"
+        :pagination="sourceList.pagination"
+        :config="config"
+        :loading="loading"
+        highlight-current-row
+        :selectConfig="selectConfig"
+        :table-events="{
+          select: select,
+        }"
+        :action-list="[
+          {
+            text: '添加任务',
+            action: () => openModal('add'),
+          },
+        ]"
+        @get-list="getList"
+      >
+      </byTable>
+    </div>
+    <el-dialog
+      :title="modalType == 'add' ? '添加任务' : '查看任务'"
+      v-model="dialogVisible"
+      width="700"
+      v-loading="loading"
+      destroy-on-close
+    >
+      <byForm
+        :formConfig="formConfig"
+        :formOption="formOption"
+        v-model="formData.data"
+        :rules="rules"
+        ref="byform"
+        v-if="modalType == 'add'"
+      >
+        <template
+          v-for="(cur, index) in productionProcessesList"
+          :key="cur.id"
+          v-slot:[cur.id]="{ item }"
+        >
+          <el-select
+            v-model="productionObj[cur.id]"
+            multiple
+            placeholder="请选择负责人"
+          >
+            <el-option
+              v-for="item in userList"
+              :key="item.value"
+              :label="item.label"
+              :value="item.value"
+            />
+          </el-select>
+        </template>
+      </byForm>
+
+      <byForm
+        :formConfig="formConfigOne"
+        :formOption="formOptionOne"
+        v-model="formData.dataOne"
+        ref="byformOne"
+        v-else
+      >
+        <template #list>
+          <div style="width: 100%">
+            <el-table :data="formData.dataOne.productionTaskDetailList">
+              <el-table-column prop="productSn" label="产品SN" />
+              <el-table-column
+                prop="productionProcessesName"
+                label="当前工序"
+              />
+              <el-table-column prop="cumulativeTime" label="累计耗时" />
+              <el-table-column
+                label="工序状态"
+                :formatter="
+                  (row) =>
+                    dictValueLabel(row.processesStatus, processesStatusData)
+                "
+              />
+            </el-table>
+          </div>
+        </template>
+      </byForm>
+
+      <template #footer>
+        <el-button @click="dialogVisible = false" size="large">取 消</el-button>
+        <el-button
+          type="primary"
+          @click="submitForm()"
+          size="large"
+          :loading="submitLoading"
+          v-if="modalType == 'add'"
+        >
+          确 定
+        </el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ElMessage, ElMessageBox } from "element-plus";
+import byTable from "@/components/byTable/index";
+import byForm from "@/components/byForm/index";
+import useUserStore from "@/store/modules/user";
+
+const { proxy } = getCurrentInstance();
+const loading = ref(false);
+const submitLoading = ref(false);
+const sourceList = ref({
+  data: [],
+  pagination: {
+    total: 3,
+    pageNum: 1,
+    pageSize: 10,
+    keyword: "",
+  },
+});
+const processesStatusData = ref([
+  {
+    label: "0",
+    value: "未开始",
+  },
+  {
+    label: "1",
+    value: "进行中",
+  },
+  {
+    label: "2",
+    value: "驳回",
+  },
+  {
+    label: "3",
+    value: "完成",
+  },
+]);
+const dialogVisible = ref(false);
+const modalType = ref("add");
+const rules = ref({
+  productionPlanId: [
+    { required: true, message: "请选择生产计划", trigger: "change" },
+  ],
+  dueDate: [{ required: true, message: "请选择完成期限", trigger: "change" }],
+  quantity: [{ required: true, message: "请输入生产数量", trigger: "blur" }],
+});
+const selectConfig = reactive([]);
+const config = computed(() => {
+  return [
+    {
+      attrs: {
+        label: "计划单号",
+        prop: "productionPlanCode",
+      },
+    },
+
+    {
+      attrs: {
+        label: "任务编码",
+        prop: "code",
+      },
+    },
+    {
+      attrs: {
+        label: "产品名称",
+        prop: "productName",
+      },
+    },
+    {
+      attrs: {
+        label: "任务数量",
+        prop: "quantity",
+      },
+    },
+
+    {
+      attrs: {
+        label: "完成期限",
+        prop: "dueDate",
+      },
+    },
+
+    {
+      attrs: {
+        label: "操作",
+        width: "80",
+        align: "center",
+      },
+      renderHTML(row) {
+        return [
+          {
+            attrs: {
+              label: "查看",
+              type: "primary",
+              text: true,
+            },
+            el: "button",
+            click() {
+              getDtl(row);
+            },
+          },
+        ];
+      },
+    },
+  ];
+});
+const formData = reactive({
+  data: {},
+  dataOne: {},
+});
+const formOption = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const formOptionOne = reactive({
+  inline: true,
+  labelWidth: 100,
+  itemWidth: 100,
+  rules: [],
+});
+const byform = ref(null);
+const formConfig = computed(() => {
+  return [
+    {
+      type: "select",
+      prop: "productionPlanId",
+      label: "生产计划",
+      required: true,
+      filterable: true,
+      data: planData.value,
+      fn: (val) => {
+        changeFn(val);
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "productName",
+      label: "产品名称",
+      disabled: true,
+      style: {
+        width: "25%",
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "waitQuantity",
+      label: "待排程数量",
+      disabled: true,
+      style: {
+        width: "25%",
+      },
+    },
+    {
+      type: "number",
+      prop: "quantity",
+      label: "任务数量",
+      precision: 0,
+      min: 0,
+      controls: false,
+    },
+    {
+      type: "date",
+      itemType: "date",
+      prop: "dueDate",
+      label: "完成期限",
+      required: true,
+    },
+  ];
+});
+const formConfigOne = computed(() => {
+  return [
+    {
+      type: "select",
+      prop: "productionPlanId",
+      label: "生产计划",
+      required: true,
+      filterable: true,
+      data: planDataOne.value,
+      fn: (val) => {
+        changeFn(val);
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "productName",
+      label: "产品名称",
+      disabled: true,
+      style: {
+        width: "25%",
+      },
+    },
+    {
+      type: "input",
+      itemType: "text",
+      prop: "waitQuantity",
+      label: "待排程数量",
+      disabled: true,
+      style: {
+        width: "25%",
+      },
+    },
+    {
+      type: "number",
+      prop: "quantity",
+      label: "任务数量",
+      precision: 0,
+      min: 0,
+      controls: false,
+    },
+    {
+      type: "date",
+      itemType: "date",
+      prop: "dueDate",
+      label: "完成期限",
+      required: true,
+    },
+    {
+      type: "slot",
+      slotName: "list",
+      label: "产品明细",
+    },
+  ];
+});
+const getList = async (req) => {
+  sourceList.value.pagination = { ...sourceList.value.pagination, ...req };
+  loading.value = true;
+  proxy
+    .post("/productionTask/page", sourceList.value.pagination)
+    .then((message) => {
+      sourceList.value.data = message.rows;
+      sourceList.value.pagination.total = message.total;
+      setTimeout(() => {
+        loading.value = false;
+      }, 200);
+    });
+};
+const openModal = () => {
+  dialogVisible.value = true;
+  modalType.value = "add";
+  formOption.disabled = false;
+  formData.data = {};
+};
+
+const submitForm = () => {
+  byform.value.handleSubmit(() => {
+    if (Number(formData.data.quantity) > Number(formData.data.waitQuantity)) {
+      return ElMessage({
+        message: "任务数量不可大于待排程数量",
+        type: "info",
+      });
+    }
+    // if (proxy.compareTime(formData.data.startDate, formData.data.dueDate)) {
+    //   return ElMessage({
+    //     message: "完成期限不可小于计划开始时间",
+    //     type: "info",
+    //   });
+    // }
+    for (const key in productionObj.value) {
+      if (productionObj.value[key] && productionObj.value[key].length > 0) {
+      } else {
+        return ElMessage({
+          message: "所有工序都需选择负责人!",
+          type: "info",
+        });
+      }
+    }
+    formData.data.taskProcessesUser = JSON.stringify(productionObj.value);
+    submitLoading.value = true;
+    proxy.post("/productionTask/addByJxst", formData.data).then(
+      () => {
+        ElMessage({
+          message: "添加成功",
+          type: "success",
+        });
+        productionProcessesList.value = [];
+        productionObj.value = {};
+        dialogVisible.value = false;
+        submitLoading.value = false;
+        getList();
+      },
+      (err) => {
+        console.log(err);
+        submitLoading.value = false;
+      }
+    );
+  });
+};
+const getDtl = (row) => {
+  modalType.value = "detail";
+  formOptionOne.disabled = true;
+  proxy.post("/productionTask/detailByJxst", { id: row.id }).then((res) => {
+    formData.dataOne = res;
+    formData.dataOne.waitQuantity = res.remainingQuantity;
+    dialogVisible.value = true;
+  });
+};
+const userList = ref([]);
+const planData = ref([]);
+const planDataOne = ref([]);
+
+const statusData = ref([
+  {
+    label: "未开始",
+    value: "0",
+  },
+  {
+    label: "进行中",
+    value: "1",
+  },
+  {
+    label: "完成",
+    value: "2",
+  },
+]);
+
+const getDict = () => {
+  proxy
+    .get("/tenantUser/list", {
+      pageNum: 1,
+      pageSize: 10000,
+      tenantId: useUserStore().user.tenantId,
+    })
+    .then((res) => {
+      userList.value = res.rows.map((item) => {
+        return {
+          label: item.nickName,
+          value: item.userId,
+        };
+      });
+    });
+
+  proxy
+    .post("/productionPlan/page", {
+      pageNum: 1,
+      pageSize: 9999,
+      isRemaining: "1",
+    })
+    .then((res) => {
+      planData.value = res.rows.map((x) => ({
+        label: x.code,
+        value: x.id,
+        ...x,
+      }));
+    });
+
+  proxy
+    .post("/productionPlan/page", {
+      pageNum: 1,
+      pageSize: 9999,
+    })
+    .then((res) => {
+      planDataOne.value = res.rows.map((x) => ({
+        label: x.code,
+        value: x.id,
+        ...x,
+      }));
+    });
+};
+getDict();
+getList();
+
+const changeFn = (val) => {
+  const current =
+    modalType.value == "add"
+      ? planData.value.find((x) => x.value == val)
+      : planDataOne.value.find((x) => x.value == val);
+  if (current) {
+    formData.data.productName = current.productName;
+    formData.data.waitQuantity = current.remainingQuantity;
+  }
+  if (
+    productionProcessesList.value &&
+    productionProcessesList.value.length > 0
+  ) {
+    let id = productionProcessesList.value[0].id;
+    const index = formConfig.value.findIndex((x) => x.slotName === id);
+    formConfig.value.splice(index, productionProcessesList.value.length);
+    productionProcessesList.value = [];
+    productionObj.value = {};
+  }
+  getProductionDetails(val);
+};
+
+const productionProcessesList = ref([]);
+const productionObj = ref({});
+const getProductionDetails = (id) => {
+  proxy.post("/productionPlan/detail", { id }).then((res) => {
+    productionProcessesList.value = res.productionProcessesList;
+    for (let i = 0; i < productionProcessesList.value.length; i++) {
+      const e = productionProcessesList.value[i];
+      formConfig.value.push({
+        type: "slot",
+        label: e.name + " 负责人",
+        slotName: e.id,
+      });
+      productionObj.value[e.id] = [];
+    }
+  });
+};
+</script>
+
+<style lang="scss" scoped>
+.tenant {
+  padding: 20px;
+}
+::v-deep(.el-input-number .el-input__inner) {
+  text-align: left;
+}
+</style>

+ 26 - 3
src/views/JXSK/production/workOrder/index.vue

@@ -16,8 +16,16 @@
         :action-list="[]"
         @get-list="getList"
       >
-        <template #slotName="{ item }">
-          {{ item.createTime }}
+        <template #arrangedQuantity="{ item }">
+          <div
+            v-if="item.quantity > item.arrangedQuantity"
+            style="color: red; font-weight: 700"
+          >
+            {{ item.arrangedQuantity }}
+          </div>
+          <div v-else>
+            {{ item.arrangedQuantity }}
+          </div>
         </template>
       </byTable>
     </div>
@@ -312,6 +320,20 @@ const selectConfig = computed(() => [
     prop: "source",
     data: workOrderSource.value,
   },
+  {
+    label: "是否定制",
+    prop: "isCustomized",
+    data: [
+      {
+        label: "是",
+        value: "1",
+      },
+      {
+        label: "否",
+        value: "0",
+      },
+    ],
+  },
 ]);
 
 const config = computed(() => {
@@ -366,8 +388,9 @@ const config = computed(() => {
     },
     {
       attrs: {
+        type: "slot",
         label: "已计划数量",
-        prop: "arrangedQuantity",
+        slot: "arrangedQuantity",
       },
     },
     {

+ 4 - 1
src/views/production/project/technology/index.vue

@@ -121,7 +121,10 @@
       width="70%"
       append-to-body
     >
-      <SelectProduct @handleSelect="handleSelect"></SelectProduct>
+      <SelectProduct
+        @handleSelect="handleSelect"
+        :isTechnology="'0'"
+      ></SelectProduct>
       <template #footer>
         <span class="dialog-footer">
           <el-button @click="openProduct = false">取消</el-button>