Merge branch 'dev' of gitea.51mars.com:Oak-Team/oak-general-business into dev

This commit is contained in:
Xu Chang 2025-11-06 15:09:21 +08:00
commit a4040a397b
22 changed files with 399 additions and 111 deletions

View File

@ -43,6 +43,9 @@ export declare function bindByEmail<ED extends EntityDict>(params: {
captcha: string;
env: WebEnv | WechatMpEnv | NativeEnv;
}, context: BRC<ED>): Promise<void>;
export declare function setUserAvatarFromWechat<ED extends EntityDict>(params: {
avatar: string;
}, context: BRC<ED>): Promise<void>;
export declare function refreshWechatPublicUserInfo<ED extends EntityDict>({}: {}, context: BRC<ED>): Promise<void>;
export declare function loginByWechat<ED extends EntityDict>(params: {
wechatLoginId: string;

View File

@ -1408,6 +1408,81 @@ async function setUserInfoFromWechat(user, userInfo, context) {
}, {});
}
}
//将获取的微信头像作为用户头像
export async function setUserAvatarFromWechat(params, context) {
const { avatar } = params;
const application = context.getApplication();
const { type, config } = application;
assert(type === 'wechatMp' || config.type === 'wechatMp');
const applicationId = context.getApplicationId();
const userId = context.getCurrentUserId();
const extraFiles = await context.select('extraFile', {
data: {
id: 1,
tag1: 1,
origin: 1,
bucket: 1,
objectId: 1,
filename: 1,
extra1: 1,
entity: 1,
entityId: 1,
},
filter: {
entity: 'user',
entityId: userId,
tag1: 'avatar',
}
}, { forUpdate: true });
const updateData = {};
if (avatar &&
(extraFiles?.length === 0 ||
composeFileUrl(application, extraFiles[0]) !== avatar)) {
// 需要更新新的avatar extra file
const extraFileOperations = [
{
id: await generateNewIdAsync(),
action: 'create',
data: Object.assign({
id: await generateNewIdAsync(),
tag1: 'avatar',
entity: 'user',
entityId: userId,
objectId: await generateNewIdAsync(),
origin: 'unknown',
extra1: avatar,
type: 'image',
filename: '',
bucket: '',
applicationId: applicationId,
}),
},
];
if (extraFiles.length > 0) {
extraFileOperations.push({
id: await generateNewIdAsync(),
action: 'remove',
data: {},
filter: {
id: extraFiles[0].id,
},
});
}
Object.assign(updateData, {
extraFile$entity: extraFileOperations,
});
}
if (Object.keys(updateData).length > 0) {
await context.operate('user', {
id: await generateNewIdAsync(),
action: 'update',
data: updateData,
filter: {
id: userId,
},
}, {});
}
}
async function tryRefreshWechatPublicUserInfo(wechatUserId, context) {
const [wechatUser] = await context.select('wechatUser', {
data: {
@ -2469,8 +2544,8 @@ export async function refreshToken(params, context) {
// 只有server模式去刷新token
// 'development' | 'production' | 'staging'
const intervals = {
development: 7200 * 1000,
staging: 600 * 1000,
development: 7200 * 1000, // 2小时
staging: 600 * 1000, // 十分钟
production: 600 * 1000, // 十分钟
};
let applicationId = token.applicationId;

View File

@ -4,6 +4,6 @@ declare const _default: (props: import("oak-frontend-base").ReactComponentProps<
entity: keyof EntityDict;
entityId: string;
autoUpload: boolean;
origin: import("../../../types/Config").CosOrigin | null;
origin: EntityDict["extraFile"]["Schema"]["origin"] | null;
}>) => React.ReactElement;
export default _default;

View File

@ -45,40 +45,47 @@ export default OakComponent({
origin: null,
},
methods: {
async onPickByMp() {
try {
const { errMsg, tempFiles } = await wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['album', 'camera'],
});
if (errMsg !== 'chooseMedia:ok') {
this.setMessage({
type: 'warning',
content: errMsg,
});
}
else {
await Promise.all(tempFiles.map(async (tempExtraFile) => {
const { tempFilePath, thumbTempFilePath, fileType, size, } = tempExtraFile;
const filePath = tempFilePath || thumbTempFilePath;
const fileFullName = filePath.match(/[^/]+(?!.*\/)/g)[0];
this.pushExtraFile({
name: fileFullName,
fileType,
size,
extra1: filePath,
});
}));
}
async onPickByMp(e) {
const { avatarUrl } = e.detail;
if (avatarUrl) {
// 使用微信头像
await this.features.cache.exec('setUserAvatarFromWechat', { avatar: avatarUrl });
}
catch (err) {
console.error(err);
if (err.errMsg !== 'chooseMedia:fail cancel') {
this.setMessage({
type: 'error',
content: err.errMsg,
else {
try {
const { errMsg, tempFiles } = await wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['album', 'camera'],
});
if (errMsg !== 'chooseMedia:ok') {
this.setMessage({
type: 'warning',
content: errMsg,
});
}
else {
await Promise.all(tempFiles.map(async (tempExtraFile) => {
const { tempFilePath, thumbTempFilePath, fileType, size, } = tempExtraFile;
const filePath = tempFilePath || thumbTempFilePath;
const fileFullName = filePath.match(/[^/]+(?!.*\/)/g)[0];
this.pushExtraFile({
name: fileFullName,
fileType,
size,
extra1: filePath,
});
}));
}
}
catch (err) {
console.error(err);
if (err.errMsg !== 'chooseMedia:fail cancel') {
this.setMessage({
type: 'error',
content: err.errMsg,
});
}
}
}
},

View File

@ -1,3 +1,6 @@
@import "../../../config/styles/mp/index.less";
@import "../../../config/styles/mp/mixins.less";
.avatar-box {
background: none;
}

View File

@ -1,8 +1,8 @@
<view class="avatar-box oak-class" bind:tap="onPickByMp">
<button class="avatar-box oak-class" open-type="chooseAvatar" bind:chooseavatar="onPickByMp">
<block wx:if="{{avatarUrl}}">
<l-avatar src="{{avatarUrl}}" size="120" />
</block>
<block wx:else>
<l-avatar icon="user" size="120" icon-size="60" />
<l-avatar icon="user" size="120" icon-size="60" />
</block>
</view>
</button>

View File

@ -18,14 +18,15 @@
oakPath="{{oakFullpath}}.extraFile$entity"
entity="user"
/>
<l-button
<!-- 2.27.1及以上版本不再支持 -->
<!-- <l-button
wx:if="{{canSyncWechat}}"
size="mini"
l-class="avatar-btn"
bind:lintap="syncWechatInfoMp"
>
{{t('syncWeChat')}}
</l-button>
</l-button> -->
</view>
<l-list
title="昵称"

View File

@ -212,6 +212,7 @@ export class Token extends Feature {
this.checkNeedSetPassword();
}
async syncUserInfoWechatMp() {
// 2.27.1及以上版本不再支持getUserProfile(返回头像为【灰色头像】,昵称为【微信用户】)
const info = await wx.getUserProfile({
desc: '同步微信昵称和头像信息',
});

View File

@ -727,5 +727,13 @@ export type AspectDict<ED extends EntityDict> = {
data: EntityDict['oauthApplication']['Schema'] | null;
alreadyAuth: boolean;
}>;
/**
*
* @param avatar url
* @returns
*/
setUserAvatarFromWechat: (params: {
avatar: string;
}, context: BackendRuntimeContext<ED>) => Promise<void>;
};
export default AspectDict;

View File

@ -1,4 +1,4 @@
import { bindByEmail, bindByMobile, loginByAccount, loginByEmail, loginByMobile, loginWechat, loginWechatMp, loginWechatNative, syncUserInfoWechatMp, sendCaptchaByMobile, sendCaptchaByEmail, switchTo, refreshWechatPublicUserInfo, getWechatMpUserPhoneNumber, logout, loginByWechat, wakeupParasite, refreshToken, verifyPassword, loginWebByMpToken } from './token';
import { bindByEmail, bindByMobile, loginByAccount, loginByEmail, loginByMobile, loginWechat, loginWechatMp, loginWechatNative, syncUserInfoWechatMp, sendCaptchaByMobile, sendCaptchaByEmail, switchTo, refreshWechatPublicUserInfo, getWechatMpUserPhoneNumber, logout, loginByWechat, wakeupParasite, refreshToken, verifyPassword, loginWebByMpToken, setUserAvatarFromWechat } from './token';
import { getInfoByUrl } from './extraFile';
import { getApplication, signatureJsSDK, uploadWechatMedia, batchGetArticle, getArticle, batchGetMaterialList, getMaterial, deleteMaterial } from './application';
import { updateConfig, updateApplicationConfig, updateStyle } from './config';
@ -85,6 +85,7 @@ declare const aspectDict: {
getOAuthClientInfo: typeof getOAuthClientInfo;
createOAuthState: typeof createOAuthState;
authorize: typeof authorize;
setUserAvatarFromWechat: typeof setUserAvatarFromWechat;
};
export default aspectDict;
export { AspectDict } from './AspectDict';

View File

@ -88,5 +88,6 @@ const aspectDict = {
getOAuthClientInfo: oauth_1.getOAuthClientInfo,
createOAuthState: oauth_1.createOAuthState,
authorize: oauth_1.authorize,
setUserAvatarFromWechat: token_1.setUserAvatarFromWechat,
};
exports.default = aspectDict;

View File

@ -43,6 +43,9 @@ export declare function bindByEmail<ED extends EntityDict>(params: {
captcha: string;
env: WebEnv | WechatMpEnv | NativeEnv;
}, context: BRC<ED>): Promise<void>;
export declare function setUserAvatarFromWechat<ED extends EntityDict>(params: {
avatar: string;
}, context: BRC<ED>): Promise<void>;
export declare function refreshWechatPublicUserInfo<ED extends EntityDict>({}: {}, context: BRC<ED>): Promise<void>;
export declare function loginByWechat<ED extends EntityDict>(params: {
wechatLoginId: string;

View File

@ -1,6 +1,28 @@
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.loginWebByMpToken = exports.refreshToken = exports.wakeupParasite = exports.logout = exports.getWechatMpUserPhoneNumber = exports.switchTo = exports.sendCaptchaByEmail = exports.sendCaptchaByMobile = exports.syncUserInfoWechatMp = exports.loginWechatMp = exports.loginWechat = exports.loginWechatNative = exports.loginByWechat = exports.refreshWechatPublicUserInfo = exports.bindByEmail = exports.bindByMobile = exports.loginByEmail = exports.loginByAccount = exports.verifyPassword = exports.loginByMobile = exports.loadTokenInfo = exports.setUpTokenAndUser = void 0;
exports.setUpTokenAndUser = setUpTokenAndUser;
exports.loadTokenInfo = loadTokenInfo;
exports.loginByMobile = loginByMobile;
exports.verifyPassword = verifyPassword;
exports.loginByAccount = loginByAccount;
exports.loginByEmail = loginByEmail;
exports.bindByMobile = bindByMobile;
exports.bindByEmail = bindByEmail;
exports.setUserAvatarFromWechat = setUserAvatarFromWechat;
exports.refreshWechatPublicUserInfo = refreshWechatPublicUserInfo;
exports.loginByWechat = loginByWechat;
exports.loginWechatNative = loginWechatNative;
exports.loginWechat = loginWechat;
exports.loginWechatMp = loginWechatMp;
exports.syncUserInfoWechatMp = syncUserInfoWechatMp;
exports.sendCaptchaByMobile = sendCaptchaByMobile;
exports.sendCaptchaByEmail = sendCaptchaByEmail;
exports.switchTo = switchTo;
exports.getWechatMpUserPhoneNumber = getWechatMpUserPhoneNumber;
exports.logout = logout;
exports.wakeupParasite = wakeupParasite;
exports.refreshToken = refreshToken;
exports.loginWebByMpToken = loginWebByMpToken;
const tslib_1 = require("tslib");
const uuid_1 = require("oak-domain/lib/utils/uuid");
const WechatSDK_1 = tslib_1.__importDefault(require("oak-external-sdk/lib/WechatSDK"));
@ -380,7 +402,6 @@ createData, user) {
}
}
}
exports.setUpTokenAndUser = setUpTokenAndUser;
async function setupMobile(mobile, env, context) {
const result2 = await context.select('mobile', {
data: {
@ -444,7 +465,6 @@ async function loadTokenInfo(tokenValue, context) {
},
}, {});
}
exports.loadTokenInfo = loadTokenInfo;
async function loginByMobile(params, context) {
const { mobile, captcha, env, disableRegister } = params;
const loginLogic = async (isRoot) => {
@ -540,7 +560,6 @@ async function loginByMobile(params, context) {
closeRootMode();
return tokenValue;
}
exports.loginByMobile = loginByMobile;
async function verifyPassword(params, context) {
const { password } = params;
const systemId = context.getSystemId();
@ -605,7 +624,6 @@ async function verifyPassword(params, context) {
}
}, {});
}
exports.verifyPassword = verifyPassword;
async function loginByAccount(params, context) {
const { account, password, env } = params;
let needUpdatePassword = false;
@ -958,7 +976,6 @@ async function loginByAccount(params, context) {
closeRootMode();
return tokenValue;
}
exports.loginByAccount = loginByAccount;
async function loginByEmail(params, context) {
const { email, captcha, env, disableRegister } = params;
const loginLogic = async () => {
@ -1029,7 +1046,6 @@ async function loginByEmail(params, context) {
closeRootMode();
return tokenValue;
}
exports.loginByEmail = loginByEmail;
async function bindByMobile(params, context) {
const { mobile, captcha, env, } = params;
const userId = context.getCurrentUserId();
@ -1141,7 +1157,6 @@ async function bindByMobile(params, context) {
await bindLogic();
closeRootMode();
}
exports.bindByMobile = bindByMobile;
async function bindByEmail(params, context) {
const { email, captcha, env, } = params;
const userId = context.getCurrentUserId();
@ -1254,7 +1269,6 @@ async function bindByEmail(params, context) {
await bindLogic();
closeRootMode();
}
exports.bindByEmail = bindByEmail;
async function setupLoginName(name, env, context) {
const result2 = await context.select('loginName', {
data: {
@ -1420,6 +1434,81 @@ async function setUserInfoFromWechat(user, userInfo, context) {
}, {});
}
}
//将获取的微信头像作为用户头像
async function setUserAvatarFromWechat(params, context) {
const { avatar } = params;
const application = context.getApplication();
const { type, config } = application;
(0, assert_1.assert)(type === 'wechatMp' || config.type === 'wechatMp');
const applicationId = context.getApplicationId();
const userId = context.getCurrentUserId();
const extraFiles = await context.select('extraFile', {
data: {
id: 1,
tag1: 1,
origin: 1,
bucket: 1,
objectId: 1,
filename: 1,
extra1: 1,
entity: 1,
entityId: 1,
},
filter: {
entity: 'user',
entityId: userId,
tag1: 'avatar',
}
}, { forUpdate: true });
const updateData = {};
if (avatar &&
(extraFiles?.length === 0 ||
(0, index_backend_1.composeFileUrl)(application, extraFiles[0]) !== avatar)) {
// 需要更新新的avatar extra file
const extraFileOperations = [
{
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'create',
data: Object.assign({
id: await (0, uuid_1.generateNewIdAsync)(),
tag1: 'avatar',
entity: 'user',
entityId: userId,
objectId: await (0, uuid_1.generateNewIdAsync)(),
origin: 'unknown',
extra1: avatar,
type: 'image',
filename: '',
bucket: '',
applicationId: applicationId,
}),
},
];
if (extraFiles.length > 0) {
extraFileOperations.push({
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'remove',
data: {},
filter: {
id: extraFiles[0].id,
},
});
}
Object.assign(updateData, {
extraFile$entity: extraFileOperations,
});
}
if (Object.keys(updateData).length > 0) {
await context.operate('user', {
id: await (0, uuid_1.generateNewIdAsync)(),
action: 'update',
data: updateData,
filter: {
id: userId,
},
}, {});
}
}
async function tryRefreshWechatPublicUserInfo(wechatUserId, context) {
const [wechatUser] = await context.select('wechatUser', {
data: {
@ -1508,7 +1597,6 @@ async function refreshWechatPublicUserInfo({}, context) {
(0, assert_1.assert)(token.entityId);
return await tryRefreshWechatPublicUserInfo(token.entityId, context);
}
exports.refreshWechatPublicUserInfo = refreshWechatPublicUserInfo;
// 用户在微信端授权登录后在web端触发该方法
async function loginByWechat(params, context) {
const { wechatLoginId, env } = params;
@ -1538,7 +1626,6 @@ async function loginByWechat(params, context) {
closeRootMode();
return tokenValue;
}
exports.loginByWechat = loginByWechat;
async function loginFromWechatEnv(code, env, context, wechatLoginId) {
const application = context.getApplication();
const { type, config, systemId } = application;
@ -1882,7 +1969,6 @@ async function loginWechatNative({ code, env, }, context) {
closeRootMode();
return tokenValue;
}
exports.loginWechatNative = loginWechatNative;
/**
* 公众号授权登录
* @param param0
@ -1913,7 +1999,6 @@ async function loginWechat({ code, env, wechatLoginId, }, context) {
closeRootMode();
return tokenValue;
}
exports.loginWechat = loginWechat;
/**
* 小程序授权登录
* @param param0
@ -1927,7 +2012,6 @@ async function loginWechatMp({ code, env, }, context) {
closeRootMode();
return tokenValue;
}
exports.loginWechatMp = loginWechatMp;
/**
* 同步从wx.getUserProfile拿到的用户信息
* @param param0
@ -1981,7 +2065,6 @@ async function syncUserInfoWechatMp({ nickname, avatarUrl, encryptedData, iv, si
// 实测发现解密出来的和userInfo完全一致……
await setUserInfoFromWechat(user, { nickname, avatar: avatarUrl }, context);
}
exports.syncUserInfoWechatMp = syncUserInfoWechatMp;
async function sendCaptchaByMobile({ mobile, env, type: captchaType, }, context) {
const { type } = env;
let visitorId = mobile;
@ -2146,7 +2229,6 @@ async function sendCaptchaByMobile({ mobile, env, type: captchaType, }, context)
return '验证码发送失败';
}
}
exports.sendCaptchaByMobile = sendCaptchaByMobile;
async function sendCaptchaByEmail({ email, env, type: captchaType, }, context) {
const { type } = env;
let visitorId = email;
@ -2294,7 +2376,6 @@ async function sendCaptchaByEmail({ email, env, type: captchaType, }, context) {
return '验证码发送失败';
}
}
exports.sendCaptchaByEmail = sendCaptchaByEmail;
async function switchTo({ userId }, context) {
const reallyRoot = context.isReallyRoot();
if (!reallyRoot) {
@ -2316,7 +2397,6 @@ async function switchTo({ userId }, context) {
},
}, {});
}
exports.switchTo = switchTo;
async function getWechatMpUserPhoneNumber({ code, env }, context) {
const application = context.getApplication();
const { type, config, systemId } = application;
@ -2332,7 +2412,6 @@ async function getWechatMpUserPhoneNumber({ code, env }, context) {
closeRootMode();
return reuslt;
}
exports.getWechatMpUserPhoneNumber = getWechatMpUserPhoneNumber;
async function logout(params, context) {
const { tokenValue } = params;
if (tokenValue) {
@ -2355,7 +2434,6 @@ async function logout(params, context) {
closeRootMode();
}
}
exports.logout = logout;
/**
* 创建一个当前parasite上的token
* @param params
@ -2422,7 +2500,6 @@ async function wakeupParasite(params, context) {
closeRootMode();
return tokenValue;
}
exports.wakeupParasite = wakeupParasite;
/**
* todo 检查登录环境一致性同一个token不能跨越不同设备
* @param env1
@ -2493,8 +2570,8 @@ async function refreshToken(params, context) {
// 只有server模式去刷新token
// 'development' | 'production' | 'staging'
const intervals = {
development: 7200 * 1000,
staging: 600 * 1000,
development: 7200 * 1000, // 2小时
staging: 600 * 1000, // 十分钟
production: 600 * 1000, // 十分钟
};
let applicationId = token.applicationId;
@ -2567,7 +2644,6 @@ async function refreshToken(params, context) {
closeRootMode();
return tokenValue;
}
exports.refreshToken = refreshToken;
/**
* 使用微信小程序中的token登录web
* @param tokenValue
@ -2635,4 +2711,3 @@ async function loginWebByMpToken(params, context) {
closeRootMode();
return tokenValue;
}
exports.loginWebByMpToken = loginWebByMpToken;

View File

@ -215,6 +215,7 @@ class Token extends Feature_1.Feature {
this.checkNeedSetPassword();
}
async syncUserInfoWechatMp() {
// 2.27.1及以上版本不再支持getUserProfile(返回头像为【灰色头像】,昵称为【微信用户】)
const info = await wx.getUserProfile({
desc: '同步微信昵称和头像信息',
});

View File

@ -997,6 +997,17 @@ export type AspectDict<ED extends EntityDict> = {
data: EntityDict['oauthApplication']['Schema'] | null;
alreadyAuth: boolean;
}>;
/**
*
* @param avatar url
* @returns
*/
setUserAvatarFromWechat: (
params: {
avatar: string;
},
context: BackendRuntimeContext<ED>
) => Promise<void>;
};
export default AspectDict;

View File

@ -19,6 +19,7 @@ import {
refreshToken,
verifyPassword,
loginWebByMpToken,
setUserAvatarFromWechat,
} from './token';
import { getInfoByUrl } from './extraFile';
import {
@ -142,6 +143,7 @@ const aspectDict = {
getOAuthClientInfo,
createOAuthState,
authorize,
setUserAvatarFromWechat,
};
export default aspectDict;

View File

@ -1817,6 +1817,91 @@ async function setUserInfoFromWechat<ED extends EntityDict>(
}
}
//将获取的微信头像作为用户头像
export async function setUserAvatarFromWechat<ED extends EntityDict>(params: {
avatar: string;
}, context: BRC<ED>) {
const { avatar } = params;
const application = context.getApplication();
const { type, config } = application as Partial<EntityDict['application']['Schema']>;
assert(type === 'wechatMp' || config!.type === 'wechatMp');
const applicationId = context.getApplicationId();
const userId = context.getCurrentUserId();
const extraFiles = await context.select('extraFile', {
data: {
id: 1,
tag1: 1,
origin: 1,
bucket: 1,
objectId: 1,
filename: 1,
extra1: 1,
entity: 1,
entityId: 1,
},
filter: {
entity: 'user',
entityId: userId,
tag1: 'avatar',
}
}, { forUpdate: true });
const updateData = {};
if (
avatar &&
(extraFiles?.length === 0 ||
composeFileUrl<ED>(application as EntityDict['application']['Schema'], extraFiles![0] as EntityDict['extraFile']['Schema']) !== avatar)
) {
// 需要更新新的avatar extra file
const extraFileOperations: ExtraFileOperation['data'][] = [
{
id: await generateNewIdAsync(),
action: 'create',
data: Object.assign({
id: await generateNewIdAsync(),
tag1: 'avatar',
entity: 'user',
entityId: userId,
objectId: await generateNewIdAsync(),
origin: 'unknown',
extra1: avatar,
type: 'image',
filename: '',
bucket: '',
applicationId: applicationId!,
}),
},
];
if (extraFiles!.length > 0) {
extraFileOperations.push({
id: await generateNewIdAsync(),
action: 'remove',
data: {},
filter: {
id: extraFiles![0].id,
},
});
}
Object.assign(updateData, {
extraFile$entity: extraFileOperations,
});
}
if (Object.keys(updateData).length > 0) {
await context.operate(
'user',
{
id: await generateNewIdAsync(),
action: 'update',
data: updateData,
filter: {
id: userId!,
},
},
{}
);
}
}
async function tryRefreshWechatPublicUserInfo<ED extends EntityDict>(wechatUserId: string, context: BRC<ED>) {
const [wechatUser] = await context.select(
'wechatUser',
@ -2664,7 +2749,7 @@ export async function sendCaptchaByMobile<ED extends EntityDict>(
dontCollect: true,
}
);
if(!applicationPassport?.passport) {
if (!applicationPassport?.passport) {
throw new OakIncompleteConfig(application!.id!);
}
const config = applicationPassport.passport.config as SmsConfig;

View File

@ -1,3 +1,6 @@
@import "../../../config/styles/mp/index.less";
@import "../../../config/styles/mp/mixins.less";
.avatar-box {
background: none;
}

View File

@ -51,46 +51,52 @@ export default OakComponent({
origin: null as EntityDict['extraFile']['Schema']['origin'] | null,
},
methods: {
async onPickByMp() {
try {
const { errMsg, tempFiles } = await wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['album', 'camera'],
});
if (errMsg !== 'chooseMedia:ok') {
this.setMessage({
type: 'warning',
content: errMsg,
});
} else {
await Promise.all(
tempFiles.map(async (tempExtraFile) => {
const {
tempFilePath,
thumbTempFilePath,
fileType,
size,
} = tempExtraFile;
const filePath = tempFilePath || thumbTempFilePath;
const fileFullName =
filePath.match(/[^/]+(?!.*\/)/g)![0];
this.pushExtraFile({
name: fileFullName,
fileType,
size,
extra1: filePath,
});
})
);
}
} catch (err: any) {
console.error(err);
if (err.errMsg !== 'chooseMedia:fail cancel') {
this.setMessage({
type: 'error',
content: err.errMsg,
async onPickByMp(e: any) {
const { avatarUrl } = e.detail
if (avatarUrl) {
// 使用微信头像
await this.features.cache.exec('setUserAvatarFromWechat', { avatar: avatarUrl });
} else {
try {
const { errMsg, tempFiles } = await wx.chooseMedia({
count: 1,
mediaType: ['image'],
sourceType: ['album', 'camera'],
});
if (errMsg !== 'chooseMedia:ok') {
this.setMessage({
type: 'warning',
content: errMsg,
});
} else {
await Promise.all(
tempFiles.map(async (tempExtraFile) => {
const {
tempFilePath,
thumbTempFilePath,
fileType,
size,
} = tempExtraFile;
const filePath = tempFilePath || thumbTempFilePath;
const fileFullName =
filePath.match(/[^/]+(?!.*\/)/g)![0];
this.pushExtraFile({
name: fileFullName,
fileType,
size,
extra1: filePath,
});
})
);
}
} catch (err: any) {
console.error(err);
if (err.errMsg !== 'chooseMedia:fail cancel') {
this.setMessage({
type: 'error',
content: err.errMsg,
});
}
}
}
},

View File

@ -1,8 +1,8 @@
<view class="avatar-box oak-class" bind:tap="onPickByMp">
<button class="avatar-box oak-class" open-type="chooseAvatar" bind:chooseavatar="onPickByMp">
<block wx:if="{{avatarUrl}}">
<l-avatar src="{{avatarUrl}}" size="120" />
</block>
<block wx:else>
<l-avatar icon="user" size="120" icon-size="60" />
<l-avatar icon="user" size="120" icon-size="60" />
</block>
</view>
</button>

View File

@ -18,14 +18,15 @@
oakPath="{{oakFullpath}}.extraFile$entity"
entity="user"
/>
<l-button
<!-- 2.27.1及以上版本不再支持 -->
<!-- <l-button
wx:if="{{canSyncWechat}}"
size="mini"
l-class="avatar-btn"
bind:lintap="syncWechatInfoMp"
>
{{t('syncWeChat')}}
</l-button>
</l-button> -->
</view>
<l-list
title="昵称"

View File

@ -307,6 +307,7 @@ export class Token<ED extends EntityDict> extends Feature {
}
async syncUserInfoWechatMp() {
// 2.27.1及以上版本不再支持getUserProfile(返回头像为【灰色头像】,昵称为【微信用户】)
const info = await wx.getUserProfile({
desc: '同步微信昵称和头像信息',
});