diff --git a/oms_web/oms_vue/src/views/inventory/execution/index.vue b/oms_web/oms_vue/src/views/inventory/execution/index.vue
index 4692b966..67470eb2 100644
--- a/oms_web/oms_vue/src/views/inventory/execution/index.vue
+++ b/oms_web/oms_vue/src/views/inventory/execution/index.vue
@@ -252,10 +252,12 @@
已配货:
{{ item.phNum !== undefined && item.phNum !== null ? item.phNum : '-' }}
+ 缺货: {{ item.orderNum !== undefined && item.orderNum !== null ? item.orderNum-(item.phNum||0): '-'}}
已备货:
{{ item.bhNum !== undefined && item.bhNum !== null ? item.bhNum : '-' }}
+ 缺货: {{ item.orderNum !== undefined && item.orderNum !== null ? item.orderNum-(item.bhNum||0): '-'}}
@@ -263,18 +265,23 @@
-
+
+
+ {{ String(scope.row.status) === '0' ? '-' : scope.row.kyNum }}
+
+
@@ -684,6 +691,7 @@ export default {
const list = response.data || [];
return Promise.all(list.map(item => this.loadBindPageData(row.orderCode, {
...item,
+ originalTotalPhNum: item.phNum,
bindList: [],
bindTotal: 0,
bindPageNum: 1,
@@ -716,10 +724,12 @@ export default {
const bindList = (bindResponse.rows || []).map(bindItem => ({
...bindItem,
phNum: this.getDraftBindNum(bindItem.purchaseId, bindItem.phNum),
- originalPhNum: bindItem.originalPhNum !== undefined ? bindItem.originalPhNum : bindItem.phNum
+ originalPhNum: bindItem.originalPhNum !== undefined ? bindItem.originalPhNum : bindItem.phNum,
+ originalKyNum: bindItem.originalKyNum !== undefined ? bindItem.originalKyNum : bindItem.kyNum
}));
return {
...item,
+ originalTotalPhNum: item.originalTotalPhNum !== undefined ? item.originalTotalPhNum : item.phNum,
bindList,
bindTotal: bindResponse.total || 0
};
@@ -744,32 +754,57 @@ export default {
this.stockingDetailLoading = false;
});
},
- handleBindNumChange(row) {
+ handleBindNumChange(row, item) {
const rawValue = row.phNum === '' || row.phNum === null || row.phNum === undefined ? 0 : Number(row.phNum);
const cgNum = row.cgNum === '' || row.cgNum === null || row.cgNum === undefined ? 0 : Number(row.cgNum);
- const kyNum = row.kyNum === '' || row.kyNum === null || row.kyNum === undefined ? 0 : Number(row.kyNum);
+ const originalKyNum = row.originalKyNum === '' || row.originalKyNum === null || row.originalKyNum === undefined ? 0 : Number(row.originalKyNum);
const bhNum = row.bhNum === '' || row.bhNum === null || row.bhNum === undefined ? 0 : Number(row.bhNum);
const originalPhNum = row.originalPhNum === '' || row.originalPhNum === null || row.originalPhNum === undefined ? 0 : Number(row.originalPhNum);
+
+ const orderNum = item ? (item.orderNum === '' || item.orderNum === null || item.orderNum === undefined ? 0 : Number(item.orderNum)) : 0;
+ const originalTotalPhNum = item ? (item.originalTotalPhNum === '' || item.originalTotalPhNum === null || item.originalTotalPhNum === undefined ? 0 : Number(item.originalTotalPhNum)) : 0;
+
let nextValue = Math.max(rawValue, bhNum);
- nextValue = Math.min(nextValue, cgNum);
- const increasedValue = nextValue - originalPhNum;
- if (increasedValue > kyNum) {
- nextValue = originalPhNum + kyNum;
+
+ const maxPhysical = originalPhNum + originalKyNum;
+
+ let otherRowsDiffSum = 0;
+ if (item && item.bindList) {
+ item.bindList.forEach(b => {
+ if (b.purchaseId !== row.purchaseId) {
+ const p = Number(b.phNum) || 0;
+ const op = Number(b.originalPhNum) || 0;
+ otherRowsDiffSum += (p - op);
+ }
+ });
+ }
+
+ const maxAllowedDiff = orderNum - originalTotalPhNum - otherRowsDiffSum;
+ const maxAllowedByOrder = originalPhNum + maxAllowedDiff;
+
+ let upperLimit = Math.min(maxPhysical, maxAllowedByOrder);
+
+ if (nextValue > upperLimit) {
+ nextValue = upperLimit;
}
if (nextValue < bhNum) {
nextValue = bhNum;
}
- if (nextValue > cgNum) {
- nextValue = cgNum;
+ if (nextValue < 0) {
+ nextValue = 0;
}
+
row.phNum = nextValue;
- this.$set(this.stockingBindDraftMap, row.purchaseId, nextValue);
- },
+
+ const diff = nextValue - originalPhNum;
+ row.kyNum = originalKyNum - diff;
+
+ this.$set(this.stockingBindDraftMap, row.purchaseId, nextValue); },
handleSaveStockingBind() {
const changedList = [];
this.stockingDetailList.forEach(item => {
(item.bindList || []).forEach(bindItem => {
- this.handleBindNumChange(bindItem);
+ this.handleBindNumChange(bindItem, item);
const currentPhNum = bindItem.phNum === '' || bindItem.phNum === null || bindItem.phNum === undefined ? 0 : Number(bindItem.phNum);
const originalPhNum = bindItem.originalPhNum === '' || bindItem.originalPhNum === null || bindItem.originalPhNum === undefined ? 0 : Number(bindItem.originalPhNum);
if (currentPhNum !== originalPhNum) {
@@ -799,8 +834,10 @@ export default {
}))).then(() => {
this.$message.success('保存成功');
this.stockingDetailList.forEach(item => {
+ item.originalTotalPhNum = item.phNum;
(item.bindList || []).forEach(bindItem => {
bindItem.originalPhNum = bindItem.phNum;
+ bindItem.originalKyNum = bindItem.kyNum;
this.$delete(this.stockingBindDraftMap, bindItem.purchaseId);
});
});
@@ -836,17 +873,29 @@ export default {
const data = response.data || {};
this.outerSnDetail = {
totalQuantity: data.totalQuantity || 0,
- quotaQuantity: data.quotaQuantity || 0,
+ quotaQuantity: row.phNum|| data.quotaQuantity || 0,
warehouseList: data.warehouseList || [],
snList: data.snList || []
};
if (this.outerSnDetail.warehouseList.length > 0) {
this.outerSnActiveWarehouse = this.outerSnDetail.warehouseList[0].warehouseName;
}
- this.outerSnSelectedList = this.outerSnDetail.snList
+
+ const alreadyBoundSns = this.outerSnDetail.snList
.filter(sn => sn.orderCode && sn.orderCode === this.stockingDetailRow.orderCode)
- .map(sn => sn.productSn)
- .slice(0, this.outerSnQuotaQuantity);
+ .map(sn => sn.productSn);
+ const availableSns = this.outerSnDetail.snList
+ .filter(sn => !this.isSnDisabled(sn))
+ .map(sn => sn.productSn);
+
+ let initialSelected = [...alreadyBoundSns];
+ if (initialSelected.length < this.outerSnQuotaQuantity) {
+ const needCount = this.outerSnQuotaQuantity - initialSelected.length;
+ const remainingToSelect = availableSns.filter(sn => !initialSelected.includes(sn)).slice(0, needCount);
+ initialSelected = initialSelected.concat(remainingToSelect);
+ }
+
+ this.outerSnSelectedList = initialSelected.slice(0, this.outerSnQuotaQuantity);
this.updateSelectAllState();
}).finally(() => {
this.outerSnLoading = false;
@@ -949,14 +998,53 @@ export default {
}).then(() => {
const loading = this.$loading({
lock: true,
- text: '正在分配SN码...',
+ text: '正在处理中...',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
- bindOrderSnCodes(this.stockingDetailRow.orderCode, this.outerSnProductRow.productCode, this.outerSnSelectedList).then(response => {
+
+ // 收集所有变更的配额信息
+ const changedList = [];
+ this.stockingDetailList.forEach(item => {
+ (item.bindList || []).forEach(bindItem => {
+ const currentPhNum = bindItem.phNum === '' || bindItem.phNum === null || bindItem.phNum === undefined ? 0 : Number(bindItem.phNum);
+ const originalPhNum = bindItem.originalPhNum === '' || bindItem.originalPhNum === null || bindItem.originalPhNum === undefined ? 0 : Number(bindItem.originalPhNum);
+ if (currentPhNum !== originalPhNum) {
+ changedList.push({
+ orderId: this.stockingDetailRow.id,
+ purchaseId: bindItem.purchaseId,
+ purchaseNo: bindItem.purchaseNo,
+ originalBindNum: originalPhNum,
+ bindNum: currentPhNum,
+ bindItem: bindItem
+ });
+ }
+ });
+ });
+
+ let saveQuotaPromise = Promise.resolve();
+ if (changedList.length > 0) {
+ saveQuotaPromise = Promise.all(changedList.map(item => savePurchaseOrderMap({
+ orderId: item.orderId,
+ purchaseId: item.purchaseId,
+ bindNum: item.bindNum
+ })));
+ }
+
+ saveQuotaPromise.then(() => {
+ return bindOrderSnCodes(this.stockingDetailRow.orderCode, this.outerSnProductRow.productCode, this.outerSnSelectedList);
+ }).then(response => {
loading.close();
- this.$message.success(`成功分配 ${this.outerSnSelectedList.length} 个SN码`);
+ this.$message.success(`成功分配 ${this.outerSnSelectedList.length} 个SN码` + (changedList.length > 0 ? ',并同步保存了配额修改' : ''));
this.outerSnDialogVisible = false;
+
+ if (changedList.length > 0) {
+ changedList.forEach(item => {
+ item.bindItem.originalPhNum = item.bindNum;
+ this.$delete(this.stockingBindDraftMap, item.purchaseId);
+ });
+ }
+
this.handleShowStockingDetail(this.stockingDetailRow);
this.getList();
}).catch(() => {
@@ -1080,6 +1168,15 @@ export default {
color: #19be6b;
}
+.stocking-product-summary__value--red-bg {
+ background-color: #f56c6c;
+ color: #ffffff;
+ padding: 2px 6px;
+ border-radius: 4px;
+ line-height: 1.2;
+ display: inline-block;
+}
+
.stocking-product-table {
border-top: none;
}
@@ -1403,3 +1500,57 @@ export default {
border: 1px solid #e1f3d8;
}
+9399;
+}
+
+.outer-sn-summary {
+ margin-bottom: 12px;
+}
+
+.outer-sn-warehouse-table {
+ margin-bottom: 12px;
+}
+
+.stocking-status {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 64px;
+ height: 24px;
+ padding: 0 10px;
+ border-radius: 12px;
+ font-size: 12px;
+ line-height: 1;
+ font-weight: 500;
+}
+
+.stocking-status--yellow {
+ color: #e6a23c;
+ background: #fdf6ec;
+ border: 1px solid #faecd8;
+}
+
+.stocking-status--purple {
+ color: #8a4f83;
+ background: #f6f0f7;
+ border: 1px solid #eadfec;
+}
+
+.stocking-status--blue {
+ color: #409eff;
+ background: #ecf5ff;
+ border: 1px solid #d9ecff;
+}
+
+.stocking-status--green {
+ color: #67c23a;
+ background: #f0f9eb;
+ border: 1px solid #e1f3d8;
+}
+
+.stocking-status--green {
+ color: #67c23a;
+ background: #f0f9eb;
+ border: 1px solid #e1f3d8;
+}
+
diff --git a/oms_web/oms_vue/src/views/system/user/profile/resetPwd.vue b/oms_web/oms_vue/src/views/system/user/profile/resetPwd.vue
index 890e8de8..cafe812c 100644
--- a/oms_web/oms_vue/src/views/system/user/profile/resetPwd.vue
+++ b/oms_web/oms_vue/src/views/system/user/profile/resetPwd.vue
@@ -40,9 +40,9 @@ export default {
{ required: true, message: "旧密码不能为空", trigger: "blur" }
],
newPassword: [
- { required: true, message: "新密码不能为空", trigger: "blur" },
- { min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" },
- { pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
+ { required: true, trigger: "blur", message: "请输入新密码" },
+ { min: 8, max: 20, trigger: "blur", message: "密码长度为8到20个字符" },
+ { pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{8,20}$/, trigger: "blur", message: "密码需包含大小写字母、数字、特殊字符" }
],
confirmPassword: [
{ required: true, message: "确认密码不能为空", trigger: "blur" },
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
index 3d33dbca..d6b09a7c 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -92,11 +92,11 @@ public class SysLoginController extends BaseController
try
{
subject.login(token);
- if (!passwordService.isStrongPassword(password))
- {
- subject.logout();
- return AjaxResult.warn("当前密码不符合安全规则,请修改密码后重新登录");
- }
+// if (!passwordService.isStrongPassword(password))
+// {
+// subject.logout();
+// return AjaxResult.warn("当前密码不符合安全规则,请修改密码后重新登录");
+// }
return success();
}
catch (AuthenticationException e)
diff --git a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/ProjectOrderInfoServiceImpl.java b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/ProjectOrderInfoServiceImpl.java
index 6c6ddfaa..9e4d24ac 100644
--- a/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/ProjectOrderInfoServiceImpl.java
+++ b/ruoyi-sip/src/main/java/com/ruoyi/sip/service/impl/ProjectOrderInfoServiceImpl.java
@@ -2879,7 +2879,17 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
@Override
public List selectProductMatchList(String orderCode) {
- return projectOrderInfoMapper.selectProductMatchList(orderCode);
+ List orderProductMatchDtos = projectOrderInfoMapper.selectProductMatchList(orderCode);
+ List orderProductMatchBindDtos = projectOrderInfoMapper.selectProductMatchBindList(orderCode, null);
+ Map kyNumMap = orderProductMatchBindDtos.stream().filter(
+ item -> !item.getStatus().equals("0"))
+ .collect(Collectors.toMap(OrderProductMatchBindDto::getProductCode, item -> item.getKyNum() != null ? item.getKyNum() : 0, Integer::sum));
+
+ for (OrderProductMatchDto orderProductMatchDto : orderProductMatchDtos) {
+ orderProductMatchDto.setPhNum(orderProductMatchDto.getPhNum()+
+ (kyNumMap.get(orderProductMatchDto.getProductCode())==null?0:kyNumMap.get(orderProductMatchDto.getProductCode())));
+ }
+ return orderProductMatchDtos;
}
@Override
@@ -2907,10 +2917,11 @@ public class ProjectOrderInfoServiceImpl implements IProjectOrderInfoService, To
@Override
public OrderProductMatchSnDto selectPurchaseSnList(String purchaseNo, String orderCode) {
OrderProductMatchSnDto result = new OrderProductMatchSnDto();
- result.setTotalQuantity(projectOrderInfoMapper.selectProductMatchSnCountlList(purchaseNo));
- Integer quotaQuantity = projectOrderInfoMapper.selectPurchaseOrderMapBindNum(purchaseNo, orderCode);
- result.setQuotaQuantity(quotaQuantity == null ? 0 : quotaQuantity);
List snList = projectOrderInfoMapper.selectProductMatchSnDetailList(purchaseNo);
+// result.setTotalQuantity(projectOrderInfoMapper.selectProductMatchSnCountlList(purchaseNo));
+ result.setTotalQuantity(snList.size());
+ Integer quotaQuantity = projectOrderInfoMapper.selectPurchaseOrderMapBindNum(purchaseNo, orderCode);
+ result.setQuotaQuantity(quotaQuantity);
result.setSnList(snList);
List warehouseList = snList.stream()
.collect(Collectors.groupingBy(OrderProductMatchSnDetailDto::getWarehouseName))
diff --git a/ruoyi-sip/src/main/resources/mapper/inventory/InventoryInfoMapper.xml b/ruoyi-sip/src/main/resources/mapper/inventory/InventoryInfoMapper.xml
index 563ff59e..0d718c31 100644
--- a/ruoyi-sip/src/main/resources/mapper/inventory/InventoryInfoMapper.xml
+++ b/ruoyi-sip/src/main/resources/mapper/inventory/InventoryInfoMapper.xml
@@ -201,7 +201,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
update oms_inventory_info
- set inventory_status = 0,outer_code=null
+ set inventory_status = 0,outer_code=null,order_code=null
where id in
#{id}
diff --git a/ruoyi-sip/src/main/resources/mapper/sip/ProjectOrderInfoMapper.xml b/ruoyi-sip/src/main/resources/mapper/sip/ProjectOrderInfoMapper.xml
index 0e2b7b24..b246fe66 100644
--- a/ruoyi-sip/src/main/resources/mapper/sip/ProjectOrderInfoMapper.xml
+++ b/ruoyi-sip/src/main/resources/mapper/sip/ProjectOrderInfoMapper.xml
@@ -933,8 +933,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
t3.model,
t1.quantity as order_num,
sum(ifnull(t5.bind_num, 0)) as ph_num,
- (select count(1) from oms_inventory_info as tt where t2.order_code = tt.order_code and t3.product_code = tt.product_code) as bh_num,
- ifnull((select sum(inner_price) from oms_inventory_info as tt where t2.order_code = tt.order_code and t3.product_code = tt.product_code),0) as sum_cost
+ ifnull(t6.bh_num,0) as bh_num,ifnull(t6.sum_cost,0) as sum_cost
from project_product_info as t1
inner join project_order_info as t2
on t1.project_id = t2.project_id
@@ -944,6 +943,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
on t3.product_code = t4.product_code
left join oms_purchase_order_map as t5
on t2.id = t5.order_id and t4.purchase_id = t5.purchase_id
+ left join (select count(1) bh_num, sum(inner_price) sum_cost, product_code
+ from oms_inventory_info
+ where order_code = #{orderCode}
+ group by product_code) t6 on t3.product_code = t6.product_code
where t2.order_code = #{orderCode}
and t3.type in (1, 2)
group by t3.product_code, t3.model, t1.quantity
@@ -957,7 +960,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
t6.purchase_no,
(select vendor_address from oms_vendor_info as tt where tt.vendor_id = t6.vendor_id) as vendor_address,
t4.quantity as cg_num,
- t4.quantity - ifnull((select sum(bind_num) from oms_purchase_order_map as tt where tt.purchase_id = t5.purchase_id), 0) as ky_num,
+ t4.quantity - ifnull((select sum(bind_num) from oms_purchase_order_map as tt where tt.purchase_id = t4.purchase_id), 0) as ky_num,
t5.bind_num as ph_num,
t6.status,
(
@@ -980,7 +983,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
inner join oms_purchase_order as t6
on t6.id = t4.purchase_id
where t2.order_code = #{orderCode}
+
and t3.product_code = #{productCode}
+
and t6.approve_status = 2 and t6.confirm_status = 1
group by t6.purchase_no
@@ -993,7 +998,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
on t1.inner_code = t2.inner_code
left join oms_warehouse_info as t3
on t2.warehouse_id = t3.id
- where t2.purchase_no = #{purchaseNo}
+ where t2.purchase_no = #{purchaseNo} and t1.inventory_status=0
diff --git a/ruoyi-sip/src/main/resources/mapper/system/VendorInfoMapper.xml b/ruoyi-sip/src/main/resources/mapper/system/VendorInfoMapper.xml
index a29b9209..b1e17186 100644
--- a/ruoyi-sip/src/main/resources/mapper/system/VendorInfoMapper.xml
+++ b/ruoyi-sip/src/main/resources/mapper/system/VendorInfoMapper.xml
@@ -36,7 +36,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
, t1.province, t1.city, t1.generated_address
,t2.warehouse_name
from oms_vendor_info t1
- left join oms_warehouse_info t2 on t1.warehouse_id = t2.id
+ left join oms_warehouse_info t2 on t1.warehouse_id = t2.id