wangxinhui
昨天 a8756c3526832332db4ef5685348d9b188c2bf2b
Merge branch 'master' of http://115.159.85.185:8098/r/MeiRuiAn/HuaiAn

# Conflicts:
# 代码管理/WMS/WIDESEA_WMSServer/WIDESEA_OutboundService/ProOutOrderService.cs
已修改40个文件
已添加16个文件
4400 ■■■■■ 文件已修改
代码管理/WCS/WIDESEAWCS_Client/public/index.html 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/public/webconfig.js 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/img/1.png 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/store/index.js 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/views/Home.vue 143 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/views/Index.vue 297 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/AuxiliaryWarehouse.vue 257 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/BoardWarehouse.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/DryFilmWarehouse.vue 464 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/InkWarehouse.vue 343 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/PpWarehouse.vue 503 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/SolderMaskWarehouse.vue 430 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/TestFrameWarehouse.vue 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/QuartzJob/DeviceProtocolController.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/PP仓/ConveyorLineJob_PP.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/PP仓/PPReadData.cs 234 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/PP仓/StackerCraneJob_PP.cs 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/PP仓/TSJConveyorLineJob_PP.cs 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/UpdateExpirationlabelJob.cs 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/干膜仓/ConveyorLineJob_GM.cs 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/干膜仓/GMReadData.cs 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/干膜仓/StackerCraneJob_GM.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/油墨仓/CommonHoisterJob.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/油墨仓/StackerCraneJob_YM.cs 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/油墨仓/YMReadData.cs 106 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/辅料仓/ConveyorLineJob_FL.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/辅料仓/FLReadData.cs 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/阻焊仓/GroundStationJob_ZH.cs 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/阻焊仓/StackerCraneJob_ZH.cs 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/阻焊仓/ZHReadData.cs 174 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/AddErpProScrapSheet.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/stock/ProStockView.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/stock/stockView.js 110 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/extension/taskinfo/task.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/outbound/outStockLockInfo.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/stock/ProStockView.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/stock/stockInfoDetail.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/ExpirationlabelEnum.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Helper/UtilConvert.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Core/Utilities/EntityProperties.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Stock/StockViewDTO.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundLockInfo.cs 21 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Stock/Dt_StockInfo.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/TaskInfo/Dt_Task.cs 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/ProStockViewService.cs 95 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs 76 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockViewService.cs 243 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_DictionaryService.cs 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Completed.cs 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
代码管理/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/public/index.html
@@ -9,6 +9,7 @@
  <meta name="description" content="" />
  <link rel="icon" href="<%= BASE_URL %>wcslogo.png">
  <title><%= htmlWebpackPlugin.options.title %></title>
  <script src="webconfig.js"></script>
</head>
<body>
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/public/webconfig.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,6 @@
window.webConfig = {
    "webApiDevelopment": "http://localhost:9291/",
    "webApiProduction": "http://localhost:9291/",
    "webApiDebug": "http://localhost:9291/",
    "webSocketUrl": "ws://localhost:9260/",
}
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/img/1.png
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/store/index.js
@@ -38,7 +38,16 @@
    },
    updateLoadingState(state, flag) {
      state.isLoading = flag
    },
    uphomedata(state, data) {
      // console.log('123',data);
      state.homedata = data;
      // console.log('12state.homedata3',state.homedata);
    }
  }, getters: {
    getPermission: (state) => (path) => {  //调用方式 store.getters.getPermission('sys_User')
      if (!path) return state.permission;
@@ -85,6 +94,10 @@
    },
    onLoading(context, flag) {
      context.commit("updateLoadingState", flag);
    },
    sethomedata(context, data) {
      context.commit("uphomedata", data);
    }
  }
})
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/views/Home.vue
@@ -1,24 +1,145 @@
<template>
  <div class="title"></div>
  <div class="warehouse-dashboard">
    <!-- å¯¼èˆªæ  -->
    <nav class="navbar">
      <div class="nav-container">
        <h1 class="logo">仓库调度系统</h1>
        <ul class="nav-links">
          <li
            v-for="(warehouse, index) in warehouses"
            :key="index"
            :class="{ active: activeWarehouse === index }"
            @click="switchWarehouse(index)"
          >
            {{ warehouse.name }}
          </li>
        </ul>
      </div>
    </nav>
    <!-- ä¸»å†…容区 - åŠ¨æ€æ¸²æŸ“é€‰ä¸­çš„ä»“åº“é¡µé¢ -->
    <main class="content-area">
      <component :is="currentComponent" class="warehouse-content"></component>
    </main>
  </div>
</template>
<script>
import { ref, reactive } from 'vue'
import { ref, computed } from 'vue';
// å¯¼å…¥å„个仓库的组件
import BoardWarehouse from './deviceMonitoring/BoardWarehouse.vue';
import TestFrameWarehouse from './deviceMonitoring/TestFrameWarehouse.vue';
import SolderMaskWarehouse from './deviceMonitoring/SolderMaskWarehouse.vue';
import PpWarehouse from './deviceMonitoring/PpWarehouse.vue';
import InkWarehouse from './deviceMonitoring/InkWarehouse.vue';
import AuxiliaryWarehouse from './deviceMonitoring/AuxiliaryWarehouse.vue';
import DryFilmWarehouse from './deviceMonitoring/DryFilmWarehouse.vue';
export default {
  setup() {
    return {
    // å®šä¹‰ä»“库列表
    const warehouses = [
      { name: '板材仓', component: BoardWarehouse },
      { name: '测试架仓', component: TestFrameWarehouse },
      { name: '阻焊仓', component: SolderMaskWarehouse },
      { name: 'PP仓', component: PpWarehouse },
      { name: '油墨仓', component: InkWarehouse },
      { name: '辅料仓', component: AuxiliaryWarehouse },
      { name: '成品仓', component: BoardWarehouse },
      { name: '干膜仓', component: DryFilmWarehouse},
    ];
    }
    // å½“前选中的仓库索引
    const activeWarehouse = ref(0);
    // åˆ‡æ¢ä»“库
    const switchWarehouse = (index) => {
      activeWarehouse.value = index;
    };
    // æ ¹æ®é€‰ä¸­çš„仓库获取当前要渲染的组件
    const currentComponent = computed(() => {
      return warehouses[activeWarehouse.value].component;
    });
    return {
      warehouses,
      activeWarehouse,
      switchWarehouse,
      currentComponent
    };
  }
}
};
</script>
<style scoped>
.title {
  line-height: 70vh;
  text-align: center;
  font-size: 28px;
  color: orange;
.warehouse-dashboard {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
}
</style>
.navbar {
  background-color: #2c3e50;
  color: white;
  padding: 0 20px;
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.nav-container {
  max-width: 1200px;
  margin: 0 auto;
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 60px;
}
.logo {
  margin: 0;
  font-size: 1.5rem;
  font-weight: 600;
}
.nav-links {
  display: flex;
  list-style: none;
  margin: 0;
  padding: 0;
  gap: 1px;
}
.nav-links li {
  padding: 0 15px;
  height: 60px;
  display: flex;
  align-items: center;
  cursor: pointer;
  transition: all 0.3s ease;
  background-color: #34495e;
}
.nav-links li:hover {
  background-color: #3d5a7c;
}
.nav-links li.active {
  background-color: #3498db;
  font-weight: 500;
  box-shadow: inset 0 -3px 0 #2980b9;
}
.content-area {
  flex: 1;
  padding: 20px;
  background-color: #f5f7fa;
}
.warehouse-content {
  background-color: white;
  border-radius: 8px;
  padding: 20px;
  min-height: calc(100vh - 100px);
  box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
}
</style>
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/views/Index.vue
@@ -3,20 +3,30 @@
    <div class="vol-aside" :style="{ width: menuWidth + 'px' }">
      <div class="header" :style="{ width: menuWidth - 1 + 'px' }">
        <img v-show="!isCollapse" v-bind:src="logo" />
        <i @click="toggleLeft" class="el-icon-s-fold collapse-menu" />
        <i
          @click="toggleLeft"
          class="collapse-menu"
          :class="isCollapse ? 'el-icon-s-unfold' : 'el-icon-s-fold'"
        />
      </div>
      <div class="vol-menu">
        <el-scrollbar style="height: 100%">
          <VolMenu :currentMenuId="currentMenuId" :on-select="onSelect" :enable="true" :open-select="false"
            :isCollapse="isCollapse" :list="menuOptions"></VolMenu>
          <VolMenu
            :currentMenuId="currentMenuId"
            :on-select="onSelect"
            :enable="true"
            :open-select="false"
            :isCollapse="isCollapse"
            :list="menuOptions"
          ></VolMenu>
        </el-scrollbar>
      </div>
    </div>
    <div class="vol-container" :style="{ left: menuWidth - 1 + 'px' }">
      <div class="vol-header">
        <div class="project-name">WCS</div>
        <div class="project-name">WMS</div>
        <div class="header-text">
          <!-- <div class="h-link">
          <div class="h-link">
            <a
              href="javascript:void(0)"
              @click="to(item)"
@@ -25,19 +35,38 @@
              })"
              :key="index"
            >
              <span v-if="!item.icon"> {{ item.text }}</span>
              <span v-if="!item.icon">{{ item.text }}</span>
              <i v-else :class="item.icon"></i>
            </a>
          </div> -->
          </div>
        </div>
        <div class="header-info">
          <div class="h-link">
            <a href="javascript:void(0)" @click="to(item)" v-for="(item, index) in links.filter((c) => {
              return c.icon;
            })" :key="index">
              <span> {{ item.text }}</span>
            <a
              href="javascript:void(0)"
              @click="to(item)"
              v-for="(item, index) in links.filter((c) => {
                return c.icon;
              })"
              :key="index"
            >
              <span v-if="!item.icon">{{ item.text }}</span>
              <i v-else :class="item.icon"></i>
            </a>
          </div>
          <!--消息管理-->
          <div class="h-link" @click="messageModel = true">
            <a>
              <i class="el-icon-message-solid">
                <el-badge
                  :value="messageList.length"
                  :type="messageList.length > 0 ? 'danger' : 'success'"
                  class="item"
                  style="width: 10px"
                ></el-badge>
              </i>
            </a>
          </div>
          <div>
            <img class="user-header" :src="userImg" :onerror="errorImg" />
@@ -52,10 +81,23 @@
        </div>
      </div>
      <div class="vol-path">
        <el-tabs @tab-click="selectNav" @tab-remove="removeNav" @contextmenu.prevent="bindRightClickMenu(false)"
          type="border-card" class="header-navigation" v-model="selectId" :strtch="false">
          <el-tab-pane v-for="(item, navIndex) in navigation" type="card" :name="navIndex + ''" :closable="navIndex > 0"
            :key="navIndex" :label="item.name">
        <el-tabs
          @tab-click="selectNav"
          @tab-remove="removeNav"
          @contextmenu.prevent="bindRightClickMenu(false)"
          type="border-card"
          class="header-navigation"
          v-model="selectId"
          :strtch="false"
        >
          <el-tab-pane
            v-for="(item, navIndex) in navigation"
            type="card"
            :name="navIndex + ''"
            :closable="navIndex > 0"
            :key="navIndex"
            :label="item.name"
          >
            <span style="display: none">{{ navIndex }}</span>
          </el-tab-pane>
        </el-tabs>
@@ -66,18 +108,23 @@
              <el-button link @click="closeTabs()">
                <i class="el-icon-close"></i>
                {{
                  navigation.length == 2 ? "关闭菜单" : "关闭所有"
                }}</el-button>
                navigation.length == 2 ? "关闭菜单" : "关闭所有"
                }}
              </el-button>
            </li>
            <li v-show="visibleItem.left">
              <el-button link @click="closeTabs('left')"><i class="el-icon-back"></i>关闭左边</el-button>
              <el-button link @click="closeTabs('left')">
                <i class="el-icon-back"></i>关闭左边
              </el-button>
            </li>
            <li v-show="visibleItem.right">
              <el-button link @click="closeTabs('right')">
                <i class="el-icon-right"></i>关闭右边</el-button>
                <i class="el-icon-right"></i>关闭右边
              </el-button>
            </li>
            <li v-show="visibleItem.other">
              <el-button link @click="closeTabs('other')"><i class="el-icon-right"></i>关闭其他
              <el-button link @click="closeTabs('other')">
                <i class="el-icon-right"></i>关闭其他
              </el-button>
            </li>
          </ul>
@@ -88,26 +135,45 @@
          <loading v-show="$store.getters.isLoading()"></loading>
          <router-view v-slot="{ Component }">
            <keep-alive>
              <component :is="Component" :key="$route.name"
                v-if="!$route.meta || ($route.meta && !$route.meta.hasOwnProperty('keepAlive'))" />
              <component
                :is="Component"
                :key="$route.name"
                v-if="
                  !$route.meta ||
                  ($route.meta && !$route.meta.hasOwnProperty('keepAlive'))
                "
              />
            </keep-alive>
            <component :is="Component" :key="$route.name" v-if="$route.meta && $route.meta.hasOwnProperty('keepAlive')" />
            <component
              :is="Component"
              :key="$route.name"
              v-if="$route.meta && $route.meta.hasOwnProperty('keepAlive')"
            />
          </router-view>
        </el-scrollbar>
      </div>
    </div>
    <el-drawer title="选择主题" v-model="drawer_model" direction="rtl" destroy-on-close>
      <div class="theme-selector">
        <div @click="changeTheme(item.name)" class="item" v-for="(item, index) in theme_color" :key="index"
          :style="{ background: item.color }">
          <div v-show="item.leftColor" :style="{ background: item.leftColor }" style="height: 100%; width: 20px"
            class="t-left"></div>
        <div
          @click="changeTheme(item.name)"
          class="item"
          v-for="(item, index) in theme_color"
          :key="index"
          :style="{ background: item.color }"
        >
          <div
            v-show="item.leftColor"
            :style="{ background: item.leftColor }"
            style="height: 100%; width: 20px"
            class="t-left"
          ></div>
          <div class="t-right"></div>
        </div>
      </div>
    </el-drawer>
    <el-drawer title="消息列表" v-model="messageModel" direction="rtl" destroy-on-close>
    <el-drawer title="消息列表" v-model="messageModel" direction="rtl" destroy-on-close size="40%">
      <Message :list="messageList"></Message>
    </el-drawer>
  </div>
