Compare commits

...

19 Commits

Author SHA1 Message Date
YunaiV 9ede13e82e fix: 修复客服新会话消息超出可视区域 2026-06-08 08:54:55 +08:00
YunaiV 84a9fb5c78 feat: 支持 H5 公众号微信商家转账确认收款 2026-06-08 08:43:43 +08:00
YunaiV 8338321786 fix(mall): 校验售后申请类型必填
- 后端售后申请接口启用请求体参数校验
- 前端申请售后提交前校验售后类型
- 修正售后类型 radio 选中态绑定字段
2026-06-07 23:15:32 +08:00
YunaiV 41211d17b3 fix: 修复 H5 分享链接未绑定推广用户 2026-05-31 16:35:09 +08:00
YunaiV 164551a22e fix: 修复刷新令牌缺失后不弹登录框
刷新令牌缺失时不再标记为刷新中,避免刷新状态永久卡住,导致后续访问订单等登录接口时不弹出登录框。
2026-05-31 10:58:37 +08:00
YunaiV 6587fb15c6 fix: 登录失效时未弹出登录框
将 isRefreshToken = true 移到 getRefreshToken() 检查之后:
当本地无 refreshToken 时,提前 return handleAuthorized() 会绕过
finally 块,导致 isRefreshToken 永久卡在 true,后续所有 401
请求静默进入队列而不弹登录框。

修复 https://github.com/yudaocode/yudao-mall-uniapp/issues/38
2026-05-31 10:56:38 +08:00
YunaiV d6f272ad75 fix: 显式声明 Vue 依赖
显式声明 vue 依赖版本,避免 npm install 时因 Pinia peer dependency 解析到 Vue 2 而必须添加 --legacy-peer-deps。
2026-05-31 10:45:09 +08:00
芋道源码 2c489b2cab
!181 feat: 增加体验版后端接口地址判断
Merge pull request !181 from 背起行囊/master
2026-05-31 02:31:24 +00:00
zhangfengchen 5ccddfa082 docs: 增加体验版后端接口地址判断 2026-05-26 09:43:57 +08:00
zhangfengchen be05df9d91 feat: 增加体验版后端接口地址判断-方法抽离 2026-05-26 09:24:30 +08:00
zhangfengchen ef6ba21a56 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	.env
2026-05-25 17:51:08 +08:00
zhangfengchen c6c240115d feat: 增加体验版后端接口地址判断 2026-05-25 17:50:49 +08:00
zhangfengchen a6c4179611 feat: 增加体验版后端接口地址判断 2026-05-25 17:47:06 +08:00
芋道源码 75eed2ba19
!178 refactor(store): 优化 Pinia store 定义方式
Merge pull request !178 from 爱宇阳/master
2026-05-23 09:30:01 +00:00
芋道源码 9e7ef1e9f1
!179 update pages/commission/promoter.vue.
Merge pull request !179 from 爱宇阳/N/A
2026-05-23 09:06:14 +00:00
芋道源码 3a27171cda
!180 chore(s-layout): 支持定义顶部导航栏背景颜色
Merge pull request !180 from 背起行囊/master
2026-05-23 08:59:46 +00:00
zhangfengchen 014b0dd508 chore(s-layout): 支持定义顶部导航栏背景颜色 2026-05-21 14:46:49 +08:00
爱宇阳 c034b59a7b
update pages/commission/promoter.vue.
修复getList()未定义错误

Signed-off-by: 爱宇阳 <thedanyang@qq.com>
2026-05-13 03:42:48 +00:00
aiyvyang 43d2d02e8e refactor(store): 优化 Pinia store 定义方式
将所有 store 模块从旧版 defineStore({ id: 'xxx', ... }) 形式
改为新版 defineStore('xxx', { ... }) 形式,符合 Pinia 推荐的最佳实践。

涉及模块:
  - app.js
  - cart.js
  - modal.js
  - sys.js
  - user.js
