Selaa lähdekoodia

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

ooo 1 vuosi sitten
vanhempi
commit
961915f67f

+ 1 - 1
.env.development

@@ -12,7 +12,7 @@ VITE_APP_UPLOAD_URL = 'http://192.168.101.4:9000'
 # 开发接口地址
 # VITE_APP_API_URL = 'http://192.168.101.4:8078'
 #VITE_APP_API_URL = 'http://192.168.101.188:8078'
- VITE_APP_API_URL = 'http://192.168.101.30:8078'  #lup
+ VITE_APP_API_URL = 'http://192.168.101.188:8078'  #lup
 #VITE_APP_API_URL = 'http://192.168.101.64:8078'  #hetao
 
 # 是否启用 Mock 服务

+ 47 - 1
src/api/device/index.ts

@@ -1,5 +1,4 @@
 import request from "@/utils/request";
-import {OrderInfoQuery} from "@/api/order/types";
 
 /**
  * 设备维护
@@ -55,3 +54,50 @@ export function queryTypeDataList() {
     method: "get",
   });
 }
+
+export function treeList() {
+  return request({
+    url: "/api/v1/device/tree",
+    method: "get",
+  });
+}
+
+export function configList(params: any) {
+  return request({
+    url: "/api/v1/device/config/list",
+    method: "post",
+    data: params,
+  });
+}
+
+export function configSave(params: any) {
+  return request({
+    url: "/api/v1/device/config/addBatch",
+    method: "post",
+    data: params,
+  });
+}
+export function deviceUpdate(params: any) {
+  return request({
+    url: "/api/v1/device/update",
+    method: "post",
+    data: params,
+  });
+}
+export function queryDeviceList(params: any) {
+  return request({
+    url: "/api/v1/device/list",
+    method: "post",
+    data: params,
+  });
+}
+
+export function queryTypeAliasList(params: any) {
+  return request({
+    url: "/api/v1/device/fieldAlias/list",
+    method: "post",
+    data: params,
+  });
+}
+
+

+ 39 - 0
src/api/device/rule/index.ts

@@ -0,0 +1,39 @@
+import request from "@/utils/request";
+
+/**
+ * 设备维护
+ *
+ * @param ids
+ */
+export function rulePage(params: any) {
+    return request({
+        url: "/api/v1/device/rule/page",
+        method: "post",
+        data: params,
+    });
+}
+
+export function aliasList(params: any) {
+    return request({
+        url: "/api/v1/device/fieldAlias/list",
+        method: "post",
+        data: params,
+    });
+}
+
+export function ruleAdd(params: any) {
+    return request({
+        url: "/api/v1/device/rule/add",
+        method: "post",
+        data: params,
+    });
+}
+
+export function ruleRemove(params: any) {
+    return request({
+        url: "/api/v1/device/rule/del",
+        method: "post",
+        data: params,
+    });
+}
+

+ 18 - 0
src/api/system/skill/index.ts

@@ -0,0 +1,18 @@
+import request from "@/utils/request";
+import { AxiosPromise } from "axios";
+
+
+
+/**
+ * 批量插入技能
+ *
+ * @param id
+ * @param data
+ */
+export function addPostSkill(data: any) {
+  return request({
+    url: "/api/v1/sys/postSkill/add",
+    method: "post",
+    data: data,
+  });
+}

+ 15 - 3
src/common/configs/dictDataUtil.ts