@@ -131,15 +197,19 @@
  watch,
  onMounted,
  getCurrentInstance,
  h
} from "vue";
import { useRouter, useRoute } from "vue-router";
import store from "../store/index";
import http from "@/../src/api/http.js";
import { ElNotification } from "element-plus";
import { useStore } from "vuex";
export default defineComponent({
  components: {
    VolMenu,
    loading,
    Message,
    Message
  },
  data() {
@@ -149,11 +219,14 @@
      rightTabs: true,
      otherTabs: true,
      menuLeft: 0,
      menuTop: 0,
      menuTop: 0
      //  contextMenuVisible: false, // å³é”®å…³é—­æ˜¾/隐
    };
  },
  setup(props, context) {
    let client = ref(null);
    // èŽ·å–å…¨å±€å±žæ€§å’Œæ–¹æ³•
    const { proxy } = getCurrentInstance();
@@ -173,31 +246,16 @@
      { name: "orange2", color: "#ff9900", leftColor: "rgb(232 141 5)" },
      { name: "green", color: "rgb(25, 190, 107)" },
      { name: "green2", color: "rgb(25, 190, 107)", leftColor: "#019e4f" },
      { name: "white", color: "#fff" },
      { name: "white", color: "#fff" }
    ]);
    const links = ref([
      // {
      //   text: "框架视频",
      //   path: "https://www.cctalk.com/m/group/90268531",
      //   id: -3,
      // },
      // { text: "大屏数据", path: "/bigdata", id: -3 },
      // {
      //   text: "框架文档",
      //   path: "http://v2.volcore.xyz/document/guide",
      //   id: -2,
      // },   {
      //   text: "框架企业版",
      //   path: "http://pro.volcore.xyz/",
      //   id: 10,
      // },
      { text: "个人中心", path: "/UserInfo", id: -1, icon: "el-icon-s-custom" },
      {
        text: "安全退出",
        path: "/login",
        id: -4,
        icon: "el-icon-switch-button",
      },
        icon: "el-icon-switch-button"
      }
    ]);
    const errorImg = ref(
      'this.src="' + require("@/assets/imgs/error-img.png") + '"'
@@ -208,16 +266,17 @@
    //2022.05.29增加tab选项与菜单联动功能
    const currentMenuId = ref(0);
    const userName = ref("--");
    const userTrueName = ref("--");
    const userInfo = ref({});
    const visibleItem = reactive({
      left: false,
      right: false,
      all: false,
      other: false,
      other: false
    });
    const userImg = ref("");
    const navigation = reactive([
      { orderNo: "0", id: "1", name: "首页", path: "/home" },
      { orderNo: "0", id: "1", name: "首页", path: "/home" }
    ]);
    const logo = ref(imgUrl);
    const theme = ref("blue2");
@@ -237,23 +296,77 @@
      },
      hide() {
        toggleLeft();
      },
      }
    };
    const changeTheme = (name) => {
    const Store = useStore();
    const s = ref(null);
    const handleMessage = e => {
      if (e) {
        s.value = e.data;
        console.log("WebSocket æ”¶åˆ°æ¶ˆæ¯: ", e.data);
        store.dispatch("sethomedata", s.value);
        let data = JSON.parse(e.data);
        messageList.push(data);
        ElNotification({
          title: data.title,
          message: h("i", { style: "color: teal" }, data.message),
          position: "bottom-right"
        });
      }
    };
    const createSocket = url => {
      //console.log(url);
      //创建WebSocket连接
      //"ws://127.0.0.1:9295/admin"
      //client = new WebSocket("ws://192.168.0.250:9260/");
      client = new WebSocket("ws:localhost:9260/");
      client.onopen = function() {
        //client.onmessage = handleMessage;
        // store.commit("setWebsocket", client);
        console.log("WebSocket è¿žæŽ¥æˆåŠŸ");
      };
      client.onmessage = function(event) {
        // console.log("WebSocket æ”¶åˆ°æ¶ˆæ¯: ", event);
        if (event != undefined) {
          store.dispatch("sethomedata", JSON.parse(event.data));
        }
        // handleMessage(event);
      };
      client.onclose = function() {
        console.log("WebSocket è¿žæŽ¥å…³é—­");
        setTimeout(createSocket, 10000);
      };
      client.onerror = function(err) {
        console.log("WebSocket è¿žæŽ¥é”™è¯¯: ", err);
      };
      client.onmessage();
    };
    const changeTheme = name => {
      if (theme.value != name) {
        theme.value = name;
      }
      localStorage.setItem("vol3_theme", name);
    };
    const to = (item) => {
    const to = item => {
      /* 2020.07.31增加手动打开tabs*/
      if (item.path == "#") {
        window.open("https://github.com/cq-panda/Vue.NetCore");
        return;
      }
      if (item.path.indexOf("http") != -1) {
        window.open(item.path);
        return;
      }
      if (typeof item == "string" || item.path == "/login") {
        if (item == "/login" || item.path == "/login") {
          //确认是否退出
          store.commit("clearUserInfo", "");
          window.location.href = "/";
          return;
@@ -266,7 +379,7 @@
    };
    const open = (item, useRoute) => {
      /* 2020.07.31增加手动打开tabs*/
      let _index = navigation.findIndex((x) => {
      let _index = navigation.findIndex(x => {
        return x.path == item.path;
      });
      if (_index == -1) {
@@ -275,7 +388,7 @@
          id: item.id + "",
          name: item.name || item.text || "无标题",
          path: item.path,
          query: item.query, //2021.03.20修复自定义二次打开$tabs时参数丢失的问题
          query: item.query //2021.03.20修复自定义二次打开$tabs时参数丢失的问题
        });
        //新打开的tab移至最后一个选项
        selectId.value = navigation.length - 1 + "";
@@ -290,13 +403,13 @@
      }
      currentMenuId.value = item.id * 1;
      // tab菜单绑定右键事件
      proxy.$nextTick(function (e) {
      proxy.$nextTick(function(e) {
        proxy.bindRightClickMenu(true);
      });
    };
    const close = (path) => {
    const close = path => {
      /* 2020.07.31增加手动打开tabs*/
      let index = navigation.findIndex((x) => {
      let index = navigation.findIndex(x => {
        return x.path == path;
      });
      if (index == -1) {
@@ -304,7 +417,7 @@
      }
      removeNav(index);
    };
    const setItem = (item) => {
    const setItem = item => {
      /* 2020.07.31增加手动打开tabs*/
      localStorage.setItem(
        window.location.origin + "_tabs",
@@ -316,23 +429,23 @@
      let nav = localStorage.getItem(window.location.origin + "_tabs");
      return nav ? JSON.parse(nav) : null;
    };
    const selectNav = (item) => {
    const selectNav = item => {
      //升级element正式版修改
      selectId.value = item.props.name;
      let _path = navigation[item.index].path;
      currentMenuId.value = (
        menuOptions.value.find((c) => {
        menuOptions.value.find(c => {
          return c.path == _path;
        }) || { id: 0 }
      ).id;
      router.push({
        path: navigation[item.index].path,
        query: navigation[item.index].query,
        query: navigation[item.index].query
      });
    };
    const removeNav = (_index) => {
    const removeNav = _index => {
      return new Promise(() => {
        //关闭的当前项,跳转到前一个页面
        if (selectId.value == _index + "") {
@@ -341,7 +454,7 @@
          router.push({
            path: navigation[_index - 1].path,
            //2022.06.27修复tabs二次切换后参数丢失的问题
            query: navigation[_index - 1].query,
            query: navigation[_index - 1].query
          });
          navigation.splice(_index, 1);
          selectId.value = selectId.value - 1 + "";
@@ -352,19 +465,19 @@
        }
        navigation.splice(_index, 1);
        currentMenuId.value = (
          menuOptions.value.find((c) => {
          menuOptions.value.find(c => {
            return c.path == navigation[selectId.value * 1].path;
          }) || { id: 0 }
        ).id;
      });
    };
    const getSelectMenuName = (id) => {
      return menuOptions.value.find(function (x) {
    const getSelectMenuName = id => {
      return menuOptions.value.find(function(x) {
        return x.id == id;
      });
    };
    const onSelect = (treeId) => {
    const onSelect = treeId => {
      /* 2020.07.31增加手动打开tabs*/
      var item = getSelectMenuName(treeId);
      open(item, false);
@@ -374,7 +487,7 @@
     * æ˜¾ç¤ºå³é”®èœå•
     * @param {*} e äº‹ä»¶å¯¹è±¡
     */
    const openTabsMenu = function (e) {
    const openTabsMenu = function(e) {
      e.preventDefault(); // é˜²æ­¢é»˜è®¤èœå•弹出
      let tabId = e.target.id.split("-")[1] * 1;
@@ -417,14 +530,14 @@
    const toHome = () => {
      open({
        text: navigation[0].name,
        path: navigation[0].path,
        path: navigation[0].path
      });
    };
    /**
     * å…³é—­å…¶å®ƒæ ‡ç­¾é¡µ
     * @param {*} par å…³é—­ç±»åž‹(left,right,other)
     */
    const closeTabs = (value) => {
    const closeTabs = value => {
      let _menuId = navigation[selectId.value * 1].id;
      let currnetIndex = selectId.value * 1; // navigation.findIndex(c => { return c.id == selectId.value });
      switch (value) {
@@ -463,7 +576,7 @@
        }
      }
      selectId.value =
        navigation.findIndex((c) => {
        navigation.findIndex(c => {
          return c.id == _menuId;
        }) + "";
      closeTabsMenu();
@@ -493,28 +606,33 @@
      let _userInfo = store.getters.getUserInfo();
      if (_userInfo) {
        userName.value = _userInfo.userName;
        userTrueName.value = _userInfo.userTrueName;
        if (_userInfo.img) {
          userImg.value = _config.base.getImgSrc(_userInfo.img, http.ipAddress);
        }
      }
      createSocket(window.webConfig.webSocketUrl);
      Object.assign(_config.$tabs, { open: open, close: close });
      http.get("api/Sys_Menu/getTreeMenu", {}, true).then((data) => {
      http.get("api/Sys_Menu/getTreeMenu", {}, true).then(data => {
        data.push({ id: "1", name: "首页", url: "/home" }); // ä¸ºäº†èŽ·å–é€‰ä¸­id使用
        data.forEach((d) => {
        data.forEach(d => {
          d.path = (d.url || "").replace("/Manager", "");
          d.to = (d.url || "").replace("/Manager", "");
          if (!d.icon || d.icon.substring(0, 3) != "el-") {
            d.icon = "el-icon-menu";
          }
        });
        store.dispatch("setPermission", data);
        menuOptions.value = data;
        permissionInited.value = true;
        //开启消息推送(main.js中设置是否开启signalR)2022.05.05
        if (_config.$global.signalR) {
          MessageConfig(http, (result) => {
          MessageConfig(http, result => {
            messageList.unshift(result);
            //    console.log(result)
          });
@@ -523,12 +641,12 @@
        //当前刷新是不是首页
        if (router.currentRoute.value.path != navigation[0].path) {
          //查找系统菜单
          let item = menuOptions.value.find((x) => {
          let item = menuOptions.value.find(x => {
            return x.path == router.currentRoute.value.path; //this.$route.path;
          });
          if (item) return onSelect(item.id);
          //查找顶部快捷连接
          item = links.value.find((x) => {
          item = links.value.find(x => {
            return x.path == router.currentRoute.value.path; //this.$route.path;
          });
          //查找最后一次跳转的页面
@@ -551,6 +669,7 @@
      errorImg,
      userInfo,
      userName,
      userTrueName,
      userImg,
      selectId,
      selectMenuIndex,
@@ -574,7 +693,7 @@
      visibleItem,
      closeTabsMenu,
      closeTabs,
      currentMenuId,
      currentMenuId
    };
  },
  /**
@@ -584,7 +703,7 @@
    let _date = showTime();
    $indexDate = document.getElementById("index-date");
    $indexDate.innerText = _date;
    $interval = setInterval(function () {
    $interval = setInterval(function() {
      $indexDate.innerText = showTime();
    }, 1000);
@@ -610,7 +729,7 @@
          item.oncontextmenu = that.openTabsMenu;
        });
      });
    },
    }
  },
  /**
@@ -619,7 +738,7 @@
  destroyed() {
    $this = null;
    clearInterval($interval);
  },
  }
});
const week = new Array(
  "星期一",
@@ -663,6 +782,11 @@
  padding: 0;
}
.item {
  margin-top: -20px;
  margin-right: 40px;
}
.contextMenu {
  width: 120px;
  margin: 0;
@@ -676,7 +800,6 @@
  font-size: 14px;
  color: #333;
  box-shadow: 2px 2px 3px 0 rgb(182 182 182 / 20%);
  i,
  button {
    font-size: 14px !important;
@@ -699,8 +822,12 @@
  letter-spacing: 1px;
}
.el-tabs.el-tabs--top.el-tabs--border-card.header-navigation>.el-tabs__header .el-tabs__item:last-child,
.el-tabs--top.el-tabs--border-card.header-navigation>.el-tabs__header .el-tabs__item:nth-child(2) {
.el-tabs.el-tabs--top.el-tabs--border-card.header-navigation
  > .el-tabs__header
  .el-tabs__item:last-child,
.el-tabs--top.el-tabs--border-card.header-navigation
  > .el-tabs__header
  .el-tabs__item:nth-child(2) {
  padding: 0;
}
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/AuxiliaryWarehouse.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,257 @@
<template>
  <div id="title">
    <div id="bkuang" style="border-top: none">
      <div class="skuang">
        <div class="zhuname">入库8005站台</div>
        <div class="zhankuang">
          <div class="xname">放货完成(写):</div>
          <div class="xzhi" :title="data.W_PutFinish5">{{ data.W_PutFinish5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">入库到位指令(读):</div>
          <div class="xzhi" :title="data.R_ConveyArrivaled5">{{ data.R_ConveyArrivaled5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">到位托盘号(读):</div>
          <div class="xzhi" :title="data.R_Barcode5">{{ data.R_Barcode5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">到位任务号(读):</div>
          <div class="xzhi" :title="data.R_TaskNum5">{{ data.R_TaskNum5 }}</div>
        </div>
      </div>
      <div class="skuang">
        <div class="zhuname">出库8001站台</div>
        <div class="zhankuang">
          <div class="xname">放货完成(写):</div>
          <div class="xzhi" :title="data.W_PutFinish1">{{ data.W_PutFinish1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否允许放货(读):</div>
          <div class="xzhi" :title="data.R_IsCanPut">{{ data.R_IsCanPut }}</div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { ref, nextTick } from "vue";
import { useStore } from "vuex";
import { onMounted } from "vue";
export default {
  data() {
    return {
      xuan: 0
    };
  },
  methods: {
  },
  setup() {
    const store = useStore();
    const data = ref({});
    // 1. å®šä¹‰æ™®é€šå­—段的映射规则
    const statusMap = {
    };
    // 2. å®šä¹‰éœ€è¦å…±ç”¨æ˜ å°„规则的字段列表和对应的映射规则
    const booleanFields = [
      "W_PutFinish5", "W_PutFinish1",
      "R_IsCanPut", "R_ConveyArrivaled5",
    ];
    const booleanMap = {
      true: "是",
      false: "否"
    };
    // å¤„理数据,先处理普通映射,再批量处理共用映射的字段
    const processData = (rawData) => {
      if (!rawData) return {};
      const processed = { ...rawData };
      // å¤„理普通字段映射
      Object.keys(statusMap).forEach(key => {
        if (processed.hasOwnProperty(key)) {
          const map = statusMap[key];
          processed[key] = map[processed[key]] || processed[key];
        }
      });
      // æ‰¹é‡å¤„理共用映射规则的字段
      booleanFields.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = booleanMap[processed[key]] || processed[key];
        }
      });
      return processed;
    };
    onMounted(() => {
      nextTick(() => {
        setInterval(() => {
          const rawData = store.state.homedata;
          data.value = processData(rawData);
          const xian = document.getElementsByClassName("xzhi");
          for (let i = 0; i < xian.length; i++) {
            if (xian[i].innerHTML === "是") {
              xian[i].style.color = "yellow";
            } else if (xian[i].innerHTML === "否") {
              xian[i].style.color = "red";
            }
          }
        });
      });
    });
    return {
      data,
    };
  }
};
</script>
<style scoped>
.ding {
  float: left;
  width: 20px;
  height: 20px;
  margin-top: 7px;
}
.yan {
  color: white;
  float: left;
  font-size: 25px;
}
.dakuang {
  width: 250px;
  height: 50px;
  position: absolute;
  top: 150px;
  left: 200px;
}
#xiugai {
  width: 100px;
  height: 30px;
  float: left;
  border-radius: 5px;
  text-align: center;
  line-height: 30px;
  cursor: pointer;
  border: 1px solid white;
  color: white;
  background: rgba(255, 255, 255, 0.5);
  font-size: 25px;
  position: absolute;
  top: 150px;
  left: 450px;
}
#xiugai:hover {
  background: #f60;
}
#shu1,
#shu2 {
  width: 200px;
  height: 30px;
  float: left;
  margin-top: 0px;
  margin-right: 0px;
  border-radius: 5px;
  border: 1px solid white;
}
#guan {
  width: 40px;
  height: 40px;
  float: left;
  font-size: 1.1cqw;
  text-align: center;
  line-height: 40px;
  cursor: pointer;
  margin-left: 560px;
  color: white;
  position: absolute;
}
#ti {
  width: 600px;
  height: 300px;
  position: relative;
  background: rgba(255, 255, 255, 1);
  border-radius: 10px;
  top: 230px;
  left: 35%;
  display: none;
  background-image: url("../../img/1.png");
  background-repeat: no-repeat;
  background-size: 170%;
  background-position: -220px 0px;
}
.zhuname {
  width: 100%;
  height: 5vh;
  float: left;
  text-align: center;
  line-height: 50px;
  font-weight: 700;
  font-size: 1.1cqw;
  color: white;
}
.xname {
  width: 70%;
  height: 80px;
  float: left;
  line-height: 7vh;
  font-size: 1.1cqw;
  color: white;
}
.xzhi {
  width: 30%;
  height: 7vh;
  float: left;
  line-height: 50px;
  font-size: 1.1cqw;
  color: rgb(242, 242, 50);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.zhankuang {
  width: 45%;
  height: 3vh;
  margin-top: 10px;
  margin-left: 5%;
  float: left;
}
#title {
  float: left;
  width: 95%;
  height: 88vh;
  margin-top: 40px;
  margin-left: 3%;
  background-image: url("../../img/1.png");
  background-repeat: no-repeat;
  background-size: 100%;
  container-type: inline-size;
}
#bkuang {
  width: 100%;
  height: 55vh;
  float: left;
}
.skuang {
  width: 31%;
  height: 55vh;
  float: left;
  border-top: none;
  border-left: none;
  border-bottom: none;
  background: rgba(255, 255, 255, 0.2);
  margin-left: 1.7%;
  border-radius: 10px;
}
</style>
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/BoardWarehouse.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
<template>
  <div class="message-container">
    <div class="item" v-for="(item, index) in list" :key="index">
      <div class="title">{{ item.title }}({{ item.date }})</div>
      <div class="content">{{ item.message }}</div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    list: {
      type: Array,
      default: () => {
        return [];
      }
    }
  },
  created() {
    if (!this.list.length) {
      this.list.push({
        title: '消息测试标qweqweqweqw题',
        message: '消息测试内容消息测试内容消息测试内容消息测试内容',
        date: '2022-05-02 03:10'
      });
    }
  }
};
</script>
<style scoped lang="less">
.message-container {
  .title {
    padding-bottom: 10px;
  }
  .item {
    border-bottom: 1px solid #eee;
    padding: 10px 20px;
  }
  .content {
    color: #7e7e7e;
    font-size: 13px;
  }
}
</style>
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/DryFilmWarehouse.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,464 @@
<template>
  <div id="title">
    <div id="bkuang" style="border-top: none">
      <div class="skuang">
        <div class="zhuname">干膜仓堆垛机</div>
        <div class="zhankuang">
          <div class="xname">堆垛机状态:</div>
          <div class="xzhi" :title="data.R_GM_Status">{{ data.R_GM_Status }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">堆垛机手自动状态:</div>
          <div class="xzhi" :title="data.R_GM_AutoStatus">{{ data.R_GM_AutoStatus }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">正在执行的任务号:</div>
          <div class="xzhi" :title="data.R_GM_TaskNum">{{ data.R_GM_TaskNum }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">堆垛机工作状态:</div>
          <div class="xzhi" :title="data.R_GM_WorkStatus">{{ data.R_GM_WorkStatus }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">作业类型:</div>
          <div class="xzhi" :title="data.R_GM_WorkType">{{ data.R_GM_WorkType }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">托盘类型:</div>
          <div class="xzhi" :title="data.R_GM_TrayType">{{ data.R_GM_TrayType }}</div>
        </div>
      </div>
      <div class="skuang">
        <div class="zhuname">入库7003站台</div>
        <div class="zhankuang">
          <div class="xname">读取箱体码(读):</div>
          <div class="xzhi" :title="data.R_GM_Boxcode">{{ data.R_GM_Boxcode }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">握手信号(读):</div>
          <div class="xzhi" :title="data.R_GM_HandShake3">{{ data.R_GM_HandShake3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否联机(读):</div>
          <div class="xzhi" :title="data.R_GM_Online3">{{ data.R_GM_Online3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否空闲(读):</div>
          <div class="xzhi" :title="data.R_GM_Free3">{{ data.R_GM_Free3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否有货(读):</div>
          <div class="xzhi" :title="data.R_GM_Goods3">{{ data.R_GM_Goods3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否故障(读):</div>
          <div class="xzhi" :title="data.R_GM_Alarm3">{{ data.R_GM_Alarm3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(读):</div>
          <div class="xzhi" :title="data.R_GM_STB3">{{ data.R_GM_STB3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(读):</div>
          <div class="xzhi" :title="data.R_GM_ACK3">{{ data.R_GM_ACK3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(写):</div>
          <div class="xzhi" :title="data.W_GM_STB3">{{ data.W_GM_STB3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(写):</div>
          <div class="xzhi" :title="data.W_GM_ACK3">{{ data.W_GM_ACK3 }}</div>
        </div>
      </div>
      <div class="skuang">
        <div class="zhuname">出库终点7004站台</div>
        <div class="zhankuang">
          <div class="xname">握手信号(读):</div>
          <div class="xzhi" :title="data.R_GM_HandShake4">{{ data.R_GM_HandShake4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否联机(读):</div>
          <div class="xzhi" :title="data.R_GM_Online4">{{ data.R_GM_Online4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否空闲(读):</div>
          <div class="xzhi" :title="data.R_GM_Free4">{{ data.R_GM_Free4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否有货(读):</div>
          <div class="xzhi" :title="data.R_GM_Goods4">{{ data.R_GM_Goods4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否故障(读):</div>
          <div class="xzhi" :title="data.R_GM_Alarm4">{{ data.R_GM_Alarm4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(读):</div>
          <div class="xzhi" :title="data.R_GM_STB4">{{ data.R_GM_STB4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(读):</div>
          <div class="xzhi" :title="data.R_GM_ACK4">{{ data.R_GM_ACK4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(写):</div>
          <div class="xzhi" :title="data.W_GM_STB4">{{ data.W_GM_STB4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(写):</div>
          <div class="xzhi" :title="data.W_GM_ACK4">{{ data.W_GM_ACK4 }}</div>
        </div>
        <div class="zhuname">出库7005站台</div>
        <div class="zhankuang">
          <div class="xname">握手信号(读):</div>
          <div class="xzhi" :title="data.R_GM_HandShake5">{{ data.R_GM_HandShake5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否联机(读):</div>
          <div class="xzhi" :title="data.R_GM_Online5">{{ data.R_GM_Online5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否空闲(读):</div>
          <div class="xzhi" :title="data.R_GM_Free5">{{ data.R_GM_Free5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否有货(读):</div>
          <div class="xzhi" :title="data.R_GM_Goods5">{{ data.R_GM_Goods5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否故障(读):</div>
          <div class="xzhi" :title="data.R_GM_Alarm5">{{ data.R_GM_Alarm5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(读):</div>
          <div class="xzhi" :title="data.R_GM_STB5">{{ data.R_GM_STB5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(读):</div>
          <div class="xzhi" :title="data.R_GM_ACK5">{{ data.R_GM_ACK5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(写):</div>
          <div class="xzhi" :title="data.W_GM_STB5">{{ data.W_GM_STB5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(写):</div>
          <div class="xzhi" :title="data.W_GM_ACK5">{{ data.W_GM_ACK5 }}</div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { ref, nextTick } from "vue";
import { useStore } from "vuex";
import { onMounted } from "vue";
export default {
  data() {
    return {
      xuan: 0
    };
  },
  methods: {
  },
  setup() {
    const store = useStore();
    const data = ref({});
    // 1. å®šä¹‰æ™®é€šå­—段的映射规则
    const statusMap = {
      R_GM_Status: {
        1: "正常",
        2: "故障",
        3: "急停",
      },
      R_GM_AutoStatus: {
        0: "ç»´ä¿®",
        1: "手动",
        2: "半自动",
        3: "自动",
      },
      R_GM_WorkStatus: {
        0: "待机",
        1: "取货中",
        2: "取货完成",
        4: "放货中",
        5: "放货完成",
        6: "任务完成",
      },
      R_GM_WorkType: {
        0: "无作业任务(0)",
        1: "取放货作业(1)",
        2: "只取货作业(2)",
        3: "只放货作业(3)",
        4: "移动到指定位置"
      },
      R_GM_TrayType: {
        "-1": "空箱(-1)",
        1: "小托盘(1)",
        2: "中托盘(2)",
        3: "大托盘(3)",
        4: "特大托盘(4)",
      }
    };
    const onlines = [
        "R_GM_Online3","R_GM_Online4",
        "R_GM_Online5",
    ]
    const online = {
      1: "联机",
      0: "脱机"
    };
    const alarms = [
        "R_GM_Alarm3","R_GM_Alarm4",
        "R_GM_Alarm5",
    ]
    const alarm = {
      1: "故障",
      0: "正常"
    };
    const frees = [
        "R_GM_Free3","R_GM_Free4",
        "R_GM_Free5",
    ]
    const free = {
      1: "空闲",
      0: "繁忙"
    };
    const goods = [
        "R_GM_Goods3", "R_GM_Goods4",
        "R_GM_Goods5",
    ]
    const good = {
      1: "有货",
      0: "无货"
    };
    // 2. å®šä¹‰éœ€è¦å…±ç”¨æ˜ å°„规则的字段列表和对应的映射规则
    const booleanFields = [
      "R_GM_HandShake3",
       "R_GM_STB3",
      "R_GM_ACK3", "W_GM_STB3",
      "W_GM_ACK3",
      "R_GM_HandShake4",
       "R_GM_STB4",
      "R_GM_ACK4", "W_GM_STB4",
      "W_GM_ACK4",
      "R_GM_HandShake5",
       "R_GM_STB5",
      "R_GM_ACK5", "W_GM_STB5",
      "W_GM_ACK5",
    ];
    const booleanMap = {
      true: "是",
      false: "否"
    };
    // å¤„理数据,先处理普通映射,再批量处理共用映射的字段
    const processData = (rawData) => {
      if (!rawData) return {};
      const processed = { ...rawData };
      // å¤„理普通字段映射
      Object.keys(statusMap).forEach(key => {
        if (processed.hasOwnProperty(key)) {
          const map = statusMap[key];
          processed[key] = map[processed[key]] || processed[key];
        }
      });
      // æ‰¹é‡å¤„理共用映射规则的字段
      booleanFields.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = booleanMap[processed[key]] || processed[key];
        }
      });
      onlines.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = online[processed[key]] || processed[key];
        }
      });
      alarms.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = alarm[processed[key]] || processed[key];
        }
      });
      frees.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = free[processed[key]] || processed[key];
        }
      });
      goods.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = good[processed[key]] || processed[key];
        }
      });
      return processed;
    };
    onMounted(() => {
      nextTick(() => {
        setInterval(() => {
          const rawData = store.state.homedata;
          data.value = processData(rawData);
          const xian = document.getElementsByClassName("xzhi");
          for (let i = 0; i < xian.length; i++) {
            if (xian[i].innerHTML === "是" || xian[i].innerHTML === "联机") {
              xian[i].style.color = "yellow";
            } else if (xian[i].innerHTML === "否") {
              xian[i].style.color = "red";
            }
          }
        });
      });
    });
    return {
      data,
    };
  }
};
</script>
<style scoped>
.ding {
  float: left;
  width: 20px;
  height: 20px;
  margin-top: 7px;
}
.yan {
  color: white;
  float: left;
  font-size: 25px;
}
.dakuang {
  width: 250px;
  height: 50px;
  position: absolute;
  top: 150px;
  left: 200px;
}
#xiugai {
  width: 100px;
  height: 30px;
  float: left;
  border-radius: 5px;
  text-align: center;
  line-height: 30px;
  cursor: pointer;
  border: 1px solid white;
  color: white;
  background: rgba(255, 255, 255, 0.5);
  font-size: 25px;
  position: absolute;
  top: 150px;
  left: 450px;
}
#xiugai:hover {
  background: #f60;
}
#shu1,
#shu2 {
  width: 200px;
  height: 30px;
  float: left;
  margin-top: 0px;
  margin-right: 0px;
  border-radius: 5px;
  border: 1px solid white;
}
#guan {
  width: 40px;
  height: 40px;
  float: left;
  font-size: 1.1cqw;
  text-align: center;
  line-height: 40px;
  cursor: pointer;
  margin-left: 560px;
  color: white;
  position: absolute;
}
#ti {
  width: 600px;
  height: 300px;
  position: relative;
  background: rgba(255, 255, 255, 1);
  border-radius: 10px;
  top: 230px;
  left: 35%;
  display: none;
  background-image: url("../../img/1.png");
  background-repeat: no-repeat;
  background-size: 170%;
  background-position: -220px 0px;
}
.zhuname {
  width: 100%;
  height: 5vh;
  float: left;
  text-align: center;
  line-height: 50px;
  font-weight: 700;
  font-size: 1.1cqw;
  color: white;
}
.xname {
  width: 70%;
  height: 80px;
  float: left;
  line-height: 7vh;
  font-size: 1.1cqw;
  color: white;
}
.xzhi {
  width: 30%;
  height: 7vh;
  float: left;
  line-height: 50px;
  font-size: 1.1cqw;
  color: rgb(242, 242, 50);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.zhankuang {
  width: 45%;
  height: 3vh;
  margin-top: 10px;
  margin-left: 5%;
  float: left;
}
#title {
  float: left;
  width: 95%;
  height: 88vh;
  margin-top: 40px;
  margin-left: 3%;
  background-image: url("../../img/1.png");
  background-repeat: no-repeat;
  background-size: 100%;
  container-type: inline-size;
}
#bkuang {
  width: 100%;
  height: 55vh;
  float: left;
}
.skuang {
  width: 31%;
  height: 55vh;
  float: left;
  border-top: none;
  border-left: none;
  border-bottom: none;
  background: rgba(255, 255, 255, 0.2);
  margin-left: 1.7%;
  border-radius: 10px;
}
</style>
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/InkWarehouse.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,343 @@
<template>
  <div id="title">
    <div id="bkuang" style="border-top: none">
      <div class="skuang">
        <div class="zhuname">油墨仓堆垛机</div>
        <div class="zhankuang">
          <div class="xname">堆垛机状态:</div>
          <div class="xzhi" :title="data.R_YM_Status">{{ data.R_YM_Status }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">堆垛机手自动状态:</div>
          <div class="xzhi" :title="data.R_YM_AutoStatus">{{ data.R_YM_AutoStatus }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">正在执行的任务号:</div>
          <div class="xzhi" :title="data.R_YM_TaskNum">{{ data.R_YM_TaskNum }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">堆垛机工作状态:</div>
          <div class="xzhi" :title="data.R_YM_WorkStatus">{{ data.R_YM_WorkStatus }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">作业类型:</div>
          <div class="xzhi" :title="data.R_YM_WorkType">{{ data.R_YM_WorkType }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">托盘类型:</div>
          <div class="xzhi" :title="data.R_YM_TrayType">{{ data.R_YM_TrayType }}</div>
        </div>
      </div>
      <div class="skuang">
        <div class="zhuname">出入库9001站台</div>
        <div class="zhankuang">
          <div class="xname">有货(读):</div>
          <div class="xzhi" :title="data.R_YM_Tray1">{{ data.R_YM_Tray1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">入库执行中(读):</div>
          <div class="xzhi" :title="data.R_YM_Inbounding1">{{ data.R_YM_Inbounding1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">提升机空闲(读):</div>
          <div class="xzhi" :title="data.R_YM_Leisure1">{{ data.R_YM_Leisure1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">出库执行中(读):</div>
          <div class="xzhi" :title="data.R_YM_Outbounding1">{{ data.R_YM_Outbounding1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">申请入库(写):</div>
          <div class="xzhi" :title="data.W_YM_RequestIn1">{{ data.W_YM_RequestIn1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">申请出库(写):</div>
          <div class="xzhi" :title="data.W_YM_RequestOut1">{{ data.W_YM_RequestOut1 }}</div>
        </div>
      </div>
      <div class="skuang">
        <div class="zhuname">出入库9002站台</div>
        <div class="zhankuang">
          <div class="xname">有货(读):</div>
          <div class="xzhi" :title="data.R_YM_Tray2">{{ data.R_YM_Tray2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">入库执行中(读):</div>
          <div class="xzhi" :title="data.R_YM_Inbounding2">{{ data.R_YM_Inbounding2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">提升机空闲(读):</div>
          <div class="xzhi" :title="data.R_YM_Leisure2">{{ data.R_YM_Leisure2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">出库执行中(读):</div>
          <div class="xzhi" :title="data.R_YM_Outbounding2">{{ data.R_YM_Outbounding2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">申请入库(写):</div>
          <div class="xzhi" :title="data.W_YM_RequestIn2">{{ data.W_YM_RequestIn2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">申请出库(写):</div>
          <div class="xzhi" :title="data.W_YM_RequestOut2">{{ data.W_YM_RequestOut2 }}</div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { ref, nextTick } from "vue";
import { useStore } from "vuex";
import { onMounted } from "vue";
export default {
  data() {
    return {
      xuan: 0
    };
  },
  methods: {
  },
  setup() {
    const store = useStore();
    const data = ref({});
    // 1. å®šä¹‰æ™®é€šå­—段的映射规则
    const statusMap = {
      R_YM_Status: {
        1: "正常",
        2: "故障",
        3: "急停",
      },
      R_YM_AutoStatus: {
        0: "ç»´ä¿®",
        1: "手动",
        2: "半自动",
        3: "自动",
      },
      R_YM_WorkStatus: {
        0: "待机",
        1: "取货中",
        2: "取货完成",
        4: "放货中",
        5: "放货完成",
        6: "任务完成",
      },
      R_YM_WorkType: {
        0: "无作业任务(0)",
        1: "取放货作业(1)",
        2: "只取货作业(2)",
        3: "只放货作业(3)",
        4: "移动到指定位置"
      },
      R_YM_TrayType: {
        "-1": "空箱(-1)",
        1: "小托盘(1)",
        2: "中托盘(2)",
        3: "大托盘(3)",
        4: "特大托盘(4)",
      }
    };
    // 2. å®šä¹‰éœ€è¦å…±ç”¨æ˜ å°„规则的字段列表和对应的映射规则
    const booleanFields = [
      "R_YM_Tray1", "R_YM_Inbounding1",
      "R_YM_Leisure1", "R_YM_Outbounding1",
      "W_YM_RequestIn1", "W_YM_RequestOut1",
      "R_YM_Tray2", "R_YM_Inbounding2",
      "R_YM_Leisure2", "R_YM_Outbounding2",
      "W_YM_RequestIn2", "W_YM_RequestOut2",
    ];
    const booleanMap = {
      true: "是",
      false: "否"
    };
    // å¤„理数据,先处理普通映射,再批量处理共用映射的字段
    const processData = (rawData) => {
      if (!rawData) return {};
      const processed = { ...rawData };
      // å¤„理普通字段映射
      Object.keys(statusMap).forEach(key => {
        if (processed.hasOwnProperty(key)) {
          const map = statusMap[key];
          processed[key] = map[processed[key]] || processed[key];
        }
      });
      // æ‰¹é‡å¤„理共用映射规则的字段
      booleanFields.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = booleanMap[processed[key]] || processed[key];
        }
      });
      return processed;
    };
    onMounted(() => {
      nextTick(() => {
        setInterval(() => {
          const rawData = store.state.homedata;
          data.value = processData(rawData);
          const xian = document.getElementsByClassName("xzhi");
          for (let i = 0; i < xian.length; i++) {
            if (xian[i].innerHTML === "是") {
              xian[i].style.color = "yellow";
            } else if (xian[i].innerHTML === "否") {
              xian[i].style.color = "red";
            }
          }
        });
      });
    });
    return {
      data,
    };
  }
};
</script>
<style scoped>
.ding {
  float: left;
  width: 20px;
  height: 20px;
  margin-top: 7px;
}
.yan {
  color: white;
  float: left;
  font-size: 25px;
}
.dakuang {
  width: 250px;
  height: 50px;
  position: absolute;
  top: 150px;
  left: 200px;
}
#xiugai {
  width: 100px;
  height: 30px;
  float: left;
  border-radius: 5px;
  text-align: center;
  line-height: 30px;
  cursor: pointer;
  border: 1px solid white;
  color: white;
  background: rgba(255, 255, 255, 0.5);
  font-size: 25px;
  position: absolute;
  top: 150px;
  left: 450px;
}
#xiugai:hover {
  background: #f60;
}
#shu1,
#shu2 {
  width: 200px;
  height: 30px;
  float: left;
  margin-top: 0px;
  margin-right: 0px;
  border-radius: 5px;
  border: 1px solid white;
}
#guan {
  width: 40px;
  height: 40px;
  float: left;
  font-size: 1.1cqw;
  text-align: center;
  line-height: 40px;
  cursor: pointer;
  margin-left: 560px;
  color: white;
  position: absolute;
}
#ti {
  width: 600px;
  height: 300px;
  position: relative;
  background: rgba(255, 255, 255, 1);
  border-radius: 10px;
  top: 230px;
  left: 35%;
  display: none;
  background-image: url("../../img/1.png");
  background-repeat: no-repeat;
  background-size: 170%;
  background-position: -220px 0px;
}
.zhuname {
  width: 100%;
  height: 5vh;
  float: left;
  text-align: center;
  line-height: 50px;
  font-weight: 700;
  font-size: 1.1cqw;
  color: white;
}
.xname {
  width: 70%;
  height: 80px;
  float: left;
  line-height: 7vh;
  font-size: 1.1cqw;
  color: white;
}
.xzhi {
  width: 30%;
  height: 7vh;
  float: left;
  line-height: 50px;
  font-size: 1.1cqw;
  color: rgb(242, 242, 50);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.zhankuang {
  width: 45%;
  height: 3vh;
  margin-top: 10px;
  margin-left: 5%;
  float: left;
}
#title {
  float: left;
  width: 95%;
  height: 88vh;
  margin-top: 40px;
  margin-left: 3%;
  background-image: url("../../img/1.png");
  background-repeat: no-repeat;
  background-size: 100%;
  container-type: inline-size;
}
#bkuang {
  width: 100%;
  height: 55vh;
  float: left;
}
.skuang {
  width: 31%;
  height: 55vh;
  float: left;
  border-top: none;
  border-left: none;
  border-bottom: none;
  background: rgba(255, 255, 255, 0.2);
  margin-left: 1.7%;
  border-radius: 10px;
}
</style>
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/PpWarehouse.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,503 @@
<template>
  <div id="title">
    <div id="bkuang" style="border-top: none">
      <div class="skuang">
        <div class="zhuname">PP仓堆垛机</div>
        <div class="zhankuang">
          <div class="xname">堆垛机状态:</div>
          <div class="xzhi" :title="data.R_PP_Status">{{ data.R_PP_Status }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">堆垛机手自动状态:</div>
          <div class="xzhi" :title="data.R_PP_AutoStatus">{{ data.R_PP_AutoStatus }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">正在执行的任务号:</div>
          <div class="xzhi" :title="data.R_PP_TaskNum">{{ data.R_PP_TaskNum }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">堆垛机工作状态:</div>
          <div class="xzhi" :title="data.R_PP_WorkStatus">{{ data.R_PP_WorkStatus }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">作业类型:</div>
          <div class="xzhi" :title="data.R_PP_WorkType">{{ data.R_PP_WorkType }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">托盘类型:</div>
          <div class="xzhi" :title="data.R_PP_TrayType">{{ data.R_PP_TrayType }}</div>
        </div>
      </div>
      <div class="skuang">
        <div class="zhuname">入库2004站台</div>
        <div class="zhankuang">
          <div class="xname">读取箱体码(读):</div>
          <div class="xzhi" :title="data.R_PP_Boxcode">{{ data.R_PP_Boxcode }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">握手信号(读):</div>
          <div class="xzhi" :title="data.R_PP_HandShake4">{{ data.R_PP_HandShake4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否联机(读):</div>
          <div class="xzhi" :title="data.R_PP_Online4">{{ data.R_PP_Online4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否空闲(读):</div>
          <div class="xzhi" :title="data.R_PP_Free4">{{ data.R_PP_Free4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否有货(读):</div>
          <div class="xzhi" :title="data.R_PP_Goods4">{{ data.R_PP_Goods4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否故障(读):</div>
          <div class="xzhi" :title="data.R_PP_Alarm4">{{ data.R_PP_Alarm4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(读):</div>
          <div class="xzhi" :title="data.R_PP_STB4">{{ data.R_PP_STB4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(读):</div>
          <div class="xzhi" :title="data.R_PP_ACK4">{{ data.R_PP_ACK4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(写):</div>
          <div class="xzhi" :title="data.W_PP_STB4">{{ data.W_PP_STB4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(写):</div>
          <div class="xzhi" :title="data.W_PP_ACK4">{{ data.W_PP_ACK4 }}</div>
        </div>
        <div class="zhuname">出库2005站台</div>
        <div class="zhankuang">
          <div class="xname">握手信号(读):</div>
          <div class="xzhi" :title="data.R_PP_HandShake5">{{ data.R_PP_HandShake5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否联机(读):</div>
          <div class="xzhi" :title="data.R_PP_Online5">{{ data.R_PP_Online5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否空闲(读):</div>
          <div class="xzhi" :title="data.R_PP_Free5">{{ data.R_PP_Free5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否有货(读):</div>
          <div class="xzhi" :title="data.R_PP_Goods5">{{ data.R_PP_Goods5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否故障(读):</div>
          <div class="xzhi" :title="data.R_PP_Alarm5">{{ data.R_PP_Alarm5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(读):</div>
          <div class="xzhi" :title="data.R_PP_STB5">{{ data.R_PP_STB5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(读):</div>
          <div class="xzhi" :title="data.R_PP_ACK5">{{ data.R_PP_ACK5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(写):</div>
          <div class="xzhi" :title="data.W_PP_STB5">{{ data.W_PP_STB5 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(写):</div>
          <div class="xzhi" :title="data.W_PP_ACK5">{{ data.W_PP_ACK5 }}</div>
        </div>
      </div>
      <div class="skuang">
        <div class="zhuname">出库2016站台</div>
        <div class="zhankuang">
          <div class="xname">握手信号(读):</div>
          <div class="xzhi" :title="data.R_PP_HandShake6">{{ data.R_PP_HandShake6 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否联机(读):</div>
          <div class="xzhi" :title="data.R_PP_Online6">{{ data.R_PP_Online6 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否空闲(读):</div>
          <div class="xzhi" :title="data.R_PP_Free6">{{ data.R_PP_Free6 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否有货(读):</div>
          <div class="xzhi" :title="data.R_PP_Goods6">{{ data.R_PP_Goods6 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否故障(读):</div>
          <div class="xzhi" :title="data.R_PP_Alarm6">{{ data.R_PP_Alarm6 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(读):</div>
          <div class="xzhi" :title="data.R_PP_STB6">{{ data.R_PP_STB6 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(读):</div>
          <div class="xzhi" :title="data.R_PP_ACK6">{{ data.R_PP_ACK6 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(写):</div>
          <div class="xzhi" :title="data.W_PP_STB6">{{ data.W_PP_STB6 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(写):</div>
          <div class="xzhi" :title="data.W_PP_ACK6">{{ data.W_PP_ACK6 }}</div>
        </div>
        <div class="zhuname">出库2017站台</div>
        <div class="zhankuang">
          <div class="xname">握手信号(读):</div>
          <div class="xzhi" :title="data.R_PP_HandShake7">{{ data.R_PP_HandShake7 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否联机(读):</div>
          <div class="xzhi" :title="data.R_PP_Online7">{{ data.R_PP_Online7 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否空闲(读):</div>
          <div class="xzhi" :title="data.R_PP_Free7">{{ data.R_PP_Free7 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否有货(读):</div>
          <div class="xzhi" :title="data.R_PP_Goods7">{{ data.R_PP_Goods7 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否故障(读):</div>
          <div class="xzhi" :title="data.R_PP_Alarm7">{{ data.R_PP_Alarm7 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(读):</div>
          <div class="xzhi" :title="data.R_PP_STB7">{{ data.R_PP_STB7 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(读):</div>
          <div class="xzhi" :title="data.R_PP_ACK7">{{ data.R_PP_ACK7 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">请求信号(写):</div>
          <div class="xzhi" :title="data.W_PP_STB7">{{ data.W_PP_STB7 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">响应信号(写):</div>
          <div class="xzhi" :title="data.W_PP_ACK7">{{ data.W_PP_ACK7 }}</div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { ref, nextTick } from "vue";
import { useStore } from "vuex";
import { onMounted } from "vue";
export default {
  data() {
    return {
      xuan: 0
    };
  },
  methods: {
  },
  setup() {
    const store = useStore();
    const data = ref({});
    // 1. å®šä¹‰æ™®é€šå­—段的映射规则
    const statusMap = {
      R_PP_Status: {
        1: "正常",
        2: "故障",
        3: "急停",
      },
      R_PP_AutoStatus: {
        0: "ç»´ä¿®",
        1: "手动",
        2: "半自动",
        3: "自动",
      },
      R_PP_WorkStatus: {
        0: "待机",
        1: "取货中",
        2: "取货完成",
        4: "放货中",
        5: "放货完成",
        6: "任务完成",
      },
      R_PP_WorkType: {
        0: "无作业任务(0)",
        1: "取放货作业(1)",
        2: "只取货作业(2)",
        3: "只放货作业(3)",
        4: "移动到指定位置"
      },
      R_PP_TrayType: {
        "-1": "空箱(-1)",
        1: "小托盘(1)",
        2: "中托盘(2)",
        3: "大托盘(3)",
        4: "特大托盘(4)",
      }
    };
    const onlines = [
        "R_PP_Online6","R_PP_Online4",
        "R_PP_Online5","R_PP_Online7"
    ]
    const online = {
      true: "联机",
      false: "脱机"
    };
    const alarms = [
        "R_PP_Alarm6","R_PP_Alarm4",
        "R_PP_Alarm5","R_PP_Alarm7"
    ]
    const alarm = {
      true: "故障",
      false: "正常"
    };
    const frees = [
        "R_PP_Free6","R_PP_Free4",
        "R_PP_Free5","R_PP_Free7"
    ]
    const free = {
      true: "空闲",
      false: "繁忙"
    };
    const goods = [
        "R_PP_Goods6", "R_PP_Goods4",
        "R_PP_Goods5","R_PP_Goods7"
    ]
    const good = {
      true: "有货",
      false: "无货"
    };
    // 2. å®šä¹‰éœ€è¦å…±ç”¨æ˜ å°„规则的字段列表和对应的映射规则
    const booleanFields = [
      "R_PP_HandShake4", "R_PP_STB4",
      "R_PP_ACK4", "W_PP_STB4",
      "W_PP_ACK4",
      "R_PP_HandShake5", "R_PP_STB5",
      "R_PP_ACK5", "W_PP_STB5",
      "W_PP_ACK5",
      "R_PP_HandShake6", "R_PP_STB6",
      "R_PP_ACK6", "W_PP_STB6",
      "W_PP_ACK6",
      "R_PP_HandShake7", "R_PP_STB7",
      "R_PP_ACK7", "W_PP_STB7",
      "W_PP_ACK7",
    ];
    const booleanMap = {
      true: "是",
      false: "否"
    };
    // å¤„理数据,先处理普通映射,再批量处理共用映射的字段
    const processData = (rawData) => {
      if (!rawData) return {};
      const processed = { ...rawData };
      // å¤„理普通字段映射
      Object.keys(statusMap).forEach(key => {
        if (processed.hasOwnProperty(key)) {
          const map = statusMap[key];
          processed[key] = map[processed[key]] || processed[key];
        }
      });
      // æ‰¹é‡å¤„理共用映射规则的字段
      booleanFields.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = booleanMap[processed[key]] || processed[key];
        }
      });
      onlines.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = online[processed[key]] || processed[key];
        }
      });
      alarms.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = alarm[processed[key]] || processed[key];
        }
      });
      frees.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = free[processed[key]] || processed[key];
        }
      });
      goods.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = good[processed[key]] || processed[key];
        }
      });
      return processed;
    };
    onMounted(() => {
      nextTick(() => {
        setInterval(() => {
          const rawData = store.state.homedata;
          data.value = processData(rawData);
          const xian = document.getElementsByClassName("xzhi");
          for (let i = 0; i < xian.length; i++) {
            if (xian[i].innerHTML === "是") {
              xian[i].style.color = "yellow";
            } else if (xian[i].innerHTML === "否") {
              xian[i].style.color = "red";
            }
          }
        });
      });
    });
    return {
      data,
    };
  }
};
</script>
<style scoped>
.ding {
  float: left;
  width: 20px;
  height: 20px;
  margin-top: 7px;
}
.yan {
  color: white;
  float: left;
  font-size: 25px;
}
.dakuang {
  width: 250px;
  height: 50px;
  position: absolute;
  top: 150px;
  left: 200px;
}
#xiugai {
  width: 100px;
  height: 30px;
  float: left;
  border-radius: 5px;
  text-align: center;
  line-height: 30px;
  cursor: pointer;
  border: 1px solid white;
  color: white;
  background: rgba(255, 255, 255, 0.5);
  font-size: 25px;
  position: absolute;
  top: 150px;
  left: 450px;
}
#xiugai:hover {
  background: #f60;
}
#shu1,
#shu2 {
  width: 200px;
  height: 30px;
  float: left;
  margin-top: 0px;
  margin-right: 0px;
  border-radius: 5px;
  border: 1px solid white;
}
#guan {
  width: 40px;
  height: 40px;
  float: left;
  font-size: 1.1cqw;
  text-align: center;
  line-height: 40px;
  cursor: pointer;
  margin-left: 560px;
  color: white;
  position: absolute;
}
#ti {
  width: 600px;
  height: 300px;
  position: relative;
  background: rgba(255, 255, 255, 1);
  border-radius: 10px;
  top: 230px;
  left: 35%;
  display: none;
  background-image: url("../../img/1.png");
  background-repeat: no-repeat;
  background-size: 170%;
  background-position: -220px 0px;
}
.zhuname {
  width: 100%;
  height: 5vh;
  float: left;
  text-align: center;
  line-height: 50px;
  font-weight: 700;
  font-size: 1.1cqw;
  color: white;
}
.xname {
  width: 70%;
  height: 80px;
  float: left;
  line-height: 7vh;
  font-size: 1.1cqw;
  color: white;
}
.xzhi {
  width: 30%;
  height: 7vh;
  float: left;
  line-height: 50px;
  font-size: 1.1cqw;
  color: rgb(242, 242, 50);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.zhankuang {
  width: 45%;
  height: 3vh;
  margin-top: 10px;
  margin-left: 5%;
  float: left;
}
#title {
  float: left;
  width: 95%;
  height: 88vh;
  margin-top: 40px;
  margin-left: 3%;
  background-image: url("../../img/1.png");
  background-repeat: no-repeat;
  background-size: 100%;
  container-type: inline-size;
}
#bkuang {
  width: 100%;
  height: 55vh;
  float: left;
}
.skuang {
  width: 31%;
  height: 55vh;
  float: left;
  border-top: none;
  border-left: none;
  border-bottom: none;
  background: rgba(255, 255, 255, 0.2);
  margin-left: 1.7%;
  border-radius: 10px;
}
</style>
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/SolderMaskWarehouse.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,430 @@
<template>
  <div id="title">
    <div id="bkuang" style="border-top: none">
      <div class="skuang">
        <div class="zhuname">阻焊仓堆垛机</div>
        <div class="zhankuang">
          <div class="xname">堆垛机状态:</div>
          <div class="xzhi" :title="data.R_ZH_Status">{{ data.R_ZH_Status }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">堆垛机手自动状态:</div>
          <div class="xzhi" :title="data.R_ZH_AutoStatus">{{ data.R_ZH_AutoStatus }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">正在执行的任务号:</div>
          <div class="xzhi" :title="data.R_ZH_TaskNum">{{ data.R_ZH_TaskNum }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">堆垛机工作状态:</div>
          <div class="xzhi" :title="data.R_ZH_WorkStatus">{{ data.R_ZH_WorkStatus }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">作业类型:</div>
          <div class="xzhi" :title="data.R_ZH_WorkType">{{ data.R_ZH_WorkType }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">托盘类型:</div>
          <div class="xzhi" :title="data.R_ZH_TrayType">{{ data.R_ZH_TrayType }}</div>
        </div>
      </div>
      <div class="skuang">
        <div class="zhuname">入库301站台</div>
        <div class="zhankuang">
          <div class="xname">是否允许放货(读):</div>
          <div class="xzhi" :title="data.R_ZH_IsCanPut1">{{ data.R_ZH_IsCanPut1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否允许取货(读):</div>
          <div class="xzhi" :title="data.R_ZH_IsCanTake1">{{ data.R_ZH_IsCanTake1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货托盘类型(读):</div>
          <div class="xzhi" :title="data.R_ZH_TakePalletType1">{{ data.R_ZH_TakePalletType1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货托盘类型(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutPalletType1">{{ data.W_ZH_PutPalletType1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货请求(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutRequest1">{{ data.W_ZH_PutRequest1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货完成(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutFinish1">{{ data.W_ZH_PutFinish1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货请求(写):</div>
          <div class="xzhi" :title="data.W_ZH_TakeRequest1">{{ data.W_ZH_TakeRequest1 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货完成(写):</div>
          <div class="xzhi" :title="data.W_ZH_TakeFinish1">{{ data.W_ZH_TakeFinish1 }}</div>
        </div>
        <div class="zhuname">入库302站台</div>
        <div class="zhankuang">
          <div class="xname">是否允许放货(读):</div>
          <div class="xzhi" :title="data.R_ZH_IsCanPut2">{{ data.R_ZH_IsCanPut2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否允许取货(读):</div>
          <div class="xzhi" :title="data.R_ZH_IsCanTake2">{{ data.R_ZH_IsCanTake2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货托盘类型(读):</div>
          <div class="xzhi" :title="data.R_ZH_TakePalletType2">{{ data.R_ZH_TakePalletType2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货托盘类型(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutPalletType2">{{ data.W_ZH_PutPalletType2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货请求(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutRequest2">{{ data.W_ZH_PutRequest2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货完成(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutFinish2">{{ data.W_ZH_PutFinish2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货请求(写):</div>
          <div class="xzhi" :title="data.W_ZH_TakeRequest2">{{ data.W_ZH_TakeRequest2 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货完成(写):</div>
          <div class="xzhi" :title="data.W_ZH_TakeFinish2">{{ data.W_ZH_TakeFinish2 }}</div>
        </div>
      </div>
      <div class="skuang">
        <div class="zhuname">出库303站台</div>
        <div class="zhankuang">
          <div class="xname">是否允许放货(读):</div>
          <div class="xzhi" :title="data.R_ZH_IsCanPut3">{{ data.R_ZH_IsCanPut3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否允许取货(读):</div>
          <div class="xzhi" :title="data.R_ZH_IsCanTake3">{{ data.R_ZH_IsCanTake3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货托盘类型(读):</div>
          <div class="xzhi" :title="data.R_ZH_TakePalletType3">{{ data.R_ZH_TakePalletType3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货托盘类型(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutPalletType3">{{ data.W_ZH_PutPalletType3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货请求(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutRequest3">{{ data.W_ZH_PutRequest3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货完成(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutFinish3">{{ data.W_ZH_PutFinish3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货请求(写):</div>
          <div class="xzhi" :title="data.W_ZH_TakeRequest3">{{ data.W_ZH_TakeRequest3 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货完成(写):</div>
          <div class="xzhi" :title="data.W_ZH_TakeFinish3">{{ data.W_ZH_TakeFinish3 }}</div>
        </div>
        <div class="zhuname">出库304站台</div>
        <div class="zhankuang">
          <div class="xname">是否允许放货(读):</div>
          <div class="xzhi" :title="data.R_ZH_IsCanPut4">{{ data.R_ZH_IsCanPut4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">是否允许取货(读):</div>
          <div class="xzhi" :title="data.R_ZH_IsCanTake4">{{ data.R_ZH_IsCanTake4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货托盘类型(读):</div>
          <div class="xzhi" :title="data.R_ZH_TakePalletType4">{{ data.R_ZH_TakePalletType4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货托盘类型(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutPalletType4">{{ data.W_ZH_PutPalletType4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货请求(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutRequest4">{{ data.W_ZH_PutRequest4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">放货完成(写):</div>
          <div class="xzhi" :title="data.W_ZH_PutFinish4">{{ data.W_ZH_PutFinish4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货请求(写):</div>
          <div class="xzhi" :title="data.W_ZH_TakeRequest4">{{ data.W_ZH_TakeRequest4 }}</div>
        </div>
        <div class="zhankuang">
          <div class="xname">取货完成(写):</div>
          <div class="xzhi" :title="data.W_ZH_TakeFinish4">{{ data.W_ZH_TakeFinish4 }}</div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
import { ref, nextTick } from "vue";
import { useStore } from "vuex";
import { onMounted } from "vue";
export default {
  data() {
    return {
      xuan: 0
    };
  },
  methods: {
  },
  setup() {
    const store = useStore();
    const data = ref({});
    // 1. å®šä¹‰æ™®é€šå­—段的映射规则
    const statusMap = {
      R_ZH_Status: {
        1: "正常",
        2: "故障",
        3: "急停",
      },
      R_ZH_AutoStatus: {
        0: "ç»´ä¿®",
        1: "手动",
        2: "半自动",
        3: "自动",
      },
      R_ZH_WorkStatus: {
        0: "待机",
        1: "取货中",
        2: "取货完成",
        4: "放货中",
        5: "放货完成",
        6: "任务完成",
      },
      R_ZH_WorkType: {
        0: "无作业任务(0)",
        1: "取放货作业(1)",
        2: "只取货作业(2)",
        3: "只放货作业(3)",
        4: "移动到指定位置"
      },
      R_ZH_TrayType: {
        "-1": "空箱(-1)",
        1: "小托盘(1)",
        2: "中托盘(2)",
        3: "大托盘(3)",
        4: "特大托盘(4)",
      }
    };
    // 2. å®šä¹‰éœ€è¦å…±ç”¨æ˜ å°„规则的字段列表和对应的映射规则
    const booleanFields = [
      "R_ZH_IsCanPut1", "R_ZH_IsCanTake1",
      "W_ZH_PutRequest1", "W_ZH_PutFinish1",
      "W_ZH_TakeRequest1", "W_ZH_TakeFinish1",
      "R_ZH_IsCanPut2", "R_ZH_IsCanTake2",
      "W_ZH_PutRequest2", "W_ZH_PutFinish2",
      "W_ZH_TakeRequest2", "W_ZH_TakeFinish2",
      "R_ZH_IsCanPut3", "R_ZH_IsCanTake3",
      "W_ZH_PutRequest3", "W_ZH_PutFinish3",
      "W_ZH_TakeRequest3", "W_ZH_TakeFinish3",
      "R_ZH_IsCanPut4", "R_ZH_IsCanTake4",
      "W_ZH_PutRequest4", "W_ZH_PutFinish4",
      "W_ZH_TakeRequest4", "W_ZH_TakeFinish4",
    ];
    const booleanMap = {
      true: "是",
      false: "否"
    };
    // å¤„理数据,先处理普通映射,再批量处理共用映射的字段
    const processData = (rawData) => {
      if (!rawData) return {};
      const processed = { ...rawData };
      // å¤„理普通字段映射
      Object.keys(statusMap).forEach(key => {
        if (processed.hasOwnProperty(key)) {
          const map = statusMap[key];
          processed[key] = map[processed[key]] || processed[key];
        }
      });
      // æ‰¹é‡å¤„理共用映射规则的字段
      booleanFields.forEach(key => {
        if (processed.hasOwnProperty(key)) {
          processed[key] = booleanMap[processed[key]] || processed[key];
        }
      });
      return processed;
    };
    onMounted(() => {
      nextTick(() => {
        setInterval(() => {
          const rawData = store.state.homedata;
          data.value = processData(rawData);
          const xian = document.getElementsByClassName("xzhi");
          for (let i = 0; i < xian.length; i++) {
            if (xian[i].innerHTML === "是") {
              xian[i].style.color = "yellow";
            } else if (xian[i].innerHTML === "否") {
              xian[i].style.color = "red";
            }
          }
        });
      });
    });
    return {
      data,
    };
  }
};
</script>
<style scoped>
.ding {
  float: left;
  width: 20px;
  height: 20px;
  margin-top: 7px;
}
.yan {
  color: white;
  float: left;
  font-size: 25px;
}
.dakuang {
  width: 250px;
  height: 50px;
  position: absolute;
  top: 150px;
  left: 200px;
}
#xiugai {
  width: 100px;
  height: 30px;
  float: left;
  border-radius: 5px;
  text-align: center;
  line-height: 30px;
  cursor: pointer;
  border: 1px solid white;
  color: white;
  background: rgba(255, 255, 255, 0.5);
  font-size: 25px;
  position: absolute;
  top: 150px;
  left: 450px;
}
#xiugai:hover {
  background: #f60;
}
#shu1,
#shu2 {
  width: 200px;
  height: 30px;
  float: left;
  margin-top: 0px;
  margin-right: 0px;
  border-radius: 5px;
  border: 1px solid white;
}
#guan {
  width: 40px;
  height: 40px;
  float: left;
  font-size: 1.1cqw;
  text-align: center;
  line-height: 40px;
  cursor: pointer;
  margin-left: 560px;
  color: white;
  position: absolute;
}
#ti {
  width: 600px;
  height: 300px;
  position: relative;
  background: rgba(255, 255, 255, 1);
  border-radius: 10px;
  top: 230px;
  left: 35%;
  display: none;
  background-image: url("../../img/1.png");
  background-repeat: no-repeat;
  background-size: 170%;
  background-position: -220px 0px;
}
.zhuname {
  width: 100%;
  height: 5vh;
  float: left;
  text-align: center;
  line-height: 50px;
  font-weight: 700;
  font-size: 1.1cqw;
  color: white;
}
.xname {
  width: 70%;
  height: 80px;
  float: left;
  line-height: 7vh;
  font-size: 1.1cqw;
  color: white;
}
.xzhi {
  width: 30%;
  height: 7vh;
  float: left;
  line-height: 50px;
  font-size: 1.1cqw;
  color: rgb(242, 242, 50);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.zhankuang {
  width: 45%;
  height: 3vh;
  margin-top: 10px;
  margin-left: 5%;
  float: left;
}
#title {
  float: left;
  width: 95%;
  height: 88vh;
  margin-top: 40px;
  margin-left: 3%;
  background-image: url("../../img/1.png");
  background-repeat: no-repeat;
  background-size: 100%;
  container-type: inline-size;
}
#bkuang {
  width: 100%;
  height: 55vh;
  float: left;
}
.skuang {
  width: 31%;
  height: 55vh;
  float: left;
  border-top: none;
  border-left: none;
  border-bottom: none;
  background: rgba(255, 255, 255, 0.2);
  margin-left: 1.7%;
  border-radius: 10px;
}
</style>
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Client/src/views/deviceMonitoring/TestFrameWarehouse.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,45 @@
<template>
  <div class="message-container">
    <div class="item" v-for="(item, index) in list" :key="index">
      <div class="title">{{ item.title }}({{ item.date }})</div>
      <div class="content">{{ item.message }}</div>
    </div>
  </div>
</template>
<script>
export default {
  props: {
    list: {
      type: Array,
      default: () => {
        return [];
      }
    }
  },
  created() {
    if (!this.list.length) {
      this.list.push({
        title: '消息werwer测试标题',
        message: '消息测试内容消息测试内容消息测试内容消息测试内容',
        date: '2022-05-02 03:10'
      });
    }
  }
};
</script>
<style scoped lang="less">
.message-container {
  .title {
    padding-bottom: 10px;
  }
  .item {
    border-bottom: 1px solid #eee;
    padding: 10px 20px;
  }
  .content {
    color: #7e7e7e;
    font-size: 13px;
  }
}
</style>
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Controllers/QuartzJob/DeviceProtocolController.cs
@@ -5,6 +5,7 @@
using WIDESEAWCS_Core.BaseController;
using WIDESEAWCS_QuartzJob.Models;
using WIDESEAWCS_QuartzJob.Service;
using WIDESEAWCS_Tasks;
namespace WIDESEAWCS_Server.Controllers.QuartzJob
{
@@ -18,6 +19,7 @@
        [HttpPost, Route("GetImportData"), AllowAnonymous]
        public WebResponseContent GetImportData(List<IFormFile> fileInput)
        {
            return Service.GetImportData(fileInput);
        }
    }
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Server/Program.cs
@@ -33,6 +33,7 @@
    builder.RegisterModule<AutofacPropertityModuleReg>();//
}).ConfigureAppConfiguration((hostingContext, config) =>
{
    hostingContext.Configuration.ConfigureApplication();
    config.Sources.Clear();
    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: false);
@@ -54,6 +55,9 @@
builder.Services.AddHostedService<QuartzJobDataTableHostedService>();
//builder.Services.AddWebSocketSetup();
builder.Services.AddWebSocketSetup();
builder.Services.AddHostedService<WarehouseHostedService>();
builder.Services.AddAutoMapperSetup();
@@ -67,6 +71,7 @@
builder.Services.AddHttpContextSetup();
builder.Services.AddHostedService<QuartzJobHostedService>();
builder.Services.AddMvc(options =>
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/PP²Ö/ConveyorLineJob_PP.cs
@@ -225,6 +225,27 @@
                    {
                        WriteInfo(device.DeviceName, $"未找到设备子编号{item.StationCode}的协议信息");
                    }
                    R_ConveyorLineInfo conveyorLineInfoRead1 = device.Communicator.ReadCustomer<R_ConveyorLineInfo>(deviceProRead.DeviceProAddress);
                    W_ConveyorLineInfo conveyorLineInfoWrite1 = device.Communicator.ReadCustomer<W_ConveyorLineInfo>(deviceProWrite.DeviceProAddress);
                    R_ConveyorLineStatus conveyorLineStatus1 = conveyorLineInfoRead1.Status.ByteToBoolObject<R_ConveyorLineStatus>();
                    ConveyorLineSignal conveyorLineSignalRead1 = conveyorLineInfoRead1.Signal.ByteToBoolObject<ConveyorLineSignal>();
                    ConveyorLineSignal conveyorLineSignalWrite1 = conveyorLineInfoWrite1.Signal.ByteToBoolObject<ConveyorLineSignal>();
                    if (item.StationCode == "2004")
                    {
                        if (conveyorLineSignalRead1.STB && conveyorLineStatus1.Online && conveyorLineStatus1.Goods && !conveyorLineStatus1.Alarm && !conveyorLineSignalWrite1.ACK)
                        {
                            StackerCraneJob_PP.pPReadData.R_PP_Boxcode = device.Communicator.Read<string>("DB900.578.0");
                        }
                        StackerCraneJob_PP.pPReadData.R_PP_HandShake4 = conveyorLineStatus1.HandShake;
                        StackerCraneJob_PP.pPReadData.R_PP_Online4 = conveyorLineStatus1.Online;
                        StackerCraneJob_PP.pPReadData.R_PP_Free4 = conveyorLineStatus1.Free;
                        StackerCraneJob_PP.pPReadData.R_PP_Goods4 = conveyorLineStatus1.Goods;
                        StackerCraneJob_PP.pPReadData.R_PP_Alarm4 = conveyorLineStatus1.Alarm;
                        StackerCraneJob_PP.pPReadData.R_PP_STB4 = conveyorLineSignalRead1.STB;
                        StackerCraneJob_PP.pPReadData.R_PP_ACK4 = conveyorLineSignalRead1.ACK;
                        StackerCraneJob_PP.pPReadData.W_PP_STB4 = conveyorLineSignalWrite1.STB;
                        StackerCraneJob_PP.pPReadData.W_PP_ACK4 = conveyorLineSignalWrite1.ACK;
                    }
                }
            }
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/PP²Ö/PPReadData.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,234 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEAWCS_Tasks.PP仓
{
    public class PPReadData
    {
        /// <summary>
        /// å †åž›æœºçŠ¶æ€
        /// </summary>
        public short R_PP_Status;
        /// <summary>
        /// å †åž›æœºæ‰‹è‡ªåŠ¨çŠ¶æ€
        /// </summary>
        public short R_PP_AutoStatus;
        /// <summary>
        /// å½“前正在执行的任务号
        /// </summary>
        public int R_PP_TaskNum;
        /// <summary>
        /// å †åž›æœºå·¥ä½œçŠ¶æ€
        /// </summary>
        public short R_PP_WorkStatus;
        /// <summary>
        /// ä½œä¸šç±»åž‹
        /// </summary>
        public short R_PP_WorkType;
        /// <summary>
        /// æ‰˜ç›˜ç±»åž‹
        /// </summary>
        public short R_PP_TrayType;
        ///站台
        ///<summary>
        /// è¯»å–条码
        /// </summary>
        public string R_PP_Boxcode;
        /// <summary>
        /// æ¡æ‰‹ä¿¡å·
        /// </summary>
        public bool R_PP_HandShake4;
        /// <summary>
        /// 1联机 0脱机
        /// </summary>
        public bool R_PP_Online4;
        /// <summary>
        /// 1空闲 0繁忙
        /// </summary>
        public bool R_PP_Free4;
        /// <summary>
        /// 1有货 0无货
        /// </summary>
        public bool R_PP_Goods4;
        /// <summary>
        /// 1故障 0正常
        /// </summary>
        public bool R_PP_Alarm4;
        /// <summary>
        /// è¯·æ±‚信号(读)
        /// </summary>
        public bool R_PP_STB4;
        /// <summary>
        /// å“åº”信号(读)
        /// </summary>
        public bool R_PP_ACK4;
        /// <summary>
        /// è¯·æ±‚信号(写)
        /// </summary>
        public bool W_PP_STB4;
        /// <summary>
        /// å“åº”信号(写)
        /// </summary>
        public bool W_PP_ACK4;
        /// <summary>
        /// æ¡æ‰‹ä¿¡å·
        /// </summary>
        public bool R_PP_HandShake5;
        /// <summary>
        /// 1联机 0脱机
        /// </summary>
        public bool R_PP_Online5;
        /// <summary>
        /// 1空闲 0繁忙
        /// </summary>
        public bool R_PP_Free5;
        /// <summary>
        /// 1有货 0无货
        /// </summary>
        public bool R_PP_Goods5;
        /// <summary>
        /// 1故障 0正常
        /// </summary>
        public bool R_PP_Alarm5;
        /// <summary>
        /// è¯·æ±‚信号(读)
        /// </summary>
        public bool R_PP_STB5;
        /// <summary>
        /// å“åº”信号(读)
        /// </summary>
        public bool R_PP_ACK5;
        /// <summary>
        /// è¯·æ±‚信号(写)
        /// </summary>
        public bool W_PP_STB5;
        /// <summary>
        /// å“åº”信号(写)
        /// </summary>
        public bool W_PP_ACK5;
        /// <summary>
        /// æ¡æ‰‹ä¿¡å·
        /// </summary>
        public bool R_PP_HandShake6;
        /// <summary>
        /// 1联机 0脱机
        /// </summary>
        public bool R_PP_Online6;
        /// <summary>
        /// 1空闲 0繁忙
        /// </summary>
        public bool R_PP_Free6;
        /// <summary>
        /// 1有货 0无货
        /// </summary>
        public bool R_PP_Goods6;
        /// <summary>
        /// 1故障 0正常
        /// </summary>
        public bool R_PP_Alarm6;
        /// <summary>
        /// è¯·æ±‚信号(读)
        /// </summary>
        public bool R_PP_STB6;
        /// <summary>
        /// å“åº”信号(读)
        /// </summary>
        public bool R_PP_ACK6;
        /// <summary>
        /// è¯·æ±‚信号(写)
        /// </summary>
        public bool W_PP_STB6;
        /// <summary>
        /// å“åº”信号(写)
        /// </summary>
        public bool W_PP_ACK6;
        /// <summary>
        /// æ¡æ‰‹ä¿¡å·
        /// </summary>
        public bool R_PP_HandShake7;
        /// <summary>
        /// 1联机 0脱机
        /// </summary>
        public bool R_PP_Online7;
        /// <summary>
        /// 1空闲 0繁忙
        /// </summary>
        public bool R_PP_Free7;
        /// <summary>
        /// 1有货 0无货
        /// </summary>
        public bool R_PP_Goods7;
        /// <summary>
        /// 1故障 0正常
        /// </summary>
        public bool R_PP_Alarm7;
        /// <summary>
        /// è¯·æ±‚信号(读)
        /// </summary>
        public bool R_PP_STB7;
        /// <summary>
        /// å“åº”信号(读)
        /// </summary>
        public bool R_PP_ACK7;
        /// <summary>
        /// è¯·æ±‚信号(写)
        /// </summary>
        public bool W_PP_STB7;
        /// <summary>
        /// å“åº”信号(写)
        /// </summary>
        public bool W_PP_ACK7;
    }
}
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/PP²Ö/StackerCraneJob_PP.cs
@@ -28,6 +28,9 @@
using WIDESEAWCS_DTO.TaskInfo;
using WIDESEAWCS_Core.Caches;
using AutoMapper;
using WIDESEAWCS_Tasks.PP仓;
using HslCommunication.WebSocket;
using WIDESEAWCS_Tasks.干膜仓;
namespace WIDESEAWCS_Tasks
{
@@ -39,11 +42,13 @@
        private readonly ITaskService _taskService;
        private readonly ITaskExecuteDetailService _taskExecuteDetailService;
        private readonly ITaskRepository _taskRepository;
        public static PPReadData pPReadData = new PPReadData();
        private readonly IRouterService _routerService;
        private readonly IStationMangerRepository _stationMangerRepository;
        private List<Dt_ApiInfo> apiInfos;
        private WebSocketServer _webSocketServer;
        public StackerCraneJob_PP(IMapper mapper, ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IStationMangerRepository stationMangerRepository, ICacheService cacheService)
        public StackerCraneJob_PP(IMapper mapper, ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IStationMangerRepository stationMangerRepository, ICacheService cacheService,WebSocketServer webSocketServer)
        {
            _taskService = taskService;
            _taskExecuteDetailService = taskExecuteDetailService;
@@ -52,6 +57,7 @@
            _stationMangerRepository = stationMangerRepository;
            _cacheService = cacheService;
            _mapper=mapper;
            _webSocketServer = webSocketServer;
            string? apiInfoStr = _cacheService.Get("apiInfos");
            if (!string.IsNullOrEmpty(apiInfoStr))
@@ -103,6 +109,14 @@
                            }
                        }
                    }
                    pPReadData.R_PP_Status = ((short)commonStackerCrane.StackerCraneStatusValue);
                    pPReadData.R_PP_AutoStatus = ((short)commonStackerCrane.StackerCraneAutoStatusValue);
                    pPReadData.R_PP_WorkStatus = ((short)commonStackerCrane.StackerCraneWorkStatusValue);
                    pPReadData.R_PP_TaskNum = commonStackerCrane.CurrentTaskNum.ObjToInt();
                    pPReadData.R_PP_WorkType = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType);
                    pPReadData.R_PP_TrayType = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.TrayType);
                    string pPData = JsonConvert.SerializeObject(pPReadData);
                    _webSocketServer.PublishAllClientPayload(pPData);
                }
            }
            catch (Exception ex)
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/PP²Ö/TSJConveyorLineJob_PP.cs
@@ -219,6 +219,50 @@
                    {
                        WriteInfo(device.DeviceName, $"未找到设备子编号{item.StationCode}的协议信息");
                    }
                    R_ConveyorLineInfo conveyorLineInfoRead1 = device.Communicator.ReadCustomer<R_ConveyorLineInfo>(deviceProRead.DeviceProAddress);
                    W_ConveyorLineInfo conveyorLineInfoWrite1 = device.Communicator.ReadCustomer<W_ConveyorLineInfo>(deviceProWrite.DeviceProAddress);
                    R_ConveyorLineStatus conveyorLineStatus1 = conveyorLineInfoRead1.Status.ByteToBoolObject<R_ConveyorLineStatus>();
                    ConveyorLineSignal conveyorLineSignalRead1 = conveyorLineInfoRead1.Signal.ByteToBoolObject<ConveyorLineSignal>();
                    ConveyorLineSignal conveyorLineSignalWrite1 = conveyorLineInfoWrite1.Signal.ByteToBoolObject<ConveyorLineSignal>();
                    if (item.StationCode == "2005")
                    {
                        if (conveyorLineSignalRead1.STB && conveyorLineStatus1.Online && conveyorLineStatus1.Goods && !conveyorLineStatus1.Alarm && !conveyorLineSignalWrite1.ACK)
                        {
                            StackerCraneJob_PP.pPReadData.R_PP_Boxcode = device.Communicator.Read<string>("DB900.578.0");
                        }
                        StackerCraneJob_PP.pPReadData.R_PP_HandShake5 = conveyorLineStatus1.HandShake;
                        StackerCraneJob_PP.pPReadData.R_PP_Online5 = conveyorLineStatus1.Online;
                        StackerCraneJob_PP.pPReadData.R_PP_Free5 = conveyorLineStatus1.Free;
                        StackerCraneJob_PP.pPReadData.R_PP_Goods5 = conveyorLineStatus1.Goods;
                        StackerCraneJob_PP.pPReadData.R_PP_Alarm5 = conveyorLineStatus1.Alarm;
                        StackerCraneJob_PP.pPReadData.R_PP_STB5 = conveyorLineSignalRead1.STB;
                        StackerCraneJob_PP.pPReadData.R_PP_ACK5 = conveyorLineSignalRead1.ACK;
                        StackerCraneJob_PP.pPReadData.W_PP_STB5 = conveyorLineSignalWrite1.STB;
                        StackerCraneJob_PP.pPReadData.W_PP_ACK5 = conveyorLineSignalWrite1.ACK;
                    }else if(item.StationCode == "2016")
                    {
                        StackerCraneJob_PP.pPReadData.R_PP_HandShake6 = conveyorLineStatus1.HandShake;
                        StackerCraneJob_PP.pPReadData.R_PP_Online6 = conveyorLineStatus1.Online;
                        StackerCraneJob_PP.pPReadData.R_PP_Free6 = conveyorLineStatus1.Free;
                        StackerCraneJob_PP.pPReadData.R_PP_Goods6 = conveyorLineStatus1.Goods;
                        StackerCraneJob_PP.pPReadData.R_PP_Alarm6 = conveyorLineStatus1.Alarm;
                        StackerCraneJob_PP.pPReadData.R_PP_STB6 = conveyorLineSignalRead1.STB;
                        StackerCraneJob_PP.pPReadData.R_PP_ACK6 = conveyorLineSignalRead1.ACK;
                        StackerCraneJob_PP.pPReadData.W_PP_STB6 = conveyorLineSignalWrite1.STB;
                        StackerCraneJob_PP.pPReadData.W_PP_ACK6 = conveyorLineSignalWrite1.ACK;
                    }
                    else if (item.StationCode == "2016")
                    {
                        StackerCraneJob_PP.pPReadData.R_PP_HandShake7 = conveyorLineStatus1.HandShake;
                        StackerCraneJob_PP.pPReadData.R_PP_Online7 = conveyorLineStatus1.Online;
                        StackerCraneJob_PP.pPReadData.R_PP_Free7 = conveyorLineStatus1.Free;
                        StackerCraneJob_PP.pPReadData.R_PP_Goods7 = conveyorLineStatus1.Goods;
                        StackerCraneJob_PP.pPReadData.R_PP_Alarm7 = conveyorLineStatus1.Alarm;
                        StackerCraneJob_PP.pPReadData.R_PP_STB7 = conveyorLineSignalRead1.STB;
                        StackerCraneJob_PP.pPReadData.R_PP_ACK7 = conveyorLineSignalRead1.ACK;
                        StackerCraneJob_PP.pPReadData.W_PP_STB7 = conveyorLineSignalWrite1.STB;
                        StackerCraneJob_PP.pPReadData.W_PP_ACK7 = conveyorLineSignalWrite1.ACK;
                    }
                }
            }
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/UpdateExpirationlabelJob.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,40 @@
using Newtonsoft.Json;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WIDESEAWCS_Core.Helper;
using WIDESEAWCS_Core;
using WIDESEAWCS_QuartzJob;
namespace WIDESEAWCS_Tasks
{
    [DisallowConcurrentExecution]
    public partial class UpdateExpirationlabelJob : JobBase, IJob
    {
        public Task Execute(IJobExecutionContext context)
        {
            Thread.Sleep(4320000);
            try
            {
                string address = AppSettings.Get("WMSApiAddress");
                if (string.IsNullOrEmpty(address)) throw new Exception("未找到WMSApi地址");
                string responseStr = HttpHelper.Get($"{address}/api/StockInfo/UpdateExpirationlabel");
                WebResponseContent? responseContent = JsonConvert.DeserializeObject<WebResponseContent>(responseStr);
                if (responseContent.Status)
                {
                    return Task.CompletedTask;
                }
            }
            catch (Exception ex)
            {
                Console.Out.WriteLine(nameof(UpdateExpirationlabelJob) + ":" + ex.Message);
            }
            return Task.CompletedTask;
        }
    }
}
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/¸ÉĤ²Ö/ConveyorLineJob_GM.cs
@@ -17,6 +17,7 @@
using WIDESEAWCS_ITaskInfoService;
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_QuartzJob.ConveyorLine.Enum;
using WIDESEAWCS_QuartzJob.DTO;
using WIDESEAWCS_QuartzJob.Models;
using WIDESEAWCS_QuartzJob.Repository;
@@ -239,6 +240,50 @@
                    {
                        WriteInfo(device.DeviceName, $"未找到设备子编号{item.StationCode}的协议信息");
                    }
                    R_ConveyorLineInfo conveyorLineInfoRead1 = device.Communicator.ReadCustomer<R_ConveyorLineInfo>(deviceProRead.DeviceProAddress);
                    W_ConveyorLineInfo conveyorLineInfoWrite1 = device.Communicator.ReadCustomer<W_ConveyorLineInfo>(deviceProWrite.DeviceProAddress);
                    R_ConveyorLineStatus conveyorLineStatus1 = conveyorLineInfoRead1.Status.ByteToBoolObject<R_ConveyorLineStatus>();
                    ConveyorLineSignal conveyorLineSignalRead1 = conveyorLineInfoRead1.Signal.ByteToBoolObject<ConveyorLineSignal>();
                    ConveyorLineSignal conveyorLineSignalWrite1 = conveyorLineInfoWrite1.Signal.ByteToBoolObject<ConveyorLineSignal>();
                    if (item.StationCode == "7003") {
                        if (conveyorLineSignalRead1.STB && conveyorLineStatus1.Online && conveyorLineStatus1.Goods && !conveyorLineStatus1.Alarm && !conveyorLineSignalWrite1.ACK)
                        {
                            StackerCraneJob_GM.gMReadData.R_GM_Boxcode = device.Communicator.Read<string>("DB900.478.0");
                        }
                        StackerCraneJob_GM.gMReadData.R_GM_HandShake3 = conveyorLineStatus1.HandShake;
                        StackerCraneJob_GM.gMReadData.R_GM_Online3 = conveyorLineStatus1.Online;
                        StackerCraneJob_GM.gMReadData.R_GM_Free3 = conveyorLineStatus1.Free;
                        StackerCraneJob_GM.gMReadData.R_GM_Goods3 = conveyorLineStatus1.Goods;
                        StackerCraneJob_GM.gMReadData.R_GM_Alarm3 = conveyorLineStatus1.Alarm;
                        StackerCraneJob_GM.gMReadData.R_GM_STB3 = conveyorLineSignalRead1.STB;
                        StackerCraneJob_GM.gMReadData.R_GM_ACK3 = conveyorLineSignalRead1.ACK;
                        StackerCraneJob_GM.gMReadData.W_GM_STB3 = conveyorLineSignalWrite1.STB;
                        StackerCraneJob_GM.gMReadData.W_GM_ACK3 = conveyorLineSignalWrite1.ACK;
                    }
                    else if(item.StationCode == "7004")
                    {
                        StackerCraneJob_GM.gMReadData.R_GM_HandShake4 = conveyorLineStatus1.HandShake;
                        StackerCraneJob_GM.gMReadData.R_GM_Online4 = conveyorLineStatus1.Online;
                        StackerCraneJob_GM.gMReadData.R_GM_Free4 = conveyorLineStatus1.Free;
                        StackerCraneJob_GM.gMReadData.R_GM_Goods4 = conveyorLineStatus1.Goods;
                        StackerCraneJob_GM.gMReadData.R_GM_Alarm4 = conveyorLineStatus1.Alarm;
                        StackerCraneJob_GM.gMReadData.R_GM_STB4 = conveyorLineSignalRead1.STB;
                        StackerCraneJob_GM.gMReadData.R_GM_ACK4 = conveyorLineSignalRead1.ACK;
                        StackerCraneJob_GM.gMReadData.W_GM_STB4 = conveyorLineSignalWrite1.STB;
                        StackerCraneJob_GM.gMReadData.W_GM_ACK4 = conveyorLineSignalWrite1.ACK;
                    }
                    else if (item.StationCode == "7005")
                    {
                        StackerCraneJob_GM.gMReadData.R_GM_HandShake5 = conveyorLineStatus1.HandShake;
                        StackerCraneJob_GM.gMReadData.R_GM_Online5 = conveyorLineStatus1.Online;
                        StackerCraneJob_GM.gMReadData.R_GM_Free5 = conveyorLineStatus1.Free;
                        StackerCraneJob_GM.gMReadData.R_GM_Goods5 = conveyorLineStatus1.Goods;
                        StackerCraneJob_GM.gMReadData.R_GM_Alarm5 = conveyorLineStatus1.Alarm;
                        StackerCraneJob_GM.gMReadData.R_GM_STB5 = conveyorLineSignalRead1.STB;
                        StackerCraneJob_GM.gMReadData.R_GM_ACK5 = conveyorLineSignalRead1.ACK;
                        StackerCraneJob_GM.gMReadData.W_GM_STB5 = conveyorLineSignalWrite1.STB;
                        StackerCraneJob_GM.gMReadData.W_GM_ACK5 = conveyorLineSignalWrite1.ACK;
                    }
                }
            }
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/¸ÉĤ²Ö/GMReadData.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,185 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEAWCS_Tasks.干膜仓
{
    public class GMReadData
    {
        /// <summary>
        /// å †åž›æœºçŠ¶æ€
        /// </summary>
        public short R_GM_Status;
        /// <summary>
        /// å †åž›æœºæ‰‹è‡ªåŠ¨çŠ¶æ€
        /// </summary>
        public short R_GM_AutoStatus;
        /// <summary>
        /// å½“前正在执行的任务号
        /// </summary>
        public int R_GM_TaskNum;
        /// <summary>
        /// å †åž›æœºå·¥ä½œçŠ¶æ€
        /// </summary>
        public short R_GM_WorkStatus;
        /// <summary>
        /// ä½œä¸šç±»åž‹
        /// </summary>
        public short R_GM_WorkType;
        /// <summary>
        /// æ‰˜ç›˜ç±»åž‹
        /// </summary>
        public short R_GM_TrayType;
        ///站台
        ///<summary>
        /// è¯»å–条码
        /// </summary>
        public string R_GM_Boxcode;
        /// <summary>
        /// æ¡æ‰‹ä¿¡å·
        /// </summary>
        public bool R_GM_HandShake3;
        /// <summary>
        /// 1联机 0脱机
        /// </summary>
        public bool R_GM_Online3;
        /// <summary>
        /// 1空闲 0繁忙
        /// </summary>
        public bool R_GM_Free3;
        /// <summary>
        /// 1有货 0无货
        /// </summary>
        public bool R_GM_Goods3;
        /// <summary>
        /// 1故障 0正常
        /// </summary>
        public bool R_GM_Alarm3;
        /// <summary>
        /// è¯·æ±‚信号(读)
        /// </summary>
        public bool R_GM_STB3;
        /// <summary>
        /// å“åº”信号(读)
        /// </summary>
        public bool R_GM_ACK3;
        /// <summary>
        /// è¯·æ±‚信号(写)
        /// </summary>
        public bool W_GM_STB3;
        /// <summary>
        /// å“åº”信号(写)
        /// </summary>
        public bool W_GM_ACK3;
        /// <summary>
        /// æ¡æ‰‹ä¿¡å·
        /// </summary>
        public bool R_GM_HandShake4;
        /// <summary>
        /// 1联机 0脱机
        /// </summary>
        public bool R_GM_Online4;
        /// <summary>
        /// 1空闲 0繁忙
        /// </summary>
        public bool R_GM_Free4;
        /// <summary>
        /// 1有货 0无货
        /// </summary>
        public bool R_GM_Goods4;
        /// <summary>
        /// 1故障 0正常
        /// </summary>
        public bool R_GM_Alarm4;
        /// <summary>
        /// è¯·æ±‚信号(读)
        /// </summary>
        public bool R_GM_STB4;
        /// <summary>
        /// å“åº”信号(读)
        /// </summary>
        public bool R_GM_ACK4;
        /// <summary>
        /// è¯·æ±‚信号(写)
        /// </summary>
        public bool W_GM_STB4;
        /// <summary>
        /// å“åº”信号(写)
        /// </summary>
        public bool W_GM_ACK4;
        /// <summary>
        /// æ¡æ‰‹ä¿¡å·
        /// </summary>
        public bool R_GM_HandShake5;
        /// <summary>
        /// 1联机 0脱机
        /// </summary>
        public bool R_GM_Online5;
        /// <summary>
        /// 1空闲 0繁忙
        /// </summary>
        public bool R_GM_Free5;
        /// <summary>
        /// 1有货 0无货
        /// </summary>
        public bool R_GM_Goods5;
        /// <summary>
        /// 1故障 0正常
        /// </summary>
        public bool R_GM_Alarm5;
        /// <summary>
        /// è¯·æ±‚信号(读)
        /// </summary>
        public bool R_GM_STB5;
        /// <summary>
        /// å“åº”信号(读)
        /// </summary>
        public bool R_GM_ACK5;
        /// <summary>
        /// è¯·æ±‚信号(写)
        /// </summary>
        public bool W_GM_STB5;
        /// <summary>
        /// å“åº”信号(写)
        /// </summary>
        public bool W_GM_ACK5;
    }
}
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/¸ÉĤ²Ö/StackerCraneJob_GM.cs
@@ -28,6 +28,8 @@
using WIDESEAWCS_QuartzJob.Repository;
using WIDESEAWCS_DTO.TaskInfo;
using AutoMapper;
using HslCommunication.WebSocket;
using WIDESEAWCS_Tasks.干膜仓;
namespace WIDESEAWCS_Tasks
{
@@ -38,13 +40,15 @@
        private readonly ITaskService _taskService;
        private readonly ITaskExecuteDetailService _taskExecuteDetailService;
        private readonly ITaskRepository _taskRepository;
        public static GMReadData gMReadData = new GMReadData();
        private readonly IRouterService _routerService;
        private readonly IStationMangerRepository _stationMangerRepository;
        private readonly IRouterRepository _routerRepository;
        private readonly IMapper _mapper;
        private List<Dt_ApiInfo> apiInfos;
        private WebSocketServer _webSocketServer;
        public StackerCraneJob_GM(ITaskService taskService, ICacheService cacheService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IStationMangerRepository stationMangerRepository, IRouterRepository routerRepository, IMapper mapper)
        public StackerCraneJob_GM(ITaskService taskService, ICacheService cacheService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IStationMangerRepository stationMangerRepository, IRouterRepository routerRepository, IMapper mapper,WebSocketServer webSocketServer)
        {
            _taskService = taskService;
            _taskExecuteDetailService = taskExecuteDetailService;
@@ -54,6 +58,7 @@
            _cacheService = cacheService;
            _routerRepository = routerRepository;
            _mapper = mapper;
            _webSocketServer = webSocketServer;
            string? apiInfoStr = _cacheService.Get("apiInfos");
            if (!string.IsNullOrEmpty(apiInfoStr))
@@ -111,6 +116,14 @@
                            }
                        }
                    }
                    gMReadData.R_GM_Status = ((short)commonStackerCrane.StackerCraneStatusValue);
                    gMReadData.R_GM_AutoStatus = ((short)commonStackerCrane.StackerCraneAutoStatusValue);
                    gMReadData.R_GM_WorkStatus = ((short)commonStackerCrane.StackerCraneWorkStatusValue);
                    gMReadData.R_GM_TaskNum = commonStackerCrane.CurrentTaskNum.ObjToInt();
                    gMReadData.R_GM_WorkType = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType);
                    gMReadData.R_GM_TrayType = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.TrayType);
                    string gMData = JsonConvert.SerializeObject(gMReadData);
                    _webSocketServer.PublishAllClientPayload(gMData);
                }
            }
            catch (Exception ex)
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ÓÍÄ«²Ö/CommonHoisterJob.cs
@@ -1,4 +1,5 @@
using Quartz;
using Autofac.Core;
using Quartz;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -156,6 +157,24 @@
                                WriteError(hoister.DeviceName, $"未找到对应站台信息,{deviceChildCode}");
                            }
                        }
                        if (deviceChildCode == "9001")
                        {
                            StackerCraneJob_YM.yMReadData.R_YM_Tray1 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.Tray, deviceChildCode);
                            StackerCraneJob_YM.yMReadData.R_YM_Leisure1 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.Leisure, deviceChildCode);
                            StackerCraneJob_YM.yMReadData.W_YM_RequestIn1 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.RequestIn, deviceChildCode);
                            StackerCraneJob_YM.yMReadData.W_YM_RequestOut1 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.RequestOut, deviceChildCode);
                            StackerCraneJob_YM.yMReadData.R_YM_Inbounding1 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.Inbounding, deviceChildCode);
                            StackerCraneJob_YM.yMReadData.R_YM_Outbounding1 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.Outbounding, deviceChildCode);
                        }
                        else if (deviceChildCode == "9002")
                        {
                            StackerCraneJob_YM.yMReadData.R_YM_Tray2 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.Tray, deviceChildCode);
                            StackerCraneJob_YM.yMReadData.R_YM_Leisure2 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.Leisure, deviceChildCode);
                            StackerCraneJob_YM.yMReadData.W_YM_RequestIn2 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.RequestIn, deviceChildCode);
                            StackerCraneJob_YM.yMReadData.W_YM_RequestOut2 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.RequestOut, deviceChildCode);
                            StackerCraneJob_YM.yMReadData.R_YM_Inbounding2 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.Inbounding, deviceChildCode);
                            StackerCraneJob_YM.yMReadData.R_YM_Outbounding2 = hoister.GetValue<HoisterDBName, bool>(HoisterDBName.Outbounding, deviceChildCode);
                        }
                    }
                }
            }
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ÓÍÄ«²Ö/StackerCraneJob_YM.cs
@@ -1,4 +1,5 @@
using Microsoft.AspNetCore.Components.Routing;
using HslCommunication.WebSocket;
using Microsoft.AspNetCore.Components.Routing;
using Newtonsoft.Json;
using Quartz;
using System;
@@ -24,6 +25,8 @@
using WIDESEAWCS_QuartzJob.StackerCrane.Enum;
using WIDESEAWCS_Tasks.HoisterJob;
using WIDESEAWCS_Tasks.StackerCraneJob;
using WIDESEAWCS_Tasks.油墨仓;
using WIDESEAWCS_Tasks.阻焊仓;
namespace WIDESEAWCS_Tasks
{
@@ -35,12 +38,14 @@
    {
        private readonly ICacheService _cacheService;
        private readonly ITaskService _taskService;
        public static YMReadData yMReadData = new YMReadData();
        private readonly ITaskExecuteDetailService _taskExecuteDetailService;
        private readonly ITaskRepository _taskRepository;
        private readonly IRouterService _routerService;
        private readonly IStationMangerRepository _stationMangerRepository;
        private WebSocketServer _webSocketServer;
        public StackerCraneJob_YM(ITaskService taskService, ICacheService cacheService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IStationMangerRepository stationMangerRepository)
        public StackerCraneJob_YM(ITaskService taskService, ICacheService cacheService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IStationMangerRepository stationMangerRepository,WebSocketServer webSocketServer)
        {
            _cacheService = cacheService;
            _taskService = taskService;
@@ -48,6 +53,7 @@
            _taskRepository = taskRepository;
            _routerService = routerService;
            _stationMangerRepository = stationMangerRepository;
            _webSocketServer = webSocketServer;
        }
        public Task Execute(IJobExecutionContext context)
@@ -87,6 +93,14 @@
                                }
                            }
                        }
                        yMReadData.R_YM_Status = ((short)commonStackerCrane.StackerCraneStatusValue);
                        yMReadData.R_YM_AutoStatus = ((short)commonStackerCrane.StackerCraneAutoStatusValue);
                        yMReadData.R_YM_WorkStatus = ((short)commonStackerCrane.StackerCraneWorkStatusValue);
                        yMReadData.R_YM_TaskNum = commonStackerCrane.CurrentTaskNum.ObjToInt();
                        yMReadData.R_YM_WorkType = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType);
                        yMReadData.R_YM_TrayType = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.TrayType);
                        string yMData = JsonConvert.SerializeObject(yMReadData);
                        _webSocketServer.PublishAllClientPayload(yMData);
                    }
                }
                catch (Exception ex)
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/ÓÍÄ«²Ö/YMReadData.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,106 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEAWCS_Tasks.油墨仓
{
    public class YMReadData
    {
        /// <summary>
        /// å †åž›æœºçŠ¶æ€
        /// </summary>
        public short R_YM_Status;
        /// <summary>
        /// å †åž›æœºæ‰‹è‡ªåŠ¨çŠ¶æ€
        /// </summary>
        public short R_YM_AutoStatus;
        /// <summary>
        /// å½“前正在执行的任务号
        /// </summary>
        public int R_YM_TaskNum;
        /// <summary>
        /// å †åž›æœºå·¥ä½œçŠ¶æ€
        /// </summary>
        public short R_YM_WorkStatus;
        /// <summary>
        /// ä½œä¸šç±»åž‹
        /// </summary>
        public short R_YM_WorkType;
        /// <summary>
        /// æ‰˜ç›˜ç±»åž‹
        /// </summary>
        public short R_YM_TrayType;
        ///提升机
        /// <summary>
        /// æœ‰è´§(读)
        /// </summary>
        public bool R_YM_Tray1;
        /// <summary>
        /// å…¥åº“执行中(读)
        /// </summary>
        public bool R_YM_Inbounding1;
        /// <summary>
        /// æå‡æœºç©ºé—²(读)
        /// </summary>
        public bool R_YM_Leisure1;
        /// <summary>
        /// å‡ºåº“执行中(读)
        /// </summary>
        public bool R_YM_Outbounding1;
        /// <summary>
        /// ç”³è¯·å…¥åº“(写)
        /// </summary>
        public bool W_YM_RequestIn1;
        /// <summary>
        /// ç”³è¯·å‡ºåº“(写)
        /// </summary>
        public bool W_YM_RequestOut1;
        /// <summary>
        /// æœ‰è´§(读)
        /// </summary>
        public bool R_YM_Tray2;
        /// <summary>
        /// å…¥åº“执行中(读)
        /// </summary>
        public bool R_YM_Inbounding2;
        /// <summary>
        /// æå‡æœºç©ºé—²(读)
        /// </summary>
        public bool R_YM_Leisure2;
        /// <summary>
        /// å‡ºåº“执行中(读)
        /// </summary>
        public bool R_YM_Outbounding2;
        /// <summary>
        /// ç”³è¯·å…¥åº“(写)
        /// </summary>
        public bool W_YM_RequestIn2;
        /// <summary>
        /// ç”³è¯·å‡ºåº“(写)
        /// </summary>
        public bool W_YM_RequestOut2;
    }
}
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/¸¨ÁϲÖ/ConveyorLineJob_FL.cs
@@ -1,10 +1,12 @@
using Microsoft.AspNetCore.Components.Routing;
using HslCommunication.WebSocket;
using Microsoft.AspNetCore.Components.Routing;
using Newtonsoft.Json;
using Quartz;
using SqlSugar.Extensions;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using WIDESEAWCS_Common;
@@ -19,6 +21,7 @@
using WIDESEAWCS_QuartzJob.Repository;
using WIDESEAWCS_QuartzJob.Service;
using WIDESEAWCS_Tasks.ConveyorLineJob;
using WIDESEAWCS_Tasks.辅料仓;
using ICacheService = WIDESEAWCS_Core.Caches.ICacheService;
namespace WIDESEAWCS_Tasks
@@ -30,13 +33,15 @@
        private readonly ITaskService _taskService;
        private readonly ITaskExecuteDetailService _taskExecuteDetailService;
        private readonly ITaskRepository _taskRepository;
        public static FLReadData fLReadData = new FLReadData();
        private readonly IStationMangerRepository _stationMangerRepository;
        private readonly IRouterRepository _routerRepository;
        private readonly IRouterService _routerService;
        private readonly IRouterExtension _routerExtension;
        private readonly List<Dt_WarehouseDevice> warehouseDevices;
        private WebSocketServer _webSocketServer;
        public ConveyorLineJob_FL(ICacheService cacheService, ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IStationMangerRepository stationMangerRepository, IRouterRepository routerRepository, IRouterService routerService, IRouterExtension routerExtension)
        public ConveyorLineJob_FL(ICacheService cacheService, ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IStationMangerRepository stationMangerRepository, IRouterRepository routerRepository, IRouterService routerService, IRouterExtension routerExtension,WebSocketServer webSocketServer)
        {
            _cacheService = cacheService;
            _taskService = taskService;
@@ -46,6 +51,7 @@
            _routerRepository = routerRepository;
            _routerService = routerService;
            _routerExtension = routerExtension;
            _webSocketServer = webSocketServer;
            string? warehouseDevicesStr = _cacheService.Get<string>(nameof(Dt_WarehouseDevice));
            if (!string.IsNullOrEmpty(warehouseDevicesStr))
@@ -98,6 +104,22 @@
                                _taskService.UpdateTask(newTask, TaskStatusEnum.Line_Executing);
                            }
                        }
                        if (item.StationCode == "8005")
                        {
                            R_ConveyorLineFLInfo conveyorLineInfoRead = device.Communicator.ReadCustomer<R_ConveyorLineFLInfo>(deviceProRead.DeviceProAddress);
                            bool conveyArrivaled = device.GetValue<R_ConveyorLineFLDB, bool>(R_ConveyorLineFLDB.ConveyArrivaled, item.StationCode);
                            fLReadData.W_PutFinish5 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_PutFinish, item.StationCode);
                            fLReadData.R_ConveyArrivaled5 = device.GetValue<R_ConveyorLineFLDB, bool>(R_ConveyorLineFLDB.ConveyArrivaled, item.StationCode);
                            fLReadData.R_Barcode5 = conveyorLineInfoRead.Barcode;
                            fLReadData.R_TaskNum5 = conveyorLineInfoRead.TaskNum;
                        }
                        else if (item.StationCode == "8001")
                        {
                            fLReadData.W_PutFinish1 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_PutFinish, item.StationCode);
                            fLReadData.R_IsCanPut = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.R_IsCanPut, item.StationCode);
                        }
                        string yMData = JsonConvert.SerializeObject(fLReadData);
                        _webSocketServer.PublishAllClientPayload(yMData);
                    }
                }
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/¸¨ÁϲÖ/FLReadData.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEAWCS_Tasks.辅料仓
{
    public class FLReadData
    {
        ///输送线
        /// <summary>
        /// æ”¾è´§å®Œæˆ(写)
        /// </summary>
        public bool W_PutFinish5;
        /// <summary>
        /// æ‰˜ç›˜å·
        /// </summary>
        public string W_Barcode5;
        /// <summary>
        /// å†™å…¥ä»»åŠ¡å·
        /// </summary>
        public string W_TaskNum5;
        /// <summary>
        /// å…¥åº“到位指令
        /// </summary>
        public bool R_ConveyArrivaled5;
        /// <summary>
        /// å…¥åº“到位托盘号
        /// </summary>
        public string R_Barcode5;
        /// <summary>
        /// å…¥åº“到位任务号
        /// </summary>
        public string R_TaskNum5;
        /// <summary>
        /// æ”¾è´§å®Œæˆ(写)
        /// </summary>
        public bool W_PutFinish1;
        /// <summary>
        /// æ˜¯å¦å…è®¸æ”¾è´§(读)
        /// </summary>
        public bool R_IsCanPut;
    }
}
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/×躸²Ö/GroundStationJob_ZH.cs
@@ -15,6 +15,7 @@
using WIDESEAWCS_Model.Models;
using WIDESEAWCS_QuartzJob;
using WIDESEAWCS_Tasks.HoisterJob;
using WIDESEAWCS_Tasks.阻焊仓;
namespace WIDESEAWCS_Tasks
{
@@ -100,6 +101,49 @@
                                _taskService.UpdateTask(task, TaskStatusEnum.SC_Execute, currentAddress: stationManger.StackerCraneStationCode, targetAddress: locationCode, nextAddress: locationCode, deviceCode: stationManger.StackerCraneCode);
                            }
                        }
                        if (item.StationCode == "301")
                        {
                            StackerCraneJob_ZH.zHReadData.R_ZH_TakePalletType1= device.GetValue<GroundStationDBName, short>(GroundStationDBName.R_TakePalletType, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.R_ZH_IsCanPut1 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.R_IsCanPut, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.R_ZH_IsCanTake1 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.R_IsCanTake, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutPalletType1 = device.GetValue<GroundStationDBName, short>(GroundStationDBName.W_PutPalletType, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutRequest1 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_PutRequest, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutFinish1 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_PutFinish, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_TakeRequest1 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_TakeRequest, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_TakeFinish1 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_TakeFinish, item.StationCode);
                        }else if(item.StationCode == "302")
                        {
                            StackerCraneJob_ZH.zHReadData.R_ZH_TakePalletType2 = device.GetValue<GroundStationDBName, short>(GroundStationDBName.R_TakePalletType, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.R_ZH_IsCanPut2 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.R_IsCanPut, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.R_ZH_IsCanTake2 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.R_IsCanTake, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutPalletType2 = device.GetValue<GroundStationDBName, short>(GroundStationDBName.W_PutPalletType, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutRequest2 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_PutRequest, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutFinish2 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_PutFinish, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_TakeRequest2 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_TakeRequest, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_TakeFinish2 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_TakeFinish, item.StationCode);
                        }
                        else if (item.StationCode == "303")
                        {
                            StackerCraneJob_ZH.zHReadData.R_ZH_TakePalletType3 = device.GetValue<GroundStationDBName, short>(GroundStationDBName.R_TakePalletType, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.R_ZH_IsCanPut3 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.R_IsCanPut, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.R_ZH_IsCanTake3 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.R_IsCanTake, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutPalletType3 = device.GetValue<GroundStationDBName, short>(GroundStationDBName.W_PutPalletType, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutRequest3 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_PutRequest, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutFinish3 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_PutFinish, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_TakeRequest3 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_TakeRequest, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_TakeFinish3 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_TakeFinish, item.StationCode);
                        }
                        else if (item.StationCode == "304")
                        {
                            StackerCraneJob_ZH.zHReadData.R_ZH_TakePalletType4 = device.GetValue<GroundStationDBName, short>(GroundStationDBName.R_TakePalletType, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.R_ZH_IsCanPut4 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.R_IsCanPut, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.R_ZH_IsCanTake4 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.R_IsCanTake, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutPalletType4 = device.GetValue<GroundStationDBName, short>(GroundStationDBName.W_PutPalletType, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutRequest4 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_PutRequest, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_PutFinish4 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_PutFinish, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_TakeRequest4 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_TakeRequest, item.StationCode);
                            StackerCraneJob_ZH.zHReadData.W_ZH_TakeFinish4 = device.GetValue<GroundStationDBName, bool>(GroundStationDBName.W_TakeFinish, item.StationCode);
                        }
                    }
                    catch (Exception ex)
                    {
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/×躸²Ö/StackerCraneJob_ZH.cs
@@ -27,6 +27,8 @@
using WIDESEAWCS_DTO.TaskInfo;
using WIDESEAWCS_Core.Caches;
using AutoMapper;
using WIDESEAWCS_Tasks.阻焊仓;
using HslCommunication.WebSocket;
namespace WIDESEAWCS_Tasks
{
@@ -35,14 +37,16 @@
    {
        private readonly ITaskService _taskService;
        private readonly ITaskExecuteDetailService _taskExecuteDetailService;
        public static ZHReadData zHReadData = new ZHReadData();
        private readonly ITaskRepository _taskRepository;
        private readonly IRouterService _routerService;
        private readonly IStationMangerRepository _stationMangerRepository;
        private readonly ICacheService _cacheService;
        private readonly IMapper _mapper;
        private WebSocketServer _webSocketServer;
        private List<Dt_ApiInfo> apiInfos;
        public StackerCraneJob_ZH(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IStationMangerRepository stationMangerRepository,ICacheService cacheService, IMapper mapper)
        public StackerCraneJob_ZH(ITaskService taskService, ITaskExecuteDetailService taskExecuteDetailService, ITaskRepository taskRepository, IRouterService routerService, IStationMangerRepository stationMangerRepository,ICacheService cacheService, IMapper mapper, WebSocketServer webSocketServer)
        {
            _taskService = taskService;
            _taskExecuteDetailService = taskExecuteDetailService;
@@ -51,6 +55,7 @@
            _stationMangerRepository = stationMangerRepository;
            _cacheService = cacheService;
            _mapper = mapper;
            _webSocketServer = webSocketServer;
            string? apiInfoStr = _cacheService.Get("apiInfos");
            if (!string.IsNullOrEmpty(apiInfoStr))
            {
@@ -100,6 +105,14 @@
                            }
                        }
                    }
                    zHReadData.R_ZH_Status = ((short)commonStackerCrane.StackerCraneStatusValue);
                    zHReadData.R_ZH_AutoStatus = ((short)commonStackerCrane.StackerCraneAutoStatusValue);
                    zHReadData.R_ZH_WorkStatus = ((short)commonStackerCrane.StackerCraneWorkStatusValue);
                    zHReadData.R_ZH_TaskNum = commonStackerCrane.CurrentTaskNum.ObjToInt();
                    zHReadData.R_ZH_WorkType = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.WorkType);
                    zHReadData.R_ZH_TrayType = commonStackerCrane.GetValue<StackerCraneDBName, short>(StackerCraneDBName.TrayType);
                    string zHData = JsonConvert.SerializeObject(zHReadData);
                    _webSocketServer.PublishAllClientPayload(zHData);
                }
            }
            catch (Exception ex)
´úÂë¹ÜÀí/WCS/WIDESEAWCS_Server/WIDESEAWCS_Tasks/×躸²Ö/ZHReadData.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,174 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEAWCS_Tasks.阻焊仓
{
    public class ZHReadData
    {
        /// <summary>
        /// å †åž›æœºçŠ¶æ€
        /// </summary>
        public short R_ZH_Status;
        /// <summary>
        /// å †åž›æœºæ‰‹è‡ªåŠ¨çŠ¶æ€
        /// </summary>
        public short R_ZH_AutoStatus;
        /// <summary>
        /// å½“前正在执行的任务号
        /// </summary>
        public int R_ZH_TaskNum;
        /// <summary>
        /// å †åž›æœºå·¥ä½œçŠ¶æ€
        /// </summary>
        public short R_ZH_WorkStatus;
        /// <summary>
        /// ä½œä¸šç±»åž‹
        /// </summary>
        public short R_ZH_WorkType;
        /// <summary>
        /// æ‰˜ç›˜ç±»åž‹
        /// </summary>
        public short R_ZH_TrayType;
        ///各站台读取301
        ///取货托盘类型(读)
        public short R_ZH_TakePalletType1;
        /// <summary>
        /// æ”¾è´§æ‰˜ç›˜ç±»åž‹(写)
        /// </summary>
        public short W_ZH_PutPalletType1;
        /// <summary>
        /// æ˜¯å¦å…è®¸æ”¾è´§(读)
        /// </summary>
        public bool R_ZH_IsCanPut1;
        /// <summary>
        /// æ˜¯å¦å…è®¸å–è´§(读)
        /// </summary>
        public bool R_ZH_IsCanTake1;
        /// <summary>
        /// æ”¾è´§è¯·æ±‚(写)
        /// </summary>
        public bool W_ZH_PutRequest1;
        /// <summary>
        /// æ”¾è´§å®Œæˆ(写)
        /// </summary>
        public bool W_ZH_PutFinish1;
        /// <summary>
        /// å–货请求(写)
        /// </summary>
        public bool W_ZH_TakeRequest1;
        /// <summary>
        /// å–货完成(写)
        /// </summary>
        public bool W_ZH_TakeFinish1;
        ///各站台读取302
        ///取货托盘类型(读)
        public short R_ZH_TakePalletType2;
        /// <summary>
        /// æ”¾è´§æ‰˜ç›˜ç±»åž‹(写)
        /// </summary>
        public short W_ZH_PutPalletType2;
        /// <summary>
        /// æ˜¯å¦å…è®¸æ”¾è´§(读)
        /// </summary>
        public bool R_ZH_IsCanPut2;
        /// <summary>
        /// æ˜¯å¦å…è®¸å–è´§(读)
        /// </summary>
        public bool R_ZH_IsCanTake2;
        /// <summary>
        /// æ”¾è´§è¯·æ±‚(写)
        /// </summary>
        public bool W_ZH_PutRequest2;
        /// <summary>
        /// æ”¾è´§å®Œæˆ(写)
        /// </summary>
        public bool W_ZH_PutFinish2;
        /// <summary>
        /// å–货请求(写)
        /// </summary>
        public bool W_ZH_TakeRequest2;
        /// <summary>
        /// å–货完成(写)
        /// </summary>
        public bool W_ZH_TakeFinish2;
        ///各站台读取303
        ///取货托盘类型(读)
        public short R_ZH_TakePalletType3;
        /// <summary>
        /// æ”¾è´§æ‰˜ç›˜ç±»åž‹(写)
        /// </summary>
        public short W_ZH_PutPalletType3;
        /// <summary>
        /// æ˜¯å¦å…è®¸æ”¾è´§(读)
        /// </summary>
        public bool R_ZH_IsCanPut3;
        /// <summary>
        /// æ˜¯å¦å…è®¸å–è´§(读)
        /// </summary>
        public bool R_ZH_IsCanTake3;
        /// <summary>
        /// æ”¾è´§è¯·æ±‚(写)
        /// </summary>
        public bool W_ZH_PutRequest3;
        /// <summary>
        /// æ”¾è´§å®Œæˆ(写)
        /// </summary>
        public bool W_ZH_PutFinish3;
        /// <summary>
        /// å–货请求(写)
        /// </summary>
        public bool W_ZH_TakeRequest3;
        /// <summary>
        /// å–货完成(写)
        /// </summary>
        public bool W_ZH_TakeFinish3;
        ///各站台读取304
        ///取货托盘类型(读)
        public short R_ZH_TakePalletType4;
        /// <summary>
        /// æ”¾è´§æ‰˜ç›˜ç±»åž‹(写)
        /// </summary>
        public short W_ZH_PutPalletType4;
        /// <summary>
        /// æ˜¯å¦å…è®¸æ”¾è´§(读)
        /// </summary>
        public bool R_ZH_IsCanPut4;
        /// <summary>
        /// æ˜¯å¦å…è®¸å–è´§(读)
        /// </summary>
        public bool R_ZH_IsCanTake4;
        /// <summary>
        /// æ”¾è´§è¯·æ±‚(写)
        /// </summary>
        public bool W_ZH_PutRequest4;
        /// <summary>
        /// æ”¾è´§å®Œæˆ(写)
        /// </summary>
        public bool W_ZH_PutFinish4;
        /// <summary>
        /// å–货请求(写)
        /// </summary>
        public bool W_ZH_TakeRequest4;
        /// <summary>
        /// å–货完成(写)
        /// </summary>
        public bool W_ZH_TakeFinish4;
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/outbound/extend/AddErpProScrapSheet.vue
@@ -401,12 +401,6 @@
      this.proCodeOptions = [];
    }
  },
  created() {
    // åˆå§‹åŒ–时预加载仓库数据
    if (this.warehouses.length === 0) {
      this.getWarehouseList();
    }
  }
};
</script>
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/stock/ProStockView.js
@@ -78,6 +78,29 @@
          }
        }
        if (column.field == 'proinventoryage') {
          const today = new Date()
          column.formatter = (row) => {
              if (row.details.length > 0) {
                  const closestDate = row.details
                      .map(x => {
                          const date = new Date(x.createDate);
                          const ageInDays = Math.ceil((today - date) / (1000 * 60 * 60 * 24));
                          return { date, ageInDays };
                      })
                      .reduce((closest, current) => (current.ageInDays < closest.ageInDays ? current : closest))
                      .date;
                  const inventoryAge = Math.ceil((today - closestDate) / (1000 * 60 * 60 * 24));
                  row.inventoryAge = inventoryAge;
                  return `${inventoryAge} å¤©`;
              }
              // å¦‚果没有明细,返回空或提示信息
              return '-';
          }
        }
        if (column.field == 'sumStock') {
          column.formatter = (row) => {
            if (row.details.length > 0) {
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/stock/stockView.js
@@ -1,4 +1,3 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
import { el } from "element-plus/es/locales.mjs";
@@ -54,36 +53,58 @@
            return str = list[0] == "" ? "无" : str;
          }
        }
    if (column.field == 'materielInfo') {
    const today = new Date()
    column.formatter = (row) => {
        if (row.details.length > 0) {
            const today = new Date();
            const closestDate = row.details
                .map(x => {
                    const date = new Date(x.effectiveDate);
                    const diffInDays = Math.ceil((date - today) / (1000 * 60 * 60 * 24)); // æ”¹ä¸ºè®¡ç®—剩余天数
                    return { date, diffInDays };
                })
                .reduce((closest, current) => (current.diffInDays < closest.diffInDays ? current : closest))
                .date;
        if (column.field == 'materielInfo') {
        const today = new Date()
        column.formatter = (row) => {
            if (row.details.length > 0) {
                const today = new Date();
                const closestDate = row.details
                    .map(x => {
                        const date = new Date(x.effectiveDate);
                        const diffInDays = Math.ceil((date - today) / (1000 * 60 * 60 * 24)); // æ”¹ä¸ºè®¡ç®—剩余天数
                        return { date, diffInDays };
                    })
                    .reduce((closest, current) => (current.diffInDays < closest.diffInDays ? current : closest))
                    .date;
            const daysRemaining = Math.ceil((closestDate - today) / (1000 * 60 * 60 * 24));
            row.expiryDays = daysRemaining;
            if (daysRemaining <= 0) {
                return '<span style="color:rgb(30, 27, 27)">无保质期</span>';
                const daysRemaining = Math.ceil((closestDate - today) / (1000 * 60 * 60 * 24));
                row.expiryDays = daysRemaining;
                if (daysRemaining <= 0) {
                    return '<span style="color:rgb(30, 27, 27)">无保质期</span>';
                } else {
                    return '<span style="color: #F56C6C">' + daysRemaining + "天" + '</span>';
                }
            } else {
                return '<span style="color: #F56C6C">' + daysRemaining + "天" + '</span>';
                row.expiryDays = null;
                return '<span style="color:rgb(24, 18, 18)">无保质期</span>';
            }
        } else {
            row.expiryDays = null;
            return '<span style="color:rgb(24, 18, 18)">无保质期</span>';
        }
    }
        }
      }
      if (column.field == 'inventoryage') {
          const today = new Date()
          column.formatter = (row) => {
              if (row.details.length > 0) {
                  const closestDate = row.details
                      .map(x => {
                          const date = new Date(x.createDate);
                          const ageInDays = Math.ceil((today - date) / (1000 * 60 * 60 * 24));
                          return { date, ageInDays };
                      })
                      .reduce((closest, current) => (current.ageInDays < closest.ageInDays ? current : closest))
                      .date;
                  const inventoryAge = Math.ceil((today - closestDate) / (1000 * 60 * 60 * 24));
                  row.inventoryAge = inventoryAge;
                  return `${inventoryAge} å¤©`;
              }
              // å¦‚果没有明细,返回空或提示信息
              return '-';
          }
        }
        if (column.field == 'sumStock') {
          column.formatter = (row) => {
@@ -93,9 +114,9 @@
                .map(x => {
                  sum += (x.stockQuantity)
                })
              return '<span style="color: #F56C6C">' + sum.toFixed(3) + row.details[0].unit + '</span>';
              return '<span style="color: rgb(24, 18, 18)">' + sum.toFixed(3) + row.details[0].unit + '</span>';
            } else {
              return '<span style="color: #F56C6C">' + "1个" + '</span>';
              return '<span style="color: rgb(24, 18, 18)">' + "1个" + '</span>';
            }
          }
@@ -103,28 +124,17 @@
      })
      this.columns.forEach((column) => {
        column.cellStyle = (row) => {
        // åªå¤„理有保质期数据的情况
        if (row.expiryDays !== null && row.expiryDays !== undefined) {
            if (row.expiryDays <= 0) {
                return { background: 'red' }; // çº¢è‰²èƒŒæ™¯ï¼ˆå·²è¿‡æœŸï¼‰
            } else if (row.expiryDays <= 30) {
                return { background: 'yellow' }; // é»„色背景(临期)
          if (row.expirationlabel !== undefined && row.expirationlabel !== null) {
            if (row.expirationlabel === 2) {
              return { background: 'yellow' };
            } else if (row.expirationlabel === 3) {
              return { background: '#ffc0cb' };
            }
        }
        return {}; // é»˜è®¤æ— èƒŒæ™¯è‰²
    };
          }
          return {};
        };
      });
        //如果根据行的某个值设置整行颜色
        //设置整行背景颜色
        // x.cellStyle = (row, rowIndex, columnIndex) => {
        //   if (row.ProductCode == '10044464880643') {
        //     return { background: '#ddecfd' };
        //   }
        // };
        });
    },
    onInited() {
      //框架初始化配置后
@@ -172,4 +182,4 @@
    }
  }
};
export default extension;
export default extension;
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/extension/taskinfo/task.js
@@ -20,6 +20,12 @@
        let TaskHandCancelBtn = this.buttons.find(x => x.value == 'TaskHandCancel');
      if (TaskHandCancelBtn) {
        TaskHandCancelBtn.onClick = function () {
          this.$confirm("是否确认取消任务","手动任务取消警告",{
              confirmButtonText: "确定",
              cancelButtonText: "取消",
              type: "warning",
              center: true,
              }).then(() => {
          let rows = this.$refs.table.getSelected();
          if (rows.length == 0) return this.$error("请选择数据!");
          if (rows.length > 1) return this.$error("请选择一条数据!");
@@ -35,6 +41,8 @@
                return this.$error(x.message);
              }
            });
            });
        }
      }
      let TaskHandCompletedBtn = this.buttons.find(x => x.value == 'TaskHandCompleted');
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/inbound/inboundOrder.vue
@@ -136,7 +136,7 @@
          type: "string",
          width: 90,
          align: "left",
          bind:{key: "warehouses", data: []}
          bind:{ key: "warehouses", data: []}
      },
      {
        field: "orderType",
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/outbound/outStockLockInfo.vue
@@ -113,6 +113,9 @@
        { title: "任务号", field: "taskNum", type: "like" },
        { title: "状态", field: "status", type: "select",dataKey:"outLockStockStatusEnum", data:[]},
      ],
      [
        { title: "出库时间",field: "createDate",type: "datetime"},
      ],
    ]);
    const columns = ref([
      {
@@ -129,7 +132,7 @@
        field: "orderNo",
        title: "单据编号",
        type: "string",
        width: 150,
        width: 180,
        align: "left",
        
      },
@@ -189,7 +192,7 @@
        field: "locationCode",
        title: "货位编号",
        type: "datetime",
        width: 160,
        width: 220,
        align: "left",
      },
      {
@@ -235,6 +238,20 @@
        align: "left",
        bind:{key:"outLockStockStatusEnum", data: []}
      },
      {
        field: "creater",
        title: "创建人",
        type: "string",
        width: 90,
        align: "left",
      },
      {
        field: "createDate",
        title: "创建时间",
        type: "datetime",
        width: 160,
        align: "left",
      },
    ]);
    const detail = ref({
      cnName: "#detailCnName",
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/stock/ProStockView.vue
@@ -56,6 +56,7 @@
        ],
        [
          { title: "产品版本", field: "productVersion",type: "like"},
          { title: "库存创建时间",field: "createDate",type: "datetime"},
        ]
      ]);
      const columns = ref([
@@ -144,6 +145,13 @@
          align: "left",
        },
        {
          field: "proinventoryage",
          title: "成品库龄",
          type: "string",
          width: 80,
          align: "left",
        },
        {
          field: "lotNumber",
          title: "产品批号",
          type: "string",
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/stock/stockInfoDetail.vue
@@ -124,6 +124,7 @@
      [
        { title: "批次号", field: "batchNo",type :"like"},
        {title: "库存明细状态",field: "status",type: "select",dataKey:"stockStatusEmun", data: []},
        { title: "有效期查询",field: "effectiveDate",type: "datetime"},
      ],
    ]);
    const columns = ref([
´úÂë¹ÜÀí/WMS/WIDESEA_WMSClient/src/views/stock/stockView.vue
@@ -51,6 +51,11 @@
        { title: "物料编号", field: "materielCode",type: "like"},
        { title: "批次号", field: "batchNo",type: "like"},
        { title: "所属仓库", field: "warehouseId",type: "selectList",dataKey: "warehouses",data: [],},
        { title: "库存创建时间",field: "createDate",type: "datetime"},
      ],
      [
        { title: "有效期查询",field: "effectiveDate",type: "date"},
        {title: "物料有效期",field: "expirationlabel",type: "selectList",dataKey:"expirationlabelEnum",data:[]},
      ],
    ]);
    const columns = ref([
@@ -117,8 +122,23 @@
        align: "left"
      },
      {
        field: "expirationlabel",
        title: "物料有效期",
        type: "string",
        width: 140,
        align: "left",
        bind: { key: "expirationlabelEnum", data: [] },
      },
      {
        field: "materielInfo",
        title: "所含物料最早临期",
        type: "string",
        width: 140,
        align: "left",
      },
      {
        field: "inventoryage",
        title: "库龄",
        type: "string",
        width: 140,
        align: "left",
@@ -170,6 +190,7 @@
        align: "left",
        bind: { key: "stockStatusEmun", data: [] },
      },
      {
        field: "locationType",
        title: "货位类型",
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_Common/StockEnum/ExpirationlabelEnum.cs
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WIDESEA_Common.StockEnum
{
    public enum ExpirationlabelEnum
    {
        [Description("未临期")]
        æœªä¸´æœŸ = 1,
        [Description("临期预警")]
        ä¸´æœŸé¢„è­¦ = 2,
        [Description("过期")]
        è¿‡æœŸ = 3,
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_Core/Helper/UtilConvert.cs
@@ -958,10 +958,10 @@
                case HtmlElementType.Contains:
                    linqExpression = LinqExpressionType.In;
                    break;
                case HtmlElementType.ThanOrEqual:
                case HtmlElementType.thanorequal:
                    linqExpression = LinqExpressionType.ThanOrEqual;
                    break;
                case HtmlElementType.LessOrequal:
                case HtmlElementType.lessorequal:
                    linqExpression = LinqExpressionType.LessThanOrEqual;
                    break;
                case HtmlElementType.GT:
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_Core/Utilities/EntityProperties.cs
@@ -88,16 +88,19 @@
                else
                {
                    int length = sugarColumn.Length;
                    if (length == 0) { return (true, null, value); }
                    //判断双字节与单字段
                    else if (length < 8000 &&
                        ((dbType.Substring(0, 1) != "n"
                        && Encoding.UTF8.GetBytes(val.ToCharArray()).Length > length)
                         || val.Length > length)
                         )
                    if (sugarColumn != null)
                    {
                        reslutMsg = $"最多只能【{length}】个字符。";
                        int length = sugarColumn.Length;
                        if (length == 0) { return (true, null, null); }
                        //判断双字节与单字段
                        else if (length < 8000 &&
                            ((dbType.Substring(0, 1) != "n"
                            && Encoding.UTF8.GetBytes(val.ToCharArray()).Length > length)
                             || val.Length > length)
                             )
                        {
                            reslutMsg = $"最多只能【{length}】个字符。";
                        }
                    }
                }
            }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_DTO/Stock/StockViewDTO.cs
@@ -134,6 +134,12 @@
        public int StockStatus { get; set; }
        /// <summary>
        /// åº“存超期标识
        /// </summary>
        [ExporterHeader(IsIgnore = true)]
        public int Expirationlabel { get; set; }
        /// <summary>
        /// åº“存备注
        /// </summary>
        [ExporterHeader(IsIgnore = true)]
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs
@@ -29,5 +29,7 @@
        List<PPStockSelectViewDTO> PPGetStockSelectViews(int orderId, string materielCode);
        List<PPStockSelectViewDTO> PPGetPKStockSelectViews(int orderId, string materielCode);
        WebResponseContent UpdateExpirationlabel();
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Outbound/Dt_OutboundLockInfo.cs
@@ -1,4 +1,5 @@
using SqlSugar;
using Magicodes.ExporterAndImporter.Core;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
@@ -18,106 +19,124 @@
        /// <summary>
        /// ä¸»é”®
        /// </summary>
        [ExporterHeader(DisplayName = "主键")]
        [SugarColumn(IsPrimaryKey = true, IsIdentity = true, ColumnDescription = "主键")]
        public int Id { get; set; }
        /// <summary>
        /// å•据编号
        /// </summary>
        [ExporterHeader(DisplayName = "单据编号")]
        [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "单据编号")]
        public string OrderNo { get; set; }
        /// <summary>
        /// å•据明细主键
        /// </summary>
        [ExporterHeader(DisplayName = "单据明细主键")]
        [SugarColumn(IsNullable = false, ColumnDescription = "单据明细主键")]
        public int OrderDetailId { get; set; }
        /// <summary>
        /// å•据类型
        /// </summary>
        [ExporterHeader(DisplayName = "单据类型")]
        [SugarColumn(IsNullable = false, ColumnDescription = "单据类型")]
        public int OrderType { get; set; }
        /// <summary>
        /// æ‰¹æ¬¡å·
        /// </summary>
        [ExporterHeader(DisplayName = "批次号")]
        [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "批次号")]
        public string BatchNo { get; set; }
        /// <summary>
        /// ç‰©æ–™ç¼–号
        /// </summary>
        [ExporterHeader(DisplayName = "物料编号")]
        [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "物料编号")]
        public string MaterielCode { get; set; }
        /// <summary>
        /// ç‰©æ–™åç§°
        /// </summary>
        [ExporterHeader(DisplayName = "物料名称")]
        [SugarColumn(IsNullable = true, Length = 200, ColumnDescription = "物料名称")]
        public string MaterielName { get; set; }
        /// <summary>
        /// åº“存主键
        /// </summary>
        [ExporterHeader(DisplayName = "库存主键")]
        [SugarColumn(IsNullable = false, ColumnDescription = "库存主键")]
        public int StockId { get; set; }
        /// <summary>
        /// å•据数量
        /// </summary>
        [ExporterHeader(DisplayName = "单据数量")]
        [SugarColumn(IsNullable = false, ColumnDescription = "单据数量")]
        public float OrderQuantity { get; set; }
        /// <summary>
        /// åŽŸå§‹åº“å­˜é‡
        /// </summary>
        [ExporterHeader(DisplayName = "原始库存量")]
        [SugarColumn(IsNullable = false, ColumnDescription = "原始库存量")]
        public float OriginalQuantity {  get; set; }
        /// <summary>
        /// åˆ†é…å‡ºåº“量
        /// </summary>
        [ExporterHeader(DisplayName = "分配出库量")]
        [SugarColumn(IsNullable = false, ColumnDescription = "分配出库量")]
        public float AssignQuantity {  get; set; }
        /// <summary>
        /// è´§ä½ç¼–号
        /// </summary>
        [ExporterHeader(DisplayName = "货位编号")]
        [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "货位编号")]
        public string LocationCode { get; set; }
        /// <summary>
        /// æ‰˜ç›˜ç¼–号
        /// </summary>
        [ExporterHeader(DisplayName = "托盘编号")]
        [SugarColumn(IsNullable = false, Length = 50, ColumnDescription = "托盘编号")]
        public string PalletCode { get; set; }
        /// <summary>
        /// å•位
        /// </summary>
        [ExporterHeader(DisplayName = "单位")]
        [SugarColumn(IsNullable = true, ColumnDescription = "单位")]
        public string Unit { get; set; }
        /// <summary>
        /// ä»»åŠ¡å·
        /// </summary>
        [ExporterHeader(DisplayName = "任务号")]
        [SugarColumn(IsNullable = true, ColumnDescription = "任务号")]
        public int? TaskNum { get; set; }
        /// <summary>
        /// çŠ¶æ€
        /// </summary>
        [ExporterHeader(DisplayName = "状态")]
        [SugarColumn(IsNullable = false, ColumnDescription = "状态")]
        public int Status { get; set; }
        /// <summary>
        /// ç”Ÿäº§æ—¥æœŸ
        /// </summary>
        [ExporterHeader(DisplayName = "生产日期")]
        [SugarColumn(IsNullable = false, ColumnDescription = "生产日期")]
        public string ProductionDate { get; set; }
        /// <summary>
        /// æœ‰æ•ˆæœŸ
        /// </summary>
        [ExporterHeader(DisplayName = "有效期")]
        [SugarColumn(IsNullable = false, ColumnDescription = "有效期")]
        public string EffectiveDate { get; set; }
    }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/Stock/Dt_StockInfo.cs
@@ -62,6 +62,12 @@
        public int StockLength { get; set; }
        /// <summary>
        /// åº“存过期标识
        /// </summary>
        [SugarColumn(IsNullable = true, ColumnDescription = "库存过期标识")]
        public int Expirationlabel { get; set; }
        /// <summary>
        /// åº“存明细
        /// </summary>
        [Navigate(NavigateType.OneToMany, nameof(Dt_StockInfoDetail.StockId), nameof(Id))]
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_Model/Models/TaskInfo/Dt_Task.cs
@@ -44,6 +44,7 @@
        /// <summary>
        /// æ‰˜ç›˜ç±»åž‹
        /// </summary>
        [ImporterHeader(Name = "托盘类型")]
        [SugarColumn(IsNullable = false, ColumnDescription = "托盘类型")]
        public int PalletType { get; set; }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_StockService/ProStockViewService.cs
@@ -22,6 +22,7 @@
using WIDESEA_Common.StockEnum;
using WIDESEA_IBasicRepository;
using WIDESEA_Common.WareHouseEnum;
using WIDESEA_Core.Enums;
namespace WIDESEA_StockService
{
@@ -55,50 +56,70 @@
                    try
                    {
                        List<SearchParameters> searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
                        if (searchParametersList.Count > 0)
                        if (searchParametersList?.Any() == true)
                        {
                            foreach (var param in searchParametersList)
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_ProStockInfoDetail.ProductCode).FirstLetterToLower());
                                if (searchParameters != null)
                                switch (param.Name)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.proStockInfoDetails.Any(v => v.ProductCode.Contains(searchParameters.Value)));
                                }
                            }
                                    case var name when name == nameof(Dt_ProStockInfoDetail.ProductCode).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.proStockInfoDetails.Any(v => v.ProductCode.Contains(param.Value.ToString())));
                                        }
                                        break;
                                    case var name when name == nameof(Dt_ProStockInfoDetail.LotNumber).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.proStockInfoDetails.Any(v => v.LotNumber.Contains(param.Value.ToString())));
                                        }
                                        break;
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_ProStockInfoDetail.ProductVersion).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.proStockInfoDetails.Any(v => v.ProductVersion.Contains(searchParameters.Value)));
                                }
                            }
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_ProStockInfoDetail.SpecifyVer).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.proStockInfoDetails.Any(v => v.SpecifyVer.Contains(searchParameters.Value)));
                                }
                            }
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_ProStockInfoDetail.LotNumber).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.proStockInfoDetails.Any(v => v.LotNumber.Contains(searchParameters.Value)));
                                }
                            }
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_ProStockInfo.LocationCode).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.LocationCode == searchParameters.Value);
                                }
                            }
                                    case var name when name == nameof(Dt_ProStockInfo.LocationCode).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.LocationCode == param.Value.ToString());
                                        }
                                        break;
                                    case var name when name == nameof(Dt_ProStockInfoDetail.ProductVersion).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.proStockInfoDetails.Any(v => v.ProductVersion.Contains(param.Value.ToString())));
                                        }
                                        break;
                                    case var name when name == nameof(Dt_ProStockInfoDetail.SpecifyVer).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.proStockInfoDetails.Any(v => v.SpecifyVer.Contains(param.Value.ToString())));
                                        }
                                        break;
                                    case var name when name == nameof(Dt_ProStockInfo.CreateDate).FirstLetterToLower():
                                        if (DateTime.TryParse(param.Value?.ToString(), out DateTime minDate))
                                        {
                                            LinqExpressionType expressionType = param.DisplayType.GetLinqCondition();
                                            if (expressionType == LinqExpressionType.ThanOrEqual)
                                            {
                                                sugarQueryable1 = sugarQueryable1.Where(x => x.CreateDate >= minDate);
                                            }
                                            else if (expressionType == LinqExpressionType.LessThanOrEqual)
                                            {
                                                sugarQueryable1 = sugarQueryable1.Where(x => x.CreateDate <= minDate);
                                            }
                                        }
                                        break;
                                }
                            }
                        }
                    }
                    catch { }
                    catch (Exception ex)
                    {
                    }
                }
                string whereSto = GetDataRole(typeof(Dt_ProStockInfo));
                sugarQueryable1 = sugarQueryable1.Where(whereSto);
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
@@ -289,5 +289,81 @@
            return BaseDal.GetStockInfos(materielCode, batchNo, locationCodes);
        }
        public WebResponseContent UpdateExpirationlabel()
        {
            try
            {
                var today = DateTime.Today;
                int batchSize = 1000; // æ‰¹æ¬¡å¤„理大小
                var query = BaseDal.Db.Queryable<Dt_StockInfoDetail>()
                    .InnerJoin<Dt_StockInfo>((detail, master) => detail.StockId == master.Id)
                    .Select((detail, master) => new
                    {
                        MasterId = master.Id,
                        master.WarehouseId,
                        detail.EffectiveDate,
                        CurrentExpirationlabel = master.Expirationlabel // ç”¨äºŽåˆ¤æ–­æ˜¯å¦éœ€è¦æ›´æ–°
                    });
                // åˆ†æ‰¹å¤„理,使用Take和Skip实现分页
                var totalUpdated = 0;
                int skipCount = 0;
                while (true)
                {
                    // ä½¿ç”¨Skip和Take实现分页获取数据
                    var batchData = query.Skip(skipCount).Take(batchSize).ToList();
                    if (!batchData.Any()) break; // æ²¡æœ‰æ›´å¤šæ•°æ®æ—¶é€€å‡ºå¾ªçޝ
                    var updateDic = new Dictionary<long, int>();
                    foreach (var item in batchData)
                    {
                        if (!DateTime.TryParse(item.EffectiveDate, out DateTime effectiveDate))
                            continue;
                        int newLabel;
                        if (effectiveDate < today)
                        {
                            newLabel = ExpirationlabelEnum.过期.ObjToInt();
                        }
                        else if (item.WarehouseId == 3)
                        {
                            int daysDiff = (effectiveDate - today).Days;
                            newLabel = daysDiff <= 60 ? ExpirationlabelEnum.临期预警.ObjToInt() : ExpirationlabelEnum.未临期.ObjToInt();
                        }
                        else
                        {
                            int daysDiff = (effectiveDate - today).Days;
                            newLabel = daysDiff <= 30 ? ExpirationlabelEnum.临期预警.ObjToInt() : ExpirationlabelEnum.未临期.ObjToInt();
                        }
                        // åªæ›´æ–°æœ‰å˜åŒ–的值,并且去重
                        if (newLabel != item.CurrentExpirationlabel && !updateDic.ContainsKey(item.MasterId))
                        {
                            updateDic[item.MasterId] = newLabel;
                        }
                    }
                    if (updateDic.Any())
                    {
                        // æž„建批量更新语句
                        var updateBuilder = BaseDal.Db.Updateable<Dt_StockInfo>();
                        foreach (var kvp in updateDic)
                        {
                            updateBuilder.SetColumns(m => m.Expirationlabel == kvp.Value)
                                         .Where(m => m.Id == kvp.Key);
                        }
                        totalUpdated += updateBuilder.ExecuteCommand();
                    }
                    skipCount += batchSize; // å‡†å¤‡èŽ·å–ä¸‹ä¸€æ‰¹æ•°æ®
                }
                return WebResponseContent.Instance.OK($"更新成功,共更新 {totalUpdated} æ¡è®°å½•");
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error("更新失败,请联系管理员");
            }
        }
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_StockService/StockViewService.cs
@@ -46,58 +46,100 @@
        {
            try
            {
                List<StockViewDTO> stockViewDTOs = new List<StockViewDTO>();
                string where = string.Empty;
                ISugarQueryable<Dt_StockInfo> sugarQueryable1 = _dbBase.Queryable<Dt_StockInfo>().Includes(x => x.Details);
                if (!string.IsNullOrEmpty(options.Wheres))
                {
                    try
                    {
                        List<SearchParameters> searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
                        if (searchParametersList.Count > 0)
                        if (searchParametersList?.Any() == true)
                        {
                            foreach (var param in searchParametersList)
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.MaterielCode).FirstLetterToLower());
                                if (searchParameters != null)
                                switch (param.Name)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.Details.Any(v => v.MaterielCode.Contains(searchParameters.Value)));
                                }
                            }
                                    case var name when name == nameof(Dt_StockInfoDetail.MaterielCode).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.Details.Any(v => v.MaterielCode.Contains(param.Value.ToString())));
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfoDetail.BatchNo).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.Details.Any(v => v.BatchNo.Contains(param.Value.ToString())));
                                        }
                                        break;
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.BatchNo).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.Details.Any(v => v.BatchNo.Contains(searchParameters.Value)));
                                }
                            }
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfo.LocationCode).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.LocationCode == searchParameters.Value);
                                }
                            }
                                    case var name when name == nameof(Dt_StockInfo.LocationCode).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.LocationCode == param.Value.ToString());
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfo.CreateDate).FirstLetterToLower():
                                        if (DateTime.TryParse(param.Value?.ToString(), out DateTime minDate))
                                        {
                                            LinqExpressionType expressionType = param.DisplayType.GetLinqCondition();
                                            if(expressionType == LinqExpressionType.ThanOrEqual)
                                            {
                                                sugarQueryable1 = sugarQueryable1.Where(x => x.CreateDate >= minDate);
                                            }
                                            else if(expressionType == LinqExpressionType.LessThanOrEqual)
                                            {
                                                sugarQueryable1 = sugarQueryable1.Where(x => x.CreateDate <= minDate);
                                            }
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfoDetail.EffectiveDate).FirstLetterToLower():
                                        // å‰ç«¯ä¼ é€’的参数需是 yyyy-MM-dd æ ¼å¼ï¼ˆå¦‚ "2025-05-08"),直接作为字符串处理
                                        string effectiveDateStr = param.Value?.ToString().Trim();
                                        if (!string.IsNullOrEmpty(effectiveDateStr) && effectiveDateStr.Length == 10)
                                        {
                                            LinqExpressionType expressionType = param.DisplayType.GetLinqCondition();
                                            if (expressionType == LinqExpressionType.ThanOrEqual)
                                            {
                                                sugarQueryable1 = sugarQueryable1.Where(x => x.Details
                                                    .Any(d =>!string.IsNullOrEmpty(d.EffectiveDate) && d.EffectiveDate.CompareTo(effectiveDateStr) >= 0));
                                            }
                                            else if (expressionType == LinqExpressionType.LessThanOrEqual)
                                            {
                                                sugarQueryable1 = sugarQueryable1.Where(x => x.Details
                                                    .Any(d =>!string.IsNullOrEmpty(d.EffectiveDate) && d.EffectiveDate.CompareTo(effectiveDateStr) <= 0));
                                            }
                                        }
                                        break;
                                }
                            }
                        }
                    }
                    catch { }
                    catch (Exception ex)
                    {
                    }
                }
                string whereSto = GetDataRole(typeof(Dt_StockInfo));
                sugarQueryable1 = sugarQueryable1.Where(whereSto);
                EntityProperties.ValidatePageOptions(options, ref sugarQueryable1);
                string whereLo = GetDataRole(typeof(Dt_LocationInfo));
                ISugarQueryable<Dt_LocationInfo> sugarQueryable = _dbBase.Queryable<Dt_LocationInfo>().Where(whereLo);
                ISugarQueryable<Dt_LocationInfo> sugarQueryable = _dbBase.Queryable<Dt_LocationInfo>()
                    .Where(whereLo);
                EntityProperties.ValidatePageOptions(options, ref sugarQueryable);
                ISugarQueryable<StockViewDTO> list = sugarQueryable1.InnerJoin(sugarQueryable, (b, a) => a.LocationCode == b.LocationCode).Select((b, a)
                    => new StockViewDTO
                ISugarQueryable<StockViewDTO> list = sugarQueryable1
                    .InnerJoin(sugarQueryable, (b, a) => a.LocationCode == b.LocationCode)
                    .Select((b, a) => new StockViewDTO
                    {
                        LocationCode = b.LocationCode,
                        Expirationlabel = b.Expirationlabel,
                        Column = a.Column,
                        WarehouseId = b.WarehouseId,
                        CreateDate = b.CreateDate,
@@ -119,52 +161,55 @@
                        Details = b.Details,
                    });
                var pklist = sugarQueryable1.Where(b => b.LocationCode == "平库位").Select(b => new StockViewDTO
                {
                    LocationCode = b.LocationCode,
                    Column = 0,
                    WarehouseId = b.WarehouseId,
                    CreateDate = b.CreateDate,
                    Creater = b.Creater,
                    Depth = 0,
                    EnalbeStatus = EnableStatusEnum.Normal.ObjToInt(),
                    Layer = 0,
                    LocationName = "平库位",
                    LocationStatus = LocationStatusEnum.InStock.ObjToInt(),
                    LocationType = LocationTypeEnum.Undefined.ObjToInt(),
                    Modifier = b.Modifier,
                    ModifyDate = b.ModifyDate,
                    PalletCode = b.PalletCode,
                    StockRemark = b.Remark,
                    RoadwayNo = "平库",
                    Row = 0,
                    StockId = b.Id,
                    StockStatus = b.StockStatus,
                    Details = b.Details,
                });
                // å¹³åº“位数据查询
                var pklist = sugarQueryable1
                    .Where(b => b.LocationCode == "平库位")
                    .Select(b => new StockViewDTO
                    {
                        LocationCode = b.LocationCode,
                        Column = 0,
                        WarehouseId = b.WarehouseId,
                        CreateDate = b.CreateDate,
                        Expirationlabel = b.Expirationlabel,
                        Creater = b.Creater,
                        Depth = 0,
                        EnalbeStatus = EnableStatusEnum.Normal.ObjToInt(),
                        Layer = 0,
                        LocationName = "平库位",
                        LocationStatus = LocationStatusEnum.InStock.ObjToInt(),
                        LocationType = LocationTypeEnum.Undefined.ObjToInt(),
                        Modifier = b.Modifier,
                        ModifyDate = b.ModifyDate,
                        PalletCode = b.PalletCode,
                        StockRemark = b.Remark,
                        RoadwayNo = "平库",
                        Row = 0,
                        StockId = b.Id,
                        StockStatus = b.StockStatus,
                        Details = b.Details,
                    });
                int totalCount = 0;
                int pktotalCount = 0;
                stockViewDTOs = list.ToPageList(options.Page, options.Rows, ref totalCount);
                var stockViewDTOs = list.ToPageList(options.Page, options.Rows, ref totalCount);
                stockViewDTOs.AddRange(pklist.ToPageList(options.Page, options.Rows, ref pktotalCount));
                stockViewDTOs.ForEach(x =>
                {
                    x.MaterielCode = string.Join(",", x.Details.Select(x => x.MaterielCode).Distinct());
                    x.BatchNo = string.Join(",", x.Details.Select(x => x.BatchNo).Distinct());
                    x.MaterielCode = string.Join(",", x.Details.Select(d => d.MaterielCode).Distinct());
                    x.BatchNo = string.Join(",", x.Details.Select(d => d.BatchNo).Distinct());
                    x.MaterielSpec = x.Details.FirstOrDefault()?.MaterielSpec ?? "";
                    x.MaterielName = x.Details.FirstOrDefault()?.MaterielName ?? "";
                }
                );
                });
                return new PageGridData<StockViewDTO>(totalCount + pktotalCount, stockViewDTOs);
            }
            catch (Exception ex)
            {
            }
            return new PageGridData<StockViewDTO>();
        }
        public virtual object GetDetailPage(PageDataOptions pageData)
        {
@@ -224,28 +269,76 @@
                    try
                    {
                        List<SearchParameters> searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
                        if (searchParametersList.Count > 0)
                        if (searchParametersList?.Any() == true)
                        {
                            foreach (var param in searchParametersList)
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.MaterielCode).FirstLetterToLower());
                                if (searchParameters != null)
                                switch (param.Name)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.Details.Any(v => v.MaterielCode.Contains(searchParameters.Value)));
                                    case var name when name == nameof(Dt_StockInfoDetail.MaterielCode).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.Details.Any(v => v.MaterielCode.Contains(param.Value.ToString())));
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfoDetail.BatchNo).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.Details.Any(v => v.BatchNo.Contains(param.Value.ToString())));
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfo.LocationCode).FirstLetterToLower():
                                        if (!string.IsNullOrEmpty(param.Value?.ToString()))
                                        {
                                            sugarQueryable1 = sugarQueryable1
                                                .Where(x => x.LocationCode == param.Value.ToString());
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfo.CreateDate).FirstLetterToLower():
                                        if (DateTime.TryParse(param.Value?.ToString(), out DateTime minDate))
                                        {
                                            LinqExpressionType expressionType = param.DisplayType.GetLinqCondition();
                                            if (expressionType == LinqExpressionType.ThanOrEqual)
                                            {
                                                sugarQueryable1 = sugarQueryable1.Where(x => x.CreateDate >= minDate);
                                            }
                                            else if (expressionType == LinqExpressionType.LessThanOrEqual)
                                            {
                                                sugarQueryable1 = sugarQueryable1.Where(x => x.CreateDate <= minDate);
                                            }
                                        }
                                        break;
                                    case var name when name == nameof(Dt_StockInfoDetail.EffectiveDate).FirstLetterToLower():
                                        // å‰ç«¯ä¼ é€’的参数需是 yyyy-MM-dd æ ¼å¼ï¼ˆå¦‚ "2025-05-08"),直接作为字符串处理
                                        string effectiveDateStr = param.Value?.ToString().Trim();
                                        if (!string.IsNullOrEmpty(effectiveDateStr) && effectiveDateStr.Length == 10)
                                        {
                                            LinqExpressionType expressionType = param.DisplayType.GetLinqCondition();
                                            if (expressionType == LinqExpressionType.ThanOrEqual)
                                            {
                                                sugarQueryable1 = sugarQueryable1.Where(x => x.Details
                                                    .Any(d => !string.IsNullOrEmpty(d.EffectiveDate) && d.EffectiveDate.CompareTo(effectiveDateStr) >= 0));
                                            }
                                            else if (expressionType == LinqExpressionType.LessThanOrEqual)
                                            {
                                                sugarQueryable1 = sugarQueryable1.Where(x => x.Details
                                                    .Any(d => !string.IsNullOrEmpty(d.EffectiveDate) && d.EffectiveDate.CompareTo(effectiveDateStr) <= 0));
                                            }
                                        }
                                        break;
                                }
                            }
                            {
                                SearchParameters? searchParameters = searchParametersList.FirstOrDefault(x => x.Name == nameof(Dt_StockInfoDetail.BatchNo).FirstLetterToLower());
                                if (searchParameters != null)
                                {
                                    sugarQueryable1 = sugarQueryable1.Where(x => x.Details.Any(v => v.BatchNo.Contains(searchParameters.Value)));
                                }
                            }
                        }
                    }
                    catch { }
                    catch (Exception ex)
                    {
                    }
                }
                string whereSto = GetDataRole(typeof(Dt_StockInfo));
                sugarQueryable1 = sugarQueryable1.Where(whereSto);
@@ -261,6 +354,7 @@
                    {
                        LocationCode = b.LocationCode,
                        Column = a.Column,
                        Expirationlabel = b.Expirationlabel,
                        WarehouseId = b.WarehouseId,
                        CreateDate = b.CreateDate,
                        Creater = b.Creater,
@@ -286,6 +380,7 @@
                    LocationCode = b.LocationCode,
                    Column = 0,
                    WarehouseId = b.WarehouseId,
                    Expirationlabel = b.Expirationlabel,
                    CreateDate = b.CreateDate,
                    Creater = b.Creater,
                    Depth = 0,
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_SystemService/Sys_DictionaryService.cs
@@ -1315,6 +1315,32 @@
                            result = new VueDictionaryDTO { DicNo = key, Config = "", Data = data };
                        }
                        break;
                    case "expirationlabelEnum":
                        {
                            List<object> data = new List<object>();
                            {
                                Type type = typeof(ExpirationlabelEnum);
                                List<int> enums = Enum.GetValues(typeof(ExpirationlabelEnum)).Cast<int>().ToList();
                                int index = 0;
                                foreach (var item in enums)
                                {
                                    FieldInfo? fieldInfo = typeof(ExpirationlabelEnum).GetField(((ExpirationlabelEnum)item).ToString());
                                    DescriptionAttribute? description = fieldInfo.GetCustomAttribute<DescriptionAttribute>();
                                    if (description != null)
                                    {
                                        data.Add(new { key = item.ToString(), value = description.Description });
                                    }
                                    else
                                    {
                                        data.Add(new { key = item.ToString(), value = item.ToString() });
                                    }
                                    index++;
                                }
                            }
                            result = new VueDictionaryDTO { DicNo = key, Config = "", Data = data };
                        }
                        break;
                }
                return result;
            }
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService.cs
@@ -1155,5 +1155,53 @@
            }
            return content;
        }
        public WebResponseContent InboundTaskHandCancel(int taskNum, int warehouseId)
        {
            try
            {
                Dt_Task task = BaseDal.QueryFirst(x => x.TaskNum == taskNum);
                if (task == null)
                {
                    return WebResponseContent.Instance.Error($"未找到该任务信息");
                }
                Dt_StockInfo stockInfo = _stockRepository.StockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x => x.PalletCode == task.PalletCode && x.WarehouseId == task.WarehouseId).Includes(x => x.Details).First();
                if (stockInfo == null)
                {
                    return WebResponseContent.Instance.Error($"未找到托盘对应的组盘信息");
                }
                if (stockInfo.Details.Count == 0 && stockInfo.PalletType != PalletTypeEnum.Empty.ObjToInt())
                {
                    return WebResponseContent.Instance.Error($"未找到该托盘库存明细信息");
                }
                if (task.TaskType == TaskTypeEnum.MesPalletLargeReturn.ObjToInt() || task.TaskType == TaskTypeEnum.MesPalletSmallReturn.ObjToInt())
                {
                    task.TaskStatus = TaskStatusEnum.Cancel.ObjToInt();
                    _unitOfWorkManage.BeginTran();
                    BaseDal.DeleteAndMoveIntoHty(task, App.User.UserId > 0 ? OperateTypeEnum.人工删除 : OperateTypeEnum.自动删除);
                    _stockService.StockInfoService.Repository.DeleteAndMoveIntoHty(stockInfo, App.User.UserId == 0 ? OperateTypeEnum.自动删除 : OperateTypeEnum.人工删除);
                    _stockService.StockInfoDetailService.Repository.DeleteAndMoveIntoHty(stockInfo.Details, App.User.UserId == 0 ? OperateTypeEnum.自动删除 : OperateTypeEnum.人工删除);
                    _unitOfWorkManage.CommitTran();
                    return WebResponseContent.Instance.OK();
                }
                Dt_LocationInfo locationInfo = _basicService.LocationInfoService.Repository.QueryFirst(x => x.LocationCode == task.TargetAddress);
                if (locationInfo != null)
                {
                    if (locationInfo.LocationStatus == LocationStatusEnum.InStock.ObjToInt())
                    {
                        return WebResponseContent.Instance.Error($"货位状态不正确");
                    }
                    LocationStatusEnum lastStatus = (LocationStatusEnum)locationInfo.LocationStatus;
                    locationInfo.LocationStatus = LocationStatusEnum.InStock.ObjToInt();
                }
                return WebResponseContent.Instance.OK();
            }
            catch(Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_TaskInfoService/TaskService_Completed.cs
@@ -136,7 +136,12 @@
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        /// <summary>
        /// ä»»åŠ¡å–æ¶ˆ
        /// </summary>
        /// <param name="taskNum"></param>
        /// <param name="warehouseId"></param>
        /// <returns></returns>
        public async Task<WebResponseContent> TaskHandCancel(int taskNum,int warehouseId)
        {
            try
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Stock/StockInfoController.cs
@@ -79,5 +79,15 @@
        {
            return Service.StockQueryData(saveModel);
        }
        /// <summary>
        /// è¿‡æœŸæ ‡è¯†æ›´æ–°
        /// </summary>
        /// <param name="saveModel"></param>
        /// <returns></returns>
        [HttpPost, HttpGet, Route("UpdateExpirationlabel"),AllowAnonymous]
        public WebResponseContent UpdateExpirationlabel()
        {
            return Service.UpdateExpirationlabel();
        }
    }
}
´úÂë¹ÜÀí/WMS/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/TaskInfo/TaskController.cs
@@ -413,7 +413,7 @@
        /// </summary>
        /// <param name="taskNum">任务号</param>
        /// <returns></returns>
        [HttpPost, HttpGet, Route("TaskHandCancel"), AllowAnonymous]
        [HttpPost, HttpGet, Route("TaskHandCa"), AllowAnonymous]
        public async Task<WebResponseContent> TaskHandCancel(int taskNum ,int warehouseId)
        {
            return await Service.TaskHandCancel(taskNum,warehouseId);