dfbda420
“wangming”
更改了一堆东西
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
|
# 商品成本价体系与调价单开发计划
> **现有基础**:前端 `wtPriceAdjust/index.vue` + `Form.vue`(骨架页面),后端和数据库均不存在
## 一、背景与目标
### 现状问题
1. **没有统一的成本价存储**:当前成本价只能从最近一次采购入库单的单价推算,不准确
2. **同一商品不同仓库成本不同**:如"卡带 开心镇"在莱迪仓平均成本 42.92,景枫仓 111.00
3. **出库时不记录成本价**:`wt_xsckd_mx` 表只有售价(dj),无法计算毛利
4. **拆装单成本价精度丢失**:`wt_czdmx.cbdj` 字段是 `decimal(50,0)`,没有小数位
5. **缺少调价单功能**:无法对在库商品进行成本调整
### 目标
建立完整的**加权平均成本价体系**,支持:采购入库自动算成本 → 调价单手动调整 → 出库时记录快照 → 拆装单/调拨单联动
---
## 二、数据库变更
### 2.1 新建表:`wt_sp_cost`(商品仓库成本表)
> 核心表,按「商品+仓库」维度存储当前加权平均成本价
```sql
CREATE TABLE wt_sp_cost (
F_Id VARCHAR(50) NOT NULL COMMENT '主键',
spbh VARCHAR(50) NOT NULL COMMENT '商品编号',
ck VARCHAR(50) NOT NULL COMMENT '仓库ID',
cbj DECIMAL(18,2) DEFAULT 0.00 COMMENT '当前加权平均成本价',
sl INT DEFAULT 0 COMMENT '当前在库数量',
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',
PRIMARY KEY (F_Id),
UNIQUE KEY uk_sp_ck (spbh, ck)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品仓库成本表';
```
### 2.2 新建表:`wt_tjd`(调价单主表)
```sql
CREATE TABLE wt_tjd (
F_Id VARCHAR(50) NOT NULL COMMENT '单据编号(TJD+日期+序号)',
djrq DATETIME COMMENT '单据日期',
ck VARCHAR(50) COMMENT '仓库(选仓库加载全部商品)',
jsr VARCHAR(50) COMMENT '经手人',
zdr VARCHAR(50) COMMENT '制单人',
djzt VARCHAR(50) DEFAULT '草稿' COMMENT '单据状态(草稿/已审核)',
bz TEXT COMMENT '备注',
PRIMARY KEY (F_Id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品调价单';
```
### 2.3 新建表:`wt_tjd_mx`(调价单明细)
```sql
CREATE TABLE wt_tjd_mx (
F_Id VARCHAR(50) NOT NULL COMMENT '主键',
djbh VARCHAR(50) NOT NULL COMMENT '单据编号(FK→wt_tjd)',
ck VARCHAR(50) COMMENT '仓库',
spbh VARCHAR(50) COMMENT '商品编号',
spmc VARCHAR(200) COMMENT '商品名称',
dw VARCHAR(50) COMMENT '单位',
sl INT DEFAULT 0 COMMENT '数量(在库数量,自动带出)',
tqdj DECIMAL(18,2) DEFAULT 0.00 COMMENT '调前单价(自动带出)',
tjbl DECIMAL(8,4) DEFAULT 0.00 COMMENT '调价比率%',
thdj DECIMAL(18,2) DEFAULT 0.00 COMMENT '调后单价',
tqje DECIMAL(18,2) DEFAULT 0.00 COMMENT '调前金额(sl×tqdj)',
thje DECIMAL(18,2) DEFAULT 0.00 COMMENT '调后金额(sl×thdj)',
bz VARCHAR(500) COMMENT '备注',
PRIMARY KEY (F_Id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='商品调价单明细';
```
### 2.4 修改表:`wt_xsckd_mx`(出库单明细加成本价字段)
> 出库时保存成本价快照,用于后续毛利计算
```sql
ALTER TABLE wt_xsckd_mx
ADD COLUMN cbdj DECIMAL(18,2) DEFAULT 0.00 COMMENT '成本单价(出库时快照)',
ADD COLUMN cbje DECIMAL(18,2) DEFAULT 0.00 COMMENT '成本金额(出库时快照)';
```
### 2.5 修改表:`wt_czdmx` + `wt_czdmx_2`(修复精度)
> 当前 cbdj/cbje 是 decimal(50,0) 没有小数位,需要修复
```sql
ALTER TABLE wt_czdmx MODIFY COLUMN cbdj DECIMAL(18,2) DEFAULT 0.00 COMMENT '成本单价';
ALTER TABLE wt_czdmx MODIFY COLUMN cbje DECIMAL(18,2) DEFAULT 0.00 COMMENT '成本金额';
ALTER TABLE wt_czdmx_2 MODIFY COLUMN cbdj DECIMAL(18,2) DEFAULT 0.00 COMMENT '成本单价';
ALTER TABLE wt_czdmx_2 MODIFY COLUMN cbje DECIMAL(18,2) DEFAULT 0.00 COMMENT '成本金额';
```
### 2.6 初始化 `wt_sp_cost` 数据
> 根据当前在库序列号的批次入库价计算加权平均成本
```sql
INSERT INTO wt_sp_cost (F_Id, spbh, ck, cbj, sl, update_time)
SELECT
CONCAT(sub.spbh, '_', sub.in_warehouse) AS F_Id,
sub.spbh,
sub.in_warehouse AS ck,
ROUND(SUM(IFNULL(mx.dj, 0) * sub.qty) / NULLIF(SUM(sub.qty), 0), 2) AS cbj,
SUM(sub.qty) AS sl,
NOW() AS update_time
FROM (
SELECT sn.spbh, sn.in_warehouse, sn.in_djbh, COUNT(*) AS qty
FROM wt_serial_number sn
WHERE sn.status = 0
GROUP BY sn.spbh, sn.in_warehouse, sn.in_djbh
) sub
LEFT JOIN wt_xsckd_mx mx ON sub.in_djbh = mx.djbh AND sub.spbh = mx.spbh
GROUP BY sub.spbh, sub.in_warehouse;
```
---
## 三、业务逻辑变更
### 3.1 成本价读取(统一入口)
所有需要取成本价的地方,统一从 `wt_sp_cost` 读取:
```
GetProductCost(商品ID, 仓库ID)
→ SELECT cbj FROM wt_sp_cost WHERE spbh = 商品ID AND ck = 仓库ID
→ 如果没记录,兜底取最近采购入库单价 → 取零售价 → 返回 0
```
**影响范围**:拆装单(WtCzdService)、出库单(WtXsckdService)、调价单(新)
### 3.2 采购入库时更新成本(WtXsckdService.Create)
> 当 djlx = "采购入库单" 时,保存后自动更新 wt_sp_cost
```
对每个明细行:
旧记录 = SELECT cbj, sl FROM wt_sp_cost WHERE spbh AND ck
如果存在:
新成本 = (旧sl × 旧cbj + 入库数 × 入库单价) ÷ (旧sl + 入库数)
UPDATE wt_sp_cost SET cbj = 新成本, sl = 旧sl + 入库数
如果不存在:
INSERT wt_sp_cost (spbh, ck, cbj, sl) VALUES (商品, 仓库, 入库单价, 入库数)
```
### 3.3 销售出库时记录成本快照(WtXsckdService.Create)
> 当 djlx = "销售出库单" 时
```
对每个明细行:
cbdj = SELECT cbj FROM wt_sp_cost WHERE spbh AND ck
cbje = cbdj × 数量
保存到 wt_xsckd_mx.cbdj, wt_xsckd_mx.cbje
UPDATE wt_sp_cost SET sl = sl - 出库数 WHERE spbh AND ck
```
### 3.4 调价单审核时更新成本(WtTjdService,新建)
```
对每个明细行:
UPDATE wt_sp_cost SET cbj = 调后单价 WHERE spbh AND ck
```
### 3.5 拆装单保存时联动(WtCzdService.Create)
```
出货明细:
cbdj 从 wt_sp_cost 取出货仓库的成本价
UPDATE wt_sp_cost SET sl = sl - 出库数 WHERE 出货仓库
入货明细:
cbdj = 出货总成本金额 ÷ 入货总数量(分摊成本)
UPSERT wt_sp_cost SET cbj = 加权后新成本, sl = sl + 入库数 WHERE 入货仓库
```
### 3.6 调拨单联动
```
出仓成本不变(从 wt_sp_cost 取)
入仓按出仓成本入库(加权平均计入)
```
### 3.7 采购退货 / 销售退货
```
退货入库:按原出库成本价回入(不改变成本单价,只增加数量和总成本)
退货出库:减少数量,成本单价不变
```
---
## 四、后端开发任务
### 4.1 数据库与 Entity
| 任务 | 说明 |
|------|------|
| 执行 SQL 建表/改表 | 2.1~2.6 的 SQL 语句 |
| WtSpCostEntity | 映射 wt_sp_cost |
| WtTjdEntity | 映射 wt_tjd |
| WtTjdMxEntity | 映射 wt_tjd_mx |
| WtXsckdMxEntity 加字段 | 加 Cbdj、Cbje 属性 |
| WtCzdmxEntity 修复精度 | cbdj/cbje 改为 decimal |
### 4.2 调价单 Service(WtTjdService,新建)
| 接口 | 方法 | 说明 |
|------|------|------|
| GET /api/Extend/WtTjd/{id} | GetInfo | 获取调价单详情 |
| GET /api/Extend/WtTjd | GetList | 列表查询(分页) |
| POST /api/Extend/WtTjd | Create | 新建调价单 |
| PUT /api/Extend/WtTjd/{id} | Update | 修改调价单 |
| DELETE /api/Extend/WtTjd/{id} | Delete | 删除调价单 |
| POST /api/Extend/WtTjd/Actions/Audit/{id} | Audit | 审核(更新 wt_sp_cost) |
| GET /api/Extend/WtTjd/Actions/LoadProducts | LoadProducts | 按仓库加载商品+成本价+库存 |
### 4.3 成本价 Service(WtSpCostService,新建或合并)
| 接口 | 说明 |
|------|------|
| GET /api/Extend/WtSpCost/GetCost?spbh=&ck= | 查询单个商品在指定仓库的成本价 |
| POST /api/Extend/WtSpCost/RecalcAll | 重算所有成本(基于当前库存数据) |
### 4.4 改造现有 Service
| Service | 改造内容 |
|---------|---------|
| WtXsckdService.Create | 采购入库:更新 wt_sp_cost 加权平均<br>销售出库:快照 cbdj/cbje 到明细 |
| WtCzdService.Create | 出货:快照 cbdj 从 wt_sp_cost 取<br>入货:按出货总成本分摊 |
| WtCzdService.GetProductCost | 改为从 wt_sp_cost 读取 |
---
## 五、前端开发任务
### 5.1 调价单页面(新建)
**列表页 `views/wtTjd/index.vue`**:
- 搜索条件:单据编号、仓库、日期范围、状态
- 列表字段:单据编号、单据日期、仓库、经手人、状态、操作(编辑/审核/删除)
**表单页 `views/wtTjd/Form.vue`**:
- 主表:单据编号(自动生成 TJD+日期+序号)、单据日期、仓库(下拉选择)、经手人、备注
- 明细表(el-table 内嵌编辑):
| 列 | 说明 | 交互 |
|----|------|------|
| 仓库 | 自动带出(跟主表仓库) | 只读 |
| 商品编码 | 选择或仓库加载 | 可选/只读 |
| 商品名称 | 自动带出 | 只读 |
| 单位 | 自动带出 | 只读 |
| 数量 | 在库数量 | 只读 |
| 调前单价 | 自动从 wt_sp_cost 带出 | 只读 |
| 调价比率% | 用户输入 | **可编辑**,变化 → 自动算调后单价 |
| 调后单价 | 用户输入或自动算 | **可编辑**,变化 → 自动算比率 |
| 调前金额 | 数量×调前单价 | 自动算,只读 |
| 调后金额 | 数量×调后单价 | 自动算,只读 |
| 备注 | | 可编辑 |
**交互逻辑**:
1. 选择仓库 → 调用 LoadProducts → 加载该仓库所有有库存商品到明细表
2. 也可手动添加行选择商品
3. 输入调价比率 → 调后单价 = 调前单价 × (1 + 比率/100)
4. 输入调后单价 → 调价比率 = (调后 - 调前) / 调前 × 100
5. 审核按钮 → 确认后批量更新成本价
### 5.2 改造拆装单
- `GetProductCost` 接口改为从 `wt_sp_cost` 取成本价(后端改,前端无需变)
### 5.3 改造出库单
- 保存时后端自动写入 cbdj/cbje(后端改,前端可选显示)
---
## 六、开发顺序(建议)
| 阶段 | 任务 | 依赖 |
|------|------|------|
| **P1** | 执行 SQL:建 wt_sp_cost 表 + 初始化数据 | 无 |
| **P1** | 执行 SQL:修复 wt_czdmx 精度 | 无 |
| **P1** | 执行 SQL:wt_xsckd_mx 加 cbdj/cbje | 无 |
| **P2** | 后端:WtSpCostEntity + GetCost 接口 | P1 |
| **P2** | 后端:改造 GetProductCost 从 wt_sp_cost 读 | P2 |
| **P3** | 执行 SQL:建 wt_tjd + wt_tjd_mx 表 | 无 |
| **P3** | 后端:WtTjdEntity/DTO/Service 全套 CRUD | P3 |
| **P3** | 后端:LoadProducts + Audit 接口 | P2+P3 |
| **P3** | 前端:调价单列表页 + 表单页 | P3 后端 |
| **P4** | 后端:改造 WtXsckdService 采购入库更新成本 | P2 |
| **P4** | 后端:改造 WtXsckdService 出库快照成本 | P2 |
| **P4** | 后端:改造 WtCzdService 拆装单成本联动 | P2 |
| **P5** | 测试:全流程验证 | 全部 |
---
## 七、验收标准
1. ✅ `wt_sp_cost` 初始化后,每个商品+仓库组合有正确的加权平均成本价
2. ✅ 拆装单选商品后自动带出成本单价(从 wt_sp_cost)
3. ✅ 调价单:选仓库加载所有商品,调价比率和调后单价双向联动
4. ✅ 调价单审核后,wt_sp_cost.cbj 更新为调后单价
5. ✅ 采购入库后,wt_sp_cost 自动重算加权平均成本
6. ✅ 销售出库时,wt_xsckd_mx.cbdj/cbje 记录出库时刻的成本价
7. ✅ 成本金额精度为 2 位小数
|