2026-05-09 15:36:10 +08:00
18 changed files with 145 additions and 23 deletions

5
.env
View File

@ -1,9 +1,12 @@
# 版本号 # 版本号
SHOPRO_VERSION=v2.4.1 SHOPRO_VERSION=v2.4.1
# 后端接口 - 正式环境(通过 process.env.NODE_ENV 非 development # 后端接口 - 正式环境(通过 process.env.NODE_ENV 非 development -生产环境-release
SHOPRO_BASE_URL=http://api-dashboard.yudao.iocoder.cn SHOPRO_BASE_URL=http://api-dashboard.yudao.iocoder.cn
# 后端接口 - 体验环境(通过 process.env.NODE_ENV 非 development -体验环境-trial
SHOPRO_TRIAL_BASE_URL=http://api-dashboard.yudao.iocoder.cn/trial
# 后端接口 - 测试环境(通过 process.env.NODE_ENV = development # 后端接口 - 测试环境(通过 process.env.NODE_ENV = development
SHOPRO_DEV_BASE_URL=http://127.0.0.1:48080 SHOPRO_DEV_BASE_URL=http://127.0.0.1:48080
### SHOPRO_DEV_BASE_URL=http://10.171.1.188:48080 ### SHOPRO_DEV_BASE_URL=http://10.171.1.188:48080

View File

@ -94,6 +94,7 @@
"luch-request": "^3.0.8", "luch-request": "^3.0.8",
"pinia": "^2.0.33", "pinia": "^2.0.33",
"pinia-plugin-persist-uni": "^1.2.0", "pinia-plugin-persist-uni": "^1.2.0",
"vue": "^3.5.11",
"weixin-js-sdk": "^1.6.0" "weixin-js-sdk": "^1.6.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -253,8 +253,8 @@
.message-container { .message-container {
width: 100%; width: 100%;
/* 确保容器至少有一屏高度 */ /* 倒置滚动区内,容器高度只需要撑满聊天区域 */
min-height: 100vh; min-height: v-bind(chatScrollHeight);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-end; justify-content: flex-end;

View File

@ -105,7 +105,7 @@
return; return;
} }
state.pagination.pageNo++; state.pagination.pageNo++;
getList(); getRankList();
} }
// //

View File

