Browse Source

Merge branch 'master' of http://192.168.101.4:3000/jiaxiaoqiang/JG-ADMIN-TEMP

# Conflicts:
#	src/api/process/index.ts
qinhb 1 year ago
parent
commit
751e6299c1
32 changed files with 2094 additions and 488 deletions
  1. 8 0
      src/api/craft/process/index.ts
  2. 16 0
      src/api/drawing/index.ts
  3. 4 0
      src/api/drawing/types.ts
  4. 1 0
      src/api/file/index.ts
  5. 9 1
      src/api/process/index.ts
  6. 73 0
      src/components/CommonTable/configs/tableConfig.ts
  7. 15 3
      src/components/CommonTable/index.vue
  8. 89 0
      src/components/PDFView/index.vue
  9. 105 0
      src/components/Upload/FilesUpload.vue
  10. 6 4
      src/components/Upload/SingleUpload.vue
  11. 45 11
      src/hooks/userCrud.ts
  12. 3 1
      src/store/modules/dictionary.ts
  13. 1 1
      src/utils/request.ts
  14. 6 0
      src/views/base/bom/columns.ts
  15. 150 0
      src/views/base/bom/components/version-page.vue
  16. 59 8
      src/views/base/bom/index.vue
  17. 51 9
      src/views/base/craftManagement/route/components/bottomTable.vue
  18. 244 226
      src/views/base/craftManagement/route/components/configs.ts
  19. 9 4
      src/views/base/craftManagement/route/components/processComponent.vue
  20. 128 0
      src/views/base/defectCheck/index.vue
  21. 105 0
      src/views/base/information/columns.ts
  22. 102 0
      src/views/base/information/index.vue
  23. 4 5
      src/views/base/materials/columns.ts
  24. 153 169
      src/views/base/materials/components/drawing-page.vue
  25. 12 1
      src/views/base/modeling/factory/index.vue
  26. 19 0
      src/views/demo/hooksDemo.vue
  27. 8 38
      src/views/pro/traceability/components/equitCom.vue
  28. 112 0
      src/views/pro/traceability/components/faultCom.vue
  29. 74 7
      src/views/pro/traceability/index.vue
  30. 43 0
      src/views/quality/unqualified/columns.ts
  31. 260 0
      src/views/quality/unqualified/index.vue
  32. 180 0
      src/views/storage/vehicleMaterial/index.vue

+ 8 - 0
src/api/craft/process/index.ts

@@ -33,3 +33,11 @@ export function sortGXJLList(data: object) {
     data: data,
     data: data,
   });
   });
 }
 }
+
+export function getBomVersion(data: object) {
+  return request({
+    url: `/api/v1/base/bomVersion/list`,
+    method: "post",
+    data: data,
+  });
+}

+ 16 - 0
src/api/drawing/index.ts

@@ -0,0 +1,16 @@
+import request from "@/utils/request";
+import { Drawing} from "./types";
+
+/**
+ * 修改图纸启用,禁用状态
+ *
+ * @param id
+ * @param data
+ */
+export function updateDrawaing(data: Drawing) {
+  return request({
+    url: "/api/v1/base/drawing/update",
+    method: "post",
+    data: data,
+  });
+}

+ 4 - 0
src/api/drawing/types.ts

@@ -0,0 +1,4 @@
+export interface Drawing {
+  id?:number;
+  enable?: number;
+}

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

@@ -10,6 +10,7 @@ import { FileInfo } from "./types";
 export function uploadFileApi(file: File): AxiosPromise<FileInfo> {
 export function uploadFileApi(file: File): AxiosPromise<FileInfo> {
   const formData = new FormData();
   const formData = new FormData();
   formData.append("file", file);
   formData.append("file", file);
+  formData.append("fileName", file.name);
   return request({
   return request({
     url: "/api/v1/base/upload",
     url: "/api/v1/base/upload",
     method: "post",
     method: "post",

+ 9 - 1
src/api/process/index.ts

@@ -29,4 +29,12 @@ export function queryChildrenInfo(
   });
   });
 }
 }
 
 
-
+export function traceabilityTabCount(
+    params: object
+): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/process/web/traceability/tabCount",
+    method: "post",
+    data: params
+  });
+}

+ 73 - 0
src/components/CommonTable/configs/tableConfig.ts

