dengrui hace 7 meses
padre
commit
1207c9226d

+ 1 - 1
public/version.json

@@ -1,3 +1,3 @@
 {
-  "version": "1.9"
+  "version": "2.0"
 }

+ 14 - 0
src/api/file/index.ts

@@ -23,7 +23,21 @@ export function uploadFileApi(file: File): AxiosPromise<FileInfo> {
     },
   });
 }
+export function uploadFileApi1(file: File): AxiosPromise<FileInfo> {
+  const formData = new FormData();
+  formData.append("file", file);
+
+  formData.append("fileName", file.name);
 
+  return request({
+    url: "/api/v1/base/upload",
+    method: "post",
+    data: formData,
+    headers: {
+      "Content-Type": "multipart/form-data",
+    },
+  });
+}
 /**
  * 删除文件
  *

+ 23 - 0
src/api/prosteps/gongxuwenjian.ts

@@ -0,0 +1,23 @@
+import request from "@/utils/request";
+
+export function getData(data: any) {
+  return request({
+    url: `/api/v1/process/test/record/page`,
+    method: "post",
+    data,
+  });
+}
+export function addData(data: any) {
+  return request({
+    url: `/api/v1/process/test/record/add`,
+    method: "post",
+    data,
+  });
+}
+export function delData(data: any) {
+  return request({
+    url: `/api/v1/process/test/record/del`,
+    method: "post",
+    data,
+  });
+}

+ 166 - 0
src/components/Upload/FilesUpload.vue

@@ -0,0 +1,166 @@
+<template>
+  <el-upload
+    v-model:file-list="fileList"
+    class="upload-demo"
+    :on-change="handleChange"
+    :limit="limit"
+    :auto-upload="false"
+    :show-file-list="false"
+  >
+    <el-button
+      type="primary"
+      :loading="loading"
+      :disabled="fileList.length >= limit"
+      >点击上传文件</el-button
+    >
+    <template #tip>
+      <div class="tip" v-if="showTip">
+        文件类型限制为.jpg,.jpeg,.png,word文档,pdf,大小不超过{{ size }}M
+      </div>
+    </template>
+    <div>
+      <el-tag
+        class="file-item"
+        v-for="(file, index) in fileList"
+        :key="file.name"
+        closable
+        type="success"
+        @close="deleteFile(index)"
+        @click.stop.prevent="handlePreview(index)"
+      >
+        {{ file.name }}
+      </el-tag>
+    </div>
+  </el-upload>
+  <el-drawer
+    v-model="PDFVisible"
+    :footer="false"
+    :header="false"
+    :show-close="false"
+    destroy-on-close
+    direction="rtl"
+    :append-to-body="true"
+    size="972px"
+  >
+    <VuePdfEmbed :source="pdfSource" annotation-layer text-layer />
+  </el-drawer>
+</template>
+<script lang="ts" setup>
+import { ref } from "vue";
+import { UploadFile, UploadFiles, UploadUserFile } from "element-plus";
+import { uploadFileApi1 } from "@/api/file";
+import PDFView from "@/components/PDFView/index.vue";
+import VuePdfEmbed from "vue-pdf-embed";
+
+const props = defineProps({
+  size: {
+    type: Number,
+    default: 4,
+  },
+  limit: {
+    type: Number,
+    default: 1,
+  },
+  src: {
+    type: String,
+    default: "",
+  },
+  srcList: {
+    type: Array<string>,
+    default: () => [],
+  },
+  pdfList: {
+    type: Array<string>,
+    default: () => [],
+  },
+  fileNameList: {
+    type: Array<string>,
+    default: () => [],
+  },
+  generatePdf: {
+    type: Boolean,
+    default: false,
+  },
+  showTip: {
+    type: Boolean,
+    default: true,
+  },
+});
+
+const loading = ref(false);
+
+const emit = defineEmits([
+  "update:src",
+  "update:srcList",
+  "update:pdfList",
+  "update:fileNameList",
+  "finished",
+]);
+
+// 上传文件成功返回的值
+const src = useVModel(props, "src", emit); //单文件用这个
+const srcList = useVModel(props, "srcList", emit); //多文件用这个
+const pdfList = useVModel(props, "pdfList", emit); //转换成pdf后的多文件用这个
+const fileNameList = useVModel(props, "fileNameList", emit); //多文件上传要显示文件名
+
+// el-upload 绑定的值
+const fileList = ref<UploadUserFile[]>([]);
+const resetFileList = (value: Array) => {
+  fileList.value = value;
+};
+
+const handleChange = async (uploadFile: UploadFile) => {
+  console.log(uploadFile, "22");
+  if (uploadFile.size! > props.size * 1048 * 1048) {
+    ElMessage.warning(`上传文件不能大于${props.size}M`);
+    return;
+  }
+  loading.value = true;
+  uploadFileApi1(uploadFile.raw as File, props.generatePdf)
+    .then((res: any) => {
+      loading.value = false;
+      src.value = res.data.fileUrl;
+      pdfList.value.push(res.data.pdfUrl);
+      srcList.value.push(res.data.fileUrl);
+      fileNameList.value.push(res.data.fileName);
+      emit("finished");
+    })
+    .catch((err) => {
+      ElMessage.error(err.message);
+      loading.value = false;
+    });
+};
+
+const deleteFile = (index: number) => {
+  src.value = ""; //删除直接清空src即可,不用考虑是哪个,因为单文件不会有多个
+  fileList.value.splice(index, 1);
+  srcList.value.splice(index, 1);
+  pdfList.value.splice(index, 1);
+  fileNameList.value.splice(index, 1);
+};
+
+const PDFVisible = ref(false);
+const pdfSource = ref("");
+const handlePreview = (index: number) => {
+  if (srcList.value.length > index && props.generatePdf) {
+    pdfSource.value =
+      import.meta.env.VITE_APP_UPLOAD_URL + pdfList.value[index];
+    PDFVisible.value = true;
+  }
+};
+defineExpose({
+  resetFileList,
+  fileList,
+});
+</script>
+
+<style scoped lang="scss">
+.tip {
+  font-size: 12px;
+  color: #e6a23c;
+  margin-top: 5px;
+}
+.file-item {
+  margin-left: 10px;
+}
+</style>

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

@@ -133,6 +133,16 @@ export default {
             keepAlive: true,
           },
         },
+        {
+          path: "gongxuwenjian",
+          component: () =>
+            import("@/views/pro-steps/components/gongxuwenjian.vue"),
+          name: "Gongxuwenjian",
+          meta: {
+            back: true,
+            keepAlive: true,
+          },
+        },
       ],
     },
     {

+ 24 - 0
src/utils/downLoad.ts

@@ -0,0 +1,24 @@
+import axios from "axios";
+const downService = axios.create({
+  baseURL: import.meta.env.VITE_APP_UPLOAD_URL,
+});
+async function downloadFile(url: string, fileName: string) {
+  try {
+    const response = await downService.get(url, {
+      responseType: "blob",
+    });
+    const blob = new Blob([response.data]);
+    const link = document.createElement("a");
+    const resurl = url;
+    link.href = window.URL.createObjectURL(blob);
+    const lastDotIndex = resurl.lastIndexOf(".");
+    link.download = fileName + "." + resurl.substring(lastDotIndex + 1);
+    document.body.appendChild(link);
+    link.click();
+    window.URL.revokeObjectURL(link.href);
+    document.body.removeChild(link);
+  } catch (error) {
+    console.error("文件下载失败:", error);
+  }
+}
+export { downloadFile };

+ 1 - 1
src/views/pro-operation/report-work/index.vue

@@ -210,7 +210,7 @@ const confirmClick = () => {
     processId: processStore.scanInfo.id,
     processUserReportList: persons.value,
     seqList: selectedProcess.value,
-    signatureId: selectedSign,
+    signatureId: selectedSign.value,
   };
 
   reportWork(params).then((res: any) => {

+ 225 - 0
src/views/pro-steps/components/gongxuwenjian.vue

@@ -0,0 +1,225 @@
+<template>
+  <div>
+    <div v-if="!addStatus">
+      <div class="stepsViewScrollH">
+        <div class="right">
+          <div class="btns">
+            <el-button
+              style="font-size: 16px"
+              type="primary"
+              class="btn"
+              @click="addStatus = true"
+              >新增</el-button
+            >
+          </div>
+          <div style="border-radius: 16px">
+            <el-table :data="fileDatas" class="tableView">
+              <el-table-column
+                fixed
+                prop="fileName"
+                label="文件名称"
+                align="center"
+              />
+
+              <el-table-column label="操作" fixed="right" width="200">
+                <template #default="scope">
+                  <el-button
+                    link
+                    v-if="scope.row.writeData !== ''"
+                    class="btnText"
+                    type="primary"
+                    @click="downLoad(scope.row.filePath, scope.row.fileName)"
+                  >
+                    下载
+                  </el-button>
+                  <el-button
+                    link
+                    v-if="scope.row.writeData !== ''"
+                    class="btnText"
+                    type="primary"
+                    @click="delDatas(scope.row.id)"
+                  >
+                    删除
+                  </el-button>
+                </template>
+              </el-table-column>
+            </el-table>
+          </div>
+        </div>
+      </div>
+    </div>
+    <div v-else>
+      <div :key="addKey" class="addForm">
+        <div>
+          <el-form
+            :model="form"
+            label-width="100px"
+            ref="formRef"
+            :rules="rules"
+          >
+            <el-form-item label="文件" prop="filePath">
+              <FilesUpload
+                v-model:src="form.filePath"
+                ref="uploadRef"
+                v-model:src-list="srcList"
+                v-model:pdf-list="pdfUrlList"
+                v-model:file-name-list="fileNameList"
+                :limit="1"
+                :generate-pdf="true"
+                @finished="testFiles"
+              />
+            </el-form-item>
+          </el-form>
+          <div style="padding-left: 80px">
+            <el-button class="leftBtn" @click="resetAdd">取消</el-button>
+            <el-button class="rightBtn" @click="submit" type="primary"
+              >确认</el-button
+            >
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script setup>
+import { addData, getData, delData } from "@/api/prosteps/gongxuwenjian.ts";
+import { useProcessStore } from "@/store";
+import { downloadFile } from "@/utils/downLoad";
+
+defineOptions({
+  name: "Gongxuwenjian",
+});
+const addKey = ref(false);
+const addStatus = ref(false);
+const srcList = ref([]);
+const pdfUrlList = ref([]);
+const fileNameList = ref([]);
+const testFiles = () => {
+  form.value.filePath = srcList.value[0];
+};
+const form = ref({
+  fileName: "",
+});
+const formRef = ref(null);
+const rules = reactive({
+  filePath: [{ required: true, trigger: "change" }],
+});
+const resetAdd = () => {
+  addKey.value = !addKey.value;
+  addStatus.value = false;
+  form.value.filePath = "";
+  srcList.value = [];
+  fileNameList.value = [];
+};
+const delDatas = async (id) => {
+  const { data, code } = await delData({
+    id,
+  });
+  if (code == "200") {
+    ElMessage.success("操作成功!");
+    getDatas();
+  }
+};
+//新增提交
+const submit = async () => {
+  await formRef.value.validate(async (valid) => {
+    if (valid) {
+      const { data, code } = await addData({
+        fileName: fileNameList.value[0],
+        filePath: srcList.value[0],
+        operationId: store.odersData.operationId,
+        processId: store.scanInfo.id,
+        seqNo: store.scanInfo.seqNo,
+        workOrderCode: store.odersData.workOrderCode,
+      });
+      if (code == "200") {
+        ElMessage.success("新增成功!");
+        resetAdd();
+        getDatas();
+      }
+    } else {
+      ElMessage.error("请检查表单");
+    }
+  });
+};
+
+const store = useProcessStore();
+const tpDatas = ref([]);
+const fileDatas = ref([]);
+const downLoad = async (url, name) => {
+  let names = name.split(".")[0];
+  let resUrl = url;
+  await downloadFile(resUrl, names);
+};
+//模版数据获取
+const getTpDatas = async () => {
+  const { data } = await templateData({
+    pageNo: 1,
+    pageSize: 999,
+    processId: store.odersData.operationId,
+  });
+  tpDatas.value = data.records;
+};
+//数据列表获取
+const getDatas = async () => {
+  const { data } = await getData({
+    pageNo: 1,
+    pageSize: 999,
+    processId: store.scanInfo.id,
+  });
+  fileDatas.value = data.records;
+};
+onMounted(() => {
+  getDatas();
+});
+</script>
+<style lang="scss" scoped>
+.tableView {
+  width: 100%;
+  height: calc(100vh - 290px);
+  padding: 20px 0px;
+  border-radius: 16px;
+}
+.addForm {
+  width: 100%;
+  height: calc(100vh - 290px);
+  display: flex;
+  background-color: white;
+  border-radius: 16px;
+  justify-content: center;
+  align-items: center;
+}
+.stepsViewScrollH {
+  width: 100%;
+  height: calc(100vh - 270px);
+  display: flex;
+  padding: 20px;
+  padding-top: 0px;
+  .left {
+    width: 25%;
+    height: 100%;
+    border-radius: 16px;
+    background-color: white;
+  }
+  .right {
+    flex: 1;
+    border-radius: 16px;
+    margin-left: 20px;
+    .tableView {
+      width: 100%;
+      height: calc(100vh - 340px);
+      padding: 20px 0px;
+      border-radius: 16px !important;
+    }
+    .btns {
+      height: 50px;
+      display: flex;
+      align-items: center;
+      background-color: rgb(241, 243, 245);
+      .btn {
+        height: 30px;
+      }
+    }
+  }
+}
+</style>

+ 6 - 0
src/views/pro-steps/index.vue

@@ -165,6 +165,12 @@ const defaultComponents = [
     path: "screwdriver",
     name: "Screwdriver",
   },
+  {
+    compentName: "工序文件",
+    iconName: "mingpai",
+    path: "gongxuwenjian",
+    name: "Gongxuwenjian",
+  },
 ];
 //当前路由在setpComponents中的index
 const selectIndex = ref(0);