647556386
2026-01-08 e7dac9ecb16aa627f0603beec9930c75ee6aa3f7
盘点
已添加1个文件
已修改14个文件
1040 ■■■■ 文件已修改
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/OrderStockTake.vue 83 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/inbound/extend/TakeStockSelect.vue 288 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/extension/inbound/takeStockOrderDetail.js 251 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/inbound/takeStockOrder.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WIDESEA_WMSClient/src/views/inbound/takeStockOrderDetail.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_BasicService/MESOperation/FeedbackMesService.cs 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/TakeStockStatusEnum.cs 28 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IInboundService/ITakeStockOrderService.cs 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundPickingService.cs 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_InboundService/InboundService.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_InboundService/TakeStockOrderService.cs 301 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_InboundService/WIDESEA_InboundService.csproj 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_TakeStockOrderDetail.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
项目代码/WMS无仓储版/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/TakeStockOrderController.cs 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/extend/OrderStockTake.vue
@@ -61,6 +61,35 @@
            </el-input>
          </el-form-item>
          <!-- æ–°å¢žï¼šç«™å°é€‰æ‹©ä¸‹æ‹‰æ¡† -->
          <el-form-item
            label="回库站台:"
            name="station"
            :rules="[
              {
                required: true,
                message: '请选择回库站台',
                trigger: 'blur',
              },
            ]"
            class="form-item"
          >
            <el-select
              v-model="selectedStation"
              placeholder="请选择回库站台"
              :disabled="!formData.boxNo.trim() || loading"
              class="custom-input"
              :class="{ 'has-value': selectedStation }"
            >
              <el-option
                v-for="item in stations"
                :key="item.key || item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
          <!-- æ¡ç è¾“入框 -->
          <el-form-item
            label="盘点条码:"
@@ -147,7 +176,7 @@
            type="info"
            size="small"
            @click="handleBoxReturn"
            :disabled="!formData.boxNo.trim() || loading"
            :disabled="!formData.boxNo.trim() || !selectedStation || loading"
            class="return-btn"
          >
            <Return /> æ–™ç®±å›žåº“
@@ -188,6 +217,8 @@
import VolBox from "@/components/basic/VolBox.vue";
import http from "@/api/http";
// æ–°å¢žï¼šå¼•入站台管理工具(和示例代码保持一致)
import { stationManager, STATION_STORAGE_KEY } from "@/../src/uitils/stationManager";
// å“åº”式变量 - å•据号
const orderNo = ref("");
@@ -205,6 +236,13 @@
});
const loading = ref(false);
const formRef = ref(null);
// æ–°å¢žï¼šç«™å°ç›¸å…³å“åº”式数据(仿照示例代码)
const stations = ref([
  { label: "站台2", value: "2-1" },
  { label: "站台3", value: "3-1" },
]);
const selectedStation = ref(stationManager.getStation() || ""); // é»˜è®¤é€‰ä¸­ç¼“存的站台
// æ¨¡æ¿å¼•用
const boxNoInputRef = ref(null);
@@ -232,6 +270,8 @@
      formData.barcode = "";
      formData.stockQuantity = "";
      formData.actualQuantity = "";
      // æ–°å¢žï¼šæ–™ç®±å·æ¸…空时,重置站台选择
      selectedStation.value = stationManager.getStation() || "";
    }
  },
  { immediate: true }
@@ -257,6 +297,8 @@
  formData.barcode = "";
  formData.stockQuantity = "";
  formData.actualQuantity = "";
  // æ–°å¢žï¼šæ‰“开弹窗时重置站台选择(默认取缓存的站台)
  selectedStation.value = stationManager.getStation() || "";
  nextTick(() => {
    boxNoInputRef.value?.focus();
  });
