Преглед на файлове

1.物料流转接口。2.公共扫码input修改。3.numberInput修改。4.工位上料页面。

jiaxiaoqiang преди 1 година
родител
ревизия
ca833791a4

+ 53 - 0
src/api/process/materialFlow.ts

@@ -0,0 +1,53 @@
+import request from "@/utils/request";
+
+// 获取物料流转终点,有仓库,也有工位
+export function getDestinationList() {
+  return request({
+    url: `/api/v1/process/circulation/target`,
+    method: "get",
+  });
+}
+
+// 根据仓库获取具体的坐标列表
+export function getStoreListByNo(no: string) {
+  return request({
+    url: `/api/v1/wms/position/list`,
+    method: "post",
+    data: { houseNo: no },
+  });
+}
+
+// 扫码料箱获取料箱详情
+export function getBoxDetailByLabel(label: string) {
+  return request({
+    url: `/api/v1/process/circulation/vehicle/${label}`,
+    method: "get",
+  });
+}
+
+// 通过扫码获取物料信息
+export function getMaterialInfoByLabel(label: string) {
+  return request({
+    url: `/api/v1/process/circulation/material`,
+    method: "post",
+    data: { label },
+  });
+}
+
+//新增物料流转过程
+export function addMaterialFlow(data: any) {
+  return request({
+    url: `/api/v1/process/circulation/add`,
+    method: "post",
+    data,
+  });
+}
+
+//获取物料流转历史记录列表
+export function getMaterialFlowHistoryList(data?: any) {
+  return request({
+    url: `/api/v1/process/circulation/page`,
+    method: "post",
+    data,
+  });
+}

+ 1 - 1
src/components/NumberInput/index.vue

