pan
3 天以前 e4e304318532574e418bc01b5a45b8836dac3e1a
提交
已添加1个文件
已修改12个文件
703 ■■■■ 文件已修改
项目代码/WIDESEA_WMSClient/src/extension/check/extend/StockSelect.vue 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/AllocateStockSelect.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/StockSelect.vue 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/allocateOrderDetail.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/newAllocateOrderDetail.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/uitils/stationManager.js 100 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/Index.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/Login.vue 253 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderDetailService.cs 56 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoDetailService.cs 124 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs 66 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/check/extend/StockSelect.vue
@@ -173,7 +173,7 @@
<script>
import VolBox from "@/components/basic/VolBox.vue";
import { ElMessage } from "element-plus";
import { stationManager, STATION_STORAGE_KEY } from "@/../src/uitils/stationManager";
export default {
  components: { VolBox },
  data() {
@@ -216,6 +216,17 @@
      ],
    };
  },
      onMounted() {
      // ä»Žæœ¬åœ°å­˜å‚¨åŠ è½½ä¿å­˜çš„ç«™å°å€¼
      const savedStation = stationManager.getStation();
      console.log(savedStation);
      if (savedStation) {
        outboundForm.selectedPlatform = savedStation;
      } else if (stationOptions.length > 0) {
        // å¦‚果没有保存的值,使用第一个选项
        //stationValue.value = stationOptions[0].value;
      }
    },
  methods: {
    open(row) {
      this.row = row;
@@ -247,8 +258,14 @@
      if (this.selection.length === 0) {
        return ElMessage.error("请选择单据明细");
      }
      // é‡ç½®è¡¨å•避免残留值
      this.outboundForm.selectedPlatform = "";
      const savedStation = stationManager.getStation();
      if (savedStation) {
        outboundForm.selectedPlatform = savedStation;
      }
      this.showOutboundDialog = true;
    },
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/extend/AllocateStockSelect.vue
@@ -126,7 +126,7 @@
<script>
import VolBox from "@/components/basic/VolBox.vue";
import { ElMessage } from "element-plus";
import { stationManager, STATION_STORAGE_KEY } from "@/../src/uitils/stationManager";
export default {
  components: { VolBox },
  data() {
@@ -161,6 +161,17 @@
      ],
    };
  },
        onMounted() {
      // ä»Žæœ¬åœ°å­˜å‚¨åŠ è½½ä¿å­˜çš„ç«™å°å€¼
      const savedStation = stationManager.getStation();
      console.log(savedStation);
      if (savedStation) {
        outboundForm.selectedPlatform = savedStation;
      } else if (stationOptions.length > 0) {
        // å¦‚果没有保存的值,使用第一个选项
        //stationValue.value = stationOptions[0].value;
      }
    },
  methods: {
    open(row) {
      this.row = row;
@@ -193,6 +204,11 @@
      }
      // é‡ç½®è¡¨å•避免残留值
      this.outboundForm.selectedPlatform = "";
         const savedStation = stationManager.getStation();
         console.log(savedStation);
      if (savedStation) {
        this.outboundForm.selectedPlatform = savedStation;
      }
      this.showOutboundDialog = true;
    },
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/extend/StockSelect.vue
@@ -126,7 +126,7 @@
<script>
import VolBox from "@/components/basic/VolBox.vue";
import { ElMessage } from "element-plus";
import { stationManager, STATION_STORAGE_KEY } from "@/../src/uitils/stationManager";
export default {
  components: { VolBox },
  data() {
@@ -160,6 +160,17 @@
      ],
    };
  },
        onMounted() {
      // ä»Žæœ¬åœ°å­˜å‚¨åŠ è½½ä¿å­˜çš„ç«™å°å€¼
      const savedStation = stationManager.getStation();
      console.log(savedStation);
      if (savedStation) {
        outboundForm.selectedPlatform.value = savedStation;
      } else if (stationOptions.length > 0) {
        // å¦‚果没有保存的值,使用第一个选项
        //stationValue.value = stationOptions[0].value;
      }
    },
  methods: {
    open(row) {
      this.row = row;
@@ -192,6 +203,10 @@
      }
      // é‡ç½®è¡¨å•避免残留值
      this.outboundForm.selectedPlatform = "";
      const savedStation = stationManager.getStation();
      if (savedStation) {
        outboundForm.selectedPlatform = savedStation;
      }
      this.showOutboundDialog = true;
    },
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/extend/allocateOrderDetail.vue
@@ -112,6 +112,7 @@
import SelectedStock from "./SelectedStock.vue";
import { h,createVNode, render,reactive  } from 'vue';
import { ElDialog , ElForm, ElFormItem, ElSelect,ElOption, ElButton, ElMessage } from 'element-plus';
import { stationManager, STATION_STORAGE_KEY } from "@/../src/uitils/stationManager";
export default {
  components: { VolBox, VolForm, StockSelect, SelectedStock },
  data() {
@@ -344,6 +345,11 @@
      const formData = reactive({
        selectedPlatform: platformOptions[0].value // é»˜è®¤ç»‘定「站台3」的value
      });
      const savedStation = stationManager.getStation();
      console.log(savedStation);
      if (savedStation) {
        formData.selectedPlatform = savedStation;
      }
      // 3. åŠ¨æ€åˆ›å»ºå¼¹çª—ç»„ä»¶
      const vnode = createVNode(ElDialog, {
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/outbound/extend/newAllocateOrderDetail.vue
@@ -131,6 +131,7 @@
import { h,createVNode, render,reactive  } from 'vue';
import { ElDialog , ElForm, ElFormItem, ElSelect,ElOption, ElButton, ElInput, ElMessage } from 'element-plus';
import { th } from 'element-plus/es/locale';
import { stationManager, STATION_STORAGE_KEY } from "@/../src/uitils/stationManager";
export default {
  components: { VolBox, VolForm, StockSelect, SelectedStock,NoStockOut},
@@ -381,7 +382,10 @@
      const formData = reactive({
        selectedPlatform: platformOptions[0].value // é»˜è®¤ç»‘定「站台3」的value
      });
     const savedStation = stationManager.getStation();
      if (savedStation) {
        formData.selectedPlatform = savedStation;
      }
      // 3. åŠ¨æ€åˆ›å»ºå¼¹çª—ç»„ä»¶
      const vnode = createVNode(ElDialog, {
        title: '出库操作 - é€‰æ‹©å‡ºåº“站台',
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/outbound/extend/outOrderDetail.vue
@@ -129,6 +129,7 @@
import StockSelect from "./StockSelect.vue";
import SelectedStock from "./SelectedStock.vue";
import NoStockOut from "./NoStockOut.vue";
import { stationManager, STATION_STORAGE_KEY } from "@/../src/uitils/stationManager";
import { h, createVNode, render, reactive } from "vue";
import {
  ElDialog,
@@ -316,6 +317,17 @@
      dictionaryList: null,
    };
  },
        onMounted() {
      // ä»Žæœ¬åœ°å­˜å‚¨åŠ è½½ä¿å­˜çš„ç«™å°å€¼
      const savedStation = stationManager.getStation();
      console.log(savedStation);
      if (savedStation) {
        outboundForm.selectedPlatform = savedStation;
      } else if (stationOptions.length > 0) {
        // å¦‚果没有保存的值,使用第一个选项
        //stationValue.value = stationOptions[0].value;
      }
    },
  methods: {
    toggleAssignStockColumn() {
      const assignStockColumn = this.tableColumns.find(
@@ -390,6 +402,8 @@
      });
    },
    outbound() {
        const savedStation = stationManager.getStation();
      console.log(savedStation);
      if (this.selection.length === 0) {
        return this.$message.error("请选择单据明细");
      }
@@ -404,6 +418,9 @@
        selectedPlatform: platformOptions[0].value,
      });
      if (savedStation) {
        formData.selectedPlatform = savedStation;
      }
      const vnode = createVNode(
        ElDialog,
        {
@@ -532,6 +549,8 @@
      render(vnode, mountNode);
    },
    outboundbatch() {
       const savedStation = stationManager.getStation();
      console.log(savedStation);
      if (this.selection.length === 0) {
        return this.$message.error("请选择单据明细");
      }
@@ -549,7 +568,9 @@
        selectedPlatform: platformOptions[0].value,
        outboundDecimal: "",
      });
  if (savedStation) {
        formData.selectedPlatform = savedStation;
      }
      const vnode = createVNode(
        ElDialog,
        {
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/uitils/stationManager.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,100 @@
// æœ¬åœ°å­˜å‚¨é”®å
export const STATION_STORAGE_KEY = "wms_selected_station";
/**
 * ç«™å°ç®¡ç†å™¨ - æä¾›ç«™å°ä¿¡æ¯çš„æŒä¹…化存储和获取
 */
export const stationManager = {
  /**
   * ä¿å­˜ç«™å°ä¿¡æ¯åˆ°æœ¬åœ°å­˜å‚¨
   * @param {string} station - ç«™å°å€¼
   */
  saveStation(station) {
    try {
      // ä½¿ç”¨localStorage进行持久化存储
      localStorage.setItem(STATION_STORAGE_KEY, station);
      // åŒæ—¶ä¿å­˜åˆ°sessionStorage,作为备用
      sessionStorage.setItem(STATION_STORAGE_KEY, station);
      // è§¦å‘自定义事件,通知其他组件站台已更新
      window.dispatchEvent(new CustomEvent('station-changed', {
        detail: { station }
      }));
      console.log(`站台已保存: ${station}`);
    } catch (error) {
      console.error("保存站台信息失败:", error);
    }
  },
  /**
   * èŽ·å–ä¿å­˜çš„ç«™å°ä¿¡æ¯
   * @returns {string|null} ç«™å°å€¼æˆ–null
   */
  getStation() {
    try {
      // ä¼˜å…ˆä»ŽlocalStorage获取
      let station = localStorage.getItem(STATION_STORAGE_KEY);
      // å¦‚æžœlocalStorage没有,尝试从sessionStorage获取
      if (!station) {
        station = sessionStorage.getItem(STATION_STORAGE_KEY);
      }
      return station;
    } catch (error) {
      console.error("获取站台信息失败:", error);
      return null;
    }
  },
  /**
   * æ¸…除站台信息
   */
  clearStation() {
    try {
      localStorage.removeItem(STATION_STORAGE_KEY);
      sessionStorage.removeItem(STATION_STORAGE_KEY);
      console.log("站台信息已清除");
    } catch (error) {
      console.error("清除站台信息失败:", error);
    }
  },
  /**
   * ç›‘听站台变化
   * @param {Function} callback - å˜åŒ–回调函数
   * @returns {Function} å–消监听的函数
   */
  onStationChange(callback) {
    const handler = (event) => {
      if (callback && typeof callback === 'function') {
        callback(event.detail.station);
      }
    };
    window.addEventListener('station-changed', handler);
    // è¿”回取消监听的函数
    return () => {
      window.removeEventListener('station-changed', handler);
    };
  },
  /**
   * èŽ·å–ç«™å°æ˜¾ç¤ºæ ‡ç­¾
   * @param {string} value - ç«™å°å€¼
   * @param {Array} options - ç«™å°é€‰é¡¹æ•°ç»„
   * @returns {string} ç«™å°æ ‡ç­¾
   */
  getStationLabel(value, options) {
    if (!value || !options) return value || '';
    const option = options.find(opt => opt.value === value);
    return option ? option.label : value;
  }
};
// é»˜è®¤å¯¼å‡º
export default stationManager;
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/Index.vue
@@ -24,7 +24,7 @@
    </div>
    <div class="vol-container" :style="{ left: menuWidth - 1 + 'px' }">
      <div class="vol-header">
        <div class="project-name">WMS</div>
        <div class="project-name">WMS      {{ stationValue.replace('-1','') }}站台</div>
        <div class="header-text">
          <div class="h-link">
            <a
@@ -203,6 +203,7 @@
import VolMenu from "@/components/basic/VolElementMenu.vue";
import Message from "./index/Message.vue";
import MessageConfig from "./index/MessageConfig.js";
import { stationManager, STATION_STORAGE_KEY } from "@/../src/uitils/stationManager";
var imgUrl = require("@/assets/imgs/wms_x.png");
var $this;
var $interval;
@@ -241,7 +242,12 @@
  },
  setup(props, context) {
    let client = ref(null);
    const stationValue = ref("");
     const savedStation = stationManager.getStation();
     console.log("Saved Station:", savedStation);
      if (savedStation) {
        stationValue.value = savedStation;
      }
    // èŽ·å–å…¨å±€å±žæ€§å’Œæ–¹æ³•
    const { proxy } = getCurrentInstance();
@@ -686,6 +692,7 @@
      visibleItem,
      closeTabsMenu,
      closeTabs,
      stationValue,
      currentMenuId,
    };
  },
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/Login.vue
@@ -29,9 +29,27 @@
            placeholder="请输入密码"
          />
        </div>
         <div class="item station-select-item">
          <div class="input-icon el-icon-lock"></div>
          <el-select
            v-model="stationValue"
            placeholder="选择站台"
            class="station-select"
            @change="handleStationChange"
          >
            <el-option
              v-for="item in stationOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </div>
        <div class="item">
          <div class="input-icon el-icon-mobile"></div>
          <input
            v-focus
            type="text"
@@ -56,72 +74,61 @@
          <span v-else>正在登录...</span>
        </el-button>
      </div>
      <!-- è´¦å·ä¿¡æ¯ -->
      <!-- <div class="account-info">
        <p>演示账号:admin666 &nbsp; &nbsp;密码:123456</p>
        <p>本地账号:admin &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;密码:123456</p>
        <p><a href="https://jq.qq.com/?_wv=1027&k=Sqstuy0M" style="text-decoration: none"
            target="_blank">QQ3群:743852316</a>
          &nbsp; &nbsp;&nbsp; &nbsp;
          <a href="http://v2.volcore.xyz/document/guide" style="text-decoration: none" target="_blank">框架文档</a>
        </p>
      </div> -->
      <!-- é“¾æŽ¥ä½ç½® -->
      <!-- <div class="app-link" >
        <a href="#" style="text-decoration: none">移动端扫码</a>
        <a>
          <i class="el-icon-chat-dot-round"></i> å°ç¨‹åº
          <img src="https://app-1256993465.cos.ap-nanjing.myqcloud.com/wechat.jpg" /></a>
        <a>
          <i class="el-icon-apple"></i>
          Android
          <img src="https://app-1256993465.cos.ap-nanjing.myqcloud.com/Android.png" /></a>
        <a>
          <i class="el-icon-document"></i>
          H5
          <img src="https://app-1256993465.cos.ap-nanjing.myqcloud.com/H5.png" /></a>
      </div> -->
    </div>
    <!-- é¡µé¢åº•部 -->
    <!-- <div class="login-footer">
      <a style="text-decoration: none" href="https://beian.miit.gov.cn/" target="_blank">京ICP备19056538号-1</a>
      <a href="https://dotnet9.com/" style="text-decoration: none" target="blank">Dotnet9</a>
      <a href="https://space.bilibili.com/525836469" style="text-decoration: none" target="blank">NET视频教程(微软MVP-ACE录制)</a>
      <a href="https://www.cctalk.com/m/group/90268531" style="text-decoration: none" target="blank">VOL框架视频</a>
      <a href="http://120.48.115.252:9990" style="text-decoration: none" target="blank">视频演示地址</a>
    </div> -->
    <img class="login-bg" src="/static/login_bg.png" />
  </div>
</template>
<script >
<script>
import {
  defineComponent,
  ref,
  reactive,
  toRefs,
  getCurrentInstance,
  onMounted,
} from "vue";
import { useRouter, useRoute } from "vue-router";
import store from "../store/index";
import http from "@/../src/api/http.js";
import { stationManager, STATION_STORAGE_KEY } from "@/../src/uitils/stationManager";
export default defineComponent({
  setup(props, context) {
    store.commit("clearUserInfo", "");
    const loading = ref(false);
    const codeImgSrc = ref("");
    const value = ref("");
    const userInfo = reactive({
      userName: "",
      password: "",
      verificationCode: "",
      UUID: undefined,
    });
     const stationValue = ref("");
   const stationOptions = reactive([
      { label: "站台2", value: "2-1" },
      { label: "站台3", value: "3-1" },
    ]);
     // åˆå§‹åŒ–站台值
    onMounted(() => {
      // ä»Žæœ¬åœ°å­˜å‚¨åŠ è½½ä¿å­˜çš„ç«™å°å€¼
      const savedStation = stationManager.getStation();
      if (savedStation) {
        stationValue.value = savedStation;
      } else if (stationOptions.length > 0) {
        // å¦‚果没有保存的值,使用第一个选项
        stationValue.value = stationOptions[0].value;
      }
    });
    const handleStationChange = (value) => {
      // ä¿å­˜ç«™å°é€‰æ‹©åˆ°æœ¬åœ°å­˜å‚¨
      if (value) {
        stationManager.saveStation(value);
        // ä¹Ÿä¿å­˜åˆ°Vuex/store中,方便全局访问
        store.commit("setStation", value);
      }
    };
    const getVierificationCode = () => {
      http.get("/api/User/getVierificationCode").then((x) => {
@@ -130,7 +137,7 @@
      });
    };
    getVierificationCode();
    let appContext = getCurrentInstance().appContext;
    let $message = appContext.config.globalProperties.$message;
    let router = useRouter();
@@ -141,6 +148,13 @@
      if (!userInfo.verificationCode) {
        return $message.error("请输入验证码");
      }
          // ç¡®ä¿ç«™å°å€¼å·²ä¿å­˜
      if (stationValue.value) {
        stationManager.saveStation(stationValue.value);
        store.commit("setStation", stationValue.value);
      }
      loading.value = true;
      http.post("/api/User/login", userInfo, "正在登录....").then((result) => {
        if (!result.status) {
@@ -150,7 +164,7 @@
        }
        $message.success("登录成功,正在跳转!");
        store.commit("setUserInfo", result.data);
        router.push({ path: "/" });
      });
    };
@@ -170,6 +184,9 @@
      userInfo,
      loginPress,
      openUrl,
     stationOptions,
      stationValue,
      handleStationChange,
    };
  },
  directives: {
@@ -196,12 +213,9 @@
  width: 50%;
  display: flex;
  flex-direction: column;
  // margin-right: 150px;
  z-index: 999;
  .form-user {
    // margin: 25px 0;
    .item {
      border-radius: 5px;
      border: 1px solid #ececec;
@@ -210,19 +224,31 @@
      background: #ffff;
      height: 45px;
      padding-left: 20px;
      display: flex;
      align-items: center;
      &.station-select-item {
        padding-left: 0;
        .input-icon {
          margin-left: 20px;
          min-width: 20px;
        }
      }
      .code {
        position: relative;
        cursor: pointer;
        width: 74px;
        padding: 5px 10px 0 0;
        display: flex;
        align-items: center;
      }
      .input-icon {
        line-height: 45px;
        color: #7a7a7a;
        padding-right: 20px;
        display: flex;
        align-items: center;
      }
    }
  }
@@ -241,12 +267,27 @@
    margin: 0;
    padding: 0;
    color: #323233;
    line-height: inherit;
    text-align: left;
    border: 0;
    outline: none;
    font-size: 16px;
    line-height: 20px;
    height: 100%;
    line-height: normal;
  }
  select {
    background: white;
    display: block;
    box-sizing: border-box;
    width: 100%;
    min-width: 0;
    margin: 0;
    padding: 0;
    color: #323233;
    text-align: left;
    border: 0;
    outline: none;
    font-size: 16px;
  }
}
@@ -270,7 +311,6 @@
  font-weight: bolder;
  font-size: 20px;
  letter-spacing: 2px;
  position: relative;
  display: flex;
@@ -309,10 +349,120 @@
  color: transparent;
  font-size: 25px;
}
// ä¸‹æ‹‰æ¡†è‡ªå®šä¹‰æ ·å¼ - ç§»é™¤æ‰€æœ‰äº¤äº’效果
.station-select {
  width: 100%;
  height: 100%;
  flex: 1;
  :deep(.el-input) {
    height: 100%;
    cursor: pointer; // æ·»åŠ æŒ‡é’ˆæ˜¾ç¤ºä¸ºå¯ç‚¹å‡»
  }
  :deep(.el-input__wrapper) {
    height: 100%;
    box-shadow: none;
    border: none;
    padding: 0;
    background: transparent;
    // ç§»é™¤æ‰€æœ‰hover、focus效果
    &:hover, &:focus, &.is-focus {
      box-shadow: none !important;
      outline: none !important;
      border: none !important;
    }
  }
  :deep(.el-input__inner) {
    height: 100%;
    padding-left: 10px;
    padding-top: 10px;
    font-size: 16px;
    color: #323233;
    cursor: pointer; // æ·»åŠ æŒ‡é’ˆæ˜¾ç¤ºä¸ºå¯ç‚¹å‡»
    &::placeholder {
      color: #c0c4cc;
    }
  }
  :deep(.el-input__suffix) {
    display: flex;
    align-items: center;
    height: 100%;
  }
  :deep(.el-select__caret) {
    height: 100%;
    display: flex;
    align-items: center;
    margin-right: 10px;
  }
  // ç§»é™¤æ•´ä¸ªç»„件上的任何hover和focus样式
  &:hover, &:focus, &.is-focus {
    :deep(.el-input__wrapper) {
      box-shadow: none !important;
      outline: none !important;
      border: none !important;
    }
  }
}
// ä¿®æ”¹å…¨å±€çš„下拉框样式
:deep(.el-select-dropdown) {
  border: 1px solid #ececec;
  border-radius: 5px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  .el-select-dropdown__item {
    height: 45px;
    line-height: 45px;
    font-size: 16px;
    color: #323233;
    padding: 0 20px;
    &:hover {
      background-color: #f5f7fa;
    }
    &.selected {
      color: #3a6cd1;
      font-weight: normal;
      background-color: #f0f7ff;
    }
  }
  // éšè—æ»šåŠ¨æ¡æˆ–è°ƒæ•´æ»šåŠ¨æ¡æ ·å¼
  &::-webkit-scrollbar {
    width: 6px;
  }
  &::-webkit-scrollbar-track {
    background: #f1f1f1;
    border-radius: 3px;
  }
  &::-webkit-scrollbar-thumb {
    background: #c1c1c1;
    border-radius: 3px;
  }
}
// ç§»é™¤æ‰€æœ‰input的focus和hover样式
input {
  &:hover, &:focus {
    border: none !important;
    outline: none !important;
    box-shadow: none !important;
  }
}
</style>
<style lang="less" scoped>
.app-link {
  // font-weight: bolder;
  text-align: center;
  padding-top: 5px;
  font-size: 12px;
@@ -343,7 +493,6 @@
      top: -130px;
      width: 120px;
      left: -22px;
      border: 1px solid #b1b1b1;
    }
  }
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_IStockService/IStockInfoService.cs
@@ -26,5 +26,9 @@
        List<StockSelectViewDTO> GetSelectViewDTOs(string orderNo, string materielCode);
        List<Dt_StockInfo> GetUseableStocks(string materielCode, string batchNo, string supplyCode, string wearhouseCode, string factoryCode);
        List<Dt_StockInfo> GetStockInfos(string materielCode, string lotNo, string supplyCode, List<string> locationCodes, string wearhouseCode, string factoryCode);
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_OutboundService/OutboundOrderDetailService.cs
@@ -78,13 +78,14 @@
            // æŒ‰ç‰©æ–™å’Œæ‰¹æ¬¡åˆ†ç»„处理
            var groupDetails = outboundOrderDetails
                .GroupBy(x => new { x.MaterielCode, x.BatchNo, x.SupplyCode })
                .GroupBy(x => new { x.MaterielCode, x.BatchNo, x.SupplyCode,x.WarehouseCode })
                .Select(x => new
                {
                    MaterielCode = x.Key.MaterielCode,
                    BatchNo = x.Key.BatchNo,
                    SupplyCode = x.Key.SupplyCode,
                    Details = x.ToList(),
                    WarehouseCode=x.Key.WarehouseCode,
                    TotalNeedQuantity = CalculateReassignNeedQuantity(x.ToList())
                })
                .Where(x => x.TotalNeedQuantity > 0)
@@ -93,9 +94,9 @@
            foreach (var item in groupDetails)
            {
                var needQuantity = item.TotalNeedQuantity;
                // èŽ·å–å¯ç”¨åº“å­˜ï¼ˆæŒ‰å…ˆè¿›å…ˆå‡ºæŽ’åºï¼‰
                List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(item.MaterielCode, item.BatchNo, item.SupplyCode);
                List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(item.MaterielCode, item.BatchNo, item.SupplyCode,item.WarehouseCode, outboundOrder.FactoryArea);
                if (!stockInfos.Any())
                {
@@ -311,12 +312,13 @@
            // æŒ‰ç‰©æ–™å’Œæ‰¹æ¬¡åˆ†ç»„处理(这里只有一个明细)
            var groupDetails = new List<Dt_OutboundOrderDetail> { orderDetail }
                .GroupBy(x => new { x.MaterielCode, x.BatchNo, x.SupplyCode })
                .GroupBy(x => new { x.MaterielCode, x.BatchNo, x.SupplyCode ,x.WarehouseCode})
                .Select(x => new
                {
                    MaterielCode = x.Key.MaterielCode,
                    BatchNo = x.Key.BatchNo,
                    SupplyCode = x.Key.SupplyCode,
                    WarehouseCode=x.Key.WarehouseCode,
                    Details = x.ToList(),
                    TotalNeedQuantity = batchQuantity  // ä½¿ç”¨åˆ†æ‰¹æ•°é‡
                })
@@ -328,7 +330,7 @@
                var needQuantity = item.TotalNeedQuantity;
                // èŽ·å–å¯ç”¨åº“å­˜ï¼ˆæŒ‰å…ˆè¿›å…ˆå‡ºæŽ’åºï¼‰
                List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(item.MaterielCode, item.BatchNo, item.SupplyCode);
                List<Dt_StockInfo> stockInfos = _stockService.StockInfoService.GetUseableStocks(item.MaterielCode, item.BatchNo, item.SupplyCode,item.WarehouseCode,outboundOrder.FactoryArea);
                if (!stockInfos.Any())
                {
                    throw new Exception($"物料[{item.MaterielCode}]批次[{item.BatchNo}]未找到可分配库存");
@@ -669,47 +671,7 @@
          
            if (remainingNeedQuantity > 0)
            {
                //// å¯é€‰ï¼šè¿™é‡Œå¯ä»¥æ ¹æ®ä¸šåŠ¡éœ€æ±‚å†³å®šæ˜¯å¦å…è®¸è‡ªåŠ¨åˆ†é…
                //// å¦‚果要求严格按用户选择出库,可以抛出异常
                //// throw new Exception($"用户选择的库存数量不足,还需{remainingNeedQuantity},请重新选择");
                //// å¦‚果需要自动分配,记录日志
                //_logger.LogInformation($"用户选择的库存数量不足,还需{remainingNeedQuantity},系统将自动分配");
                //List<Dt_StockInfo> autoStocks = _stockService.StockInfoService.GetUseableStocks(
                //    outboundOrderDetail.MaterielCode,
                //    outboundOrderDetail.BatchNo,
                //    "");
                //// æŽ’除用户已选择且已分配的托盘
                //var assignedPalletCodes = outStocks.Select(x => x.PalletCode).ToList();
                //autoStocks = autoStocks
                //    .Where(x => !assignedPalletCodes.Contains(x.PalletCode))
                //    .ToList();
                //var (autoAssignStocks, stockAllocations) = _stockService.StockInfoService.GetOutboundStocks(
                //    autoStocks,
                //    outboundOrderDetail.MaterielCode,
                //    remainingNeedQuantity,
                //    out decimal residueQuantity);
                //if (autoAssignStocks != null && autoAssignStocks.Any())
                //{
                //    outStocks.AddRange(autoAssignStocks);
                //    // ä¸ºè‡ªåŠ¨åˆ†é…çš„åº“å­˜åˆ›å»ºé”å®šè®°å½•
                //    var autoLockInfos = CreateLockInfosForAutoAssign(outboundOrder, outboundOrderDetail, autoAssignStocks, stockAllocations);
                //    outStockLockInfos.AddRange(autoLockInfos);
                //    // æ›´æ–°å·²åˆ†é…æ•°é‡
                //    decimal autoAssignedQuantity = remainingNeedQuantity - residueQuantity;
                //    totalAssignedFromUserSelection += autoAssignedQuantity;
                //    remainingNeedQuantity = residueQuantity; // æ›´æ–°å‰©ä½™éœ€æ±‚
                //}
                //else if (remainingNeedQuantity > 0)
                //{
                //    _logger.LogWarning($"自动分配失败,剩余需求{remainingNeedQuantity}无法满足");
                //}
            }
            // æ›´æ–°é”å®šæ•°é‡
@@ -762,6 +724,8 @@
                .Where(d => d.MaterielCode == detail.MaterielCode &&
                           (d.StockQuantity - d.OutboundQuantity) > 0 &&
                           d.Barcode == barcode); // åªåˆ†é…æŒ‡å®šæ¡ç 
            query = query.Where(x => x.WarehouseCode == detail.WarehouseCode);
            if (!string.IsNullOrEmpty(detail.BatchNo))
            {
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoDetailService.cs
@@ -33,16 +33,42 @@
        public PageGridData<StockInfoDetailWithPalletDto> GetPageData2(PageDataOptions options)
        {
            // 1. èŽ·å–åŸºç¡€åˆ†é¡µæ•°æ®
            PageGridData<Dt_StockInfoDetail> pageData = base.GetPageData(options);
            List<Dt_StockInfoDetail> filteredDetails = pageData.Rows.ToList(); // å…ˆæ‹·è´åŽŸå§‹æ•°æ®
            string wheres = ValidatePageOptions(options);
            var sugarQueryable = Db.Queryable<Dt_StockInfoDetail>().InnerJoin<Dt_StockInfo>((detail, item) => detail.StockId == item.Id);
            Dictionary<string, SqlSugar.OrderByType> orderbyDic = GetPageDataSort(options, TProperties);
            List<OrderByModel> orderByModels = new List<OrderByModel>();
            foreach (var item in orderbyDic)
            {
                if (item.Key.ToLower() == "id")
                {
                    OrderByModel orderByModel = new()
                    {
                        FieldName = "detail."+item.Key,
                        OrderByType = item.Value
                    };
                }
                else
                {
                    OrderByModel orderByModel = new()
                    {
                        FieldName = item.Key,
                        OrderByType = item.Value
                    };
                }
                //orderByModels.Add(orderByModel);
            }
            int totalCount = 0;
            List<SearchParameters> searchParametersList = new List<SearchParameters>();
            if (!string.IsNullOrEmpty(options.Wheres))
            {
                try
                {
                    List<SearchParameters> searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
                    if (searchParametersList?.Any() == true)
                    searchParametersList = options.Wheres.DeserializeObject<List<SearchParameters>>();
                    if (searchParametersList != null && searchParametersList.Any())
                    {
                        foreach (var param in searchParametersList)
                        {
@@ -50,20 +76,7 @@
                            if (param.Name.Equals(nameof(Dt_StockInfo.PalletCode).FirstLetterToLower(), StringComparison.OrdinalIgnoreCase)
                                && !string.IsNullOrEmpty(param.Value?.ToString()))
                            {
                                // ä¼˜åŒ–:批量查询(如果有多个托盘码,这里也可以扩展)
                                string palletCode = param.Value.ToString().Trim();
                                var targetStock = _stockinfoRepository.QueryFirst(x => x.PalletCode == palletCode);
                                // ç©ºå€¼æ ¡éªŒï¼šæœªæ‰¾åˆ°å¯¹åº”托盘的库存,直接过滤为空
                                if (targetStock != null)
                                {
                                    filteredDetails = filteredDetails.Where(x => x.StockId == targetStock.Id).ToList();
                                }
                                else
                                {
                                    filteredDetails = new List<Dt_StockInfoDetail>();
                                }
                                break; // å•个托盘码查询,匹配后退出循环
                                sugarQueryable = sugarQueryable.Where((detail, item) => item.PalletCode.Contains(param.Value));
                            }
                        }
                    }
@@ -73,48 +86,43 @@
                }
            }
            List<int> stockIds = filteredDetails.Select(detail => detail.StockId).Distinct().ToList();
            var stockDict = _stockinfoRepository.QueryData(x => stockIds.Contains(x.Id))
                                                .ToDictionary(x => x.Id, x => x.PalletCode ?? "无托盘编号");
            var data = sugarQueryable
             .WhereIF(!wheres.IsNullOrEmpty(), wheres)
             .OrderBy(orderByModels)
             .Select((detail, item) => new StockInfoDetailWithPalletDto
             {
                 Id = detail.Id,
                 StockId = detail.StockId,
                 MaterielCode = detail.MaterielCode,
                 MaterielName = detail.MaterielName,
                 OrderNo = detail.OrderNo,
                 BatchNo = detail.BatchNo,
                 ProductionDate = detail.ProductionDate,
                 EffectiveDate = detail.EffectiveDate,
                 SerialNumber = detail.SerialNumber,
                 StockQuantity = detail.StockQuantity,
                 OutboundQuantity = detail.OutboundQuantity,
                 Status = detail.Status,
                 Unit = detail.Unit,
                 InboundOrderRowNo = detail.InboundOrderRowNo,
                 SupplyCode = detail.SupplyCode,
                 WarehouseCode = detail.WarehouseCode,
                 Barcode = detail.Barcode,
                 BusinessType = detail.BusinessType,
                 Remark = detail.Remark,
                 Creater = detail.Creater,
                 CreateDate = detail.CreateDate,
                 Modifier = detail.Modifier,
                 ModifyDate = detail.ModifyDate,
                 PalletCode = item.PalletCode
             })
             .ToPageList(options.Page, options.Rows, ref totalCount);
            List<StockInfoDetailWithPalletDto> dtoList = filteredDetails
                .Select(detail => new StockInfoDetailWithPalletDto
                {
                    Id = detail.Id,
                    StockId = detail.StockId,
                    MaterielCode = detail.MaterielCode,
                    MaterielName = detail.MaterielName,
                    OrderNo = detail.OrderNo,
                    BatchNo = detail.BatchNo,
                    ProductionDate = detail.ProductionDate,
                    EffectiveDate = detail.EffectiveDate,
                    SerialNumber = detail.SerialNumber,
                    StockQuantity = detail.StockQuantity,
                    OutboundQuantity = detail.OutboundQuantity,
                    Status = detail.Status,
                    Unit = detail.Unit,
                    InboundOrderRowNo = detail.InboundOrderRowNo,
                    SupplyCode = detail.SupplyCode,
                    WarehouseCode = detail.WarehouseCode,
                    Barcode = detail.Barcode,
                    BusinessType = detail.BusinessType,
                    Remark = detail.Remark,
                    Creater = detail.Creater,
                    CreateDate = detail.CreateDate,
                    Modifier = detail.Modifier,
                    ModifyDate = detail.ModifyDate,
                    PalletCode = stockDict.TryGetValue(detail.StockId, out var palletCode) ? palletCode : "无托盘编号"
                })
                .ToList();
            return new PageGridData<StockInfoDetailWithPalletDto>
            {
                Rows = dtoList.Where(x=>x.PalletCode != "无托盘编号").ToList(),
                Total = pageData.Total,
                Summary = pageData.Summary
            };
            return new PageGridData<StockInfoDetailWithPalletDto>(totalCount, data);
        }
    }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_StockService/StockInfoService.cs
@@ -224,6 +224,51 @@
            return GetStockInfos(materielCode, batchNo, supplyCode, locationCodes);
        }
        public List<Dt_StockInfo> GetUseableStocks(string materielCode, string batchNo, string supplyCode, string wearhouseCode, string factoryCode)
        {
            List<string> locationCodes = _locationInfoService.GetCanOutLocationCodes();
            return GetStockInfos(materielCode, batchNo, supplyCode, locationCodes,wearhouseCode,factoryCode);
        }
        public List<Dt_StockInfo> GetStockInfos(string materielCode, string lotNo, string supplyCode, List<string> locationCodes, string wearhouseCode, string factoryCode)
        {
            if (string.IsNullOrWhiteSpace(wearhouseCode))
            {
                throw new ArgumentNullException("仓库不能为空");
            }
            if (string.IsNullOrWhiteSpace(factoryCode))
            {
                throw new ArgumentNullException("厂区不能为空");
            }
            var query = Db.Queryable<Dt_StockInfo>()
             .Where(x => locationCodes.Contains(x.LocationCode) && x.StockStatus == StockStatusEmun.入库完成.ObjToInt()
             //  && x.StockStatus == (int)StockStatusEmun.正常)
             ).Includes(x => x.Details);
            query = query.Where(x => x.Details.Any(d => d.WarehouseCode == wearhouseCode));
            query = query.Where(x => x.Details.Any(d => d.FactoryArea == factoryCode));
            if (!string.IsNullOrEmpty(materielCode))
            {
                query = query.Where(x => x.Details.Any(d => d.MaterielCode == materielCode));
            }
            if (!string.IsNullOrEmpty(lotNo))
            {
                query = query.Where(x => x.Details.Any(d => d.BatchNo == lotNo));
            }
            if (!string.IsNullOrEmpty(supplyCode))
            {
                query = query.Where(x => x.Details.Any(d => d.SupplyCode == supplyCode));
            }
            return query.OrderBy(x => x.CreateDate).ToList();
            //ISugarQueryable<Dt_LocationInfo> sugarQueryable = Db.Queryable<Dt_LocationInfo>().Where(x => locationCodes.Contains(x.LocationCode));
            //ISugarQueryable<Dt_StockInfo> sugarQueryable1 = Db.Queryable<Dt_StockInfo>().Includes(x => x.Details).Where(x => x.Details.Any(v => v.MaterielCode == materielCode));
            //return sugarQueryable.InnerJoin(sugarQueryable1, (a, b) => a.LocationCode == b.LocationCode).Select((a, b) => b).OrderBy(a => a.CreateDate).Includes(a => a.Details).ToList();
        }
        public Dt_StockInfo GetPalletStockInfo(int locationType)
        {
@@ -295,15 +340,15 @@
            //}
            var outboundOrder = SqlSugarHelper.DbWMS.Queryable<Dt_OutboundOrder>().Includes(x=>x.Details) .Where(x => x.Details.Any(o=>o.OrderId==orderId)).First();
            var outboundOrder = SqlSugarHelper.DbWMS.Queryable<Dt_OutboundOrder>().Includes(x => x.Details).Where(x => x.Details.Any(o => o.OrderId == orderId)).First();
            if (outboundOrder == null)
            {
                throw new Exception($"未找到单据编号为{outboundOrder.UpperOrderNo}的出库单信息");
            }
            return GetStockSelectViews(outboundOrder.Id,orderdetailid, materielCode);
            return GetStockSelectViews(outboundOrder.Id, orderdetailid, materielCode);
        }
        public List<StockSelectViewDTO> GetStockSelectViews(int orderId,int orderdetailid, string materielCode)
        public List<StockSelectViewDTO> GetStockSelectViews(int orderId, int orderdetailid, string materielCode)
        {
            Dt_OutboundOrder outboundOrder = _outboundOrderService.Repository.QueryFirst(x => x.Id == orderId);
            if (outboundOrder == null)
@@ -312,7 +357,7 @@
            }
            // èŽ·å–å‡ºåº“å•æ˜Žç»†ï¼Œç”¨äºŽç¡®å®šéœ€è¦çš„æ‰¹æ¬¡å’Œä¾›åº”å•†
            var orderDetails = SqlSugarHelper.DbWMS.Queryable<Dt_OutboundOrderDetail>().Where(x =>x.Id==orderdetailid && x.OrderId == orderId && x.MaterielCode == materielCode).ToList();
            var orderDetails = SqlSugarHelper.DbWMS.Queryable<Dt_OutboundOrderDetail>().Where(x => x.Id == orderdetailid && x.OrderId == orderId && x.MaterielCode == materielCode).ToList();
            if (!orderDetails.Any())
            {
@@ -333,18 +378,16 @@
                // æ‰§è¡ŒæŸ¥è¯¢å¹¶æŒ‰å…ˆè¿›å…ˆå‡ºæŽ’序
                var Qstocks = stockQuery.Where(x => x.Details.Any(d => d.MaterielCode == materielCode && d.StockQuantity > d.OutboundQuantity));
                Qstocks = stockQuery.Where(x => x.Details.Any(d => d.FactoryArea == outboundOrder.FactoryArea));
                Qstocks = stockQuery.Where(x => x.Details.Any(d => d.WarehouseCode == orderDetail.WarehouseCode));
                if (!string.IsNullOrEmpty(orderDetail.BatchNo))
                {
                    Qstocks = stockQuery.Where(x => x.Details.Any(d => d.BatchNo == orderDetail.BatchNo));
                }
                if (!string.IsNullOrEmpty(orderDetail.SupplyCode))
                {
                    Qstocks = stockQuery.Where(x => x.Details.Any(d => d.SupplyCode == orderDetail.SupplyCode));
                }
                var stocks = Qstocks.OrderBy(x => x.CreateDate).ToList();
@@ -425,17 +468,16 @@
                // æ‰§è¡ŒæŸ¥è¯¢å¹¶æŒ‰å…ˆè¿›å…ˆå‡ºæŽ’序
                var Qstocks = stockQuery.Where(x => x.Details.Any(d => d.MaterielCode == materielCode && d.StockQuantity > d.OutboundQuantity));
                Qstocks = stockQuery.Where(x => x.Details.Any(d => d.FactoryArea == outboundOrder.FactoryArea));
                Qstocks = stockQuery.Where(x => x.Details.Any(d => d.WarehouseCode == orderDetail.WarehouseCode));
                if (!string.IsNullOrEmpty(orderDetail.BatchNo))
                {
                    Qstocks = stockQuery.Where(x => x.Details.Any(d => d.BatchNo == orderDetail.BatchNo));
                }
                if (!string.IsNullOrEmpty(orderDetail.SupplyCode))
                {
                    Qstocks = stockQuery.Where(x => x.Details.Any(d => d.SupplyCode == orderDetail.SupplyCode));
                }
                var stocks = Qstocks.OrderBy(x => x.CreateDate).ToList();