@@ -468,16 +510,21 @@
  }
};
// æ–™ç®±å›žåº“功能
// æ–™ç®±å›žåº“功能(核心修改:增加站台验证 + ä¼ å…¥sourceAddress参数)
const handleBoxReturn = async () => {
  const boxNo = formData.boxNo.trim();
  // æ–°å¢žï¼šéªŒè¯ç«™å°æ˜¯å¦é€‰æ‹©
  if (!boxNo) {
    ElMessage.warning("请先输入或扫描料箱号");
    return;
  }
  if (!selectedStation.value) {
    ElMessage.warning("请选择回库站台");
    return;
  }
  try {
    await ElMessageBox.confirm(`确定将料箱【${boxNo}】回库吗?`, "回库确认", {
    await ElMessageBox.confirm(`确定将料箱【${boxNo}】回库至【${selectedStation.value}】站台吗?`, "回库确认", {
      confirmButtonText: "确定",
      cancelButtonText: "取消",
      type: "info",
@@ -488,19 +535,21 @@
    loading.value = true;
    // æ–°å¢žï¼šæ‹¼æŽ¥sourceAddress参数(站台数据)到接口请求中
    const res = await http.post(
      `/api/TakeStockOrder/ReturnBox?boxNo=${encodeURIComponent(boxNo)}&orderNo=${encodeURIComponent(
        orderNo.value
      )}`,
      )}&sourceAddress=${encodeURIComponent(selectedStation.value)}`, // æ–°å¢žsourceAddress参数
      "料箱回库中..."
    );
    if (res.status) {
      ElMessage.success(`料箱【${boxNo}】回库成功!`);
      ElMessage.success(`料箱【${boxNo}】回库至【${selectedStation.value}】站台成功!`);
      formData.boxNo = "";
      formData.barcode = "";
      formData.stockQuantity = "";
      formData.actualQuantity = "";
      selectedStation.value = stationManager.getStation() || ""; // é‡ç½®ç«™å°é€‰æ‹©
      nextTick(() => {
        boxNoInputRef.value?.focus();
      });
@@ -588,13 +637,15 @@
}
/* æœ‰å€¼æ—¶éšè—å ä½ç¬¦ + ä¼˜åŒ–边框 */
.custom-input.has-value :deep(.el-input__inner) {
.custom-input.has-value :deep(.el-input__inner),
.custom-input.has-value :deep(.el-select__wrapper) {
  --el-input-placeholder-color: transparent; /* éšè—å ä½ç¬¦ */
  border-color: #8cc5ff; /* æµ…蓝边框,区分无值状态 */
  background-color: #ffffff;
}
.custom-input :deep(.el-input__inner) {
.custom-input :deep(.el-input__inner),
.custom-input :deep(.el-select__wrapper) {
  border-radius: 8px;
  border-color: #e5f0fa;
  transition: all 0.2s ease;
@@ -606,7 +657,8 @@
}
/* èšç„¦æ ·å¼ä¼˜åŒ– */
.custom-input :deep(.el-input__inner:focus) {
.custom-input :deep(.el-input__inner:focus),
.custom-input :deep(.el-select__wrapper:focus) {
  border-color: #409eff;
  box-shadow: 0 0 0 3px rgba(64, 158, 255, 0.1);
  background-color: #ffffff;
@@ -666,7 +718,8 @@
}
/* æœ‰å€¼æ—¶å³ä½¿éªŒè¯å¤±è´¥ï¼Œä¹Ÿä¸æ˜¾ç¤ºé”™è¯¯è¾¹æ¡† */
.custom-input.has-value :deep(.el-input__inner.el-input__inner--error) {
.custom-input.has-value :deep(.el-input__inner.el-input__inner--error),
.custom-input.has-value :deep(.el-select__wrapper.el-select__wrapper--error) {
  border-color: #8cc5ff;
  box-shadow: none;
}
@@ -807,22 +860,26 @@
}
/* å ä½ç¬¦æ ·å¼ - ç»Ÿä¸€é¢œè‰² */
.el-input__inner::-webkit-input-placeholder {
.el-input__inner::-webkit-input-placeholder,
.el-select__placeholder {
  color: #b3d8ff;
  font-size: 13px;
}
.el-input__inner::-moz-placeholder {
.el-input__inner::-moz-placeholder,
.el-select__placeholder {
  color: #b3d8ff;
  font-size: 13px;
}
.el-input__inner:-ms-input-placeholder {
.el-input__inner:-ms-input-placeholder,
.el-select__placeholder {
  color: #b3d8ff;
  font-size: 13px;
}
.el-input__inner::placeholder {
.el-input__inner::placeholder,
.el-select__placeholder {
  color: #b3d8ff;
  font-size: 13px;
}
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/extend/TakeStockSelect.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,288 @@
<template>
  <el-dialog
    v-model="dialogVisible"
    title="杂收杂发平账"
    width="1000px"
    :close-on-click-modal="false"
    :destroy-on-close="true"
    @closed="handleDialogClosed"
  >
    <div class="reconciliation-container">
      <!-- å•据基本信息 -->
      <div class="order-info">
        <div class="info-row">
          <span class="label">单据ID:</span>
          <span class="value">{{ currentRow.id || '-' }}</span>
        </div>
        <div class="info-row" v-if="selectedItem">
          <span class="label">已选订单:</span>
          <span class="value selected-order">{{ selectedItem.orderId }}</span>
        </div>
      </div>
      <!-- æ•°æ®åˆ—表展示 -->
      <el-scrollbar height="400px" class="custom-scrollbar">
        <transition-group name="data-item-transition">
          <div class="data-item" v-for="(item, index) in displayData" :key="`${item.orderId}-${index}`">
            <div class="radio-container">
              <el-radio
                v-model="selectedItem"
                :label="item"
                :value="item"
                @change="handleRadioChange(item)"
              >
                <!-- å•选按钮的内容留空,只显示单选按钮 -->
              </el-radio>
            </div>
            <div class="data-detail">
              <div class="detail-row">
                <span class="label">订单ID:</span>
                <span class="value">{{ item.orderId || '-' }}</span>
              </div>
              <div class="detail-row">
                <span class="label">物料编码:</span>
                <span class="value">{{ item.materielCode || '-' }}</span>
              </div>
              <div class="detail-row">
                <span class="label">物料名称:</span>
                <span class="value">{{ item.materielName || '-' }}</span>
              </div>
              <div class="detail-row">
                <span class="label">批次号:</span>
                <span class="value">{{ item.batchNo || '-' }}</span>
              </div>
              <div class="detail-row">
                <span class="label">订单数量:</span>
                <span class="value">{{ item.orderQuantity || 0 }}</span>
              </div>
              <div class="detail-row">
                <span class="label">单位:</span>
                <span class="value">{{ item.unit || '-' }}</span>
              </div>
              <div class="detail-row">
                <span class="label">供应商编码:</span>
                <span class="value">{{ item.supplyCode || '-' }}</span>
              </div>
              <div class="detail-row">
                <span class="label">仓库编码:</span>
                <span class="value">{{ item.warehouseCode || '-' }}</span>
              </div>
            </div>
          </div>
        </transition-group>
        <div class="empty-tip" v-if="displayData.length === 0">
          <span>暂无相关数据</span>
        </div>
      </el-scrollbar>
    </div>
    <template #footer>
      <el-button @click="dialogVisible = false">关闭</el-button>
      <el-button
        type="primary"
        @click="handleConfirm"
        :disabled="!selectedItem"
        :loading="loading"
      >
        {{ loading ? '平账中...' : '确认平账' }}
      </el-button>
    </template>
  </el-dialog>
</template>
<script setup>
import { ref } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
// æ ¹æ®æ‚¨çš„实际项目引入请求方法,这里使用axios作为示例
import axios from 'axios';
// å¼¹çª—显示状态
const dialogVisible = ref(false);
// å½“前选中的行数据
const currentRow = ref({});
// è¦å±•示的数据列表
const displayData = ref([]);
// é€‰ä¸­çš„æ•°æ®é¡¹
const selectedItem = ref(null);
// åŠ è½½çŠ¶æ€
const loading = ref(false);
// æ‰“开弹窗方法(供父组件调用)
const open = (row, data) => {
  currentRow.value = row;
  displayData.value = data;
  selectedItem.value = null; // é‡ç½®é€‰æ‹©
  dialogVisible.value = true;
};
// å¤„理单选按钮变化
const handleRadioChange = (item) => {
  selectedItem.value = item;
};
// å¼¹çª—关闭时的处理
const handleDialogClosed = () => {
  selectedItem.value = null;
  loading.value = false;
};
// ç¡®è®¤å¹³è´¦æ“ä½œ
const handleConfirm = async () => {
  if (!selectedItem.value) {
    ElMessage.warning('请选择一条数据进行平账处理');
    return;
  }
  try {
    // ç¡®è®¤æç¤º
    await ElMessageBox.confirm(
      `确定要对订单 ${selectedItem.value.orderId} è¿›è¡Œå¹³è´¦å¤„理吗?`,
      '平账确认',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning',
      }
    );
    loading.value = true;
    // è°ƒç”¨å¹³è´¦æŽ¥å£
    const params = {
      id: currentRow.value.id, // è¡ŒID
      orderId: selectedItem.value.orderId // é€‰æ‹©çš„单据orderId
    };
    // æ ¹æ®æ‚¨çš„æŽ¥å£å®žé™…情况调整请求方式
    const response = await axios.get('/api/TakeStockOrder/DocumentReconciliation', {
      params: params // GET请求传参
      // å¦‚果是POST请求,可以这样写:
      // data: params
    });
    if (response.status) {
      ElMessage.success('平账操作成功');
      dialogVisible.value = false;
      // å¯ä»¥é€šè¿‡emit通知父组件刷新表格
      // emit('refresh-table');
    } else {
    }
  } catch (error) {
    // å¦‚果是用户取消操作,不显示错误信息
    if (error === 'cancel' || error === 'close') {
      return;
    }
    ElMessage.error('平账操作失败,请稍后重试');
  } finally {
    loading.value = false;
  }
};
// æš´éœ²æ–¹æ³•给父组件
defineExpose({
  open
});
</script>
<style scoped>
.reconciliation-container {
  padding: 10px 0;
}
.order-info {
  margin-bottom: 20px;
  padding: 10px;
  background: #f5f7fa;
  border-radius: 4px;
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}
.info-row {
  display: flex;
  align-items: center;
}
.label {
  font-weight: 600;
  color: #606266;
  margin-right: 5px;
  min-width: 80px;
  text-align: right;
}
.value {
  color: #303133;
}
.selected-order {
  color: #409EFF;
  font-weight: 600;
}
.custom-scrollbar {
  border: 1px solid #e4e7ed;
  border-radius: 4px;
}
.data-item {
  display: flex;
  align-items: flex-start;
  padding: 15px;
  margin: 10px;
  background: #fff;
  border: 1px solid #e4e7ed;
  border-radius: 4px;
  transition: all 0.3s;
}
.data-item:hover {
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
}
.data-item.selected {
  border-color: #409EFF;
  background-color: #f0f7ff;
}
.radio-container {
  margin-right: 12px;
  margin-top: 4px;
}
.data-detail {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  flex: 1;
}
.detail-row {
  display: flex;
  align-items: center;
}
.empty-tip {
  text-align: center;
  padding: 50px 0;
  color: #909399;
}
.data-item-transition-enter-from,
.data-item-transition-leave-to {
  opacity: 0;
  transform: translateY(10px);
}
.data-item-transition-enter-active,
.data-item-transition-leave-active {
  transition: all 0.3s ease;
}
:deep(.el-radio__label) {
  display: none;
}
</style>
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/extension/inbound/takeStockOrderDetail.js
@@ -1,58 +1,201 @@
//此js文件是用来自定义扩展业务代码,可以扩展一些自定义页面或者重新配置生成的代码
// è‡ªå®šä¹‰æ‰©å±•业务代码
import gridBody from "./extend/OrderStockTake.vue";
// å¼•入杂收杂发平账弹窗组件
import gridHeader from "./extend/TakeStockSelect.vue";
import { ElMessageBox, ElLoading, ElMessage } from "element-plus";
let extension = {
    components: {
      //查询界面扩展组件
      gridHeader: '',
      gridBody: '',
      gridFooter: '',
      //新建、编辑弹出框扩展组件
      modelHeader: '',
      modelBody: '',
      modelFooter: ''
    },
    tableAction: '', //指定某张表的权限(这里填写表名,默认不用填写)
    buttons: { view: [], box: [], detail: [] }, //扩展的按钮
    methods: {
       //下面这些方法可以保留也可以删除
      onInit() {
      },
      onInited() {
        //框架初始化配置后
        //如果要配置明细表,在此方法操作
        //this.detailOptions.columns.forEach(column=>{ });
      },
      searchBefore(param) {
        //界面查询前,可以给param.wheres添加查询参数
        //返回false,则不会执行查询
        return true;
      },
      searchAfter(result) {
        //查询后,result返回的查询数据,可以在显示到表格前处理表格的值
        return true;
      },
      addBefore(formData) {
        //新建保存前formData为对象,包括明细表,可以给给表单设置值,自己输出看formData的值
        return true;
      },
      updateBefore(formData) {
        //编辑保存前formData为对象,包括明细表、删除行的Id
        return true;
      },
      rowClick({ row, column, event }) {
        //查询界面点击行事件
        this.$refs.table.$refs.table.toggleRowSelection(row); //单击行时选中当前行;
      },
      modelOpenAfter(row) {
        //点击编辑、新建按钮弹出框后,可以在此处写逻辑,如,从后台获取数据
        //(1)判断是编辑还是新建操作: this.currentAction=='Add';
        //(2)给弹出框设置默认值
        //(3)this.editFormFields.字段='xxx';
        //如果需要给下拉框设置默认值,请遍历this.editFormOptions找到字段配置对应data属性的key值
        //看不懂就把输出看:console.log(this.editFormOptions)
  components: {
    // æŸ¥è¯¢ç•Œé¢æ‰©å±•组件
    gridHeader: gridHeader,
    gridBody: gridBody, // åŽŸæœ‰ç›˜ç‚¹å¼¹çª—ç»„ä»¶
    gridFooter: '',
    modelHeader: '',
    modelBody: '',
    modelFooter: ''
  },
  tableAction: '', // æ— éœ€æŒ‡å®šè¡¨å
  buttons: { view: [], box: [], detail: [] }, // æ‰©å±•按钮
  methods: {
    onInit() {
      // åŽŸæœ‰ç›˜ç‚¹æŒ‰é’®é€»è¾‘ä¿ç•™
      let OrderStockTakeBtn = this.buttons.find(x => x.value === 'OrderStockTake');
      if (OrderStockTakeBtn) {
        OrderStockTakeBtn.onClick = function () {
          let rows = this.$refs.table.getSelected();
          if (rows.length === 0) return this.$error("请选择一条盘点单据数据!");
          if (rows.length > 1) return this.$error("只能选择一条盘点单据数据!");
          const selectedReceiptNo = rows[0].orderNo;
          if (!selectedReceiptNo) return this.$error("选中的单据缺少有效的单据号!");
          this.$refs.gridBody.open(selectedReceiptNo);
        };
      }
      // ç›‘听原有弹窗事件(保留)
      this.$nextTick(() => {
        const stockTakeComp = this.$refs.gridBody;
        if (stockTakeComp) {
          stockTakeComp.$on('refresh', () => {
            this.$refs.table.reload();
          });
          stockTakeComp.$on('box-returned', (boxNo) => {
            this.$success(`料箱【${boxNo}】回库成功,表格将刷新!`);
            this.$refs.table.reload();
          });
        }
      });
      // ========== æ–°å¢žæ“ä½œåˆ—:人工平账 + æ‚收杂发平账 ==========
      this.columns.push({
        field: 'operation',
        title: '操作',
        width: 200,
        fixed: 'right',
        align: 'center',
        formatter: (row) => {
          return `
            <span style="cursor: pointer;color: #2d8cf0;margin-right: 10px;" class="manual-reconciliation">
              <i class="el-icon-check"></i>人工平账
            </span>
            <span style="cursor: pointer;color: #1989fa;" class="misc-reconciliation">
              <i class="el-icon-edit"></i>杂收杂发平账
            </span>
          `;
        },
        click: (row, column, event) => {
          const target = event.target;
          // åŒºåˆ†ç‚¹å‡»çš„æ˜¯äººå·¥å¹³è´¦è¿˜æ˜¯æ‚收杂发平账
          if (target.closest('.manual-reconciliation')) {
            this.handleManualReconciliation(row); // äººå·¥å¹³è´¦é€»è¾‘
          } else if (target.closest('.misc-reconciliation')) {
            this.handleMiscReconciliation(row); // æ‚收杂发平账逻辑
          }
        }
      });
    },
    // ========== äººå·¥å¹³è´¦æ ¸å¿ƒé€»è¾‘ ==========
    handleManualReconciliation(row) {
      // å¼¹å‡ºç¡®è®¤æ¡†
      ElMessageBox.confirm(
        '确认要执行人工平账操作吗?',
        '操作确认',
        {
          confirmButtonText: '确认',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).then(async () => {
        // æ·»åŠ é®ç½©å±‚é˜²æ­¢é‡å¤ç‚¹å‡»
        const loading = ElLoading.service({
          lock: true,
          text: '处理中,请稍候...',
          background: 'rgba(0, 0, 0, 0.7)'
        });
        try {
          // è°ƒç”¨äººå·¥å¹³è´¦æŽ¥å£
          const response = await this.http.get(`/api/TakeStockOrder/ManualReconciliation?id=${row.id}`);
          if (response.status) {
            ElMessage.success('人工平账操作成功!');
            this.$refs.table.reload(); // åˆ·æ–°è¡¨æ ¼
          } else {
            ElMessage.error(`操作失败:${response.message || '未知错误'}`);
          }
        } catch (error) {
        } finally {
          // å…³é—­é®ç½©å±‚
          loading.close();
        }
      }).catch(() => {
        ElMessage.info('已取消人工平账操作');
      });
    },
    // ========== æ‚收杂发平账核心逻辑(修改后) ==========
    handleMiscReconciliation(row) {
      // é€‰ä¸­å½“前行
      const table = this.$refs.table.$refs.table;
      if (table) {
        table.clearSelection();
        table.toggleRowSelection(row, true);
      }
      // è°ƒç”¨æŽ¥å£èŽ·å–æ‚æ”¶æ‚å‘å¹³è´¦æ•°æ®
      const fetchMiscData = async () => {
        const loading = ElLoading.service({
          lock: true,
          text: '加载数据中...',
          background: 'rgba(0, 0, 0, 0.7)'
        });
        try {
          // è°ƒç”¨æŽ¥å£ï¼Œä¼ é€’row中的remark和id参数
          const response = await this.http.get(`/api/TakeStockOrder/SelectOrder?remark=${row.remark || ''}&id=${row.id}`);
          loading.close();
          if (response.status) {
            if (!Array.isArray(response.data) || response.data.length === 0) {
              ElMessage.warning("未查询到相关数据");
              // æ‰“开空数据的弹窗
              this.$refs.gridHeader.open(row, []);
              return;
            }
            // æå–需要展示的字段
            const displayData = response.data.map(item => ({
              orderId: item.orderId || '',
              materielCode: item.materielCode || '',
              materielName: item.materielName || '',
              batchNo: item.batchNo || '',
              orderQuantity: item.orderQuantity || 0,
              unit: item.unit || '',
              supplyCode: item.supplyCode || '',
              warehouseCode: item.warehouseCode || ''
            }));
            // æ‰“开弹窗并传递处理后的数据
            this.$refs.gridHeader.open(row, displayData);
          } else {
            ElMessage.error(`查询失败:${response.message || '未知错误'}`);
          }
        } catch (error) {
          loading.close();
          ElMessage.error(`网络异常:${error.message || '接口调用失败'}`);
        }
      };
      // æ‰§è¡Œæ•°æ®æŸ¥è¯¢å¹¶æ‰“开弹窗
      fetchMiscData();
    },
    onInited() {
      // æ¡†æž¶åˆå§‹åŒ–完成后执行
    },
    searchBefore(param) {
      // æŸ¥è¯¢å‰æ‹¦æˆª
      return true;
    },
    searchAfter(result) {
      // æŸ¥è¯¢åŽæ•°æ®å¤„理
      return true;
    },
    addBefore(formData) {
      return true;
    },
    updateBefore(formData) {
      return true;
    },
    rowClick({ row, column, event }) {
      // å•击行选中当前行
      this.$refs.table.$refs.table.toggleRowSelection(row);
    },
    modelOpenAfter(row) {
      // æ–°å»º/编辑弹窗打开后处理
    }
  };
  export default extension;
  }
};
export default extension;
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/inbound/takeStockOrder.vue
@@ -40,7 +40,15 @@
      });
      const searchFormOptions = ref([
        [
        { title: "所含盘点托盘", field: "allPalletCode", type: "like" },
        { title: "单据编号", field: "orderNo", type: "like" },
        {
          field: "takeStockStatus",
          title: "盘点状态",
          type: "select",
          dataKey: "takeStockStatusEnum",
          data: [] ,
        },
        ]
      ]);
  
ÏîÄ¿´úÂë/WIDESEA_WMSClient/src/views/inbound/takeStockOrderDetail.vue
@@ -50,9 +50,16 @@
        { title: "条码", field: "barcode", type: "like" },
        { title: "仓库", field: "warehouseCode", type: "like" },
        { title: "厂区", field: "factoryArea", type: "like" },
        { title: "供应商编号", field: "supplyCode", type: "like" },
        {
          field: "takeDetalStatus",
          title: "盘点明细状态",
          type: "select",
          dataKey: "takeStockDetailStatusEnum",
          data: [] ,
        },
        ],
        [
        { title: "供应商编号", field: "supplyCode", type: "like" },
        { title: "创建人", field: "creater", type: "like" },
        { title: "创建时间", field: "createDate", type: "datetime" },
        ]
@@ -172,6 +179,15 @@
            edit: { type: "decimal" }
          },
          {
            field: "differenceQty",
            title: "待平账数量",
            type: "decimal",
            width: 90,
            align: "left",
            required: true,
            edit: { type: "decimal" }
          },
          {
            field: "unit",
            title: "单位",
            type: "string",
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_BasicService/MESOperation/FeedbackMesService.cs
@@ -98,7 +98,7 @@
                    if (returnDTO.Details.Count <= 0)
                    {
                        return webResponse = WebResponseContent.Instance.Error($"该单据无明细可回传");
                        return webResponse = WebResponseContent.Instance.OK($"该单据没有需要回传明细,失败数据回传{returnRecords.Count()}条,回传成功{returnRecords.Count(x=>x.ReturnStatus == 1)}条,回传失败{returnRecords.Count(x => x.ReturnStatus == 2)}条");
                    }
                    string apiUrl = AppSettings.GetValue("MaterialOutboundFeedbackUrl");
@@ -129,7 +129,7 @@
                    if (returnDTO.Details.Count <= 0)
                    {
                        return webResponse = WebResponseContent.Instance.Error($"该单据无明细可回传");
                        return webResponse = WebResponseContent.Instance.OK($"该单据没有需要回传明细,失败数据回传{returnRecords.Count()}条,回传成功{returnRecords.Count(x => x.ReturnStatus == 1)}条,回传失败{returnRecords.Count(x => x.ReturnStatus == 2)}条");
                    }
                    string apiUrl = AppSettings.GetValue("AllocationFeedbackUrl"); ;
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Common/OrderEnum/TakeStockStatusEnum.cs
@@ -33,8 +33,8 @@
        /// <summary>
        /// ç›˜ç‚¹å…³é—­
        /// </summary>
        [Description("盘点关闭")]
        ç›˜ç‚¹å…³é—­ = 3,
        //[Description("盘点关闭")]
        //盘点关闭 = 3,
    }
    /// <summary>
    /// ç›˜ç‚¹æ˜Žç»†çŠ¶æ€
@@ -42,27 +42,27 @@
    public enum TakeStockDetailStatusEnum
    {
        /// <summary>
        /// æœªç›˜ç‚¹
        /// æœªè¿›è¡Œå¹³è´¦å¤„理
        /// </summary>
        [Description("未盘点")]
        æœªç›˜ç‚¹ = 0,
        [Description("未进行平账处理")]
        æœªè¿›è¡Œå¹³è´¦å¤„理 = 0,
        /// <summary>
        /// ç›˜ç‚¹ä¸­
        /// å·²è¿›è¡Œå¹³è´¦å¤„理
        /// </summary>
        [Description("盘点出库中")]
        ç›˜ç‚¹å‡ºåº“中 = 1,
        [Description("人工平账处理")]
        å·²è¿›è¡Œå¹³è´¦å¤„理 = 1,
        /// <summary>
        /// ç›˜ç‚¹å‡ºåº“完成
        /// æ‚收杂发平账处理
        /// </summary>
        [Description("盘点出库完成")]
        ç›˜ç‚¹å‡ºåº“完成 = 2,
        [Description("杂收杂发平账处理")]
        æ‚收杂发平账处理 = 2,
        /// <summary>
        /// ç›˜ç‚¹å®Œæˆ
        /// æ‚收杂发平账处理中
        /// </summary>
        [Description("盘点完成")]
        ç›˜ç‚¹å®Œæˆ = 3
        [Description("杂收杂发平账处理中")]
        æ‚收杂发平账处理中 = 3
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_IInboundService/ITakeStockOrderService.cs
@@ -19,6 +19,13 @@
        WebResponseContent CompleteStockTake([FromBody] CompleteStockTakeDTO completeStockTakeDTO);
        WebResponseContent ReturnBox(string orderNo, string boxNo);
        WebResponseContent ReturnBox(string orderNo, string boxNo, string sourceAddress);
        WebResponseContent ManualReconciliation(int id);
        WebResponseContent SelectOrder(string remark, int id);
        WebResponseContent DocumentReconciliation(int orderId, int id);
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_IOutboundService/IOutboundPickingService.cs
@@ -58,5 +58,7 @@
        /// <param name="barcode"></param>
        /// <returns></returns>
        public WebResponseContent GetPurchaseOrderByBarcode(string barcode);
        public WebResponseContent NoStockOutBatchInOrderFeedbackToMes(int id, List<string> barCodeList);
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_InboundService/InboundOrderService.cs
@@ -106,9 +106,10 @@
                    foreach (var item in model.Details)
                    {
                        Dt_MaterielInfo materielInfo = materielInfos.First(x => x.MaterielCode == item.MaterielCode);
                        //var purchaseToStockResult = await _materialUnitService.ConvertPurchaseToStockAsync(item.MaterielCode, item.BarcodeQty);
                        UnitConvertResultDTO totalResult = _basicService.UnitQuantityConvert(item.MaterielCode, item.Unit, item.BarcodeUnit, item.OrderQuantity);
                        UnitConvertResultDTO totalResult = _basicService.UnitQuantityConvert(item.MaterielCode, item.Unit, materielInfo.inventoryUOM, item.OrderQuantity);
                        item.Unit = totalResult.ToUnit;
                        item.OrderQuantity = totalResult.ToQuantity;
                        if (materielInfos.Any())
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_InboundService/InboundService.cs
@@ -10,6 +10,7 @@
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using WIDESEA_Common.AllocateEnum;
@@ -23,6 +24,7 @@
using WIDESEA_Core.Utilities;
using WIDESEA_DTO.Allocate;
using WIDESEA_DTO.Inbound;
using WIDESEA_DTO.Mes;
using WIDESEA_DTO.ReturnMES;
using WIDESEA_IBasicService;
using WIDESEA_IInboundService;
@@ -439,7 +441,7 @@
                    if (allocatefeedmodel.Details.Count <= 0)
                    {
                        throw new Exception("未找到需要回传的数据");
                        return WebResponseContent.Instance.OK($"该单据没有需要回传明细,失败数据回传{returnRecords.Count()}条,回传成功{returnRecords.Count(x => x.ReturnStatus == 1)}条,回传失败{returnRecords.Count(x => x.ReturnStatus == 2)}条");
                    }
                    var response = responseModel(inboundOrder, 3, null, allocatefeedmodel);
@@ -473,7 +475,7 @@
                    if (feedmodel.details.Count<=0)
                    {
                        throw new Exception("未找到需要回传的数据");
                        return WebResponseContent.Instance.OK($"该单据没有需要回传明细,失败数据回传{returnRecords.Count()}条,回传成功{returnRecords.Count(x => x.ReturnStatus == 1)}条,回传失败{returnRecords.Count(x => x.ReturnStatus == 2)}条");
                    }
                    var response = responseModel(inboundOrder, 3, feedmodel);
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_InboundService/TakeStockOrderService.cs
@@ -22,6 +22,11 @@
using WIDESEA_Common.CommonEnum;
using WIDESEA_Common.TaskEnum;
using WIDESEA_IBasicService;
using static HslCommunication.Profinet.Knx.KnxCode;
using System.Collections;
using WIDESEA_Common.AllocateEnum;
using WIDESEA_Model.Models.Basic;
using WIDESEA_IOutboundService;
namespace WIDESEA_InboundService
{
@@ -34,7 +39,12 @@
        private readonly IRepository<Dt_TakeStockOrderDetail> _takeStockOrderDetail;
        private readonly IRepository<Dt_Task> _taskRepository;
        private readonly ILocationInfoService _locationInfoService;
        public TakeStockOrderService(IRepository<Dt_TakeStockOrder> BaseDal, IUnitOfWorkManage unitOfWorkManage,IRepository<Dt_TakeStockOrder> takeStockOrder,IRepository<Dt_StockInfo> stockInfoRepository,IRepository<Dt_TakeStockOrderDetail> takeStockOrderDetail,IRepository<Dt_Task> taskRepository,ILocationInfoService locationInfoService) : base(BaseDal)
        private readonly IRepository<Dt_InboundOrder> _inboundOrderRepository;
        private readonly IRepository<Dt_OutboundOrder> _outboundOrderRepository;
        private readonly IRepository<Dt_InboundOrderDetail> _inboundOrderDetailRepository;
        private readonly IRepository<Dt_OutboundOrderDetail> _outboundOrderDetailRepository;
        private readonly IOutboundPickingService _outboundPickingService;
        public TakeStockOrderService(IRepository<Dt_TakeStockOrder> BaseDal, IUnitOfWorkManage unitOfWorkManage,IRepository<Dt_TakeStockOrder> takeStockOrder,IRepository<Dt_StockInfo> stockInfoRepository,IRepository<Dt_TakeStockOrderDetail> takeStockOrderDetail,IRepository<Dt_Task> taskRepository,ILocationInfoService locationInfoService, IRepository<Dt_InboundOrder> inboundOrderRepository,IRepository<Dt_OutboundOrder> outboundOrderRepository,IRepository<Dt_InboundOrderDetail> inboundOrderDetailRepository, IRepository<Dt_OutboundOrderDetail> outboundOrderDetailRepository, IOutboundPickingService outboundPickingService) : base(BaseDal)
        {
            _unitOfWorkManage = unitOfWorkManage;
            _takeStockOrder = takeStockOrder;
@@ -42,6 +52,11 @@
            _takeStockOrderDetail = takeStockOrderDetail;
            _taskRepository = taskRepository;
            _locationInfoService = locationInfoService;
            _inboundOrderRepository = inboundOrderRepository;
            _outboundOrderRepository = outboundOrderRepository;
            _inboundOrderDetailRepository = inboundOrderDetailRepository;
            _outboundOrderDetailRepository = outboundOrderDetailRepository;
            _outboundPickingService = outboundPickingService;
        }
        public WebResponseContent ValidateBoxNo(string orderNo, string boxNo)
@@ -52,7 +67,7 @@
                if (stockInfo == null) {
                    return WebResponseContent.Instance.Error("未找到该托盘库存");
                }
                if(stockInfo.StockStatus != StockStatusEmun.盘点出库完成.ObjToInt())
                if(stockInfo.StockStatus != StockStatusEmun.盘点出库完成.ObjToInt() && stockInfo.StockStatus != StockStatusEmun.盘点库存完成.ObjToInt())
                {
                    return WebResponseContent.Instance.Error("该托盘处于非盘点状态,请检查盘点任务");
                }
@@ -76,15 +91,7 @@
                    bool isMatch = remarkValues.Any(val => val.Equals(boxNo, StringComparison.OrdinalIgnoreCase));
                    if (!isMatch)
                    {
                        return WebResponseContent.Instance.Error($"箱号【{boxNo}】未在盘点单箱号【{takeStockOrder.Remark}】中找到匹配项");
                    }
                }
                else
                {
                    bool isMatch = takeStockOrder.Remark.Trim().Equals(boxNo, StringComparison.OrdinalIgnoreCase);
                    if (!isMatch)
                    {
                        return WebResponseContent.Instance.Error($"箱号【{boxNo}】与盘点单箱号【{takeStockOrder.Remark}】不匹配");
                        return WebResponseContent.Instance.Error($"箱号【{boxNo}】未在盘点单箱号【{takeStockOrder.AllPalletCode}】中找到匹配项");
                    }
                }
@@ -132,6 +139,10 @@
        {
            try
            {
                if(completeStockTakeDTO.actualQuantity == completeStockTakeDTO.stockQuantity)
                {
                    return WebResponseContent.Instance.OK("该条码为平账,无需记录差异");
                }
                Dt_TakeStockOrder takeStockOrder = _takeStockOrder.QueryFirst(x=>x.OrderNo == completeStockTakeDTO.orderNo);
                if (takeStockOrder == null)
                {
@@ -147,38 +158,58 @@
                {
                    return WebResponseContent.Instance.Error("条码库存数据未找到匹配数据");
                }
                List<Dt_AllocateMaterialInfo> allocateMaterialInfos = new List<Dt_AllocateMaterialInfo>();
                Dt_TakeStockOrderDetail takeStockOrderDetail = new Dt_TakeStockOrderDetail()
                {
                    TakeStockId = takeStockOrder.Id,
                    MaterielCode = stockInfoDetail.MaterielCode,
                    MaterielName = stockInfoDetail.MaterielName??"",
                    MaterielName = stockInfoDetail.MaterielName ?? "",
                    BatchNo = stockInfoDetail.BatchNo,
                    TakePalletCode = completeStockTakeDTO.boxNo,
                    TakeDetalStatus = TakeStockDetailStatusEnum.盘点完成.ObjToInt(),
                    TakeDetalStatus = TakeStockDetailStatusEnum.未进行平账处理.ObjToInt(),
                    Unit = stockInfoDetail.Unit,
                    SysQty = completeStockTakeDTO.stockQuantity,
                    Qty =completeStockTakeDTO.actualQuantity,
                    Remark = completeStockTakeDTO.stockQuantity-completeStockTakeDTO.actualQuantity>=0 ?"盘亏":"盘盈",
                    Qty = completeStockTakeDTO.actualQuantity,
                    Remark = completeStockTakeDTO.stockQuantity - completeStockTakeDTO.actualQuantity >= 0 ? "盘亏" : "盘盈",
                    barcode = completeStockTakeDTO.barcode,
                    WarehouseCode = stockInfoDetail.WarehouseCode??"",
                    WarehouseCode = stockInfoDetail.WarehouseCode ?? "",
                    FactoryArea = stockInfoDetail.FactoryArea,
                    SupplyCode = stockInfoDetail.SupplyCode??"",
                    SupplyCode = stockInfoDetail.SupplyCode ?? "",
                    TakeStockNo = takeStockOrder.OrderNo,
                    DifferenceQty = completeStockTakeDTO.stockQuantity - completeStockTakeDTO.actualQuantity
                };
                foreach (var item in stockInfo.Details)
                {
                    Dt_AllocateMaterialInfo allocateMaterialInfo = new Dt_AllocateMaterialInfo()
                    {
                        Barcode = item.Barcode,
                        BatchNo = item.BatchNo,
                        FactoryArea = item.FactoryArea,
                        MaterialCode = item.MaterielCode,
                        MaterialName = item.MaterielName,
                        OrderId = takeStockOrder.Id,
                        OrderNo = takeStockOrder.OrderNo,
                        Quantity = item.StockQuantity,
                        SupplyCode = item.SupplyCode,
                        Unit = item.Unit
                    };
                }
                stockInfo.StockStatus = StockStatusEmun.盘点库存完成.ObjToInt();
                _unitOfWorkManage.BeginTran();
                _takeStockOrderDetail.AddData(takeStockOrderDetail);
                _stockInfoRepository.UpdateData(stockInfo);
                _unitOfWorkManage.CommitTran();
                return WebResponseContent.Instance.OK();
            }
            catch (Exception ex)
                return WebResponseContent.Instance.OK("盘点完成,请取走该异常料箱进行平账处理!");
            }
            catch (Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        public WebResponseContent ReturnBox(string orderNo, string boxNo)
        public WebResponseContent ReturnBox(string orderNo, string boxNo, string sourceAddress)
        {
            WebResponseContent content = new WebResponseContent();
            try
@@ -202,13 +233,33 @@
                {
                    return content.Error($"托盘{boxNo}存在任务回库失败!");
                }
                if(stock.StockStatus != StockStatusEmun.盘点出库完成.ObjToInt())
                if(stock.StockStatus != StockStatusEmun.盘点出库完成.ObjToInt() && stock.StockStatus != StockStatusEmun.盘点库存完成.ObjToInt())
                {
                    return content.Error("该托盘状态不对,不允许盘点入库");
                }
                stock.StockStatus = StockStatusEmun.入库确认.ObjToInt();
                takeStockOrder.TakeStockStatus = TakeStockStatusEnum.盘点完成.ObjToInt();
                var palletCodes = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
                if (!string.IsNullOrEmpty(takeStockOrder.AllPalletCode))
                {
                    palletCodes = takeStockOrder.AllPalletCode
                        .Split(new[] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries)
                        .Select(p => p.Trim())
                        .ToHashSet(StringComparer.OrdinalIgnoreCase);
                }
                Dt_TakeStockOrderDetail isReturn = _takeStockOrderDetail.QueryFirst(x => x.TakePalletCode == boxNo && (x.TakeDetalStatus == TakeStockDetailStatusEnum.未进行平账处理.ObjToInt() || x.TakeDetalStatus == TakeStockDetailStatusEnum.杂收杂发平账处理中.ObjToInt()));
                if(isReturn != null)
                {
                    return WebResponseContent.Instance.Error("该托盘还有条码待平账,请先处理再回库");
                }
                bool hasRelatedTasks = _taskRepository.QueryData(x => palletCodes.Contains(x.PalletCode)).Any();
                bool hasRelatedDetails = _takeStockOrderDetail.QueryData(x => palletCodes.Contains(x.TakePalletCode)).Any();
                if (!hasRelatedTasks && !hasRelatedDetails)
                {
                    takeStockOrder.TakeStockStatus = (int)TakeStockStatusEnum.盘点完成;
                }
                // åˆ†é…æ–°è´§ä½
                var newLocation = _locationInfoService.AssignLocation(stock.LocationType);
@@ -220,7 +271,7 @@
                    NextAddress = "",
                    OrderNo = takeStockOrder.OrderNo,
                    Roadway = newLocation.RoadwayNo,
                    SourceAddress = takeStockOrder.Remark,
                    SourceAddress = sourceAddress,
                    TargetAddress = newLocation.LocationCode,
                    TaskStatus = (int)TaskStatusEnum.New,
                    TaskType = TaskTypeEnum.InInventory.ObjToInt(),
@@ -247,6 +298,208 @@
                return content.Error(ex.Message);
            }
        }
        public WebResponseContent ManualReconciliation(int id)
        {
            try
            {
                Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetail.QueryFirst(x=>x.Id == id);
                if(takeStockOrderDetail == null)
                {
                    return WebResponseContent.Instance.Error("未找到该盘点差异记录");
                }
                else
                {
                    if(takeStockOrderDetail.TakeDetalStatus != TakeStockDetailStatusEnum.未进行平账处理.ObjToInt())
                    {
                        return WebResponseContent.Instance.Error("该记录已经进行了平账操作");
                    }
                    takeStockOrderDetail.DifferenceQty = 0;
                    takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.已进行平账处理.ObjToInt();
                }
                _takeStockOrderDetail.UpdateData(takeStockOrderDetail);
                return WebResponseContent.Instance.OK();
            }
            catch(Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        public WebResponseContent SelectOrder(string remark, int id)
        {
            try
            {
                Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetail.QueryFirst(x => x.Id == id);
                if (takeStockOrderDetail == null)
                {
                    return WebResponseContent.Instance.Error("未找到该盘点差异记录");
                }
                else
                {
                    //查杂收单
                    if (takeStockOrderDetail.Remark == "盘盈")
                    {
                        List<Dt_InboundOrderDetail> inboundOrderDetails = new List<Dt_InboundOrderDetail>();
                        List<Dt_InboundOrder> inboundOrders = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().Where(x => x.BusinessType == "12" && x.OrderStatus != InOrderStatusEnum.入库完成.ObjToInt()).Includes(x => x.Details).ToList();
                        foreach (var inboundOrder in inboundOrders)
                        {
                            var matchedDetails = inboundOrder.Details
                                .Where(detail => !string.IsNullOrEmpty(detail.MaterielCode)
                                              && detail.MaterielCode == takeStockOrderDetail.MaterielCode && detail.OrderDetailStatus != OrderDetailStatusEnum.Over.ObjToInt())
                                .WhereIF(!string.IsNullOrEmpty(takeStockOrderDetail.FactoryArea),
                                         detail => !string.IsNullOrEmpty(inboundOrder.FactoryArea)
                                              && inboundOrder.FactoryArea == takeStockOrderDetail.FactoryArea)
                                .WhereIF(!string.IsNullOrEmpty(takeStockOrderDetail.WarehouseCode),
                                         detail => !string.IsNullOrEmpty(detail.WarehouseCode)
                                         && detail.WarehouseCode == takeStockOrderDetail.WarehouseCode)
                                .ToList();
                            // å°†åŒ¹é…çš„æ˜Žç»†æ·»åŠ åˆ°æ€»åˆ—è¡¨
                            if (matchedDetails.Any())
                            {
                                inboundOrderDetails.AddRange(matchedDetails);
                            }
                        }
                        return WebResponseContent.Instance.OK("成功",data: inboundOrderDetails);
                    }
                    else
                    {
                        List<Dt_OutboundOrderDetail> outboundOrderDetails = new List<Dt_OutboundOrderDetail>();
                        List<Dt_OutboundOrder> outboundOrders = _outboundOrderRepository.Db.Queryable<Dt_OutboundOrder>().Where(x => x.BusinessType == "23" && x.OrderStatus != OutOrderStatusEnum.出库完成.ObjToInt()).Includes(x => x.Details).ToList();
                        foreach (var outboundOrder in outboundOrders)
                        {
                            var matchedDetails = outboundOrder.Details
                                .Where(detail => !string.IsNullOrWhiteSpace(detail.MaterielCode)
                                              && detail.MaterielCode == takeStockOrderDetail.MaterielCode)
                                .WhereIF(!string.IsNullOrWhiteSpace(takeStockOrderDetail.FactoryArea),
                                         detail => !string.IsNullOrWhiteSpace(outboundOrder.FactoryArea)
                                              && outboundOrder.FactoryArea == takeStockOrderDetail.FactoryArea)
                                .WhereIF(!string.IsNullOrWhiteSpace(takeStockOrderDetail.WarehouseCode),
                                         detail => !string.IsNullOrWhiteSpace(detail.WarehouseCode)
                                              && detail.WarehouseCode == takeStockOrderDetail.WarehouseCode)
                                .Where(detail => string.IsNullOrWhiteSpace(detail.BatchNo)||
                                         detail.BatchNo == takeStockOrderDetail.BatchNo)
                                .Where(detail => string.IsNullOrWhiteSpace(detail.SupplyCode) ||
                                         detail.SupplyCode == takeStockOrderDetail.SupplyCode)
                                .ToList();
                            if (matchedDetails.Any())
                            {
                                outboundOrderDetails.AddRange(matchedDetails);
                            }
                        }
                        return WebResponseContent.Instance.OK("成功", data: outboundOrderDetails);
                    }
                }
            }
            catch (Exception ex)
            {
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
        public WebResponseContent DocumentReconciliation(int orderId, int id)
        {
            try
            {
                Dt_TakeStockOrderDetail takeStockOrderDetail = _takeStockOrderDetail.QueryFirst(x => x.Id == id);
                if(takeStockOrderDetail== null)
                {
                    return WebResponseContent.Instance.Error("未找到该盘点差异数据");
                }
                if(takeStockOrderDetail.Remark == "盘盈")
                {
                    Dt_InboundOrderDetail inboundOrderDetail = _inboundOrderDetailRepository.QueryFirst(x => x.OrderId == orderId);
                    if(inboundOrderDetail == null)
                    {
                        return WebResponseContent.Instance.Error("未找到选择的杂收平账单据");
                    }
                    Dt_InboundOrder inboundOrder = _inboundOrderRepository.Db.Queryable<Dt_InboundOrder>().Where(x=>x.Id == orderId).Includes(x=>x.Details).First();
                    Dt_StockInfo  stockInfo = _stockInfoRepository.Db.Queryable<Dt_StockInfo>().Where(x=>x.PalletCode == takeStockOrderDetail.TakePalletCode && x.StockStatus == StockStatusEmun.盘点库存完成.ObjToInt()).Includes(x=>x.Details).First();
                    if(stockInfo== null)
                    {
                        return WebResponseContent.Instance.Error($"盘点托盘{takeStockOrderDetail.TakePalletCode}的库存信息未找到,或托盘状态不正确");
                    }
                    var datevaliDate = _inboundOrderRepository.Db.Queryable<Dt_MaterialExpirationDate>().Where(x => x.MaterialCode.Contains(inboundOrderDetail.MaterielCode.Substring(0, 6))).First();
                    var newStockDetail = new Dt_StockInfoDetail
                    {
                        StockId = stockInfo == null ? 0 : stockInfo.Id,
                        Barcode = inboundOrderDetail.Barcode,
                        MaterielCode = inboundOrderDetail.MaterielCode,
                        MaterielName = inboundOrderDetail.MaterielName,
                        BatchNo = inboundOrderDetail.BatchNo,
                        Unit = inboundOrderDetail.Unit,
                        InboundOrderRowNo = inboundOrderDetail.lineNo,
                        SupplyCode = inboundOrderDetail.SupplyCode,
                        WarehouseCode = inboundOrderDetail.WarehouseCode,
                        StockQuantity = inboundOrderDetail.OrderQuantity,
                        BarcodeQty = inboundOrderDetail.BarcodeQty,
                        BarcodeUnit = inboundOrderDetail.BarcodeUnit,
                        FactoryArea = inboundOrder.FactoryArea,
                        Status = 0,
                        OrderNo = inboundOrder.InboundOrderNo,
                        BusinessType = inboundOrder.BusinessType,
                        ValidDate = inboundOrder.BusinessType == BusinessTypeEnum.外部仓库调智仓.ToString() ? inboundOrderDetail.ValidDate : datevaliDate == null ? null : Convert.ToDateTime(DateTime.Now).AddDays(Convert.ToDouble(datevaliDate.ValidityDays)),
                    };
                    stockInfo.Details.Add(newStockDetail);
                    inboundOrderDetail.ReceiptQuantity = inboundOrderDetail.OrderQuantity;
                    inboundOrderDetail.OverInQuantity = inboundOrderDetail.OrderQuantity;
                    inboundOrderDetail.OrderDetailStatus = OrderDetailStatusEnum.Over.ObjToInt();
                    int overCount = 1;
                    int moreOverCount = inboundOrder.Details.Count(x => x.OrderDetailStatus == OrderDetailStatusEnum.Over.ObjToInt());
                    if (inboundOrder.Details.Count() == overCount + moreOverCount)
                    {
                        inboundOrder.OrderStatus = InOrderStatusEnum.入库完成.ObjToInt();
                    }
                    else
                    {
                        inboundOrder.OrderStatus = InOrderStatusEnum.入库中.ObjToInt();
                    }
                    takeStockOrderDetail.DifferenceQty += inboundOrderDetail.OrderQuantity;
                    if(takeStockOrderDetail.DifferenceQty > 0)
                    {
                        return WebResponseContent.Instance.Error("该杂收单据明细条码数量大于待平账数量,请另选其他单据平账");
                    }
                    else if (takeStockOrderDetail.DifferenceQty == 0)
                    {
                        takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.杂收杂发平账处理.ObjToInt();
                    }
                    else
                    {
                        takeStockOrderDetail.TakeDetalStatus = TakeStockDetailStatusEnum.杂收杂发平账处理中.ObjToInt();
                    }
                    _unitOfWorkManage.BeginTran();
                    _inboundOrderRepository.UpdateData(inboundOrder);
                    _inboundOrderDetailRepository.UpdateData(inboundOrderDetail);
                    _takeStockOrderDetail.UpdateData(takeStockOrderDetail);
                    BaseDal.Db.Insertable(newStockDetail).ExecuteCommand();
                    _unitOfWorkManage.CommitTran();
                    List<string> barcodes = new List<string>();
                    barcodes.Add(inboundOrderDetail.Barcode);
                    _outboundPickingService.NoStockOutBatchInOrderFeedbackToMes(orderId, barcodes);
                }
                else
                {
                }
                return WebResponseContent.Instance.OK();
            }
            catch(Exception ex)
            {
                _unitOfWorkManage.RollbackTran();
                return WebResponseContent.Instance.Error(ex.Message);
            }
        }
    }
    
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_InboundService/WIDESEA_InboundService.csproj
@@ -9,6 +9,7 @@
  <ItemGroup>
    <ProjectReference Include="..\WIDESEA_IBasicService\WIDESEA_IBasicService.csproj" />
    <ProjectReference Include="..\WIDESEA_IInboundService\WIDESEA_IInboundService.csproj" />
    <ProjectReference Include="..\WIDESEA_IOutboundService\WIDESEA_IOutboundService.csproj" />
    <ProjectReference Include="..\WIDESEA_IRecordService\WIDESEA_IRecordService.csproj" />
    <ProjectReference Include="..\WIDESEA_IStockService\WIDESEA_IStockService.csproj" />
    <ProjectReference Include="..\WIDESEA_ITaskInfoService\WIDESEA_ITaskInfoService.csproj" />
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_Model/Models/Inbound/Dt_TakeStockOrderDetail.cs
@@ -140,5 +140,12 @@
        [SugarColumn(IsNullable = true, Length = 50, ColumnDescription = "盘点单单据")]
        [ExporterHeader(DisplayName = "盘点单单据")]
        public string TakeStockNo { get; set; }
        /// <summary>
        /// å·®å¼‚数量
        /// </summary>
        [SugarColumn(IsNullable = true, ColumnDescription = "差异数量")]
        [ExporterHeader(DisplayName = "差异数量")]
        public decimal DifferenceQty { get; set; }
    }
}
ÏîÄ¿´úÂë/WMSÎÞ²Ö´¢°æ/WIDESEA_WMSServer/WIDESEA_WMSServer/Controllers/Inbound/TakeStockOrderController.cs
@@ -49,9 +49,36 @@
        /// ç›˜ç‚¹æ–™ç®±å›žåº“
        /// </summary>
        [HttpPost, HttpGet, Route("ReturnBox"), AllowAnonymous]
        public WebResponseContent ReturnBox(string orderNo, string boxNo)
        public WebResponseContent ReturnBox(string orderNo, string boxNo, string sourceAddress)
        {
            return Service.ReturnBox(orderNo, boxNo);
            return Service.ReturnBox(orderNo, boxNo,sourceAddress);
        }
        /// <summary>
        /// äººå·¥å¹³è´¦å¤„理
        /// </summary>
        [HttpPost, HttpGet, Route("ManualReconciliation"), AllowAnonymous]
        public WebResponseContent ManualReconciliation(int id)
        {
            return Service.ManualReconciliation(id);
        }
        /// <summary>
        /// æ‚收杂发单据查询
        /// </summary>
        [HttpPost, HttpGet, Route("SelectOrder"), AllowAnonymous]
        public WebResponseContent SelectOrder(string remark,int id)
        {
            return Service.SelectOrder(remark,id);
        }
        /// <summary>
        /// æ‚发杂收单处理
        /// </summary>
        [HttpPost, HttpGet, Route("DocumentReconciliation"), AllowAnonymous]
        public WebResponseContent DocumentReconciliation(int orderId, int id)
        {
            return Service.DocumentReconciliation(orderId, id);
        }
    }
}