fe97f49afe
- 修复专区商品抽屉分页中20/100条/页按键无效,增加动态分页参数支持 - 修复商城商品导出功能无反应问题,调整loading初始值保证导出流程执行 - 支持商品导出携带当前筛选条件,保证导出数据符合筛选结果 - 商品导出增加封面图路径列,导出URL文本方式避免跨域限制 - 优化UserSelectModal手机号码展示,改为优先展示真实号码字段 - 相关组件调整分页及导出事件参数,提升交互准确性与稳定性
25 KiB
25 KiB
2026-08-17 工作日志
专区商品「移除」假成功 bug 修复
- 现象:guilixu.websoft.top/special/zone 移除专区商品提示成功,刷新(重查库)后商品仍在。
- 根因:
ShopHomeSectionController.removeGoods用listByIds+updateBatchById改shop_goods.section_ids;单专区商品移除后 section_ids 变 null,但ShopGoods.sectionIds无更新策略注解,MP 全局默认NOT_NULL会忽略 null 值 → 不生成SET section_ids=NULL→ 库字段保持原值(假成功)。多专区商品(变非 null)正常,故仅单专区场景坏。 - 修复:
addGoods/removeGoods改用UpdateWrapper.set("section_ids", newVal).eq("goods_id", id)显式更新(newVal 可为 null),绕过字段策略。文件:guilixu-javaShopHomeSectionController.java。 - 部署:需重新编译部署 guilixu-java(线上 shop-api)后端生效;前端无需改动。添加用同样模式统一修复。
- 验证:部署后用单专区商品移除测试,刷新不应再出现。
- 注:本机环境无 maven,未本地编译;改动为标准 MP 用法(IService.update(Wrapper) / UpdateWrapper.set 允许 null)。
专区白名单功能诊断(功能当前不可用)
- 设计意图:专区设为"受限专区"(restricted=1) 后,该专区商品仅白名单用户可用余额购买;小程序结算页 checkout.tsx 已调
check-permission前端拦截。 - 致命错配:后台白名单弹窗
UserSelectModal.vue用pageUsers(@/api/system/user → sys_user 后台员工) 选用户;后端ShopHomeSectionController.checkPermission用getLoginUser().getUserId()(= shop_user 小程序买家 userId)。两套用户体系 id 不一致 → 白名单里加的任何人(后台员工)对真实买家都匹配不上 → 受限专区对买家永远拦截/强制余额,白名单形同虚设。 - 次要隐患:后端创建订单接口未做白名单强校验,仅前端拦截,可被绕过。
- 修复方向:① 白名单弹窗数据源从
pageUsers(sys_user) 改为pageShopUser(@/api/shop/shopUser → shop_user 买家),使存的 user_id 与校验 userId 同体系;② 后端下单接口加白名单强校验防绕过。后台已有 pageShopUser 可用。
专区白名单:用户体系澄清 + 后端强校验(用户 2026-08-17 01:50 指令)
- 用户澄清:本项目的买家(小程序用户)就是
sys_user体系,pageShopUser实际不用/返回空。故白名单弹窗用pageUsers(sys_user) 是正确的,之前"用户体系错配"判断为误判。 - 白名单弹窗
UserSelectModal.vue现状(8-16 已改):pageUsers({ keywords, ... }),不传 isStaff(搜索覆盖全部 sys_user)。源码无需再改。已 grep 确认 zone 目录下无残留 isStaff/pageShopUser。 - 后端补「受限专区白名单强校验」:
OrderBusinessService.java新增- import:
ShopHomeSectionService、ShopHomeSectionUserService、QueryWrapper、java.util.Set/LinkedHashSet; @Resource注入homeSectionService、homeSectionUserService;createOrder在validateDeliveryRegionIfNeeded之后调用validateSectionPermissionIfNeeded(request, shopOrder, loginUser);- 新方法逻辑:遍历
request.goodsItems→ 取ShopGoods.sectionIds→ 找 restricted=1 的专区 → 校验loginUser.getUserId()是否在shop_home_section_user(count>0),否则抛BusinessException("该商品属于受限专区,仅限指定白名单用户购买")。
- import:
- 作用:前端
check-permission的后端兜底,防止直接调/shop/shop-order下单绕过白名单。 - 部署:需重新编译部署 guilixu-java(shop-api)。前端无需改动。
- 注:本机无 maven,未本地编译;改动为标准 MP 用法(IService.count(QueryWrapper) / getById)。
- 待确认:用户 "2.帮我补" 指令只写了前半句,已按上文补后端强校验;若其本意是"补菜单记录"(专区管理入口,动态路由待插入),需另出 INSERT SQL(菜单表结构待确认)。
专区白名单弹窗 checkbox 不显示(第三次修复,根因确认)
- 现象:白名单弹窗数据正常(12 条用户),但表格无 checkbox 勾选列,用户无法选择。
- 已尝试修复(前两次均未生效):
- 8-16:
reactive→computed+columnWidth: 48(与 shopCoupon 对齐) - 同期:去掉
isStaff: true
- 8-16:
- 真正根因(读
ele-pro-table源码node_modules/ele-admin-pro/es/ele-pro-table/index.js第 94-114 行确认):ele-pro-table内部tableSelectionTypecomputed 有前置条件:必须传selection、current或selectionType="radio"三者之一,否则返回undefined- 返回 undefined →
tableRowSelection也返回 undefined → ant-design-vue Table 收到rowSelection=undefined→ 不渲染 checkbox 列 - 我们的弹窗三个条件都不满足(没传 :selection / :current / selectionType),所以不管 row-selection 配置多正确都不会出勾选框
- 最终修复:模板
<ele-pro-table>加selection-type="checkbox"(第 18 行),使源码判断走通:props2.selectionType !== "radio"为 true(是 "checkbox")→ 不走 early return → 返回 "checkbox" → checkbox 列正常渲染。 - 改动文件:
src/views/special/zone/components/UserSelectModal.vue(仅模板加 1 个 prop) - 部署:重新构建前端即可(
npm run dev热更新或npm run build部署)。
专区白名单弹窗 checkbox 修复(8-17 纠正:8-16 修复实际无效)
- 反馈:用户截图仍无勾选框,8-16 加的
selection-type="checkbox"未生效。 - 重读 ele-pro-table 源码确认 8-16 根因判断错误(
node_modules/ele-admin-pro/es/ele-pro-table/index.js94-103 行):三个条件同时满足才 return。即const noSelection = typeof props2.selection === "undefined"; const noCurrent = typeof props2.current === "undefined"; if (noSelection && noCurrent && props2.selectionType !== "radio") { return; // 不渲染 }noSelection && noCurrent && selectionType !== "radio"。我传的selection-type="checkbox"让selectionType !== "radio"为 true,反而满足了 early return 条件 → 不渲染。这正是 8-16 修复无效的真因。 - 另外发现
tableRowSelection.selectedRowKeys强制用内部 ref(源码 111 行),不支持外部初始化已选——即使绕过 selection 限制,弹窗打开时已选的人也不会显示勾选。 - 正确修复:弃用 ele-pro-table 的 selection 机制,将
UserSelectModal.vue重写为 antda-table:- 受控
selectedRowKeys,watch props.visible 时用props.selectedUserIds初始化 → 打开弹窗已选即勾选 rowSelectioncomputed:{ columnWidth:48, selectedRowKeys, onChange }- datasource 用
pageUsers包成 Promise,分页用 antdpaginationreactive,@change调 reload - search
a-input-search,@search/@pressEnter reload - confirm emit
selectedRowKeys
- 受控
- 字段已与 User 模型对齐(userId/realName/mobile/nickname/organizationName),
PageResult<T>={list,count}。 - 改动文件:
src/views/special/zone/components/UserSelectModal.vue(整体重写约 130 行)。 - 部署:刷新页面(
npm run dev热更新)或重新构建 admin 前端即可。无需后端改动。
专区小程序码(扫码直接进入专区)
- 需求:/special/zone 专区管理加「二维码」入口,生成该专区的小程序码,用户微信扫码直接进入小程序对应专区。
- 后端(guilixu-java
ShopHomeSectionController.java):新增GET /api/shop/shop-home-section/{id}/qrcode- 调微信
getwxacodeunlimit生成无限场景码;scene=sectionId=xxx,page=pages/shop/section-detail;按专区tenantId经WxMiniappAccessTokenService.getAccessToken(tenantId)取 token;prod 用release否则trial(与现有 getOrderQRCodeUnlimited 一致)。 - 复用 Hutool
HttpRequest调微信,返回 PNG 流;微信出错时返回 JSON 并识别application/json。
- 调微信
- 用户端小程序(guilixu-taro
pages/shop/section-detail.tsx):解析useRouter().params.scene(小程序码扫码透传的sectionId=xxx),兼容原?sectionId=普通跳转。 - 管理后台(guilixu-admin
views/special/zone/index.vue+api/shop/shopZone):列表操作列加「二维码」按钮 → 弹窗显示小程序码图片;新增getSectionQrcode(id)(responseType blob → objectURL,遇 JSON 错误解析 message 并 reject)。 - 部署:① 重新编译部署 guilixu-java(shop-api)使新接口生效;② 重新构建前端 admin 与 taro 小程序(section-detail 需重新发布/体验版,因小程序码 page 指向已发布页面)。
- 注:本机无 maven,后端未本地编译;改动完全复用 WxLoginController 既有 getwxacodeunlimit 写法。
- 限制:getwxacodeunlimit 的 page 必须已存在于小程序(pages/shop/section-detail 已在 app.config 的 pages 列表);scene 仅限可见字符、≤32 位,
sectionId=xxx满足。
专区小程序码报 41030 invalid page 修复
- 现象:后台点「二维码」生成小程序码,微信返回
{"errcode":41030,"errmsg":"invalid page"}。 - 根因:原代码按 profile 决定 env_version——active=dev 时走
trial(体验版)。微信 41030=所请求版本的小程序代码包里没有该页面。页面pages/shop/section-detail在源码 app.config 存在,但体验版小程序没上传含此页面的代码 → 失败。 - 修复:
- 后端(ShopHomeSectionController.getSectionQrcode):去掉按 profile 判断,改为
envVersion请求参数,@RequestParam(defaultValue="release"),env_version直接用该参数(release/trial/develop)。 - 前端(admin):
getSectionQrcode(id, envVersion='release')支持传参;弹窗加「正式版/体验版/开发版」RadioGroup(默认正式版),切换即重新生成。
- 后端(ShopHomeSectionController.getSectionQrcode):去掉按 profile 判断,改为
- 关键前提(务必告诉用户):生成成功 ≠ 扫码能进专区。
- 生成码所请求的版本(正式/体验)其代码包必须包含
pages/shop/section-detail页面,否则仍 41030。 - 扫码能正确进专区,还要求把「能解析 scene 的 section-detail.tsx」发布到同一版本:正式版需发版、体验版需上传体验版、开发版需开发者工具预览。
- 若默认正式版仍 41030,说明线上版本也没有此页面 → 需先发布小程序(该页面虽在 app.config,但可能未上线)。
- 生成码所请求的版本(正式/体验)其代码包必须包含
- 部署:需重新编译部署 guilixu-java + 重新构建发布 taro 小程序(到目标版本)。
专区白名单「添加/移除」功能确认 + tenantId 修复
- 现状确认:
shop_home_section_user白名单的「添加/移除」功能此前已完整实现,本次只是排查确认:- 后端
ShopHomeSectionController:GET /{id}/users(查)、PUT /{id}/users(覆盖式保存);ShopHomeSectionUserService.listBySectionId→selectBySectionId(XML)。 - 前端
index.vue:列表「白名单」按钮 →openUsers调listSectionUsers加载已选 → 弹窗;onSaveUsers调setSectionUsers保存。 UserSelectModal.vue:用pageUsers(sys_user) 选人,勾选=添加、取消=移除、保存=覆盖提交;columns 与 User 模型字段(userId/realName/mobile/nickname/organizationName)已核对匹配。
- 后端
- 真 bug 修复:后端
setUsers新建ShopHomeSectionUser时未设 tenantId(实体有该字段,本项目手动多租户)。若表tenant_id有 NOT NULL 约束会插入报错;即便不报错也缺租户归属。- 修复:从专区
homeSectionService.getById(id).getTenantId()取租户,set 到每条白名单记录(ShopHomeSectionController.setUsers,line ~119)。 - 查询侧(
selectBySectionId)按section_id隔离,未动;下单强校验checkPermission也按 section_id 隔离,一致。
- 修复:从专区
- 用户体系统一结论(沿用 01:50 澄清):买家=sys_user,
pageUsers选人正确,白名单 user_id 与下单校验 userId 同体系。 - 部署:重新编译部署 guilixu-java(shop-api)生效后,后台 /special/zone 每条专区「白名单」即可勾选添加、取消移除并保存。
白名单弹窗搜索报错修复([object PointerEvent] 误作 limit 传给后端)
- 现象:白名单弹窗点搜索触发 400:
BindException ... Field error in object 'userParam' on field 'limit': rejected value [[object PointerEvent]]。 - 根因:重写后的
UserSelectModal.vue模板@search="reload"/@pressEnter="reload"。antda-input-search的search事件签名是(value, event),故reload实际收到reload(搜索词, PointerEvent);reload(page, limit)把第二个参数当limit传给pageUsers,pageSize变成 PointerEvent → 序列化[object PointerEvent]传给后端limit字段 → 类型转换失败。 - 修复:模板改为
@search="() => reload(1)"/@pressEnter="() => reload(1)",只传页码、不传事件对象;reload(1)时limit=undefined→pageSize回退pagination.pageSize。 - 改动:
UserSelectModal.vue两行模板。 - 部署:刷新 admin 前端(
npm run dev热更新或重新构建)即可。
白名单保存报 Duplicate entry(逻辑删除×唯一索引死局)
- 现象:保存专区白名单
PUT /{id}/users报SQLIntegrityConstraintViolationException: Duplicate entry '1-35771-1' for key 'shop_home_section_user.uk_section_user',失败 SQL 是UPDATE shop_home_section_user SET deleted=1 WHERE tenant_id=10606 AND deleted=0 AND section_id=?(MP 逻辑删除)。 - 根因(已确证):
add_shop_home_section.sql:40定义UNIQUE KEY uk_section_user (section_id, user_id, deleted)——唯一索引包含 deleted 列;而实体ShopHomeSectionUser上有@TableLogic(逻辑删除)。setUsers用「remove全部 +saveBatch」覆盖式保存,remove被 MP 转成UPDATE SET deleted=1;历史多次保存已囤积deleted=1旧行,下次再把某条deleted=0行改成deleted=1就与旧deleted=1行撞唯一键。 - 修复(绕过逻辑删除,用物理删除):
ShopHomeSectionUserMapper.java新增int physicsDeleteBySection(@Param sectionId, @Param tenantId);ShopHomeSectionUserMapper.xml新增<delete id="physicsDeleteBySection"> DELETE FROM shop_home_section_user WHERE section_id=? <if tenantId not null>AND tenant_id=?</if> </delete>(自定义 SQL,MP 不会注入逻辑删除 → 真物理删除);ShopHomeSectionController.setUsers把homeSectionUserService.remove(new QueryWrapper...eq("section_id", id))换成homeSectionUserMapper.physicsDeleteBySection(id, currentTenantId),再saveBatch。每次保存前把该专区所有行(含 deleted=1 残留)真正删掉再插新行,不再囤积,不撞键。selectBySectionId已带deleted=0过滤,查询侧无影响。
- 说明:此表使用逻辑删除 + 含 deleted 的唯一索引本就是反模式;本修复用物理删除规避,安全且低风险(本机无 maven 未编译)。前端无需改动。
- 遗留(无害):其他未再保存过的专区可能仍有历史 deleted=1 重复行,因
selectBySectionId过滤 deleted=0 且保存已改物理删除,不影响业务;如需彻底清可用DELETE FROM shop_home_section_user WHERE deleted=1 GROUP BY section_id,user_id HAVING COUNT(*)>1之类语句(谨慎,先备份)。
白名单弹窗改为商品式(打开列已加、搜索追加、单条即时增删)
- 用户反馈:旧版覆盖式勾选弹窗「勾了别的用户后前面勾过的又不见了」。
UserSelectModal.vue重写,统一成与专区「商品」抽屉一致的交互:打开只列已添加的白名单用户;搜索手机/姓名/昵称出候选,点「+添加」即时入库、点「移除」即时删。 - 根因(旧交互):覆盖式保存依赖
selectedRowKeys跨打开/重渲染保持,易丢;且setUsers覆盖写遇到唯一键冲突会整体失败。商品式用「单条即时增删」彻底规避。 - 后端(guilixu-java
ShopHomeSectionController):GET /{id}/users改为联表返回用户详情List<User>(realName/mobile/nickname/organizationName/userId),不再只返回关系行(旧返回 ShopHomeSectionUser 仅含 userId,前端展示空白)。新增注入UserService,先取关系行再userService.listByIds取详情。- 新增
POST /{id}/usersaddUsers:追加用户,先查已存在 userIds 跳过(防 uk_section_user 唯一键冲突),再saveBatch,带 tenantId。 - 新增
DELETE /{id}/usersremoveUsers:物理删除指定用户,调homeSectionUserMapper.physicsDeleteBySectionAndUsers(id, userIds, tenantId)(新增 mapper/XML 方法,foreach user_id IN,绕过 @TableLogic)。 - 旧
PUT /{id}/userssetUsers(覆盖式)保留兼容,前端不再使用。 - 原
users用的homeSectionUserService.listBySectionId不再调用(改用list(new QueryWrapper...))。
- 前端:
api/shop/shopZone/index.ts:listSectionUsers返回类型改User[](import systemUser,移除SectionUser);新增addSectionUsers(id, userIds)(POST)、removeSectionUsers(id, userIds)(DELETE)。components/UserSelectModal.vue整体重写:props(visible,sectionId),内部 watch(visible) 调listSectionUsers加载已加名单;pageUsers({keywords})搜索候选(排除已加);addOne/removeOne即时调接口并重载;移除 footer 与@confirm,改用:footer="null"。index.vue:弹窗调用去掉:selectedUserIds/@confirm;openUsers简化为只置currentSectionId+开弹窗;删除onSaveUsers、currentUserIds、未用 import(setSectionUsers/listSectionUsers在 index 内已无引用)。
- 后端
users关键字搜索:sys_userUserParam.keywords已覆盖 username/user_id/nickname/real_name/alias/phone(含手机、姓名、昵称),满足需求。 - 部署:重新编译部署 guilixu-java(shop-api)+ 重新构建 admin 前端。本机无 maven 未编译;改动为标准 MP/MyBatis 用法,风险低。
专区白名单弹窗改为右侧抽屉(modal → drawer)
- 用户要求:专区「白名单」入口的交互与同页「商品」一致,改成右边弹出的抽屉。
- 改动:
src/views/special/zone/components/UserSelectModal.vue外层容器由<a-modal>改为<a-drawer placement="right" :width="820">,内部搜索/候选/已添加列表逻辑原样保留,props/emits(visible/sectionId/update:visible) 不变。 index.vue中<UserSelectModal v-model:visible="showUser" :sectionId="currentSectionId" />调用方式无需改动(与商品抽屉同为右侧弹出)。- 部署:重新构建 admin 前端(npm run dev 热更新或 build)即可,无需后端改动。
专区白名单手机号改为不脱敏
- 需求:专区「白名单」抽屉里手机号不要脱敏显示。
- 根因:系统 User 实体
mobile是@TableField(exist=false)的脱敏字段(getMobile()返回DesensitizedUtil.mobilePhone(phone));phone才是 DB 真实号码,无@JsonIgnore、无全局脱敏 → 接口同时返回phone(真实) 与mobile(脱敏)。 - 改动:
UserSelectModal.vue两处展示由u.mobile改为u.phone(候选行u.phone || u.mobile || '-';表格列dataIndex:'phone'+customRender回退record.mobile),后端无需改动。 - 部署:重新构建 admin 前端即可。
专区商品抽屉分页「20/100 条/页」不可用修复
- 现象:专区商品抽屉右下角切 20/100 条/页不生效,始终只展示 10 条。
- 根因:
src/views/special/zone/index.vue中商品表格的:pagination把pageSize: 10写死,且onChange只接收page参数、未处理pageSize;翻页事件里还误写成goodsPage = page(应.value)。 - 修复:
- 新增
goodsPageSize = ref(10); loadGoods请求参数limit改为goodsPageSize.value;- 分页配置改为
pageSize: goodsPageSize、showSizeChanger: true,onChange(page, pageSize)同时更新goodsPage.value与goodsPageSize.value后调loadGoods。
- 新增
- 改动文件:
src/views/special/zone/index.vue。 - 部署:重新构建 admin 前端即可。
商城商品导出「完全无反应」修复(/shop/shopGoods 导出功能不可用)
- 现象:/shop/shopGoods 点「导出xls」完全没反应(无下载、无报错提示)。
- 根因:
src/views/shop/shopGoods/index.vue第236行const loading = ref(true);,而handleExport第一行if (loading.value) return;。loading这个变量只有handleExport自己会改(导出中设 true / 结束或失败设 false),列表加载的reload()(只调tableRef.reload)、query()(只加载分类树)从不碰它 → 页面加载后 loading 永远是初始的true→ 导出首行被永久拦截、逻辑从未执行。 - 已排除项:按钮 emit、后端
/shop/shop-goods返回ApiResult<List<ShopGoods>>、xlsx@0.18.5 依赖、viteoptimizeDeps.include:['xlsx']均正常——不是接口/依赖/打包问题。 - 修复(按用户"修守卫+带筛选导出"):
index.vue第236行ref(true)→ref(false)(loading 恢复成"导出中防重复点击"语义,首击可进入)。- 导出携带当前筛选:
search.vueemit 签名(e:'export', where?: ShopGoodsParam),handleExportemit('export', where);index.vuehandleExport(where?)调listShopGoods(where || {})(原listShopGoods({})导出全部、忽略筛选)。where 来自 search.vue 的useSearch<ShopGoodsParam>,与列表 datasource 用的 where 同源,完全复现筛选。
- 改动文件:
src/views/shop/shopGoods/index.vue、src/views/shop/shopGoods/components/search.vue(共5处小改)。 - 部署:重新构建 admin 前端(npm run dev 热更新或 npm run build)即可,无需后端改动。
- 验证清单:① 进 /shop/shopGoods 点「导出xls」应弹"正在准备导出数据"并下载 xlsx;② 先筛选分类/关键词/状态再导出,xlsx 内容应与筛选结果一致;③ 导出中连点不应重复触发(loading 防重生效)。
商城商品导出增加「封面图」路径列(用户改主意:不内嵌图片,只导出路径)
- 背景:用户原想 Excel 内嵌封面图(前端 fetch OSS 图→base64→xlsx !images),但 OSS(oss.wsdns.cn) 与 admin(websoft.top) 跨域,浏览器 fetch 会被 CORS 拦截;且逐张下载会导致导出变慢、xlsx 体积暴涨。用户明确改为「图片导出路径就行了」——即 Excel 里加一列封面图 URL 文本。
- 实现:
src/views/shop/shopGoods/index.vue的handleExport导出列末尾新增「封面图」列,值为ensureFullUrl(goods.image)(@/utils/image的 ensureFullUrl:相对路径补成https://oss.wsdns.cn/...完整 URL,已是 http(s) 原样返回)。表头/每行/!cols列数均由 10 增到 11,封面图列宽 wch:50。 - 补 import:
import { ensureFullUrl } from '@/utils/image';(紧接 xlsx 的 import 之后)。 - 改动文件:
src/views/shop/shopGoods/index.vue(handleExport 内共 4 处:import / 表头 / forEach / !cols)。 - 说明:Excel 单元格中是 URL 文本,运营复制/点开即可在浏览器看原图;不是内嵌缩略图。OSS 图片无 CORS 依赖,导出不再受跨域影响。
- 部署:重新构建 admin 前端即可,无需后端改动。
注册页复制:website-admin → guilixu-admin 的表选型分析
- 用户想复制 website-admin 的
/register(四步建站:邮箱验证→企业信息→站点初始化→开通)到 guilixu-admin。 - 关键事实:
- website-admin 注册「创建站点」调
@/api/cms/site.createSite→POST /api/cms/cms-website,落 modules.cms_website(mp-java,cms-api.websoft.top)。superAdminRegister(建租户)走其主后端 SERVER_API_URL。 - guilixu-admin 现有
views/passport/register|register2调createCmsWebSite→SERVER_API_URL/superAdminRegister;但 guilixu-java 里无 superAdminRegister 方法(仅 SecurityConfig 放行/api/cms/website/createWebsite)→ 该端点生产上实际未接通/404。 - guilixu-admin 的 cms 站点管理 UI(
api/cms/cmsWebsite)走CMS_API_BASE_URL=cms-api.websoft.top= mp-java/modules,即 modules.cms_website。 - db_guilixu(guilixu-java)没有 cms_website 表:全仓搜 CmsWebsite/cms_website 仅 MybatisPlusConfig 一行被注释的
"cms_website";有shop_setting(@TableName("shop_setting"),字段 category/settingKey/settingValue = K/V 商城配置,非站点主记录)。
- website-admin 注册「创建站点」调
- 结论(待与用户确认):复制注册应选 modules.cms_website(走 CMS_API_BASE_URL,与 website-admin 的 createSite、guilixu-admin 现有 cmsWebsite UI 完全一致),不要用 db_guilixu.shop_setting(语义不符)+ db_guilixu.cms_website 根本不存在。另需决定:guilixu-admin 是单租户(10606)后台,注册多半只「在 10606 下建微官网」而非新建租户 → 应跳过 superAdminRegister,仅保留 createSite(cms_website) 一步。