同学们好久不见了,最近业余时间我完成了一个微信小程序的开发,今天想和大家分享一下整个项目的技术栈和开发心得。
MySQL作为主数据库存储核心业务数据
Redis用于:
虽然Uni-app可以跨平台,但考虑到:
jwt
***
通过静默授权
获取用户的code
小程序的代码如下
onLaunch() {
wx.login({
success: (res) => {
const { code } = res;
loginApi({ code: code }).then(response => {
if (response.code === 200) {
const token = response.data.token;
this.globalData.token = token;
this.globalData.username = response.data.nickName
wx.setStorageSync('token', token)
}
}).finally( () => {
})
}
})
},
通过小程序的code
拿到用户的openid
,其中openid
是唯一值 nestjs
代码如下
@Injectable()
export class WxAuthService {
constructor(
private readonly httpService: HttpService,
private configService: ConfigService<ConfigKeyPaths>,
private readonly wxTokenService: WxTokenService,
private readonly wxUserService: WxUserService,
) { }
async login(wxCode: string) {
const { appid, secret, grant_type } = this.configService.get<IWxConfig>('wx', { infer: true });
const response = await firstValueFrom(
this.httpService.get('https://api.weixin.qq.com/sns/jscode2session', {
params: {
appid,secret,grant_type,js_code:wxCode
}
})
)
// 如果请求错误 则返回错误信息
if (response.data.errcode)
throw new BadRequestException(response.data.errmsg,{
cause: new Error(),
description: response.data.errcode
})
const {openid, nickName} = await this.wxUserService.wxRegister({openid: response.data.openid});
const token = await this.wxTokenService.generateAccessTokenByWechat(openid);
return {openid,token,nickName};
}
}
***
通过该接口https://api.weixin.qq.com/sns/jscode2session
获取到openid
, 同学们我这边是通过openid
生成对应的token
其实和后台管理系统生成的token
类似,区别在于后台一般是账号、密码、验证码
生成一个token
小程序这边我直接使用的是openid
唯一标识
细心的同学一定发现了上面代码的一个问题,老哥你的27
行代码的nickName
咋来的,忽悠我的吧。各位同学别急等我娓娓道来!
使用的是微信静默授权
其实是拿不到用户的相关详细信息、性别
、图像
、手机号
等,这些属于用户的隐私信息
。单纯的去看openid
你是不知道是谁在操作,是不是可以给这个用户取一个别名
呢。以下就是取别名
的js逻辑
/**
* 随机生成名字
*/
async function generateRandomNames(count = 1) {
// 常用姓氏(单姓和复姓)
const commonSurnames = [
'李', '王', '张', '刘', '陈', '杨', '赵', '黄', '周', '吴',
'欧阳', '诸葛', '司马', '上官', '东方', '南宫', '西门', '慕容',
'令狐', '长孙', '端木', '轩辕', '皇甫'
];
// 辅助函数:从数组中随机获取一个元素
const getRandomElement = arr => arr[Math.floor(Math.random() * arr.length)];
// 辅助函数:生成随机汉字(常用字范围)
const getRandomHanzi = () => {
// 常用汉字Unicode范围: 0x4E00-0x9FA5 (20902个字符)
// 这里取较常用的前6000字
const start = 0x4E00;
const end = start + 6000;
return String.fromCharCode(Math.floor(Math.random() * (end - start + 1)) + start);
};
// 辅助函数:随机生成1-3个字的名称部分
const generateNamePart = () => {
const length = Math.floor(Math.random() * 3) + 1; // 1-3个字
let part = '';
for (let i = 0; i < length; i++) {
part += getRandomHanzi();
}
return part;
};
const results = [];
for (let i = 0; i < count; i++) {
// 随机选择姓氏(30%概率用复姓)
const surname = Math.random() < 0.3
? getRandomElement(commonSurnames.filter(s => s.length > 1))
: getRandomElement(commonSurnames.filter(s => s.length === 1));
// 随机生成名字部分(1-3个字)
const namePart = generateNamePart();
// 10%概率添加特殊连接符
const connector = Math.random() < 0.1
? getRandomElement(['·', '之', '-', '丶'])
: '';
// 组合成完整名字(2-5个字)
const fullName = surname + connector + namePart;
results.push(fullName);
}
return results;
}
其中会在nestjs
中调用该方法
@Injectable()
export class WxUserService {
constructor(
@InjectRepository(WxUserEntity)
private readonly wxUserRepository: Repository<WxUserEntity>,
// 使用事务 对数据进行写入操作
@InjectEntityManager() private entityManager: EntityManager,
) { }
/**
* 微信用户注册
*/
async wxRegister({ openid }: RegisterWxUserDto): Promise<any> {
const exists = await this.wxUserRepository.findOneBy({ openid })
if (!isEmpty(exists)) {
// 直接返回用户的相关信息
return exists;
}
const [nickName] = await generateRandomNames();
const wxUserInfo = this.wxUserRepository.create({
openid,
nickName
});
const wxUser = await this.wxUserRepository.save(wxUserInfo);
return wxUser;
}
}
***
业余时间做的一个小程序,可以探讨全栈(nestjs
、flutter
、小程序
)相关问题
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。