Przeglądaj źródła

1.多媒体采集。2.物料流转记录。

jiaxiaoqiang 1 rok temu
rodzic
commit
0b5ccf00cf

+ 3 - 2
src/api/prosteps/medias.ts

@@ -1,7 +1,7 @@
 import request from "@/utils/request";
 
 // 新增多媒体信息
-export function addMedia(data: { filePath: string; operationMediaId: string }) {
+export function addMedia(data: object) {
   return request({
     url: "/api/v1/process/media/add",
     method: "post",
@@ -19,12 +19,13 @@ export function deleteMedias(ids: string[]) {
 }
 
 //分页查询
-export function pageMedias(proId: string) {
+export function pageMedias(proId: string, processId: string) {
   return request({
     url: "/api/v1/process/media/page",
     method: "post",
     data: {
       operationMediaId: proId,
+      processId,
       pageNum: 1,
       pageSize: 200,
     },

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

@@ -8,9 +8,9 @@
         @click="value = value - step"
       />
     </div>
-    <el-input
+    <el-input-number
       v-model="value"
-      :disabled="jiaDisabled"
+      :controls="false"
       :max="max"
       :min="min"
       class="showSum"

+ 11 - 11
src/components/Upload/CameraUpload.vue

@@ -5,12 +5,8 @@
       <svg-icon icon-class="bendishangchuan" size="80" @click="selectFile" />
     </div>
     <div class="row">
-      <svg-icon icon-class="paizhao" size="80" @click="clickReset" />
-      <svg-icon
-        icon-class="bendishangchuan"
-        size="80"
-        @click="clickDeleteAll"
-      />
+      <RefreshRight color="#0a59f7" size="70px" @click="clickReset" />
+      <Delete color="#ff4d4f" size="60px" @click="clickDeleteAll" />
     </div>
 
     <input v-show="false" id="fileInput" accept="image/*" type="file" />
@@ -37,6 +33,7 @@
 
 <script setup>
 import { uploadFileApi } from "@/api/file";
+import { Delete, RefreshRight } from "@element-plus/icons-vue";
 
 let mediaStreamTrack = null; // 视频对象(全局)
 let video;
@@ -55,6 +52,7 @@ const openMedia = async () => {
     navigator.mediaDevices
       .getUserMedia(constraints)
       .then((mediaStream) => {
+        console.log("mediaStream", mediaStream);
         // mediaStreamTrack = typeof mediaStream.stop === 'function' ? mediaStream : mediaStream.getTracks()[1];
         mediaStreamTrack = mediaStream.getVideoTracks();
         video.srcObject = mediaStream;
@@ -103,11 +101,13 @@ function takePhoto() {
 // 关闭摄像头
 function closeMedia() {
   let stream = document.getElementById("video").srcObject;
-  let tracks = stream.getTracks();
+  if (stream) {
+    let tracks = stream.getTracks();
 
-  tracks.forEach(function (track) {
-    track.stop();
-  });
+    tracks?.forEach(function (track) {
+      track.stop();
+    });
+  }
 
   document.getElementById("video").srcObject = null;
   visible.value = false;
@@ -123,7 +123,7 @@ const selectFile = () => {
     console.log(file);
     if (file) {
       uploadFileApi(file).then((res) => {
-        cameraEmit("uploadFinish", res.data);
+        cameraEmit("uploadFinish", res.data.fileUrl);
       });
     }
   };

+ 3 - 1
src/views/material-flow/creatTask.vue

@@ -7,6 +7,7 @@
         <div style="display: flex; margin-bottom: 15px">
           <ScanCodeInput
             v-model="currentBox"
+            :clearable="true"
             placeholder="请扫描或输入料箱编号"
             style="width: 50%"
             @keyup.enter="enterBox"
@@ -20,6 +21,7 @@
         <div class="type-title">请扫码物料</div>
         <ScanCodeInput
           v-model="scanCodeInput"
+          placeholder="请扫描或输入物料编码"
           @keyup.enter="handleScanCodeInput"
         />
         <div style="height: calc(100vh - 450px); margin-top: 15px">
@@ -36,7 +38,7 @@
                 </div>
                 <div class="bottom">
                   <NumberInput v-model="item.num" />
-                  <span class="unit">{{ item.unitDictValue }}</span>
+                  <span class="unit">{{ item.unitDictLabel }}</span>
                 </div>
               </div>
             </div>

+ 1 - 1
src/views/material-flow/index.vue

@@ -10,7 +10,7 @@
         <CreatTask />
       </el-tab-pane>
       <el-tab-pane label="历史记录" name="second">
-        <TaskRecords />
+        <TaskRecords v-if="activeName === 'second'" />
       </el-tab-pane>
     </el-tabs>
   </div>

+ 155 - 0
src/views/material-flow/recordDetail.vue

@@ -0,0 +1,155 @@
+<template>
+  <div>
+    <el-dialog
+      id="custom-dialog"
+      v-model="visible"
+      :title="null"
+      close-icon="null"
+    >
+      <div class="top-title">{{ boxDetail.vehicleName }}</div>
+      <div class="desc-title">{{ boxDetail.vehicleCode }}</div>
+      <div class="center-content">
+        <el-scrollbar>
+          <div
+            v-for="(item, index) in boxDetail?.processMaterialList ?? []"
+            :key="index"
+            class="item-container"
+          >
+            <div>
+              <div class="item-header">{{ item?.materialName }}</div>
+              <div class="item-describe">{{ item?.spec }}</div>
+            </div>
+            <div>
+              <span class="item-count">{{ item?.num }}</span>
+              <span class="item-unit">{{ item?.unitLabel }}</span>
+            </div>
+          </div>
+        </el-scrollbar>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script lang="ts" setup>
+const visible = ref(false);
+
+const boxDetail = ref<any>({});
+
+const showDetails = (boxObj: any) => {
+  visible.value = true;
+  boxDetail.value = boxObj;
+};
+
+defineExpose({
+  showDetails,
+});
+</script>
+
+<style lang="scss" scoped>
+:deep(.el-dialog) {
+  background: #f1f3f5;
+  box-shadow: 0px 0px 80px 10px rgba(0, 0, 0, 0.25);
+  border-radius: 16px;
+}
+
+#custom-dialog {
+  background: #f1f3f5;
+  box-shadow: 0px 0px 80px 10px rgba(0, 0, 0, 0.25);
+  border-radius: 16px 16px 16px 16px;
+  width: 924px;
+  max-height: 80vh;
+
+  .top-title {
+    width: 100%;
+
+    font-weight: 500;
+    font-size: 38px;
+    color: rgba(0, 0, 0, 0.9);
+    text-align: center;
+  }
+
+  .desc-title {
+    font-weight: 400;
+    font-size: 20px;
+    color: rgba(0, 0, 0, 0.6);
+    text-align: center;
+  }
+
+  .center-content {
+    margin-top: 24px;
+    width: 100%;
+    height: 500px;
+
+    font-size: 24px;
+    overflow-y: auto;
+    color: rgba(0, 0, 0, 0.9);
+    border-radius: 16px 16px 16px 16px;
+    border: 1px solid rgba(0, 0, 0, 0.2);
+  }
+
+  .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;
+      background: #0a59f7;
+      border-radius: 76px 76px 76px 76px;
+    }
+  }
+}
+
+.item-container {
+  width: 100%;
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  padding-left: 30px;
+  padding-right: 20px;
+  height: 80px;
+}
+
+.item-header {
+  font-weight: 500;
+  font-size: 24px;
+  color: rgba(0, 0, 0, 0.9);
+  text-align: left;
+}
+
+.item-describe {
+  font-weight: 400;
+  font-size: 20px;
+  color: rgba(0, 0, 0, 0.6);
+  text-align: left;
+}
+
+.item-count {
+  font-weight: bold;
+  font-size: 38px;
+  color: rgba(0, 0, 0, 0.9);
+
+  text-align: right;
+}
+
+.item-unit {
+  font-weight: 500;
+  font-size: 20px;
+  color: rgba(0, 0, 0, 0.6);
+
+  text-align: right;
+}
+</style>

+ 28 - 8
src/views/material-flow/taskRecords.vue

@@ -1,11 +1,16 @@
 <template>
   <el-scrollbar height="calc(100vh - 250px)">
-    <div class="grid-container">
-      <div v-for="(box, index) in historyList" :key="index" class="suit-box">
+    <div v-loading="loading" class="grid-container">
+      <div
+        v-for="(box, index) in historyList"
+        :key="index"
+        class="suit-box"
+        @click="handleClick(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" />-->
+        <svg-icon class="svgStyle" icon-class="jiaobiao" size="25" />
       </div>
     </div>
   </el-scrollbar>
@@ -16,11 +21,15 @@
     size="large"
     @pagination="paginationChange"
   />
+  <RecordDetail ref="recordDetailRef" />
 </template>
 
 <script lang="ts" setup>
 import { getMaterialFlowHistoryList } from "@/api/process/materialFlow";
+import RecordDetail from "@/views/material-flow/recordDetail.vue";
 
+const recordDetailRef = ref<InstanceType<typeof RecordDetail>>();
+const loading = ref(false);
 const page = reactive({
   pageSize: 10,
   pageNo: 1,
@@ -30,14 +39,19 @@ const page = reactive({
 const historyList = ref<any>([]);
 
 const getData = () => {
+  loading.value = true;
   getMaterialFlowHistoryList({
     pageNo: page.pageNo,
     pageSize: page.pageSize,
-  }).then((res) => {
-    console.log(res);
-    historyList.value = res.data.records;
-    page.total = res.data.totalCount;
-  });
+  })
+    .then((res) => {
+      console.log(res);
+      historyList.value = res.data.records;
+      page.total = res.data.totalCount;
+    })
+    .finally(() => {
+      loading.value = false;
+    });
 };
 
 const paginationChange = () => {
@@ -47,6 +61,12 @@ const paginationChange = () => {
 onMounted(() => {
   getData();
 });
+
+const handleClick = (item: any) => {
+  if (item.processMaterialList && item.processMaterialList.length > 0) {
+    recordDetailRef.value?.showDetails(item);
+  }
+};
 </script>
 
 <style lang="scss" scoped>

+ 26 - 12
src/views/pro-steps/components/duomeiticaiji.vue

@@ -1,12 +1,25 @@
 <template>
   <el-scrollbar style="width: 100%; height: 100%">
     <div class="media-container">
-      <CameraUpload @reset-select="clickReset" @upload-finish="finish" @delete-all="clickDeleteAll" />
-      <div v-for="(item, index) in medias.filter((item: any) => item.filePath)" :key="index" class="media-item">
+      <CameraUpload
+        @reset-select="clickReset"
+        @upload-finish="finish"
+        @delete-all="clickDeleteAll"
+      />
+      <div
+        v-for="(item, index) in medias.filter((item: any) => item.filePath)"
+        :key="index"
+        class="media-item"
+        @click="item.isSelected = !item.isSelected"
+      >
+        <i-ep-delete
+          v-show="item.isSelected"
+          class="check"
+          color="#ff4d4f"
+          size="20px"
+        />
+
         <img :src="getImgurl(item)" alt="" class="img-box" object-fit="cover" />
-        <svg-icon v-if="item.isSelected" class="check" icon-class="bendishangchuan" size="30"
-          @click="item.isSelected = false" />
-        <svg-icon v-else class="check" icon-class="edit" size="30" @click="item.isSelected = true" />
       </div>
     </div>
   </el-scrollbar>
@@ -31,6 +44,7 @@ const finish = (value: string) => {
   addMedia({
     filePath: value,
     operationMediaId: proStore.odersData.operationId,
+    processId: proStore.scanInfo.id,
   }).then((res) => {
     getListData();
   });
@@ -41,9 +55,11 @@ onMounted(() => {
 });
 
 const getListData = () => {
-  pageMedias(proStore.odersData.operationId).then((res) => {
-    medias.value = res.data.records || [];
-  });
+  pageMedias(proStore.odersData.operationId, proStore.scanInfo.id).then(
+    (res) => {
+      medias.value = res.data.records || [];
+    }
+  );
 };
 
 const getImgurl = (item: any) => {
@@ -75,9 +91,9 @@ const clickDeleteAll = () => {
   width: 100%;
   display: grid;
   /*行间距*/
-  //grid-row-gap: 24px;
+  grid-row-gap: 24px;
   /*列间距*/
-  //grid-column-gap: 24px;
+  grid-column-gap: 24px;
   /*每3行有2个行间距,所以每个格子的宽高都要减去(24*2) / 3 */
   //grid-template-columns: repeat(4, calc(33.33% - 16px));
   //grid-template-rows: repeat(4, calc(33.33% - 16px));
@@ -104,8 +120,6 @@ const clickDeleteAll = () => {
     position: absolute;
     top: 20px;
     right: 20px;
-    width: 48px;
-    height: 48px;
   }
 }
 </style>