diff --git a/README.md b/README.md
index e24feaad7..8713f80ab 100644
--- a/README.md
+++ b/README.md
@@ -162,19 +162,42 @@ lilishop-ui
## 8. 升级计划
-> 更新日期:2026-11-04,依据各端近期提交及当前代码实现同步。
-
### ✅ 已完成特性
-| 功能模块 | 功能模块 |
-| :--- | :--- |
-| ✅ 商品定时上下架 | ✅ 商品分组 / 会员分组 |
-| ✅ 商品虚拟销量 | ✅ 专用发票(发票上传) |
-| ✅ 置顶评论 | ✅ 客户等级体系 |
-| ✅ 购物卡 | ✅ 腾讯云-云直播 |
-| ✅ 卡密商品 | ✅ 二级分销 |
-| ✅ 定时任务管理(数据库配置驱动) | ✅ 预约服务商品 |
-| ✅ 主题色管理 | ✅ 立减优惠券 |
-| ✅ 小程序订单管理(简单版) | ✅ 微信订单自动上报开关 |
+
+按可核实的实现或完善时间倒序记录;日期表示代码完成或功能更新时间,不代表生产上线时间。
+
+| 时间 | 功能模块 | 完成内容 |
+| :--- | :--- | :--- |
+| 2026-11-05 | ✅ 付费会员 | 单一付费会员、开通与续费、有效期、关联权益、商家与商品折扣、平台补贴及付费记录。 |
+| 2026-11-04 | ✅ 客户等级体系 / 客户权益 | 等级配置、权益介绍、经验值任务与明细、权益发放及重试,提供默认等级与权益数据。 |
+| 2026-11-04 | ✅ 小程序订单管理 | 增加小程序订单查询入口及微信订单自动上报开关。 |
+| 2026-11-04 | ✅ 立减优惠券 | 新增立减券,完善优惠券校验、领取与订单优惠计算。 |
+| 2026-11-04 | ✅ 商品定时上下架 | 完善定时上下架计划管理、独立列表及执行校验。 |
+| 2026-11-04 | ✅ 微信小程序原生能力 | 接入微信地址导入、头像选择和昵称填写。 |
+| 2026-11-02 | ✅ 消息模板 | 支持多渠道模板矩阵维护,统一站内信、短信、微信公众号及小程序订阅消息的场景配置和异步发送。 |
+| 2026-10-30 | ✅ PC 页面装修 | 重构楼层组件,支持自适应高度、可视化热区绘制及配置交互优化。 |
+| 2026-10-29 | ✅ 定时任务管理 | 重构为数据库配置驱动,支持运营后台维护任务。 |
+| 2026-10-29 | ✅ 敏感词管理 | 支持按业务场景配置过滤开关,并优化词库加载。 |
+| 2026-10-29 | ✅ PC 店铺搜索 | 新增店铺列表,支持商品与店铺双模式搜索。 |
+| 2026-10-22 | ✅ 分类设置 | 支持四种分类页模板选择、商品列表展示字段开关及模板图片预览。 |
+| 2026-10-20 | ✅ 移动端页面装修 | 完善可视化编辑器,新增首页组合组件及优惠券、店铺、文章等楼层。 |
+| 2026-10-09 | ✅ 主题色管理 | 完善主题设置,支持自定义模式。 |
+| 2026-10-02 | ✅ 预约服务商品 | 完善预约商品、预约交易及订单详情功能。 |
+| 2026-08-05 | ✅ 二级分销 | 由一级分销扩展为二级分销,增加节点配置及分销员中心。 |
+| 2026-08-03 | ✅ 卡密商品 | 完善电子卡券履约、订单状态及卡池管理。 |
+| 2026-07-23 | ✅ 素材库管理 | 增加文件分类、目录管理及目录归属校验。 |
+| 2026-07-20 | ✅ 经营统计报表 | 新增店铺业绩、商品同比环比、销售订单明细及商品销售汇总报表。 |
+| 2026-07-13 | ✅ 腾讯云直播 | 接入并完善直播、聊天与直播商品相关功能。 |
+| 2026-06-30 | ✅ 移动端技术升级 | 升级 Vue 3 与 uView Plus,适配组件和页面。 |
+| 2026-06-29 | ✅ 电子面单发货 | 完善快递鸟电子面单,支持自动携带运单号发货。 |
+| 2026-06-05 | ✅ 后端与管理端框架升级 | 5 月 25 日至 6 月 5 日完成 Spring Boot 4、管理端 Vue 3 与 Element Plus 升级。 |
+| 2026-05-22 | ✅ 购物卡 | 新增礼品卡接口,以及选择、绑定、激活和列表管理。 |
+| 2026-05-20 | ✅ 微信提现 | 完善转账状态查询、确认回调和重试处理,后续补充提现规则说明配置。 |
+| 2026-04-16 | ✅ 置顶评论 | 支持评论置顶及商品评价管理。 |
+| 2026-04-13 | ✅ 专用发票(发票上传) | 完善发票信息字段、发票详情及管理展示。 |
+| 2026-04-01 | ✅ 商品虚拟销量 | 支持按商品规格设置虚拟销量,提供单个及批量设置入口。 |
+| 2026-03-30 | ✅ 商品分组 | 新增商品分组管理及商品关联功能。 |
+| 2026-03-24 | ✅ 会员分组 | 新增会员分组管理。 |
### 🔜 近期规划中
- 🔜 微信小店对接
diff --git a/manager/src/api/paid-member.js b/manager/src/api/paid-member.js
new file mode 100644
index 000000000..89ff161e9
--- /dev/null
+++ b/manager/src/api/paid-member.js
@@ -0,0 +1,6 @@
+import { getRequest, putRequestWithNoForm } from '@/libs/axios';
+export const getPaidConfig = () => getRequest('/member/paid/config');
+export const savePaidConfig = data => putRequestWithNoForm('/member/paid/config', data);
+export const getPaidOrders = params => getRequest('/member/paid/orders', params);
+export const getPaidResources = (type, ids) => getRequest('/member/paid/resources', { type, ids: ids.join(',') });
+export const getPaidDiscountSkus = params => getRequest('/member/paid/discount-skus', params);
diff --git a/manager/src/components/lili-dialog/goods-dialog.vue b/manager/src/components/lili-dialog/goods-dialog.vue
index 498088384..9a3ded903 100644
--- a/manager/src/components/lili-dialog/goods-dialog.vue
+++ b/manager/src/components/lili-dialog/goods-dialog.vue
@@ -92,6 +92,9 @@
{{ row.simpleSpecs || "默认规格" }}
+
+ {{ row.storeName || '—' }}
+
@@ -111,7 +114,7 @@
- {{ goodsTypeLabel(row.goodsType) }}
+ {{ goodsTypeLabel(row.goodsType) }}
@@ -136,11 +139,13 @@
-
diff --git a/manager/src/components/store-selector/README.md b/manager/src/components/store-selector/README.md
new file mode 100644
index 000000000..cf7ab8afb
--- /dev/null
+++ b/manager/src/components/store-selector/README.md
@@ -0,0 +1,25 @@
+# 统一店铺选择器
+
+作者:Bulbasaur;2026-11-05。
+
+默认从右侧打开抽屉,支持搜索、分页、多选和已选回显。取消不提交,确认通过 `selected` 返回完整已选店铺数组。店铺类型、状态均为普通文字,无右侧预览区。
+
+```vue
+
+```
+
+导入 `@/components/store-selector/index.vue`,通过 `selector.value.open(selectedRows)` 打开。`selectedRows` 为包含 `id` 的店铺对象数组;每次打开建立独立选择草稿。
+
+| 参数 | 默认值 | 用途 |
+| --- | --- | --- |
+| multiple | true | false 时单选,返回数组最多一项 |
+| embedded | false | true 时在父容器展示列表,并在选择时立即通知;适用于装修链接面板 |
+| selectedWay | [] | 初始店铺数组;内嵌模式监听外部选择变化 |
+| queryParams | {} | 店铺查询限制,例如 `{ storeDisable: 'OPEN' }` |
+| title | 选择店铺 | 抽屉标题 |
+| size | 1080px | 抽屉宽度,最大为视口宽度 |
+| tableHeight | 自动 | 可选表格高度 |
+
+已接入付费会员、装修链接单选、移动端装修店铺列表配置。查询复用 `getShopListData`(`/store/store`),不新增后端接口。
+
+验证:在工作区根目录运行 `node scripts/test-store-selector.cjs`。
diff --git a/manager/src/components/store-selector/index.vue b/manager/src/components/store-selector/index.vue
new file mode 100644
index 000000000..37bc88f53
--- /dev/null
+++ b/manager/src/components/store-selector/index.vue
@@ -0,0 +1,115 @@
+
+
+
+
+ 搜索重置
+
+
+
+
重新加载
+
+
+
+ 店{{ row.storeName || '未命名店铺' }}
ID:{{ row.id }}
+ {{ selfOperated(row) ? '自营' : '非自营' }}
+ {{ storeStatus(row.storeDisable) }}
+
+
+
+
+
+
+
+
+
diff --git a/manager/src/router/router.js b/manager/src/router/router.js
index b815c1533..6f50f663a 100644
--- a/manager/src/router/router.js
+++ b/manager/src/router/router.js
@@ -224,6 +224,14 @@ export const otherRouter = {
name: "member-benefit",
component: () => import("@/views/member/benefit/index.vue")
},
+ {
+ path: "paid-member-settings", title: "付费会员", name: "paid-member-settings",
+ component: () => import("@/views/member/paid/settings.vue")
+ },
+ {
+ path: "paid-member-records", title: "付费记录", name: "paid-member-records",
+ component: () => import("@/views/member/paid/records.vue")
+ },
{
path: "member-benefit-deliveries",
title: "权益发放明细",
@@ -242,7 +250,7 @@ export const otherRouter = {
name: "member-grade-experience-log",
component: () => import("@/views/member/grade/experience-log.vue")
},
-
+
{
path: "goods/goods-info/goodsDetail",
diff --git a/manager/src/views/member/benefit/index.vue b/manager/src/views/member/benefit/index.vue
index d57b37504..3ccabfa5c 100644
--- a/manager/src/views/member/benefit/index.vue
+++ b/manager/src/views/member/benefit/index.vue
@@ -111,7 +111,7 @@
-
+
@@ -1585,3 +1585,6 @@ onMounted(() => {
}
+
+
+
diff --git a/manager/src/views/member/paid/records.vue b/manager/src/views/member/paid/records.vue
new file mode 100644
index 000000000..09363ba47
--- /dev/null
+++ b/manager/src/views/member/paid/records.vue
@@ -0,0 +1,47 @@
+
+
+
+
+
+ 搜索重置
+
+
导出记录付费会员
+
+
+ {{ name(row) }}
+ {{ status(row) }}
+ {{ membership(row) }}
+
+
+
+
+
+
+
+
diff --git a/manager/src/views/member/paid/settings.vue b/manager/src/views/member/paid/settings.vue
new file mode 100644
index 000000000..b00f1b61f
--- /dev/null
+++ b/manager/src/views/member/paid/settings.vue
@@ -0,0 +1,159 @@
+
+
+
重新加载
+
+ 基本信息
+ 关闭后,已支付会员仍有效至到期
+
+ 推荐100 × 100像素,透明PNG
+ 背景色背景图
+
+
+ 元
+ 个月按自然月计算;未到期续费从原到期时间顺延。
+
+
+ 商家设置
+ 自营商家自定义选择
+ 添加商家{{ stores[id]?.storeName || id }}
+
+ 商品折扣
+ 所有适用商品统一折扣自定义商品折扣
+ 折
+ 添加商品{{ goods[row.skuId]?.goodsName || row.skuId }}{{ goods[row.skuId]?.sn || row.skuId }}{{ goods[row.skuId]?.simpleSpecs?.trim() || '—' }}{{ goods[row.skuId]?.categoryName || '—' }}{{ goods[row.skuId]?.brandName || '—' }}{{ goods[row.skuId]?.price == null ? '—' : '¥' + Number(goods[row.skuId].price).toFixed(2) }} 折 r.skuId !== row.skuId)">移除
+
+ 会员中心推荐商品
+ 添加商品
+ {{ row.goodsName || row.id }}{{ row.simpleSpecs?.trim() || '—' }}{{ row.categoryName || '—' }}{{ row.brandName || '—' }}{{ row.price == null ? '—' : '¥' + Number(row.price).toFixed(2) }}移除
+
+
+ 展示设置
+
+
+ 未开通会员入口
+
+ {{ form.unopenedFontColor }}
+ 用于个人中心未开通及已到期入口,推荐 750 × 160 像素,支持 PNG/JPG;不设置时使用默认渐变背景。
+ ![未开通入口背景]()
{{ form.unopenedText || '开通付费会员,享专属权益' }}开通享商品优惠与专属权益
›
+
+
+ 已开通会员入口
+
+ {{ form.openedFontColor }}
+ 用于个人中心有效会员入口,推荐 750 × 160 像素,支持 PNG/JPG;不设置时使用默认渐变背景。
+ ![已开通入口背景]()
{{ form.openedText || '我的付费会员' }}有效期至 2027-11-05(示例)
›
+
+
+ 展示在商品列表、商品详情的会员价前,推荐 48 × 48 像素、透明 PNG;不设置时只显示会员价文字。
+
会员价 ¥88.00
+
+
+ 购买说明展示在移动端付费会员页面,可填写权益介绍和使用说明。
全屏编辑
+
+
+
+ 会员协议用户购买前阅读并同意的协议,开启购买前请完善内容。
全屏编辑
+
+
+ 保存设置
+
+
+
+
+
+
+
diff --git a/manager/src/views/page-decoration/wap/config-panel/PanelShop.vue b/manager/src/views/page-decoration/wap/config-panel/PanelShop.vue
index d5cc6104f..639765408 100644
--- a/manager/src/views/page-decoration/wap/config-panel/PanelShop.vue
+++ b/manager/src/views/page-decoration/wap/config-panel/PanelShop.vue
@@ -80,7 +80,7 @@
@@ -176,38 +176,7 @@
/>
-
-
-
-
-
-
-
![]()
-
{{ row.storeName }}
-
-
-
-
- {{ row.selfOperated ? "自营" : "旗舰店" }}
-
-
-
- 取消
- 确定
-
-
+
@@ -217,7 +186,7 @@ import ColorField from "../controls/ColorField.vue";
import SliderField from "../controls/SliderField.vue";
import ossManage from "@/views/sys/oss-manage/ossManage";
import ways from "@/components/lili-dialog/wap.js";
-import { getShopListData } from "@/api/shops";
+import StoreSelector from "@/components/store-selector/index.vue";
const DEFAULTS = {
bgColor1: "#FFFFFF",
@@ -247,7 +216,7 @@ const DEFAULT_ITEM = {
export default {
name: "PanelShop",
hideDecorateTitle: true,
- components: { GradientField, ColorField, SliderField, ossManage },
+ components: { GradientField, ColorField, SliderField, ossManage, StoreSelector },
props: {
res: { type: Object, required: true },
},
@@ -260,10 +229,6 @@ export default {
{ key: "style", title: "样式" },
],
picModelFlag: false,
- shopDialogVisible: false,
- shopLoading: false,
- shopOptions: [],
- selectedShops: [],
};
},
computed: {
@@ -284,30 +249,15 @@ export default {
if (!Array.isArray(item.shopList)) item.shopList = [];
},
methods: {
- // 加载店铺列表供选择
- loadShops() {
- this.shopLoading = true;
- this.selectedShops = [];
- getShopListData({ pageNumber: 1, pageSize: 100, status: "OPEN" })
- .then((res) => {
- this.shopOptions = (res && res.result && res.result.records) || [];
- })
- .finally(() => {
- this.shopLoading = false;
- });
- },
- onShopSelection(rows) {
- this.selectedShops = rows;
- },
- confirmShops() {
- this.firstItem.shopList = this.selectedShops.map((s) => ({
+ openShops() { this.$refs.storeSelector.open(this.firstItem.shopList); },
+ confirmShops(rows) {
+ this.firstItem.shopList = rows.map((s) => ({
id: s.id,
storeName: s.storeName,
storeLogo: s.storeLogo,
selfOperated: s.selfOperated,
storeBanner: s.storeBanner || "",
}));
- this.shopDialogVisible = false;
},
removeShop(index) {
this.firstItem.shopList.splice(index, 1);