@@ -416,6 +416,12 @@ export const tableConfig = {
 		url: "/api/v1/base/materialBom/list",
 		url: "/api/v1/base/materialBom/list",
 		column: [
 		column: [
 			{
 			{
+				label: "物料版本",
+				prop: "bomVersion",
+				search: true,
+				type: "select",
+			},
+			{
 				label: "物料编码",
 				label: "物料编码",
 				prop: "materialCode",
 				prop: "materialCode",
 				hide: true
 				hide: true
@@ -456,6 +462,73 @@ export const tableConfig = {
 		],
 		],
 	},
 	},
 
 
+	OP_CHECK: {
+		url: "/api/v1/op/base/check",
+		column: [
+			{
+			  label: "点检项名称",
+			  prop: "checkName",
+			  span: 12,
+			  labelWidth: '150',
+			  search: true,
+			  editDisabled: true,
+			},
+			{
+			  label: "点检项编码",
+			  prop: "checkCode",
+			  labelWidth: '150',
+			  editDisabled: true,
+			  span: 12,
+			  search: true,
+			},
+			{
+			  label: "内容",
+			  prop: "content",
+			  span: 12,
+			  search: false,
+			},
+		],
+	},
+	
+	ESOP: {
+		url: "/api/v1/base/drawing",
+		column: [
+			{
+			  label: "图纸编码",
+			  prop: "drawingCode",
+			  span: 12,
+			  labelWidth: '150',
+			  search: true,
+			  editDisabled: true,
+			},
+			{
+			  label: "标题",
+			  prop: "drawingTitle",
+			  labelWidth: '150',
+			  editDisabled: true,
+			  span: 12,
+			  search: false,
+			},
+			{
+			  label: "版本号",
+			  prop: "drawingVersion",
+			  span: 12,
+			  search: false,
+			},
+			{
+			  label: "图纸",
+			  prop: "drawingPath",
+			  type: "img",
+			  span: 24,
+			  display: false,
+			  slot: true,
+			  // formatter: (row, column, cellValue, index) => {
+			  //   return `${row.drawingPath}`;
+			  // },
+			}
+		],
+	},
+
 	USERS: {
 	USERS: {
 		url: "/api/v1/sys/employeeSkill/users",
 		url: "/api/v1/sys/employeeSkill/users",
 		column: [
 		column: [

+ 15 - 3
src/components/CommonTable/index.vue

@@ -48,8 +48,7 @@ const props = defineProps({
 });
 });
 
 
 const isShowTable = ref(false);
 const isShowTable = ref(false);
-
-const startSelect = (param) => {
+const startSelect = async (param) => {
   if (param) {
   if (param) {
     commonConfig.value.params = param;
     commonConfig.value.params = param;
   }
   }
@@ -57,6 +56,19 @@ const startSelect = (param) => {
   isShowTable.value = true;
   isShowTable.value = true;
 };
 };
 
 
+/**
+ * propName 要跟字典配置的key一致
+ * dictData 字典数据, 注意props的value和label
+ * */
+const refreshDictData = (propName, dictData, keyName = "value") => {
+  nextTick(() => {
+    if (dictData && dictData.length > 0 && crudRef.value) {
+      crudRef.value.updateDic(propName, dictData);
+      search.value[propName] = dictData[0][keyName];
+    }
+  });
+};
+
 // 传入一个url,后面不带/
 // 传入一个url,后面不带/
 const {
 const {
   url,
   url,
@@ -153,5 +165,5 @@ const onSelected = () => {
   isShowTable.value = false;
   isShowTable.value = false;
 };
 };
 
 
-defineExpose({ startSelect });
+defineExpose({ startSelect, refreshDictData });
 </script>
 </script>

+ 89 - 0
src/components/PDFView/index.vue

@@ -0,0 +1,89 @@
+<template>
+  <el-button
+    v-if="contentType === 'button'"
+    :type="btnType"
+    :link="isLink"
+    @click="showPdf"
+  >
+    {{ btnText }}
+  </el-button>
+  <VuePdfEmbed
+    v-else
+    :source="pdfSource"
+    :page="pageNumber"
+    annotation-layer
+    text-layer
+    @click="showPdf"
+  />
+  <el-drawer
+    v-if="needToShowPdf"
+    v-model="visible"
+    :footer="false"
+    :header="false"
+    :show-close="false"
+    destroy-on-close
+    direction="rtl"
+    size="972px"
+  >
+    <VuePdfEmbed
+      :source="pdfSource"
+      :page="showPdfNumber"
+      annotation-layer
+      text-layer
+    />
+  </el-drawer>
+</template>
+
+<script lang="ts" setup>
+import VuePdfEmbed from "vue-pdf-embed";
+// essential styles
+import "vue-pdf-embed/dist/style/index.css";
+
+// optional styles
+import "vue-pdf-embed/dist/style/annotationLayer.css";
+import "vue-pdf-embed/dist/style/textLayer.css";
+
+// either URL, Base64, binary, or document proxy
+const props = defineProps({
+  pdfSource: {
+    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);
+
+const showPdf = () => {
+  visible.value = true;
+};
+</script>
+
+<style lang="scss" scoped></style>

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

@@ -0,0 +1,105 @@
+<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">
+        文件类型限制为.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)"
+      >
+        {{ file.name }}
+      </el-tag>
+    </div>
+  </el-upload>
+</template>
+<script lang="ts" setup>
+import { ref } from "vue";
+
+const props = defineProps({
+  size: {
+    type: Number,
+    default: 4,
+  },
+  limit: {
+    type: Number,
+    default: 1,
+  },
+  src: {
+    type: String,
+    default: "",
+  },
+  srcList: {
+    type: Array,
+    default: [],
+  },
+});
+
+const loading = ref(false);
+
+const emit = defineEmits(["update:src", "update:srcList"]);
+
+// 上传文件成功返回的值
+const src = useVModel(props, "src", emit); //单文件用这个
+const srcList = useVModel(props, "srcList", emit); //多文件用这个
+
+import { UploadFile, UploadFiles, UploadUserFile } from "element-plus";
+import { uploadFileApi } from "@/api/file";
+
+// el-upload 绑定的值
+const fileList = ref<UploadUserFile[]>([]);
+
+const handleChange = async (uploadFile: UploadFile) => {
+  if (uploadFile.size! > props.size * 1048 * 1048) {
+    ElMessage.warning(`上传文件不能大于${props.size}M`);
+    return;
+  }
+  loading.value = true;
+  uploadFileApi(uploadFile.raw as File)
+    .then((res: any) => {
+      loading.value = false;
+      src.value = res.data.fileUrl;
+      srcList.value.push(res.data.fileUrl);
+    })
+    .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);
+};
+</script>
+
+<style scoped lang="scss">
+.tip {
+  font-size: 12px;
+  color: #e6a23c;
+  margin-top: 5px;
+}
+.file-item {
+  margin-left: 10px;
+}
+</style>

+ 6 - 4
src/components/Upload/SingleUpload.vue

@@ -8,7 +8,7 @@
     :before-upload="handleBeforeUpload"
     :before-upload="handleBeforeUpload"
     :http-request="uploadFile"
     :http-request="uploadFile"
   >
   >
-    <img v-if="imgUrl" :src="imgUrl" class="single-uploader__image" />
+    <img v-if="imgUrl" :src="photoSource" class="single-uploader__image" />
     <el-icon v-else class="single-uploader__icon"><i-ep-plus /></el-icon>
     <el-icon v-else class="single-uploader__icon"><i-ep-plus /></el-icon>
   </el-upload>
   </el-upload>
 </template>
 </template>
@@ -32,6 +32,7 @@ const props = defineProps({
 
 
 const emit = defineEmits(["update:modelValue"]);
 const emit = defineEmits(["update:modelValue"]);
 const imgUrl = useVModel(props, "modelValue", emit);
 const imgUrl = useVModel(props, "modelValue", emit);
+const photoSource = ref<string>("");
 
 
 /**
 /**
  * 自定义图片上传
  * 自定义图片上传
@@ -39,18 +40,19 @@ const imgUrl = useVModel(props, "modelValue", emit);
  * @param options
  * @param options
  */
  */
 async function uploadFile(options: UploadRequestOptions): Promise<any> {
 async function uploadFile(options: UploadRequestOptions): Promise<any> {
-  const res = await uploadFileApi(options.file);
+  const res: any = await uploadFileApi(options.file);
   //绝对路径
   //绝对路径
   // imgUrl.value = import.meta.env.VITE_APP_UPLOAD_URL + res.data;
   // imgUrl.value = import.meta.env.VITE_APP_UPLOAD_URL + res.data;
   //使用相对路径
   //使用相对路径
-  imgUrl.value = res.data;
+  imgUrl.value = res.data.fileUrl + "";
+  photoSource.value = import.meta.env.VITE_APP_UPLOAD_URL + res.data.fileUrl;
 }
 }
 
 
 /**
 /**
  * 限制用户上传文件的格式和大小
  * 限制用户上传文件的格式和大小
  */
  */
 function handleBeforeUpload(file: UploadRawFile) {
 function handleBeforeUpload(file: UploadRawFile) {
-  if (file.size > 2 * 1048 * 1048) {
+  if (file.size > 4 * 1048 * 1048) {
     ElMessage.warning("上传图片不能大于2M");
     ElMessage.warning("上传图片不能大于2M");
     return false;
     return false;
   }
   }

+ 45 - 11
src/hooks/userCrud.ts

@@ -112,13 +112,51 @@ export const useCrud = (config?: UseCrudConfig) => {
           },
           },
         });
         });
         if (res?.data) {
         if (res?.data) {
-		  if(res?.data instanceof Array){
-			 data.value = res?.data || []
-			 page.value.total = res?.data?.length || 0
-		  }else{
-			data.value = res?.data?.records || [];
-			page.value.total = res?.data?.totalCount || 0;
-		  }
+          if (res?.data instanceof Array) {
+            data.value = res?.data || [];
+            page.value.total = res?.data?.length || 0;
+          } else {
+            data.value = res?.data?.records || [];
+            page.value.total = res?.data?.totalCount || 0;
+          }
+        }
+        config?.done && config?.done();
+      } catch (err) {
+        config?.loading && config?.loading();
+      } finally {
+        config?.done && config?.done();
+      }
+    },
+    dataEditList: async (config?: UseCrudConfig) => {
+      handleSearchData();
+      try {
+        const res = await request({
+          url: `${url.value}/page`,
+          method: "post",
+          data: {
+            pageNo: page.value.currentPage,
+            pageSize: page.value.pageSize,
+            ...search.value,
+            ...(commonConfig.value?.params ?? {}),
+          },
+        });
+        if (res?.data) {
+          if(res?.data instanceof Array){
+            data.value = res?.data || []
+            page.value.total = res?.data?.length || 0
+          }else{
+            data.value = res?.data?.records || [];
+            for (let i = 0; i < data.value.length; i++) {
+              data.value[i].$cellEdit = true;
+              if(data.value[i].children!=undefined&&data.value[i].children!=null&&data.value[i].children.length > 0 ){
+                for(let j=0;j < data.value[i].children.length; j++){
+                  data.value[i].children[j].$cellEdit = true;
+                }
+              }
+            }
+            console.info(data.value);
+            page.value.total = res?.data?.totalCount || 0;
+          }
 
 
         }
         }
         config?.done && config?.done();
         config?.done && config?.done();
@@ -141,9 +179,6 @@ export const useCrud = (config?: UseCrudConfig) => {
         if (res?.data) {
         if (res?.data) {
           data.value = res?.data || [];
           data.value = res?.data || [];
         }
         }
-        for (let i = 0; i < data.value.length; i++) {
-          data.value[i].$cellEdit = true;
-        }
         config?.done && config?.done();
         config?.done && config?.done();
       } catch (err) {
       } catch (err) {
         config?.loading && config?.loading();
         config?.loading && config?.loading();
@@ -152,7 +187,6 @@ export const useCrud = (config?: UseCrudConfig) => {
       }
       }
     },
     },
     createRow: (row: any, done: () => void, loading: () => void) => {
     createRow: (row: any, done: () => void, loading: () => void) => {
-      console.info(row);
       save({ row: row, done: done, loading: loading });
       save({ row: row, done: done, loading: loading });
     },
     },
 
 

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

@@ -23,8 +23,10 @@ export const useDictionaryStore = defineStore("dictionaryStore", () => {
     "danwei_type",
     "danwei_type",
     "trace_type",
     "trace_type",
     "skill_type",
     "skill_type",
+    "drawing_type",
+    "vehicle_level",
   ];
   ];
-  const dicts = ref<{ string?: any[] }>({});
+  const dicts = ref<{ [key: string]: any[] }>({});
   function checkDicts() {
   function checkDicts() {
     if (JSON.stringify(dicts.value) === "{}") {
     if (JSON.stringify(dicts.value) === "{}") {
       getUserDicts(types).then((res) => {
       getUserDicts(types).then((res) => {

+ 1 - 1
src/utils/request.ts

@@ -43,7 +43,7 @@ service.interceptors.response.use(
     if (error.response.data) {
     if (error.response.data) {
       const { code, msg } = error.response.data;
       const { code, msg } = error.response.data;
       // token 过期,重新登录
       // token 过期,重新登录
-      if (code === "A0230") {
+      if (code === "4106") {
         ElMessageBox.confirm("当前页面已失效,请重新登录", "提示", {
         ElMessageBox.confirm("当前页面已失效,请重新登录", "提示", {
           confirmButtonText: "确定",
           confirmButtonText: "确定",
           cancelButtonText: "取消",
           cancelButtonText: "取消",

+ 6 - 0
src/views/base/bom/columns.ts

@@ -40,6 +40,12 @@ export const columns = [
     type: "number",
     type: "number",
     precision: 2,
     precision: 2,
   },
   },
+  {
+    label: "版本号",
+    prop: "bomVersion",
+    type: "number",
+    precision: 1,
+  },
 
 
 
 
 ];
 ];

+ 150 - 0
src/views/base/bom/components/version-page.vue

@@ -0,0 +1,150 @@
+<template>
+
+
+  <div class="mainContentBox">
+    <avue-form
+      ref="formRef"
+      v-model="form"
+      :option="option"
+      @submit="rowSave"
+    >
+      <template #drawingPath="scope">
+        <single-upload v-model="form.drawingPath" />
+      </template>
+    </avue-form>
+    <avue-crud
+      ref="crudRef"
+      v-model:search="search"
+      v-model="form"
+      :data="data"
+      :option="option"
+      v-model:page="page"
+      @row-save="createRow"
+      @row-click="rowClick"
+      @row-update="updateRow"
+      @row-del="deleteRow"
+      @search-change="searchChange"
+      @search-reset="resetChange"
+      @size-change="dataList"
+      @current-change="dataList"
+      search-option="false"
+    >
+
+
+    </avue-crud>
+    <div class="detail-footer">
+      <el-button type="primary" @click="onSelected"> 确定 </el-button>
+      <el-button @click="cancelWindow">取消</el-button>
+
+    </div>
+  </div>
+
+
+
+</template>
+
+<script setup>
+  import { ref, getCurrentInstance } from "vue";
+  import { useCrud } from "@/hooks/userCrud";
+  import ButtonPermKeys from "@/common/configs/buttonPermission";
+  import { useCommonStoreHook } from "@/store";
+
+  const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+  import { useDictionaryStoreHook } from "@/store";
+  const test = () => {
+    isShowTable.value = true;
+    tableType.value = tableType.value == 1 ? 2 : 1;
+  };
+
+  // 传入一个url,后面不带/
+  const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+    useCrud({
+      src: "/api/v1/base/bomVersion",
+    });
+  const commonTableEmits = defineEmits(["selectedSure"]);
+  const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
+    Methords; //增删改查
+  const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
+  const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
+  // checkBtnPerm(ButtonPermKeys.PLAN.BTNS.order_add) :permission="permission"
+  // const permission = reactive({
+  //   delBtn: checkPerm(buttonPermission.PLAN.BTNS.order_del),
+  //   addBtn: checkPerm(buttonPermission.PLAN.BTNS.order_add),
+  //   editBtn: checkPerm(buttonPermission.PLAN.BTNS.order_edit),
+  //   menu: true,
+  // });
+  function rowSave(form2,done,loading) {
+    form.value.materialCode=props.materialCode;
+    createRow(form,done,loading);
+
+  }
+
+
+
+  const crudRef = ref(null); //crudRef.value 获取avue-crud对象
+
+  onMounted(() => {
+    console.log(props)
+    search.value.materialCode=props.materialCode;
+    dataList();
+  });
+
+
+  const uploadFinished = () => {
+    // 上传完成后的刷新操作
+    page.currentPage = 1;
+    dataList();
+  };
+
+
+
+
+  // 设置表格列或者其他自定义的option
+  option.value = Object.assign(option.value, {
+    highlightCurrentRow: true,
+    align:'center',
+    menuAlign:'center',
+    column: [
+      {
+        label: "版本号",
+        prop: "bomVersion",
+        type:"number",
+        controlsPosition: '',
+        min:1.0,
+        precision: 1,
+      },
+      { label: "物料编码", prop: "materialCode", width: 130,overHidden: true,display:false,hide:true},
+
+
+
+      ],
+    viewBtn: false,
+    addBtn:false,
+  });
+  const props = defineProps({
+    materialCode: {
+      type: String,
+      default: () => {
+        return 0;
+      }
+    },
+    dialog:{
+      type:Object,
+      default:()=>{
+        return {};
+      }
+    }
+  })
+  const selectRowValue = ref({});
+  const rowClick = (row) => {
+    selectRowValue.value = row;
+  };
+  const onSelected = () => {
+    commonTableEmits("selectedSure", selectRowValue.value);
+    props.dialog.visible = false;
+  };
+  const cancelWindow=()=>{
+    props.dialog.visible = false;
+  }
+</script>
+

+ 59 - 8
src/views/base/bom/index.vue

@@ -20,12 +20,26 @@
       @selection-change="selectionChange"
       @selection-change="selectionChange"
     >
     >
       <template #menu-left="{ size }">
       <template #menu-left="{ size }">
+        <div style="display:flex">
         <el-button
         <el-button
           type="primary"
           type="primary"
           icon="el-icon-plus"
           icon="el-icon-plus"
           @click="openMaterial"
           @click="openMaterial"
-          >新增</el-button
-        ></template>
+          >新增</el-button>
+           <el-select v-model="version" placeholder="请选择BOM版本" style="width:150px;margin-left:15px" @click="openBomVersion">
+          <el-option
+            v-for="item in options"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+
+          </div>
+
+
+      </template>
 
 
         <CommonTable
         <CommonTable
           ref="ctableRef"
           ref="ctableRef"
@@ -40,13 +54,18 @@
 
 
         </div>
         </div>
       </template>
       </template>
+
       <template #menu-right="{}">
       <template #menu-right="{}">
+
+
         <el-dropdown split-button
         <el-dropdown split-button
           >导入
           >导入
           <template #dropdown>
           <template #dropdown>
+
             <el-dropdown-menu>
             <el-dropdown-menu>
+
               <el-dropdown-item
               <el-dropdown-item
-                @click="downloadTemplate('/api/v1/plan/order/template')"
+                @click="downloadTemplate('/api/v1/base/materialBom/template')"
               >
               >
                 <i-ep-download />下载模板
                 <i-ep-download />下载模板
               </el-dropdown-item>
               </el-dropdown-item>
@@ -64,7 +83,14 @@
       tableType="MARTERIAL"
       tableType="MARTERIAL"
       @selected-sure="onSelectedFinish"
       @selected-sure="onSelectedFinish"
     />
     />
-
+    <el-dialog
+      v-model="dialog.visible"
+      :title="dialog.title"
+      width="900px"
+      @close="dialog.visible = false"
+    >
+      <version-page  :materialCode="route.params.materialCode" :dialog="dialog"  @selected-sure="selectedFinish"/>
+    </el-dialog>
   </div>
   </div>
 </template>
 </template>
 <script setup lang="ts">
 <script setup lang="ts">
@@ -99,14 +125,27 @@ const openMaterial=()=>{
     ctableRef.value.startSelect();
     ctableRef.value.startSelect();
   }
   }
 }
 }
-const formData=ref({});
+const openBomVersion=()=>{
+
+
+  dialog.visible=true;
+}
+const version=ref({
+    value: '0',
+    label: '请选择BOM版本',
+});
+const options=ref([]);
 const dataBomLists=()=>{
 const dataBomLists=()=>{
-  search.value.materialCode=route.value.materialCode;
+  search.value.materialCode=route.params.materialCode;
   dataNoPageList();
   dataNoPageList();
 }
 }
 
 
 const ctableRef = ref(null);
 const ctableRef = ref(null);
-
+const dialog = reactive({
+  title: "BOM版本",
+  visible: false,
+});
+const material=ref(null);
 const binding = (row) => {
 const binding = (row) => {
   if (ctableRef.value) {
   if (ctableRef.value) {
     ctableRef.value.startSelect();
     ctableRef.value.startSelect();
@@ -114,6 +153,7 @@ const binding = (row) => {
 };
 };
 const onSelected=()=>{
 const onSelected=()=>{
   for(var i=0;i<data.value.length;i++){
   for(var i=0;i<data.value.length;i++){
+
     if(data.value[i].bomMaterialNumber<=0){
     if(data.value[i].bomMaterialNumber<=0){
       ElMessage({
       ElMessage({
         message: data.value[i].bomMaterialName+"数量不能为0",
         message: data.value[i].bomMaterialName+"数量不能为0",
@@ -183,8 +223,9 @@ const uploadFinished = () => {
   dataNoPageList();
   dataNoPageList();
 };
 };
 const importExcelData = () => {
 const importExcelData = () => {
+
   if (uploadRef.value) {
   if (uploadRef.value) {
-    uploadRef.value.show("/api/v1/plan/order/import");
+    uploadRef.value.show("/api/v1/base/materialBom/import?"+route.params.materialCode);
   }
   }
 };
 };
 
 
@@ -202,6 +243,7 @@ const routeBack =()=>{
   router.back();
   router.back();
 }
 }
 const onSelectedFinish = (selectedValue) => {
 const onSelectedFinish = (selectedValue) => {
+
   for(var i=0;i<data.value.length;i++){
   for(var i=0;i<data.value.length;i++){
     if(data.value[i].bomMaterialCode===selectedValue.materialCode){
     if(data.value[i].bomMaterialCode===selectedValue.materialCode){
       ElMessage({
       ElMessage({
@@ -215,6 +257,7 @@ const onSelectedFinish = (selectedValue) => {
     materialCode:route.params.materialCode,
     materialCode:route.params.materialCode,
     bomMaterialCode:selectedValue.materialCode,
     bomMaterialCode:selectedValue.materialCode,
     bomMaterialName:selectedValue.materialName,
     bomMaterialName:selectedValue.materialName,
+    bomVersion:version.value.value,
     bomMaterialAttribute:selectedValue.attributeDictValue,
     bomMaterialAttribute:selectedValue.attributeDictValue,
     bomMaterialNumber:0,
     bomMaterialNumber:0,
     $cellEdit:true,
     $cellEdit:true,
@@ -236,6 +279,14 @@ const queryMaterialDetail = () => {
     }
     }
   );
   );
 };
 };
+
+const selectedFinish=(selectedValue)=> {
+
+  version.value.value=selectedValue.bomVersion;
+  version.value.label=selectedValue.bomVersion;
+  search.value.bomVersion = version.value.value;
+  dataNoPageList();
+}
 </script>
 </script>
 <style type="text/css">
 <style type="text/css">
   .title-detail{
   .title-detail{

+ 51 - 9
src/views/base/craftManagement/route/components/bottomTable.vue

@@ -17,14 +17,15 @@
       @size-change="dataList"
       @size-change="dataList"
       @current-change="dataList"
       @current-change="dataList"
     >
     >
-      <template #imgUrl-form="scope">
-        <single-upload v-model="form.imgUrl" />
-      </template>
-      <template #imgUrl="{ row }">
+      <!-- <template #filePath-form="scope">
+        <single-upload v-model="form.filePath" />
+        <FilesUpload v-model:src="form.filePath" v-model:src-list="form.filePath" />
+      </template> -->
+      <!-- <template #filePath="{ row }">
         <el-button link type="primary" @click.stop="imgUrlClick(row)">{{
         <el-button link type="primary" @click.stop="imgUrlClick(row)">{{
-          row.imgUrl
+          row.filePath
         }}</el-button>
         }}</el-button>
-      </template>
+      </template> -->
     </avue-crud>
     </avue-crud>
     <CommonTable
     <CommonTable
       ref="commonTableRef"
       ref="commonTableRef"
@@ -41,7 +42,7 @@
 import { ref, getCurrentInstance } from "vue";
 import { ref, getCurrentInstance } from "vue";
 import { useCrud } from "@/hooks/userCrud";
 import { useCrud } from "@/hooks/userCrud";
 import { getTableConfig } from "./configs";
 import { getTableConfig } from "./configs";
-import { saveCompoents } from "@/api/craft/process/index";
+import { saveCompoents, getBomVersion } from "@/api/craft/process/index";
 import SingleUpload from "@/components/Upload/SingleUpload.vue";
 import SingleUpload from "@/components/Upload/SingleUpload.vue";
 
 
 const props = defineProps({
 const props = defineProps({
@@ -72,8 +73,38 @@ const crudRef = ref(null); //crudRef.value 获取avue-crud对象
 
 
 const startCreat = () => {
 const startCreat = () => {
   if (props.tableType === "wuliaocaiji") {
   if (props.tableType === "wuliaocaiji") {
-	  //根据物料编码获取对应的物料BOM
-    commonTableRef.value && commonTableRef.value.startSelect({ materialCode: route.query.prodtCode });
+    commonTableType.value = "MARTERIAL_BOM";
+    if (!route.query.prodtCode) {
+      ElMessage.error("物料编号读取错误");
+      return;
+    }
+    //根据物料编码和版本号获取对应的物料BOM
+    let bomParam = {
+      materialCode: route.query.prodtCode,
+    };
+    getBomVersion(bomParam).then((res) => {
+      let resListMap = [];
+      //说明时物料采集的添加框 进行物料采集的下拉框数据获取
+      res?.data.forEach((versions) => {
+        resListMap.push({
+          label: versions.bomVersion,
+          value: versions.bomVersion,
+        });
+      });
+      //根据物料编码和版本号获取对应的物料BOM
+      commonTableRef.value?.startSelect({
+        materialCode: route.query.prodtCode,
+      });
+      commonTableRef.value?.refreshDictData("bomVersion", resListMap, "value");
+    });
+  } else if (props.tableType === "dianjian") {
+    commonTableType.value = "OP_CHECK";
+    commonTableRef.value?.startSelect();
+  } else if (props.tableType === "ESOP") {
+    commonTableType.value = "ESOP";
+    commonTableRef.value?.startSelect({
+      materialCode: route.query.prodtCode,
+    });
   } else {
   } else {
     crudRef.value && crudRef.value.rowAdd();
     crudRef.value && crudRef.value.rowAdd();
   }
   }
@@ -100,9 +131,20 @@ const onSelectedFinish = (itemValue) => {
     form.value.itemName = itemValue.bomMaterialName;
     form.value.itemName = itemValue.bomMaterialName;
     form.value.itemCode = itemValue.bomMaterialCode;
     form.value.itemCode = itemValue.bomMaterialCode;
     form.value.itemModel = itemValue.bomMaterialAttribute;
     form.value.itemModel = itemValue.bomMaterialAttribute;
+    form.value.recordVersion = itemValue.bomVersion;
     form.value.num = itemValue.bomMaterialNumber;
     form.value.num = itemValue.bomMaterialNumber;
     form.value.traceType = "S";
     form.value.traceType = "S";
     form.value.unit = itemValue.unitDictValue;
     form.value.unit = itemValue.unitDictValue;
+  } else if (props.tableType === "dianjian") {
+    form.value.checkName = itemValue.checkName;
+    form.value.checkCode = itemValue.checkCode;
+    form.value.content = itemValue.content;
+  } else if (props.tableType === "ESOP") {
+    form.value.filePath = itemValue.drawingPath;
+    form.value.drawingCode = itemValue.drawingCode;
+    form.value.recordVersion = itemValue.drawingVersion;
+    form.value.sortNum = itemValue.sort;
+    form.value.title = itemValue.drawingTitle;
   }
   }
 };
 };
 
 

+ 244 - 226
src/views/base/craftManagement/route/components/configs.ts

@@ -1,234 +1,252 @@
 import { useDictionaryStoreHook } from "@/store";
 import { useDictionaryStoreHook } from "@/store";
 const { dicts } = useDictionaryStoreHook();
 const { dicts } = useDictionaryStoreHook();
 
 
-export const getTableConfig = (id: string) => {
-  return {
-    // 获取工序记录项信息信息
-    jiluxiang: {
-      url: `/api/v1/op/operationRecord`,
-      column: [
-        {
-          label: "工序id",
-          prop: "operationId",
-          display: false,
-          hide: true,
-          value: id,
-        },
-        { label: "记录项", prop: "thName" },
-        {
-          label: "单位",
-          prop: "unit",
-          search: true,
-          filterable: true,
-          type: "select",
-          dataType: "string",
-          dicData: dicts.danwei_type,
-          props: { label: "dictLabel", value: "dictValue" },
-        },
-        { label: "标准值", prop: "standard" },
-        { label: "上限值", prop: "upper" },
-        { label: "下限值", prop: "lower" },
-      ],
-    },
-    //工序物料
-    wuliaocaiji: {
-      url: "/api/v1/op/operationItem",
-      column: [
-        {
-          label: "工序id",
-          prop: "operationId",
-          display: false,
-          hide: true,
-          value: id,
-        },
-        { label: "物料名称", prop: "itemName" },
-        { label: "物料编码", prop: "itemCode" },
-        { label: "物料规格", prop: "itemModel" },
-        { label: "所需数量", prop: "num" },
-        {
-          label: "追溯类型",
-          prop: "traceType",
-          search: true,
-          filterable: true,
-          type: "select",
-          dataType: "string",
-          dicData: dicts.trace_type,
-          props: { label: "dictLabel", value: "dictValue" },
-        },
-        {
-          label: "单位",
-          prop: "unit",
-          search: true,
-          filterable: true,
-          type: "select",
-          dataType: "string",
-          dicData: dicts.danwei_type,
-          props: { label: "dictLabel", value: "dictValue" },
-        },
-        {
-          label: "是否需要",
-          prop: "isTrace",
-          type: "radio", //类型为单选框
-          dicData: [
-            {
-              label: "需采集物料",
-              value: 1,
-            },
-            {
-              label: "非必须采集物料",
-              value: 0,
-            },
-          ],
-          value: 1,
-          rules: [
-            {
-              required: true,
-              message: "是否需要",
-              trigger: "blur",
-            },
-          ],
-        },
-      ],
-    },
-    dianjian: {
-      url: `/api/v1/op/operationCheck`,
-      column: [
-        {
-          label: "工序id",
-          prop: "operationId",
-          display: false,
-          hide: true,
-          value: id,
-        },
-        { label: "点检名称", prop: "checkName" },
-        { label: "点检编码", prop: "checkCode" },
-        { label: "内容", prop: "content" },
-        {
-          label: "单位",
-          prop: "unit",
-          search: true,
-          filterable: true,
-          type: "select",
-          dataType: "string",
-          dicData: dicts.danwei_type,
-          props: { label: "dictLabel", value: "dictValue" },
-        },
-        { label: "标准值", prop: "standard" },
-        { label: "上限值", prop: "upper" },
-        { label: "下限值", prop: "lower" },
-      ],
-    },
-    shebeijilu: {
-      url: "/api/v1/op/operationEquit",
-      column: [
-        {
-          label: "工序id",
-          prop: "operationId",
-          display: false,
-          hide: true,
-          value: id,
-        },
-        { label: "精度要求", prop: "accuracy" },
-        { label: "所需数量", prop: "num", display: false, hide: true },
-        {
-          label: "设备类型",
-          prop: "equitType",
-          search: true,
-          filterable: true,
-          type: "select",
-          dataType: "string",
-          dicData: dicts.device_type,
-          props: { label: "dictLabel", value: "dictValue" },
-        },
-        {
-          label: "必须采集",
-          prop: "collection",
-          type: "radio", //类型为单选框
-          dicData: [
-            {
-              label: "必须",
-              value: 1,
-            },
-            {
-              label: "非必须",
-              value: 0,
-            },
-          ],
-          value: 1,
-          rules: [
-            {
-              required: true,
-              message: "是否必须采集",
-              trigger: "blur",
-            },
-          ],
-        },
-      ],
-    },
-    ESOP: {
-      url: "/api/v1/op/esop",
-      column: [
-        {
-          label: "工序id",
-          prop: "operationId",
-          display: false,
-          hide: true,
-          value: id,
-        },
-        { label: "内容", prop: "content" },
-        { label: "标题", prop: "title" },
-        {
-          label: "文件",
-          prop: "imgUrl",
-          span: 24,
-          slot: true,
-          viewDisplay: false,
-        },
-      ],
-    },
-  };
+export const getTableConfig = (id : string) => {
+	return {
+		// 获取工序记录项信息信息
+		jiluxiang: {
+			url: `/api/v1/op/operationRecord`,
+			column: [
+				{
+					label: "工序id",
+					prop: "operationId",
+					display: false,
+					hide: true,
+					value: id,
+				},
+				{ label: "记录项", prop: "thName" },
+				{
+					label: "单位",
+					prop: "unit",
+					search: true,
+					filterable: true,
+					type: "select",
+					dataType: "string",
+					dicData: dicts.danwei_type,
+					props: { label: "dictLabel", value: "dictValue" },
+				},
+				{ label: "标准值", prop: "standard" },
+				{ label: "上限值", prop: "upper" },
+				{ label: "下限值", prop: "lower" },
+			],
+		},
+		//工序物料
+		wuliaocaiji: {
+			url: "/api/v1/op/operationItem",
+			column: [
+				{
+					label: "工序id",
+					prop: "operationId",
+					display: false,
+					hide: true,
+					value: id,
+				},
+				{ label: "物料名称", prop: "itemName", addDisabled: true, editDisabled: true },
+				{ label: "物料版本号", prop: "recordVersion", addDisabled: true, editDisabled: true },
+				{ label: "物料编码", prop: "itemCode", addDisabled: true, editDisabled: true },
+				{ label: "物料规格", prop: "itemModel", addDisabled: true, editDisabled: true },
+				{ label: "所需数量", prop: "num" },
+				{
+					label: "追溯类型",
+					prop: "traceType",
+					search: true,
+					filterable: true,
+					type: "select",
+					dataType: "string",
+					dicData: dicts.trace_type,
+					props: { label: "dictLabel", value: "dictValue" },
+				},
+				{
+					label: "单位",
+					prop: "unit",
+					search: true,
+					filterable: true,
+					type: "select",
+					dataType: "string",
+					dicData: dicts.danwei_type,
+					props: { label: "dictLabel", value: "dictValue" },
+				},
+				{
+					label: "是否需要",
+					prop: "isTrace",
+					type: "radio", //类型为单选框
+					dicData: [
+						{
+							label: "需采集物料",
+							value: 1,
+						},
+						{
+							label: "非必须采集物料",
+							value: 0,
+						},
+					],
+					value: 1,
+					rules: [
+						{
+							required: true,
+							message: "是否需要",
+							trigger: "blur",
+						},
+					],
+				},
+			],
+		},
+		dianjian: {
+			url: `/api/v1/op/operationCheck`,
+			column: [
+				{
+					label: "工序id",
+					prop: "operationId",
+					display: false,
+					hide: true,
+					value: id,
+				},
+				{ label: "点检名称", prop: "checkName", addDisabled: true, editDisabled: true },
+				{ label: "点检编码", prop: "checkCode", addDisabled: true, editDisabled: true },
+				{ label: "内容", prop: "content", addDisabled: true, editDisabled: true },
+				{
+					label: "单位",
+					prop: "unit",
+					search: true,
+					filterable: true,
+					type: "select",
+					dataType: "string",
+					dicData: dicts.danwei_type,
+					props: { label: "dictLabel", value: "dictValue" },
+				},
+				{ label: "标准值", prop: "standard" },
+				{ label: "上限值", prop: "upper" },
+				{ label: "下限值", prop: "lower" },
+			],
+		},
+		shebeijilu: {
+			url: "/api/v1/op/operationEquit",
+			column: [
+				{
+					label: "工序id",
+					prop: "operationId",
+					display: false,
+					hide: true,
+					value: id,
+				},
+				{ label: "精度要求", prop: "accuracy" },
+				{ label: "所需数量", prop: "num", display: false, hide: true },
+				{
+					label: "设备类型",
+					prop: "equitType",
+					search: true,
+					filterable: true,
+					type: "select",
+					dataType: "string",
+					dicData: dicts.device_type,
+					props: { label: "dictLabel", value: "dictValue" },
+				},
+				{
+					label: "必须采集",
+					prop: "collection",
+					type: "radio", //类型为单选框
+					dicData: [
+						{
+							label: "必须",
+							value: 1,
+						},
+						{
+							label: "非必须",
+							value: 0,
+						},
+					],
+					value: 1,
+					rules: [
+						{
+							required: true,
+							message: "是否必须采集",
+							trigger: "blur",
+						},
+					],
+				},
+			],
+		},
+		ESOP: {
+			url: "/api/v1/op/esop",
+			column: [
+				{
+					label: "工序id",
+					prop: "operationId",
+					display: false,
+					hide: true,
+					value: id,
+				},
+
+				{ label: "标题", prop: "title", addDisabled: true, editDisabled: true },
+				{ label: "展示页数", prop: "showAppointPageNum", type: "number" },
+				{ label: "总页数", prop: "pageNum", type: "number" },
+				{
+					label: "版本号", prop: "recordVersion", type: "number", addDisabled: true, editDisabled: true,
+					rules: [
+						{
+							required: true,
+							message: "版本号",
+							trigger: "blur",
+						},
+					],
+				},
+				{ label: "图纸编码", prop: "drawingCode", hide: true, addDisabled: true, editDisabled: true, },
+				{ label: "内容", prop: "content", hide: true,addDisabled: true, editDisabled: true, },
+				{ label: "排序", prop: "sortNum", hide: true,addDisabled: true, editDisabled: true, },
+				{
+					label: "文件",
+					prop: "filePath",
+					span: 24,
+					type: "img",
+					slot: true,
+					viewDisplay: false,
+					addDisabled: true, editDisabled: true
+				},
+			],
+		},
+	};
 };
 };
 
 
 // 工艺工序组件路径的组件类别
 // 工艺工序组件路径的组件类别
 interface comType {
 interface comType {
-  compentName: string;
-  compentType: string;
+	compentName : string;
+	compentType : string;
 }
 }
-export const comTypes: comType[] = [
-  {
-    compentName: "记录项",
-    compentType: "jiluxiang",
-  },
-  {
-    compentName: "物料采集",
-    compentType: "wuliaocaiji",
-  },
-  {
-    compentName: "ESOP",
-    compentType: "ESOP",
-  },
-  {
-    compentName: "点检",
-    compentType: "dianjian",
-  },
-  {
-    compentName: "设备记录",
-    compentType: "shebeijilu",
-  },
-  {
-    compentName: "紧固",
-    compentType: "jingu",
-  },
-  {
-    compentName: "调试配对",
-    compentType: "tiaoshipipei",
-  },
-  {
-    compentName: "铭牌绑定",
-    compentType: "mingpai",
-  },
-  {
-    compentName: "多媒体采集",
-    compentType: "duomeiticaiji",
-  },
-];
+export const comTypes : comType[] = [
+	{
+		compentName: "记录项",
+		compentType: "jiluxiang",
+	},
+	{
+		compentName: "物料采集",
+		compentType: "wuliaocaiji",
+	},
+	{
+		compentName: "ESOP",
+		compentType: "ESOP",
+	},
+	{
+		compentName: "点检",
+		compentType: "dianjian",
+	},
+	{
+		compentName: "设备记录",
+		compentType: "shebeijilu",
+	},
+	{
+		compentName: "紧固",
+		compentType: "jingu",
+	},
+	{
+		compentName: "调试配对",
+		compentType: "tiaoshipipei",
+	},
+	{
+		compentName: "铭牌绑定",
+		compentType: "mingpai",
+	},
+	{
+		compentName: "多媒体采集",
+		compentType: "duomeiticaiji",
+	},
+];

+ 9 - 4
src/views/base/craftManagement/route/components/processComponent.vue

@@ -146,11 +146,16 @@ const clickToolCom = (com, index) => {
     ElMessage.warning("请先保存组件!!!");
     ElMessage.warning("请先保存组件!!!");
     return;
     return;
   }
   }
-  tipTitle = '编辑'+com.compentName
+  tipTitle.value = "编辑" + com.compentName;
   selectIndex.value = index;
   selectIndex.value = index;
   currentCom.value = com;
   currentCom.value = com;
-  if (com.compentType === "mingpai" || com.compentType === "duomeiticaiji"
-   || com.compentType === "tiaoshipipei" || com.compentType === "jingu") {
+  if (
+    com.compentType === "jiluxiang" ||
+    com.compentType === "mingpai" ||
+    com.compentType === "duomeiticaiji" ||
+    com.compentType === "tiaoshipipei" ||
+    com.compentType === "jingu"
+  ) {
     isNoneedEdit.value = true;
     isNoneedEdit.value = true;
   } else {
   } else {
     tableType.value = com.compentType;
     tableType.value = com.compentType;
@@ -175,7 +180,7 @@ const getNameClass = (index) => {
 };
 };
 
 
 // 底部table ===============
 // 底部table ===============
-let tipTitle = ref("编辑物料采集");
+let tipTitle = ref({});
 const bottomTableRef = ref({});
 const bottomTableRef = ref({});
 const tableType = ref("MARTERIAL_BOM");
 const tableType = ref("MARTERIAL_BOM");
 
 

+ 128 - 0
src/views/base/defectCheck/index.vue

@@ -0,0 +1,128 @@
+<template>
+  <div class="mainContentBox">
+    <avue-crud
+      ref="crudRef"
+      v-model:search="search"
+      v-model="form"
+      :data="data"
+      :option="option"
+      v-model:page="page"
+      @row-save="createRow"
+      @row-update="updateRow"
+      @row-del="deleteRow"
+      @search-change="searchChange"
+      @search-reset="resetChange"
+      @size-change="dataList"
+      @current-change="dataList"
+      @selection-change="selectionChange"
+    >
+      <template #menu-left="{ size }">
+        <el-button
+          :disabled="toDeleteIds.length < 1"
+          type="danger"
+          icon="el-icon-delete"
+          :size="size"
+          @click="multipleDelete"
+          >删除</el-button
+        >
+      </template>
+
+    </avue-crud>
+    <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+import ButtonPermKeys from "@/common/configs/buttonPermission";
+import { useCommonStoreHook, useDictionaryStoreHook } from "@/store";
+
+// 数据字典相关
+const { dicts } = useDictionaryStoreHook();
+
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/op/base/check",
+  });
+const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
+  Methords; //增删改查
+const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
+const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
+
+const crudRef = ref(null); //crudRef.value 获取avue-crud对象
+
+onMounted(() => {
+  // console.log("crudRef", crudRef)
+  dataList();
+});
+
+/**
+ * 上传excel相关
+ */
+const uploadRef = ref(null);
+const uploadFinished = () => {
+  // 上传完成后的刷新操作
+  page.currentPage = 1;
+  dataList();
+};
+const importExcelData = () => {
+  if (uploadRef.value) {
+    uploadRef.value.show("/api/v1/plan/order/import");
+  }
+};
+
+// 设置表格列或者其他自定义的option
+const switchOp = [
+  {
+    label: "",
+    value: 0,
+  },
+  {
+    label: "",
+    value: 1,
+  },
+];
+option.value = Object.assign(option.value, {
+  selection: true,
+  labelWidth: 110,
+  searchLabelWidth: 110,
+  column: [
+    {
+      label: "点检项名称",
+      prop: "checkName",
+      span: 12,
+      search: true,
+      editDisabled: true,
+      rules: [
+        {
+          required: true,
+          message: "点检项名称不能为空",
+          trigger: "blur",
+        },
+      ],
+    },
+    {
+      label: "点检项编码",
+      prop: "checkCode",
+	  editDisabled: true,
+      span: 12,
+      search: true,
+      rules: [
+        {
+          required: true,
+          message: "点检项编码不能为空",
+          trigger: "blur",
+        },
+      ],
+    },
+    {
+      label: "内容",
+      prop: "content",
+      span: 12,
+      search: false,
+    },
+  ],
+});
+</script>

+ 105 - 0
src/views/base/information/columns.ts

@@ -0,0 +1,105 @@
+import { useDictionaryStoreHook } from "@/store";
+const { dicts } = useDictionaryStoreHook();
+import {updateDrawaing} from "@/api/drawing";
+import { useCrud } from "@/hooks/userCrud";
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/base/drawing",
+  });
+const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
+  Methords;
+const drawing=reactive({});
+
+export const columns = [
+  { label: "图纸名称", prop: "drawingTitle", width: 130,overHidden: true,search: true ,rules: [{
+      required: true,
+      message: "请填写图纸名称",
+      trigger: "blur"
+    }],},
+  { label: "图纸编号", prop: "drawingCode", width: 140,search: true,overHidden: true,search: true ,rules: [{
+      required: true,
+      message: "请填写图纸编号",
+      trigger: "blur"
+    }],},
+  {
+    label: "图纸类型",
+    prop: "drawingDictValue",
+    search: true,
+    filterable: true,
+    type: 'select',
+    width: 100,overHidden: true,
+    dicData:dicts.drawing_type,
+    props: { label: "dictLabel", value: "dictValue" },
+    rules: [{
+      required: true,
+      message: "请选择物料属性",
+      trigger: "blur"
+    }],
+  },
+  {
+    label: "文件",
+    prop: "drawingPath",
+    span: 24,
+    slot: true,
+    hide:true,
+  },
+  { label: "文件",
+    prop: "drawing",
+    type: 'img',
+    span: 24,
+    display:false,
+    slot: true,
+    formatter: (row, column, cellValue, index) => {
+      return `${row.drawingPath}`;} },
+  {
+    label: "版本",
+    prop: "drawingVersion",
+    type:"number",
+    precision:1,
+    rules: [{
+      required: true,
+      message: "版本号不能为空",
+      trigger: "blur"
+    }]
+
+
+  },
+  {
+    label: "创建时间",
+    prop: "created",
+    display:false,
+  },
+  { label: "启用状态",
+    slot:true,
+    cell: true,
+    align: 'center',
+    headerAlign: 'center',
+    prop: "enable",
+    dicData: [{
+      label: '',
+      value: 0
+    }, {
+      label: '',
+      value: 1
+    }],
+    value: 1,
+    width: 100,
+    type: 'switch',
+    overHidden: true,
+    value:1,
+    click:(row, column, cellValue, index)=>{
+
+      drawing.id=row.row.id;
+      if(row.row.enable===1){
+        drawing.enable=0;
+      }
+      if(row.row.enable===0){
+        drawing.enable=1;
+      }
+      updateDrawaing(drawing).then(
+        ()=>{dataList();}
+
+      );
+   }
+  },
+];

+ 102 - 0
src/views/base/information/index.vue

@@ -0,0 +1,102 @@
+<template>
+  <div class="mainContentBox">
+    <avue-crud
+      ref="crudRef"
+      v-model:search="search"
+      v-model="form"
+      :data="data"
+      :option="option"
+      v-model:page="page"
+      @row-save="createRow"
+      @row-update="updateRow"
+      @row-del="deleteRow"
+      @search-change="searchChange"
+      @search-reset="resetChange"
+      @size-change="dataList"
+      @current-change="dataList"
+      @selection-change="selectionChange"
+    >
+      <template #drawingPath-form="scope">
+        <single-upload v-model="form.drawingPath" />
+      </template>
+      <template #menu="{row,index,type}">
+        <el-button @click="deleteRecord(row,index,done)"
+                   text
+                   type="primary"
+        >删除</el-button>
+      </template>
+    </avue-crud>
+
+
+    <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
+  </div>
+</template>
+<script setup lang="ts">
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import ButtonPermKeys from "@/common/configs/buttonPermission";
+import { columns } from "./columns";
+import { useCommonStoreHook, useDictionaryStoreHook } from "@/store";
+import {updateDrawaing} from "@/api/drawing";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+// 数据字典相关
+const { dicts } = useDictionaryStoreHook();
+
+const test = () => {
+  isShowTable.value = true;
+  tableType.value = tableType.value == 1 ? 2 : 1;
+};
+
+
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/base/drawing",
+  });
+const { dataEditList, createRow, updateRow, deleteRow, searchChange, resetChange } =
+  Methords; //增删改查
+const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
+const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
+// checkBtnPerm(ButtonPermKeys.PLAN.BTNS.order_add) :permission="permission"
+// const permission = reactive({
+//   delBtn: checkPerm(buttonPermission.PLAN.BTNS.order_del),
+//   addBtn: checkPerm(buttonPermission.PLAN.BTNS.order_add),
+//   editBtn: checkPerm(buttonPermission.PLAN.BTNS.order_edit),
+//   menu: true,
+// });
+
+const crudRef = ref(null); //crudRef.value 获取avue-crud对象
+const router = useRouter();
+
+onMounted(() => {
+  // console.log("crudRef", crudRef)
+  dataEditList();
+});
+
+
+
+/**
+ * 上传excel相关
+ */
+const uploadRef = ref(null);
+const uploadFinished = () => {
+  // 上传完成后的刷新操作
+  page.currentPage = 1;
+  dataEditList();
+};
+
+
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  selection: false,
+  viewBtn:false,
+  editBtn:false,
+
+  column: columns,
+});
+
+const deleteRecord=(row,index,done)=>{
+  deleteRow(row,index,done);
+  dataEditList();
+}
+</script>

+ 4 - 5
src/views/base/materials/columns.ts

@@ -26,7 +26,7 @@ export const columns = [
       trigger: "blur"
       trigger: "blur"
     }],
     }],
   },
   },
-  { label: "物料规格", prop: "spec", width: 100,overHidden: true,search: true,rules: [{
+  { label: "物料规格", prop: "spec", width: 100,overHidden: true,rules: [{
       required: true,
       required: true,
       message: "请填写物料规格",
       message: "请填写物料规格",
       trigger: "blur"
       trigger: "blur"
@@ -34,7 +34,6 @@ export const columns = [
   {
   {
     label: "单位",
     label: "单位",
     prop: "unitDictValue",
     prop: "unitDictValue",
-    search: true,
     filterable: true,
     filterable: true,
     type: "select",
     type: "select",
     dicData:dicts.danwei_type,
     dicData:dicts.danwei_type,
@@ -124,8 +123,8 @@ export const columns = [
     dicData:dicts.stage,
     dicData:dicts.stage,
     props: { label: "dictLabel", value: "dictValue" },
     props: { label: "dictLabel", value: "dictValue" },
   },
   },
-  { label: "客户型号", prop: "customerModel",width: 100,overHidden: true, search: true },
-  { label: "保质期(天)", prop: "qualityGuaranteePeriod",width: 100,overHidden: true, search: true },
+  { label: "客户型号", prop: "customerModel",width: 100,overHidden: true,  },
+  { label: "保质期(天)", prop: "qualityGuaranteePeriod",width: 100,overHidden: true, },
   {
   {
     label: "封装方法",
     label: "封装方法",
     prop: "packageDictValue",
     prop: "packageDictValue",
@@ -162,7 +161,7 @@ export const columns = [
       trigger: "blur"
       trigger: "blur"
     }],
     }],
   },
   },
-  { label: "筛选规范", prop: "selectionSpec",width: 150,overHidden: true, search: true , type: "textarea",span:18},
+  { label: "筛选规范", prop: "selectionSpec",width: 150,overHidden: true,  type: "textarea",span:18},
 
 
   { label: "备注", prop: "remark", width: 150,overHidden: true,type: "textarea", span:18 },
   { label: "备注", prop: "remark", width: 150,overHidden: true,type: "textarea", span:18 },
 ];
 ];

+ 153 - 169
src/views/base/materials/components/drawing-page.vue

@@ -1,13 +1,6 @@
 <template>
 <template>
-
-
   <div class="mainContentBox">
   <div class="mainContentBox">
-    <avue-form
-      ref="formRef"
-      v-model="form"
-      :option="option"
-      @submit="rowSave"
-    >
+    <avue-form ref="formRef" v-model="form" :option="option" @submit="rowSave">
       <template #drawingPath="scope">
       <template #drawingPath="scope">
         <single-upload v-model="form.drawingPath" />
         <single-upload v-model="form.drawingPath" />
       </template>
       </template>
@@ -29,7 +22,6 @@
       @selection-change="selectionChange"
       @selection-change="selectionChange"
       search-option="false"
       search-option="false"
     >
     >
-
       <template #menu-left="{ size }">
       <template #menu-left="{ size }">
         <el-button
         <el-button
           :disabled="toDeleteIds.length < 1"
           :disabled="toDeleteIds.length < 1"
@@ -37,10 +29,9 @@
           icon="el-icon-delete"
           icon="el-icon-delete"
           :size="size"
           :size="size"
           @click="multipleDelete"
           @click="multipleDelete"
-        >删除</el-button
+          >删除</el-button
         >
         >
       </template>
       </template>
-
     </avue-crud>
     </avue-crud>
     <CommonTable
     <CommonTable
       ref="ctableRef"
       ref="ctableRef"
@@ -49,183 +40,176 @@
       @selected-sure="onSelectedFinish"
       @selected-sure="onSelectedFinish"
     />
     />
   </div>
   </div>
-
 </template>
 </template>
 <script setup>
 <script setup>
-  import { ref, getCurrentInstance } from "vue";
-  import { useCrud } from "@/hooks/userCrud";
-  import ButtonPermKeys from "@/common/configs/buttonPermission";
-  import { useCommonStoreHook } from "@/store";
-
-  const { isShowTable, tableType } = toRefs(useCommonStoreHook());
-  import { useDictionaryStoreHook } from "@/store";
-  import {
-    addStationDevice,
-  } from "@/api/station";
-  const test = () => {
-    isShowTable.value = true;
-    tableType.value = tableType.value == 1 ? 2 : 1;
-  };
-
-  // 传入一个url,后面不带/
-  const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
-    useCrud({
-      src: "/api/v1/base/drawing",
-    });
-  const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
-    Methords; //增删改查
-  const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
-  const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
-  // checkBtnPerm(ButtonPermKeys.PLAN.BTNS.order_add) :permission="permission"
-  // const permission = reactive({
-  //   delBtn: checkPerm(buttonPermission.PLAN.BTNS.order_del),
-  //   addBtn: checkPerm(buttonPermission.PLAN.BTNS.order_add),
-  //   editBtn: checkPerm(buttonPermission.PLAN.BTNS.order_edit),
-  //   menu: true,
-  // });
-  function rowSave(form2,done,loading) {
-    form.value.associationCode=props.materialCode;
-    createRow(form,done,loading);
-
-  }
-
-
-
-  const crudRef = ref(null); //crudRef.value 获取avue-crud对象
-
-  onMounted(() => {
-    // console.log("crudRef", crudRef)
-    search.value.materialCode=props.materialCode;
-    dataList();
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import ButtonPermKeys from "@/common/configs/buttonPermission";
+import { useCommonStoreHook } from "@/store";
+
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+import { useDictionaryStoreHook } from "@/store";
+import { addStationDevice } from "@/api/station";
+const test = () => {
+  isShowTable.value = true;
+  tableType.value = tableType.value == 1 ? 2 : 1;
+};
+
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/base/drawing",
   });
   });
-
-  /**
-   * 上传excel相关
-   */
-  const uploadRef = ref(null);
-  const uploadFinished = () => {
-    // 上传完成后的刷新操作
-    page.currentPage = 1;
-    dataList();
-  };
-  const importExcelData = () => {
-    if (uploadRef.value) {
-      uploadRef.value.show("/api/v1/base/stationDevice");
-    }
-  };
-  const ctableRef=ref(null);
-  const deviceList=()=>{
-    ctableRef.value.startSelect();
+const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
+  Methords; //增删改查
+const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
+const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
+// checkBtnPerm(ButtonPermKeys.PLAN.BTNS.order_add) :permission="permission"
+// const permission = reactive({
+//   delBtn: checkPerm(buttonPermission.PLAN.BTNS.order_del),
+//   addBtn: checkPerm(buttonPermission.PLAN.BTNS.order_add),
+//   editBtn: checkPerm(buttonPermission.PLAN.BTNS.order_edit),
+//   menu: true,
+// });
+function rowSave(form2, done) {
+  form.value.associationCode = props.materialCode;
+  createRow(form, done, done);
+}
+
+const crudRef = ref(null); //crudRef.value 获取avue-crud对象
+
+onMounted(() => {
+  // console.log("crudRef", crudRef)
+  search.value.materialCode = props.materialCode;
+  dataList();
+});
+
+/**
+ * 上传excel相关
+ */
+const uploadRef = ref(null);
+const uploadFinished = () => {
+  // 上传完成后的刷新操作
+  page.currentPage = 1;
+  dataList();
+};
+const importExcelData = () => {
+  if (uploadRef.value) {
+    uploadRef.value.show("/api/v1/base/stationDevice");
   }
   }
+};
+const ctableRef = ref(null);
+const deviceList = () => {
+  ctableRef.value.startSelect();
+};
+
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  selection: true,
+  column: [
+    {
+      label: "物料编号",
+      prop: "associationCode",
+      hide: true,
+      display: false,
+    },
 
 
-  // 设置表格列或者其他自定义的option
-  option.value = Object.assign(option.value, {
-    selection: true,
-    column: [
-      {
-        label: "物料编号",
-        prop: "associationCode",
-        hide:true,
-        display:false,
-      },
-
-
-      {
+    {
       label: "图纸编号",
       label: "图纸编号",
       prop: "drawingCode",
       prop: "drawingCode",
-      rules: [{
-        required: true,
-        message: "图纸编号不能为空",
-        trigger: "blur"
-      }]
+      rules: [
+        {
+          required: true,
+          message: "图纸编号不能为空",
+          trigger: "blur",
+        },
+      ],
     },
     },
-      {
-        label: "图纸标题",
-        prop: "drawingTitle",
-        rules: [{
+    {
+      label: "图纸标题",
+      prop: "drawingTitle",
+      rules: [
+        {
           required: true,
           required: true,
           message: "图纸名称不能为空",
           message: "图纸名称不能为空",
-          trigger: "blur"
-        }],
-      },
-
-
-      {
-        label: "图纸类型",
-        prop: "drawingDictValue",
-        value:"material",
-        display: false,
-        hide:true,
-      },
-      {
-        label: "排序",
-        prop: "sort",
-        type:"number",
+          trigger: "blur",
+        },
+      ],
+    },
 
 
-      },
-      {
-        label: "版本",
-        prop: "drawingVersion",
-        type:"number",
-        precision:1,
-        rules: [{
+    {
+      label: "图纸类型",
+      prop: "drawingDictValue",
+      value: "material",
+      display: false,
+      hide: true,
+    },
+    {
+      label: "排序",
+      prop: "sort",
+      type: "number",
+    },
+    {
+      label: "版本",
+      prop: "drawingVersion",
+      type: "number",
+      precision: 1,
+      rules: [
+        {
           required: true,
           required: true,
           message: "版本号不能为空",
           message: "版本号不能为空",
-          trigger: "blur"
-        }]
-
-
-      },
-      {
-        label: "图纸上传",
-        prop: "drawingPath",
-        span: 24,
-        slot: true,
-        hide:true,
-        /*formatter: (row, column, cellValue, index) => {
+          trigger: "blur",
+        },
+      ],
+    },
+    {
+      label: "图纸上传",
+      prop: "drawingPath",
+      span: 24,
+      slot: true,
+      hide: true,
+      /*formatter: (row, column, cellValue, index) => {
           return `<img src="${row.drawingPath}" alt="${row.drawingPath}" width="50" height="50">`;
           return `<img src="${row.drawingPath}" alt="${row.drawingPath}" width="50" height="50">`;
         }
         }
 */
 */
-      },
-      {
-        label: "图纸",
-        prop: "drawing",
-        type: 'img',
-        span: 24,
-        display:false,
-        slot: true,
-        formatter: (row, column, cellValue, index) => {
+    },
+    {
+      label: "图纸",
+      prop: "drawing",
+      type: "img",
+      span: 24,
+      display: false,
+      slot: true,
+      formatter: (row, column, cellValue, index) => {
         return `${row.drawingPath}`;
         return `${row.drawingPath}`;
-    }
+      },
+    },
+  ],
+  delBtn: false,
+  editBtn: false,
+  viewBtn: false,
+  addBtn: false,
+  menu: false,
+});
+const props = defineProps({
+  materialCode: {
+    type: String,
+    default: () => {
+      return 0;
+    },
   },
   },
-      ],
-    delBtn: false,
-    editBtn: false,
-    viewBtn: false,
-    addBtn:false,
-    menu: false,
-  });
-  const props = defineProps({
-    materialCode: {
-      type: String,
-      default: () => {
-        return 0;
-      }
+  dialog: {
+    type: Object,
+    default: () => {
+      return {};
     },
     },
-    dialog:{
-      type:Object,
-      default:()=>{
-        return {};
-      }
-    }
-  })
-
-  const onSelectedFinish=(selectedValue)=>{
+  },
+});
 
 
-    form.value.materialCode=selectedValue.materialCode;
-    form.value.materialName=selectedValue.materialName;
+const onSelectedFinish = (selectedValue) => {
+  form.value.materialCode = selectedValue.materialCode;
+  form.value.materialName = selectedValue.materialName;
 
 
-    form.value.productionLineId=props.productionLineId;
-  }
+  form.value.productionLineId = props.productionLineId;
+};
 </script>
 </script>
-

+ 12 - 1
src/views/base/modeling/factory/index.vue

@@ -9,7 +9,7 @@
       v-model:page="page"
       v-model:page="page"
       @row-save="createRow"
       @row-save="createRow"
       @row-update="updateRow"
       @row-update="updateRow"
-      @row-del="deleteRow"
+      @row-del="delete(row,index,done)"
       @search-change="searchChange"
       @search-change="searchChange"
       @search-reset="resetChange"
       @search-reset="resetChange"
       @size-change="dataList"
       @size-change="dataList"
@@ -92,6 +92,17 @@
     }
     }
 
 
   };
   };
+  const delete=(row,index,done)=>{
+    if(row.level==="first"){
+      deleteRow(row,index,done);
+    }
+    if(row.level==="second"){
+      workShopRef.value.startSelect();
+    }
+    if(row.level==="third"){
+      productionLineRef.value.startSelect();
+    }
+  }
   const dialog = reactive({
   const dialog = reactive({
     title: "绑定子项",
     title: "绑定子项",
     visible: false,
     visible: false,

+ 19 - 0
src/views/demo/hooksDemo.vue

@@ -72,6 +72,17 @@
       @selected-sure="onSelectedFinish"
       @selected-sure="onSelectedFinish"
     />
     />
     <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
     <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
+    <FilesUpload v-model:src="fileUrl" v-model:src-list="fileUrlList" />
+    <el-button @click="testFiles">测试上传文件的值</el-button>
+    <div style="height: 100px; width: 100px; overflow: hidden">
+      <PDFView
+        :need-to-show-pdf="true"
+        content-type="button"
+        :is-link="true"
+        :show-pdf-number="3"
+        pdf-source="http://192.168.101.4:9000/jgfile/2024/04/20/%E7%AC%AC08%E7%AB%A0_%E8%81%9A%E5%90%88%E5%87%BD%E6%95%B0.pdf"
+      />
+    </div>
   </div>
   </div>
 </template>
 </template>
 <script setup>
 <script setup>
@@ -81,6 +92,14 @@ import dictDataUtil from "@/common/configs/dictDataUtil";
 import ButtonPermKeys from "@/common/configs/buttonPermission";
 import ButtonPermKeys from "@/common/configs/buttonPermission";
 import { useCommonStoreHook, useDictionaryStoreHook } from "@/store";
 import { useCommonStoreHook, useDictionaryStoreHook } from "@/store";
 import SingleUpload from "@/components/Upload/SingleUpload.vue";
 import SingleUpload from "@/components/Upload/SingleUpload.vue";
+import PDFView from "@/components/PDFView/index.vue";
+// 测试上传文件相关
+const fileUrl = ref(""); //单文件
+const fileUrlList = ref([]); //多文件
+const testFiles = () => {
+  console.log("fileUrl", fileUrl.value);
+  console.log("fileUrlList", fileUrlList.value);
+};
 
 
 // 数据字典相关
 // 数据字典相关
 const { dicts } = useDictionaryStoreHook();
 const { dicts } = useDictionaryStoreHook();

+ 8 - 38
src/views/pro/traceability/components/equitCom.vue

@@ -73,61 +73,31 @@ option.value = Object.assign(option.value, {
       prop: "opName",
       prop: "opName",
     },
     },
     {
     {
-      label: "点检项名称",
-      prop: "checkName",
+      label: "设备类型",
+      prop: "equitType",
       search: false,
       search: false,
     },
     },
     {
     {
-      label: "点检项编码",
-      prop: "checkCode",
+      label: "精度要求",
+      prop: "accuracy",
       search: false,
       search: false,
     },
     },
     {
     {
-      label: "内容",
-      prop: "content",
+      label: "设备有效期",
+      prop: "validDate",
       search: false,
       search: false,
     },
     },
     {
     {
-      label: "结果",
+      label: "设备名称",
       prop: "result",
       prop: "result",
       search: false,
       search: false,
     },
     },
-    // {
-    //   label: "操作人",
-    //   prop: "operator",
-    //   search: false,
-    // },
     {
     {
-      label: "标准值",
+      label: "设备编码",
       prop: "standard",
       prop: "standard",
       search: false,
       search: false,
     },
     },
     {
     {
-      label: "上限值",
-      prop: "upper",
-      search: false,
-    },
-    {
-      label: "下限值",
-      prop: "lower",
-      search: false,
-    },
-    {
-      label: "实测值",
-      prop: "realValue",
-      search: false,
-    },
-    {
-      label: "单位",
-      prop: "unit",
-      search: false,
-      dicData: dicts.danwei_type,
-      props: {
-        label: "dictLabel",
-        value: "dictValue",
-      },
-    },
-    {
       label: "录入时间",
       label: "录入时间",
       prop: "created",
       prop: "created",
       search: false,
       search: false,

+ 112 - 0
src/views/pro/traceability/components/faultCom.vue

@@ -0,0 +1,112 @@
+<template>
+  <div class="mainContentBox">
+    <avue-crud
+      ref="crudRef2"
+      v-model:search="search"
+      v-model="form"
+      :data="data"
+      :option="option"
+      v-model:page="page"
+    />
+    <!-- <el-collapse accordion>
+      <el-collapse-item
+        :title="item.opName"
+        :name="item.id"
+        v-for="item in data"
+        :key="item.id"
+      />
+    </el-collapse> -->
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+import ButtonPermKeys from "@/common/configs/buttonPermission";
+import { useCommonStoreHook, useDictionaryStoreHook } from "@/store";
+
+// 数据字典相关
+const { dicts } = useDictionaryStoreHook();
+
+// 传入一个url,后面不带/
+const {
+  form,
+  data,
+  option,
+  search,
+  page,
+  toDeleteIds,
+  Methords,
+  Utils,
+  commonConfig,
+} = useCrud({
+  src: "/api/v1/process/web/traceability/escalationRecordInfo",
+});
+const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
+  Methords; //增删改查
+const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
+const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
+
+const crudRef = ref(null); //crudRef.value 获取avue-crud对象
+
+const refreshTra = (row) => {
+  commonConfig.value.params = { seqNo: row.seqNo };
+  dataList();
+};
+defineExpose({ refreshTra });
+onMounted(() => {});
+
+option.value = Object.assign(option.value, {
+  selection: false,
+  border: true,
+  index: false,
+  expandLevel: 3,
+  headerAlign: "center",
+  align: "center",
+  labelWidth: 100,
+  addBtn: false,
+  menu: false,
+  header: false,
+  column: [
+    {
+      label: "冻结状态",
+      prop: "state",
+      dicData: dicts.escalation_fault_state,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+    },
+    {
+      label: "报故人",
+      prop: "personResponsible",
+      search: false,
+    },
+    {
+      label: "报故工位",
+      prop: "stationName",
+      search: false,
+    },
+    {
+      label: "报故时间",
+      prop: "created",
+      search: false,
+    },
+    {
+      label: "处理结果",
+      prop: "disposalMeasures",
+      dicData: dicts.disposal_measures_type,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+      search: false,
+    },
+    {
+      label: "备注",
+      prop: "standard",
+      search: false,
+    },
+  ],
+});
+</script>

+ 74 - 7
src/views/pro/traceability/index.vue

@@ -56,24 +56,74 @@
               <TraceabilityCom ref="traceabilityComRef" />
               <TraceabilityCom ref="traceabilityComRef" />
             </el-tab-pane>
             </el-tab-pane>
             <el-tab-pane name="materialsComRef" label="已采物料">
             <el-tab-pane name="materialsComRef" label="已采物料">
+              <template #label>
+                <span
+                  >已采物料
+                  <el-badge
+                    :value="tabCount.materials"
+                    class="item"
+                    type="primary"
+                  />
+                </span>
+              </template>
               <MaterialsCom ref="materialsComRef" />
               <MaterialsCom ref="materialsComRef" />
             </el-tab-pane>
             </el-tab-pane>
             <el-tab-pane name="recordComRef" label="记录项">
             <el-tab-pane name="recordComRef" label="记录项">
+              <template #label>
+                <span
+                  >记录项
+                  <el-badge
+                    :value="tabCount.record"
+                    class="item"
+                    type="primary"
+                  />
+                </span>
+              </template>
               <RecordCom ref="recordComRef"
               <RecordCom ref="recordComRef"
             /></el-tab-pane>
             /></el-tab-pane>
             <el-tab-pane name="checkComRef" label="点检判定">
             <el-tab-pane name="checkComRef" label="点检判定">
+              <template #label>
+                <span
+                  >点检判定
+                  <el-badge
+                    :value="tabCount.check"
+                    class="item"
+                    type="primary"
+                  />
+                </span>
+              </template>
               <CheckCom ref="checkComRef" />
               <CheckCom ref="checkComRef" />
             </el-tab-pane>
             </el-tab-pane>
-            <el-tab-pane name="equitComRef" label="设备使用"
-              ><EquitCom ref="equitComRef"
+            <el-tab-pane name="equitComRef" label="设备使用">
+              <template #label>
+                <span
+                  >设备使用
+                  <el-badge
+                    :value="tabCount.equit"
+                    class="item"
+                    type="primary"
+                  />
+                </span>
+              </template>
+              <EquitCom ref="equitComRef"
             /></el-tab-pane>
             /></el-tab-pane>
+            <el-tab-pane name="faultComRef" label="报故记录">
+              <template #label>
+                <span
+                  >报故记录
+                  <el-badge
+                    :value="tabCount.fault"
+                    class="item"
+                    type="primary"
+                  />
+                </span>
+              </template>
+              <FaultCom ref="faultComRef" />
+            </el-tab-pane>
             <el-tab-pane name="bugComRef" label="缺陷项">缺陷项</el-tab-pane>
             <el-tab-pane name="bugComRef" label="缺陷项">缺陷项</el-tab-pane>
             <el-tab-pane name="imgComRef" label="图片采集"
             <el-tab-pane name="imgComRef" label="图片采集"
               >图片采集</el-tab-pane
               >图片采集</el-tab-pane
             >
             >
-            <el-tab-pane name="faultComRef" label="报故记录"
-              >报故记录</el-tab-pane
-            >
           </el-tabs>
           </el-tabs>
         </el-main>
         </el-main>
       </el-container>
       </el-container>
@@ -84,7 +134,7 @@
 import { ref, getCurrentInstance } from "vue";
 import { ref, getCurrentInstance } from "vue";
 import { useCrud } from "@/hooks/userCrud";
 import { useCrud } from "@/hooks/userCrud";
 import ButtonPermKeys from "@/common/configs/buttonPermission";
 import ButtonPermKeys from "@/common/configs/buttonPermission";
-
+import { traceabilityTabCount } from "@/api/process";
 import { useCommonStoreHook } from "@/store";
 import { useCommonStoreHook } from "@/store";
 import { getMaterialDetailsByseqNo, getOperationCompent } from "@/api/material";
 import { getMaterialDetailsByseqNo, getOperationCompent } from "@/api/material";
 import TraceabilityCom from "@/views/pro/traceability/components/traceabilityCom.vue";
 import TraceabilityCom from "@/views/pro/traceability/components/traceabilityCom.vue";
@@ -92,6 +142,7 @@ import MaterialsCom from "@/views/pro/traceability/components/materialsCom.vue";
 import RecordCom from "@/views/pro/traceability/components/recordCom.vue";
 import RecordCom from "@/views/pro/traceability/components/recordCom.vue";
 import CheckCom from "@/views/pro/traceability/components/checkCom.vue";
 import CheckCom from "@/views/pro/traceability/components/checkCom.vue";
 import EquitCom from "@/views/pro/traceability/components/equitCom.vue";
 import EquitCom from "@/views/pro/traceability/components/equitCom.vue";
+import FaultCom from "@/views/pro/traceability/components/faultCom.vue";
 
 
 // 传入一个url,后面不带/
 // 传入一个url,后面不带/
 const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
 const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
@@ -110,6 +161,7 @@ const materialsComRef = ref(null);
 const recordComRef = ref(null);
 const recordComRef = ref(null);
 const checkComRef = ref(null);
 const checkComRef = ref(null);
 const equitComRef = ref(null);
 const equitComRef = ref(null);
+const faultComRef = ref(null);
 let defaultTabName = ref("traceabilityComRef");
 let defaultTabName = ref("traceabilityComRef");
 //tab页组件
 //tab页组件
 const tabNameComRef = new Map([
 const tabNameComRef = new Map([
@@ -118,11 +170,14 @@ const tabNameComRef = new Map([
   ["recordComRef", recordComRef],
   ["recordComRef", recordComRef],
   ["checkComRef", checkComRef],
   ["checkComRef", checkComRef],
   ["equitComRef", equitComRef],
   ["equitComRef", equitComRef],
+  ["faultComRef", faultComRef],
 ]);
 ]);
 let temRow = ref({});
 let temRow = ref({});
 const tabsEvent = (pane, ev) => {
 const tabsEvent = (pane, ev) => {
   defaultTabName.value = pane.props.name;
   defaultTabName.value = pane.props.name;
-  tabNameComRef.get(pane.props.name)?.value.refreshTra(temRow.value);
+  if (temRow.value.seqNo) {
+    tabNameComRef.get(pane.props.name)?.value.refreshTra(temRow.value);
+  }
 };
 };
 
 
 const chooseTagType = (row, type) => {
 const chooseTagType = (row, type) => {
@@ -153,6 +208,15 @@ let productReviewInfo = reactive({
   outNum: "",
   outNum: "",
 });
 });
 
 
+let tabCount = reactive({
+  traceability: "",
+  materials: "",
+  record: "",
+  check: "",
+  equit: "",
+  fault: "",
+});
+
 const handleCellClick = (row, column, event) => {
 const handleCellClick = (row, column, event) => {
   //获取出单的数量
   //获取出单的数量
   if (data.value) {
   if (data.value) {
@@ -183,6 +247,9 @@ const handleCellClick = (row, column, event) => {
       productReviewInfo.workOrderCode = row.workOrderCode;
       productReviewInfo.workOrderCode = row.workOrderCode;
       // productReviewInfo.outNum =
       // productReviewInfo.outNum =
     });
     });
+    traceabilityTabCount({ seqNo: row.seqNo }).then(({ data }) => {
+      tabCount = Object.assign(tabCount, data);
+    });
   }
   }
 };
 };
 
 

+ 43 - 0
src/views/quality/unqualified/columns.ts

@@ -0,0 +1,43 @@
+import { useDictionaryStoreHook } from "../../../store/index";
+const { dicts } = useDictionaryStoreHook();
+export const columns = [
+
+  {
+    label: "报故时间",
+    prop: "created",
+  },
+
+
+  {
+    label: "物料名称",
+    prop: "bomMaterialName",
+    overHidden:true,
+  },
+  {
+    label: "物料属性",
+    prop: "bomMaterialAttribute",
+    type: 'select',
+    dicData:dicts.material_properties,
+    props: { label: "dictLabel", value: "dictValue" },
+  },
+  {
+    label: "物料数量",
+    prop: "bomMaterialNumber",
+    min:0,
+    slot:true,
+    cell: true,
+    type: "number",
+    precision: 2,
+  },
+  {
+    label: "物料名称",
+    prop: "materialName",
+    overHidden:true,
+  },
+
+  {
+    label: "物料编码",
+    prop: "bomMaterialCode",
+  },
+
+];

+ 260 - 0
src/views/quality/unqualified/index.vue

@@ -0,0 +1,260 @@
+<template>
+  <div class="mainContentBox">
+    <!--{{dataDetail}}-->
+    <!--{{dicts}}-->
+    <div class="detail">
+      <div class="title-detail">物料名称:{{dataDetail.materialCode}}</div>
+      <div class="title-detail">物料编码:{{dataDetail.materialName}}</div>
+      <div class="title-detail">物料属性:{{dataDetail.attributeDictLabel}}</div>
+    </div>
+    <avue-crud
+      ref="crudRef"
+      v-model:search="search"
+      v-model="form"
+      :data="data"
+      :option="option"
+      @row-update="updateRow"
+      @row-del="deleteRow"
+      @search-change="searchChange"
+      @search-reset="resetChange"
+      @selection-change="selectionChange"
+    >
+      <template #menu-left="{ size }">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          @click="openMaterial"
+          >新增</el-button
+        ></template>
+
+        <CommonTable
+          ref="ctableRef"
+          tableTitle="物料选择"
+          tableType="BOM"
+          @selected-sure="onSelectedFinish"
+        />
+      <template #footer>
+        <div class="detail-footer">
+          <el-button type="primary" @click="onSelected"> 保存 </el-button>
+          <el-button @click="routeBack">取消</el-button>
+
+        </div>
+      </template>
+      <template #menu-right="{}">
+        <el-dropdown split-button
+          >导入
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item
+                @click="downloadTemplate('/api/v1/plan/order/template')"
+              >
+                <i-ep-download />下载模板
+              </el-dropdown-item>
+              <el-dropdown-item @click="importExcelData">
+                <i-ep-top />导入数据
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </template>
+    </avue-crud>
+    <CommonTable
+      ref="ctableRef"
+      tableTitle="BOM添加"
+      tableType="MARTERIAL"
+      @selected-sure="onSelectedFinish"
+    />
+
+  </div>
+</template>
+<script setup lang="ts">
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "../../../hooks/userCrud";
+import ButtonPermKeys from "../../../common/configs/buttonPermission";
+import { columns } from "./columns";
+import { useCommonStoreHook, useDictionaryStoreHook } from "../../../store/index";
+import {
+  getList,
+} from "@/api/bom";
+import {
+  getMaterialDetails,
+} from "@/api/material";
+
+import {
+  batchAddBom,
+} from "@/api/bom";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+// 数据字典相关
+const { dicts } = useDictionaryStoreHook();
+const router = useRouter();
+const route = useRoute();
+
+const dataDetail=ref({});
+const test = () => {
+  isShowTable.value = true;
+  tableType.value = tableType.value == 1 ? 2 : 1;
+};
+const openMaterial=()=>{
+  if (ctableRef.value) {
+    ctableRef.value.startSelect();
+  }
+}
+const formData=ref({});
+const dataBomLists=()=>{
+  search.value.materialCode=route.value.materialCode;
+  dataNoPageList();
+}
+
+const ctableRef = ref(null);
+
+const binding = (row) => {
+  if (ctableRef.value) {
+    ctableRef.value.startSelect();
+  }
+};
+const onSelected=()=>{
+  for(var i=0;i<data.value.length;i++){
+    if(data.value[i].bomMaterialNumber<=0){
+      ElMessage({
+        message: data.value[i].bomMaterialName+"数量不能为0",
+        type: "error",
+      });
+      return;
+    }
+  }
+  if(data.value.length===0){
+    ElMessage({
+      message: "物料记录不能为空!",
+      type: "error",
+    });
+    return;
+  }
+  batchAddBom(data.value).then(
+    (data: any)=>{
+      if(data.code==="200") {
+        ElMessage({
+          message: data.msg,
+          type: "success",
+        });
+        router.back();
+      }
+      else {
+        ElMessage({
+          message: data.msg,
+          type: "error",
+        });
+      }
+    }
+  );
+}
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/base/materialBom",
+  });
+const { dataNoPageList,createRow, updateRow, deleteRow, searchChange, resetChange } =
+  Methords; //增删改查
+const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
+const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
+// checkBtnPerm(ButtonPermKeys.PLAN.BTNS.order_add) :permission="permission"
+// const permission = reactive({
+//   delBtn: checkPerm(buttonPermission.PLAN.BTNS.order_del),
+//   addBtn: checkPerm(buttonPermission.PLAN.BTNS.order_add),
+//   editBtn: checkPerm(buttonPermission.PLAN.BTNS.order_edit),
+//   menu: true,
+// });
+
+const crudRef = ref(null); //crudRef.value 获取avue-crud对象
+
+onMounted(() => {
+  // console.log("crudRef", crudRef)
+  search.value.materialCode=route.params.materialCode;
+  queryMaterialDetail();
+  dataNoPageList();
+
+});
+
+/**
+ * 上传excel相关
+ */
+const uploadRef = ref(null);
+const uploadFinished = () => {
+  // 上传完成后的刷新操作
+  dataNoPageList();
+};
+const importExcelData = () => {
+  if (uploadRef.value) {
+    uploadRef.value.show("/api/v1/plan/order/import");
+  }
+};
+
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  selection: true,
+  addBtn: false,
+  viewBtn: false,
+  editBtn:false,
+  saveBtn:false,
+  cellBtn: true,
+  column: columns,
+});
+const routeBack =()=>{
+  router.back();
+}
+const onSelectedFinish = (selectedValue) => {
+  for(var i=0;i<data.value.length;i++){
+    if(data.value[i].bomMaterialCode===selectedValue.materialCode){
+      ElMessage({
+        message: data.value[i].bomMaterialName+"已经添加过了",
+        type: "error",
+      });
+      return;
+    }
+  }
+  const bom=ref({
+    materialCode:route.params.materialCode,
+    bomMaterialCode:selectedValue.materialCode,
+    bomMaterialName:selectedValue.materialName,
+    bomMaterialAttribute:selectedValue.attributeDictValue,
+    bomMaterialNumber:0,
+    $cellEdit:true,
+  });
+  data.value.push(bom.value);
+};
+const queryMaterialDetail = () => {
+  getMaterialDetails(route.params.materialCode).then(
+
+    ({ data }) => {
+      dataDetail.value=data;
+      dicts.material_properties;
+      for(var i=0;i<dicts.material_properties.length;i++){
+        if(data.attributeDictValue===dicts.material_properties[i].dictValue){
+          dataDetail.value.attributeDictLabel=dicts.material_properties[i].dictLabel;
+        }
+      }
+
+    }
+  );
+};
+</script>
+<style type="text/css">
+  .title-detail{
+    width: 30%;
+    height: 50px;
+    line-height: 50px;
+    margin: 25px 20px 25px 0;
+    float: left;
+  }
+  .detail{
+    margin: 0 auto;
+    width: 100%;
+  }
+  .avue-crud{
+    float: left;
+  }
+  .detail-footer{
+    float: right;
+    margin-top:15px;
+  }
+
+</style>

+ 180 - 0
src/views/storage/vehicleMaterial/index.vue

@@ -0,0 +1,180 @@
+<template>
+  <div class="mainContentBox">
+    <avue-crud
+      ref="crudRef"
+      v-model:search="search"
+      v-model="form"
+      :data="data"
+      :option="option"
+      v-model:page="page"
+      @row-save="rowSave"
+      @row-update="updateRow"
+      @row-del="deleteRow"
+      @search-change="searchChange"
+      @search-reset="resetChange"
+      @size-change="dataList"
+      @current-change="dataList"
+      @selection-change="selectionChange"
+    >
+      <template #menu-left="{ size }">
+        <el-button
+          :disabled="toDeleteIds.length < 1"
+          type="danger"
+          icon="el-icon-delete"
+          :size="size"
+          @click="multipleDelete"
+        >删除</el-button
+        >
+      </template>
+
+    </avue-crud>
+    <CommonTable
+      ref="ctableRef"
+      tableTitle="BOM添加"
+      tableType="MARTERIAL"
+      @selected-sure="onSelectedFinish"
+    />
+  </div>
+</template>
+<script setup="ts">
+  import { ref, getCurrentInstance } from "vue";
+  import { useCrud } from "@/hooks/userCrud";
+  import ButtonPermKeys from "@/common/configs/buttonPermission";
+  import { useCommonStoreHook } from "@/store";
+
+  const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+  import { useDictionaryStoreHook } from "../../../store/index";
+  const { dicts } = useDictionaryStoreHook();
+  const test = () => {
+    isShowTable.value = true;
+    tableType.value = tableType.value == 1 ? 2 : 1;
+  };
+  const ctableRef = ref(null);
+  // 传入一个url,后面不带/
+  const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+    useCrud({
+      src: "/api/v1/wms/vehicleMaterial",
+    });
+  const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
+    Methords; //增删改查
+  const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
+  const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
+  // checkBtnPerm(ButtonPermKeys.PLAN.BTNS.order_add) :permission="permission"
+  // const permission = reactive({
+  //   delBtn: checkPerm(buttonPermission.PLAN.BTNS.order_del),
+  //   addBtn: checkPerm(buttonPermission.PLAN.BTNS.order_add),
+  //   editBtn: checkPerm(buttonPermission.PLAN.BTNS.order_edit),
+  //   menu: true,
+  // });
+  function rowSave(form,done,loading) {
+    console.info(form);
+    createRow(form,done,loading);
+
+  }
+  const crudRef = ref(null); //crudRef.value 获取avue-crud对象
+
+  onMounted(() => {
+    // console.log("crudRef", crudRef)
+    dataList();
+  });
+
+  /**
+   * 上传excel相关
+   */
+  const uploadRef = ref(null);
+  const uploadFinished = () => {
+    // 上传完成后的刷新操作
+    page.currentPage = 1;
+    dataList();
+  };
+  const importExcelData = () => {
+    if (uploadRef.value) {
+      uploadRef.value.show("/api/v1/base/station");
+    }
+  };
+
+  // 设置表格列或者其他自定义的option
+  option.value = Object.assign(option.value, {
+    selection: true,
+    column: [
+
+      {
+        label: "料箱等级",
+        prop: "vehicleLevel",
+        search: true,
+        rules: [{
+          required: true,
+          message: "请选择工位类型",
+          trigger: "blur"
+        }],
+        type: 'select',
+        dicData:dicts.vehicle_level,
+        filterable: true, //添加filterable属性即可启用搜索功能
+        props: {
+          label: "dictLabel", // 下拉菜单显示的字段
+          value: "dictValue" // 下拉菜单值的字段
+        },
+      },
+
+      {
+        label: "物料编号",
+        prop: "materialCode",
+        display:false,
+        search:true,
+        rules: [{
+          required: true,
+          message: "请填选择物料编码",
+          trigger: "blur",
+        }],
+      },
+      {
+        label: "物料编号",
+        prop: "code",
+        hide:true,
+        click:({ value, column }) => {
+          ctableRef.value.startSelect();
+        },
+        rules: [{
+          required: true,
+          message: "请填选择物料编码",
+          trigger: "blur",
+        }],
+      },
+      {
+        label: "物料名称",
+        prop: "materialName",
+        search:true,
+        disabled:true,
+
+      },
+      {
+        label: "规格",
+        prop: "spec",
+        disabled:true,
+      },
+      {
+        label: "描述",
+        prop: "remark",
+        type: 'textarea',
+        span: 24,
+      },
+      {
+        label: "创建人",
+        prop: "creator",
+        display:false
+      },
+      {
+        label: "创建时间",
+        prop: "created",
+        display:false
+      },
+    ],
+  });
+  const onSelectedFinish = (selectedValue) => {
+    form.value.materialCode=selectedValue.materialCode;
+    form.value.code=selectedValue.materialCode;
+    form.value.materialName=selectedValue.materialName;
+    form.value.spec=selectedValue.spec;
+  }
+</script>
+