初始化

缺陷:主题配色需要优化整体的同风格
This commit is contained in:
2026-08-14 23:17:19 +08:00
parent 6da262b134
commit 516f077568
26 changed files with 2280 additions and 1370 deletions

92
api/env.js Normal file
View File

@@ -0,0 +1,92 @@
/**
* 小程序运行环境与品牌配置(统一入口)
*
* 老代码在 interceptor.js 里把 5 个 baseURL 用注释切换,极易把测试地址发上线。
* 这里把所有环境相关的值收口到一个文件,interceptor.js 只读这里的常量。
*
* 【品牌区分】
* lgp-wx 和 lgp-wx-new 是同一套代码的两个目录,差异只有品牌(brm=铂尔曼 / wl=维伦)。
* 因为 uni-app 条件编译(#ifdef)只支持平台维度(MP-WEIXIN 等),不支持自定义变量,
* 而本项目又是纯 HBuilderX 工程(没有 CLI 环境变量注入),唯一可靠的品牌区分点
* 是 manifest.json 的 mp-weixin.appid。这里用 BRAND 常量收敛:
* - 铂尔曼项目(lgp-wx):BRAND = 'brm'
* - 维伦项目(lgp-wx-new):BRAND = 'wl'
* 同步到另一个项目时只改这一行 BRAND,baseURL / appid / 名称会自动跟着切。
*
* 【环境区分】
* ENV 用 process.env.NODE_ENV 区分开发/生产(uni-app 编译时注入),
* 默认生产,开发环境用 LOCAL_BASE。
*/
/** 当前品牌:'brm' 铂尔曼 / 'wl' 维伦 —— 同步项目时改这一行 */
export const BRAND = 'wl';
/**
* 品牌维度的配置表。
* appid 必须与 manifest.json 的 mp-weixin.appid 保持一致(构建时校验,防止串包)。
* baseURL 是该品牌的线上 API 地址。
* name 是该品牌的展示名。
*/
export const BRAND_CONFIG = {
brm: {
appid: 'wx679d36842570cea7',
baseURL: 'https://brm.wx.api.borman.top/api/wx/',
name: '佛山铂尔曼',
},
wl: {
appid: 'wx57b54060a579c31a',
baseURL: 'https://wx.api.borman.top/api/wx/',
name: '维伦家具',
},
};
/** 本地联调地址(开发环境用,按需指向本机或测试服) */
export const LOCAL_BASE = 'http://127.0.0.1:18004/api/wx/';
/**
* 当前环境:开发模式下走本地地址,否则走品牌线上地址。
* process.env.NODE_ENV 由 uni-app 编译时注入(HBuilderX 运行=development,发行=production)。
*/
const ENV = process.env.NODE_ENV === 'development' ? 'dev' : 'prod';
/** 当前生效的 API baseURL,interceptor.js 只读这一个值 */
export const API_BASE =
ENV === 'dev' ? LOCAL_BASE : BRAND_CONFIG[BRAND].baseURL;
/** 当前品牌名(页面标题等展示用) */
export const BRAND_NAME = BRAND_CONFIG[BRAND].name;
/** 当前品牌 appid(与 manifest.json 校验用) */
export const BRAND_APPID = BRAND_CONFIG[BRAND].appid;
/**
* 启动时校验 manifest.json 的 appid 与 BRAND 是否匹配。
* 不匹配说明改了 BRAND 忘了改 manifest(或反之),构建出的包会串品牌,必须报错。
*/
function checkBrandAppid() {
// #ifdef MP-WEIXIN
// 小程序端用 wx.getAccountInfoSync 拿真实 appid 校验
try {
const info = wx.getAccountInfoSync();
const realAppid = info && info.miniProgram && info.miniProgram.appId;
if (realAppid && realAppid !== BRAND_APPID) {
// eslint-disable-next-line no-console
console.error(
`[env] 品牌不匹配:当前 BRAND=${BRAND}(期望 appid=${BRAND_APPID}),但小程序真实 appid=${realAppid}。请检查 manifest.json 或 api/env.js 的 BRAND。`,
);
}
} catch (e) {
// 获取失败不阻塞,仅打日志
}
// #endif
}
checkBrandAppid();
export default {
BRAND,
API_BASE,
BRAND_NAME,
BRAND_APPID,
ENV,
};

View File

