diff --git a/README.en.md b/README.en.md index 3cbec73b..4039d217 100644 --- a/README.en.md +++ b/README.en.md @@ -67,14 +67,21 @@ One codebase supports: Built with: - Spring Boot -- Spring Cloud +- MySQL - Redis -- RocketMQ -- Elasticsearch - Docker -- ShardingSphere -Supports distributed deployment and high concurrency ecommerce scenarios. +Supports standalone deployment: **buyer-api** (8888), **manager-api** (8887, includes store APIs), **im-api** (8885). Product search uses MySQL. Async messaging uses Redis queues. Scheduled tasks use Spring `@Scheduled`. + +### Frontend API paths + +| App | Public API prefix | +| :--- | :--- | +| Buyer | `{buyerUrl}/buyer/common/*` | +| Seller | `{sellerUrl}/store/common/*` | +| Manager | `{managerUrl}/manager/common/*` | + +The legacy `common-api` and `/common/common/*` paths are removed. ### Ecommerce Features @@ -96,14 +103,11 @@ Supports distributed deployment and high concurrency ecommerce scenarios. ### Backend -- Java -- Spring Boot -- Spring Cloud +- Java 21 +- Spring Boot 4 - MyBatis Plus - MySQL - Redis -- RocketMQ -- Elasticsearch - JWT - Docker diff --git a/README.md b/README.md index 39ac5917..218bbf72 100644 --- a/README.md +++ b/README.md @@ -103,10 +103,30 @@ LILISHOP 是基于 Spring Boot / Spring Cloud / Vue / Uniapp 开发的 Java 开 [**部署文档 -> 环境准备**](https://docs.pickmall.cn/deply/deply.html) #### 数据库初始化 -- **推荐方式**: 使用项目提供的 `docker-compose` 配置,可自动完成数据库(MySQL, Redis, Elasticsearch等)的部署与初始化。 +- **推荐方式**: 使用 [`docker`](https://gitee.com/beijing_hongye_huicheng/docker) 仓库中的 `docker-compose`,可自动完成 **MySQL、Redis** 等中间件的部署与初始化。 - **手动方式**: 如果您选择手动部署,SQL脚本位于以下地址。请确保获取与您代码版本一致的SQL文件。 [**数据库脚本 (Gitee)**](https://gitee.com/beijing_hongye_huicheng/docker/tree/master/init/mysql) +#### 后端服务与端口(`vue3` 分支) + +| 服务 | 端口 | 说明 | +| :--- | :--- | :--- | +| buyer-api | 8888 | 买家端 API | +| manager-api | 8887 | 平台 + 商家 API(`/manager/**`、`/store/**`) | +| im-api | 8885 | 客服 IM / WebSocket | + +运行依赖:**MySQL + Redis**。商品搜索使用 MySQL;异步消息使用 Redis 队列;定时任务使用 Spring `@Scheduled`(内嵌在 manager-api)。 + +#### 前端 API 路径约定 + +| 端 | 公共接口前缀 | +| :--- | :--- | +| 买家 PC/H5 | `{buyerUrl}/buyer/common/*` | +| 商家端 | `{sellerUrl}/store/common/*` | +| 平台端 | `{managerUrl}/manager/common/*` | + +`common-api` 已下线,请勿再使用 `/common/common/*` 旧路径。 + --- ### 5. 架构文档边界 @@ -120,16 +140,11 @@ LILISHOP 是基于 Spring Boot / Spring Cloud / Vue / Uniapp 开发的 Java 开 - H5 / 小程序 / APP:`lilishop-uniapp` - 部署、SQL、镜像与启动脚本:`docker` -All-In-One 仅用于本地体验、演示或验证,不代表生产高可用部署架构。生产部署应按实际访问量、稳定性、监控、备份和扩缩容要求拆分数据库、缓存、搜索、消息、任务调度、前端静态资源和后端服务。 - ### 6. 功能列表 [功能清单](https://bdwx2tfwwt.feishu.cn/sheets/FFQKscQKDhUx60to1k9cbMngnYb?from=from_copylink) - - - ### 7. 开源与授权 1. **开源协议**: 本项目遵循 `AGPL-3.0` 开源协议。 diff --git a/buyer/public/config.js b/buyer/public/config.js index 2272ff76..593ec1d4 100644 --- a/buyer/public/config.js +++ b/buyer/public/config.js @@ -3,15 +3,9 @@ var BASE = { * @description api请求基础路径 */ API_DEV: { - common: "https://common-api.pickmall.cn", buyer: "https://buyer-api.pickmall.cn", - seller: "https://store-api.pickmall.cn", - manager: "https://admin-api.pickmall.cn" }, API_PROD: { - common: "https://common-api.pickmall.cn", buyer: "https://buyer-api.pickmall.cn", - seller: "https://store-api.pickmall.cn", - manager: "https://admin-api.pickmall.cn" }, }; diff --git a/buyer/src/api/address.js b/buyer/src/api/address.js index a522bc32..dadbcb27 100644 --- a/buyer/src/api/address.js +++ b/buyer/src/api/address.js @@ -1,5 +1,5 @@ import request, { - Method, commonUrl + Method, buyerUrl } from '@/plugins/request.js'; // 会员收货地址列表 @@ -55,7 +55,7 @@ export function getAddrDetail (id) { // 传给后台citycode 获取城市街道等id export function handleRegion (params) { return request({ - url: `${commonUrl}/common/common/region/region`, + url: `${buyerUrl}/buyer/common/region/region`, needToken: true, method: Method.GET, params diff --git a/buyer/src/api/common.js b/buyer/src/api/common.js index db827304..92f6d924 100644 --- a/buyer/src/api/common.js +++ b/buyer/src/api/common.js @@ -1,11 +1,11 @@ -import request, {Method, commonUrl} from '@/plugins/request.js'; +import request, {Method, buyerUrl} from '@/plugins/request.js'; /** * 获取拼图验证 */ export function getVerifyImg (verificationEnums) { return request({ - url: `${commonUrl}/common/common/slider/${verificationEnums}`, + url: `${buyerUrl}/buyer/common/slider/${verificationEnums}`, method: Method.GET, needToken: false }); @@ -15,7 +15,7 @@ export function getVerifyImg (verificationEnums) { */ export function postVerifyImg (params) { return request({ - url: `${commonUrl}/common/common/slider/${params.verificationEnums}`, + url: `${buyerUrl}/buyer/common/slider/${params.verificationEnums}`, method: Method.POST, needToken: false, params @@ -26,7 +26,7 @@ export function postVerifyImg (params) { */ export function sendSms (params) { return request({ - url: `${commonUrl}/common/common/sms/${params.verificationEnums}/${params.mobile}`, + url: `${buyerUrl}/buyer/common/sms/${params.verificationEnums}/${params.mobile}`, method: Method.GET, needToken: false, params @@ -36,7 +36,7 @@ export function sendSms (params) { // 地区数据,用于三级联动 export function getRegion (id) { return request({ - url: `${commonUrl}/common/common/region/item/${id}`, + url: `${buyerUrl}/buyer/common/region/item/${id}`, needToken: true, method: Method.GET, loading: false @@ -80,7 +80,7 @@ export function articleDetail (id) { // 获取IM接口前缀 export function getIMDetail () { return request({ - url: `${commonUrl}/common/common/IM`, + url: `${buyerUrl}/buyer/common/IM`, method: Method.GET }); } @@ -89,7 +89,7 @@ export function getIMDetail () { //获取图片logo export function getBaseSite(){ return request ({ - url:`${commonUrl}/common/common/site`, + url:`${buyerUrl}/buyer/common/site`, method: Method.GET, needToken: false }) @@ -98,7 +98,7 @@ export function getBaseSite(){ // 获取主题色配置 export function getThemeSetting() { return request({ - url: `${commonUrl}/common/common/site/theme`, + url: `${buyerUrl}/buyer/common/site/theme`, method: Method.GET, needToken: false, }); diff --git a/buyer/src/api/goods.js b/buyer/src/api/goods.js index 89dbd28f..76fe0d03 100644 --- a/buyer/src/api/goods.js +++ b/buyer/src/api/goods.js @@ -5,7 +5,7 @@ import request, { // 商品列表 export function goodsList (params) { return request({ - url: '/buyer/goods/goods/es', + url: '/buyer/goods/goods/search', method: Method.GET, needToken: false, optionalToken: true, @@ -16,7 +16,7 @@ export function goodsList (params) { // 商品分类 筛选条件 品牌, 尺寸等 export function filterList (params) { return request({ - url: '/buyer/goods/goods/es/related', + url: '/buyer/goods/goods/search/related', method: Method.GET, needToken: false, optionalToken: true, diff --git a/buyer/src/components/verify/verify.js b/buyer/src/components/verify/verify.js index e6cda9f6..4cd73138 100644 --- a/buyer/src/components/verify/verify.js +++ b/buyer/src/components/verify/verify.js @@ -1,5 +1,5 @@ -import request, {Method, commonUrl} from '@/plugins/request.js'; +import request, {Method, buyerUrl} from '@/plugins/request.js'; import storage from '@/plugins/storage.js'; /** @@ -7,7 +7,7 @@ import storage from '@/plugins/storage.js'; */ export function getVerifyImg (verificationEnums) { return request({ - url: `${commonUrl}/common/common/slider/${verificationEnums}`, + url: `${buyerUrl}/buyer/common/slider/${verificationEnums}`, method: Method.GET, needToken: false, headers: {uuid: storage.getItem('uuid')} @@ -19,7 +19,7 @@ export function getVerifyImg (verificationEnums) { */ export function postVerifyImg (params) { return request({ - url: `${commonUrl}/common/common/slider/${params.verificationEnums}`, + url: `${buyerUrl}/buyer/common/slider/${params.verificationEnums}`, method: Method.POST, needToken: false, params, diff --git a/buyer/src/pages/home/memberCenter/Profile.vue b/buyer/src/pages/home/memberCenter/Profile.vue index 7f5a2858..cf773c32 100644 --- a/buyer/src/pages/home/memberCenter/Profile.vue +++ b/buyer/src/pages/home/memberCenter/Profile.vue @@ -47,8 +47,12 @@ diff --git a/manager/src/views/live/list.vue b/manager/src/views/live/list.vue index 96d4f6b0..e84f105e 100644 --- a/manager/src/views/live/list.vue +++ b/manager/src/views/live/list.vue @@ -237,7 +237,7 @@ export default { }, buildH5ShareUrl(liveId) { const base = (this.wapUrl || BASE?.WAP_URL || config.website || "").replace(/\/?$/, "/"); - return `${base}pages/promotions/live/detail?id=${liveId}`; + return `${base}pages/promotion/live/room?id=${liveId}`; }, handleShare(row) { this.shareTitle = row.title || ""; @@ -246,8 +246,40 @@ export default { }, copyShareUrl() { if (!this.shareH5Url) return; - navigator.clipboard.writeText(this.shareH5Url); - this.$Message.success("链接已复制"); + this.copyText(this.shareH5Url); + }, + copyText(text) { + const onSuccess = () => this.$Message.success("链接已复制"); + const onFail = () => this.$Message.error("复制失败,请手动复制"); + + if (navigator.clipboard?.writeText) { + navigator.clipboard + .writeText(text) + .then(onSuccess) + .catch(() => { + this.copyTextFallback(text) ? onSuccess() : onFail(); + }); + return; + } + + this.copyTextFallback(text) ? onSuccess() : onFail(); + }, + copyTextFallback(text) { + const textArea = document.createElement("textarea"); + textArea.value = text; + textArea.style.position = "fixed"; + textArea.style.left = "-9999px"; + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + let ok = false; + try { + ok = document.execCommand("copy"); + } catch (e) { + ok = false; + } + document.body.removeChild(textArea); + return ok; }, handleStart(row) { if (row.liveStatus === "LIVING") { diff --git a/manager/src/views/sys/oss-manage/ossManage.vue b/manager/src/views/sys/oss-manage/ossManage.vue index e3e9c686..9fc95aae 100644 --- a/manager/src/views/sys/oss-manage/ossManage.vue +++ b/manager/src/views/sys/oss-manage/ossManage.vue @@ -190,7 +190,7 @@
-
- 重新生成所有商品索引 - 删除ES中下架的商品 - 生成所有商品的缓存 - 删除不存在的索引 -
- -
-
保存
@@ -69,7 +60,7 @@