DESKTOP-RQ919RC\Pc ced718c079 标注,4.4之前
2025-04-16 18:33:36 +08:00

1289 lines
45 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

var initial_url = "https://app.gter.net/tenement";
var app = null;
function initial(self) {
// const fs = wx.getFileSystemManager();
// console.log("getCurrentDate", getCurrentDate());
// fs.mkdir({
// dirPath: `${wx.env.USER_DATA_PATH}/${getCurrentDate()}`,
// // dirPath: `${wx.env.USER_DATA_PATH}/2025-04-13`,
// success(res) {
// console.log("res", res);
// },
// fail(err) {
// console.log("err", err);
// },
// });
// fs.close();
app = self;
getUserInfo(function (code) {
sendData(code);
self.globalData.code = code;
});
return true;
}
function sendData(code) {
let Authorization = wx.getStorageSync("Authorization");
if (!Authorization) {
Authorization = app.randomString(32);
wx.setStorageSync("Authorization", Authorization);
wx.setStorageSync("session", Authorization);
}
wx.request({
url: initial_url,
data: {
session: wx.getStorageSync("Authorization") || "",
Authorization: wx.getStorageSync("Authorization") || "",
code: code,
options: app.globalData.options || "",
},
method: "POST", // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
header: {
"content-type": "application/json",
Accept: "application/json, text/plain",
Cookie: "miucms_session=" + wx.getStorageSync("Authorization"),
Authorization: wx.getStorageSync("Authorization") || "",
},
success: function (res) {
var data = typeof res.data == "string" ? JSON.parse(res.data) : res.data;
bindingUser(data.user || {});
// 将配置与用户session存于本地
// if (!data.session) {
// // 这里报错.用户授权不成功
// return false;
// }
// wx.setStorageSync('session', data.user.session)
app.globalData.session = data.user.session;
// wx.setStorageSync('Authorization', data.user.session)
app.globalData.Authorization = data.user.session;
app.globalData.isUserAuthorization = data.user.session && data.user.session.length > 0 ? 2 : 1;
app.globalData.expiration_day = data.expiration_day;
app.globalData.config = data.config;
app.globalData.notice = data.notice;
app.globalData.title = data.title;
app.globalData.initialState = true;
app.globalData.user = data.user;
app.globalData.status = data.status;
app.globalData.StudentapartmentNew = data.StudentapartmentNew;
app.globalData.listTab = data.listTab;
app.globalData.wechat = data.wechat;
app.globalData.isMapFindState = data.isMapFindState;
app.globalData.isShowVideo = data.reviewmode == 1 ? false : true;
// app.globalData.isShowVideo = false
// console.log(data.popwindow);
app.globalData.popwindow = data.popwindow;
app.globalData.header = {
"content-type": "application/json",
Accept: "application/json, text/plain",
Cookie: "miucms_session=" + wx.getStorageSync("Authorization"),
Authorization: wx.getStorageSync("Authorization") || "",
};
// count()
app.globalData.offerkaipingadvertisement = data.popup || {};
const openAdTimer = wx.getStorageSync("openAdTimer");
if (openAdTimer && isToday(openAdTimer)) app.globalData.offerkaipingadvertisementState = true;
},
fail: function () {
// fail
},
complete: function () {
// complete
useSocket();
},
});
}
function isToday(timestamp) {
const date = new Date(timestamp);
const today = new Date();
return date.getFullYear() === today.getFullYear() && date.getMonth() === today.getMonth() && date.getDate() === today.getDate();
}
// 发送未读消息数请求
function count() {
return new Promise((resolve, reject) => {
request(app.globalData.baseURL + "/tenement/message/count")
.then((res) => {
if (res.code == 200) {
app.globalData["unreadMessages"] = res.data.count;
app.globalData["unreadMessagesState"] = true;
} else {
wx.showModal({
title: "提示",
content: res.message,
});
}
resolve(res);
})
.catch((error) => {
reject(error);
});
});
}
// 发送验证码
function verify() {
// 得到 uniqid 和过期时间
}
// 验证验证码并注册
function register(o) {
var config = wx.getStorageSync("config");
var self = this;
wx.request({
url: config.user.register,
data: {
session: wx.getStorageSync("session"),
data: wx.getStorageSync("rawData"),
uniqid: null, //上一步获取的ID
code: null, //接收到的验证码
},
method: "POST", // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
header: {
"content-type": "application/json",
Accept: "application/json, text/plain",
},
success: function (res) {
var data = typeof res.data == "string" ? JSON.parse(res.data) : res.data;
console.log("登录/注册成功");
initial(initial_url, app);
},
fail: function () {
// fail
},
complete: function () {
// complete
},
});
}
//用户登录
function login() {
return new Promise((resolve, reject) =>
wx.login({
success: resolve,
fail: reject,
})
);
}
//获取用户信息
function getUserInfo(o) {
login()
.then((res) => {
var code = res.code;
o(code);
})
.catch((res) => {
console.log(res);
});
}
function share(app, name) {
if (!app.globalData.config.stat || !app.globalData.config.stat.share) {
return false;
}
wx.request({
url: app.globalData.config.stat.share,
data: {
page: name,
},
method: "POST", // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
header: app.globalData.header,
success: function (res) {},
fail: function (res) {},
});
}
function html2wxml(str, index, that) {
var arr = [];
if (str.indexOf("</a>") != -1) {
// 有a标签
that.data.newFunction.text[index].push({
text: str.substring(0, str.indexOf("<a")),
node: "text",
});
var rest = str.substring(str.indexOf("<a"));
// a标签后面剩下的字符串
// 第一个出现href的位置
var href1 = rest.indexOf('href="') + 6;
// 第二个“出现的位置
var href2 = rest.substring(href1).indexOf('"');
// 链接地址
var href = rest.substring(href1, href1 + href2);
rest = rest.substring(rest.indexOf(">"));
var text1 = rest.substring(1, rest.indexOf("</a>"));
that.data.newFunction.text[index].push({
text: text1,
node: "a",
href: href,
});
rest = rest.substring(rest.indexOf("</a>") + 4);
if (rest.length > 0) {
// a标签后还有字符串
if (rest.indexOf("</a>") != -1) {
// 还有A标签存在再一次调用
that.html2wxml(rest, index);
} else {
that.data.newFunction.text[index].push({
text: rest,
node: "text",
});
}
}
} else {
that.data.newFunction.text[index] = [{
text: str,
node: "text",
}, ];
}
}
function change_data(that, newFunction) {
var arr = newFunction.split("\n");
var arr2 = [];
for (var i = 0; i < arr.length; i++) {
var str = arr[i];
that.data.newFunction.text[i] = [];
that.html2wxml(str, i);
}
that.setData({
newFunction: that.data.newFunction,
});
}
function copy(content, hintText) {
return new Promise((resolve, reject) => {
wx.setClipboardData({
data: content,
success: function (res) {
wx.showToast({
icon: "none",
title: hintText || "复制成功!",
});
resolve();
},
fail(err) {
reject(err);
},
});
});
}
//封装Request请求方法
function request(url, data = {}, ishint = true) {
return new Promise((resolve, reject) => {
// if (!app.globalData.config || !app.globalData.config.list) {
// reject()
// return false
// }
let Authorization = wx.getStorageSync("Authorization");
if (!Authorization) {
Authorization = app.randomString(32);
wx.setStorageSync("Authorization", Authorization);
wx.setStorageSync("session", Authorization);
}
let sendData = Object.assign({
session: wx.getStorageSync("session"),
},
app.globalData.options,
data
);
wx.request({
url: url,
data: sendData,
timeout: data.timeout || 60000,
header: {
"content-type": "application/json",
Accept: "application/json, text/plain",
Cookie: "miucms_session=" + Authorization,
Authorization: Authorization || "",
},
method: "POST", // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
success: function (res) {
var json = res.data;
if (typeof json != "object") {
if (json != null) {
json = json.replace("\ufeff", "");
try {
var jj = JSON.parse(json);
res.data = jj;
} catch (error) {
if (ishint) {
wx.showModal({
title: "提示",
content: "请求失败",
});
}
}
}
}
var data = res.data;
resolve(data);
},
fail: function (msg) {
wx.hideLoading();
if (ishint) {
wx.showToast({
title: msg,
icon: "none",
duration: 2000,
mask: true,
});
}
reject("fail");
},
});
});
}
const wxget = function (url, data = {}) {
data = Object.assign({}, app.globalData.options, data);
return new Promise((resolve, reject) => {
var authorization = wx.getStorageSync("Authorization");
if (!authorization) {
authorization = app.randomString(32);
wx.setStorageSync("Authorization", authorization);
wx.setStorageSync("session", authorization);
}
wx.request({
url: url,
data: data,
header: {
Cookie: "miucms_session=" + authorization,
Authorization: authorization,
},
method: "GET",
success: (res) => {
if (res.data.code == 200) {
resolve(res.data);
} else if (res.data.code == 401) {
// 需要授权
app.globalData.user.uid = 0;
wx.showToast({
icon: "none",
title: res.data.message,
});
reject(res);
} else {
wx.hideLoading();
wx.showModal({
title: "提示",
content: res.message || res.data.message,
});
reject(res.data);
}
},
fail(res) {
wx.showModal({
title: "提示",
content: res,
});
reject(res);
},
});
});
};
function closeAD(id) {
if (!app.globalData.config || !app.globalData.config.adv) return false;
request(app.globalData.config.adv.close, {
advid: id,
}).then((res) => {});
}
function clickAD(id) {
if (!app.globalData.config || !app.globalData.config.adv) {
return false;
}
request(app.globalData.config.adv.click, {
advid: id,
}).then((res) => {});
}
function getTopTitle(that, app) {
let topTitle = app.globalData.topTitle;
if (topTitle) {
that.setData({
topTitle: app.globalData.topTitle,
miniProgram: app.globalData.miniProgram,
});
} else {
setTimeout(() => {
that.getTopTitle();
}, 300);
}
}
function getTimeAgo(Time) {
const now = new Date();
let time = new Date(Time);
const diff = now - time;
const seconds = Math.floor(diff / 1000);
const minutes = Math.floor(seconds / 60);
const hours = Math.floor(minutes / 60);
const days = Math.floor(hours / 24);
if (seconds < 60) return `${seconds}秒前`;
else if (minutes < 60) return `${minutes}分钟前`;
else if (hours < 24) return `${hours}小时前`;
else if (days < 7) return `${days}天前`;
else return Time;
}
// 开启socket
let socketCount = 0; // 链接次数,判断失败
const useSocket = () => {
if (app.globalData.isConnected) {
console.log("已经连接,不再重复连接");
return; // 如果已经连接,则不再创建新的 socketTask
}
app.globalData.socketTask = wx.connectSocket({
url: `wss://socket.gter.net/socket?token=${wx.getStorageSync("Authorization") || ""}`,
success: function (res) {
app.globalData.isConnected = true; // 连接成功,设置为 true
},
fail: function (err) {
app.globalData.isConnected = false; // 连接成功,设置为 true
console.log(err, "err");
},
});
app.globalData.socketTask.onOpen(function () {
// 初始化发消息
if (wx.getStorageSync("Authorization")) {
let getAccountInfoSync = wx.getAccountInfoSync();
let dataToSend = {
type: "bind",
data: {
token: wx.getStorageSync("Authorization") || "",
app: getAccountInfoSync.miniProgram.appId,
// uid: user.uid || 0
},
};
app.globalData.socketTask.send({
data: JSON.stringify(dataToSend),
});
}
// 开始定时发
setTimeout(() => timedTransmission(), 50000);
});
app.globalData.socketTask.onClose(function () {
// console.log('socket关闭了', new Date())
socketCount++;
if (socketCount > 3) return;
setTimeout(() => useSocket(), 3000);
app.globalData.isConnected = false; // 连接关闭,重置为 false
});
};
// 定时发送
const timedTransmission = () => {
if (app.globalData.socketTask.readyState != 1) return;
var dataToSend = {
type: "ping",
};
app.globalData.socketTask.send({
data: JSON.stringify(dataToSend),
complete: () => setTimeout(() => timedTransmission(), 50000),
});
};
// 专门在初始化 获取筛选全局的值和传入的值
const updateProperty = (key, options, brandSelectionObj) => {
if (options[key] != undefined) return options[key];
else if (brandSelectionObj[key] != undefined) return brandSelectionObj[key];
};
// 字符串转base64
function base64_encode(str) {
var c1, c2, c3;
var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var i = 0,
len = str.length,
string = "";
while (i < len) {
c1 = str.charCodeAt(i++) & 0xff;
if (i == len) {
string += base64EncodeChars.charAt(c1 >> 2);
string += base64EncodeChars.charAt((c1 & 0x3) << 4);
string += "==";
break;
}
c2 = str.charCodeAt(i++);
if (i == len) {
string += base64EncodeChars.charAt(c1 >> 2);
string += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4));
string += base64EncodeChars.charAt((c2 & 0xf) << 2);
string += "=";
break;
}
c3 = str.charCodeAt(i++);
string += base64EncodeChars.charAt(c1 >> 2);
string += base64EncodeChars.charAt(((c1 & 0x3) << 4) | ((c2 & 0xf0) >> 4));
string += base64EncodeChars.charAt(((c2 & 0xf) << 2) | ((c3 & 0xc0) >> 6));
string += base64EncodeChars.charAt(c3 & 0x3f);
}
return string;
}
// 公共跳转页面
function goPage(url) {
wx.navigateTo({
url,
fail: function (err) {
if ((err.errMsg = "navigateTo:fail webview count limit exceed")) {
wx.redirectTo({
url,
});
}
},
});
}
function getTitleName(url) {
const obj = {
"pages/index/index": "首页",
"pages/appeal/appeal": "申诉",
"pages/needHousing/needHousing": "求房源",
"pages/personList/personList": "个人房源列表",
"pages/agentList/agentList": "中介房源列表",
"pages/brandApartmentList/brandApartmentList": "公寓房源列表",
"pages/report/report": "举报",
"pages/irentPark/irentPark": "学生公寓",
"pages/user/user": "我的",
"pages/search/search": "搜索",
"pages/edit/edit": "发布",
"pages/ad/ad": "广告模板展示",
"pages/brandApartmentDetail/brandApartmentDetail": "公寓详情",
"pages/show/show": "房源详情",
"pages/share/share": "分享海报",
"pages/messageCenter/messageCenter": "系统通知",
"pages/webViewwebweb/index": "H5",
"pages/circularize/circularize": "申诉",
"pages/askHousing/askHousing": "发布求房源",
"pages/transfer/transfer": "中转页面",
"pages/video_show/video_show": "媒体展示页面",
"pagesLoginRequired/pages/setAvatarNickname/setAvatarNickname": "设置头像昵称",
"mapFind/pages/placeMap/index": "地图找房",
};
return obj[url] || "首页";
}
// 调用 统计接口
function statistics(obj) {
return;
let url = "";
let options = {};
let pages = null;
if (obj.path) {
url = obj.path;
options = obj.query || {};
} else {
pages = getCurrentPages(); // 获取当前页面栈
const currentPage = pages[pages.length - 1]; // 当前页面对象
url = currentPage.route;
options = currentPage.options;
}
// // 当页面显示时执行
// const pages = getCurrentPages(); // 获取当前页面栈
// const currentPage = pages[pages.length - 1]; // 当前页面对象
// const url = currentPage.route; // 当前页面url
// const options = currentPage.options; // 当前页面url的参数
const launchOptions = wx.getLaunchOptionsSync() || {};
// 构建带参数的URL
let urlWithArgs = url + objectToQueryString(options);
// 缓存 systemInfo
let systemInfo = wx.getStorageSync("xstatSystemInfo");
if (!systemInfo) {
const accountInfo = wx.getAccountInfoSync();
const deviceInfo = wx.getDeviceInfo();
const windowInfo = wx.getWindowInfo();
const base = wx.getAppBaseInfo();
systemInfo = {
website: accountInfo.miniProgram.appId,
hostname: accountInfo.miniProgram.appId,
screen: `${windowInfo.windowWidth}x${windowInfo.windowHeight}`,
language: base.language || "",
os: deviceInfo.system || "",
platform: deviceInfo.platform || "",
device: deviceInfo.model || "",
session: wx.getStorageSync("xstatSession") || "",
scene: launchOptions.scene || "",
};
wx.setStorageSync("xstatSystemInfo", systemInfo);
}
let payload = {
title: getTitleName(url),
url: "/" + urlWithArgs,
};
if (Object.keys(launchOptions.referrerInfo).length > 0) payload.referrer = launchOptions.referrerInfo.appId + objectToQueryString(launchOptions.referrerInfo.extraData);
if (obj.name) payload.name = obj.name;
if (obj.data && Object.keys(obj.data).length > 0) payload.data = obj.data;
try {
wx.request({
url: "https://stat.gter.net/api/send",
method: "POST",
data: {
payload,
type: obj.type || "event",
},
timeout: 5000,
header: {
"Content-Type": "application/json",
"x-stat-token": base64_encode(JSON.stringify(systemInfo)),
},
success: (res) => {
if (res.data.code == 200 && res.data.data && res.data.data.session && res.data.data.session != systemInfo.session) {
wx.setStorageSync("xstatSession", res.data.data.session);
wx.setStorageSync("xstatSystemInfo", {
...systemInfo,
session: res.data.data.session,
});
}
},
});
} catch (error) {
console.error("发送失败:", error);
}
}
// 判断是否登录 如果登录需要发送 绑定微信信息埋点
function bindingUser(user = {}) {
if (user.uid <= 0) return;
wx.xstat && wx.xstat.setUserid(user.uid); // 登录后手动设置用户id , 如果有
// setTimeout(() => {
// statistics({
// data: {
// uid: user.uid,
// uin: user.uin
// },
// type: "identify",
// });
// }, 600);
}
// 将一个JavaScript对象转换为路由参数的形式将键值对转换为key=value的形式
function objectToQueryString(obj = {}) {
const queryString = Object.keys(obj)
.map((key) => encodeURIComponent(key) + "=" + encodeURIComponent(obj[key]))
.join("&");
return queryString ? "?" + queryString : "";
}
// 返回上一页或者首页
function backOrIndex() {
wx.navigateBack({
fail: function () {
wx.redirectTo({
url: "/pages/index/index",
});
},
});
}
// 生成海报 type 1: 公寓 2认证中介 3: 普通中介 4个人房东 5认证个人房源 6招室友 7其他
function generatePoster(target) {
return new Promise(async (resolve, reject) => {
const user = getApp().globalData.user || {};
// 修改画布创建方式
const canvas = wx.createOffscreenCanvas({
type: "2d",
width: 280 * 2, // 增加分辨率
height: 224 * 2, // 增加分辨率
});
// target.bj = "https://oss.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-c-p4scXnqqsgFptxhT66QUmybYLYnAVBJQe2HpJNYt7VMACPX-Rzv5EQpu30SjsUfxT00NDI5";
const ctx = canvas.getContext("2d");
ctx.scale(2, 2); // 缩放绘图上下文
const tempFilePath = await downloadPic(target.bj);
let bgImg = canvas.createImage();
bgImg.src = tempFilePath;
await new Promise((resolve) => {
bgImg.onload = resolve;
});
console.log("加载背景图片");
// 计算aspectFill模式参数
const containerRatio = 280 / 219; // 容器宽高比 (280x219)
const imageRatio = bgImg.width / bgImg.height;
let drawWidth,
drawHeight,
offsetX = 0,
offsetY = 0;
if (imageRatio > containerRatio) {
// 图片更宽,按高度缩放
drawHeight = 219;
drawWidth = drawHeight * imageRatio;
offsetX = (280 - drawWidth) / 2;
} else {
// 图片更高,按宽度缩放
drawWidth = 280;
drawHeight = drawWidth / imageRatio;
offsetY = (219 - drawHeight) / 2;
}
// 绘制圆角背景修改drawImage参数
ctx.save();
ctx.beginPath();
ctx.moveTo(15, 4);
ctx.arcTo(280, 4, 280, 224, 15);
ctx.arcTo(280, 224, 0, 224, 15);
ctx.arcTo(0, 224, 0, 4, 15);
ctx.arcTo(0, 4, 280, 4, 15);
ctx.closePath();
ctx.clip();
// 计算源图片裁剪区域
let srcX = 0,
srcY = 0,
srcWidth = bgImg.width,
srcHeight = bgImg.height;
// 修正缩放逻辑
if (imageRatio > containerRatio) {
// 图片更宽时,按容器高度缩放
drawHeight = 219;
drawWidth = drawHeight * imageRatio;
offsetX = (280 - drawWidth) / 2;
// 源图片裁剪:取中间宽度区域
srcWidth = bgImg.height * containerRatio;
srcX = (bgImg.width - drawHeight) / 2;
} else {
// 图片更高时,按容器宽度缩放
drawWidth = 280;
drawHeight = drawWidth / imageRatio;
offsetY = (219 - drawHeight) / 2;
// 源图片裁剪:取中间高度区域
srcHeight = bgImg.width / containerRatio;
srcY = (bgImg.height - drawWidth) / 2;
}
console.log("srcWidth", srcWidth, "srcHeight", srcHeight, "bgImg.width", bgImg.width, "drawWidth", drawWidth, "drawHeight", drawHeight, "srcX", srcX, "srcY", srcY);
// 修改后的drawImage调用
ctx.drawImage(
bgImg,
// srcX,
// 源图像裁剪区域
imageRatio > containerRatio ? (bgImg.width - srcWidth) / 2 : srcX, // 修正水平居中计算
srcY,
srcWidth, // 改为计算后的裁剪宽度
srcHeight, // 改为计算后的裁剪高度
offsetX,
4,
drawWidth,
drawHeight
);
ctx.restore();
console.log("绘制背景图片");
// 绘制右上角标签
if (target.type == 1) {
let tagImg = canvas.createImage();
await new Promise((resolve) => {
tagImg.onload = resolve;
tagImg.src = `https://app.gter.net/image/miniApp/HKRenting/high-quality-tag.png?${Date.now()}`;
});
ctx.drawImage(tagImg, 215, 0, 65, 54);
} else if (target.type == 2 || target.type == 5) {
let tagImg = canvas.createImage();
const objSrc = {
2: "certification-intermediary-icon.png",
5: "certification-listing-icon.png",
};
await new Promise((resolve) => {
tagImg.onload = resolve;
tagImg.src = `https://app.gter.net/image/miniApp/HKRenting/${objSrc[target.type]}?${Date.now()}`;
});
ctx.drawImage(tagImg, 215, 4, 50, 58);
} else if (target.type == 3 || target.type == 4 || target.type == 6) {
// 绘制红色价格标签
ctx.save();
const tagX = target.type == 6 ? 210 : 225; // 从右侧开始计算位置
const tagY = 10;
const tagWidth = target.type == 6 ? 60 : 46;
const tagHeight = 23;
const objBJ = {
3: "#6fc16d",
4: "#8080ff",
6: "#8080ff",
};
// 绘制圆角背景
ctx.fillStyle = objBJ[target.type];
ctx.beginPath();
ctx.moveTo(tagX + 10, tagY);
ctx.arcTo(tagX + tagWidth, tagY, tagX + tagWidth, tagY + tagHeight, 10);
ctx.arcTo(tagX + tagWidth, tagY + tagHeight, tagX, tagY + tagHeight, 10);
ctx.arcTo(tagX, tagY + tagHeight, tagX, tagY, 10);
ctx.arcTo(tagX, tagY, tagX + tagWidth, tagY, 10);
ctx.closePath();
ctx.fill();
// 绘制文字(调整垂直居中)
ctx.fillStyle = "#FFFFFF";
ctx.font = "bold 15px PingFang SC";
ctx.textAlign = "center";
ctx.textBaseline = "middle"; // 确保基线设置为中间
// Y坐标计算去掉+1偏移直接使用精确中点
const objName = {
3: "中介",
4: "房东",
6: "招室友",
};
ctx.fillText(objName[target.type], tagX + tagWidth / 2, tagY + tagHeight / 2);
ctx.restore();
}
console.log("绘制右上角标签");
let username = user.nickname || "匿名用户";
// 绘制用户信息区域
// 先测量文本长度
ctx.font = "14px PingFang SC";
ctx.fillStyle = "#000";
let displayText = username + " 为你推荐";
let textMetrics = ctx.measureText(displayText);
let textWidth = textMetrics.width;
// 添加文本截断逻辑
const MAX_TEXT_WIDTH = 165; // 最大允许文本宽度
if (textWidth > MAX_TEXT_WIDTH) {
let limit = username.length;
// 逐步减少字符直到宽度合适
while (textWidth > MAX_TEXT_WIDTH && limit > 0) {
limit--;
displayText = username.substring(0, limit) + "... 为你推荐";
textMetrics = ctx.measureText(displayText);
textWidth = textMetrics.width;
}
}
// 动态计算区域宽度头像24 + 边距4 + 文本宽度 + 右边距10
const infoWidth = 24 + 4 + textWidth + 10;
const startX = 0;
const startY = 24;
const radius = 16;
ctx.fillStyle = "#f2f2f2";
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(infoWidth - radius, startY);
ctx.arcTo(infoWidth, startY, infoWidth, startY + 28, radius);
ctx.lineTo(infoWidth, startY + 28 - radius);
ctx.arcTo(infoWidth, startY + 28, startX, startY + 28, radius);
ctx.lineTo(startX, startY + 28);
ctx.closePath();
ctx.fill();
console.log("用户名好了", user.avatar);
// 绘制头像
let avatarImg = canvas.createImage();
await new Promise((resolve) => {
avatarImg.onload = resolve;
const avatarUrl = user.avatar ? `${user.avatar}?${Date.now()}` : `https://app.gter.net/image/miniApp/HKRenting/defaultAvatar.png?${Date.now()}`; // 增加时间戳避免缓存
avatarImg.src = avatarUrl;
});
console.log("加载头像");
ctx.restore(); // 确保之前的裁剪状态被清除
ctx.save();
ctx.beginPath();
ctx.arc(14, 38, 12, 0, Math.PI * 2);
ctx.clip();
ctx.drawImage(avatarImg, 2, 26, 24, 24);
ctx.restore();
// 绘制用户名
ctx.fillStyle = "#000";
ctx.font = "14px PingFang SC";
// 修改最终文本绘制调用
ctx.fillText(displayText, 30, 43); // 使用处理后的文本
// 绘制底部信息栏
const gradient = ctx.createLinearGradient(0, 190, 0, 224);
gradient.addColorStop(0, "rgba(51, 51, 51, 0.2)");
gradient.addColorStop(1, "rgba(51, 51, 51, 0.9)");
ctx.fillStyle = gradient;
ctx.beginPath();
ctx.moveTo(0, 190);
ctx.arcTo(280, 190, 280, 224, 0);
ctx.arcTo(280, 224, 0, 224, 15);
ctx.arcTo(0, 224, 0, 190, 15);
ctx.closePath();
ctx.fill();
console.log("绘制位置图标11");
// 绘制位置图标
let positionIcon = canvas.createImage();
await new Promise((resolve) => {
positionIcon.onload = resolve;
positionIcon.src = `https://app.gter.net/image/miniApp/HKRenting/position-icon.png?${Date.now()}`;
});
ctx.drawImage(positionIcon, 9, 200, 10, 14);
console.log("绘制位置图标完成");
// 绘制位置文本
ctx.fillStyle = "#fff";
ctx.font = "15px microsoft yahei";
ctx.fillText(`香港 | ${target.title}`, 25, 212);
console.log("开始绘制箭头图标");
// 绘制箭头图标
let arrowIcon = canvas.createImage();
await new Promise((resolve) => {
arrowIcon.onload = resolve;
arrowIcon.src = `https://app.gter.net/image/miniApp/HKRenting/arrow-round-yellow.png?${Date.now()}`;
});
ctx.drawImage(arrowIcon, 255, 200, 16, 16);
console.log("绘制箭头图标完成-开始保存");
wx.canvasToTempFilePath({
quality: 1,
canvas,
success: (res) => {
console.log("生成路径", res.tempFilePath)
resolve(res.tempFilePath);
},
fail: err => {
console.log("生成失败", err);
}
})
return
// 修改最后保存图片的尺寸
const imgData = canvas.toDataURL({
width: 280,
height: 224,
destWidth: 280 * 2, // 输出双倍分辨率
destHeight: 224 * 2,
});
const filePath = `${wx.env.USER_DATA_PATH}/${getCurrentDate()}/poster_share_${Date.now()}.png`;
const fs = wx.getFileSystemManager();
console.log("开始保存");
let writeFileSum = 0; // 写入次数
const writeFile = () => {
writeFileSum++;
console.log("writeFileSum:", writeFileSum);
if (writeFileSum > 10) return;
fs.writeFile({
filePath,
data: imgData.replace(/^data:image\/\w+;base64,/, ""),
encoding: "base64",
success: (res) => {
console.log("生成成功", res);
fs.close();
resolve(filePath);
},
fail: (err) => {
console.log("err", err);
// 此处可能存在内存满了的情况
if (err?.errMsg?.indexOf("file storage limit is exceeded") != -1) {
fs.readdir({
dirPath: `${wx.env.USER_DATA_PATH}/${getCurrentDate()}`,
success: (res) => {
// 过滤并排序文件
const files = res.files
.filter((f) => f.startsWith("poster_share_") && f.endsWith(".png"))
.map((f) => ({
name: f,
timestamp: parseInt(f.match(/poster_share_(\d+)\.png/)[1]), // 提取时间戳
}))
.sort((a, b) => a.timestamp - b.timestamp); // 按时间戳升序排列
// 计算需要删除的数量取前50%
const deleteCount = Math.ceil(files.length / 2);
const toDelete = files.slice(0, deleteCount);
// 批量删除旧文件
toDelete.forEach((file) => {
fs.unlink({
filePath: `${wx.env.USER_DATA_PATH}/${getCurrentDate()}/${file.name}`,
success: () => console.log("已清理文件:", file.name),
fail: (e) => console.log("文件清理失败:", file.name, e),
});
});
// 重试写入
setTimeout(() => writeFile(), 1000);
},
});
}
if (err?.errMsg?.indexOf("fail no such file or directory") != -1) {
fs.mkdir({
dirPath: `${wx.env.USER_DATA_PATH}/${getCurrentDate()}`,
complete: (res) => writeFile(),
});
}
},
});
};
writeFile();
cleanupOldDateFolders();
});
}
// 生成海报 没有图片
function generatePosterNoImage(target) {
return new Promise(async (resolve, reject) => {
const user = getApp().globalData.user || {};
const canvas = wx.createOffscreenCanvas({
type: "2d",
width: 280 * 2,
height: 224 * 2,
});
const ctx = canvas.getContext("2d");
ctx.scale(2, 2);
// 绘制白色背景
ctx.fillStyle = "#FFFFFF";
ctx.fillRect(0, 0, 280, 224);
// 绘制用户信息区域
ctx.font = "14px PingFang SC";
ctx.fillStyle = "#555555";
// 绘制圆形头像
const avatarImg = canvas.createImage();
await new Promise((resolve) => {
avatarImg.onload = resolve;
const avatarUrl = user.avatar ? `${user.avatar}?${Date.now()}` : `https://app.gter.net/image/miniApp/HKRenting/defaultAvatar.png?${Date.now()}`; // 增加时间戳避免缓存
avatarImg.src = avatarUrl;
});
ctx.save();
ctx.beginPath();
ctx.arc(12, 12, 12, 0, Math.PI * 2);
ctx.clip();
ctx.drawImage(avatarImg, 0, 0, 24, 24);
ctx.restore();
let username = user.nickname || "匿名用户";
// 绘制用户名
let displayText = username + " 为你推荐";
let textMetrics = ctx.measureText(displayText);
let textWidth = textMetrics.width;
// 添加文本截断逻辑
const MAX_TEXT_WIDTH = 240; // 最大允许文本宽度
if (textWidth > MAX_TEXT_WIDTH) {
let limit = username.length;
// 逐步减少字符直到宽度合适
while (textWidth > MAX_TEXT_WIDTH && limit > 0) {
limit--;
displayText = username.substring(0, limit) + "... 为你推荐";
textMetrics = ctx.measureText(displayText);
textWidth = textMetrics.width;
}
}
ctx.fillText(displayText, 30, 18); // 使用处理后的文本
// ctx.fillText(`${ user.nickname || "匿名用户" } 为你推荐`, 30, 18);
// 绘制背景卡片
const bgImg = canvas.createImage();
await new Promise((resolve) => {
bgImg.onload = resolve;
bgImg.src = `https://app.gter.net/image/miniApp/HKRenting/share-default-bj.png?${Date.now()}`;
});
ctx.save();
ctx.beginPath();
console.log("ctx", ctx);
// ctx.roundRect(0, 40, 280, 184, [10]);
// 手动绘制圆角路径替代roundRect
const x = 0,
y = 40,
width = 280,
height = 184,
radius = 10;
ctx.moveTo(x + radius, y);
ctx.arcTo(x + width, y, x + width, y + height, radius);
ctx.arcTo(x + width, y + height, x, y + height, radius);
ctx.arcTo(x, y + height, x, y, radius);
ctx.arcTo(x, y, x + width, y, radius);
ctx.closePath();
ctx.clip();
ctx.drawImage(bgImg, 0, 40, 280, 184);
ctx.restore();
// 绘制文字信息
ctx.font = "16px PingFang SC";
ctx.fillStyle = "#000000";
console.log("渲染文字信息完成");
// 位置信息
ctx.fillText(target.position, 44, 71);
console.log("渲染位置信息完成");
// 类型信息
ctx.fillText(target.typeText, 44, 121);
console.log("渲染类型完成");
// 价格信息
ctx.font = "20px PingFang SC";
ctx.fillStyle = "#FA6B11";
ctx.fillText(target.price, 44, 171);
ctx.font = "16px PingFang SC";
ctx.fillStyle = "#000000";
ctx.fillText("HK$/月", 44 + ctx.measureText(target.price).width + 12, 171);
console.log("渲染价格完成");
wx.canvasToTempFilePath({
quality: 1,
canvas,
success: (res) => {
console.log("生成路径", res.tempFilePath)
resolve(res.tempFilePath);
},
fail: err => {
console.log("生成失败", err);
}
})
return
// 导出图片
const imgData = canvas.toDataURL({
destWidth: 280 * 2,
destHeight: 224 * 2,
});
const filePath = `${wx.env.USER_DATA_PATH}/${getCurrentDate()}/poster_share_${Date.now()}.png`;
wx.getFileSystemManager().writeFile({
filePath,
data: imgData.split(",")[1],
encoding: "base64",
success: () => resolve(filePath),
fail: reject,
});
cleanupOldDateFolders();
});
}
// 下载图片
function downloadPic(src) {
return new Promise(async (resolve, reject) => {
console.log("开始下载海报");
wx.getImageInfo({
src,
success(res) {
console.log(src);
resolve(res.path);
},
fail(err) {
console.log("err", err);
},
});
});
}
function cleanupOldDateFolders() {
const fs = wx.getFileSystemManager();
const currentDate = getCurrentDate();
fs.readdir({
dirPath: wx.env.USER_DATA_PATH,
success(res) {
res.files.forEach((folder) => {
// 严格匹配YYYY-MM-DD格式的目录名2023-12-31
if (/^\d{4}-\d{2}-\d{2}$/.test(folder) && folder !== currentDate) {
const dirPath = `${wx.env.USER_DATA_PATH}/${folder}`;
fs.rmdir({
dirPath,
recursive: true,
success: () => console.log("已清理目录:", dirPath),
fail: (err) => console.log("清理失败:", dirPath, err),
});
}
});
},
});
}
function getCurrentDate() {
const date = new Date();
const year = date.getFullYear();
// getMonth() 返回值是 0一月 到 11十二月 之间的一个整数,所以要加 1
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
module.exports = {
generatePosterNoImage,
generatePoster,
initial: initial,
share: share,
change_data: change_data,
html2wxml: html2wxml,
copy,
sendData,
request,
wxget,
closeAD,
clickAD,
count,
getTopTitle,
getTimeAgo,
useSocket,
updateProperty,
goPage,
https: function (url, data, success, fail) {
wx.request({
url: url,
data: data,
method: "POST", // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT
header: {
"content-type": "application/json",
Accept: "application/json, text/plain",
Cookie: "miucms_session=" + wx.getStorageSync("Authorization"),
Authorization: wx.getStorageSync("Authorization") || "",
},
success: function (res) {
typeof success == "function" && success(res);
},
fail: function () {
typeof fail == "function" && fail(res);
},
complete: function () {
typeof fail == "function" && fail(res);
},
});
},
statistics,
bindingUser,
objectToQueryString,
gtergreenonionqrcode: "https://oss.x-php.com/Zvt57TuJSUvkyhw-xG7Y2l-d_pIqcXjqqsgFptxhcq_cQnrlcvd3DQYcBq_D-81qNDQyOQ~~",
backOrIndex,
};