@@ -1,14 +1,14 @@
// 定义一个全局请求配置(可被多个拦截器修改)
import {setCache} from "@/utils/cache";
import {API_BASE, BRAND} from './env.js';
export let globalConfig = {
baseURL: 'https://wx.api.borman.top/api/',
// baseURL: 'http://brm.wx.api.borman.top/api/',
// baseURL: 'https://wx.boerman.top/api/',
// baseURL: 'http://127.0.0.1:18004/api/', // 本地测试地址
// baseURL: 'http://127.0.0.1:18006/api/', // 本地测试地址
// baseURL 由 api/env.js 统一注入:开发环境走本地,生产环境按 BRAND(brm/wl)切换
baseURL: API_BASE,
header: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
// 双品牌共用后端时靠这个分流 AppID / 默认装修模板
'X-App-Code': BRAND,
}
};
@@ -48,10 +48,8 @@ export async function runResponseInterceptors(response) {
// 初始化默认拦截器(可选)
addRequestInterceptor(config => {
// 自动携带token示例
// 自动携带token:从本地缓存读,不再有硬编码测试 token
const token = uni.getStorageSync('token');
// 临时token(测试用)
// const token = 'JG7hKhTQoANh/hyL67BzIg==';
if (token) {
config.header.Authorization = `Bearer ${token}`;
}

View File

@@ -2,8 +2,14 @@ import {get, post} from '../request';
const prefix = 'list/'
export const getCartListApi = async () => {
return await get(`${prefix}list`)
/**
* 我的清单列表
* - 不传参数:返回全量数组(老调用方兼容)
* - 传 { page, pageSize }:后端返回 { items, total, page, pageSize, has_more }
* @param {{page?: number, pageSize?: number}} params
*/
export const getCartListApi = async (params) => {
return await get(`${prefix}list`, params)
}
export const getCartItemApi = async (id) => {
return await get(`${prefix}detail`, {id})
@@ -21,10 +27,24 @@ export const deleteCartItemApi = async (id) => {
ids: [id]
})
}
export const toCartApi = async (listId, productId) => {
export const toCartApi = async (listId, productId, extra = {}) => {
return await post(`${prefix}to-cart`, {
list_id: listId,
product_id: productId
product_id: productId,
...extra
})
}
/**
* 改清单明细的规格 / 数量 / 备注。
* 对齐后端 wx/list/update-item(WxListService::updateItem),
* 只传需要改的字段即可,后端按 array_key_exists 判断。
* @param {number} id 明细 id(list_item.id,不是清单 id)
* @param {{price_sheet_id?: number, quantity?: number, material_key?: string, remark?: string}} params
*/
export const updateItemApi = async (id, params = {}) => {
return await post(`${prefix}update-item`, {
id,
...params
})
}

View File

@@ -1,15 +0,0 @@
import {get, post} from '../request';
const prefix = 'w-oss/'
export const getImageApi = async (hash = '') => {
return await get(`${prefix}getImage`, {
hash
})
}
export const uploadImageWatermarkApi = async (imageUrl = '', watermark = 'BRM') => {
return await post(`${prefix}watermark`, {
image_url: imageUrl,
watermark
})
}

96
api/page/order.js Normal file
View File

@@ -0,0 +1,96 @@
import {get, post} from '../request';
import {API_BASE} from '../env';
/**
* 订单 API(对齐后端 lgp-admin-plus-api/app/Service/wx/WxOrderService.php)
* 前缀 wx/order,走鉴权组(nl.wx 中间件)。
* 金额字段后端是整数分,详情接口会带 *_text 元字段,这里直接用。
*/
const prefix = 'order/'
/** 我的订单列表,可按状态筛,透传分页参数 {status, page, pageSize} */
export const getOrderListApi = async (params = {}) => {
return await get(`${prefix}list`, params)
}
/** 订单详情(含明细、支付记录、发货记录) */
export const getOrderDetailApi = async (id) => {
return await get(`${prefix}detail`, {id})
}
/**
* 清单转订单。
* @param listId 清单 id
* @param params 收货信息:receiver_name / receiver_phone / receiver_address / delivery_type / remark
*/
export const createOrderApi = async (listId, params = {}) => {
return await post(`${prefix}create`, {list_id: listId, ...params})
}
/**
* 上传转账凭证。
* @param orderId 订单 id
* @param voucher 凭证图 URL(多张逗号分隔或数组)
* @param amount 可选,本次转账金额(分),不传则按订单未付金额
*/
export const submitVoucherApi = async (orderId, voucher, amount) => {
const body = {order_id: orderId, voucher}
if (amount !== undefined && amount !== null) {
body.amount = amount
}
return await post(`${prefix}voucher`, body)
}
/** 调起微信 JSAPI 支付,后端返回 uni.requestPayment 所需参数 */
export const wechatPayApi = async (orderId) => {
return await post(`${prefix}wechat-pay`, {order_id: orderId})
}
/** 取消订单(仅未付款/已付款未发货可用) */
export const cancelOrderApi = async (id) => {
return await post(`${prefix}cancel`, {id})
}
/** 确认收货(已发货状态可用) */
export const completeOrderApi = async (id) => {
return await post(`${prefix}complete`, {id})
}
/**
* 上传转账凭证图片到 OSS(wx/upload/image)。
*
* uni.uploadFile 不走 request.js 拦截器,所以这里手动拼 baseURL + token + 解包 result。
* 返回后端 result.url(可直接访问的图片地址),供 submitVoucher 拼成逗号串提交。
*
* @param filePath chooseImage 返回的本地 tempFilePath
* @returns Promise<string> OSS 图片 URL
*/
export const uploadVoucherImageApi = (filePath) => {
return new Promise((resolve, reject) => {
const token = uni.getStorageSync('token')
uni.uploadFile({
url: `${API_BASE}upload/image`,
filePath,
name: 'file',
header: token ? {Authorization: `Bearer ${token}`} : {},
success: (res) => {
try {
const body = typeof res.data === 'string' ? JSON.parse(res.data) : res.data
if (body.code === 0 && body.result && body.result.url) {
resolve(body.result.url)
} else {
uni.showToast({title: body.message || '上传失败', icon: 'none'})
reject(new Error(body.message || '上传失败'))
}
} catch (e) {
uni.showToast({title: '上传失败', icon: 'none'})
reject(e)
}
},
fail: (err) => {
uni.showToast({title: '上传失败', icon: 'none'})
reject(err)
},
})
})
}

19
api/page/theme.js Normal file
View File

@@ -0,0 +1,19 @@
/**
* 主题 API(免鉴权)
* baseURL 已含 /api/wx/,这里请求 theme → GET .../api/wx/theme
*/
import { get } from '../request'
/** 当前生效主题(含 tokens / layout / css_vars) */
export const getThemeApi = async (code = '') => {
const params = {}
if (code) {
params.code = code
}
return await get('theme', params)
}
/** 可选风格列表 */
export const getThemeGalleryApi = async () => {
return await get('theme-gallery')
}