diff --git a/README.md b/README.md index 7da3c222a..6fea1f461 100644 --- a/README.md +++ b/README.md @@ -162,6 +162,8 @@ lilishop-ui ## 8. 升级计划 +> 更新日期:2026-11-03,依据各端近期提交及当前代码实现同步。 + ### ✅ 已完成特性 | 功能模块 | 功能模块 | | :--- | :--- | @@ -170,17 +172,21 @@ lilishop-ui | ✅ 置顶评论 | ✅ 客户等级体系 | | ✅ 购物卡 | ✅ 腾讯云-云直播 | | ✅ 卡密商品 | ✅ 二级分销 | -| ✅ 定时任务管理 | ✅ 预约服务商品 | +| ✅ 定时任务管理(数据库配置驱动) | ✅ 预约服务商品 | | ✅ 主题色管理 | ✅ 新增无需配送发货方式 | | ✅ 多维统计(营业/商品/会员/积分/储值/营销/分销) | ✅ 经营报表(店铺业绩/商品同比环比/订单明细/销售汇总) | | ✅ 分类页多模板设置 | ✅ 移动端楼层装修组件库 | -| ✅ PC端楼层装修重构 | ✅ 全站统一顶栏 | -| ✅ PC端店铺独立列表 | ✅ 敏感词场景化过滤 | +| ✅ PC端楼层装修重构(自适应高度 / 可视化热区绘制) | ✅ 全站统一顶栏 / 商品与店铺双模式搜索 | +| ✅ PC端店铺独立列表 | ✅ 敏感词场景化过滤与分组开关 | +| ✅ 店铺结算汇总 / 结算台账 | ✅ 支付方式汇总 / 钱包流水 | +| ✅ 平台经营报表 / 商家周期财务汇总 | ✅ 财务报表与流水 Excel 导出 / 结算单批量下载 | +| ✅ 会员消息四渠道异步通知(站内信 / 短信 / 公众号 / 小程序) | ✅ 消息模板多渠道矩阵管理(模板配置 / 渠道开关) | +| ✅ 平台订单详情优化 / 标准 A4 出库发货单打印 | ✅ 售后详情展示优化 / 移动端售后入口整合至订单列表 | +| ✅ 商品详情视频内嵌相册 | ✅ 评价管理增强(回复状态 / 图片筛选 / 评价分级) | +| ✅ PC会员中心订单快捷入口 / 资产卡片 | ✅ 平台表单抽屉化 / 文章独立编辑页 | ### 🔜 近期规划中 -- 🔜 店铺结算汇总 & 结算台账 -- 🔜 支付方式汇总 & 钱包流水 & 财务汇总 - 🔜 微信小店对接 - 🔜 抖店对接 -- 🔜 微信小程序原生重构与体验对齐 +- 🔜 微信小程序原生重构与体验对齐(持续完善;已接入预约交易、分类多模板与首页楼层装修) - 🔜 OpenAPI 开放平台与开发者中心 diff --git a/buyer/src/assets/styles/element.scss b/buyer/src/assets/styles/element.scss index 8e9cca446..3b19c2b2b 100644 --- a/buyer/src/assets/styles/element.scss +++ b/buyer/src/assets/styles/element.scss @@ -1,3 +1,8 @@ +/* 全局禁止多行输入框拖动缩放,覆盖组件生成的内联 resize 样式。 */ +.el-textarea__inner { + resize: none !important; +} + :root { --el-color-primary: var(--theme-color, #ff3c2a); --el-color-danger: var(--theme-color, #ff3c2a); diff --git a/buyer/src/components/footer/Footer.vue b/buyer/src/components/footer/Footer.vue index 0f5c4add0..10f517806 100644 --- a/buyer/src/components/footer/Footer.vue +++ b/buyer/src/components/footer/Footer.vue @@ -43,25 +43,20 @@
@@ -71,11 +66,12 @@ diff --git a/manager/src/composables/useSiteSettings.js b/manager/src/composables/useSiteSettings.js new file mode 100644 index 000000000..781523fa6 --- /dev/null +++ b/manager/src/composables/useSiteSettings.js @@ -0,0 +1,33 @@ +import { computed, onMounted, ref } from "vue"; +import { getBaseSite } from "@/api/common.js"; +import config from "@/config"; + +// 同页的页头、页脚共享请求;每次重新进入页面时刷新,避免旧缓存覆盖后台设置。 +const settings = ref(null); +let pendingRequest; + +export function loadSiteSettings() { + if (!pendingRequest) { + pendingRequest = getBaseSite() + .then((res) => { + if (res.success && res.result?.settingValue) { + settings.value = JSON.parse(res.result.settingValue); + } + return settings.value; + }) + .catch(() => settings.value) + .finally(() => { pendingRequest = null; }); + } + return pendingRequest; +} + +export function useSiteSettings() { + onMounted(loadSiteSettings); + const siteName = computed(() => settings.value?.siteName || config.title); + const companyName = computed(() => settings.value ? settings.value.companyName || "" : config.company?.name || ""); + const companyUrl = computed(() => settings.value ? settings.value.companyUrl || "" : config.company?.href || ""); + const website = computed(() => settings.value ? settings.value.website || "" : config.website || ""); + const icp = computed(() => settings.value ? settings.value.icp || "" : config.icpMessage || ""); + const copyrightOwner = computed(() => settings.value?.copyrightOwner?.trim() || siteName.value); + return { settings, siteName, companyName, companyUrl, website, icp, copyrightOwner }; +} diff --git a/manager/src/libs/util.js b/manager/src/libs/util.js index 6db29f7c6..683371234 100644 --- a/manager/src/libs/util.js +++ b/manager/src/libs/util.js @@ -8,6 +8,8 @@ let util = {}; /** 已弃用、前端未实现或已移除的菜单 frontRoute,注册路由时跳过 */ const DEPRECATED_FRONT_ROUTES = new Set([ "goods/goods-manage/spec", + "member/list/memberRecycle", + "order/order/fictitiousOrderList", ]); function isDeprecatedMenu(menu) { diff --git a/manager/src/stores/app.js b/manager/src/stores/app.js index 003912d07..7e1d76ff1 100644 --- a/manager/src/stores/app.js +++ b/manager/src/stores/app.js @@ -2,6 +2,8 @@ import { defineStore } from "pinia"; import { otherRouter } from "@/router/router"; import i18n from "@/locale"; +const removedPageNames = new Set(["memberRecycle", "fictitiousOrderList"]); + // 原 vuex app 模块 + 根 state(openStyleStore/openStoreId/notices)合并 // mutation 全部转为同名 action;两个例外: // - pageOpenedList mutation 与 state 同名,改名 updateOpenedList @@ -73,7 +75,8 @@ export const useAppStore = defineStore("app", { }, initCachePage() { if (localStorage.cachePage) { - this.cachePage = JSON.parse(localStorage.cachePage); + this.cachePage = JSON.parse(localStorage.cachePage).filter((name) => !removedPageNames.has(name)); + localStorage.cachePage = JSON.stringify(this.cachePage); } }, removeTag(name) { @@ -120,8 +123,9 @@ export const useAppStore = defineStore("app", { }, setOpenedList() { this.pageOpenedList = localStorage.pageOpenedList - ? JSON.parse(localStorage.pageOpenedList) + ? JSON.parse(localStorage.pageOpenedList).filter((page) => !removedPageNames.has(page.name)) : [otherRouter.children[0]]; + localStorage.pageOpenedList = JSON.stringify(this.pageOpenedList); }, setAvatarPath(path) { localStorage.avatorImgPath = path; diff --git a/manager/src/styles/element.scss b/manager/src/styles/element.scss index ef9625311..0181ad5d8 100644 --- a/manager/src/styles/element.scss +++ b/manager/src/styles/element.scss @@ -1,3 +1,8 @@ +/* 全局禁止多行输入框拖动缩放,覆盖组件生成的内联 resize 样式。 */ +.el-textarea__inner { + resize: none !important; +} + /* Element Plus 主题覆盖(对齐原 iView 主色) */ :root { // --el-color-primary: #ff5c58; diff --git a/manager/src/views/login.vue b/manager/src/views/login.vue index 7b2a3e827..f37b76cf0 100644 --- a/manager/src/views/login.vue +++ b/manager/src/views/login.vue @@ -11,7 +11,7 @@
  • 多店铺管理与经营数据分析
  • - +
    @@ -94,11 +94,13 @@ import verify from "@/components/verify"; import { setStore } from "@/libs/storage"; import { md5 } from "@/utils/md5.js"; import { useAppStore } from "@/stores/app"; +import { useSiteSettings } from "@/composables/useSiteSettings"; const router = useRouter(); const appStore = useAppStore(); const year = ref(new Date().getFullYear()); +const { copyrightOwner } = useSiteSettings(); const loading = ref(false); const form = reactive({ username: "", diff --git a/manager/src/views/main-parts/footer.vue b/manager/src/views/main-parts/footer.vue index c5c01eab1..77ee40d5b 100644 --- a/manager/src/views/main-parts/footer.vue +++ b/manager/src/views/main-parts/footer.vue @@ -1,24 +1,23 @@ diff --git a/manager/src/views/order/order/fictitiousOrderList.vue b/manager/src/views/order/order/fictitiousOrderList.vue deleted file mode 100644 index 835eabf4a..000000000 --- a/manager/src/views/order/order/fictitiousOrderList.vue +++ /dev/null @@ -1,235 +0,0 @@ - - - - - diff --git a/manager/src/views/order/order/orderDetail.vue b/manager/src/views/order/order/orderDetail.vue index e2199a76a..4f301949f 100644 --- a/manager/src/views/order/order/orderDetail.vue +++ b/manager/src/views/order/order/orderDetail.vue @@ -1,18 +1,20 @@