Przeglądaj źródła

Merge remote-tracking branch 'remotes/origin/xf_dev' into js_dev

# Conflicts:
#	.env.development
qinhb 2 miesięcy temu
rodzic
commit
cfffd034a7
56 zmienionych plików z 2874 dodań i 255 usunięć
  1. 20 0
      .run/docker_Dockerfile_xf.run.xml
  2. 3 2
      README.md
  3. 7 2
      docker/Dockerfile_xf
  4. 10 0
      src/api/aps/index.ts
  5. 8 0
      src/api/bigScreen/index.ts
  6. 12 0
      src/api/fault/index.ts
  7. 16 0
      src/api/plan/index.ts
  8. 10 0
      src/api/process/index.ts
  9. 7 0
      src/api/report/index.ts
  10. 39 0
      src/api/returnMaterial/index.ts
  11. 27 0
      src/api/storage/index.ts
  12. 2 0
      src/common/configs/dictDataUtil.ts
  13. 18 0
      src/hooks/timeInterval.ts
  14. 3 0
      src/layout/components/NavBar/components/NavbarRight.vue
  15. 5 0
      src/router/index.ts
  16. 2 2
      src/views/base/bom/index.vue
  17. 8 8
      src/views/base/craftManagement/process/index.vue
  18. 4 4
      src/views/base/craftManagement/route/bindConfig.ts
  19. 7 4
      src/views/base/craftManagement/route/bindProcess.vue
  20. 6 6
      src/views/base/craftManagement/route/components/bottomTable.vue
  21. 46 12
      src/views/base/craftManagement/route/index.vue
  22. 34 13
      src/views/base/materials/index.vue
  23. 26 2
      src/views/base/modeling/station/index.vue
  24. 42 2
      src/views/device/instance/index.vue
  25. 2 2
      src/views/device/screwdriver/index.vue
  26. 18 6
      src/views/plan/order/index.vue
  27. 11 10
      src/views/plan/prepare/index.vue
  28. 159 99
      src/views/plan/prepareTemplate/index.vue
  29. 82 0
      src/views/plan/requisition/exportInfo.vue
  30. 35 11
      src/views/plan/requisition/index.vue
  31. 154 0
      src/views/plan/requisition/print.vue
  32. 306 0
      src/views/plan/returnMaterial/index.vue
  33. 24 1
      src/views/plan/schedule/index.vue
  34. 10 1
      src/views/plan/workOrder/components/work-order-seq.vue
  35. 38 1
      src/views/plan/workOrder/index.vue
  36. 6 6
      src/views/pro/baseoperation/index.vue
  37. 6 2
      src/views/pro/traceability/components/collectionCom.vue
  38. 78 2
      src/views/quality/outsource/index.vue
  39. 153 0
      src/views/quality/unqualified/index.vue
  40. 99 0
      src/views/report/statistics/outTime/components/PieChart1.vue
  41. 99 0
      src/views/report/statistics/outTime/components/PieChart2.vue
  42. 99 0
      src/views/report/statistics/outTime/components/PieChart3.vue
  43. 148 0
      src/views/report/statistics/outTime/index.vue
  44. 13 7
      src/views/report/statistics/screens/line/index.vue
  45. 252 0
      src/views/report/statistics/screens/repertoryStatistic/index.vue
  46. 204 29
      src/views/report/statistics/screens/tasks/index.vue
  47. 15 2
      src/views/storage/alarm/index.vue
  48. 133 0
      src/views/storage/entry/index.vue
  49. 14 2
      src/views/storage/stock/index.vue
  50. 4 3
      src/views/storage/storage/index.vue
  51. 161 0
      src/views/storage/warningInfo/index.vue
  52. 163 0
      src/views/storage/warningRole/index.vue
  53. 7 0
      src/views/storage/wmsOrder/index.vue
  54. 5 1
      src/views/system/dept/index.vue
  55. 12 12
      src/views/system/user/index.vue
  56. 2 1
      vite.config.ts

+ 20 - 0
.run/docker_Dockerfile_xf.run.xml

@@ -0,0 +1,20 @@
+<component name="ProjectRunConfigurationManager">
+  <configuration default="false" name="docker/Dockerfile_xf" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
+    <deployment type="dockerfile">
+      <settings>
+        <option name="imageTag" value="mes-admin-xf:latest" />
+        <option name="containerName" value="mes-admin-xf" />
+        <option name="portBindings">
+          <list>
+            <DockerPortBindingImpl>
+              <option name="containerPort" value="80" />
+              <option name="hostPort" value="10000" />
+            </DockerPortBindingImpl>
+          </list>
+        </option>
+        <option name="sourceFilePath" value="docker/Dockerfile_xf" />
+      </settings>
+    </deployment>
+    <method v="2" />
+  </configuration>
+</component>

+ 3 - 2
README.md

@@ -3,8 +3,9 @@
 git clone https://gitee.com/icemelonreagon/vue-admin.git
 # 安装 pnpm
 npm install pnpm -g
-# 安装依赖
-pnpm install
+# 安装依赖 一定要这么安装,不然会出现各种问题
+pnpm install --frozen-lockfile
+
 # 启动运行
 pnpm run dev
 

+ 7 - 2
docker/Dockerfile_xf

@@ -5,16 +5,21 @@ VOLUME /tmp
 ENV LANG en_US.UTF-8
 RUN echo "server {  \
                       listen       80; \
+                      gzip          on; \
+                      gzip_static on; \
+                      gzip_types text/plain text/css application/json application/javascript;\
+                      gzip_min_length 1024;\
+                      gzip_vary on;\
                       client_max_body_size 100m;\
                       location   /mes-server/ { \
-                      proxy_pass              http://192.168.101.4:8078/; \
+                      proxy_pass              http://139.155.176.112:8078/; \
                       proxy_redirect          off; \
                       proxy_set_header        Host mes-server; \
                       proxy_set_header        X-Real-IP \$remote_addr; \
                       proxy_set_header        X-Forwarded-For \$proxy_add_x_forwarded_for; \
                   } \
                   location /jgfile/ { \
-                              proxy_pass          http://192.168.101.4:9000/jgfile/; \
+                              proxy_pass          http://139.155.176.112:19000/jgfile/; \
                               proxy_redirect      off; \
                               proxy_set_header    Host jgfile; \
                               proxy_set_header    X-Real-IP \$remote_addr; \

+ 10 - 0
src/api/aps/index.ts

@@ -0,0 +1,10 @@
+import request from "@/utils/request";
+import { AxiosPromise } from "axios";
+
+export function syncAps(data): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/aps/sync",
+    method: "post",
+    data: data,
+  });
+}

+ 8 - 0
src/api/bigScreen/index.ts

@@ -54,6 +54,14 @@ export function getOffLineInfo() {
     method: "post",
   });
 }
+// 线边库库存统计数据
+export function getLineSideStock() {
+  return request({
+    url: "/api/v1/process/census/stock/info",
+    method: "post",
+  });
+}
+
 export function getStationState() {
   return request({
     url: "/api/v1/process/census/station/state",

+ 12 - 0
src/api/fault/index.ts

@@ -98,3 +98,15 @@ export function updateFault(data:Object) {
   });
 }
 
+/**
+ * 获取不合格品审理单二维码
+ *
+ * @param id
+ * @param data
+ */
+export function getFaultScanCode(id: Number): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/process/escalationFault/scan/" + id,
+    method: "get",
+  });
+}

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

@@ -0,0 +1,16 @@
+import request from "@/utils/request";
+//获取物料信息
+export function getMaterialInfo(code: string) {
+  return request({
+    url: `/api/v1/plan/requisition/queryReceive/${code}`,
+    method: "get",
+  });
+}
+//获取配置后信息
+export function getPrintInfo(data: any) {
+  return request({
+    url: `/api/v1/plan/requisition/handleExcel`,
+    method: "post",
+    data
+  });
+}

+ 10 - 0
src/api/process/index.ts

@@ -48,3 +48,13 @@ export function sendTdm(
     data: params
   });
 }
+
+export function sendTdmTBom(
+  params: object
+): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/process/outsource/bom",
+    method: "post",
+    data: params
+  });
+}

+ 7 - 0
src/api/report/index.ts

@@ -32,3 +32,10 @@ export function getOperationInfo(data: string) {
     data,
   });
 }
+export function outTimeInfo(data: string) {
+  return request({
+    url: "/api/v1/process/census/outTime/info",
+    method: "post",
+    data: {}
+  });
+}

+ 39 - 0
src/api/returnMaterial/index.ts

@@ -0,0 +1,39 @@
+import request from "@/utils/request";
+import { AxiosPromise } from "axios";
+
+export function addReturnMaterial(data: object): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/ReturnDetails/add",
+    method: "post",
+    data: data,
+  });
+}
+
+export function queryList(data: object): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/ReturnDetails/list",
+    method: "post",
+    data: data,
+  });
+}
+export function sendWms(data: object): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/ReturnDetails/send",
+    method: "post",
+    data: data,
+  });
+}
+export function del(data: object): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/ReturnDetails/del",
+    method: "post",
+    data: data,
+  });
+}
+export function scanItem(data: object): AxiosPromise<any> {
+  return request({
+    url: "/mes/query/scanCode",
+    method: "post",
+    data: data,
+  });
+}

+ 27 - 0
src/api/storage/index.ts

@@ -69,3 +69,30 @@ export function syncPositionVehicle(
     data: queryParams,
   });
 }
+export function queryWarningUser(
+    queryParams: object
+): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/warningUser/page",
+    method: "post",
+    data: queryParams,
+  });
+}
+export function delWarningUser(
+    queryParams: object
+): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/warningUser/del",
+    method: "post",
+    data: queryParams,
+  });
+}
+export function addWarningUser(
+    queryParams: object
+): AxiosPromise<any> {
+  return request({
+    url: "/api/v1/warningUser/add",
+    method: "post",
+    data: queryParams,
+  });
+}

+ 2 - 0
src/common/configs/dictDataUtil.ts

