瀏覽代碼

设备相关

qinhb 1 年之前
父節點
當前提交
d76f11d82f

+ 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,
+  });
+}
+
+

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

@@ -0,0 +1,31 @@
+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,
+    });
+}
+

+ 7 - 1
src/common/configs/dictDataUtil.ts

@@ -42,7 +42,13 @@ 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",
   },
   EXPAND_FIELD_TABLE: {
     //字段类型

+ 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,
     },
   ],

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

@@ -0,0 +1,125 @@
+<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: 'daterange',
+          format: 'YYYY-MM-DD HH:mm:ss',
+          valueFormat: 'YYYY-MM-DD HH:mm:ss',
+          searchRange: true,
+          startPlaceholder: '开始范围',
+          endPlaceholder: '结束范围',
+        }]
+      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: 'daterange',
+      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>

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

@@ -0,0 +1,250 @@
+<!-- 用户管理 -->
+<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"
+            />-->
+          </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
+} from "@/api/device/rule";
+const deviceInfo =(value)=>{
+  queryParams.deviceNo = value.deviceNo
+  queryParams.deviceType = value.deviceType
+  handleQuery()
+  queryAliasField(value.deviceType)
+}
+
+const queryFormRef = ref(ElForm); // 查询表单
+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 formData = reactive({
+  state: 0,
+  sex: 0
+});
+
+const queryAliasField = (deviceType)=>{
+  aliasList({deviceType: deviceType}).then((data)=>{
+    fieldOptions.value = data.data
+  })
+}
+const fieldOptions = 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);
+  }
+  if(selection.length === 0){
+    formDataList.value = []
+  }else{
+    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 = {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>

+ 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>