|
|
@@ -9,7 +9,7 @@
|
|
|
style="margin-bottom: 12px"
|
|
|
:title="
|
|
|
isSuperAdmin
|
|
|
- ? '手工登记商户号。收款前必须先在这里登记一行 —— 下单时提示「未配置商户号」就是这里还没登记。新增时要选择归属租户;企业 ID 留空 = 整个租户共用这个号;填了 = 只有这家企业用。'
|
|
|
+ ? '手工登记商户号。收款前必须先在这里登记一行 —— 下单时提示「未配置商户号」就是这里还没登记。新增时要选择归属租户;一个租户可以登记多个商户号,下单时用 merchant_code 指定用哪一个(不指定且只有一个时才自动选中)。'
|
|
|
: '这里显示的是本租户已登记的商户号(只读)。商户号由平台运营录入,如需新增或修改请联系平台运营。'
|
|
|
"
|
|
|
/>
|
|
|
@@ -19,7 +19,7 @@
|
|
|
<el-form-item label="关键字">
|
|
|
<el-input
|
|
|
v-model="query.keyword"
|
|
|
- placeholder="商户号 / 商户名 / 企业ID"
|
|
|
+ placeholder="商户号 / 商户名"
|
|
|
clearable
|
|
|
style="width: 260px"
|
|
|
@keyup.enter="handleSearch"
|
|
|
@@ -41,14 +41,6 @@
|
|
|
<el-table-column v-if="isSuperAdmin" label="租户" min-width="140">
|
|
|
<template #default="{ row }">{{ tenantName(row.tenant_id) }}</template>
|
|
|
</el-table-column>
|
|
|
- <!-- ★ 留空的 enterprise_id 必须显示成「租户级」而不是空白格:
|
|
|
- 空单元格与「这一列没数据」无法区分,管理员看不出哪一行是租户级兜底映射。 -->
|
|
|
- <el-table-column label="企业 ID" min-width="180">
|
|
|
- <template #default="{ row }">
|
|
|
- <el-tag v-if="!row.enterprise_id" type="warning" size="small">租户级</el-tag>
|
|
|
- <span v-else>{{ row.enterprise_id }}</span>
|
|
|
- </template>
|
|
|
- </el-table-column>
|
|
|
<el-table-column prop="mch_no" label="商户号" min-width="160" />
|
|
|
<el-table-column prop="shop_no" label="门店号" min-width="140" />
|
|
|
<el-table-column prop="merchant_name" label="商户名称" min-width="180" />
|
|
|
@@ -110,14 +102,12 @@
|
|
|
/>
|
|
|
</el-select>
|
|
|
</el-form-item>
|
|
|
- <!-- ★ 选填(2026-09-22 去企业化):留空 ⇒ 这一行是**租户级**映射,
|
|
|
- 下单时不带 enterprise_id 的请求都会落到它上面。 -->
|
|
|
- <el-form-item label="企业 ID" prop="enterprise_id">
|
|
|
- <el-input
|
|
|
- v-model="form.enterprise_id"
|
|
|
- placeholder="可空 —— 留空即租户级(该租户下所有下单可用)"
|
|
|
- />
|
|
|
- </el-form-item>
|
|
|
+ <!-- ★ 2026-09-30 去企业化:这里原先还有一个「企业 ID」(选填,留空 = 租户级)。
|
|
|
+ 乐收赢与企业概念无关,那一格是整个模块里最后两个企业维度的消费者之一
|
|
|
+ (另一个是下单入口的寻址),两者本批都已拿掉;后端 `LsyMerchantEntity`
|
|
|
+ 的 `enterpriseId` 字段也已删。**别再把它加回来**:加了就是一个
|
|
|
+ 填了也无效的输入框 —— 后端没有这个字段,`FAIL_ON_UNKNOWN_PROPERTIES`
|
|
|
+ 会让整个保存请求报错(见 `LsyMerchantService.save` 的 javadoc)。 -->
|
|
|
<el-form-item label="商户号" prop="mch_no">
|
|
|
<el-input v-model="form.mch_no" placeholder="请输入商户号" />
|
|
|
</el-form-item>
|
|
|
@@ -199,18 +189,20 @@ const formVisible = ref(false);
|
|
|
const formRef = ref();
|
|
|
|
|
|
/**
|
|
|
- * 表单**只认**这 7 个键(`id` + `tenant_id` + 5 个业务字段)。其余字段(含服务端将来新增的)一律不得进入表单模型 ——
|
|
|
+ * 表单**只认**这 6 个键(`id` + `tenant_id` + 4 个业务字段)。其余字段(含服务端将来新增的)一律不得进入表单模型 ——
|
|
|
* `buildForm` 是按这张白名单**逐键取值**的,不是把服务端整行摊进来。
|
|
|
*
|
|
|
* ★ `tenant_id` 是 2026-09-30 加进来的(超管代录要选归属)。加了它就会**在编辑态被回传**,
|
|
|
* 而后端编辑分支一律忽略这个值(改归属在结构上不成立,见 `LsyMerchantService#save` 的
|
|
|
* javadoc)—— 那不是「多传了一个没用的键」:不放进白名单的话,`buildForm` 会把它丢掉,
|
|
|
* 下拉框在编辑态就是空的。
|
|
|
+ *
|
|
|
+ * ★ 同一天去掉的 `enterprise_id`(原第 3 项):后端实体已删该字段,留着它会让保存请求
|
|
|
+ * 撞 `FAIL_ON_UNKNOWN_PROPERTIES` 直接报错 —— 不是「多传一个被忽略的键」。
|
|
|
*/
|
|
|
const FORM_FIELDS = [
|
|
|
"id",
|
|
|
"tenant_id",
|
|
|
- "enterprise_id",
|
|
|
"mch_no",
|
|
|
"shop_no",
|
|
|
"merchant_name",
|
|
|
@@ -220,13 +212,12 @@ const FORM_FIELDS = [
|
|
|
/**
|
|
|
* ★ 键名必须 snake_case:后端 `@RequestBody LsyMerchantEntity` 走全局 SNAKE_CASE 反序列化。
|
|
|
*
|
|
|
- * ★ 可空列(V1.8 DDL:`shop_no` / `merchant_name` / `description`,2026-09-22 起加上
|
|
|
- * `enterprise_id`)的初值是 `null` 而**不是** `""`:
|
|
|
- * 这四列的语义是「空 ⇒ 库里 NULL」,而 `""` 与 `NULL` 在库里是两回事 ——
|
|
|
+ * ★ 可空列(V1.8 DDL:`shop_no` / `merchant_name` / `description`)的初值是 `null`
|
|
|
+ * 而**不是** `""`:这三列的语义是「空 ⇒ 库里 NULL」,而 `""` 与 `NULL` 在库里是两回事 ——
|
|
|
* 表格里都显示空白,但 `WHERE shop_no IS NULL` 查不到 `''`,于是数据悄悄查不出来。
|
|
|
* 初值给 `""` 会让「打开新增表单、什么都不填直接保存」写出空串。
|
|
|
- * `enterprise_id` 上这条尤其致命:租户级映射就是靠 `enterprise_id IS NULL` 找的,
|
|
|
- * 存成 `''` 之后下单方直接报「未配置商户号」。
|
|
|
+ * (这句话原先还举了 `enterprise_id` 当「尤其致命」的例子 —— 那个字段已随去企业化删除,
|
|
|
+ * 例子连同字段一起作废,但规则本身对剩下这三列一字不变。)
|
|
|
* `el-input` 把 `null` 当空串显示(不会报错也不会显示 "null"),界面无差别。
|
|
|
*/
|
|
|
function emptyForm(): Record<string, any> {
|
|
|
@@ -236,7 +227,6 @@ function emptyForm(): Record<string, any> {
|
|
|
// 空串会绕过那道判断并以 "" 进 INSERT —— 而 tenant_id 是 bigint,""
|
|
|
// 在 PG 上直接是类型错误(报错位置离现场很远)。
|
|
|
tenant_id: null,
|
|
|
- enterprise_id: null,
|
|
|
mch_no: "",
|
|
|
shop_no: null,
|
|
|
merchant_name: null,
|
|
|
@@ -247,7 +237,7 @@ function emptyForm(): Record<string, any> {
|
|
|
/**
|
|
|
* ★ 白名单投影 —— **不要**改回 `Object.assign(form, row)` / `{ ...row }`。
|
|
|
*
|
|
|
- * 服务端回的是**整行**:除这 7 个键外还带 status / review_status / created_time / updated_time,
|
|
|
+ * 服务端回的是**整行**:除这 6 个键外还带 status / review_status / created_time / updated_time,
|
|
|
* 以及**以后新增的任何字段**。整行摊进表单会静默写坏数据(每一跳都有依据):
|
|
|
* · `status` / `review_status` —— 新增时,从上一行残留的非空值会**直接进 INSERT**
|
|
|
* (后端只在空值时才补默认值);编辑时后端已改成定向更新、不写这两列,
|
|
|
@@ -276,9 +266,7 @@ function buildForm(row?: any): Record<string, any> {
|
|
|
|
|
|
const form = ref<Record<string, any>>(emptyForm());
|
|
|
|
|
|
-// ★ `enterprise_id` 没有规则 —— 它是选填的(留空 = 租户级)。
|
|
|
-// 不要加回 required:那会把「配租户级映射」这条正常路径堵死在表单校验上,
|
|
|
-// 而服务端早就不认这个前提了(LsyMerchantService.save 只校验 mch_no)。
|
|
|
+// ★ 其余字段(shop_no / merchant_name / description)都没有规则:它们是选填的。
|
|
|
//
|
|
|
// ★ `tenant_id` 只在**新增**时必填(与后端 `save` 的新增分支同一条件)。
|
|
|
// 编辑态不加规则:归属改不了(下拉已置灰),而给旧数据卡一条必填会让超管
|
|
|
@@ -331,10 +319,15 @@ async function handleSubmit() {
|
|
|
}
|
|
|
|
|
|
async function handleDelete(row: any) {
|
|
|
- const scope = row.enterprise_id ? `企业「${row.enterprise_id}」` : "本租户";
|
|
|
- await ElMessageBox.confirm(`确认删除登记「${row.mch_no}」?删除后${scope}将无法下单。`, "提示", {
|
|
|
- type: "warning",
|
|
|
- });
|
|
|
+ // ★ 2026-09-30 去企业化:这里原先是 `row.enterprise_id ? \`企业「…」\` : "本租户"`。
|
|
|
+ // 企业那一维度没了,措辞改成被删的那一行自己的两项身份(商户号 + 归属租户),
|
|
|
+ // 比一句笼统的「本租户」更能让操作员确认自己删的是哪一行。
|
|
|
+ const owner = isSuperAdmin.value ? `(租户 ${tenantName(row.tenant_id)})` : "(本租户)";
|
|
|
+ await ElMessageBox.confirm(
|
|
|
+ `确认删除登记「${row.mch_no}」${owner}?删除后该商户号将无法下单。`,
|
|
|
+ "提示",
|
|
|
+ { type: "warning" }
|
|
|
+ );
|
|
|
await deleteLsyMerchant(row.id);
|
|
|
// 成功提示同上:由拦截器统一弹,页面不重复弹。
|
|
|
loadData();
|