@@ -4,6 +4,10 @@ const DictDataUtil = {
   request_url:
     import.meta.env.VITE_APP_BASE_API + "/api/v1/sys/dictData/queryByType/",
   dept_tree_url: import.meta.env.VITE_APP_BASE_API + "/api/v1/sys/dept/orgTree",
+  dept_list_url:
+    import.meta.env.VITE_APP_BASE_API + "/api/v1/sys/dept/parent/list",
+  post_list_url: import.meta.env.VITE_APP_BASE_API + "/api/v1/sys/post/list",
+
   TYPE_CODE: {
     //订单类型
     plan_order_type: "plan_order_type",
@@ -23,8 +27,8 @@ const DictDataUtil = {
     device_maintenance_cycle: "device_maintenance_cycle",
     // 工艺路线类型
     routing_type: "routing_type",
-	//缺陷管理
-	defect_mana: "defect_mana",
+    //缺陷管理
+    defect_mana: "defect_mana",
     //封装方法
     packaging_method: "packaging_method",
     //岗位组
@@ -42,7 +46,15 @@ const DictDataUtil = {
     //载具类型
     vehicle_type: "vehicle_type",
     //载具状态
-    vehicle_state: "vehicle_state"
+    vehicle_state: "vehicle_state",
+    //生产准备-设备信息
+    prepare_device_info: "prepare_device_info",
+    //生产准备-图纸
+    prepare_data_file: "prepare_data_file",
+    //生产准备-工艺文件
+    prepare_craft_file: "prepare_craft_file",
+    //   生产计划-工位任务状态
+    station_task_state: "station_task_state",
   },
   EXPAND_FIELD_TABLE: {
     //字段类型

+ 42 - 1
src/components/CommonTable/configs/tableConfig.ts

@@ -1,6 +1,6 @@
 import { useDictionaryStoreHook } from "@/store";
 const { dicts } = useDictionaryStoreHook();
-
+import dictDataUtil from "@/common/configs/dictDataUtil";
 export const tableConfig = {
   MARTERIAL: {
     url: "/api/v1/base/material",
@@ -456,4 +456,45 @@ export const tableConfig = {
 		],
 	},
 
+  USERS: {
+    url: "/api/v1/sys/employeeSkill/users",
+    column: [
+      {
+        label: "员工编码",
+        prop: "employeeCode",
+        search: true,
+      },
+      {
+        label: "用户id",
+        prop: "id",
+        /*display:false,*/
+      },
+      {
+        label: "用户名",
+        prop: "userName",
+        search: true,
+        width: '120',
+      },
+      {
+        label: "用户电话",
+        prop: "phone",
+        search: true,
+      },
+
+      { label: "部门", prop: "deptName", overHidden: true,
+        disabled:true, },
+      { label: "所属机构", prop: "institution", width: 130,overHidden: true,search: true ,
+        search: true,
+        filterable: true,
+        type: "select",
+        width: 100,overHidden: true,
+        dicUrl:dictDataUtil.dept_list_url,
+        dicMethod:"post",
+        props: { label: "deptName", value: "id" },
+        disabled:true,
+
+      },
+    ],
+  },
+
 };

+ 2 - 1
src/hooks/userCrud.ts

@@ -61,6 +61,7 @@ export const useCrud = (config?: UseCrudConfig) => {
   const save = async (config?: UseCrudConfig) => {
     try {
       const path = config?.isEdit ? "/update" : "/add";
+
       const res = (await request({
         url: `${url.value}${path}`,
         method: "post",
@@ -137,7 +138,6 @@ export const useCrud = (config?: UseCrudConfig) => {
         for (let i = 0; i < data.value.length; i++) {
           data.value[i].$cellEdit = true;
         }
-        console.info(data);
         config?.done && config?.done();
       } catch (err) {
         config?.loading && config?.loading();
@@ -146,6 +146,7 @@ export const useCrud = (config?: UseCrudConfig) => {
       }
     },
     createRow: (row: any, done: () => void, loading: () => void) => {
+      console.info(row);
       save({ row: row, done: done, loading: loading });
     },
 

+ 0 - 1
src/typings/components.d.ts

@@ -110,4 +110,3 @@ declare module 'vue' {
 export interface ComponentCustomProperties {
   vLoading: typeof import('element-plus/es')['ElLoadingDirective']
 }
-}

+ 231 - 0
src/views/base/materials/components/drawing-page.vue

@@ -0,0 +1,231 @@
+<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-update="updateRow"
+      @row-del="deleteRow"
+      @search-change="searchChange"
+      @search-reset="resetChange"
+      @size-change="dataList"
+      @current-change="dataList"
+      @selection-change="selectionChange"
+      search-option="false"
+    >
+
+      <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="物料列表"
+      tableType="MARTERIAL"
+      @selected-sure="onSelectedFinish"
+    />
+  </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";
+  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();
+  });
+
+  /**
+   * 上传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,
+      },
+
+
+      {
+      label: "图纸编号",
+      prop: "drawingCode",
+      rules: [{
+        required: true,
+        message: "图纸编号不能为空",
+        trigger: "blur"
+      }]
+    },
+      {
+        label: "图纸标题",
+        prop: "drawingTitle",
+        rules: [{
+          required: true,
+          message: "图纸名称不能为空",
+          trigger: "blur"
+        }],
+      },
+
+
+      {
+        label: "图纸类型",
+        prop: "drawingDictValue",
+        value:"material",
+        display: false,
+        hide:true,
+      },
+      {
+        label: "排序",
+        prop: "sort",
+        type:"number",
+
+      },
+      {
+        label: "版本",
+        prop: "drawingVersion",
+        type:"number",
+        precision:1,
+        rules: [{
+          required: true,
+          message: "版本号不能为空",
+          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">`;
+        }
+*/
+      },
+      {
+        label: "图纸",
+        prop: "drawing",
+        type: 'img',
+        span: 24,
+        display:false,
+        slot: true,
+        formatter: (row, column, cellValue, index) => {
+        return `${row.drawingPath}`;
+    }
+  },
+      ],
+    delBtn: false,
+    editBtn: false,
+    viewBtn: false,
+    addBtn:false,
+    menu: false,
+  });
+  const props = defineProps({
+    materialCode: {
+      type: String,
+      default: () => {
+        return 0;
+      }
+    },
+    dialog:{
+      type:Object,
+      default:()=>{
+        return {};
+      }
+    }
+  })
+
+  const onSelectedFinish=(selectedValue)=>{
+
+    form.value.materialCode=selectedValue.materialCode;
+    form.value.materialName=selectedValue.materialName;
+
+    form.value.productionLineId=props.productionLineId;
+  }
+</script>
+

+ 23 - 2
src/views/base/materials/index.vue

@@ -31,9 +31,13 @@
                      text
                      type="primary"
           >BOM</el-button>
+          <el-button @click="drawing(row)"
+                     icon="el-icon-link"
+                     text
+                     type="primary"
+          >图纸</el-button>
         </template>
 
-
       <template #menu-right="{}">
         <el-dropdown split-button
           >导入
@@ -58,6 +62,15 @@
         </el-button>
       </template>
     </avue-crud>
+
+      <el-dialog
+      v-model="dialog.visible"
+      :title="dialog.title"
+      width="900px"
+      @close="dialog.visible = false"
+    >
+      <drawing-page  :materialCode="drawingDetail.materialCode" :dialog="dialog"/>
+    </el-dialog>
     <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
   </div>
 </template>
@@ -75,7 +88,15 @@ const test = () => {
   isShowTable.value = true;
   tableType.value = tableType.value == 1 ? 2 : 1;
 };
-
+const dialog = reactive({
+  title: "图纸",
+  visible: false,
+});
+const drawingDetail=ref(null);
+const drawing=(row)=>{
+   drawingDetail.value=row;
+   dialog.visible=true;
+}
 // 传入一个url,后面不带/
 const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
   useCrud({

+ 12 - 1
src/views/base/modeling/station/components/station-page.vue

@@ -133,11 +133,20 @@
     }
   );
   const onSelectedFinish=(selectedValue)=>{
+    for(let i=0;i<data.value.length;i++){
+      if(data.value[i].deviceNo===selectedValue.deviceNo){
+        ElMessage({
+          message: "设备已绑定过,无需再次绑定",
+          type: "error",
+        });
+        return;
+      }
+    }
     const selectDevice=ref({
       deviceNo: selectedValue.deviceNo,
       stationId:props.stationId,
   });
-    console.info(selectDevice);
+
     addStationDevice(selectDevice.value).then(
       (data:any)=>{
         if(data.code==="200") {
@@ -145,6 +154,8 @@
             message: data.msg,
             type: "success",
           });
+          search.value.stationId = props.stationId;
+          dataList()
         }
         else {
           ElMessage({

+ 238 - 0
src/views/base/skill/components/user-skill.vue

@@ -0,0 +1,238 @@
+<template>
+  <div class="mainContentBox">
+    <avue-form
+      ref="formRef"
+      v-model:search="search"
+      v-model="form"
+      :data="data"
+      :option="option2"
+      v-model:page="page"
+      @row-save="createRow"
+      @row-update="updateRow"
+      @row-del="deleteRow"
+      @search-change="searchChange"
+      @size-change="dataList"
+      @current-change="dataList"
+      @selection-change="selectionChange"
+    >
+    </avue-form>
+    <avue-crud
+      ref="crudRef"
+      v-model="form"
+      :data="data"
+      :option="option"
+      v-model:page="page"
+      @row-save="createRow"
+      @row-update="updateRow"
+      @row-del="deleteRow"
+    >
+      <template #menu-left="{ size }">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          circle
+          @click="addSkill"
+        ></el-button
+        ></template>
+    </avue-crud>
+    <CommonTable
+      ref="ctableRef"
+      tableTitle="员工选择"
+      tableType="USERS"
+      @selected-sure="onSelectedFinish"
+    />
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import ButtonPermKeys from "@/common/configs/buttonPermission";
+import { useCommonStoreHook, useDictionaryStoreHook } from "@/store";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+import SingleUpload from "@/components/Upload/SingleUpload.vue";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+// 数据字典相关
+const { dicts } = useDictionaryStoreHook();
+
+const test = () => {
+  isShowTable.value = true;
+  tableType.value = tableType.value == 1 ? 2 : 1;
+};
+const data2=ref(null);
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/sys/skillScore",
+  });
+const { dataList, createRow, updateRow, deleteRow, searchChange, dataNoPageList } =
+  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 option2=ref(null);
+const ctableRef = ref(null); //crudRef.value 获取avue-crud对象
+const router = useRouter();
+const binding = (row) => {
+  router.push(`/base/bom/${row.materialCode}`);
+};
+onMounted(() => {
+  // console.log("crudRef", crudRef)
+  dataNoPageList();
+
+});
+
+const addSkill = () => {
+  const bom=ref({
+    $cellEdit:true,
+  });
+  data.value.push(bom.value);
+};
+
+/**
+ * 上传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
+option2.value = {
+  selection: true,
+  submitBtn:false,
+  clearAbleBtn:false,
+  emptyBtn:false,
+  column: [
+
+    { label: "用户id", prop: "userId", width: 130,overHidden: true,search: true ,
+      filterable: true,
+      width: 100,overHidden: true,
+      disabled:true,
+      display:false,
+
+    },
+    { label: "用户名", prop: "userName", width: 140,overHidden: true,search: true ,rules: [{
+        required: true,
+        search: true,
+        message: "请选择员工姓名",
+        trigger: "blur"
+      }],
+      click: ({ value, column }) => {
+        ctableRef.value.startSelect();
+      },},
+    { label: "所属机构", prop: "institution", width: 130,overHidden: true,search: true ,
+      filterable: true,
+      width: 100,overHidden: true,
+      disabled:true,
+
+    },
+    {
+      label: "员工编号",
+      prop: "employeeCode",
+      search: true,
+      disabled:true,
+    },
+    { label: "岗位", prop: "postId", overHidden: true,search: true ,
+      search: true,
+      filterable: true,
+      type: "select",
+      overHidden: true,
+      dicUrl:dictDataUtil.post_list_url,
+      dicMethod:"post",
+      change:({ value, column })=>{
+
+      },
+      props: { label: "postName", value: "id" },
+
+    },
+    { label: "部门", prop: "deptName", overHidden: true,
+      disabled:true, },
+
+  ],
+};
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value,{
+  selection: false,
+  addBtn: false,
+  viewBtn: false,
+  editBtn:false,
+  saveBtn:false,
+
+  cellBtn: true,
+  column: [{
+    label: "技能",
+    prop: "skillDictValue",
+    align: 'center',
+    headerAlign: 'center',
+    cell: true,
+    span:24,
+    type: 'select',
+    /*dicUrl: `${baseUrl}/getProvince?id={{key}}`,*/
+    dicData:dicts.skill_type,
+    props: {
+      label: "dictLabel", // 下拉菜单显示的字段
+      value: "dictValue" // 下拉菜单值的字
+    },
+  },
+    {
+      label: "分数",
+      prop: "score",
+      align: 'center',
+      headerAlign: 'center',
+      cell: true,
+      span:24,
+      dicData:dicts.skill_type,
+      props: {
+        label: "dictLabel", // 下拉菜单显示的字段
+        value: "dictValue" // 下拉菜单值的字
+      },
+    },],
+});
+const onSelectedFinish=(selectedValue)=>{
+  form.value.userId=selectedValue.id;
+
+  form.value.userName=selectedValue.userName;
+  form.value.deptName=selectedValue.deptName;
+  form.value.employeeCode=selectedValue.employeeCode;
+  form.value.institution=selectedValue.institution;
+
+}
+
+</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;
+  }
+  .el-select__selection{
+    width: 150px;
+  }
+
+</style>

+ 173 - 0
src/views/base/skill/index.vue

@@ -0,0 +1,173 @@
+<template>
+  <div class="mainContentBox">
+    <avue-crud
+      ref="crudRef"
+      v-model:search="search"
+      v-model="form"
+      :data="data"
+      :option="option"
+      v-model:page="page"
+      @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
+          type="primary"
+          icon="el-icon-plus"
+          :size="size"
+          @click="addRow"
+        >新增</el-button
+        >
+        <el-button
+          :disabled="toDeleteIds.length < 1"
+          type="danger"
+          icon="el-icon-delete"
+          :size="size"
+          @click="multipleDelete"
+          >删除</el-button
+        ></template>
+        <template #menu="{row,index,type}">
+          <el-button @click="binding(row)"
+                     icon="el-icon-link"
+                     text
+                     type="primary"
+          >BOM</el-button>
+        </template>
+
+    </avue-crud>
+    <el-dialog
+      v-model="dialog.visible"
+      :title="dialog.title"
+      width="800px"
+      @close="dialog.visible = false"
+    >
+      <user-skill   :dialog="dialog"/>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import ButtonPermKeys from "@/common/configs/buttonPermission";
+import { useCommonStoreHook, useDictionaryStoreHook } from "@/store";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+// 数据字典相关
+const { dicts } = useDictionaryStoreHook();
+
+const test = () => {
+  isShowTable.value = true;
+  tableType.value = tableType.value == 1 ? 2 : 1;
+};
+const dialog = reactive({
+  title: "员工技能",
+  visible: false,
+});
+
+const addRow=()=>{
+  dialog.visible=true;
+}
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/sys/employeeSkill",
+  });
+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,
+// });
+
+const ctableRef = ref(null); //crudRef.value 获取avue-crud对象
+const router = useRouter();
+const binding = (row) => {
+  router.push(`/base/bom/${row.materialCode}`);
+};
+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
+option.value = Object.assign(option.value, {
+  selection: true,
+  addBtn:false,
+  column: [
+
+
+    { label: "所属机构", prop: "institution", width: 130,overHidden: true,search: true ,
+      search: true,
+      filterable: true,
+      type: "select",
+      width: 100,overHidden: true,
+      dicUrl:dictDataUtil.dept_list_url,
+      dicMethod:"post",
+      props: { label: "deptName", value: "id" },
+      disabled:true,
+
+    },
+    { label: "员工姓名", prop: "userName", width: 140,overHidden: true,search: true ,rules: [{
+        required: true,
+        search: true,
+        message: "请选择员工姓名",
+        trigger: "blur"
+      }],
+    },
+    {
+      label: "员工编号",
+      prop: "employeeCode",
+      search: true,
+      disabled:true,
+    },
+    { label: "岗位", prop: "postId", overHidden: true,search: true ,
+      search: true,
+      filterable: true,
+      type: "select",
+      overHidden: true,
+      dicUrl:dictDataUtil.post_list_url,
+      dicMethod:"post",
+      props: { label: "postName", value: "id" },
+
+    },
+    { label: "部门", prop: "deptName", overHidden: true,
+      disabled:true, },
+    {
+      label: "分数",
+      prop: "scopes",
+      filterable: true,
+    },
+  ],
+});
+const onSelectedFinish=()=>{
+
+}
+
+</script>