@ -229,7 +229,7 @@
} }
let openid; let openid;
if (state.accountInfo.type === '5') { if (state.accountInfo.type === '5') {
openid = await sheep.$platform.useProvider('wechat').getOpenid(); openid = await sheep.$platform.useProvider('wechat').getOpenid(true);
// openid // openid
if (!openid) { if (!openid) {
goBindWeixin(); goBindWeixin();

View File

@ -24,7 +24,7 @@
:key="index" :key="index"
> >
<radio <radio
:checked="formData.type === item.value" :checked="formData.way === item.value"
color="var(--ui-BG-Main)" color="var(--ui-BG-Main)"
style="transform: scale(0.8)" style="transform: scale(0.8)"
:value="item.value" :value="item.value"
@ -159,6 +159,10 @@
// //
async function submit() { async function submit() {
if (!formData.way) {
sheep.$helper.toast('请选择售后类型');
return;
}
let data = { let data = {
orderItemId: state.itemId, orderItemId: state.itemId,
refundPrice: state.item.payPrice, refundPrice: state.item.payPrice,

View File

@ -12,6 +12,7 @@
:color="color" :color="color"
:tools="tools" :tools="tools"
:opacityBgUi="opacityBgUi" :opacityBgUi="opacityBgUi"
:backgroundColor="navbarBackgroundColor"
@search="(e) => emits('search', e)" @search="(e) => emits('search', e)"
:defaultSearch="defaultSearch" :defaultSearch="defaultSearch"
/> />
@ -80,6 +81,11 @@
type: String, type: String,
default: 'bg-white', default: 'bg-white',
}, },
// navbar === 'normal'
navbarBackgroundColor: {
type: String,
default: '',
},
color: { color: {
type: String, type: String,
default: '', default: '',
@ -213,16 +219,16 @@
// #endif // #endif
// 使 onMounted 使 onShow // 使 onMounted 使 onShow
onMounted(()=>{ onMounted(() => {
// #ifdef MP-ALIPAY // #ifdef MP-ALIPAY
uni.setNavigationBarTitle({ uni.setNavigationBarTitle({
title: "", title: '',
}); });
// #endif // #endif
if (!isEmpty(shareInfo.value)) { if (!isEmpty(shareInfo.value)) {
sheep.$platform.share.updateShareInfo(shareInfo.value); sheep.$platform.share.updateShareInfo(shareInfo.value);
} }
}) });
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,4 +1,5 @@
import packageInfo from '@/package.json'; import packageInfo from '@/package.json';
import { getWxEnvVersion } from '@/sheep/helper/env';
const { version } = packageInfo; const { version } = packageInfo;
@ -7,7 +8,21 @@ export let baseUrl;
if (process.env.NODE_ENV === 'development') { if (process.env.NODE_ENV === 'development') {
baseUrl = import.meta.env.SHOPRO_DEV_BASE_URL; baseUrl = import.meta.env.SHOPRO_DEV_BASE_URL;
} else { } else {
baseUrl = import.meta.env.SHOPRO_BASE_URL; // 非本地 dev 模式开发环境,判断是体验版还是正式版
const wxEnvVersion = getWxEnvVersion();
if (wxEnvVersion === 'trial') {
// 体验版使用体验版服务器地址
baseUrl = import.meta.env.SHOPRO_TRIAL_BASE_URL || import.meta.env.SHOPRO_BASE_URL;
console.log('当前运行环境:体验版');
} else if (wxEnvVersion === 'release') {
// 正式版使用生产服务器地址
baseUrl = import.meta.env.SHOPRO_BASE_URL;
console.log('当前运行环境:正式版');
} else {
// 其他平台或获取失败,使用默认地址
baseUrl = import.meta.env.SHOPRO_BASE_URL;
}
} }
if (typeof baseUrl === 'undefined') { if (typeof baseUrl === 'undefined') {
console.error('请检查.env配置文件是否存在'); console.error('请检查.env配置文件是否存在');

21
sheep/helper/env.js Normal file
View File

@ -0,0 +1,21 @@
/**
* 微信小程序运行环境develop / trial / release
* 其它平台默认 release整个 App 生命周期内不会变缓存一次
*/
let cachedEnvVersion;
export function getWxEnvVersion() {
if (cachedEnvVersion) return cachedEnvVersion;
// #ifdef MP-WEIXIN
try {
cachedEnvVersion = wx.getAccountInfoSync().miniProgram.envVersion;
} catch (e) {
console.log('获取微信小程序环境失败', e);
cachedEnvVersion = 'release';
}
// #endif
// #ifndef MP-WEIXIN
cachedEnvVersion = 'release';
// #endif
return cachedEnvVersion;
}

View File

@ -9,6 +9,7 @@ import $helper from '@/sheep/helper';
import AuthUtil from '@/sheep/api/member/auth'; import AuthUtil from '@/sheep/api/member/auth';
let configSuccess = false; let configSuccess = false;
let configAppId = ''; // JSSDK 初始化所使用的公众号 appId确认收款时需要
export default { export default {
// 判断是否在微信中 // 判断是否在微信中
@ -47,9 +48,11 @@ export default {
'updateAppMessageShareData', 'updateAppMessageShareData',
'updateTimelineShareData', 'updateTimelineShareData',
'scanQRCode', 'scanQRCode',
// 'requestMerchantTransfer', // TODO @使用者:如果需要微信商家转账功能,请打开该注释;
], // TODO 芋艿:后续可以设置更多权限; ], // TODO 芋艿:后续可以设置更多权限;
openTagList: data.openTagList, openTagList: data.openTagList,
}); });
configAppId = data.appId;
} else { } else {
console.log('请求 JSSDK 配置失败,错误码:', code); console.log('请求 JSSDK 配置失败,错误码:', code);
} }
@ -195,4 +198,50 @@ export default {
}); });
}); });
}, },
// 商家转账用户确认收款H5 / 公众号)
// 可见 https://pay.weixin.qq.com/doc/v3/merchant/4012716430 文档
requestMerchantTransfer(data, callback) {
const invoke = () => {
// WeixinJSBridge 内置对象,仅在微信客户端中有效
if (typeof WeixinJSBridge === 'undefined') {
callback.fail && callback.fail({ errMsg: '请在微信客户端中打开页面后再确认收款' });
return;
}
WeixinJSBridge.invoke(
'requestMerchantTransfer',
{
mchId: data.mchId,
appId: data.appId || configAppId,
package: data.package,
},
function (res) {
if (res.err_msg === 'requestMerchantTransfer:ok') {
callback.success && callback.success(res);
} else if (res.err_msg === 'requestMerchantTransfer:cancel') {
callback.cancel && callback.cancel(res);
} else {
callback.fail && callback.fail(res);
}
},
);
};
this.isReady(() => {
// 校验微信客户端是否支持 requestMerchantTransfer
jweixin.checkJsApi({
jsApiList: ['requestMerchantTransfer'],
success: function (res) {
if (res.checkResult && res.checkResult['requestMerchantTransfer']) {
invoke();
} else {
callback.fail && callback.fail({ errMsg: '你的微信版本过低,请更新至最新版本' });
}
},
fail: function () {
// checkJsApi 失败时,兜底直接尝试调用
invoke();
},
});
});
},
}; };

