新增入库单据管理页面
This commit is contained in:
53
.trae/documents/修复打印两页问题并完善打印模板.md
Normal file
53
.trae/documents/修复打印两页问题并完善打印模板.md
Normal file
@@ -0,0 +1,53 @@
|
||||
## 问题判断
|
||||
- 仅勾选一条子单仍打印两页,典型原因是分页规则对最后一页也生效或伪类匹配异常导致空白页。
|
||||
- `:last-child` 在存在空白文本节点/注释节点的情况下可能失效,导致最后一个实际页面元素仍应用分页。
|
||||
- 也可能存在重复数据(同一个 `stockinDetailId` 被选中两次),引发两页输出。
|
||||
|
||||
## 修复与优化方案
|
||||
### 1. 明确分页控制(按索引条件渲染)
|
||||
- 将分页控制从 CSS 伪类改为模板条件,避免 `:last-child` 因节点影响而失效:
|
||||
- 模板改为:
|
||||
```vue
|
||||
<div
|
||||
v-for="(item, idx) in printData"
|
||||
:key="item.stockinDetailId"
|
||||
class="print-page"
|
||||
:style="{ pageBreakAfter: idx < printData.length - 1 ? 'always' : 'auto' }"
|
||||
>
|
||||
<!-- 原卡片内容保持不变 -->
|
||||
</div>
|
||||
```
|
||||
|
||||
### 2. 去重与防重复打印
|
||||
- 在 `printDetailQRCodes` 中对 `detailSelections` 去重,确保同一子单只打印一次:
|
||||
```js
|
||||
const map = new Map()
|
||||
this.printData = []
|
||||
for (const row of this.detailSelections) {
|
||||
const key = row.stockinDetailId
|
||||
if (key && !map.has(key)) {
|
||||
map.set(key, true)
|
||||
this.printData.push(row)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 保证单页不被拆分
|
||||
- 保留并强化:`.print-page { page-break-inside: avoid; }`,防止卡片高度导致跨页拆分。
|
||||
- 控制卡片外层高度与内边距不超过 A4 可打印区域(当前 720px 宽 + 常规内容高度安全)。
|
||||
|
||||
### 4. 打印触发时机与副本数
|
||||
- 维持 `this.$nextTick(() => setTimeout(() => this.$refs.easyPrint2.print(), 100))`,避免多次触发。
|
||||
- 如仍出现两页,追加保护:打印前记录 `printData.length` 与内容,控制仅当 `length >= 1` 才触发一次。
|
||||
|
||||
## 代码变更摘要
|
||||
- 更新模板:将分页规则改为基于索引的内联样式条件。
|
||||
- 更新方法:`printDetailQRCodes` 增加去重逻辑与空数组保护。
|
||||
- 保留样式:`page-break-inside: avoid`;移除或忽略 `:last-child` 分页伪类。
|
||||
|
||||
## 验证步骤
|
||||
- 勾选 1 条子单打印,预览应仅 1 页。
|
||||
- 勾选 2 条子单打印,预览应为 2 页且无末尾空白页。
|
||||
- 检查不同浏览器(Chromium/Edge)表现一致性。
|
||||
|
||||
请确认按此方案实施,我将立即更新代码并验证。
|
||||
104
.trae/documents/创建并接入 in_stockin_detail_n 明细存储.md
Normal file
104
.trae/documents/创建并接入 in_stockin_detail_n 明细存储.md
Normal file
@@ -0,0 +1,104 @@
|
||||
## 目标
|
||||
|
||||
* 在 SQL Server 新增表 `in_stockin_detail_n`,用于存储 ERP 返回的入库产品明细(Cols/Rows)。
|
||||
|
||||
* 以实体、Mapper、Service 的方式接入到现有 WMS 代码,并在 `ToErpServiceImpl#getInStock` 中解析 JSON 后落库。
|
||||
|
||||
* 字段覆盖现有 ERP 索引映射,支持来源、创建/更新时间等审计信息。
|
||||
|
||||
## 数据表设计(SQL Server)
|
||||
|
||||
* 表名:`in_stockin_detail_n`
|
||||
|
||||
* 关键字段:
|
||||
|
||||
* stockin\_detail\_id (入库单主键,插入时,主单对应有几条子单,在主单ID后拼接“-”子单条数)
|
||||
* stockin\_id 主单ID 与主单ID保持一致
|
||||
* `erp_detail_id`(ERP入库明细ID,对应 Rows\[0])
|
||||
* `product_name` nvarchar(200)(Rows\[1])
|
||||
* `product_model` nvarchar(200)(Rows\[2],型号)
|
||||
* `unit` nvarchar(50)(Rows\[3])
|
||||
* `unit_price` decimal(18,6)(Rows\[4])
|
||||
* `aux_unit` nvarchar(50) 或 int(Rows\[5],与现有实现保持兼容;建议 nvarchar 以避免字典耦合)
|
||||
* `attr1` nvarchar(100)(Rows\[6])
|
||||
* `attr2` nvarchar(100)(Rows\[7])
|
||||
* `quantity` decimal(18,6)(Rows\[9])
|
||||
* `in_quantity` decimal(18,6)(Rows\[10])
|
||||
* `aux_quantity` decimal(18,6)(Rows\[11])
|
||||
* `total_price` decimal(18,6)(Rows\[12])
|
||||
* `cost_unit_price` decimal(18,6)(Rows\[13])
|
||||
* `cost_total_price` decimal(18,6)(Rows\[14])
|
||||
* `accounting_cost_total` decimal(18,6)(Rows\[15])
|
||||
* `accounting_quantity` decimal(18,6)(Rows\[16])
|
||||
* `accounting_status` int(Rows\[17])
|
||||
* `batch_no` nvarchar(100)(Rows\[18])
|
||||
* `serial_no` nvarchar(100)(Rows\[19])
|
||||
* `production_date` datetime2(3)(Rows\[20])
|
||||
* `expiry_date` datetime2(3)(Rows\[21])
|
||||
* `arrival_date` datetime2(3)(Rows\[22])
|
||||
* `remark` nvarchar(255)(Rows\[23])
|
||||
* `custom1`..`custom6` nvarchar(255)(Rows\[24]..Rows\[29])
|
||||
* `stevedore` nvarchar(100)(Rows\[30],装卸工)
|
||||
* `create_time` datetime2(3) 默认 `SYSDATETIME()`
|
||||
* `update_time` datetime2(3) 可在更新时写入 `SYSDATETIME()`
|
||||
|
||||
* 约束:`detail_id` 主键;如需防重复插入,可使用 `detail_id + production_date` 唯一索引(按您确认)。
|
||||
|
||||
## Java 代码接入
|
||||
|
||||
* 新增实体 `com.ruoyi.system.domain.InStockinDetailN`
|
||||
|
||||
* 字段与表结构一一对应,类型与上面一致;保留必要的 `@Excel` 注解,遵循现有风格。
|
||||
|
||||
* 继承 `BaseEntity`,复用 `createTime`、`updateTime` 字段。
|
||||
|
||||
* 新增 Mapper 接口 `com.ruoyi.system.mapper.InStockinDetailNMapper`
|
||||
|
||||
* 方法:`insertInStockinDetailN`、`updateInStockinDetailN`、`selectByDetailId`、`batchInsert(List<...>)`、`selectByDetailIdAndDate`(防重复)。
|
||||
|
||||
* 新增 XML `mapper/system/InStockinDetailNMapper.xml`
|
||||
|
||||
* 定义 `resultMap` 与列映射;提供 `insert`、`update`、`select`、`batchInsert`(`foreach`)语句,时间字段默认使用 `SYSDATETIME()`。
|
||||
|
||||
* 新增 Service `IInStockinDetailNService` 与实现 `InStockinDetailNServiceImpl`
|
||||
|
||||
* 封装批量写入与防重复逻辑(按 `detail_id` 或当天 `create_time` 过滤)。
|
||||
|
||||
## 解析与入库逻辑
|
||||
|
||||
* 在 `ToErpServiceImpl#getInStock` 中:
|
||||
|
||||
* 从 `row.get(15)`(产品明细 JSON)解析出 `Rows` 列表。
|
||||
|
||||
* 按上面索引映射生成 `InStockinDetailN` 对象,填充 `order_src='ERP'`、`create_time=当前时间`。
|
||||
|
||||
* 通过 `selectByDetailIdAndDate(detail_id, today)` 判断是否已存在,未存在则插入,已存在忽略。
|
||||
|
||||
* 将 `stockin_guid` 关联为当前主单 `newStockin.getStockinGuid()`(若可获得)。
|
||||
|
||||
## 索引映射校验
|
||||
|
||||
* 结合已有 `ErpInStockinDetail` 的使用位置(`ToErpServiceImpl#AddStockinDetailByErpStockinDetail`),确保以下关键位一致:
|
||||
|
||||
* `id`→Rows\[0]、`spare1`(产品名称)→Rows\[1]、`spare2`(产品编号/型号)→Rows\[2]
|
||||
|
||||
* 数量→Rows\[9]、批号→Rows\[17]、序列号→Rows\[18]、生产/有效/到货日期→Rows\[19]/\[20]/\[21]
|
||||
|
||||
* 如您确认 `Clos` 与 `Rows` 存在偏移或后续附加列,我们将按您提供的最终结构调整表与映射。
|
||||
|
||||
## 验证与回归
|
||||
|
||||
* 本地运行 `getInStock`,抓取一次 ERP 返回;在控制台输出解析计数与首条样例,以确认列位。
|
||||
|
||||
* 手工查询:`SELECT TOP 10 * FROM in_stockin_detail_n ORDER BY create_time DESC;`
|
||||
|
||||
* 回归检查:对 `in_stockin_n` 与新表之间的 `stockin_guid` 关联是否正确。
|
||||
|
||||
## 提交约定
|
||||
|
||||
* 在实现时,所有 Java 代码将补充详细中文注释,解释每一步改动原因与映射关系。
|
||||
|
||||
* 不自动创建 `.md` 或 `.sql` 文件;如您需要,我们可生成对应 SQL 文件并在您确认后执行。
|
||||
|
||||
* 仅在您确认后进行代码与数据库变更,并按您要求的 Git 提交规范执行提交。
|
||||
|
||||
61
.trae/documents/在入库单新增中隐藏打印、选择物料并编辑子单,生成单号与默认来源.md
Normal file
61
.trae/documents/在入库单新增中隐藏打印、选择物料并编辑子单,生成单号与默认来源.md
Normal file
@@ -0,0 +1,61 @@
|
||||
## 目标
|
||||
- 在 `InStockIn` 页面满足 5 项需求:
|
||||
1. 点击“单据新增”时,打开弹框隐藏“打印入库条码”按钮
|
||||
2. 弹框内新增“选择物料”按钮,打开第二个弹框显示物料列表,选择后将物料加入子单明细
|
||||
3. 子单明细中的“计划数量”和“入库数量”可编辑
|
||||
4. 新增时自动生成 `stockinId`:`RK` + 当前毫秒时间戳
|
||||
5. 提交时 `orderSrc` 默认赋值为“自建单”
|
||||
|
||||
## 技术实现
|
||||
- 页面文件:`ruoyi-ui/src/views/system/inStockIn/index.vue`
|
||||
- 参考实现:`ruoyi-ui/src/views/in/stockIn/add/index_new.vue` 的“添加物料”与“选择物料”弹框逻辑
|
||||
|
||||
## 详细改动
|
||||
### 新增状态标识
|
||||
- 在 `data()` 中新增:`isAddMode: false`
|
||||
- 用于区分“新增”与“编辑/查看”,控制按钮显示与表格可编辑
|
||||
|
||||
### 隐藏打印按钮
|
||||
- 对话框底部的打印按钮(`printDetailQRCodes`)改为:`v-if="!isAddMode"`
|
||||
- 点击“单据新增”时将 `isAddMode = true`,从而隐藏打印按钮
|
||||
|
||||
### 选择物料入口
|
||||
- 在“子单信息”卡片标题区域新增一个按钮:`选择物料`
|
||||
- 按钮事件 `openProductSelector()` 打开二级弹框
|
||||
|
||||
### 物料选择弹框
|
||||
- 复用 `index_new.vue` 的模式:
|
||||
- 引入 API:`import { listBasProduct } from "@/api/bas/BasProduct"`
|
||||
- 在 `data()` 中新增:`productSelectVisible, productOptions, selectedProducts, productTotal, queryProductParams, productLoading`
|
||||
- 弹框内容包含搜索表单、物料表格(带选择)、分页与“确定/取消”
|
||||
- 事件:`getProductList()、resetProductQuery()、handleProductSelectionChange()、confirmSelectProduct()`
|
||||
|
||||
### 子单明细数据与可编辑列
|
||||
- 子单明细列表数据源仍使用 `inStockinDetailNList`
|
||||
- 在“新增”模式下,`confirmSelectProduct()` 将选中的物料映射并 `push` 到 `inStockinDetailNList`:
|
||||
- 字段映射示例:`productName、productModel(来自 productId 或 spec)、unit、quantity(默认 1)、inQuantity(默认 0)`
|
||||
- 在子单表格中为 `quantity` 与 `inQuantity` 列增加模板:`<el-input-number v-model="scope.row.quantity" ...>` 与 `<el-input-number v-model="scope.row.inQuantity" ...>`,并用 `v-if="isAddMode"` 控制仅在新增时可编辑
|
||||
|
||||
### 自动生成主单号
|
||||
- 在 `handleAdd()`:
|
||||
- `this.reset()` 后设置:`this.form.stockinId = 'RK' + Date.now()`
|
||||
- `this.isAddMode = true; this.open = true; this.isView = false; this.title = '添加入库单据管理'`
|
||||
- 由于 `watch('form.stockinId')` 会尝试拉取子单,新增生成的主单号在后端不存在,列表将为空,此时通过物料选择填充本地子单明细
|
||||
|
||||
### 提交默认来源
|
||||
- 在 `submitForm()` 里,在发起 `addInStockIn(this.form)` 前设置:`this.form.orderSrc = '自建单'`
|
||||
- 编辑场景保持原逻辑不变;新增成功后 `isAddMode` 复位为 `false`
|
||||
|
||||
## 校验与兼容
|
||||
- 行内“修改/删除”按钮逻辑保持现有条件控制;新增模式下仅本地操作子单明细
|
||||
- 不影响历史单据查询与打印
|
||||
- 若后端需要接收子单明细,一并在后续迭代中按后端接口扩展(当前仅前端本地编辑)
|
||||
|
||||
## 代码触点
|
||||
- 模板:对话框底部按钮处、子单卡片标题区新增按钮、子单表格新增可编辑列
|
||||
- 脚本:新增 `isAddMode` 标识、导入 `listBasProduct`、新增弹框及方法、在 `handleAdd()` 和 `submitForm()` 中按要求赋值
|
||||
|
||||
## 期望交互
|
||||
- 点击“新增”→ 弹框打开且不显示打印按钮;自动生成主单号
|
||||
- 点“选择物料”→ 打开物料选择弹框,勾选并确定→ 子单明细填充,可编辑数量
|
||||
- 点“确定”提交→ 主单 `orderSrc` 自动为“自建单”
|
||||
@@ -0,0 +1,55 @@
|
||||
## 目标
|
||||
- 为 `in_stockin_n_finish` 和 `in_stockin_detail_n_finish` 两张“完成/归档表”新增后端代码(Mapper 接口 + MyBatis XML + Service 接口与实现)。
|
||||
- 字段结构与现有 `in_stockin_n`、`in_stockin_detail_n` 完全一致,仅更换表名与命名空间。
|
||||
|
||||
## 范围
|
||||
- 复用现有领域模型:直接复用 `InStockinN` 与 `InStockinDetailN` 两个实体类,不新增冗余实体。
|
||||
- 新增 Mapper 接口与 XML:Finish 版本分别指向 `_finish` 表名。
|
||||
- 新增 Service 接口与实现:提供基本 CRUD 与“从原表批量归档到 finish 表”的能力。
|
||||
- 不改动现有 Controller(如需页面展示 Finish 列表,可后续扩展)。
|
||||
|
||||
## 技术方案
|
||||
- MyBatis:在 `mapper/system` 目录新增两个 XML 文件,`resultMap` 的 `type` 仍然使用现有实体类;`select`/`insert`/`update`/`delete` 语句的 `from`/`into` 指向 `_finish` 表。
|
||||
- Mapper 接口:在 `com.ruoyi.system.mapper` 新增 `InStockinNFinishMapper`、`InStockinDetailNFinishMapper`,方法签名与现有 Mapper 保持一致(命名不同)。
|
||||
- Service:在 `com.ruoyi.system.service` 新增 `IInStockinNFinishService`、`IInStockinDetailNFinishService`;在 `com.ruoyi.system.service.impl` 新增对应实现类,注入 Finish Mapper 完成操作。
|
||||
|
||||
## 文件清单
|
||||
- `ruoyi-admin/src/main/java/com/ruoyi/system/mapper/InStockinNFinishMapper.java`
|
||||
- `ruoyi-admin/src/main/java/com/ruoyi/system/mapper/InStockinDetailNFinishMapper.java`
|
||||
- `ruoyi-admin/src/main/resources/mapper/system/InStockinNFinishMapper.xml`
|
||||
- `ruoyi-admin/src/main/resources/mapper/system/InStockinDetailNFinishMapper.xml`
|
||||
- `ruoyi-admin/src/main/java/com/ruoyi/system/service/IInStockinNFinishService.java`
|
||||
- `ruoyi-admin/src/main/java/com/ruoyi/system/service/IInStockinDetailNFinishService.java`
|
||||
- `ruoyi-admin/src/main/java/com/ruoyi/system/service/impl/InStockinNFinishServiceImpl.java`
|
||||
- `ruoyi-admin/src/main/java/com/ruoyi/system/service/impl/InStockinDetailNFinishServiceImpl.java`
|
||||
|
||||
## 方法签名(示例)
|
||||
- InStockinNFinishMapper / Service:
|
||||
- `InStockinN selectByStockinGuid(String stockinGuid)`
|
||||
- `List<InStockinN> selectList(InStockinN query)`
|
||||
- `int insert(InStockinN row)` / `int update(InStockinN row)` / `int deleteByStockinGuid(String stockinGuid)`
|
||||
- `int batchArchiveFromSource(String date)`(可选:将当日数据从源表复制到 finish 表)
|
||||
- InStockinDetailNFinishMapper / Service:
|
||||
- `InStockinDetailN selectByStockinDetailId(String stockinDetailId)`
|
||||
- `List<InStockinDetailN> selectListByStockinGuid(String stockinGuid)`
|
||||
- `int insert(InStockinDetailN row)` / `int update(InStockinDetailN row)` / `int deleteByStockinDetailId(String stockinDetailId)`
|
||||
- `int batchArchiveByStockinGuid(String stockinGuid)`(从源明细表按主单 guid 复制到 finish 表)
|
||||
|
||||
## 归档流程(可在 Service 中提供便捷方法)
|
||||
- 主单:`archiveStockinNByGuid(stockinGuid)`
|
||||
- 从 `in_stockin_n` 查询主单,存在则插入/更新到 `in_stockin_n_finish`
|
||||
- 子单:`archiveStockinDetailNByGuid(stockinGuid)`
|
||||
- 从 `in_stockin_detail_n` 批量查询 `stockin_guid=...` 的子单,批量插入到 `in_stockin_detail_n_finish`
|
||||
- 幂等:`insert` 使用 `stockin_guid` 或 `stockin_detail_id` 作为唯一约束进行“存在则更新”的 upsert 逻辑(与现有 XML 风格保持一致)。
|
||||
|
||||
## 校验与验证
|
||||
- 本地运行现有入库拉取逻辑,手工触发一次归档方法,验证两张 finish 表插入成功。
|
||||
- 使用已有前端页面查询与导出功能验证数据一致性(如果后续增加 Controller,将绑定至 `/system/inStockInFinish` 与 `/system/inStockInDetailFinish`)。
|
||||
|
||||
## 不改动项
|
||||
- 不修改实体字段与现有源表 Mapper/Service;Finish 仅新增并依赖现有结构。
|
||||
- 不自动生成 SQL DDL(如需要我可根据现有表结构快速给出 `_finish` 建表 SQL)。
|
||||
|
||||
## 实施说明
|
||||
- 所有新增 Java/XML 文件将包含详细中文注释,解释与源表的字段一致性、使用场景与幂等处理原因。
|
||||
- 完成后不进行 Git 提交,等待您提供提交说明/提交人/提交时间/提交备注后再执行。
|
||||
Reference in New Issue
Block a user