246 lines
7.8 KiB
JavaScript
246 lines
7.8 KiB
JavaScript
// pages/invite-manager/invite-manager.js — 组长推广海报
|
|
import request from '../../utils/request.js';
|
|
import {
|
|
getFullImageUrl,
|
|
loadPosterPageConfig,
|
|
posterInviteCacheKey,
|
|
posterQrCacheKey,
|
|
} from '../../utils/poster-page.js';
|
|
|
|
const app = getApp();
|
|
|
|
Page({
|
|
data: {
|
|
qrcodeUrl: '',
|
|
yaoqingma: '',
|
|
isLoading: false,
|
|
showPosterCanvas: false,
|
|
posterImageTemp: '',
|
|
avatarUrl: '',
|
|
uid: '',
|
|
nickName: '',
|
|
posterBgUrl: '',
|
|
},
|
|
|
|
async onLoad() {
|
|
const { bgUrl, qrCacheKey } = await loadPosterPageConfig('zuzhang', app);
|
|
this._qrCacheKey = qrCacheKey;
|
|
this._inviteCacheKey = posterInviteCacheKey();
|
|
this.setData({ posterBgUrl: bgUrl });
|
|
this.loadFromCache();
|
|
this.loadUserInfo();
|
|
},
|
|
|
|
onShow() {
|
|
this.registerNotificationComponent();
|
|
},
|
|
|
|
registerNotificationComponent() {
|
|
const notificationComp = this.selectComponent('#global-notification');
|
|
if (notificationComp && notificationComp.showNotification) {
|
|
app.globalData.globalNotification = {
|
|
show: (data) => notificationComp.showNotification(data),
|
|
hide: () => notificationComp.hideNotification(),
|
|
};
|
|
}
|
|
},
|
|
|
|
loadFromCache() {
|
|
try {
|
|
const key = this._qrCacheKey || posterQrCacheKey('zuzhang');
|
|
const relativeUrl = wx.getStorageSync(key);
|
|
if (relativeUrl) {
|
|
this.setData({ qrcodeUrl: getFullImageUrl(relativeUrl, app) });
|
|
}
|
|
const inviteKey = this._inviteCacheKey || posterInviteCacheKey();
|
|
const yaoqingma = wx.getStorageSync(inviteKey);
|
|
if (yaoqingma) this.setData({ yaoqingma });
|
|
} catch (error) {
|
|
console.error('读取缓存失败', error);
|
|
}
|
|
},
|
|
|
|
loadUserInfo() {
|
|
const touxiang = wx.getStorageSync('touxiang');
|
|
const ossUrl = app.globalData.ossImageUrl || '';
|
|
const defaultAvatar = ossUrl + (app.globalData.morentouxiang || 'avatar/default.jpg');
|
|
let avatarUrl = defaultAvatar;
|
|
if (touxiang && typeof touxiang === 'string' && touxiang.trim() !== '') {
|
|
avatarUrl = getFullImageUrl(touxiang, app);
|
|
}
|
|
const uid = wx.getStorageSync('uid') || '';
|
|
const nickName = app.globalData.nicheng || wx.getStorageSync('nicheng') || '组长';
|
|
this.setData({ avatarUrl, uid, nickName });
|
|
},
|
|
|
|
refreshQRCode() {
|
|
if (this.data.isLoading) return;
|
|
this.setData({ isLoading: true });
|
|
request({ url: '/peizhi/zuzhanghb', method: 'POST' })
|
|
.then((res) => {
|
|
if (res.data && res.data.code === 0) {
|
|
const { url: relativeUrl, yaoqingma } = res.data.data || {};
|
|
if (relativeUrl) {
|
|
const key = this._qrCacheKey || posterQrCacheKey('zuzhang');
|
|
wx.setStorageSync(key, relativeUrl);
|
|
this.setData({ qrcodeUrl: getFullImageUrl(relativeUrl, app) });
|
|
}
|
|
if (yaoqingma) {
|
|
const inviteKey = this._inviteCacheKey || posterInviteCacheKey();
|
|
wx.setStorageSync(inviteKey, yaoqingma);
|
|
this.setData({ yaoqingma });
|
|
}
|
|
wx.showToast({ title: '获取成功', icon: 'success' });
|
|
} else {
|
|
wx.showToast({ title: res.data.msg || res.data.message || '获取失败', icon: 'none' });
|
|
}
|
|
})
|
|
.catch((err) => {
|
|
console.error('获取组长海报失败', err);
|
|
wx.showToast({ title: '网络错误', icon: 'none' });
|
|
})
|
|
.finally(() => this.setData({ isLoading: false }));
|
|
},
|
|
|
|
saveToAlbum() {
|
|
if (!this.data.qrcodeUrl) {
|
|
wx.showToast({ title: '暂无二维码', icon: 'none' });
|
|
return;
|
|
}
|
|
wx.showLoading({ title: '保存中...', mask: true });
|
|
wx.downloadFile({
|
|
url: this.data.qrcodeUrl,
|
|
success: (res) => {
|
|
wx.hideLoading();
|
|
if (res.statusCode === 200) this.downloadAndSave(res.tempFilePath);
|
|
else wx.showToast({ title: '下载失败', icon: 'none' });
|
|
},
|
|
fail: () => {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: '下载失败', icon: 'none' });
|
|
},
|
|
});
|
|
},
|
|
|
|
copyInviteCode() {
|
|
if (!this.data.yaoqingma) {
|
|
wx.showToast({ title: '暂无邀请码', icon: 'none' });
|
|
return;
|
|
}
|
|
wx.setClipboardData({
|
|
data: this.data.yaoqingma,
|
|
success: () => wx.showToast({ title: '复制成功', icon: 'success' }),
|
|
});
|
|
},
|
|
|
|
generateMyPoster() {
|
|
if (!this.data.qrcodeUrl) {
|
|
wx.showToast({ title: '请先生成二维码', icon: 'none' });
|
|
return;
|
|
}
|
|
wx.showLoading({ title: '生成海报中...', mask: true });
|
|
const bgUrl = this.data.posterBgUrl;
|
|
Promise.all([bgUrl, this.data.qrcodeUrl, this.data.avatarUrl].map((u) => this.loadImage(u)))
|
|
.then((images) => {
|
|
wx.hideLoading();
|
|
this.setData({ showPosterCanvas: true }, () => {
|
|
setTimeout(() => this.drawPoster(images[0], images[1], images[2]), 200);
|
|
});
|
|
})
|
|
.catch(() => {
|
|
wx.hideLoading();
|
|
wx.showToast({ title: '图片加载失败', icon: 'none' });
|
|
});
|
|
},
|
|
|
|
loadImage(url) {
|
|
return new Promise((resolve, reject) => {
|
|
wx.getImageInfo({ src: url, success: (res) => resolve(res.path), fail: reject });
|
|
});
|
|
},
|
|
|
|
drawPoster(bgPath, qrPath, avatarPath) {
|
|
const ctx = wx.createCanvasContext('posterCanvas', this);
|
|
wx.createSelectorQuery().in(this).select('.poster-canvas').boundingClientRect((rect) => {
|
|
if (!rect) {
|
|
wx.showToast({ title: '画布获取失败', icon: 'none' });
|
|
return;
|
|
}
|
|
const canvasWidth = rect.width;
|
|
const canvasHeight = rect.height;
|
|
ctx.drawImage(bgPath, 0, 0, canvasWidth, canvasHeight);
|
|
const qrSize = 100;
|
|
const margin = 15;
|
|
const qrX = canvasWidth - qrSize - margin;
|
|
const qrY = canvasHeight - qrSize - margin;
|
|
ctx.drawImage(qrPath, qrX, qrY, qrSize, qrSize);
|
|
const avatarSize = 60;
|
|
const avatarX = margin + 10;
|
|
const avatarY = canvasHeight - avatarSize - margin;
|
|
ctx.save();
|
|
ctx.beginPath();
|
|
ctx.arc(avatarX + avatarSize / 2, avatarY + avatarSize / 2, avatarSize / 2, 0, 2 * Math.PI);
|
|
ctx.clip();
|
|
ctx.drawImage(avatarPath, avatarX, avatarY, avatarSize, avatarSize);
|
|
ctx.restore();
|
|
ctx.setFontSize(16);
|
|
ctx.setFillStyle('#333333');
|
|
ctx.setTextAlign('left');
|
|
let nick = this.data.nickName || '组长';
|
|
if (nick.length > 3) nick = nick.substring(0, 3) + '...';
|
|
ctx.fillText(nick, avatarX + avatarSize + 8, avatarY + avatarSize / 2 + 6);
|
|
ctx.setFontSize(18);
|
|
ctx.setFillStyle('#ffaa00');
|
|
ctx.fillText('加入我的团队 ✦', avatarX, avatarY - 12);
|
|
ctx.draw(false, () => {
|
|
wx.canvasToTempFilePath({
|
|
canvasId: 'posterCanvas',
|
|
success: (res) => this.setData({ posterImageTemp: res.tempFilePath }),
|
|
}, this);
|
|
});
|
|
}).exec();
|
|
},
|
|
|
|
savePoster() {
|
|
if (!this.data.posterImageTemp) {
|
|
wx.showToast({ title: '海报尚未生成', icon: 'none' });
|
|
return;
|
|
}
|
|
this.downloadAndSave(this.data.posterImageTemp);
|
|
},
|
|
|
|
hidePoster() {
|
|
this.setData({ showPosterCanvas: false, posterImageTemp: '' });
|
|
},
|
|
|
|
downloadAndSave(filePath) {
|
|
wx.getSetting({
|
|
success: (res) => {
|
|
if (!res.authSetting['scope.writePhotosAlbum']) {
|
|
wx.authorize({
|
|
scope: 'scope.writePhotosAlbum',
|
|
success: () => this._saveImage(filePath),
|
|
fail: () => {
|
|
wx.showModal({
|
|
title: '提示',
|
|
content: '需要您授权保存到相册',
|
|
success: (m) => { if (m.confirm) wx.openSetting(); },
|
|
});
|
|
},
|
|
});
|
|
} else {
|
|
this._saveImage(filePath);
|
|
}
|
|
},
|
|
});
|
|
},
|
|
|
|
_saveImage(filePath) {
|
|
wx.saveImageToPhotosAlbum({
|
|
filePath,
|
|
success: () => wx.showToast({ title: '保存成功', icon: 'success' }),
|
|
fail: () => wx.showToast({ title: '保存失败', icon: 'none' }),
|
|
});
|
|
},
|
|
});
|