View File

@ -2,6 +2,7 @@ import $wxsdk from '@/sheep/libs/sdk-h5-weixin';
import { getRootUrl } from '@/sheep/helper'; import { getRootUrl } from '@/sheep/helper';
import AuthUtil from '@/sheep/api/member/auth'; import AuthUtil from '@/sheep/api/member/auth';
import SocialApi from '@/sheep/api/member/social'; import SocialApi from '@/sheep/api/member/social';
import sheep from '@/sheep';
const socialType = 31; // 社交类型 - 微信公众号 const socialType = 31; // 社交类型 - 微信公众号
@ -94,6 +95,30 @@ async function getInfo() {
return data; return data;
} }
// 商家转账用户确认模式下,拉起页面请求用户确认收款 Transfer
// 入参与小程序保持一致:(mchId, packageInfo, successCallback, failCallback)
function requestMerchantTransfer(mchId, packageInfo, successCallback, failCallback) {
$wxsdk.requestMerchantTransfer(
{
mchId,
package: packageInfo,
},
{
success: (res) => {
successCallback && successCallback({ result: 'success', ...res });
},
cancel: (res) => {
sheep.$helper.toast('确认收款已取消');
failCallback && failCallback({ result: 'cancel', errMsg: '确认收款已取消', ...res });
},
fail: (res) => {
sheep.$helper.toast(res.errMsg || '确认收款失败');
failCallback && failCallback({ result: 'fail', ...res });
},
},
);
}
export default { export default {
load, load,
login, login,
@ -101,5 +126,6 @@ export default {
unbind, unbind,
getInfo, getInfo,
getOpenid, getOpenid,
requestMerchantTransfer,
jsWxSdk: $wxsdk, jsWxSdk: $wxsdk,
}; };

View File

@ -107,7 +107,7 @@ const buildSpmLink = (query, linkAddress = '') => {
}; };
// 解析Spm // 解析Spm
const decryptSpm = (spm) => { const decryptSpm = async (spm) => {
const user = $store('user'); const user = $store('user');
let shareParamsArray = spm.split('.'); let shareParamsArray = spm.split('.');
let shareParams = { let shareParams = {
@ -168,7 +168,7 @@ const decryptSpm = (spm) => {
uni.setStorageSync('shareId', shareParams.shareId); uni.setStorageSync('shareId', shareParams.shareId);
// 已登录 绑定推广员 // 已登录 绑定推广员
if (!!user.isLogin) { if (!!user.isLogin) {
bindBrokerageUser(shareParams.shareId); await bindBrokerageUser(shareParams.shareId);
} }
} }

View File

@ -230,12 +230,14 @@ const refreshToken = async (config) => {
// 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了 // 如果未认证,并且未进行刷新令牌,说明可能是访问令牌过期了
if (!isRefreshToken) { if (!isRefreshToken) {
isRefreshToken = true;
// 1. 如果获取不到刷新令牌,则只能执行登出操作 // 1. 如果获取不到刷新令牌,则只能执行登出操作
const refreshToken = getRefreshToken(); const refreshToken = getRefreshToken();
if (!refreshToken) { if (!refreshToken) {
return handleAuthorized(); return handleAuthorized();
} }
// 只有真正发起刷新时才标记刷新中,避免无刷新令牌时状态一直卡住,后续 401 不再弹登录框
// https://github.com/yudaocode/yudao-mall-uniapp/issues/38
isRefreshToken = true;
// 2. 进行刷新访问令牌 // 2. 进行刷新访问令牌
try { try {
const refreshTokenResult = await AuthUtil.refreshToken(refreshToken); const refreshTokenResult = await AuthUtil.refreshToken(refreshToken);

View File

@ -8,8 +8,7 @@ import user from './user';
import sys from './sys'; import sys from './sys';
import { baseUrl, h5Url } from '@/sheep/config'; import { baseUrl, h5Url } from '@/sheep/config';
const app = defineStore({ const app = defineStore('app', {
id: 'app',
state: () => ({ state: () => ({
paramsForTabbar: {}, // 为全局tabbar跳转传参用。原因是 tabbar 无法传参,只能通过全局状态传递 paramsForTabbar: {}, // 为全局tabbar跳转传参用。原因是 tabbar 无法传参,只能通过全局状态传递
info: { info: {

View File

@ -1,8 +1,7 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import CartApi from '@/sheep/api/trade/cart'; import CartApi from '@/sheep/api/trade/cart';
const cart = defineStore({ const cart = defineStore('cart', {
id: 'cart',
state: () => ({ state: () => ({
list: [], // 购物车列表invalidList + validList list: [], // 购物车列表invalidList + validList
selectedIds: [], // 已选列表 selectedIds: [], // 已选列表

View File

@ -1,7 +1,6 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
const modal = defineStore({ const modal = defineStore('modal', {
id: 'modal',
state: () => ({ state: () => ({
auth: '', // 授权弹框 accountLogin|smsLogin|resetPassword|changeMobile|changePassword|changeUsername auth: '', // 授权弹框 accountLogin|smsLogin|resetPassword|changeMobile|changePassword|changeUsername
share: false, // 分享弹框 share: false, // 分享弹框

View File

@ -1,8 +1,7 @@
import { defineStore } from 'pinia'; import { defineStore } from 'pinia';
import app from './app'; import app from './app';
const sys = defineStore({ const sys = defineStore('sys', {
id: 'sys',
state: () => ({ state: () => ({
theme: '', // 主题, theme: '', // 主题,
mode: 'light', // 明亮模式、暗黑模式(暂未支持) mode: 'light', // 明亮模式、暗黑模式(暂未支持)

View File

@ -36,8 +36,7 @@ const defaultNumData = {
}, },
}; };
const user = defineStore({ const user = defineStore('user', {
id: 'user',
state: () => ({ state: () => ({
userInfo: clone(defaultUserInfo), // 用户信息 userInfo: clone(defaultUserInfo), // 用户信息
userWallet: clone(defaultUserWallet), // 用户钱包信息 userWallet: clone(defaultUserWallet), // 用户钱包信息