From 450d4d8bdef369111268bd024377b8f7c5c3bc84 Mon Sep 17 00:00:00 2001 From: “wangming” <“wangming@antissoft.com”> Date: Tue, 3 Feb 2026 16:04:24 +0800 Subject: [PATCH] refactor: 废弃 lq_mdxx.kjb,科技部门店改由 lq_md_target 按月份获取 --- netcore/src/Modularity/Extend/NCC.Extend/LqAnnualSummaryService.cs | 2 +- netcore/src/Modularity/Extend/NCC.Extend/LqReportService.cs | 29 +++++++++++++++++++---------- netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsTechDeptService.cs | 23 +++++++++++++---------- netcore/src/Modularity/Extend/NCC.Extend/LqTechGeneralManagerSalaryService.cs | 55 +++++++++++++++++++++++++++++-------------------------- netcore/src/Modularity/Extend/NCC.Extend/LqZjlMdsmxszService.cs | 35 ++++++++++++++++++++++++++++++++--- netcore/test-kjb-removal-apis.sh | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ sql/根据产品平均单价更新库存领取金额.sql | 43 +++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 281 insertions(+), 50 deletions(-) create mode 100755 netcore/test-kjb-removal-apis.sh create mode 100644 sql/根据产品平均单价更新库存领取金额.sql diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqAnnualSummaryService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqAnnualSummaryService.cs index d180b1b..bd48802 100644 --- a/netcore/src/Modularity/Extend/NCC.Extend/LqAnnualSummaryService.cs +++ b/netcore/src/Modularity/Extend/NCC.Extend/LqAnnualSummaryService.cs @@ -82,7 +82,7 @@ namespace NCC.Extend var storeIds = list.list.Select(x => x.StoreId).Distinct().ToList(); var stores = await _db.Queryable() .Where(x => storeIds.Contains(x.Id)) - .Select(x => new { x.Id, x.Syb, x.Kjb }) + .Select(x => new { x.Id, x.Syb }) .ToListAsync(); var storeDict = stores.ToDictionary(x => x.Id, x => x); diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqReportService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqReportService.cs index d8e8954..24b4b1d 100644 --- a/netcore/src/Modularity/Extend/NCC.Extend/LqReportService.cs +++ b/netcore/src/Modularity/Extend/NCC.Extend/LqReportService.cs @@ -4653,7 +4653,7 @@ namespace NCC.Extend // 从门店目标表获取归属ID var businessUnitId = target?.BusinessUnit ?? store.Syb; - var techDepartmentId = target?.TechDepartment ?? store.Kjb; + var techDepartmentId = target?.TechDepartment; var educationDepartmentId = target?.EducationDepartment ?? store.Jyb; var majorProjectDepartmentId = target?.MajorProjectDepartment ?? store.Dxmb; @@ -4783,7 +4783,7 @@ namespace NCC.Extend // 从门店目标表获取归属ID var businessUnitId = target?.BusinessUnit ?? store.Syb; - var techDepartmentId = target?.TechDepartment ?? store.Kjb; + var techDepartmentId = target?.TechDepartment; var educationDepartmentId = target?.EducationDepartment ?? store.Jyb; var majorProjectDepartmentId = target?.MajorProjectDepartment ?? store.Dxmb; @@ -5353,11 +5353,13 @@ namespace NCC.Extend .Select(x => x.Id) .ToListAsync(); } - else if (!string.IsNullOrWhiteSpace(store.Kjb)) + else if (target != null && !string.IsNullOrWhiteSpace(target.TechDepartment)) { - sameOrgStoreIds = await _db.Queryable() - .Where(x => x.Kjb == store.Kjb && x.Zxzt == "开店" && x.Id != input.StoreId) - .Select(x => x.Id) + // 科技部已废弃 lq_mdxx.kjb,按统计月份从门店目标表取同科技部门店(且开店) + sameOrgStoreIds = await _db.Queryable((t, m) => t.StoreId == m.Id && m.Zxzt == "开店") + .Where((t, m) => t.Month == statisticsMonth && t.TechDepartment == target.TechDepartment && t.StoreId != input.StoreId) + .Select((t, m) => t.StoreId) + .Distinct() .ToListAsync(); } @@ -6212,6 +6214,11 @@ namespace NCC.Extend throw NCCException.Oh("门店不存在"); } + // 获取当月门店目标(用于同组织门店-科技部从 lq_md_target 取) + var target = await _db.Queryable() + .Where(x => x.StoreId == input.StoreId && x.Month == statisticsMonth) + .FirstAsync(); + // 获取业绩排名 var allStoresPerformance = await _db.Ado.SqlQueryAsync($@" SELECT @@ -6302,11 +6309,13 @@ namespace NCC.Extend .Select(x => x.Id) .ToListAsync(); } - else if (!string.IsNullOrWhiteSpace(store.Kjb)) + else if (target != null && !string.IsNullOrWhiteSpace(target.TechDepartment)) { - sameOrgStoreIds = await _db.Queryable() - .Where(x => x.Kjb == store.Kjb && x.Zxzt == "开店" && x.Id != input.StoreId) - .Select(x => x.Id) + // 科技部已废弃 lq_mdxx.kjb,按统计月份从门店目标表取同科技部门店(且开店) + sameOrgStoreIds = await _db.Queryable((t, m) => t.StoreId == m.Id && m.Zxzt == "开店") + .Where((t, m) => t.Month == statisticsMonth && t.TechDepartment == target.TechDepartment && t.StoreId != input.StoreId) + .Select((t, m) => t.StoreId) + .Distinct() .ToListAsync(); } diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsTechDeptService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsTechDeptService.cs index fee903b..d037183 100644 --- a/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsTechDeptService.cs +++ b/netcore/src/Modularity/Extend/NCC.Extend/LqShareStatisticsTechDeptService.cs @@ -4,6 +4,7 @@ using NCC.Dependency; using NCC.DynamicApiController; using NCC.Extend.Entitys.Dto.LqShareStatisticsTechDept; using NCC.Extend.Entitys.lq_share_statistics_tech_dept; +using NCC.Extend.Entitys.lq_md_target; using NCC.Extend.Entitys.lq_mdxx; using NCC.Extend.Entitys.lq_kd_pxmx; using NCC.Extend.Entitys.lq_kd_kdjlb; @@ -88,7 +89,7 @@ namespace NCC.Extend }; // 计算各项数据 - await CalculateIncome(entity, deptName, startDate, endDate); + await CalculateIncome(entity, deptName, startDate, endDate, input.StatisticsMonth); await CalculateCost(entity, deptName, startDate, endDate, input.StatisticsMonth); CalculateProfit(entity); @@ -175,7 +176,7 @@ namespace NCC.Extend /// /// 计算收入部分 /// - private async Task CalculateIncome(LqShareStatisticsTechDeptEntity entity, string deptName, DateTime startDate, DateTime endDate) + private async Task CalculateIncome(LqShareStatisticsTechDeptEntity entity, string deptName, DateTime startDate, DateTime endDate, string statisticsMonth) { // 1. 通过组织名称找到组织ID var organize = await _db.Queryable() @@ -188,10 +189,11 @@ namespace NCC.Extend return; } - // 2. 找到该科技部管辖的所有门店(通过组织ID) - var stores = await _db.Queryable() - .Where(x => x.Kjb == organize.Id) - .Select(x => x.Id) + // 2. 找到该科技部当月管辖的门店(lq_mdxx.kjb 已废弃,从 lq_md_target 按月份取) + var stores = await _db.Queryable() + .Where(x => x.Month == statisticsMonth && x.TechDepartment == organize.Id) + .Select(x => x.StoreId) + .Distinct() .ToListAsync(); if (stores.Count == 0) @@ -282,10 +284,11 @@ namespace NCC.Extend return; } - // 2. 找到该科技部管辖的所有门店(通过组织ID) - var stores = await _db.Queryable() - .Where(x => x.Kjb == organize.Id) - .Select(x => x.Id) + // 2. 找到该科技部当月管辖的门店(lq_mdxx.kjb 已废弃,从 lq_md_target 按月份取) + var stores = await _db.Queryable() + .Where(x => x.Month == statisticsMonth && x.TechDepartment == organize.Id) + .Select(x => x.StoreId) + .Distinct() .ToListAsync(); // 1. 成本-报销:筛选一级分类为"科技部费用"的申请,根据申请门店的归属区分一部/二部 diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqTechGeneralManagerSalaryService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqTechGeneralManagerSalaryService.cs index 081c0ff..40501bf 100644 --- a/netcore/src/Modularity/Extend/NCC.Extend/LqTechGeneralManagerSalaryService.cs +++ b/netcore/src/Modularity/Extend/NCC.Extend/LqTechGeneralManagerSalaryService.cs @@ -15,6 +15,7 @@ using NCC.Extend.Entitys.lq_kd_jksyj; using NCC.Extend.Entitys.lq_kd_kdjlb; using NCC.Extend.Entitys.lq_kd_pxmx; using NCC.Extend.Entitys.lq_md_general_manager_lifeline; +using NCC.Extend.Entitys.lq_md_target; using NCC.Extend.Entitys.lq_mdxx; using NCC.Extend.Entitys.lq_tech_general_manager_salary_statistics; using NCC.Extend.Entitys.lq_xmzl; @@ -273,35 +274,30 @@ namespace NCC.Extend } // 1.3 获取科技部总经理归属信息(从lq_md_general_manager_lifeline表) - // 通过门店的科技部组织ID(kjb字段)找到科技一部或科技二部管理的门店 - // 然后在lifeline表中找到这些门店的记录,这些记录对应的总经理就是科技部总经理 - var lifelineList = await _db.Queryable( - (lifeline, store) => lifeline.StoreId == store.Id) - .Where((lifeline, store) => - lifeline.Month == monthStr - && techOrganizeIds.Contains(store.Kjb)) - .Select((lifeline, store) => lifeline) + // lq_mdxx.kjb 已废弃,按统计月份从 lq_md_target 取科技一部/二部管理的门店,再关联 lifeline + var techManagedStoreIdsForMonth = await _db.Queryable() + .Where(x => x.Month == monthStr && techOrganizeIds.Contains(x.TechDepartment)) + .Select(x => x.StoreId) + .Distinct() .ToListAsync(); - - // 1.4 获取科技一部和科技二部管理的门店(通过门店的kjb字段) - var techManagedStoreIds = await _db.Queryable() - .Where(x => techOrganizeIds.Contains(x.Kjb)) - .Select(x => x.Id) + var lifelineList = await _db.Queryable() + .Where(x => x.Month == monthStr && techManagedStoreIdsForMonth.Contains(x.StoreId)) .ToListAsync(); - // 1.5 按科技部总经理ID分组,获取每个科技部总经理管理的门店 - // 科技部总经理管理的门店 = 科技一部/科技二部管理的所有门店(通过门店的kjb字段确定) + // 1.4 获取科技一部和科技二部当月管理的门店(从 lq_md_target) + var techManagedStoreIds = techManagedStoreIdsForMonth; + + // 1.5 按科技部总经理ID分组,获取每个科技部总经理当月管理的门店(从 lq_md_target) var managerStoreDict = new Dictionary>(); foreach (var managerUser in techGeneralManagerUserList) { var managerId = managerUser.Id; var managerOrganizeId = managerUser.OrganizeId; - // 如果该总经理属于科技一部,则管理所有科技一部的门店 - // 如果该总经理属于科技二部,则管理所有科技二部的门店 - var managedStores = await _db.Queryable() - .Where(x => x.Kjb == managerOrganizeId) - .Select(x => x.Id) + var managedStores = await _db.Queryable() + .Where(x => x.Month == monthStr && x.TechDepartment == managerOrganizeId) + .Select(x => x.StoreId) + .Distinct() .ToListAsync(); managerStoreDict[managerId] = managedStores; @@ -415,6 +411,15 @@ namespace NCC.Extend } } + // 批量查询当月门店科技部归属(lq_md_target),避免循环内查询 + var storeTechDeptList = await _db.Queryable() + .Where(x => x.Month == monthStr && allManagedStoreIds.Contains(x.StoreId)) + .Select(x => new { x.StoreId, x.TechDepartment }) + .ToListAsync(); + var storeTechDeptDict = storeTechDeptList + .GroupBy(x => x.StoreId) + .ToDictionary(g => g.Key, g => g.First().TechDepartment); + // 遍历所有门店,构建门店明细 foreach (var storeId in allManagedStoreIds) { @@ -429,16 +434,14 @@ namespace NCC.Extend _logger.LogInformation($"[科技部总经理工资计算] 门店ID: {storeId}, 开单Cell金额: {storeCellBilling}, 退卡Cell金额: {storeCellRefund}, Cell金额: {storeCellBilling - storeCellRefund}"); } - // 获取该门店属于哪些科技部总经理 - // 通过门店的kjb字段确定:如果门店的kjb等于科技一部的组织ID,则该门店属于科技一部总经理 + // 获取该门店属于哪些科技部总经理(按当月 lq_md_target 的科技部归属) var store = storeDict.ContainsKey(storeId) ? storeDict[storeId] : null; var managersOfStore = new List(); - - if (store != null && !string.IsNullOrEmpty(store.Kjb)) + var storeTechDept = storeTechDeptDict.ContainsKey(storeId) ? storeTechDeptDict[storeId] : null; + if (!string.IsNullOrEmpty(storeTechDept)) { - // 找到组织ID等于门店kjb的科技部总经理 var managers = techGeneralManagerUserList - .Where(x => x.OrganizeId == store.Kjb) + .Where(x => x.OrganizeId == storeTechDept) .Select(x => x.Id) .ToList(); managersOfStore.AddRange(managers); diff --git a/netcore/src/Modularity/Extend/NCC.Extend/LqZjlMdsmxszService.cs b/netcore/src/Modularity/Extend/NCC.Extend/LqZjlMdsmxszService.cs index 2f9a81a..7a59521 100644 --- a/netcore/src/Modularity/Extend/NCC.Extend/LqZjlMdsmxszService.cs +++ b/netcore/src/Modularity/Extend/NCC.Extend/LqZjlMdsmxszService.cs @@ -8,6 +8,7 @@ using NCC.Extend.Entitys.Dto.LqZjlMdsmxsz; using NCC.Extend.Entitys.Entity.lq_zjl_mdsmxsz; using NCC.Extend.Interfaces.LqZjlMdsmxsz; using NCC.System.Entitys.Permission; +using NCC.Extend.Entitys.lq_md_target; using NCC.Extend.Entitys.lq_mdxx; using SqlSugar; using System; @@ -263,10 +264,38 @@ namespace NCC.Extend public async Task GetManagedStores(string userid) { var userOrganizeId = await _db.Queryable().Where(x => x.Id == userid && x.DeleteMark == null).Select(x => x.OrganizeId).FirstAsync(); - // 根据组织权限获取门店 - var stores = await _db.Queryable() - .Where(s => s.Syb == userOrganizeId || s.Jyb == userOrganizeId || s.Kjb == userOrganizeId || s.Dxmb == userOrganizeId) + if (string.IsNullOrEmpty(userOrganizeId)) + { + return new { list = new List() }; + } + + // 科技部(科技一部/科技二部)已废弃 lq_mdxx.kjb,按当月 lq_md_target 取管理门店 + var techOrganizeIds = await _db.Queryable() + .Where(x => x.FullName != null && (x.FullName.Contains("科技一部") || x.FullName.Contains("科技二部")) && x.DeleteMark == null && x.EnabledMark == 1) + .Select(x => x.Id) .ToListAsync(); + + List stores; + if (techOrganizeIds.Contains(userOrganizeId)) + { + var monthStr = DateTime.Now.ToString("yyyyMM"); + var storeIds = await _db.Queryable() + .Where(x => x.Month == monthStr && x.TechDepartment == userOrganizeId) + .Select(x => x.StoreId) + .Distinct() + .ToListAsync(); + stores = storeIds.Any() + ? await _db.Queryable().Where(s => storeIds.Contains(s.Id)).ToListAsync() + : new List(); + } + else + { + // 事业部、教育部、大项目部:按门店表当前归属(不再使用已废弃的 Kjb) + stores = await _db.Queryable() + .Where(s => s.Syb == userOrganizeId || s.Jyb == userOrganizeId || s.Dxmb == userOrganizeId) + .ToListAsync(); + } + return new { list = stores }; } #endregion diff --git a/netcore/test-kjb-removal-apis.sh b/netcore/test-kjb-removal-apis.sh new file mode 100755 index 0000000..c7bed7a --- /dev/null +++ b/netcore/test-kjb-removal-apis.sh @@ -0,0 +1,144 @@ +#!/bin/bash +# 测试废弃 kjb 后修改的接口是否返回正确 +# 使用方式: ./test-kjb-removal-apis.sh [BASE_URL],默认 http://localhost:2011 + +set -e +BASE_URL="${1:-http://localhost:2011}" +echo "=== 使用 API 地址: $BASE_URL ===" + +# 1. 登录获取 token +echo "" +echo ">>> 1. 登录获取 token..." +LOGIN_RESP=$(curl -s -X POST "$BASE_URL/api/oauth/Login" \ + -H "Content-Type: application/x-www-form-urlencoded" \ + -d "account=admin&password=e10adc3949ba59abbe56e057f20f883e") +TOKEN=$(echo "$LOGIN_RESP" | grep -o '"token":"[^"]*"' | sed 's/"token":"//;s/"$//') +if [ -z "$TOKEN" ]; then + echo "登录失败,响应: $LOGIN_RESP" + exit 1 +fi +echo "登录成功,已获取 token" + +# 2. LqReport - get-store-base-info(空 storeId 校验 + 可选真实门店校验) +echo "" +echo ">>> 2. POST /api/Extend/LqReport/get-store-base-info (空 storeId 校验)" +RESP=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/api/Extend/LqReport/get-store-base-info" \ + -H "Content-Type: application/json" \ + -H "Authorization: $TOKEN" \ + -d '{"storeId":"","statisticsMonth":"202601"}') +HTTP_CODE=$(echo "$RESP" | tail -n1) +BODY=$(echo "$RESP" | sed '$d') +if [ "$HTTP_CODE" = "400" ] || echo "$BODY" | grep -q "门店ID不能为空"; then + echo " [预期] 未传 storeId 时返回 400 或提示门店ID不能为空: HTTP $HTTP_CODE" +else + echo " HTTP $HTTP_CODE (若为200且 body 含 code 非200 也为参数校验行为)" + echo "$BODY" | head -c 400 + echo "" +fi +# 使用真实门店ID验证归属来自 lq_md_target(如 绿纤龙湖店) +if [ -n "${STORE_ID:-}" ]; then + echo ">>> 2b. get-store-base-info (真实 storeId=$STORE_ID)" + curl -s -X POST "$BASE_URL/api/Extend/LqReport/get-store-base-info" \ + -H "Content-Type: application/json" -H "Authorization: $TOKEN" \ + -d "{\"storeId\":\"$STORE_ID\",\"statisticsMonth\":\"202601\"}" | head -c 600 + echo "" +fi + +# 3. LqReport get-store-data-analysis(同上,验证接口可调通) +echo "" +echo ">>> 3. POST /api/Extend/LqReport/get-store-data-analysis" +RESP=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/api/Extend/LqReport/get-store-data-analysis" \ + -H "Content-Type: application/json" \ + -H "Authorization: $TOKEN" \ + -d '{"storeId":"","statisticsMonth":"202601"}') +HTTP_CODE=$(echo "$RESP" | tail -n1) +BODY=$(echo "$RESP" | sed '$d') +if [ "$HTTP_CODE" = "400" ] || echo "$BODY" | grep -q "门店ID不能为空"; then + echo " [预期] 未传 storeId 时返回 400 或提示门店ID不能为空: HTTP $HTTP_CODE" +else + echo " HTTP $HTTP_CODE" + echo "$BODY" | head -c 500 + echo "" +fi + +# 4. LqReport get-store-comparison-analysis +echo "" +echo ">>> 4. POST /api/Extend/LqReport/get-store-comparison-analysis" +RESP=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/api/Extend/LqReport/get-store-comparison-analysis" \ + -H "Content-Type: application/json" \ + -H "Authorization: $TOKEN" \ + -d '{"storeId":"","statisticsMonth":"202601"}') +HTTP_CODE=$(echo "$RESP" | tail -n1) +BODY=$(echo "$RESP" | sed '$d') +if [ "$HTTP_CODE" = "400" ] || echo "$BODY" | grep -q "门店ID不能为空"; then + echo " [预期] 未传 storeId 时返回 400 或提示门店ID不能为空: HTTP $HTTP_CODE" +else + echo " HTTP $HTTP_CODE" + echo "$BODY" | head -c 500 + echo "" +fi + +# 5. LqTechGeneralManagerSalary - GET tech-general-manager +echo "" +echo ">>> 5. GET /api/Extend/LqTechGeneralManagerSalary/tech-general-manager (2026年1月)" +RESP=$(curl -s -w "\n%{http_code}" -X GET "$BASE_URL/api/Extend/LqTechGeneralManagerSalary/tech-general-manager?Year=2026&Month=1¤tPage=1&pageSize=10" \ + -H "Authorization: $TOKEN") +HTTP_CODE=$(echo "$RESP" | tail -n1) +BODY=$(echo "$RESP" | sed '$d') +echo " HTTP $HTTP_CODE" +echo "$BODY" | head -c 800 +echo "" + +# 6. LqTechGeneralManagerSalary - POST calculate/tech-general-manager(仅触发计算,不校验结果) +echo "" +echo ">>> 6. POST /api/Extend/LqTechGeneralManagerSalary/calculate/tech-general-manager (year=2026, month=1)" +RESP=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/api/Extend/LqTechGeneralManagerSalary/calculate/tech-general-manager?year=2026&month=1" \ + -H "Authorization: $TOKEN") +HTTP_CODE=$(echo "$RESP" | tail -n1) +BODY=$(echo "$RESP" | sed '$d') +echo " HTTP $HTTP_CODE" +echo "$BODY" | head -c 400 +echo "" + +# 7. LqShareStatisticsTechDept - generate +echo "" +echo ">>> 7. POST /api/Extend/LqShareStatisticsTechDept/generate (statisticsMonth=202601)" +RESP=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/api/Extend/LqShareStatisticsTechDept/generate" \ + -H "Content-Type: application/json" \ + -H "Authorization: $TOKEN" \ + -d '{"statisticsMonth":"202601"}') +HTTP_CODE=$(echo "$RESP" | tail -n1) +BODY=$(echo "$RESP" | sed '$d') +echo " HTTP $HTTP_CODE" +echo "$BODY" +echo "" + +# 8. LqZjlMdsmxsz - GET ManagedStores/{userid}(科技部总经理 userid 需从系统获取,这里用占位验证 404/200) +echo "" +echo ">>> 8. GET /api/Extend/LqZjlMdsmxsz/ManagedStores/{userid} (使用占位 userid 验证路由与逻辑)" +RESP=$(curl -s -w "\n%{http_code}" -X GET "$BASE_URL/api/Extend/LqZjlMdsmxsz/ManagedStores/000000000000000001" \ + -H "Authorization: $TOKEN") +HTTP_CODE=$(echo "$RESP" | tail -n1) +BODY=$(echo "$RESP" | sed '$d') +echo " HTTP $HTTP_CODE" +echo "$BODY" | head -c 500 +echo "" + +# 9. LqMdTarget GetManagedStores(未改 kjb 逻辑,但可顺带验证科技部按 lq_md_target 返回) +echo "" +echo ">>> 9. POST /api/Extend/LqMdTarget/GetManagedStores (科技部+月份 202601,需有效 DepartmentId)" +RESP=$(curl -s -w "\n%{http_code}" -X POST "$BASE_URL/api/Extend/LqMdTarget/GetManagedStores" \ + -H "Content-Type: application/json" \ + -H "Authorization: $TOKEN" \ + -d '{"month":"202601","organizationType":"科技部","departmentId":""}') +HTTP_CODE=$(echo "$RESP" | tail -n1) +BODY=$(echo "$RESP" | sed '$d') +echo " HTTP $HTTP_CODE" +if echo "$BODY" | grep -q "部门ID不能为空"; then + echo " [预期] departmentId 为空时返回错误提示" +else + echo "$BODY" | head -c 500 +fi +echo "" + +echo "=== 接口测试脚本执行完毕 ===" diff --git a/sql/根据产品平均单价更新库存领取金额.sql b/sql/根据产品平均单价更新库存领取金额.sql new file mode 100644 index 0000000..edfeaee --- /dev/null +++ b/sql/根据产品平均单价更新库存领取金额.sql @@ -0,0 +1,43 @@ +-- ============================================================ +-- 根据产品 F_AveragePrice 更新库存领取的单价、总价 +-- 说明:领取记录在 lq_inventory_usage,单价 F_UnitPrice、总价 F_TotalAmount; +-- 单价取产品 F_AveragePrice,若为 0 或 NULL 则取 F_Price;总价 = 单价 × 领取数量。 +-- 同时按批次汇总,回写 lq_inventory_usage_application 的 F_TotalAmount。 +-- ============================================================ + +-- 一、预览:将要更新的使用记录条数及金额变化(不修改数据) +SELECT + u.F_Id AS 使用记录ID, + u.F_ProductId AS 产品ID, + p.F_ProductName AS 产品名称, + u.F_UsageQuantity AS 领取数量, + u.F_UnitPrice AS 当前单价, + u.F_TotalAmount AS 当前总价, + IFNULL(NULLIF(p.F_AveragePrice, 0), p.F_Price) AS 新单价_取自产品, + IFNULL(NULLIF(p.F_AveragePrice, 0), p.F_Price) * u.F_UsageQuantity AS 新总价 +FROM lq_inventory_usage u +INNER JOIN lq_product p ON u.F_ProductId = p.F_Id +WHERE u.F_IsEffective = 1 + AND (u.F_UnitPrice != IFNULL(NULLIF(p.F_AveragePrice, 0), p.F_Price) + OR u.F_TotalAmount != IFNULL(NULLIF(p.F_AveragePrice, 0), p.F_Price) * u.F_UsageQuantity) +LIMIT 500; + +-- 二、更新库存使用记录:单价、总价(按产品 F_AveragePrice,否则 F_Price) +UPDATE lq_inventory_usage u +INNER JOIN lq_product p ON u.F_ProductId = p.F_Id +SET + u.F_UnitPrice = IFNULL(NULLIF(p.F_AveragePrice, 0), p.F_Price), + u.F_TotalAmount = IFNULL(NULLIF(p.F_AveragePrice, 0), p.F_Price) * u.F_UsageQuantity, + u.F_UpdateTime = NOW() +WHERE u.F_IsEffective = 1; + +-- 三、按批次汇总,更新申请表的 F_TotalAmount +UPDATE lq_inventory_usage_application a +INNER JOIN ( + SELECT F_UsageBatchId, SUM(F_TotalAmount) AS batch_total + FROM lq_inventory_usage + WHERE F_IsEffective = 1 + GROUP BY F_UsageBatchId +) t ON a.F_UsageBatchId = t.F_UsageBatchId +SET a.F_TotalAmount = t.batch_total +WHERE a.F_IsEffective = 1; -- libgit2 0.21.4