Переглянути джерело

1.报故修改。2.pdf组件修改。3.图片多上传修改

jiaxiaoqiang 1 рік тому
батько
коміт
39d43dd60f

+ 9 - 0
src/api/process/reportBreak.ts

@@ -8,6 +8,15 @@ export function breakReportInfoById(processId: string) {
   });
 }
 
+// 根据缺陷分类,获取原因列表(缺陷大类获取二类)
+export function basebugsByType(type: string) {
+  return request({
+    url: `/api/v1/op/baseBug/list`,
+    method: "post",
+    data: { bugType: type },
+  });
+}
+
 // 不合格品分布情况及工序(通过序列号获取关联工序)
 export function operationListByIds(ids: string[]) {
   return request({

+ 45 - 1
src/components/PDFView/index.vue

@@ -1,11 +1,22 @@
 <template>
+  <el-button
+    v-if="contentType === 'button'"
+    :link="isLink"
+    :type="btnType"
+    @click="showPdf"
+  >
+    {{ btnText }}
+  </el-button>
   <VuePdfEmbed
+    v-else
+    :page="pageNumber"
     :source="pdfSource"
     annotation-layer
     text-layer
     @click="showPdf"
   />
   <el-drawer
+    v-if="needToShowPdf"
     v-model="visible"
     :footer="false"
     :header="false"
@@ -14,7 +25,12 @@
     direction="rtl"
     size="972px"
   >
-    <VuePdfEmbed :source="pdfSource" annotation-layer text-layer />
+    <VuePdfEmbed
+      :page="showPdfNumber"
+      :source="pdfSource"
+      annotation-layer
+      text-layer
+    />
   </el-drawer>
 </template>
 
@@ -33,6 +49,34 @@ const props = defineProps({
     type: String,
     required: true,
   },
+  pageNumber: {
+    type: Number,
+    default: 0,
+  },
+  needToShowPdf: {
+    type: Boolean,
+    default: false,
+  },
+  contentType: {
+    type: String as PropType<"button" | "pdf">,
+    default: "pdf",
+  },
+  btnText: {
+    type: String,
+    default: "预览",
+  },
+  btnType: {
+    type: String,
+    default: "primary",
+  },
+  isLink: {
+    type: Boolean,
+    default: false,
+  },
+  showPdfNumber: {
+    type: Number,
+    default: 0,
+  },
 });
 
 const visible = ref(false);

+ 67 - 79
src/components/Upload/MultiUpload.vue

@@ -1,36 +1,35 @@
-<!--
-  多图上传组件
-  @author: youlaitech
-  @date 2022/11/20
--->
-
 <template>
-  <el-upload
-    v-model:file-list="fileList"
-    list-type="picture-card"
-    :before-upload="handleBeforeUpload"
-    :http-request="handleUpload"
-    :on-remove="handleRemove"
-    :on-preview="previewImg"
-    :limit="props.limit"
-  >
-    <i-ep-plus />
-  </el-upload>
+  <div class="upload-container">
+    <el-upload
+      v-model:file-list="fileList"
+      :before-upload="handleBeforeUpload"
+      :http-request="handleUpload"
+      :limit="limit"
+      :show-file-list="false"
+      class="img-box"
+      list-type="picture-card"
+    >
+      <i-ep-plus />
+    </el-upload>
+    <div v-for="(item, index) in fileList" :key="index" class="img-container">
+      <img :src="item.url" class="img-box" object-fit="cover" />
+      <Delete class="delete-icon" @click="deleteImg(index)" />
+    </div>
+  </div>
 
   <el-dialog v-model="dialogVisible">
-    <img w-full :src="previewImgUrl" alt="Preview Image" />
+    <img :src="previewImgUrl" alt="Preview Image" w-full />
   </el-dialog>
 </template>
 
-<script setup lang="ts">
+<script lang="ts" setup>
 import {
   UploadRawFile,
   UploadRequestOptions,
   UploadUserFile,
-  UploadFile,
-  UploadProps,
 } from "element-plus";
-import { uploadFileApi, deleteFileApi } from "@/api/file";
+import { Delete } from "@element-plus/icons-vue";
+import { uploadFileApi } from "@/api/file";
 
 const emit = defineEmits(["update:modelValue"]);
 
@@ -55,26 +54,7 @@ const previewImgUrl = ref("");
 const dialogVisible = ref(false);
 
 const fileList = ref([] as UploadUserFile[]);
-watch(
-  () => props.modelValue,
-  (newVal: string[]) => {
-    const filePaths = fileList.value.map((file) => file.url);
-    // 监听modelValue文件集合值未变化时,跳过赋值
-    if (
-      filePaths.length > 0 &&
-      filePaths.length === newVal.length &&
-      filePaths.every((x) => newVal.some((y) => y === x)) &&
-      newVal.every((y) => filePaths.some((x) => x === y))
-    ) {
-      return;
-    }
-
-    fileList.value = newVal.map((filePath) => {
-      return { url: filePath } as UploadUserFile;
-    });
-  },
-  { immediate: true }
-);
+const urlList = ref([] as string[]); // 上传成功后的图片路径集合,要传给父组件
 
 /**
  * 自定义图片上传
@@ -83,39 +63,9 @@ watch(
  */
 async function handleUpload(options: UploadRequestOptions): Promise<any> {
   // 上传API调用
-  const { data: fileInfo } = await uploadFileApi(options.file);
-
-  // 上传成功需手动替换文件路径为远程URL,否则图片地址为预览地址 blob:http://
-  const fileIndex = fileList.value.findIndex(
-    (file) => file.uid == (options.file as any).uid
-  );
-
-  fileList.value.splice(fileIndex, 1, {
-    name: fileInfo.name,
-    url: fileInfo.url,
-  } as UploadUserFile);
-
-  emit(
-    "update:modelValue",
-    fileList.value.map((file) => file.url)
-  );
-}
-
-/**
- * 删除图片
- */
-function handleRemove(removeFile: UploadFile) {
-  const filePath = removeFile.url;
-
-  if (filePath) {
-    deleteFileApi(filePath).then(() => {
-      // 删除成功回调
-      emit(
-        "update:modelValue",
-        fileList.value.map((file) => file.url)
-      );
-    });
-  }
+  const res: any = await uploadFileApi(options.file);
+  urlList.value.push(res.data.fileUrl);
+  emit("update:modelValue", urlList.value);
 }
 
 /**
@@ -129,11 +79,49 @@ function handleBeforeUpload(file: UploadRawFile) {
   return true;
 }
 
+const deleteImg = (index: number) => {
+  fileList.value.splice(index, 1);
+  urlList.value.splice(index, 1);
+  emit("update:modelValue", urlList.value);
+};
+
 /**
  * 预览图片
  */
-const previewImg: UploadProps["onPreview"] = (uploadFile) => {
-  previewImgUrl.value = uploadFile.url!;
-  dialogVisible.value = true;
-};
+// const previewImg: UploadProps["onPreview"] = (uploadFile) => {
+//   previewImgUrl.value = uploadFile.url!;
+//   dialogVisible.value = true;
+// };
 </script>
+
+<style lang="scss" scoped>
+.upload-container {
+  display: flex;
+  justify-content: start;
+  flex-wrap: wrap;
+}
+
+.img-container {
+  position: relative;
+}
+
+.img-box {
+  width: 148px;
+  height: 148px;
+  display: block;
+  margin-right: 10px;
+  margin-top: 10px;
+  border-radius: 4px;
+}
+
+.delete-icon {
+  position: absolute;
+  width: 20px;
+  height: 20px;
+  left: 50%;
+  top: 50%;
+  transform: translate(-50%, -50%);
+  color: red;
+  cursor: pointer;
+}
+</style>

+ 1 - 6
src/store/modules/dictionary.ts

@@ -3,12 +3,7 @@ import { defineStore } from "pinia";
 import { getUserDicts, getUserList } from "@/api/auth";
 
 export const useDictionaryStore = defineStore("dictionaryStore", () => {
-  const types = [
-    "unqualified_type",
-    "stage",
-    "process_state",
-    "outsource_state",
-  ];
+  const types = ["defect_mana", "stage", "process_state", "outsource_state"];
   const dicts = ref<{ [key: string]: any[] }>({});
 
   // 所有的用户列表

+ 69 - 64
src/views/pro-operation/report-break/index.vue

@@ -5,7 +5,7 @@
     :show-close="false"
     destroy-on-close
     direction="rtl"
-    size="972px"
+    size="990px"
   >
     <template #header>
       <div class="drawerTitle">报故</div>
@@ -67,90 +67,87 @@
                 />
               </el-select>
             </el-form-item>
-            <el-form-item label="不合格原因分类" prop="reasonList">
-              <el-select
-                v-model="formLabelAlign.reasonList"
-                multiple
-                placeholder="请选择"
-                value-key="dictValue"
-              >
-                <el-option
-                  v-for="item in dictStroe.dicts.unqualified_type"
-                  :key="item.dictValue"
-                  :label="item.dictLabel"
-                  :value="item.dictValue"
-                />
-              </el-select>
-            </el-form-item>
-            <el-form-item label="是否首检" prop="firstInspection">
-              <el-radio-group v-model="formLabelAlign.firstInspection">
-                <el-radio :value="0" border size="large">否</el-radio>
-                <el-radio :value="1" border size="large">是</el-radio>
-              </el-radio-group>
-            </el-form-item>
-            <el-form-item label="不合格品分布情况及工序" prop="processesList">
-              <el-select
-                v-model="formLabelAlign.processesList"
-                multiple
-                placeholder="请选择"
-                value-key="operationId"
-              >
-                <el-option
-                  v-for="item in operationList"
-                  :key="item.operationId"
-                  :label="item.operationName"
-                  :value="item.operationId"
-                />
-              </el-select>
-            </el-form-item>
 
-            <el-row :gutter="20" style="width: 100%">
-              <el-col :span="12">
-                <el-form-item label="责任/经办者" prop="personResponsible">
+            <el-row>
+              <el-col :span="11">
+                <el-form-item label="缺陷分类" prop="reasonType">
                   <el-select
-                    v-model="formLabelAlign.personResponsible"
-                    filterable
+                    v-model="formLabelAlign.reasonType"
                     placeholder="请选择"
-                    value-key="id"
+                    value-key="dictValue"
+                    @change="selectQuexianType"
                   >
                     <el-option
-                      v-for="item in dictStroe.allUsers"
-                      :key="item.id"
-                      :label="item.userName"
-                      :value="item.userName"
+                      v-for="item in dictStroe.dicts.defect_mana"
+                      :key="item.dictValue"
+                      :label="item.dictLabel"
+                      :value="item.dictValue"
                     />
                   </el-select>
                 </el-form-item>
               </el-col>
-              <el-col :span="12">
-                <el-form-item label="检验员" prop="userName">
+              <el-col :offset="1" :span="12">
+                <el-form-item label="缺陷名称" prop="reasonList">
                   <el-select
-                    v-model="formLabelAlign.userName"
+                    v-model="formLabelAlign.reasonList"
                     filterable
+                    multiple
                     placeholder="请选择"
                     value-key="id"
                   >
                     <el-option
-                      v-for="item in dictStroe.allUsers"
+                      v-for="item in quexianList"
                       :key="item.id"
-                      :label="item.userName"
-                      :value="item.userName"
+                      :label="item.bugName"
+                      :value="item.bugCode"
                     />
                   </el-select>
                 </el-form-item>
               </el-col>
             </el-row>
 
-            <el-form-item label="归档编号" prop="archiveNumber">
-              <el-input v-model="formLabelAlign.archiveNumber" />
+            <el-form-item label="是否首检" prop="firstInspection">
+              <el-radio-group v-model="formLabelAlign.firstInspection">
+                <el-radio :value="0" border size="large">否</el-radio>
+                <el-radio :value="1" border size="large">是</el-radio>
+              </el-radio-group>
+            </el-form-item>
+            <el-form-item label="不合格品分布情况及工序" prop="processesList">
+              <el-select
+                v-model="formLabelAlign.processesList"
+                multiple
+                placeholder="请选择"
+                value-key="operationId"
+              >
+                <el-option
+                  v-for="item in operationList"
+                  :key="item.operationId"
+                  :label="item.operationName"
+                  :value="item.operationId"
+                />
+              </el-select>
             </el-form-item>
-            <el-form-item label="工作令号" prop="workOrderNumber">
-              <el-input v-model="formLabelAlign.workOrderNumber" />
+
+            <el-form-item label="责任/经办者" prop="personResponsible">
+              <el-select
+                v-model="formLabelAlign.personResponsible"
+                filterable
+                placeholder="请选择"
+                value-key="id"
+              >
+                <el-option
+                  v-for="item in dictStroe.allUsers"
+                  :key="item.id"
+                  :label="item.userName"
+                  :value="item.userName"
+                />
+              </el-select>
             </el-form-item>
-            <el-form-item label="追踪卡号" prop="trackingNumber">
-              <el-input v-model="formLabelAlign.trackingNumber" />
+            <el-form-item>
+              <MultiUpload v-model="formLabelAlign.fileList" />
             </el-form-item>
-            <el-form-item label="特征和程度" prop="remark">
+
+            <el-form-item label="备注" prop="remark">
               <el-input
                 v-model="formLabelAlign.remark"
                 :rows="3"
@@ -175,12 +172,14 @@
 <script lang="ts" setup>
 import {
   addBreakReport,
+  basebugsByType,
   breakReportInfoById,
   operationListByIds,
 } from "@/api/process/reportBreak";
 import { useProcessStore } from "@/store/modules/processView";
 import { useDictionaryStore } from "@/store/modules/dictionary";
 import { getProcessInfo } from "@/api/prosteps";
+import MultiUpload from "@/components/Upload/MultiUpload.vue";
 
 const processStore = useProcessStore();
 const dictStroe = useDictionaryStore();
@@ -192,14 +191,13 @@ const infoData = ref<any>({});
 const formRef = ref<InstanceType<typeof ElForm>>();
 const formLabelAlign = reactive({
   seqNoList: [],
+  reasonType: "",
   reasonList: [],
   processesList: [],
+  fileList: [],
   firstInspection: 0,
   personResponsible: "",
   userName: "",
-  archiveNumber: "",
-  workOrderNumber: "",
-  trackingNumber: "",
   remark: "",
 });
 const rules = reactive({
@@ -238,12 +236,19 @@ const selectProcessWorkSeqChange = useDebounceFn(() => {
   });
 }, 2000);
 
+const quexianList = ref<any>([]);
+const selectQuexianType = (value: string) => {
+  basebugsByType(value).then((res) => {
+    quexianList.value = res.data || [];
+  });
+};
+
 const cancelClick = () => {
   drawerVisible.value = false;
 };
 
 const confirmClick = () => {
-  // drawerVisible.value = false;
+  drawerVisible.value = false;
   formRef.value &&
     formRef.value.validate((valid: boolean) => {
       if (valid) {