feat: 初始化项目配置和样式- 添加项目环境变量配置文件 (.env)

- 创建代码忽略文件列表 (.gitignore)
- 设置代码格式化规则 (.prettierrc)- 添加各种样式文件,包括背景、边框、按钮、卡片等组件样式
- 创建暗黑主题样式文件
- 添加表单和代码样式文件
This commit is contained in:
liguigong
2025-09-12 09:53:45 +08:00
commit b91b273686
582 changed files with 90552 additions and 0 deletions
+175
View File
@@ -0,0 +1,175 @@
/**
* Shopro 第三方平台功能聚合
* @version 1.0.3
* @author lidongtony
* @param {String} name - 厂商+平台名称
* @param {String} provider - 厂商
* @param {String} platform - 平台名称
* @param {String} os - 系统型号
* @param {Object} device - 设备信息
*/
import { isEmpty } from 'lodash-es';
// #ifdef H5
import { isWxBrowser } from '@/sheep/helper/utils';
// #endif
import wechat from './provider/wechat/index.js';
import apple from './provider/apple';
import share from './share';
import Pay from './pay';
const device = uni.getWindowInfo();
const os = uni.getDeviceInfo().platform;
let name = '';
let provider = '';
let platform = '';
let isWechatInstalled = true;
// #ifdef H5
if (isWxBrowser()) {
name = 'WechatOfficialAccount';
provider = 'wechat';
platform = 'officialAccount';
} else {
name = 'H5';
platform = 'h5';
}
// #endif
// #ifdef APP-PLUS
name = 'App';
platform = 'openPlatform';
// 检查微信客户端是否安装,否则AppleStore会因此拒绝上架
if (os === 'ios') {
isWechatInstalled = plus.ios.import('WXApi').isWXAppInstalled();
}
// #endif
// #ifdef MP-WEIXIN
name = 'WechatMiniProgram';
platform = 'miniProgram';
provider = 'wechat';
// #endif
if (isEmpty(name)) {
uni.showToast({
title: '暂不支持该平台',
icon: 'none',
});
}
// 加载当前平台前置行为
const load = () => {
if (provider === 'wechat') {
wechat.load();
}
};
// 使用厂商独占sdk name = 'wechat' | 'alipay' | 'apple'
const useProvider = (_provider = '') => {
if (_provider === '') _provider = provider;
if (_provider === 'wechat') return wechat;
if (_provider === 'apple') return apple;
};
// 支付服务转发
const pay = (payment, orderType, orderSN) => {
return new Pay(payment, orderType, orderSN);
};
/**
* 检查更新 (只检查小程序和App)
* @param {Boolean} silence - 静默检查
*/
const checkUpdate = (silence = false) => {
let canUpdate;
// #ifdef MP-WEIXIN
useProvider().checkUpdate(silence);
// #endif
// #ifdef APP-PLUS
// TODO: 热更新
// #endif
};
/**
* 检查网络
* @param {Boolean} silence - 静默检查
*/
async function checkNetwork() {
const networkStatus = await uni.getNetworkType();
if (networkStatus.networkType == 'none') {
return Promise.resolve(false);
}
return Promise.resolve(true);
}
// 获取小程序胶囊信息
const getCapsule = () => {
// #ifdef MP
let capsule = uni.getMenuButtonBoundingClientRect();
if (!capsule) {
capsule = {
bottom: 56,
height: 32,
left: 278,
right: 365,
top: 24,
width: 87,
};
}
return capsule;
// #endif
// #ifndef MP
return {
bottom: 56,
height: 32,
left: 278,
right: 365,
top: 24,
width: 87,
};
// #endif
};
const capsule = getCapsule();
// 标题栏高度
const getNavBar = () => {
return device.statusBarHeight + 44;
};
const navbar = getNavBar();
function getLandingPage() {
let page = '';
// #ifdef H5
page = location.href.split('?')[0];
// #endif
return page;
}
// 设置ios+公众号网页落地页 解决微信sdk签名问题
const landingPage = getLandingPage();
const _platform = {
name,
device,
os,
provider,
platform,
useProvider,
checkUpdate,
checkNetwork,
pay,
share,
load,
capsule,
navbar,
landingPage,
isWechatInstalled,
};
export default _platform;
+415
View File
@@ -0,0 +1,415 @@
import sheep from '@/sheep';
// #ifdef H5
import $wxsdk from '@/sheep/libs/sdk-h5-weixin';
// #endif
import { getRootUrl } from '@/sheep/helper';
import PayOrderApi from '@/sheep/api/pay/order';
/**
* 支付
*
* @param {String} payment = ['wechat','alipay','wallet','mock'] - 支付方式
* @param {String} orderType = ['goods','recharge','groupon'] - 订单类型
* @param {String} id - 订单号
*/
export default class SheepPay {
constructor(payment, orderType, id) {
this.payment = payment;
this.id = id;
this.orderType = orderType;
this.payAction();
}
payAction() {
const payAction = {
WechatOfficialAccount: {
wechat: () => {
this.wechatOfficialAccountPay();
},
alipay: () => {
this.redirectPay(); // 现在公众号可以直接跳转支付宝页面
},
wallet: () => {
this.walletPay();
},
mock: () => {
this.mockPay();
},
},
WechatMiniProgram: {
wechat: () => {
this.wechatMiniProgramPay();
},
alipay: () => {
this.copyPayLink();
},
wallet: () => {
this.walletPay();
},
mock: () => {
this.mockPay();
},
},
App: {
wechat: () => {
this.wechatAppPay();
},
alipay: () => {
this.alipay();
},
wallet: () => {
this.walletPay();
},
mock: () => {
this.mockPay();
},
},
H5: {
wechat: () => {
this.wechatWapPay();
},
alipay: () => {
this.redirectPay();
},
wallet: () => {
this.walletPay();
},
mock: () => {
this.mockPay();
},
},
};
return payAction[sheep.$platform.name][this.payment]();
}
// 预支付
prepay(channel) {
return new Promise(async (resolve, reject) => {
let data = {
id: this.id,
channelCode: channel,
channelExtras: {},
};
// 特殊逻辑:微信公众号、小程序支付时,必须传入 openid
if (['wx_pub', 'wx_lite'].includes(channel)) {
const openid = await sheep.$platform.useProvider('wechat').getOpenid();
// 如果获取不到 openid,微信无法发起支付,此时需要引导
if (!openid) {
this.bindWeixin();
return;
}
data.channelExtras.openid = openid;
}
// 发起预支付 API 调用
PayOrderApi.submitOrder(data).then((res) => {
// 成功时
res.code === 0 && resolve(res);
// 失败时
if (res.code !== 0 && res.msg.indexOf('无效的openid') >= 0) {
// 特殊逻辑:微信公众号、小程序支付时,必须传入 openid 不正确的情况
if (
res.msg.indexOf('无效的openid') >= 0 || // 获取的 openid 不正确时,或者随便输入了个 openid
res.msg.indexOf('下单账号与支付账号不一致') >= 0
) {
// https://developers.weixin.qq.com/community/develop/doc/00008c53c347804beec82aed051c00
this.bindWeixin();
}
}
});
});
}
// #ifdef H5
// 微信公众号 JSSDK 支付
async wechatOfficialAccountPay() {
let { code, data } = await this.prepay('wx_pub');
if (code !== 0) {
return;
}
const payConfig = JSON.parse(data.displayContent);
$wxsdk.wxpay(payConfig, {
success: () => {
this.payResult('success');
},
cancel: () => {
sheep.$helper.toast('支付已手动取消');
},
fail: (error) => {
if (error.errMsg.indexOf('chooseWXPay:没有此SDK或暂不支持此SDK模拟') >= 0) {
sheep.$helper.toast(
'发起微信支付失败,原因:可能是微信开发者工具不支持,建议使用微信打开网页后支付',
);
return;
}
this.payResult('fail');
},
});
}
// 浏览器微信 H5 支付 TODO 芋艿:待接入(注意:H5 支付是给普通浏览器,不是微信公众号的支付,绝大多数人用不到,可以忽略)
async wechatWapPay() {
const { error, data } = await this.prepay();
if (error === 0) {
const redirect_url = `${getRootUrl()}pages/pay/result?id=${this.id}&payment=${
this.payment
}&orderType=${this.orderType}`;
location.href = `${data.pay_data.h5_url}&redirect_url=${encodeURIComponent(redirect_url)}`;
}
}
// 支付链接(支付宝 wap 支付)
async redirectPay() {
let { code, data } = await this.prepay('alipay_wap');
if (code !== 0) {
return;
}
location.href = data.displayContent;
}
// #endif
// 微信小程序支付
async wechatMiniProgramPay() {
// let that = this;
let { code, data } = await this.prepay('wx_lite');
if (code !== 0) {
return;
}
// 调用微信小程序支付
const payConfig = JSON.parse(data.displayContent);
uni.requestPayment({
provider: 'wxpay',
timeStamp: payConfig.timeStamp,
nonceStr: payConfig.nonceStr,
package: payConfig.packageValue,
signType: payConfig.signType,
paySign: payConfig.paySign,
success: (res) => {
this.payResult('success');
},
fail: (err) => {
if (err.errMsg === 'requestPayment:fail cancel') {
sheep.$helper.toast('支付已手动取消');
} else {
this.payResult('fail');
}
},
});
}
// 余额支付
async walletPay() {
const { code } = await this.prepay('wallet');
code === 0 && this.payResult('success');
}
// 模拟支付
async mockPay() {
const { code } = await this.prepay('mock');
code === 0 && this.payResult('success');
}
// 支付宝复制链接支付(通过支付宝 wap 支付实现)
async copyPayLink() {
let { code, data } = await this.prepay('alipay_wap');
if (code !== 0) {
return;
}
// 引入 showModal 点击确认:复制链接;
uni.showModal({
title: '支付宝支付',
content: '复制链接到外部浏览器',
confirmText: '复制链接',
success: (res) => {
if (res.confirm) {
sheep.$helper.copyText(data.displayContent);
}
},
});
}
// 支付宝支付(App
async alipay() {
let that = this;
const { code, data } = await this.prepay('alipay_app');
if (code !== 0) {
return;
}
// TODO @芋艿:【可优化】如果是沙箱支付,EnvUtils.setEnv(EnvUtils.EnvEnum.SANDBOX),相关 https://t.zsxq.com/yjyJQ
uni.requestPayment({
provider: 'alipay',
orderInfo: data.displayContent, // 直接使用返回的支付参数
success: (res) => {
that.payResult('success');
},
fail: (err) => {
if (err.errMsg === 'requestPayment:fail [paymentAlipay:62001]user cancel') {
sheep.$helper.toast('支付已手动取消');
} else {
that.payResult('fail');
}
},
});
}
// 微信支付(App
async wechatAppPay() {
let that = this;
// 获取预支付信息
let { code, data } = await this.prepay('wx_app');
if (code !== 0) {
sheep.$helper.toast('获取支付信息失败');
return;
}
// 解析支付参数
let payConfig = JSON.parse(data.displayContent);
if(typeof payConfig.appId === 'undefined'){
payConfig.appId = payConfig.appid;
}
if(typeof payConfig.nonceStr === 'undefined'){
payConfig.nonceStr = payConfig.noncestr;
}
if(typeof payConfig.timeStamp === 'undefined'){
payConfig.timeStamp = payConfig.timestamp;
}
// 调用微信支付
uni.requestPayment({
provider: 'wxpay',
timeStamp: payConfig.timeStamp,
nonceStr: payConfig.nonceStr,
package: payConfig.packageValue,
signType: payConfig.signType,
paySign: payConfig.paySign,
success: (res) => {
that.payResult('success');
},
fail: (err) => {
if (err.errMsg === 'requestPayment:fail cancel') {
sheep.$helper.toast('支付已手动取消');
} else {
sheep.$helper.toast('支付失败:' + err.errMsg);
that.payResult('fail');
}
},
});
}
// 支付结果跳转,success:成功,fail:失败
payResult(resultType) {
goPayResult(this.id, this.orderType, resultType);
}
// 引导绑定微信
bindWeixin() {
goBindWeixin();
}
}
export function getPayMethods(channels) {
const payMethods = [
{
icon: '/static/img/shop/pay/wechat.png',
title: '微信支付',
value: 'wechat',
disabled: true,
},
{
icon: '/static/img/shop/pay/alipay.png',
title: '支付宝支付',
value: 'alipay',
disabled: true,
},
{
icon: '/static/img/shop/pay/wallet.png',
title: '余额支付',
value: 'wallet',
disabled: true,
},
{
icon: '/static/img/shop/pay/apple.png',
title: 'Apple Pay',
value: 'apple',
disabled: true,
},
{
icon: '/static/img/shop/pay/wallet.png',
title: '模拟支付',
value: 'mock',
disabled: true,
},
];
const platform = sheep.$platform.name;
// 1. 处理【微信支付】
const wechatMethod = payMethods[0];
if (
(platform === 'WechatOfficialAccount' && channels.includes('wx_pub')) ||
(platform === 'WechatMiniProgram' && channels.includes('wx_lite')) ||
(platform === 'App' && channels.includes('wx_app'))
) {
wechatMethod.disabled = false;
}
// 2. 处理【支付宝支付】
const alipayMethod = payMethods[1];
if (
(platform === 'H5' && channels.includes('alipay_wap')) ||
(platform === 'WechatOfficialAccount' && channels.includes('alipay_wap')) ||
(platform === 'WechatMiniProgram' && channels.includes('alipay_wap')) ||
(platform === 'App' && channels.includes('alipay_app'))
) {
alipayMethod.disabled = false;
}
// 3. 处理【余额支付】
const walletMethod = payMethods[2];
if (channels.includes('wallet')) {
walletMethod.disabled = false;
}
// 4. 处理【苹果支付】TODO 芋艿:未来接入
// 5. 处理【模拟支付】
const mockMethod = payMethods[4];
if (channels.includes('mock')) {
mockMethod.disabled = false;
}
return payMethods;
}
// 支付结果跳转,success:成功,fail:失败
export function goPayResult(id, orderType, resultType) {
sheep.$router.redirect('/pages/pay/result', {
id,
orderType,
payState: resultType,
});
}
export function goBindWeixin() {
uni.showModal({
title: '微信支付',
content: '请先绑定微信再使用微信支付',
success: function (res) {
if (res.confirm) {
sheep.$platform.useProvider('wechat').bind();
}
},
});
}
// 获取微信支付渠道码
export function getWeixinPayChannelCode() {
const platform = sheep.$platform.name;
switch (platform) {
case 'WechatOfficialAccount':
return 'wx_pub';
case 'WechatMiniProgram':
return 'wx_lite';
case 'App':
return 'wx_app';
case 'H5':
return 'wx_wap';
default:
return '';
}
}
+36
View File
@@ -0,0 +1,36 @@
// import third from '@/sheep/api/third';
// TODO 芋艿:等后面搞 App 再弄
const login = () => {
return new Promise(async (resolve, reject) => {
const loginRes = await uni.login({
provider: 'apple',
success: () => {
uni.getUserInfo({
provider: 'apple',
success: async (res) => {
if (res.errMsg === 'getUserInfo:ok') {
const payload = res.userInfo;
const { error } = await third.apple.login({
payload,
shareInfo: uni.getStorageSync('shareLog') || {},
});
if (error === 0) {
resolve(true);
} else {
resolve(false);
}
}
},
});
},
fail: (err) => {
resolve(false);
},
});
});
};
export default {
login,
};
+9
View File
@@ -0,0 +1,9 @@
// #ifdef APP-PLUS
import service from './app';
// #endif
let apple = {};
if (typeof service !== 'undefined') {
apple = service;
}
export default apple;
+15
View File
@@ -0,0 +1,15 @@
// #ifdef H5
import service from './officialAccount';
// #endif
// #ifdef MP-WEIXIN
import service from './miniProgram';
// #endif
// #ifdef APP-PLUS
import service from './openPlatform';
// #endif
const wechat = service;
export default wechat;
@@ -0,0 +1,241 @@
import AuthUtil from '@/sheep/api/member/auth';
import SocialApi from '@/sheep/api/member/social';
import UserApi from '@/sheep/api/member/user';
import sheep from '@/sheep';
const socialType = 34; // 社交类型 - 微信小程序
let subscribeEventList = [];
// 加载微信小程序
function load() {
checkUpdate();
getSubscribeTemplate();
}
// 微信小程序静默授权登陆
const login = async () => {
return new Promise(async (resolve, reject) => {
// 1. 获得微信 code
const codeResult = await uni.login();
if (codeResult.errMsg !== 'login:ok') {
return resolve(false);
}
// 2. 社交登录
const loginResult = await AuthUtil.socialLogin(socialType, codeResult.code, 'default');
if (loginResult.code === 0) {
setOpenid(loginResult.data.openid);
return resolve(true);
} else {
return resolve(false);
}
});
};
// 微信小程序手机号授权登陆
const mobileLogin = async (e) => {
return new Promise(async (resolve, reject) => {
if (e.errMsg !== 'getPhoneNumber:ok') {
return resolve(false);
}
// 1. 获得微信 code
const codeResult = await uni.login();
if (codeResult.errMsg !== 'login:ok') {
return resolve(false);
}
// 2. 一键登录
const loginResult = await AuthUtil.weixinMiniAppLogin(e.code, codeResult.code, 'default');
if (loginResult.code === 0) {
setOpenid(loginResult.data.openid);
return resolve(true);
} else {
return resolve(false);
}
});
};
// 微信小程序绑定
const bind = () => {
return new Promise(async (resolve, reject) => {
// 1. 获得微信 code
const codeResult = await uni.login();
if (codeResult.errMsg !== 'login:ok') {
return resolve(false);
}
// 2. 绑定账号
const bindResult = await SocialApi.socialBind(socialType, codeResult.code, 'default');
if (bindResult.code === 0) {
setOpenid(bindResult.data);
return resolve(true);
} else {
return resolve(false);
}
});
};
// 微信小程序解除绑定
const unbind = async (openid) => {
const { code } = await SocialApi.socialUnbind(socialType, openid);
return code === 0;
};
// 绑定用户手机号
const bindUserPhoneNumber = (e) => {
return new Promise(async (resolve, reject) => {
const { code } = await UserApi.updateUserMobileByWeixin(e.code);
if (code === 0) {
resolve(true);
}
resolve(false);
});
};
// 设置 openid 到本地存储,目前只有 pay 支付时会使用
function setOpenid(openid) {
uni.setStorageSync('openid', openid);
}
// 获得 openid
async function getOpenid(force = false) {
let openid = uni.getStorageSync('openid');
if (!openid && force) {
const info = await getInfo();
if (info && info.openid) {
openid = info.openid;
setOpenid(openid);
}
}
return openid;
}
// 获得社交信息
async function getInfo() {
const { code, data } = await SocialApi.getSocialUser(socialType);
if (code !== 0) {
return undefined;
}
return data;
}
// ========== 非登录相关的逻辑 ==========
// 小程序更新
const checkUpdate = async (silence = true) => {
if (uni.canIUse('getUpdateManager')) {
const updateManager = uni.getUpdateManager();
updateManager.onCheckForUpdate(function (res) {
// 请求完新版本信息的回调
if (res.hasUpdate) {
updateManager.onUpdateReady(function () {
uni.showModal({
title: '更新提示',
content: '新版本已经准备好,是否重启应用?',
success: function (res) {
if (res.confirm) {
// 新的版本已经下载好,调用 applyUpdate 应用新版本并重启
updateManager.applyUpdate();
}
},
});
});
updateManager.onUpdateFailed(function () {
// 新的版本下载失败
// uni.showModal({
// title: '已经有新版本了哟~',
// content: '新版本已经上线啦,请您删除当前小程序,重新搜索打开~',
// });
});
} else {
if (!silence) {
uni.showModal({
title: '当前为最新版本',
showCancel: false,
});
}
}
});
}
};
// 获取订阅消息模板
async function getSubscribeTemplate() {
const { code, data } = await SocialApi.getSubscribeTemplateList();
if (code === 0) {
subscribeEventList = data;
}
}
// 订阅消息
function subscribeMessage(event, callback = undefined) {
let tmplIds = [];
if (typeof event === 'string') {
const temp = subscribeEventList.find((item) => item.title.includes(event));
if (temp) {
tmplIds.push(temp.id);
}
}
if (typeof event === 'object') {
event.forEach((e) => {
const temp = subscribeEventList.find((item) => item.title.includes(e));
if (temp) {
tmplIds.push(temp.id);
}
});
}
if (tmplIds.length === 0) return;
uni.requestSubscribeMessage({
tmplIds,
success: () => {
// 不管是拒绝还是同意都触发
callback && callback();
},
fail: (err) => {
console.log(err);
},
});
}
// 商家转账用户确认模式下,拉起页面请求用户确认收款 Transfer
function requestMerchantTransfer(mchId, packageInfo, successCallback, failCallback) {
if (!wx.canIUse('requestMerchantTransfer')) {
wx.showModal({
content: '你的微信版本过低,请更新至最新版本。',
showCancel: false,
});
return;
}
wx.requestMerchantTransfer({
mchId: mchId,
appId: wx.getAccountInfoSync().miniProgram.appId,
package: packageInfo,
success: (res) => {
// res.err_msg 将在页面展示成功后返回应用时返回 ok,并不代表付款成功
console.log('success:', res);
successCallback && successCallback(res);
},
fail: (res) => {
console.log('fail:', res);
sheep.$helper.toast(res.errMsg);
failCallback && failCallback(res);
},
});
}
export default {
load,
login,
bind,
unbind,
bindUserPhoneNumber,
mobileLogin,
getInfo,
getOpenid,
subscribeMessage,
checkUpdate,
requestMerchantTransfer,
};
@@ -0,0 +1,105 @@
import $wxsdk from '@/sheep/libs/sdk-h5-weixin';
import { getRootUrl } from '@/sheep/helper';
import AuthUtil from '@/sheep/api/member/auth';
import SocialApi from '@/sheep/api/member/social';
const socialType = 31; // 社交类型 - 微信公众号
// 加载微信公众号JSSDK
async function load() {
$wxsdk.init();
}
// 微信公众号登陆
async function login(code = '', state = '') {
// 情况一:没有 code 时,去获取 code
if (!code) {
const loginUrl = await getLoginUrl();
if (loginUrl) {
uni.setStorageSync('returnUrl', location.href);
window.location = loginUrl;
}
// 情况二:有 code 时,使用 code 去自动登录
} else {
// 解密 code 发起登陆
const loginResult = await AuthUtil.socialLogin(socialType, code, state);
if (loginResult.code === 0) {
setOpenid(loginResult.data.openid);
return loginResult;
}
}
return false;
}
// 微信公众号绑定
async function bind(code = '', state = '') {
// 情况一:没有 code 时,去获取 code
if (code === '') {
const loginUrl = await getLoginUrl('bind');
if (loginUrl) {
uni.setStorageSync('returnUrl', location.href);
window.location = loginUrl;
}
} else {
// 情况二:有 code 时,使用 code 去自动绑定
const loginResult = await SocialApi.socialBind(socialType, code, state);
if (loginResult.code === 0) {
setOpenid(loginResult.data);
return loginResult;
}
}
return false;
}
// 微信公众号解除绑定
const unbind = async (openid) => {
const { code } = await SocialApi.socialUnbind(socialType, openid);
return code === 0;
};
// 获取公众号登陆地址
async function getLoginUrl(event = 'login') {
const page = getRootUrl() + 'pages/index/login' + '?event=' + event; // event 目的,区分是 login 还是 bind
const { code, data } = await AuthUtil.socialAuthRedirect(socialType, page);
if (code !== 0) {
return undefined;
}
return data;
}
// 设置 openid 到本地存储,目前只有 pay 支付时会使用
function setOpenid(openid) {
uni.setStorageSync('openid', openid);
}
// 获得 openid
async function getOpenid(force = false) {
let openid = uni.getStorageSync('openid');
if (!openid && force) {
const info = await getInfo();
if (info && info.openid) {
openid = info.openid;
setOpenid(openid);
}
}
return openid;
}
// 获得社交信息
async function getInfo() {
const { code, data } = await SocialApi.getSocialUser(socialType);
if (code !== 0) {
return undefined;
}
return data;
}
export default {
load,
login,
bind,
unbind,
getInfo,
getOpenid,
jsWxSdk: $wxsdk,
};
@@ -0,0 +1,64 @@
// 登录
import third from '@/sheep/api/migration/third';
import SocialApi from '@/sheep/api/member/social';
import $share from '@/sheep/platform/share';
// TODO 芋艿:等后面搞 App 再弄
const socialType = 32; // 社交类型 - 微信开放平台
const load = async () => {};
// 微信开放平台移动应用授权登陆
const login = () => {
return new Promise(async (resolve, reject) => {
const loginRes = await uni.login({
provider: 'weixin',
onlyAuthorize: true,
});
debugger
if (loginRes.errMsg == 'login:ok') {
// TODO third.wechat.login 函数未实现
const res = await third.wechat.login({
platform: 'openPlatform',
shareInfo: uni.getStorageSync('shareLog') || {},
payload: encodeURIComponent(
JSON.stringify({
code: loginRes.code,
}),
),
});
if (res.error === 0) {
$share.bindBrokerageUser()
resolve(true);
}
} else {
uni.showToast({
icon: 'none',
title: loginRes.errMsg,
});
}
resolve(false);
});
};
// 微信 App 解除绑定
const unbind = async (openid) => {
const { code } = await SocialApi.socialUnbind(socialType, openid);
return code === 0;
};
// 获得社交信息
async function getInfo() {
const { code, data } = await SocialApi.getSocialUser(socialType);
if (code !== 0) {
return undefined;
}
return data;
}
export default {
load,
login,
getInfo
};
+213
View File
@@ -0,0 +1,213 @@
import $store from '@/sheep/store';
import $platform from '@/sheep/platform';
import $router from '@/sheep/router';
import $url from '@/sheep/url';
import BrokerageApi from '@/sheep/api/trade/brokerage';
import { SharePageEnum } from '@/sheep/helper/const';
// #ifdef H5
import $wxsdk from '@/sheep/libs/sdk-h5-weixin';
// #endif
// 设置分享的平台渠道: 1=H5,2=微信公众号网页,3=微信小程序,4=App,...按需扩展
const platformMap = ['H5', 'WechatOfficialAccount', 'WechatMiniProgram', 'App'];
// 设置分享方式: 1=直接转发,2=海报,3=复制链接,...按需扩展
const fromMap = ['forward', 'poster', 'link'];
// 设置分享信息参数
const getShareInfo = (
scene = {
title: '', // 自定义分享标题
desc: '', // 自定义描述
image: '', // 自定义分享图片
params: {}, // 自定义分享参数
},
poster = {
// 自定义海报数据
type: 'user',
},
) => {
const shareInfo = {
title: '', // 分享标题
desc: '', // 描述
image: '', // 分享图片
path: '', // 分享页面+参数
link: '', // 分享Url+参数
query: '', // 分享参数
poster, // 海报所需数据
forward: {}, // 转发所需参数
};
shareInfo.title = scene.title;
shareInfo.image = $url.cdn(scene.image);
shareInfo.desc = scene.desc;
const app = $store('app');
const shareConfig = app.platform.share;
// 自动拼接分享用户参数
const query = buildSpmQuery(scene.params);
shareInfo.query = query;
// 配置分享链接地址
shareInfo.link = buildSpmLink(query, shareConfig.linkAddress);
// 配置页面地址带参数
shareInfo.path = buildSpmPath();
// 配置页面转发参数
if (shareConfig.methods.includes('forward')) {
shareInfo.forward.path = buildSpmPath(query);
}
return shareInfo;
};
/**
* 构造 spm 分享参数
*
* @param params json 格式,其中包含:1shareId 分享用户的编号;2page 页面类型;3)query 页面 ID(参数);4platform 平台类型;5)from 分享来源类型。
* @return 分享串 `spm=${shareId}.${page}.${query}.${platform}.${from}`
*/
const buildSpmQuery = (params) => {
const user = $store('user');
let shareId = '0'; // 设置分享者用户ID
if (typeof params.shareId === 'undefined') {
if (user.isLogin) {
shareId = user.userInfo.id;
}
}
let page = SharePageEnum.HOME.value; // 页面类型,默认首页
if (typeof params.page !== 'undefined') {
page = params.page;
}
let query = '0'; // 设置页面ID: 如商品ID、拼团ID等
if (typeof params.query !== 'undefined') {
query = params.query;
}
let platform = platformMap.indexOf($platform.name) + 1;
let from = '1';
if (typeof params.from !== 'undefined') {
from = platformMap.indexOf(params.from) + 1;
}
// spmParams = ... 可按需扩展
return `spm=${shareId}.${page}.${query}.${platform}.${from}`;
};
// 构造页面分享参数: 所有的分享都先到首页进行 spm 参数解析
const buildSpmPath = (query) => {
// 默认是主页,页面 page,例如 pages/index/index,根路径前不要填加 /
// 不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面。scancode_time为系统保留参数,不允许配置
// 页面分享时参数使用 ? 拼接
return typeof query === 'undefined' ? `pages/index/index` : `pages/index/index?${query}`;
};
// 构造分享链接
const buildSpmLink = (query, linkAddress = '') => {
return `${linkAddress}?${query}`;
};
// 解析Spm
const decryptSpm = (spm) => {
const user = $store('user');
let shareParamsArray = spm.split('.');
let shareParams = {
spm,
shareId: 0,
page: '',
query: {},
platform: '',
from: '',
};
let query;
shareParams.shareId = shareParamsArray[0];
switch (shareParamsArray[1]) {
case SharePageEnum.HOME.value:
// 默认首页不跳转
shareParams.page = SharePageEnum.HOME.page;
break;
case SharePageEnum.GOODS.value:
// 普通商品
shareParams.page = SharePageEnum.GOODS.page;
shareParams.query = {
id: shareParamsArray[2], // 设置活动编号
};
break;
case SharePageEnum.GROUPON.value:
// 拼团商品
shareParams.page = SharePageEnum.GROUPON.page;
shareParams.query = {
id: shareParamsArray[2], // 设置活动编号
};
break;
case SharePageEnum.SECKILL.value:
// 秒杀商品
shareParams.page = SharePageEnum.SECKILL.page;
shareParams.query = {
id: shareParamsArray[2], // 设置活动编号
};
break;
case SharePageEnum.GROUPON_DETAIL.value:
// 参与拼团
shareParams.page = SharePageEnum.GROUPON_DETAIL.page;
shareParams.query = {
id: shareParamsArray[2], // 设置活动编号
};
break;
case SharePageEnum.POINT.value:
// 积分商品
shareParams.page = SharePageEnum.POINT.page;
shareParams.query = {
id: shareParamsArray[2], // 设置活动编号
};
break;
}
shareParams.platform = platformMap[shareParamsArray[3] - 1];
shareParams.from = fromMap[shareParamsArray[4] - 1];
if (shareParams.shareId !== 0) {
// 记录分享者编号
uni.setStorageSync('shareId', shareParams.shareId);
// 已登录 绑定推广员
if (!!user.isLogin) {
bindBrokerageUser(shareParams.shareId);
}
}
if (shareParams.page !== SharePageEnum.HOME.page) {
$router.go(shareParams.page, shareParams.query);
}
return shareParams;
};
// 绑定推广员
const bindBrokerageUser = async (val = undefined) => {
try {
const shareId = val || uni.getStorageSync('shareId');
if (!shareId) {
return;
}
// 绑定成功返回 true,失败返回 false
const { data } = await BrokerageApi.bindBrokerageUser({ bindUserId: shareId });
// 绑定成功后清除缓存
if (data) {
uni.removeStorageSync('shareId');
}
} catch (e) {
console.error(e);
}
};
// 更新公众号分享sdk
const updateShareInfo = (shareInfo) => {
// #ifdef H5
if ($platform.name === 'WechatOfficialAccount') {
$wxsdk.updateShareInfo(shareInfo);
}
// #endif
};
export default {
getShareInfo,
updateShareInfo,
decryptSpm,
bindBrokerageUser,
};