@@ -19,6 +19,8 @@ const DictDataUtil = {
     plan_work_order_state: "plan_work_order_state",
     //订单状态
     plan_order_state: "plan_order_state",
+    //预警角色
+    warning_role: "warning_role",
     //设备类型
     device_type: "device_type",
     //设备状态

+ 18 - 0
src/hooks/timeInterval.ts

@@ -0,0 +1,18 @@
+import { onMounted, onUnmounted, ref } from "vue";
+
+export function useTimeInterval(callback, delay = 300000) {
+  const intervalId = ref(null);
+
+  onMounted(() => {
+    // 设置定时器,每5分钟(300000毫秒)执行一次回调函数
+    callback();
+    intervalId.value = setInterval(callback, delay);
+  });
+
+  onUnmounted(() => {
+    // 组件卸载时清除定时器
+    if (intervalId.value) {
+      clearInterval(intervalId.value);
+    }
+  });
+}

+ 3 - 0
src/layout/components/NavBar/components/NavbarRight.vue

@@ -153,6 +153,9 @@ const clickItem =(row) =>{
   if(row.msgId === '4'){
     window.open("/outsource",'_blank')
   }
+  if(row.msgId === '5'){
+    window.open("/storage/warningInfo",'_blank')
+  }
 }
 const openMessageDialog = () => {
   handleQuery();

+ 5 - 0
src/router/index.ts

@@ -63,6 +63,11 @@ export const constantRoutes: RouteRecordRaw[] = [
     path: "/lineScreen",
     component: () => import("@/views/report/statistics/screens/line/index.vue"),
   },
+  {
+    path: "/repertoryStatistic",
+    component: () =>
+      import("@/views/report/statistics/screens/repertoryStatistic/index.vue"),
+  },
   // 外部链接
   // {
   //   path: "/external-link",

+ 2 - 2
src/views/base/bom/index.vue

@@ -67,7 +67,7 @@
         </div>
       </template>
 
-      <template #menu-right="{}">
+<!--      <template #menu-right="{}">
         <el-dropdown split-button
           >导入
           <template #dropdown>
@@ -84,7 +84,7 @@
           </template>
         </el-dropdown>
         <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
-      </template>
+      </template>-->
     </avue-crud>
     <CommonTable
       ref="ctableRef"

+ 8 - 8
src/views/base/craftManagement/process/index.vue

@@ -26,7 +26,7 @@
           >删除</el-button
         >
       </template>
-      <template #menu-right="{}">
+<!--      <template #menu-right="{}">
         <el-dropdown split-button
           >导入
           <template #dropdown>
@@ -42,13 +42,13 @@
             </el-dropdown-menu>
           </template>
         </el-dropdown>
-        <!-- <el-button
+        &lt;!&ndash; <el-button
           class="ml-3"
           @click="exportData('/api/v1/plan/order/export')"
         >
           <template #icon> <i-ep-download /> </template>导出
-        </el-button> -->
-      </template>
+        </el-button> &ndash;&gt;
+      </template>-->
     </avue-crud>
     <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
   </div>
@@ -328,7 +328,7 @@ option.value = Object.assign(option.value, {
     //    dicData: switchOp,
     //    value: 0,
     //  },
-    {
+    /*{
       label: "是否首检",
       prop: "firstCheck",
       span: 8,
@@ -354,7 +354,7 @@ option.value = Object.assign(option.value, {
       type: "switch",
       dicData: switchOp,
       value: 0,
-    },
+    },*/
     //  {
     //    label: "是否工艺数量",
     //    prop: "common",
@@ -373,7 +373,7 @@ option.value = Object.assign(option.value, {
     //    dicData: switchOp,
     //    value: 0,
     //  },
-    {
+    /*{
       label: "是否合批",
       prop: "merge",
       span: 8,
@@ -389,7 +389,7 @@ option.value = Object.assign(option.value, {
           },
         };
       },
-    },
+    },*/
     {
       label: "是否委外",
       prop: "outsourcing",

+ 4 - 4
src/views/base/craftManagement/route/bindConfig.ts

@@ -119,14 +119,14 @@ export const formOption = {
       // slot:true, // 自定义列
     },
     {
-      label: "是否外",
-      prop: "externalCooperation",
+      label: "是否外",
+      prop: "outsourcing",
       span: 24,
       type: "switch",
       dicData: switchOp,
       value: 0,
     },
-    {
+    /*{
       label: "是否首检",
       prop: "firstCheck",
       span: 24,
@@ -165,7 +165,7 @@ export const formOption = {
       type: "switch",
       dicData: switchOp,
       value: 0,
-    },
+    },*/
     {
       label: "是否可跳过",
       prop: "skipped",

+ 7 - 4
src/views/base/craftManagement/route/bindProcess.vue

@@ -102,7 +102,7 @@
             v-model="currentProcess"
             style="padding: 10px; background-color: white"
           >
-           <!-- <template #tbomUrl>
+            <!-- <template #tbomUrl>
               <FilesUpload
                 v-model:src="currentProcess.tbomUrl"
                 :show-tip="false"
@@ -192,6 +192,9 @@ const saveFlow = async () => {
       list2.value[i].nextOperationId = list2.value[i + 1]?.operationVO?.id;
     }
   }
+  if (currentProcess.value) {
+    list2.value[selectIndex.value] = currentProcess.value;
+  }
   let p = {
     processRouteId: route.params.id,
     routeOpList: list2.value,
@@ -261,8 +264,8 @@ const editProComponent = async () => {
   let res = await updateProcess(currentProcess.value);
   ElMessage.success("保存成功");
   router.push({
-    path: `/base/craftManagement/processCom/${currentProcess.value.id}`,
-    query: { prodtCode: route.query.prodtCode, routeId: route.query.routeId },
+    path: `/base/craftManagement/processCom/${currentProcess.value.id}/${route.params.prodtCode}/${route.params.routeId}`,
+    // query: { prodtCode: route.query.prodtCode, routeId: route.query.routeId },
   });
 };
 
@@ -270,7 +273,7 @@ const editProComponent = async () => {
 onMounted(() => {
   loadTreeData();
   loadProcessesFlow();
-  if (route.query.usable == 1) {
+  if (route.params.usable == 1) {
     editStauts.value = false;
   } else {
     editStauts.value = true;

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

@@ -102,13 +102,13 @@ const startCreat = () => {
       bomVersion.value = data.value[0].recordVersion;
     }
 
-    if (!route.query.prodtCode) {
+    if (!route.params.prodtCode) {
       ElMessage.error("物料编号读取错误");
       return;
     }
     //根据物料编码和版本号获取对应的物料BOM
     let bomParam = {
-      materialCode: route.query.prodtCode,
+      materialCode: route.params.prodtCode,
     };
     getBomVersion(bomParam).then((res) => {
       let resListMap = [];
@@ -121,7 +121,7 @@ const startCreat = () => {
       });
       //查询参数
       let configParam = {};
-      configParam.materialCode = route.query.prodtCode;
+      configParam.materialCode = route.params.prodtCode;
       if (bomVersion.value) {
         configParam.bomVersion = bomVersion.value;
       }
@@ -154,7 +154,7 @@ const startCreat = () => {
     commonTableType.value = "ESOP";
     nextTick(() => {
       commonTableRef.value?.startSelect({
-        materialCode: route.query.prodtCode,
+        materialCode: route.params.prodtCode,
         enable: 1,
       });
       commonTableRef.value?.mergeOption({
@@ -329,7 +329,7 @@ onMounted(() => {
     column: tableConfig[props.tableType].column,
   });
   dataList();
-  getRouteMaxVersion(route.query.routeId).then(({ data }) => {
+  getRouteMaxVersion(route.params.routeId).then(({ data }) => {
     if (data) {
       bomVersion.value = data;
     }
@@ -350,7 +350,7 @@ watch(
       column: tableConfig[props.tableType].column,
     });
     dataList();
-    getRouteMaxVersion(route.query.routeId).then(({ data }) => {
+    getRouteMaxVersion(route.params.routeId).then(({ data }) => {
       if (data) {
         bomVersion.value = data;
       }

+ 46 - 12
src/views/base/craftManagement/route/index.vue

@@ -19,7 +19,16 @@
         <el-tag v-if="row.usable == '1'" type="success">已绑定</el-tag>
         <el-tag v-else type="info">未绑定</el-tag>
       </template>
-
+      <template #menu-left="{ size }">
+        <el-button
+          :disabled="toDeleteIds.length < 1"
+          type="refresh"
+          icon="el-icon-refresh"
+          :size="size"
+          @click="apsSync"
+          >APS同步</el-button
+        >
+      </template>
       <!-- :disabled="row.usable == '1' ? false : true" -->
       <template #menu-right="{}">
         <el-dropdown split-button
@@ -29,10 +38,18 @@
               <el-dropdown-item
                 @click="downloadTemplate('/api/v1/op/route/template')"
               >
-                <i-ep-download />下载模板
+                <i-ep-download />下载工艺模板
+              </el-dropdown-item>
+              <el-dropdown-item
+                  @click="downloadTemplate('/api/v1/op/route/template1')"
+              >
+                <i-ep-download />下载工序模板
+              </el-dropdown-item>
+              <el-dropdown-item @click="importExcelData(0)">
+                <i-ep-top />导入工艺数据
               </el-dropdown-item>
-              <el-dropdown-item @click="importExcelData">
-                <i-ep-top />导入数据
+              <el-dropdown-item @click="importExcelData(1)">
+                <i-ep-top />导入工序数据
               </el-dropdown-item>
             </el-dropdown-menu>
           </template>
@@ -112,16 +129,29 @@
 <script setup>
 import { ref, getCurrentInstance } from "vue";
 import { useCrud } from "@/hooks/userCrud";
-import ButtonPermKeys from "@/common/configs/buttonPermission";
 import dictDataUtil from "@/common/configs/dictDataUtil";
 import { useDictionaryStore } from "@/store";
 import { copyRoute } from "@/api/craft/route/index";
-
+import { ElMessage, ElMessageBox } from "element-plus";
+import { syncAps } from "@/api/aps";
 // 数据字典相关
 const { dicts } = useDictionaryStore();
 
-const testDebunce = () => {
-  console.log("执行了事件");
+const apsSync = () => {
+  ElMessageBox.confirm("是否同步所选中数据?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(async () => {
+    let param = { type: 4, codes: toDeleteIds.value };
+    syncAps(param).then((data) => {
+      if (data.code === "200") {
+        ElMessage.success(data.msg);
+      } else {
+        ElMessage.error(data.msg);
+      }
+    });
+  });
 };
 
 // 传入一个url,后面不带/
@@ -161,9 +191,13 @@ const uploadFinished = () => {
   page.currentPage = 1;
   dataList();
 };
-const importExcelData = () => {
+const importExcelData = (type) => {
   if (uploadRef.value) {
-    uploadRef.value.show("/api/v1/op/route/import");
+    if(type === 0){
+      uploadRef.value.show("/api/v1/op/route/import");
+    }else{
+      uploadRef.value.show("/api/v1/op/route/import1");
+    }
   }
 };
 
@@ -211,8 +245,8 @@ const router = useRouter();
 // 绑定工序
 const bindProcess = (row) => {
   router.push({
-    path: `/base/craftManagement/bindProcess/${row.id}`,
-    query: { prodtCode: row.prodtCode, routeId: row.id, usable: row.usable },
+    path: `/base/craftManagement/bindProcess/${row.id}/${row.prodtCode}/${row.id}/${row.usable}`,
+    // query: { prodtCode: row.prodtCode, routeId: row.id, usable: row.usable },
   });
 };
 

+ 34 - 13
src/views/base/materials/index.vue

@@ -24,8 +24,16 @@
           :size="size"
           @click="multipleDelete"
           >删除</el-button
-        ></template
-      >
+        >
+        <el-button
+          :disabled="toDeleteIds.length < 1"
+          type="refresh"
+          icon="el-icon-refresh"
+          :size="size"
+          @click="apsSync"
+          >APS同步</el-button
+        >
+      </template>
       <template #menu="{ row, index, type }">
         <el-button @click="binding(row)" text type="primary"
           >BOM
@@ -54,11 +62,13 @@
           </template>
         </el-dropdown>
         <el-dropdown split-button style="margin-left: 10px"
-        >BOM导入
+          >BOM导入
           <template #dropdown>
             <el-dropdown-menu>
               <el-dropdown-item
-                @click="downloadTemplate('/api/v1/base/materialBom/bom/template')"
+                @click="
+                  downloadTemplate('/api/v1/base/materialBom/bom/template')
+                "
               >
                 <i-ep-download />下载模板
               </el-dropdown-item>
@@ -96,16 +106,27 @@
 <script setup lang="ts">
 import { ref, getCurrentInstance } from "vue";
 import { useCrud } from "@/hooks/userCrud";
-import ButtonPermKeys from "@/common/configs/buttonPermission";
-import {
-  useCommonStoreHook,
-  useDictionaryStore,
-  useDictionaryStoreHook,
-} from "@/store";
+import { syncAps } from "@/api/aps";
+import { useCommonStoreHook, useDictionaryStore } from "@/store";
+import { ElMessage, ElMessageBox } from "element-plus";
 const { isShowTable, tableType } = toRefs(useCommonStoreHook());
-import { columns } from "./columns";
 const { dicts } = useDictionaryStore();
-
+const apsSync = () => {
+  ElMessageBox.confirm("是否同步所选中数据?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(async () => {
+    let param = { type: 2, codes: toDeleteIds.value };
+    syncAps(param).then((data) => {
+      if (data.code === "200") {
+        ElMessage.success(data.msg);
+      } else {
+        ElMessage.error(data.msg);
+      }
+    });
+  });
+};
 const test = () => {
   isShowTable.value = true;
   tableType.value = tableType.value == 1 ? 2 : 1;
@@ -176,10 +197,10 @@ option.value = Object.assign(option.value, {
       width: 130,
       overHidden: true,
       search: true,
+      editDisabled: true,
       rules: [
         {
           required: true,
-          editDisabled: false,
           message: "请填写物料编码",
           trigger: "blur",
         },

+ 26 - 2
src/views/base/modeling/station/index.vue

@@ -38,6 +38,14 @@
           @click="multipleDelete"
           >删除</el-button
         >
+        <el-button
+            :disabled="toDeleteIds.length < 1"
+            type="refresh"
+            icon="el-icon-refresh"
+            :size="size"
+            @click="apsSync"
+        >APS同步</el-button
+        >
       </template>
       <template #menu="{ row, index, type }">
         <el-button @click="binding(row)" text type="primary"
@@ -66,11 +74,12 @@
 <script setup="ts">
 import { ref, getCurrentInstance } from "vue";
 import { useCrud } from "@/hooks/userCrud";
-import ButtonPermKeys from "@/common/configs/buttonPermission";
+import {syncAps} from "@/api/aps";
 import { useCommonStoreHook } from "@/store";
 import { updateStation } from "@/api/station";
 const { isShowTable, tableType } = toRefs(useCommonStoreHook());
 import { useDictionaryStore } from "@/store";
+import {ElMessage, ElMessageBox} from "element-plus";
 const { dicts } = useDictionaryStore();
 const test = () => {
   isShowTable.value = true;
@@ -116,7 +125,22 @@ function rowSave(form, done, loading) {
   createRow(form, done, loading);
 }
 const crudRef = ref(null); //crudRef.value 获取avue-crud对象
-
+const apsSync = () =>{
+  ElMessageBox.confirm("是否同步所选中数据?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(async () => {
+    let param = {type: 1,codes: toDeleteIds.value}
+    syncAps(param).then((data)=>{
+      if (data.code === "200") {
+        ElMessage.success(data.msg);
+      } else {
+        ElMessage.error(data.msg);
+      }
+    })
+  });
+}
 onMounted(() => {
   // console.log("crudRef", crudRef)
   dataList();

+ 42 - 2
src/views/device/instance/index.vue

@@ -53,6 +53,15 @@
           @click="multipleDelete"
           >删除</el-button
         >
+
+        <!--        <el-button
+            :disabled="toDeleteIds.length < 1"
+            type="refresh"
+            icon="el-icon-refresh"
+            :size="size"
+            @click="apsSync"
+        >APS同步</el-button
+        >-->
       </template>
       <template #menu-right="{}">
         <el-dropdown split-button
@@ -144,17 +153,25 @@
     </el-dialog>
     <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
   </div>
+  <CommonTable
+    ref="ctableRef"
+    tableTitle="负责人选择"
+    tableType="USERS"
+    @selected-sure="onSelectedFinish"
+  />
 </template>
 <script setup>
 import { ref, getCurrentInstance } from "vue";
 import { useCrud } from "@/hooks/userCrud";
 import buttonPermission from "@/common/configs/buttonPermission";
 import { configSave, configList, deviceUpdateCollect } from "@/api/device";
+import { syncAps } from "@/api/aps";
 import { useCommonStoreHook } from "@/store";
 import ChoiceWorkshopPage from "../../plan/workOrder/components/choice-workshop-page.vue";
 import ChoiceStationPage from "./components/choice-station-page.vue";
 import dictDataUtil from "@/common/configs/dictDataUtil";
 import { checkPerm } from "@/directive/permission";
+import { ElMessage, ElMessageBox } from "element-plus";
 const { isShowTable, tableType } = toRefs(useCommonStoreHook());
 const test = () => {
   isShowTable.value = true;
@@ -193,6 +210,22 @@ const changeItem = (obj, row) => {
     }
   });
 };
+const apsSync = () => {
+  ElMessageBox.confirm("是否同步所选中数据?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(async () => {
+    let param = { type: 1, codes: toDeleteIds.value };
+    syncAps(param).then((data) => {
+      if (data.code === "200") {
+        ElMessage.success(data.msg);
+      } else {
+        ElMessage.error(data.msg);
+      }
+    });
+  });
+};
 const clickRow = ref(null);
 const showParamsPage = (row) => {
   clickRow.value = row;
@@ -244,6 +277,10 @@ const workShopInfo = (value) => {
   form.value.workshop = value.name;
   dialog2.visible = false;
 };
+const ctableRef = ref(null);
+const onSelectedFinish = (selectedValue) => {
+  form.value.head = selectedValue.userName;
+};
 const stationInfo = (value) => {
   form.value.station = value.name;
   dialog3.visible = false;
@@ -345,7 +382,7 @@ option.value = Object.assign(option.value, {
         }
       },
     },
-    {
+    /*{
       label: "连接状态",
       prop: "collectState",
       width: 100,
@@ -358,7 +395,7 @@ option.value = Object.assign(option.value, {
           return '<b class="el-tag el-tag--warning el-tag--light">未连接</b>';
         }
       },
-    },
+    },*/
     {
       label: "负责人",
       prop: "head",
@@ -371,6 +408,9 @@ option.value = Object.assign(option.value, {
           trigger: "trigger",
         },
       ],
+      click: ({ value, column }) => {
+        ctableRef.value.startSelect();
+      },
     },
     {
       label: "计量有效期",

+ 2 - 2
src/views/device/screwdriver/index.vue

@@ -78,8 +78,8 @@
 
       <el-tabs v-model="activeName" class="demo-tabs">
         <el-tab-pane
-          :label="'任务' + (index + 1)"
-          :name="`task` + (index + 1)"
+          :label="'任务' + index"
+          :name="`task` + index"
           v-for="(item, index) in 8"
           :key="index"
         >

+ 18 - 6
src/views/plan/order/index.vue

@@ -9,6 +9,7 @@
       :option="option"
       :permission="permission"
       :table-loading="loading"
+      :row-style="tableRowClassName"
       @search-change="handleQuery"
       @search-reset="resetChange"
       @size-change="handleQuery"
@@ -304,6 +305,14 @@ const importData = reactive({
   file: undefined,
   fileList: [],
 });
+const tableRowClassName = ({ row, rowIndex }) => {
+  const currentDate = new Date(); // 获取当前日期
+  const compareDate = new Date(row.deliverTime); // 设置要比较的日期
+  if (currentDate > compareDate && row.orderState !== '5') {
+    return { backgroundColor: '#F1BFBFFF'};
+  }
+  return '';
+};
 const materialInfo = (value) => {
   form.value.materialCode = value.materialCode;
   form.value.materialName = value.materialName;
@@ -396,13 +405,13 @@ option.value = {
         },
       ],
     },
-    {
+   /* {
       label: "计划单号",
       prop: "planCode",
       search: true,
       width: 130,
       overHidden: true,
-    },
+    },*/
     {
       label: "订单类型",
       prop: "orderType",
@@ -519,13 +528,13 @@ option.value = {
       disabled: true,
       prop: "materialModel",
     },
-    {
+   /* {
       label: "工作令号",
       width: 130,
       overHidden: true,
       prop: "workOrder",
-    },
-    {
+    },*/
+  /*  {
       label: "部(组)件代号",
       width: 130,
       overHidden: true,
@@ -536,7 +545,7 @@ option.value = {
       width: 130,
       overHidden: true,
       prop: "assemblyName",
-    },
+    },*/
     {
       label: "订单状态",
       prop: "orderState",
@@ -957,6 +966,9 @@ const onSelectedFinish = (selectedValue) => {
 </script>
 
 <style lang="scss" scoped>
+.warning-row{
+  background-color: rgb(204, 136, 136) !important;
+}
 .scanInfo {
   width: 100%;
 

+ 11 - 10
src/views/plan/prepare/index.vue

@@ -97,17 +97,17 @@
       <el-form ref="dataFormRef" :model="form" label-width="90px">
         <el-row :gutter="24">
           <el-col :span="8">
-            <el-form-item label="工单编码" prop="materialCode">
+            <el-form-item label="工单编码" prop="workOrderCode">
               <el-input v-model="form.workOrderCode" disabled />
             </el-form-item>
           </el-col>
           <el-col :span="8">
-            <el-form-item label="订单编码" prop="materialName">
+            <el-form-item label="订单编码" prop="orderCode">
               <el-input v-model="form.orderCode" disabled />
             </el-form-item>
           </el-col>
           <el-col :span="8">
-            <el-form-item label="订单名称" prop="materialModel">
+            <el-form-item label="订单名称" prop="orderName">
               <el-input v-model="form.orderName" disabled />
             </el-form-item>
           </el-col>
@@ -131,7 +131,7 @@
         </el-row>
         <el-row :gutter="24">
           <el-col :span="24">
-            <el-form-item label="工单数量" prop="materialModel">
+            <el-form-item label="工单数量" prop="workOrderNum">
               <el-input v-model="form.workOrderNum" disabled />
             </el-form-item>
           </el-col>
@@ -210,17 +210,17 @@
       <el-form ref="formRef" :model="form" label-width="90px">
         <el-row :gutter="24">
           <el-col :span="8">
-            <el-form-item label="工单编码" prop="materialCode">
+            <el-form-item label="工单编码" prop="workOrderCode">
               <el-input v-model="form.workOrderCode" disabled />
             </el-form-item>
           </el-col>
           <el-col :span="8">
-            <el-form-item label="订单编码" prop="materialName">
+            <el-form-item label="订单编码" prop="orderCode">
               <el-input v-model="form.orderCode" disabled />
             </el-form-item>
           </el-col>
           <el-col :span="8">
-            <el-form-item label="订单名称" prop="materialModel">
+            <el-form-item label="订单名称" prop="orderName">
               <el-input v-model="form.orderName" disabled />
             </el-form-item>
           </el-col>
@@ -244,7 +244,7 @@
         </el-row>
         <el-row :gutter="24">
           <el-col :span="24">
-            <el-form-item label="工单数量" prop="materialModel">
+            <el-form-item label="工单数量" prop="workOrderNum">
               <el-input v-model="form.workOrderNum" disabled />
             </el-form-item>
           </el-col>
@@ -502,7 +502,7 @@ option.value = Object.assign(option.value, {
           message: "工单号不能为空",
           trigger: "trigger",
         },
-      ],
+      ]/*,
       click: ({ value, column }) => {
         if (column.boxType) {
           dialog.visible = true;
@@ -512,8 +512,9 @@ option.value = Object.assign(option.value, {
         if (value) {
           checkInfo(value);
         }
-      },
+      },*/
     },
+
     {
       label: "物料编码",
       prop: "materialCode",

+ 159 - 99
src/views/plan/prepareTemplate/index.vue

@@ -1,87 +1,123 @@
 <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"
+      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 #state="scope">
         <el-switch
-            active-value="1"
-            inactive-value="0"
-            inline-prompt
-            active-text="是"
-            inactive-text="否"
-            v-model="scope.row.state"
-            @click="changeItem($event,scope.row)"
-            class="ml-2"
-            style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
+          active-value="1"
+          inactive-value="0"
+          inline-prompt
+          active-text="是"
+          inactive-text="否"
+          v-model="scope.row.state"
+          @click="changeItem($event, scope.row)"
+          class="ml-2"
+          style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
         />
       </template>
       <template #menu-left="{ size }">
         <el-button
-            type="primary"
-            icon="el-icon-plus"
-            :size="size"
-            @click="openDialog(0, null)"
-        >新增</el-button>
+          type="primary"
+          icon="el-icon-plus"
+          :size="size"
+          @click="openDialog(0, null)"
+          >新增</el-button
+        >
       </template>
 
       <template #menu="{ size, row, index }">
-        <el-button
-            type="primary"
-            link
-            size="small"
-            @click="openDialog(1, row)"
-        ><i-ep-edit />编辑
+        <el-button type="primary" link size="small" @click="openDialog(1, row)"
+          ><i-ep-edit />编辑
         </el-button>
       </template>
+      <template #menu-right="{}">
+        <el-dropdown split-button
+          >准备模板导入
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item
+                @click="downloadTemplate('/api/v1/prepareTemplate/template')"
+              >
+                <i-ep-download />下载模板
+              </el-dropdown-item>
+              <el-dropdown-item @click="importExcelData">
+                <i-ep-top />导入数据
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </template>
     </avue-crud>
     <el-dialog
-        v-model="dialog1.visible"
-        :title="dialog1.title"
-        width="45%"
-        @close="dialog1.visible = false"
+      v-model="dialog1.visible"
+      :title="dialog1.title"
+      width="45%"
+      @close="dialog1.visible = false"
     >
-      <el-form ref="dataFormRef" :model="form" label-width="90px" :rules="rules">
+      <el-form
+        ref="dataFormRef"
+        :model="form"
+        label-width="90px"
+        :rules="rules"
+      >
         <el-row :gutter="24">
           <el-col :span="8">
-          <el-form-item label="物料编码" prop="materialCode">
-            <el-input v-model="form.materialCode" @click="openDialog" readOnly placeholder="请选择物料" />
-          </el-form-item>
+            <el-form-item label="物料编码" prop="materialCode">
+              <el-input
+                v-model="form.materialCode"
+                @click="openDialog"
+                readOnly
+                placeholder="请选择物料"
+              />
+            </el-form-item>
           </el-col>
           <el-col :span="8">
-          <el-form-item label="物料名称" prop="materialName">
-            <el-input v-model="form.materialName" disabled placeholder="请选择物料" />
-          </el-form-item>
+            <el-form-item label="物料名称" prop="materialName">
+              <el-input
+                v-model="form.materialName"
+                disabled
+                placeholder="请选择物料"
+              />
+            </el-form-item>
           </el-col>
           <el-col :span="8">
             <el-form-item label="物料型号" prop="materialModel">
-              <el-input v-model="form.materialModel" disabled placeholder="请选择物料" />
+              <el-input
+                v-model="form.materialModel"
+                disabled
+                placeholder="请选择物料"
+              />
             </el-form-item>
           </el-col>
         </el-row>
         <el-row :gutter="24">
           <el-col :span="24">
             <el-form-item label="物料模板" prop="template">
-              <el-select v-model="form.template" multiple placeholder="请选择模板" @change="changeTemplate">
+              <el-select
+                v-model="form.template"
+                multiple
+                placeholder="请选择模板"
+                @change="changeTemplate"
+              >
                 <el-option
-                    v-for="item in templates"
-                    :label="item.dictLabel"
-                    :value="item.dictValue"
-                    :key="item.dictLabel"
+                  v-for="item in templates"
+                  :label="item.dictLabel"
+                  :value="item.dictValue"
+                  :key="item.dictLabel"
                 />
               </el-select>
             </el-form-item>
@@ -90,14 +126,17 @@
         <el-row :gutter="24" v-for="item in clickTemplates">
           <el-col :span="24">
             <el-form-item :label="item.name">
-            <el-switch
+              <el-switch
                 class="mb-2"
-                style="--el-switch-on-color: #13ce66; --el-switch-off-color: #ff4949"
+                style="
+                  --el-switch-on-color: #13ce66;
+                  --el-switch-off-color: #ff4949;
+                "
                 active-text="完成"
                 inactive-text="未完成"
                 active-value="1"
                 inactive-value="0"
-            />
+              />
             </el-form-item>
           </el-col>
         </el-row>
@@ -110,13 +149,14 @@
       </template>
     </el-dialog>
     <el-dialog
-        v-model="dialog.visible"
-        :title="dialog.title"
-        width="80%"
-        @close="dialog.visible = false"
+      v-model="dialog.visible"
+      :title="dialog.title"
+      width="80%"
+      @close="dialog.visible = false"
     >
       <choice-item-page @material-info="materialInfo" />
     </el-dialog>
+    <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
   </div>
 </template>
 
@@ -133,7 +173,8 @@ const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
   useCrud({
     src: "/api/v1/prepareTemplate",
   });
-const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } = Methords; //增删改查
+const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
+  Methords; //增删改查
 const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
 const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
 const dataFormRef = ref(ElForm);
@@ -146,54 +187,74 @@ const dialog1 = reactive({
   title: "模板保存",
   visible: false,
 });
+const uploadRef = ref(null);
+const importExcelData = () => {
+  if (uploadRef.value) {
+    uploadRef.value.show("/api/v1/prepareTemplate/importExcel");
+  }
+};
+const uploadFinished = () => {
+  // 上传完成后的刷新操作
+  page.currentPage = 1;
+  dataList();
+};
 const openDialog = (type, row) => {
-  if(type === 0 ){
+  if (type === 0) {
     form.value.materialCode = "";
-    form.value.materialName = ""
-    form.value.materialModel = ""
-    form.value.template = []
-    clickTemplates.value = []
+    form.value.materialName = "";
+    form.value.materialModel = "";
+    form.value.template = [];
+    templates.value.forEach((item)=>{
+      form.value.template.push(item.dictValue)
+    })
+    clickTemplates.value = [];
     dialog1.visible = true;
-  }else if(type === 1){
-    form.value = row
-    if(!Array.isArray(row.template)){
-      form.value.template = eval("(" +row.template + ")")
+  } else if (type === 1) {
+    form.value = row;
+    if (!Array.isArray(row.template)) {
+      form.value.template = eval("(" + row.template + ")");
     }
     //form.value.templateList = row.template.split(",")
-    changeTemplate()
+    changeTemplate();
     dialog1.visible = true;
-  }else{
+  } else {
     dialog.visible = true;
   }
 };
-const changeItem =(obj,row) => {
-  form.value = {id: row.id,state: row.state}
-  updateRow()
-  form.value = null
-}
-const templates = ref([])
-const clickTemplates = ref([])
-const changeTemplate = ()=>{
-  clickTemplates.value = []
-  if(form.value.template){
-    for(let i = 0 ; i< form.value.template.length; i ++){
-      clickTemplates.value.push({value: form.value.template[i],name: templates.value.find(option => option.dictValue === form.value.template[i]).dictLabel});
+const changeItem = (obj, row) => {
+  form.value = { id: row.id, state: row.state };
+  updateRow();
+  form.value = null;
+  dataList();
+};
+const templates = ref([]);
+const clickTemplates = ref([]);
+const changeTemplate = () => {
+  clickTemplates.value = [];
+  if (form.value.template) {
+    for (let i = 0; i < form.value.template.length; i++) {
+      clickTemplates.value.push({
+        value: form.value.template[i],
+        name: templates.value.find(
+          (option) => option.dictValue === form.value.template[i]
+        ).dictLabel,
+      });
     }
   }
-}
-const onSubmit = (done,loading) => {
+};
+const onSubmit = (done, loading) => {
   dataFormRef.value.validate((isValid) => {
     if (isValid) {
-      if(!form.value.id){
-        createRow(done,loading)
-      }else{
-        updateRow(done,loading)
+      if (!form.value.id) {
+        createRow(done, loading);
+      } else {
+        updateRow(done, loading);
       }
-      dialog1.visible = false
+      dialog1.visible = false;
     }
   });
-  console.log('submit!')
-}
+  console.log("submit!");
+};
 const materialInfo = (value) => {
   form.value.materialCode = value.materialCode;
   form.value.materialName = value.materialName;
@@ -209,7 +270,7 @@ option.value = Object.assign(option.value, {
   menuBtn: true,
   menuWidth: 150,
   addBtn: false,
-  dialogWidth: '45%', // 设置编辑弹窗的宽度为50%
+  dialogWidth: "45%", // 设置编辑弹窗的宽度为50%
   column: [
     {
       label: "物料编码",
@@ -265,13 +326,13 @@ option.value = Object.assign(option.value, {
       label: "创建时间",
       prop: "created",
       width: 200,
-      display: false
+      display: false,
     },
     {
       label: "创建人",
       width: 200,
       prop: "creator",
-      display: false
+      display: false,
     },
   ],
 });
@@ -282,11 +343,10 @@ const rules = reactive({
 
 onMounted(() => {
   dataList();
-  queryDictDataByType("prepare_template").then((res)=>{
-    templates.value = res.data
-  })
+  queryDictDataByType("prepare_template").then((res) => {
+    templates.value = res.data;
+  });
 });
-
 </script>
 <style scoped>
 :deep(.el-progress-bar__innerText) {

+ 82 - 0
src/views/plan/requisition/exportInfo.vue

@@ -0,0 +1,82 @@
+<template>
+  <div class="mainContentBox">
+    <div class="btns">
+      <el-button type="primary" @click="toPrintSet"> 打印</el-button>
+    </div>
+    <el-table ref="tableRef" :data="tableData" style="height: 90vh" border>
+      <el-table-column type="selection" width="55" />
+      <el-table-column label="物料名称" prop="materialName" />
+      <el-table-column label="物料型号" prop="materialModel" />
+      <el-table-column label="物料编码" prop="materialCode" />
+      <el-table-column label="更改数量" prop="receiveNum">
+        <template #default="{ row }">
+          <el-input v-model="row.receiveNum" />
+        </template>
+      </el-table-column>
+      <el-table-column label="打印数量" prop="receiveNum">
+        <template #default="{ row }">
+          <el-input v-model="row.printNum" />
+        </template>
+      </el-table-column>
+    </el-table>
+    <el-dialog
+      v-model="dialog.visible"
+      :title="dialog.title"
+      width="90%"
+      @close="dialog.visible = false"
+    >
+      <Print :printData @close="dialog.visible = false" />
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCommonStoreHook, useDictionaryStore } from "@/store";
+import { getMaterialInfo, getPrintInfo } from "@/api/plan";
+import Print from "./print.vue";
+import dictDataUtil from "@/common/configs/dictDataUtil";
+const props = defineProps({
+  excelRow: {
+    type: Object,
+    default: () => {
+      return {};
+    },
+  },
+});
+// 数据字典相关
+const { dicts } = useDictionaryStore();
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+const tableRef = ref(null);
+const dialog = reactive({
+  title: "打印预览",
+  visible: false,
+});
+const tableData = ref([]);
+const printData = ref([]);
+const toPrintSet = async () => {
+  const { data } = await getPrintInfo(tableRef.value.getSelectionRows());
+  printData.value = data;
+  if (printData.value.length > 0) {
+    dialog.visible = true;
+  } else {
+    ElMessage.error("暂无打印内容");
+  }
+};
+const getTableData = async () => {
+  const { data } = await getMaterialInfo(props.excelRow.applyCode);
+  tableData.value = data;
+};
+const router = useRouter();
+onMounted(() => {
+  getTableData();
+});
+watch(()=>props.excelRow, () => {  getTableData();
+},{
+  deep:true
+});
+</script>
+<style>
+.btns {
+  margin-bottom: 10px;
+}
+</style>

+ 35 - 11
src/views/plan/requisition/index.vue

@@ -41,9 +41,24 @@
         <el-button type="primary" link size="small" @click="openDialog(2, row)"
           ><i-ep-edit />{{ row.state === "0" ? "编辑" : "流程" }}</el-button
         >
+        <el-button
+          type="primary"
+          link
+          size="small"
+          @click="openDialog1(row)"
+          ><i-ep-position />导出物料信息</el-button
+        >
       </template>
     </avue-crud>
     <el-dialog
+      v-model="dialog1.visible"
+      :title="dialog1.title"
+      @close="dialog1.visible = false"
+      width="90%"
+    >
+      <ExportInfo :excelRow />
+    </el-dialog>
+    <el-dialog
       v-model="dialog.visible"
       :title="dialog.title"
       width="75%"
@@ -58,16 +73,19 @@
           >打印</el-button
         >
       </template>
-      <div style="width:100%; height: 30px;">
-<!--        <el-steps :active="1" finish-status="success">-->
-        <el-steps :active="form.state === '6' ? 1: 0" finish-status="success">
+      <div style="width: 100%; height: 30px">
+        <!--        <el-steps :active="1" finish-status="success">-->
+        <el-steps
+          :active="form.state === '8' ? 3 : form.state === '9' ? 2 : 1"
+          finish-status="success"
+        >
           <el-step :title="form.sendOrg" />
           <el-step title="运输中" />
           <el-step :title="form.applyOrg" />
         </el-steps>
       </div>
       <div class="card-container">
-        <el-card style="width: 70%;margin-top:30px;" shadow="always">
+        <el-card style="width: 70%; margin-top: 30px" shadow="always">
           <div ref="toPrintRef">
             <el-row style="text-align: center">
               <el-col :span="24"
@@ -210,7 +228,7 @@
           </div>
         </el-card>
 
-        <el-card style="width: 28%;margin-top:30px;" shadow="always">
+        <el-card style="width: 28%; margin-top: 30px" shadow="always">
           <template #header>
             <div class="card-header">
               <span>领用流程</span>
@@ -437,15 +455,11 @@
                     <el-form-item label="审批结果">
                       <el-text
                         tag="p"
-                        v-if="
-                          dialogType === 1 ||
-                          form.state === '6' ||
-                          form.state === '7'
-                        "
+                        v-if="dialogType === 1 || form.state > 5"
                         >{{
                           form.state === "5"
                             ? "待审批"
-                            : form.state === "6"
+                            : form.state > 5
                               ? "通过"
                               : "未通过"
                         }}</el-text
@@ -498,6 +512,7 @@ import {
 } from "@/api/order";
 import { getUserList } from "@/api/system/user";
 import { useCommonStoreHook } from "@/store";
+import ExportInfo from "./exportInfo.vue";
 const { isShowTable, tableType } = toRefs(useCommonStoreHook());
 const test = () => {
   isShowTable.value = true;
@@ -526,6 +541,11 @@ const changeOrder = (val) => {
     tableDataList.value = data.data;
   });
 };
+const excelRow = ref(null);
+const openDialog1 = (row) => {
+  dialog1.visible = true;
+  excelRow.value = row;
+};
 const saveForm = (type) => {
   let state = type;
   let step = null;
@@ -631,6 +651,10 @@ const dialog = reactive({
   title: "领用单",
   visible: false,
 });
+const dialog1 = reactive({
+  title: "物料信息配置(请使用谷歌浏览器实现)",
+  visible: false,
+});
 const tableDataList = ref([]);
 const openDialog = (type, row) => {
   dialogType.value = type;

+ 154 - 0
src/views/plan/requisition/print.vue

@@ -0,0 +1,154 @@
+<template>
+  <div class="mainContentBox">
+    <div class="viewBox">
+      <el-scrollbar height="400px">
+        <div class="printView">
+          <template
+            v-for="(item, index) of props.printData"
+            :key="index + item"
+          >
+            <div
+              class="printItem"
+              v-for="obj of item.printNum"
+              :key="index + item + obj"
+            >
+              <div>
+                <div class="lable">物料名称:</div>
+                <div class="value">{{ item.materialName }}</div>
+                <div class="lable">物料型号:</div>
+                <div class="value">{{ item.materialModel }}</div>
+                <div class="lable">物料编码:</div>
+                <div class="value">{{ item.materialCode }}</div>
+              </div>
+
+              <div>
+                <vue-qrcode
+                  :value="item.code"
+                  size="30"
+                  error-level="H"
+                ></vue-qrcode>
+              </div>
+            </div>
+          </template>
+        </div>
+      </el-scrollbar>
+    </div>
+    <div class="printViewBox">
+      <div ref="toPrintRef" id="printScreen">
+        <template v-for="(item, index) of props.printData" :key="index + item">
+          <div
+            class="printItem"
+            v-for="obj of item.printNum"
+            :key="index + item + obj"
+          >
+            <div>
+              <div class="lable">物料名称:</div>
+              <div class="value">{{ item.materialName }}</div>
+              <div class="lable">物料型号:</div>
+              <div class="value">{{ item.materialModel }}</div>
+              <div class="lable">物料编码:</div>
+              <div class="value">{{ item.materialCode }}</div>
+            </div>
+
+            <div>
+              <vue-qrcode
+                :value="item.code"
+                size="30"
+                error-level="H"
+              ></vue-qrcode>
+            </div>
+          </div>
+        </template>
+      </div>
+    </div>
+    <div class="dialog-footer" align="center">
+      <el-button @click="emits('close')">取消</el-button>
+      <el-button type="primary" v-print="'#printScreen'">打印</el-button>
+    </div>
+  </div>
+</template>
+<script setup>
+const props = defineProps({
+  printData: {
+    type: Object,
+    default: () => {
+      return {};
+    },
+  },
+});
+const toPrintRef = ref(null);
+const emits = defineEmits(["close"]);
+const printPage = () => {
+  html2CanvasPrint(toPrintRef.value);
+};
+</script>
+<style>
+.viewBox {
+  width: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  padding: 20px;
+}
+.printView {
+  display: grid;
+  grid-template-columns: repeat(3, 1fr);
+  gap: 20px;
+  width: 100%;
+  .printItem {
+    width: 80mm;
+    height: 60mm;
+    padding: 2mm;
+    border: 1px dashed black;
+    display: flex;
+    justify-content: space-between;
+    margin-bottom: 10px;
+    border-radius: 16px;
+    .lable {
+      font-weight: 500;
+      color: black;
+    }
+    .value {
+      font-weight: 500;
+      color: black;
+    }
+  }
+}
+.printViewBox {
+  position: fixed;
+  top: 0;
+  left: 0;
+  display: none;
+}
+#printScreen {
+  width: 80mm;
+  .printItem {
+    width: 80mm !important;
+    height: 60mm !important;
+    padding: 2mm;
+    display: flex;
+    justify-content: space-between;
+    .lable {
+      font-weight: 500;
+      color: black;
+    }
+    .value {
+      font-weight: 500;
+      color: black;
+    }
+  }
+}
+
+@media print {
+  body,
+  html,
+  div {
+    height: auto !important;
+    width: auto !important;
+    overflow: visible !important;
+  }
+  #printScreen {
+    width: 80mm;
+  }
+}
+</style>

+ 306 - 0
src/views/plan/returnMaterial/index.vue

@@ -0,0 +1,306 @@
+<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
+          type="primary"
+          icon="el-icon-plus"
+          :size="size"
+          @click="showDialog"
+          >新增</el-button
+        >
+      </template>
+      <template #menu="{ row, index }">
+        <el-button
+          text
+          type="info"
+          v-if="row.state === 1"
+          :icon="'el-icon-info'"
+          @click="showDialog(2, row.returnCode)"
+        >
+          详情
+        </el-button>
+        <el-button
+          text
+          type="primary"
+          v-if="row.state === 0"
+          :icon="'el-icon-info'"
+          @click="sendToWms(row.returnCode)"
+        >
+          发送WMS
+        </el-button>
+        <el-button
+          text
+          type="primary"
+          v-if="row.state === 0"
+          :icon="'el-icon-edit'"
+          @click="showDialog(1, row.returnCode)"
+        >
+          编辑
+        </el-button>
+        <el-button
+          text
+          type="danger"
+          v-if="row.state === 0"
+          :icon="'el-icon-del'"
+          @click="rowDelObj(row)"
+        >
+          删除
+        </el-button>
+      </template>
+    </avue-crud>
+    <el-dialog
+      v-model="dialog.visible"
+      :title="dialog.title"
+      width="80%"
+      @close="dialog.visible = false"
+    >
+      <el-input
+        v-if="dialog.type !== 2"
+        placeholder="扫码回车添加"
+        v-model="scanInput"
+        @keyup.enter="searchCode"
+        clearable
+      >
+      </el-input>
+      <avue-crud
+        :data="materialData"
+        :option="materialOption"
+        @selection-change="crudSelect"
+      >
+        <template #menu="{ row, index }">
+          <el-button
+            text
+            v-if="dialog.type !== 2"
+            type="danger"
+            :icon="'el-icon-del'"
+            @click="avueRowDel(row, index)"
+          >
+            删除
+          </el-button>
+        </template>
+      </avue-crud>
+      <template #footer>
+        <div class="dialog-footer" v-if="dialog.type !== 2">
+          <el-button type="primary" @click="handleSubmit">确 定</el-button>
+          <el-button @click="dialog.visible = false">取 消</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import {
+  addReturnMaterial,
+  scanItem,
+  queryList,
+  del,
+  sendWms,
+} from "@/api/returnMaterial";
+import { useCommonStoreHook } from "@/store";
+import { ElMessage } from "element-plus";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+const test = () => {
+  isShowTable.value = true;
+  tableType.value = tableType.value == 1 ? 2 : 1;
+};
+const loading = ref(false); //  加载状态
+const dialog = reactive({
+  title: "物料选择",
+  type: 0,
+  visible: false,
+});
+const sendToWms = (returnCode) => {
+  ElMessageBox.confirm("确定要发送记录吗?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+    lockScroll: false,
+  }).then(() => {
+    sendWms({ returnCode: returnCode }).then((res) => {
+      ElMessage.success("操作成功");
+      dataList();
+    });
+  });
+};
+const showDialog = (type, returnCode) => {
+  currentCode.value = "";
+  dialog.visible = true;
+  if (type) {
+    dialog.type = type;
+  }
+  materialData.value = [];
+  if (type === 1 || type == 2) {
+    currentCode.value = returnCode;
+    queryList({ returnCode: returnCode }).then((res) => {
+      if (type === 1) {
+        res.data.forEach((item) => {
+          item.$cellEdit = true;
+        });
+      } else {
+        res.data.forEach((item) => {
+          item.$cellEdit = false;
+        });
+      }
+      materialData.value = res.data;
+    });
+  }
+};
+const currentCode = ref();
+const handleSubmit = () => {
+  if (materialData.value.length === 0) {
+    ElMessage.error("请先扫码添加物料");
+    return;
+  }
+  addReturnMaterial(materialData.value).then(() => {
+    dialog.visible = false;
+    dataList();
+    ElMessage.success("操作成功");
+  });
+};
+const avueRowDel = (row, index) => {
+  materialData.value.splice(index, 1);
+};
+const rowDelObj = (row) => {
+  ElMessageBox.confirm("确定要删除记录吗?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+    lockScroll: false,
+  }).then(() => {
+    del({ returnCode: row.returnCode }).then((res) => {
+      ElMessage.success("操作成功");
+      dataList();
+    });
+  });
+};
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/ReturnDetails",
+  });
+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 crud = ref(null);
+const crudSelect = (row) => {
+  alert(JSON.stringify(JSON.stringify(row)));
+};
+const searchCode = () => {
+  let params = { code: scanInput.value };
+  let exists = false;
+  if (materialData.value) {
+    materialData.value.forEach((item) => {
+      if (item.batchCode == scanInput.value) {
+        exists = true;
+      }
+    });
+  }
+  if (exists) {
+    scanInput.value = "";
+    return;
+  }
+  scanItem(params).then((data) => {
+    if (data.data) {
+      let obj = data.data;
+      materialData.value.push({
+        returnCode: currentCode.value,
+        materialCode: obj.materialCode,
+        materialName: obj.materialName,
+        batchCode: scanInput.value,
+        num: 1,
+        materialModel: obj.spec,
+        $cellEdit: true,
+      });
+      scanInput.value = "";
+    }
+  });
+};
+
+const scanInput = ref();
+const materialData = ref([]);
+const materialOption = ref({
+  addBtn: false,
+  saveBtn: false,
+  cancelBtn: false,
+  cellBtn: true,
+  editBtn: false,
+  delBtn: false,
+  column: [
+    { label: "物料编码", prop: "materialCode", fixed: true },
+    { label: "物料名称", prop: "materialName" },
+    { label: "物料型号", prop: "materialModel" },
+    { label: "二维码", prop: "batchCode" },
+    {
+      label: "退回数量",
+      prop: "num",
+      cell: true,
+      rules: [{ required: true, trigger: "blur" }],
+    },
+  ],
+});
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  delBtn: false,
+  addBtn: false,
+  viewBtn: false,
+  editBtn: false,
+  selection: false,
+  column: [
+    {
+      label: "退料单号",
+      prop: "returnCode",
+      overHidden: true,
+    },
+    {
+      label: "发送WMS",
+      type: "select",
+      dicData: [
+        { label: "未发送", value: 0 },
+        { label: "已发送", value: 1 },
+      ],
+      prop: "state",
+      addDisplay: false,
+      editDisplay: false,
+    },
+    {
+      label: "创建时间",
+      prop: "created",
+      overHidden: true,
+      display: false,
+      type: "datetime",
+      valueFormat: "yyyy-MM-dd HH:mm:ss",
+    },
+    {
+      label: "创建人",
+      prop: "creator",
+      display: false,
+      overHidden: true,
+    },
+  ],
+});
+
+onMounted(() => {
+  // console.log("crudRef", crudRef)
+  dataList();
+});
+</script>

+ 24 - 1
src/views/plan/schedule/index.vue

@@ -6,6 +6,7 @@
       v-model="form"
       :data="data"
       :option="option"
+      :row-style="tableRowClassName"
       v-model:page="page"
       @row-save="createRow"
       @row-update="updateRow"
@@ -59,7 +60,16 @@ import { queryStationByLineId } from "@/api/station";
 import { useDictionaryStore } from "@/store";
 import { getStatistics } from "@/api/order/index";
 import * as echarts from "echarts";
-
+const tableRowClassName = ({ row, rowIndex }) => {
+  if(row.planStartEnd){
+    const currentDate = new Date(); // 获取当前日期
+    const compareDate = new Date(row.planStartEnd); // 设置要比较的日期
+    if (currentDate > compareDate && row.state !== '2' && row.state !== '3') {
+      return { backgroundColor: '#F1BFBFFF'};
+    }
+  }
+  return '';
+};
 // 数据字典相关
 const { dicts } = useDictionaryStore();
 
@@ -171,6 +181,12 @@ option.value = Object.assign(option.value, {
       search: true,
     },
     {
+      label: "工单编码",
+      prop: "workOrderCode",
+      editDisabled: true,
+      search: true,
+    },
+    {
       label: "工位名称",
       prop: "stationName",
       search: true,
@@ -257,6 +273,7 @@ option.value = Object.assign(option.value, {
       prop: "planStartWhen",
       type: "datetime",
       valueFormat: "YYYY-MM-DD HH:mm:ss",
+      search: true,
       rules: [
         {
           required: true,
@@ -270,8 +287,14 @@ option.value = Object.assign(option.value, {
       label: "结束时间",
       prop: "planStartEnd",
       type: "datetime",
+      search: true,
       valueFormat: "YYYY-MM-DD HH:mm:ss",
     },
+    {
+      label: "来源",
+      prop: "source",
+      editDisabled: true
+    },
   ],
 });
 </script>

+ 10 - 1
src/views/plan/workOrder/components/work-order-seq.vue

@@ -69,8 +69,10 @@
         @close="dialog.visible = false"
     >
       <div style="display: flex;flex-wrap: wrap;" ref="toPrintRef">
-        <div v-for="item of clickObjs" style="width: 238px;height:325px;font-size:10px;">
+        <div v-for="item of clickObjs" style="width: 238px;overflow: hidden;font-size:10px;">
+          <div style="float: left;padding-bottom: 30px">
           <vue-qrcode  :value="item.seqNo"  size="45" error-level="H"></vue-qrcode>
+
           <div>
             <el-text>{{item.seqNo}}</el-text>
           </div>
@@ -89,8 +91,11 @@
           <div>
             <el-text>物料型号:</el-text><el-text>{{info.materialModel}}</el-text>
           </div>
+          </div>
+
         </div>
       </div>
+
       <div class="dialog-footer" align="center">
         <el-button @click="dialog.visible = false">取消</el-button>
         <el-button type="primary" @click="printPage">打印</el-button>
@@ -149,6 +154,10 @@ watch(
       dataList();
     }
 );
+
+const tdmSeqNo=(seqNo)=>{
+  return seqNo.replace("_","-");
+}
 // 传入一个url,后面不带/
 const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
   useCrud({

+ 38 - 1
src/views/plan/workOrder/index.vue

@@ -9,6 +9,7 @@
       :option="option"
       v-model:page="page"
       :permission="permission"
+      :row-style="tableRowClassName"
       @row-save="createRow"
       @row-update="updateRow"
       @row-del="deleteRow"
@@ -38,6 +39,14 @@
             <svg-icon icon-class="paicheng" />
           </template>
         </el-button>
+        <el-button
+            :disabled="toDeleteIds.length < 1"
+            type="refresh"
+            icon="el-icon-refresh"
+            :size="size"
+            @click="apsSync"
+        >APS同步</el-button
+        >
       </template>
       <template #menu="{ size, row, index }">
         <el-button
@@ -287,6 +296,7 @@ import {
   lockWorkOrder,
   zipWorkOrder,
 } from "@/api/order";
+import {syncAps} from "@/api/aps";
 import { useCommonStoreHook } from "@/store";
 import dictDataUtil from "@/common/configs/dictDataUtil";
 import ChoiceRoutePage from "./components/choice-route-page.vue";
@@ -294,7 +304,19 @@ import ChoiceWorkshopPage from "./components/choice-workshop-page.vue";
 import WorkOrderSeq from "./components/work-order-seq.vue";
 import { checkPerm } from "@/directive/permission";
 import { queryDictDataByType } from "@/api/system/dict";
+import {ElMessage, ElMessageBox} from "element-plus";
 const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+
+const tableRowClassName = ({ row, rowIndex }) => {
+  if(row.planStartEnd){
+    const currentDate = new Date(); // 获取当前日期
+    const compareDate = new Date(row.planStartEnd); // 设置要比较的日期
+    if (currentDate > compareDate && row.workOrderState !== '6') {
+      return { backgroundColor: '#F1BFBFFF'};
+    }
+  }
+  return '';
+};
 const router = useRouter();
 const test = () => {
   isShowTable.value = true;
@@ -310,7 +332,22 @@ const permission = reactive({
 const disabledDate = (time) => {
   return time.getTime() < Date.now(); // 8.64e7 毫秒数代表一天
 };
-
+const apsSync = () =>{
+  ElMessageBox.confirm("是否同步所选中数据?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(async () => {
+    let param = {type: 3,codes: toDeleteIds.value}
+    syncAps(param).then((data)=>{
+      if (data.code === "200") {
+        ElMessage.success(data.msg);
+      } else {
+        ElMessage.error(data.msg);
+      }
+    })
+  });
+}
 const jumpPage = (workOrderCode, type) => {
   if (type === 1) {
     router.push("/requisition?workOrderCode=" + workOrderCode);

+ 6 - 6
src/views/pro/baseoperation/index.vue

@@ -141,11 +141,11 @@
                     prop: "timeingNum",
                     search: false,
                 },
-                {
+               /* {
                     label: "是否外协",
                     prop: "externalCooperation",
                     search: false,
-                },
+                },*/
                 {
                     label: "加工要求",
                     prop: "processAsk",
@@ -156,7 +156,7 @@
                     prop: "preparationTime",
                     search: false,
                 },
-                {
+                /*{
                     label: "是否自检",
                     prop: "selfCheck",
                     search: false,
@@ -170,7 +170,7 @@
                     label: "是否首检",
                     prop: "firstCheck",
                     search: false,
-                },
+                },*/
                 {
                     label: "是否委外",
                     prop: "outsourcing",
@@ -206,11 +206,11 @@
                     prop: "batch",
                     search: false,
                 },
-                {
+                /*{
                     label: "是否合批",
                     prop: "merge",
                     search: false,
-                },
+                },*/
                 {
                     label: "是否工艺数量",
                     prop: "common",

+ 6 - 2
src/views/pro/traceability/components/collectionCom.vue

@@ -197,10 +197,12 @@ useCrud2.value.option = Object.assign(useCrud2.value.option, {
 });
 const showLable = (key) => {
   switch (key) {
+    case "tipTemperature":
+      return "温度";
     case "CH5Val":
-      return "CH5";
+      return "温度";
     case "CH6Val":
-      return "CH6";
+      return "湿度";
     case "DataTimes":
       return "采集时间";
     case "torquetarget":
@@ -209,6 +211,8 @@ const showLable = (key) => {
       return "拧紧过程中最大扭力值";
     case "taskNo":
       return "当前任务号";
+    case "taskName":
+      return "任务名";
     case "warning":
       return "警报";
     case "tightenResult":

+ 78 - 2
src/views/quality/outsource/index.vue

@@ -45,7 +45,7 @@
           </template>
         </el-button>
         <el-button
-          v-if="row.state === '1' && row.sendState != '3'"
+          v-if="row.state === '1' && row.sendState==='1'"
           icon="el-icon-position"
           text
           @click="sendTdms(row.id)"
@@ -53,6 +53,15 @@
           :size="size"
           >发送TDM</el-button
         >
+        <el-button
+          v-if="row.state === '1'&& row.sendState==='0'"
+          icon="el-icon-position"
+          text
+          @click="sendTBom(row.id)"
+          type="primary"
+          :size="size"
+        >同步tBom</el-button
+        >
       </template>
     </avue-crud>
     <el-dialog
@@ -171,6 +180,29 @@
         <el-button type="primary" @click="audit">审 核</el-button>
       </div>
     </el-dialog>
+    <el-dialog  v-model="dialogTBom.visible"
+                :title="dialogTBom.title"
+                width="950px"
+                :destroy-on-close="true"
+                @close="dialog.visible = false">
+      <el-form>
+      <el-form-item label="附件上传">
+        <el-radio-group v-model="tBom.upload" class="ml-4">
+          <FilesUpload
+            v-model:src="fileUrl"
+            v-model:file-name-list="fileNameList"
+            :limit="1"
+            @finished="testFiles"
+          />
+        </el-radio-group>
+      </el-form-item>
+      <el-form-item style="margin-left: 45%">
+        <el-button type="primary" @click="tdmUpload" :loading="isLoading"
+        >同步tBom</el-button
+        >
+      </el-form-item>
+      </el-form>
+    </el-dialog>
   </div>
 </template>
 <script setup>
@@ -178,11 +210,23 @@ import { ref, getCurrentInstance } from "vue";
 import { useCrud } from "@/hooks/userCrud";
 import { checkPerm } from "@/directive/permission";
 import ButtonPermKeys from "@/common/configs/buttonPermission";
+const loading=ref(false);
 import {
   queryOutSourceDetails,
   updateOutSourceApply,
   sendTdm,
+  sendTdmTBom,
 } from "@/api/process";
+
+const fileUrl = ref();
+const fileNameList = ref([]);
+const tBom=ref({});
+const testFiles = () => {
+  tBom.value.filePath = fileUrl.value;
+  tBom.value.fileName = fileNameList.value[0];
+  tBom.value.id=rowId.value;
+  console.log(tBom.value);
+};
 import { useCommonStoreHook } from "@/store";
 import dictDataUtil from "@/common/configs/dictDataUtil";
 const { isShowTable, tableType } = toRefs(useCommonStoreHook());
@@ -200,13 +244,35 @@ const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } =
   Methords; //增删改查
 const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
 const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
-const loading = ref(false);
+const isLoading = ref(false);
 const crudRef = ref(null); //crudRef.value 获取avue-crud对象
 const dialog = reactive({
   title: "委外详情",
   visible: false,
   type: 0,
 });
+const tdmUpload =()=>{
+  console.log(tBom.value);
+  if(!tBom||!tBom.value||!tBom.value.filePath){
+    ElMessage.error("没有上传文件!");
+    return;
+  }
+  isLoading.value=true;
+  sendTdmTBom(tBom.value).then(
+   (data)=>{
+     if(data.code==='200'){
+       dialogTBom.visible=false;
+       dataList();
+     }
+   }
+  ).finally(
+    isLoading.value=false
+  )
+}
+const dialogTBom = reactive({
+  title: "tBom同步到TDM",
+  visible: false,
+});
 const openDialog = (type, id) => {
   dialog.title = type === 0 ? "委外详情" : "委外审核";
   queryOutSourceDetails(id).then((data) => {
@@ -221,6 +287,16 @@ const openDialog = (type, id) => {
     dialog.type = type;
   });
 };
+const rowId =ref(null);
+const sendTBom =(id)=>{
+  rowId.value=id;
+  tBom.value.id=id;
+  fileUrl.value = {};
+  fileNameList.value =[];
+  dialogTBom.visible=true;
+
+
+}
 const audit = () => {
   form.value.state = radio.value === 0 ? 1 : 2;
   updateOutSourceApply(form.value).then((data) => {

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

@@ -25,6 +25,13 @@
                    text
                    type="primary"
         >查看</el-button>
+          <el-button
+                  v-if="row.currentState==='5'"
+                  size="small"
+                  type="primary"
+                  @click="handleScanCode(row.id)"
+          >二维码生成
+          </el-button>
       </template>
 
 
@@ -39,7 +46,41 @@
     >
       <FaultDetail  :escalationFaultId="fault.id" :dialog="dialog" />
     </el-dialog>
+    <el-dialog
+      v-model="dialog3.visible"
+      :title="dialog3.title"
+      width="950px"
+      @close="
+        dialog3.visible = false;
+        scanCodeArray = [];
+      "
+    >
+      <div class="scanInfo">
+        <div style="padding: 0 20px; text-align: center">
+          二维码数量:{{ scanCodeArray.length }}
+        </div>
+        <el-scrollbar class="scrollbarA">
+          <div
+            :style="
+              scanCodeArray.length == 1 ? '   justify-content: center;' : ''
+            "
+            class="box"
+          >
+            <div
+              v-for="(item, index) in scanCodeArray"
+              :key="index"
+              class="scancodeitem"
+            >
+              <div class="qrcodeItem">
+                <vue-qrcode :value="item" error-level="low" size="70" />
+              </div>
+            </div>
+          </div>
 
+          <div v-if="scanCodeArray.length < 1">暂无数据</div>
+        </el-scrollbar>
+      </div>
+    </el-dialog>
 
   </div>
 </template>
@@ -53,6 +94,7 @@
   const { isShowTable, tableType } = toRefs(useCommonStoreHook());
   // 数据字典相关
   const { dicts } = useDictionaryStore();
+  import {getFaultScanCode} from "@/api/fault";
 
   const test = () => {
     isShowTable.value = true;
@@ -62,6 +104,10 @@
     title: "报故详情",
     visible: false,
   });
+  const dialog3 = reactive({
+    title: "二维码详情",
+    visible: false,
+  });
   const fault=ref({});
   const faultInfo=ref({});
   const faultEs=ref({});
@@ -76,7 +122,18 @@
     faultEs.value.id=row.id;
     dialog2.value.visible=true;
   }
+  function useScanCode() {
+    const scanCodeArray = ref([]);
 
+    const handleScanCode = async (id) => {
+      const { data, code } = await getFaultScanCode(id);
+      scanCodeArray.value = data;
+      dialog3.visible = true;
+    };
+    return { scanCodeArray, handleScanCode };
+  }
+
+  const { scanCodeArray, handleScanCode } = useScanCode();
   const faultExamine =(row)=>{
     faultExa.value.id=row.id;
     dialog3.value.visible=true;
@@ -132,3 +189,99 @@
 
 
 </script>
+<style lang="scss" scoped>
+.scanInfo {
+  width: 100%;
+
+  .scrollbar {
+    padding: 20px;
+    height: 350px;
+
+    .item {
+      margin: 20px 0;
+      width: 100%;
+      background-color: #80808030;
+      border-radius: 16px;
+      height: 60px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding: 0 20px;
+
+      .el-icon {
+        width: 50px;
+        height: 50px;
+        color: red;
+        cursor: pointer;
+      }
+    }
+
+    .scancodeitem {
+      width: 300px;
+      height: 300px;
+      margin: 0 20px;
+      display: inline-block;
+      border-radius: 16px;
+      border: 1px solid black;
+      padding-top: 10px;
+
+      .qrcodeItem {
+        display: flex;
+        justify-content: center;
+        align-items: center;
+      }
+    }
+  }
+
+  .bottombtn {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
+
+  .scrollbarA {
+    padding: 20px;
+    height: 350px;
+
+    .box {
+      display: flex;
+      align-items: center;
+
+      .item {
+        margin: 20px 0;
+        width: 100%;
+        background-color: #80808030;
+        border-radius: 16px;
+        height: 60px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 0 20px;
+
+        .el-icon {
+          width: 50px;
+          height: 50px;
+          color: red;
+          cursor: pointer;
+        }
+      }
+
+      .scancodeitem {
+        width: 300px;
+        height: 300px;
+        margin: 0 20px;
+        display: inline-block;
+        border-radius: 16px;
+        border: 1px solid black;
+        padding-top: 10px;
+
+        .qrcodeItem {
+          display: flex;
+          justify-content: center;
+          align-items: center;
+        }
+      }
+    }
+  }
+}
+</style>

+ 99 - 0
src/views/report/statistics/outTime/components/PieChart1.vue

@@ -0,0 +1,99 @@
+<!-- 饼图 -->
+<template>
+  <el-card>
+    <div :id="id" :class="className" :style="{ height, width }"></div>
+  </el-card>
+</template>
+
+<script setup lang="ts">
+import * as echarts from "echarts";
+import {defineProps, ref} from "vue";
+
+const props = defineProps({
+  id: {
+    type: String,
+    default: "pieChart",
+  },
+  className: {
+    type: String,
+    default: "",
+  },
+  width: {
+    type: String,
+    default: "200px",
+    required: true,
+  },
+  height: {
+    type: String,
+    default: "200px",
+    required: true,
+  },
+  list: {
+    type: Array,
+    default: [],
+    required: true
+  }
+});
+const options = {
+  title : {
+    text: '订单准时完成率',
+    x:'center'
+  },
+  tooltip : {
+    trigger: 'item',
+    formatter: "{b} : {c} ({d}%)"
+  },
+  legend: {
+    orient : 'vertical',
+    x : 'left',
+    data:['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
+  },
+  calculable : true,
+  series : [
+    {
+      name:'访问来源',
+      type:'pie',
+      radius : '75%',
+      center: ['50%', '50%'],
+      data:[
+        { name:'直接访问',value:70},
+        {value:30, name:'邮件营销'},
+      ]
+    }
+  ]
+};
+
+const chart = ref<any>("");
+watch?.(
+    () => props.list,
+    (newVal) => {
+      options.series[0].data = props.list
+      options.legend.data = []
+      props.list.forEach(item=>{
+        options.legend.data.push(item.name)
+      })
+      handle()
+    }
+);
+
+const handle=()=>{
+  chart.value = markRaw(
+      echarts.init(document.getElementById(props.id) as HTMLDivElement)
+  );
+
+  chart.value.setOption(options);
+
+  window.addEventListener("resize", () => {
+    chart.value.resize();
+  });
+}
+onMounted(() => {
+ handle();
+});
+
+onActivated(() => {
+  if (chart.value) {
+    chart.value.resize();
+  }
+});
+</script>

+ 99 - 0
src/views/report/statistics/outTime/components/PieChart2.vue

@@ -0,0 +1,99 @@
+<!-- 饼图 -->
+<template>
+  <el-card>
+    <div :id="id" :class="className" :style="{ height, width }"></div>
+  </el-card>
+</template>
+
+<script setup lang="ts">
+import * as echarts from "echarts";
+import {defineProps, ref} from "vue";
+
+const props = defineProps({
+  id: {
+    type: String,
+    default: "pieChart",
+  },
+  className: {
+    type: String,
+    default: "",
+  },
+  width: {
+    type: String,
+    default: "200px",
+    required: true,
+  },
+  height: {
+    type: String,
+    default: "200px",
+    required: true,
+  },
+  list: {
+    type: Array,
+    default: [],
+    required: true
+  }
+});
+const options = {
+  title : {
+    text: '工单准时完成率',
+    x:'center'
+  },
+  tooltip : {
+    trigger: 'item',
+    formatter: "{b} : {c} ({d}%)"
+  },
+  legend: {
+    orient : 'vertical',
+    x : 'left',
+    data:['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
+  },
+  calculable : true,
+  series : [
+    {
+      name:'访问来源',
+      type:'pie',
+      radius : '75%',
+      center: ['50%', '50%'],
+      data:[
+        { name:'直接访问',value:70},
+        {value:30, name:'邮件营销'},
+      ]
+    }
+  ]
+};
+
+const chart = ref<any>("");
+watch?.(
+    () => props.list,
+    (newVal) => {
+      options.series[0].data = props.list
+      options.legend.data = []
+      props.list.forEach(item=>{
+        options.legend.data.push(item.name)
+      })
+      handle()
+    }
+);
+
+const handle=()=>{
+  chart.value = markRaw(
+      echarts.init(document.getElementById(props.id) as HTMLDivElement)
+  );
+
+  chart.value.setOption(options);
+
+  window.addEventListener("resize", () => {
+    chart.value.resize();
+  });
+}
+onMounted(() => {
+  handle();
+});
+
+onActivated(() => {
+  if (chart.value) {
+    chart.value.resize();
+  }
+});
+</script>

+ 99 - 0
src/views/report/statistics/outTime/components/PieChart3.vue

@@ -0,0 +1,99 @@
+<!-- 饼图 -->
+<template>
+  <el-card>
+    <div :id="id" :class="className" :style="{ height, width }"></div>
+  </el-card>
+</template>
+
+<script setup lang="ts">
+import * as echarts from "echarts";
+import {defineProps, ref} from "vue";
+
+const props = defineProps({
+  id: {
+    type: String,
+    default: "pieChart",
+  },
+  className: {
+    type: String,
+    default: "",
+  },
+  width: {
+    type: String,
+    default: "200px",
+    required: true,
+  },
+  height: {
+    type: String,
+    default: "200px",
+    required: true,
+  },
+  list: {
+    type: Array,
+    default: [],
+    required: true
+  }
+});
+const options = {
+  title : {
+    text: '超期原因分析',
+    x:'center'
+  },
+  tooltip : {
+    trigger: 'item',
+    formatter: "{b} : {c} ({d}%)"
+  },
+  legend: {
+    orient : 'vertical',
+    x : 'left',
+    data:['直接访问','邮件营销','联盟广告','视频广告','搜索引擎']
+  },
+  calculable : true,
+  series : [
+    {
+      name:'访问来源',
+      type:'pie',
+      radius : '75%',
+      center: ['50%', '50%'],
+      data:[
+        { name:'直接访问',value:70},
+        {value:30, name:'邮件营销'},
+      ]
+    }
+  ]
+};
+
+const chart = ref<any>("");
+watch?.(
+    () => props.list,
+    (newVal) => {
+      options.series[0].data = props.list
+      options.legend.data = []
+      props.list.forEach(item=>{
+        options.legend.data.push(item.name)
+      })
+      handle()
+    }
+);
+
+const handle=()=>{
+  chart.value = markRaw(
+      echarts.init(document.getElementById(props.id) as HTMLDivElement)
+  );
+
+  chart.value.setOption(options);
+
+  window.addEventListener("resize", () => {
+    chart.value.resize();
+  });
+}
+onMounted(() => {
+  handle();
+});
+
+onActivated(() => {
+  if (chart.value) {
+    chart.value.resize();
+  }
+});
+</script>

+ 148 - 0
src/views/report/statistics/outTime/index.vue

@@ -0,0 +1,148 @@
+<template>
+  <div class="dashboard-container">
+    <!-- 数据卡片 -->
+    <el-row :gutter="10" class="mt-3">
+      <el-col :xs="24" :sm="12" :lg="12">
+        <el-card shadow="never">
+          <template #header>
+            <div class="flex items-center justify-between">
+              <span class="text-[var(--el-text-color-secondary)]">总订单数</span>
+              <el-tag type="success">{{ amount1 }}</el-tag>
+            </div>
+          </template>
+
+          <div
+            class="flex items-center justify-between mt-5 text-sm text-[var(--el-text-color-secondary)]"
+          >
+            <span> 超期订单 </span>
+            <el-tag type="error">{{outAmount1}}</el-tag>
+          </div>
+        </el-card>
+      </el-col>
+
+      <!--消息数-->
+      <el-col :xs="24" :sm="12" :lg="12">
+        <el-card shadow="never">
+          <template #header>
+            <div class="flex items-center justify-between">
+              <span class="text-[var(--el-text-color-secondary)]">总工单数</span>
+              <el-tag type="success">{{amount2}}</el-tag>
+            </div>
+          </template>
+
+
+          <div
+            class="flex items-center justify-between mt-5 text-sm text-[var(--el-text-color-secondary)]"
+          >
+            <span> 超期工单 </span>
+            <el-tag type="error">{{outAmount2}}</el-tag>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- Echarts 图表 -->
+    <el-row :gutter="10" class="mt-3">
+      <el-col :xs="24" :sm="12" :lg="8" class="mb-2">
+        <PieChart1
+            id="pieChart1"
+            height="400px"
+            width="100%"
+            class="bg-[var(--el-bg-color-overlay)]"
+            :list="list1"
+        />
+      </el-col>
+      <el-col :xs="24" :sm="12" :lg="8" class="mb-2">
+        <PieChart2
+          id="pieChart2"
+          height="400px"
+          width="100%"
+          class="bg-[var(--el-bg-color-overlay)]"
+          :list="list2"
+        />
+      </el-col>
+
+      <el-col :xs="24" :sm="12" :lg="8" class="mb-2">
+        <PieChart3
+            id="pieChart3"
+            height="400px"
+            width="100%"
+            class="bg-[var(--el-bg-color-overlay)]"
+            :list="list3"
+        />
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup lang="ts">
+defineOptions({
+  name: "Dashboard",
+  inheritAttrs: false,
+});
+import { useUserStore } from "@/store/modules/user";
+import {outTimeInfo} from "@/api/report"
+const userStore = useUserStore();
+const date: Date = new Date();
+
+const duration = 5000;
+
+const list1 = ref([])
+const list2 = ref([])
+const list3 = ref([])
+// 销售额
+const amount1 = ref(0);
+const amount2 = ref(0);
+
+
+const outAmount1 = ref(0);
+const outAmount2 = ref(0);
+
+onMounted(() => {
+  outTimeInfo("").then((res)=>{
+    amount1.value = res.data.orderNum;
+    amount2.value = res.data.workOrderNum;
+    outAmount1.value = res.data.outOrder;
+    outAmount2.value = res.data.outWorkOrder;
+    list1.value = res.data.orderRate;
+    list2.value = res.data.workOrderRate;
+    list3.value = res.data.reasons;
+  });
+});
+</script>
+
+<style lang="scss" scoped>
+.dashboard-container {
+  position: relative;
+  padding: 24px;
+
+  .user-avatar {
+    width: 40px;
+    height: 40px;
+    border-radius: 50%;
+  }
+
+  .github-corner {
+    position: absolute;
+    top: 0;
+    right: 0;
+    z-index: 1;
+    border: 0;
+  }
+
+  .data-box {
+    display: flex;
+    justify-content: space-between;
+    padding: 20px;
+    font-weight: bold;
+    color: var(--el-text-color-regular);
+    background: var(--el-bg-color-overlay);
+    border-color: var(--el-border-color);
+    box-shadow: var(--el-box-shadow-dark);
+  }
+
+  .svg-icon {
+    fill: currentcolor !important;
+  }
+}
+</style>

+ 13 - 7
src/views/report/statistics/screens/line/index.vue

@@ -96,7 +96,7 @@
                   <div class="info">
                     <div class="info1">{{ item.deviceName }}</div>
                     <div class="info2">
-                      <div class="text2">
+<!--                      <div class="text2">
                         今日稼动
                         <span class="nums">{{ item.utilizationRate }}</span>
                       </div>
@@ -106,7 +106,7 @@
                         <span class="nums" style="color: white">{{
                           item.totalRate
                         }}</span>
-                      </div>
+                      </div>-->
                     </div>
                     <div class="info3">
                       <div class="ip">IP:{{ item.ip }}</div>
@@ -173,7 +173,7 @@
           <TitleHeaderB title="今日报故" />
           <div class="titleInfo">
             <div class="infoItem">
-              <div class="leftItem">工位名称</div>
+              <div class="leftItem">物料名称</div>
               <div class="rightItem">报故数量</div>
             </div>
           </div>
@@ -224,6 +224,7 @@ import {
 } from "@/api/bigScreen";
 import Middle3D from "./middle3D.vue";
 import moment from "moment";
+import { useTimeInterval } from "@/hooks/timeInterval";
 const fontSize = ref(0);
 const scrollbarRef1 = ref(null);
 const ShowScrollRef1 = ref(null);
@@ -389,16 +390,21 @@ const setChart1Option = () => {
 onMounted(async () => {
   setFontSize();
   await getData4();
+
+  charts2.value = echarts.init(document.getElementById("charts2"));
+
+  window.addEventListener("resize", function () {
+    charts2.value.resize();
+  });
+});
+
+useTimeInterval(async () => {
   getTodayData();
   getRateArray();
   getDevice();
   getMaterialArray();
   getTodayErrorArray();
-  charts2.value = echarts.init(document.getElementById("charts2"));
   setChart1Option();
-  window.addEventListener("resize", function () {
-    charts2.value.resize();
-  });
 });
 </script>
 

+ 252 - 0
src/views/report/statistics/screens/repertoryStatistic/index.vue

@@ -0,0 +1,252 @@
+<template>
+  <div
+    :key="viewKey"
+    class="screen-container"
+    @click.stop="animationState = !animationState"
+  >
+    <common-header title="线边库库存统计" />
+    <div class="screen-content">
+      <div class="chartsCarouselBox itemBackgroud">
+        <div class="carouselHeader tableStyle">
+          <div class="a1 center1Text">物料名称</div>
+          <div class="a2 center1Text">当前库存</div>
+          <div class="a2 center1Text">入库数量</div>
+          <div class="a2 center1Text">出库数量</div>
+          <div class="a2 center1Text">库存预警</div>
+        </div>
+        <div v-if="animationState" class="carouselBody">
+          <TransitionGroup name="list" tag="ul">
+            <li
+              class="carouselItem tableStyle"
+              :key="item"
+              style="height: 9.6vh"
+              v-for="item in showDatas"
+            >
+              <div class="a1 infoBackgroud centerText textComent">
+                {{ item.materialName }}
+              </div>
+              <div class="a2 infoBackgroud centerText textComent">
+                {{ item.allNum }}
+              </div>
+              <div
+                class="a2 infoBackgroud centerText textComent"
+                style="font-weight: bolder"
+              >
+                {{ item.inNum }}
+              </div>
+              <div
+                class="a2 infoBackgroud centerText textComent"
+                style="font-weight: bolder"
+              >
+                {{ item.outNum }}
+              </div>
+              <div
+                class="a2 infoBackgroud centerText textComent"
+                style="font-weight: bolder"
+              >
+                {{ item.warningNum }}
+              </div>
+            </li>
+          </TransitionGroup>
+        </div>
+        <div v-else class="carouselBody">
+          <div name="list" tag="ul">
+            <li
+              class="carouselItem tableStyle"
+              :key="item"
+              style="height: 9.6vh"
+              v-for="item in showDatas"
+            >
+              <div class="a1 infoBackgroud centerText textComent">
+                {{ item.materialName }}
+              </div>
+              <div class="a2 infoBackgroud centerText textComent">
+                {{ item.allNum }}
+              </div>
+              <div
+                class="a2 infoBackgroud centerText textComent"
+                style="font-weight: bolder"
+              >
+                {{ item.inNum }}
+              </div>
+              <div
+                class="a2 infoBackgroud centerText textComent"
+                style="font-weight: bolder"
+              >
+                {{ item.outNum }}
+              </div>
+              <div
+                class="a2 infoBackgroud centerText textComent"
+                style="font-weight: bolder"
+              >
+                {{ item.warningNum }}
+              </div>
+            </li>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import CommonHeader from "@/views/report/statistics/screens/common-header.vue";
+import { getLineSideStock, getOffLineInfo } from "@/api/bigScreen";
+import { useTimeInterval } from "@/hooks/timeInterval";
+const animationState = ref(true);
+const viewKey = ref(false);
+const checkFullscreen = () => {
+  viewKey.value = !viewKey.value;
+};
+const datas = ref([]);
+const borderRef = ref(null);
+const showDatas = ref([]);
+const interval1 = ref(null);
+const sum1 = ref(1);
+const setShowData1 = (num, time) => {
+  sum1.value = num;
+  if (datas.value.length > num) {
+    const dataA = JSON.parse(JSON.stringify(datas.value));
+    showDatas.value = dataA.splice(0, num);
+    interval1.value = setInterval(async () => {
+      await showDatas.value.push(datas.value[sum1.value % datas.value.length]);
+      showDatas.value.splice(0, 1);
+      sum1.value = sum1.value + 1;
+    }, time);
+  } else {
+    showDatas.value = datas.value;
+  }
+};
+const getListData = async () => {
+  const { data } = await getLineSideStock();
+  datas.value = data;
+};
+
+onMounted(async () => {
+  window.addEventListener("resize", checkFullscreen);
+  borderRef.value?.initWH();
+});
+
+useTimeInterval(async () => {
+  await getListData();
+  setShowData1(8, 3000);
+});
+
+onUnmounted(() => {
+  if (interval1.value) {
+    clearInterval(interval1.value);
+  }
+  document.removeEventListener("resize", checkFullscreen);
+});
+</script>
+
+<style lang="scss" scoped>
+.list-move,
+.list-enter-active,
+.list-leave-active {
+  transition: all 0.5s ease;
+}
+.list-enter-from,
+.list-leave-to {
+  opacity: 0;
+  transform: translateY(-4.6vh);
+}
+.list-leave-active {
+  position: absolute;
+}
+.screen-container {
+  width: 100vw;
+  height: 100vh;
+  background-image: url("@/assets/images/screen_bg_task.png");
+  background-size: cover;
+  background-position: center;
+}
+.itemBackgroud {
+  background-color: rgba(0, 0, 0, 0.6);
+}
+.screen-content {
+  width: 100vw;
+  height: 88vh;
+  margin-top: 2vh;
+  padding: 0 2vh;
+  display: flex;
+  justify-content: space-between;
+  flex-wrap: wrap;
+  position: relative;
+}
+.tableStyle {
+  display: flex;
+  justify-content: space-between;
+  width: 100%;
+  .left {
+    width: 66%;
+  }
+  .middle {
+    width: 19%;
+  }
+  .right {
+    width: 13%;
+  }
+}
+.centerText {
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 3vh;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  line-height: 9.6vh;
+  text-align: center;
+  padding: 0 1vh;
+}
+.center1Text {
+  color: rgba(255, 255, 255, 0.8);
+  font-size: 2vh;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  padding: 0 0.3vh;
+}
+.infoBackgroud {
+  background-color: rgba(255, 255, 255, 0.05);
+}
+.textComent {
+  white-space: nowrap; /* 不允许换行 */
+  overflow: hidden; /* 超出长度时隐藏 */
+  text-overflow: ellipsis; /* 超出部分显示省略号 */
+}
+.chartsCarouselBox {
+  flex: 1;
+  display: flex;
+  flex-direction: column;
+  padding: 2vh;
+  .carouselHeader {
+    height: calc(3vh);
+    line-height: 3vh;
+    margin-bottom: 0.5vh;
+    .a1 {
+      width: 25vw;
+    }
+    .a2 {
+      width: 17vw;
+    }
+  }
+  .carouselBody {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+
+    .carouselItem {
+      margin-bottom: 0.5vh;
+      width: 96vw;
+      .a1 {
+        width: 25vw;
+        display: inline-block;
+      }
+      .a2 {
+        width: 17vw;
+      }
+    }
+  }
+}
+</style>

+ 204 - 29
src/views/report/statistics/screens/tasks/index.vue

@@ -1,5 +1,9 @@
 <template>
-  <div :key="viewKey" class="screen-container">
+  <div
+    :key="viewKey"
+    class="screen-container"
+    @click.stop="animationState = !animationState"
+  >
     <common-header title="工位任务分布/防静电监控" />
     <!-- <div
       style="
@@ -17,7 +21,7 @@
         :style="{ transform: 'scale(' + 1.5 + ')' }"
       />
     </div> -->
-    <div class="screen-content">
+    <div v-if="animationState" class="screen-content">
       <!-- <TransitionGroup class="rowbox" name="list1" tag="ul">
         <div v-for="(item, index) in showdatas1" :key="item" class="grid-item">
           <title-header :title="item.stationName" />
@@ -113,12 +117,12 @@
               <div class="box">
                 <div style="display: flex; align-items: center">
                   <dv-digital-flop
-                    :config="completeNumConfigs[index + 3]"
+                    :config="completeNumConfigs[index]"
                     class="flop"
                   />
                   <span class="plan-num">/</span>
                   <dv-digital-flop
-                    :config="taskNumConfigs[index + 3]"
+                    :config="taskNumConfigs[index]"
                     class="flop"
                   />
                 </div>
@@ -183,6 +187,194 @@
         </div>
       </TransitionGroup>
     </div>
+    <div v-else class="screen-content">
+      <!-- <TransitionGroup class="rowbox" name="list1" tag="ul">
+        <div v-for="(item, index) in showdatas1" :key="item" class="grid-item">
+          <title-header :title="item.stationName" />
+          <div class="grid-bottom">
+            <div class="left-info">
+              <div
+                class="box"
+                style="
+                  display: flex;
+                  flex-direction: column;
+                  justify-content: center;
+                "
+              >
+                <div class="title">{{ item.materialName }}</div>
+                <div class="code">{{ item.materialModel }}</div>
+              </div>
+              <div class="box">
+                <div style="display: flex; align-items: center">
+                  <dv-digital-flop
+                    :config="completeNumConfigs[index]"
+                    class="flop"
+                  />
+                  <span class="plan-num">/</span>
+                  <dv-digital-flop
+                    :config="taskNumConfigs[index]"
+                    class="flop"
+                  />
+                </div>
+                <div class="desc">完成数量 / 计划数量</div>
+              </div>
+            </div>
+            <div class="right-chart">
+              <dv-water-level-pond
+                :config="{
+                  data: [setPondNumber(item.rate)],
+                  shape: 'round',
+                }"
+                :key="sum1"
+                style="width: 16vh; height: 16vh"
+              />
+            </div>
+          </div>
+        </div>
+      </TransitionGroup> -->
+      <div class="rowbox itemBackgroud" name="list1" tag="ul">
+        <title-header :title="'防静电监控'" />
+        <div class="chartsCarouselBox">
+          <div class="carouselHeader tableStyle">
+            <div class="left center1Text">工位名称</div>
+            <div class="right center1Text">状态</div>
+          </div>
+          <div class="carouselBody">
+            <div name="list" tag="ul">
+              <li
+                class="carouselItem tableStyle"
+                :key="item"
+                v-for="item in showData1"
+              >
+                <div class="left infoBackgroud centerText textComent">
+                  {{ item.stationName }}
+                </div>
+                <div
+                  :class="{
+                    outline: item.state === '离线',
+                    error: item.state === '故障',
+                  }"
+                  class="right infoBackgroud centerText textComent"
+                  style="font-weight: bolder"
+                >
+                  {{ item.state }}
+                </div>
+              </li>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="rowbox" name="list2" tag="ul">
+        <div v-for="(item, index) in showdatas2" :key="item" class="grid-item">
+          <title-header :title="item.stationName" />
+          <div class="grid-bottom">
+            <div class="left-info">
+              <div
+                class="box"
+                style="
+                  display: flex;
+                  flex-direction: column;
+                  justify-content: center;
+                "
+              >
+                <div class="title">{{ item.materialName }}</div>
+                <div class="code">{{ item.materialModel }}</div>
+              </div>
+              <div class="box">
+                <div style="display: flex; align-items: center">
+                  <span class="flopStatic" style="color: rgb(58, 223, 195)">{{
+                    completeNumConfigs[index].number[0]
+                  }}</span>
+                  <span class="plan-num">/</span>
+                  <span class="flopStatic" style="color: white">{{
+                    taskNumConfigs[index].number[0]
+                  }}</span>
+                </div>
+                <div class="desc">完成数量 / 计划数量</div>
+              </div>
+            </div>
+            <div class="right-chart">
+              <div
+                :config="{
+                  data: [setPondNumber(item.rate)],
+                  shape: 'round',
+                }"
+                :key="sum1"
+                style="
+                  width: 16vh;
+                  height: 16vh;
+                  border: 0.6vh solid #24d4de;
+                  border-radius: 8vh;
+                  display: flex;
+                  align-items: center;
+                  justify-content: center;
+                  color: #24d4de;
+                  font-size: 4vh;
+                  font-weight: bolder;
+                "
+              >
+                {{ setPondNumber(item.rate) }}%
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="rowbox" name="list3" tag="ul">
+        <div v-for="(item, index) in showdatas3" :key="item" class="grid-item">
+          <title-header :title="item.stationName" />
+          <div class="grid-bottom">
+            <div class="left-info">
+              <div
+                class="box"
+                style="
+                  display: flex;
+                  flex-direction: column;
+                  justify-content: center;
+                "
+              >
+                <div class="title">{{ item.materialName }}</div>
+                <div class="code">{{ item.materialModel }}</div>
+              </div>
+              <div class="box">
+                <div style="display: flex; align-items: center">
+                  <span class="flopStatic" style="color: rgb(58, 223, 195)">{{
+                    completeNumConfigs[index + 3].number[0]
+                  }}</span>
+                  <span class="plan-num">/</span>
+                  <span class="flopStatic" style="color: white">{{
+                    taskNumConfigs[index + 3].number[0]
+                  }}</span>
+                </div>
+                <div class="desc">完成数量 / 计划数量</div>
+              </div>
+            </div>
+            <div class="right-chart">
+              <div
+                :config="{
+                  data: [setPondNumber(item.rate)],
+                  shape: 'round',
+                }"
+                :key="sum1"
+                style="
+                  width: 16vh;
+                  height: 16vh;
+                  border: 0.6vh solid #24d4de;
+                  border-radius: 8vh;
+                  display: flex;
+                  align-items: center;
+                  justify-content: center;
+                  color: #24d4de;
+                  font-size: 4vh;
+                  font-weight: bolder;
+                "
+              >
+                {{ setPondNumber(item.rate) }}%
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
   </div>
 </template>
 
@@ -190,6 +382,7 @@
 import CommonHeader from "@/views/report/statistics/screens/common-header.vue";
 import TitleHeader from "@/views/report/statistics/screens/titleHeader.vue";
 import { getStationTaskInfo, getStationState } from "@/api/bigScreen";
+const animationState = ref(true);
 const showData1 = ref([]);
 const fontSize = ref(0);
 const setPondNumber = (str) => {
@@ -314,24 +507,6 @@ const completeNumConfigs = ref([
       fontSize: fontSize,
     },
   },
-  {
-    number: [0],
-    style: {
-      fontSize: fontSize,
-    },
-  },
-  {
-    number: [0],
-    style: {
-      fontSize: fontSize,
-    },
-  },
-  {
-    number: [0],
-    style: {
-      fontSize: fontSize,
-    },
-  },
 ]);
 
 const taskNumConfigs = ref([
@@ -413,16 +588,12 @@ const setNumber = (time) => {
   // }
   if (showdatas2.value.length > 0) {
     showdatas2.value.forEach((item, index) => {
-      setTimeOutFnc(
-        completeNumConfigs.value[index + 3],
-        item.completeNum,
-        time
-      );
-      setTimeOutFnc(taskNumConfigs.value[index + 3], item.taskNum, time);
+      setTimeOutFnc(completeNumConfigs.value[index], item.completeNum, time);
+      setTimeOutFnc(taskNumConfigs.value[index], item.taskNum, time);
     });
   }
   if (showdatas3.value.length > 0) {
-    showdatas2.value.forEach((item, index) => {
+    showdatas3.value.forEach((item, index) => {
       setTimeOutFnc(
         completeNumConfigs.value[index + 3],
         item.completeNum,
@@ -623,6 +794,10 @@ onUnmounted(() => {
   display: block;
   font-size: 4vh;
 }
+.flopStatic {
+  font-size: 4vh;
+  margin: 0 3.5vh;
+}
 .screen-content {
   height: 84vh;
   margin-top: 2vh;

+ 15 - 2
src/views/storage/alarm/index.vue

@@ -182,14 +182,27 @@ option.value = Object.assign(option.value, {
       ],
     },
     {
-      label: "提示内容",
+      label: "不足提示",
+      prop: "minMsg",
+      width: 200,
+      overHidden: true,
+      rules: [
+        {
+          required: true,
+          message: "库存不足提示不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "过多提示",
       prop: "msg",
       width: 200,
       overHidden: true,
       rules: [
         {
           required: true,
-          message: "提示内容不能为空",
+          message: "库存过多提示不能为空",
           trigger: "trigger",
         },
       ],

+ 133 - 0
src/views/storage/entry/index.vue

@@ -0,0 +1,133 @@
+<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-right="{}">
+        <el-dropdown split-button
+          >入库单导入同步到WMS
+          <template #dropdown>
+            <el-dropdown-menu>
+              <el-dropdown-item
+                @click="downloadTemplate('/api/v1/warehousing/entry/template')"
+              >
+                <i-ep-download />下载模板
+              </el-dropdown-item>
+              <el-dropdown-item @click="importExcelData">
+                <i-ep-top />导入数据
+              </el-dropdown-item>
+            </el-dropdown-menu>
+          </template>
+        </el-dropdown>
+      </template>
+    </avue-crud>
+
+    <ExcelUpload ref="uploadRef" @finished="uploadFinished" />
+  </div>
+</template>
+<script setup lang="ts">
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import { syncAps } from "@/api/aps";
+import { useCommonStoreHook, useDictionaryStore } from "@/store";
+import { ElMessage, ElMessageBox } from "element-plus";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+const { dicts } = useDictionaryStore();
+const apsSync = () => {
+  ElMessageBox.confirm("是否同步所选中数据?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(async () => {
+    let param = { type: 2, codes: toDeleteIds.value };
+    syncAps(param).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({
+    src: "/api/v1/warehousing/entry",
+  });
+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 crudRef = ref(null); //crudRef.value 获取avue-crud对象
+const router = useRouter();
+const binding = (row) => {
+  router.push(`/base/bom/${row.materialCode}`);
+};
+onMounted(() => {
+  // 设置表格列或者其他自定义的option
+
+  dataList();
+});
+
+/**
+ * 上传excel相关
+ */
+const uploadRef = ref(null);
+const uploadFinished = () => {
+  // 上传完成后的刷新操作
+  page.currentPage = 1;
+  dataList();
+};
+const importExcelData = () => {
+  if (uploadRef.value) {
+    uploadRef.value.show("/api/v1/warehousing/entry/import");
+  }
+};
+
+option.value = Object.assign(option.value, {
+  selection: true,
+  addBtn: false,
+  editBtn: false,
+  viewBtn: false,
+  column: [
+    {
+      label: "操作人",
+      prop: "creator",
+    },
+    {
+      label: "文件名称",
+      prop: "fileName",
+    },
+    {
+      label: "操作时间",
+      prop: "created",
+    },
+
+  ],
+});
+</script>

+ 14 - 2
src/views/storage/stock/index.vue

@@ -146,17 +146,28 @@ option.value = Object.assign(option.value, {
       ],
     },
     {
+      label: "层数",
+      prop: "position",
+      rules: [
+        {
+          required: true,
+          message: "层数不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
       label: "批次号",
       width: 120,
       overHidden: true,
       prop: "batchCode",
       search: true
     },
-    {
+    /*{
       label: "入库单号",
       prop: "taskNo",
       search: true,
-    },
+    },*/
     {
       label: "计划单号",
       prop: "planNo",
@@ -172,6 +183,7 @@ option.value = Object.assign(option.value, {
       label: "物料名称",
       prop: "materialName",
       width: 130,
+      readonly: true,
       overHidden: true,
       click: ({ value, column }) => {
         if(column.boxType){

+ 4 - 3
src/views/storage/storage/index.vue

@@ -179,13 +179,14 @@ option.value = Object.assign(option.value, {
       label: "状态",
       prop: "enable",
       type: "select",
-      dicData: [{label: '启用' , value: 0},{label: '禁用' , value: 1}],
+      dicData: [{label: '启用' , value: "0"},{label: '禁用' , value: "1"}],
       html: true,
       formatter: (val) => {
-        if (val.state === 0) {
+        if (val.enable === "0") {
           return '<b class="el-tag el-tag--success el-tag--light">启用</b>';
+        }else{
+          return '<b class="el-tag el-tag--danger el-tag--light">禁用</b>';
         }
-        return '<b class="el-tag el-tag--danger el-tag--light">禁用</b>';
       },
       rules: [
         {

+ 161 - 0
src/views/storage/warningInfo/index.vue

@@ -0,0 +1,161 @@
+<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-button
+            v-if="row.state === '0' && row.userName === userStore.user.username"
+            type="primary"
+            link
+            size="small"
+            @click="test(row, 0)"
+        ><i-ep-edit />处理
+        </el-button>
+      </template>
+    </avue-crud>
+    <el-dialog
+        v-model="dialog1.visible"
+        :title="dialog1.title"
+        width="950px"
+        @close="dialog1.visible = false"
+    >
+      <choice-item-page enabled="" @materialInfo="materialInfo"/>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import { useCommonStoreHook,useUserStoreHook} from "@/store";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+const userStore = useUserStoreHook();
+const test = (row) => {
+  ElMessageBox.confirm("你确定要处理当前消息吗", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+  }).then(() => {
+    row.state = 1;
+    form.value = row
+    updateRow(row).then((res)=>{
+      dataList()
+    });
+  });
+};
+
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/warningInfo",
+  });
+const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } = Methords; //增删改查
+const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
+const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
+const dialog1 = reactive({
+  title: "物料选择",
+  visible: false,
+});
+const materialInfo = (value) => {
+  form.value.code = value.materialCode
+  form.value.name = value.materialName
+  form.value.unit = value.unitDictValue
+  dialog1.visible = false
+}
+const crudRef = ref(null); //crudRef.value 获取avue-crud对象
+
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  delBtn: false,
+  selection: false,
+  editBtn: false,
+  viewBtn: false,
+  addBtn: false,
+  column: [
+    {
+      label: "物料编码",
+      prop: "materialCode",
+      width: 150,
+      overHidden: true,
+      search: true,
+    },
+    {
+      label: "物料名称",
+      prop: "materialName",
+      search: true,
+      width: 150,
+      overHidden: true,
+      disabled: true,
+    },
+    {
+      label: "物料型号",
+      prop: "materialModel",
+      search: true,
+      width: 150,
+      overHidden: true,
+      disabled: true,
+      rules: [
+        {
+          required: true,
+          message: "物料名称不能为空",
+          trigger: "trigger",
+        },
+      ],
+    },
+    {
+      label: "预警信息",
+      prop: "warningInfo",
+
+    },
+    {
+      label: "处理人",
+      prop: "userName",
+      search: true,
+      display: false
+    },
+    {
+      label: "状态",
+      prop: "state",
+      type: 'select',
+      dicData: [{label: '未处理',value : '0'},{label: '已处理', value : '1'}],
+    },
+    {
+      label: "创建时间",
+      prop: "created",
+      width: 180,
+      display: false
+    },
+    {
+      label: "处理时间",
+      prop: "updated",
+      width: 180,
+      html: true,
+      formatter: (val) => {
+        if (val.state === "1") {
+          return val.updated
+        } else {
+          return '';
+        }
+      },
+    },
+  ],
+});
+
+onMounted(() => {
+  // console.log("crudRef", crudRef)
+  dataList();
+});
+</script>

+ 163 - 0
src/views/storage/warningRole/index.vue

@@ -0,0 +1,163 @@
+<template>
+  <div class="mainContentBox" style="width:50%; float: left;">
+    <avue-crud
+        ref="crudRef1"
+        v-model="form"
+        :data="data"
+        :option="option"
+        @row-update="userSave"
+        @row-click="rowClick"
+    >
+    </avue-crud>
+  </div>
+  <div class="mainContentBox" style="width:50%;float: left;">
+    <avue-crud
+        ref="crudRef2"
+        v-model="form"
+        :data="data1"
+        :option="option1"
+        @row-del="delUser"
+    >
+    </avue-crud>
+  </div>
+</template>
+<script setup>
+import { ref, getCurrentInstance } from "vue";
+import { useCrud } from "@/hooks/userCrud";
+import {queryDictDataByType } from "@/api/system/dict"
+import {queryWarningUser,delWarningUser,addWarningUser} from "@/api/storage"
+import {getUserList} from "@/api/system/user"
+import { useCommonStoreHook } from "@/store";
+const { isShowTable, tableType } = toRefs(useCommonStoreHook());
+const crudRef1 = ref(null);
+const crudRef2 = ref(null);
+const rowClick = (row) => {
+  selectRow.value = row
+  crudRef1.value.setCurrentRow(row);
+  queryUsers(row.dictValue)
+};
+const selectRow = ref()
+const userSave =(row,done, loading)=>{
+  loading()
+  row.roleCode = row.dictValue
+  let userObj = []
+  row.userName.forEach(item=>{
+    const user = userList.value.filter((u)=>u.userName == item)[0]
+    userObj.push({"userId": user.id,"userName": item})
+  })
+  row.users = userObj;
+  //createRow(row,done, loading)
+  addWarningUser(row).then(()=>{
+    rowClick(selectRow.value)
+  })
+  done()
+}
+// 传入一个url,后面不带/
+const { form, data, option, search, page, toDeleteIds, Methords, Utils } =
+  useCrud({
+    src: "/api/v1/warningUser",
+  });
+const { dataList, createRow, updateRow, deleteRow, searchChange, resetChange } = Methords; //增删改查
+const { selectionChange, multipleDelete } = Methords; //选中和批量删除事件
+const { checkBtnPerm, downloadTemplate, exportData } = Utils; //按钮权限等工具
+const userList = ref([])
+//crudRef.value 获取avue-crud对象
+// 设置表格列或者其他自定义的option
+option.value = Object.assign(option.value, {
+  delBtn: false,
+  selection: false,
+  viewBtn: false,
+  editBtn: true,
+  menu: true,
+  addBtn: false,
+  searchBtn: false,
+  toolBtn: false,
+  highlightCurrentRow: true,
+  column: [
+    {
+      label: "角色名称",
+      prop: "dictLabel",
+      overHidden: true,
+      type: "select",
+      editDisplay: false,
+    },
+    {
+      label: "用户名称",
+      prop: "userName",
+      overHidden: true,
+      hide: true,
+      type: "select",   //下拉框类型
+      multiple: true,
+      dicData: userList,
+      props: {
+        label: "userName",
+        value: "userName",
+      },
+    },
+  ],
+});
+const data1 = ref([])
+const option1 = ref({
+  delBtn: true,
+  selection: false,
+  viewBtn: false,
+  editBtn: false,
+  menu: true,
+  addBtn: false,
+  searchBtn: false,
+  refreshBtn: false,
+  column: [
+    {
+      label: "用户名称",
+      prop: "userName",
+      overHidden: true,
+    },
+  ],
+});
+const queryRoles = () => {
+  queryDictDataByType("warning_role").then((res)=>{
+    data.value = res.data
+    rowClick(data.value[0])
+    data.value.forEach(item=>{
+      let users = []
+      queryWarningUser({roleCode: item.dictValue}).then((u)=>{
+        u.data.records.forEach((uu)=>{
+          users.push(uu.userName)
+        })
+        item.userName = users
+      })
+    })
+  });
+};
+const delUser = (row)=>{
+  ElMessageBox.confirm("确定要删除数据吗?", "提示", {
+    confirmButtonText: "确定",
+    cancelButtonText: "取消",
+    type: "warning",
+    lockScroll: false,
+  }).then(() => {
+    delWarningUser(row).then((res)=>{
+      queryRoles()
+    });
+  });
+}
+
+const queryUsers = (code)=>{
+  data1.value = []
+  queryWarningUser({roleCode: code}).then((res)=>{
+    data1.value = res.data.records
+  })
+
+}
+const queryUserList = ()=>{
+  getUserList({}).then((res)=>{
+    userList.value = res.data
+  })
+}
+onMounted(() => {
+  queryUserList()
+  // console.log("crudRef", crudRef)
+  //search.value.type = '2'
+  queryRoles();
+});
+</script>

+ 7 - 0
src/views/storage/wmsOrder/index.vue

@@ -142,6 +142,13 @@ option.value = Object.assign(option.value, {
       }
     },
     {
+      label: "操作日志",
+      prop: "message",
+      width: 180,
+      overHidden: true,
+      display: false
+    },
+    {
       label: "操作时间",
       prop: "created",
       width: 180,

+ 5 - 1
src/views/system/dept/index.vue

@@ -120,7 +120,11 @@
           />
         </el-form-item>
         <el-form-item label="组织编码" prop="deptCode">
-          <el-input v-model="formData.deptCode" placeholder="请输入组织编码" />
+          <el-input
+            v-model="formData.deptCode"
+            :disabled="dialog.title === '修改组织'"
+            placeholder="请输入组织编码"
+          />
         </el-form-item>
         <el-form-item label="组织名称" prop="deptName">
           <el-input v-model="formData.deptName" placeholder="请输入组织名称" />

+ 12 - 12
src/views/system/user/index.vue

@@ -14,7 +14,7 @@
             <el-form-item label="关键字" prop="keywords">
               <el-input
                 v-model="queryParams.keywords"
-                placeholder="用户名/昵称/手机号"
+                placeholder="账号/姓名/工作证号"
                 clearable
                 style="width: 200px"
                 @keyup.enter="handleQuery"
@@ -90,7 +90,7 @@
           >
             <el-table-column type="selection" width="50" align="center" />
             <el-table-column
-              label="用户名"
+              label="账号"
               width="120"
               align="center"
               prop="userName"
@@ -103,7 +103,7 @@
             />
             <el-table-column
                 key="employeeCode"
-                label="员工编号"
+                label="工作证号"
                 align="center"
                 prop="employeeCode"
             />
@@ -209,27 +209,27 @@
       >
         <el-row :gutter="22">
           <el-col :span="11">
-            <el-form-item label="用户名" prop="userName">
+            <el-form-item label="账号" prop="userName">
               <el-input
                   v-model="formData.userName"
                   :disabled="!!formData.id"
-                  placeholder="请输入用户名"
+                  placeholder="请输入账号"
               />
             </el-form-item>
           </el-col>
             <el-col :span="11">
-            <el-form-item label="用户昵称" prop="nickName">
-              <el-input v-model="formData.nickName" placeholder="请输入用户昵称" />
+            <el-form-item label="姓名" prop="nickName">
+              <el-input v-model="formData.nickName" placeholder="请输入姓名" />
             </el-form-item>
           </el-col>
         </el-row>
 
         <el-row :gutter="22">
           <el-col :span="11">
-            <el-form-item label="员工编号" prop="employeeCode">
+            <el-form-item label="工作证号" prop="employeeCode">
               <el-input
                   v-model="formData.employeeCode"
-                  placeholder="请输入员工编号"
+                  placeholder="请输入工作证号"
               />
             </el-form-item>
           </el-col>
@@ -440,9 +440,9 @@ const importData = reactive({
 
 // 校验规则
 const rules = reactive({
-  userName: [{ required: true, message: "用户名不能为空", trigger: "blur" }],
-  nickName: [{ required: true, message: "用户昵称不能为空", trigger: "blur" }],
-  employeeCode: [{ required: true, message: "员工编号不能为空", trigger: "blur" }],
+  userName: [{ required: true, message: "账号不能为空", trigger: "blur" }],
+  nickName: [{ required: true, message: "姓名不能为空", trigger: "blur" }],
+  employeeCode: [{ required: true, message: "工作证号不能为空", trigger: "blur" }],
   deptIds: [{ required: true, message: "所属部门不能为空", trigger: "blur" }],
   roleIds: [{ required: true, message: "用户角色不能为空", trigger: "blur" }],
   postIds: [{ required: true, message: "用户岗位不能为空", trigger: "blur" }],

+ 2 - 1
vite.config.ts

@@ -10,7 +10,7 @@ import IconsResolver from "unplugin-icons/resolver";
 
 import { createSvgIconsPlugin } from "vite-plugin-svg-icons";
 import mockDevServerPlugin from "vite-plugin-mock-dev-server";
-
+// import ElementPlus from "unplugin-element-plus/vite";
 import UnoCSS from "unocss/vite";
 import { resolve } from "path";
 import {
@@ -70,6 +70,7 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
     },
     plugins: [
       vue(),
+      // ElementPlus(),
       // jsx、tsx语法支持
       vueJsx(),
       // MOCK 服务