+ 23 - 5
src/views/device/allocate/index.vue

@@ -225,11 +225,14 @@ option.value = Object.assign(option.value, {
       label: "调拨单号",
       prop: "allocateNo",
       display: false,
-      overHidden: true
+      width: 130,
+      overHidden: true,
     },
     {
       label: "设备编号",
       prop: "deviceNo",
+      width: 130,
+      overHidden: true,
       search: true,
       rules: [
         {
@@ -248,12 +251,16 @@ option.value = Object.assign(option.value, {
       label: "设备名称",
       prop: "deviceName",
       addDisabled: true,
+      width: 130,
+      overHidden: true,
       search: true,
     },
     {
       label: "设备类型",
       prop: "deviceType",
       type: "select",
+      width: 100,
+      overHidden: true,
       addDisabled: true,
       search: true,
       dicUrl:
@@ -275,6 +282,8 @@ option.value = Object.assign(option.value, {
       label: "原部门",
       prop: "oldDept",
       type: "tree",
+      width: 130,
+      overHidden: true,
       addDisabled: true,
       dicUrl: dictDataUtil.dept_tree_url,
       props: {
@@ -286,6 +295,8 @@ option.value = Object.assign(option.value, {
       label: "新部门",
       prop: "applyDept",
       type: "tree",
+      width: 130,
+      overHidden: true,
       dicUrl: dictDataUtil.dept_tree_url,
       props: {
         label: "deptName",
@@ -302,11 +313,15 @@ option.value = Object.assign(option.value, {
     {
       label: "原负责人",
       prop: "oldHead",
+      width: 100,
+      overHidden: true,
       addDisabled: true,
     },
     {
       label: "新负责人",
       prop: "newHead",
+      width: 100,
+      overHidden: true,
       rules: [
         {
           required: true,
@@ -319,14 +334,14 @@ option.value = Object.assign(option.value, {
       label: "设备原位置",
       addDisabled: true,
       prop: "devicePosition",
-      width: "115",
-      overHidden: true
+      width: 130,
+      overHidden: true,
     },
     {
       label: "设备新位置",
       prop: "deviceToPosition",
+      width: 130,
       overHidden: true,
-      width: "115",
       rules: [
         {
           required: true,
@@ -360,12 +375,15 @@ option.value = Object.assign(option.value, {
     {
       label: "申请人",
       prop: "applyUser",
+      width: 130,
+      overHidden: true,
       display: false,
     },
     {
       label: "申请时间",
       prop: "created",
-      width: "180",
+      width: 130,
+      overHidden: true,
       display: false,
     },
   ],

+ 129 - 0
src/views/device/data/index.vue

@@ -0,0 +1,129 @@
+<template>
+  <div class="mainContentBox">
+    <avue-crud
+        ref="crudRef"
+        v-model:search="search"
+        v-model="form"
+        :data="data"
+        :option="option"
+        :table-loading="loading"
+        v-model:page="page"
+        @row-save="createRow"
+        @row-update="updateRow"
+        @row-del="deleteRow"
+        @search-change="searchPage"
+        @search-reset="resetChange"
+        @size-change="dataList"
+        @current-change="dataList"
+        @selection-change="selectionChange"
+    >
+    </avue-crud>
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import buttonPermission from "@/common/configs/buttonPermission";
+import {queryDeviceList,queryTypeAliasList} from "@/api/device";
+import { useCommonStoreHook } from "@/store";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+const loading = ref(false);
+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/device/data",
+  });
+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 deviceList = ref([])
+const searchPage = (params, done) =>{
+  if(!search.value.deviceNo || search.value.ts.length == 0){
+    ElMessage.warning("设备或者日期不能为空");
+    done()
+    return;
+  }
+  queryTypeAliasList({deviceNo: search.value.deviceNo}).then((data)=>{
+    if(data.data){
+      option.value.column = [{
+        label: "设备编号",
+        prop: "deviceNo",
+        search: true,
+        hide: true,
+        type: "select",
+        dicData: deviceList,
+        props: { label: "deviceName", value: "deviceNo", },
+      },
+        {
+          label: "采集时间",
+          prop: "ts",
+          search: true,
+          hide: true,
+          type: 'datetimerange',
+          format: 'YYYY-MM-DD HH:mm:ss',
+          valueFormat: 'YYYY-MM-DD HH:mm:ss',
+          searchRange: true,
+          startPlaceholder: '开始范围',
+          endPlaceholder: '结束范围',
+        }, {
+          label: "采集时间",
+          prop: "ts",
+        },
+      ]
+      data.data.forEach(item=>{
+        option.value.column.push({
+          label: item.filedLabel,
+          prop: item.alias,
+          overHidden: true,
+        })
+      })
+    }
+  })
+  search.value.startTime = search.value.ts[0]
+  search.value.endTime = search.value.ts[1]
+  dataList()
+  done()
+
+}
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  delBtn: false,
+  selection: false,
+  index: false,
+  addBtn: false,
+  viewBtn: false,
+  editBtn: false,
+  menu: false,
+  column: [{
+    label: "设备编号",
+    prop: "deviceNo",
+    search: true,
+    hide: true,
+    type: "select",
+    dicData: deviceList,
+    props: { label: "deviceName", value: "deviceNo", },
+  },
+    {
+      label: "采集时间",
+      prop: "ts",
+      search: true,
+      hide: true,
+      type: 'datetimerange',
+      format: 'YYYY-MM-DD HH:mm:ss',
+      valueFormat: 'YYYY-MM-DD HH:mm:ss',
+      searchRange: true,
+      startPlaceholder: '开始范围',
+      endPlaceholder: '结束范围',
+    }],
+});
+onMounted(() => {
+  queryDeviceList({protocol: 1}).then((data)=>{
+    deviceList.value = data.data
+  })
+});
+</script>

+ 145 - 4
src/views/device/instance/index.vue

@@ -16,6 +16,16 @@
         @current-change="dataList"
         @selection-change="selectionChange"
     >
+      <template #menu="{size,row,index}">
+        <el-button
+            v-hasPerm="[buttonPermission.DEVICE.BTNS.maintenance_edit]"
+            type="primary"
+            link
+            size="small"
+            @click="showParamsPage(row)"
+        ><i-ep-edit />参数
+        </el-button>
+      </template>
       <template #menu-left="{ size }">
         <el-button
           :disabled="toDeleteIds.length < 1"
@@ -50,14 +60,65 @@
         </el-button>
       </template>
     </avue-crud>
+    <el-dialog
+        v-model="dialog.visible"
+        :title="dialog.title"
+        width="30%"
+        @close="dialog.visible = false"
+    >
+      <el-button type="primary" @click="addItem" icon="el-icon-plus" style="margin-left:15px;width:25px;height:25px;" circle />
+      <el-table
+          v-loading="loading"
+          ref="ruleListRef"
+          :data="pageData"
+          style="height: 280px"
+      >
+        <el-table-column
+            label="参数"
+            prop="fieldCode"
+        >
+          <template v-slot="{ row}">
+            <el-input v-model="row.fieldCode"/>
+          </template>
+        </el-table-column>
+        <el-table-column
+            label="参数名称"
+            prop="fieldLabel"
+        >
+          <template v-slot="{ row}">
+            <el-input v-model="row.fieldLabel"/>
+          </template>
+        </el-table-column>
+        <el-table-column
+            label="参数值"
+            prop="fieldValue"
+        >
+          <template v-slot="{ row}">
+            <el-input v-model="row.fieldValue"/>
+          </template>
+        </el-table-column>
+        <el-table-column
+            label="操作"
+            align="center"
+        >
+          <template v-slot="{ row}">
+            <el-button type="danger" @click="minusItem(row)" icon="el-icon-minus" style="margin-left:15px;width:25px;height:25px;" circle />
+          </template>
+        </el-table-column>
+      </el-table>
+      <div class="dialog-footer" style="margin-top:20px"  align="center">
+        <el-button type="primary" v-if="pageData.length>0" @click="handleSubmit">保 存</el-button>
+        <el-button @click="dialog.visible = false">取消</el-button>
+      </div>
+    </el-dialog>
     <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
   </div>
 </template>
 <script setup>
 import { ref, getCurrentInstance } from "vue";
 import { useCrud } from "@/hooks/userCrud";
-import ButtonPermKeys from "@/common/configs/buttonPermission";
-
+import buttonPermission from "@/common/configs/buttonPermission";
+import {configSave,configList} from "@/api/device";
 import { useCommonStoreHook } from "@/store";
 import dictDataUtil from "@/common/configs/dictDataUtil";
 const { isShowTable, tableType } = toRefs(useCommonStoreHook());
@@ -65,7 +126,51 @@ const test = () => {
   isShowTable.value = true;
   tableType.value = tableType.value == 1 ? 2 : 1;
 };
-
+const pageData = ref([]);
+const loading = ref(false); //  加载状态
+const addItem = () =>{
+  pageData.value.push({deviceType: clickRow.value.deviceType,deviceNo: clickRow.value.deviceNo,type: 1})
+}
+const minusItem = (row) =>{
+  pageData.value = pageData.value.filter(item=>item.fieldCode !== row.fieldCode)
+}
+const clickRow = ref(null)
+const showParamsPage = (row)=>{
+  clickRow.value = row
+  configList({deviceNo: row.deviceNo}).then((data)=>{
+    pageData.value = data.data
+    dialog.visible = true
+  })
+}
+const dialog = reactive({
+  title: "参数设置",
+  visible: false,
+});
+const handleSubmit = () => {
+  //判断参数
+  let errorData = pageData.value.filter(item=>!item.fieldCode)
+  if(errorData.length > 0){
+    ElMessage.warning("请填写参数");
+    return
+  }
+  errorData = pageData.value.filter(item=>!item.fieldLabel)
+  if(errorData.length > 0){
+    ElMessage.warning("请填写参数名");
+    return
+  }
+  errorData = pageData.value.filter(item=>!item.fieldValue)
+  if(errorData.length > 0){
+    ElMessage.warning("请填写参数值");
+    return
+  }
+  configSave(pageData.value).then((data)=>{
+    if(data.code === '200'){
+      ElMessage.success(data.msg);
+    }else{
+      ElMessage.error(data.msg);
+    }
+  })
+};
 // 传入一个url,后面不带/
 const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
   useCrud({
@@ -74,7 +179,6 @@ const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
 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对象
 
 // 设置表格列或者其他自定义的option
@@ -86,6 +190,8 @@ option.value = Object.assign(option.value, {
       label: "设备编号",
       prop: "deviceNo",
       search: true,
+      width: 160,
+      overHidden: true,
       rules: [
         {
           required: true,
@@ -98,6 +204,8 @@ option.value = Object.assign(option.value, {
       label: "设备名称",
       prop: "deviceName",
       search: true,
+      width: 160,
+      overHidden: true,
       rules: [
         {
           required: true,
@@ -110,6 +218,8 @@ option.value = Object.assign(option.value, {
       label: "设备类型",
       prop: "deviceType",
       type: "select",
+      width: 130,
+      overHidden: true,
       search: true,
       dicUrl:
         dictDataUtil.request_url +
@@ -130,6 +240,8 @@ option.value = Object.assign(option.value, {
       label: "设备状态",
       prop: "state",
       type: "select",
+      width: 160,
+      overHidden: true,
       search: true,
       dicUrl:
           dictDataUtil.request_url +
@@ -149,6 +261,8 @@ option.value = Object.assign(option.value, {
     {
       label: "负责人",
       prop: "head",
+      width: 160,
+      overHidden: true,
       rules: [
         {
           required: true,
@@ -158,12 +272,29 @@ option.value = Object.assign(option.value, {
       ],
     },
     {
+      label: "所属PAC",
+      prop: "terminal",
+      type: "select",
+      width: 160,
+      overHidden: true,
+      search: true,
+      dicUrl:import.meta.env.VITE_APP_BASE_API + "/api/v1/device/pacList",
+      props: {
+        label: "deviceName",
+        value: "deviceNo",
+      }
+    },
+    {
       label: "供应厂商",
       prop: "manufacturer",
+      width: 160,
+      overHidden: true,
     },
     {
       label: "所属部门",
       prop: "deptId",
+      width: 160,
+      overHidden: true,
       type: "tree",
       dicUrl: dictDataUtil.dept_tree_url,
       props: {
@@ -174,21 +305,31 @@ option.value = Object.assign(option.value, {
     {
       label: "所在车间",
       prop: "workshop",
+      width: 160,
+      overHidden: true,
     },
     {
       label: "所在工位",
       prop: "station",
+      width: 160,
+      overHidden: true,
     },
     {
       label: "设备位置",
       prop: "devicePosition",
+      width: 160,
+      overHidden: true,
     },
     {
       label: "规格",
       prop: "specifications",
+      width: 160,
+      overHidden: true,
     },
     {
       label: "品牌",
+      width: 160,
+      overHidden: true,
       prop: "brand",
     },
   ],

+ 100 - 0
src/views/device/log/index.vue

@@ -0,0 +1,100 @@
+<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>
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import { useCommonStoreHook } from "@/store";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+const test = () => {
+  isShowTable.value = true;
+  tableType.value = tableType.value == 1 ? 2 : 1;
+};
+const loading = ref(false); //  加载状态
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/device/log",
+  });
+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对象
+
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  delBtn: false,
+  editBtn: false,
+  selection: true,
+  addBtn: false,
+  column: [
+    {
+      label: "日志来源",
+      prop: "logFrom",
+      search: true,
+    },
+    {
+      label: "日志类型",
+      prop: "logType",
+      search: true,
+      type: 'select',
+      dicData: [{label: "通知",value:"0"},{label: "预警",value:"1"},{label: "错误",value:"2"}],
+      html: true,
+      formatter: (val) => {
+        if (val.logType === "0") {
+          return '<b class="el-tag el-tag--info el-tag--light">通知</b>';
+        } else if (val.logType === "1") {
+          return '<b class="el-tag el-tag--warning el-tag--light">预警</b>';
+        } else if (val.logType === "2") {
+          return '<b class="el-tag el-tag--danger el-tag--light">错误</b>';
+        }
+      },
+    },
+    {
+      label: "日志内容",
+      prop: "logContent",
+      width: 350,
+      overHidden: true
+    },
+    {
+      label: "创建时间",
+      width: 160,
+      display: false,
+      prop: "created",
+    },
+  ],
+});
+
+onMounted(() => {
+  // console.log("crudRef", crudRef)
+  dataList();
+});
+</script>

+ 150 - 0
src/views/device/model/index.vue

@@ -0,0 +1,150 @@
+<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>
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import buttonPermission from "@/common/configs/buttonPermission";
+import {configList} from "@/api/device";
+import { useCommonStoreHook } from "@/store";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+const test = () => {
+  isShowTable.value = true;
+  tableType.value = tableType.value == 1 ? 2 : 1;
+};
+const pageData = ref([]);
+const loading = ref(false); //  加载状态
+const dialog = reactive({
+  title: "参数设置",
+  visible: false,
+});
+const handleSubmit = () => {
+  //
+};
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/device/model",
+  });
+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对象
+
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  delBtn: false,
+  selection: true,
+  column: [
+    {
+      label: "设备类型",
+      prop: "deviceType",
+      type: "select",
+      width: 130,
+      overHidden: true,
+      search: true,
+      dicUrl:
+        dictDataUtil.request_url +
+        dictDataUtil.TYPE_CODE.device_type,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+      rules: [
+        {
+          required: true,
+          message: "设备类型不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "参数",
+      prop: "paramField",
+      rules: [
+        {
+          required: true,
+          message: "参数不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "参数名",
+      prop: "paramLabel",
+      rules: [
+        {
+          required: true,
+          message: "参数名不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "参数类型",
+      prop: "paramType",
+      type: "select",
+      dicUrl:
+          dictDataUtil.request_url +
+          dictDataUtil.EXPAND_FIELD_TABLE.expand_field_type,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+      rules: [
+        {
+          required: true,
+          message: "参数类型不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "创建人",
+      prop: "creator",
+      width: 160,
+      display: false
+    },
+    {
+      label: "创建时间",
+      width: 160,
+      display: false,
+      prop: "created",
+    },
+  ],
+});
+
+onMounted(() => {
+  // console.log("crudRef", crudRef)
+  dataList();
+});
+</script>

+ 196 - 0
src/views/device/pac/index.vue

@@ -0,0 +1,196 @@
+<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>
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import buttonPermission from "@/common/configs/buttonPermission";
+import {configList} from "@/api/device";
+import { useCommonStoreHook } from "@/store";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+const test = () => {
+  isShowTable.value = true;
+  tableType.value = tableType.value == 1 ? 2 : 1;
+};
+const pageData = ref([]);
+const loading = ref(false); //  加载状态
+const dialog = reactive({
+  title: "参数设置",
+  visible: false,
+});
+const handleSubmit = () => {
+  //
+};
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/pac",
+  });
+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对象
+
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  delBtn: false,
+  selection: true,
+  column: [
+    {
+      label: "设备编号",
+      prop: "deviceNo",
+      search: true,
+      width: 160,
+      overHidden: true,
+      rules: [
+        {
+          required: true,
+          message: "设备编号不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "设备名称",
+      prop: "deviceName",
+      search: true,
+      width: 160,
+      overHidden: true,
+      rules: [
+        {
+          required: true,
+          message: "设备名称不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "设备类型",
+      prop: "deviceType",
+      type: "select",
+      width: 130,
+      overHidden: true,
+      search: true,
+      dicUrl:
+        dictDataUtil.request_url +
+        dictDataUtil.TYPE_CODE.device_type,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+      rules: [
+        {
+          required: true,
+          message: "设备类型不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "设备状态",
+      prop: "state",
+      type: "select",
+      width: 160,
+      overHidden: true,
+      search: true,
+      dicUrl:
+          dictDataUtil.request_url +
+          dictDataUtil.TYPE_CODE.device_status,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+      rules: [
+        {
+          required: true,
+          message: "设备状态不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "负责人",
+      prop: "head",
+      width: 160,
+      overHidden: true,
+      rules: [
+        {
+          required: true,
+          message: "负责人不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "供应厂商",
+      prop: "manufacturer",
+      width: 160,
+      overHidden: true,
+    },
+    {
+      label: "所属部门",
+      prop: "deptId",
+      width: 160,
+      overHidden: true,
+      type: "tree",
+      dicUrl: dictDataUtil.dept_tree_url,
+      props: {
+        label: "deptName",
+        value: "id",
+      }
+    },
+    {
+      label: "设备位置",
+      prop: "devicePosition",
+      width: 160,
+      overHidden: true,
+    },
+    {
+      label: "规格",
+      prop: "specifications",
+      width: 160,
+      overHidden: true,
+    },
+    {
+      label: "品牌",
+      width: 160,
+      overHidden: true,
+      prop: "brand",
+    },
+  ],
+});
+
+onMounted(() => {
+  // console.log("crudRef", crudRef)
+  dataList();
+});
+</script>

+ 226 - 0
src/views/device/protocol/index.vue

@@ -0,0 +1,226 @@
+<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="{size,row,index}">
+        <el-switch
+            active-value="1"
+            inactive-value="0"
+            v-model="row.collect"
+            @change="changeItem(row)"
+            class="ml-2"
+            style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
+        />
+      </template>
+    </avue-crud>
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import buttonPermission from "@/common/configs/buttonPermission";
+import {deviceUpdate} from "@/api/device";
+import { useCommonStoreHook } from "@/store";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+const test = () => {
+  isShowTable.value = true;
+  tableType.value = tableType.value == 1 ? 2 : 1;
+};
+const loading = ref(false); //  加载状态
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/device",
+  });
+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 changeItem =(row) => {
+  deviceUpdate({id: row.id,collect: row.collect,deviceNo: row.deviceNo}).then((data)=>{
+    if(data.code === '200'){
+      ElMessage.success(data.msg);
+    }else{
+      ElMessage.error(data.msg);
+    }
+  })
+}
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  delBtn: false,
+  selection: true,
+  addBtn: false,
+  editBtn: false,
+  viewBtn: false,
+  menuTitle: "是否采集",
+  column: [
+    {
+      label: "设备编号",
+      prop: "deviceNo",
+      search: true,
+      width: 160,
+      overHidden: true,
+      rules: [
+        {
+          required: true,
+          message: "设备编号不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "设备名称",
+      prop: "deviceName",
+      search: true,
+      width: 160,
+      overHidden: true,
+      rules: [
+        {
+          required: true,
+          message: "设备名称不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "设备类型",
+      prop: "deviceType",
+      type: "select",
+      width: 130,
+      overHidden: true,
+      search: true,
+      dicUrl:
+        dictDataUtil.request_url +
+        dictDataUtil.TYPE_CODE.device_type,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+      rules: [
+        {
+          required: true,
+          message: "设备类型不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "设备状态",
+      prop: "state",
+      type: "select",
+      width: 160,
+      overHidden: true,
+      search: true,
+      dicUrl:
+          dictDataUtil.request_url +
+          dictDataUtil.TYPE_CODE.device_status,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+      rules: [
+        {
+          required: true,
+          message: "设备状态不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "负责人",
+      prop: "head",
+      width: 160,
+      overHidden: true,
+      rules: [
+        {
+          required: true,
+          message: "负责人不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "所属PAC",
+      prop: "terminal",
+      type: "select",
+      width: 160,
+      overHidden: true,
+      search: true,
+      dicUrl:import.meta.env.VITE_APP_BASE_API + "/api/v1/device/pacList",
+      props: {
+        label: "deviceName",
+        value: "deviceNo",
+      }
+    },
+    {
+      label: "供应厂商",
+      prop: "manufacturer",
+      width: 160,
+      overHidden: true,
+    },
+    {
+      label: "所属部门",
+      prop: "deptId",
+      width: 160,
+      overHidden: true,
+      type: "tree",
+      dicUrl: dictDataUtil.dept_tree_url,
+      props: {
+        label: "deptName",
+        value: "id",
+      }
+    },
+    {
+      label: "所在车间",
+      prop: "workshop",
+      width: 160,
+      overHidden: true,
+    },
+    {
+      label: "所在工位",
+      prop: "station",
+      width: 160,
+      overHidden: true,
+    },
+    {
+      label: "设备位置",
+      prop: "devicePosition",
+      width: 160,
+      overHidden: true,
+    },
+    {
+      label: "规格",
+      prop: "specifications",
+      width: 160,
+      overHidden: true,
+    },
+    {
+      label: "品牌",
+      width: 160,
+      overHidden: true,
+      prop: "brand",
+    },
+  ],
+});
+
+onMounted(() => {
+  search.value.protocol = "1"
+  // console.log("crudRef", crudRef)
+  dataList();
+});
+</script>

+ 64 - 0
src/views/device/rule/components/device-tree.vue

@@ -0,0 +1,64 @@
+<template>
+  <el-card shadow="never">
+    <el-input v-model="deptName" placeholder="设备名称" clearable>
+      <template #prefix>
+        <i-ep-search />
+      </template>
+    </el-input>
+
+    <el-tree
+      ref="deptTreeRef"
+      class="mt-2"
+      :data="deptList"
+      :props="{ children: 'childs', label: 'deviceName', disabled: '' }"
+      :expand-on-click-node="false"
+      :filter-node-method="handleFilter"
+      default-expand-all
+      @node-click="handleNodeClick"
+    />
+  </el-card>
+</template>
+
+<script setup lang="ts">
+import { treeList } from "@/api/device";
+import {defineProps} from "vue";
+
+const emit = defineEmits(["deviceInfo"])
+
+const deptList = ref<OptionType[]>();
+const deptTreeRef = ref(ElTree);
+const deptName = ref();
+
+//const emits = defineEmits(["node-click"]);
+//const emits = defineEmits(['update:modelValue'])
+//const clickObj = useVModel(props, "modelValue", emits);
+//const deviceType = useVModel(props, "deviceType", emits);
+watchEffect?.(
+  () => {
+    deptTreeRef.value.filter(deptName.value);
+  },
+  {
+    flush: "post", // watchEffect会在DOM挂载或者更新之前就会触发,此属性控制在DOM元素更新后运行
+  }
+);
+
+function handleFilter(value: string, data: any) {
+  if (!value) {
+    return true;
+  }
+  return data.deptName.indexOf(value) !== -1;
+}
+
+function handleNodeClick(data: { [key: string]: any }) {
+  emit("deviceInfo", data)
+}
+
+onBeforeMount?.(() => {
+  treeList().then((response) => {
+    if(response.data){
+      emit("deviceInfo", response.data[0])
+    }
+    deptList.value = response.data;
+  });
+});
+</script>

+ 268 - 0
src/views/device/rule/index.vue

@@ -0,0 +1,268 @@
+<!-- 用户管理 -->
+<template>
+  <div class="app-container">
+    <el-row :gutter="20">
+      <el-col :lg="4" :xs="24">
+        <device-tree @deviceInfo="deviceInfo" @node-click="handleQuery" />
+      </el-col>
+      <el-col :lg="20" :xs="24" >
+        <Memo style="width: 1em; height: 1em; margin-right: 8px" />
+        <el-text class="mx-1" size="large">配置列表</el-text>
+        <el-card shadow="never">
+          <el-table
+              v-loading="loading"
+              ref="ruleListRef"
+              :data="pageData"
+              style="height: 280px"
+              @selection-change="handleSelectionChange"
+          >
+            <el-table-column type="selection" width="50" align="center" />
+            <el-table-column
+                label="设备名称"
+                width="150"
+                align="center"
+                prop="deviceName"
+            />
+            <el-table-column
+                label="参数项"
+                width="250"
+                align="center"
+                prop="label"
+            />
+            <el-table-column
+                label="规则内容"
+                align="center"
+                prop="ruleContent"
+            />
+            <el-table-column
+                label="操作"
+                align="center"
+                prop="unit"
+            >
+              <template v-slot="{ row}">
+                <el-button type="danger" @click="minusItem2(row)" icon="el-icon-minus" style="margin-left:15px;width:25px;height:25px;" circle />
+              </template>
+            </el-table-column>
+          </el-table>
+<!--          <pagination
+              v-if="total > 0"
+              v-model:total="total"
+              v-model:page="queryParams.pageNo"
+              v-model:limit="queryParams.pageSize"
+              @pagination="handleQuery"
+          />-->
+
+          <div style="width:100%; height: 20px;"></div>
+          <Edit style="width: 1em; height: 1em; margin-right: 8px" />
+          <el-text class="mx-1" size="large">配置规则</el-text>
+          <el-button type="primary" @click="addItem" icon="el-icon-plus" style="margin-left:15px;width:25px;height:25px;" circle />
+          <el-divider />
+          <el-text v-if="formDataList.length !==0" class="mx-1" type="primary">关系式成立,则异常报警</el-text>
+          <el-form
+              ref="ruleFormRef"
+              label-width="90px"
+          >
+              <el-row :gutter="22" style="margin-top:5px;" v-for="(item, index) in formDataList" :key="index">
+
+                <el-col :span="6">
+                  <el-select
+                      v-model="item.field"
+                      placeholder="请选择字段"
+                      @change="(e) => change1(e, item)"
+                  >
+                    <el-option
+                        v-for="option in fieldOptions"
+                        :key="option.alias"
+                        :label="option.filedLabel"
+                        :value="option.alias"
+                    />
+                  </el-select>
+                </el-col>
+                <el-col :span="6">
+                  <el-select
+                      v-model="item.rule"
+                      placeholder="请选择规则"
+                  >
+                    <el-option label="小于" value="小于"/>
+                    <el-option label="大于" value="大于"/>
+                    <el-option label="等于" value="等于"/>
+                  </el-select>
+                </el-col>
+                <el-col :span="6">
+                  <el-input
+                      v-model="item.val"
+                      placeholder="请输入数值"
+                  />
+                </el-col>
+                <el-col :span="2" v-if="index !== (formDataList.length-1)">
+                  <el-select
+                      v-model="item.luoji"
+                      placeholder="逻辑"
+                  >
+                    <el-option selected label="且" value="且"/>
+                    <el-option label="或" value="或"/>
+                  </el-select>
+                </el-col>
+                <el-col :span="4">
+                  <el-button type="danger" @click="minusItem(index)" icon="el-icon-minus" style="margin-left:15px;width:25px;height:25px;" circle />
+                </el-col>
+              </el-row>
+
+            <div class="dialog-footer" style="margin-top:20px" v-if="formDataList.length > 0" align="center">
+              <el-button type="primary" @click="handleSubmit">确 定</el-button>
+            </div>
+          </el-form>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+import {ElTable} from "element-plus";
+
+defineOptions({
+  name: "rulePage",
+  inheritAttrs: false,
+});
+
+import {
+  rulePage,aliasList,ruleAdd,ruleRemove
+} from "@/api/device/rule";
+import {deleteDict} from "@/api/system/dict";
+const deviceInfo =(value)=>{
+  queryParams.deviceNo = value.deviceNo
+  queryParams.deviceType = value.deviceType
+  handleQuery()
+  queryAliasField(value.deviceType)
+}
+
+const ruleListRef = ref(ElTable);
+const loading = ref(false); //  加载状态
+const queryParams = reactive({
+  pageNo: 1,
+  pageSize: 99999,
+});
+const total = ref(0); // 数据总数
+const pageData = ref<[]>();
+const formDataList = ref([]);
+const options = ref([])
+const addItem =()=>{
+  if(queryParams.deviceNo){
+    formDataList.value.push({luoji: '且'})
+  }else{
+    ElMessage.warning("请先选择设备");
+  }
+}
+const change1 =(val0,item) =>{
+  const selectedOption = fieldOptions.value.find(option => option.alias === val0).filedLabel;
+  item.fieldStr = selectedOption
+}
+const minusItem =(index)=>{
+  formDataList.value.splice(index,1)
+}
+const minusItem2 = (row) =>{
+  ElMessageBox.confirm("确认删除已选中的数据项?", "警告", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(() => {
+    ruleRemove({id: row.id}).then(() => {
+      ElMessage.success("删除成功");
+      handleQuery();
+    });
+  });
+}
+// 用户表单数据
+const formData = reactive({
+  state: 0,
+  sex: 0
+});
+
+const queryAliasField = (deviceType)=>{
+  aliasList({deviceType: deviceType}).then((data)=>{
+    fieldOptions.value = data.data
+  })
+}
+const fieldOptions = ref([])
+const clickId = ref([])
+/** 查询 */
+function handleQuery() {
+  loading.value = true;
+  if(queryParams.deviceNo){
+    rulePage(queryParams)
+        .then(({ data }) => {
+          pageData.value = data.records;
+          total.value = data.totalCount;
+        })
+        .finally(() => {
+          loading.value = false;
+        });
+  }
+}
+
+
+/** 行选中 */
+function handleSelectionChange(selection: any) {
+  if(selection.length > 1){
+    const preVal = selection.shift()
+    ruleListRef.value.toggleRowSelection(preVal, false);
+  }
+  clickId.value = null
+  if(selection.length === 0){
+    formDataList.value = []
+  }else{
+    clickId.value = selection[0].id
+    formDataList.value = JSON.parse(selection[0].ruleExpression)
+  }
+}
+
+
+
+/** 表单提交 */
+const handleSubmit = useThrottleFn(() => {
+  let constStr = ""
+  let field = ""
+  let label = ""
+  if(formDataList.value){
+    formDataList.value.forEach(item=>{
+      if(!item.field){
+        ElMessage.warning("请选择字段");
+        return
+      }
+      if(!item.rule){
+        ElMessage.warning("请选择规则");
+        return
+      }
+      if(!item.val){
+        ElMessage.warning("请填写规则");
+        return
+      }
+      if(constStr !== ''){
+        constStr += item.luoji
+      }
+      constStr += item.fieldStr + item.rule + item.val
+      if(field === ''){
+        field = item.field
+      }else{
+        field += ',' + item.field
+      }
+      if(label === ''){
+        label = item.fieldStr
+      }else{
+        label += ',' + item.fieldStr
+      }
+    })
+  }
+  const params = {id: clickId.value,field: field,label: label,deviceNo: queryParams.deviceNo,ruleContent: constStr,ruleExpression: JSON.stringify(formDataList.value)}
+  ruleAdd(params).then((data)=>{
+    ElMessage.success(data.msg);
+    formDataList.value = []
+    handleQuery()
+  })
+}, 3000);
+
+onMounted?.(() => {
+  handleQuery();
+});
+</script>

+ 293 - 0
src/views/plan/prepare/index.vue

@@ -0,0 +1,293 @@
+<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>
+    <el-dialog
+        v-model="dialog.visible"
+        :title="dialog.title"
+        width="80%"
+        @close="dialog.visible = false"
+    >
+      <work-order-page queryType="1"  @orderInfo="orderInfo"/>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import ButtonPermKeys from "@/common/configs/buttonPermission";
+
+import { useCommonStoreHook } from "@/store";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+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/process/prepare",
+  });
+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 dialog = reactive({
+  title: "订单选择",
+  visible: false,
+});
+const orderInfo = (value) => {
+  form.value.workOrderCode = value.workOrderCode
+  form.value.orderCode = value.orderCode
+  form.value.orderName = value.orderName
+  form.value.materialCode = value.materialCode
+  form.value.materialName = value.materialName
+  form.value.materialModel = value.materialModel
+  dialog.visible = false
+}
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  delBtn: false,
+  selection: true,
+  editBtn: false,
+  dialogWidth: '45%', // 设置编辑弹窗的宽度为50%
+  column: [
+    {
+      label: "工单号",
+      prop: "workOrderCode",
+      search: true,
+      width: 150,
+      overHidden: true,
+      rules: [
+        {
+          required: true,
+          message: "工单号不能为空",
+          trigger: "trigger",
+        },
+      ],
+      click: ({ value, column }) => {
+        if(column.boxType){
+          dialog.visible = true
+        }
+      },
+    },
+    {
+      label: "计划单号",
+      prop: "orderCode",
+      search: true,
+      width: 150,
+      overHidden: true,
+      disabled: true,
+      rules: [
+        {
+          required: true,
+          message: "计划单号不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "计划名称",
+      prop: "orderName",
+      search: true,
+      disabled: true,
+      width: 150,
+      overHidden: true,
+      rules: [
+        {
+          required: true,
+          message: "计划名称不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "产品编码",
+      prop: "materialCode",
+      search: true,
+      width: 150,
+      overHidden: true,
+      disabled: true,
+      rules: [
+        {
+          required: true,
+          message: "产品编码不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "产品名称",
+      prop: "materialName",
+      disabled: true,
+      width: 150,
+      overHidden: true,
+      search: true,
+      rules: [
+        {
+          required: true,
+          message: "产品名称不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "产品规格",
+      prop: "materialModel",
+      disabled: true,
+      search: true,
+      width: 150,
+      overHidden: true,
+      rules: [
+        {
+          required: true,
+          message: "产品规格不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "工艺文件",
+      width: 150,
+      overHidden: true,
+      prop: "craftFiles",
+      type: 'checkbox',
+      span: 24,
+      multiple: true,
+      dicUrl:
+          dictDataUtil.request_url + dictDataUtil.TYPE_CODE.prepare_craft_file,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+    },
+    {
+      label: "工艺路线",
+      width: 150,
+      span: 24,
+      type: "radio",
+      overHidden: true,
+      prop: "routeId",
+      dicData: [
+        {
+          label: "版本正确",
+          value: "1",
+        },
+        {
+          label: "版本不正确",
+          value: "0",
+        },
+      ],
+    },
+    {
+      label: "图纸资料",
+      prop: "dataFiles",
+      width: 150,
+      overHidden: true,
+      type: 'checkbox',
+      span: 24,
+      multiple: true,
+      dicUrl:
+          dictDataUtil.request_url + dictDataUtil.TYPE_CODE.prepare_data_file,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+    },
+    {
+      label: "设备状况",
+      prop: "deviceStates",
+      width: 150,
+      overHidden: true,
+      type: 'checkbox',
+      span: 24,
+      multiple: true,
+      dicUrl:
+          dictDataUtil.request_url + dictDataUtil.TYPE_CODE.prepare_device_info,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+    },
+    {
+      label: "物料状态",
+      prop: 'materialState',
+      type: "radio",
+      width: 130,
+      overHidden: true,
+      span: 24,
+      dicData: [
+        {
+          label: "齐套",
+          value: 1,
+        },
+        {
+          label: "未齐套",
+          value: 0,
+        },
+      ],
+    },
+    {
+      label: "创建时间",
+      prop: "created",
+      width: 160,
+      display: false
+    },
+    {
+      label: "创建人",
+      prop: "creator",
+      display: false
+    },
+  ],
+});
+
+onMounted(() => {
+  form.value.routeId = "1"
+  form.value.materialState = 1
+  // 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/device/import");
+  }
+};
+</script>

+ 145 - 0
src/views/plan/schedule/index.vue

@@ -0,0 +1,145 @@
+<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 }">
+        <div id="charts"></div>
+      </template>
+    </avue-crud>
+  </div>
+</template>
+<script setup>
+import { ref } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+
+import { useDictionaryStoreHook } from "@/store";
+
+// 数据字典相关
+const { dicts } = useDictionaryStoreHook();
+
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/plan/task",
+  });
+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(() => {
+  dataList();
+});
+
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  selection: true,
+  menu: false,
+  addBtn: false,
+  filterBtn: false,
+  searchShowBtn: false,
+  columnBtn: false,
+  gridBtn: false,
+  column: [
+    {
+      label: "序列号",
+      prop: "seqNo",
+      search: true,
+    },
+    {
+      label: "工位名称",
+      prop: "stationName",
+      search: true,
+    },
+    {
+      label: "工单编码",
+      prop: "workOrderCode",
+      search: true,
+    },
+    {
+      label: "工单名称",
+      prop: "workOrderName",
+    },
+    {
+      label: "产线编码",
+      prop: "productLineCode",
+      search: true,
+    },
+    {
+      label: "产线名称",
+      prop: "productLineName",
+    },
+    {
+      label: "工艺路线名称",
+      prop: "routeName",
+    },
+    {
+      label: "物料编号",
+      prop: "materialCode",
+      search: true,
+    },
+    {
+      label: "工单名称",
+      prop: "workOrderName",
+    },
+    {
+      label: "工序编码",
+      prop: "operationCode",
+      search: true,
+    },
+    {
+      label: "工序名称",
+      prop: "operationName",
+    },
+
+    {
+      label: "状态",
+      prop: "state",
+      type: "select",
+      search: true,
+      dicUrl:
+        dictDataUtil.request_url + dictDataUtil.TYPE_CODE.station_task_state,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+    },
+    {
+      label: "计划开始时间",
+      prop: "planStartWhen",
+    },
+    {
+      label: "计划结束时间",
+      prop: "planStartEnd",
+    },
+    {
+      label: "修改时间",
+      prop: "updated",
+    },
+  ],
+});
+</script>
+
+<style lang="scss" scoped>
+#charts {
+  width: 100%;
+  height: 300px;
+}
+</style>

+ 213 - 0
src/views/plan/workOrder/components/work-order-page.vue

@@ -0,0 +1,213 @@
+<template>
+  <div class="mainContentBox">
+    <avue-crud
+        ref="crudRef"
+        v-model:search="search"
+        v-model="form"
+        :data="data"
+        :option="option"
+        v-model:page="page"
+        @row-click="rowClick"
+        @search-change="searchChange"
+        @search-reset="resetChange"
+        @size-change="dataList"
+        @current-change="dataList"
+    >
+    </avue-crud>
+  </div>
+</template>
+<script setup>
+import {defineProps, ref} from "vue";
+import { useCrud } from "@/hooks/userCrud";
+
+import { useCommonStoreHook } from "@/store";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+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/plan/workOrder",
+  });
+const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } = Methords; //增删改查
+const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
+const { checkBtnPerm, downloadTemplate } = Utils; //按钮权限等工具
+
+const crudRef = ref(null); //crudRef.value 获取avue-crud对象
+const emit = defineEmits(["orderInfo"])
+const rowClick = (row)=>{
+  emit("orderInfo", row)
+}
+const props = defineProps({
+  queryType: {
+    type: String,
+    default: () => {
+      return "0";
+    }
+  }
+})
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  delBtn: false,
+  selection: false,
+  search: false,
+  editBtn: false,
+  addBtn: false,
+  viewBtn: false,
+  menu: false,
+  column: [
+    {
+      label: "工单编号",
+      prop: "workOrderCode",
+      search: true,
+      display: false,
+      width: 125,
+      overHidden: true,
+    },
+    {
+      label: "订单编号",
+      prop: "orderCode",
+      search: true,
+      width: 125,
+      overHidden: true,
+    },
+    {
+      label: "订单名称",
+      prop: "orderName",
+      search: true,
+      disabled: true,
+      width: 125,
+      overHidden: true,
+    },
+    {
+      label: "产品编号",
+      width: 125,
+      overHidden: true,
+      search: true,
+      disabled: true,
+      prop: "materialCode",
+    },
+    {
+      label: "产品名称",
+      width: 125,
+      overHidden: true,
+      search: true,
+      disabled: true,
+      prop: "materialName",
+    },
+    {
+      label: "产品规格",
+      width: 125,
+      search: true,
+      overHidden: true,
+      disabled: true,
+      prop: "materialModel",
+    },
+    {
+      label: "优先级",
+      prop: "priority",
+      display: false,
+      width: "80",
+      type: "select", //类型为下拉选择框
+      dicUrl:
+          dictDataUtil.request_url + dictDataUtil.TYPE_CODE.plan_order_priority,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+    },
+    {
+      label: "状态",
+      prop: "workOrderState",
+      width: "80",
+      display: false,
+      type: "select", //类型为下拉选择框
+      dicUrl:
+          dictDataUtil.request_url + dictDataUtil.TYPE_CODE.plan_work_order_state,
+      props: {
+        label: "dictLabel",
+        value: "dictValue",
+      },
+    },
+    {
+      label: "工艺路线",
+      prop: "processRouteName",
+      width: 125,
+      overHidden: true,
+    },
+    {
+      label: "生产车间",
+      prop: "workshopName",
+      width: 120,
+      overHidden: true,
+    },
+    {
+      label: "产线名称",
+      prop: "productLineName",
+      width: 120,
+      overHidden: true,
+    },
+    {
+      label: "开始时间",
+      prop: "planStartWhen",
+      width: 180,
+      overHidden: true,
+      display: false,
+    },
+    {
+      label: "结束时间",
+      prop: "planStartEnd",
+      width: 180,
+      display: false,
+      overHidden: true,
+    },
+    {
+      label: "工单数量",
+      prop: "planNum",
+      width: 85,
+      type: "number",
+      min: 1,
+      max: 99999,
+    },
+    {
+      label: "完成数量",
+      width: 85,
+      display: false,
+      prop: "completeNum",
+
+    },
+    {
+      label: "下线数量",
+      width: 85,
+      display: false,
+      prop: "beforeNum",
+    },
+    {
+      label: "报废数量",
+      width: 85,
+      display: false,
+      prop: "scrapNum",
+    },
+    {
+      label: "创建时间",
+      width: 180,
+      display: false,
+      prop: "created",
+    },
+    {
+      label: "创建人",
+      width: 90,
+      display: false,
+      prop: "creator",
+    },
+  ],
+});
+
+onMounted(() => {
+  search.value.queryType = props.queryType
+  dataList();
+});
+</script>

+ 173 - 130
src/views/system/post/components/post-skill.vue

@@ -1,123 +1,109 @@
-<!--<template>
+<template>
+  <div class="mainContentBox">
+    <!--{{dataDetail}}-->
+    <!--{{dicts}}-->
+    <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"
+          circle
+          @click="addSkill"
+        ></el-button
+        ></template>
 
-  <avue-form :option="option"
-             v-model="form">
-    <template #input="{row}">
+      <template #footer>
+        <div class="detail-footer">
+          <el-button type="primary" @click="addList"> 保存 </el-button>
+          <el-button @click="cancel">取消</el-button>
 
-    </template>
-  </avue-form>
-</template>
-<script ssetup lang="ts">
-  export default {
-    data () {
-      return {
-        form: {
-          dynamic: [{
-            input: 1,
-            select: 1
-          }, {
-            input: 2,
-            select: 2
-          }]
-        },
-        option: {
-          column: [
-            {
-              label: '技能',
-              prop: 'dynamic',
-              type: 'dynamic',
-              span: 24,
-              children: {
-                align: 'center',
-                headerAlign: 'center',
-                rowAdd: (done) => {
-                  this.$message.success('新增回调');
-                  done({
-                    input: '默认值'
-                  });
-                },
-                rowDel: (row, done) => {
-                  this.$message.success('删除回调' + JSON.stringify(row));
-                  done();
-                },
-                column: [{
-                  label: '选择框',
-                  prop: "select",
-                  type: 'select',
-                  dicData: [{
-                    label: '测试1',
-                    value: 1
-                  }, {
-                    label: '测试2',
-                    value: 2
-                  }]
-                }]
-              }
-            },
+        </div>
+      </template>
+    </avue-crud>
 
-          ]
-        }
-      }
-    },
-    methods: {
-      addAll () {
-        for (let i = 0; i < 10; i++) {
-          this.form.dynamic.push({
-            input: 1,
-            select: 1
-          })
-        }
-      }
-    }
-  }
-</script>-->
-
-<template>
-<avue-form :option="option"
-           v-model="form">
-  <template #input="{row}">
-
-  </template>
-</avue-form>
+  </div>
 </template>
 <script setup lang="ts">
   import { ref, getCurrentInstance } from "vue";
   import { useCrud } from "@/hooks/userCrud";
   import ButtonPermKeys from "@/common/configs/buttonPermission";
-  import { useCommonStoreHook } from "@/store";
-
+  import { useCommonStoreHook, useDictionaryStoreHook } from "@/store/index";
+  import {addPostSkill} from "../../../../api/system/skill";
   const { isShowTable, tableType } = toRefs(useCommonStoreHook());
-  import { useDictionaryStoreHook } from "@/store";
+  // 数据字典相关
   const { dicts } = useDictionaryStoreHook();
-  import {
-    addStationDevice,
-  } from "@/api/station";
+  const router = useRouter();
+  const route = useRoute();
+
+  const dataDetail=ref({});
   const test = () => {
     isShowTable.value = true;
     tableType.value = tableType.value == 1 ? 2 : 1;
   };
-  const props = defineProps({
-    postId: {
-      type: Number,
-      default: () => {
-        return 0;
+
+  const formData=ref({});
+  const dataBomLists=()=>{
+    search.value.materialCode=route.value.materialCode;
+    dataNoPageList();
+  }
+
+
+  const dialog=ref(null);
+
+
+
+  const addList=()=>{
+    for(var i=0;i<data.value.length;i++){
+      if(data.value[i].skillDictValue==="0"||data.value[i].skillDictValue ===null){
+        ElMessage({
+          message:"技能选项存在空值",
+          type: "error",
+        });
+        return;
       }
     }
-  })
-
-  watch?.(
-    () => props.postId,
-    (newVal: string) => {
-      search.value.postId = newVal
-      dataList()
+    if(data.value.length===0){
+      ElMessage({
+        message: "没有添加记录!",
+        type: "error",
+      });
+      return;
     }
-  );
+    addPostSkill(data.value).then(
+      (data: any)=>{
+        if(data.code==="200") {
+          ElMessage({
+            message: data.msg,
+            type: "success",
+          });
+        }
+        else {
+          ElMessage({
+            message: data.msg,
+            type: "error",
+          });
+        }
+        props.dialog.visible=false;
+      }
+    );
+  }
   // 传入一个url,后面不带/
   const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
     useCrud({
       src: "/api/v1/sys/postSkill",
     });
-  const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
+  const { dataNoPageList,createRow, updateRow, deleteRow, searchChange, resetChange } =
     Methords; //增删改查
   const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
   const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
@@ -128,44 +114,101 @@
   //   editBtn: checkPerm(buttonPermission.PLAN.BTNS.order_edit),
   //   menu: true,
   // });
-  const crudRef = ref(null); //crudRef.value 获取avue-crud对象
 
+  const crudRef = ref(null); //crudRef.value 获取avue-crud对象
+  const props = defineProps({
+    postId: {
+      type: Number,
+      default: () => {
+        return 0;
+      }
+    },
+    dialog:{
+      type:Object,
+      default:()=>{
+        return {};
+      }
+    }
+  })
   onMounted(() => {
     // console.log("crudRef", crudRef)
-    dataList();
+    search.value.postId=props.postId;
+    dataNoPageList();
+
   });
- /* const form=ref({
-    dynamic: [{
-      input: 1,
-      select: 1
-    }, {
-      input: 2,
-      select: 2
-    }]
-  });*/
+   const cancel=()=>{
+     props.dialog.visible=false;
+   }
+  /**
+   * 上传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, {
-    column: [
-      {label: '技能',
-      prop: 'dynamic',
-      type: 'dynamic',
-      span: 24,
-      children: {
-        align: 'center',
-        type: 'form',
-        headerAlign: 'center',
-        column: [
-          {
-            label: "技能",
-            prop: "skill_dict_value",
-            type: 'select',
-            dicData:dicts.skill_type,
-            props: { label: "dictLabel", value: "dictValue" },
-          }
-        ]
-      }
-    }
-    ],
+    selection: false,
+    addBtn: false,
+    viewBtn: false,
+    editBtn:false,
+    saveBtn:false,
+    cellBtn: true,
+    column: [{
+      label: "技能",
+      prop: "skillDictValue",
+      align: 'center',
+      headerAlign: 'center',
+      cell: true,
+      span:24,
+      type: 'select',
+      dicData:dicts.skill_type,
+      props: {
+        label: "dictLabel", // 下拉菜单显示的字段
+        value: "dictValue" // 下拉菜单值的字
+      },
+    },],
   });
+  const routeBack =()=>{
+    router.back();
+  }
+  const addSkill = () => {
+    const bom=ref({
+      postId:props.postId,
+      $cellEdit:true,
+    });
+    data.value.push(bom.value);
+  };
 
 </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;
+  }
+  .el-select__selection{
+    width: 400px;
+  }
+
+</style>

+ 1 - 2
src/views/system/post/index.vue

@@ -40,7 +40,7 @@
       width="800px"
       @close="dialog.visible = false"
     >
-      <post-skill  :postId="post.id"/>
+      <post-skill  :postId="post.id" :dialog="dialog"/>
     </el-dialog>
     <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
   </div>
@@ -62,7 +62,6 @@ const binding=(row)=>{
   post.value=row;
   dialog.visible=true;
 }
-
 // 传入一个url,后面不带/
 const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
   useCrud({