@@ -54,7 +54,7 @@ const jiaDisabled = computed(() => {
 
 const value = computed({
   get() {
-    return props.modelValue;
+    return Number(props.modelValue);
   },
   set(val) {
     if (val < props.min) {

+ 19 - 25
src/components/ScanCodeInput/index.vue

@@ -1,11 +1,5 @@
 <template>
-  <el-input
-    v-model="value"
-    class="scanInput"
-    placeholder="Please input"
-    @blur="enter"
-    @keyup.enter="enter"
-  >
+  <el-input class="scanInput" v-bind="$attrs">
     <template #prefix>
       <img src="@/assets/icons/shaoma.svg" />
     </template>
@@ -13,24 +7,24 @@
 </template>
 
 <script lang="ts" setup>
-const props = defineProps({
-  modelValue: {
-    type: String,
-    default: "",
-  },
-});
-const emits = defineEmits(["update:modelValue", "enterfnc"]);
-const enter = () => {
-  emits("enterfnc");
-};
-const value = computed({
-  get() {
-    return props.modelValue;
-  },
-  set(val) {
-    emits("update:modelValue", val);
-  },
-});
+// const props = defineProps({
+//   modelValue: {
+//     type: String,
+//     default: "",
+//   },
+// });
+// const emits = defineEmits(["update:modelValue", "enterfnc"]);
+// const enter = () => {
+//   emits("enterfnc");
+// };
+// const value = computed({
+//   get() {
+//     return props.modelValue;
+//   },
+//   set(val) {
+//     emits("update:modelValue", val);
+//   },
+// });
 </script>
 
 <style lang="scss" scoped>

+ 10 - 4
src/router/modules/process.ts

@@ -111,7 +111,6 @@ export default {
       name: "call-materiel",
       meta: {
         title: "叫料",
-
         back: true,
       },
     },
@@ -121,7 +120,6 @@ export default {
       name: "drawing-list",
       meta: {
         title: "图纸",
-
         back: true,
       },
     },
@@ -131,7 +129,6 @@ export default {
       name: "appoint-out",
       meta: {
         title: "委外",
-
         back: true,
       },
     },
@@ -141,7 +138,16 @@ export default {
       name: "material-flow",
       meta: {
         title: "物料流转",
-
+        back: true,
+      },
+    },
+    {
+      path: "station-up-material",
+      component: () =>
+        import("@/views/pro-operation/station-up-material/index.vue"),
+      name: "station-up-material",
+      meta: {
+        title: "工位上料",
         back: true,
       },
     },

+ 119 - 23
src/views/material-flow/creatTask.vue

@@ -7,20 +7,20 @@
         <div style="display: flex; margin-bottom: 15px">
           <ScanCodeInput
             v-model="currentBox"
+            placeholder="请扫描或输入料箱编号"
             style="width: 50%"
-            @enterfnc="enterBox"
+            @keyup.enter="enterBox"
           />
           <div class="current-box">
-            <span class="left">当前料箱</span>
-            <span class="right">{{ currentBox }}</span>
+            <span class="left">{{ boxDetail?.name || "未绑定料箱" }}</span>
+            <span class="right">{{ boxDetail?.code || "未绑定料箱" }}</span>
           </div>
         </div>
 
-        <div class="type-title">料箱绑定</div>
+        <div class="type-title">请扫码物料</div>
         <ScanCodeInput
           v-model="scanCodeInput"
-          style="width: 50%"
-          @enterfnc="handleScanCodeInput"
+          @keyup.enter="handleScanCodeInput"
         />
         <div style="height: calc(100vh - 450px); margin-top: 15px">
           <el-scrollbar>
@@ -31,12 +31,12 @@
                 class="list-box"
               >
                 <div>
-                  <div class="name">{{ item.name }}name</div>
-                  <div class="spec">{{ item.spec }}spec</div>
+                  <div class="name">{{ item.materialName }}</div>
+                  <div class="spec">{{ item.spec }}</div>
                 </div>
                 <div class="bottom">
-                  <NumberInput v-model="item.number" />
-                  <span class="unit">{{ item.unit }}</span>
+                  <NumberInput v-model="item.num" />
+                  <span class="unit">{{ item.unitDictValue }}</span>
                 </div>
               </div>
             </div>
@@ -51,12 +51,35 @@
             :key="index"
             :class="{ selected: index === currentDestinationIndex }"
             class="end-box"
-            @click="onEndBoxClick(index)"
+            @click="onEndBoxClick(index, item)"
           >
-            ddd
+            <div class="name">{{ item.name }}</div>
+            <div
+              v-if="
+                item.targetType === 'stock' && index === currentDestinationIndex
+              "
+            >
+              <el-select
+                v-model="selectStore"
+                filterable
+                placeholder="请选择"
+                size="large"
+                style="width: 200px"
+                value-key="id"
+              >
+                <el-option
+                  v-for="store in storeMap.get(item.houseNo)"
+                  :key="store.id"
+                  :label="store.name"
+                  :value="store"
+                />
+              </el-select>
+            </div>
           </div>
         </div>
-        <el-button class="sureBtn" type="primary">创建任务</el-button>
+        <el-button class="sureBtn" type="primary" @click="createTask"
+          >创建任务
+        </el-button>
       </el-col>
     </el-row>
   </div>
@@ -64,25 +87,89 @@
 
 <script lang="ts" setup>
 //料箱
-const currentBox = ref("");
+import {
+  addMaterialFlow,
+  getBoxDetailByLabel,
+  getDestinationList,
+  getMaterialInfoByLabel,
+  getStoreListByNo,
+} from "@/api/process/materialFlow";
+
+const currentBox = ref("ZJ000011");
+const boxDetail = ref<any>({});
 const enterBox = () => {
-  console.log("enterBox", currentBox);
+  getBoxDetailByLabel(currentBox.value).then((res) => {
+    boxDetail.value = res.data;
+    // materialList.value = res.data.materialList;
+  });
 };
 
 // 物料
-const scanCodeInput = ref("");
+const scanCodeInput = ref("2010100002301#gys022#sc022#100#20220929#31");
+const materialList = ref<any>([]);
+
 const handleScanCodeInput = () => {
-  console.log("handleScanCodeInput", scanCodeInput.value);
+  getMaterialInfoByLabel(scanCodeInput.value).then((res) => {
+    materialList.value.push(res.data);
+    scanCodeInput.value = "";
+  });
 };
-
-const materialList = ref([{}, {}, {}, {}, {}, {}, {}, {}, {}]);
-
 // 流转终点
-const destinationList = ref([{}, {}, {}, {}, {}, {}, {}, {}, {}]);
+const destinationList = ref<any>();
+const currentDestination = ref<any>({});
 const currentDestinationIndex = ref(-1);
-const onEndBoxClick = (index: number) => {
+const storeMap = new Map<string, Array<any>>();
+const selectStore = ref<any>({});
+const onEndBoxClick = (index: number, item: any) => {
+  currentDestination.value = item;
   currentDestinationIndex.value = index;
-  console.log("onEndBoxClick", index);
+  // 如果是仓库,会根据仓库的no获取仓储的列表,存入map, 如果已经有数据了则不需要再次请求接口
+  if (item.targetType === "stock") {
+    if (!storeMap.has(item.houseNo)) {
+      getStoreListByNo(item.houseNo).then((res) => {
+        storeMap.set(item.houseNo, res.data || []);
+      });
+    }
+  }
+};
+
+onMounted(() => {
+  let wm = new WeakMap();
+  getDestinationList().then((res) => {
+    console.log("destinationList", res);
+    destinationList.value = res.data;
+  });
+});
+
+const createTask = () => {
+  const params = {
+    circulationDetail: [...materialList.value],
+    coordinate: "",
+    houseNo: "",
+    locationNo: "",
+    stationId: 0,
+    targetType: "",
+    vehicleCode: "",
+    vehicleId: 0,
+    vehicleName: "",
+  };
+  params.targetType = currentDestination.value.targetType;
+  if (currentDestination.value.targetType === "stock") {
+    params.houseNo = currentDestination.value.houseNo;
+    params.locationNo = selectStore.value.locationNo;
+    params.coordinate = selectStore.value.coordinate;
+  } else {
+    params.stationId = currentDestination.value.id;
+  }
+
+  params.vehicleId = boxDetail.value.id;
+  params.vehicleCode = boxDetail.value.code;
+  params.vehicleName = boxDetail.value.name;
+
+  addMaterialFlow(params).then((res) => {
+    ElMessage.success("创建成功");
+    console.log("res", res);
+  });
 };
 </script>
 
@@ -182,6 +269,9 @@ const onEndBoxClick = (index: number) => {
     font-weight: 500;
     font-size: 24px;
     color: rgba(0, 0, 0, 0.9);
+    display: flex;
+    justify-content: space-evenly;
+    align-items: center;
   }
 
   .end-box:not(:last-child) {
@@ -192,6 +282,12 @@ const onEndBoxClick = (index: number) => {
     border-radius: 40px;
     border: 2px solid rgba(10, 89, 247, 1);
   }
+
+  .name {
+    font-weight: 500;
+    font-size: 24px;
+    color: rgba(0, 0, 0, 0.9);
+  }
 }
 
 .sureBtn {

+ 91 - 3
src/views/material-flow/taskRecords.vue

@@ -1,7 +1,95 @@
 <template>
-  <div>src/views/material-flow /taskRecords</div>
+  <el-scrollbar height="calc(100vh - 250px)">
+    <div class="grid-container">
+      <div v-for="(box, index) in historyList" :key="index" class="suit-box">
+        <div class="suit-title">料箱名称: {{ box.vehicleName }}</div>
+        <div class="suit-desc">料箱编号:{{ box.vehicleCode }}</div>
+        <div class="suit-desc">创建时间:{{ box.created }}</div>
+        <!--        <svg-icon class="svgStyle" icon-class="jiaobiao" size="25" />-->
+      </div>
+    </div>
+  </el-scrollbar>
+  <Pagination
+    v-model:limit="page.pageSize"
+    v-model:page="page.pageNo"
+    :total="page.total"
+    size="large"
+    @pagination="paginationChange"
+  />
 </template>
 
-<script lang="ts" setup></script>
+<script lang="ts" setup>
+import { getMaterialFlowHistoryList } from "@/api/process/materialFlow";
 
-<style lang="scss" scoped></style>
+const page = reactive({
+  pageSize: 10,
+  pageNo: 1,
+  total: 0,
+});
+
+const historyList = ref<any>([]);
+
+const getData = () => {
+  getMaterialFlowHistoryList({
+    pageNo: page.pageNo,
+    pageSize: page.pageSize,
+  }).then((res) => {
+    console.log(res);
+    historyList.value = res.data.records;
+    page.total = res.data.totalCount;
+  });
+};
+
+const paginationChange = () => {
+  getData();
+};
+
+onMounted(() => {
+  getData();
+});
+</script>
+
+<style lang="scss" scoped>
+.grid-container {
+  width: 100%;
+  display: grid;
+  /*行间距*/
+  grid-row-gap: 24px;
+  /*列间距*/
+  grid-column-gap: 24px;
+
+  grid-template-columns: 1fr 1fr 1fr;
+  overflow-y: auto;
+
+  .suit-box {
+    height: 210px;
+    background-color: white;
+    border-radius: 16px 16px 16px 16px;
+    padding: 30px;
+    display: flex;
+    flex-direction: column;
+    align-items: start;
+    justify-content: center;
+    position: relative;
+
+    .suit-title {
+      font-weight: 500;
+      font-size: 20px;
+      color: rgba(0, 0, 0, 0.9);
+      text-align: left;
+    }
+
+    .suit-desc {
+      font-size: 20px;
+      color: rgba(0, 0, 0, 0.6);
+      text-align: left;
+    }
+
+    .svgStyle {
+      position: absolute;
+      bottom: 0;
+      right: 0;
+    }
+  }
+}
+</style>

+ 7 - 2
src/views/pro-operation/drawing/index.vue

@@ -3,10 +3,13 @@
     <div class="grid-container">
       <div v-for="(box, index) in drawingData" :key="index" class="suit-box">
         <div class="pdf-box">
-          <PDFView :pdf-source="box.drawingPath" />
+          <PDFView
+            :need-to-show-pdf="true"
+            :pdf-source="baseUrl + box.drawingPath"
+          />
         </div>
         <div class="suit-title">{{ box?.drawingTitle }}</div>
-        <!--        <div class="suit-desc">{{ box?.desc }}对待</div>-->
+        <div class="suit-desc">{{ box?.created }}</div>
       </div>
     </div>
   </el-scrollbar>
@@ -20,6 +23,8 @@ import PDFView from "@/components/PDFView/index.vue";
 const processStore = useProcessStore();
 const drawingData = ref<any>([]);
 
+const baseUrl = import.meta.env.VITE_APP_UPLOAD_URL;
+
 onMounted(() => {
   drawingList({ materialCode: processStore.scanInfo.materialCode }).then(
     (res) => {

+ 177 - 0
src/views/pro-operation/station-up-material/index.vue

@@ -0,0 +1,177 @@
+<template>
+  <div>
+    <ScanCodeInput
+      v-model="currentCode"
+      style="width: 400px; margin-left: 20px"
+      @enterfnc="enter"
+    />
+    <div class="bar-container">
+      <el-scrollbar>
+        <div class="grid-container">
+          <div v-for="(item, index) in dataList" :key="index" class="list-box">
+            <div>
+              <div class="name">{{ item.name }}name</div>
+              <div class="spec">{{ item.spec }}spec</div>
+            </div>
+            <div class="bottom">
+              <NumberInput v-model="item.number" />
+              <span class="unit">{{ item.unit }}个</span>
+            </div>
+          </div>
+        </div>
+      </el-scrollbar>
+    </div>
+    <div class="station-bottom-btns">
+      <el-button class="cancelBtn" @click="cancelClick">取消</el-button>
+      <el-button class="sureBtn" type="primary" @click="confirmClick"
+        >确认上料
+      </el-button>
+    </div>
+  </div>
+</template>
+
+<script lang="ts" setup>
+import { useProcessStore } from "@/store/modules/processView";
+import router from "@/router";
+
+const currentCode = ref("");
+const enter = () => {};
+
+const processStore = useProcessStore();
+const dataList = ref<any>([
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+  {},
+]);
+
+const cancelClick = () => {
+  router.back();
+};
+
+const confirmClick = () => {};
+
+onMounted(() => {
+  if ("EventSource" in window) {
+    const source = new EventSource(
+      "/api/v1/pro-operation/station-up-material/stream",
+      { withCredentials: true }
+    );
+    source.onmessage = (event) => {
+      const data = JSON.parse(event.data);
+      console.log(data);
+    };
+    source.onerror = (event) => {
+      console.log("EventSource error");
+    };
+    source.onopen = (event) => {
+      console.log("EventSource connected");
+    };
+  } else {
+    console.log("EventSource not supported");
+  }
+});
+</script>
+
+<style lang="scss" scoped>
+.bar-container {
+  height: calc(100vh - 240px);
+}
+
+.grid-container {
+  display: grid;
+  /*行间距*/
+  grid-row-gap: 24px;
+  /*列间距*/
+  grid-column-gap: 24px;
+
+  overflow-y: auto;
+  padding: 24px;
+  width: calc(100% - 48px);
+  grid-template-columns: 1fr 1fr 1fr;
+
+  .list-box {
+    height: 210px;
+    background: #fff;
+    border-radius: 16px 16px 16px 16px;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    align-items: start;
+    padding: 30px 30px;
+
+    .name {
+      font-weight: 500;
+      font-size: 24px;
+      color: rgba(0, 0, 0, 0.9);
+      text-align: left;
+    }
+
+    .spec {
+      font-size: 20px;
+      color: rgba(0, 0, 0, 0.6);
+      text-align: left;
+    }
+
+    .bottom {
+      display: flex;
+      justify-content: start;
+      align-items: end;
+    }
+
+    .unit {
+      font-weight: 500;
+      font-size: 24px;
+      color: rgba(0, 0, 0, 0.6);
+      text-align: left;
+      margin-left: 5px;
+    }
+  }
+}
+
+.station-bottom-btns {
+  display: flex;
+  justify-content: center;
+  margin-top: 20px;
+  //margin-bottom: 20px;
+
+  .button {
+    margin-right: 20px;
+  }
+
+  .cancelBtn {
+    width: 292px;
+    height: 80px;
+    background: rgba(0, 0, 0, 0.06);
+    border-radius: 76px 76px 76px 76px;
+  }
+
+  .sureBtn {
+    width: 292px;
+    height: 80px;
+    margin-left: 24px;
+    background: #0a59f7;
+    border-radius: 76px 76px 76px 76px;
+  }
+}
+</style>

+ 1 - 0
src/views/pro-steps/components/operates.vue

@@ -39,6 +39,7 @@ const setIndex = (index: number) => {
       router.push({ name: "call-materiel" });
       break;
     case "gongweishangliao":
+      router.push({ name: "station-up-material" });
       break;
     case "liuzhuan":
       router.push({ name: "material-flow" });