From 79ebcec7600bea32621308703e189f658b8aec7c Mon Sep 17 00:00:00 2001
From: dzc <2388224167@qq.com>
Date: Fri, 18 Sep 2026 12:53:39 +0800
Subject: [PATCH] =?UTF-8?q?feat:app=E6=B5=81=E6=B0=B4=E9=80=9A=E7=9F=A5?=
=?UTF-8?q?=E6=98=BE=E7=A4=BA=E5=A4=87=E6=B3=A8=20feat:=E5=92=96=E5=95=A1?=
=?UTF-8?q?=E6=9C=BA=E5=88=9D=E6=AD=A5?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.env | 8 +--
...ss_2f84e437-4934-4daf-adb8-4927b8c6fcf4.md | 67 +++++++++++++++++++
src/i18n/pages/message/en.ts | 1 +
src/i18n/pages/message/zh-cn.ts | 1 +
src/i18n/pages/message/zh-hk.ts | 1 +
src/pages/message/detail.vue | 6 ++
src/sheep/api/app-message.ts | 2 +
7 files changed, 82 insertions(+), 4 deletions(-)
create mode 100644 .zcode/plans/plan-sess_2f84e437-4934-4daf-adb8-4927b8c6fcf4.md
diff --git a/.env b/.env
index 600e23d..33ffb49 100644
--- a/.env
+++ b/.env
@@ -33,11 +33,11 @@ VITE_OAUTH2_SOCIAL_CLIENT='social:social'
# 是否开启websocket 消息接受,
VITE_WEBSOCKET_ENABLE = true
# --------------------------- start 开发环境 start ----------------------------------
-VITE_APP_DEV_SERVICE = https://www.zianxin.com/api
-# VITE_APP_DEV_SERVICE = https://dzc-test-1.fy.takin.cc
+# VITE_APP_DEV_SERVICE = https://www.zianxin.com/api
+VITE_APP_DEV_SERVICE = https://dzc-test-1.fy.takin.cc
# VITE_APP_DEV_SERVICE = http://127.0.0.1:9999
-VITE_APP_DEV_SERVICE = https://www.zianxin.com/api
-# VITE_APP_DEV_SERVICE = https://dzc-test-1.fy.takin.cc
+# VITE_APP_DEV_SERVICE = https://www.zianxin.com/api
+VITE_APP_DEV_SERVICE = https://dzc-test-1.fy.takin.cc
#VITE_APP_DEV_SERVICE = http://127.0.0.1:9999
VITE_IMAGE_DEV_PATH = https://www.zianxin.com/api
diff --git a/.zcode/plans/plan-sess_2f84e437-4934-4daf-adb8-4927b8c6fcf4.md b/.zcode/plans/plan-sess_2f84e437-4934-4daf-adb8-4927b8c6fcf4.md
new file mode 100644
index 0000000..4cfa042
--- /dev/null
+++ b/.zcode/plans/plan-sess_2f84e437-4934-4daf-adb8-4927b8c6fcf4.md
@@ -0,0 +1,67 @@
+# 钱包变动通知携带流水备注(remark)实施计划
+
+## 链路现状(已核实)
+
+```
+wallet_transaction 落库(remark 可在创建时写入,如充值导入审批)
+ → WalletTransactionServiceImpl.save() 同事务 createMessageOutbox() 写 wallet_message_outbox(不可变快照,目前无 remark)
+ → WalletMessageOutboxJob(10s, 2s归并) → buildDetail() → Feign /app-message/inner/wallet-event
+ → ThirdAppMessageServiceImpl.receiveWalletEvent()
+ ├─ walletContent() 用 i18n 模板拼 title/content(content 同时用于站内信正文和极光推送栏文案)
+ ├─ serializeWalletPayload() → payloadJson(details=WalletMessageDetailDto 列表,App 拉取时按语言重渲染正文)
+ └─ insert third_app_message + 创建推送投递任务
+ → ThirdAppMessagePushJob → JPush(直接透传 title/content,无需改)
+```
+
+方案采用**快照模式**:remark 随其他展示字段一起在 Outbox 落库时快照,与该表"不可变展示快照"的设计一致。
+
+## 后端改动(biz-api-cloud-zax,6 个文件 + 1 个 DDL)
+
+1. **新增 DDL** `db/20260918_add_wallet_outbox_remark.sql`:
+ ```sql
+ ALTER TABLE `pjcloudx_wallet`.`wallet_message_outbox`
+ ADD COLUMN `remark` varchar(256) DEFAULT NULL COMMENT '流水备注快照,由后台操作人员补充业务说明,最多256字符' AFTER `balance`;
+ ```
+2. **`WalletMessageOutboxEntity.java`**(pjcloud-wallet-api,balance 字段后):加 `private String remark;` + 注释。
+3. **`WalletTransactionServiceImpl.createMessageOutbox()`** L245 附近:`outbox.setRemark(transaction.getRemark());`
+4. **`WalletMessageOutboxServiceImpl.buildDetail()`** L266 附近:`detail.setRemark(outbox.getRemark());`
+5. **`WalletMessageDetailDto.java`**(pjcloud-thirdparty-api):加 `@Size(max = 256) private String remark;` —— 自动进入 payloadJson,支撑 App 端按语言重渲染正文。
+6. **`ThirdAppMessageServiceImpl.walletContent()`** L442 后:remark 非空白时在每条明细后追加备注段:
+ ```java
+ detailsText.append(MsgUtils.getMessage(detailCode, walletName, amount, balance));
+ if (StrUtil.isNotBlank(detail.getRemark())) {
+ detailsText.append(MsgUtils.getMessage(ErrorCodes.APP_MSG_WALLET_DETAIL_REMARK, detail.getRemark().trim()));
+ }
+ ```
+7. **`ErrorCodes.java`** L1342 附近:加 `String APP_MSG_WALLET_DETAIL_REMARK = "app.msg.wallet.detail.remark";`
+8. **i18n 三份 properties**(messages_zh_CN / zh_HK / en,L446 后同步):
+ - zh_CN:`app.msg.wallet.detail.remark=(备注:{0})`
+ - zh_HK:`app.msg.wallet.detail.remark=(備註:{0})`
+ - en:`app.msg.wallet.detail.remark= (Note: {0})`
+
+效果示例:`充值已到账:饭卡钱包增加100.00元,余额200.00元(备注:九月补贴发放)`。该 content 即为 App 列表正文(2 行截断)和极光推送通知栏文案。
+
+## 前端改动(biz_zax_app_cloud,3 个文件)
+
+1. **`src/sheep/api/app-message.ts`** `AppWalletMessageDetail`(L127-140):加 `remark?: string`。
+2. **`src/pages/message/detail.vue`** 钱包变动行(L56-64):余额行下方按需追加备注行(`hasRemark` 判断空白,沿用 wallet/detail.vue 的 `Boolean(String(v?.remark || "").trim())` 模式),样式 `mt-6rpx text-22rpx color-#98a2b3 break-all`,不做行数截断(详情页展示完整备注)。
+3. **`src/i18n/pages/message/{zh-cn,zh-hk,en}.ts`**:加 `transactionRemark`:zh-cn `"备注:{remark}"`、zh-hk `"備註:{remark}"`、en `"Remark: {remark}"`。
+
+列表页 `list.vue` **不需要改**:正文来自服务端拼接的 content,remark 进模板后自动显示。
+
+## 无需改动的环节(已核实)
+
+- 极光推送侧(`ThirdPushDeliveryServiceImpl.processOne` / `JPushProvider` / `ThirdThirdJgPushServiceImpl`):直接透传消息 title/content,备注进 content 后自动到达通知栏。
+- 监护人(RELATION)消息:包裹本人 title/content,自动携带。
+- `WalletMessageEventDto`:details 列表元素加字段后自动携带。
+
+## 已知限制(产品语义说明)
+
+- Outbox 为交易时快照:流水创建**之后**再通过 `PUT /wallet-transaction/update-remark` 补写/修改的备注,不会同步到已发出的通知(通知已投递);创建时已带 remark 的场景(充值导入审批等)完整覆盖。
+- 历史消息 payload 无 remark,多语言重渲染不追加备注段,行为不变。
+
+## 验证
+
+- 后端:在 biz-api-cloud-zax 仓库根目录 `mvn -pl pjcloud-wallet/pjcloud-wallet-biz,pjcloud-thirdparty/pjcloud-thirdparty-biz -am compile -DskipTests`
+- 前端:`pnpm type-check`,与既有基线 17 个错误对比(不新增错误即通过)
+- DDL 需要单独在数据库执行后才生效(部署时执行)
\ No newline at end of file
diff --git a/src/i18n/pages/message/en.ts b/src/i18n/pages/message/en.ts
index 1f0aafa..d1de675 100644
--- a/src/i18n/pages/message/en.ts
+++ b/src/i18n/pages/message/en.ts
@@ -37,6 +37,7 @@ export default {
walletChange: "Wallet changes",
wallet: "Wallet",
balanceAfter: "Balance after change {balance}",
+ transactionRemark: "Remark: {remark}",
verifyInfo: "Redemption info",
mealContent: "Meal",
orderNo: "Order No.",
diff --git a/src/i18n/pages/message/zh-cn.ts b/src/i18n/pages/message/zh-cn.ts
index 730f70f..3846e0f 100644
--- a/src/i18n/pages/message/zh-cn.ts
+++ b/src/i18n/pages/message/zh-cn.ts
@@ -37,6 +37,7 @@ export default {
walletChange: "钱包变动",
wallet: "钱包",
balanceAfter: "变动后余额 {balance}",
+ transactionRemark: "备注:{remark}",
verifyInfo: "核销信息",
mealContent: "用餐内容",
orderNo: "订单编号",
diff --git a/src/i18n/pages/message/zh-hk.ts b/src/i18n/pages/message/zh-hk.ts
index 5207284..b4f862f 100644
--- a/src/i18n/pages/message/zh-hk.ts
+++ b/src/i18n/pages/message/zh-hk.ts
@@ -37,6 +37,7 @@ export default {
walletChange: "錢包變動",
wallet: "錢包",
balanceAfter: "變動後餘額 {balance}",
+ transactionRemark: "備註:{remark}",
verifyInfo: "核銷信息",
mealContent: "用餐內容",
orderNo: "訂單編號",
diff --git a/src/pages/message/detail.vue b/src/pages/message/detail.vue
index 10ebcca..c293df8 100644
--- a/src/pages/message/detail.vue
+++ b/src/pages/message/detail.vue
@@ -57,6 +57,7 @@
{{ detail.walletName || t("mobile.message.wallet") }}
{{ t("mobile.message.balanceAfter", { balance: formatBalance(detail.balance) }) }}
+ {{ remarkText(detail) }}
{{ formatAmount(detail.amount) }}
@@ -161,6 +162,11 @@ const formatAmount = (amount: number): string => {
const formatBalance = (balance: number): string => `¥${((Number(balance) || 0) / 100).toFixed(2)}`
+const remarkText = (detail: AppWalletMessageDetail): string => {
+ const remark = String(detail.remark || "").trim()
+ return remark ? t("mobile.message.transactionRemark", { remark }) : ""
+}
+
const loadMessage = async () => {
if (!state.messageId || state.loading) return
state.loading = true
diff --git a/src/sheep/api/app-message.ts b/src/sheep/api/app-message.ts
index 2d165f1..7bf9eaf 100644
--- a/src/sheep/api/app-message.ts
+++ b/src/sheep/api/app-message.ts
@@ -135,6 +135,8 @@ export interface AppWalletMessageDetail {
amount: number
/** 变动完成后的余额,单位分。 */
balance: number
+ /** 流水备注快照,由后台操作人员补充业务说明,最多256字符,可为空。 */
+ remark?: string
/** 钱包业务类型持久化编码。 */
walletBizType: string
}