diff --git a/abacus.springboot.example/.gitignore b/abacus.springboot.example/.gitignore new file mode 100644 index 0000000..6ec27bd --- /dev/null +++ b/abacus.springboot.example/.gitignore @@ -0,0 +1,35 @@ +# --- OS --- +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +desktop.ini + +# --- Editors / IDEs --- +.idea/ +.vscode/ +*.swp +*.swo +*~ +*.sublime-workspace + +# --- Secrets / local env --- +.env +.env.* +!.env.example +*.pem +*.key +secrets.* + +# --- Logs / temp --- +*.log +*.tmp +tmp/ +.cache/ + +# --- Build output (ADS: append stack-specific rules below) --- +# e.g. node: node_modules/ dist/ ; python: __pycache__/ .venv/ *.pyc ; +# rust: target/ ; java: build/ *.class ; swift/xcode: DerivedData/ *.xcuserstate diff --git a/abacus.springboot.example/.project.agents/AGENTS.md b/abacus.springboot.example/.project.agents/AGENTS.md new file mode 100644 index 0000000..6c22e2d --- /dev/null +++ b/abacus.springboot.example/.project.agents/AGENTS.md @@ -0,0 +1,56 @@ +# Repository Guidelines + +AGENTS.md is the cross-vendor contributor guide (Claude, Codex, and others read it). Keep it in English by convention. It overlaps CLAUDE.md on purpose — this is the canonical version for non-Claude agents. + +## Authority & Required Reading +Rules in `.project.agents/CLAUDE.md` apply to every agent working here. Direct user instructions still take precedence. + +The canonical contributor guide is `.project.agents/AGENTS.md`. Do not create or maintain a root-level `AGENTS.md` unless the user explicitly asks for one. + +Before any code-changing task, read `.project.agents/SELF_CONSTRAINTS.md` and `.project.agents/VIBECODING_GUIDE.md`, then run `git status --short`. For product work, also read the relevant sections of `PRD.md`, `ARCHITECTURE.md`, `ROADMAP.md`, and `CONVENTIONS.md` under `.project.agents/docs/context/`. Shared front-backend constraints live in the workspace-level `docs/` (see `../../../docs/coding-standards.md`) — read the referenced sections instead of duplicating them here. + +## Project Structure & Module Organization +`abacus.springboot.example` is a Spring Boot Maven microservice template (multi-database + abacus framework), parent `abacus.framework:abacus.springcloud.pom:1.5.0`. Business code lives in `src/main/java/abacus/springboot..{api,controller,dao,esb,pi,impl,repository,wsi,config,util,vo}/` (reference template: the `example` JcBill vertical slice, copy-and-rewrite); config in `src/main/resources/config/{dev,test,prod}/`; SQL in `src/main/resources/sql/`. No automated tests. + +Target architecture is documented in `ARCHITECTURE.md`: layered packages (api/controller → esb/wsi → pi/impl/repository → dao) with unified response-body wrapping and BusinessException-based errors. + +## Source-of-Truth Rules +`PRD.md` defines behavior and scope. +`ARCHITECTURE.md` is the authority for modules, dependencies, contracts, and directory layout. Derived documents follow upstream changes, not the other way around. + +Feature changes must update `PRD.md`. Module, dependency, entity, or invariant changes must update `ARCHITECTURE.md` in the same commit. Do not let code and architecture drift for more than 24 hours. + +## Build, Test, and Development Commands + +```sh +# Build (produces target/*-bin.zip: jar + doc + sql + html) +mvn package -Pdev -DskipTests + +# Run +mvn spring-boot:run + +# Test +No automated tests (manual smoke only) +``` + +Environment: Nacos must be reachable (bootstrap.yml: server-addr/namespace; extension-configs pull abacus-database/discovery/acas/redis/actuator/xxljob); build depends on the company Maven private repo (abacus framework jars); set `` to `abacus.springboot.`. + +## Architecture & Coding Style +Use Java, 4-space indentation, max line width 120. Controllers: `@RestController` + `@RequestMapping` + springdoc `@Tag`/`@Operation`; `throws Exception`; `@RequestParam(required=false)`; blank-param guard throws `BusinessException`; **return business objects directly** (the wrapper builds the unified response). Services orchestrate in `esb/`; raw SQL lives in `impl/` and MUST use `?` placeholders (no string concatenation). Entities: `@Entity @Table @JsonIgnoreProperties(ignoreUnknown=true) @Schema`, `@Id String`, `@Version Integer`, `STATUS_*` constants, hand-written getters/setters. Business IDs come from `DaoIdGenerator` beans — never hand-craft UUIDs. + +Do not add modules that are not registered in `ARCHITECTURE.md`. Preserve the dependency DAG; no reverse dependencies, no cross-feature imports, and no direct access to another module's private implementation. Avoid empty names such as `Manager`, `Helper`, `Util`, or `Common` for new code (legacy `util/`/`vo/` files are reference-only — cite but do not add). + +UI/presentation code should consume state and send intents only — put business logic in services/use cases, and keep data-model types thin. Controllers must not write SQL or touch repositories directly; orchestration goes through `esb` services. + +## Testing Guidelines +No automated test framework. Required validation from `ARCHITECTURE.md`: manual smoke per API (list / query / create / edit / export) plus real-environment checks. Multi-datasource routing, Kafka consumption, XXL-JOB scheduling, Nacos config pull, and real database migrations require real-environment validation; mock/simulator-only evidence is not enough for those claims. + +## Git, Logs, and PRs +Do not pile new work onto unrelated dirty changes without calling it out. Prefer Conventional Commits such as `feat: ...`, `fix: ...`, `docs: ...`. This repository is part of a single git repo rooted at the workspace (`D:\workBuddySpace\member`); commit scope should stay within this subproject unless the change is cross-project (docs/). + +Each independently verifiable feature, milestone, non-trivial fix, or refactor needs an execution log in `.project.agents/log/YYYY-MM-DD-.md` unless it is only a minor documentation edit. Logs must include what changed, relevant commits (or "uncommitted" with reason), verification performed, and next steps. Feature updates also append to `src/main/resources/doc/升级日志.md` per the shared spec §5.11. + +Pull requests should include scope, linked issues, screenshots for UI changes, environment/device coverage, and any documentation updates. + +## Security & Configuration +Do not commit secrets, credentials, build output, or personal IDE files. Nacos credentials and datasource settings live in `src/main/resources/config//` (git-tracked per team convention) — do not add new secrets outside those files. Agent configuration and generated agent notes belong under `.project.agents/`, not the repository root, `.claude/`, or a global home directory. diff --git a/abacus.springboot.example/.project.agents/CLAUDE.md b/abacus.springboot.example/.project.agents/CLAUDE.md new file mode 100644 index 0000000..a222d08 --- /dev/null +++ b/abacus.springboot.example/.project.agents/CLAUDE.md @@ -0,0 +1,63 @@ +# CLAUDE.md + +This file guides Claude Code (and other agents) when working in this repository. +**保持本文件最新**:它是项目级入口——项目是什么、怎么构建、门控一切变更的规则。 + +## Project + +`abacus.springboot.example` 是 **Spring Boot Maven 微服务模板**(多数据库 + abacus 框架),父工程 `abacus.framework:abacus.springcloud.pom:1.5.0`。业务代码位于 `src/main/java/abacus/springboot.<应用名>.{api,controller,dao,esb,pi,impl,repository,wsi,config,util,vo}/`(参考模板:`example` 下的 JcBill 稽查示例,供复制改写);配置位于 `src/main/resources/config/{dev,test,prod}/`,SQL 位于 `src/main/resources/sql/`。 + +- Entry point: `src/main/java/abacus/springboot/example/Application.java` +- **分层即契约**:`api(+api/view)` / `controller` / `dao`(Entity) / `esb`(Service 编排) / `pi`(数据访问 IF) / `impl`(原生 SQL 实现) / `repository`(Spring Data JPA) / `wsi`(ServiceIF) / `config` / `util` / `vo`;扫描配置 `springdoc.packages-to-scan=.api`、`abacus.entitypackages=.dao`、`abacus.controllerPackages=.controller`。 +- **统一响应体**由 `abacus.commons` 的 `ResultResponseBodyWrapper` 包装(`Application.java` 注册 `@Bean`),Controller 直接 return 业务对象;业务异常统一抛 `BusinessException`。 +- Known environment constraints: Nacos(bootstrap.yml 配置 server-addr/namespace,extension-configs 引入 abacus-database/discovery/acas/redis/actuator/xxljob 公共配置);Maven profile `dev`(默认)/`test`/`prod` 决定加载 `config//`;多数据库驱动已内置(MySQL/jtds+mssql/Oracle/达梦)。 + +## Common commands + +```sh +# Build(产出 target/*-bin.zip:jar + doc + sql + html) +mvn package -Pdev -DskipTests + +# Run +mvn spring-boot:run + +# Test +无自动化测试(人工冒烟验证) +``` + +环境注意:Nacos 需可达(配置中心/注册中心);构建依赖公司 Maven 私服(abacus 二方框架 jar);`pom.xml` `` 建议为 `abacus.springboot.<应用名>`。 + +## Architecture + +实现遵循 `.project.agents/docs/context/ARCHITECTURE.md` 的模块边界;模块清单(职责一句话): + +- **api / controller**:接口层(对外接口与前端/内部接口),Controller 只做参数校验与编排调用,直接 return 业务对象。 +- **esb / wsi**:Service 编排层(@Service)与对外服务接口(*ServiceIF),只编排不做 SQL。 +- **dao**:JPA 实体(表映射,含状态常量与 @Version 乐观锁)。 +- **pi / impl**:数据访问接口与实现(原生 SQL 全量参数化)。 +- **repository**:Spring Data JPA 仓储(派生查询 findByXxx)。 +- **config**:@Configuration(DaoIdGenerator、AbacusConfigNote 等基础设施 Bean)与配置常量。 +- 前后端共享约束见工作区 `docs/`(`../../../docs/coding-standards.md` §5 后端规范、§6 接口契约)。 + +## Project-level rules + +- **动手前必读两文件**——它们编码了本项目所有门控决策的经验: + - `.project.agents/VIBECODING_GUIDE.md` — 实践指南(为什么 & 怎么做) + - `.project.agents/SELF_CONSTRAINTS.md` — 硬约束(什么禁止、什么必须、何时停下) + + 任何非平凡任务,编辑前先跑 `SELF_CONSTRAINTS.md §A`(开工前自检)。 + +- **共享约束单一来源**:前后端共享的编码规范/接口契约/命名纪律,**只存在于工作区 `docs/`(`../../../docs/coding-standards.md`、`../../../docs/architecture.md`、`../../../docs/agent-guide.md`)**;本仓库 `.project.agents/docs/context/` 只写本仓库特有内容与指针,**禁止复制 docs/ 正文**。改共享内容先改 docs/ 再同步指针。 + +- **Agent 配置**一律写在 `.project.agents/` 下(或子目录),禁止写到仓库根、`.claude/` 或全局目录。 + +- **项目文档**位于 `.project.agents/docs/context/`(单层目录):`PRD.md`(行为权威)、`ARCHITECTURE.md`(模块/依赖/契约)、`ROADMAP.md`(里程碑)、`CONVENTIONS.md`(命名/风格/提交)。 + +- **源真相层级**(冲突时上游优先): + ``` + PRD.md > ARCHITECTURE.md > CONVENTIONS.md > 派生文档 + 仓库级 CONVENTIONS 再下接共享 docs/coding-standards.md(仅作全仓公共约定引用) + ``` + 上游变更须在同 commit 内回写受影响的派生文档;代码与架构漂移不得超过 24 小时。 + +- **路线图执行规则**:按 `.project.agents/docs/context/ROADMAP.md` 顺序推进,勾选与完成同 commit;milestone 级/多文件任务先写 plan/spec 再动手;每个 milestone 后按 `.project.agents/log/` 模板写执行日志。 diff --git a/abacus.springboot.example/.project.agents/SELF_CONSTRAINTS.md b/abacus.springboot.example/.project.agents/SELF_CONSTRAINTS.md new file mode 100644 index 0000000..7dad999 --- /dev/null +++ b/abacus.springboot.example/.project.agents/SELF_CONSTRAINTS.md @@ -0,0 +1,130 @@ +# Agent 自我约束清单(本项目硬规则) + +> 这是 Agent 在本项目工作时必须遵守的硬约束。每次开工前自查本清单,违反任何一条都应**先停下**,与用户对齐后再继续。 +> 完整背景与原理请见 [`VIBECODING_GUIDE.md`](./VIBECODING_GUIDE.md)。本清单只列"不许做什么 / 必须做什么"。 +> +> 文档约定(本项目):上游文档位于 `.project.agents/docs/context`,依次为 +> `PRD.md`(行为与范围)、`ARCHITECTURE.md`(模块/依赖/契约/目录)、`CONVENTIONS.md`(命名/风格/提交)。 +> 派生文档不得反向修改上游。 + +--- + +## A. 开工前的强制自检(每个新会话开始时执行) + +在进行任何编辑动作之前,必须确认以下事项;任一项不满足则先暂停业务任务,处理掉再继续。 + +- [ ] **A1. 仓库是否在版本控制下?** 若否:立即停下,先初始化仓库 + 配置 ignore + 初始 commit。 +- [ ] **A2. 工作区是否干净?** 有未提交的旧改动?先与用户确认是否要先提交/暂存,**不允许在脏工作区上叠加新改动**。 +- [ ] **A3. 是否已有 `ARCHITECTURE.md`?** + - 若否,且本次任务**涉及写业务代码**:先停下,按 `VIBECODING_GUIDE` 的流程产出架构文档,再写代码。 + - 若否,且本次任务**只是文档/讨论**:可继续,但应主动提醒用户补架构文档。 +- [ ] **A4. 任务的归属模块清楚吗?** 我能否在 `ARCHITECTURE.md` 的模块清单里指出"这个改动属于哪个模块"?指不出来则停下补架构。 +- [ ] **A5. 上游文档是否已读?** `PRD.md` / `ARCHITECTURE.md` / `CONVENTIONS.md` 中与本任务相关的章节是否读过?没读过先读,不要凭印象动手。 + +--- + +## B. 写代码时的硬约束 + +### B1. 模块边界 +- ❌ 不允许新增**未在 `ARCHITECTURE.md` 中登记**的模块;要新增必须先更新架构文档。 +- ❌ 不允许引入**反向依赖**(低层模块依赖高层模块)。需要时改为接口/回调倒置。 +- ❌ 不允许跨模块**直接访问私有实现**;只能走该模块对外暴露的接口。 +- ❌ 不允许出现 `Manager` / `Helper` / `Util` / `Common` / `Misc` / `Tools` 这类语义为空的新模块名;用动词+名词描述真实职责。 + +### B2. 单一职责 +- ❌ 不允许在 UI/展示层写业务判断或副作用(仅消费状态、发送意图)。 +- ❌ 不允许在数据模型类里堆业务方法;模型保持瘦,逻辑放 Service / UseCase。 +- ❌ 不允许"顺手"修改不在任务范围内的模块;越界的改动走单独提交并明确告知用户。 + +### B3. 文档同步(与代码改动**同一个 commit** 内) +- 加/删/改功能 → 同步更新 `PRD.md` +- 加/删/改模块或依赖 → 同步更新 `ARCHITECTURE.md`(模块清单 + 依赖图) +- 派生文档发现与上游不一致 → 回去改上游,不能让派生文档自走 + +### B4. 注释与命名 +- 默认不写注释;只在 WHY 不明显时写一行。 +- 不写解释 WHAT 的注释(命名应自解释)。 +- 不写"为某 issue/任务而加"这类会随时间失效的注释。 +- 严格遵守 `CONVENTIONS.md` 中的命名规范(不存在则先补)。 + +### B5. 错误处理 +- 只在系统边界(用户输入、外部 API、文件 IO)做防御;内部模块互相信任。 +- 不为不可能发生的情况加 fallback。 +- 不引入向后兼容 shim,除非用户明确要求。 + +### B6. 实施日志(execution log) +- **每完成一个可独立验收的部分(milestone 或子任务),必须在 `.project.agents/log` 写日志**。格式与时机见 `VIBECODING_GUIDE`。 +- 日志内必须包含本段的版本控制提交列表;若本段未提交,明确写出"未提交"及原因。 +- 完成路线图任一 milestone → **必须**写日志,且与该 milestone 的提交同一会话完成。 +- 单次会话即将结束(用户表示收工 / 上下文将被压缩)→ **必须**写一份兜底日志记录当前状态与下一步。 +- ❌ 不允许只提交不写日志(除非属于豁免情况:纯文档微调 / 被回滚的实验性探索)。 +- ❌ 不允许写日志但跳过更新 `ARCHITECTURE.md` —— 若本段触发架构变更,先改架构、再提交、再写日志。 + +--- + +## C. 改动范围控制 + +- ❌ 一次任务一个目的。不要"既加功能又重构又改样式"。 +- ❌ 不允许在 bug 修复任务中做无关清理。 +- ❌ 不允许引入"为未来准备"的抽象(YAGNI);三处相似优于一处过度抽象。 +- ❌ 不允许半完成的实现(要么这次完成,要么不要开始)。 + +--- + +## D. 出问题时的排查纪律 + +bug 处理必须按下列顺序,**严禁跳步**: + +1. 复现现象(明确触发路径) +2. 在 `ARCHITECTURE.md` 上**圈出嫌疑模块** +3. 检查跨模块**接口契约** +4. 缩小到单模块后再读代码 +5. 修完后:若是架构问题,必须更新 `ARCHITECTURE.md` 或 `CONVENTIONS.md` + +**禁止行为**:bug 一来就全仓 grep、试改一行看效果、连续 try-fail 循环。出现这种倾向立刻停下,回到第 2 步。 + +--- + +## E. 与用户的协作约束 + +- ❌ 不替用户做架构决策。涉及模块拆分、依赖方向、命名规范这类**长期影响**的决定,必须明确询问。 +- ❌ 不在用户没要求的时候主动创建文档(除非本清单或 `CLAUDE.md` 已要求)。 +- ❌ 不在没看代码的情况下凭推测回答 "X 是怎么实现的"。 +- ✅ 每次涉及架构/文档/规范变更,先告知影响面,再动手。 +- ✅ 用户的明确指示永远高于本清单和任何 skill。冲突时遵循用户。 + +--- + +## F. 触发"全员停车"的红线 + +出现以下任一情况,**立即停止当前任务,与用户对齐后再决定下一步**: + +1. 发现自己在脏工作区上累积了大量未提交改动 +2. 发现自己正在新增一个"无处归属"的模块/文件 +3. 发现代码与 `ARCHITECTURE.md` 已经矛盾,且无法用小补丁同步 +4. 同一个 bug 连续 3 次尝试修复未果 +5. 用户的请求与本清单 / `CLAUDE.md` / 上游文档存在冲突 —— 必须先澄清,不能默默选边 +6. 即将做出"难以回滚"的动作(删除文件 / 重命名模块 / 调整目录结构 / 强制 push) + +--- + +## G. 文件路径合规 + +- Agent 的配置文件**只**写入 `.project.agents` 子树,禁止写入仓库根目录或其他非约定位置。 +- 项目文档**只**写入 `.project.agents/docs/context`(不允许再分子目录,除非用户明确要求)。 +- 本清单(`SELF_CONSTRAINTS.md`)与指南(`VIBECODING_GUIDE.md`)位于 `.project.agents` 根,与 `CLAUDE.md` 同级。 + +--- + +## H. 自查触发器(什么时候重读本清单) + +至少在以下时机重读本清单: + +- 新会话开始,且任务涉及代码改动 +- 用户要求"加新功能"/"修 bug"/"重构" +- 自己感到"差不多可以直接动手了" —— 这种感觉本身就是触发器 +- 即将创建超过 1 个新文件 +- 即将修改 3 个以上文件 +- 即将修改任何 `.project.agents/docs/context` 下的文档 +- **完成一个路线图 milestone 或子任务前**(确认是否需要按 §B6 写日志) +- **会话即将结束前**(确认兜底日志已写) \ No newline at end of file diff --git a/abacus.springboot.example/.project.agents/VIBECODING_GUIDE.md b/abacus.springboot.example/.project.agents/VIBECODING_GUIDE.md new file mode 100644 index 0000000..ac4ef3b --- /dev/null +++ b/abacus.springboot.example/.project.agents/VIBECODING_GUIDE.md @@ -0,0 +1,250 @@ +# 项目开发实践指南(VIBECODING GUIDE) + +> 本文档是基于"踩过的坑"沉淀下来的项目工作方式约定,适用于本仓库及后续所有同性质的项目。 +> 它的姊妹文件是 [`SELF_CONSTRAINTS.md`](./SELF_CONSTRAINTS.md) —— 那是 Agent 每次开工前必须自查的硬约束清单。 +> 本文回答 "为什么这么做";`SELF_CONSTRAINTS.md` 回答 "具体不许做什么"。 + +--- + +## 0. 三条核心教训(本指南的来由,优先级严格递减) + +1. **版本控制必须从第 0 天开始。** + 不是 "等做出点东西再说",是写第一行代码之前先初始化仓库、写好 ignore 规则、提交一个空骨架。 + 理由:高频改动 + 频繁推翻是 AI 协作的常态,没有版本控制兜底就等于在悬崖边裸奔。 + +2. **文档必须在写代码之前定下来。** + 需求、架构、路线图、开发规范、目录结构、命名规范、模块边界 —— 这些不是"做完之后补的",是"做之前定的"。 + 理由:一旦上下文被代码细节占满,后续每个新会话都只能 freestyle,项目会朝不可逆的方向漂移。 + +3. **架构 > UI > 用户体验。** + 最致命的不是界面丑、不是体验差,而是模块互相纠缠到无法定位问题。 + 一个出问题就能立刻指认 "是 X 模块的责任" 的项目,比一个好看但耦合一团的项目,存活率高一个数量级。 + 理由:耦合一旦发生,AI 协作模式会迅速放大它 —— 因为每次新会话都看不全全貌,只会在原有耦合上继续添乱。 + +> 这三条的优先级是严格递减的:先有版本控制,再有文档,再谈架构;架构稳了之后才轮到 UI 和体验。 + +--- + +## 1. 项目启动 Checklist(Day 0) + +下列每一项都必须在写第一行业务代码之前完成。顺序即优先级。 + +### 1.1 仓库与版本控制 +- [ ] 初始化版本控制并立即建立 ignore 规则(语言 / IDE / 系统三类至少齐全) +- [ ] 提交一个 **空骨架 commit**(README + ignore 规则 + 空目录结构),作为"零点参照系" +- [ ] 约定分支模型(最简:主干 + 短命的功能分支;不要等到分叉时才想) +- [ ] 约定 commit message 风格(推荐 Conventional Commits,至少要求动词开头 + 一句话原因) + +### 1.2 文档骨架(必须先于代码存在) +在 `.project.agents/docs/context` 下建立以下文件,**哪怕只有大纲也比没有强**: + +| 文件 | 角色 | 上下游关系 | +|---|---|---| +| `PRD.md` | 产品需求(要做什么) | 上游 | +| `ARCHITECTURE.md` | 架构(怎么拆) | 上游 | +| `ROADMAP.md` | 路线图(什么时候做哪一块) | 由需求 + 架构推导 | +| `CONVENTIONS.md` | 开发规范(命名、目录、提交、风格) | 上游 | +| 派生文档(实现 spec / 资产清单等) | 屏幕级实现 / 资产清单 | **派生**,由上游产生 | + +**判断标准**:如果一个新会话的 Agent 只读需求 + 架构 + 开发规范就能正确开始一个任务 —— 文档就算合格。 + +### 1.3 Agent 协作配置 +- [ ] 在 `CLAUDE.md` 写明项目级规则(已有,保持更新) +- [ ] 在本文件 + `SELF_CONSTRAINTS.md` 中固化经验 +- [ ] 在 `.project.agents/settings.json` 中配置必要的 hook / 权限(不要散落到根目录或全局) + +--- + +## 2. 架构原则 + +### 2.1 三条硬规则 + +1. **单一职责到模块级** + 每个模块只回答一个问题。 + 反例:"一个模块既管数据持久化,又管网络请求,又管 UI 状态" —— 这种模块必须拆。 + +2. **依赖方向单向** + 高层依赖低层,UI 依赖业务,业务依赖数据;**反向依赖一律禁止**,遇到就用接口/事件/回调倒置。 + 依赖关系必须能画成一张**有向无环图(DAG)**,且这张图要在 `ARCHITECTURE.md` 里画出来。 + +3. **跨模块只走"接口契约"** + 模块 A 想用模块 B 的能力,只能通过 B 暴露的接口/协议,不能 reach into B 的内部实现。 + 接口契约必须在 `ARCHITECTURE.md` 中显式声明(哪怕只是函数签名清单)。 + +### 2.2 判断架构是否健康的三个问句 + +随时可以用这三个问句自检: + +1. **指认问题**:现在出 bug 了,我能否在 30 秒内指出"这是哪个模块的责任"? +2. **替换实现**:如果要把模块 X 整体换掉(换数据库、换框架),改动是否能控制在 X 内部 + 一个接口适配层? +3. **新增功能归属**:用户要加一个新功能,我能否立刻说出它"属于哪个模块、或需要新增哪个模块"? + +任何一个回答不出来,架构就有问题,**先停下修架构,再写代码**。 + +### 2.3 反耦合纪律 + +- **不在新功能开发时顺手重构无关模块**(重构走单独 commit + 单独会话) +- **不在 UI 层做业务判断**(UI 只接收状态、发送意图) +- **不让数据模型自己跑业务逻辑**(模型类保持瘦,业务放 Service / UseCase) +- **不要"为了少写一个文件"把两个模块塞进同一个文件** + +--- + +## 3. 项目架构文档生成流程 + +这是从零到 `ARCHITECTURE.md` 的标准流程。每一步都有产出物,下一步必须基于上一步的产出物。 + +### Step 1 — 需求收敛(产出 `PRD.md`) +- 列功能清单,按 **核心 / 增强 / 可选** 三档分类 +- 每个核心功能写一句 "用户故事"("作为 X,我想 Y,以便 Z") +- **冻结 MVP 范围**:圈出 MVP 包含哪些核心功能,其余明确标 "Out of MVP" + +### Step 2 — 领域建模(产出 `ARCHITECTURE.md` §1 领域模型) +- 列出所有**名词实体**(用户、订单、会话…) +- 标注每个实体的字段、关系、生命周期 +- 标记哪些是**持久化实体**,哪些是**瞬态状态** + +### Step 3 — 模块划分(产出 `ARCHITECTURE.md` §2 模块清单) +对照领域模型与需求功能清单,拆分模块。每个模块写一张卡片: + +``` +## 模块名: +- 职责:一句话 +- 不负责:明确写出"不做什么"(防止职责蔓延) +- 输入:从哪些模块/外部来 +- 输出:暴露给谁 +- 关键类型/接口:列签名(不写实现) +- 持有状态:有没有自己的状态? +``` + +**经验**:如果一个模块的"不负责"写不出来,说明它的职责还没想清楚,回到 Step 2。 + +### Step 4 — 依赖图(产出 `ARCHITECTURE.md` §3 依赖图) +- 画出模块间依赖箭头(推荐 Mermaid,纯文本可 diff) +- **手动验证 DAG**:从任一节点 DFS 不应回到自己 +- 标出"接口边界":哪些依赖是接口注入,哪些是直接调用 + +### Step 5 — 路线图(产出 `ROADMAP.md`) +按依赖图的拓扑顺序排开发节奏: +- 先做被依赖最多的底层模块 +- 每个 milestone 必须能独立通过编译/构建并跑出某种"可见行为" +- 写明每个 milestone 完成的"验收标准"(不是"做完了",是"做完了之后能演示什么") + +### Step 6 — 开发规范(产出 `CONVENTIONS.md`) +- 命名(类型 / 文件 / 目录 / 资产) +- 代码风格(缩进 / 注释策略 / 错误处理边界) +- 提交规范 +- 测试策略(哪些必须有测试,哪些不要求) + +### Step 7 — 派生文档(产出实现 spec / 资产清单等) +**只有上面 6 步都齐了,才能开始写派生文档**。 +派生文档必须显式引用上游章节("对应 `ARCHITECTURE.md` §2.3 的 XxxService 模块"),方便后续 diff 校验。 + +--- + +## 4. 文档变更协议 + +文档不是写完就锁死的,但变更必须**沿着上下游传播**: + +| 变更点 | 必须同步更新 | +|---|---| +| 需求加/删/改功能 | 架构模块清单、路线图、派生文档 | +| 架构调整模块边界 | 依赖图、开发规范(如有命名调整)、派生文档 | +| 加新模块 | 架构 §2 + §3、路线图、开发规范(如新目录) | + +**权威链**:`PRD.md > ARCHITECTURE.md > CONVENTIONS.md > 派生文档`。 +派生文档永远不能**反向**修改上游。如果在派生文档中发现矛盾,回去改上游,再让派生文档重新对齐。 +**代码与架构漂移 > 24 小时即违规。** + +--- + +## 5. 实施日志(execution log) + +写代码 / 执行路线图期间,**每完成一个可独立验收的"部分",必须在 `.project.agents/log` 写一份日志**。日志是给"下一个会话的我"看的 —— 让接手的会话能在不读所有代码的情况下知道:刚才完成了什么、哪些提交、下一步是什么。 + +### 5.1 何时写日志 +- 完成一个路线图 milestone +- 完成一个 milestone 内独立可验收的子任务 +- 完成一次非平凡的重构 / bug 修复 +- 当前会话即将结束时(兜底,把上下文沉淀下来) + +**判断标准**:如果这段工作下一个会话需要知道,就写。 + +### 5.2 日志文件命名 +`.project.agents/log/YYYY-MM-DD-.md` +- `` = 简短动词 + 范围,kebab-case +- 同日多份日志按写作顺序累积(不覆盖、不合并),文件名加序号后缀:`-1`、`-2`… + +### 5.3 日志内容模板 +```markdown +# <一句话标题:完成了什么> + +- **日期**:YYYY-MM-DD +- **关联**:路线图 M / 子任务名 / 关联文档 +- **会话上下文**:(可选)本会话从哪开始接手的 + +## 做了什么 +- bullet 1 +- bullet 2 + +## 提交 +- `` + +(若本段未提交:明确写"未提交,工作树状态:…"并说明原因) + +## 状态变更 +- 架构文档:是否动过?动了哪一节? +- 需求/UI 文档:是否触发回归? +- 测试:跑了什么,结果 + +## 下一步 +- 接下来要做的第一件事(具体到任务名) +- 已知阻塞 / 待澄清项 +``` + +### 5.4 与提交的关系 +日志**不替代** commit message,commit message 仍按 `CONVENTIONS.md` 写;日志是提交的**索引与解释**。 + +### 5.5 不写日志的情况 +- 还没完成一个"可独立验收"的部分 —— 不要"写日志凑数" +- 纯文档调整 —— commit 自身已足够说明 +- 实验性探索(最终被回滚的内容)—— 用 commit message 记录即可 + +--- + +## 6. 出问题时的排查流程 + +bug 来了不要直接钻进代码。按下列顺序: + +1. **复现并定位现象**:能在哪个入口 / 哪个调用稳定复现? +2. **回到架构图**:这个现象涉及哪些模块?沿着依赖图圈出可能责任方。 +3. **审查接口契约**:跨模块调用是否符合 `ARCHITECTURE.md` 中声明的接口?输入输出是否符合契约? +4. **缩小到单模块**:把嫌疑缩小到一个模块后,再读该模块代码。 +5. **修复并回写经验**:如果发现是架构层面的漏洞,修完代码后**必须更新 `ARCHITECTURE.md` 或 `CONVENTIONS.md`**。 + +**反模式**:bug 一来就 grep 关键字、改一行试一下、再改一行试一下 —— 这是死亡螺旋,必须用流程压下去。 + +--- + +## 7. 反模式清单("看到这些立刻警觉") + +- 出现语义为空的模块名(`Manager` / `Helper` / `Util` / `Common` / `Misc` / `Tools`)且行数 > 100 行 +- 一个文件 import 超过 10 个本地模块 +- 改一个 UI 改动需要动 3 个以上其他模块 +- 同一份业务逻辑在两个地方各写了一遍 +- PR 描述写"顺便修了 X" +- 新增功能时发现"无处归属",于是塞进入口文件或主组件 +- 文档与代码不一致超过 24 小时 +- 出现没有在 `ARCHITECTURE.md` 中登记的新模块/新依赖方向 + +任何一条出现,**先停下来回到本指南或架构文档,不要继续往前推**。 + +--- + +## 8. 本项目当前阶段 + +> 本节随项目演进,不是规则的一部分。由 Agent 在每个 milestone 后更新。 + + +- 当前状态:后端模板(`abacus.springboot.example`)已完成治理落地(Retrofit),分层以示例模块实际结构为准(api/controller/dao/esb/pi/impl/repository/wsi/config/util/vo);前后端共享约束单源化于工作区 `docs/`(`../../../docs/coding-standards.md`)。 +- 下一步合规动作:新业务模块按 `docs/coding-standards.md §5`(后端规范)与 §7(AI 生成工作流)开发;任何新增包、依赖方向或 SQL 变更先回写本仓库 `ARCHITECTURE.md` 与 `sql/` 约定,再写代码。 diff --git a/abacus.springboot.example/.project.agents/assets/.gitkeep b/abacus.springboot.example/.project.agents/assets/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/abacus.springboot.example/.project.agents/bugs/.gitkeep b/abacus.springboot.example/.project.agents/bugs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/abacus.springboot.example/.project.agents/docs/context/ARCHITECTURE.md b/abacus.springboot.example/.project.agents/docs/context/ARCHITECTURE.md new file mode 100644 index 0000000..1720e4a --- /dev/null +++ b/abacus.springboot.example/.project.agents/docs/context/ARCHITECTURE.md @@ -0,0 +1,178 @@ +# abacus.springboot.example — 架构文档(ARCHITECTURE) + +> 模块、依赖、契约、目录布局的**唯一权威**(本仓库视角)。新增/重命名/移动模块或调整依赖方向,必须先改本文,再改代码(同一个 commit)。 +> 上游:`PRD.md`(行为)。前后端共享约束见工作区 `docs/`(`../../../../docs/coding-standards.md` §5 后端规范、§6 接口契约),本文不复制其正文。 + +## 0. 阅读指引 + +本文描述后端模板的模块划分与依赖方向;§2 模块清单与 §6 目录一一对应,§3.2 是跨模块接口契约。新会话先读 §2 + §6 定位任务归属,再动手。 + +## 1. 领域模型(Domain Model) + +### 1.1 实体 + +模板自带示例纵切面(稽查 JcBill),供复制改写: + +| 实体 | 字段 | 关系 | 持久化? | +|---|---|---|---| +| jc_bill(稽查主单) | id(@Id)/version(@Version)/status/… | 1:N 明细 | 是 | +| jc_bill_item / jc_bill_photo / jc_bill_hg / jc_bill_hg_pay / jc_source_item / jc_bill_in_item / jc_bill_source_item | id/主单关联字段 | N:1 主单 | 是 | + +字段细节见 `dao/*.java` 与 `sql/upgrade.xml`(建表 DDL)。 + +### 1.2 派生概念(非持久化) + +- `api/view/*`:请求/响应 DTO(ApiReq*/ApiResp*),编排层与 Controller 之间传递。 +- `@Transient` 字段:实体上的非持久化附加信息(如 `recsource`)。 + +### 1.3 不变量(任何模块都必须维护) + +- I1. 业务主键一律由 `DaoIdGenerator` 生成(prefix+yyyyMMdd+serialLength),禁止手拼/UUID。 +- I2. 原生 SQL 全量 `?` 参数化,禁止字符串拼接。 +- I3. 分层依赖单向:api/controller → esb/wsi → {pi/impl, repository} → dao;禁止反向依赖。 +- I4. Controller 直接 return 业务对象,禁止手拼统一响应体。 + +## 2. 模块清单 + +按依赖层级从低到高排列。 + +### Layer 0 — dao(实体层) +``` +## 模块名:dao +- 职责:JPA 实体(表映射、状态常量、@Version 乐观锁) +- 不负责:查询逻辑、业务规则 +- 输入:无(被 repository/impl 引用) +- 输出:实体类型 +- 关键类型/接口:@Entity 类(如 JcBill) +- 持有状态:无(纯数据) +``` + +### Layer 0 — config(基础设施配置) +``` +## 模块名:config +- 职责:@Configuration(DaoIdGenerator、AbacusConfigNote 默认值)+ 配置 key 常量 +- 不负责:业务规则 +- 输入:application.yml / Nacos 配置 +- 输出:基础设施 Bean +- 持有状态:无 +``` + +### Layer 1 — repository / pi+impl(数据访问) +``` +## 模块名:repository(Spring Data JPA) +- 职责:标准 CRUD 与派生查询(findByXxx) +- 不负责:复杂查询(走 pi/impl) +- 输出:实体查询结果 + +## 模块名:pi + impl(原生 SQL 访问) +- 职责:复杂查询/批量写(pi 定义接口,impl 实现,SQL 参数化) +- 不负责:业务编排 +- 输出:DTO/实体结果 +``` + +### Layer 2 — esb / wsi(服务编排与接口) +``` +## 模块名:esb + wsi +- 职责:业务用例编排(esb/*BizService,@Service)、对外服务接口(wsi/*ServiceIF) +- 不负责:直接 SQL、Controller 层参数解析 +- 输入:Controller 传入的 DTO/参数 +- 输出:编排结果(DTO/实体) +- 持有状态:事务边界(@Transactional 按需) +``` + +### Layer 3 — api / controller(接口层) +``` +## 模块名:api + controller +- 职责:对外接口(api/,springdoc 扫描)与前端/内部接口(controller/,abacus.controllerPackages 扫描) +- 不负责:业务编排与 SQL +- 输入:HTTP 请求(@RequestParam/@RequestBody) +- 输出:业务对象(由 ResultResponseBodyWrapper 包装) +- 持有状态:无 +``` + +## 3. 依赖图(DAG) + +```mermaid +graph TD + api_controller[api / controller] --> esb_wsi[esb / wsi] + esb_wsi --> pi_impl[pi / impl] + esb_wsi --> repository[repository] + pi_impl --> dao[dao] + repository --> dao + esb_wsi --> dao + config -.注入.-> esb_wsi + config -.注入.-> pi_impl +``` + +### 3.1 依赖方向规则 + +- 高层依赖低层,单向;**禁止** dao 依赖 repository、esb 依赖 controller 等反向依赖。 +- 跨层调用走接口(wsi ServiceIF / pi AccessIF),不 reach into 实现。 + +### 3.2 跨模块接口契约(写代码时必须遵守的签名) + +``` +// module: controller +// @RequestMapping(value, method) -> 业务对象(throws Exception) // 直接 return,I4 + +// module: esb/wsi +// XxxServiceIF.method(dto...) throws Exception // 编排用例,事务边界 + +// module: pi/impl +// XxxAccessIF.method(params...) -> List // 原生 SQL,I2 参数化 + +// module: repository +// XxxRepository extends JpaRepository, JpaSpecificationExecutor + +// module: config +// @Bean DaoIdGenerator(prefix/useDateFormat/yyyyMMdd/serialLength) // I1 +``` + +## 4. 持久化与边界 + +- 数据源:Druid 连接池 + JPA;多数据源由 Nacos `abacus-database.yml` 提供(enableMultiSource / multidb0~9 / defaultDB / readDB / dynamicRelation)。 +- 外部边界:Nacos(注册+配置)、Kafka(消息)、XXL-JOB(调度)、Feign(服务间调用)、springdoc(接口文档)、Actuator(监控)。 + +## 5. 测试边界 + +- 无自动化单测(PRD 决策);接口人工冒烟。 +- **必须真机验证**:多数据源路由、Kafka 消费、XXL-JOB 调度、Nacos 配置拉取、真实数据库迁移——mock/模拟器不算数。 + +## 6. 目录结构(与 §2 模块清单一一对应) + +``` +src/main/java/abacus/springboot/<应用名>/ +├── Application.java # 入口(注册 ResultResponseBodyWrapper) +├── api/ # 对外 Controller(springdoc 扫描);api/view/ 放 DTO +├── controller/ # 前端/内部 Controller(abacus.controllerPackages 扫描) +├── dao/ # JPA 实体(abacus.entitypackages 扫描) +├── esb/ # Service 编排层(@Service) +├── wsi/ # 服务接口 *ServiceIF +├── pi/ # 数据访问接口 *AccessIF +├── impl/ # 数据访问实现(原生 SQL) +├── repository/ # Spring Data JPA Repository +├── config/ # @Configuration + 配置常量 +├── util/ vo/ # 既有兼容(可引不可增) +src/main/resources/ +├── config/{dev,test,prod}/ # 三套同构配置 +├── sql/{table,data}/ + upgrade.xml # 建表双份/初始化/版本化升级 +├── html/vue/<应用名>/ # 前端构建产物(打包入 *-bin.zip) +└── doc/升级日志.md # 功能更新记录 +``` + +## 7. 自检(架构健康度三问) + +1. 出 bug 了,能否 30 秒内指出是哪个包(controller/esb/impl/repository)的责任? +2. 换数据库/换 JPA 实现,改动能否控制在 impl/repository + 配置内? +3. 加新业务接口,能否立刻说出它落在 api 还是 controller、esb 是否要新增 BizService? + +## 8. 待办与已知技术负债 + +- `springdoc-openapi-maven-plugin` 的 `apiDocsUrl` 硬编码 `http://localhost:8080/v3/api-docs`,与应用实际端口(9060)不一致,生成 openapi.json 时需手工修正。 +- `prod/application.yml` 引用 `abacus.springboot.example.springdoc` 扫描路径但该包不存在(模板未创建 springdoc 包)——新系统以实际包为准。 + +## 9. 文档变更协议 + +- 加/删模块或改依赖方向 → 改本文 §2 + §3,同一 commit。 +- 改对外签名 → 先改 §3.2,再改代码。 +- 与 `PRD.md` 冲突 → 以 `PRD.md` 为准,回改本文;与共享 `docs/coding-standards.md` 冲突 → 以 docs/ 为准并回改本文。 diff --git a/abacus.springboot.example/.project.agents/docs/context/CONVENTIONS.md b/abacus.springboot.example/.project.agents/docs/context/CONVENTIONS.md new file mode 100644 index 0000000..d92f1ea --- /dev/null +++ b/abacus.springboot.example/.project.agents/docs/context/CONVENTIONS.md @@ -0,0 +1,94 @@ +# abacus.springboot.example — 开发规范(CONVENTIONS) + +> 命名、目录、提交、风格、测试的权威(本仓库视角)。前后端共享约束见工作区 `docs/coding-standards.md`(`../../../../docs/coding-standards.md`),本文只写后端特有内容 + 指针,**禁止复制 docs/ 正文**。 + +## 0. 阅读指引 + +- 适用范围:`src/main/java/abacus/springboot.<应用名>/**` 业务开发(模板基础结构 pom/assembly/config 原则上不动)。 +- 分工:ARCHITECTURE 管"拆成什么模块";本文管"怎么命名/写";共享编码规范、接口契约、SQL 约定、AI 生成工作流在 `docs/coding-standards.md` §5~§7。 + +## 1. 命名 + +### 1.1 标识符 + +- 类:PascalCase;接口带后缀 `IF`(pi 层 `XxxAccessIF`、wsi 层 `XxxServiceIF`);编排服务 `XxxBizService`;实现 `XxxAccess`。 +- Controller:`XxxController`(api 对外 / controller 内部);基类 `BaseServlet`。 +- 实体:表名小写下划线(`jc_bill`),类名驼峰(`JcBill`);DTO:请求 `ApiReqXxx`、响应 `ApiRespXxx` 或 `ApiXxx`(api/view)。 +- 配置:`XxxConfiguration`、`XxxConfigKey`(常量类)。 + +### 1.2 模块命名(语义禁区) + +- 禁止 `Manager` / `Helper` / `Util` / `Common` / `Misc` / `Tools` 这类语义为空的名字;用"动词+名词"。 +- **util/ vo/ 兼容**:既有 `util/DateUtil`、`vo/BaiduToken` 等**可引不可增**——新代码禁止在 `util/`、`vo/` 包新增文件(共享规范 §8.4)。 + +### 1.3 文件 / 1.4 目录 / 1.5 资产命名 + +- 文件按类名命名(一文件一公共类);目录即包名(分层见 ARCHITECTURE §6)。 +- SQL:`sql/table/{mysql,sqlserver}.sql`、`sql/upgrade.xml`、`sql/data/`;版本号 `yyyy-MM-dd[.count]`。 + +### 1.6 字符串与本地化 + +- 异常消息中文、可行动("参数[x]为空!");不硬编码无意义字符串;状态常量用 `public final static int STATUS_*`。 + +## 2. 代码风格 + +### 2.1 排版 + +- Java 4 空格缩进、行宽 ≤ 120;分号/括号按 Java 惯例。 +- 不使用 Lombok(手写 getter/setter,与示例一致)。 + +### 2.2 分层纪律 + +- Controller 只做参数校验 + 调编排,不写 SQL、不碰 Repository;esb 只编排不做 SQL。 +- 原生 SQL 在 `impl/`,**全量 `?` 参数化**;标准 CRUD/派生查询用 `repository`。 +- 业务主键一律 `DaoIdGenerator`,禁止手拼。 + +### 2.3 并发 / 2.4 错误处理 + +- 事务边界在 esb 编排方法(按需 `@Transactional`);JPA 乐观锁用 `@Version`。 +- 业务错误抛 `BusinessException`(中文消息);Controller 方法级 try/catch(Throwable) 记日志后 rethrow;**禁止吞异常**。 + +### 2.5 注释 + +- 默认不写注释;只在 WHY 不明显时写一行;不写解释 WHAT 的注释(命名应自解释)。 + +## 3. 提交规范 + +### 3.1 Commit message 风格 + +Conventional Commits:`type(scope): subject`。允许 type:`feat` / `fix` / `docs` / `refactor` / `test` / `chore`。例:`feat(jcbill): 新增稽查收货保存接口`。 + +### 3.2 提交粒度 / 3.3 工作区纪律 / 3.4 分支模型 + +- 一次提交一个目的;不在脏工作区叠加不相关改动。 +- 分支模型:主干 + 短命功能分支(按需,单人开发可直推主干)。 +- 本仓库属于工作区单一 git 仓库(`D:\workBuddySpace\member`);纯后端改动 commit 限定本目录,跨项目改动(docs/)单独 commit。 + +### 3.5 实施日志 + +- 规则见 `VIBECODING_GUIDE §5`:每个可独立验收的部分写 `.project.agents/log/YYYY-MM-DD-.md`。 +- 功能更新同步追加 `src/main/resources/doc/升级日志.md`(共享规范 §5.11 格式)。 + +## 4. 测试策略 + +### 4.1 框架 / 4.2 必须有测试的模块 + +- 无自动化测试框架(PRD 决策);接口人工冒烟。 + +### 4.3 必须真机/真环境验证 + +- **必须真机验证**(mock/模拟器不算数):多数据源路由、Kafka 消费、XXL-JOB 调度、Nacos 配置拉取、真实数据库迁移。 + +## 5. 与上游文档的同步矩阵 + +| 变更点 | 必须同步更新 | +|---|---| +| 新增/改动业务功能 | `PRD.md`(功能定义);共享规范如有涉及先改 `docs/coding-standards.md` | +| 新增包/模块/依赖方向 | 本仓库 `ARCHITECTURE.md` §2+§3 | +| 新增 SQL/表结构 | `sql/table/` 双份 + `sql/upgrade.xml`;`ARCHITECTURE.md §1` 实体清单 | +| 配置项变更 | `config/{dev,test,prod}/` 三套同步 | +| 依赖版本变更 | `pom.xml` + `doc/升级日志.md` | + +## 6. 不在本文范围(明确划清) + +- 模块拆分归 `ARCHITECTURE.md`;行为/范围归 `PRD.md`;前后端共享约束(响应体/异常码/分页/APP_NAME/打包)归 `docs/coding-standards.md`。 diff --git a/abacus.springboot.example/.project.agents/docs/context/PRD.md b/abacus.springboot.example/.project.agents/docs/context/PRD.md new file mode 100644 index 0000000..369cf2f --- /dev/null +++ b/abacus.springboot.example/.project.agents/docs/context/PRD.md @@ -0,0 +1,91 @@ +# abacus.springboot.example — 产品需求文档(PRD) + +> 行为与范围的**唯一权威**。功能的加/删/改必须先改本文,再动代码与下游文档。 +> 本文回答"做什么 / 给谁 / 为什么",不回答"怎么实现"(那是 `ARCHITECTURE.md`)。 + +## 1. 产品愿景 + +为 abacus 微服务体系提供**可复用的 Spring Boot 微服务模板**:业务团队(人 + AI)在本模板上按分层规范添加业务模块(Controller / Service / 数据访问 / Entity / SQL / 配置),即可获得统一响应体、异常体系、多数据库支持、Nacos 注册配置、定时任务与动静分离打包能力,实现跨系统一致的后端工程结构与低成本复制开发。 + +## 2. 目标用户与典型场景 + +- 用户画像:公司内部业务系统后端开发团队(后端开发、全栈、AI 辅助开发人员)。 +- 场景 1:作为业务开发,我想复制本模板新建一个微服务,以便快速获得 Nacos / 多库 / 打包 / 日志等基础设施。 +- 场景 2:作为 AI 助手,我想依据 `docs/coding-standards.md §5/§7` 把界面需求直接生成 Controller→Service→数据访问→SQL 全链路代码。 +- 场景 3:作为发布负责人,我想让所有服务打出结构一致的 `*-bin.zip`(jar+doc+sql+html),以便统一发布流程。 + +## 3. 范围(Scope) + +### 3.1 MVP 必含(In Scope) +- 分层骨架(api/controller/dao/esb/pi/impl/repository/wsi/config)与扫描配置(springdoc/entitypackages/controllerPackages)。 +- 统一响应体包装(`ResultResponseBodyWrapper`)与业务异常(`BusinessException`)。 +- 多数据库(MySQL / SQL Server / Oracle / 达梦)+ Druid + JPA;Nacos 注册/配置中心。 +- SQL 三件套(table 双份 / upgrade.xml 版本化 / data 初始化)与动静分离打包(assembly.xml → *-bin.zip)。 +- 示例业务纵切面(JcBill 稽查示例:Controller + BizService + Access + Repository + Entity + 升级 SQL)。 + +### 3.2 明确不做(Out of Scope) +- 不包含具体生产业务(业务模块由团队基于模板复制开发)。 +- 不提供自动化测试框架与 CI(人工冒烟验证)。 +- 不维护前端页面(前端属 `abacus-static-framework` 仓库)。 + +## 4. 核心功能定义 + +### 4.1 统一响应体与异常(【核心】) +- **用户故事**:作为前端/调用方,我想所有接口返回一致的 `{status, message, data, errorCode}`,以便统一处理。 +- **行为**:`Application.java` 注册 `ResultResponseBodyWrapper`;Controller 直接 return 业务对象;参数空校验抛 `BusinessException("参数[x]为空!")`。 +- **边界 / 异常**:`abacus.responseExcludePath` 配置的 URI 不被包装;业务异常码首位 9、系统异常码首位 5(共享规范 §6.2)。 + +### 4.2 分层开发模型(【核心】) +- **用户故事**:作为团队开发,我想按固定分层写代码,以便职责清晰、可评审、可复制。 +- **行为**:Controller(api/controller)→ esb 编排 → wsi/pi/repository 数据访问 → dao 实体;依赖单向。 +- **边界 / 异常**:Controller 不写 SQL、不碰 Repository;esb 只编排不做 SQL;原生 SQL 全量参数化。 + +### 4.3 数据库多库支持(【核心】) +- **用户故事**:作为实施,我想同一套代码跑 MySQL 与 SQL Server,以便一套系统多客户部署。 +- **行为**:建表脚本 `sql/table/{mysql,sqlserver}.sql` 双份同步;历史变更 `sql/upgrade.xml`(`translator="true"` 以 SQL Server 语法书写由框架翻译)。 +- **边界 / 异常**:多数据源路由、真实迁移必须真机验证。 + +### 4.4 动静分离打包(【核心】) +- **用户故事**:作为发布,我想一个发布包包含前后端全部产物,以便统一发版。 +- **行为**:前端产物输出到 `resources/html/vue/<应用名>/`,`mvn package` 经 `assembly.xml` 打出 `*-bin.zip`(jar+doc+sql+html)。 +- **边界 / 异常**:jar 内不含 html;`pom.xml` artifactId 建议 `abacus.springboot.<应用名>`。 + +## 5. 信息架构与导航 + +微服务间通过 Nacos 注册发现 + Feign 调用;接口文档由 springdoc 提供(扫描 `api` 包);监控经 Actuator(base-path `/services/actuator`)暴露 Prometheus 指标;定时任务由 XXL-JOB(`application-xxljob.yml`)承载。 + +## 6. 数据模型(概念级) + +业务数据实体集中在 `dao/` 包(JPA 映射);概念级实体清单由各业务模块在 `ARCHITECTURE.md §1` 维护。模板自带示例实体:`jc_bill`(稽查主单)及其明细/关联表(见 `sql/upgrade.xml`)。 + +## 7. 非功能性需求 + +- 多环境配置 `config/{dev,test,prod}/` 三套同构;dev 端口 9060 / test、prod 9000(以实际为准)。 +- 上传限制 50MB;Druid 连接池(初始 10 / 最大 60);Feign 超时 10s 连接 / 30s 读取。 +- JPA 与 Bean 延迟启动(`lazy-initialization`)以加速启动。 + +## 8. 国际化与文案语气 + +异常消息使用中文,直接面向用户可理解(如"参数[x]为空!");接口文档(@Operation summary)用中文。 + +## 9. 隐私与合规 + +- 数据库连接与 Nacos 凭据放在 `config//` 配置文件(git 跟踪按团队约定);**不得**新增明文密钥到非约定位置。 +- 审计信息(菜单/模块/业务域)由前端 commonParam 提供,见共享规范 §6.7。 + +## 10. 风险与缓解 + +- **APP_NAME 四处漏配静默失败**:按共享规范 §3 四联检(bootstrap.yml / 扫描包 / URL 首段 / outDir)。 +- **多库语法差异**:新 SQL 以 SQL Server 语法编写并加 `translator="true"`,建表双份同步。 +- **框架 jar 版本升级**:`pom.xml` 依赖版本变更需在升级日志记录并回归验证。 + +## 11. 发布里程碑(建议,待路线图细化) + +- M0:治理与规范落地(本次已完成)。 +- M1+:按 `ROADMAP.md` 以新业务模块验证模板可复制性(界面→代码全链路)。 + +## 12. 假设与待澄清项(复核时请逐条回应) + +- Q1. 新业务是否一律采用 `abacus.springboot.<应用名>.<层>` 包前缀?(默认:是) +- Q2. 是否引入后端单元测试(如 JUnit/Testcontainers)?(默认:否,人工冒烟 + 真机验证) +- Q3. `util/`、`vo/` 包是否冻结不再新增?(默认:是,既有兼容、新增禁止) diff --git a/abacus.springboot.example/.project.agents/docs/context/ROADMAP.md b/abacus.springboot.example/.project.agents/docs/context/ROADMAP.md new file mode 100644 index 0000000..d795fdc --- /dev/null +++ b/abacus.springboot.example/.project.agents/docs/context/ROADMAP.md @@ -0,0 +1,55 @@ +# abacus.springboot.example — 实施路线图(ROADMAP) + +> 由 `PRD.md` + `ARCHITECTURE.md` 推导。按依赖图拓扑顺序排开发节奏。每完成一个复选框,在**同一个 commit**里打勾;每完成一个 milestone,按 `.project.agents/log/` 模板写日志。 + +## 0. 排序原则 + +- 先基础设施(config/dao/repository 等底层)后接口(esb/api)。 +- 本仓库为**后端模板**:里程碑以"验证模板可复制性 + 治理可持续性"为主线,而非业务功能交付。 + +## 1. 里程碑总览 + +| Milestone | 目标 | 验收(能演示什么) | +|---|---|---| +| M0 | 治理落地(本次):git 单一仓库、docs/ 文档中心、.project.agents 全套、共享规范 | 克隆仓库 → `mvn package -Pdev -DskipTests` 可出包;治理文档无残留 token | +| M1 | 模板可复制性验证:按 `docs/coding-standards.md §7` 用第一个业务模块(界面→代码)跑通全链路 | 新业务接口可调用(springdoc 可见)、SQL 可在 MySQL/SQL Server 执行 | +| M2 | 沉淀与回写:业务中发现的共性需求回写模板/规范 | 模板与规范有增量,升级日志有记录 | + +## 2. 里程碑详细 + +### M0 — 治理与规范落地(已完成) +- [x] 版本控制 + ignore + 骨架提交(工作区单一仓库 `D:\workBuddySpace\member`) +- [x] docs/ 文档中心(README / architecture / coding-standards / agent-guide) +- [x] 本仓库 .project.agents 治理文件(CLAUDE / AGENTS / SELF_CONSTRAINTS / VIBECODING_GUIDE / settings / context 四文档) +- [x] 完成门禁(治理文档无残留模板 token / FILL 标记) +- **验收**:克隆仓库 → `mvn package -Pdev -DskipTests` 可出包;治理文档无残留 token。 + +### M1 — 模板可复制性验证(首个业务模块) +- **依赖**:M0 +- [ ] 按 `docs/coding-standards.md §7` 从界面需求生成:Controller(api 或 controller)→ esb/wsi → pi/impl 或 repository → dao/DTO → SQL(table 双份 + upgrade.xml) +- [ ] 扫描配置核对(`springdoc.packages-to-scan` / `abacus.entitypackages` / `abacus.controllerPackages` 覆盖新包) +- [ ] APP_NAME 四联检 + 前后端 URL 逐字对齐 +- [ ] 多库验证:DDL 在 MySQL 与 SQL Server 均可执行;接口冒烟通 +- **验收**:新业务接口 springdoc 可见、可调用,SQL 双库可执行。 + +### M2 — 沉淀与回写 +- **依赖**:M1 +- [ ] 收集业务开发中的共性需求(分层盲点/框架 jar 能力/规范补缺) +- [ ] 规范盲点回写 `docs/coding-standards.md`(先改 docs/ 再同步各仓库指针) +- [ ] `doc/升级日志.md` 记录模板演进 +- **验收**:模板与规范有可见增量,新业务直接复用。 + +## 3. 并行轨道(与代码 milestone 解耦) + +- 无(CI 等暂不纳入;如团队需要可补充构建门禁脚本到 `.project.agents/scripts/`)。 + +## 4. 完成定义(DoD) + +- 构建通过(`mvn package -Pdev -DskipTests` 无错);涉及多库场景需真机验证。 +- 触及的架构变更已回写 `ARCHITECTURE.md`;共享约束变更先改 `docs/coding-standards.md`。 +- 已写执行日志(`.project.agents/log/YYYY-MM-DD-.md`)并追加 `doc/升级日志.md`。 + +## 5. 跨 milestone 不变量 + +- I1~I4(ARCHITECTURE §1.3):主键走 DaoIdGenerator、SQL 参数化、依赖单向、Controller 不拼响应体。 +- 任何新增包/依赖方向先登记 `ARCHITECTURE.md` 再写代码。 diff --git a/abacus.springboot.example/.project.agents/docs/superpowers/plans/.gitkeep b/abacus.springboot.example/.project.agents/docs/superpowers/plans/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/abacus.springboot.example/.project.agents/docs/superpowers/specs/.gitkeep b/abacus.springboot.example/.project.agents/docs/superpowers/specs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/abacus.springboot.example/.project.agents/log/2026-08-19-ads-governance.md b/abacus.springboot.example/.project.agents/log/2026-08-19-ads-governance.md new file mode 100644 index 0000000..17c27e8 --- /dev/null +++ b/abacus.springboot.example/.project.agents/log/2026-08-19-ads-governance.md @@ -0,0 +1,30 @@ +# 治理体系落地(ADS Retrofit) + +- **日期**:2026-08-19 +- **关联**:ROADMAP M0 +- **会话上下文**:工作区两个参考模板(后端 abacus.springboot.example、前端 abacus-static-framework)此前无 git、无 docs/ 文档中心、无 .project.agents 治理。 + +## 做了什么 + +- 工作区根 `D:\workBuddySpace\member` 建单一 git 仓库 + `.gitignore`。 +- 创建 `docs/` 文档中心(单源化):`README.md`、`architecture.md`、`coding-standards.md`(★前后端开发约束规范)、`agent-guide.md`。 +- 本仓库落地 `.project.agents/`:CLAUDE.md / AGENTS.md / SELF_CONSTRAINTS.md / VIBECODING_GUIDE.md / settings.json / log/README.md + `docs/context/{PRD,ARCHITECTURE,ROADMAP,CONVENTIONS}.md`(无 UIUX,include_uiux=false),全部填充无残留 token。 +- 分层以示例模块实际结构为准(api/controller/dao/esb/pi/impl/repository/wsi/config/util/vo);`util`、`vo` 冻结(可引不可增)。 +- 共享内容以指针引用 `../../../../docs/`,未复制正文;`doc/升级日志.md` 追加 1.0.2(2026-08-19) 治理记录。 +- 分析过程使用 CodeGraph MCP 索引本仓库(82 文件);符号级上下文工具受限,降级为关键文件定向读取。 + +## 提交 + +- 见工作区根 git 提交(docs/ 文档中心、前端治理、后端治理三个原子提交)。 + +## 状态变更 + +- ARCHITECTURE:本仓库 ARCHITECTURE.md 已按实际分层编写;不变量 I1~I4(主键 DaoIdGenerator / SQL 参数化 / 依赖单向 / Controller 不拼响应体)。 +- PRD:已填充(统一响应体/分层模型/多库/动静分离四核心)。 +- 测试:无代码改动,未触发。 + +## 下一步 + +- 按 ROADMAP M1 用第一个业务模块(界面→代码)验证模板可复制性。 +- 待澄清项见 PRD §12(包前缀 / 是否引入后端单测 / util、vo 冻结)。 +- 已知负债:`springdoc-openapi-maven-plugin` apiDocsUrl 硬编码 8080(ARCHITECTURE §8)。 diff --git a/abacus.springboot.example/.project.agents/log/README.md b/abacus.springboot.example/.project.agents/log/README.md new file mode 100644 index 0000000..c2863f8 --- /dev/null +++ b/abacus.springboot.example/.project.agents/log/README.md @@ -0,0 +1,54 @@ +# 实施日志(execution log) + +本目录沉淀"做了什么 + 哪些提交 + 下一步",供下一个会话接手用。 +规则与时机见 `../VIBECODING_GUIDE.md §5`;硬约束见 `../SELF_CONSTRAINTS.md §B6`。 + +--- + +## 文件命名 + +`YYYY-MM-DD-.md` + +- `` = 简短动词 + 范围,kebab-case +- 同日多份按写作顺序加 `-1`、`-2` 后缀 + +## 模板 + +```markdown +# <一句话标题:完成了什么> + +- **日期**:YYYY-MM-DD +- **关联**:ROADMAP M / 子任务名 / 关联文档 +- **会话上下文**:(可选)本会话从哪开始接手的 + +## 做了什么 +- bullet 1 +- bullet 2 + +## 提交 +- `` + +(若本段未提交:明确写"未提交,工作树状态:…"并说明原因) + +## 状态变更 +- ARCHITECTURE:是否动过?动了哪一节? +- PRD:是否触发回归? +- 测试:跑了什么,结果 + +## 下一步 +- 接下来要做的第一件事(具体到任务名) +- 已知阻塞 / 待澄清项 +``` + +## 何时写 + +- 完成一个 ROADMAP milestone +- 完成一个独立可验收的子任务 +- 完成非平凡的重构 / bug 修复 +- 会话即将结束(兜底) + +## 何时不写 + +- 还没完成一个"可独立验收"的部分(别凑数) +- 纯文档微调(commit 自身已够说明) +- 实验性探索且最终 revert(commit 即可) diff --git a/abacus.springboot.example/.project.agents/scripts/.gitkeep b/abacus.springboot.example/.project.agents/scripts/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/abacus.springboot.example/.project.agents/settings.json b/abacus.springboot.example/.project.agents/settings.json new file mode 100644 index 0000000..351f972 --- /dev/null +++ b/abacus.springboot.example/.project.agents/settings.json @@ -0,0 +1,7 @@ +{ + "permissions": { + "allow": [], + "deny": [] + }, + "hooks": {} +} diff --git a/abacus.springboot.example/README.md b/abacus.springboot.example/README.md new file mode 100644 index 0000000..f5fbe40 --- /dev/null +++ b/abacus.springboot.example/README.md @@ -0,0 +1,100 @@ +# abacus.base.demo + +是前后端分离的基于 Spring Boot 的基础项目,作为使用 agent 应用开发前后端项目的**基础模板**。本项目自身不包含业务 Java 代码,业务能力由 abacus 框架(`abacus.config`、`abacus.commons`、`abacus.fundation`、`abacus.business.service` 等)提供,开发者/agent 在本模板上添加业务模块即可。 + + + +## 技术栈 + +| 项 | 说明 | +| --- | --- | +| 构建 | Maven,父工程 `abacus.framework:abacus.springcloud.pom:1.5.0` | +| 框架 | Spring Boot + abacus 系列框架(配置、通用、基础、业务服务) | +| 注册/配置中心 | Nacos(见 `bootstrap.yml`) | +| 数据库 | MySQL / SQL Server / Oracle / 达梦,Druid 连接池 + JPA | +| 定时任务 | XXL-JOB(`application-xxljob.yml`) | +| 消息队列 | Kafka | +| 接口文档 | springdoc(OpenAPI) | +| 监控 | Spring Actuator + Prometheus | + +## 目录结构 + +``` +abacus.base.demo/ +├── pom.xml # Maven 构建配置:依赖、多环境 profile(dev/test/prod)、打包插件 +├── assembly.xml # Maven 发布包(zip)打包规则:jar + doc + sql + html +├── .project / .classpath # Eclipse IDE 工程配置(Java + Maven 项目) +├── .settings/ # Eclipse 偏好配置(编码、JDK、m2e) +├── src/ +│ └── main/ +│ ├── java/ # 【业务代码目录】Java 源码(当前为空,新增业务代码放这里) +│ ├── resources/ +│ │ ├── config/ +│ │ │ ├── dev/ # dev 环境配置(Maven profile 默认激活) +│ │ │ │ ├── application.yml # 主配置:端口、数据源、JPA、Druid、Kafka、springdoc、abacus 扫描路径等 +│ │ │ │ ├── bootstrap.yml # 启动引导配置:应用名、Nacos 注册中心/配置中心 +│ │ │ │ ├── application-xxljob.yml # XXL-JOB 调度中心与执行器配置 +│ │ │ │ ├── logback-spring.xml # 应用日志配置 +│ │ │ │ └── logback-access.xml # 访问日志配置 +│ │ │ ├── test/ # test 环境配置(与 dev 文件同名同结构) +│ │ │ └── prod/ # prod 环境配置(与 dev 文件同名同结构) +│ │ ├── doc/ +│ │ │ └── 升级日志.md # 版本升级日志,按版本记录更新说明 +│ │ ├── sql/ +│ │ │ ├── table/ +│ │ │ │ ├── mysql.sql # MySQL 建表 DDL(示例表 example_category) +│ │ │ │ └── sqlserver.sql # SQL Server 建表 DDL(与 mysql.sql 对应) +│ │ │ ├── data/ +│ │ │ │ └── sqlserver.sql # 初始化数据(acas 子系统/菜单/模块注册) +│ │ │ └── upgrade.xml # 数据库版本升级 SQL 配置(按版本号执行,支持多库语法翻译) +│ │ ├── vue/ # 【Vue 项目源码目录】存放 vue 项目,映射过来的,前后端分离(当前为空) +│ │ └── html/ # 【前端构建产物目录】存放 vue 项目编译后的 html 等静态资源(当前为空,由 assembly.xml 打入发布包) +│ └── (META-INF) # 若存在,会按 pom.xml 配置打入发布包 +└── target/ # Maven 构建输出目录(编译产物、打包 zip,可忽略/删除) +``` + +## 关键配置说明(agent 开发时必须了解) + +### 1. pom.xml +- 多环境 profile:`dev`(默认)/ `test` / `prod`,通过 `-P` 指定,决定加载 `src/main/resources/config//` 下的配置。 +- 打包资源:仅打包 `META-INF`、当前环境 config 目录、`sql/**` 到 jar 内;`doc`、`sql`、`html` 通过 `assembly.xml` 额外打入 zip 发布包。 +- 发布包:`mvn package` 生成 `${artifactId}-${version}-bin.zip`(含 jar + doc + sql + html)。 + +### 2. application.yml(以 dev 为例,三个环境结构一致) +- `server.port`:服务端口(示例 9003)。 +- `spring.datasource`:Druid 数据源;`enableMultiSource` 可开启多数据源(`multidb0~multidb9` 预设 10 个),含 `defaultDB` 默认库、`readDB` 读库、`dynamicRelation` 业务路由配置。 +- `spring.jpa`:JPA/Hibernate 配置,命名策略使用框架的 `LowercaseNamingStrategyStandardImpl`。 +- `spring.kafka`:Kafka 生产/消费配置。 +- `springdoc.packages-to-scan`:在线接口文档扫描的包路径。 +- `abacus.controllerPackages` / `abacus.entitypackages`:**框架扫描 Controller 与实体的包路径,新增业务代码必须将包名加入此配置**(示例包前缀 `abacus.springboot.example`)。 +- `abacus.responseExcludePath`:不被统一响应体包装器拦截的 URI。 +- `management.endpoints.web.base-path`:Actuator 端点基础路径(`/services/actuator`)。 + +### 3. bootstrap.yml +- `spring.application.name`:应用名(示例 `example`),Nacos 中需唯一。 +- `spring.cloud.nacos`:Nacos 服务地址、账号、命名空间;通过 `extension-configs` 引入公共配置(`abacus-discovery.yml`、`abacus-acas.yml`、`abacus-redis.yml` 等)。 + +### 4. sql/ 目录 +- `table/`:建表 DDL,按数据库分文件(mysql.sql / sqlserver.sql),新建业务表需同步维护两个文件。 +- `data/`:初始化数据(子系统、菜单、模块注册,依赖 acas 框架)。 +- `upgrade.xml`:版本化升级 SQL,`` 按版本升序执行;`translator="true"` 时以 SQL Server 语法编写,由框架翻译到各数据库。 + +## 给 agent 的开发约定 + +1. **新增 Java 代码**:放入 `src/main/java`,包名建议以 `abacus.springboot.应用名.*` 为前缀(保持框架扫描配置一致,或同步修改 `application.yml` 中 `abacus.controllerPackages` / `springdoc.packages-to-scan` / `abacus.entitypackages`)。 +2. **新增前端 Vue 项目**:Vue 源码放在 `src/main/resources/vue/`,构建(编译)产物输出到 `src/main/resources/html/`,由 `assembly.xml` 自动打入发布包。 +3. **新增配置项**:优先写入 `src/main/resources/config//application.yml` 对应环境,环境间保持字段一致。 +4. **数据库变更**:建表写 `sql/table/`,历史变更写 `sql/upgrade.xml`,初始化数据写 `sql/data/`。 +5. **文档与日志**:功能更新记录到 `src/main/resources/doc/升级日志.md`。 +6. **打包产物**:`target/` 目录为构建输出,无需维护;发布包为 `target/*-bin.zip`。 +7. **多环境配置**:修改配置时需同步 `dev` / `test` / `prod` 三个目录(或按需仅改某环境)。 +8. **pom.xml**:``建议以`abacus.springboot.应用名`设置 + + + + + + + + + diff --git a/abacus.springboot.example/assembly.xml b/abacus.springboot.example/assembly.xml new file mode 100644 index 0000000..4024f01 --- /dev/null +++ b/abacus.springboot.example/assembly.xml @@ -0,0 +1,41 @@ + + + bin + + + zip + + false + + + + ${project.build.directory} + / + + *.jar + + + *-sources.jar + + + + src/main/resources/doc + doc + + + src/main/resources/sql + sql + + + src/main/resources/html + html + + + + diff --git a/abacus.springboot.example/pom.xml b/abacus.springboot.example/pom.xml new file mode 100644 index 0000000..349f8ed --- /dev/null +++ b/abacus.springboot.example/pom.xml @@ -0,0 +1,235 @@ + + + 4.0.0 + + + abacus.framework + abacus.springcloud.pom + 1.5.0 + + + abacus.springboot.example + 1.0.0 + + abacus.springboot.example + + + + abacus + abacus.config + 2.1.0 + + + org.bouncycastle + bcprov-ext-jdk15 + + + + + + + abacus.framework + abacus.commons + 1.6.5 + + + + + com.alibaba + fastjson + 1.2.83 + + + + + mysql + mysql-connector-java + + + net.sourceforge.jtds + jtds + + + com.microsoft.sqlserver + mssql-jdbc + + + oracle + oracle-jdbc + 11.2.0.3.0 + + + com.xuxueli + xxl-job-core + 2.3.0 + + + + + org.apache.httpcomponents + httpclient + + + commons-httpclient + commons-httpclient + 3.1 + + + org.apache.httpcomponents + httpmime + 4.5 + + + + abacus.framework + abacus.asyncTool + 1.0.0 + + + + + abacus + abacus.fundation + 3.4.4 + + + + + abacus.org.pms + abacus.org.pms.service + 4.3.1 + + + + com.dameng + DmJdbcDriver18 + 8.1.3.140 + + + + + dev + + dev + + + true + + + + test + + test + + + + prod + + prod + + + + + + + META-INF + META-INF + + + + src/main/resources/config/${profiles.active} + + + src/main/resources + + sql/** + + + + + + org.springframework.boot + spring-boot-maven-plugin + + true + + + + + build-info + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.5.4 + + + make-assembly + package + + single + + + ${project.artifactId}-${project.version} + assembly.xml + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + 2.5.6 + + + -Dspring.application.admin.enabled=true + + + + pre-integration-test + + start + + + + post-integration-test + + stop + + + + + + + + org.springdoc + springdoc-openapi-maven-plugin + 1.5 + + + integration-test + + generate + + + + + + http://localhost:8080/v3/api-docs + openapi.json + ${project.build.directory} + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/Application.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/Application.java new file mode 100644 index 0000000..7380c0f --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/Application.java @@ -0,0 +1,58 @@ +package abacus.springboot.example; + +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.impl.client.HttpClientBuilder; +import org.springframework.boot.SpringApplication; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.autoconfigure.domain.EntityScan; +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; +import org.springframework.cloud.openfeign.EnableFeignClients; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.data.jpa.repository.config.EnableJpaRepositories; +import org.springframework.http.client.ClientHttpRequestFactory; +import org.springframework.http.client.HttpComponentsClientHttpRequestFactory; +import org.springframework.web.client.RestTemplate; + +import abacus.commons.responsebody.wrapper.ResultResponseBodyWrapper; + +@SpringBootApplication +@EnableDiscoveryClient +// @EnableHystrix +// 配置扫描 +@ComponentScan(basePackages = { "abacus.springboot.example", "abacus.springboot.example.*" }) +// 指定加载的repository 否则不能加载外部的repository +@EnableJpaRepositories(basePackages = { "abacus.springboot.example.*", }) +// 指定加载的外部entity 否则不能加载外部的entity +@EntityScan(basePackages = { "abacus.springboot.example.*", "com.abacus.pms.*", "com.abacus.xpos.foundation.dao" }) +//指定加载外部Feign +@EnableFeignClients("abacus.springboot.example.feign") +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + + @Bean + public ResultResponseBodyWrapper getResultResponseBodyWrapper() { + return new ResultResponseBodyWrapper(); + } + + @Bean + public RestTemplate getRestTemplate() { + + RequestConfig config = RequestConfig.custom().setConnectTimeout(5000).setSocketTimeout(5000).build(); + + HttpClient httpClient = HttpClientBuilder.create().setDefaultRequestConfig(config).build(); + + ClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient); + + // SimpleClientHttpRequestFactory re = new + // SimpleClientHttpRequestFactory(); + // re.setConnectTimeout(5000); + // re.setReadTimeout(5000); + return new RestTemplate(requestFactory); + + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/JcBillController.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/JcBillController.java new file mode 100644 index 0000000..cb0e3ea --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/JcBillController.java @@ -0,0 +1,1621 @@ +package abacus.springboot.example.api; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.abacus.pms.wsi.ProductServiceIF; +import com.abacus.xpos.foundation.dao.Employee; +import com.abacus.xpos.foundation.pubs.DaoIdGenerator; +import com.abacus.xpos.foundation.wsi.EmployeeServiceIF; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +import abacus.commons.component.http.AbacusRestTemplate; +import abacus.commons.exception.BusinessException; +import abacus.commons.standard.util.FileUtil; +import abacus.config.dao.AbacusConfigItem; +import abacus.springboot.example.api.view.ApiBillHg; +import abacus.springboot.example.api.view.ApiBillHgId; +import abacus.springboot.example.api.view.ApiBillHgItem; +import abacus.springboot.example.api.view.ApiBillHgPayment; +import abacus.springboot.example.api.view.ApiJcBill; +import abacus.springboot.example.api.view.ApiJcBillCollect; +import abacus.springboot.example.api.view.ApiJcBillGoodsPhoto; +import abacus.springboot.example.api.view.ApiJcBillHgSearch; +import abacus.springboot.example.api.view.ApiJcBillHgSearchItem; +import abacus.springboot.example.api.view.ApiJcBillItem; +import abacus.springboot.example.api.view.ApiJcBillSearch; +import abacus.springboot.example.api.view.ApiReqJcBill; +import abacus.springboot.example.api.view.ApiReqJcBillGoodsPhoto; +import abacus.springboot.example.api.view.ApiReqJcBillHg; +import abacus.springboot.example.api.view.ApiReqJcBillItem; +import abacus.springboot.example.api.view.ApiReqJcBillPayment; +import abacus.springboot.example.api.view.ApiReqJcBillPhoto; +import abacus.springboot.example.api.view.ApiReqJcBillPhotoItem; +import abacus.springboot.example.api.view.ApiRespBillHgPay; +import abacus.springboot.example.api.view.ApiRespJcPorduct; +import abacus.springboot.example.api.view.ApiRespJcPorductAcount; +import abacus.springboot.example.api.view.ApiRespJcPorductItem; +import abacus.springboot.example.api.view.ApiRespJcPorductProduct; +import abacus.springboot.example.api.view.ApiRespReceiveGoods; +import abacus.springboot.example.api.view.ApiRespWarehouse; +import abacus.springboot.example.api.view.EdgBcsCode; +import abacus.springboot.example.api.view.JcBillCount; +import abacus.springboot.example.api.view.JcCodeFlow; +import abacus.springboot.example.api.view.JcProduct; +import abacus.springboot.example.api.view.JcProductBillSouce; +import abacus.springboot.example.config.JcConfigKey; +import abacus.springboot.example.controller.BaseServlet; +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillHg; +import abacus.springboot.example.dao.JcBillHgPay; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.dao.JcSourceItem; +import abacus.springboot.example.pi.AutoCompleteAccessIF; +import abacus.springboot.example.util.DateUtil; +import abacus.springboot.example.esb.JcBillBizService; +import abacus.springboot.example.wsi.ApiJcBillServiceIF; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; + +/** + *

Title:JcBillController

+

Description: 对外接口

+ @author chuanZeng + @date 2026年8月18日 + */ +@RestController +@RequestMapping(value = "/3.0/jc") +@Tag(name="稽查接口服务", description="稽查接口服务说明") +public class JcBillController extends BaseServlet{ + + private static final Logger LOG = LoggerFactory.getLogger(JcBillController.class); + + @Autowired + private ApiJcBillServiceIF apiJcBillService; + + @Autowired + private DaoIdGenerator jcBillIdGenerator; + + @Autowired + private ProductServiceIF productService; + + @Autowired + private EmployeeServiceIF employeeService; + + @Autowired + private AutoCompleteAccessIF autoCompleteAccess; + + @Autowired + private JcBillBizService jcBillBizService; + + // TODO 百度通用文字识别和二维码识别 + @RequestMapping(value="recogInterface", method = RequestMethod.POST) + @Operation(summary="百度通用文字识别和二维码识别") + @Parameters({ + @Parameter(name="imageUrl", required = false, description="HTTP URL地址", schema = @Schema(pattern = "", defaultValue=""), example="HTTP:IP/1.PNG"), + }) + public JSONObject recogInterface(@RequestParam String imageUrl) + throws Exception { + try { + String bdurl = this.getConfigValue("si.baidu.url"); +// String appid = this.getConfigValue("si.baidu.appid"); +// String apikey = this.getConfigValue("si.baidu.apikey"); +// String secretkey = this.getConfigValue("si.baidu.secretkey"); + + String token = apiJcBillService.getBaiduToken(); + + if(StringUtils.isBlank(token)) throw new BusinessException("百度token没有获取!"); + + AbacusRestTemplate art = new AbacusRestTemplate(); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + // 创建MultiValueMap对象并添加表单数据 + MultiValueMap params = new LinkedMultiValueMap<>(); + params.add("url", imageUrl); + + // 创建HttpEntity对象 + HttpEntity> requestEntity = new HttpEntity<>(params, headers); + + // 同用文字识别 + ResponseEntity resultOcr = art.restTemplate().postForEntity(bdurl + "/rest/2.0/ocr/v1/accurate_basic?access_token=" + token, requestEntity, String.class); + + ResponseEntity resultQrcode = art.restTemplate().postForEntity(bdurl + "/rest/2.0/ocr/v1/qrcode?access_token=" + token, requestEntity, String.class); + + JSONObject obj = new JSONObject(); + obj.put("OCR", JSONObject.parse(resultOcr.getBody())); + obj.put("qrcode", JSONObject.parse(resultQrcode.getBody())); + return obj; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 稽查收货查询 + @RequestMapping(value="getJcBillSearch", method = RequestMethod.GET) + @Operation(summary="稽查收货查询") + @Parameters({ + @Parameter(name="keyword", required = false, description="搜索内容(稽查单号货收货产品、货品编号模糊搜索)", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001"), + @Parameter(name="employee", required = false, description="员工编码", schema = @Schema(pattern = "", defaultValue=""), example="0"), + @Parameter(name="status", required = false, description="状态", schema = @Schema(pattern = "溯源驳回:-2,待提交:0,待溯源:2,待入库:3,已入库:5 ,回购通知:6,出库:8", defaultValue=""), example="1"), + @Parameter(name="page", required = false, description="页数", schema = @Schema(pattern = "", defaultValue="1"), example="1"), + @Parameter(name="size", required = false, description="每页显示的条数", schema = @Schema(pattern = "", defaultValue="10"), example="10") + }) + public ApiJcBillCollect getJcBillSearch( + @RequestParam(required = false) String keyword, + @RequestParam(required = false) String employee, + @RequestParam(required = false) String status, + @RequestParam(required = false) String page, + @RequestParam(required = false) String size + ) throws Exception{ + try { + LOG.info("稽查收货查询>>>keyword>>>{}, employee>>>{}, status>>>{}, page>>>{}, size>>>{}, 处理开始", keyword, employee, status, page, size); + long time0 = System.currentTimeMillis(); + + // 页数默认为:1 + Integer pageNumber = 1; + if(StringUtils.isNotBlank(page)) { + pageNumber = Integer.parseInt(page); + } + + // 每页显示的条数默认为:10 + Integer pageSize = 10; + if(StringUtils.isNotBlank(size)) { + pageSize = Integer.parseInt(size); + } + + // 当前页 + Pageable pageable = PageRequest.of(pageNumber - 1, pageSize); + long time1 = System.currentTimeMillis(); + Page pageLists = apiJcBillService.queryApiJcBillSearch(keyword, employee, status, pageable); + long time2 = System.currentTimeMillis(); + LOG.info("稽查收货查询>>>queryApiJcBillSearch查询耗时>>>{}", (time2 - time1)); + + for(ApiJcBillSearch jcBill : pageLists.getContent()) { + if (jcBill.getHgstatus() == 1) jcBill.setStatus(JcBill.STATUS_SIX); + else if (jcBill.getHgstatus() == 2) jcBill.setStatus(JcBill.STATUS_SEVEN); + } + + if("8".equals(status)) {// 出库状态 + + // 获取稽查单号集合 + List billIds = pageLists.getContent().stream() + .map(ApiJcBillSearch::getBillid) + .collect(Collectors.toList()); + + List hgs = apiJcBillService.qeryJcBillHgs(billIds); + + Map> mapHgs = hgs.stream() + .collect(Collectors.groupingBy(e -> { + return e.getBillid(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + Map mapBillStatus = new HashMap(); + for(String key : mapHgs.keySet()) { + List billHgs = mapHgs.get(key); + + // 是否全部出库 + boolean hgFale = true; + for(JcBillHg billHg : billHgs) { + if(billHg.getStatus() == 5 || billHg.getStatus() == 4 || billHg.getStatus() == 3 + || billHg.getStatus() == 2 || billHg.getStatus() == 1) { + hgFale = false; + continue; + } + } + + if(hgFale) mapBillStatus.put(key, 9); + else mapBillStatus.put(key, 8); + } + + for(ApiJcBillSearch jcBill : pageLists.getContent()) { + + if(mapBillStatus.containsKey(jcBill.getBillid())) { + Integer ckStatus = mapBillStatus.get(jcBill.getBillid()); + if (jcBill.getStatus() == JcBill.STATUS_SIX) { + jcBill.setStatus(8); + } else if (jcBill.getStatus() == JcBill.STATUS_SEVEN) { + jcBill.setStatus(ckStatus); + } + } + } + } + + + + ApiJcBillCollect abc = new ApiJcBillCollect(); + abc.setTotal(pageLists.getTotalElements()); + abc.setTotalPages(pageLists.getTotalPages()); + abc.setBills(pageLists.getContent()); + + long time3 = System.currentTimeMillis(); + LOG.info("稽查收货查询>>>总耗时>>>{}", (time3 - time0)); + + return abc; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 稽查收货订单详情查询 + @RequestMapping(value="getJcBillDetails", method = RequestMethod.GET) + @Operation(summary="稽查收货订单详情查询") + @Parameters({ + @Parameter(name="billId", required = true, description="稽查单号", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001") + }) + public ApiJcBill getJcBillDetails( + @RequestParam(required = false) String billId + ) throws Exception{ + try { + if(StringUtils.isBlank(billId)) throw new BusinessException("稽查单号不能为空!"); + + LOG.info("稽查收货订单详情查询>>>billId>>>{}, 处理开始", billId); + long time0 = System.currentTimeMillis(); + + ApiJcBill bill = apiJcBillService.queryApiJcBillById(billId); + long time1 = System.currentTimeMillis(); + LOG.info("稽查收货订单详情查询>>>queryApiJcBillById查询耗时>>>{}", (time1 - time0)); + + List sourceItems = apiJcBillService.queryJcBillSourceItemByBillId(billId); + long time2 = System.currentTimeMillis(); + LOG.info("稽查收货订单详情查询>>>queryJcBillSourceItemByBillId查询耗时>>>{}", (time2 - time1)); + + if(sourceItems != null) { + Map> mapPhoto = apiJcBillService.queryJcBillPhoto(billId); + long time3 = System.currentTimeMillis(); + LOG.info("稽查收货订单详情查询>>>queryJcBillPhoto查询耗时>>>{}", (time3 - time2)); + + Map> map = sourceItems.stream() + .collect(Collectors.groupingBy(e -> { + return String.valueOf(e.getIndexno()); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + List billItems = new ArrayList(); + ApiJcBillItem billItem = null; + boolean flagStaus = true; + List goodsPhotos = null; + // 解析图片+明细 + for(String key : map.keySet()) { + billItem = new ApiJcBillItem(); + List temps = map.get(key); + JcBillSourceItem temp = null; + + // 汇总数量 + BigDecimal quantityBig = new BigDecimal("0"); + // 汇总件数 + BigDecimal numbersBig = new BigDecimal("0"); + // 汇总金额 +// BigDecimal subtotalBig = new BigDecimal("0"); + + goodsPhotos = new ArrayList(); + ApiJcBillGoodsPhoto goodsPhoto = null; + for(JcBillSourceItem item : temps) { + temp = item; + + // 货品图 + List hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(item.getIndexno()) + "#" + String.valueOf(item.getGoodsid())); + List hptList = new ArrayList(); + if(hpts != null && hpts.size() >= 1) { + for(JcBillPhoto hpt : hpts) { + hptList.add(hpt.getUrlphoto()); + } + } + + // 汇总 + quantityBig = quantityBig.add(new BigDecimal(String.valueOf(item.getQuantity()))); + numbersBig = numbersBig.add(new BigDecimal(String.valueOf(item.getNumbers()))); +// subtotalBig = subtotalBig.add(new BigDecimal(String.valueOf(item.getSubtotal()))); + + // 图片 + goodsPhoto = new ApiJcBillGoodsPhoto(); + goodsPhoto.setId(item.getId()); + goodsPhoto.setStatus(item.getStatus()); + goodsPhoto.setGoodsid(item.getGoodsid()); + goodsPhoto.setLogisticsid(item.getLogisticsid()); + goodsPhoto.setGoodsPhotos(hptList); + goodsPhoto.setReason(item.getReason()); + + if(item.getStatus() == 0) { + flagStaus = false; + } + + goodsPhotos.add(goodsPhoto); + } + + // 稽查付款截图 + List fkts = mapPhoto.get(JcBillPhoto.JC_FK + "#" + String.valueOf(temp.getIndexno())); + if(fkts != null && fkts.size() >= 1) { + List fkList = new ArrayList(); + + for(JcBillPhoto fkt : fkts) { + fkList.add(fkt.getUrlphoto()); + } + + billItem.setPaymentPhoto(fkList); + } + + + billItem.setId(temp.getId()); + billItem.setIndexno(temp.getIndexno()); + billItem.setRecsource(temp.getRecsource()); + billItem.setChannel(temp.getChannel()); + billItem.setRecplatform(temp.getRecplatform()); + billItem.setPrice(temp.getPrice()); + billItem.setQuantity(quantityBig.doubleValue()); + billItem.setNumbers(numbersBig.doubleValue()); + billItem.setSubtotal(temp.getSubtotal()); + billItem.setGoodsPhotos(goodsPhotos); + + billItems.add(billItem); + } + + if(bill.getStatus() <= 1) { + if(bill.getStatus() == -2) { + bill.setStatus(JcBill.STATUS_MINUS_TWO); + } else { + if(flagStaus) { + bill.setStatus(JcBill.STATUS_ONE); + } + } + } + + bill.setItems(billItems); + } + + long time4 = System.currentTimeMillis(); + LOG.info("稽查收货订单详情查询>>>总耗时>>>{}>>>{}", (time4 - time0), JSON.toJSONString(bill)); + + return bill; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 稽查收货-删除订单详情 + @RequestMapping(value="deleteJcBillDetails", method = RequestMethod.GET) + @Operation(summary="稽查收货删除订单详情") + @Parameters({ + @Parameter(name="billId", required = true, description="稽查单号", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001"), + @Parameter(name="itemid", required = true, description="稽查明细单号", schema = @Schema(pattern = "", defaultValue=""), example="1") + }) + public void deleteJcBillDetails( + @RequestParam(required = false) String billId, + @RequestParam(required = false) String itemid + ) throws Exception{ + try { + if(StringUtils.isBlank(billId)) throw new BusinessException("参数[billId]为空!"); + if(StringUtils.isBlank(itemid)) throw new BusinessException("参数[itemid]为空!"); + + LOG.info("稽查收货删除订单详情>>>billInfo:{},itemid:{},处理开始", billId, itemid); + long time0 = System.currentTimeMillis(); + + apiJcBillService.deleteJcSourceItem(billId, itemid); + + long time4 = System.currentTimeMillis(); + LOG.info("稽查收货删除订单详情>>>总耗时>>>{}", (time4 - time0)); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 稽查收货订单保存 + @RequestMapping(value="createJcBill", method = RequestMethod.POST) + @Operation(summary="稽查收货订单保存") + @Parameters({ + @Parameter(name="billInfo", required = true, description="稽查收货JSONObject", schema = @Schema(implementation = ApiReqJcBill.class)) + }) + public ApiReqJcBill createJcBill( + @RequestParam(required = false) String billInfo + ) throws Exception{ + try { + if(StringUtils.isBlank(billInfo)) throw new BusinessException("参数[billInfo]为空!"); + + LOG.info("稽查收货订单保存>>>billInfo:{},处理开始", billInfo); + long time0 = System.currentTimeMillis(); + + ApiReqJcBill reqJcBill = JSON.parseObject(billInfo, ApiReqJcBill.class); + + if(StringUtils.isBlank(reqJcBill.getApplicant()) || StringUtils.isBlank(reqJcBill.getApplicantname())) + throw new BusinessException("参数[applicant]或[applicantname]为空!"); + + + if(StringUtils.isBlank(reqJcBill.getId())) jcBillBizService.saveJcBill(reqJcBill); + else jcBillBizService.updateJcbill(reqJcBill); + + long time1 = System.currentTimeMillis(); + LOG.info("稽查收货订单保存>>>总耗时>>>{}", (time1 - time0)); + + return reqJcBill; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 验证溯源 + @RequestMapping(value="checkSource", method = RequestMethod.POST) + @Operation(summary="验证溯源") + @Parameters({ + @Parameter(name="billId", required = true, description="稽查单号", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001") + }) + public List checkSource( + @RequestParam(required = false) String billId + ) throws Exception{ + try { + if(StringUtils.isBlank(billId)) throw new BusinessException("稽查单号不能为空!"); + + LOG.info("验证溯源>>>billId>>>{}, 处理开始", billId); + long time0 = System.currentTimeMillis(); + + JcBill jcBill = apiJcBillService.queryJcBillById(billId); + long time01 = System.currentTimeMillis(); + LOG.info("验证溯源>>>queryJcBillById耗时>>>{}", (time01 - time0)); + + if(jcBill == null) throw new BusinessException("无收记录信息!"); + + List items = apiJcBillService.queryJcBillSourceItemByBillId(billId); + long time1 = System.currentTimeMillis(); + LOG.info("验证溯源>>>queryJcBillSourceItemByBillId耗时>>>{}", (time1 - time01)); + + if(items == null) throw new BusinessException("无收货信息!"); + + // 获取物流码集合 + List codes = new ArrayList<>(); + for(JcBillSourceItem item : items) { + if(StringUtils.isNotBlank(item.getLogisticsid())) { + codes.add(item.getLogisticsid()); + } + } + + List sourceItems = new ArrayList(); + if(codes != null && codes.size() >= 1) { + long time2 = System.currentTimeMillis(); + List jcCodeFlows = apiJcBillService.queryJcCodeFlow(codes); + long time3 = System.currentTimeMillis(); + LOG.info("验证溯源>>>queryJcCodeFlow耗时>>>{}", (time3 - time2)); + + List edgBcsCodes = edgopenapiBcscode(codes); + long time4 = System.currentTimeMillis(); + LOG.info("验证溯源>>>物流码溯源查询耗时>>>{}", (time4 - time3)); + + + JcSourceItem sourceItem = null; + JcSourceItem sourceItem2 = null; + + for(JcBillSourceItem item : items) { + String key_code = item.getLogisticsid(); + + // 是否只有一个出库单号 + boolean billFlage = true; + // 是否溯源成功 + boolean flage = false; + + + String billouts = null, billout = null, billoutdt = null, billoutwh = null, billoutwhname = null, + product = null, productname = null, account = null, accountname = null, + operator = null, operatorname = null, groupid = null, groupname = null, + salearea = null, saleareaname = null, source = null; + // 二维码来源 + if(edgBcsCodes != null && edgBcsCodes.size() >= 1) { + for(EdgBcsCode bcsCode : edgBcsCodes) { + if(key_code.equals(bcsCode.getCode())) { + flage = true; + + if(StringUtils.isBlank(billouts)) { + billouts = bcsCode.getCk_id(); + } else { + billouts += "," + bcsCode.getCk_id(); + } + + billout = bcsCode.getCk_id(); + billoutdt = bcsCode.getCdt(); + billoutwh = bcsCode.getDccw_id(); + billoutwhname = bcsCode.getDccw_name(); + product = bcsCode.getProductid(); + productname = bcsCode.getProductname(); + account = bcsCode.getCustomerid(); + accountname = bcsCode.getCustomername(); + operator = bcsCode.getEmployeeid(); + operatorname = bcsCode.getEmployeename(); + groupid = bcsCode.getGroup_id(); + groupname = bcsCode.getGroup_name(); + salearea = bcsCode.getDepartmentid(); + saleareaname = bcsCode.getDepartmentname(); + source = JcBillSourceItem.SOURCE_EWM; + + sourceItem = new JcSourceItem(); + sourceItem.setStatus(JcSourceItem.STATUS_ZERO); + sourceItem.setBillid(billId); + sourceItem.setSrcitemid(String.valueOf(item.getId())); + sourceItem.setGoodsid(item.getGoodsid()); + sourceItem.setLogisticsid(item.getLogisticsid()); + sourceItem.setBillout(billout); + sourceItem.setBilloutdt(DateUtil.toDateTime(billoutdt)); + sourceItem.setBilloutwh(billoutwh); + sourceItem.setBilloutwhname(billoutwhname); + sourceItem.setProduct(product); + sourceItem.setProductname(productname); + sourceItem.setAccount(account); + sourceItem.setAccountname(accountname); + sourceItem.setOperator(operator); + sourceItem.setOperatorname(operatorname); + sourceItem.setGroupid(groupid); + sourceItem.setGroupname(groupname); + sourceItem.setSalearea(salearea); + sourceItem.setSaleareaname(saleareaname); + sourceItem.setSource(source); + sourceItem.setDt(new Date()); + + sourceItems.add(sourceItem); + } + } + } + + // 业务中台 + if(jcCodeFlows != null && jcCodeFlows.size() >= 1) { + for(JcCodeFlow codeFlow : jcCodeFlows) { + + if(key_code.equals(codeFlow.getCode())) { + flage = true; + + if(StringUtils.isBlank(billouts)) { + billouts = codeFlow.getId(); + } else { + billouts += "," + codeFlow.getId(); + } + + billout = codeFlow.getId(); + billoutdt = codeFlow.getTdate(); + billoutwh = codeFlow.getDeposit(); + billoutwhname = codeFlow.getDepositname(); + product = codeFlow.getProductid(); + productname = codeFlow.getProductname(); + account = codeFlow.getCustomerid(); + accountname = codeFlow.getCustomername(); + operator = codeFlow.getAprssalemanid(); + operatorname = codeFlow.getAprssalemanname(); + groupid = codeFlow.getBizgroupid(); + groupname = codeFlow.getBizgroupname(); + salearea = codeFlow.getWsareaid(); + saleareaname = codeFlow.getWsareaname(); + source = JcBillSourceItem.SOURCE_ERP; + + sourceItem2 = new JcSourceItem(); + sourceItem2.setStatus(JcSourceItem.STATUS_ZERO); + sourceItem2.setBillid(billId); + sourceItem2.setSrcitemid(String.valueOf(item.getId())); + sourceItem2.setGoodsid(item.getGoodsid()); + sourceItem2.setLogisticsid(item.getLogisticsid()); + sourceItem2.setBillout(billout); + sourceItem2.setBilloutdt(DateUtil.toDateTime(billoutdt)); + sourceItem2.setBilloutwh(billoutwh); + sourceItem2.setBilloutwhname(billoutwhname); + sourceItem2.setProduct(product); + sourceItem2.setProductname(productname); + sourceItem2.setAccount(account); + sourceItem2.setAccountname(accountname); + sourceItem2.setOperator(operator); + sourceItem2.setOperatorname(operatorname); + sourceItem2.setGroupid(groupid); + sourceItem2.setGroupname(groupname); + sourceItem2.setSalearea(salearea); + sourceItem2.setSaleareaname(saleareaname); + sourceItem2.setSource(source); + sourceItem2.setDt(new Date()); + + sourceItems.add(sourceItem2); + } + } + } + + if(flage) { + item.setStatus(JcBillSourceItem.STATUS_ONE); + } else { + item.setStatus(JcBillSourceItem.STATUS_MINUS_ONE); + } + + if(StringUtils.isNotBlank(billouts)) item.setBillout(billouts); + if(StringUtils.isNotBlank(billoutdt)) item.setBilloutdt(DateUtil.toDateTime(billoutdt)); + if(StringUtils.isNotBlank(billoutwh)) item.setBilloutwh(billoutwh); + if(StringUtils.isNotBlank(billoutwhname)) item.setBilloutwhname(billoutwhname); + if(StringUtils.isNotBlank(product)) item.setProduct(product); + if(StringUtils.isNotBlank(productname)) item.setProductname(productname); + if(StringUtils.isNotBlank(account)) item.setAccount(account); + if(StringUtils.isNotBlank(accountname)) item.setAccountname(accountname); + if(StringUtils.isNotBlank(operator)) item.setOperator(operator); + if(StringUtils.isNotBlank(operatorname)) item.setOperatorname(operatorname); + if(StringUtils.isNotBlank(groupid)) item.setGroupid(groupid); + if(StringUtils.isNotBlank(groupname)) item.setGroupname(groupname); + if(StringUtils.isNotBlank(salearea)) item.setSalearea(salearea); + if(StringUtils.isNotBlank(saleareaname)) item.setSaleareaname(saleareaname); + if(StringUtils.isNotBlank(source)) item.setSource(source); + + } + } else { + for(JcBillSourceItem item : items) { + item.setStatus(JcBillSourceItem.STATUS_MINUS_ONE); + } + } + + long time5 = System.currentTimeMillis(); + apiJcBillService.saveJcSourceItem(items, sourceItems, jcBill); + long time00 = System.currentTimeMillis(); + LOG.info("验证溯源>>>saveJcSourceItem耗时>>>{}", (time00 - time5)); + + LOG.info("验证溯源>>>总耗时>>>{}", (time00 - time0)); + + return items; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 调第三方接口查询,物流码溯源查询 + * @param codes + * @return + * @throws Exception + */ + public List edgopenapiBcscode(List logisticss) throws Exception{ + try { + long time0 = System.currentTimeMillis(); + List codes = new ArrayList(); + // 取对应连接后32位,生成溯源码 + for(String logistics : logisticss) { + String[] codeArray = logistics.split("/"); + + String code = codeArray[codeArray.length - 1]; + + if(StringUtils.isNotBlank(code)) codes.add(code); + } + + String rzUrl = getConfigValue("pms.rzUrl"); + String param_appkey = getConfigValue("pms.edg_appkey"); + String param_appsecret = getConfigValue("pms.edg_appsecret"); + String bcscodeUrl = rzUrl + "/edgopenapi/services/bcscode"; + String getTokenUrl = rzUrl + getConfigValue("pms.rztokenUrl") + "?EDG-APPKEY=" + param_appkey + "&EDG-APPSECRET=" + param_appsecret; + + long time1 = System.currentTimeMillis(); + LOG.info("验证溯源>>>edgopenapiBcscode>>>接口配置参数耗时>>>{}", (time1 - time0)); + + String result = null, token=null; + + AbacusRestTemplate art = new AbacusRestTemplate(); + + // 获取token + result = art.restTemplate().getForObject(getTokenUrl, String.class); + + if(result != null && !result.equals("")){ + JSONObject json = JSONObject.parseObject(result); + token = json.getJSONObject("data").getString("token"); + } + long time2 = System.currentTimeMillis(); + LOG.info("验证溯源>>>edgopenapiBcscode>>>接口token获取耗时>>>{}", (time2 - time1)); + + if (token != null) { + // 请求头 + String header_token = "EDAPI-TOKEN"; + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set(header_token, token); + + JSONObject requestJsonObj = new JSONObject(); + JSONObject bodyJsonObj = new JSONObject(); + bodyJsonObj.put("code", codes); + bodyJsonObj.put("$query-page-size","100"); + bodyJsonObj.put("$query-page-index",1); + requestJsonObj.put("request", bodyJsonObj); + + // 设置body,headers + HttpEntity requestEntity = new HttpEntity(requestJsonObj.toString(), headers); + + // 物流码溯源查询 + result = art.restTemplate().postForObject(bcscodeUrl, requestEntity, String.class); + long time3 = System.currentTimeMillis(); + LOG.info("验证溯源>>>edgopenapiBcscode>>>物流码溯源查询耗时>>>{}", (time3 - time2)); + + JSONObject rq = JSONObject.parseObject(result); + + if(rq.getString("retcode").equals("EDAC-200")) { + + JSONArray jsonArrays = rq.getJSONObject("response").getJSONArray("$data-detail"); + + if(!jsonArrays.isEmpty()){ + + List edgBcsCodes = JSONArray.parseArray(jsonArrays.toJSONString(), EdgBcsCode.class); + +// Map map = edgBcsCodes.stream() +// .collect(Collectors.groupingBy(e -> { +// return e.getCode(); +// }, +// Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)) +// )); + + return edgBcsCodes; + } else { + return null; + } + } else { + throw new BusinessException("睿治物流码溯源查询接口(" + bcscodeUrl + "),返回异常:" + rq.getString("msg")); + } + } else { + throw new BusinessException("睿治token未获取到,无法调用物流码溯源查询接口!"); + } + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 提交溯源 + @RequestMapping(value="submitSource", method = RequestMethod.POST) + @Operation(summary="提交溯源") + @Parameters({ + @Parameter(name="billId", required = true, description="稽查单号", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001") + }) + public void submitSource( + @RequestParam(required = false) String billId + ) throws Exception{ + try { + if(StringUtils.isBlank(billId)) throw new BusinessException("参数[billId]为空!"); + + LOG.info("提交溯源>>>billId:{},处理开始", billId); + long time0 = System.currentTimeMillis(); + + JcBill bill = apiJcBillService.queryJcBillById(billId); + long time1 = System.currentTimeMillis(); + LOG.info("提交溯源>>>queryJcBillById耗时>>>{}", (time1 - time0)); + + if(bill == null) throw new BusinessException("稽查单号:" + billId + ",未查询到稽查单"); + + // 状态 + int oldStatus = bill.getStatus(); + + List sourceItems = apiJcBillService.queryJcBillSourceItemByBillId(billId); + long time2 = System.currentTimeMillis(); + LOG.info("提交溯源>>>queryJcBillSourceItemByBillId耗时>>>{}", (time2 - time1)); + + if(sourceItems == null) throw new BusinessException("稽查单号:" + billId + ",未查询到稽查收货信息"); + + Map> mapPhto = apiJcBillService.queryJcBillPhoto(billId); + long time3 = System.currentTimeMillis(); + LOG.info("提交溯源>>>queryJcBillPhoto耗时>>>{}", (time3 - time2)); + + if(mapPhto == null) throw new BusinessException("稽查单号:" + billId + ",未查询到稽查收货货品图货收款图信息"); + + if(StringUtils.isBlank(bill.getGoods())) throw new BusinessException("收货产品,不能为空!"); + if(StringUtils.isBlank(bill.getReceivedt())) throw new BusinessException("收货日期,不能为空!"); + if(StringUtils.isBlank(bill.getWarehouse())) throw new BusinessException("收货仓库,不能为空!"); + + for(JcBillSourceItem item : sourceItems) { + if(StringUtils.isBlank(item.getRecsource())) throw new BusinessException("收货来源,不能为空!"); +// if(StringUtils.isBlank(item.getRecplatform())) throw new BusinessException("收货平台,不能为空!"); + if(StringUtils.isBlank(item.getChannel())) throw new BusinessException("收货渠道,不能为空!"); + if(item.getPrice() <= 0) throw new BusinessException("收货单价,不能小于等于0!"); + + if(item.getQuantity() <= 0) throw new BusinessException("收货数量,不能小于等于0!"); + if(item.getNumbers() <= 0) throw new BusinessException("收货件数,不能小于等于0!"); + if(item.getSubtotal() <= 0) throw new BusinessException("收货金额,不能小于等于0!"); + + if(StringUtils.isBlank(item.getGoodsid())) throw new BusinessException("货品编号,不能为空!"); +// if(StringUtils.isBlank(item.getLogisticsid())) throw new BusinessException("物流码,不能为空!"); + + if(item.getStatus() == JcBillSourceItem.STATUS_ZERO) throw new BusinessException("货品编号:" + item.getGoodsid() + ",系统溯源未验证!"); + + String fkt = JcBillPhoto.JC_FK + "#" + item.getIndexno(); + if(!mapPhto.containsKey(fkt)) throw new BusinessException("付款图未上传!"); + + String hpt = JcBillPhoto.JC_HP + "#" + item.getIndexno() + "#" + item.getGoodsid(); + if(!mapPhto.containsKey(hpt)) throw new BusinessException("货品图未上传!"); + } + + bill.setStatus(JcBill.STATUS_TWO); + + long time4 = System.currentTimeMillis(); + apiJcBillService.updateStatusJcBill(bill, oldStatus); + long time5 = System.currentTimeMillis(); + LOG.info("提交溯源>>>updateStatusJcBill耗时>>>{}", (time5 - time4)); + + LOG.info("提交溯源>>>总耗时>>>{}", (time5 - time0)); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 回购列表查询 + @RequestMapping(value="getJcBillHgSearch", method = RequestMethod.GET) + @Operation(summary="回购列表查询") + @Parameters({ + @Parameter(name="keyword", required = false, description="搜索内容(回购/稽查单号/客户名称/编码/收货人手机号/商品名称)", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001"), + @Parameter(name="employee", required = false, description="员工编码", schema = @Schema(pattern = "", defaultValue=""), example="0"), + @Parameter(name="status", required = false, description="状态", schema = @Schema(pattern = "待提交:1,待付款:2,待分仓:3,待出库:5,已出库:6 ", defaultValue=""), example="1"), + @Parameter(name="page", required = false, description="页数", schema = @Schema(pattern = "", defaultValue="1"), example="1"), + @Parameter(name="size", required = false, description="每页显示的条数", schema = @Schema(pattern = "", defaultValue="10"), example="10") + }) + public ApiJcBillHgSearch getJcBillHgSearch( + @RequestParam(required = false) String keyword, + @RequestParam(required = false) String employee, + @RequestParam(required = false) String status, + @RequestParam(required = false) String page, + @RequestParam(required = false) String size + ) throws Exception{ + try { + LOG.info("回购列表查询>>>keyword>>>{}, employee>>>{}, status>>>{}, page>>>{}, size>>>{}, 处理开始", keyword, employee, status, page, size); + long time0 = System.currentTimeMillis(); + + // 页数默认为:1 + Integer pageNumber = 1; + if(StringUtils.isNotBlank(page)) { + pageNumber = Integer.parseInt(page); + } + + // 每页显示的条数默认为:10 + Integer pageSize = 10; + if(StringUtils.isNotBlank(size)) { + pageSize = Integer.parseInt(size); + } + + // 当前页 + Pageable pageable = PageRequest.of(pageNumber - 1, pageSize); + + long time1 = System.currentTimeMillis(); + Page pageLists = apiJcBillService.queryApiJcBillHgSearchItem(keyword, employee, status, pageable); + long time2 = System.currentTimeMillis(); + LOG.info("回购列表查询>>>queryApiJcBillHgSearchItem查询耗时>>>{}", (time2 - time1)); + + // 获取回购订单的集合 + List ids = new ArrayList(); + for(ApiJcBillHgSearchItem item : pageLists) { + if(StringUtils.isNotBlank(item.getBillHg())) { + ids.add(item.getBillHg()); + } + } + + long time3 = System.currentTimeMillis(); + Map mapCounts = apiJcBillService.queryJcBillCount(ids); + long time4 = System.currentTimeMillis(); + LOG.info("回购列表查询>>>queryJcBillCount查询耗时>>>{}", (time4 - time3)); + + // 回购相关图片 + Map> mapPhoto = apiJcBillService.queryJcBillPhotoIn(ids); + long time5 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryJcBillPhotoIn查询耗时>>>{}", (time5 - time4)); + +// String erpUrl = getConfigValue(JcConfigKey.KEY_JC_ERP_URL); + long time6 = System.currentTimeMillis(); +// LOG.info("回购订单详情查询>>>getConfigValue查询耗时>>>{}", (time6 - time5)); + + List payments = apiJcBillService.queryApiBillHgPaymentByHgId(ids); + long time7 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryApiBillHgPaymentByHgId查询耗时>>>{}", (time7 - time6)); + + Map> paymentsMap = new HashMap>(); + if(payments != null && payments.size() >= 1) { + paymentsMap = payments.stream() + .collect(Collectors.groupingBy(e -> { + return e.getBillhg(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + } + + + for(ApiJcBillHgSearchItem item : pageLists.getContent()) { + String billHg = item.getBillHg(); + + JcBillCount count = mapCounts.get(billHg); + if(count != null) { + item.setBreednum(count.getBreednum()); + item.setNumbers(count.getNumbers()); + } + + // 回购通知函 + String tzh_key = JcBillPhoto.HG_TZH + "#" + billHg; + List tzh = mapPhoto.get(tzh_key); + + // 回购违规通知函 + String wgtzh_key = JcBillPhoto.HG_WGTZH + "#" + billHg; + List wgtzh = mapPhoto.get(wgtzh_key); + + // 回购支付凭证 + String zfpz_key = JcBillPhoto.HG_ZFPZ + "#" + billHg; + List zfpz = mapPhoto.get(zfpz_key); + + item.setTzhUrl((tzh != null && tzh.size() >= 1) ? "/" + FileUtil.getFileAccessPath(tzh.get(0).getUrlphoto()) : ""); + item.setWgtzhUrl((wgtzh != null && wgtzh.size() >= 1) ? wgtzh : null); + item.setZfpzUrl((zfpz != null && zfpz.size() >= 1) ? zfpz : null); + + item.setPayments(paymentsMap.get(billHg)); + } + + ApiJcBillHgSearch abc = new ApiJcBillHgSearch(); + abc.setTotal(pageLists.getTotalElements()); + abc.setTotalPages(pageLists.getTotalPages()); + abc.setItems(pageLists.getContent()); + + long time00 = System.currentTimeMillis(); + LOG.info("回购列表查询>>>总耗时>>>{}", (time00 - time0)); + + return abc; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 回购订单详情查询 + @RequestMapping(value="getJcBillHgDetails", method = RequestMethod.GET) + @Operation(summary="回购订单详情查询") + @Parameters({ + @Parameter(name="billHg", required = true, description="回购单号", schema = @Schema(pattern = "", defaultValue=""), example="HG202411180001") + }) + public ApiBillHg getJcBillHgDetails( + @RequestParam(required = false) String billHg + ) throws Exception{ + try { + if(StringUtils.isBlank(billHg)) throw new BusinessException("回购单号不能为空!"); + + LOG.info("回购订单详情查询>>>billHg>>>{}, 处理开始", billHg); + long time0 = System.currentTimeMillis(); + + ApiBillHg bill = apiJcBillService.queryApiBillHgById(billHg); + long time1 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryApiBillHgById查询耗时>>>{}", (time1 - time0)); + + if(bill == null) throw new BusinessException("回购单号:" + billHg + ",未查询到回购单!"); + + List billItems = apiJcBillService.queryApiBillHgItemByHgId(billHg); + long time2 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryApiBillHgItemByHgId查询耗时>>>{}", (time2 - time1)); + + List payments = apiJcBillService.queryApiBillHgPaymentByHgId(billHg); + long time3 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryApiBillHgPaymentByHgId查询耗时>>>{}", (time3 - time2)); + + // 获取商品编码集合 + List productids = billItems.stream() + .map(ApiBillHgItem::getProduct) + .collect(Collectors.toList()); + +// Map mapProductPhoto = productService.getProductsPhoto(productids); + Map mapProductPhoto = new HashMap(); + long time4 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>getProductsPhoto查询耗时>>>{}", (time4 - time3)); + + // 设置商品图片 + for(ApiBillHgItem item : billItems) { + JSONObject obj = mapProductPhoto.get(item.getProduct()); + if(obj != null) item.setProductphoto(obj); + } + + // 回购相关图片 + long time5 = System.currentTimeMillis(); + Map> mapPhoto = apiJcBillService.queryJcBillPhoto(billHg); + long time6 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryJcBillPhoto查询耗时>>>{}", (time6 - time5)); + + // 回购通知函 + String tzh_key = JcBillPhoto.HG_TZH + "#" + billHg; + List tzh = mapPhoto.get(tzh_key); + + // 回购违规通知函 + String wgtzh_key = JcBillPhoto.HG_WGTZH + "#" + billHg; + List wgtzh = mapPhoto.get(wgtzh_key); + + // 回购支付凭证 + String zfpz_key = JcBillPhoto.HG_ZFPZ + "#" + billHg; + List zfpz = mapPhoto.get(zfpz_key); +// List zfpzs = new ArrayList(); +// if(zfpz != null) { +// for(JcBillPhoto photo : zfpz) { +// zfpzs.add(photo.getUrlphoto()); +// } +// } + +// bill.setTzhUrl((tzh != null && tzh.size() >= 1) ? tzh.get(0).getUrlphoto() : ""); +// bill.setWgtzhUrl((wgtzh != null && wgtzh.size() >= 1) ? wgtzh.get(0).getUrlphoto() : ""); +// bill.setZfpzUrl(zfpzs); + bill.setTzhUrl(tzh); + bill.setTzhUrls((tzh != null && tzh.size() >= 1) ? "/" + FileUtil.getFileAccessPath(tzh.get(0).getUrlphoto()) : ""); + bill.setWgtzhUrl(wgtzh); + bill.setZfpzUrl(zfpz); + bill.setItems(billItems); + bill.setPayments(payments); + + long time00 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>总耗时>>>{}", (time00 - time0)); + + return bill; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 提交回购订单 + @RequestMapping(value="submitBillHg", method = RequestMethod.POST) + @Operation(summary="提交回购订单") + @Parameters({ + @Parameter(name="billInfo", required = true, description="回购订单JSONObject", schema = @Schema(implementation = ApiReqJcBillHg.class)) + }) + public ApiBillHgId submitBillHg( + @RequestParam(required = false) String billInfo + ) throws Exception{ + try { + if(StringUtils.isBlank(billInfo)) throw new BusinessException("参数[billInfo]为空!"); + + LOG.info("提交回购订单>>>billInfo>>>{}, 处理开始", billInfo); + long time0 = System.currentTimeMillis(); + + ApiReqJcBillHg reqJcBill = JSON.parseObject(billInfo, ApiReqJcBillHg.class); + + if(StringUtils.isBlank(reqJcBill.getId())) + throw new BusinessException("参数[id]为空!"); + if(reqJcBill.getSubtotal() == null) + throw new BusinessException("参数[subtotal]为空!"); + if(reqJcBill.getFreight() == null) + throw new BusinessException("参数[freight]为空!"); + if(StringUtils.isBlank(reqJcBill.getConsignee())) + throw new BusinessException("参数[consignee]为空!"); + if(StringUtils.isBlank(reqJcBill.getConsigneephone())) + throw new BusinessException("参数[consigneephone]为空!"); + if(StringUtils.isBlank(reqJcBill.getProvincename())) + throw new BusinessException("参数[provincename]为空!"); + if(StringUtils.isBlank(reqJcBill.getCityname())) + throw new BusinessException("参数[cityname]为空!"); + if(StringUtils.isBlank(reqJcBill.getAreaname())) + throw new BusinessException("参数[areaname]为空!"); + if(StringUtils.isBlank(reqJcBill.getAddress())) + throw new BusinessException("参数[address]为空!"); + if(StringUtils.isBlank(reqJcBill.getSubmit())) + throw new BusinessException("参数[submit]为空!"); + if(StringUtils.isBlank(reqJcBill.getSubmitname())) + throw new BusinessException("参数[submitname]为空!"); + + long time1 = System.currentTimeMillis(); + JcBillHg billHg = apiJcBillService.queryJcBillHg(reqJcBill.getId()); + long time2 = System.currentTimeMillis(); + LOG.info("提交回购订单>>>queryJcBillHg查询耗时>>>{}", (time2 - time1)); + + if(billHg == null) throw new BusinessException("回购单号:" + reqJcBill.getId() + ",未查询到回购单!"); + + // 计算支付众金额 +// BigDecimal paymentAmount = new BigDecimal(String.valueOf(reqJcBill.getSubtotal())).add(new BigDecimal(String.valueOf(reqJcBill.getFreight()))); + + // 支付 + List pays = new ArrayList(); + JcBillHgPay pay = null; + List payments = reqJcBill.getPayments(); + for(ApiReqJcBillPayment payment : payments) { + if(payment.getAmount() == null) + throw new BusinessException("参数[amount]为空!"); + if(StringUtils.isBlank(payment.getPayment())) + throw new BusinessException("参数[payment]为空!"); + if(StringUtils.isBlank(payment.getZhmc())) + throw new BusinessException("参数[zhmc]为空!"); + if(StringUtils.isBlank(payment.getKhyh())) + throw new BusinessException("参数[khyh]为空!"); + if(StringUtils.isBlank(payment.getYhzh())) + throw new BusinessException("参数[yhzh]为空!"); + + pay = new JcBillHgPay(); + pay.setBillid(billHg.getBillid()); + pay.setBillhg(billHg.getId()); + pay.setPayment(payment.getPayment()); + pay.setAmount(payment.getAmount()); + pay.setZhmc(payment.getZhmc()); + pay.setKhyh(payment.getKhyh()); + pay.setYhzh(payment.getYhzh()); + pay.setDt(new Date()); + + pays.add(pay); + } + + billHg.setStatus(JcBillHg.STATUS_TWO); + billHg.setSubtotal(reqJcBill.getSubtotal()); + billHg.setFreight(reqJcBill.getFreight()); + billHg.setConsignee(reqJcBill.getConsignee()); + billHg.setConsigneephone(reqJcBill.getConsigneephone()); + billHg.setProvince(reqJcBill.getProvince()); + billHg.setProvincename(reqJcBill.getProvincename()); + billHg.setCity(reqJcBill.getCity()); + billHg.setCityname(reqJcBill.getCityname()); + billHg.setArea(reqJcBill.getArea()); + billHg.setAreaname(reqJcBill.getAreaname()); + billHg.setAddress(reqJcBill.getAddress()); + billHg.setRemark(reqJcBill.getRemark()); + billHg.setRemark1(reqJcBill.getRemark1()); + billHg.setSubmit(reqJcBill.getSubmit()); + billHg.setSubmitname(reqJcBill.getSubmitname()); + billHg.setSubmitdt(new Date()); + + long time3 = System.currentTimeMillis(); + LOG.info("提交回购订单>>>逻辑处理耗时>>>{}", (time3 - time2)); + + apiJcBillService.updateJcBillHg(billHg, pays); + long time4 = System.currentTimeMillis(); + LOG.info("提交回购订单>>>updateJcBillHg耗时>>>{}", (time4 - time3)); + + String lastHgId = apiJcBillService.lastBillHgId(); + long time5 = System.currentTimeMillis(); + LOG.info("提交回购订单>>>lastBillHgId耗时>>>{}", (time5 - time4)); + + LOG.info("提交回购订单>>>总耗时>>>{}", (time5 - time0)); + + return new ApiBillHgId(lastHgId); + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 查询支付方式 + @RequestMapping(value="queryPayments", method = RequestMethod.GET) + @Operation(summary="查询支付方式") + @Parameters({ + }) + public List queryPayments( + ) throws Exception { + try { + LOG.info("查询支付方式>>>处理开始"); + long time0 = System.currentTimeMillis(); + + Map offlineMaps = getConfigSet(JcConfigKey.KEY_GROUP, JcConfigKey.KEY_JC_PAYMENT_OFFLINE); + long time1 = System.currentTimeMillis(); + LOG.info("查询支付方式>>>getConfigSet耗时>>>{}", (time1 - time0)); + + List pays = new ArrayList(); + ApiRespBillHgPay pay = new ApiRespBillHgPay(); + pay.setPayment("线下支付"); + pay.setKhyh(offlineMaps.get("khyh")); + pay.setYhzh(offlineMaps.get("yhzh")); + pay.setZhmc(offlineMaps.get("zhmc")); + pays.add(pay); + + long time00 = System.currentTimeMillis(); + LOG.info("查询支付方式>>>总耗时>>>{}", (time00 - time0)); + + return pays; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 上传图片 + @RequestMapping(value="uploadingBillPhoto", method = RequestMethod.POST) + @Operation(summary="上传图片") + @Parameters({ + @Parameter(name="billInfo", required = true, description="图片JSONObject", schema = @Schema(implementation = ApiReqJcBillPhoto.class)), + @Parameter(name="type", required = true, description="类型", schema = @Schema(pattern = "溯源入库:1,回购发货:2", defaultValue=""), example="HG202411180001"), + @Parameter(name="accountName", required = false, description="账号名称", schema = @Schema(pattern = "当type=2时,必填", defaultValue=""), example="HG202411180001") + }) + public void uploadingBillPhoto( + @RequestParam(required = false) String billInfo, + @RequestParam(required = false) String type, + @RequestParam(required = false) String accountName + ) throws Exception{ + try { + if(StringUtils.isBlank(billInfo)) throw new BusinessException("参数[billInfo]为空!"); + if(StringUtils.isBlank(type)) throw new BusinessException("参数[type]为空!"); + + LOG.info("上传图片>>>type>>>{}, billInfo>>>{},处理开始", type, billInfo); + long time0 = System.currentTimeMillis(); + + ApiReqJcBillPhoto reqBillPhoto = JSON.parseObject(billInfo, ApiReqJcBillPhoto.class); + + if("1".equals(type)) { + if(StringUtils.isBlank(reqBillPhoto.getId())) + throw new BusinessException("参数[id]为空!"); + JcBill bill = apiJcBillService.queryJcBillById(reqBillPhoto.getId()); + long time_2 = System.currentTimeMillis(); + LOG.info("上传图片>>>queryJcBillById查询耗时>>>{}", (time_2 - time0)); + + if(bill == null)throw new BusinessException("溯源入库单不存在!"); + + List items = reqBillPhoto.getItems(); + JcBillPhoto billPhoto = null; + List billPhotos = new ArrayList(); + for(ApiReqJcBillPhotoItem item : items) { + billPhoto = new JcBillPhoto(); + + billPhoto.setSrcid(reqBillPhoto.getId()); + billPhoto.setSrcitemid(reqBillPhoto.getId()); + billPhoto.setTypephoto(item.getTypePhoto()); + billPhoto.setUrlphoto(item.getUrlPhoto()); + billPhotos.add(billPhoto); + } + + long time1 = System.currentTimeMillis(); + apiJcBillService.saveAndDeletePhoto(billPhotos, reqBillPhoto.getId()); + long time2 = System.currentTimeMillis(); + LOG.info("上传图片>>>saveAndDeletePhoto耗时>>>{}", (time2 - time1)); + } else { + if(StringUtils.isBlank(reqBillPhoto.getId())) + throw new BusinessException("参数[id]为空!"); + + JcBillHg billHg = apiJcBillService.queryJcBillHg(reqBillPhoto.getId()); + long time_2 = System.currentTimeMillis(); + LOG.info("上传图片>>>queryJcBillHg查询耗时>>>{}", (time_2 - time0)); + + if(billHg == null)throw new BusinessException("回购单不存在!"); + + List items = reqBillPhoto.getItems(); + + JcBillPhoto billPhoto = null; + List billPhotos = new ArrayList(); + for(ApiReqJcBillPhotoItem item : items) { + billPhoto = new JcBillPhoto(); + + billPhoto.setSrcid(reqBillPhoto.getId()); + billPhoto.setSrcitemid(reqBillPhoto.getId()); + billPhoto.setTypephoto(item.getTypePhoto()); + billPhoto.setUrlphoto(item.getUrlPhoto()); + billPhotos.add(billPhoto); + + if(JcBillPhoto.HG_ZFPZ.equals(item.getTypePhoto())) { + if(StringUtils.isBlank(accountName)) throw new BusinessException("参数[accountName]为空!"); + billHg.setStatus(JcBillHg.STATUS_THREE); + billHg.setProofaccountname(accountName); + billHg.setProofdt(new Date()); + } + } + + long time1 = System.currentTimeMillis(); + apiJcBillService.saveAndDeletePhoto(billPhotos, billHg); + long time2 = System.currentTimeMillis(); + LOG.info("上传图片>>>saveAndDeletePhoto耗时>>>{}", (time2 - time1)); + } + long time3 = System.currentTimeMillis(); + LOG.info("上传图片>>>总耗时>>>{}", (time3 - time0)); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 删除图片 + @RequestMapping(value="deleteBillPhoto", method = RequestMethod.POST) + @Operation(summary="删除图片") + @Parameters({ + @Parameter(name="id", required = true, description="图片序号", schema = @Schema(pattern = "", defaultValue=""), example="1") + }) + public void deleteBillPhoto( + @RequestParam(required = false) String id + ) throws Exception{ + try { + + if(StringUtils.isBlank(id)) throw new BusinessException("参数[id]为空!"); + + LOG.info("删除图片>>>id>>>{},处理开始", id); + long time0 = System.currentTimeMillis(); + + JcBillPhoto billPhoto = apiJcBillService.queryJcBillPhotoById(id); + long time2 = System.currentTimeMillis(); + LOG.info("删除图片>>>queryJcBillPhotoById查询耗时>>>{}", (time2 - time0)); + + if(billPhoto == null) return; + + apiJcBillService.deleteJcBillPhotoById(billPhoto); + long time3 = System.currentTimeMillis(); + LOG.info("删除图片>>>deleteJcBillPhotoById耗时>>>{}", (time3 - time2)); + + LOG.info("删除图片>>>总耗时>>>{}", (time3 - time0)); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 查询收货仓库 + @RequestMapping(value="queryWarehouse", method = RequestMethod.GET) + @Operation(summary="查询收货仓库") + @Parameters({ + @Parameter(name="keyCode", required = true, description="编码或者名称", schema = @Schema(pattern = "", defaultValue=""), example="1") + }) + public List queryWarehouse( + @RequestParam(required = false) String keyCode + ) throws Exception { + try { + LOG.info("查询收货仓库>>>处理开始"); + long time0 = System.currentTimeMillis(); + + List objs = this.autoCompleteAccess.abacusConfigItemGroupAutoComplete(keyCode, JcConfigKey.KEY_GROUP, JcConfigKey.KEY_JC_WAREHOUSE); + long time1 = System.currentTimeMillis(); + LOG.info("查询收货仓库>>>getConfigSet耗时>>>{}", (time1 - time0)); + + List warehouses = new ArrayList(); + ApiRespWarehouse warehouse = null; + for(AbacusConfigItem obj : objs) { + warehouse = new ApiRespWarehouse(); + warehouse.setCode(obj.getCode()); + warehouse.setName(obj.getName()); + + warehouses.add(warehouse); + } + + long time00 = System.currentTimeMillis(); + LOG.info("查询收货仓库>>>总耗时>>>{}", (time00 - time0)); + + return warehouses; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 稽查货品查询---华致第三方用的 + @RequestMapping(value="queryJcProduct", method = RequestMethod.GET) + @Operation(summary="稽查货品查询") + @Parameters({ + @Parameter(name="product", required = false, description="货品编码", schema = @Schema(pattern = "", defaultValue=""), example="1010400021"), + @Parameter(name="stockInId", required = false, description="入库单号", schema = @Schema(pattern = "", defaultValue=""), example="WDT2292992992"), + @Parameter(name="hgId", required = false, description="回购单号", schema = @Schema(pattern = "", defaultValue=""), example="HG202501090002") + }) + public List queryJcProduct( + @RequestParam(required = false) String product, + @RequestParam(required = false) String stockInId, + @RequestParam(required = false) String hgId + ) throws Exception { + try { + LOG.info("稽查货品查询>>>处理开始"); + long time0 = System.currentTimeMillis(); + + if(StringUtils.isBlank(product) && StringUtils.isBlank(stockInId) && StringUtils.isBlank(hgId)) + throw new BusinessException("参数不能同时为空!"); + + List respJcProducts = new ArrayList(); + respJcProducts.addAll(jcBillBizService.hgAnalyze(product, stockInId, hgId)); + + LOG.info("稽查货品查询>>>总耗时>>>{}", (System.currentTimeMillis() - time0)); + + return respJcProducts; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 修改稽查单状态 + @RequestMapping(value="updateStatus", method = RequestMethod.POST) + @Operation(summary="修改稽查单状态") + @Parameters({ + @Parameter(name="billId", required = true, description="稽查单号", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001"), + @Parameter(name="status", required = true, description="状态", schema = @Schema(pattern = "-3:取消,0:待提交", defaultValue=""), example="-3") + }) + public void updateStatus( + @RequestParam(required = false) String billId, + @RequestParam(required = false) String status + ) throws Exception { + try { + LOG.info("修改稽查单状态>>>处理开始"); + long time0 = System.currentTimeMillis(); + + if(StringUtils.isBlank(billId)) throw new BusinessException("参数[billId]为空!"); + if(StringUtils.isBlank(status)) throw new BusinessException("参数[status]为空!"); + + JcBill bill = apiJcBillService.queryJcBillById(billId); + long time1 = System.currentTimeMillis(); + LOG.info("修改稽查单状态>>>queryJcBillById耗时>>>{}", (time1 - time0)); + + if(status.equals("0") || status.equals("-3")) { + apiJcBillService.updateStatusByJcBill(bill, Integer.parseInt(status)); + LOG.info("修改稽查单状态>>>updateStatusByJcBill耗时>>>{}", (System.currentTimeMillis() - time1)); + } else { + throw new BusinessException("该状态不支持修改!"); + } + + LOG.info("修改稽查单状态>>>总耗时>>>{}", (System.currentTimeMillis() - time0)); + + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + + // TODO 溯源结果 + @RequestMapping(value="billSourceItem", method = RequestMethod.POST) + @Operation(summary="溯源结果") + @Parameters({ + @Parameter(name="itemId", required = true, description="明细序号", schema = @Schema(pattern = "", defaultValue=""), example="11"), + }) + public JcBillSourceItem billSourceItem( + @RequestParam(required = false) String itemId + ) throws Exception { + try { + LOG.info("溯源结果>>>处理开始"); + long time0 = System.currentTimeMillis(); + + if(StringUtils.isBlank(itemId)) throw new BusinessException("参数[itemId]为空!"); + + JcBillSourceItem sourceItem = apiJcBillService.queryJcBillSourceItembyId(Long.parseLong(itemId)); + LOG.info("溯源结果>>>queryJcBillSourceItembyId查询耗时>>>{}", (System.currentTimeMillis() - time0)); + + LOG.info("溯源结果>>>总耗时>>>{}", (System.currentTimeMillis() - time0)); + + return sourceItem; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 根据回购明细id,查询物流码和对应的出库单号 + @RequestMapping(value="receiveGoods", method = RequestMethod.POST) + @Operation(summary="查看收货信息") + @Parameters({ + @Parameter(name="billHg", required = true, description="回购单号", schema = @Schema(pattern = "", defaultValue=""), example="HG202501020001"), + }) + public List receiveGoods( + @RequestParam(required = false) String billHg + ) throws Exception { + try { + LOG.info("查看收货信息>>>处理开始"); + long time0 = System.currentTimeMillis(); + + if(StringUtils.isBlank(billHg)) throw new BusinessException("参数[billHg]为空!"); + + ApiBillHg bill = apiJcBillService.queryApiBillHgById(billHg); + long time1 = System.currentTimeMillis(); + LOG.info("查看收货信息>>>queryApiBillHgById查询耗时>>>{}", (time1 - time0)); + + if(bill == null) throw new BusinessException("回购单号:" + billHg + ",未查询到回购单!"); + + List billItems = apiJcBillService.queryApiBillHgItemByHgId(billHg); + long time2 = System.currentTimeMillis(); + LOG.info("查看收货信息>>>queryApiBillHgItemByHgId查询耗时>>>{}", (time2 - time1)); + + List sources = apiJcBillService.queryJcBillSourceItemByBillId(bill.getBillid()); + LOG.info("查看收货信息>>>queryJcBillSourceItemByBillId查询耗时>>>{}", (System.currentTimeMillis() - time0)); + + Map> sourceMaps = sources.stream() + .collect(Collectors.groupingBy(e -> { + return e.getAccount() + e.getProduct(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + List apiLists = new ArrayList(); + ApiRespReceiveGoods arg = null; + for(ApiBillHgItem hgItem : billItems) { + List tempLists = sourceMaps.get(bill.getAccount() + hgItem.getProduct()); + + for(JcBillSourceItem item : tempLists) { + arg = new ApiRespReceiveGoods(); + arg.setBillid(bill.getBillid()); + arg.setLogisticsid(item.getLogisticsid()); + arg.setBillout(item.getBillout()); + + apiLists.add(arg); + } + } + + LOG.info("查看收货信息>>>总耗时>>>{}", (System.currentTimeMillis() - time0)); + + return apiLists; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/JcBillController.java.bak.20260818 b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/JcBillController.java.bak.20260818 new file mode 100644 index 0000000..a86cb6a --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/JcBillController.java.bak.20260818 @@ -0,0 +1,1722 @@ +package abacus.springboot.example.api; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.LinkedMultiValueMap; +import org.springframework.util.MultiValueMap; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.abacus.pms.wsi.ProductServiceIF; +import com.abacus.xpos.foundation.dao.Employee; +import com.abacus.xpos.foundation.pubs.DaoIdGenerator; +import com.abacus.xpos.foundation.wsi.EmployeeServiceIF; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +import abacus.commons.component.http.AbacusRestTemplate; +import abacus.commons.exception.BusinessException; +import abacus.commons.standard.util.FileUtil; +import abacus.config.dao.AbacusConfigItem; +import abacus.springboot.example.api.view.ApiBillHg; +import abacus.springboot.example.api.view.ApiBillHgId; +import abacus.springboot.example.api.view.ApiBillHgItem; +import abacus.springboot.example.api.view.ApiBillHgPayment; +import abacus.springboot.example.api.view.ApiJcBill; +import abacus.springboot.example.api.view.ApiJcBillCollect; +import abacus.springboot.example.api.view.ApiJcBillGoodsPhoto; +import abacus.springboot.example.api.view.ApiJcBillHgSearch; +import abacus.springboot.example.api.view.ApiJcBillHgSearchItem; +import abacus.springboot.example.api.view.ApiJcBillItem; +import abacus.springboot.example.api.view.ApiJcBillSearch; +import abacus.springboot.example.api.view.ApiReqJcBill; +import abacus.springboot.example.api.view.ApiReqJcBillGoodsPhoto; +import abacus.springboot.example.api.view.ApiReqJcBillHg; +import abacus.springboot.example.api.view.ApiReqJcBillItem; +import abacus.springboot.example.api.view.ApiReqJcBillPayment; +import abacus.springboot.example.api.view.ApiReqJcBillPhoto; +import abacus.springboot.example.api.view.ApiReqJcBillPhotoItem; +import abacus.springboot.example.api.view.ApiRespBillHgPay; +import abacus.springboot.example.api.view.ApiRespJcPorduct; +import abacus.springboot.example.api.view.ApiRespJcPorductAcount; +import abacus.springboot.example.api.view.ApiRespJcPorductItem; +import abacus.springboot.example.api.view.ApiRespJcPorductProduct; +import abacus.springboot.example.api.view.ApiRespReceiveGoods; +import abacus.springboot.example.api.view.ApiRespWarehouse; +import abacus.springboot.example.api.view.EdgBcsCode; +import abacus.springboot.example.api.view.JcBillCount; +import abacus.springboot.example.api.view.JcCodeFlow; +import abacus.springboot.example.api.view.JcProduct; +import abacus.springboot.example.api.view.JcProductBillSouce; +import abacus.springboot.example.config.JcConfigKey; +import abacus.springboot.example.controller.BaseServlet; +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillHg; +import abacus.springboot.example.dao.JcBillHgPay; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.dao.JcSourceItem; +import abacus.springboot.example.pi.AutoCompleteAccessIF; +import abacus.springboot.example.util.DateUtil; +import abacus.springboot.example.esb.JcBillBizService; +import abacus.springboot.example.wsi.ApiJcBillServiceIF; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; + +/** + *

Title:JcBillController

+

Description: 对外接口

+ @author chuanZeng + @date 2026年8月18日 + */ +@RestController +@RequestMapping(value = "/3.0/jc") +@Tag(name="稽查接口服务", description="稽查接口服务说明") +public class JcBillController extends BaseServlet{ + + private static final Logger LOG = LoggerFactory.getLogger(JcBillController.class); + + @Autowired + private ApiJcBillServiceIF apiJcBillService; + + @Autowired + private DaoIdGenerator jcBillIdGenerator; + + @Autowired + private ProductServiceIF productService; + + @Autowired + private EmployeeServiceIF employeeService; + + @Autowired + private AutoCompleteAccessIF autoCompleteAccess; + + @Autowired + private JcBillBizService jcBillBizService; + + // TODO 百度通用文字识别和二维码识别 + @RequestMapping(value="recogInterface", method = RequestMethod.POST) + @Operation(summary="百度通用文字识别和二维码识别") + @Parameters({ + @Parameter(name="imageUrl", required = false, description="HTTP URL地址", schema = @Schema(pattern = "", defaultValue=""), example="HTTP:IP/1.PNG"), + }) + public JSONObject recogInterface(@RequestParam String imageUrl) + throws Exception { + try { + String bdurl = this.getConfigValue("si.baidu.url"); +// String appid = this.getConfigValue("si.baidu.appid"); +// String apikey = this.getConfigValue("si.baidu.apikey"); +// String secretkey = this.getConfigValue("si.baidu.secretkey"); + + String token = apiJcBillService.getBaiduToken(); + + if(StringUtils.isBlank(token)) throw new BusinessException("百度token没有获取!"); + + AbacusRestTemplate art = new AbacusRestTemplate(); + + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); + + // 创建MultiValueMap对象并添加表单数据 + MultiValueMap params = new LinkedMultiValueMap<>(); + params.add("url", imageUrl); + + // 创建HttpEntity对象 + HttpEntity> requestEntity = new HttpEntity<>(params, headers); + + // 同用文字识别 + ResponseEntity resultOcr = art.restTemplate().postForEntity(bdurl + "/rest/2.0/ocr/v1/accurate_basic?access_token=" + token, requestEntity, String.class); + + ResponseEntity resultQrcode = art.restTemplate().postForEntity(bdurl + "/rest/2.0/ocr/v1/qrcode?access_token=" + token, requestEntity, String.class); + + JSONObject obj = new JSONObject(); + obj.put("OCR", JSONObject.parse(resultOcr.getBody())); + obj.put("qrcode", JSONObject.parse(resultQrcode.getBody())); + return obj; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 稽查收货查询 + @RequestMapping(value="getJcBillSearch", method = RequestMethod.GET) + @Operation(summary="稽查收货查询") + @Parameters({ + @Parameter(name="keyword", required = false, description="搜索内容(稽查单号货收货产品、货品编号模糊搜索)", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001"), + @Parameter(name="employee", required = false, description="员工编码", schema = @Schema(pattern = "", defaultValue=""), example="0"), + @Parameter(name="status", required = false, description="状态", schema = @Schema(pattern = "溯源驳回:-2,待提交:0,待溯源:2,待入库:3,已入库:5 ,回购通知:6,出库:8", defaultValue=""), example="1"), + @Parameter(name="page", required = false, description="页数", schema = @Schema(pattern = "", defaultValue="1"), example="1"), + @Parameter(name="size", required = false, description="每页显示的条数", schema = @Schema(pattern = "", defaultValue="10"), example="10") + }) + public ApiJcBillCollect getJcBillSearch( + @RequestParam(required = false) String keyword, + @RequestParam(required = false) String employee, + @RequestParam(required = false) String status, + @RequestParam(required = false) String page, + @RequestParam(required = false) String size + ) throws Exception{ + try { + LOG.info("稽查收货查询>>>keyword>>>{}, employee>>>{}, status>>>{}, page>>>{}, size>>>{}, 处理开始", keyword, employee, status, page, size); + long time0 = System.currentTimeMillis(); + + // 页数默认为:1 + Integer pageNumber = 1; + if(StringUtils.isNotBlank(page)) { + pageNumber = Integer.parseInt(page); + } + + // 每页显示的条数默认为:10 + Integer pageSize = 10; + if(StringUtils.isNotBlank(size)) { + pageSize = Integer.parseInt(size); + } + + // 当前页 + Pageable pageable = PageRequest.of(pageNumber - 1, pageSize); + long time1 = System.currentTimeMillis(); + Page pageLists = apiJcBillService.queryApiJcBillSearch(keyword, employee, status, pageable); + long time2 = System.currentTimeMillis(); + LOG.info("稽查收货查询>>>queryApiJcBillSearch查询耗时>>>{}", (time2 - time1)); + + for(ApiJcBillSearch jcBill : pageLists.getContent()) { + if (jcBill.getHgstatus() == 1) jcBill.setStatus(JcBill.STATUS_SIX); + else if (jcBill.getHgstatus() == 2) jcBill.setStatus(JcBill.STATUS_SEVEN); + } + + if("8".equals(status)) {// 出库状态 + + // 获取稽查单号集合 + List billIds = pageLists.getContent().stream() + .map(ApiJcBillSearch::getBillid) + .collect(Collectors.toList()); + + List hgs = apiJcBillService.qeryJcBillHgs(billIds); + + Map> mapHgs = hgs.stream() + .collect(Collectors.groupingBy(e -> { + return e.getBillid(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + Map mapBillStatus = new HashMap(); + for(String key : mapHgs.keySet()) { + List billHgs = mapHgs.get(key); + + // 是否全部出库 + boolean hgFale = true; + for(JcBillHg billHg : billHgs) { + if(billHg.getStatus() == 5 || billHg.getStatus() == 4 || billHg.getStatus() == 3 + || billHg.getStatus() == 2 || billHg.getStatus() == 1) { + hgFale = false; + continue; + } + } + + if(hgFale) mapBillStatus.put(key, 9); + else mapBillStatus.put(key, 8); + } + + for(ApiJcBillSearch jcBill : pageLists.getContent()) { + + if(mapBillStatus.containsKey(jcBill.getBillid())) { + Integer ckStatus = mapBillStatus.get(jcBill.getBillid()); + if (jcBill.getStatus() == JcBill.STATUS_SIX) { + jcBill.setStatus(8); + } else if (jcBill.getStatus() == JcBill.STATUS_SEVEN) { + jcBill.setStatus(ckStatus); + } + } + } + } + + + + ApiJcBillCollect abc = new ApiJcBillCollect(); + abc.setTotal(pageLists.getTotalElements()); + abc.setTotalPages(pageLists.getTotalPages()); + abc.setBills(pageLists.getContent()); + + long time3 = System.currentTimeMillis(); + LOG.info("稽查收货查询>>>总耗时>>>{}", (time3 - time0)); + + return abc; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 稽查收货订单详情查询 + @RequestMapping(value="getJcBillDetails", method = RequestMethod.GET) + @Operation(summary="稽查收货订单详情查询") + @Parameters({ + @Parameter(name="billId", required = true, description="稽查单号", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001") + }) + public ApiJcBill getJcBillDetails( + @RequestParam(required = false) String billId + ) throws Exception{ + try { + if(StringUtils.isBlank(billId)) throw new BusinessException("稽查单号不能为空!"); + + LOG.info("稽查收货订单详情查询>>>billId>>>{}, 处理开始", billId); + long time0 = System.currentTimeMillis(); + + ApiJcBill bill = apiJcBillService.queryApiJcBillById(billId); + long time1 = System.currentTimeMillis(); + LOG.info("稽查收货订单详情查询>>>queryApiJcBillById查询耗时>>>{}", (time1 - time0)); + + List sourceItems = apiJcBillService.queryJcBillSourceItemByBillId(billId); + long time2 = System.currentTimeMillis(); + LOG.info("稽查收货订单详情查询>>>queryJcBillSourceItemByBillId查询耗时>>>{}", (time2 - time1)); + + if(sourceItems != null) { + Map> mapPhoto = apiJcBillService.queryJcBillPhoto(billId); + long time3 = System.currentTimeMillis(); + LOG.info("稽查收货订单详情查询>>>queryJcBillPhoto查询耗时>>>{}", (time3 - time2)); + + Map> map = sourceItems.stream() + .collect(Collectors.groupingBy(e -> { + return String.valueOf(e.getIndexno()); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + List billItems = new ArrayList(); + ApiJcBillItem billItem = null; + boolean flagStaus = true; + List goodsPhotos = null; + // 解析图片+明细 + for(String key : map.keySet()) { + billItem = new ApiJcBillItem(); + List temps = map.get(key); + JcBillSourceItem temp = null; + + // 汇总数量 + BigDecimal quantityBig = new BigDecimal("0"); + // 汇总件数 + BigDecimal numbersBig = new BigDecimal("0"); + // 汇总金额 +// BigDecimal subtotalBig = new BigDecimal("0"); + + goodsPhotos = new ArrayList(); + ApiJcBillGoodsPhoto goodsPhoto = null; + for(JcBillSourceItem item : temps) { + temp = item; + + // 货品图 + List hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(item.getIndexno()) + "#" + String.valueOf(item.getGoodsid())); + List hptList = new ArrayList(); + if(hpts != null && hpts.size() >= 1) { + for(JcBillPhoto hpt : hpts) { + hptList.add(hpt.getUrlphoto()); + } + } + + // 汇总 + quantityBig = quantityBig.add(new BigDecimal(String.valueOf(item.getQuantity()))); + numbersBig = numbersBig.add(new BigDecimal(String.valueOf(item.getNumbers()))); +// subtotalBig = subtotalBig.add(new BigDecimal(String.valueOf(item.getSubtotal()))); + + // 图片 + goodsPhoto = new ApiJcBillGoodsPhoto(); + goodsPhoto.setId(item.getId()); + goodsPhoto.setStatus(item.getStatus()); + goodsPhoto.setGoodsid(item.getGoodsid()); + goodsPhoto.setLogisticsid(item.getLogisticsid()); + goodsPhoto.setGoodsPhotos(hptList); + goodsPhoto.setReason(item.getReason()); + + if(item.getStatus() == 0) { + flagStaus = false; + } + + goodsPhotos.add(goodsPhoto); + } + + // 稽查付款截图 + List fkts = mapPhoto.get(JcBillPhoto.JC_FK + "#" + String.valueOf(temp.getIndexno())); + if(fkts != null && fkts.size() >= 1) { + List fkList = new ArrayList(); + + for(JcBillPhoto fkt : fkts) { + fkList.add(fkt.getUrlphoto()); + } + + billItem.setPaymentPhoto(fkList); + } + + + billItem.setId(temp.getId()); + billItem.setIndexno(temp.getIndexno()); + billItem.setRecsource(temp.getRecsource()); + billItem.setChannel(temp.getChannel()); + billItem.setRecplatform(temp.getRecplatform()); + billItem.setPrice(temp.getPrice()); + billItem.setQuantity(quantityBig.doubleValue()); + billItem.setNumbers(numbersBig.doubleValue()); + billItem.setSubtotal(temp.getSubtotal()); + billItem.setGoodsPhotos(goodsPhotos); + + billItems.add(billItem); + } + + if(bill.getStatus() <= 1) { + if(bill.getStatus() == -2) { + bill.setStatus(JcBill.STATUS_MINUS_TWO); + } else { + if(flagStaus) { + bill.setStatus(JcBill.STATUS_ONE); + } + } + } + + bill.setItems(billItems); + } + + long time4 = System.currentTimeMillis(); + LOG.info("稽查收货订单详情查询>>>总耗时>>>{}>>>{}", (time4 - time0), JSON.toJSONString(bill)); + + return bill; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 稽查收货-删除订单详情 + @RequestMapping(value="deleteJcBillDetails", method = RequestMethod.GET) + @Operation(summary="稽查收货删除订单详情") + @Parameters({ + @Parameter(name="billId", required = true, description="稽查单号", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001"), + @Parameter(name="itemid", required = true, description="稽查明细单号", schema = @Schema(pattern = "", defaultValue=""), example="1") + }) + public void deleteJcBillDetails( + @RequestParam(required = false) String billId, + @RequestParam(required = false) String itemid + ) throws Exception{ + try { + if(StringUtils.isBlank(billId)) throw new BusinessException("参数[billId]为空!"); + if(StringUtils.isBlank(itemid)) throw new BusinessException("参数[itemid]为空!"); + + LOG.info("稽查收货删除订单详情>>>billInfo:{},itemid:{},处理开始", billId, itemid); + long time0 = System.currentTimeMillis(); + + apiJcBillService.deleteJcSourceItem(billId, itemid); + + long time4 = System.currentTimeMillis(); + LOG.info("稽查收货删除订单详情>>>总耗时>>>{}", (time4 - time0)); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 稽查收货订单保存 + @RequestMapping(value="createJcBill", method = RequestMethod.POST) + @Operation(summary="稽查收货订单保存") + @Parameters({ + @Parameter(name="billInfo", required = true, description="稽查收货JSONObject", schema = @Schema(implementation = ApiReqJcBill.class)) + }) + public ApiReqJcBill createJcBill( + @RequestParam(required = false) String billInfo + ) throws Exception{ + try { + if(StringUtils.isBlank(billInfo)) throw new BusinessException("参数[billInfo]为空!"); + + LOG.info("稽查收货订单保存>>>billInfo:{},处理开始", billInfo); + long time0 = System.currentTimeMillis(); + + ApiReqJcBill reqJcBill = JSON.parseObject(billInfo, ApiReqJcBill.class); + + if(StringUtils.isBlank(reqJcBill.getApplicant()) || StringUtils.isBlank(reqJcBill.getApplicantname())) + throw new BusinessException("参数[applicant]或[applicantname]为空!"); + + + if(StringUtils.isBlank(reqJcBill.getId())) jcBillBizService.saveJcBill(reqJcBill); + else jcBillBizService.updateJcbill(reqJcBill); + + long time1 = System.currentTimeMillis(); + LOG.info("稽查收货订单保存>>>总耗时>>>{}", (time1 - time0)); + + return reqJcBill; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + + /** + * 稽查收货明细保存逻辑 + + /** + + /** + * 稽查收货明细修改逻辑 + + + // TODO 验证溯源 + @RequestMapping(value="checkSource", method = RequestMethod.POST) + @Operation(summary="验证溯源") + @Parameters({ + @Parameter(name="billId", required = true, description="稽查单号", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001") + }) + public List checkSource( + @RequestParam(required = false) String billId + ) throws Exception{ + try { + if(StringUtils.isBlank(billId)) throw new BusinessException("稽查单号不能为空!"); + + LOG.info("验证溯源>>>billId>>>{}, 处理开始", billId); + long time0 = System.currentTimeMillis(); + + JcBill jcBill = apiJcBillService.queryJcBillById(billId); + long time01 = System.currentTimeMillis(); + LOG.info("验证溯源>>>queryJcBillById耗时>>>{}", (time01 - time0)); + + if(jcBill == null) throw new BusinessException("无收记录信息!"); + + List items = apiJcBillService.queryJcBillSourceItemByBillId(billId); + long time1 = System.currentTimeMillis(); + LOG.info("验证溯源>>>queryJcBillSourceItemByBillId耗时>>>{}", (time1 - time01)); + + if(items == null) throw new BusinessException("无收货信息!"); + + // 获取物流码集合 + List codes = new ArrayList<>(); + for(JcBillSourceItem item : items) { + if(StringUtils.isNotBlank(item.getLogisticsid())) { + codes.add(item.getLogisticsid()); + } + } + + List sourceItems = new ArrayList(); + if(codes != null && codes.size() >= 1) { + long time2 = System.currentTimeMillis(); + List jcCodeFlows = apiJcBillService.queryJcCodeFlow(codes); + long time3 = System.currentTimeMillis(); + LOG.info("验证溯源>>>queryJcCodeFlow耗时>>>{}", (time3 - time2)); + + List edgBcsCodes = edgopenapiBcscode(codes); + long time4 = System.currentTimeMillis(); + LOG.info("验证溯源>>>物流码溯源查询耗时>>>{}", (time4 - time3)); + + + JcSourceItem sourceItem = null; + JcSourceItem sourceItem2 = null; + + for(JcBillSourceItem item : items) { + String key_code = item.getLogisticsid(); + + // 是否只有一个出库单号 + boolean billFlage = true; + // 是否溯源成功 + boolean flage = false; + + + String billouts = null, billout = null, billoutdt = null, billoutwh = null, billoutwhname = null, + product = null, productname = null, account = null, accountname = null, + operator = null, operatorname = null, groupid = null, groupname = null, + salearea = null, saleareaname = null, source = null; + // 二维码来源 + if(edgBcsCodes != null && edgBcsCodes.size() >= 1) { + for(EdgBcsCode bcsCode : edgBcsCodes) { + if(key_code.equals(bcsCode.getCode())) { + flage = true; + + if(StringUtils.isBlank(billouts)) { + billouts = bcsCode.getCk_id(); + } else { + billouts += "," + bcsCode.getCk_id(); + } + + billout = bcsCode.getCk_id(); + billoutdt = bcsCode.getCdt(); + billoutwh = bcsCode.getDccw_id(); + billoutwhname = bcsCode.getDccw_name(); + product = bcsCode.getProductid(); + productname = bcsCode.getProductname(); + account = bcsCode.getCustomerid(); + accountname = bcsCode.getCustomername(); + operator = bcsCode.getEmployeeid(); + operatorname = bcsCode.getEmployeename(); + groupid = bcsCode.getGroup_id(); + groupname = bcsCode.getGroup_name(); + salearea = bcsCode.getDepartmentid(); + saleareaname = bcsCode.getDepartmentname(); + source = JcBillSourceItem.SOURCE_EWM; + + sourceItem = new JcSourceItem(); + sourceItem.setStatus(JcSourceItem.STATUS_ZERO); + sourceItem.setBillid(billId); + sourceItem.setSrcitemid(String.valueOf(item.getId())); + sourceItem.setGoodsid(item.getGoodsid()); + sourceItem.setLogisticsid(item.getLogisticsid()); + sourceItem.setBillout(billout); + sourceItem.setBilloutdt(DateUtil.toDateTime(billoutdt)); + sourceItem.setBilloutwh(billoutwh); + sourceItem.setBilloutwhname(billoutwhname); + sourceItem.setProduct(product); + sourceItem.setProductname(productname); + sourceItem.setAccount(account); + sourceItem.setAccountname(accountname); + sourceItem.setOperator(operator); + sourceItem.setOperatorname(operatorname); + sourceItem.setGroupid(groupid); + sourceItem.setGroupname(groupname); + sourceItem.setSalearea(salearea); + sourceItem.setSaleareaname(saleareaname); + sourceItem.setSource(source); + sourceItem.setDt(new Date()); + + sourceItems.add(sourceItem); + } + } + } + + // 业务中台 + if(jcCodeFlows != null && jcCodeFlows.size() >= 1) { + for(JcCodeFlow codeFlow : jcCodeFlows) { + + if(key_code.equals(codeFlow.getCode())) { + flage = true; + + if(StringUtils.isBlank(billouts)) { + billouts = codeFlow.getId(); + } else { + billouts += "," + codeFlow.getId(); + } + + billout = codeFlow.getId(); + billoutdt = codeFlow.getTdate(); + billoutwh = codeFlow.getDeposit(); + billoutwhname = codeFlow.getDepositname(); + product = codeFlow.getProductid(); + productname = codeFlow.getProductname(); + account = codeFlow.getCustomerid(); + accountname = codeFlow.getCustomername(); + operator = codeFlow.getAprssalemanid(); + operatorname = codeFlow.getAprssalemanname(); + groupid = codeFlow.getBizgroupid(); + groupname = codeFlow.getBizgroupname(); + salearea = codeFlow.getWsareaid(); + saleareaname = codeFlow.getWsareaname(); + source = JcBillSourceItem.SOURCE_ERP; + + sourceItem2 = new JcSourceItem(); + sourceItem2.setStatus(JcSourceItem.STATUS_ZERO); + sourceItem2.setBillid(billId); + sourceItem2.setSrcitemid(String.valueOf(item.getId())); + sourceItem2.setGoodsid(item.getGoodsid()); + sourceItem2.setLogisticsid(item.getLogisticsid()); + sourceItem2.setBillout(billout); + sourceItem2.setBilloutdt(DateUtil.toDateTime(billoutdt)); + sourceItem2.setBilloutwh(billoutwh); + sourceItem2.setBilloutwhname(billoutwhname); + sourceItem2.setProduct(product); + sourceItem2.setProductname(productname); + sourceItem2.setAccount(account); + sourceItem2.setAccountname(accountname); + sourceItem2.setOperator(operator); + sourceItem2.setOperatorname(operatorname); + sourceItem2.setGroupid(groupid); + sourceItem2.setGroupname(groupname); + sourceItem2.setSalearea(salearea); + sourceItem2.setSaleareaname(saleareaname); + sourceItem2.setSource(source); + sourceItem2.setDt(new Date()); + + sourceItems.add(sourceItem2); + } + } + } + + if(flage) { + item.setStatus(JcBillSourceItem.STATUS_ONE); + } else { + item.setStatus(JcBillSourceItem.STATUS_MINUS_ONE); + } + + if(StringUtils.isNotBlank(billouts)) item.setBillout(billouts); + if(StringUtils.isNotBlank(billoutdt)) item.setBilloutdt(DateUtil.toDateTime(billoutdt)); + if(StringUtils.isNotBlank(billoutwh)) item.setBilloutwh(billoutwh); + if(StringUtils.isNotBlank(billoutwhname)) item.setBilloutwhname(billoutwhname); + if(StringUtils.isNotBlank(product)) item.setProduct(product); + if(StringUtils.isNotBlank(productname)) item.setProductname(productname); + if(StringUtils.isNotBlank(account)) item.setAccount(account); + if(StringUtils.isNotBlank(accountname)) item.setAccountname(accountname); + if(StringUtils.isNotBlank(operator)) item.setOperator(operator); + if(StringUtils.isNotBlank(operatorname)) item.setOperatorname(operatorname); + if(StringUtils.isNotBlank(groupid)) item.setGroupid(groupid); + if(StringUtils.isNotBlank(groupname)) item.setGroupname(groupname); + if(StringUtils.isNotBlank(salearea)) item.setSalearea(salearea); + if(StringUtils.isNotBlank(saleareaname)) item.setSaleareaname(saleareaname); + if(StringUtils.isNotBlank(source)) item.setSource(source); + + } + } else { + for(JcBillSourceItem item : items) { + item.setStatus(JcBillSourceItem.STATUS_MINUS_ONE); + } + } + + long time5 = System.currentTimeMillis(); + apiJcBillService.saveJcSourceItem(items, sourceItems, jcBill); + long time00 = System.currentTimeMillis(); + LOG.info("验证溯源>>>saveJcSourceItem耗时>>>{}", (time00 - time5)); + + LOG.info("验证溯源>>>总耗时>>>{}", (time00 - time0)); + + return items; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 调第三方接口查询,物流码溯源查询 + * @param codes + * @return + * @throws Exception + */ + public List edgopenapiBcscode(List logisticss) throws Exception{ + try { + long time0 = System.currentTimeMillis(); + List codes = new ArrayList(); + // 取对应连接后32位,生成溯源码 + for(String logistics : logisticss) { + String[] codeArray = logistics.split("/"); + + String code = codeArray[codeArray.length - 1]; + + if(StringUtils.isNotBlank(code)) codes.add(code); + } + + String rzUrl = getConfigValue("pms.rzUrl"); + String param_appkey = getConfigValue("pms.edg_appkey"); + String param_appsecret = getConfigValue("pms.edg_appsecret"); + String bcscodeUrl = rzUrl + "/edgopenapi/services/bcscode"; + String getTokenUrl = rzUrl + getConfigValue("pms.rztokenUrl") + "?EDG-APPKEY=" + param_appkey + "&EDG-APPSECRET=" + param_appsecret; + + long time1 = System.currentTimeMillis(); + LOG.info("验证溯源>>>edgopenapiBcscode>>>接口配置参数耗时>>>{}", (time1 - time0)); + + String result = null, token=null; + + AbacusRestTemplate art = new AbacusRestTemplate(); + + // 获取token + result = art.restTemplate().getForObject(getTokenUrl, String.class); + + if(result != null && !result.equals("")){ + JSONObject json = JSONObject.parseObject(result); + token = json.getJSONObject("data").getString("token"); + } + long time2 = System.currentTimeMillis(); + LOG.info("验证溯源>>>edgopenapiBcscode>>>接口token获取耗时>>>{}", (time2 - time1)); + + if (token != null) { + // 请求头 + String header_token = "EDAPI-TOKEN"; + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.set(header_token, token); + + JSONObject requestJsonObj = new JSONObject(); + JSONObject bodyJsonObj = new JSONObject(); + bodyJsonObj.put("code", codes); + bodyJsonObj.put("$query-page-size","100"); + bodyJsonObj.put("$query-page-index",1); + requestJsonObj.put("request", bodyJsonObj); + + // 设置body,headers + HttpEntity requestEntity = new HttpEntity(requestJsonObj.toString(), headers); + + // 物流码溯源查询 + result = art.restTemplate().postForObject(bcscodeUrl, requestEntity, String.class); + long time3 = System.currentTimeMillis(); + LOG.info("验证溯源>>>edgopenapiBcscode>>>物流码溯源查询耗时>>>{}", (time3 - time2)); + + JSONObject rq = JSONObject.parseObject(result); + + if(rq.getString("retcode").equals("EDAC-200")) { + + JSONArray jsonArrays = rq.getJSONObject("response").getJSONArray("$data-detail"); + + if(!jsonArrays.isEmpty()){ + + List edgBcsCodes = JSONArray.parseArray(jsonArrays.toJSONString(), EdgBcsCode.class); + +// Map map = edgBcsCodes.stream() +// .collect(Collectors.groupingBy(e -> { +// return e.getCode(); +// }, +// Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)) +// )); + + return edgBcsCodes; + } else { + return null; + } + } else { + throw new BusinessException("睿治物流码溯源查询接口(" + bcscodeUrl + "),返回异常:" + rq.getString("msg")); + } + } else { + throw new BusinessException("睿治token未获取到,无法调用物流码溯源查询接口!"); + } + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 提交溯源 + @RequestMapping(value="submitSource", method = RequestMethod.POST) + @Operation(summary="提交溯源") + @Parameters({ + @Parameter(name="billId", required = true, description="稽查单号", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001") + }) + public void submitSource( + @RequestParam(required = false) String billId + ) throws Exception{ + try { + if(StringUtils.isBlank(billId)) throw new BusinessException("参数[billId]为空!"); + + LOG.info("提交溯源>>>billId:{},处理开始", billId); + long time0 = System.currentTimeMillis(); + + JcBill bill = apiJcBillService.queryJcBillById(billId); + long time1 = System.currentTimeMillis(); + LOG.info("提交溯源>>>queryJcBillById耗时>>>{}", (time1 - time0)); + + if(bill == null) throw new BusinessException("稽查单号:" + billId + ",未查询到稽查单"); + + // 状态 + int oldStatus = bill.getStatus(); + + List sourceItems = apiJcBillService.queryJcBillSourceItemByBillId(billId); + long time2 = System.currentTimeMillis(); + LOG.info("提交溯源>>>queryJcBillSourceItemByBillId耗时>>>{}", (time2 - time1)); + + if(sourceItems == null) throw new BusinessException("稽查单号:" + billId + ",未查询到稽查收货信息"); + + Map> mapPhto = apiJcBillService.queryJcBillPhoto(billId); + long time3 = System.currentTimeMillis(); + LOG.info("提交溯源>>>queryJcBillPhoto耗时>>>{}", (time3 - time2)); + + if(mapPhto == null) throw new BusinessException("稽查单号:" + billId + ",未查询到稽查收货货品图货收款图信息"); + + if(StringUtils.isBlank(bill.getGoods())) throw new BusinessException("收货产品,不能为空!"); + if(StringUtils.isBlank(bill.getReceivedt())) throw new BusinessException("收货日期,不能为空!"); + if(StringUtils.isBlank(bill.getWarehouse())) throw new BusinessException("收货仓库,不能为空!"); + + for(JcBillSourceItem item : sourceItems) { + if(StringUtils.isBlank(item.getRecsource())) throw new BusinessException("收货来源,不能为空!"); +// if(StringUtils.isBlank(item.getRecplatform())) throw new BusinessException("收货平台,不能为空!"); + if(StringUtils.isBlank(item.getChannel())) throw new BusinessException("收货渠道,不能为空!"); + if(item.getPrice() <= 0) throw new BusinessException("收货单价,不能小于等于0!"); + + if(item.getQuantity() <= 0) throw new BusinessException("收货数量,不能小于等于0!"); + if(item.getNumbers() <= 0) throw new BusinessException("收货件数,不能小于等于0!"); + if(item.getSubtotal() <= 0) throw new BusinessException("收货金额,不能小于等于0!"); + + if(StringUtils.isBlank(item.getGoodsid())) throw new BusinessException("货品编号,不能为空!"); +// if(StringUtils.isBlank(item.getLogisticsid())) throw new BusinessException("物流码,不能为空!"); + + if(item.getStatus() == JcBillSourceItem.STATUS_ZERO) throw new BusinessException("货品编号:" + item.getGoodsid() + ",系统溯源未验证!"); + + String fkt = JcBillPhoto.JC_FK + "#" + item.getIndexno(); + if(!mapPhto.containsKey(fkt)) throw new BusinessException("付款图未上传!"); + + String hpt = JcBillPhoto.JC_HP + "#" + item.getIndexno() + "#" + item.getGoodsid(); + if(!mapPhto.containsKey(hpt)) throw new BusinessException("货品图未上传!"); + } + + bill.setStatus(JcBill.STATUS_TWO); + + long time4 = System.currentTimeMillis(); + apiJcBillService.updateStatusJcBill(bill, oldStatus); + long time5 = System.currentTimeMillis(); + LOG.info("提交溯源>>>updateStatusJcBill耗时>>>{}", (time5 - time4)); + + LOG.info("提交溯源>>>总耗时>>>{}", (time5 - time0)); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 回购列表查询 + @RequestMapping(value="getJcBillHgSearch", method = RequestMethod.GET) + @Operation(summary="回购列表查询") + @Parameters({ + @Parameter(name="keyword", required = false, description="搜索内容(回购/稽查单号/客户名称/编码/收货人手机号/商品名称)", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001"), + @Parameter(name="employee", required = false, description="员工编码", schema = @Schema(pattern = "", defaultValue=""), example="0"), + @Parameter(name="status", required = false, description="状态", schema = @Schema(pattern = "待提交:1,待付款:2,待分仓:3,待出库:5,已出库:6 ", defaultValue=""), example="1"), + @Parameter(name="page", required = false, description="页数", schema = @Schema(pattern = "", defaultValue="1"), example="1"), + @Parameter(name="size", required = false, description="每页显示的条数", schema = @Schema(pattern = "", defaultValue="10"), example="10") + }) + public ApiJcBillHgSearch getJcBillHgSearch( + @RequestParam(required = false) String keyword, + @RequestParam(required = false) String employee, + @RequestParam(required = false) String status, + @RequestParam(required = false) String page, + @RequestParam(required = false) String size + ) throws Exception{ + try { + LOG.info("回购列表查询>>>keyword>>>{}, employee>>>{}, status>>>{}, page>>>{}, size>>>{}, 处理开始", keyword, employee, status, page, size); + long time0 = System.currentTimeMillis(); + + // 页数默认为:1 + Integer pageNumber = 1; + if(StringUtils.isNotBlank(page)) { + pageNumber = Integer.parseInt(page); + } + + // 每页显示的条数默认为:10 + Integer pageSize = 10; + if(StringUtils.isNotBlank(size)) { + pageSize = Integer.parseInt(size); + } + + // 当前页 + Pageable pageable = PageRequest.of(pageNumber - 1, pageSize); + + long time1 = System.currentTimeMillis(); + Page pageLists = apiJcBillService.queryApiJcBillHgSearchItem(keyword, employee, status, pageable); + long time2 = System.currentTimeMillis(); + LOG.info("回购列表查询>>>queryApiJcBillHgSearchItem查询耗时>>>{}", (time2 - time1)); + + // 获取回购订单的集合 + List ids = new ArrayList(); + for(ApiJcBillHgSearchItem item : pageLists) { + if(StringUtils.isNotBlank(item.getBillHg())) { + ids.add(item.getBillHg()); + } + } + + long time3 = System.currentTimeMillis(); + Map mapCounts = apiJcBillService.queryJcBillCount(ids); + long time4 = System.currentTimeMillis(); + LOG.info("回购列表查询>>>queryJcBillCount查询耗时>>>{}", (time4 - time3)); + + // 回购相关图片 + Map> mapPhoto = apiJcBillService.queryJcBillPhotoIn(ids); + long time5 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryJcBillPhotoIn查询耗时>>>{}", (time5 - time4)); + +// String erpUrl = getConfigValue(JcConfigKey.KEY_JC_ERP_URL); + long time6 = System.currentTimeMillis(); +// LOG.info("回购订单详情查询>>>getConfigValue查询耗时>>>{}", (time6 - time5)); + + List payments = apiJcBillService.queryApiBillHgPaymentByHgId(ids); + long time7 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryApiBillHgPaymentByHgId查询耗时>>>{}", (time7 - time6)); + + Map> paymentsMap = new HashMap>(); + if(payments != null && payments.size() >= 1) { + paymentsMap = payments.stream() + .collect(Collectors.groupingBy(e -> { + return e.getBillhg(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + } + + + for(ApiJcBillHgSearchItem item : pageLists.getContent()) { + String billHg = item.getBillHg(); + + JcBillCount count = mapCounts.get(billHg); + if(count != null) { + item.setBreednum(count.getBreednum()); + item.setNumbers(count.getNumbers()); + } + + // 回购通知函 + String tzh_key = JcBillPhoto.HG_TZH + "#" + billHg; + List tzh = mapPhoto.get(tzh_key); + + // 回购违规通知函 + String wgtzh_key = JcBillPhoto.HG_WGTZH + "#" + billHg; + List wgtzh = mapPhoto.get(wgtzh_key); + + // 回购支付凭证 + String zfpz_key = JcBillPhoto.HG_ZFPZ + "#" + billHg; + List zfpz = mapPhoto.get(zfpz_key); + + item.setTzhUrl((tzh != null && tzh.size() >= 1) ? "/" + FileUtil.getFileAccessPath(tzh.get(0).getUrlphoto()) : ""); + item.setWgtzhUrl((wgtzh != null && wgtzh.size() >= 1) ? wgtzh : null); + item.setZfpzUrl((zfpz != null && zfpz.size() >= 1) ? zfpz : null); + + item.setPayments(paymentsMap.get(billHg)); + } + + ApiJcBillHgSearch abc = new ApiJcBillHgSearch(); + abc.setTotal(pageLists.getTotalElements()); + abc.setTotalPages(pageLists.getTotalPages()); + abc.setItems(pageLists.getContent()); + + long time00 = System.currentTimeMillis(); + LOG.info("回购列表查询>>>总耗时>>>{}", (time00 - time0)); + + return abc; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 回购订单详情查询 + @RequestMapping(value="getJcBillHgDetails", method = RequestMethod.GET) + @Operation(summary="回购订单详情查询") + @Parameters({ + @Parameter(name="billHg", required = true, description="回购单号", schema = @Schema(pattern = "", defaultValue=""), example="HG202411180001") + }) + public ApiBillHg getJcBillHgDetails( + @RequestParam(required = false) String billHg + ) throws Exception{ + try { + if(StringUtils.isBlank(billHg)) throw new BusinessException("回购单号不能为空!"); + + LOG.info("回购订单详情查询>>>billHg>>>{}, 处理开始", billHg); + long time0 = System.currentTimeMillis(); + + ApiBillHg bill = apiJcBillService.queryApiBillHgById(billHg); + long time1 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryApiBillHgById查询耗时>>>{}", (time1 - time0)); + + if(bill == null) throw new BusinessException("回购单号:" + billHg + ",未查询到回购单!"); + + List billItems = apiJcBillService.queryApiBillHgItemByHgId(billHg); + long time2 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryApiBillHgItemByHgId查询耗时>>>{}", (time2 - time1)); + + List payments = apiJcBillService.queryApiBillHgPaymentByHgId(billHg); + long time3 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryApiBillHgPaymentByHgId查询耗时>>>{}", (time3 - time2)); + + // 获取商品编码集合 + List productids = billItems.stream() + .map(ApiBillHgItem::getProduct) + .collect(Collectors.toList()); + +// Map mapProductPhoto = productService.getProductsPhoto(productids); + Map mapProductPhoto = new HashMap(); + long time4 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>getProductsPhoto查询耗时>>>{}", (time4 - time3)); + + // 设置商品图片 + for(ApiBillHgItem item : billItems) { + JSONObject obj = mapProductPhoto.get(item.getProduct()); + if(obj != null) item.setProductphoto(obj); + } + + // 回购相关图片 + long time5 = System.currentTimeMillis(); + Map> mapPhoto = apiJcBillService.queryJcBillPhoto(billHg); + long time6 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>queryJcBillPhoto查询耗时>>>{}", (time6 - time5)); + + // 回购通知函 + String tzh_key = JcBillPhoto.HG_TZH + "#" + billHg; + List tzh = mapPhoto.get(tzh_key); + + // 回购违规通知函 + String wgtzh_key = JcBillPhoto.HG_WGTZH + "#" + billHg; + List wgtzh = mapPhoto.get(wgtzh_key); + + // 回购支付凭证 + String zfpz_key = JcBillPhoto.HG_ZFPZ + "#" + billHg; + List zfpz = mapPhoto.get(zfpz_key); +// List zfpzs = new ArrayList(); +// if(zfpz != null) { +// for(JcBillPhoto photo : zfpz) { +// zfpzs.add(photo.getUrlphoto()); +// } +// } + +// bill.setTzhUrl((tzh != null && tzh.size() >= 1) ? tzh.get(0).getUrlphoto() : ""); +// bill.setWgtzhUrl((wgtzh != null && wgtzh.size() >= 1) ? wgtzh.get(0).getUrlphoto() : ""); +// bill.setZfpzUrl(zfpzs); + bill.setTzhUrl(tzh); + bill.setTzhUrls((tzh != null && tzh.size() >= 1) ? "/" + FileUtil.getFileAccessPath(tzh.get(0).getUrlphoto()) : ""); + bill.setWgtzhUrl(wgtzh); + bill.setZfpzUrl(zfpz); + bill.setItems(billItems); + bill.setPayments(payments); + + long time00 = System.currentTimeMillis(); + LOG.info("回购订单详情查询>>>总耗时>>>{}", (time00 - time0)); + + return bill; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 提交回购订单 + @RequestMapping(value="submitBillHg", method = RequestMethod.POST) + @Operation(summary="提交回购订单") + @Parameters({ + @Parameter(name="billInfo", required = true, description="回购订单JSONObject", schema = @Schema(implementation = ApiReqJcBillHg.class)) + }) + public ApiBillHgId submitBillHg( + @RequestParam(required = false) String billInfo + ) throws Exception{ + try { + if(StringUtils.isBlank(billInfo)) throw new BusinessException("参数[billInfo]为空!"); + + LOG.info("提交回购订单>>>billInfo>>>{}, 处理开始", billInfo); + long time0 = System.currentTimeMillis(); + + ApiReqJcBillHg reqJcBill = JSON.parseObject(billInfo, ApiReqJcBillHg.class); + + if(StringUtils.isBlank(reqJcBill.getId())) + throw new BusinessException("参数[id]为空!"); + if(reqJcBill.getSubtotal() == null) + throw new BusinessException("参数[subtotal]为空!"); + if(reqJcBill.getFreight() == null) + throw new BusinessException("参数[freight]为空!"); + if(StringUtils.isBlank(reqJcBill.getConsignee())) + throw new BusinessException("参数[consignee]为空!"); + if(StringUtils.isBlank(reqJcBill.getConsigneephone())) + throw new BusinessException("参数[consigneephone]为空!"); + if(StringUtils.isBlank(reqJcBill.getProvincename())) + throw new BusinessException("参数[provincename]为空!"); + if(StringUtils.isBlank(reqJcBill.getCityname())) + throw new BusinessException("参数[cityname]为空!"); + if(StringUtils.isBlank(reqJcBill.getAreaname())) + throw new BusinessException("参数[areaname]为空!"); + if(StringUtils.isBlank(reqJcBill.getAddress())) + throw new BusinessException("参数[address]为空!"); + if(StringUtils.isBlank(reqJcBill.getSubmit())) + throw new BusinessException("参数[submit]为空!"); + if(StringUtils.isBlank(reqJcBill.getSubmitname())) + throw new BusinessException("参数[submitname]为空!"); + + long time1 = System.currentTimeMillis(); + JcBillHg billHg = apiJcBillService.queryJcBillHg(reqJcBill.getId()); + long time2 = System.currentTimeMillis(); + LOG.info("提交回购订单>>>queryJcBillHg查询耗时>>>{}", (time2 - time1)); + + if(billHg == null) throw new BusinessException("回购单号:" + reqJcBill.getId() + ",未查询到回购单!"); + + // 计算支付众金额 +// BigDecimal paymentAmount = new BigDecimal(String.valueOf(reqJcBill.getSubtotal())).add(new BigDecimal(String.valueOf(reqJcBill.getFreight()))); + + // 支付 + List pays = new ArrayList(); + JcBillHgPay pay = null; + List payments = reqJcBill.getPayments(); + for(ApiReqJcBillPayment payment : payments) { + if(payment.getAmount() == null) + throw new BusinessException("参数[amount]为空!"); + if(StringUtils.isBlank(payment.getPayment())) + throw new BusinessException("参数[payment]为空!"); + if(StringUtils.isBlank(payment.getZhmc())) + throw new BusinessException("参数[zhmc]为空!"); + if(StringUtils.isBlank(payment.getKhyh())) + throw new BusinessException("参数[khyh]为空!"); + if(StringUtils.isBlank(payment.getYhzh())) + throw new BusinessException("参数[yhzh]为空!"); + + pay = new JcBillHgPay(); + pay.setBillid(billHg.getBillid()); + pay.setBillhg(billHg.getId()); + pay.setPayment(payment.getPayment()); + pay.setAmount(payment.getAmount()); + pay.setZhmc(payment.getZhmc()); + pay.setKhyh(payment.getKhyh()); + pay.setYhzh(payment.getYhzh()); + pay.setDt(new Date()); + + pays.add(pay); + } + + billHg.setStatus(JcBillHg.STATUS_TWO); + billHg.setSubtotal(reqJcBill.getSubtotal()); + billHg.setFreight(reqJcBill.getFreight()); + billHg.setConsignee(reqJcBill.getConsignee()); + billHg.setConsigneephone(reqJcBill.getConsigneephone()); + billHg.setProvince(reqJcBill.getProvince()); + billHg.setProvincename(reqJcBill.getProvincename()); + billHg.setCity(reqJcBill.getCity()); + billHg.setCityname(reqJcBill.getCityname()); + billHg.setArea(reqJcBill.getArea()); + billHg.setAreaname(reqJcBill.getAreaname()); + billHg.setAddress(reqJcBill.getAddress()); + billHg.setRemark(reqJcBill.getRemark()); + billHg.setRemark1(reqJcBill.getRemark1()); + billHg.setSubmit(reqJcBill.getSubmit()); + billHg.setSubmitname(reqJcBill.getSubmitname()); + billHg.setSubmitdt(new Date()); + + long time3 = System.currentTimeMillis(); + LOG.info("提交回购订单>>>逻辑处理耗时>>>{}", (time3 - time2)); + + apiJcBillService.updateJcBillHg(billHg, pays); + long time4 = System.currentTimeMillis(); + LOG.info("提交回购订单>>>updateJcBillHg耗时>>>{}", (time4 - time3)); + + String lastHgId = apiJcBillService.lastBillHgId(); + long time5 = System.currentTimeMillis(); + LOG.info("提交回购订单>>>lastBillHgId耗时>>>{}", (time5 - time4)); + + LOG.info("提交回购订单>>>总耗时>>>{}", (time5 - time0)); + + return new ApiBillHgId(lastHgId); + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 查询支付方式 + @RequestMapping(value="queryPayments", method = RequestMethod.GET) + @Operation(summary="查询支付方式") + @Parameters({ + }) + public List queryPayments( + ) throws Exception { + try { + LOG.info("查询支付方式>>>处理开始"); + long time0 = System.currentTimeMillis(); + + Map offlineMaps = getConfigSet(JcConfigKey.KEY_GROUP, JcConfigKey.KEY_JC_PAYMENT_OFFLINE); + long time1 = System.currentTimeMillis(); + LOG.info("查询支付方式>>>getConfigSet耗时>>>{}", (time1 - time0)); + + List pays = new ArrayList(); + ApiRespBillHgPay pay = new ApiRespBillHgPay(); + pay.setPayment("线下支付"); + pay.setKhyh(offlineMaps.get("khyh")); + pay.setYhzh(offlineMaps.get("yhzh")); + pay.setZhmc(offlineMaps.get("zhmc")); + pays.add(pay); + + long time00 = System.currentTimeMillis(); + LOG.info("查询支付方式>>>总耗时>>>{}", (time00 - time0)); + + return pays; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 上传图片 + @RequestMapping(value="uploadingBillPhoto", method = RequestMethod.POST) + @Operation(summary="上传图片") + @Parameters({ + @Parameter(name="billInfo", required = true, description="图片JSONObject", schema = @Schema(implementation = ApiReqJcBillPhoto.class)), + @Parameter(name="type", required = true, description="类型", schema = @Schema(pattern = "溯源入库:1,回购发货:2", defaultValue=""), example="HG202411180001"), + @Parameter(name="accountName", required = false, description="账号名称", schema = @Schema(pattern = "当type=2时,必填", defaultValue=""), example="HG202411180001") + }) + public void uploadingBillPhoto( + @RequestParam(required = false) String billInfo, + @RequestParam(required = false) String type, + @RequestParam(required = false) String accountName + ) throws Exception{ + try { + if(StringUtils.isBlank(billInfo)) throw new BusinessException("参数[billInfo]为空!"); + if(StringUtils.isBlank(type)) throw new BusinessException("参数[type]为空!"); + + LOG.info("上传图片>>>type>>>{}, billInfo>>>{},处理开始", type, billInfo); + long time0 = System.currentTimeMillis(); + + ApiReqJcBillPhoto reqBillPhoto = JSON.parseObject(billInfo, ApiReqJcBillPhoto.class); + + if("1".equals(type)) { + if(StringUtils.isBlank(reqBillPhoto.getId())) + throw new BusinessException("参数[id]为空!"); + JcBill bill = apiJcBillService.queryJcBillById(reqBillPhoto.getId()); + long time_2 = System.currentTimeMillis(); + LOG.info("上传图片>>>queryJcBillById查询耗时>>>{}", (time_2 - time0)); + + if(bill == null)throw new BusinessException("溯源入库单不存在!"); + + List items = reqBillPhoto.getItems(); + JcBillPhoto billPhoto = null; + List billPhotos = new ArrayList(); + for(ApiReqJcBillPhotoItem item : items) { + billPhoto = new JcBillPhoto(); + + billPhoto.setSrcid(reqBillPhoto.getId()); + billPhoto.setSrcitemid(reqBillPhoto.getId()); + billPhoto.setTypephoto(item.getTypePhoto()); + billPhoto.setUrlphoto(item.getUrlPhoto()); + billPhotos.add(billPhoto); + } + + long time1 = System.currentTimeMillis(); + apiJcBillService.saveAndDeletePhoto(billPhotos, reqBillPhoto.getId()); + long time2 = System.currentTimeMillis(); + LOG.info("上传图片>>>saveAndDeletePhoto耗时>>>{}", (time2 - time1)); + } else { + if(StringUtils.isBlank(reqBillPhoto.getId())) + throw new BusinessException("参数[id]为空!"); + + JcBillHg billHg = apiJcBillService.queryJcBillHg(reqBillPhoto.getId()); + long time_2 = System.currentTimeMillis(); + LOG.info("上传图片>>>queryJcBillHg查询耗时>>>{}", (time_2 - time0)); + + if(billHg == null)throw new BusinessException("回购单不存在!"); + + List items = reqBillPhoto.getItems(); + + JcBillPhoto billPhoto = null; + List billPhotos = new ArrayList(); + for(ApiReqJcBillPhotoItem item : items) { + billPhoto = new JcBillPhoto(); + + billPhoto.setSrcid(reqBillPhoto.getId()); + billPhoto.setSrcitemid(reqBillPhoto.getId()); + billPhoto.setTypephoto(item.getTypePhoto()); + billPhoto.setUrlphoto(item.getUrlPhoto()); + billPhotos.add(billPhoto); + + if(JcBillPhoto.HG_ZFPZ.equals(item.getTypePhoto())) { + if(StringUtils.isBlank(accountName)) throw new BusinessException("参数[accountName]为空!"); + billHg.setStatus(JcBillHg.STATUS_THREE); + billHg.setProofaccountname(accountName); + billHg.setProofdt(new Date()); + } + } + + long time1 = System.currentTimeMillis(); + apiJcBillService.saveAndDeletePhoto(billPhotos, billHg); + long time2 = System.currentTimeMillis(); + LOG.info("上传图片>>>saveAndDeletePhoto耗时>>>{}", (time2 - time1)); + } + long time3 = System.currentTimeMillis(); + LOG.info("上传图片>>>总耗时>>>{}", (time3 - time0)); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 删除图片 + @RequestMapping(value="deleteBillPhoto", method = RequestMethod.POST) + @Operation(summary="删除图片") + @Parameters({ + @Parameter(name="id", required = true, description="图片序号", schema = @Schema(pattern = "", defaultValue=""), example="1") + }) + public void deleteBillPhoto( + @RequestParam(required = false) String id + ) throws Exception{ + try { + + if(StringUtils.isBlank(id)) throw new BusinessException("参数[id]为空!"); + + LOG.info("删除图片>>>id>>>{},处理开始", id); + long time0 = System.currentTimeMillis(); + + JcBillPhoto billPhoto = apiJcBillService.queryJcBillPhotoById(id); + long time2 = System.currentTimeMillis(); + LOG.info("删除图片>>>queryJcBillPhotoById查询耗时>>>{}", (time2 - time0)); + + if(billPhoto == null) return; + + apiJcBillService.deleteJcBillPhotoById(billPhoto); + long time3 = System.currentTimeMillis(); + LOG.info("删除图片>>>deleteJcBillPhotoById耗时>>>{}", (time3 - time2)); + + LOG.info("删除图片>>>总耗时>>>{}", (time3 - time0)); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + // TODO 查询收货仓库 + @RequestMapping(value="queryWarehouse", method = RequestMethod.GET) + @Operation(summary="查询收货仓库") + @Parameters({ + @Parameter(name="keyCode", required = true, description="编码或者名称", schema = @Schema(pattern = "", defaultValue=""), example="1") + }) + public List queryWarehouse( + @RequestParam(required = false) String keyCode + ) throws Exception { + try { + LOG.info("查询收货仓库>>>处理开始"); + long time0 = System.currentTimeMillis(); + + List objs = this.autoCompleteAccess.abacusConfigItemGroupAutoComplete(keyCode, JcConfigKey.KEY_GROUP, JcConfigKey.KEY_JC_WAREHOUSE); + long time1 = System.currentTimeMillis(); + LOG.info("查询收货仓库>>>getConfigSet耗时>>>{}", (time1 - time0)); + + List warehouses = new ArrayList(); + ApiRespWarehouse warehouse = null; + for(AbacusConfigItem obj : objs) { + warehouse = new ApiRespWarehouse(); + warehouse.setCode(obj.getCode()); + warehouse.setName(obj.getName()); + + warehouses.add(warehouse); + } + + long time00 = System.currentTimeMillis(); + LOG.info("查询收货仓库>>>总耗时>>>{}", (time00 - time0)); + + return warehouses; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 稽查货品查询---华致第三方用的 + @RequestMapping(value="queryJcProduct", method = RequestMethod.GET) + @Operation(summary="稽查货品查询") + @Parameters({ + @Parameter(name="product", required = false, description="货品编码", schema = @Schema(pattern = "", defaultValue=""), example="1010400021"), + @Parameter(name="stockInId", required = false, description="入库单号", schema = @Schema(pattern = "", defaultValue=""), example="WDT2292992992"), + @Parameter(name="hgId", required = false, description="回购单号", schema = @Schema(pattern = "", defaultValue=""), example="HG202501090002") + }) + public List queryJcProduct( + @RequestParam(required = false) String product, + @RequestParam(required = false) String stockInId, + @RequestParam(required = false) String hgId + ) throws Exception { + try { + LOG.info("稽查货品查询>>>处理开始"); + long time0 = System.currentTimeMillis(); + + if(StringUtils.isBlank(product) && StringUtils.isBlank(stockInId) && StringUtils.isBlank(hgId)) + throw new BusinessException("参数不能同时为空!"); + + List respJcProducts = new ArrayList(); + respJcProducts.addAll(jcBillBizService.hgAnalyze(product, stockInId, hgId)); +// if(StringUtils.isNotBlank(hgId)) { +// respJcProducts.addAll(jcBillBizService.hgAnalyze(product, stockInId, hgId)); +// } else { +// +// } + + LOG.info("稽查货品查询>>>总耗时>>>{}", (System.currentTimeMillis() - time0)); + + return respJcProducts; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 以稽查单为主,解析逻辑 + * @param product + * @param stockInId + * @return + * @throws Exception + */ + private List jcAnalyze(String product, String stockInId) throws Exception { + try { + long time1 = System.currentTimeMillis(); + List jcProducts = apiJcBillService.queryJcProduct(product, stockInId, null); + LOG.info("稽查货品查询>>>稽查单逻辑>>>queryJcProduct耗时>>>{}", (System.currentTimeMillis() - time1)); + + // 按稽查单号+入库单号+回购单号+出库单号,分组 + Map> mapProducts = jcProducts.stream() + .collect(Collectors.groupingBy(e -> { + return e.getBillid() + e.getBillin() + e.getBillhg() + e.getWdtbillout(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + LOG.info("稽查货品查询>>>稽查单逻辑>>>按稽查单号+入库单号+回购单号+出库单号,分组后数据>>>{}", JSON.toJSONString(mapProducts)); + + long time4 = System.currentTimeMillis(); + List respJcProducts = new ArrayList(); + ApiRespJcPorduct respJcProduct = null; + for(String key : mapProducts.keySet()) { + + List tempJcProducts = mapProducts.get(key); + + JcProduct jcProduct = tempJcProducts.get(0); + + // 生成单号相关信息 + respJcProduct = new ApiRespJcPorduct(); + if(jcProduct.getBillid() != null) respJcProduct.setBillId(jcProduct.getBillid()); + if(jcProduct.getBillin() != null) respJcProduct.setStockInId(jcProduct.getBillin()); + if(jcProduct.getBillhg() != null) respJcProduct.setHgId(jcProduct.getBillhg()); + if(jcProduct.getWdtbillout() != null) respJcProduct.setStockOutId(jcProduct.getWdtbillout()); + + // 按稽查单号+入库单号+回购单号+客户编码,汇总同一客户数据 + Map> mapAccProducts = jcProducts.stream() + .collect(Collectors.groupingBy(e -> { + return e.getBillid() + e.getBillin() + e.getBillhg()+ e.getAccount(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + LOG.info("稽查货品查询>>>稽查单逻辑>>>按稽查单号+入库单号+回购单号+客户编码,汇总同一客户数据>>>{}", JSON.toJSONString(mapAccProducts)); + + String keyAccount = jcProduct.getBillid() + jcProduct.getBillin() + jcProduct.getBillhg() +jcProduct.getAccount(); + + List accTempJcProducts = mapAccProducts.get(keyAccount); + + List accounts = new ArrayList(); + ApiRespJcPorductAcount account = null; + for(JcProduct accJcProduct : accTempJcProducts) { + + // 设置客户 + account = new ApiRespJcPorductAcount(); + account.setAccount(accJcProduct.getAccount()); + account.setAccountName(accJcProduct.getAccountname()); + + List products = new ArrayList(); + // 设置商品 + ApiRespJcPorductProduct ajproduct = new ApiRespJcPorductProduct(); + ajproduct.setProduct(accJcProduct.getProduct()); + ajproduct.setProductName(accJcProduct.getProductname()); + ajproduct.setQuantity(accJcProduct.getQuantity() + "瓶/" + accJcProduct.getNumbers() + "件"); + + } + } + + return null; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * 回购单号是按回购单显示明细,以回购单号为主,解析 + * @param product + * @param stockInId + + + // TODO 修改稽查单状态 + @RequestMapping(value="updateStatus", method = RequestMethod.POST) + @Operation(summary="修改稽查单状态") + @Parameters({ + @Parameter(name="billId", required = true, description="稽查单号", schema = @Schema(pattern = "", defaultValue=""), example="JC202411180001"), + @Parameter(name="status", required = true, description="状态", schema = @Schema(pattern = "-3:取消,0:待提交", defaultValue=""), example="-3") + }) + public void updateStatus( + @RequestParam(required = false) String billId, + @RequestParam(required = false) String status + ) throws Exception { + try { + LOG.info("修改稽查单状态>>>处理开始"); + long time0 = System.currentTimeMillis(); + + if(StringUtils.isBlank(billId)) throw new BusinessException("参数[billId]为空!"); + if(StringUtils.isBlank(status)) throw new BusinessException("参数[status]为空!"); + + JcBill bill = apiJcBillService.queryJcBillById(billId); + long time1 = System.currentTimeMillis(); + LOG.info("修改稽查单状态>>>queryJcBillById耗时>>>{}", (time1 - time0)); + + if(status.equals("0") || status.equals("-3")) { + apiJcBillService.updateStatusByJcBill(bill, Integer.parseInt(status)); + LOG.info("修改稽查单状态>>>updateStatusByJcBill耗时>>>{}", (System.currentTimeMillis() - time1)); + } else { + throw new BusinessException("该状态不支持修改!"); + } + + LOG.info("修改稽查单状态>>>总耗时>>>{}", (System.currentTimeMillis() - time0)); + + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + + // TODO 溯源结果 + @RequestMapping(value="billSourceItem", method = RequestMethod.POST) + @Operation(summary="溯源结果") + @Parameters({ + @Parameter(name="itemId", required = true, description="明细序号", schema = @Schema(pattern = "", defaultValue=""), example="11"), + }) + public JcBillSourceItem billSourceItem( + @RequestParam(required = false) String itemId + ) throws Exception { + try { + LOG.info("溯源结果>>>处理开始"); + long time0 = System.currentTimeMillis(); + + if(StringUtils.isBlank(itemId)) throw new BusinessException("参数[itemId]为空!"); + + JcBillSourceItem sourceItem = apiJcBillService.queryJcBillSourceItembyId(Long.parseLong(itemId)); + LOG.info("溯源结果>>>queryJcBillSourceItembyId查询耗时>>>{}", (System.currentTimeMillis() - time0)); + + LOG.info("溯源结果>>>总耗时>>>{}", (System.currentTimeMillis() - time0)); + + return sourceItem; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 根据回购明细id,查询物流码和对应的出库单号 + @RequestMapping(value="receiveGoods", method = RequestMethod.POST) + @Operation(summary="查看收货信息") + @Parameters({ + @Parameter(name="billHg", required = true, description="回购单号", schema = @Schema(pattern = "", defaultValue=""), example="HG202501020001"), + }) + public List receiveGoods( + @RequestParam(required = false) String billHg + ) throws Exception { + try { + LOG.info("查看收货信息>>>处理开始"); + long time0 = System.currentTimeMillis(); + + if(StringUtils.isBlank(billHg)) throw new BusinessException("参数[billHg]为空!"); + + ApiBillHg bill = apiJcBillService.queryApiBillHgById(billHg); + long time1 = System.currentTimeMillis(); + LOG.info("查看收货信息>>>queryApiBillHgById查询耗时>>>{}", (time1 - time0)); + + if(bill == null) throw new BusinessException("回购单号:" + billHg + ",未查询到回购单!"); + + List billItems = apiJcBillService.queryApiBillHgItemByHgId(billHg); + long time2 = System.currentTimeMillis(); + LOG.info("查看收货信息>>>queryApiBillHgItemByHgId查询耗时>>>{}", (time2 - time1)); + + List sources = apiJcBillService.queryJcBillSourceItemByBillId(bill.getBillid()); + LOG.info("查看收货信息>>>queryJcBillSourceItemByBillId查询耗时>>>{}", (System.currentTimeMillis() - time0)); + + Map> sourceMaps = sources.stream() + .collect(Collectors.groupingBy(e -> { + return e.getAccount() + e.getProduct(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + List apiLists = new ArrayList(); + ApiRespReceiveGoods arg = null; + for(ApiBillHgItem hgItem : billItems) { + List tempLists = sourceMaps.get(bill.getAccount() + hgItem.getProduct()); + + for(JcBillSourceItem item : tempLists) { + arg = new ApiRespReceiveGoods(); + arg.setBillid(bill.getBillid()); + arg.setLogisticsid(item.getLogisticsid()); + arg.setBillout(item.getBillout()); + + apiLists.add(arg); + } + } + + LOG.info("查看收货信息>>>总耗时>>>{}", (System.currentTimeMillis() - time0)); + + return apiLists; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHg.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHg.java new file mode 100644 index 0000000..c38cfb6 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHg.java @@ -0,0 +1,390 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import abacus.springboot.example.dao.JcBillPhoto; +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "回购主单" , name = "ApiBillHg") +public class ApiBillHg { + + @Schema(description="回购单单号", required = false, example="HG202411180001") + private String id; + + @Schema(description = "稽查单号", required = false, example = "JC202411180001") + private String billid; + + @Schema(description="状态", required = false, pattern = "待提交:1,待付款:2,待分仓(已付款):3,已分仓(待出库):4,已出库:5", example = "1") + private int status; + + @Schema(description = "订单来源", required = false, example = "掌上华致") + private String source; + + @Schema(description = "客户编码", required = false, example = "20200089") + private String account; + + @Schema(description = "客户名称", required = false, example = "广东众之品酒有限公司") + private String accountname; + + @Schema(description = "总数量", required = false, example = "6") + private double quantity; + + @Schema(description = "总金额", required = false, example = "4800") + private double subtotal; + + @Schema(description = "运费", required = false, example = "50") + private double freight; + + @Schema(description = "运营经理编码", required = false, example = "zhangsan") + private String manager; + + @Schema(description = "运营经理名称", required = false, example = "张三") + private String managername; + + @Schema(description = "收货人姓名", required = false, example = "李四") + private String consignee; + + @Schema(description = "收货人电话", required = false, example = "1888888888") + private String consigneephone; + + @Schema(description = "省", required = false, example = "10001") + private String province; + + @Schema(description = "省", required = false, example = "广东") + private String provincename; + + @Schema(description = "市", required = false, example = "1000101") + private String city; + + @Schema(description = "市", required = false, example = "广州") + private String cityname; + + @Schema(description = "区", required = false, example = "100010101") + private String area; + + @Schema(description = "区", required = false, example = "越秀区") + private String areaname; + + @Schema(description = "详细地址", required = false, example = "东风24路") + private String address; + + @Schema(description = "收货方式", required = false, example = "送货上门") + private String receiveway; + + @Schema(description = "订单备注", required = false, example = "订单备注~~~") + private String remark; + + @Schema(description = "运营备注", required = false, example = "运营备注~~~") + private String remark1; + + @Schema(description = "物流公司名称", required = false, example = "京东快递") + private String logisticsname; + + @Schema(description = "物流公司代码", required = false, example = "JD") + private String logisticscode; + + @Schema(description = "物流方式", required = false, example = "") + private String logisticstype; + + @Schema(description = "物流单号", required = false, example = "JD00001") + private String logisticsno; + + @Schema(description="回购明细", required = false, example="") + private List items; + + @Schema(description="回购支付明细", required = false, example="") + private List payments; + + @Schema(description="回购通知函", required = false, example="") + private List tzhUrl; + + @Schema(description="违规回购通知函", required = false, example="") + private List wgtzhUrl; + + @Schema(description="支付凭证", required = false, example="") + private List zfpzUrl; + + @Schema(description="回购通知函", required = false, example="") + private String tzhUrls; +// +// @Schema(description="违规回购通知函", required = false, example="") +// private String wgtzhUrl; +// +// @Schema(description="支付凭证", required = false, example="") +// private List zfpzUrl; + + public String getId() { + return id; + } + + public String getTzhUrls() { + return tzhUrls; + } + + public void setTzhUrls(String tzhUrls) { + this.tzhUrls = tzhUrls; + } + + public List getTzhUrl() { + return tzhUrl; + } + + public void setTzhUrl(List tzhUrl) { + this.tzhUrl = tzhUrl; + } + + public List getWgtzhUrl() { + return wgtzhUrl; + } + + public void setWgtzhUrl(List wgtzhUrl) { + this.wgtzhUrl = wgtzhUrl; + } + + public List getZfpzUrl() { + return zfpzUrl; + } + + public void setZfpzUrl(List zfpzUrl) { + this.zfpzUrl = zfpzUrl; + } + + public void setId(String id) { + this.id = id; + } + + public String getBillid() { + return billid; + } + + public void setBillid(String billid) { + this.billid = billid; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAccountname() { + return accountname; + } + + public void setAccountname(String accountname) { + this.accountname = accountname; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public double getSubtotal() { + return subtotal; + } + + public void setSubtotal(double subtotal) { + this.subtotal = subtotal; + } + + public double getFreight() { + return freight; + } + + public void setFreight(double freight) { + this.freight = freight; + } + + public String getManager() { + return manager; + } + + public void setManager(String manager) { + this.manager = manager; + } + + public String getManagername() { + return managername; + } + + public void setManagername(String managername) { + this.managername = managername; + } + + public String getConsignee() { + return consignee; + } + + public void setConsignee(String consignee) { + this.consignee = consignee; + } + + public String getConsigneephone() { + return consigneephone; + } + + public void setConsigneephone(String consigneephone) { + this.consigneephone = consigneephone; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getProvincename() { + return provincename; + } + + public void setProvincename(String provincename) { + this.provincename = provincename; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCityname() { + return cityname; + } + + public void setCityname(String cityname) { + this.cityname = cityname; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getAreaname() { + return areaname; + } + + public void setAreaname(String areaname) { + this.areaname = areaname; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getReceiveway() { + return receiveway; + } + + public void setReceiveway(String receiveway) { + this.receiveway = receiveway; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getRemark1() { + return remark1; + } + + public void setRemark1(String remark1) { + this.remark1 = remark1; + } + + public String getLogisticsname() { + return logisticsname; + } + + public void setLogisticsname(String logisticsname) { + this.logisticsname = logisticsname; + } + + public String getLogisticscode() { + return logisticscode; + } + + public void setLogisticscode(String logisticscode) { + this.logisticscode = logisticscode; + } + + public String getLogisticstype() { + return logisticstype; + } + + public void setLogisticstype(String logisticstype) { + this.logisticstype = logisticstype; + } + + public String getLogisticsno() { + return logisticsno; + } + + public void setLogisticsno(String logisticsno) { + this.logisticsno = logisticsno; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } + + public List getPayments() { + return payments; + } + + public void setPayments(List payments) { + this.payments = payments; + } +} + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHgId.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHgId.java new file mode 100644 index 0000000..4707da0 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHgId.java @@ -0,0 +1,26 @@ +package abacus.springboot.example.api.view; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "回购Id列表" , name = "ApiBillHgId") +public class ApiBillHgId { + + @Schema(description="回购单单号", required = false, example="HG202411180001") + private String id; + + public ApiBillHgId() { + super(); + } + + public ApiBillHgId(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHgItem.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHgItem.java new file mode 100644 index 0000000..3c22411 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHgItem.java @@ -0,0 +1,130 @@ +package abacus.springboot.example.api.view; + +import com.alibaba.fastjson.JSONObject; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "回购明细" , name = "ApiBillHgItem") +public class ApiBillHgItem { + + @Schema(description = "明细序号", required = false, hidden = true, example = "2") + private Long id; + + @Schema(description = "状态", required = false, pattern = "终止:-1,待通知回购:1,已通知回购:2", example = "2") + private int status; + + @Schema(description = "商品编码", required = false, example = "00001") + private String product; + + @Schema(description = "商品名称", required = false, example = "钓鱼台") + private String productname; + + @Schema(description = "商品规格", required = false, example = "500ml*6") + private String spec; + + @Schema(description = "商品图片地址", required = false, example = "") + private JSONObject productphoto; + + @Schema(description = "收货单价", required = false, example = "10") + private double price; + + @Schema(description = "入库数量", required = false, example = "1") + private double quantity; + + @Schema(description = "入库件数", required = false, example = "1") + private double numbers; + + @Schema(description = "回购单价", required = false, example = "100") + private double hgprice; + + @Schema(description = "回购金额", required = false, example = "100") + private double hgamount; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public JSONObject getProductphoto() { + return productphoto; + } + + public void setProductphoto(JSONObject productphoto) { + this.productphoto = productphoto; + } + + public String getSpec() { + return spec; + } + + public void setSpec(String spec) { + this.spec = spec; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getProduct() { + return product; + } + + public void setProduct(String product) { + this.product = product; + } + + public String getProductname() { + return productname; + } + + public void setProductname(String productname) { + this.productname = productname; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public double getNumbers() { + return numbers; + } + + public void setNumbers(double numbers) { + this.numbers = numbers; + } + + public double getHgprice() { + return hgprice; + } + + public void setHgprice(double hgprice) { + this.hgprice = hgprice; + } + + public double getHgamount() { + return hgamount; + } + + public void setHgamount(double hgamount) { + this.hgamount = hgamount; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHgPayment.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHgPayment.java new file mode 100644 index 0000000..4dcb59e --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiBillHgPayment.java @@ -0,0 +1,74 @@ +package abacus.springboot.example.api.view; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "回购支付明细" , name = "ApiBillHgPayment") +public class ApiBillHgPayment { + + @Schema(description = "回购单号", required = false, example = "线下支付") + private String billhg; + + @Schema(description = "支付方式", required = false, example = "线下支付") + private String payment; + + @Schema(description = "支付金额", required = false, example = "1000") + private Double amount; + + @Schema(description = "账号名称", required = false, example = "张三") + private String zhmc; + + @Schema(description = "开发银行", required = false, example = "工商银行") + private String khyh; + + @Schema(description = "银行账号", required = false, example = "10102010201201021020101") + private String yhzh; + + + public String getBillhg() { + return billhg; + } + + public void setBillhg(String billhg) { + this.billhg = billhg; + } + + public String getPayment() { + return payment; + } + + public void setPayment(String payment) { + this.payment = payment; + } + + public Double getAmount() { + return amount; + } + + public void setAmount(Double amount) { + this.amount = amount; + } + + public String getZhmc() { + return zhmc; + } + + public void setZhmc(String zhmc) { + this.zhmc = zhmc; + } + + public String getKhyh() { + return khyh; + } + + public void setKhyh(String khyh) { + this.khyh = khyh; + } + + public String getYhzh() { + return yhzh; + } + + public void setYhzh(String yhzh) { + this.yhzh = yhzh; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBill.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBill.java new file mode 100644 index 0000000..9f4e9fd --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBill.java @@ -0,0 +1,142 @@ +package abacus.springboot.example.api.view; + +import java.util.Date; +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "稽查收货主单" , name = "ApiJcBill") +public class ApiJcBill { + + @Schema(description="稽查单号", required = false, example="JC202411180001") + private String id; + + @Schema(description="状态", required = false, pattern = "溯源驳回:-2,待提交:0,系统溯源验证通过:1,待溯源:2,待入库:3,入库待审核:4,已入库:5 ,部分回购:6,回购完成:7", example = "1") + private int status; + + @Schema(description = "收货产品", required = false, example = "钓鱼台") + private String goods; + + @Schema(description = "收货仓库编码", required = false, example = "9090025") + private String warehouse; + + @Schema(description = "收货仓库名称", required = false, example = "精品广州库") + private String warehousename; + + @Schema(description = "收货日期", required = false, example = "2024-11-11") + private String receivedt; + + @Schema(description = "收货数量", required = false, example = "10") + private double quantity; + + @Schema(description = "收货总金额", required = false, example = "9609") + private double subtotal; + + @Schema(description = "申请人编码", required = false, example = "zhangsan") + private String applicant; + + @Schema(description = "申请人名称", required = false, example = "张三") + private String applicantname; + + @Schema(description = "申请人时间", required = false, example = "2024-11-11 00:00:00") + private Date applicantdt; + + @Schema(description="稽查收货明细", required = false, example="") + private List items; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getGoods() { + return goods; + } + + public void setGoods(String goods) { + this.goods = goods; + } + + public String getWarehouse() { + return warehouse; + } + + public void setWarehouse(String warehouse) { + this.warehouse = warehouse; + } + + public String getWarehousename() { + return warehousename; + } + + public void setWarehousename(String warehousename) { + this.warehousename = warehousename; + } + + public String getReceivedt() { + return receivedt; + } + + public void setReceivedt(String receivedt) { + this.receivedt = receivedt; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public double getSubtotal() { + return subtotal; + } + + public void setSubtotal(double subtotal) { + this.subtotal = subtotal; + } + + public String getApplicant() { + return applicant; + } + + public void setApplicant(String applicant) { + this.applicant = applicant; + } + + public String getApplicantname() { + return applicantname; + } + + public void setApplicantname(String applicantname) { + this.applicantname = applicantname; + } + + public Date getApplicantdt() { + return applicantdt; + } + + public void setApplicantdt(Date applicantdt) { + this.applicantdt = applicantdt; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillCollect.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillCollect.java new file mode 100644 index 0000000..2f6755a --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillCollect.java @@ -0,0 +1,42 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "分页对象" , name = "ApiJcBillCollect") +public class ApiJcBillCollect { + + @Schema(description="总数", required = false, example="100") + private long total; + + @Schema(description="总页数", required = false, example="10") + private int totalPages; + + @Schema(description="稽查收货列表", required = false, example="") + private List bills; + + public long getTotal() { + return total; + } + + public void setTotal(long total) { + this.total = total; + } + + public int getTotalPages() { + return totalPages; + } + + public void setTotalPages(int totalPages) { + this.totalPages = totalPages; + } + + public List getBills() { + return bills; + } + + public void setBills(List bills) { + this.bills = bills; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillGoodsPhoto.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillGoodsPhoto.java new file mode 100644 index 0000000..19ccc1e --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillGoodsPhoto.java @@ -0,0 +1,75 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "货品图片" , name = "ApiJcBillGoodsPhoto") +public class ApiJcBillGoodsPhoto { + + @Schema(description = "明细序号", required = false, hidden = true, example = "2") + private Long id; + + @Schema(description = "状态", required = false, pattern = "人工朔源驳回:-2,系统朔源验证未通过(无结果):-1,系统溯源未验证:0,系统朔源验证通过:1,人工朔源待确认:2,人工朔源已确认:3", example = "2") + private int status; + + @Schema(description = "货品编号", required = false, example = "B20181118-001") + private String goodsid; + + @Schema(description = "物流码", required = false, example = "HTTPS://M.DIAOYUTAIJI") + private String logisticsid; + + @Schema(description = "驳回原因", required = true, example = "") + private String reason; + + @Schema(description = "货品图片", required = false, pattern = "这是个JSON数组,不是JSONArray对象", example = "[\"44444\",\"aaaaa\"]") + private List goodsPhotos; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getLogisticsid() { + return logisticsid; + } + + public void setLogisticsid(String logisticsid) { + this.logisticsid = logisticsid; + } + + public String getGoodsid() { + return goodsid; + } + + public void setGoodsid(String goodsid) { + this.goodsid = goodsid; + } + + public List getGoodsPhotos() { + return goodsPhotos; + } + + public void setGoodsPhotos(List goodsPhotos) { + this.goodsPhotos = goodsPhotos; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillHgSearch.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillHgSearch.java new file mode 100644 index 0000000..93cbb25 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillHgSearch.java @@ -0,0 +1,42 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "分页对象" , name = "ApiJcBillHgSearch") +public class ApiJcBillHgSearch { + + @Schema(description="总数", required = false, example="100") + private long total; + + @Schema(description="总页数", required = false, example="10") + private int totalPages; + + @Schema(description="回购订单列表", required = false, example="") + private List items; + + public long getTotal() { + return total; + } + + public void setTotal(long total) { + this.total = total; + } + + public int getTotalPages() { + return totalPages; + } + + public void setTotalPages(int totalPages) { + this.totalPages = totalPages; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillHgSearchItem.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillHgSearchItem.java new file mode 100644 index 0000000..d097ac4 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillHgSearchItem.java @@ -0,0 +1,176 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import abacus.springboot.example.dao.JcBillPhoto; +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "回购订单列表" , name = "ApiJcBillHgSearchItem") +public class ApiJcBillHgSearchItem { + + @Schema(description="回购订单号", required = false, example="HG202412080001") + private String billHg; + + @Schema(description="状态", required = false, pattern = "待提交:1,待付款:2,待分仓(已付款):3,已分仓(待出库):4,已出库:5", example = "1") + private int status; + + @Schema(description="客户编码", required = false, example="2020089") + private String account; + + @Schema(description="回购订单号", required = false, example="广东众之品酒有限公司") + private String accountname; + + @Schema(description="运营经理编码", required = false, example="zhangsan") + private String manager; + + @Schema(description="运营经理名称", required = false, example="张三") + private String managername; + + @Schema(description="品种个数", required = false, example="1") + private int breednum; + + @Schema(description="件数", required = false, example="2") + private int numbers; + + @Schema(description = "物流公司名称", required = false, example = "京东") + private String logisticsname; + + @Schema(description = "物流单号", required = false, example = "JD20240000001") + private String logisticsno; + + @Schema(description = "金额", required = false, example = "1000") + private double subtotal; + + @Schema(description="回购通知函", required = false, example="") + private String tzhUrl; + + @Schema(description="违规回购通知函", required = false, example="") + private List wgtzhUrl; + + @Schema(description="支付凭证", required = false, example="") + private List zfpzUrl; + + @Schema(description="支付方式", required = false, example="") + private List payments; + + public double getSubtotal() { + return subtotal; + } + + public void setSubtotal(double subtotal) { + this.subtotal = subtotal; + } + + public List getPayments() { + return payments; + } + + public void setPayments(List payments) { + this.payments = payments; + } + + public String getTzhUrl() { + return tzhUrl; + } + + public void setTzhUrl(String tzhUrl) { + this.tzhUrl = tzhUrl; + } + + public List getWgtzhUrl() { + return wgtzhUrl; + } + + public void setWgtzhUrl(List wgtzhUrl) { + this.wgtzhUrl = wgtzhUrl; + } + + public List getZfpzUrl() { + return zfpzUrl; + } + + public void setZfpzUrl(List zfpzUrl) { + this.zfpzUrl = zfpzUrl; + } + + public String getBillHg() { + return billHg; + } + + public void setBillHg(String billHg) { + this.billHg = billHg; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAccountname() { + return accountname; + } + + public void setAccountname(String accountname) { + this.accountname = accountname; + } + + public String getManager() { + return manager; + } + + public void setManager(String manager) { + this.manager = manager; + } + + public String getManagername() { + return managername; + } + + public void setManagername(String managername) { + this.managername = managername; + } + + public int getBreednum() { + return breednum; + } + + public void setBreednum(int breednum) { + this.breednum = breednum; + } + + public int getNumbers() { + return numbers; + } + + public void setNumbers(int numbers) { + this.numbers = numbers; + } + + public String getLogisticsname() { + return logisticsname; + } + + public void setLogisticsname(String logisticsname) { + this.logisticsname = logisticsname; + } + + public String getLogisticsno() { + return logisticsno; + } + + public void setLogisticsno(String logisticsno) { + this.logisticsno = logisticsno; + } + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillItem.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillItem.java new file mode 100644 index 0000000..54bafe7 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillItem.java @@ -0,0 +1,130 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "稽查收货明细" , name = "ApiJcBillItem") +public class ApiJcBillItem { + + @Schema(description = "明细序号", required = false, hidden = true, example = "2") + private Long id; + + @Schema(description = "行号", required = false, pattern = "修改时必填", example = "2") + private int indexno; + + @Schema(description = "收货来源", required = false, example = "掌上华致") + private String recsource; + + @Schema(description = "收货渠道", required = false, example = "线下") + private String channel; + + @Schema(description = "收货平台", required = true, example = "") + private String recplatform; + + @Schema(description = "收货单价", required = false, example = "100") + private double price; + + @Schema(description = "收货数量", required = false, example = "10") + private double quantity; + + @Schema(description = "收货件数", required = false, example = "1") + private double numbers; + + @Schema(description = "收货金额", required = false, example = "1000") + private double subtotal; + + @Schema(description = "付款图片", required = false, pattern = "这是个JSON数组,不是JSONArray对象", example = "[\"44444\",\"aaaaa\"]") + private List paymentPhoto; + + @Schema(description = "货品图片", required = false, pattern = "", example = "") + private List goodsPhotos; + + public String getRecplatform() { + return recplatform; + } + + public void setRecplatform(String recplatform) { + this.recplatform = recplatform; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getRecsource() { + return recsource; + } + + public void setRecsource(String recsource) { + this.recsource = recsource; + } + + public String getChannel() { + return channel; + } + + public void setChannel(String channel) { + this.channel = channel; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public double getNumbers() { + return numbers; + } + + public void setNumbers(double numbers) { + this.numbers = numbers; + } + + public double getSubtotal() { + return subtotal; + } + + public void setSubtotal(double subtotal) { + this.subtotal = subtotal; + } + + public List getPaymentPhoto() { + return paymentPhoto; + } + + public void setPaymentPhoto(List paymentPhoto) { + this.paymentPhoto = paymentPhoto; + } + + public int getIndexno() { + return indexno; + } + + public void setIndexno(int indexno) { + this.indexno = indexno; + } + + public List getGoodsPhotos() { + return goodsPhotos; + } + + public void setGoodsPhotos(List goodsPhotos) { + this.goodsPhotos = goodsPhotos; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillSearch.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillSearch.java new file mode 100644 index 0000000..5e13856 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiJcBillSearch.java @@ -0,0 +1,73 @@ +package abacus.springboot.example.api.view; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "稽查收货列表" , name = "ApiJcBillSearch") +public class ApiJcBillSearch { + + @Schema(description="稽查单号", required = false, example="JC202411180001") + private String billid; + + @Schema(description = "收货日期", required = false, example = "2024-11-11") + private String receivedt; + + @Schema(description = "收货产品", required = false, example = "荷花") + private String goods; + + @Schema(description = "收货数量", required = false, example = "6") + private double quantity; + + @Schema(description="状态", required = false, pattern = "溯源驳回:-2,待提交:0,系统溯源验证通过:1,待溯源:2,待入库:3,入库待审核:4,已入库:5 ,部分回购:6,回购完成:7", example = "1") + private int status; + + @Schema(hidden = true) + private int hgstatus; + + public int getHgstatus() { + return hgstatus; + } + + public void setHgstatus(int hgstatus) { + this.hgstatus = hgstatus; + } + + public String getBillid() { + return billid; + } + + public void setBillid(String billid) { + this.billid = billid; + } + + public String getReceivedt() { + return receivedt; + } + + public void setReceivedt(String receivedt) { + this.receivedt = receivedt; + } + + public String getGoods() { + return goods; + } + + public void setGoods(String goods) { + this.goods = goods; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBill.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBill.java new file mode 100644 index 0000000..8b5e22e --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBill.java @@ -0,0 +1,97 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "稽查收货主单" , name = "ApiReqJcBill") +public class ApiReqJcBill { + + @Schema(description="稽查单号", required = false, pattern = "修改时必填", example="JC202411180001") + private String id; + + @Schema(description = "收货产品", required = false, example = "钓鱼台") + private String goods; + + @Schema(description = "收货日期", required = false, example = "2024-11-11") + private String receivedt; + + @Schema(description = "收货仓库编码", required = false, example = "9090025") + private String warehouse; + + @Schema(description = "收货仓库名称", required = false, example = "精品广州库") + private String warehousename; + + @Schema(description = "申请人编码", required = true, example = "zhangsan") + private String applicant; + + @Schema(description = "申请人名称", required = true, example = "张三") + private String applicantname; + + @Schema(description="稽查收货明细", required = false, example="") + private List items; + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getGoods() { + return goods; + } + + public void setGoods(String goods) { + this.goods = goods; + } + + public String getReceivedt() { + return receivedt; + } + + public void setReceivedt(String receivedt) { + this.receivedt = receivedt; + } + + public String getWarehouse() { + return warehouse; + } + + public void setWarehouse(String warehouse) { + this.warehouse = warehouse; + } + + public String getWarehousename() { + return warehousename; + } + + public void setWarehousename(String warehousename) { + this.warehousename = warehousename; + } + + public String getApplicant() { + return applicant; + } + + public void setApplicant(String applicant) { + this.applicant = applicant; + } + + public String getApplicantname() { + return applicantname; + } + + public void setApplicantname(String applicantname) { + this.applicantname = applicantname; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillGoodsPhoto.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillGoodsPhoto.java new file mode 100644 index 0000000..8bd06d5 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillGoodsPhoto.java @@ -0,0 +1,42 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "货品图片" , name = "ApiReqJcBillGoodsPhoto") +public class ApiReqJcBillGoodsPhoto { + + @Schema(description = "货品编号", required = false, example = "B20181118-001") + private String goodsid; + + @Schema(description = "物流码", required = false, example = "HTTPS://M.DIAOYUTAIJI") + private String logisticsid; + + @Schema(description = "货品图片", required = false, pattern = "这是个JSON数组,不是JSONArray对象", example = "[\"44444\",\"aaaaa\"]") + private List goodsPhotos; + + public String getLogisticsid() { + return logisticsid; + } + + public void setLogisticsid(String logisticsid) { + this.logisticsid = logisticsid; + } + + public String getGoodsid() { + return goodsid; + } + + public void setGoodsid(String goodsid) { + this.goodsid = goodsid; + } + + public List getGoodsPhotos() { + return goodsPhotos; + } + + public void setGoodsPhotos(List goodsPhotos) { + this.goodsPhotos = goodsPhotos; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillHg.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillHg.java new file mode 100644 index 0000000..ea90b54 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillHg.java @@ -0,0 +1,196 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "回购单主单" , name = "ApiReqJcBillHg") +public class ApiReqJcBillHg { + + @Schema(description="回购单单号", required = true, example="HG202411180001") + private String id; + + @Schema(description = "商品总金额", required = false, example = "4800") + private Double subtotal; + + @Schema(description = "运费", required = true, example = "50") + private Double freight; + + @Schema(description = "收货人姓名", required = true, example = "李四") + private String consignee; + + @Schema(description = "收货人电话", required = true, example = "1888888888") + private String consigneephone; + + @Schema(description = "省", required = false, example = "10001") + private String province; + + @Schema(description = "省", required = true, example = "广东") + private String provincename; + + @Schema(description = "市", required = false, example = "1000101") + private String city; + + @Schema(description = "市", required = true, example = "广州") + private String cityname; + + @Schema(description = "区", required = false, example = "100010101") + private String area; + + @Schema(description = "区", required = true, example = "越秀区") + private String areaname; + + @Schema(description = "详细地址", required = true, example = "东风24路") + private String address; + + @Schema(description = "订单备注", required = false, example = "订单备注~~~") + private String remark; + + @Schema(description = "运营备注", required = false, example = "运营备注~~~") + private String remark1; + + @Schema(description = "提交人编码", required = true, example = "zhangsan") + private String submit; + + @Schema(description = "提交人名称", required = true, example = "张三") + private String submitname; + + @Schema(description = "回购支付明细", required = true, example = "") + private List payments; + + public List getPayments() { + return payments; + } + + public void setPayments(List payments) { + this.payments = payments; + } + + public String getSubmit() { + return submit; + } + + public void setSubmit(String submit) { + this.submit = submit; + } + + public String getSubmitname() { + return submitname; + } + + public void setSubmitname(String submitname) { + this.submitname = submitname; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Double getSubtotal() { + return subtotal; + } + + public void setSubtotal(Double subtotal) { + this.subtotal = subtotal; + } + + public Double getFreight() { + return freight; + } + + public void setFreight(Double freight) { + this.freight = freight; + } + + public String getConsignee() { + return consignee; + } + + public void setConsignee(String consignee) { + this.consignee = consignee; + } + + public String getConsigneephone() { + return consigneephone; + } + + public void setConsigneephone(String consigneephone) { + this.consigneephone = consigneephone; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getProvincename() { + return provincename; + } + + public void setProvincename(String provincename) { + this.provincename = provincename; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCityname() { + return cityname; + } + + public void setCityname(String cityname) { + this.cityname = cityname; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getAreaname() { + return areaname; + } + + public void setAreaname(String areaname) { + this.areaname = areaname; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getRemark1() { + return remark1; + } + + public void setRemark1(String remark1) { + this.remark1 = remark1; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillItem.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillItem.java new file mode 100644 index 0000000..8abaa47 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillItem.java @@ -0,0 +1,130 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "稽查收货明细" , name = "ApiReqJcBillItem") +public class ApiReqJcBillItem { + + @Schema(description = "明细序号", required = false, pattern = "修改时必填", example = "2") + private Long id; + + @Schema(description = "行号", required = false, pattern = "修改时必填", example = "2") + private int indexno; + + @Schema(description = "收货来源", required = false, example = "线下") + private String recsource; + + @Schema(description = "收货平台", required = false, example = "") + private String recplatform; + + @Schema(description = "收货渠道", required = false, example = "XXX烟酒店") + private String channel; + + @Schema(description = "收货单价", required = false, example = "100") + private Double price; + + @Schema(description = "收货数量", required = false, example = "10") + private Double quantity; + + @Schema(description = "收货件数", required = false, example = "1") + private Double numbers; + + @Schema(description = "收货金额", required = false, example = "1000") + private Double subtotal; + + @Schema(description = "付款图片", required = false, pattern = "这是个JSON数组,不是JSONArray对象", example = "[\"44444\",\"aaaaa\"]") + private List paymentPhoto; + + @Schema(description = "货品图片", required = false, pattern = "", example = "") + private List goodsPhotos; + + public List getGoodsPhotos() { + return goodsPhotos; + } + + public void setGoodsPhotos(List goodsPhotos) { + this.goodsPhotos = goodsPhotos; + } + + public int getIndexno() { + return indexno; + } + + public void setIndexno(int indexno) { + this.indexno = indexno; + } + + public String getRecplatform() { + return recplatform; + } + + public void setRecplatform(String recplatform) { + this.recplatform = recplatform; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getRecsource() { + return recsource; + } + + public void setRecsource(String recsource) { + this.recsource = recsource; + } + + public String getChannel() { + return channel; + } + + public void setChannel(String channel) { + this.channel = channel; + } + + public Double getPrice() { + return price; + } + + public void setPrice(Double price) { + this.price = price; + } + + public Double getQuantity() { + return quantity; + } + + public void setQuantity(Double quantity) { + this.quantity = quantity; + } + + public Double getNumbers() { + return numbers; + } + + public void setNumbers(Double numbers) { + this.numbers = numbers; + } + + public Double getSubtotal() { + return subtotal; + } + + public void setSubtotal(Double subtotal) { + this.subtotal = subtotal; + } + + public List getPaymentPhoto() { + return paymentPhoto; + } + + public void setPaymentPhoto(List paymentPhoto) { + this.paymentPhoto = paymentPhoto; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillPayment.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillPayment.java new file mode 100644 index 0000000..bb68f6b --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillPayment.java @@ -0,0 +1,62 @@ +package abacus.springboot.example.api.view; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "回购支付明细" , name = "ApiReqJcBillPayment") +public class ApiReqJcBillPayment { + + @Schema(description = "支付方式", required = true, example = "线下付款") + private String payment; + + @Schema(description = "支付金额", required = true, example = "4820") + private Double amount; + + @Schema(description = "账号名称", required = true, example = "张三") + private String zhmc; + + @Schema(description = "开发银行", required = true, example = "工商银行") + private String khyh; + + @Schema(description = "银行账号", required = true, example = "0101020102102010210201") + private String yhzh; + + public String getPayment() { + return payment; + } + + public void setPayment(String payment) { + this.payment = payment; + } + + public Double getAmount() { + return amount; + } + + public void setAmount(Double amount) { + this.amount = amount; + } + + public String getZhmc() { + return zhmc; + } + + public void setZhmc(String zhmc) { + this.zhmc = zhmc; + } + + public String getKhyh() { + return khyh; + } + + public void setKhyh(String khyh) { + this.khyh = khyh; + } + + public String getYhzh() { + return yhzh; + } + + public void setYhzh(String yhzh) { + this.yhzh = yhzh; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillPhoto.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillPhoto.java new file mode 100644 index 0000000..550bd2d --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillPhoto.java @@ -0,0 +1,29 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "图片对象" , name = "ApiReqJcBillPhoto") +public class ApiReqJcBillPhoto { + + @Schema(description = "回购单号、溯源入库单号", pattern="type=1时,为溯源入库单号,type=2时,为回购单号",required = true, example = "HG202411180001") + private String id; + + @Schema(description = "图片明细", required = true, example = "") + private List items; + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillPhotoItem.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillPhotoItem.java new file mode 100644 index 0000000..c9f228c --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiReqJcBillPhotoItem.java @@ -0,0 +1,32 @@ +package abacus.springboot.example.api.view; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "图片明细" , name = "ApiReqJcBillPhotoItem") +public class ApiReqJcBillPhotoItem { + + @Schema(description = "货品编号", pattern="type=1时,必填",required = false, example = "HG202411180001") + private String id; + + @Schema(description = "图片类型", required = true, pattern = "回购违规通知函、回购支付凭证、稽查付款截图、稽查货品图", example = "回购违规通知函") + private String typePhoto; + + @Schema(description = "图片地址", required = true, example = "http:ip/1.jpg") + private String urlPhoto; + + public String getTypePhoto() { + return typePhoto; + } + + public void setTypePhoto(String typePhoto) { + this.typePhoto = typePhoto; + } + + public String getUrlPhoto() { + return urlPhoto; + } + + public void setUrlPhoto(String urlPhoto) { + this.urlPhoto = urlPhoto; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespBillHgPay.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespBillHgPay.java new file mode 100644 index 0000000..9185a3e --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespBillHgPay.java @@ -0,0 +1,51 @@ +package abacus.springboot.example.api.view; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "回购支付方式" , name = "ApiRespBillHgPay") +public class ApiRespBillHgPay { + + @Schema(description = "支付方式", required = false, example = "线下支付") + private String payment; + + @Schema(description = "账号名称", required = false, example = "张三") + private String zhmc; + + @Schema(description = "开发银行", required = false, example = "工商银行") + private String khyh; + + @Schema(description = "银行账号", required = false, example = "10021020120102102012010") + private String yhzh; + + public String getPayment() { + return payment; + } + + public void setPayment(String payment) { + this.payment = payment; + } + + public String getZhmc() { + return zhmc; + } + + public void setZhmc(String zhmc) { + this.zhmc = zhmc; + } + + public String getKhyh() { + return khyh; + } + + public void setKhyh(String khyh) { + this.khyh = khyh; + } + + public String getYhzh() { + return yhzh; + } + + public void setYhzh(String yhzh) { + this.yhzh = yhzh; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorduct.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorduct.java new file mode 100644 index 0000000..3d04671 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorduct.java @@ -0,0 +1,64 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "稽查货品" , name = "ApiRespJcPorduct") +public class ApiRespJcPorduct { + + @Schema(description="稽查单号", required = false, example="JC202501090002") + private String billId; + + @Schema(description="入库单号", required = false, example="WDT2292992992") + private String stockInId; + + @Schema(description="回购单号", required = false, example="HG202501090002") + private String hgId; + + @Schema(description="出库单号", required = false, example="WDTCK202501090001") + private String stockOutId; + + @Schema(description="客户信息", required = false, example="") + private List accounts; + + public String getBillId() { + return billId; + } + + public void setBillId(String billId) { + this.billId = billId; + } + + public String getStockInId() { + return stockInId; + } + + public void setStockInId(String stockInId) { + this.stockInId = stockInId; + } + + public String getHgId() { + return hgId; + } + + public void setHgId(String hgId) { + this.hgId = hgId; + } + + public String getStockOutId() { + return stockOutId; + } + + public void setStockOutId(String stockOutId) { + this.stockOutId = stockOutId; + } + + public List getAccounts() { + return accounts; + } + + public void setAccounts(List accounts) { + this.accounts = accounts; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorductAcount.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorductAcount.java new file mode 100644 index 0000000..6156ee4 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorductAcount.java @@ -0,0 +1,42 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "稽查货品-客户信息" , name = "ApiRespJcPorductAcount") +public class ApiRespJcPorductAcount { + + @Schema(description="客户编码", required = false, example="1050000322") + private String account; + + @Schema(description="客户名称", required = false, example="四川有限公司") + private String accountName; + + @Schema(description="商品信息", required = false, example="") + private List products; + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAccountName() { + return accountName; + } + + public void setAccountName(String accountName) { + this.accountName = accountName; + } + + public List getProducts() { + return products; + } + + public void setProducts(List products) { + this.products = products; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorductItem.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorductItem.java new file mode 100644 index 0000000..1f474dd --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorductItem.java @@ -0,0 +1,31 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "稽查货品-货品信息" , name = "ApiRespJcPorductItem") +public class ApiRespJcPorductItem { + + @Schema(description = "货品图片", required = true, example = "") + private List photos; + + @Schema(description = "货品编号", required = true, example = "") + private String goodsId; + + public List getPhotos() { + return photos; + } + + public void setPhotos(List photos) { + this.photos = photos; + } + + public String getGoodsId() { + return goodsId; + } + + public void setGoodsId(String goodsId) { + this.goodsId = goodsId; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorductProduct.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorductProduct.java new file mode 100644 index 0000000..3088446 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespJcPorductProduct.java @@ -0,0 +1,53 @@ +package abacus.springboot.example.api.view; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "稽查货品-商品信息" , name = "ApiRespJcPorductProduct") +public class ApiRespJcPorductProduct { + + @Schema(description="商品编码", required = false, example="1010400021") + private String product; + + @Schema(description="商品名称", required = false, example="52度500ml五粮液") + private String productName; + + @Schema(description="数量", required = false, example="12瓶/2件") + private String quantity; + + @Schema(description="货品信息", required = false, example="") + private List items; + + public String getProduct() { + return product; + } + + public void setProduct(String product) { + this.product = product; + } + + public String getProductName() { + return productName; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public String getQuantity() { + return quantity; + } + + public void setQuantity(String quantity) { + this.quantity = quantity; + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespReceiveGoods.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespReceiveGoods.java new file mode 100644 index 0000000..a370c74 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespReceiveGoods.java @@ -0,0 +1,40 @@ +package abacus.springboot.example.api.view; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "收货信息" , name = "ApiRespReceiveGoods") +public class ApiRespReceiveGoods { + + @Schema(description = "稽查单号", required = false, example = "JC202411180001") + private String billid; + + @Schema(description = "物流码", required = true, example = "") + private String logisticsid; + + @Schema(description = "出库单号", required = true, example = "") + private String billout; + + public String getBillid() { + return billid; + } + + public void setBillid(String billid) { + this.billid = billid; + } + + public String getLogisticsid() { + return logisticsid; + } + + public void setLogisticsid(String logisticsid) { + this.logisticsid = logisticsid; + } + + public String getBillout() { + return billout; + } + + public void setBillout(String billout) { + this.billout = billout; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespWarehouse.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespWarehouse.java new file mode 100644 index 0000000..9b7e663 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/ApiRespWarehouse.java @@ -0,0 +1,26 @@ +package abacus.springboot.example.api.view; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Schema(description = "收货仓库" , name = "ApiRespWarehouse") +public class ApiRespWarehouse { + + @Schema(description = "收货仓库编码", required = false, example = "0001") + private String code; + + @Schema(description = "收货仓库名称", required = false, example = "四川仓") + private String name; + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/EdgBcsCode.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/EdgBcsCode.java new file mode 100644 index 0000000..c0652a4 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/EdgBcsCode.java @@ -0,0 +1,123 @@ +package abacus.springboot.example.api.view; + +/** + *

Title:EdgBcsCode

+

Description:睿治物流码溯源查询接口-返回参数

+ @author chuanZeng + @date 2024年12月11日 + */ +public class EdgBcsCode { + private String code;// 物流码字符串 + private String ck_id;// 出库单号字符串 + private String dccw_id;// 出库仓编码字符串 + private String dccw_name;// 出库仓名称字符串 + private String cdt;// 出库⽇期字符串 + private String productid;// 商品编码字符串 + private String productname;// 商品名称字符串 + private String customerid;// 客户编码字符串 + private String customername;// 客户名称字符串 + private String employeeid;// 业务员编码字符串 + private String employeename;// 业务员名称字符串 + private String group_id;// 业务组编码字符串 + private String group_name;// 业务组名称字符串 + private String departmentid;// 分销区域编码字符串 + private String departmentname;// 分销区域名称字符串 + private String data_source;// 数据源来源字符串 + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getCk_id() { + return ck_id; + } + public void setCk_id(String ck_id) { + this.ck_id = ck_id; + } + public String getDccw_id() { + return dccw_id; + } + public void setDccw_id(String dccw_id) { + this.dccw_id = dccw_id; + } + public String getDccw_name() { + return dccw_name; + } + public void setDccw_name(String dccw_name) { + this.dccw_name = dccw_name; + } + public String getCdt() { + return cdt; + } + public void setCdt(String cdt) { + this.cdt = cdt; + } + public String getProductid() { + return productid; + } + public void setProductid(String productid) { + this.productid = productid; + } + public String getProductname() { + return productname; + } + public void setProductname(String productname) { + this.productname = productname; + } + public String getCustomerid() { + return customerid; + } + public void setCustomerid(String customerid) { + this.customerid = customerid; + } + public String getCustomername() { + return customername; + } + public void setCustomername(String customername) { + this.customername = customername; + } + public String getEmployeeid() { + return employeeid; + } + public void setEmployeeid(String employeeid) { + this.employeeid = employeeid; + } + public String getEmployeename() { + return employeename; + } + public void setEmployeename(String employeename) { + this.employeename = employeename; + } + public String getGroup_id() { + return group_id; + } + public void setGroup_id(String group_id) { + this.group_id = group_id; + } + public String getGroup_name() { + return group_name; + } + public void setGroup_name(String group_name) { + this.group_name = group_name; + } + public String getDepartmentid() { + return departmentid; + } + public void setDepartmentid(String departmentid) { + this.departmentid = departmentid; + } + public String getDepartmentname() { + return departmentname; + } + public void setDepartmentname(String departmentname) { + this.departmentname = departmentname; + } + public String getData_source() { + return data_source; + } + public void setData_source(String data_source) { + this.data_source = data_source; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcBillCount.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcBillCount.java new file mode 100644 index 0000000..4392622 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcBillCount.java @@ -0,0 +1,25 @@ +package abacus.springboot.example.api.view; + +public class JcBillCount { + private String id;// 回购单号 + private int breednum;// 品种个数 + private int numbers;// 件数 + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public int getBreednum() { + return breednum; + } + public void setBreednum(int breednum) { + this.breednum = breednum; + } + public int getNumbers() { + return numbers; + } + public void setNumbers(int numbers) { + this.numbers = numbers; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcCodeFlow.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcCodeFlow.java new file mode 100644 index 0000000..93c01d9 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcCodeFlow.java @@ -0,0 +1,123 @@ +package abacus.springboot.example.api.view; + +/** + *

Title:JcCodeFlow

+

Description: 根据物流码查询出的

+ @author chuanZeng + @date 2024年12月11日 + */ +public class JcCodeFlow { + + private String id;// 出库单号 + private String deposit;// 出库仓编码 + private String depositname;// 出库仓名称 + private String tdate;// 出库⽇期 + private String orderid;// 销售订单号 + private String customerid;// 客户编码 + private String customername;// 客户名称 + private String aprssalemanid;// 业务员编码 + private String aprssalemanname;// 业务员名称 + private String bizgroupid;// 业务组编码 + private String bizgroupname;// 业务组名称 + private String wsareaid;// 分销区域编码 + private String wsareaname;// 分销区域名称 + private String code;// 物流码 + private String productid;// 商品 + private String productname;// 商品名称 + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public String getDeposit() { + return deposit; + } + public void setDeposit(String deposit) { + this.deposit = deposit; + } + public String getDepositname() { + return depositname; + } + public void setDepositname(String depositname) { + this.depositname = depositname; + } + public String getTdate() { + return tdate; + } + public void setTdate(String tdate) { + this.tdate = tdate; + } + public String getOrderid() { + return orderid; + } + public void setOrderid(String orderid) { + this.orderid = orderid; + } + public String getCustomerid() { + return customerid; + } + public void setCustomerid(String customerid) { + this.customerid = customerid; + } + public String getCustomername() { + return customername; + } + public void setCustomername(String customername) { + this.customername = customername; + } + public String getAprssalemanid() { + return aprssalemanid; + } + public void setAprssalemanid(String aprssalemanid) { + this.aprssalemanid = aprssalemanid; + } + public String getAprssalemanname() { + return aprssalemanname; + } + public void setAprssalemanname(String aprssalemanname) { + this.aprssalemanname = aprssalemanname; + } + public String getBizgroupid() { + return bizgroupid; + } + public void setBizgroupid(String bizgroupid) { + this.bizgroupid = bizgroupid; + } + public String getBizgroupname() { + return bizgroupname; + } + public void setBizgroupname(String bizgroupname) { + this.bizgroupname = bizgroupname; + } + public String getWsareaid() { + return wsareaid; + } + public void setWsareaid(String wsareaid) { + this.wsareaid = wsareaid; + } + public String getWsareaname() { + return wsareaname; + } + public void setWsareaname(String wsareaname) { + this.wsareaname = wsareaname; + } + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } + public String getProductid() { + return productid; + } + public void setProductid(String productid) { + this.productid = productid; + } + public String getProductname() { + return productname; + } + public void setProductname(String productname) { + this.productname = productname; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcProduct.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcProduct.java new file mode 100644 index 0000000..62088f7 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcProduct.java @@ -0,0 +1,84 @@ +package abacus.springboot.example.api.view; + +// 货品查询 +public class JcProduct { + + private String billid; + private String billin; + private String billhg; + private String account; + private String accountname; + private String product; + private String productname; + private String wdtbillout; + private int quantity; + private int numbers; + private String goodsid; + + public String getGoodsid() { + return goodsid; + } + public void setGoodsid(String goodsid) { + this.goodsid = goodsid; + } + public int getQuantity() { + return quantity; + } + public void setQuantity(int quantity) { + this.quantity = quantity; + } + public int getNumbers() { + return numbers; + } + public void setNumbers(int numbers) { + this.numbers = numbers; + } + public String getBillid() { + return billid; + } + public void setBillid(String billid) { + this.billid = billid; + } + public String getBillin() { + return billin; + } + public void setBillin(String billin) { + this.billin = billin; + } + public String getBillhg() { + return billhg; + } + public void setBillhg(String billhg) { + this.billhg = billhg; + } + public String getAccount() { + return account; + } + public void setAccount(String account) { + this.account = account; + } + public String getAccountname() { + return accountname; + } + public void setAccountname(String accountname) { + this.accountname = accountname; + } + public String getProduct() { + return product; + } + public void setProduct(String product) { + this.product = product; + } + public String getProductname() { + return productname; + } + public void setProductname(String productname) { + this.productname = productname; + } + public String getWdtbillout() { + return wdtbillout; + } + public void setWdtbillout(String wdtbillout) { + this.wdtbillout = wdtbillout; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcProductBillSouce.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcProductBillSouce.java new file mode 100644 index 0000000..6c49e1e --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/api/view/JcProductBillSouce.java @@ -0,0 +1,41 @@ +package abacus.springboot.example.api.view; + +public class JcProductBillSouce { + + private String indexno; + private String billid; + private String account; + private String product; + private String goodsid; + + public String getIndexno() { + return indexno; + } + public void setIndexno(String indexno) { + this.indexno = indexno; + } + public String getBillid() { + return billid; + } + public void setBillid(String billid) { + this.billid = billid; + } + public String getAccount() { + return account; + } + public void setAccount(String account) { + this.account = account; + } + public String getProduct() { + return product; + } + public void setProduct(String product) { + this.product = product; + } + public String getGoodsid() { + return goodsid; + } + public void setGoodsid(String goodsid) { + this.goodsid = goodsid; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/config/JcConfigKey.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/config/JcConfigKey.java new file mode 100644 index 0000000..d4b15ca --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/config/JcConfigKey.java @@ -0,0 +1,37 @@ +package abacus.springboot.example.config; + +/** + *

Title:JcConfigKey

+

Description: 配置key的值

+ @author chuanZeng + @date 2026年8月18日 + */ +public class JcConfigKey { + + /** keyGroup:系统号*/ + public static final String KEY_GROUP = "jc"; + + /** 二维码域名*/ + public static final String KEY_JC_SCAN_SOURCE = "jc.scan.source"; + + /** 固定店铺编码*/ + public static final String KEY_JC_WDT_DEPT = "jc.wdt.dept"; + + /** 是否自动分仓*/ + public static final String KEY_JC_WDT_FCFLAGE = "jc.wdt.fcFlage"; + + /** ERP-url*/ + public static final String KEY_JC_ERP_URL = "jc.erp.url"; + + /** set:线下支付*/ + public static final String KEY_JC_PAYMENT_OFFLINE = "jc.payment.offline"; + /** jc.payment.offline:账号名称*/ + public static final String KEY_JC_ZHMC = "zhmc"; + /** jc.payment.offline:开户银行*/ + public static final String KEY_JC_KHYH = "khyh"; + /** jc.payment.offline:银行账号*/ + public static final String KEY_JC_YHZH = "yhzh"; + + /** set:稽查收货仓库*/ + public static final String KEY_JC_WAREHOUSE = "jc.warehouse"; +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/config/JcConfiguration.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/config/JcConfiguration.java new file mode 100644 index 0000000..a13e1bc --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/config/JcConfiguration.java @@ -0,0 +1,175 @@ +package abacus.springboot.example.config; + +import java.util.ArrayList; +import java.util.List; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import abacus.config.dao.AbacusConfig; +import abacus.config.dao.AbacusConfigItem; +import abacus.config.wso.AbacusConfigNote; + +/** + *

Title:JcConfiguration

+

Description: 系统配置定义

+ @author chuanZeng + @date 2024年12月9日 + */ +@Configuration +public class JcConfiguration { + + @Bean + public AbacusConfigNote key_jc_scan_source() { + AbacusConfigNote abacusConfigNote = new AbacusConfigNote(); + + AbacusConfig abacusConfig = new AbacusConfig(); + abacusConfig.setKeyGroup(JcConfigKey.KEY_GROUP); + abacusConfig.setKey(JcConfigKey.KEY_JC_SCAN_SOURCE); + abacusConfig.setValueType(AbacusConfig._Value); + abacusConfig.setValuees("http://c.ztyxkj.com/,https://scan.vatsliquor.com/logistic/,https://scan.vats.com.cn/scan/"); + abacusConfig.setProcedures("API"); + abacusConfig.setInsulate(null); + abacusConfig.setDescribe("溯源:二维码域名IP"); + + abacusConfigNote.setAbacusConfig(abacusConfig); + return abacusConfigNote; + } + + @Bean + public AbacusConfigNote key_jc_payment_offline() { + AbacusConfigNote abacusConfigNote = new AbacusConfigNote(); + + AbacusConfig abacusConfig = new AbacusConfig(); + abacusConfig.setKeyGroup(JcConfigKey.KEY_GROUP); + abacusConfig.setKey(JcConfigKey.KEY_JC_PAYMENT_OFFLINE); + abacusConfig.setValueType(AbacusConfig._Set); + abacusConfig.setValuees(null); + abacusConfig.setProcedures("API"); + abacusConfig.setInsulate(null); + abacusConfig.setDescribe("支付方式:线下支付"); + + List abacusConfigItems = new ArrayList(); + + AbacusConfigItem aci = new AbacusConfigItem(); + aci.setKeyGroup(JcConfigKey.KEY_GROUP); + aci.setKey(JcConfigKey.KEY_JC_PAYMENT_OFFLINE); + aci.setCode(JcConfigKey.KEY_JC_ZHMC); + aci.setName("张三"); + aci.setInsulate(null); + aci.setDescribe("账户名称"); + abacusConfigItems.add(aci); + + AbacusConfigItem aci1 = new AbacusConfigItem(); + aci1.setKeyGroup(JcConfigKey.KEY_GROUP); + aci1.setKey(JcConfigKey.KEY_JC_PAYMENT_OFFLINE); + aci1.setCode(JcConfigKey.KEY_JC_KHYH); + aci1.setName("工商银行"); + aci1.setInsulate(null); + aci1.setDescribe("开户银行"); + abacusConfigItems.add(aci1); + + AbacusConfigItem aci2 = new AbacusConfigItem(); + aci2.setKeyGroup(JcConfigKey.KEY_GROUP); + aci2.setKey(JcConfigKey.KEY_JC_PAYMENT_OFFLINE); + aci2.setCode(JcConfigKey.KEY_JC_YHZH); + aci2.setName("0101010020023090"); + aci2.setInsulate(null); + aci2.setDescribe("银行账户"); + abacusConfigItems.add(aci2); + + abacusConfigNote.setAbacusConfig(abacusConfig); + abacusConfigNote.setAbacusConfigItems(abacusConfigItems); + return abacusConfigNote; + } + + + @Bean + public AbacusConfigNote key_jc_wdt_dept() { + AbacusConfigNote abacusConfigNote = new AbacusConfigNote(); + + AbacusConfig abacusConfig = new AbacusConfig(); + abacusConfig.setKeyGroup(JcConfigKey.KEY_GROUP); + abacusConfig.setKey(JcConfigKey.KEY_JC_WDT_DEPT); + abacusConfig.setValueType(AbacusConfig._Value); + abacusConfig.setValuees("0001"); + abacusConfig.setProcedures("旺店通固定店铺编码"); + abacusConfig.setInsulate(null); + abacusConfig.setDescribe("旺店通固定店铺编码"); + + abacusConfigNote.setAbacusConfig(abacusConfig); + return abacusConfigNote; + } + + @Bean + public AbacusConfigNote key_jc_wdt_fcflage() { + AbacusConfigNote abacusConfigNote = new AbacusConfigNote(); + + AbacusConfig abacusConfig = new AbacusConfig(); + abacusConfig.setKeyGroup(JcConfigKey.KEY_GROUP); + abacusConfig.setKey(JcConfigKey.KEY_JC_WDT_FCFLAGE); + abacusConfig.setValueType(AbacusConfig._Value); + abacusConfig.setValuees("true"); + abacusConfig.setProcedures("是否自动分仓"); + abacusConfig.setInsulate(null); + abacusConfig.setDescribe("是否自动分仓"); + + abacusConfigNote.setAbacusConfig(abacusConfig); + return abacusConfigNote; + } + + @Bean + public AbacusConfigNote key_jc_erp_url() { + AbacusConfigNote abacusConfigNote = new AbacusConfigNote(); + + AbacusConfig abacusConfig = new AbacusConfig(); + abacusConfig.setKeyGroup(JcConfigKey.KEY_GROUP); + abacusConfig.setKey(JcConfigKey.KEY_JC_ERP_URL); + abacusConfig.setValueType(AbacusConfig._Value); + abacusConfig.setValuees("http://"); + abacusConfig.setProcedures("erp的IP"); + abacusConfig.setInsulate(null); + abacusConfig.setDescribe("erp的IP"); + + abacusConfigNote.setAbacusConfig(abacusConfig); + return abacusConfigNote; + } + + @Bean + public AbacusConfigNote key_jc_warehouse() { + AbacusConfigNote abacusConfigNote = new AbacusConfigNote(); + + AbacusConfig abacusConfig = new AbacusConfig(); + abacusConfig.setKeyGroup(JcConfigKey.KEY_GROUP); + abacusConfig.setKey(JcConfigKey.KEY_JC_WAREHOUSE); + abacusConfig.setValueType(AbacusConfig._Set); + abacusConfig.setValuees(null); + abacusConfig.setProcedures("API"); + abacusConfig.setInsulate(null); + abacusConfig.setDescribe("稽查收货仓库"); + +// List abacusConfigItems = new ArrayList(); +// +// AbacusConfigItem aci = new AbacusConfigItem(); +// aci.setKeyGroup(JcConfigKey.KEY_GROUP); +// aci.setKey(JcConfigKey.KEY_JC_WAREHOUSE); +// aci.setCode("237881"); +// aci.setName("江苏致众盐城仓库"); +// aci.setInsulate(null); +// aci.setDescribe("稽查收货仓库"); +// abacusConfigItems.add(aci); +// +// AbacusConfigItem aci1 = new AbacusConfigItem(); +// aci1.setKeyGroup(JcConfigKey.KEY_GROUP); +// aci1.setKey(JcConfigKey.KEY_JC_WAREHOUSE); +// aci1.setCode("288381"); +// aci1.setName("上海一区"); +// aci1.setInsulate(null); +// aci1.setDescribe("稽查收货仓库"); +// abacusConfigItems.add(aci1); + + abacusConfigNote.setAbacusConfig(abacusConfig); +// abacusConfigNote.setAbacusConfigItems(abacusConfigItems); + return abacusConfigNote; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/config/JcIdGeneratorConfig.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/config/JcIdGeneratorConfig.java new file mode 100644 index 0000000..4e8fc9e --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/config/JcIdGeneratorConfig.java @@ -0,0 +1,50 @@ +package abacus.springboot.example.config; + +import javax.persistence.EntityManager; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.abacus.xpos.foundation.pubs.DaoIdGenerator; + +/** + *

Title:JcIdGeneratorConfig

+

Description: ID生成器

+ @author chuanZeng + @date 2024年12月5日 + */ +@Configuration +public class JcIdGeneratorConfig { + + @Autowired + private EntityManager entityManager; + + @Bean(name="jcBillIdGenerator") + public DaoIdGenerator jcBillIdGenerator() { + DaoIdGenerator daoIdGenerator = new DaoIdGenerator(); + daoIdGenerator.setTargetTableName("jc_bill"); + daoIdGenerator.setPrefix("JC"); + daoIdGenerator.setTargetIdColumnName("id"); + daoIdGenerator.setSerialLength(4); + daoIdGenerator.setUseDAOId(false); + daoIdGenerator.setUseDateFormat(true); + //年月日 + daoIdGenerator.setDateFormat("yyyyMMdd"); + return daoIdGenerator; + } + + @Bean(name="jcBillHgIdGenerator") + public DaoIdGenerator jcBillHgIdGenerator() { + DaoIdGenerator daoIdGenerator = new DaoIdGenerator(); + daoIdGenerator.setTargetTableName("jc_billhg"); + daoIdGenerator.setPrefix("HG"); + daoIdGenerator.setTargetIdColumnName("id"); + daoIdGenerator.setSerialLength(4); + daoIdGenerator.setUseDAOId(false); + daoIdGenerator.setUseDateFormat(true); + //年月日 + daoIdGenerator.setDateFormat("yyyyMMdd"); + return daoIdGenerator; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/AutoCompleteController.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/AutoCompleteController.java new file mode 100644 index 0000000..fe57969 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/AutoCompleteController.java @@ -0,0 +1,168 @@ +package abacus.springboot.example.controller; + +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.abacus.xpos.foundation.dao.Dept; +import com.abacus.xpos.foundation.dao.Employee; + +import abacus.config.dao.AbacusConfigItem; +import abacus.springboot.example.config.JcConfigKey; +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.pi.AutoCompleteAccessIF; + +/** + *

+ * Title:AutoCompleteController + *

+ *

+ * Description: 前端检索查询-api + *

+ * + * @author chuanZeng + * @date 2022年4月26日 + */ +@RestController() +@RequestMapping(value = "/autoComplete") +public class AutoCompleteController extends BaseServlet { + + private static final Logger LOG = LoggerFactory.getLogger(AutoCompleteController.class); + + @Autowired + private AutoCompleteAccessIF autoCompleteAccess; + + /** + * 检索:收货仓库 + * + * @param request + * @param response + * @return + * @throws Throwable + */ + @RequestMapping(value = "abacusConfigItemGroupAutoComplete", method = RequestMethod.POST) + public List abacusConfigItemGroupAutoComplete(@RequestParam(required = false) String keyCode) throws Throwable { + try { + List objs = this.autoCompleteAccess.abacusConfigItemGroupAutoComplete(keyCode, JcConfigKey.KEY_GROUP, JcConfigKey.KEY_JC_WAREHOUSE); + return objs; + } catch (Throwable e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 检索:稽查 + * + * @param request + * @param response + * @return + * @throws Throwable + */ + @RequestMapping(value = "jcBillAutoComplete", method = RequestMethod.POST) + public List jcBillAutoComplete(@RequestParam(required = false) String keyCode) throws Throwable { + try { + List objs = this.autoCompleteAccess.jcBillAutoComplete(keyCode); + return objs; + } catch (Throwable e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 检索:门店 + * + * @param request + * @param response + * @return + * @throws Throwable + */ + @RequestMapping(value = "deptAutoComplete", method = RequestMethod.POST) + public List deptAutoComplete(@RequestParam(required = false) String keyCode, + @RequestParam(required = false) String type) throws Throwable { + try { + List objs = this.autoCompleteAccess.deptAutoComplete(keyCode, type); + return objs; + } catch (Throwable e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 检索:分销门店 + * + * @param request + * @param response + * @return + * @throws Throwable + */ + @RequestMapping(value = "deptFxAutoComplete", method = RequestMethod.POST) + public List deptFxAutoComplete(@RequestParam(required = false) String keyCode) throws Throwable { + try { + List objs = this.autoCompleteAccess.deptAutoComplete(keyCode, "17"); + return objs; + } catch (Throwable e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + + /** + * 检索:员工 + * + * @param request + * @param response + * @return + * @throws Throwable + */ + @RequestMapping(value = "employeeAutoComplete", method = RequestMethod.POST) + public List employeeAutoComplete(@RequestParam(required = false) String keyCode) throws Throwable { + try { + List objs = this.autoCompleteAccess.employeeAutoComplete(keyCode); + return objs; + } catch (Throwable e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } +} + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/BaseServlet.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/BaseServlet.java new file mode 100644 index 0000000..23afb64 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/BaseServlet.java @@ -0,0 +1,222 @@ +package abacus.springboot.example.controller; + +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.lang.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; + +import com.abacus.xpos.foundation.pubs.UserContext; + +import abacus.commons.exception.BusinessException; +import abacus.config.ext.AbacusExtConfig; + +/** + *

Title:BaseServlet

+

Description: 基础控制器

+ @author chuanZeng + @date 2026年8月18日 + */ +public class BaseServlet{ + + @Autowired + private AbacusExtConfig abacusExtConfig; + + /** + * value-获取配置参数 + * @param configKey + * @return + * @throws WebserviceException + */ + protected String getConfigValue(String configKey) throws BusinessException { + String configValueStr = abacusExtConfig.getAbacusConfigValue(configKey); + if (StringUtils.isBlank(configValueStr)) { + throw new BusinessException("配置参数[" + configKey + "]值不存在!"); + } + return configValueStr; + } + + /** + * set-获取配置参数 + * @param configKey + * @return + * @throws WebserviceException + */ + protected Map getConfigSet(String keyGroup, String configKey) throws BusinessException { + Map configValueStr = abacusExtConfig.getAbacusConfigSetByKeyGroupByKey(keyGroup, configKey); + if (configValueStr.isEmpty()) { + throw new BusinessException("系统[" + keyGroup + "]配置参数[" + configKey + "]值不存在!"); + } + return configValueStr; + } + + /** + * 获取登陆用户id + * @return + * @throws Exception + */ + protected String getUserId() throws BusinessException { + String operatorId = UserContext.getUserId(); + if (StringUtils.isBlank(operatorId)){ + throw new BusinessException("操作员不存在,请重新登录!"); + } + + return operatorId; + } + + /** + * 获取登陆用户姓名 + * @return + */ + protected String getUserName() throws BusinessException{ + String operatorName = UserContext.getUserName(); + if (StringUtils.isBlank(operatorName)){ + throw new BusinessException("操作员不存在,请重新登录!"); + } + + return operatorName; + } + + /** + * 获取登陆用户所属部门id + * @return + */ + protected String getDeptId() throws BusinessException{ + String deptId = UserContext.getDeptId(); + if (StringUtils.isBlank(deptId)){ + throw new BusinessException("操作员所属部门不存在,请重新登录!"); + } + + return deptId; + } + + /** + * 获取登陆用户所属部门名称 + * @return + */ + protected String getDeptName() throws BusinessException{ + String deptName = UserContext.getDeptName(); + if (StringUtils.isBlank(deptName)){ + throw new BusinessException("操作员所属部门不存在,请重新登录!"); + } + + return deptName; + } + + /** + * + * 获取double型的参数 + * + * @param request + * @param paramName + * @return + */ + protected Double getDoubleParameter(HttpServletRequest request, String paramName) { + // + String paramValue = request.getParameter(paramName); + if (StringUtils.isBlank(paramValue)) { + return null; + } + + return Double.valueOf(paramValue); + } + + /** + * + * 获取long型的参数 + * + * @param request + * @param paramName + * @return + */ + protected Long getLongParameter(HttpServletRequest request, String paramName) { + // + String paramValue = request.getParameter(paramName); + if (StringUtils.isBlank(paramValue)) { + return null; + } + + return Long.valueOf(paramValue); + } + + /** + * + * 获取int型的参数 + * + * @param request + * @param paramName + * @return + */ + protected Integer getIntegerParameter(HttpServletRequest request, String paramName) { + // + String paramValue = request.getParameter(paramName); + if (StringUtils.isBlank(paramValue)) { + return null; + } + + return Integer.valueOf(paramValue); + } + + /** + * + * 获取Boolean型的参数 + * + * @param request + * @param paramName + * @return + */ + protected Boolean getBooleanParameter(HttpServletRequest request, String paramName) { + // + String paramValue = request.getParameter(paramName); + + if ("true".equalsIgnoreCase(paramValue)) { + return true; + }else if ("false".equalsIgnoreCase(paramValue)) { + return false; + }else { + return null; + } + } + + /** + * 正则表达式校验手机号码 + * + * @return false 则手机号码不合法,true 则手机号码校验通过 + */ + protected Boolean validatePhoneNumber(String phoneNumber) { + if (phoneNumber.length() != 11) { + System.out.print("手机号应为11位数 "); + return false; + } else { + String regPattern = "^(1)\\d{10}$"; + Pattern pattern = Pattern.compile(regPattern); + Matcher matcher = pattern.matcher(phoneNumber); + boolean isMatch = matcher.matches(); + if (!isMatch) { + System.out.print("请填入正确的手机号 "); + } + return isMatch; + } + } + + /** + * 良友-crm回调函数 + */ + protected Map crmReturn(int code, String message, String content) { + Map map = new LinkedHashMap(); + + map.put("code", code); + map.put("message", message); + map.put("content", content); + + return map; + } + + + + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/JcBillHgController.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/JcBillHgController.java new file mode 100644 index 0000000..887f08a --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/JcBillHgController.java @@ -0,0 +1,751 @@ +package abacus.springboot.example.controller; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.abacus.pms.dao.Account; +import com.abacus.pms.wsi.AccountServiceIF; +import com.abacus.pms.wsi.ProductServiceIF; +import com.abacus.xpos.foundation.pubs.DaoIdGenerator; +import com.abacus.xpos.foundation.wsi.EmployeeServiceIF; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +import abacus.commons.exception.BusinessException; +import abacus.springboot.example.config.JcConfigKey; +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillHg; +import abacus.springboot.example.dao.JcBillInItem; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.util.DateToUpperChinese; +import abacus.springboot.example.util.DateUtil; +import abacus.springboot.example.vo.SiDepositlocation; +import abacus.springboot.example.wsi.JcBillServiceIF; + +/** + *

Title:JcBillHgController

+

Description: 前端相关-api

+ @author chuanZeng + @date 2026年8月18日 + */ +@RestController +@RequestMapping(value = "/jc/billHg") +public class JcBillHgController extends BaseServlet{ + + private static final Logger LOG = LoggerFactory.getLogger(JcBillHgController.class); + + @Autowired + private JcBillServiceIF jcBillService; + + @Autowired + private AccountServiceIF accountService; + + @Autowired + private ProductServiceIF productService; + + @Autowired + private DaoIdGenerator jcBillHgIdGenerator; + + @Autowired + private EmployeeServiceIF employeeService; + + /** + * TODO 稽查入库(回购通知)明细 + * @param billId + * @return + * @throws Throwable + */ + @RequestMapping(value = "queryJcBillInItems", method = RequestMethod.POST) + public JSONObject queryJcBillInItems( + @RequestParam(required = true) String billId + ) + throws Throwable { + try { + + List items = jcBillService.queryJcBillInItemByBillId(billId); + + if(items == null) throw new BusinessException("回购明细不存在!"); + + List oneList = new ArrayList(); + List twoList = new ArrayList(); + + + for(JcBillInItem item : items) { + if(JcBillInItem.STATUS_TWO != item.getStatus()) { + Account account = accountService.getAccount(item.getAccount()); + if(account != null) { + item.setOperator(account.getOperator().getId()); + item.setOperatorname(account.getOperator().getName()); + item.setSalearea(account.getSalearea()); + } else { + item.setSalearea(""); + item.setSaleareaname(""); + item.setGroupid(""); + item.setGroupname(""); + } + } + } + + jcBillService.saveJcBillInItem(items); + + // 分出,已通知或未通知 + for(JcBillInItem item : items) { + if(JcBillInItem.STATUS_MINUS_ONE == item.getStatus() || JcBillInItem.STATUS_ONE == item.getStatus()) { +// item.setPrice(new BigDecimal(String.valueOf(item.getPrice())).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()); + oneList.add(item); + } else { +// item.setPrice(new BigDecimal(String.valueOf(item.getPrice())).setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()); + twoList.add(item); + } + } + + + + JSONObject obj = new JSONObject(); + + obj.put("oneList", oneList); + obj.put("twoList", twoList); + obj.put("threeList", items); + + return obj; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * TODO 查询回购明细对应的溯源信息 + * @param id + * @return + * @throws Throwable + */ + @RequestMapping(value = "queryHgSourceItems", method = RequestMethod.POST) + public List queryHgSourceItems( + @RequestParam(required = true) String id + ) + throws Throwable { + try { + JcBillInItem inItem = jcBillService.queryJcBillInItemById(Long.parseLong(id)); + + if(inItem == null) throw new BusinessException("回购明细不存在!"); + + List billItems = jcBillService.queryJcBillSourceItemByBillId(inItem.getBillid()); + + if(billItems == null) throw new BusinessException("溯源信息不存在!"); + + // 按客户编码+商品编码+收货单价分组 + Map> mapItems = billItems.stream() + .collect(Collectors.groupingBy(e -> { + return e.getAccount() + "#" + e.getProduct() + "#" + String.valueOf(e.getPrice()); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + Map> mapPhoto = jcBillService.queryJcBillPhoto(inItem.getBillid()); + + // 找出对应的来源明细 + List tempItems = mapItems.get(inItem.getAccount() + "#" + inItem.getProduct() + "#" + String.valueOf(inItem.getPrice())); + + for(JcBillSourceItem item : tempItems) { + + // 稽查付款截图 + List fkts = mapPhoto.get(JcBillPhoto.JC_FK + "#" + String.valueOf(item.getIndexno())); + if(fkts != null && fkts.size() >= 1) { + List fkList = new ArrayList(); + + for(JcBillPhoto fkt : fkts) { + fkList.add(fkt.getUrlphoto()); + } + + item.setPaymentPhoto(fkList); + } + + // 货品图 + List hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(item.getIndexno()) + "#" + item.getGoodsid()); + if(hpts != null && hpts.size() >= 1) { + List hpList = new ArrayList(); + + for(JcBillPhoto hpt : hpts) { + hpList.add(hpt.getUrlphoto()); + } + + item.setGoodsPhotos(hpList); + item.setHpts(hpts); + } + } + + + return tempItems; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * TODO 终止回购 + * @param id + * @return + * @throws Throwable + */ + @RequestMapping(value = "terminateHgInItem", method = RequestMethod.POST) + public void terminateHgInItem( + @RequestParam(required = true) String id + ) + throws Throwable { + try { + + JcBillInItem inItem = jcBillService.queryJcBillInItemById(Long.parseLong(id)); + + if(inItem == null) throw new BusinessException("回购明细不存在!"); + + inItem.setStatus(JcBillInItem.STATUS_MINUS_ONE); + + jcBillService.saveTerminateHgInItem(inItem); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * TODO 修改回购价格 + * @param id + * @return + * @throws Throwable + */ + @RequestMapping(value = "updateHgprice", method = RequestMethod.POST) + public JcBillInItem updateHgprice( + @RequestParam(required = true) String id, + @RequestParam(required = true) String hgprice + ) + throws Throwable { + try { + + JcBillInItem inItem = jcBillService.queryJcBillInItemById(Long.parseLong(id)); + if(inItem == null) throw new BusinessException("回购明细不存在!"); + + inItem.setOldhgprice(inItem.getHgprice()); + + BigDecimal bigHgprice = new BigDecimal(hgprice); + + BigDecimal bigAmount = bigHgprice.multiply(new BigDecimal(String.valueOf(inItem.getQuantity()))); + + inItem.setHgprice(bigHgprice.doubleValue()); + inItem.setHgamount(bigAmount.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue()); + + jcBillService.updateHgprice(inItem); + + return inItem; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * TODO 回购查询 + * @param id + * @return + * @throws Throwable + */ + @RequestMapping(value = "queryHg", method = RequestMethod.POST) + public JSONObject queryHg( + @RequestParam(required = false) String from, + @RequestParam(required = false) String thru, + + @RequestParam(required = false) String account, + @RequestParam(required = false) String salearea, + @RequestParam(required = false) String id, + @RequestParam(required = false) String billId, + @RequestParam(required = false) String status, + @RequestParam(required = false) String product, + @RequestParam(required = false) String manager, + @RequestParam(required = true) int typ, + + @RequestParam(required = true) int page, + @RequestParam(required = true) int size + ) + throws Throwable { + try { + + // 创建起始时间 + String fromDate = null; + if (StringUtils.isNotBlank(from)) { + fromDate = DateUtil.formatDateTime(DateUtil.getFromDate(DateUtil.toDate(from))); + } + // 创建截止时间 + String thruDate = null; + if (StringUtils.isNotBlank(thru)) { + thruDate = DateUtil.formatDateTime(DateUtil.getThruDate(DateUtil.toDate(thru))); + } + + // 当前页 +// int pageNumber = page/size + 1; + Pageable pageable = PageRequest.of(page - 1, size); + + Page pages = jcBillService.queryJcBillHg(fromDate, thruDate, account, salearea, id, billId, + status, product, manager, typ, pageable); + + for(JcBillHg hg : pages.getContent()) { + hg.setAmount(hg.getSubtotal() + hg.getFreight()); + } + + JSONObject obj = new JSONObject(); + + obj.put("list", pages.getContent()); + obj.put("total", pages.getTotalElements()); + + return obj; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * TODO 回购-驳回 + * 待提交-->回购通知节点 + * 待付款-->待提交, + * 已付款-->待付款 + * 待分仓-->已付款 + * @param billId + * @param typ 1-回购认款,2-回购分仓 + * @return + */ + @RequestMapping(value = "rejectBillHg", method = RequestMethod.POST) + public JcBillHg rejectBillHg( + @RequestParam(required = false) String billHgId, + @RequestParam(required = false) int status, + @RequestParam(required = true) int typ + ) + throws Throwable { + try { + + JcBillHg billHg = jcBillService.queryJcBillHg(billHgId); + + if(billHg == null) throw new BusinessException("回购订单不存在!"); + + List inItems = null; + JcBill jcBill = null; + if(JcBillHg.STATUS_ONE == status) { + + inItems = jcBillService.queryJcBillInItemByBillId(billHg.getBillid()); + + if(inItems == null) throw new BusinessException("回购明细不存在!"); + + // 设置明细状态和回购单号为空 + + // 是否部分回购 + boolean informFlag = false; + for(JcBillInItem item : inItems) { + if(billHgId.equals(item.getBillhg())) { + item.setStatus(JcBillInItem.STATUS_ONE); + item.setBillhg(null); + } + if(item.getStatus() == JcBillInItem.STATUS_TWO) { + informFlag = true; + } + } + + jcBill = jcBillService.queryJcBillById(billHg.getBillid()); + + if(jcBill == null) throw new BusinessException("收货记录不存在!"); + + // 稽查收货记录修改状态 +// if(informFlag) jcBill.setStatus(JcBill.STATUS_SIX); +// else jcBill.setStatus(JcBill.STATUS_FIVE); + if(informFlag) jcBill.setHgstatus(JcBill.HGSTATUS_ONE); + else jcBill.setStatus(JcBill.STATUS_FIVE); + + billHg.setStatus(JcBillHg.STATUS_MINUS_ONE); + + } else if(JcBillHg.STATUS_TWO == status) { + + billHg.setStatus(JcBillHg.STATUS_ONE); + + } else if(JcBillHg.STATUS_THREE == status || JcBillHg.STATUS_FOUR == status) { + + billHg.setStatus(JcBillHg.STATUS_TWO); + + } else if(JcBillHg.STATUS_FIVE == status) { + + SiDepositlocation sd = jcBillService.querySiDepositlocationHGfc(billHg.getId()); + + if(sd == null) {// WDT + throw new BusinessException("该单据需要通知仓库在旺店通删除入库单,并联系信息部撤回。"); + } else { + if(sd.getPush() == 1) {// WMS + + JSONObject obj = jcBillService.gwisSubCancelOrder(billHg.getId(), "B2BCK"); + + if(obj.getBooleanValue("success")) { + + billHg.setStatus(JcBillHg.STATUS_FOUR); + } else { + throw new BusinessException(obj.getString("body")); + } + } else { + throw new BusinessException("该单据需要通知仓库在旺店通删除入库单,并联系信息部撤回。"); + } + } + + } else { + throw new BusinessException("未知状态不能驳回!"); + } + + jcBillService.saveRejectBillHg(status, typ, jcBill, billHg, inItems); + + billHg.setAmount(billHg.getSubtotal() + billHg.getFreight()); + + return billHg; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * TODO 确认收款 + * @param billId + * @return + */ + @RequestMapping(value = "querenSk", method = RequestMethod.POST) + public JcBillHg querenSk( + @RequestParam(required = false) String billHgId + ) + throws Throwable { + try { + + JcBillHg billHg = jcBillService.queryJcBillHg(billHgId); + + if(billHg == null) throw new BusinessException("回购订单不存在!"); + + String key_jc_wdt_fcflage = getConfigValue(JcConfigKey.KEY_JC_WDT_FCFLAGE); + boolean fcFlag = Boolean.parseBoolean(key_jc_wdt_fcflage); + + if(fcFlag) billHg.setStatus(JcBillHg.STATUS_FIVE); + else billHg.setStatus(JcBillHg.STATUS_FOUR); + + + jcBillService.saveQuerenSk(billHg, fcFlag); + + + billHg.setAmount(billHg.getSubtotal() + billHg.getFreight()); + + return billHg; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * TODO 分仓 + * @param billId + * @return + */ + @RequestMapping(value = "createFc", method = RequestMethod.POST) + public JcBillHg createFc( + @RequestParam(required = false) String billHgId + ) + throws Throwable { + try { + + JcBillHg billHg = jcBillService.queryJcBillHg(billHgId); + + if(billHg == null) throw new BusinessException("回购订单不存在!"); + + billHg.setStatus(JcBillHg.STATUS_FIVE); + + jcBillService.savecreateFc(billHg); + + billHg.setAmount(billHg.getSubtotal() + billHg.getFreight()); + + return billHg; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * TODO 修改分仓仓库 + * @param billId + * @return + */ + @RequestMapping(value = "updateFcWarehouse", method = RequestMethod.POST) + public JcBillHg updateFcWarehouse( + @RequestParam(required = true) String billHgId, + @RequestParam(required = true) String warehouse, + @RequestParam(required = true) String warehouseName + ) + throws Throwable { + try { + JcBillHg billHg = jcBillService.queryJcBillHg(billHgId); + + if(billHg == null) throw new BusinessException("回购订单不存在!"); + + // 老对象保存为JSONString + String oldJsonStr = JSON.toJSONString(billHg); + + billHg.setFhwarehouse(warehouse); + billHg.setFhwarehousename(warehouseName); + + jcBillService.updateFcWarehouse(oldJsonStr, billHg); + + billHg.setAmount(billHg.getSubtotal() + billHg.getFreight()); + + return billHg; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * TODO 修改运营备注 + * @param billId + * @return + */ + @RequestMapping(value = "updateRemark1", method = RequestMethod.POST) + public JcBillHg updateRemark1( + @RequestParam(required = true) String billHgId, + @RequestParam(required = true) String remark + ) + throws Throwable { + try { + JcBillHg billHg = jcBillService.queryJcBillHg(billHgId); + + if(billHg == null) throw new BusinessException("回购订单不存在!"); + + // 老对象保存为JSONString + String oldJsonStr = JSON.toJSONString(billHg); + + billHg.setRemark1(remark); + + jcBillService.updateFcWarehouse(oldJsonStr, billHg); + + billHg.setAmount(billHg.getSubtotal() + billHg.getFreight()); + + return billHg; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * TODO 修改收货地址 + * @param billId + * @return + */ + @RequestMapping(value = "updatePac", method = RequestMethod.POST) + public JcBillHg updatePac( + @RequestParam(required = true) String billHgId, + @RequestParam(required = true) String provincename, + @RequestParam(required = true) String cityname, + @RequestParam(required = true) String areaname, + @RequestParam(required = true) String address, + @RequestParam(required = true) String consignee, + @RequestParam(required = true) String consigneephone + ) + throws Throwable { + try { + JcBillHg billHg = jcBillService.queryJcBillHg(billHgId); + + if(billHg == null) throw new BusinessException("回购订单不存在!"); + + // 老对象保存为JSONString + String oldJsonStr = JSON.toJSONString(billHg); + + billHg.setProvincename(provincename); + billHg.setCityname(cityname); + billHg.setAreaname(areaname); + billHg.setAddress(address); + billHg.setConsignee(consignee); + billHg.setConsigneephone(consigneephone); + + jcBillService.updatePac(oldJsonStr, billHg); + + billHg.setAmount(billHg.getSubtotal() + billHg.getFreight()); + + return billHg; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + // TODO 创建通知函文章 + @RequestMapping(value="createTzh", method = RequestMethod.POST) + public JSONObject createTzh( + @RequestParam(required = true) String inItems, + @RequestParam(required = false) String bzj + ) throws Exception { + try { + + if(StringUtils.isBlank(inItems)) throw new BusinessException("未勾选!"); + + List items = JSON.parseArray(inItems, JcBillInItem.class); + + List billItems = jcBillService.queryJcBillSourceItemByBillId(items.get(0).getBillid()); + if(billItems == null) throw new BusinessException("稽查明细不存在!"); + + if(StringUtils.isBlank(bzj)) bzj = "2、在接到本通知函后一周内,缴纳1万元市场管理保证金,汇入我司对公账户。"; + + + return creatTzhObj(items, billItems.get(0), bzj); + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 生成通知函个节点 + * @param item + * @return + * @throws Exception + */ + private JSONObject creatTzhObj(List items, JcBillSourceItem billItem, String bzj) throws Exception{ + try { + JcBillInItem inItem = items.get(0); + + JSONObject obj = new JSONObject(); + + // 客户 + obj.put("account", inItem.getAccount() + inItem.getAccountname()); + + // 回购单价 + obj.put("hgprice", String.valueOf(inItem.getHgprice()).replace("\\.0*$", "")); + + // 年月日 + obj.put("dataz", DateToUpperChinese.getUpperDate(new Date())); + + // 收货门店 + Map mapChannel = items.stream() + .collect(Collectors.groupingBy(e -> { + return e.getChannel(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0).getChannel()) + )); + String channelStr = ""; + for(String key : mapChannel.keySet()) { + if("线上".equals(billItem.getRecsource())) { + channelStr += billItem.getRecplatform() + key + "、"; + } else { + channelStr += key + "、"; + } + } + obj.put("channel", channelStr.toString().substring(0, channelStr.length() - 1)); + + // 商品 + Map mapPorduct = items.stream() + .collect(Collectors.groupingBy(e -> { + return e.getProduct() + String.valueOf(e.getPrice()); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)) + )); + + double numbers = 0; + StringBuffer productStr = new StringBuffer(); + for(String key : mapPorduct.keySet()) { + JcBillInItem productItem = mapPorduct.get(key); + BigDecimal price = new BigDecimal(String.valueOf(productItem.getPrice())); +// BigDecimal amount = price.multiply(new BigDecimal(String.valueOf(productItem.getQuantity()))).setScale(2, BigDecimal.ROUND_HALF_UP); +// +// BigDecimal numPrice = amount.divide(new BigDecimal(String.valueOf(productItem.getNumbers())), 4, BigDecimal.ROUND_HALF_UP).setScale(4, BigDecimal.ROUND_HALF_UP); +// +// LOG.info(removeZeros(String.valueOf(numPrice.doubleValue()))); + +// productStr.append("收货价格" + removeZeros(String.valueOf(price.doubleValue())) + "元/瓶、"); + +// numbers += productItem.getNumbers(); + + numbers += productItem.getQuantity(); + } + obj.put("product", inItem.getProductname()); +// obj.put("product", inItem.getProductname() + "," + productStr.toString().substring(0, productStr.length() - 1)); + + // 件数 + obj.put("numbers", numbers); + + // 支付方式-打款信息 + Map offlineMaps = getConfigSet(JcConfigKey.KEY_GROUP, JcConfigKey.KEY_JC_PAYMENT_OFFLINE); + + obj.put("dkxx", offlineMaps.get("zhmc") + "、" + offlineMaps.get("khyh") + "、" + offlineMaps.get("yhzh")); + + // 保证金 + obj.put("bzj", bzj); + + return obj; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 去掉小数位0的数字 + * @param str + * @return + */ + private String removeZeros(String str) { + if(str.indexOf(".") > 0) { + str = str.replace("0+?$", "");// 删除掉尾数为0的字符 + str = str.replace("[.]$", "");// 结尾如果是小数点,则去掉 + } + return str; + } + +} + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/JcBillInController.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/JcBillInController.java new file mode 100644 index 0000000..807d9b0 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/controller/JcBillInController.java @@ -0,0 +1,595 @@ +package abacus.springboot.example.controller; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.abacus.pms.wsi.AccountServiceIF; +import com.abacus.pms.wsi.ProductServiceIF; +import com.abacus.xpos.foundation.wsi.EmployeeServiceIF; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; + +import abacus.commons.exception.BusinessException; +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillInItem; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.dao.JcSourceItem; +import abacus.springboot.example.util.DateUtil; +import abacus.springboot.example.vo.SiDepositlocation; +import abacus.springboot.example.wsi.JcBillServiceIF; + +/** + *

Title:JcBillInController

+

Description: 前端相关-api

+ @author chuanZeng + @date 2026年8月18日 + */ +@RestController +@RequestMapping(value = "/jc") +public class JcBillInController extends BaseServlet{ + + private static final Logger LOG = LoggerFactory.getLogger(JcBillInController.class); + + @Autowired + private JcBillServiceIF jcBillService; + + @Autowired + private EmployeeServiceIF employeeService; + + @Autowired + private ProductServiceIF productService; + + @Autowired + private AccountServiceIF accountService; + + /** + * TODO (溯源入库-回购通知)--页面查询 + * @param typ 1-溯源入库 2-回购通知 + * @return + * @throws Throwable + */ + @RequestMapping(value = "queryJcBillPage", method = RequestMethod.POST) + public JSONObject queryJcBillPage( + @RequestParam(required = false) String from, + @RequestParam(required = false) String thru, + + @RequestParam(required = false) String applicant, + @RequestParam(required = false) String goods, + @RequestParam(required = false) String id, + @RequestParam(required = false) String billin, + @RequestParam(required = false) String goodsid, + @RequestParam(required = false) String product, + @RequestParam(required = false) String status, + @RequestParam(required = true) int typ, + + @RequestParam(required = true) int page, + @RequestParam(required = true) int size + ) + throws Throwable { + try { + + // 申请起始时间 + String fromDate = null; + if (StringUtils.isNotBlank(from)) { + fromDate = DateUtil.formatDateTime(DateUtil.getFromDate(DateUtil.toDate(from))); + } + // 申请截止时间 + String thruDate = null; + if (StringUtils.isNotBlank(thru)) { + thruDate = DateUtil.formatDateTime(DateUtil.getThruDate(DateUtil.toDate(thru))); + } + + // 当前页 +// int pageNumber = page/size + 1; + Pageable pageable = PageRequest.of(page - 1, size); + + Page pages = jcBillService.queryJcBill(fromDate, thruDate, id, applicant, + goods, billin, goodsid, product, status, typ, pageable); + + // 获取稽查单号集合 + List billIds = pages.getContent().stream() + .map(JcBill::getId) + .collect(Collectors.toList()); + + List items = jcBillService.queryJcBillSourceItemInBillId(billIds); + + Map mapItem = items.stream() + .collect(Collectors.groupingBy(e -> { + return e.getBillid(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)) + )); + + for(JcBill jcBill : pages.getContent()) { + JcBillSourceItem item = mapItem.get(jcBill.getId()); + if(item != null) { + jcBill.setRecsource(item.getRecsource()); + jcBill.setRecplatform(item.getRecplatform()); + jcBill.setChannel(item.getChannel()); + } + } + + JSONObject obj = new JSONObject(); + + obj.put("list", pages.getContent()); + obj.put("total", pages.getTotalElements()); + + return obj; + }catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * TODO 查询溯源详情 + * @param billId + * @return + */ + @RequestMapping(value = "queryJcBillSourceItems", method = RequestMethod.POST) + public List queryJcBillSourceItems( + @RequestParam(required = false) String billId + ) + throws Throwable { + try { + + List items = jcBillService.queryJcBillSourceItemByBillId(billId); + + if(items == null) throw new BusinessException("溯源信息不存在!"); + + Map> mapPhoto = jcBillService.queryJcBillPhoto(billId); + + for(JcBillSourceItem item : items) { + + // 稽查付款截图 + List fkts = mapPhoto.get(JcBillPhoto.JC_FK + "#" + String.valueOf(item.getIndexno())); + if(fkts != null && fkts.size() >= 1) { + List fkList = new ArrayList(); + + for(JcBillPhoto fkt : fkts) { + fkList.add(fkt.getUrlphoto()); + } + + item.setPaymentPhoto(fkList); + } + + // 货品图 + List hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(item.getIndexno()) + "#" + item.getGoodsid()); + if(hpts != null && hpts.size() >= 1) { + List hpList = new ArrayList(); + + for(JcBillPhoto hpt : hpts) { + hpList.add(hpt.getUrlphoto()); + } + + item.setGoodsPhotos(hpList); + item.setHpts(hpts); + } + } + + return items; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * TODO 查询溯源明细 + * @param billId + * @return + */ + @RequestMapping(value = "queryJcSourceItems", method = RequestMethod.POST) + public List queryJcSourceItems( + @RequestParam(required = true) String billId, + @RequestParam(required = true) String srcItemId + ) + throws Throwable { + try { + List items = jcBillService.queryJcSourceItemByBillId(billId, srcItemId); + + return items; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * TODO 确认溯源 + * @param billId + * @param srcItemId + * @return + * @throws Throwable + */ + @RequestMapping(value = "querenSourceItems", method = RequestMethod.POST) + public void querenSourceItems( + @RequestParam(required = true) String billId, + @RequestParam(required = true) String srcItemId, + @RequestParam(required = true) String sourceItemId + ) + throws Throwable { + try { +// JcBill jcBill = jcBillService.queryJcBillById(billId); + +// if(jcBill == null) throw new BusinessException("收货记录不存在!"); + + JcBillSourceItem billItem = jcBillService.queryJcBillSourceItemById(Long.parseLong(srcItemId)); + + if(billItem == null) throw new BusinessException("溯源信息不存在!"); + + JcSourceItem sourceItem = jcBillService.queryJcSourceItemById(Long.parseLong(sourceItemId)); + + if(sourceItem == null) throw new BusinessException("溯源明细不存在!"); + +// 稽查收入记录 + + // 溯源信息更新 + billItem.setStatus(JcBillSourceItem.STATUS_THREE); + billItem.setLogisticsid(sourceItem.getLogisticsid()); + billItem.setBillout(sourceItem.getBillout()); + billItem.setBilloutdt(sourceItem.getBilloutdt()); + billItem.setBilloutwh(sourceItem.getBilloutwh()); + billItem.setBilloutwhname(sourceItem.getBilloutwhname()); + billItem.setProduct(sourceItem.getProduct()); + billItem.setProductname(sourceItem.getProductname()); + billItem.setAccount(sourceItem.getAccount()); + billItem.setAccountname(sourceItem.getAccountname()); + billItem.setOperator(sourceItem.getOperator()); + billItem.setOperatorname(sourceItem.getOperatorname()); + billItem.setGroupid(sourceItem.getGroupid()); + billItem.setGroupname(sourceItem.getGroupname()); + billItem.setSalearea(sourceItem.getSalearea()); + billItem.setSaleareaname(sourceItem.getSaleareaname()); + billItem.setSource(sourceItem.getSource()); + + + // 确认溯源明细 + sourceItem.setStatus(JcSourceItem.STATUS_ONE); + + jcBillService.saveQuerenBillSourceItem(billItem, sourceItem); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * TODO 新增溯源明细信息 + * @param billId + * @param srcItemId + * @return + * @throws Throwable + */ + @RequestMapping(value = "saveSourceItems", method = RequestMethod.POST) + public JcSourceItem saveSourceItems( + @RequestParam(required = true) String billid, + @RequestParam(required = true) String srcitemid, + @RequestParam(required = true) String goodsid, + @RequestParam(required = true) String logisticsid, + @RequestParam(required = true) String billout, + @RequestParam(required = true) String billoutdt, + @RequestParam(required = true) String billoutwh, + @RequestParam(required = true) String billoutwhname, + @RequestParam(required = true) String product, + @RequestParam(required = true) String productname, + @RequestParam(required = true) String account, + @RequestParam(required = true) String accountname, + @RequestParam(required = true) String operator, + @RequestParam(required = true) String operatorname, + @RequestParam(required = true) String groupid, + @RequestParam(required = true) String groupname, + @RequestParam(required = true) String salearea, + @RequestParam(required = true) String saleareaname, + @RequestParam(required = true) String source + ) + throws Throwable { + try { + JcSourceItem sourceItem = new JcSourceItem(); + sourceItem.setStatus(JcSourceItem.STATUS_ZERO); + sourceItem.setBillid(billid); + sourceItem.setSrcitemid(srcitemid); + sourceItem.setGoodsid(goodsid); + sourceItem.setLogisticsid(logisticsid); + sourceItem.setBillout(billout); + sourceItem.setBilloutdt(DateUtil.toDate(billoutdt)); + sourceItem.setBilloutwh(billoutwh); + sourceItem.setBilloutwhname(billoutwhname); + sourceItem.setProduct(product); + sourceItem.setProductname(productname); + sourceItem.setAccount(account); + sourceItem.setAccountname(accountname); + sourceItem.setOperator(operator); + sourceItem.setOperatorname(operatorname); + sourceItem.setGroupid(groupid); + sourceItem.setGroupname(groupname); + sourceItem.setSalearea(salearea); + sourceItem.setSaleareaname(saleareaname); + sourceItem.setSource(source); + + JcSourceItem tempItem = jcBillService.saveJcSourceItem(sourceItem); + + return tempItem; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * TODO 删除溯源明细信息 + * @param billId + * @param srcItemId + * @return + * @throws Throwable + */ + @RequestMapping(value = "deleteSourceItem", method = RequestMethod.POST) + public void deleteSourceItem( + @RequestParam(required = true) String codes + ) + throws Throwable { + try { + + if (StringUtils.isEmpty(codes)) { + throw new BusinessException("溯源明细信息编码不能为空"); + } + + List ids = JSON.parseArray(codes, Long.class); + + jcBillService.deleteJcSourceItem(ids); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * TODO 溯源信息驳回 + * @param billId + * @return + */ + @RequestMapping(value = "rejectJcSourceItems", method = RequestMethod.POST) + public void rejectJcSourceItems( + @RequestParam(required = true) String billId, + @RequestParam(required = true) String srcItemId, + @RequestParam(required = true) String reason + ) + throws Throwable { + try { + JcBill jcBill = jcBillService.queryJcBillById(billId); + + if(jcBill == null) throw new BusinessException("收货记录不存在!"); + + JcBillSourceItem billItem = jcBillService.queryJcBillSourceItemById(Long.parseLong(srcItemId)); + + if(billItem == null) throw new BusinessException("溯源信息不存在!"); + + jcBill.setStatus(JcBill.STATUS_MINUS_TWO); + + billItem.setStatus(JcBillSourceItem.STATUS_MINUS_TWO); + billItem.setReason(reason); + + jcBillService.saveRejectJcSourceItems(billItem, jcBill); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * TODO 修改收货仓库 + * @param billId + * @return + */ + @RequestMapping(value = "updateWarehouse", method = RequestMethod.POST) + public JcBill updateWarehouse( + @RequestParam(required = true) String billId, + @RequestParam(required = true) String warehouse, + @RequestParam(required = true) String warehouseName + ) + throws Throwable { + try { + JcBill jcBill = jcBillService.queryJcBillById(billId); + + if(jcBill == null) throw new BusinessException("收货记录不存在!"); + + // 老对象保存为JSONString + jcBill.setOldJson(JSON.toJSONString(jcBill)); + + jcBill.setWarehouse(warehouse); + jcBill.setWarehousename(warehouseName); + + jcBillService.updateWarehouse(jcBill); + + return jcBill; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * TODO 生成入库单 + * @param billId + * @return + */ + @RequestMapping(value = "createStockIn", method = RequestMethod.POST) + public JcBill createStockIn( + @RequestParam(required = true) String billId + ) + throws Throwable { + try { + JcBill jcBill = jcBillService.queryJcBillById(billId); + + if(jcBill == null) throw new BusinessException("收货记录不存在!"); + + jcBill.setStatus(JcBill.STATUS_FOUR); + + jcBillService.createStockIn(jcBill); + + return jcBill; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * TODO 撤回 + * @param billId + * @return + */ + @RequestMapping(value = "rejectBill", method = RequestMethod.POST) + public JcBill rejectBill( + @RequestParam(required = false) String billId, + @RequestParam(required = false) int status + ) + throws Throwable { + try { + JcBill jcBill = jcBillService.queryJcBillById(billId); + + if(jcBill == null) throw new BusinessException("收货记录不存在!"); + + List inItems = jcBillService.queryJcBillInItemByBillId(billId); + + List sourceItems = jcBillService.queryJcBillSourceItemByBillId(billId); + if(sourceItems == null) throw new BusinessException("收货明细不存在!"); + + if(JcBill.STATUS_FOUR == status) {// 入库待审核 进行撤回(事件生成—进行事件删除) + + SiDepositlocation sd = jcBillService.querySiDepositlocation(jcBill.getId()); + + if(sd == null) {// WDT + throw new BusinessException("该单据需要通知仓库在旺店通删除入库单,并联系信息部撤回。"); + } else { + if(sd.getPush() == 1) {// WMS + + JSONObject obj = jcBillService.gwisSubCancelOrder(jcBill.getId(), "QTRK"); + + if(obj.getBooleanValue("success")) { + + jcBill.setStatus(JcBill.STATUS_THREE); + } else { + throw new BusinessException(obj.getString("body")); + } + } else { + throw new BusinessException("该单据需要通知仓库在旺店通删除入库单,并联系信息部撤回。"); + } + } + } else {// 待入库撤回 + jcBill.setStatus(JcBill.STATUS_TWO); + + for(JcBillSourceItem item : sourceItems) { + item.setStatus(JcBillSourceItem.STATUS_TWO); + } + } + + jcBillService.saveRejectBill(status, jcBill, inItems, sourceItems); + return jcBill; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + + /** + * TODO 查询溯源明细-已确认 + * @param billId + * @return + */ + @RequestMapping(value = "queryJcSourceItemsQue", method = RequestMethod.POST) + public List queryJcSourceItemsQue( + @RequestParam(required = true) String billId, + @RequestParam(required = true) String srcItemId + ) + throws Throwable { + try { + List items = jcBillService.queryJcSourceItemByBillId(billId, srcItemId, 1); + + return items; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBill.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBill.java new file mode 100644 index 0000000..b860504 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBill.java @@ -0,0 +1,316 @@ +package abacus.springboot.example.dao; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.persistence.Version; + +import com.fasterxml.jackson.annotation.JsonBackReference; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Entity +@Table(name = "jc_bill") +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(description = "稽查主单") +public class JcBill implements Serializable { + + private static final long serialVersionUID = 7089440541784316919L; + + /**唯一标识:订单号*/ + @Id + @Schema(description="稽查单号", required=true, example="JC202411180001") + private String id; + + @Version + @Schema(description = "版本号", required = true, example = "1") + private Integer version = 1; + + @Schema(description="状态", required=true, pattern="-3:取消,-2:溯源驳回,0:待提交,1:系统溯源验证通过,2:待溯源,3:待入库,4:入库待审核,5:已入库,6:部分回购,7:回购完成", example = "1") + private int status = 1; + /** 取消*/ + public final static int STATUS_MINUS_THREE = -3; + /** 溯源驳回*/ + public final static int STATUS_MINUS_TWO = -2; + /** 待提交*/ + public final static int STATUS_ZERO = 0; + /** 系统溯源验证通过*/ + public final static int STATUS_ONE = 1; + /** 待溯源*/ + public final static int STATUS_TWO = 2; + /** 待入库*/ + public final static int STATUS_THREE = 3; + /** 入库待审核 */ + public final static int STATUS_FOUR = 4; + /** 已入库 */ + public final static int STATUS_FIVE = 5; + /** 部分回购 */ + public final static int STATUS_SIX = 6; + /** 回购完成*/ + public final static int STATUS_SEVEN = 7; + + /** 部分出库-不保存到系统,前端使用*/ + public final static int STATUS_EIGHT = 8; + /** 已出库-不保存到系统,前端使用*/ + public final static int STATUS_NINE = 9; + + @Schema(description="状态", required=true, pattern="0:待回购,1:部分回购,2:回购完成", example = "0") + private int hgstatus = 0; + /** 待回购*/ + public final static int HGSTATUS_ZERO = 0; + /** 部分回购*/ + public final static int HGSTATUS_ONE = 1; + /** 回购完成*/ + public final static int HGSTATUS_TWO = 2; + + @Schema(description = "收货产品", required = true, example = "") + private String goods; + + @Schema(description = "收货仓库编码", required = true, example = "") + private String warehouse; + + @Schema(description = "收货仓库名称", required = true, example = "") + private String warehousename; + + @Schema(description = "收货日期", required = true, example = "2024-11-11") + private String receivedt; + + @Schema(description = "收货数量", required = true, example = "") + private double quantity; + + @Schema(description = "收货总金额", required = true, example = "") + private double subtotal; + + @Schema(description = "入库单号", required = true, example = "") + private String billin; + + @Temporal(TemporalType.TIMESTAMP) + @Schema(description = "入库单时间", required = true, example = "") + private Date billindt; + + @Schema(description = "申请人编码", required = true, example = "") + private String applicant; + + @Schema(description = "申请人名称", required = true, example = "") + private String applicantname; + + @Temporal(TemporalType.TIMESTAMP) + @Schema(description = "申请人时间", required = true, example = "") + private Date applicantdt; + + @Schema(description = "部门编码", required = true, example = "") + private String dept; + + @Temporal(TemporalType.TIMESTAMP) + @Schema(description = "时间戳", required = true, example = "") + private Date dt = new Date(); + + @Transient + @Schema(description = "收货来源", hidden = true,required = true, example = "") + private String recsource; + + @Transient + @Schema(description = "收货平台", hidden = true,required = true, example = "") + private String recplatform; + + @Transient + @Schema(description = "收货渠道", hidden = true,required = true, example = "") + private String channel; + + @Transient + @JsonBackReference + @Schema(description = "历史对象JSONString", required = false, hidden = true, pattern = "", example = "") + private String oldJson; + + public String getRecsource() { + return recsource; + } + + public void setRecsource(String recsource) { + this.recsource = recsource; + } + + public String getRecplatform() { + return recplatform; + } + + public void setRecplatform(String recplatform) { + this.recplatform = recplatform; + } + + public String getChannel() { + return channel; + } + + public void setChannel(String channel) { + this.channel = channel; + } + + public int getHgstatus() { + return hgstatus; + } + + public void setHgstatus(int hgstatus) { + this.hgstatus = hgstatus; + } + + public String getDept() { + return dept; + } + + public void setDept(String dept) { + this.dept = dept; + } + + public String getOldJson() { + return oldJson; + } + + public void setOldJson(String oldJson) { + this.oldJson = oldJson; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getGoods() { + return goods; + } + + public void setGoods(String goods) { + this.goods = goods; + } + + public String getWarehouse() { + return warehouse; + } + + public void setWarehouse(String warehouse) { + this.warehouse = warehouse; + } + + public String getWarehousename() { + return warehousename; + } + + public void setWarehousename(String warehousename) { + this.warehousename = warehousename; + } + + public String getReceivedt() { + return receivedt; + } + + public void setReceivedt(String receivedt) { + this.receivedt = receivedt; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public double getSubtotal() { + return subtotal; + } + + public void setSubtotal(double subtotal) { + this.subtotal = subtotal; + } + + public String getBillin() { + return billin; + } + + public void setBillin(String billin) { + this.billin = billin; + } + + public Date getBillindt() { + return billindt; + } + + public void setBillindt(Date billindt) { + this.billindt = billindt; + } + + public String getApplicant() { + return applicant; + } + + public void setApplicant(String applicant) { + this.applicant = applicant; + } + + public String getApplicantname() { + return applicantname; + } + + public void setApplicantname(String applicantname) { + this.applicantname = applicantname; + } + + public Date getApplicantdt() { + return applicantdt; + } + + public void setApplicantdt(Date applicantdt) { + this.applicantdt = applicantdt; + } + + public Date getDt() { + return dt; + } + + public void setDt(Date dt) { + this.dt = dt; + } +} + + + + + + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillHg.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillHg.java new file mode 100644 index 0000000..483cb1b --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillHg.java @@ -0,0 +1,671 @@ +package abacus.springboot.example.dao; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.Version; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Entity +@Table(name = "jc_billhg") +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(description = "回购单主单") +public class JcBillHg implements Serializable { + + private static final long serialVersionUID = -4735685141695682399L; + + /**唯一标识:订单号*/ + @Id + @Schema(description="回购单单号", required=true, example="HG202411180001") + private String id; + + @Version + @Schema(description = "版本号", required = true, example = "1") + private Integer version = 1; + + @Schema(description = "稽查单号", required = true, example = "") + private String billid; + + @Schema(description = "状态", required = true, pattern="-1:作废,1:待提交,2:待付款,3:已付款,4:(确认收款转待分仓)待分仓,5:已分仓-待出库,6:已出库", example = "") + private int status = 1; + /** 作废*/ + public final static int STATUS_MINUS_ONE = -1; + /** 待提交 */ + public final static int STATUS_ONE = 1; + /** 待付款 */ + public final static int STATUS_TWO = 2; + /** 已付款 */ + public final static int STATUS_THREE = 3; + /** (确认收款转待分仓)待分仓 */ + public final static int STATUS_FOUR = 4; + /** 已分仓-待出库 */ + public final static int STATUS_FIVE = 5; + /** 已出库 */ + public final static int STATUS_SIX = 6; +// /** 回购完成*/ +// public final static int STATUS_SEVEN = 7; + +// @Schema(description = "分仓状态", required = false, example = "") +// private int fcstatus = 1; +// public final static int FCSTATUS_ONE = 1;// 待分仓 +// public final static int FCSTATUS_TWO = 2;// 已分仓-待出库 +// public final static int FCSTATUS_THREE = 3;// 已出库 + + @Schema(description = "订单来源:掌上华致", required = true, example = "") + private String source; + + @Schema(description = "客户编码", required = true, example = "") + private String account; + + @Schema(description = "客户名称", required = true, example = "") + private String accountname; + + @Schema(description = "商品总数量", required = true, example = "") + private double quantity; + + @Schema(description = "商品总金额", required = true, example = "") + private double subtotal; + + @Schema(description = "运费", required = true, example = "") + private double freight; + + @Schema(description = "运营经理编码", required = true, example = "") + private String manager; + + @Schema(description = "运营经理名称", required = true, example = "") + private String managername; + + @Schema(description = "收货人姓名", required = true, example = "") + private String consignee; + + @Schema(description = "收货人电话", required = true, example = "") + private String consigneephone; + + @Schema(description = "省", required = true, example = "") + private String province; + + @Schema(description = "省", required = true, example = "") + private String provincename; + + @Schema(description = "市", required = true, example = "") + private String city; + + @Schema(description = "市", required = true, example = "") + private String cityname; + + @Schema(description = "区", required = true, example = "") + private String area; + + @Schema(description = "区", required = true, example = "") + private String areaname; + + @Schema(description = "详细地址", required = true, example = "") + private String address; + + @Schema(description = "收货方式", pattern = "0:送货上门1:仓库自提2:货站自提3:空运自提", required = true, example = "") + private String receiveway; + /** 送货上门 */ + public final static String RECEIVEWAY_ZERO = "0"; + /** 仓库自提 */ + public final static String RECEIVEWAY_ONE = "1"; + /** 货站自提 */ + public final static String RECEIVEWAY_TWO = "2"; + /** 空运自提 */ + public final static String RECEIVEWAY_THREE = "3"; + + + @Schema(description = "订单备注", required = true, example = "") + private String remark; + + @Schema(description = "运营备注", required = true, example = "") + private String remark1; + + @Schema(description = "分销区域编码", required = true, example = "") + private String salearea; + + @Schema(description = "分销区域名称", required = true, example = "") + private String saleareaname; + + @Schema(description = "业务组编码", required = true, example = "") + private String groupid; + + @Schema(description = "业务组名称", required = true, example = "") + private String groupname; + + @Schema(description = "创建人", required = true, example = "") + private String found; + + @Schema(description = "创建人编码", required = true, example = "") + private String foundname; + + @Schema(description = "创建时间", required = true, example = "") + private Date founddt; + + @Schema(description = "提交人编码", required = true, example = "") + private String submit; + + @Schema(description = "提交人名称", required = true, example = "") + private String submitname; + + @Schema(description = "提交人时间", required = true, example = "") + private Date submitdt; + + @Schema(description = "审核人编码", required = true, example = "") + private String audit; + + @Schema(description = "审核人名称", required = true, example = "") + private String auditname; + + @Schema(description = "审核人时间", required = true, example = "") + private Date auditdt; + + @Schema(description = "分货仓库编码", required = true, example = "") + private String fhwarehouse; + + @Schema(description = "分货仓库名称", required = true, example = "") + private String fhwarehousename; + + @Schema(description = "物流公司名称", required = true, example = "") + private String logisticsname; + + @Schema(description = "物流公司代码", required = true, example = "") + private String logisticscode; + + @Schema(description = "物流方式", required = true, example = "") + private String logisticstype; + + @Schema(description = "物流单号", required = true, example = "") + private String logisticsno; + + @Schema(description = "旺店通单号", required = true, example = "") + private String wdtorder; + + @Schema(description = "旺店通出库单号", required = true, example = "") + private String wdtbillout; + + @Schema(description = "旺店通出库状态", required = true, example = "") + private String wdtbillouttyp; + + @Schema(description = "旺店通出库时间", required = true, example = "") + private Date wdtoutdt; + + @Schema(description = "旺店通入库时间", required = true, example = "") + private Date wdtindt; + + @Schema(description = "传输旺店通时间", required = true, example = "") + private Date wdtdt; + + @Schema(description = "回款客户名称", required = true, example = "") + private String proofaccountname; + + @Schema(description = "凭证上传时间", required = true, example = "") + private Date proofdt; + + @Schema(description = "时间戳", required = true, example = "") + private Date dt = new Date(); + + // 合计金额=商品总金额+运费 + @Transient + private double amount; + + // 稽查单状态 + @Transient + private int jcstatus; + +// public int getFcstatus() { +// return fcstatus; +// } +// +// public void setFcstatus(int fcstatus) { +// this.fcstatus = fcstatus; +// } + + public double getAmount() { + return amount; + } + + public int getJcstatus() { + return jcstatus; + } + + public void setJcstatus(int jcstatus) { + this.jcstatus = jcstatus; + } + + public Date getWdtoutdt() { + return wdtoutdt; + } + + public void setWdtoutdt(Date wdtoutdt) { + this.wdtoutdt = wdtoutdt; + } + + public Date getWdtindt() { + return wdtindt; + } + + public void setWdtindt(Date wdtindt) { + this.wdtindt = wdtindt; + } + + public String getProofaccountname() { + return proofaccountname; + } + + public void setProofaccountname(String proofaccountname) { + this.proofaccountname = proofaccountname; + } + + public Date getProofdt() { + return proofdt; + } + + public void setProofdt(Date proofdt) { + this.proofdt = proofdt; + } + + public String getWdtorder() { + return wdtorder; + } + + public void setWdtorder(String wdtorder) { + this.wdtorder = wdtorder; + } + + public String getWdtbillout() { + return wdtbillout; + } + + public void setWdtbillout(String wdtbillout) { + this.wdtbillout = wdtbillout; + } + + public String getWdtbillouttyp() { + return wdtbillouttyp; + } + + public void setWdtbillouttyp(String wdtbillouttyp) { + this.wdtbillouttyp = wdtbillouttyp; + } + + public Date getWdtdt() { + return wdtdt; + } + + public void setWdtdt(Date wdtdt) { + this.wdtdt = wdtdt; + } + + public void setAmount(double amount) { + this.amount = amount; + } + + public String getFhwarehouse() { + return fhwarehouse; + } + + public void setFhwarehouse(String fhwarehouse) { + this.fhwarehouse = fhwarehouse; + } + + public String getFhwarehousename() { + return fhwarehousename; + } + + public void setFhwarehousename(String fhwarehousename) { + this.fhwarehousename = fhwarehousename; + } + + public String getLogisticsname() { + return logisticsname; + } + + public void setLogisticsname(String logisticsname) { + this.logisticsname = logisticsname; + } + + public String getLogisticscode() { + return logisticscode; + } + + public void setLogisticscode(String logisticscode) { + this.logisticscode = logisticscode; + } + + public String getLogisticstype() { + return logisticstype; + } + + public void setLogisticstype(String logisticstype) { + this.logisticstype = logisticstype; + } + + public String getLogisticsno() { + return logisticsno; + } + + public void setLogisticsno(String logisticsno) { + this.logisticsno = logisticsno; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getBillid() { + return billid; + } + + public void setBillid(String billid) { + this.billid = billid; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAccountname() { + return accountname; + } + + public void setAccountname(String accountname) { + this.accountname = accountname; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public double getSubtotal() { + return subtotal; + } + + public void setSubtotal(double subtotal) { + this.subtotal = subtotal; + } + + public double getFreight() { + return freight; + } + + public void setFreight(double freight) { + this.freight = freight; + } + + public String getManager() { + return manager; + } + + public void setManager(String manager) { + this.manager = manager; + } + + public String getManagername() { + return managername; + } + + public void setManagername(String managername) { + this.managername = managername; + } + + public String getConsignee() { + return consignee; + } + + public void setConsignee(String consignee) { + this.consignee = consignee; + } + + public String getConsigneephone() { + return consigneephone; + } + + public void setConsigneephone(String consigneephone) { + this.consigneephone = consigneephone; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province; + } + + public String getProvincename() { + return provincename; + } + + public void setProvincename(String provincename) { + this.provincename = provincename; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getCityname() { + return cityname; + } + + public void setCityname(String cityname) { + this.cityname = cityname; + } + + public String getArea() { + return area; + } + + public void setArea(String area) { + this.area = area; + } + + public String getAreaname() { + return areaname; + } + + public void setAreaname(String areaname) { + this.areaname = areaname; + } + + public String getAddress() { + return address; + } + + public void setAddress(String address) { + this.address = address; + } + + public String getReceiveway() { + return receiveway; + } + + public void setReceiveway(String receiveway) { + this.receiveway = receiveway; + } + + public String getRemark() { + return remark; + } + + public void setRemark(String remark) { + this.remark = remark; + } + + public String getRemark1() { + return remark1; + } + + public void setRemark1(String remark1) { + this.remark1 = remark1; + } + + public String getSalearea() { + return salearea; + } + + public void setSalearea(String salearea) { + this.salearea = salearea; + } + + public String getSaleareaname() { + return saleareaname; + } + + public void setSaleareaname(String saleareaname) { + this.saleareaname = saleareaname; + } + + public String getGroupid() { + return groupid; + } + + public void setGroupid(String groupid) { + this.groupid = groupid; + } + + public String getGroupname() { + return groupname; + } + + public void setGroupname(String groupname) { + this.groupname = groupname; + } + + public String getFound() { + return found; + } + + public void setFound(String found) { + this.found = found; + } + + public String getFoundname() { + return foundname; + } + + public void setFoundname(String foundname) { + this.foundname = foundname; + } + + public Date getFounddt() { + return founddt; + } + + public void setFounddt(Date founddt) { + this.founddt = founddt; + } + + public String getSubmit() { + return submit; + } + + public void setSubmit(String submit) { + this.submit = submit; + } + + public String getSubmitname() { + return submitname; + } + + public void setSubmitname(String submitname) { + this.submitname = submitname; + } + + public Date getSubmitdt() { + return submitdt; + } + + public void setSubmitdt(Date submitdt) { + this.submitdt = submitdt; + } + + public String getAudit() { + return audit; + } + + public void setAudit(String audit) { + this.audit = audit; + } + + public String getAuditname() { + return auditname; + } + + public void setAuditname(String auditname) { + this.auditname = auditname; + } + + public Date getAuditdt() { + return auditdt; + } + + public void setAuditdt(Date auditdt) { + this.auditdt = auditdt; + } + + public Date getDt() { + return dt; + } + + public void setDt(Date dt) { + this.dt = dt; + } +} + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillHgPay.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillHgPay.java new file mode 100644 index 0000000..adb3fcd --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillHgPay.java @@ -0,0 +1,150 @@ +package abacus.springboot.example.dao; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Version; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Entity +@Table(name = "jc_billhg_pay") +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(description = "回购支付明细") +public class JcBillHgPay implements Serializable { + + private static final long serialVersionUID = 7782628530648454397L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Schema(description = "自增长编码", required = true, example = "10") + private Long id; + + @Version + @Schema(description = "版本号", required = true, example = "1") + private Integer version; + + @Schema(description = "稽查单号", required = true, example = "") + private String billid; + + @Schema(description = "回购单号", required = true, example = "") + private String billhg; + + @Schema(description = "支付方式", required = true, example = "") + private String payment; + + @Schema(description = "支付金额", required = true, example = "") + private double amount; + + @Schema(description = "账号名称", required = true, example = "") + private String zhmc; + + @Schema(description = "开发银行", required = true, example = "") + private String khyh; + + @Schema(description = "银行账号", required = true, example = "") + private String yhzh; + + @Schema(description = "时间戳", required = true, example = "") + private Date dt = new Date(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getBillid() { + return billid; + } + + public void setBillid(String billid) { + this.billid = billid; + } + + public String getBillhg() { + return billhg; + } + + public void setBillhg(String billhg) { + this.billhg = billhg; + } + + public String getPayment() { + return payment; + } + + public void setPayment(String payment) { + this.payment = payment; + } + + public double getAmount() { + return amount; + } + + public void setAmount(double amount) { + this.amount = amount; + } + + public String getZhmc() { + return zhmc; + } + + public void setZhmc(String zhmc) { + this.zhmc = zhmc; + } + + public String getKhyh() { + return khyh; + } + + public void setKhyh(String khyh) { + this.khyh = khyh; + } + + public String getYhzh() { + return yhzh; + } + + public void setYhzh(String yhzh) { + this.yhzh = yhzh; + } + + public Date getDt() { + return dt; + } + + public void setDt(Date dt) { + this.dt = dt; + } +} + + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillInItem.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillInItem.java new file mode 100644 index 0000000..4102207 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillInItem.java @@ -0,0 +1,486 @@ +package abacus.springboot.example.dao; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Transient; +import javax.persistence.Version; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Entity +@Table(name = "jc_billin_item") +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(description = "稽查入库(回购通知)明细") +public class JcBillInItem implements Serializable { + + private static final long serialVersionUID = -3841490251161254597L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Schema(description = "自增长编码", required = true, example = "10") + private Long id; + + @Version + @Schema(description = "版本号", required = true, example = "1") + private Integer version; + + @Schema(description = "稽查单号", required = true, example = "") + private String billid; + + @Schema(description = "入库单号", required = true, example = "") + private String billin; + + @Schema(description = "回购单号", required = true, example = "") + private String billhg; + + @Schema(description = "状态", required = true, pattern="-1:终止,1:待通知回购,2:已通知回购", example = "") + private int status = 1; + /** 终止*/ + public final static int STATUS_MINUS_ONE = -1; + /** 待通知回购*/ + public final static int STATUS_ONE = 1; + /** 已通知回购*/ + public final static int STATUS_TWO = 2; + + @Schema(description = "收货渠道-收货门店", required = true, example = "") + private String channel; + + @Schema(description = "客户编码", required = true, example = "") + private String account; + + @Schema(description = "客户名称", required = true, example = "") + private String accountname; + + @Schema(description = "商品编码", required = true, example = "") + private String product; + + @Schema(description = "商品名称", required = true, example = "") + private String productname; + + @Schema(description = "收货单价", required = true, example = "") + private double price; + + @Schema(description = "入库数量", required = true, example = "") + private double quantity; + + @Schema(description = "入库件数", required = true, example = "") + private double numbers; + + @Schema(description = "回购单价", required = true, example = "") + private Double hgprice; + + @Schema(description = "回购金额", required = true, example = "") + private Double hgamount; + + @Schema(description = "业务员编码", required = true, example = "") + private String operator; + + @Schema(description = "业务员名称", required = true, example = "") + private String operatorname; + + @Schema(description = "业务组编码", required = true, example = "") + private String groupid; + + @Schema(description = "业务组名称", required = true, example = "") + private String groupname; + + @Schema(description = "分销区域编码", required = true, example = "") + private String salearea; + + @Schema(description = "分销区域名称", required = true, example = "") + private String saleareaname; + + @Schema(description = "分货数量", required = true, example = "") + private double fhquantity; + + @Schema(description = "分货件数", required = true, example = "") + private double fhnumbers; + + @Schema(description = "分货仓库编码", required = true, hidden = true, example = "") + private String fhwarehouse; + + @Schema(description = "分货仓库名称", required = true, hidden = true, example = "") + private String fhwarehousename; + + @Schema(description = "旺店通单号", required = true, hidden = true, example = "") + private String wdtorder; + + @Schema(description = "旺店通出库单号", required = true, hidden = true, example = "") + private String wdtbillout; + + @Schema(description = "旺店通出库状态", required = true, hidden = true, example = "") + private String wdtbillouttyp; + + @Schema(description = "旺店通出库时间", required = true, hidden = true, example = "") + private Date wdtoutdt; + + @Schema(description = "旺店通入库时间", required = true, hidden = true, example = "") + private Date wdtindt; + + @Schema(description = "传输旺店通时间", required = true, hidden = true, example = "") + private Date wdtdt; + + @Schema(description = "时间戳", required = true, example = "") + private Date dt = new Date(); + + @Transient + @Schema(description = "规格", hidden = true, required = false, example = "") + private String spec; + + @Transient + @Schema(description = "计量单位", hidden = true, required = false, example = "瓶") + private String measure; + + @Transient + @Schema(description = "采购包装单位", hidden = true, required = false, example = "false") + private String purunit; + + @Transient + @Schema(description = "采购包装量", hidden = true, required = true, example = "1") + private double purpkg = 1.0; + + @Transient + @Schema(description = "历史价格", hidden = true, required = true, example = "1") + private Double oldhgprice; + + @Transient + @Schema(description = "物流公司名称", hidden = true, required = true, example = "") + private String logisticsname; + + @Transient + @Schema(description = "物流单号", hidden = true, required = true, example = "") + private String logisticsno; + + public String getLogisticsname() { + return logisticsname; + } + + public void setLogisticsname(String logisticsname) { + this.logisticsname = logisticsname; + } + + public String getLogisticsno() { + return logisticsno; + } + + public void setLogisticsno(String logisticsno) { + this.logisticsno = logisticsno; + } + + public Date getWdtoutdt() { + return wdtoutdt; + } + + public void setWdtoutdt(Date wdtoutdt) { + this.wdtoutdt = wdtoutdt; + } + + public Date getWdtindt() { + return wdtindt; + } + + public void setWdtindt(Date wdtindt) { + this.wdtindt = wdtindt; + } + + public String getChannel() { + return channel; + } + + public void setChannel(String channel) { + this.channel = channel; + } + + public Double getOldhgprice() { + return oldhgprice; + } + + public void setOldhgprice(Double oldhgprice) { + this.oldhgprice = oldhgprice; + } + + public String getSpec() { + return spec; + } + + public void setSpec(String spec) { + this.spec = spec; + } + + public String getMeasure() { + return measure; + } + + public void setMeasure(String measure) { + this.measure = measure; + } + + public String getPurunit() { + return purunit; + } + + public void setPurunit(String purunit) { + this.purunit = purunit; + } + + public double getPurpkg() { + return purpkg; + } + + public void setPurpkg(double purpkg) { + this.purpkg = purpkg; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getBillid() { + return billid; + } + + public void setBillid(String billid) { + this.billid = billid; + } + + public String getBillin() { + return billin; + } + + public void setBillin(String billin) { + this.billin = billin; + } + + public String getBillhg() { + return billhg; + } + + public void setBillhg(String billhg) { + this.billhg = billhg; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAccountname() { + return accountname; + } + + public void setAccountname(String accountname) { + this.accountname = accountname; + } + + public String getProduct() { + return product; + } + + public void setProduct(String product) { + this.product = product; + } + + public String getProductname() { + return productname; + } + + public void setProductname(String productname) { + this.productname = productname; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public double getNumbers() { + return numbers; + } + + public void setNumbers(double numbers) { + this.numbers = numbers; + } + + public Double getHgprice() { + return hgprice; + } + + public void setHgprice(Double hgprice) { + this.hgprice = hgprice; + } + + public Double getHgamount() { + return hgamount; + } + + public void setHgamount(Double hgamount) { + this.hgamount = hgamount; + } + + public String getOperator() { + return operator; + } + + public void setOperator(String operator) { + this.operator = operator; + } + + public String getOperatorname() { + return operatorname; + } + + public void setOperatorname(String operatorname) { + this.operatorname = operatorname; + } + + public String getGroupid() { + return groupid; + } + + public void setGroupid(String groupid) { + this.groupid = groupid; + } + + public String getGroupname() { + return groupname; + } + + public void setGroupname(String groupname) { + this.groupname = groupname; + } + + public String getSalearea() { + return salearea; + } + + public void setSalearea(String salearea) { + this.salearea = salearea; + } + + public String getSaleareaname() { + return saleareaname; + } + + public void setSaleareaname(String saleareaname) { + this.saleareaname = saleareaname; + } + + public double getFhquantity() { + return fhquantity; + } + + public void setFhquantity(double fhquantity) { + this.fhquantity = fhquantity; + } + + public double getFhnumbers() { + return fhnumbers; + } + + public void setFhnumbers(double fhnumbers) { + this.fhnumbers = fhnumbers; + } + + public String getFhwarehouse() { + return fhwarehouse; + } + + public void setFhwarehouse(String fhwarehouse) { + this.fhwarehouse = fhwarehouse; + } + + public String getFhwarehousename() { + return fhwarehousename; + } + + public void setFhwarehousename(String fhwarehousename) { + this.fhwarehousename = fhwarehousename; + } + + public String getWdtorder() { + return wdtorder; + } + + public void setWdtorder(String wdtorder) { + this.wdtorder = wdtorder; + } + + public String getWdtbillout() { + return wdtbillout; + } + + public void setWdtbillout(String wdtbillout) { + this.wdtbillout = wdtbillout; + } + + public String getWdtbillouttyp() { + return wdtbillouttyp; + } + + public void setWdtbillouttyp(String wdtbillouttyp) { + this.wdtbillouttyp = wdtbillouttyp; + } + + public Date getWdtdt() { + return wdtdt; + } + + public void setWdtdt(Date wdtdt) { + this.wdtdt = wdtdt; + } + + public Date getDt() { + return dt; + } + + public void setDt(Date dt) { + this.dt = dt; + } +} + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillPhoto.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillPhoto.java new file mode 100644 index 0000000..061ca0b --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillPhoto.java @@ -0,0 +1,120 @@ +package abacus.springboot.example.dao; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Version; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Entity +@Table(name = "jc_bill_photo") +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(description = "稽查图片") +public class JcBillPhoto implements Serializable { + + private static final long serialVersionUID = -5561468051239492839L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Schema(description = "自增长编码", required = true, example = "10") + private Long id; + + @Version + @Schema(description = "版本号", required = true, example = "1") + private Integer version; + + @Schema(description = "来源单号", required = true, example = "1") + private String srcid; + + @Schema(description = "来源明细", required = true, example = "1") + private String srcitemid; + + @Schema(description = "图片类型", required = true, pattern="稽查付款截图,稽查货品图,回购通知函,回购违规通知函,回购支付凭证", example = "1") + private String typephoto; + public final static String JC_FK = "稽查付款截图"; + public final static String JC_HP = "稽查货品图"; + public final static String HG_TZH = "回购通知函"; + public final static String HG_WGTZH = "回购违规通知函"; + public final static String HG_ZFPZ = "回购支付凭证"; + + @Schema(description = "url地址", required = true, example = "1") + private String urlphoto; + + @Schema(description = "时间戳", required = true, example = "1") + private Date dt = new Date(); + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getSrcid() { + return srcid; + } + + public void setSrcid(String srcid) { + this.srcid = srcid; + } + + public String getSrcitemid() { + return srcitemid; + } + + public void setSrcitemid(String srcitemid) { + this.srcitemid = srcitemid; + } + + public String getTypephoto() { + return typephoto; + } + + public void setTypephoto(String typephoto) { + this.typephoto = typephoto; + } + + public String getUrlphoto() { + return urlphoto; + } + + public void setUrlphoto(String urlphoto) { + this.urlphoto = urlphoto; + } + + public Date getDt() { + return dt; + } + + public void setDt(Date dt) { + this.dt = dt; + } +} + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillSourceItem.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillSourceItem.java new file mode 100644 index 0000000..856d589 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcBillSourceItem.java @@ -0,0 +1,434 @@ +package abacus.springboot.example.dao; + +import java.io.Serializable; +import java.util.Date; +import java.util.List; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.persistence.Version; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Entity +@Table(name = "jc_billsource_item") +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(description = "稽查收货明细") +public class JcBillSourceItem implements Serializable { + + private static final long serialVersionUID = 8819914697371518608L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Schema(description = "自增长编码", required = true, example = "10") + private Long id; + + @Version + @Schema(description = "版本号", required = true, example = "1") + private Integer version = 1; + + @Schema(description = "行号", required = false, example = "2") + private int indexno; + + @Schema(description = "稽查单号", required = true, example = "") + private String billid; + + @Schema(description = "状态", required = true, pattern="-2:人工朔源驳回,-1:系统朔源验证未通过,0:系统溯源未验证,1:系统朔源验证通过,2:人工朔源待确认,3:人工朔源已确认", example = "") + private int status = 0; + /** 人工朔源驳回*/ + public final static int STATUS_MINUS_TWO = -2; + /** 系统朔源验证未通过*/ + public final static int STATUS_MINUS_ONE = -1; + /** 系统溯源未验证*/ + public final static int STATUS_ZERO = 0; + /** 系统朔源验证通过*/ + public final static int STATUS_ONE = 1; + /** 人工朔源待确认*/ + public final static int STATUS_TWO = 2; + /** 人工朔源已确认*/ + public final static int STATUS_THREE = 3; + + @Schema(description = "收货来源", required = true, example = "") + private String recsource; + + @Schema(description = "收货平台", required = true, example = "") + private String recplatform; + + @Schema(description = "收货渠道", required = true, example = "") + private String channel; + + @Schema(description = "收货单价", required = true, example = "") + private double price; + + @Schema(description = "收货数量", required = true, example = "") + private double quantity; + + @Schema(description = "收货件数", required = true, example = "") + private double numbers; + + @Schema(description = "收货金额", required = true, example = "") + private double subtotal; + + @Schema(description = "货品编号", required = true, example = "") + private String goodsid; + + @Schema(description = "物流码", required = true, example = "") + private String logisticsid; + + @Schema(description = "出库单号", required = true, example = "") + private String billout; + + @Temporal(TemporalType.TIMESTAMP) + @Schema(description = "出库日期", required = true, example = "") + private Date billoutdt; + + @Schema(description = "出库仓库编码", required = true, example = "") + private String billoutwh; + + @Schema(description = "出库仓库名称", required = true, example = "") + private String billoutwhname; + + @Schema(description = "商品编码", required = true, example = "") + private String product; + + @Schema(description = "商品名称", required = true, example = "") + private String productname; + + @Schema(description = "客户编码", required = true, example = "") + private String account; + + @Schema(description = "客户名称", required = true, example = "") + private String accountname; + + @Schema(description = "考核业务员编码", required = true, example = "") + private String operator; + + @Schema(description = "考核业务员名称", required = true, example = "") + private String operatorname; + + @Schema(description = "业务组编码", required = true, example = "") + private String groupid; + + @Schema(description = "业务组名称", required = true, example = "") + private String groupname; + + @Schema(description = "分销区域编码", required = true, example = "") + private String salearea; + + @Schema(description = "分销区域名称", required = true, example = "") + private String saleareaname; + + @Schema(description = "比对来源", required = true, example = "") + private String source; + public static final String SOURCE_ERP = "业务中台"; + public static final String SOURCE_EWM = "二维码"; + public static final String SOURCE_XX = "线下"; + + @Schema(description = "驳回原因", required = true, example = "") + private String reason; + + @Temporal(TemporalType.TIMESTAMP) + @Schema(description = "时间戳", required = true, example = "") + private Date dt = new Date(); + + @Transient + @Schema(description = "付款图片", required = false, hidden = true, pattern = "这是个JSON数组,不是JSONArray对象", example = "[\"44444\",\"aaaaa\"]") + private List paymentPhoto; + + @Transient + @Schema(description = "货品图片", required = false, hidden = true, pattern = "这是个JSON数组,不是JSONArray对象", example = "[\"44444\",\"aaaaa\"]") + private List goodsPhotos; + + @Transient + @Schema(description = "货品图片", required = false, hidden = true, pattern = "这是个JSON数组,不是JSONArray对象", example = "[\"44444\",\"aaaaa\"]") + private List hpts; + + public List getHpts() { + return hpts; + } + + public void setHpts(List hpts) { + this.hpts = hpts; + } + + public List getPaymentPhoto() { + return paymentPhoto; + } + + public void setPaymentPhoto(List paymentPhoto) { + this.paymentPhoto = paymentPhoto; + } + + public List getGoodsPhotos() { + return goodsPhotos; + } + + public void setGoodsPhotos(List goodsPhotos) { + this.goodsPhotos = goodsPhotos; + } + + public int getIndexno() { + return indexno; + } + + public void setIndexno(int indexno) { + this.indexno = indexno; + } + + public String getRecplatform() { + return recplatform; + } + + public void setRecplatform(String recplatform) { + this.recplatform = recplatform; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getBillid() { + return billid; + } + + public void setBillid(String billid) { + this.billid = billid; + } + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public String getRecsource() { + return recsource; + } + + public void setRecsource(String recsource) { + this.recsource = recsource; + } + + public String getChannel() { + return channel; + } + + public void setChannel(String channel) { + this.channel = channel; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public double getQuantity() { + return quantity; + } + + public void setQuantity(double quantity) { + this.quantity = quantity; + } + + public double getNumbers() { + return numbers; + } + + public void setNumbers(double numbers) { + this.numbers = numbers; + } + + public double getSubtotal() { + return subtotal; + } + + public void setSubtotal(double subtotal) { + this.subtotal = subtotal; + } + + public String getGoodsid() { + return goodsid; + } + + public void setGoodsid(String goodsid) { + this.goodsid = goodsid; + } + + public String getLogisticsid() { + return logisticsid; + } + + public void setLogisticsid(String logisticsid) { + this.logisticsid = logisticsid; + } + + public String getBillout() { + return billout; + } + + public void setBillout(String billout) { + this.billout = billout; + } + + public Date getBilloutdt() { + return billoutdt; + } + + public void setBilloutdt(Date billoutdt) { + this.billoutdt = billoutdt; + } + + public String getBilloutwh() { + return billoutwh; + } + + public void setBilloutwh(String billoutwh) { + this.billoutwh = billoutwh; + } + + public String getBilloutwhname() { + return billoutwhname; + } + + public void setBilloutwhname(String billoutwhname) { + this.billoutwhname = billoutwhname; + } + + public String getProduct() { + return product; + } + + public void setProduct(String product) { + this.product = product; + } + + public String getProductname() { + return productname; + } + + public void setProductname(String productname) { + this.productname = productname; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAccountname() { + return accountname; + } + + public void setAccountname(String accountname) { + this.accountname = accountname; + } + + public String getOperator() { + return operator; + } + + public void setOperator(String operator) { + this.operator = operator; + } + + public String getOperatorname() { + return operatorname; + } + + public void setOperatorname(String operatorname) { + this.operatorname = operatorname; + } + + public String getGroupid() { + return groupid; + } + + public void setGroupid(String groupid) { + this.groupid = groupid; + } + + public String getGroupname() { + return groupname; + } + + public void setGroupname(String groupname) { + this.groupname = groupname; + } + + public String getSalearea() { + return salearea; + } + + public void setSalearea(String salearea) { + this.salearea = salearea; + } + + public String getSaleareaname() { + return saleareaname; + } + + public void setSaleareaname(String saleareaname) { + this.saleareaname = saleareaname; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public String getReason() { + return reason; + } + + public void setReason(String reason) { + this.reason = reason; + } + + public Date getDt() { + return dt; + } + + public void setDt(Date dt) { + this.dt = dt; + } +} + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcSourceItem.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcSourceItem.java new file mode 100644 index 0000000..f392b62 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/dao/JcSourceItem.java @@ -0,0 +1,298 @@ +package abacus.springboot.example.dao; + +import java.io.Serializable; +import java.util.Date; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import javax.persistence.Table; +import javax.persistence.Temporal; +import javax.persistence.TemporalType; +import javax.persistence.Transient; +import javax.persistence.Version; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +import io.swagger.v3.oas.annotations.media.Schema; + +@Entity +@Table(name = "jc_source_item") +@JsonIgnoreProperties(ignoreUnknown = true) +@Schema(description = "稽查溯源明细") +public class JcSourceItem implements Serializable { + + private static final long serialVersionUID = -2272967075701112300L; + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Schema(description = "自增长编码", required = true, example = "10") + private Long id; + + @Version + @Schema(description = "版本号", required = true, example = "1") + private Integer version = 1; + + @Schema(description = "稽查单号", required = true, example = "") + private String billid; + + @Schema(description = "明细Id", required = true, example = "") + private String srcitemid; + + @Schema(description = "状态", required = true, pattern="0:待确认,1:已确认", example = "") + private int status = 0; + /** 待确认*/ + public final static int STATUS_ZERO = 0; + /** 已确认*/ + public final static int STATUS_ONE = 1; + + @Schema(description = "货品编号", required = true, example = "") + private String goodsid; + + @Schema(description = "物流码", required = true, example = "") + private String logisticsid; + + @Schema(description = "出库单号", required = true, example = "") + private String billout; + + @Temporal(TemporalType.TIMESTAMP) + @Schema(description = "出库日期", required = true, example = "") + private Date billoutdt; + + @Schema(description = "出库仓库编码", required = true, example = "") + private String billoutwh; + + @Schema(description = "出库仓库名称", required = true, example = "") + private String billoutwhname; + + @Schema(description = "商品编码", required = true, example = "") + private String product; + + @Schema(description = "商品名称", required = true, example = "") + private String productname; + + @Schema(description = "客户编码", required = true, example = "") + private String account; + + @Schema(description = "客户名称", required = true, example = "") + private String accountname; + + @Schema(description = "考核业务员编码", required = true, example = "") + private String operator; + + @Schema(description = "考核业务员名称", required = true, example = "") + private String operatorname; + + @Schema(description = "业务组编码", required = true, example = "") + private String groupid; + + @Schema(description = "业务组名称", required = true, example = "") + private String groupname; + + @Schema(description = "分销区域编码", required = true, example = "") + private String salearea; + + @Schema(description = "分销区域名称", required = true, example = "") + private String saleareaname; + + @Schema(description = "比对来源", required = true, pattern="业务中台,二维码,线下", example = "") + private String source; + + @Temporal(TemporalType.TIMESTAMP) + @Schema(description = "时间戳", required = true, example = "") + private Date dt = new Date(); + + + public int getStatus() { + return status; + } + + public void setStatus(int status) { + this.status = status; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Integer getVersion() { + return version; + } + + public void setVersion(Integer version) { + this.version = version; + } + + public String getBillid() { + return billid; + } + + public void setBillid(String billid) { + this.billid = billid; + } + + public String getSrcitemid() { + return srcitemid; + } + + public void setSrcitemid(String srcitemid) { + this.srcitemid = srcitemid; + } + + public String getGoodsid() { + return goodsid; + } + + public void setGoodsid(String goodsid) { + this.goodsid = goodsid; + } + + public String getLogisticsid() { + return logisticsid; + } + + public void setLogisticsid(String logisticsid) { + this.logisticsid = logisticsid; + } + + public String getBillout() { + return billout; + } + + public void setBillout(String billout) { + this.billout = billout; + } + + public Date getBilloutdt() { + return billoutdt; + } + + public void setBilloutdt(Date billoutdt) { + this.billoutdt = billoutdt; + } + + public String getBilloutwh() { + return billoutwh; + } + + public void setBilloutwh(String billoutwh) { + this.billoutwh = billoutwh; + } + + public String getBilloutwhname() { + return billoutwhname; + } + + public void setBilloutwhname(String billoutwhname) { + this.billoutwhname = billoutwhname; + } + + public String getProduct() { + return product; + } + + public void setProduct(String product) { + this.product = product; + } + + public String getProductname() { + return productname; + } + + public void setProductname(String productname) { + this.productname = productname; + } + + public String getAccount() { + return account; + } + + public void setAccount(String account) { + this.account = account; + } + + public String getAccountname() { + return accountname; + } + + public void setAccountname(String accountname) { + this.accountname = accountname; + } + + public String getOperator() { + return operator; + } + + public void setOperator(String operator) { + this.operator = operator; + } + + public String getOperatorname() { + return operatorname; + } + + public void setOperatorname(String operatorname) { + this.operatorname = operatorname; + } + + public String getGroupid() { + return groupid; + } + + public void setGroupid(String groupid) { + this.groupid = groupid; + } + + public String getGroupname() { + return groupname; + } + + public void setGroupname(String groupname) { + this.groupname = groupname; + } + + public String getSalearea() { + return salearea; + } + + public void setSalearea(String salearea) { + this.salearea = salearea; + } + + public String getSaleareaname() { + return saleareaname; + } + + public void setSaleareaname(String saleareaname) { + this.saleareaname = saleareaname; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + + public Date getDt() { + return dt; + } + + public void setDt(Date dt) { + this.dt = dt; + } +} + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/esb/ApiJcBillService.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/esb/ApiJcBillService.java new file mode 100644 index 0000000..86d1f09 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/esb/ApiJcBillService.java @@ -0,0 +1,835 @@ +package abacus.springboot.example.esb; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import abacus.springboot.example.api.view.ApiBillHg; +import abacus.springboot.example.api.view.ApiBillHgItem; +import abacus.springboot.example.api.view.ApiBillHgPayment; +import abacus.springboot.example.api.view.ApiJcBill; +import abacus.springboot.example.api.view.ApiJcBillHgSearchItem; +import abacus.springboot.example.api.view.ApiJcBillItem; +import abacus.springboot.example.api.view.ApiJcBillSearch; +import abacus.springboot.example.api.view.ApiReqJcBill; +import abacus.springboot.example.api.view.ApiReqJcBillGoodsPhoto; +import abacus.springboot.example.api.view.ApiReqJcBillItem; +import abacus.springboot.example.api.view.JcBillCount; +import abacus.springboot.example.api.view.JcCodeFlow; +import abacus.springboot.example.api.view.JcProduct; +import abacus.springboot.example.api.view.JcProductBillSouce; +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillHg; +import abacus.springboot.example.dao.JcBillHgPay; +import abacus.springboot.example.dao.JcBillInItem; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.dao.JcSourceItem; +import abacus.springboot.example.pi.ApiJcBillAccessIF; +import abacus.springboot.example.pi.JcBillAccessIF; +import abacus.springboot.example.repository.JcBillHgPayRepository; +import abacus.springboot.example.repository.JcBillHgRepository; +import abacus.springboot.example.repository.JcBillInItemRepository; +import abacus.springboot.example.repository.JcBillPhotoRepository; +import abacus.springboot.example.repository.JcBillRepository; +import abacus.springboot.example.repository.JcBillSourceItemRepository; +import abacus.springboot.example.repository.JcSourceItemRepository; +import abacus.springboot.example.wsi.ApiJcBillServiceIF; + +@Service +public class ApiJcBillService implements ApiJcBillServiceIF { + + private static final Logger LOG = LoggerFactory.getLogger(ApiJcBillService.class); + + @Autowired + private ApiJcBillAccessIF apiJcBillAccess; + + @Autowired + private JcBillAccessIF jcBillAccess; + + @Autowired + private JcBillRepository jcBillRepository; + + @Autowired + private JcBillSourceItemRepository jcBillSourceItemRepository; + + @Autowired + private JcBillPhotoRepository jcBillPhotoRepository; + + @Autowired + private JcBillHgRepository jcBillHgRepository; + + @Autowired + private JcBillHgPayRepository jcBillHgPayRepository; + + @Autowired + private JcSourceItemRepository jcSourceItemRepository; + + @Autowired + private JcBillInItemRepository jcBillInItemRepository; + + @Override + public Page queryApiJcBillSearch(String keyword, String employee, String status, Pageable pageable) + throws RuntimeException { + try { + return this.apiJcBillAccess.queryApiJcBillSearch(keyword, employee, status, pageable); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public ApiJcBill queryApiJcBillById(String id) throws RuntimeException { + try { + return this.apiJcBillAccess.queryApiJcBillById(id); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryApiJcBillItemByBIllId(String billId) throws RuntimeException { + try { + return this.apiJcBillAccess.queryApiJcBillItemByBIllId(billId); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public Map> queryJcBillPhoto(String srcid) throws RuntimeException { + try { + List billPhotos = jcBillAccess.queryJcBillPhoto(srcid, null, null); + + if(billPhotos == null) return new HashMap>(); + + Map> map = billPhotos.stream() + .collect(Collectors.groupingBy(e -> { + return e.getTypephoto() + "#" + e.getSrcitemid(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + return map; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public Map> queryJcBillPhotoIn(List srcids) throws RuntimeException { + try { + List billPhotos = jcBillAccess.queryJcBillPhotoIn(srcids); + + if(billPhotos == null) return new HashMap>(); + + Map> map = billPhotos.stream() + .collect(Collectors.groupingBy(e -> { + return e.getTypephoto() + "#" + e.getSrcitemid(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + return map; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public ApiReqJcBill saveApiReqJcBill(ApiReqJcBill reqJcBill, JcBill jcBill, List createItems) + throws RuntimeException { + try { + + List tempItems = jcBillSourceItemRepository.saveAll(createItems); + +// Map map = tempItems.stream() +// .collect(Collectors.groupingBy(e -> { +// return String.valueOf(e.getIndexno()) + e.getGoodsid(); +// }, +// Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)) +// )); + + // 新增 + List createPhoto = new ArrayList(); + if(reqJcBill.getItems() != null && reqJcBill.getItems().size() >= 1) { + JcBillPhoto fkPhoto = null; + JcBillPhoto hpPhoto = null; + for(ApiReqJcBillItem item : reqJcBill.getItems()) { + + // 付款图 + if(item.getPaymentPhoto() != null && item.getPaymentPhoto().size() >= 1) { + for(String urlphoto : item.getPaymentPhoto()) { + fkPhoto = new JcBillPhoto(); + fkPhoto.setSrcid(jcBill.getId()); + fkPhoto.setSrcitemid(String.valueOf(item.getIndexno())); + fkPhoto.setTypephoto(JcBillPhoto.JC_FK); + fkPhoto.setUrlphoto(urlphoto); + + createPhoto.add(fkPhoto); + } + } + + for(ApiReqJcBillGoodsPhoto photo : item.getGoodsPhotos()) { + // 货品图 + if(item.getGoodsPhotos() != null && item.getGoodsPhotos().size() >= 1) { + for(String urlphoto : photo.getGoodsPhotos()) { + hpPhoto = new JcBillPhoto(); + hpPhoto.setSrcid(jcBill.getId()); + hpPhoto.setSrcitemid(String.valueOf(item.getIndexno()) + "#" + photo.getGoodsid()); + hpPhoto.setTypephoto(JcBillPhoto.JC_HP); + hpPhoto.setUrlphoto(urlphoto); + + createPhoto.add(hpPhoto); + } + } + } + } + } + + + // 删除图片 + jcBillAccess.deleteJcBillPhoto(jcBill.getId(), null, JcBillPhoto.JC_FK); + jcBillAccess.deleteJcBillPhoto(jcBill.getId(), null, JcBillPhoto.JC_HP); + + jcBillPhotoRepository.saveAll(createPhoto); + + jcBillRepository.save(jcBill); + + return reqJcBill; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public ApiReqJcBill updateApiReqJcBill(ApiReqJcBill reqJcBill, JcBill jcBill, List createItems, + List updateItems) throws RuntimeException { + try { + +// Map map = tempItems.stream() +// .collect(Collectors.groupingBy(e -> { +// return String.valueOf(e.getIndexno()) + e.getGoodsid(); +// }, +// Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)) +// )); + + // 新增 + List createPhoto = new ArrayList(); + if(reqJcBill.getItems() != null && reqJcBill.getItems().size() >= 1) { + JcBillPhoto fkPhoto = null; + JcBillPhoto hpPhoto = null; + for(ApiReqJcBillItem item : reqJcBill.getItems()) { + + // 付款图 + if(item.getPaymentPhoto() != null && item.getPaymentPhoto().size() >= 1) { + for(String urlphoto : item.getPaymentPhoto()) { + fkPhoto = new JcBillPhoto(); + fkPhoto.setSrcid(jcBill.getId()); + fkPhoto.setSrcitemid(String.valueOf(item.getIndexno())); + fkPhoto.setTypephoto(JcBillPhoto.JC_FK); + fkPhoto.setUrlphoto(urlphoto); + + createPhoto.add(fkPhoto); + } + } + + for(ApiReqJcBillGoodsPhoto photo : item.getGoodsPhotos()) { + // 货品图 + if(item.getGoodsPhotos() != null && item.getGoodsPhotos().size() >= 1) { + for(String urlphoto : photo.getGoodsPhotos()) { + hpPhoto = new JcBillPhoto(); + hpPhoto.setSrcid(jcBill.getId()); + hpPhoto.setSrcitemid(String.valueOf(item.getIndexno()) + "#" + photo.getGoodsid()); + hpPhoto.setTypephoto(JcBillPhoto.JC_HP); + hpPhoto.setUrlphoto(urlphoto); + + createPhoto.add(hpPhoto); + } + } + } + } + } + + + // 删除图片 + jcBillAccess.deleteJcBillPhoto(jcBill.getId(), null, JcBillPhoto.JC_FK); + jcBillAccess.deleteJcBillPhoto(jcBill.getId(), null, JcBillPhoto.JC_HP); + + jcBillSourceItemRepository.deleteByBillid(jcBill.getId()); + + jcBillRepository.deleteById(jcBill.getId()); + + List tempItems = jcBillSourceItemRepository.saveAll(createItems); + + jcBillPhotoRepository.saveAll(createPhoto); + + jcBillRepository.save(jcBill); + + return reqJcBill; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + /*@Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public ApiReqJcBill updateApiReqJcBill(ApiReqJcBill reqJcBill, JcBill jcBill, List createItems, + List updateItems) throws RuntimeException { + try { + + List tempItems = jcBillSourceItemRepository.saveAll(createItems); + +// Map map = tempItems.stream() +// .collect(Collectors.groupingBy(e -> { +// return String.valueOf(e.getIndexno()); +// }, +// Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)) +// )); + + // 新增 + List createPhoto = new ArrayList(); + // 修改 + List updatePhoto = new ArrayList(); + + if(reqJcBill.getItems() != null && reqJcBill.getItems().size() >= 1) { + JcBillPhoto fkPhoto = null; + JcBillPhoto hpPhoto = null; + for(ApiReqJcBillItem item : reqJcBill.getItems()) { + + // 付款图 + if(item.getPaymentPhoto() != null && item.getPaymentPhoto().size() >= 1) { + for(String urlphoto : item.getPaymentPhoto()) { + fkPhoto = new JcBillPhoto(); + fkPhoto.setSrcid(jcBill.getId()); + fkPhoto.setSrcitemid(String.valueOf(item.getIndexno())); + fkPhoto.setTypephoto(JcBillPhoto.JC_FK); + fkPhoto.setUrlphoto(urlphoto); + + createPhoto.add(fkPhoto); + } + } + + for(ApiReqJcBillGoodsPhoto photo : item.getGoodsPhotos()) { + // 货品图 + if(item.getGoodsPhotos() != null && item.getGoodsPhotos().size() >= 1) { + for(String urlphoto : photo.getGoodsPhotos()) { + hpPhoto = new JcBillPhoto(); + hpPhoto.setSrcid(jcBill.getId()); + hpPhoto.setSrcitemid(String.valueOf(item.getIndexno()) + "#" + photo.getGoodsid()); + hpPhoto.setTypephoto(JcBillPhoto.JC_HP); + hpPhoto.setUrlphoto(urlphoto); + + createPhoto.add(hpPhoto); + } + } + } + } + } + + + // 删除图片 +// for(JcBillPhoto photo : createPhoto) { +// jcBillAccess.deleteJcBillPhoto(photo.getSrcid(), photo.getSrcitemid(), photo.getTypephoto()); +// } + jcBillAccess.deleteJcBillPhoto(jcBill.getId(), null, JcBillPhoto.JC_FK); + jcBillAccess.deleteJcBillPhoto(jcBill.getId(), null, JcBillPhoto.JC_HP); + + jcBillPhotoRepository.saveAll(createPhoto); + + jcBillAccess.updateJcBill(jcBill); + + jcBillAccess.updateJcBillSourceItem(updateItems); + + List itemsLogs = new ArrayList(); + itemsLogs.addAll(tempItems); + itemsLogs.addAll(updateItems); + + List photoLogs = new ArrayList(); + photoLogs.addAll(createPhoto); + photoLogs.addAll(updatePhoto); + + 操作日志 + OperationLog log = new OperationLog("api_jc_bill", jcBill.getId(), "更新", "", "", + JSONObject.toJSONString(jcBill) + JSONArray.toJSONString(itemsLogs) + JSONArray.toJSONString(photoLogs)); + log.setOperator(jcBill.getApplicant()); + log.setOperatorName(jcBill.getApplicantname()); + BusinessESUtil.checkService(this.operationLogService).saveOperationLog(log); + + return reqJcBill; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + }*/ + + @Override + public int countJcBillItemIndexno(String billId) throws RuntimeException { + try { + return jcBillAccess.countJcBillItemIndexno(billId); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public JcBill queryJcBillById(String billId) throws RuntimeException { + try { + Optional optional = jcBillRepository.findById(billId); + + return optional.isPresent() ? optional.get() : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcBillSourceItemByBillId(String billId) throws RuntimeException { + try { + List list = jcBillSourceItemRepository.findByBillid(billId); + + return (list != null && list.size() >= 1) ? list : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public JcBillSourceItem queryJcBillSourceItembyId(Long id) throws RuntimeException { + try { + + Optional optional = jcBillSourceItemRepository.findById(id); + + return optional.isPresent() ? optional.get() : new JcBillSourceItem(); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void updateStatusJcBill(JcBill jcBill, int oldStatus) throws RuntimeException { + try { + jcBillRepository.save(jcBill); + +// jcBillSourceItemRepository.saveAll(sourceItems); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public Page queryApiJcBillHgSearchItem(String keyword, String employee, String status, Pageable pageable) + throws RuntimeException { + try { + return this.apiJcBillAccess.queryApiJcBillHgSearchItem(keyword, employee, status, pageable); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public Map queryJcBillCount(List ids) throws RuntimeException { + try { + + if(ids != null && ids.size() >= 1) { + List counts = apiJcBillAccess.queryJcBillCount(ids); + + if(counts == null) return new HashMap(); + + Map map = counts.stream() + .collect(Collectors.groupingBy(e -> { + return e.getId(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)) + )); + + return map; + } else { + return new HashMap(); + } + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public ApiBillHg queryApiBillHgById(String hgId) throws RuntimeException { + try { + return this.apiJcBillAccess.queryApiBillHgById(hgId); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryApiBillHgItemByHgId(String hgId) throws RuntimeException { + try { + return this.apiJcBillAccess.queryApiBillHgItemByHgId(hgId); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryApiBillHgPaymentByHgId(String hgId) throws RuntimeException { + try { + return this.apiJcBillAccess.queryApiBillHgPaymentByHgId(hgId); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public JcBillHg queryJcBillHg(String billHg) throws RuntimeException { + try { + Optional optional = jcBillHgRepository.findById(billHg); + + return optional.isPresent() ? optional.get() : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void updateJcBillHg(JcBillHg entity, List pays) throws RuntimeException { + try { + jcBillHgRepository.save(entity); + + jcBillHgPayRepository.saveAll(pays); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public JcBillPhoto queryJcBillPhoto(String srcid, String srcitemid, String typephoto) throws RuntimeException { + try { + return jcBillPhotoRepository.findBySrcidAndSrcitemidAndTypephoto(srcid, srcitemid, typephoto); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcBillPhoto(String srcid, String typephoto) throws RuntimeException { + try { + return jcBillAccess.queryJcBillPhoto(srcid, null, typephoto); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveAndDeletePhoto(List photos, JcBillHg billHg) throws RuntimeException { + try { + + for(JcBillPhoto photo : photos) { + jcBillPhotoRepository.deleteBySrcidAndSrcitemidAndTypephoto(photo.getSrcid(), photo.getSrcitemid(), photo.getTypephoto()); + } + + jcBillPhotoRepository.saveAll(photos); + + jcBillHgRepository.save(billHg); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveAndDeletePhoto(List photos, String billId) throws RuntimeException { + try { + + jcBillPhotoRepository.saveAll(photos); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + + } + + @Override + public String lastBillHgId() throws RuntimeException { + try { + return jcBillAccess.lastBillHgId(); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcCodeFlow(List codes) throws RuntimeException { + try { + List flows = apiJcBillAccess.queryJcCodeFlow(codes); + + if(flows == null) return null; + +// Map map = flows.stream() +// .collect(Collectors.groupingBy(e -> { +// return e.getCode(); +// }, +// Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0)) +// )); + + return flows; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcSourceItemByBillId(String billId) throws RuntimeException { + try { + return jcBillAccess.queryJcSourceItemByBillId(billId); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveJcSourceItem(List items, List sourceItems, JcBill jcBill) throws RuntimeException { + try { + + jcBillAccess.deleteJcSourceItemBySource(jcBill.getId()); + + if(sourceItems != null && sourceItems.size() >= 1) jcSourceItemRepository.saveAll(sourceItems); + + jcBillSourceItemRepository.saveAll(items); + + boolean flag = true; + for(JcBillSourceItem item : items) { + if(item.getStatus() == 0 && item.getStatus() == -2) flag = false; + } + if(flag)jcBill.setStatus(JcBill.STATUS_ONE); + + jcBillRepository.save(jcBill); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + + } + + @Override + public JcBillPhoto queryJcBillPhotoById(String id) throws RuntimeException { + try { + Optional optional = jcBillPhotoRepository.findById(Long.parseLong(id)); + + return optional.isPresent() ? optional.get() : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void deleteJcBillPhotoById(JcBillPhoto entity) throws RuntimeException { + try { + jcBillPhotoRepository.delete(entity); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void deleteJcSourceItem(String billid, String itemid) throws RuntimeException { + try { + Optional optional = jcBillSourceItemRepository.findById(Long.parseLong(itemid)); + + if(optional.isPresent()) { + JcBillSourceItem item = optional.get(); + + jcBillAccess.deleteJcBillPhoto(billid, String.valueOf(item.getIndexno()), JcBillPhoto.JC_FK); + + jcBillAccess.deleteJcBillPhoto(billid, item.getIndexno() + "#" + item.getGoodsid(), JcBillPhoto.JC_HP); + + jcBillSourceItemRepository.delete(item); + } + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException(e); + } + } + + @Override + public List queryApiBillHgPaymentByHgId(List hgIds) throws RuntimeException { + try { + return this.apiJcBillAccess.queryApiBillHgPaymentByHgId(hgIds); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public String getBaiduToken() throws RuntimeException { + return jcBillAccess.getBaiduToken(); + } + + @Override + public List queryJcProduct(String product, String stockInId, String hgId) throws RuntimeException { + try { + return this.apiJcBillAccess.queryJcProduct(product, stockInId, hgId); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public Map> queryJcProductBillSouce(List billIds) throws RuntimeException { + try { + List billPhotos = apiJcBillAccess.queryJcProductBillSouce(billIds); + + if(billPhotos == null) return new HashMap>(); + + Map> map = billPhotos.stream() + .collect(Collectors.groupingBy(e -> { + return e.getBillid() + e.getAccount() + e.getProduct(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + return map; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcProduct(String product, String stockInId) throws RuntimeException { + try { + return this.apiJcBillAccess.queryJcProduct(product, stockInId); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public void updateStatusByJcBill(JcBill jcBill, int status) throws RuntimeException { + try { + + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List qeryJcBillHgs(List billids) throws RuntimeException { + try { + return apiJcBillAccess.qeryJcBillHgs(billids); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public JcBillInItem queryJcBillInItemById(Long id) throws RuntimeException { + try { + + Optional optional = jcBillInItemRepository.findById(id); + + return optional.isPresent() ? optional.get() : new JcBillInItem(); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/esb/JcBillBizService.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/esb/JcBillBizService.java new file mode 100644 index 0000000..c09198e --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/esb/JcBillBizService.java @@ -0,0 +1,547 @@ +package abacus.springboot.example.esb; + +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +import com.abacus.xpos.foundation.dao.Employee; +import com.abacus.xpos.foundation.pubs.DaoIdGenerator; +import com.abacus.xpos.foundation.wsi.EmployeeServiceIF; +import com.alibaba.fastjson.JSON; + +import abacus.commons.exception.BusinessException; +import abacus.springboot.example.api.view.ApiReqJcBill; +import abacus.springboot.example.api.view.ApiReqJcBillGoodsPhoto; +import abacus.springboot.example.api.view.ApiReqJcBillItem; +import abacus.springboot.example.api.view.ApiRespJcPorduct; +import abacus.springboot.example.api.view.ApiRespJcPorductAcount; +import abacus.springboot.example.api.view.ApiRespJcPorductItem; +import abacus.springboot.example.api.view.ApiRespJcPorductProduct; +import abacus.springboot.example.api.view.JcProduct; +import abacus.springboot.example.api.view.JcProductBillSouce; +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.wsi.ApiJcBillServiceIF; + +/** + *

Title:JcBillBizService

+

Description: 稽查单业务编排(原内聚于 Controller 的私有方法,按 5 层 DAG 下沉到 esb)

+ @author chuanZeng + @date 2026年8月18日 + */ +@Service +public class JcBillBizService { + + private static final Logger LOG = LoggerFactory.getLogger(JcBillBizService.class); + + @Autowired + private ApiJcBillServiceIF apiJcBillService; + + @Autowired + private DaoIdGenerator jcBillIdGenerator; + + @Autowired + private EmployeeServiceIF employeeService; + + /** + * 稽查收货主单保存逻辑 + * @param reqJcBill + * @throws Exception + */ + public void saveJcBill(ApiReqJcBill reqJcBill) throws Exception{ + try { + + // 稽查单号 + String billId = jcBillIdGenerator.takeDaoId(null); + + reqJcBill.setId(billId); + + // 明细 + List items = reqJcBill.getItems(); + + // 解析明细 + // 新增明细 + List createItems = new ArrayList(); + + // 汇总数量 + BigDecimal quantityBig = new BigDecimal("0"); + // 汇总金额 + BigDecimal subtotalBig = new BigDecimal("0"); + + if(items != null && items.size() >= 1) { + int indexno = 0; + for(ApiReqJcBillItem item : items) { + + Double quantity = item.getQuantity(); + if(quantity == null) throw new BusinessException("收货数量为空!"); + if(quantity <= 0) throw new BusinessException("收货数量不能小于等于0!"); + + Double numbers = item.getNumbers(); + if(numbers == null) throw new BusinessException("收货件数为空!"); + if(numbers <= 0) throw new BusinessException("收货件数不能小于等于0!"); + + Double price = item.getPrice(); + if(price == null) throw new BusinessException("价格为空!"); + if(price <= 0) throw new BusinessException("价格不能小于等于0!"); + + Double subtotal = item.getSubtotal(); + if(subtotal == null) throw new BusinessException("金额为空!"); + if(subtotal <= 0) throw new BusinessException("金额不能小于等于0!"); + + item.setIndexno(++indexno); + createItems.addAll(saveJcBillItem(billId, item)); + + if(item.getQuantity() != null ) quantityBig = quantityBig.add(new BigDecimal(String.valueOf(item.getQuantity()))); + + if(item.getSubtotal() != null ) subtotalBig = subtotalBig.add(new BigDecimal(String.valueOf(item.getSubtotal()))); + } + } + + + Employee emp = employeeService.getEmployee(reqJcBill.getApplicant()); + if(emp == null) throw new BusinessException("申请人不存在!"); + + // 主单对象 + JcBill jcBill = new JcBill(); + jcBill.setId(billId); + jcBill.setStatus(JcBill.STATUS_ZERO); + jcBill.setGoods(reqJcBill.getGoods()); + jcBill.setWarehouse(reqJcBill.getWarehouse()); + jcBill.setWarehousename(reqJcBill.getWarehousename()); + jcBill.setReceivedt(reqJcBill.getReceivedt()); + jcBill.setQuantity(quantityBig.doubleValue()); + jcBill.setSubtotal(subtotalBig.doubleValue()); + jcBill.setApplicant(reqJcBill.getApplicant()); + jcBill.setApplicantname(reqJcBill.getApplicantname()); + jcBill.setDept(emp.getDept().getId()); + jcBill.setApplicantdt(new Date()); + + apiJcBillService.saveApiReqJcBill(reqJcBill, jcBill, createItems); + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 稽查收货明细保存逻辑 + * @param item + * @return + * @throws Exception + */ + public List saveJcBillItem(String billId, ApiReqJcBillItem item) throws Exception{ + try { + BigDecimal numbersBig = new BigDecimal(String.valueOf(item.getNumbers())); + BigDecimal qunantiyBig = new BigDecimal(String.valueOf(item.getQuantity())); + BigDecimal bigprice = new BigDecimal(String.valueOf(item.getPrice())); + + // 余数 + double yus = item.getQuantity() % item.getNumbers(); + + // 瓶数 + BigDecimal qunantiyInt = qunantiyBig.divide(numbersBig, BigDecimal.ROUND_DOWN).setScale(0, BigDecimal.ROUND_DOWN); + + // 金额 + BigDecimal bigAmount = bigprice.multiply(new BigDecimal(String.valueOf(item.getQuantity()))); + double subtotal = bigAmount.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); + + List sourceItems = new ArrayList(); + JcBillSourceItem sourceItem = null; + for(int i = 0; i < item.getGoodsPhotos().size(); i++) { + + ApiReqJcBillGoodsPhoto photo = item.getGoodsPhotos().get(i); + + sourceItem = new JcBillSourceItem(); + sourceItem.setBillid(billId); + sourceItem.setIndexno(item.getIndexno()); + sourceItem.setStatus(0); + sourceItem.setRecsource(item.getRecsource()); + sourceItem.setRecplatform(item.getRecplatform()); + sourceItem.setChannel(item.getChannel()); + sourceItem.setPrice(item.getPrice()); + + if(i == (item.getGoodsPhotos().size() - 1)) { + sourceItem.setQuantity(qunantiyInt.doubleValue() + yus); + } else { + sourceItem.setQuantity(qunantiyInt.doubleValue()); + } + + sourceItem.setNumbers(1); + sourceItem.setSubtotal(subtotal); + + sourceItem.setGoodsid(photo.getGoodsid()); + sourceItem.setLogisticsid(photo.getLogisticsid()); + sourceItems.add(sourceItem); + } + return sourceItems; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 稽查收货主单修改逻辑 + * @param reqJcBill + * @throws Exception + */ + public void updateJcbill(ApiReqJcBill reqJcBill) throws Exception{ + try { + + // 稽查单号 + String billId = reqJcBill.getId(); + + // 明细 + List items = reqJcBill.getItems(); + + // 解析明细 + // 新增明细 + List createItems = new ArrayList(); + // 修改明细 + List updateItems = new ArrayList(); + + // 汇总数量 + BigDecimal quantityBig = new BigDecimal("0"); + // 汇总金额 + BigDecimal subtotalBig = new BigDecimal("0"); + + /*if(items != null && items.size() >= 1) { + int indexno = apiJcBillService.countJcBillItemIndexno(billId); + for(ApiReqJcBillItem item : items) { + if(item.getId() == null) { + + item.setIndexno(++indexno); + createItems.addAll(saveJcBillItem(billId, item)); + } else { + + updateItems.addAll(updateJcbillItem(billId, item)); + } + + if(item.getQuantity() != null ) quantityBig = quantityBig.add(new BigDecimal(String.valueOf(item.getQuantity()))); + + if(item.getSubtotal() != null ) subtotalBig = subtotalBig.add(new BigDecimal(String.valueOf(item.getSubtotal()))); + } + }*/ + if(items != null && items.size() >= 1) { + int indexno = 0; + for(ApiReqJcBillItem item : items) { + + Double quantity = item.getQuantity(); + if(quantity == null) throw new BusinessException("收货数量为空!"); + if(quantity <= 0) throw new BusinessException("收货数量不能小于等于0!"); + + Double numbers = item.getNumbers(); + if(numbers == null) throw new BusinessException("收货件数为空!"); + if(numbers <= 0) throw new BusinessException("收货件数不能小于等于0!"); + + Double price = item.getPrice(); + if(price == null) throw new BusinessException("价格为空!"); + if(price <= 0) throw new BusinessException("价格不能小于等于0!"); + + Double subtotal = item.getSubtotal(); + if(subtotal == null) throw new BusinessException("金额为空!"); + if(subtotal <= 0) throw new BusinessException("金额不能小于等于0!"); + + item.setIndexno(++indexno); + createItems.addAll(saveJcBillItem(billId, item)); + + if(item.getQuantity() != null ) quantityBig = quantityBig.add(new BigDecimal(String.valueOf(item.getQuantity()))); + + if(item.getSubtotal() != null ) subtotalBig = subtotalBig.add(new BigDecimal(String.valueOf(item.getSubtotal()))); + } + } + + + Employee emp = employeeService.getEmployee(reqJcBill.getApplicant()); + if(emp == null) throw new BusinessException("申请人不存在!"); + + // 主单对象 + JcBill jcBill = new JcBill(); + jcBill.setId(reqJcBill.getId()); + jcBill.setStatus(JcBill.STATUS_ZERO); + jcBill.setGoods(reqJcBill.getGoods()); + jcBill.setWarehouse(reqJcBill.getWarehouse()); + jcBill.setWarehousename(reqJcBill.getWarehousename()); + jcBill.setReceivedt(reqJcBill.getReceivedt()); + jcBill.setQuantity(quantityBig.doubleValue()); + jcBill.setSubtotal(subtotalBig.doubleValue()); + jcBill.setApplicant(reqJcBill.getApplicant()); + jcBill.setApplicantname(reqJcBill.getApplicantname()); + jcBill.setDept(emp.getDept().getId()); + jcBill.setApplicantdt(new Date()); + + apiJcBillService.updateApiReqJcBill(reqJcBill, jcBill, createItems, updateItems); + + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 稽查收货明细修改逻辑 + * @param item + * @return + * @throws Exception + */ + public List updateJcbillItem(String billId, ApiReqJcBillItem item) throws Exception{ + try { + BigDecimal numbersBig = new BigDecimal(String.valueOf(item.getNumbers())); + BigDecimal qunantiyBig = new BigDecimal(String.valueOf(item.getQuantity())); + BigDecimal bigprice = new BigDecimal(String.valueOf(item.getPrice())); + + // 余数 + double yus = item.getQuantity() % item.getNumbers(); + + // 瓶数 + BigDecimal qunantiyInt = qunantiyBig.divide(numbersBig, BigDecimal.ROUND_DOWN).setScale(0, BigDecimal.ROUND_DOWN); + + // 金额 + BigDecimal bigAmount = bigprice.multiply(new BigDecimal(String.valueOf(item.getQuantity()))); + double subtotal = bigAmount.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue(); + + List sourceItems = new ArrayList(); + JcBillSourceItem sourceItem = null; + for(int i = 0; i < item.getGoodsPhotos().size(); i++) { + + ApiReqJcBillGoodsPhoto photo = item.getGoodsPhotos().get(i); + + sourceItem = new JcBillSourceItem(); + sourceItem.setId(item.getId()); + sourceItem.setBillid(billId); + sourceItem.setIndexno(item.getIndexno()); + sourceItem.setStatus(0); + sourceItem.setRecsource(item.getRecsource()); + sourceItem.setRecplatform(item.getRecplatform()); + sourceItem.setChannel(item.getChannel()); + sourceItem.setPrice(item.getPrice()); + + if(i == (item.getGoodsPhotos().size() - 1)) { + sourceItem.setQuantity(qunantiyInt.doubleValue() + yus); + } else { + sourceItem.setQuantity(qunantiyInt.doubleValue()); + } + + sourceItem.setNumbers(1); + sourceItem.setSubtotal(subtotal); + + sourceItem.setGoodsid(photo.getGoodsid()); + sourceItem.setLogisticsid(photo.getLogisticsid()); + sourceItems.add(sourceItem); + } + return sourceItems; + +// JcBillSourceItem sourceItem = new JcBillSourceItem(); +// sourceItem.setId(item.getId()); +// sourceItem.setBillid(billId); +// sourceItem.setIndexno(item.getIndexno()); +// sourceItem.setStatus(1); +// sourceItem.setRecsource(sourceItem.getRecsource()); +// sourceItem.setRecplatform(sourceItem.getRecplatform()); +// sourceItem.setChannel(sourceItem.getChannel()); +// sourceItem.setPrice(sourceItem.getPrice()); +// sourceItem.setQuantity(sourceItem.getQuantity()); +// sourceItem.setNumbers(sourceItem.getNumbers()); +// sourceItem.setSubtotal(sourceItem.getSubtotal()); +// sourceItem.setGoodsid(sourceItem.getGoodsid()); +// sourceItem.setLogisticsid(sourceItem.getLogisticsid()); +// +// return sourceItem; + } catch(Throwable e){ + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + + /** + * 回购单号是按回购单显示明细,以回购单号为主,解析 + * @param product + * @param stockInId + * @param hgId + * @return + * @throws Exception + */ + public List hgAnalyze(String product, String stockInId, String hgId) throws Exception { + try { + + long time1 = System.currentTimeMillis(); + List jcProducts = apiJcBillService.queryJcProduct(product, stockInId, hgId); + LOG.info("稽查货品查询>>>回购单逻辑>>>queryJcProduct耗时>>>{}", (System.currentTimeMillis() - time1)); + + // 获取稽查单号集合 + List billIds = jcProducts.stream() + .map(JcProduct::getBillid) + .collect(Collectors.toList()); + + long time2 = System.currentTimeMillis(); + Map> mapGoods = apiJcBillService.queryJcProductBillSouce(billIds); + LOG.info("稽查货品查询>>>回购单逻辑>>>queryJcProductBillSouce耗时>>>{}", (System.currentTimeMillis() - time2)); + + LOG.info("稽查货品查询>>>回购单逻辑>>>按稽查单号+客户编码+商品编码,分组数据>>>{}", JSON.toJSONString(mapGoods)); + + + long time3 = System.currentTimeMillis(); + Map> mapPhoto = apiJcBillService.queryJcBillPhotoIn(billIds); + LOG.info("稽查货品查询>>>回购单逻辑>>>queryJcBillPhotoIn查询耗时>>>{}", (System.currentTimeMillis() - time3)); + + // 按稽查单号+入库单号+回购单号+出库单号,分组 + Map> mapProducts = jcProducts.stream() + .collect(Collectors.groupingBy(e -> { + return e.getBillid() + e.getBillin() + e.getBillhg() + e.getWdtbillout(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + LOG.info("稽查货品查询>>>回购单逻辑>>>按稽查单号+入库单号+回购单号+出库单号,分组数据>>>{}", JSON.toJSONString(mapProducts)); + + // 客户编码汇总,同一个客户下的商品 + Map> mapAccProducts = jcProducts.stream() + .collect(Collectors.groupingBy(e -> { + return e.getBillid() + e.getBillin() + e.getBillhg()+ e.getAccount(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + LOG.info("稽查货品查询>>>回购单逻辑>>>按稽查单号+入库单号+回购单号+客户编码,分组数据>>>{}", JSON.toJSONString(mapAccProducts)); + + + long time4 = System.currentTimeMillis(); + List respJcProducts = new ArrayList(); + ApiRespJcPorduct respJcProduct = null; + for(String key : mapProducts.keySet()) { + + List tempJcProducts = mapProducts.get(key); + + JcProduct jcProduct = tempJcProducts.get(0); + + respJcProduct = new ApiRespJcPorduct(); + if(jcProduct.getBillid() != null) respJcProduct.setBillId(jcProduct.getBillid()); + if(jcProduct.getBillin() != null) respJcProduct.setStockInId(jcProduct.getBillin()); + if(jcProduct.getBillhg() != null) respJcProduct.setHgId(jcProduct.getBillhg()); + if(jcProduct.getWdtbillout() != null) respJcProduct.setStockOutId(jcProduct.getWdtbillout()); + + List accounts = new ArrayList(); + ApiRespJcPorductAcount account = null; + for(JcProduct tempJcProduct : tempJcProducts) { + + account = new ApiRespJcPorductAcount(); + account.setAccount(tempJcProduct.getAccount()); + account.setAccountName(tempJcProduct.getAccountname()); + + String keyAccount = tempJcProduct.getBillid() + tempJcProduct.getBillin() + tempJcProduct.getBillhg() +tempJcProduct.getAccount(); + + List accTempJcProducts = mapAccProducts.get(keyAccount); + + LOG.info("稽查货品查询>>>回购单逻辑>>>按稽查单号+入库单号+回购单号+客户编码({}),汇总同一客户数据>>>{}", keyAccount, JSON.toJSONString(accTempJcProducts)); + + List products = new ArrayList(); + ApiRespJcPorductProduct ajproduct = null; + for(JcProduct accJcProduct : accTempJcProducts) { + + ajproduct = new ApiRespJcPorductProduct(); + ajproduct.setProduct(tempJcProduct.getProduct()); + ajproduct.setProductName(tempJcProduct.getProductname()); + ajproduct.setQuantity(tempJcProduct.getQuantity() + "瓶/" + tempJcProduct.getNumbers() + "件"); + + + + String keyGoods = accJcProduct.getBillid() + accJcProduct.getAccount() + accJcProduct.getProduct(); + + List tempGoods = mapGoods.get(keyGoods); + + LOG.info("稽查货品查询>>>回购单逻辑>>>按稽查单号+客户编码+商品编码({}),分组数据>>>{}", keyGoods, JSON.toJSONString(tempGoods)); + + List items = new ArrayList(); + ApiRespJcPorductItem item = null; + for(JcProductBillSouce tempGood : tempGoods) { + item = new ApiRespJcPorductItem(); + item.setGoodsId(tempGood.getGoodsid()); + + List hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(tempGood.getIndexno()) + "#" + String.valueOf(tempGood.getGoodsid())); + List hptList = new ArrayList(); + if(hpts != null && hpts.size() >= 1) { + for(JcBillPhoto hpt : hpts) { + if(tempGood.getBillid().equals(hpt.getSrcid())) { + hptList.add(hpt.getUrlphoto()); + } + } + } + item.setPhotos(hptList); + + items.add(item); + /*if(StringUtils.isBlank(product)) { + item = new ApiRespJcPorductItem(); + item.setGoodsId(tempGood.getGoodsid()); + + List hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(tempGood.getIndexno()) + "#" + String.valueOf(tempGood.getGoodsid())); + List hptList = new ArrayList(); + if(hpts != null && hpts.size() >= 1) { + for(JcBillPhoto hpt : hpts) { + hptList.add(hpt.getUrlphoto()); + } + } + item.setPhotos(hptList); + + items.add(item); + } else { + if(product.equals(tempGood.getGoodsid())) { + item = new ApiRespJcPorductItem(); + item.setGoodsId(tempGood.getGoodsid()); + + List hpts = mapPhoto.get(JcBillPhoto.JC_HP + "#" + String.valueOf(tempGood.getIndexno()) + "#" + String.valueOf(tempGood.getGoodsid())); + List hptList = new ArrayList(); + if(hpts != null && hpts.size() >= 1) { + for(JcBillPhoto hpt : hpts) { + hptList.add(hpt.getUrlphoto()); + } + } + item.setPhotos(hptList); + + items.add(item); + } + }*/ + + } + + if(items.size() >= 1) { + ajproduct.setItems(items); + + products.add(ajproduct); + } + } + + if(products.size() >= 1) { + account.setProducts(products); + + accounts.add(account); + } + } + + if(accounts.size() >= 1) { + respJcProduct.setAccounts(accounts); + + respJcProducts.add(respJcProduct); + } + } + LOG.info("稽查货品查询>>>回购单逻辑>>>数据封装耗时>>>{}", (System.currentTimeMillis() - time4)); + + return respJcProducts; + } catch (Exception e) { + LOG.error(e.getMessage(), e); + e.printStackTrace(); + throw e; + } + } + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/esb/JcBillService.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/esb/JcBillService.java new file mode 100644 index 0000000..e349cbb --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/esb/JcBillService.java @@ -0,0 +1,719 @@ +package abacus.springboot.example.esb; + +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +import org.apache.commons.lang.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Repository; +import org.springframework.transaction.annotation.Isolation; +import org.springframework.transaction.annotation.Propagation; +import org.springframework.transaction.annotation.Transactional; + +import com.alibaba.fastjson.JSONObject; + +import abacus.commons.context.interceptor.UserContext; +import abacus.commons.exception.BusinessException; +import abacus.config.ext.AbacusExtConfig; +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillHg; +import abacus.springboot.example.dao.JcBillInItem; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.dao.JcSourceItem; +import abacus.springboot.example.pi.JcBillAccessIF; +import abacus.springboot.example.repository.JcBillHgRepository; +import abacus.springboot.example.repository.JcBillInItemRepository; +import abacus.springboot.example.repository.JcBillPhotoRepository; +import abacus.springboot.example.repository.JcBillRepository; +import abacus.springboot.example.repository.JcBillSourceItemRepository; +import abacus.springboot.example.repository.JcSourceItemRepository; +import abacus.springboot.example.util.RequestUtil; +import abacus.springboot.example.vo.PMSConfigKey; +import abacus.springboot.example.vo.SiDepositlocation; +import abacus.springboot.example.wsi.JcBillServiceIF; + +@Repository +public class JcBillService implements JcBillServiceIF{ + + private static final Logger LOG = LoggerFactory.getLogger(JcBillService.class); + + @Autowired + private JcBillAccessIF jcBillAccess; + + @Autowired + private JcBillRepository jcBillRepository; + + @Autowired + private JcBillSourceItemRepository jcBillSourceItemRepository; + + @Autowired + private JcBillHgRepository jcBillHgRepository; + + @Autowired + private JcSourceItemRepository jcSourceItemRepository; + + @Autowired + private JcBillInItemRepository jcBillInItemRepository; + + @Autowired + private JcBillPhotoRepository jcBillPhotoRepository; + + @Autowired + private AbacusExtConfig abacusExtConfig; + + @Override + public Page queryJcBill(String fromDate, String thruDate, String id, String applicant, String goods, + String billin, String goodsid, String product, String status, int typ, Pageable pageable) throws RuntimeException { + try { + return this.jcBillAccess.queryJcBill(fromDate, thruDate, applicant, goods, id, billin, goodsid, product, status, typ, pageable); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public JcBill queryJcBillById(String billId) throws RuntimeException { + try { + Optional optional = jcBillRepository.findById(billId); + + return optional.isPresent() ? optional.get() : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcBillSourceItemByBillId(String billId) throws RuntimeException { + try { + List list = jcBillSourceItemRepository.findByBillid(billId); + + return (list != null && list.size() >= 1) ? list : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public JcBillHg queryJcBillHg(String billHg) throws RuntimeException { + try { + Optional optional = jcBillHgRepository.findById(billHg); + + return optional.isPresent() ? optional.get() : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcSourceItemByBillId(String billId) throws RuntimeException { + try { + return jcBillAccess.queryJcSourceItemByBillId(billId); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public Map> queryJcBillPhoto(String srcid) throws RuntimeException { + try { + List billPhotos = jcBillAccess.queryJcBillPhoto(srcid, null, null); + + if(billPhotos == null) return new HashMap>(); + + Map> map = billPhotos.stream() + .collect(Collectors.groupingBy(e -> { + return e.getTypephoto() + "#" + e.getSrcitemid(); + }, + Collectors.collectingAndThen(Collectors.toList(), value -> value) + )); + + return map; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcSourceItemByBillId(String billId, String srcitemid) throws RuntimeException { + try { + return jcSourceItemRepository.findByBillidAndSrcitemid(billId, srcitemid); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public JcBillSourceItem queryJcBillSourceItemById(Long id) throws RuntimeException { + try { + Optional optional = jcBillSourceItemRepository.findById(id); + + return optional.isPresent() ? optional.get() : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public JcSourceItem queryJcSourceItemById(Long id) throws RuntimeException { + try { + Optional optional = jcSourceItemRepository.findById(id); + + return optional.isPresent() ? optional.get() : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveQuerenBillSourceItem(JcBillSourceItem billItem, JcSourceItem sourceItem) throws RuntimeException { + try { + + jcBillSourceItemRepository.save(billItem); + + jcSourceItemRepository.save(sourceItem); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveRejectJcSourceItems(JcBillSourceItem billItem, JcBill jcBill) throws RuntimeException { + try { + + jcBillSourceItemRepository.save(billItem); + + jcBillRepository.save(jcBill); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveCompleteJcBill(List inItems, JcBill jcBill) throws RuntimeException { + try { + + jcBillInItemRepository.saveAll(inItems); + + jcBillRepository.save(jcBill); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void updateWarehouse(JcBill jcBill) throws RuntimeException { + try { + + jcBillRepository.save(jcBill); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcBillInItemByBillId(String billId, int status) throws RuntimeException { + try { + List list = jcBillInItemRepository.findByBillidAndStatus(billId, status); + + return (list != null && list.size() >= 1) ? list : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcBillInItemByBillId(String billId) throws RuntimeException { + try { + List list = jcBillInItemRepository.findByBillid(billId); + + return (list != null && list.size() >= 1) ? list : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void createStockIn(JcBill jcBill) throws RuntimeException { + try { + + jcBillRepository.save(jcBill); + + jcBillAccess.saveEvent(jcBill.getId(), "稽查收货", "其他入库"); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public JcBillInItem queryJcBillInItemById(Long id) { + try { + Optional optional = jcBillInItemRepository.findById(id); + + return optional.isPresent() ? optional.get() : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveTerminateHgInItem(JcBillInItem inItem) throws RuntimeException { + try { + + jcBillInItemRepository.save(inItem); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List findAllById(List ids) throws RuntimeException { + try { + return jcBillInItemRepository.findAllById(ids); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveInformHg(List inItems, JcBill jcBill, JcBillHg jcBillHg, String photoUrl) throws RuntimeException { + try { + + JcBillPhoto photo = new JcBillPhoto(); + photo.setSrcid(jcBillHg.getId()); + photo.setSrcitemid(jcBillHg.getId()); + photo.setTypephoto(JcBillPhoto.HG_TZH); + photo.setUrlphoto(photoUrl); + + jcBillPhotoRepository.save(photo); + + jcBillInItemRepository.saveAll(inItems); + + jcBillRepository.save(jcBill); + + jcBillHgRepository.save(jcBillHg); + + jcBillAccess.saveEvent(jcBillHg.getId(), "回购订单", "回购通知"); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public Page queryJcBillHg(String fromDate, String thruDate, String account, String salearea, String id, + String billId, String status, String product, String manager, int typ, Pageable pageable) + throws RuntimeException { + try { + + return jcBillAccess.queryJcBillHg(fromDate, thruDate, account, salearea, id, billId, status, product, manager, typ, pageable); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcBillInItemByBillHg(String billHgId) throws RuntimeException { + try { + List list = jcBillInItemRepository.findByBillhg(billHgId); + + return (list != null && list.size() >= 1) ? list : null; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveRejectBillHg(int status, int typ, JcBill jcBill, JcBillHg billHg, List inItems) throws RuntimeException { + try { + if(JcBillHg.STATUS_ONE == status) { + + jcBillRepository.save(jcBill); + jcBillHgRepository.save(billHg); + jcBillInItemRepository.saveAll(inItems); + + + } else if(JcBillHg.STATUS_TWO == status) { + + jcBillHgRepository.save(billHg); + + + } else if(JcBillHg.STATUS_THREE == status || JcBillHg.STATUS_FOUR == status) { + + jcBillHgRepository.save(billHg); + + } else if (JcBillHg.STATUS_FIVE == status){ + + // 删除对应的事件 + jcBillAccess.deleteEvent(billHg.getId(), "回购分仓", "回购分仓"); + } else { + throw new BusinessException("未知状态不能驳回!"); + } + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveQuerenSk(JcBillHg billHg, boolean fcFlag) throws RuntimeException { + try { + billHg.setAudit(UserContext.getUserId()); + billHg.setAuditname(UserContext.getUserName()); + billHg.setAuditdt(new Date()); + jcBillHgRepository.save(billHg); + + if(fcFlag) { + + jcBillAccess.saveEvent(billHg.getId(), "回购分仓", "回购分仓"); + + } + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void savecreateFc(JcBillHg billHg) throws RuntimeException { + try { + + jcBillHgRepository.save(billHg); + + jcBillAccess.saveEvent(billHg.getId(), "回购分仓", "回购分仓"); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void updateFcWarehouse(String oldJsonStr, JcBillHg billHg) throws RuntimeException { + try { + + jcBillHgRepository.save(billHg); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public JcSourceItem saveJcSourceItem(JcSourceItem item) throws RuntimeException { + try { + + JcSourceItem tempItem = jcSourceItemRepository.save(item); + + + return tempItem; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void deleteJcSourceItem(List ids) throws RuntimeException { + try { + + jcBillAccess.deleteJcSourceItem(ids); + +// /*操作日志*/ +// OperationLog log = new OperationLog("jc_bill", item.getBillid(), "删除溯源确认信息", "", "", JSON.toJSONString(item)); +// log.setOperator(UserContext.getUserId()); +// log.setOperatorName(UserContext.getUserName()); +// BusinessESUtil.checkService(this.operationLogService).saveOperationLog(log); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void updateHgprice(JcBillInItem inItem) throws RuntimeException { + try { + jcBillInItemRepository.save(inItem); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void updateRemark(String oldJsonStr, JcBillHg billHg) throws RuntimeException { + try { + + jcBillHgRepository.save(billHg); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void updatePac(String oldJsonStr, JcBillHg billHg) throws RuntimeException { + try { + + jcBillHgRepository.save(billHg); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void updateOperatorname(JcBillInItem inItem, String oldStr) throws RuntimeException { + try { + jcBillInItemRepository.save(inItem); + + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public void saveJcBillInItem(List items) throws RuntimeException { + jcBillInItemRepository.saveAll(items); + } + + @Override + public List queryJcBillSourceItemInBillId(List billIds) throws RuntimeException { + try { + return jcBillAccess.queryJcBillSourceItemInBillId(billIds); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void saveRejectBill(int status, JcBill jcBill, List inItems, List sourceItems) throws RuntimeException { + try { + + jcBillRepository.save(jcBill); + jcBillSourceItemRepository.saveAll(sourceItems); + if(inItems != null) jcBillInItemRepository.deleteAll(inItems); + + if(JcBill.STATUS_FOUR == status) {// 入库待审核 进行撤回 + + // 进行事件删除 + jcBillAccess.deleteEvent(jcBill.getId(), "稽查收货", "其他入库"); + + } + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Override + public List queryJcSourceItemByBillId(String billId, String srcitemid, int status) + throws RuntimeException { + try { + return jcSourceItemRepository.findByBillidAndSrcitemidAndStatus(billId, srcitemid, status); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + + @Transactional(isolation = Isolation.DEFAULT, propagation = Propagation.REQUIRED, rollbackFor = {Exception.class}) + @Override + public void updateSourceItemAccount(String sourceItemLogJson, String billSourceItemLogJson, String billSourceItemNewLogJson, + JcSourceItem sourceItem, List billSourceItems, + List oldInItems, List inItems) throws RuntimeException { + try { + String biillId = sourceItem.getBillid(); + + jcSourceItemRepository.save(sourceItem); + jcBillSourceItemRepository.saveAll(billSourceItems); + jcBillInItemRepository.deleteAll(oldInItems); + jcBillInItemRepository.saveAll(inItems); + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("服务异常", e.getMessage()); + throw new RuntimeException("服务异常:", e); + } + } + @Override + public SiDepositlocation querySiDepositlocation(String srcid) throws Exception { + return jcBillAccess.querySiDepositlocation(srcid); + } + @Override + public SiDepositlocation querySiDepositlocationHGfc(String srcid) throws Exception { + return jcBillAccess.querySiDepositlocationHGfc(srcid); + } + + @Override + public JSONObject gwisSubCancelOrder(String orderCode, String orderType) throws Exception { + try { + + Map configValues = this.abacusExtConfig.getAbacusConfigSetByKeyGroupByKey( + PMSConfigKey.KEY_GROUP, PMSConfigKey.PMS_WMSCONF); + if (configValues == null || configValues.isEmpty()) + throw new Exception(PMSConfigKey.PMS_WMSCONF + "为空!"); + + // 判断key是否存在 + if (!configValues.containsKey(PMSConfigKey.PMS_WMSCONF_URL)) + throw new Exception(PMSConfigKey.PMS_WMSCONF + "配置中" + PMSConfigKey.PMS_WMSCONF_URL + "不存在!"); + if (!configValues.containsKey(PMSConfigKey.PMS_WMSCONF_APPKEY)) + throw new Exception(PMSConfigKey.PMS_WMSCONF + "配置中" + PMSConfigKey.PMS_WMSCONF_APPKEY + "不存在!"); + if (!configValues.containsKey(PMSConfigKey.PMS_WMSCONF_SESSIONKEY)) + throw new Exception(PMSConfigKey.PMS_WMSCONF + "配置中" + PMSConfigKey.PMS_WMSCONF_SESSIONKEY + "不存在!"); + + // 判断值是否为空 + String url = configValues.get(PMSConfigKey.PMS_WMSCONF_URL); + if (StringUtils.isBlank(url)) + throw new Exception(PMSConfigKey.PMS_WMSCONF + "配置中" + PMSConfigKey.PMS_WMSCONF_URL + "为空!"); + + String appkey = configValues.get(PMSConfigKey.PMS_WMSCONF_APPKEY); + if (StringUtils.isBlank(appkey)) + throw new Exception(PMSConfigKey.PMS_WMSCONF + "配置中" + PMSConfigKey.PMS_WMSCONF_APPKEY + "为空!"); + + String sessionKey = configValues.get(PMSConfigKey.PMS_WMSCONF_SESSIONKEY); + if (StringUtils.isBlank(sessionKey)) + throw new Exception(PMSConfigKey.PMS_WMSCONF + "配置中" + PMSConfigKey.PMS_WMSCONF_SESSIONKEY + "为空!"); + + String goodsOwner = configValues.get(PMSConfigKey.PMS_WMSCONF_GOODSOWNER); + if (StringUtils.isBlank(goodsOwner)) + throw new Exception(PMSConfigKey.PMS_WMSCONF + "配置中" + PMSConfigKey.PMS_WMSCONF_GOODSOWNER + "为空!"); + + JSONObject head = new JSONObject(); + head.put("orderCode", orderCode); // 唯一订单号 + head.put("orderType", orderType); + head.put("goodsOwner", goodsOwner); + + // 2. 计算签名 secret = MD5(contentJson + sessionKey) + String secret = md5(head.toJSONString() + sessionKey); + + // 3. 拼接完整URL(带上method、appkey、secret) + String fullUrl = url + + "?method=gwisSubCancelOrder" + + "&appkey=" + appkey + + "&secret=" + secret; + + LOG.info("WMS取消订单>>>orderCode>>>{}>>>orderType>>>{}>>>请求参数>>>{}", orderCode, orderType, head.toJSONString()); + String returnJson = RequestUtil.send(fullUrl, head.toJSONString(), orderCode); + LOG.info("WMS取消订单>>>orderCode>>>{}>>>orderType>>>{}>>>响应参数>>>{}", orderCode, orderType, returnJson); + + JSONObject jsonObj = JSONObject.parseObject(returnJson); + + return jsonObj; + } catch (RuntimeException e) { + e.printStackTrace(); + LOG.error("WMS取消订单接口服务异常", e.getMessage()); + throw new RuntimeException("WMS取消订单接口服务异常:", e); + } + } + + private static String md5(String input) { + try { + java.security.MessageDigest md = java.security.MessageDigest.getInstance("MD5"); + byte[] digest = md.digest(input.getBytes("UTF-8")); + StringBuilder sb = new StringBuilder(); + for (byte b : digest) { + sb.append(String.format("%02X", b)); // 大写十六进制 + } + return sb.toString(); + } catch (Exception e) { + throw new RuntimeException("MD5计算失败", e); + } + } + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/ApiJcBillAccess.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/ApiJcBillAccess.java new file mode 100644 index 0000000..65bdb12 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/ApiJcBillAccess.java @@ -0,0 +1,593 @@ +package abacus.springboot.example.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import abacus.springboot.example.api.view.ApiBillHg; +import abacus.springboot.example.api.view.ApiBillHgItem; +import abacus.springboot.example.api.view.ApiBillHgPayment; +import abacus.springboot.example.api.view.ApiJcBill; +import abacus.springboot.example.api.view.ApiJcBillHgSearchItem; +import abacus.springboot.example.api.view.ApiJcBillItem; +import abacus.springboot.example.api.view.ApiJcBillSearch; +import abacus.springboot.example.api.view.JcBillCount; +import abacus.springboot.example.api.view.JcCodeFlow; +import abacus.springboot.example.api.view.JcProduct; +import abacus.springboot.example.api.view.JcProductBillSouce; +import abacus.springboot.example.dao.JcBillHg; +import abacus.springboot.example.pi.ApiJcBillAccessIF; + +/** + *

Title:ApiJcBillAccess

+

Description: 底层实现

+ @author chuanZeng + @date 2026年8月18日 + */ +@Repository +public class ApiJcBillAccess implements ApiJcBillAccessIF { + + private static final Logger LOG = LoggerFactory.getLogger(ApiJcBillAccess.class); + + @Autowired + private JdbcTemplate jdbcTemplate; + + @Override + public Page queryApiJcBillSearch(String keyword, String employee, String status, Pageable pageable) + throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer(""); + + if(StringUtils.isNotBlank(keyword)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" (a.id like '%" + keyword + "%' "); + sb.append(" or a.goods like '%" + keyword + "%'"); + sb.append(" or a.id in (select b.billid from jc_billsource_item b where b.goodsid like'%" + keyword + "%'))"); + + params.put("id", "%"+keyword+"%"); + } + + if(StringUtils.isNotBlank(employee)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" (a.dept in ("); + sb.append(" select deptid from ("); + sb.append(" select dataid as deptid from distributionmapping where erid ='" + employee + "' and rtype = 1 and ftype = 1 and dtype = 1"); + sb.append(" union"); + sb.append(" select a.dataid as deptid from distributionmapping a ,acas_assign b where a.erid =b.rolez and a.rtype = 0 and a.ftype = 1 and a.dtype = 1 and b.userz ='" + employee + "'"); + sb.append(" ) adept)"); + sb.append(" or"); + sb.append(" a.applicant in ("); + sb.append(" select dataid from ("); + sb.append(" select dataid from distributionmapping where erid ='" + employee + "' and rtype = 1 and ftype = 1 and dtype = 2"); + sb.append(" union"); + sb.append(" select dataid from distributionmapping a ,acas_assign b where a.erid =b.rolez and a.rtype = 0 and a.ftype = 1 and a.dtype = 2 and b.userz ='" + employee + "'"); + sb.append(" union"); + sb.append(" select '" + employee + "'"); + sb.append(" ) adept )"); + sb.append(" )"); + params.put("employee", employee); +// sb.append(" a.dept in ("); +// sb.append(" select deptid from ("); +// sb.append(" select dataid as deptid from distributionmapping where erid ='" + employee + "' and rtype = 1 and ftype = 1 and dtype = 1"); +// sb.append(" union "); +// sb.append(" select a.dataid as deptid from distributionmapping a ,acas_assign b where a.erid =b.rolez and a.rtype = 0 and a.ftype = 1 and a.dtype = 1 and b.userz ='" + employee + "'"); +// sb.append(" union "); +// sb.append("select (select dept as deptid from employee e where e.id = dataid) as deptid from distributionmapping where erid ='" + employee + "' and rtype = 1 and ftype = 1 and dtype = 2"); +// sb.append(" union "); +// sb.append("select (select dept as deptid from employee e where e.id = a.dataid) as deptid from distributionmapping a ,acas_assign b where a.erid =b.rolez and a.rtype = 0 and a.ftype = 1 and a.dtype = 2 and b.userz ='" + employee + "'"); +// sb.append(" union "); +// sb.append("select dept as deptid from employee e where e.id = '" + employee + "'"); +// sb.append(" ) adept"); +// sb.append(" )"); +// params.put("employee", employee); + } + + if(StringUtils.isNotBlank(status)) { + sb.append(params.size() > 0 ?" and ":" where "); + int statusInt = Integer.parseInt(status); + if(statusInt == 0) {// 待提交:已录入或者录入完成提交验证 + sb.append(" a.status in(0, 1) "); + params.put("status", statusInt); + } else if(statusInt == 2) {// 待溯源 + sb.append(" a.status = 2 "); + params.put("status", statusInt); + } else if(statusInt == -2) {// 人工溯源驳回 + sb.append(" a.status = -2 "); + params.put("status", statusInt); + } else if(statusInt == 3) {// 待入库,待入库审核 + sb.append(" a.status in(3, 4) "); + params.put("status", statusInt); + } else if(statusInt == 5) {// 已入库 + sb.append(" a.status = 5 "); + params.put("status", statusInt); + } else if(statusInt == 6 || statusInt == 8) {// 部分回购,回购完成 + sb.append(" a.hgstatus in(1, 2) "); + params.put("status", statusInt); + } + } else { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.status in(-2, 0, 1, 2, 3, 4, 5) "); + params.put("status", 1); + } + + StringBuffer orderBy = new StringBuffer(""); + + orderBy.append(" order by dt desc "); + + orderBy.append(" offset "+ (pageable.getPageNumber() * pageable.getPageSize()) + " rows fetch next "+ pageable.getPageSize() + " rows only "); + + String sql = " select a.id as billid, receivedt as receivedt, a.goods as goods, " + + " a.quantity as quantity, a.status as status, a.hgstatus as hgstatus from jc_bill a " + + sb.toString() + orderBy.toString(); + LOG.info("queryApiJcBillSearch>>>SQLgetPageNumber>>>{}", pageable.getPageNumber()); + LOG.info("queryApiJcBillSearch>>>SQLgetPageSize>>>{}", pageable.getPageSize()); + LOG.info("queryApiJcBillSearch>>>SQL>>>{}", sql); + + List lists = jdbcTemplate.query(sql, new BeanPropertyRowMapper(ApiJcBillSearch.class)); + + Long count = jdbcTemplate.queryForObject("select count(a.id) from jc_bill a " + sb.toString(), Long.class); + + Page scorePage = new PageImpl(lists, pageable, count); + return scorePage; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public ApiJcBill queryApiJcBillById(String id) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer(" select a.id, a.status, a.goods, a.warehouse, a.warehousename, a.receivedt,"); + sb.append(" a.quantity, a.subtotal, a.applicant, a.applicantname, a.applicantdt"); + sb.append(" from jc_bill a"); + + if(StringUtils.isNotBlank(id)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.id = '" + id + "' "); + params.put("id", id); + } + + LOG.info("queryApiJcBillById>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(ApiJcBill.class)); + + return (lsit != null && lsit.size() >= 1) ? lsit.get(0) : null; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryApiJcBillItemByBIllId(String billId) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer("select a.id,a.status,a.recsource,a.channel,a.price,a.quantity,"); + sb.append(" a.numbers,a.subtotal,a.goodsid,a.logisticsid "); + sb.append(" from jc_billsource_item a "); + + if(StringUtils.isNotBlank(billId)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billid = '" + billId + "' "); + params.put("billId", billId); + } + + LOG.info("queryApiJcBillItemByBIllId>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(ApiJcBillItem.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public Page queryApiJcBillHgSearchItem(String keyword, String employee, String status, Pageable pageable) + throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer(""); + + if(StringUtils.isNotBlank(keyword)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" (a.id like '%" + keyword + "%' "); + sb.append(" or a.account like '%" + keyword + "%'"); + sb.append(" or a.accountname like '%" + keyword + "%'"); + sb.append(" or a.consigneephone like '%" + keyword + "%'"); + sb.append(" or a.id in (select b.billhg from jc_billin_item b where b.product like '%" + keyword + "%' and b.productname like'%" + keyword + "%'))"); + + params.put("id", "%"+keyword+"%"); + } + + if(StringUtils.isNotBlank(employee)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" ("); + sb.append(" a.account in ("); + sb.append(" select sa.id from sams_account sa where sa.groupid in (select pc.id from pms_customergroup pc where pc.grouperid='" + employee + "' or ',' + groupempid + ',' like '%," + employee + ",%')"); + sb.append(" )"); + sb.append(" or "); + sb.append(" a.account in ("); + sb.append(" select customerid from ws_wsempmgcustomer where wsempid ='" + employee + "' "); + sb.append(" )"); + sb.append(" )"); +// sb.append(" a.account in (select sa.id from sams_account sa where sa.groupid in (select pc.id from pms_customergroup pc where pc.grouperid='" + employee + "' or ',' + groupempid + ',' like '%," + employee + ",%')) "); + params.put("employee", employee); + } + + if(StringUtils.isNotBlank(status)) { + sb.append(params.size() > 0 ?" and ":" where "); + int statusInt = Integer.parseInt(status); + if(statusInt == 1) {// 待提交 + sb.append(" a.status = 1 "); + params.put("status", statusInt); + } else if(statusInt == 2) {// 待付款 + sb.append(" a.status = 2 "); + params.put("status", statusInt); + } else if(statusInt == 3) {// 待分仓 + sb.append(" a.status in(3, 4) "); + params.put("status", statusInt); + } else if(statusInt == 5) {// 待出库 + sb.append(" a.status = 5 "); + params.put("status", statusInt); + } else if(statusInt == 6) {// 已出库 + sb.append(" a.status = 6 "); + params.put("status", statusInt); + } + } + + StringBuffer orderBy = new StringBuffer(""); + + orderBy.append(" order by dt desc "); + + orderBy.append(" offset "+ (pageable.getPageNumber() * pageable.getPageSize()) + " rows fetch next "+ pageable.getPageSize() + " rows only "); + + String sql = " select a.id as billHg, a.account, a.accountname, a.manager, a.managername, a.status, " + + " a.logisticsname, a.logisticsno, (a.subtotal+a.freight) as subtotal from jc_billhg a " + + sb.toString() + orderBy.toString(); + + LOG.info("queryApiJcBillHgSearchItem>>>SQL>>>{}", sql); + + List lists = jdbcTemplate.query(sql, new BeanPropertyRowMapper(ApiJcBillHgSearchItem.class)); + + Long count = jdbcTemplate.queryForObject("select count(a.id) from jc_billhg a " + sb.toString(), Long.class); + + Page scorePage = new PageImpl(lists, pageable, count); + return scorePage; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryJcBillCount(List ids) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer("select billhg as id, count(product) as breednum, sum(numbers) as numbers "); + sb.append(" from jc_billin_item a "); + + if(ids != null && ids.size() >= 1) { + StringBuffer idIn = new StringBuffer(); + for(String key : ids){ + idIn.append("'" + key + "',"); + } + String idIns = idIn.toString().substring(0, idIn.length() - 1); + + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billhg in (" + idIns + ") "); + params.put("billhg", idIn); + } + + sb.append(" group by billhg"); + + LOG.info("queryJcBillCount>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(JcBillCount.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public ApiBillHg queryApiBillHgById(String hgId) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer(" select a.id, a.billid, a.status, a.source, a.account,"); + sb.append(" a.accountname, a.quantity, a.subtotal, a.freight, a.manager,"); + sb.append(" a.managername, a.consignee, a.consigneephone, a.province, a.provincename,"); + sb.append(" a.city, a.cityname, a.area, a.areaname, a.address,"); + sb.append(" a.receiveway, a.remark, a.remark1, a.logisticsname, a.logisticscode,"); + sb.append(" a.logisticstype, a.logisticsno"); + sb.append(" from jc_billhg a"); + + if(StringUtils.isNotBlank(hgId)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.id = '" + hgId + "' "); + params.put("id", hgId); + } + + LOG.info("queryApiBillHgById>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(ApiBillHg.class)); + + return (lsit != null && lsit.size() >= 1) ? lsit.get(0) : null; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryApiBillHgItemByHgId(String hgId) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer("select a.id, a.status, a.product, a.productname, b.spec, a.price, "); + sb.append(" a.quantity, a.numbers, a.hgprice, a.hgamount"); + sb.append(" from jc_billin_item a"); + sb.append(" left join pms_product b on a.product = b.id"); + + if(StringUtils.isNotBlank(hgId)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billhg = '" + hgId + "' "); + params.put("billhg", hgId); + } + + LOG.info("queryApiBillHgItemByHgId>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(ApiBillHgItem.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryApiBillHgPaymentByHgId(String hgId) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer(" select a.billhg, a.payment, a.amount, a.zhmc, a.khyh, a.yhzh from jc_billhg_pay a "); + + if(StringUtils.isNotBlank(hgId)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billhg = '" + hgId + "' "); + params.put("billhg", hgId); + } + + LOG.info("queryApiBillHgPaymentByHgId>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(ApiBillHgPayment.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryJcCodeFlow(List codes) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer("select b.id, b.deposit, b.depositname, b.dt as tdate, b.orderid,"); + sb.append(" c.customerid, c.customername, c.aprssalemanid, c.aprssalemanname, c.bizgroupid,"); + sb.append(" c.bizgroupname, c.wsareaid, c.wsareaname,"); + sb.append(" a.code, a.productid, a.productname"); + sb.append(" from bcs_codeflow a"); + sb.append(" left join wmsn_despatch b on b.id = a.srcid "); + sb.append(" left join ws_wholesalebill c on c.id = b.orderid"); + + if(codes != null && codes.size() >= 1) { + StringBuffer idIn = new StringBuffer(); + for(String key : codes){ + idIn.append("'" + key + "',"); + } + String idIns = idIn.toString().substring(0, idIn.length() - 1); + + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.code in (" + idIns + ") "); + params.put("id", idIn); + } + + LOG.info("queryJcCodeFlow>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(JcCodeFlow.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryApiBillHgPaymentByHgId(List hgIds) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer(" select a.billhg, a.payment, a.amount, a.zhmc, a.khyh, a.yhzh from jc_billhg_pay a "); + + if(hgIds != null && hgIds.size() >= 1) { + StringBuffer idIn = new StringBuffer(); + for(String key : hgIds){ + idIn.append("'" + key + "',"); + } + String idIns = idIn.toString().substring(0, idIn.length() - 1); + + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billhg in (" + idIns + ") "); + params.put("id", idIn); + } + + LOG.info("queryApiBillHgPaymentByHgId>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(ApiBillHgPayment.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryJcProduct(String product, String stockInId, String hgId) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer(" select a.billid,a.billin,a.billhg,a.account,a.accountname,a.product,a.productname,"); + sb.append(" sum(a.quantity) as quantity ,sum(a.numbers) as numbers,"); + sb.append(" (select h.wdtbillout from jc_billhg h where h.billid = a.billid and h.id = a.billhg) as wdtbillout"); + sb.append(" from jc_billin_item a"); + + if(StringUtils.isNotBlank(product)) { + sb.append(params.size() > 0 ?" and ":" where "); +// sb.append(" a.product ='" + product + "' "); + sb.append(" a.billid in (select jbi.billid from jc_billsource_item jbi where jbi.goodsid ='" + product + "' and jbi.status = 3) "); + params.put("product", product); + } + if(StringUtils.isNotBlank(stockInId)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billin ='" + stockInId + "' "); + params.put("billin", stockInId); + } + if(StringUtils.isNotBlank(hgId)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billhg ='" + hgId + "' "); + params.put("billhg", hgId); + } + + sb.append(" group by a.billid,a.billin,a.billhg,a.account,a.accountname,a.product,a.productname"); + + LOG.info("queryJcProduct>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(JcProduct.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryJcProductBillSouce(List billIds) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer(" select indexno,billid,account,product,goodsid from jc_billsource_item a "); + + if(billIds != null && billIds.size() >= 1) { + StringBuffer idIn = new StringBuffer(); + for(String key : billIds){ + idIn.append("'" + key + "',"); + } + String idIns = idIn.toString().substring(0, idIn.length() - 1); + + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billid in (" + idIns + ") "); + params.put("id", idIn); + } + + LOG.info("queryJcProductBillSouce>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(JcProductBillSouce.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryJcProduct(String product, String stockInId) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sb = new StringBuffer(" select a.billid,a.billin,a.billhg,a.account,a.accountname,a.product,a.productname,"); + sb.append(" sum(a.quantity) as quantity ,sum(a.numbers) as numbers,b.goodsid,"); + sb.append(" (select h.wdtbillout from jc_billhg h where h.billid = a.billid and h.id = a.billhg) as wdtbillout"); + sb.append(" from jc_billin_item a"); + sb.append(" left join jc_billsource_item b on a.billid = b.billid and a.account = b.account and a.product = b.product "); + + if(StringUtils.isNotBlank(product)) { + sb.append(params.size() > 0 ?" and ":" where "); +// sb.append(" a.product ='" + product + "' "); + sb.append(" a.billid in (select jbi.billid from jc_billsource_item jbi where jbi.goodsid ='" + product + "' and jbi.status = 3) "); + params.put("product", product); + } + if(StringUtils.isNotBlank(stockInId)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billin ='" + stockInId + "' "); + params.put("billin", stockInId); + } + + sb.append(" group by a.billid,a.billin,a.billhg,a.account,a.accountname,a.product,a.productname,b.goodsid"); + + LOG.info("queryJcProduct>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(JcProduct.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List qeryJcBillHgs(List billids) throws RuntimeException { + try { + Map params = new HashMap(); + StringBuffer sql = new StringBuffer("select id, version, billid, status, source,"); + sql.append(" account, accountname, quantity, subtotal, freight,"); + sql.append(" manager, managername, consignee, consigneephone, province,"); + sql.append(" provincename, city, cityname, area, areaname,"); + sql.append(" address, receiveway, remark, remark1, salearea,"); + sql.append(" saleareaname, groupid, groupname, logisticsname, logisticscode,"); + sql.append(" logisticstype, logisticsno, found, foundname,"); + sql.append(" founddt, submit, submitname, submitdt, audit,"); + sql.append(" auditname, auditdt, dt, fhwarehouse, fhwarehousename,"); + sql.append(" wdtorder, wdtbillout, wdtbillouttyp"); + sql.append(" from jc_billhg a"); + + if(billids != null && billids.size() >= 1) { + StringBuffer idIn = new StringBuffer(); + for(String key : billids){ + idIn.append("'" + key + "',"); + } + String idIns = idIn.toString().substring(0, idIn.length() - 1); + + sql.append(params.size() > 0 ?" and ":" where "); + sql.append(" a.billid in (" + idIns + ") "); + params.put("billid", idIn); + } + + LOG.info("qeryJcBillHgs>>>SQL>>>{}", sql.toString()); + + List lsit = jdbcTemplate.query(sql.toString(), new BeanPropertyRowMapper(JcBillHg.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/AutoCompleteAccess.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/AutoCompleteAccess.java new file mode 100644 index 0000000..571970e --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/AutoCompleteAccess.java @@ -0,0 +1,416 @@ +package abacus.springboot.example.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import com.abacus.pms.dao.Account; +import com.abacus.pms.dao.Brand; +import com.abacus.pms.dao.MoreCategory; +import com.abacus.pms.dao.Product; +import com.abacus.pms.dao.Spec; +import com.abacus.xpos.foundation.dao.BaseArea; +import com.abacus.xpos.foundation.dao.Dept; +import com.abacus.xpos.foundation.dao.Employee; + +import abacus.config.dao.AbacusConfigItem; +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.pi.AutoCompleteAccessIF; + +/** + *

Title:ApiJcBillAccess

+

Description: 底层实现

+ @author chuanZeng + @date 2026年8月18日 + */ +@Repository("autoCompleteAccess") +public class AutoCompleteAccess extends MyJpaUtils implements AutoCompleteAccessIF { + + private final static Log LOG = LogFactory.getLog(AutoCompleteAccess.class); + + @PersistenceContext + private EntityManager entityManager; + + @Autowired + private JdbcTemplate jdbcTemplate; + + @SuppressWarnings("unchecked") + public List prductAutoComplete(String keyCode, List areaIds) throws Exception { + try { + Map params = new HashMap(); + + StringBuffer sql = new StringBuffer("from Product "); + if(StringUtils.isNotBlank(keyCode)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" (lower(name) like lower('%" + keyCode.replaceAll("'", "") + "%')"); + sql.append(" or lower(id) like lower('%" + keyCode.replaceAll("'", "") + "%')"); + sql.append(" or lower(shortstring) like lower('%" + keyCode.replaceAll("'", "") + "%'))"); + params.put("id", keyCode); + } + +// if(!areaIds.isEmpty()){ +// sql.append(params.size() > 0 ? " and " : " where "); +// sql.append(" areaid in (:areaid) "); +// params.put("areaid", areaIds); +// } + + Query query = this.entityManager.createQuery(sql.toString(), Product.class); + +// setParameters(query, params); + + List products = query.getResultList(); + + return products; + } catch (Exception e) { + e.printStackTrace(); + LOG.error(e.getMessage(), e); + throw new Exception(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Override + public List deptAutoComplete(String keyCode, String type) throws Exception { + try { + Map params = new HashMap(); + + StringBuffer sql = new StringBuffer("from Dept"); + if(StringUtils.isNotBlank(keyCode)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" (lower(name) like lower(:name)"); + sql.append(" or lower(id) like lower(:id)"); + sql.append(" or lower(shortString) like lower(:shortstring))"); + + params.put("name","%"+keyCode+"%"); + params.put("id","%"+keyCode+"%"); + params.put("shortstring","%"+keyCode+"%"); + } + + if(StringUtils.isNotBlank(type)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" typ = :typ "); + params.put("typ", Integer.parseInt(type)); + } + + Query query = this.entityManager.createQuery(sql.toString(), Dept.class); + + setParameters(query, params); + + return new ArrayList(query.getResultList()); + } catch (Exception e) { + e.printStackTrace(); + LOG.error(e.getMessage(), e); + throw new Exception(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Override + public List moreCategoryAutoComplete(String keyCode, String areaid, String levels, String lastlevel) + throws Exception { + try { + Map params = new HashMap(); + + StringBuffer sql = new StringBuffer("from MoreCategory"); + if(StringUtils.isNotBlank(keyCode)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" (lower(name) like lower(:name)"); + sql.append(" or lower(id) like lower(:id))"); + + params.put("name","%"+keyCode+"%"); + params.put("id","%"+keyCode+"%"); + } + + if(StringUtils.isNotBlank(areaid)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" areaid = :areaid "); + params.put("areaid", areaid); + } + + if(StringUtils.isNotBlank(levels)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" levels = :levels "); + params.put("levels", Integer.parseInt(levels)); + } + + if(StringUtils.isNotBlank(lastlevel)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" lastlevel = :lastlevel "); + params.put("lastlevel", Integer.parseInt(lastlevel)); + } + + Query query = this.entityManager.createQuery(sql.toString(), MoreCategory.class); + + setParameters(query, params); + + return new ArrayList(query.getResultList()); + } catch (Exception e) { + e.printStackTrace(); + LOG.error(e.getMessage(), e); + throw new Exception(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Override + public List brandAutoComplete(String keyCode, String areaid, String levels, String lastlevel) + throws Exception { + try { + Map params = new HashMap(); + + StringBuffer sql = new StringBuffer("from Brand"); + if(StringUtils.isNotBlank(keyCode)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" (lower(name) like lower(:name)"); + sql.append(" or lower(id) like lower(:id))"); + + params.put("name","%"+keyCode+"%"); + params.put("id","%"+keyCode+"%"); + } + + if(StringUtils.isNotBlank(areaid)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" areaid = :areaid "); + params.put("areaid", areaid); + } + + if(StringUtils.isNotBlank(levels)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" levels = :levels "); + params.put("levels", Integer.parseInt(levels)); + } + + if(StringUtils.isNotBlank(lastlevel)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" lastlevel = :lastlevel "); + params.put("lastlevel", Integer.parseInt(lastlevel)); + } + + Query query = this.entityManager.createQuery(sql.toString(), Brand.class); + + setParameters(query, params); + + return new ArrayList(query.getResultList()); + } catch (Exception e) { + e.printStackTrace(); + LOG.error(e.getMessage(), e); + throw new Exception(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Override + public List specAutoComplete(String keyCode, String areaid) throws Exception { + try { + Map params = new HashMap(); + + StringBuffer sql = new StringBuffer("from Spec "); + if(StringUtils.isNotBlank(keyCode)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" (lower(name) like lower('%" + keyCode.replaceAll("'", "") + "%')"); + sql.append(" or lower(id) like lower('%" + keyCode.replaceAll("'", "") + "%'))"); + } + + if(StringUtils.isNotBlank(areaid)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" areaid = :areaid "); + params.put("areaid", areaid); + } + + Query query = this.entityManager.createQuery(sql.toString(), Spec.class); + + setParameters(query, params); + + return new ArrayList(query.getResultList()); + } catch (Exception e) { + e.printStackTrace(); + LOG.error(e.getMessage(), e); + throw new Exception(e.getMessage()); + } + } + + + @SuppressWarnings("unchecked") + @Override + public List accountAutoComplete(String keyCode, String areaid) throws Exception { + try { + Map params = new HashMap(); + + StringBuffer sql = new StringBuffer("from Account"); + if(StringUtils.isNotBlank(keyCode)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" (lower(name) like lower(:name)"); + sql.append(" or lower(id) like lower(:id)"); + sql.append(" or lower(shortString) like lower(:shortstring))"); + + params.put("name","%"+keyCode+"%"); + params.put("id","%"+keyCode+"%"); + params.put("shortstring","%"+keyCode+"%"); + } + + if(StringUtils.isNotBlank(areaid)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" areaid = :areaid "); + params.put("areaid", areaid); + } + + Query query = this.entityManager.createQuery(sql.toString(), Account.class); + + setParameters(query, params); + + return new ArrayList(query.getResultList()); + } catch (Exception e) { + e.printStackTrace(); + LOG.error(e.getMessage(), e); + throw new Exception(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Override + public List employeeAutoComplete(String keyCode) throws Exception { + try { + Map params = new HashMap(); + + StringBuffer sql = new StringBuffer("from Employee"); + if(StringUtils.isNotBlank(keyCode)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" (lower(name) like lower(:name)"); + sql.append(" or lower(id) like lower(:id)"); + sql.append(" or lower(shortString) like lower(:shortstring))"); + + params.put("name","%"+keyCode+"%"); + params.put("id","%"+keyCode+"%"); + params.put("shortstring","%"+keyCode+"%"); + } + + + Query query = this.entityManager.createQuery(sql.toString(), Employee.class); + + setParameters(query, params); + + return new ArrayList(query.getResultList()); + } catch (Exception e) { + e.printStackTrace(); + LOG.error(e.getMessage(), e); + throw new Exception(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Override + public List jcBillAutoComplete(String keyCode) throws Exception { + try { + Map params = new HashMap(); + + StringBuffer sql = new StringBuffer("from JcBill "); + if(StringUtils.isNotBlank(keyCode)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" lower(id) like lower('%" + keyCode.replaceAll("'", "") + "%')"); + params.put("id", keyCode); + } + + Query query = this.entityManager.createQuery(sql.toString(), JcBill.class); + + List products = query.getResultList(); + + return products; + } catch (Exception e) { + e.printStackTrace(); + LOG.error(e.getMessage(), e); + throw new Exception(e.getMessage()); + } + } + + @SuppressWarnings("unchecked") + @Override + public List abacusConfigItemGroupAutoComplete(String keyCode, String keyGroup, String key) throws Exception { + try { + + Map params = new HashMap(); + + StringBuffer sql = new StringBuffer("from AbacusConfigItem"); + if(StringUtils.isNotBlank(keyCode)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" (lower(code) like lower(:code)"); + sql.append(" or lower(name) like lower(:name))"); + + params.put("code","%"+keyCode+"%"); + params.put("name","%"+keyCode+"%"); + } + + if(StringUtils.isNotBlank(keyGroup)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" keyGroup = :keyGroup "); + params.put("keyGroup", keyGroup); + } + if(StringUtils.isNotBlank(key)){ + sql.append(params.size() > 0 ? " and " : " where "); + sql.append(" key = :key "); + params.put("key", key); + } + + Query query = this.entityManager.createQuery(sql.toString(), AbacusConfigItem.class); + + setParameters(query, params); + + return new ArrayList(query.getResultList()); + } catch (Exception e) { + e.printStackTrace(); + LOG.error(e.getMessage(), e); + throw new Exception(e.getMessage()); + } + } + + @Override + public Map> getGovbs() throws Exception { + try { + Map> map = new HashMap>(); + + String sql = "select city, id, name from basearea order by id desc offset 0 rows fetch next 3000 rows only "; + List lists = jdbcTemplate.query(sql, new BeanPropertyRowMapper(BaseArea.class)); + + if(lists!=null&&!lists.isEmpty()){ + for(BaseArea obj:lists){ + Map mapb = map.get(obj.getCity()); + if(mapb==null){ + mapb = new HashMap(); + map.put(obj.getCity(), mapb); + } + mapb.put(obj.getId(), obj.getName()); + } + } + + return map; + } catch (Exception e) { + e.printStackTrace(); + LOG.error(e.getMessage(), e); + throw new Exception(e.getMessage()); + } + } + +} + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/JcBillAccess.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/JcBillAccess.java new file mode 100644 index 0000000..1e27420 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/JcBillAccess.java @@ -0,0 +1,670 @@ +package abacus.springboot.example.impl; + +import java.sql.PreparedStatement; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import javax.persistence.Query; + +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.jdbc.core.BatchPreparedStatementSetter; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillHg; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.dao.JcSourceItem; +import abacus.springboot.example.pi.JcBillAccessIF; +import abacus.springboot.example.util.DateUtil; +import abacus.springboot.example.vo.BaiduToken; +import abacus.springboot.example.vo.SiDepositlocation; + +/** + *

Title:ApiJcBillAccess

+

Description: 底层实现

+ @author chuanZeng + @date 2026年8月18日 + */ +@Repository +public class JcBillAccess extends MyJpaUtils implements JcBillAccessIF { + + private static final Logger LOG = LoggerFactory.getLogger(JcBillAccess.class); + + @Autowired + private JdbcTemplate jdbcTemplate; + + @PersistenceContext + private EntityManager em; + + @Override + public List queryJcBillPhoto(String srcid, String srcitemid, String typephoto) + throws RuntimeException { + try { + Map params = new HashMap(); + List args = new ArrayList(); + StringBuffer sb = new StringBuffer("select id, version, srcid, srcitemid, typephoto, urlphoto, dt from jc_bill_photo a"); + + if(StringUtils.isNotBlank(srcid)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.srcid = ? "); + args.add(srcid); + params.put("srcid", srcid); + } + if(StringUtils.isNotBlank(srcitemid)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.srcitemid = ? "); + args.add(srcitemid); + params.put("srcitemid", srcitemid); + } + if(StringUtils.isNotBlank(typephoto)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.typephoto = ? "); + args.add(typephoto); + params.put("typephoto", typephoto); + } + + LOG.info("queryJcBillPhoto>>>SQL>>>{}", sb.toString()); + + List lists = jdbcTemplate.query( sb.toString(), args.toArray(), new BeanPropertyRowMapper(JcBillPhoto.class)); + + return lists; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + public List queryJcBillPhotoIn(List srcids) throws RuntimeException { + try { + Map params = new HashMap(); + List args = new ArrayList(); + StringBuffer sb = new StringBuffer("select id, version, srcid, srcitemid, typephoto, urlphoto, dt from jc_bill_photo a"); + + if(srcids != null && srcids.size() >= 1) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.srcid in ("); + for(int i = 0; i < srcids.size(); i++){ + if(i > 0) sb.append(","); + sb.append("?"); + args.add(srcids.get(i)); + } + sb.append(") "); + } + + LOG.info("queryJcBillPhotoIn>>>SQL>>>{}", sb.toString()); + + List lists = jdbcTemplate.query( sb.toString(), args.toArray(), new BeanPropertyRowMapper(JcBillPhoto.class)); + + return lists; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public void updateJcBill(JcBill bill) throws RuntimeException { + try { + List args = new ArrayList(); + StringBuffer sql = new StringBuffer(" update jc_bill "); + sql.append(" set status = ?,"); + sql.append(" warehouse = ?,"); + sql.append(" warehousename = ?,"); + sql.append(" receivedt = ?,"); + sql.append(" quantity = ?,"); + sql.append(" subtotal = ?,"); + sql.append(" applicant = ?,"); + sql.append(" applicantname = ?,"); + sql.append(" applicantdt = ?"); + sql.append(" where id = ?"); + + args.add(bill.getStatus()); + args.add(bill.getWarehouse()); + args.add(bill.getWarehousename()); + args.add(bill.getReceivedt()); + args.add(bill.getQuantity()); + args.add(bill.getSubtotal()); + args.add(bill.getApplicant()); + args.add(bill.getApplicantname()); + args.add(DateUtil.formatDateTime(bill.getApplicantdt())); + args.add(bill.getId()); + + this.jdbcTemplate.update(sql.toString(), args.toArray()); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public void updateJcBillSourceItem(List items) throws RuntimeException { + try { + String sql = "update jc_billsource_item set recsource = ?, recplatform = ?, channel = ?, price = ?, quantity = ?," + + " numbers = ?, subtotal = ?, goodsid = ?, logisticsid = ?" + + " where id = ?"; + + this.jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + + public void setValues(PreparedStatement ps, int i) throws SQLException { + JcBillSourceItem item = items.get(i); + ps.setString(1, item.getRecsource()); + ps.setString(2, item.getRecplatform()); + ps.setString(3, item.getChannel()); + ps.setDouble(4, item.getPrice()); + ps.setDouble(5, item.getQuantity()); + + ps.setDouble(6, item.getNumbers()); + ps.setDouble(7, item.getSubtotal()); + ps.setString(8, item.getGoodsid()); + ps.setString(9, item.getLogisticsid()); + + ps.setLong(10, item.getId()); + + } + + public int getBatchSize() { + return items.size(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public void updateJcBillPhoto(List photos) throws RuntimeException { + try { + String sql = "update jc_bill_photo set urlphoto = ?, dt = ? where srcid = ? and srcitemid = ? and typephoto = ?"; + + this.jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() { + + public void setValues(PreparedStatement ps, int i) throws SQLException { + JcBillPhoto item = photos.get(i); + ps.setString(1, item.getUrlphoto()); + ps.setDate(2, new java.sql.Date(item.getDt().getTime())); + ps.setString(3, item.getSrcid()); + ps.setString(4, item.getSrcitemid()); + ps.setString(5, item.getTypephoto()); + + } + + public int getBatchSize() { + return photos.size(); + } + }); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public int countJcBillItemIndexno(String billId) throws RuntimeException { + try { + StringBuffer sb = new StringBuffer(" select max(indexno) from jc_billsource_item a where a.billid = ?"); + + Query q = this.em.createNativeQuery(sb.toString()).setParameter(1, billId); + + return q.getSingleResult() == null ? 0 : Integer.valueOf(q.getSingleResult().toString()); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public String lastBillHgId() throws RuntimeException { + try { + StringBuffer sb = new StringBuffer(" select top 1 id from jc_billhg a where a.status = 1 order by founddt asc "); + + List lists = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(JcBill.class)); + + return (lists != null && lists.size() >= 1) ? lists.get(0).getId() : ""; + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryJcSourceItemByBillId(String billId) { + try { + Map params = new HashMap(); + List args = new ArrayList(); + StringBuffer sb = new StringBuffer("select id, version, indexno, billid, srcitemid,"); + sb.append(" goodsid, logisticsid, billout, billoutdt, billoutwh,"); + sb.append(" billoutwhname, product, productname, account, accountname,"); + sb.append(" operator, operatorname, groupid, groupname, salearea,"); + sb.append(" saleareaname, source, dt"); + sb.append(" from jc_source_item a"); + + if(StringUtils.isNotBlank(billId)) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billid = ? "); + args.add(billId); + params.put("billId", billId); + } + + LOG.info("queryJcSourceItemByBillId>>>SQL>>>{}", sb.toString()); + + List lists = jdbcTemplate.query( sb.toString(), args.toArray(), new BeanPropertyRowMapper(JcSourceItem.class)); + + return lists; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public void deleteJcSourceItemBySource(String billId) throws RuntimeException { + try { + StringBuffer sb = new StringBuffer(" delete from jc_source_item where billid = ? and source in ('业务中台', '二维码')"); + + LOG.info("deleteJcSourceItemBySource>>>SQL>>>{}", sb.toString()); + + jdbcTemplate.update(sb.toString(), billId); + + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public Page queryJcBill(String fromDate, String thruDate, String applicant, String goods, String id, + String billin, String goodsid, String product, String status, int typ, Pageable pageable) throws RuntimeException { + try { + Map params = new HashMap(); + List args = new ArrayList(); + StringBuffer sb = new StringBuffer(""); + + if(StringUtils.isNotBlank(fromDate)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.applicantdt >= ? "); + args.add(fromDate); + params.put("fromDate", fromDate); + } + if(StringUtils.isNotBlank(thruDate)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.applicantdt <= ? "); + args.add(thruDate); + params.put("thruDate", thruDate); + } + if(StringUtils.isNotBlank(applicant)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.applicant = ? "); + args.add(applicant); + params.put("applicant", applicant); + } + if(StringUtils.isNotBlank(goods)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.goods = ? "); + args.add(goods); + params.put("goods", goods); + } + if(StringUtils.isNotBlank(id)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.id = ? "); + args.add(id); + params.put("id", id); + } + if(StringUtils.isNotBlank(billin)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.billin = ? "); + args.add(billin); + params.put("billin", billin); + } + if(StringUtils.isNotBlank(status)) { + if(typ == 1) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.status = ? "); + args.add(Integer.parseInt(status)); + params.put("status", Integer.parseInt(status)); + } else { + + if("1".equals(status) || "2".equals(status)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.hgstatus = ? "); + args.add(Integer.parseInt(status)); + params.put("hgstatus", Integer.parseInt(status)); + } else { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.status = ? "); + args.add(Integer.parseInt(status)); + params.put("status", Integer.parseInt(status)); + } + + } + + }else { + if(typ == 1) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.status in (-3, -2, 2, 3, 4, 5) "); + params.put("status", status); + } else { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" (a.status in (3, 4, 5) or a.hgstatus in (1, 2))"); + params.put("status", status); + } + } + if(StringUtils.isNotBlank(goodsid)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.id in (select b.billid from jc_billsource_item b where b.goods like ? ) "); + args.add("%" + goodsid + "%"); + params.put("goodsid", goodsid); + } + if(StringUtils.isNotBlank(product)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.id in (select b.billid from jc_billsource_item b where b.product = ? ) "); + args.add(product); + params.put("product", product); + } + + StringBuffer orderBy = new StringBuffer(""); + + orderBy.append(" order by dt desc "); + + orderBy.append(" offset "+ (pageable.getPageNumber() * pageable.getPageSize()) + " rows fetch next "+ pageable.getPageSize() + " rows only "); + + + StringBuffer sql = new StringBuffer("select id, version, status, hgstatus, goods, warehouse, warehousename,"); + sql.append(" receivedt, quantity, subtotal, billin, billindt, applicant, applicantname, applicantdt, dt"); + sql.append(" from jc_bill a "); + sql.append(sb.toString()); + sql.append(orderBy.toString()); + + LOG.info("queryJcBill>>>SQL>>>{}", sql.toString()); + + List lists = jdbcTemplate.query(sql.toString(), args.toArray(), new BeanPropertyRowMapper(JcBill.class)); + + Long count = jdbcTemplate.queryForObject("select count(a.id) from jc_bill a " + sb.toString(), args.toArray(), Long.class); + + Page scorePage = new PageImpl(lists, pageable, count); + return scorePage; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public void saveEvent(String srcid, String typ, String billtyp) throws RuntimeException { + try { + String sql="insert into si_siwdevent(srcid, typ, billtyp, deptid, stauts," + + " node, remake, dt, inputdate)" + + " values (?, ?, ?, ?, ?," + + " ?, ?, ?, ?) "; + Query query = em.createNativeQuery(sql); + query.setParameter(1, srcid); + query.setParameter(2, typ); + query.setParameter(3, billtyp); + query.setParameter(4, ""); + query.setParameter(5, 0); + + query.setParameter(6, 0); + query.setParameter(7, ""); + query.setParameter(8, new Date()); + query.setParameter(9, new Date()); + query.executeUpdate(); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public Page queryJcBillHg(String fromDate, String thruDate, String account, String salearea, String id, + String billId, String status, String product, String manager, int typ, Pageable pageable) + throws RuntimeException { + try { + Map params = new HashMap(); + List args = new ArrayList(); + StringBuffer sb = new StringBuffer(""); + + if(StringUtils.isNotBlank(fromDate)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.founddt >= ? "); + args.add(fromDate); + params.put("fromDate", fromDate); + } + if(StringUtils.isNotBlank(thruDate)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.founddt <= ? "); + args.add(thruDate); + params.put("thruDate", thruDate); + } + if(StringUtils.isNotBlank(account)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.account = ? "); + args.add(account); + params.put("account", account); + } + if(StringUtils.isNotBlank(salearea)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.salearea = ? "); + args.add(salearea); + params.put("salearea", salearea); + } + if(StringUtils.isNotBlank(id)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.id = ? "); + args.add(id); + params.put("id", id); + } + if(StringUtils.isNotBlank(billId)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.billid = ? "); + args.add(billId); + params.put("billId", billId); + } + if(StringUtils.isNotBlank(status)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.status = ? "); + args.add(Integer.parseInt(status)); + params.put("status", Integer.parseInt(status)); + } else { + if(typ == 1) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.status in (1, 2, 3) "); + params.put("status", status); + } else { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.status in (4, 5, 6) "); + params.put("status", status); + } + } + + if(StringUtils.isNotBlank(product)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.id in (select b.billhg from jc_billin_item b where b.product = ? ) "); + args.add(product); + params.put("product", product); + } + if(StringUtils.isNotBlank(manager)) { + sb.append(params.size() > 0 ? " and ":" where "); + sb.append(" a.manager = ? "); + args.add(manager); + params.put("manager", manager); + } + + + StringBuffer orderBy = new StringBuffer(""); + + orderBy.append(" order by founddt desc "); + + orderBy.append(" offset "+ (pageable.getPageNumber() * pageable.getPageSize()) + " rows fetch next "+ pageable.getPageSize() + " rows only "); + + + StringBuffer sql = new StringBuffer("select id, version, billid, status, source,"); + sql.append(" account, accountname, quantity, subtotal, freight,"); + sql.append(" manager, managername, consignee, consigneephone, province,"); + sql.append(" provincename, city, cityname, area, areaname,"); + sql.append(" address, receiveway, remark, remark1, salearea,"); + sql.append(" saleareaname, groupid, groupname, logisticsname, logisticscode,"); + sql.append(" logisticstype, logisticsno, found, foundname,"); + sql.append(" founddt, submit, submitname, submitdt, audit,"); + sql.append(" auditname, auditdt, dt, fhwarehouse, fhwarehousename,"); + sql.append(" wdtorder, wdtbillout, wdtbillouttyp"); + sql.append(" ,(select b.status from jc_bill b where b.id = a.billid ) as jcstatus"); + sql.append(" from jc_billhg a"); + sql.append(sb.toString()); + sql.append(orderBy.toString()); + + LOG.info("queryJcBillHg>>>SQL>>>{}", sb.toString()); + + List lists = jdbcTemplate.query(sql.toString(), args.toArray(), new BeanPropertyRowMapper(JcBillHg.class)); + + Long count = jdbcTemplate.queryForObject("select count(a.id) from jc_billhg a " + sb.toString(), args.toArray(), Long.class); + + Page scorePage = new PageImpl(lists, pageable, count); + return scorePage; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public void deleteJcSourceItem(List ids) throws RuntimeException { + if(ids==null||ids.isEmpty()) return; + for(int i=0;iids.size()?ids.size():(i+500); + em.createNativeQuery("delete from jc_source_item where id in (:ids) ").setParameter("ids", ids.subList(i, end)).executeUpdate(); + } + + } + + @Override + public void deleteJcBillPhoto(String srcid, String srcitemid, String type) throws RuntimeException { + try { + StringBuffer sb = new StringBuffer(" delete from jc_bill_photo where" + + " srcid = ?" +// + " and srcitemid = ?" + + " and typephoto = ?"); + + LOG.info("deleteJcBillPhoto>>>SQL>>>{}", sb.toString()); + + jdbcTemplate.update(sb.toString(), srcid, type); + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public String getBaiduToken() throws RuntimeException { + try { + StringBuffer sb = new StringBuffer("select token from si_baidu_token"); + + List lists = jdbcTemplate.query(sb.toString(), new BeanPropertyRowMapper(BaiduToken.class)); + + return (lists != null && lists.size() >= 1) ? lists.get(0).getToken() : ""; + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public List queryJcBillSourceItemInBillId(List billIds) throws RuntimeException { + try { + Map params = new HashMap(); + List args = new ArrayList(); + StringBuffer sb = new StringBuffer(" select billid, status, recsource, recplatform, channel "); + sb.append(" from jc_billsource_item a "); + + if(billIds != null && billIds.size() >= 1) { + sb.append(params.size() > 0 ?" and ":" where "); + sb.append(" a.billid in ("); + for(int i = 0; i < billIds.size(); i++){ + if(i > 0) sb.append(","); + sb.append("?"); + args.add(billIds.get(i)); + } + sb.append(") "); + } + + LOG.info("queryJcBillSourceItemInBillId>>>SQL>>>{}", sb.toString()); + + List lsit = jdbcTemplate.query(sb.toString(), args.toArray(), new BeanPropertyRowMapper(JcBillSourceItem.class)); + + return lsit; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public SiDepositlocation querySiDepositlocation(String srcid) throws Exception { + try { + List args = new ArrayList(); + StringBuffer sb = new StringBuffer("select a.id, a.push from wms_depositlocation a"); + sb.append(" where a.id in (select d.physicaldept from dept d where d.id in"); + sb.append(" (select c.warehouse from jc_bill c where c.id = ?))"); + args.add(srcid); + + LOG.info("querySiDepositlocation>>>SQL>>>{}", sb.toString()); + + List lists = jdbcTemplate.query( sb.toString(), args.toArray(), new BeanPropertyRowMapper(SiDepositlocation.class)); + + return (lists != null && lists.size() >= 1) ? lists.get(0) : null; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public SiDepositlocation querySiDepositlocationHGfc(String srcid) throws Exception { + try { + List args = new ArrayList(); + StringBuffer sb = new StringBuffer("select a.id, a.push from wms_depositlocation a"); + sb.append(" where a.id in (select d.physicaldept from dept d where d.id in"); + sb.append(" (select c.fhwarehouse from jc_billhg c where c.id = ?))"); + args.add(srcid); + + LOG.info("querySiDepositlocationHGfc>>>SQL>>>{}", sb.toString()); + + List lists = jdbcTemplate.query( sb.toString(), args.toArray(), new BeanPropertyRowMapper(SiDepositlocation.class)); + + return (lists != null && lists.size() >= 1) ? lists.get(0) : null; + }catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + @Override + public void deleteEvent(String srcid, String typ, String billtyp) throws RuntimeException { + try { + String sql="delete from si_siwdevent where srcid = ? and typ = ? and billtyp = ?"; + Query query = em.createNativeQuery(sql); + query.setParameter(1, srcid); + query.setParameter(2, typ); + query.setParameter(3, billtyp); + query.executeUpdate(); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/MyJpaUtils.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/MyJpaUtils.java new file mode 100644 index 0000000..3619109 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/impl/MyJpaUtils.java @@ -0,0 +1,22 @@ +package abacus.springboot.example.impl; + +import java.util.Map; + +import javax.persistence.Query; + +public class MyJpaUtils { + + + /** + * 给hql参数设置值 + * + * @param query 查询 + * @param params 参数 + */ + public void setParameters(Query query, Map params) { + for (Map.Entry entry : params.entrySet()) { + query.setParameter(entry.getKey(), entry.getValue()); + } + } + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/pi/ApiJcBillAccessIF.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/pi/ApiJcBillAccessIF.java new file mode 100644 index 0000000..90a90ba --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/pi/ApiJcBillAccessIF.java @@ -0,0 +1,200 @@ +package abacus.springboot.example.pi; + +import java.util.List; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import abacus.springboot.example.api.view.ApiBillHg; +import abacus.springboot.example.api.view.ApiBillHgItem; +import abacus.springboot.example.api.view.ApiBillHgPayment; +import abacus.springboot.example.api.view.ApiJcBill; +import abacus.springboot.example.api.view.ApiJcBillHgSearchItem; +import abacus.springboot.example.api.view.ApiJcBillItem; +import abacus.springboot.example.api.view.ApiJcBillSearch; +import abacus.springboot.example.api.view.JcBillCount; +import abacus.springboot.example.api.view.JcCodeFlow; +import abacus.springboot.example.api.view.JcProduct; +import abacus.springboot.example.api.view.JcProductBillSouce; +import abacus.springboot.example.dao.JcBillHg; + +/** + *

Title:ApiJcBillAccess

+

Description: 底层实现-interface

+ @author chuanZeng + @date 2026年8月18日 + */ +public interface ApiJcBillAccessIF { + + /** + * 稽查收货查询 + * @param keyword + * @param status + * @param pageable + * @return + * @throws RuntimeException + */ + public Page queryApiJcBillSearch(String keyword, String employee, String status, Pageable pageable) throws RuntimeException; + + /** + * 稽查收货主单查询 + * @param id + * @return + * @throws RuntimeException + */ + public ApiJcBill queryApiJcBillById(String id) throws RuntimeException; + + /** + * 稽查收货明细 + * @param billId + * @return + * @throws RuntimeException + */ + public List queryApiJcBillItemByBIllId(String billId) throws RuntimeException; + + + /** + * 回购列表查询 + * @param keyword + * @param status + * @param pageable + * @return + * @throws RuntimeException + */ + public Page queryApiJcBillHgSearchItem(String keyword, String employee, String status, Pageable pageable) throws RuntimeException; + + /** + * 回购;查询品种和件数汇总 + * @param ids + * @return + * @throws RuntimeException + */ + public List queryJcBillCount(List ids) throws RuntimeException; + + /** + * 回购:主单查询 + * @param id + * @return + * @throws RuntimeException + */ + public ApiBillHg queryApiBillHgById(String hgId) throws RuntimeException; + + /** + * 回购:明细查询 + * @param billId + * @return + * @throws RuntimeException + */ + public List queryApiBillHgItemByHgId(String hgId) throws RuntimeException; + + /** + * 回购:支付明细查询 + * @param billId + * @return + * @throws RuntimeException + */ + public List queryApiBillHgPaymentByHgId(String hgId) throws RuntimeException; + + public List queryApiBillHgPaymentByHgId(List hgIds) throws RuntimeException; + + + /** + * 根据物流码,查询出库相关信息 + * @param code + * @return + * @throws RuntimeException + */ + public List queryJcCodeFlow(List codes) throws RuntimeException; + + /** + * 稽查货品查询-单号查询 + * @param product + * @param stockInId + * @param hgId + * @return + * @throws RuntimeException + */ + public List queryJcProduct(String product, String stockInId, String hgId) throws RuntimeException; + + /** + * 稽查货品查询-单号查询 + * @param product + * @param stockInId + * @param hgId + * @return + * @throws RuntimeException + */ + public List queryJcProduct(String product, String stockInId) throws RuntimeException; + + /** + * 根据稽查单号,查询对应的货品编号 + * @param billIds + * @return + * @throws RuntimeException + */ + public List queryJcProductBillSouce(List billIds)throws RuntimeException; + + + public List qeryJcBillHgs(List billids) throws RuntimeException; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/pi/AutoCompleteAccessIF.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/pi/AutoCompleteAccessIF.java new file mode 100644 index 0000000..2b7c9b4 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/pi/AutoCompleteAccessIF.java @@ -0,0 +1,121 @@ +package abacus.springboot.example.pi; + +import java.util.List; +import java.util.Map; + +import com.abacus.pms.dao.Account; +import com.abacus.pms.dao.Brand; +import com.abacus.pms.dao.MoreCategory; +import com.abacus.pms.dao.Product; +import com.abacus.pms.dao.Spec; +import com.abacus.xpos.foundation.dao.Dept; +import com.abacus.xpos.foundation.dao.Employee; + +import abacus.config.dao.AbacusConfigItem; +import abacus.springboot.example.dao.JcBill; + +/** + *

Title:ApiJcBillAccess

+

Description: 底层实现-interface

+ @author chuanZeng + @date 2026年8月18日 + */ +public interface AutoCompleteAccessIF { + + /** + * 检索:商品 + * @param keyCode + * @return + * @throws Exception + */ + public List prductAutoComplete(String keyCode, List areaIds) throws Exception; + + /** + * 检索:门店 + * @param keycode + * @param type + * @return + * @throws Exception + */ + public List deptAutoComplete(String keyCode, String type) throws Exception; + + /** + * 检索:分类 + * @param keycode + * @param type + * @return + * @throws Exception + */ + public List moreCategoryAutoComplete(String keyCode, String areaid, String levels, String lastlevel) throws Exception; + + /** + * 检索:品牌 + * @return + * @throws Exception + */ + public List brandAutoComplete(String keyCode, String areaid, String levels, String lastlevel) throws Exception; + + /** + * 检索:商品标签 + * @param keyCode + * @param areaid + * @param lastlevel + * @return + * @throws Exception + */ + public List specAutoComplete(String keyCode, String areaid) throws Exception; + + /** + * 检索:客户 + * @param keyCode + * @param areaid + * @return + * @throws Exception + */ + public List accountAutoComplete(String keyCode, String areaid) throws Exception; + + /** + * 检索:员工 + * @param keyCode + * @param areaid + * @return + * @throws Exception + */ + public List employeeAutoComplete(String keyCode) throws Exception; + + + /** + * 检索:稽查单号 + * @param keyCode + * @param areaid + * @return + * @throws Exception + */ + public List jcBillAutoComplete(String keyCode) throws Exception; + + /** + * 检索:收货仓库 + * @param keyCode + * @return + * @throws Exception + */ + public List abacusConfigItemGroupAutoComplete(String keyCode, String keyGroup, String key) throws Exception; + + /** 查询区域 */ + public Map> getGovbs() throws Exception; +} + + + + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/pi/JcBillAccessIF.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/pi/JcBillAccessIF.java new file mode 100644 index 0000000..329b976 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/pi/JcBillAccessIF.java @@ -0,0 +1,268 @@ +package abacus.springboot.example.pi; + +import java.util.List; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillHg; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.dao.JcSourceItem; +import abacus.springboot.example.vo.SiDepositlocation; + +/** + *

Title:ApiJcBillAccess

+

Description: 底层实现-interface

+ @author chuanZeng + @date 2026年8月18日 + */ +public interface JcBillAccessIF { + + + + /** + * 根据条件查询图片 + * @param srcid + * @param srcitemid + * @param typephoto + * @return + * @throws RuntimeException + */ + public List queryJcBillPhoto(String srcid, String srcitemid, String typephoto) throws RuntimeException; + + public List queryJcBillPhotoIn(List srcids) throws RuntimeException; + + /** + * 修改 + * @throws RuntimeException + */ + public void updateJcBill(JcBill bill) throws RuntimeException; + + /** + * 修改 + * @throws RuntimeException + */ + public void updateJcBillSourceItem(List items) throws RuntimeException; + + /** + * 修改 + * @param photos + * @throws RuntimeException + */ + public void updateJcBillPhoto(List photos) throws RuntimeException; + + /** + * 当前明细行号 + * @param billId + * @return + * @throws RuntimeException + */ + public int countJcBillItemIndexno(String billId) throws RuntimeException; + + /** + * 查询:下一单待提交的回购单号 + * @return + * @throws RuntimeException + */ + public String lastBillHgId() throws RuntimeException; + + /** + * 查询朔源明细 + * @param billId + * @return + */ + public List queryJcSourceItemByBillId(String billId); + + /** + * 删除特定的来源 + * @param billId + * @throws RuntimeException + */ + public void deleteJcSourceItemBySource(String billId) throws RuntimeException; + + /** + * 界面查询 + * @param fromDate + * @param thruDate + * @param applicant + * @param goods + * @param id + * @param billin + * @param goodsid + * @param product + * @param status + * @param pageable + * @return + * @throws RuntimeException + */ + public Page queryJcBill(String fromDate, String thruDate, String applicant, + String goods, String id, String billin, String goodsid, String product, String status, + int typ, Pageable pageable) throws RuntimeException; + + /** + * 保存事件 + * @return + * @throws RuntimeException + */ + public void saveEvent(String srcid, String typ, String billtyp) throws RuntimeException; + + + /** + * 分页查询 回购订单 + * @param typ 1-回购认款,2-回购分仓 + * @return + * @throws RuntimeException + */ + public Page queryJcBillHg(String fromDate, String thruDate, String account, + String salearea, String id, String billId, String status, String product, + String manager, + int typ, Pageable pageable) throws RuntimeException; + + + /** + * 删除溯源明细信息 + * @param ids + * @throws RuntimeException + */ + public void deleteJcSourceItem(List ids) throws RuntimeException; + + + /** + * 删除溯源明细图片 + * @param ids + * @throws RuntimeException + */ + public void deleteJcBillPhoto(String srcid, String srcitemid, String type) throws RuntimeException; + + /** + * 获取百度token + * @return + * @throws RuntimeException + */ + public String getBaiduToken() throws RuntimeException; + + public List queryJcBillSourceItemInBillId(List billIds) throws RuntimeException; + + /** + * 稽查:根据稽查单号,稽查单关联物理仓管理策略 + * @param dept + * @return + * @throws Exception + */ + public SiDepositlocation querySiDepositlocation(String srcid) throws Exception; + + /** + * 回购:根据回购单号,回购单关联物理仓管理策略 + * @param dept + * @return + * @throws Exception + */ + public SiDepositlocation querySiDepositlocationHGfc(String srcid) throws Exception; + + + /** + * 删除事件 + * @param srcid + * @param typ + * @param billtyp + * @throws RuntimeException + */ + public void deleteEvent(String srcid, String typ, String billtyp) throws RuntimeException; +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillHgPayRepository.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillHgPayRepository.java new file mode 100644 index 0000000..4a07e46 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillHgPayRepository.java @@ -0,0 +1,20 @@ +package abacus.springboot.example.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import abacus.springboot.example.dao.JcBillHgPay; + +/** + *

Title:ApiJcBillAccess

+

Description: Repository

+ @author chuanZeng + @date 2026年8月18日 + */ +public interface JcBillHgPayRepository extends JpaRepository,JpaSpecificationExecutor { + + List findByBillhg(String billhg); + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillHgRepository.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillHgRepository.java new file mode 100644 index 0000000..b08b473 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillHgRepository.java @@ -0,0 +1,14 @@ +package abacus.springboot.example.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import abacus.springboot.example.dao.JcBillHg; + +public interface JcBillHgRepository extends JpaRepository,JpaSpecificationExecutor { + + List findByBillid(String billid); + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillInItemRepository.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillInItemRepository.java new file mode 100644 index 0000000..076e3dd --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillInItemRepository.java @@ -0,0 +1,18 @@ +package abacus.springboot.example.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import abacus.springboot.example.dao.JcBillInItem; + +public interface JcBillInItemRepository extends JpaRepository,JpaSpecificationExecutor { + + List findByBillid(String billid); + + List findByBillidAndStatus(String billid, int status); + + List findByBillhg(String billhg); + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillPhotoRepository.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillPhotoRepository.java new file mode 100644 index 0000000..4270c59 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillPhotoRepository.java @@ -0,0 +1,16 @@ +package abacus.springboot.example.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import abacus.springboot.example.dao.JcBillPhoto; + +public interface JcBillPhotoRepository extends JpaRepository,JpaSpecificationExecutor { + + JcBillPhoto findBySrcidAndSrcitemidAndTypephoto(String srcid, String srcitemid, String typephoto); + + void deleteBySrcidAndSrcitemid(String srcid, String srcitemid); + + void deleteBySrcidAndTypephoto(String srcid, String typephoto); + void deleteBySrcidAndSrcitemidAndTypephoto(String srcid, String srcitemid, String typephoto); +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillRepository.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillRepository.java new file mode 100644 index 0000000..4f8fbd1 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillRepository.java @@ -0,0 +1,11 @@ +package abacus.springboot.example.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import abacus.springboot.example.dao.JcBill; + +public interface JcBillRepository extends JpaRepository,JpaSpecificationExecutor { + + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillSourceItemRepository.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillSourceItemRepository.java new file mode 100644 index 0000000..7c97b1c --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcBillSourceItemRepository.java @@ -0,0 +1,15 @@ +package abacus.springboot.example.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import abacus.springboot.example.dao.JcBillSourceItem; + +public interface JcBillSourceItemRepository extends JpaRepository,JpaSpecificationExecutor { + + List findByBillid(String billid); + + void deleteByBillid(String billid); +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcSourceItemRepository.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcSourceItemRepository.java new file mode 100644 index 0000000..ee2b496 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/repository/JcSourceItemRepository.java @@ -0,0 +1,15 @@ +package abacus.springboot.example.repository; + +import java.util.List; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; + +import abacus.springboot.example.dao.JcSourceItem; + +public interface JcSourceItemRepository extends JpaRepository,JpaSpecificationExecutor { + + List findByBillidAndSrcitemid(String billid, String srcitemid); + + List findByBillidAndSrcitemidAndStatus(String billid, String srcitemid, int status); +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/util/DateToUpperChinese.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/util/DateToUpperChinese.java new file mode 100644 index 0000000..f93e3b3 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/util/DateToUpperChinese.java @@ -0,0 +1,143 @@ +package abacus.springboot.example.util; + + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +/** + *

Title:DateToUpperChinese

+

Description: 日期转成中文大写形式

+ @author chuanZeng + @date 2026年8月18日 + */ +public class DateToUpperChinese { + private static final String[] NUMBERS = {"零", "壹", "贰", "叁", "肆", "伍", + "陆", "柒", "捌", "玖"}; + + /** + * 通过 yyyy-MM-dd 得到中文大写格式 yyyy MM dd 日期 + */ + public static synchronized String toChinese(String str) { + StringBuffer sb = new StringBuffer(); + sb.append(getSplitDateStr(str, 0)).append(" ").append( + getSplitDateStr(str, 1)).append(" ").append( + getSplitDateStr(str, 2)); + return sb.toString(); + } + + /** + * 分别得到年月日的大写 默认分割符 "-" + */ + public static String getSplitDateStr(String str, int unit) { + // unit是单位 0=年 1=月 2日 + String[] DateStr = str.split("-"); + if (unit > DateStr.length) + unit = 0; + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < DateStr[unit].length(); i++) { + + if ((unit == 1 || unit == 2) && Integer.valueOf(DateStr[unit]) > 9) { + sb.append(convertNum(DateStr[unit].substring(0, 1))) + .append("拾").append( + convertNum(DateStr[unit].substring(1, 2))); + break; + } else { + sb.append(convertNum(DateStr[unit].substring(i, i + 1))); + } + } + if (unit == 1 || unit == 2) { + return sb.toString().replaceAll("^壹", "").replace("零", ""); + } + return sb.toString(); + + } + + /** + * 转换数字为大写 + */ + private static String convertNum(String str) { + return NUMBERS[Integer.valueOf(str)]; + } + public final static char[] upper = "零一二三四五六七八九十".toCharArray(); + + /** + * 根据小写数字格式的日期转换成大写格式的日期 + * @param date + * @return + */ + public static String getUpperDate(Date datez) { + + //支持yyyy-MM-dd、yyyy/MM/dd、yyyyMMdd等格式 + if(datez == null) return null; + + SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd"); + String date = sdf.format(datez); + + + //非数字的都去掉 + date = date.replaceAll("\\D", ""); + if(date.length() != 8) return null; + StringBuilder sb = new StringBuilder(); + for (int i=0;i<4;i++) {//年 + sb.append(upper[Integer.parseInt(date.substring(i, i+1))]); + } + sb.append("年");//拼接年 + int month = Integer.parseInt(date.substring(4, 6)); + if(month <= 10) { + sb.append(upper[month]); + } else { + sb.append("十").append(upper[month%10]); + } + sb.append("月");//拼接月 + + int day = Integer.parseInt(date.substring(6)); + if (day <= 10) { + sb.append(upper[day]); + } else if(day < 20) { + sb.append("十").append(upper[day % 10]); + } else { + sb.append(upper[day / 10]).append("十"); + int tmp = day % 10; + if (tmp != 0) sb.append(upper[tmp]); + } + sb.append("日");//拼接日 + return sb.toString(); + } + /** + * 判断是否是零或正整数 + */ + public static boolean isNumeric(String str) { + Pattern pattern = Pattern.compile("[0-9]*"); + Matcher isNum = pattern.matcher(str); + if (!isNum.matches()) { + return false; + } + return true; + } + + public static void main(String args[]) { + System.out.println(getUpperDate(new Date())); + + double d = 1000.0000; + + String str = String.valueOf(d); + + if(str.indexOf(".") > 0) { + str = str.replace("0+?$", "");// 删除掉尾数为0的字符 + str = str.replace("[.]$", "");// 结尾如果是小数点,则去掉 + } + System.out.println(str); +// System.out.println(dStr.replace("\\.0*$", "")); + + } +} + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/util/DateUtil.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/util/DateUtil.java new file mode 100644 index 0000000..a50c238 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/util/DateUtil.java @@ -0,0 +1,883 @@ +package abacus.springboot.example.util; + +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.Locale; + +import com.alibaba.fastjson.JSON; + +/** + * Title: 日期时间 Description: 工具类 + * + * @author xuelin chen + * @version 1.0 + */ +public class DateUtil { + + /** 本地化 */ + private static Locale locale = Locale.SIMPLIFIED_CHINESE; + + /** 缺省的DateFormat对象,可以将一个java.util.Date格式化成 yyyy-mm-dd 输出 */ + private static DateFormat dateDF = new SimpleDateFormat("yyyy-MM-dd"); + + /** 缺省的DateFormat对象,可以将一个java.util.Date格式化成 HH:SS:MM 输出 */ + private static DateFormat timeDF = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale); + + /** 缺省的DateFormat对象,可以将一个java.util.Date格式化成 yyyy-mm-dd HH:SS:MM 输出 */ +// private static DateFormat datetimeDF = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, locale); + + private static DateFormat datetimeDF = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + private static DateFormat fdt = new SimpleDateFormat("yyyyMMddHHmmss"); + private static DateFormat fdtsss = new SimpleDateFormat("yyyyMMddHHmmssSSS"); + + public static final String DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss"; + + /** + * 私有构造函数,表示不可实例化 + */ + private DateUtil() { + } + + /** + * 将任意时间生成为当天的第一秒 如:2013-10-23 0:12:12 生成为 2013-10-23 00:00:00 + * @param from 时间对象 + * @return + */ + public static Date getFromDate(Date from) { + if (from == null) { + return null; + } + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTime(new Date(from.getTime())); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + return cal.getTime(); + } + + /** + * 将任意时间生成为当天的最后一秒 如:2013-10-23 0:12:12 生成为 2013-10-23 23:59:59 + * @param thru 时间对象 + * @return + */ + public static Date getThruDate(Date thru) { + if (thru == null) { + return null; + } + + Calendar cal = Calendar.getInstance(); + cal.clear(); + cal.setTime(new Date(thru.getTime())); + cal.set(Calendar.HOUR_OF_DAY, 23); + cal.set(Calendar.MINUTE, 59); + cal.set(Calendar.SECOND, 59); + cal.set(Calendar.MILLISECOND, 998); + return cal.getTime(); + } + + /** + * 时间减去几个小时 + * @param dateStart + * @param num + * @return dateStart-num + */ + public static java.util.Date nowDateMinusHour(java.util.Date dateStart, int num) { + try { + Calendar cal = Calendar.getInstance(); + cal.setTime(dateStart); + cal.add(Calendar.HOUR_OF_DAY, -num); + return cal.getTime(); + } catch (Exception ex) { + return null; + } + } + + /** + * 时间减几分钟 + * @param dateStart + * @param num + * @return + */ + public static java.util.Date nowDateMinusTime(java.util.Date dateStart, int num) { + try { + Calendar cal = Calendar.getInstance(); + cal.setTime(dateStart); + cal.add(Calendar.MINUTE, -num); + return cal.getTime(); + } catch (Exception ex) { + return null; + } + } + + + /** 返回当前日期格式 yyyyMMddHHmmss*/ + public static String getDateFormat(Date date) { + if (date == null) + date = new Date(); + return fdt.format(date); + } + + public static String getDateFormatsss(Date date) { + if (date == null) + date = new Date(); + return fdtsss.format(date); + } + + /** + * 返回一个当前的时间,并按格式转换为字符串 例:17:27:03 + * + * @return String + */ + public static String getTime() { + GregorianCalendar gcNow = new GregorianCalendar(); + java.util.Date dNow = gcNow.getTime(); + return timeDF.format(dNow); + } + + /** + * 返回一个当前日期,并按格式转换为字符串 例:2009-12-12 + * + * @return String + */ + public static String getDate() { + GregorianCalendar gcNow = new GregorianCalendar(); + java.util.Date dNow = gcNow.getTime(); + return dateDF.format(dNow); + } + + /** + * 返回一个当前日期和时间,并按格式转换为字符串 例:2009-12-08 14:27:03 + * + * @return String + */ + public static String getDateTime() { + GregorianCalendar gcNow = new GregorianCalendar(); + java.util.Date dNow = gcNow.getTime(); + return datetimeDF.format(dNow); + } + + /** + * 返回当前年的年号 + * + * @return int + */ + public static int getYear() { + GregorianCalendar gcNow = new GregorianCalendar(); + return gcNow.get(GregorianCalendar.YEAR); + } + + /** + * 返回本月月号:从 0 开始 + * + * @return int + */ + public static int getMonth() { + GregorianCalendar gcNow = new GregorianCalendar(); + return gcNow.get(GregorianCalendar.MONTH); + } + + /** + * 返回今天是本月的第几天 + * + * @return int 从1开始 + */ + public static int getToDayOfMonth() { + GregorianCalendar gcNow = new GregorianCalendar(); + return gcNow.get(GregorianCalendar.DAY_OF_MONTH); + } + + /** + * 返回本月的第一天 + * + */ + + /** + * 返回一格式化的日期 + * + * @param date + * java.util.Date + * @return String yyyy-mm-dd 格式 + */ + public static String formatDate(java.util.Date date) { + return dateDF.format(date); + } + + /** + * 返回一格式化的日期 + * + * @param date + * @return + */ + public static String formatDate(long date) { + return formatDate(new java.util.Date(date)); + } + + /** + * 返回一格式化的时间 + * + * @param date + * Date + * @return String hh:ss:mm 格式 + */ + public static String formatTime(java.util.Date date) { + return timeDF.format(date); + } + + /** + * 返回一格式化的时间 + * + * @param date + * @return + */ + public static String formatTime(long date) { + return formatTime(new java.util.Date(date)); + } + + /** + * 返回一格式化的日期时间 + * + * @param date + * Date + * @return String yyyy-mm-dd hh:ss:mm 格式 + */ + public static String formatDateTime(java.util.Date date) { + return datetimeDF.format(date); + } + + /** + * 返回一格式化的日期时间 + * + * @param date + * @return + */ + public static String formatDateTime(long date) { + return formatDateTime(new java.util.Date(date)); + } + + /** + * 将字串转成日期和时间,字串格式: yyyy-MM-dd HH:mm:ss + * + * @param string + * String + * @return Date + */ + public static java.util.Date toDateTime(String string) { + try { + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return (java.util.Date) formatter.parse(string); + } catch (Exception ex) { + return null; + } + } + + /** + * 将字串转成日期,字串格式: yyyy-MM-dd + * + * @param string + * String + * @return Date + */ + public static java.util.Date toDate(String string) { + try { + DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd"); + return (java.util.Date) formatter.parse(string); + } catch (Exception ex) { + return null; + } + } + + /** + * 将字串转成日期,字串格式: yyyyMMdd 转换成 yyyy-MM-dd + * + * @param string + * String + * @return Date + */ + public static String toDateyymmdd(String string) { + try { + DateFormat formatter = new SimpleDateFormat("yyyyMMdd"); + return dateDF.format((java.util.Date)formatter.parse(string)); + } catch (Exception ex) { + return null; + } + } + + /** + * 取值:某日期的年号 + * + * @param date + * 格式: yyyy-MM-dd + * @return + */ + public static int getYear(String date) { + java.util.Date d = toDate(date); + if (d == null) + return 0; + + Calendar calendar = Calendar.getInstance(locale); + calendar.setTime(d); + return calendar.get(Calendar.YEAR); + } + + /** + * 取值:某日期的月号 + * + * @param date + * 格式: yyyy-MM-dd + * @return 从0开始 + */ + public static int getMonth(String date) { + java.util.Date d = toDate(date); + if (d == null) + return 0; + + Calendar calendar = Calendar.getInstance(locale); + calendar.setTime(d); + return calendar.get(Calendar.MONTH); + } + + /** + * 取值:某日期的日号 + * + * @param date + * 格式: yyyy-MM-dd + * @return 从1开始 + */ + public static int getDayOfMonth(String date) { + java.util.Date d = toDate(date); + if (d == null) + return 0; + + Calendar calendar = Calendar.getInstance(locale); + calendar.setTime(d); + return calendar.get(Calendar.DAY_OF_MONTH); + } + + /** + * 计算两个日期的年数差 + * + * @param one + * 格式: yyyy-MM-dd + * @param two + * 格式: yyyy-MM-dd + * @return + */ + public static int compareYear(String one, String two) { + return getYear(one) - getYear(two); + } + + /** + * 计算岁数 + * + * @param date + * 格式: yyyy-MM-dd + * @return + */ + public static int compareYear(String date) { + return getYear() - getYear(date); + } + + /** + * 使用format格式化Date对象为字符串 + * + * @param date + * date + * @return String + */ + public static String getDateString(Date date) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + return format.format(date); + } + + public static String getyyyyMMdd(Date date) { + SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd"); + return format.format(date); + } + + public static String getHHmmss(Date date) { + SimpleDateFormat format = new SimpleDateFormat("HHmmss"); + return format.format(date); + } + + /** + * 使用format格式化Date对象为字符串,获取年份 + * + * @param date + * date + * @return String + */ + static public String getYear(Date date) { + SimpleDateFormat format = new SimpleDateFormat("yyyy"); + return format.format(date); + } + + /** + * 使用format格式化Date对象为字符串,获取月份 + * + * @param date + * date + * @return String + */ + static public String getMonth(Date date) { + SimpleDateFormat format = new SimpleDateFormat("MM"); + return format.format(date); + } + + /** + * 使用format格式化Date对象为字符串,获取日份 + * + * @param date + * date + * @return String + */ + static public String getDay(Date date) { + SimpleDateFormat format = new SimpleDateFormat("dd"); + return format.format(date); + } + + /** + * 使用format格式化Date对象为字符串,获取中文表示的年月日 + * + * @param date + * date + * @return String 2009年12月08日 + */ + static public String getDateStrC(Date date) { + SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日"); + return format.format(date); + } + + /** + * 使用format格式化Date对象为字符串,获取年份 + * + * @param date + * date + * @return String 20091208 + */ + static public String getDateStrMonth(Date date) { + if (date == null) + return ""; + SimpleDateFormat format = new SimpleDateFormat("yyyyMM"); + String str = format.format(date); + return str; + } + + /** + * 使用format格式化Date对象为字符串,获取年份 + * + * @param date + * date + * @return String 20091208 + */ + static public String getDateStrCompact(Date date) { + if (date == null) + return ""; + SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd"); + String str = format.format(date); + return str; + } + + /** + * 使用format格式化Date对象为字符串,获取年月日和时间 + * + * @param date + * date + * @return String 2009年12月8日 14时03分10秒 + */ + static public String getDateTimeStrC(Date date) { + SimpleDateFormat format = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); + return format.format(date); + } + + /** + * 获取指定日期当前小时起始时间 + */ + static public Date getCurrentHoursFirstSecound(java.util.Date date) { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH"); + String dateStr = format.format(date); + return toDateTime(dateStr + ":00:00"); + + } + + /** + * 获取指定日期当前下一个小时时间 + */ + static public Date getCurrentNextHours(java.util.Date date) { + Calendar scalendar = new GregorianCalendar(); + scalendar.setTime(date); + scalendar.add(Calendar.HOUR, 1); + return new Date(scalendar.getTime().getTime()); + } + + /** + * 获取指定日期后下一个月的第一天 + * + * @param java.sql.Date + * date + * @return java.sql.Date + */ + static public java.sql.Date getNextMonthFirstDate(java.util.Date date) throws ParseException { + Calendar scalendar = new GregorianCalendar(); + scalendar.setTime(date); + scalendar.add(Calendar.MONTH, 1); + scalendar.set(Calendar.DATE, 1); + return new java.sql.Date(scalendar.getTime().getTime()); + } + + static public java.sql.Date getNextMonthDate(java.util.Date date) { + Calendar scalendar = new GregorianCalendar(); + scalendar.setTime(date); + scalendar.add(Calendar.MONTH, 1); + return new java.sql.Date(scalendar.getTime().getTime()); + } + + /** 上一个月 */ + public static Date getLastMonthFirstDate(Date date, int month) { + if (date == null) + return date; + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + calendar.add(Calendar.MONTH, month); + date = calendar.getTime(); + return date; + } + + /** + * 获取指定日期的前面几天 + * + * @param java.sql.Date + * date + * @param dayCount + * 表示前几天 + * @return java.sql.Date + */ + static public java.sql.Date getFrontDateByDayCount(java.sql.Date date, int dayCount) throws ParseException { + Calendar scalendar = new GregorianCalendar(); + scalendar.setTime(date); + scalendar.add(Calendar.DATE, -dayCount); + return new java.sql.Date(scalendar.getTime().getTime()); + } + + /** + * 取得指定年份和月份的第一天 + * + * @param year + * 年 + * @param month + * 月 + * @return Date + */ + static public Date getFirstDay(String year, String month) throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + return format.parse(year + "-" + month + "-1"); + } + + /** + * 取得指定年份和月份的第一天 + * + * @param year + * 年 + * @param month + * 月 + * @return Date + */ + static public Date getFirstDay(int year, int month) throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + return format.parse(year + "-" + month + "-1"); + } + + /** + * 取得指定年份和月份的最后一天 + * + * @param year + * 年 + * @param month + * 月 + * @return Date + */ + static public Date getLastDay(String year, String month) throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Date date = format.parse(year + "-" + month + "-1"); + + Calendar scalendar = new GregorianCalendar(); + scalendar.setTime(date); + scalendar.add(Calendar.MONTH, 1); + scalendar.add(Calendar.DATE, -1); + date = scalendar.getTime(); + return date; + } + + /** + * 取得指定年份和月份的最后一天 + * + * @param year + * 年 + * @param month + * 月 + * @return Date + */ + static public Date getLastDay(int year, int month) throws ParseException { + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + Date date = format.parse(year + "-" + month + "-1"); + + Calendar scalendar = new GregorianCalendar(); + scalendar.setTime(date); + scalendar.add(Calendar.MONTH, 1); + scalendar.add(Calendar.DATE, -1); + date = scalendar.getTime(); + return date; + } + + /** + * 取得指定年份之间的相隔月数 + * + * @param year + * 年 + * @param month + * 月 + * @return Date + */ + static public long getDistinceMonth(String beforedate, String afterdate) throws ParseException { + SimpleDateFormat d = new SimpleDateFormat("yyyy-MM-dd"); + long monthCount = 0; + try { + java.util.Date before = d.parse(beforedate); + java.util.Date after = d.parse(afterdate); + + monthCount = (Integer.parseInt(DateUtil.getYear(after)) - Integer.parseInt(DateUtil.getYear(before))) * 12 + + DateUtil.getMonth(afterdate) - DateUtil.getMonth(beforedate); + + } catch (ParseException e) { + System.out.println("Date parse error!"); + } + return monthCount; + } + + /** + * 取得指定年份之间的相隔天数 + * + * @param year + * 年 + * @param month + * 月 + * @return Date + */ + static public long getDistinceDay(String beforedate, String afterdate) throws ParseException { + SimpleDateFormat d = new SimpleDateFormat("yyyy-MM-dd"); + long dayCount = 0; + try { + java.util.Date d1 = d.parse(beforedate); + java.util.Date d2 = d.parse(afterdate); + + dayCount = (d2.getTime() - d1.getTime()) / (24 * 60 * 60 * 1000); + + } catch (ParseException e) { + System.out.println("Date parse error!"); + // throw e; + } + return dayCount; + } + + /** + * 指定日期加一天 + * + * @param date + * @param day + * @return + */ + static public Date getDaytoDay(Date date, int day) { + if (date == null) + return date; + + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + calendar.add(Calendar.DATE, day); + date = calendar.getTime(); + return date; + } + + static public Date getMonthtoMonth(Date date, int day) { + if (date == null) + return date; + + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + calendar.add(Calendar.MONTH, day); + date = calendar.getTime(); + return date; + } + + // 获取上一年或者下一年 + static public Date getYeartoYaer(Date date, int year) { + if (date == null) + return date; + + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + calendar.add(Calendar.YEAR, year); + date = calendar.getTime(); + return date; + } + + // 指定日期的最开始时间 + public static Date getDateStartTime(Date date) { + if (date == null) + return null; + try { + String strDate = formatDate(date); + return toDateTime(strDate + " 00:00:00"); + } catch (Exception localException) { + } + return null; + } + + static public Date getDateLastTime(Date date) { + if (date == null) + return null; + try { + String strDate = formatDate(date); + return toDateTime(strDate + " 23:59:59"); + } catch (Exception localException) { + } + return null; + } + + // 单位秒 + static public long getDistinceFen(String beforedate, String afterdate) throws ParseException { + SimpleDateFormat d = new SimpleDateFormat(DATE_TIME_FORMAT); + long dayCount = 0; + try { + java.util.Date d1 = d.parse(beforedate); + java.util.Date d2 = d.parse(afterdate); + + dayCount = (d2.getTime() - d1.getTime()) / (1000); + + } catch (ParseException e) { + System.out.println("Date parse error!"); + // throw e; + } + return dayCount; + } + + static public Date getMINUTE(Date date, int day) { + if (date == null) + return date; + + Calendar calendar = new GregorianCalendar(); + calendar.setTime(date); + calendar.add(Calendar.MINUTE, day); + date = calendar.getTime(); + return date; + } + + static public String CalTimeDifference(String fromTime, int overTime) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + Date date = null; + try { + date = dateFormat.parse(fromTime); + } catch (ParseException e) { + e.printStackTrace(); + } + Calendar calendar = Calendar.getInstance(); + calendar.setTime(date); + calendar.add(Calendar.HOUR, overTime);//这里是分钟,如果需要,可以更换为day,moth + Date date1 = calendar.getTime(); + + Timestamp overQTimeKey = new Timestamp(calendar.getTime().getTime()); + SimpleDateFormat overQTimeDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return overQTimeDateFormat.format(overQTimeKey); + } + + /** + * 10位时间戳 + * @return + */ + static public String tenBitTime() { + return String.valueOf(Calendar.getInstance().getTimeInMillis()/1000); + } + + + /** + * 使用format格式化Date对象为字符串 + * + * @param date + * date + * @return String + */ + public static String getDatetoUpperCaseString() { + // 获取当前日期 + Calendar calendar = Calendar.getInstance(); + + // 转换成大写 + String year = toUpperCase(String.valueOf(calendar.get(Calendar.YEAR))); + String month = toUpperCase(String.valueOf(calendar.get(Calendar.MONTH) + 1)); + String day = toUpperCase(String.valueOf(calendar.get(Calendar.DAY_OF_MONTH))); + + // 组合成大写格式 + String dateInChinese = year + "年" + month + "月" + day + "日"; + return dateInChinese; + } + + // 将数字字符串转换成大写 + private static String toUpperCase(String str) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < str.length(); i++) { + char c = str.charAt(i); + switch (c) { + case '0': sb.append('零'); break; + case '1': sb.append('一'); break; + case '2': sb.append('二'); break; + case '3': sb.append('三'); break; + case '4': sb.append('四'); break; + case '5': sb.append('五'); break; + case '6': sb.append('六'); break; + case '7': sb.append('七'); break; + case '8': sb.append('八'); break; + case '9': sb.append('九'); break; + default: sb.append(c); + } + } + return sb.toString(); + } + + public static void main(String[] args) throws ParseException { + // System.out.println(getDateStrC(getDaytoDay(new Date(),-7))); + // System.out.println(getDateFormat(null)); + // getDistinceFen + +// SimpleDateFormat format = new SimpleDateFormat("yyMMddHHmmss"); + + String code = ""; + + String[] codearray = code.split("/"); + System.out.println(JSON.toJSONString(codearray)); + System.out.println(codearray[codearray.length - 1]); + + System.out.println(getDatetoUpperCaseString()); + + +// System.out.println(formatDateTime(nowDateMinusTime(toDateTime("2023-19-27 00:00:00"), -10))); +// System.out.println(new Date().getTime()); +// System.out.println(1614849936503L - new Date().getTime()); +// DateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss"); + // 第一个当前日期 第二个证照有效的日期 +// Long s = DateUtil.getDistinceDay(DateUtil.getDate(), DateUtil.toDates("20190228")); +// System.out.println(s); +// System.out.println(DateUtil.toDateyymmdd("20180817")); + // TODO Auto-generated catch block + + /* + * try { System.out.println(getDateFormat(null)); } catch + * (ParseException e) { // TODO Auto-generated catch block + * e.printStackTrace(); } + */ + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/util/JsonStringRemoveRepetUtil.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/util/JsonStringRemoveRepetUtil.java new file mode 100644 index 0000000..9186550 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/util/JsonStringRemoveRepetUtil.java @@ -0,0 +1,94 @@ +package abacus.springboot.example.util; + +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang.StringUtils; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; + +/** + *

Title:JsonStringRemoveRepetUtil

+

Description:json字符串-对比

+ @author chuanZeng + @date 2026年8月18日 + */ +public class JsonStringRemoveRepetUtil { + + public String[] removeRepet(String oldStr,String newStr){ + if(StringUtils.isEmpty(oldStr)||StringUtils.isEmpty(newStr)) return new String[]{oldStr,newStr}; + try{ + JSONObject oldjo=JSONObject.parseObject(oldStr); + JSONObject newjo=JSONObject.parseObject(newStr); + if(oldjo==null||newjo==null) return new String[]{oldStr,newStr}; + List rkeys=new ArrayList(); + List akeys=new ArrayList(); + for(String key:oldjo.keySet()){ + if(oldjo.getString(key)==null&&newjo.getString(key)==null){ + rkeys.add(key); + }else if(oldjo.getString(key)==null&&newjo.getString(key)!=null||oldjo.getString(key)!=null&&newjo.getString(key)==null){ + + }else if(oldjo.getString(key).startsWith("{")){//对象 + if(oldjo.getJSONObject(key).getString("id").equals(newjo.getJSONObject(key).getString("id"))){ + rkeys.add(key); + } + }else if(oldjo.getString(key).startsWith("[")){//数组 + if(oldjo.getString(key).equals(newjo.getString(key))) + rkeys.add(key); + else + akeys.add(key); + }else if(oldjo.getString(key).equals(newjo.getString(key))){ + rkeys.add(key); + } + } + if(!rkeys.isEmpty()){ + for(String key:rkeys){ + oldjo.remove(key); + newjo.remove(key); + } + } + if(!akeys.isEmpty()){ + for(String key:akeys){ + JSONArray oldja= oldjo.getJSONArray(key); + JSONArray newja= newjo.getJSONArray(key); + if(oldja.isEmpty()||newja.isEmpty()) continue; + List oldli=new ArrayList(); + for(Object obj:oldja){ + JSONObject jo=(JSONObject) obj; + oldli.add(jo.toJSONString()); + } + List newli=new ArrayList(); + for(Object obj:newja){ + JSONObject jo=(JSONObject) obj; + newli.add(jo.toJSONString()); + } + oldli.retainAll(newli); + if(!oldli.isEmpty()){ + String olds=oldjo.getString(key); + String news=newjo.getString(key); + for(String str:oldli){ + olds=olds.replace(str, "").replace(",,", ","); + news=news.replace(str, "").replace(",,", ","); + } + olds=olds.replace("[,", "[").replace(",]", "]"); + news=news.replace("[,", "[").replace(",]", "]"); + if(olds.equals("[]")) + oldjo.remove(key); + else + oldjo.put(key, olds); + if(news.equals("[]")) + newjo.remove(key); + else + newjo.put(key, news); + } + } + } + oldStr=oldjo.toJSONString(); + newStr=newjo.toJSONString(); + }catch(Exception e){ + e.printStackTrace(); + } + return new String[]{oldStr,newStr}; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/util/MySSLProtocolSocketFactory.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/util/MySSLProtocolSocketFactory.java new file mode 100644 index 0000000..8e0b3df --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/util/MySSLProtocolSocketFactory.java @@ -0,0 +1,112 @@ +package abacus.springboot.example.util; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.Socket; +import java.net.SocketAddress; +import java.net.UnknownHostException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.security.cert.CertificateException; +import java.security.cert.X509Certificate; + +import javax.net.SocketFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManager; +import javax.net.ssl.X509TrustManager; + +import org.apache.commons.httpclient.ConnectTimeoutException; +import org.apache.commons.httpclient.params.HttpConnectionParams; +import org.apache.commons.httpclient.protocol.ProtocolSocketFactory; + + + +/** + * 调过证书 + * + * created at 2010-7-26 上午09:29:33 + */ +public class MySSLProtocolSocketFactory implements ProtocolSocketFactory { + + private SSLContext sslcontext = null; + + private SSLContext createSSLContext() { + SSLContext sslcontext=null; + try { + sslcontext = SSLContext.getInstance("SSL"); + sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom()); + } catch (NoSuchAlgorithmException e) { + e.printStackTrace(); + } catch (KeyManagementException e) { + e.printStackTrace(); + } + return sslcontext; + } + + private SSLContext getSSLContext() { + if (this.sslcontext == null) { + this.sslcontext = createSSLContext(); + } + return this.sslcontext; + } + + public Socket createSocket(Socket socket, String host, int port, boolean autoClose) + throws IOException, UnknownHostException { + return getSSLContext().getSocketFactory().createSocket( + socket, + host, + port, + autoClose + ); + } + + public Socket createSocket(String host, int port) throws IOException, + UnknownHostException { + return getSSLContext().getSocketFactory().createSocket( + host, + port + ); + } + + + public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort) + throws IOException, UnknownHostException { + return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort); + } + + public Socket createSocket(String host, int port, InetAddress localAddress, + int localPort, HttpConnectionParams params) throws IOException, + UnknownHostException, ConnectTimeoutException { + if (params == null) { + throw new IllegalArgumentException("Parameters may not be null"); + } + int timeout = params.getConnectionTimeout(); + SocketFactory socketfactory = getSSLContext().getSocketFactory(); + if (timeout == 0) { + return socketfactory.createSocket(host, port, localAddress, localPort); + } else { + Socket socket = socketfactory.createSocket(); + SocketAddress localaddr = new InetSocketAddress(localAddress, localPort); + SocketAddress remoteaddr = new InetSocketAddress(host, port); + socket.bind(localaddr); + socket.connect(remoteaddr, timeout); + return socket; + } + } + + //自定义私有类 + private static class TrustAnyTrustManager implements X509TrustManager { + + public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { + } + + public X509Certificate[] getAcceptedIssuers() { + return new X509Certificate[]{}; + } + } + + +} \ No newline at end of file diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/util/RequestUtil.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/util/RequestUtil.java new file mode 100644 index 0000000..dc6da21 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/util/RequestUtil.java @@ -0,0 +1,295 @@ +package abacus.springboot.example.util; + +import java.io.IOException; +import java.util.Map; + +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.httpclient.NameValuePair; +import org.apache.commons.httpclient.SimpleHttpConnectionManager; +import org.apache.commons.httpclient.methods.GetMethod; +import org.apache.commons.httpclient.methods.PostMethod; +import org.apache.commons.httpclient.methods.StringRequestEntity; +import org.apache.commons.httpclient.params.HttpClientParams; +import org.apache.commons.httpclient.params.HttpMethodParams; +import org.apache.commons.httpclient.protocol.Protocol; + +import com.abacus.xpos.foundation.pubs.WebserviceException; +import com.alibaba.fastjson.JSONObject; + +/** + *

Title:RequestUtil

+

Description: http-工具

+ @author chuanZeng + @date 2026年8月18日 + */ +public class RequestUtil { + private static final int connectTimeout = 5000; // 连接超时时间 + private static final int connectionRequestTimeout = 5000; // 请求超时时间 + private static final int socketTimeout = 5000; // 套接字连接超时(读取超时时间) + + public static final String charset = "utf-8"; // 编码方式 + + /** + * post Json提交 + * @param url + * @param jsonStr + * @return + * @throws WebserviceException + */ + public static String send(String url ,String jsonStr, String id) throws WebserviceException{ + + HttpClientParams params = new HttpClientParams(); + params.setContentCharset("UTF-8"); + + HttpClient hc = new HttpClient(params,new SimpleHttpConnectionManager(true)); + hc.getHttpConnectionManager().getParams().setConnectionTimeout(5000); + hc.getHttpConnectionManager().getParams().setSoTimeout(5000); + PostMethod hm = new PostMethod(url); + hm.setRequestHeader("Content-Type", "application/json; charset=UTF-8"); + try { + System.out.println(DateUtil.getDateTime()+"-"+ id + "-url:"+url); + hm.setRequestEntity(new StringRequestEntity(jsonStr, "application/json", "utf-8")); + System.out.println(DateUtil.getDateTime()+"-"+ id + "-send报文:" + jsonStr.toString()); + int status = hc.executeMethod(hm); + if(status == HttpStatus.SC_OK) { + String temp = hm.getResponseBodyAsString(); + System.out.println(DateUtil.getDateTime()+"-"+ id + "-resp data:"+temp); + return temp ; + }else{ + throw new WebserviceException("请求出错!"); + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println(e.getMessage()); + throw new WebserviceException(e.getMessage()); + }finally { + hm.releaseConnection(); + } + } + + /** + * POST 键值对提交 + * @param url + * @param paramsMap + * @return + * @throws WebserviceException + */ + public static String sendParams(String url ,Map paramsMap, String id) throws WebserviceException{ + + HttpClientParams params = new HttpClientParams(); + params.setContentCharset("UTF-8"); + + HttpClient hc = new HttpClient(params,new SimpleHttpConnectionManager(true)); + hc.getHttpConnectionManager().getParams().setConnectionTimeout(10000); + hc.getHttpConnectionManager().getParams().setSoTimeout(10000); + PostMethod hm = new PostMethod(url); +// GetMethod gm = new GetMethod(url); + hm.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); + + Protocol myhttps = new Protocol("https", new MySSLProtocolSocketFactory(), 443); + Protocol.registerProtocol("https", myhttps); + + try { + for(String key : paramsMap.keySet()){ + hm.addParameter(key, paramsMap.get(key).toString()); + } + System.out.println(DateUtil.getDateTime()+">>>" + id + ">>>url>>>" + url + + ">>>sendParams报文>>>" + paramsMap.toString()); + int status = hc.executeMethod(hm); + if(status == HttpStatus.SC_OK) { + String temp = hm.getResponseBodyAsString(); + System.out.println(DateUtil.getDateTime()+">>>" + id + ">>>resp data>>>"+ JSONObject.parseObject(temp)); + return temp ; + }else{ + throw new WebserviceException("请求出错!"+status); + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println(e.getMessage()); + throw new WebserviceException(e.getMessage()); + }finally { + hm.releaseConnection(); + } + } + + public static String sendGet(String url) throws WebserviceException{ + + HttpClientParams params = new HttpClientParams(); + params.setContentCharset("UTF-8"); + + HttpClient hc = new HttpClient(params,new SimpleHttpConnectionManager(true)); + hc.getHttpConnectionManager().getParams().setConnectionTimeout(5000); + hc.getHttpConnectionManager().getParams().setSoTimeout(5000); + GetMethod getMethod = new GetMethod(url); + getMethod.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8"); + try { + System.out.println("url:"+url); + + int status = hc.executeMethod(getMethod); + + if(status == HttpStatus.SC_OK) { + String temp = getMethod.getResponseBodyAsString(); + System.out.println("resp data:"+temp); + return temp ; + }else{ + throw new WebserviceException("请求出错!"); + } + } catch (Exception e) { + e.printStackTrace(); + System.out.println(e.getMessage()); + throw new WebserviceException(e.getMessage()); + }finally { + getMethod.releaseConnection(); + } + } + + public static String postHttp(String urls, NameValuePair[] nvp) throws Exception { + try { + String result = ""; + // 定义http客户端对象--httpClient + HttpClient httpClient = new HttpClient(); + // 定义并实例化客户端链接对象-postMethod + PostMethod postMethod = new PostMethod(urls); + httpClient.setConnectionTimeout(5000); + + try { + + postMethod.setRequestHeader("application/json", "UTF-8"); + + postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8"); + + // 将表单的值放入postMethod中 + postMethod.addParameters(nvp); + // 定义访问地址的链接状态 + int statusCode = 0; + try { + // 客户端请求url数据 + statusCode = httpClient.executeMethod(postMethod); + } catch (Exception e) { + e.printStackTrace(); + } + // 请求成功状态-200 + if (statusCode == HttpStatus.SC_OK) { + try { + result = postMethod.getResponseBodyAsString(); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + + } + + } catch (Exception e) { + + } finally { + // 释放链接 + postMethod.releaseConnection(); + httpClient.getHttpConnectionManager().closeIdleConnections(0); + } + return result; + } catch (Exception e) { + throw new Exception(e.getMessage()); + } + } + + public static String getHttp(String urls, NameValuePair[] nvp) throws Exception { + try { + String result = ""; + // 定义http客户端对象--httpClient + HttpClient httpClient = new HttpClient(); + + // 定义并实例化客户端链接对象-postMethod + GetMethod getMethod = new GetMethod(urls); + + try { + // 设置http的头 + + // (1)、这里可以设置自己想要的编码格式 + getMethod.getParams().setContentCharset("utf-8"); + + // (2)、对于get方法也可以这样设置 + getMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8"); + + // (3)、还可以如下这样设置 + getMethod.addRequestHeader("Content-Type", "text/html; charset=UTF-8"); + + getMethod.setQueryString(nvp); + + // 定义访问地址的链接状态 + int statusCode = 0; + try { + // 客户端请求url数据 + statusCode = httpClient.executeMethod(getMethod); + } catch (Exception e) { + e.printStackTrace(); + } + // 请求成功状态-200 + if (statusCode == HttpStatus.SC_OK) { + try { + result = getMethod.getResponseBodyAsString(); + } catch (IOException e) { + e.printStackTrace(); + } + } else { + + } + } catch (Exception e) { + + } finally { + // 释放链接 + getMethod.releaseConnection(); + httpClient.getHttpConnectionManager().closeIdleConnections(0); + } + return result; + } catch (Exception e) { + throw new Exception(e.getMessage()); + } + } + + public static void main(String[] args) { + // 验证设备唯一码,验证设备分配账户号 +// Map paramsMap = new HashMap(); +// paramsMap.put("error_code","1"); +// paramsMap.put("msg","TRUE1"); +// paramsMap.put("data","{\"Result\":{\"ResponseStatus\":{\"ErrorCode\":500,\"IsSuccess\":false,\"Errors\":[{\"FieldName\":null,\"Message\":\"插件取消了保存操作,可能因为数据不合法。\",\"DIndex\":0}],\"SuccessEntitys\":[],\"SuccessMessages\":[],\"MsgCode\":0},\"Id\":\"\",\"NeedReturnData\":[{}]}}"); +// +// List> mapl = new ArrayList>(); +// mapl.add(paramsMap); +// +// String str = JSONObject.toJSONString(mapl); +// System.out.println(str); +// +//// JSONObject jsonObject = JSONObject.parseObject(str); +// JSONArray jsonObject = JSONArray.parseArray(str); +// +// System.out.println(jsonObject.getJSONObject(0).getString("data")); +// +// JSONObject jsonObjects = JSONObject.parseObject(jsonObject.getJSONObject(0).getString("data")).getJSONObject("Result").getJSONObject("ResponseStatus"); +// +// String message = jsonObjects.getInteger("ErrorCode") + ":" + jsonObjects.getJSONArray("Errors").getJSONObject(0).getString("Message"); +// String FieldName = jsonObjects.getInteger("ErrorCode") + ":" + jsonObjects.getJSONArray("Errors").getJSONObject(0).getString("FieldName"); +// +// System.out.println(message); +// System.out.println(FieldName); + +// String context = "{\"type\":1,\"batchNub\":\"\",\"qctype\":2,\"prodNumber\":\"10401000006\",\"qrcode\":[\"https%3a%2f%2fbetascan.vats.com.cn%2fscan%2f3%2f001f3618fd5d4d1d84125c04d5c2ebe6\",\"https://betascan.vats.com.cn/scan/3/002f3618fd5d4d1d84125c04d5c2ebe6\",\"https://betascan.vats.com.cn/scan/3/003f3618fd5d4d1d84125c04d5c2ebe6\"],\"operateUser\":\"47\",\"companyCode\":\"25\"}"; +// try { +//// String map1 = new RequestUtil().send("https://apistest.vatsliquor.com/hzztlgs/addProductQrcode?token=aHp6dC0xNTY2Mjc4OTcwMTE5LXZhdHM_", context); +// +//// System.out.println(map1); +// } catch (WebserviceException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// + + + +// if("1".equals(jsonObject.get("error_code")) || "TRUE".equals(jsonObject.get("msg"))) { +// System.out.println(jsonObject.get("data")); +// } + + } + +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/vo/BaiduToken.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/vo/BaiduToken.java new file mode 100644 index 0000000..bd89260 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/vo/BaiduToken.java @@ -0,0 +1,48 @@ +package abacus.springboot.example.vo; + +import java.util.Date; + +/** + *

Title:BaiduToken

+

Description: BaiduToken-临时对象

+ @author chuanZeng + @date 2026年8月18日 + */ +public class BaiduToken { + + private long id; + private int version; + private String token; + private String expirydate; + private Date dt; + public long getId() { + return id; + } + public void setId(long id) { + this.id = id; + } + public int getVersion() { + return version; + } + public void setVersion(int version) { + this.version = version; + } + public String getToken() { + return token; + } + public void setToken(String token) { + this.token = token; + } + public String getExpirydate() { + return expirydate; + } + public void setExpirydate(String expirydate) { + this.expirydate = expirydate; + } + public Date getDt() { + return dt; + } + public void setDt(Date dt) { + this.dt = dt; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/vo/PMSConfigKey.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/vo/PMSConfigKey.java new file mode 100644 index 0000000..9501ea9 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/vo/PMSConfigKey.java @@ -0,0 +1,39 @@ +package abacus.springboot.example.vo; + +/** + *

Title:PMSConfigKey

+

Description:配置-key-全局设定

+ @author chuanZeng + @date 2026年8月18日 + */ +public interface PMSConfigKey { + + /** keyGroup:系统号*/ + public static final String KEY_GROUP = "pms"; + + /** set:WMS接口对接参数配置*/ + public static final String PMS_WMSCONF = "pms.wmsconf"; + /** pms.wmsconf:访问地址*/ + public static final String PMS_WMSCONF_URL = "url"; + /** pms.wmsconf:appkey*/ + public static final String PMS_WMSCONF_APPKEY = "appkey"; + /** pms.wmsconf:sessionKey*/ + public static final String PMS_WMSCONF_SESSIONKEY = "sessionKey"; + /** pms.wmsconf:goodsOwner*/ + public static final String PMS_WMSCONF_GOODSOWNER = "goodsOwner"; + + public static final String PMS_WMSCONF_SHOPCODE = "shopCode"; + public static final String PMS_WMSCONF_SHOPNAME = "shopName"; +} + + + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/vo/SiDepositlocation.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/vo/SiDepositlocation.java new file mode 100644 index 0000000..1fd65e3 --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/vo/SiDepositlocation.java @@ -0,0 +1,28 @@ +package abacus.springboot.example.vo; + +/** + *

Title:SiDepositlocation

+

Description: JDBC-数据返回-临时存储对象

+ @author chuanZeng + @date 2026年8月18日 + */ +public class SiDepositlocation { + + // 仓库编码 + private String id; + // 是否推送WMS:1-WMS,0-WDT + private int push; + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + public int getPush() { + return push; + } + public void setPush(int push) { + this.push = push; + } +} diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/wsi/ApiJcBillServiceIF.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/wsi/ApiJcBillServiceIF.java new file mode 100644 index 0000000..a3bdc8b --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/wsi/ApiJcBillServiceIF.java @@ -0,0 +1,357 @@ +package abacus.springboot.example.wsi; + +import java.util.List; +import java.util.Map; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import abacus.springboot.example.api.view.ApiBillHg; +import abacus.springboot.example.api.view.ApiBillHgItem; +import abacus.springboot.example.api.view.ApiBillHgPayment; +import abacus.springboot.example.api.view.ApiJcBill; +import abacus.springboot.example.api.view.ApiJcBillHgSearchItem; +import abacus.springboot.example.api.view.ApiJcBillItem; +import abacus.springboot.example.api.view.ApiJcBillSearch; +import abacus.springboot.example.api.view.ApiReqJcBill; +import abacus.springboot.example.api.view.JcBillCount; +import abacus.springboot.example.api.view.JcCodeFlow; +import abacus.springboot.example.api.view.JcProduct; +import abacus.springboot.example.api.view.JcProductBillSouce; +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillHg; +import abacus.springboot.example.dao.JcBillHgPay; +import abacus.springboot.example.dao.JcBillInItem; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.dao.JcSourceItem; + +/** + *

Title:ApiJcBillServiceIF

+

Description: 对外接口service服务

+ @author chuanZeng + @date 2026年8月18日 + */ +public interface ApiJcBillServiceIF { + + /** + * 稽查收货查询 + * @param keyword + * @param status + * @param pageable + * @return + * @throws RuntimeException + */ + public Page queryApiJcBillSearch(String keyword, String employee, String status, Pageable pageable) throws RuntimeException; + + + /** + * 稽查收货主单查询 + * @param id + * @return + * @throws RuntimeException + */ + public ApiJcBill queryApiJcBillById(String id) throws RuntimeException; + + /** + * 稽查收货明细 + * @param billId + * @return + * @throws RuntimeException + */ + public List queryApiJcBillItemByBIllId(String billId) throws RuntimeException; + + /** + * 根据条件查询图片 + * @param srcid + * @param srcitemid + * @param typephoto + * @return + * @throws RuntimeException + */ + public Map> queryJcBillPhoto(String srcid) throws RuntimeException; + + /** + * 根据条件查询图片 + * @param srcid + * @param srcitemid + * @param typephoto + * @return + * @throws RuntimeException + */ + public Map> queryJcBillPhotoIn(List srcids) throws RuntimeException; + + /** + * 保存 + * @param reqJcBill + * @param jcBill + * @param createItems + * @return + * @throws RuntimeException + */ + public ApiReqJcBill saveApiReqJcBill(ApiReqJcBill reqJcBill, JcBill jcBill, List createItems) throws RuntimeException; + + /** + * 修改 + * @param reqJcBill + * @param jcBill + * @param createItems + * @param updateItems + * @return + * @throws RuntimeException + */ + public ApiReqJcBill updateApiReqJcBill(ApiReqJcBill reqJcBill, JcBill jcBill, List createItems, List updateItems) throws RuntimeException; + + /** + * 当前明细行号 + * @param billId + * @return + * @throws RuntimeException + */ + public int countJcBillItemIndexno(String billId) throws RuntimeException; + + /** + * 查询 + * @param billId + * @return + * @throws RuntimeException + */ + public JcBill queryJcBillById(String billId) throws RuntimeException; + + /** + * 查询 + * @param billId + * @return + * @throws RuntimeException + */ + public List queryJcBillSourceItemByBillId(String billId) throws RuntimeException; + + /** + * 查询 + * @param id + * @return + * @throws RuntimeException + */ + public JcBillSourceItem queryJcBillSourceItembyId(Long id) throws RuntimeException; + + /** + * 查询o + * @param id + * @return + * @throws RuntimeException + */ + public JcBillInItem queryJcBillInItemById(Long id) throws RuntimeException; + + /** + * 修改状态:待提交>>>待溯源 + * @param jcBill + * @throws RuntimeException + */ + public void updateStatusJcBill(JcBill jcBill, int oldStatus) throws RuntimeException; + + + /** + * 回购列表查询 + * @param keyword + * @param status + * @param pageable + * @return + * @throws RuntimeException + */ + public Page queryApiJcBillHgSearchItem(String keyword, String employee, String status, Pageable pageable) throws RuntimeException; + + + /** + * 回购;查询品种和件数汇总 + * @param ids + * @return + * @throws RuntimeException + */ + public Map queryJcBillCount(List ids) throws RuntimeException; + + /** + * 回购:主单查询 + * @param id + * @return + * @throws RuntimeException + */ + public ApiBillHg queryApiBillHgById(String hgId) throws RuntimeException; + + /** + * 回购:明细查询 + * @param billId + * @return + * @throws RuntimeException + */ + public List queryApiBillHgItemByHgId(String hgId) throws RuntimeException; + + /** + * 回购:支付明细查询 + * @param billId + * @return + * @throws RuntimeException + */ + public List queryApiBillHgPaymentByHgId(String hgId) throws RuntimeException; + + public List queryApiBillHgPaymentByHgId(List hgIds) throws RuntimeException; + + /** + * 查询 + * @param billHg + * @return + * @throws RuntimeException + */ + public JcBillHg queryJcBillHg(String billHg) throws RuntimeException; + + /** + * 修改 + * @param bill + * @throws RuntimeException + */ + public void updateJcBillHg(JcBillHg entity, List pays) throws RuntimeException; + + /** + * 查询图片 + * @param srcid + * @param srcitemid + * @param typephoto + * @return + * @throws RuntimeException + */ + public JcBillPhoto queryJcBillPhoto(String srcid, String srcitemid, String typephoto) throws RuntimeException; + + /** + * 查询图片 + * @param srcid + * @param srcitemid + * @param typephoto + * @return + * @throws RuntimeException + */ + public List queryJcBillPhoto(String srcid, String typephoto) throws RuntimeException; + + /** + * 删除或保存图片 + * @param photos + * @param billHg + * @throws RuntimeException + */ + public void saveAndDeletePhoto(List photos, JcBillHg billHg) throws RuntimeException; + + /** + * 删除或保存图片 + * @param photos + * @param billHg + * @throws RuntimeException + */ + public void saveAndDeletePhoto(List photos, String billId) throws RuntimeException; + + /** + * 查询:下一单待提交的回购单号 + * @return + * @throws RuntimeException + */ + public String lastBillHgId() throws RuntimeException; + + /** + * 根据物流码,查询出库相关信息 + * @param code + * @return + * @throws RuntimeException + */ + public List queryJcCodeFlow(List codes) throws RuntimeException; + + /** + * 查询朔源明细 + * @param billId + * @return + */ + public List queryJcSourceItemByBillId(String billId) throws RuntimeException; + + /** + * 更新收货明细,以及保存溯源明细 + * @param items + * @param sourceItems + * @throws RuntimeException + */ + public void saveJcSourceItem(List items, List sourceItems, JcBill jcBill) throws RuntimeException; + + /** + * 查询图片 + * @param srcid + * @param srcitemid + * @param typephoto + * @return + * @throws RuntimeException + */ + public JcBillPhoto queryJcBillPhotoById(String id) throws RuntimeException; + + /** + * 删除图片 + * @param entity + * @throws RuntimeException + */ + public void deleteJcBillPhotoById(JcBillPhoto entity) throws RuntimeException; + + /** + * 删除订单详情以及对应的图片 + * @param billid + * @param itemid + * @throws RuntimeException + */ + public void deleteJcSourceItem(String billid, String itemid) throws RuntimeException; + + /** + * 获取百度token + * @return + * @throws RuntimeException + */ + public String getBaiduToken() throws RuntimeException; + + /** + * 稽查货品查询-单号查询 + * @param product + * @param stockInId + * @param hgId + * @return + * @throws RuntimeException + */ + public List queryJcProduct(String product, String stockInId, String hgId) throws RuntimeException; + + /** + * 稽查货品查询-单号查询 + * @param product + * @param stockInId + * @param hgId + * @return + * @throws RuntimeException + */ + public List queryJcProduct(String product, String stockInId) throws RuntimeException; + + /** + * 根据稽查单号,查询对应的货品编号 + * @param billIds + * @return + * @throws RuntimeException + */ + public Map> queryJcProductBillSouce(List billIds)throws RuntimeException; + + /** + * 修改状态 + * @param jcBill + * @throws RuntimeException + */ + public void updateStatusByJcBill(JcBill jcBill, int status) throws RuntimeException; + + public List qeryJcBillHgs(List billids) throws RuntimeException; +} + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/java/abacus/springboot/example/wsi/JcBillServiceIF.java b/abacus.springboot.example/src/main/java/abacus/springboot/example/wsi/JcBillServiceIF.java new file mode 100644 index 0000000..6d1960a --- /dev/null +++ b/abacus.springboot.example/src/main/java/abacus/springboot/example/wsi/JcBillServiceIF.java @@ -0,0 +1,341 @@ +package abacus.springboot.example.wsi; + +import java.util.List; +import java.util.Map; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import com.alibaba.fastjson.JSONObject; + +import abacus.springboot.example.dao.JcBill; +import abacus.springboot.example.dao.JcBillHg; +import abacus.springboot.example.dao.JcBillInItem; +import abacus.springboot.example.dao.JcBillPhoto; +import abacus.springboot.example.dao.JcBillSourceItem; +import abacus.springboot.example.dao.JcSourceItem; +import abacus.springboot.example.vo.SiDepositlocation; + +/** + *

Title:JcBillServiceIF

+

Description: service服务

+ @author chuanZeng + @date 2026年8月18日 + */ +public interface JcBillServiceIF { + + /** + * 稽查收货查询 + * @param fromDate + * @param thruDate + * @param id + * @param applicant + * @param goods + * @param billin + * @param goodsid + * @param product + * @param status + * @param pageable + * @param typ 1-溯源入库 2-回购通知 + * @return + * @throws RuntimeException + */ + public Page queryJcBill(String fromDate, String thruDate, String id, + String applicant, String goods, String billin, String goodsid, String product, + String status, int typ, Pageable pageable) throws RuntimeException; + + /** + * 查询 + * @param billId + * @return + * @throws RuntimeException + */ + public JcBill queryJcBillById(String billId) throws RuntimeException; + + /** + * 查询 + * @param billId + * @return + * @throws RuntimeException + */ + public List queryJcBillSourceItemByBillId(String billId) throws RuntimeException; + + /** + * 查询 + * @param billHg + * @return + * @throws RuntimeException + */ + public JcBillHg queryJcBillHg(String billHg) throws RuntimeException; + + /** + * 查询朔源明细 + * @param billId + * @return + */ + public List queryJcSourceItemByBillId(String billId) throws RuntimeException; + + /** + * 查询朔源明细 + * @param billId + * @return + */ + public List queryJcSourceItemByBillId(String billId, String srcitemid) throws RuntimeException; + + /** + * 查询朔源明细 + * @param billId + * @return + */ + public List queryJcSourceItemByBillId(String billId, String srcitemid, int status) throws RuntimeException; + + + /** + * 根据条件查询图片 + * @param srcid + * @param srcitemid + * @param typephoto + * @return + * @throws RuntimeException + */ + public Map> queryJcBillPhoto(String srcid) throws RuntimeException; + + /** + * 查询稽查收货明细 + * @param id + * @return + * @throws RuntimeException + */ + public JcBillSourceItem queryJcBillSourceItemById(Long id) throws RuntimeException; + + /** + * 稽查溯源明细 + * @param id + * @return + * @throws RuntimeException + */ + public JcSourceItem queryJcSourceItemById(Long id) throws RuntimeException; + + /** + * 确认溯源 + * @param billItem + * @param sourceItem + * @throws RuntimeException + */ + public void saveQuerenBillSourceItem(JcBillSourceItem billItem, JcSourceItem sourceItem) throws RuntimeException; + + /** + * 溯源信息驳回 + * @param billItem + * @param sourceItem + * @throws RuntimeException + */ + public void saveRejectJcSourceItems(JcBillSourceItem billItem, JcBill jcBill) throws RuntimeException; + + /** + * 溯源完成 + * @param billItem + * @param sourceItem + * @throws RuntimeException + */ + public void saveCompleteJcBill(List inItems, JcBill jcBill) throws RuntimeException; + + /** + * 稽查收货:仓库修改 + * @param jcBill + * @throws RuntimeException + */ + public void updateWarehouse(JcBill jcBill) throws RuntimeException; + + /** + * + * @param billId + * @return + * @throws RuntimeException + */ + public List queryJcBillInItemByBillId(String billId) throws RuntimeException; + + public List queryJcBillInItemByBillId(String billId, int status) throws RuntimeException; + + /** + * 稽查收货:生成入库单 + * @param jcBill + * @throws RuntimeException + */ + public void createStockIn(JcBill jcBill) throws RuntimeException; + + /** + * 查询回购单明细 + * @param id + * @return + */ + public JcBillInItem queryJcBillInItemById(Long id) throws RuntimeException; + + /** + * 终止回购 + * @param inItem + * @throws RuntimeException + */ + public void saveTerminateHgInItem(JcBillInItem inItem) throws RuntimeException; + + /** + * 批量查询回购单明细 + * @param ids + * @return + * @throws RuntimeException + */ + public List findAllById(List ids) throws RuntimeException; + + /** + * 确定通知 + * @param inItems + * @throws RuntimeException + */ + public void saveInformHg(List inItems, JcBill jcBill, JcBillHg jcBillHg, String photoUrl) throws RuntimeException; + + /** + * 分页查询 回购订单 + * @param typ 1-回购认款,2-回购分仓 + * @return + * @throws RuntimeException + */ + public Page queryJcBillHg(String fromDate, String thruDate, String account, + String salearea, String id, String billId, String status, String product, + String manager, + int typ, Pageable pageable) throws RuntimeException; + + /** + * + * @param billId + * @return + * @throws RuntimeException + */ + public List queryJcBillInItemByBillHg(String billHgId) throws RuntimeException; + + /** + * 回购驳回 + * @throws RuntimeException + */ + public void saveRejectBillHg(int status, int typ, JcBill jcBill, JcBillHg billHg, List inItems) throws RuntimeException; + + /** + * 确认收款 + * @param billHg + * @throws RuntimeException + */ + public void saveQuerenSk(JcBillHg billHg, boolean fcFlag) throws RuntimeException; + + /** + * 分仓 + * @param billHg + * @param fcFlag + * @throws RuntimeException + */ + public void savecreateFc(JcBillHg billHg) throws RuntimeException; + + /** + * 修改分仓仓库 + * @param oldJsonStr + * @param billHg + * @throws RuntimeException + */ + public void updateFcWarehouse(String oldJsonStr, JcBillHg billHg) throws RuntimeException; + + /** + * 修改运营备注 + * @param oldJsonStr + * @param billHg + * @throws RuntimeException + */ + public void updateRemark(String oldJsonStr, JcBillHg billHg) throws RuntimeException; + + /** + * 修改收货地址 + * @param oldJsonStr + * @param billHg + * @throws RuntimeException + */ + public void updatePac(String oldJsonStr, JcBillHg billHg) throws RuntimeException; + + /** + * 保存溯源明细信息 + * @param item + * @throws RuntimeException + */ + public JcSourceItem saveJcSourceItem(JcSourceItem item) throws RuntimeException; + + /** + * 删除溯源明细信息 + * @param ids + * @throws RuntimeException + */ + public void deleteJcSourceItem(List ids) throws RuntimeException; + + /** + * 修改回购单价 + * @param inItem + * @throws RuntimeException + */ + public void updateHgprice(JcBillInItem inItem)throws RuntimeException; + + /** + * 修改回购单价 + * @param inItem + * @throws RuntimeException + */ + public void updateOperatorname(JcBillInItem inItem, String oldStr)throws RuntimeException; + + public void saveJcBillInItem(List items)throws RuntimeException; + + public List queryJcBillSourceItemInBillId(List billIds) throws RuntimeException; + + + /** + * 待入库撤回 + * @throws RuntimeException + */ + public void saveRejectBill(int status, JcBill jcBill, List inItems, List sourceItems) throws RuntimeException; + + /** + * 修改溯源信息客户 + * @param inItems + * @throws RuntimeException + */ + public void updateSourceItemAccount(String sourceItemLogJson, String billSourceItemLogJson, String billSourceItemNewLogJson, JcSourceItem sourceItem, List billSourceItems, + List oldInItems, List inItems)throws RuntimeException; + + /** + * 稽查:根据稽查单号,稽查单关联物理仓管理策略 + * @param dept + * @return + * @throws Exception + */ + public SiDepositlocation querySiDepositlocation(String srcid) throws Exception; + + /** + * 回购:根据回购单号,回购单关联物理仓管理策略 + * @param dept + * @return + * @throws Exception + */ + public SiDepositlocation querySiDepositlocationHGfc(String srcid) throws Exception; + + /** + * WMS取消订单接口 + * @param orderCode + * @param orderType + * @return + * @throws Exception + */ + public JSONObject gwisSubCancelOrder(String orderCode, String orderType) throws Exception; +} + + + + + + + + + + diff --git a/abacus.springboot.example/src/main/resources/config/dev/application-xxljob.yml b/abacus.springboot.example/src/main/resources/config/dev/application-xxljob.yml new file mode 100644 index 0000000..c6fce20 --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/dev/application-xxljob.yml @@ -0,0 +1,31 @@ +##xxl-job +xxl: + job: +# admin: + ### 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册; http://localhost:9900/xxl-job-admin +# addresses: http://localhost:9900 +# addresses: http://192.168.2.130:9900 + executor: + ### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册 +# appname: example-test + ### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。 +# address: + ### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务"; +# ip: + ### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册 + ### 使用产品 + appname: example + ### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口; + #因为使用docker部署,为了方便docker镜像映射,发布时固定使用“9001”作为定时任务执行器端口 + port: 9061 + ### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能; + logretentiondays: 7 + ### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径; + logpath: D:\apps\file\work\log\xxljob\ + ### 执行器通讯TOKEN [选填]:非空时启用; +# accessToken: + + + + + diff --git a/abacus.springboot.example/src/main/resources/config/dev/application.yml b/abacus.springboot.example/src/main/resources/config/dev/application.yml new file mode 100644 index 0000000..f7ad519 --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/dev/application.yml @@ -0,0 +1,100 @@ +logging: + config: classpath:logback-spring.xml + maxhistory: 7 + +server: + port: 9060 + max-http-header-size: 20480 + servlet: + context-path: /example + session: + timeout: PT4H + + +spring: + data: + jpa: + repositories: + bootstrap-mode: lazy #jpa延迟启动 + main: + lazy-initialization: true #bean延迟启动 + servlet: + multipart: + max-file-size: 50MB #上传文件的大小限定 + max-request-size: 50MB #上传请求数据的大小限定,限定请求的总数据大小 + profiles: + active: xxljob + datasource: + druid: + #如果连接泄露,是否需要回收泄露的连接,默认false + removeAbandoned: true + #如果回收了泄露的连接,是否要打印一条log,默认false + logAbandoned: true + #连接回收的超时时间(单位:秒),默认5分钟 + removeAbandonedTimeout: 300 + #查询超时时间(单位:秒) + query-timeout: 300 + #事务查询超时时间(单位:秒),如果小于或等于0,则取query-timeout配置 + #transaction-query-timeout: 5 + # 配置初始化大小、最小、最大 + initial-size: 10 + minIdle: 11 + max-active: 60 + # 配置获取连接等待超时的时间(单位:毫秒) + max-wait: 60000 + + + +#在线接口文档扫描类路径 +springdoc: + packages-to-scan: + - abacus.springboot.example.api + paths-to-match: + + +abacus: + #在线数据字典扫描类路径 + entitypackages: + - abacus.springboot.example.dao + #本系统Controller扫描类路径 + controllerPackages: + - abacus.springboot.example.controller + #以下uri将不被统一响应体拦截包装器进行包装 + responseExcludePath: + +# acas系统编码 +acas: + current: + number: example + + +feign: + client: + config: + #feign全局超时配置,单位:毫秒 + default: + connectTimeout: 10000 + readTimeout: 30000 + #单个微服务超时配置,优先级高于全局 +# abacus-oauth2: +# connectTimeout: 10000 +# readTimeout: 10000 + + +management: + endpoint: + metrics: + enabled: true + prometheus: + enabled: true + startup: + enabled: true + endpoints: + web: + exposure: + include: "*" + base-path: /services/actuator + metrics: + export: + prometheus: + enabled: true \ No newline at end of file diff --git a/abacus.springboot.example/src/main/resources/config/dev/bootstrap.yml b/abacus.springboot.example/src/main/resources/config/dev/bootstrap.yml new file mode 100644 index 0000000..e78ee6a --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/dev/bootstrap.yml @@ -0,0 +1,31 @@ +spring: + application: + name: example + cloud: + nacos: + username: v10dev + password: Abacus2022 + config: + server-addr: 192.168.2.130:8848 + namespace: 3d18c67a-d086-4c16-b377-a633c487eafb + file-extension: yml + group: DEFAULT_GROUP + extension-configs: + - data-id: abacus-database.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-discovery.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-acas.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-redis.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-actuator.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-xxljob.yml + group: COMMON_GROUP + refresh: false \ No newline at end of file diff --git a/abacus.springboot.example/src/main/resources/config/dev/logback-access.xml b/abacus.springboot.example/src/main/resources/config/dev/logback-access.xml new file mode 100644 index 0000000..4047aba --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/dev/logback-access.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + ${log.path}/access/access.log + + ${log.path}/access/access-%i.log + 1 + 1 + + + 10MB + + + %t{yyyy-MM-dd HH:mm:ss.SS} "%r" %s %b %D %h "%i{Referer}" "%i{User-Agent}" "%i{X-Request-ID}" "%i{X-Forwarded-For}" + UTF-8 + + + + diff --git a/abacus.springboot.example/src/main/resources/config/dev/logback-spring.xml b/abacus.springboot.example/src/main/resources/config/dev/logback-spring.xml new file mode 100644 index 0000000..b6d705a --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/dev/logback-spring.xml @@ -0,0 +1,140 @@ + + + + + + + + logback + + + + + + + + + + + + info + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/info/info.log + + ${log.path}/info/info.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + INFO + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/warn/warn.log + + ${log.path}/warn/warn.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + WARN + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/error/error.log + + ${log.path}/error/error.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + ERROR + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/debug/debug.log + + ${log.path}/debug/debug.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + DEBUG + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + + + ${log.path}/slowsql/slowsql.log + + ${log.path}/slowsql/slowsql.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + 30 + + + ${log.pattern} + UTF-8 + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/abacus.springboot.example/src/main/resources/config/prod/application-xxljob.yml b/abacus.springboot.example/src/main/resources/config/prod/application-xxljob.yml new file mode 100644 index 0000000..c6fce20 --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/prod/application-xxljob.yml @@ -0,0 +1,31 @@ +##xxl-job +xxl: + job: +# admin: + ### 调度中心部署跟地址 [选填]:如调度中心集群部署存在多个地址则用逗号分隔。执行器将会使用该地址进行"执行器心跳注册"和"任务结果回调";为空则关闭自动注册; http://localhost:9900/xxl-job-admin +# addresses: http://localhost:9900 +# addresses: http://192.168.2.130:9900 + executor: + ### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册 +# appname: example-test + ### 执行器注册 [选填]:优先使用该配置作为注册地址,为空时使用内嵌服务 ”IP:PORT“ 作为注册地址。从而更灵活的支持容器类型执行器动态IP和动态映射端口问题。 +# address: + ### 执行器IP [选填]:默认为空表示自动获取IP,多网卡时可手动设置指定IP,该IP不会绑定Host仅作为通讯实用;地址信息用于 "执行器注册" 和 "调度中心请求并触发任务"; +# ip: + ### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册 + ### 使用产品 + appname: example + ### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口; + #因为使用docker部署,为了方便docker镜像映射,发布时固定使用“9001”作为定时任务执行器端口 + port: 9061 + ### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能; + logretentiondays: 7 + ### 执行器运行日志文件存储磁盘路径 [选填] :需要对该路径拥有读写权限;为空则使用默认路径; + logpath: D:\apps\file\work\log\xxljob\ + ### 执行器通讯TOKEN [选填]:非空时启用; +# accessToken: + + + + + diff --git a/abacus.springboot.example/src/main/resources/config/prod/application.yml b/abacus.springboot.example/src/main/resources/config/prod/application.yml new file mode 100644 index 0000000..b36690e --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/prod/application.yml @@ -0,0 +1,71 @@ +server: + port: 9000 + max-http-header-size: 20480 + servlet: + session: + timeout: PT4H + + +spring: + data: + jpa: + repositories: + bootstrap-mode: lazy #jpa延迟启动 + main: + lazy-initialization: true #bean延迟启动 + servlet: + multipart: + max-file-size: 50MB #上传文件的大小限定 + max-request-size: 50MB #上传请求数据的大小限定,限定请求的总数据大小 + profiles: + active: xxljob + datasource: + druid: + #如果连接泄露,是否需要回收泄露的连接,默认false + removeAbandoned: true + #如果回收了泄露的连接,是否要打印一条log,默认false + logAbandoned: true + #连接回收的超时时间,默认5分钟 + #removeAbandonedTimeout: 10 + #查询超时时间(单位:秒) + query-timeout: 300 + #事务查询超时时间(单位:秒),如果小于或等于0,则取query-timeout配置 + #transaction-query-timeout: 5 + # 配置初始化大小、最小、最大 + initial-size: 5 + minIdle: 10 + max-active: 30 + # 配置获取连接等待超时的时间(单位:毫秒) + max-wait: 60000 + +# acas系统编码 +acas: + current: + number: example + + +#在线接口文档扫描类路径 +springdoc: + packages-to-scan: + - abacus.springboot.example.springdoc + paths-to-match: + + +abacus: + #在线数据字典扫描类路径 + entitypackages: + - abacus.springboot.example + #本系统Controller扫描类路径 + controllerPackages: + - abacus.springboot.example + #以下uri将不被统一响应体拦截包装器进行包装 + responseExcludePath: + + + + + + + + + diff --git a/abacus.springboot.example/src/main/resources/config/prod/bootstrap.yml b/abacus.springboot.example/src/main/resources/config/prod/bootstrap.yml new file mode 100644 index 0000000..e78ee6a --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/prod/bootstrap.yml @@ -0,0 +1,31 @@ +spring: + application: + name: example + cloud: + nacos: + username: v10dev + password: Abacus2022 + config: + server-addr: 192.168.2.130:8848 + namespace: 3d18c67a-d086-4c16-b377-a633c487eafb + file-extension: yml + group: DEFAULT_GROUP + extension-configs: + - data-id: abacus-database.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-discovery.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-acas.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-redis.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-actuator.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-xxljob.yml + group: COMMON_GROUP + refresh: false \ No newline at end of file diff --git a/abacus.springboot.example/src/main/resources/config/prod/logback-access.xml b/abacus.springboot.example/src/main/resources/config/prod/logback-access.xml new file mode 100644 index 0000000..bbb0e49 --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/prod/logback-access.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + ${log.path}/access/access.log + + ${log.path}/access/access-%i.log + 1 + 1 + + + 100MB + + + %t{yyyy-MM-dd HH:mm:ss.SSS} "%r" %s %b %D %h "%i{Referer}" "%i{User-Agent}" "%i{X-Request-ID}" "%i{X-Forwarded-For}" "%i{commonParam}" + UTF-8 + + + + diff --git a/abacus.springboot.example/src/main/resources/config/prod/logback-spring.xml b/abacus.springboot.example/src/main/resources/config/prod/logback-spring.xml new file mode 100644 index 0000000..6d35a12 --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/prod/logback-spring.xml @@ -0,0 +1,168 @@ + + + + + + + + logback + + + + + + + + + + + + + + + + info + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/info/info.log + + ${log.path}/info/info.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + INFO + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/warn/warn.log + + ${log.path}/warn/warn.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + WARN + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/error/error.log + + ${log.path}/error/error.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + ERROR + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/debug/debug.log + + ${log.path}/debug/debug.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + DEBUG + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + + + ${log.path}/slowsql/slowsql.log + + ${log.path}/slowsql/slowsql.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + 30 + + + ${log.pattern} + UTF-8 + + + + + + + + + + ${log.path}/resttemplate/resttemplate.log + + ${log.path}/resttemplate/resttemplate.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + 30 + + + ${log.pattern} + UTF-8 + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/abacus.springboot.example/src/main/resources/config/test/application-xxljob.yml b/abacus.springboot.example/src/main/resources/config/test/application-xxljob.yml new file mode 100644 index 0000000..c09f69d --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/test/application-xxljob.yml @@ -0,0 +1,17 @@ +##xxl-job +xxl: + job: + executor: + ### 执行器AppName [选填]:执行器心跳注册分组依据;为空则关闭自动注册 + ### 使用产品 + appname: example + ### 执行器端口号 [选填]:小于等于0则自动获取;默认端口为9999,单机部署多个执行器时,注意要配置不同执行器端口; + #因为使用docker部署,为了方便docker镜像映射,发布时固定使用“9001”作为定时任务执行器端口 + port: 9001 + ### 执行器日志文件保存天数 [选填] : 过期日志自动清理, 限制值大于等于3时生效; 否则, 如-1, 关闭自动清理功能; + logretentiondays: 7 + + + + + diff --git a/abacus.springboot.example/src/main/resources/config/test/application.yml b/abacus.springboot.example/src/main/resources/config/test/application.yml new file mode 100644 index 0000000..36bfafe --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/test/application.yml @@ -0,0 +1,50 @@ +server: + port: 9000 +spring: + jackson: + date-format: yyyy-MM-dd HH:mm:ss + time-zone: GMT+8 + profiles: + active: xxljob + jpa: + show-sql: false + datasource: + druid: + #如果连接泄露,是否需要回收泄露的连接,默认false + removeAbandoned: true + #如果回收了泄露的连接,是否要打印一条log,默认false + logAbandoned: true + #连接回收的超时时间,默认5分钟 + #removeAbandonedTimeout: 10 + #查询超时时间(单位:秒) + query-timeout: 300 + #事务查询超时时间(单位:秒),如果小于或等于0,则取query-timeout配置 + #transaction-query-timeout: 5 + # 配置初始化大小、最小、最大 + initial-size: 5 + minIdle: 10 + max-active: 30 + # 配置获取连接等待超时的时间(单位:毫秒) + max-wait: 60000 + +acas: + current: + number: example + +springdoc: + packages-to-scan: + - abacus.springboot.example.api + paths-to-match: + +abacus: + entitypackages: + - abacus.springboot.example + + + + + + + + + diff --git a/abacus.springboot.example/src/main/resources/config/test/bootstrap.yml b/abacus.springboot.example/src/main/resources/config/test/bootstrap.yml new file mode 100644 index 0000000..22cca8c --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/test/bootstrap.yml @@ -0,0 +1,31 @@ +spring: + application: + name: example + cloud: + nacos: + username: v10dev + password: Abacus2022 + config: + server-addr: v10sys.abacus.private:8848 + namespace: 3d18c67a-d086-4c16-b377-a633c487eafb + file-extension: yml + group: DEFAULT_GROUP + extension-configs: + - data-id: abacus-database.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-discovery.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-acas.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-redis.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-actuator.yml + group: COMMON_GROUP + refresh: false + - data-id: abacus-xxljob.yml + group: COMMON_GROUP + refresh: false \ No newline at end of file diff --git a/abacus.springboot.example/src/main/resources/config/test/logback-access.xml b/abacus.springboot.example/src/main/resources/config/test/logback-access.xml new file mode 100644 index 0000000..545b1da --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/test/logback-access.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + ${log.path}/access/access.log + + ${log.path}/access/access-%i.log + 1 + 1 + + + 10MB + + + %t{yyyy-MM-dd HH:mm:ss.SSS} "%r" %s %b %D %h "%i{Referer}" "%i{User-Agent}" "%i{X-Request-ID}" "%i{X-Forwarded-For}" "%i{commonParam}" + UTF-8 + + + + diff --git a/abacus.springboot.example/src/main/resources/config/test/logback-spring.xml b/abacus.springboot.example/src/main/resources/config/test/logback-spring.xml new file mode 100644 index 0000000..555852a --- /dev/null +++ b/abacus.springboot.example/src/main/resources/config/test/logback-spring.xml @@ -0,0 +1,168 @@ + + + + + + + + logback + + + + + + + + + + + + + + + + info + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/info/info.log + + ${log.path}/info/info.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + INFO + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/warn/warn.log + + ${log.path}/warn/warn.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + WARN + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/error/error.log + + ${log.path}/error/error.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + ERROR + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + ${log.path}/debug/debug.log + + ${log.path}/debug/debug.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + ${log.maxhistory} + + + DEBUG + ACCEPT + DENY + + + ${log.pattern} + UTF-8 + + + + + + + ${log.path}/slowsql/slowsql.log + + ${log.path}/slowsql/slowsql.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + 30 + + + ${log.pattern} + UTF-8 + + + + + + + + + + ${log.path}/resttemplate/resttemplate.log + + ${log.path}/resttemplate/resttemplate.%d{yyyy-MM-dd}.%i.log.gz + + ${log.maxfilesize} + + 30 + + + ${log.pattern} + UTF-8 + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/abacus.springboot.example/src/main/resources/doc/升级日志.md b/abacus.springboot.example/src/main/resources/doc/升级日志.md new file mode 100644 index 0000000..76e67db --- /dev/null +++ b/abacus.springboot.example/src/main/resources/doc/升级日志.md @@ -0,0 +1,16 @@ +# 子系统中文名称(负责人姓名) + +## 1.0.1(2024-04-12) +**依赖子系统** +**前置条件** +**更新说明** +- 2026-08-18 M2 示例净化(示范即正确):D1 `JcBillAccess` 原生 SQL 全量参数化(86 处 `?` 占位符,0 处字符串拼参);D2 `JcBillController` 业务编排下沉至新建 `esb/JcBillBizService`(含 `saveJcBill`/`updateJcbill`/`hgAnalyze` 等 5 方法),并移除死代码 `jcAnalyze`;D3 包名 `repositroy`→`repository`(含 7 个接口文件名重命名)。详见 `docs/log/2026-08-18-m2-example-purify.md`。 + +## 1.0.2(2026-08-19) +**依赖子系统** +**前置条件** +**更新说明** +- 治理体系落地(ADS Retrofit):新增 `.project.agents/`(CLAUDE/AGENTS/SELF_CONSTRAINTS/VIBECODING_GUIDE/settings + context 四文档),前后端共享约束单源化于工作区 `docs/`(`coding-standards.md`/`architecture.md`/`agent-guide.md`),本仓库文档以指针引用。 +- 分层约定与 `docs/coding-standards.md` 对齐(api/controller/dao/esb/pi/impl/repository/wsi/config/util/vo);`util`、`vo` 包冻结(既有兼容、新增禁止)。 +- 工作区纳入单一 git 仓库(`D:\workBuddySpace\member`)。 + diff --git a/abacus.springboot.example/src/main/resources/sql/data/mysql.sql b/abacus.springboot.example/src/main/resources/sql/data/mysql.sql new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/abacus.springboot.example/src/main/resources/sql/data/mysql.sql @@ -0,0 +1 @@ + diff --git a/abacus.springboot.example/src/main/resources/sql/table/mysql.sql b/abacus.springboot.example/src/main/resources/sql/table/mysql.sql new file mode 100644 index 0000000..e69de29 diff --git a/abacus.springboot.example/src/main/resources/sql/upgrade.xml b/abacus.springboot.example/src/main/resources/sql/upgrade.xml new file mode 100644 index 0000000..3ac4943 --- /dev/null +++ b/abacus.springboot.example/src/main/resources/sql/upgrade.xml @@ -0,0 +1,259 @@ + + + + + + -- 稽查主单 + create table jc_bill ( + id varchar(20) not null, + version int not null, + status int default (1) null, + goods varchar(120) null, + warehouse varchar(20) null, + warehousename varchar(120) null, + receivedt varchar(10) null, + quantity decimal(30,8) null, + subtotal decimal(30,2) null, + billin varchar(20) null, + billindt datetime null, + applicant varchar(20) null, + applicantname varchar(120) null, + applicantdt datetime null, + dt datetime default current_timestamp not null, + constraint pk_jc_bill primary key (id) + ); + create index jc_bill_search on jc_bill(id, applicant, status, goods, + applicantdt, dt); + create index jc_bill_id on jc_bill(id, goods, dt); + create index jc_bill_dt on jc_bill(dt); + + -- 稽查明细 + create table jc_billsource_item ( + id bigint auto_increment not null primary key, -- 自增长编码 + version int not null, + indexno int null, + billid varchar(20) not null, + status int default (1) null, + recsource varchar(20) null, + recplatform varchar(20) null, + channel varchar(60) null, + price decimal(30,8) null, + quantity decimal(30,8) null, + numbers decimal(30,8) null, + subtotal decimal(30,2) null, + goodsid varchar(20) null, + logisticsid varchar(60) null, + billout varchar(600) null, + billoutdt datetime null, + billoutwh varchar(20) null, + billoutwhname varchar(60) null, + product varchar(20) null, + productname varchar(200) null, + account varchar(20) null, + accountname varchar(200) null, + operator varchar(20) null, + operatorname varchar(60) null, + groupid varchar(20) null, + groupname varchar(60) null, + salearea varchar(20) null, + saleareaname varchar(60) null, + source varchar(20) null, + reason varchar(300) null, + dt datetime default current_timestamp not null + ); + create index jc_billsource_item_billid on jc_billsource_item(billid); + + -- 溯源明细 + create table jc_source_item ( + id bigint auto_increment not null primary key, -- 自增长编码 + version int not null, + billid varchar(20) not null, + srcitemid varchar(20) not null, + status int default (0) null, + goodsid varchar(20) null, + logisticsid varchar(60) null, + billout varchar(20) null, + billoutdt datetime null, + billoutwh varchar(20) null, + billoutwhname varchar(60) null, + product varchar(20) null, + productname varchar(200) null, + account varchar(20) null, + accountname varchar(200) null, + operator varchar(20) null, + operatorname varchar(60) null, + groupid varchar(20) null, + groupname varchar(60) null, + salearea varchar(20) null, + saleareaname varchar(60) null, + source varchar(20) null, + dt datetime default current_timestamp not null + ); + create index jc_source_item_billid on jc_source_item(billid, source, + srcitemid); + create index jc_source_item_billid_status on jc_source_item(billid, + srcitemid, status); + + -- 稽查入库(回购通知)明细(对溯源信息汇总的入库信息-待生成回购) + create table jc_billin_item ( + id bigint auto_increment not null primary key, -- 自增长编码 + version int not null, + billid varchar(20) not null, + billin varchar(20) null, + billhg varchar(20) null, + status int default (1) null, + channel varchar(60) null, + account varchar(20) null, + accountname varchar(200) null, + product varchar(20) null, + productname varchar(200) null, + price decimal(30,8) null, + quantity decimal(30,8) null, + numbers decimal(30,8) null, + hgprice decimal(30,8) null, + hgamount decimal(30,2) null, + operator varchar(20) null, + operatorname varchar(60) null, + groupid varchar(20) null, + groupname varchar(60) null, + salearea varchar(20) null, + saleareaname varchar(60) null, + fhquantity decimal(30,8) null, + fhnumbers decimal(30,8) null, + fhwarehouse varchar(20) null, + fhwarehousename varchar(120) null, + wdtorder varchar(20) null, + wdtbillout varchar(20) null, + wdtbillouttyp varchar(20) null, + wdtdt datetime null, + dt datetime default current_timestamp not null + ); + create index jc_billin_item_billid on jc_billin_item(billhg, billid, + billin); + create index jc_billin_item_status on jc_billin_item(status); + + -- 回购单-主单 + create table jc_billhg ( + id varchar(20) not null, + version int not null, + billid varchar(20) not null, + status int default (1) null, + source varchar(20) null, + account varchar(20) null, + accountname varchar(200) null, + quantity decimal(30,8) null, + subtotal decimal(30,2) null, + freight decimal(30,2) null, + manager varchar(20) null, + managername varchar(60) null, + consignee varchar(20) null, + consigneephone varchar(30) null, + province varchar(10) null, + provincename varchar(60) null, + city varchar(10) null, + cityname varchar(60) null, + area varchar(10) null, + areaname varchar(60) null, + address varchar(300) null, + receiveway varchar(20) null, + remark varchar(300) null, + remark1 varchar(300) null, + salearea varchar(20) null, + saleareaname varchar(60) null, + groupid varchar(20) null, + groupname varchar(60) null, + fhwarehouse varchar(20) null, + fhwarehousename varchar(120) null, + wdtorder varchar(20) null, + wdtbillout varchar(20) null, + wdtbillouttyp varchar(20) null, + wdtdt datetime null, + logisticsname varchar(60) null, + logisticscode varchar(60) null, + logisticstype varchar(60) null, + logisticsno varchar(20) null, + found varchar(20) null, + foundname varchar(60) null, + founddt datetime null, + submit varchar(20) null, + submitname varchar(60) null, + submitdt datetime null, + audit varchar(20) null, + auditname varchar(60) null, + auditdt datetime null, + dt datetime default current_timestamp not null, + constraint pk_jc_billhg primary key (id) + ); + create index jc_billhg_founddt on jc_billhg(founddt, account, salearea, + billid, status, manager); + create index jc_billhg_billid on jc_billhg(billid); + create index jc_billhg_status_founddt on jc_billhg(status, founddt); + create index jc_billhg_consigneephone on jc_billhg(consigneephone, account, + accountname); + create index jc_billhg_dt on jc_billhg(dt); + + -- 回购单-支付明细 + create table jc_billhg_pay ( + id bigint auto_increment not null primary key, -- 自增长编码 + version int not null, + billid varchar(20) not null, + billhg varchar(20) not null, + payment varchar(20) not null, + amount decimal(30,2) null, + zhmc varchar(20) not null, + khyh varchar(150) not null, + yhzh varchar(60) not null, + dt datetime default current_timestamp not null + ); + create index jc_billhg_pay_billhg on jc_billhg_pay(billhg, payment); + create index jc_billhg_pay_billid on jc_billhg_pay(billid); + create index jc_billhg_pay_dt on jc_billhg_pay(dt); + + -- 图片 + create table jc_bill_photo ( + id bigint auto_increment not null primary key, -- 自增长编码 + version int not null, + srcid varchar(20) not null, + srcitemid varchar(20) not null, + typephoto varchar(30) not null, + urlphoto varchar(200) not null, + dt datetime default current_timestamp not null + ); + create index jc_bill_photo_srcitemid on jc_bill_photo(srcid, srcitemid, + typephoto); + create index jc_bill_photo_srcid on jc_bill_photo(srcid, typephoto); + + -- 2025-03-14 + alter table jc_billhg add column proofaccountname varchar(150) null; + alter table jc_billhg add column proofdt datetime null; + alter table jc_bill add column hgstatus int default 0 null; + + -- 2025-01-22(alter column 改为 modify column) + alter table jc_billsource_item modify column billout varchar(600) null; + + -- 2025-01-16 + alter table jc_billin_item add column wdtoutdt datetime null; + alter table jc_billin_item add column wdtindt datetime null; + alter table jc_billhg add column wdtoutdt datetime null; + alter table jc_billhg add column wdtindt datetime null; + alter table jc_billsource_item modify column logisticsid varchar(600) + null; + alter table jc_source_item modify column logisticsid varchar(600) null; + + -- 2025-01-06(原文件重复出现两次,已去重) + alter table jc_bill add column dept varchar(20) null; + + + + \ No newline at end of file