Compare commits
14 Commits
63bcf6fe86
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 8090d679b4 | |||
| 4965d6c40e | |||
| 56fb3ade00 | |||
| 8c6fb1190e | |||
|
|
4dc8e84f5c | ||
| b84c3bb409 | |||
| fa41842e75 | |||
| 3bbb64d58c | |||
| 58cf46e93d | |||
|
|
8004b26bd1 | ||
|
|
98baa371ee | ||
|
|
f87859da0e | ||
| d3390d5e81 | |||
|
|
883ce3c2c4 |
@@ -32,36 +32,52 @@ const FilterPopup = (props: FilterPopupProps) => {
|
||||
const { timeBubbleData, gamesNum } = store;
|
||||
|
||||
/**
|
||||
* @description 处理字典选项
|
||||
* @param dictionaryValue 字典选项
|
||||
* @returns 选项列表
|
||||
* @description 日期排序
|
||||
* @param a 日期字符串
|
||||
* @param b 日期字符串
|
||||
* @returns 日期差值
|
||||
*/
|
||||
// const [selectedDates, setSelectedDates] = useState<String[]>([])
|
||||
const sortByDate = (a: string, b: string) => {
|
||||
return new Date(a).getTime() - new Date(b).getTime();
|
||||
}
|
||||
|
||||
const handleDateChange = (dates: Date[]) => {
|
||||
let times: String[] = [];
|
||||
if (dates.length > 1) {
|
||||
times = [dayjs(dates[0]).format('YYYY-MM-DD'), dayjs(dates[dates.length - 1]).format('YYYY-MM-DD')]
|
||||
onChange({
|
||||
'dateRange': times,
|
||||
})
|
||||
// ================================ 日期处理 ================================
|
||||
// 默认是是当前日期为开始日期,结束日期为当前日期 + 30天
|
||||
const defaultDateRange = [dayjs().format('YYYY-MM-DD'), dayjs().add(1, 'M').format('YYYY-MM-DD')];
|
||||
// 处理空数组的情况
|
||||
if (!dates.length) {
|
||||
onChange({ dateRange: defaultDateRange });
|
||||
return;
|
||||
}
|
||||
if (Array.isArray(dates)) {
|
||||
|
||||
const currentDay = dayjs(dates[0]).format('YYYY-MM-DD');
|
||||
if (filterOptions.dateRange.length === 0 || filterOptions.dateRange.length === 2) {
|
||||
times.push(currentDay);
|
||||
} else {
|
||||
times = [...filterOptions.dateRange, currentDay].sort(
|
||||
(a, b) => new Date(a).getTime() - new Date(b).getTime()
|
||||
)
|
||||
}
|
||||
// 处理多日期范围选择(超过1个日期)
|
||||
if (dates.length > 1) {
|
||||
const dateRange = [
|
||||
dayjs(dates[0]).format('YYYY-MM-DD'),
|
||||
dayjs(dates[dates.length - 1]).format('YYYY-MM-DD')
|
||||
];
|
||||
onChange({ dateRange });
|
||||
return;
|
||||
}
|
||||
|
||||
onChange({
|
||||
'dateRange': times,
|
||||
})
|
||||
// 处理单个日期选择
|
||||
const currentFilterOptionsDateRange = Array.isArray(filterOptions?.dateRange)
|
||||
? filterOptions.dateRange
|
||||
: defaultDateRange;
|
||||
// 当前选择的日期
|
||||
const currentDay = dayjs(dates?.[0]).format('YYYY-MM-DD');
|
||||
// 当 dates 每次只返回单个日期时,使用已选范围判断是“第一次点”还是“第二次点”
|
||||
let dateRange: string[];
|
||||
if (
|
||||
currentFilterOptionsDateRange.length === 2 &&
|
||||
currentFilterOptionsDateRange?.[0] === currentFilterOptionsDateRange?.[1]
|
||||
) {
|
||||
// 已是单日,点击当前日期扩展为日期范围
|
||||
dateRange = [currentFilterOptionsDateRange[0], currentDay].sort(sortByDate);
|
||||
} else {
|
||||
// 默认区间/已选区间/异常状态,点击当前日期统一收敛为单日
|
||||
dateRange = [currentDay, currentDay];
|
||||
}
|
||||
onChange({ dateRange });
|
||||
}
|
||||
|
||||
const handleOptions = (dictionaryValue: []) => {
|
||||
|
||||
@@ -1,41 +1,13 @@
|
||||
import Taro from "@tarojs/taro";
|
||||
import dayjs, { Dayjs } from "dayjs";
|
||||
import "dayjs/locale/zh-cn";
|
||||
import { calculateDistance } from "@/utils";
|
||||
import { calculateDistance, genGameLength } from "@/utils";
|
||||
import { View, Image, Text, Map } from "@tarojs/components";
|
||||
import img from "@/config/images";
|
||||
import styles from "./index.module.scss";
|
||||
|
||||
dayjs.locale("zh-cn");
|
||||
|
||||
function genGameLength(startTime: Dayjs, endTime: Dayjs) {
|
||||
if (!startTime || !endTime) {
|
||||
return "";
|
||||
}
|
||||
const totalMinutes = endTime.diff(startTime, "minute");
|
||||
const totalHours = totalMinutes / 60;
|
||||
|
||||
if (totalHours >= 24) {
|
||||
const days = Math.floor(totalHours / 24);
|
||||
const remainingHours = totalHours % 24;
|
||||
|
||||
if (remainingHours === 0) {
|
||||
return `${days}天`;
|
||||
}
|
||||
|
||||
// 保留一位小数
|
||||
const displayHours = parseFloat(remainingHours.toFixed(1));
|
||||
return `${days}天${displayHours}小时`;
|
||||
}
|
||||
|
||||
// 如果是整数小时,不显示小数点
|
||||
if (Number.isInteger(totalHours)) {
|
||||
return `${totalHours}小时`;
|
||||
}
|
||||
// 保留一位小数,去除末尾的0
|
||||
return `${parseFloat(totalHours.toFixed(1))}小时`;
|
||||
}
|
||||
|
||||
function genGameRange(startTime: Dayjs, endTime: Dayjs) {
|
||||
if (!startTime || !endTime) {
|
||||
return "";
|
||||
|
||||
@@ -177,23 +177,32 @@
|
||||
}
|
||||
|
||||
&-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 24px;
|
||||
gap: 2px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 24px;
|
||||
gap: 2px;
|
||||
overflow: hidden;
|
||||
color: rgba(255, 255, 255, 0.85);
|
||||
text-overflow: ellipsis;
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 24px; /* 150% */
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 24px; /* 150% */
|
||||
|
||||
&-arrow {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
&-text {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
&-arrow {
|
||||
flex: 0 0 12px;
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&-time-range {
|
||||
overflow: hidden;
|
||||
|
||||
@@ -86,12 +86,12 @@ export default function OrganizerInfo(props) {
|
||||
await LoginService.followUser(id);
|
||||
}
|
||||
onUpdateUserInfo();
|
||||
Taro.showToast({
|
||||
(Taro as any).showToast({
|
||||
title: `${nickname} ${follow ? "已取消关注" : "已关注"}`,
|
||||
icon: "success",
|
||||
});
|
||||
} catch (e) {
|
||||
Taro.showToast({
|
||||
(Taro as any).showToast({
|
||||
title: `${nickname} ${follow ? "取消关注失败" : "关注失败"}`,
|
||||
icon: "error",
|
||||
});
|
||||
@@ -193,13 +193,17 @@ export default function OrganizerInfo(props) {
|
||||
className={styles["recommend-games-list-item"]}
|
||||
onClick={handleViewGame.bind(null, game.id)}
|
||||
>
|
||||
{/* game title */}
|
||||
<View className={styles["recommend-games-list-item-title"]}>
|
||||
<Text>{game.title}</Text>
|
||||
<Image
|
||||
className={
|
||||
styles["recommend-games-list-item-title-arrow"]
|
||||
}
|
||||
{/* game title */}
|
||||
<View className={styles["recommend-games-list-item-title"]}>
|
||||
<Text
|
||||
className={styles["recommend-games-list-item-title-text"]}
|
||||
>
|
||||
{game.title}
|
||||
</Text>
|
||||
<Image
|
||||
className={
|
||||
styles["recommend-games-list-item-title-arrow"]
|
||||
}
|
||||
src={img.ICON_DETAIL_ARROW_RIGHT}
|
||||
/>
|
||||
</View>
|
||||
|
||||
@@ -489,7 +489,7 @@ export default function Participants(props) {
|
||||
<Text
|
||||
className={styles["participants-list-item-level"]}
|
||||
>
|
||||
{displayNtrp}
|
||||
NTRP {displayNtrp}
|
||||
</Text>
|
||||
<Text className={styles["participants-list-item-role"]}>
|
||||
{role}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { forwardRef, useState, useEffect, useImperativeHandle } from "react";
|
||||
import { View, Button, Image, Text } from "@tarojs/components";
|
||||
import Taro, { useShareAppMessage } from "@tarojs/taro";
|
||||
import dayjs from "dayjs";
|
||||
import dayjs, { Dayjs } from "dayjs";
|
||||
import "dayjs/locale/zh-cn";
|
||||
import classnames from "classnames";
|
||||
import { generateShareImage } from "@/utils";
|
||||
@@ -12,7 +12,12 @@ import WechatLogo from "@/static/detail/wechat_icon.svg";
|
||||
// import WechatTimeline from "@/static/detail/wechat_timeline.svg";
|
||||
import LinkIcon from "@/static/detail/link.svg";
|
||||
import CrossIcon from "@/static/detail/cross.svg";
|
||||
import { genNTRPRequirementText, navto } from "@/utils/helper";
|
||||
import {
|
||||
genNTRPRequirementText,
|
||||
navto,
|
||||
genGameLength,
|
||||
formatGameStartTime,
|
||||
} from "@/utils/helper";
|
||||
import { waitForAuthInit } from "@/utils/authInit";
|
||||
import { useUserActions } from "@/store/userStore";
|
||||
import { OSS_BASE } from "@/config/api";
|
||||
@@ -28,7 +33,19 @@ export default forwardRef(({ id, from, detail, userInfo }, ref) => {
|
||||
const [shareImageUrl, setShareImageUrl] = useState("");
|
||||
const { fetchUserInfo } = useUserActions();
|
||||
|
||||
async function ensureUserInfo() {
|
||||
if (userInfo?.avatar_url && userInfo?.nickname) {
|
||||
return userInfo;
|
||||
}
|
||||
const fetchedUserInfo = await fetchUserInfo();
|
||||
return {
|
||||
avatar_url: fetchedUserInfo?.avatar_url || userInfo?.avatar_url || "",
|
||||
nickname: fetchedUserInfo?.nickname || userInfo?.nickname || "",
|
||||
};
|
||||
}
|
||||
|
||||
const publishFlag = from === "publish";
|
||||
|
||||
// const posterRef = useRef();
|
||||
const { max_participants, participant_count } = detail || {};
|
||||
|
||||
@@ -50,6 +67,16 @@ export default forwardRef(({ id, from, detail, userInfo }, ref) => {
|
||||
withShareTicket: false, // 是否需要返回 shareTicket
|
||||
isUpdatableMessage: true, // 是否是动态消息(需要服务端配置过模版)
|
||||
activityId: res.data.activity_id, // 动态消息的活动 id
|
||||
templateInfo: {
|
||||
parameterList: [
|
||||
{
|
||||
name: "member_count",
|
||||
value: (participant_count ?? 0).toString(),
|
||||
},
|
||||
{ name: "room_limit", value: (max_participants ?? 0).toString() },
|
||||
],
|
||||
templateId: "666F374D69D16C932E45D7E7D9F10CEF6177F5F5",
|
||||
},
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
@@ -85,28 +112,34 @@ export default forwardRef(({ id, from, detail, userInfo }, ref) => {
|
||||
const startTime = dayjs(start_time);
|
||||
const endTime = dayjs(end_time);
|
||||
const dayofWeek = DayOfWeekMap.get(startTime.day());
|
||||
const gameLength = `${endTime.diff(startTime, "hour")}小时`;
|
||||
console.log(userInfo, "userInfo");
|
||||
const url = await generateShareImage({
|
||||
userAvatar: userInfo.avatar_url,
|
||||
userNickname: userInfo.nickname,
|
||||
gameType: play_type,
|
||||
skillLevel: `NTRP ${genNTRPRequirementText(
|
||||
skill_level_min,
|
||||
skill_level_max,
|
||||
)}`,
|
||||
gameDate: `${startTime.format("M月D日")} (${dayofWeek})`,
|
||||
gameTime: `${startTime.format("ah")}点 ${gameLength}`,
|
||||
venueName: location_name,
|
||||
venueImages: image_list ? image_list : [],
|
||||
});
|
||||
return url;
|
||||
const gameLength = genGameLength(startTime, endTime);
|
||||
const currentUserInfo = await ensureUserInfo();
|
||||
try {
|
||||
const url = await generateShareImage({
|
||||
userAvatar: currentUserInfo.avatar_url,
|
||||
userNickname: currentUserInfo.nickname,
|
||||
gameType: play_type,
|
||||
skillLevel: `NTRP ${genNTRPRequirementText(
|
||||
skill_level_min,
|
||||
skill_level_max,
|
||||
)}`,
|
||||
gameDate: `${startTime.format("M月D日")} (${dayofWeek})`,
|
||||
gameTime: `${formatGameStartTime(startTime)} ${gameLength}`,
|
||||
venueName: location_name,
|
||||
venueImages: image_list ? image_list : [],
|
||||
});
|
||||
if (!url) {
|
||||
throw new Error("生成分享图片失败,URL 为空");
|
||||
}
|
||||
return url;
|
||||
} catch (e) {
|
||||
console.error("生成分享卡片失败", e);
|
||||
return `${OSS_BASE}/system/game_dou_di_tu.png`;
|
||||
}
|
||||
}
|
||||
|
||||
useShareAppMessage(async (res) => {
|
||||
await changeMessageType();
|
||||
const url = await generateShareImageUrl();
|
||||
// console.log(res, "res");
|
||||
useShareAppMessage(async () => {
|
||||
const url = shareImageUrl || (await generateShareImageUrl());
|
||||
return {
|
||||
title: detail.title,
|
||||
imageUrl: url,
|
||||
@@ -128,12 +161,12 @@ export default forwardRef(({ id, from, detail, userInfo }, ref) => {
|
||||
} = detail || {};
|
||||
// 先等待静默登录完成
|
||||
await waitForAuthInit();
|
||||
const userInfo = await fetchUserInfo();
|
||||
const { avatar_url, nickname } = userInfo;
|
||||
const currentUserInfo = await ensureUserInfo();
|
||||
const { avatar_url, nickname } = currentUserInfo;
|
||||
const startTime = dayjs(start_time);
|
||||
const endTime = dayjs(end_time);
|
||||
const dayofWeek = DayOfWeekMap.get(startTime.day());
|
||||
const gameLength = `${endTime.diff(startTime, "hour")}小时`;
|
||||
const game_length = genGameLength(startTime, endTime);
|
||||
let qrCodeUrl = "";
|
||||
try {
|
||||
const qrCodeUrlRes = await DetailService.getQrCodeUrl({
|
||||
@@ -161,7 +194,7 @@ export default forwardRef(({ id, from, detail, userInfo }, ref) => {
|
||||
title,
|
||||
locationName: location_name,
|
||||
date: `${startTime.format("M月D日")} (${dayofWeek})`,
|
||||
time: `${startTime.format("ah")}点 ${gameLength}`,
|
||||
time: `${formatGameStartTime(startTime)} ${game_length}`,
|
||||
qrCodeUrl,
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
@@ -24,12 +24,12 @@ function isFull(counts) {
|
||||
} = counts;
|
||||
|
||||
if (
|
||||
max_players === current_players &&
|
||||
current_players >= max_players &&
|
||||
is_substitute_supported === IsSubstituteSupported.NOTSUPPORT
|
||||
) {
|
||||
return true;
|
||||
} else if (
|
||||
max_players === current_players &&
|
||||
current_players >= max_players &&
|
||||
is_substitute_supported === IsSubstituteSupported.SUPPORT
|
||||
) {
|
||||
return max_substitute_players === current_substitute_count;
|
||||
@@ -45,7 +45,7 @@ function RmbIcon() {
|
||||
function matchNtrpRequestment(
|
||||
target?: string,
|
||||
min?: string,
|
||||
max?: string
|
||||
max?: string,
|
||||
): boolean {
|
||||
// 目标值为空或 undefined
|
||||
if (!target?.trim()) return true;
|
||||
@@ -123,7 +123,7 @@ export default function StickyButton(props) {
|
||||
|
||||
Taro.navigateTo({
|
||||
url: `/login_pages/index/index?redirect=${encodeURIComponent(
|
||||
fullPath
|
||||
fullPath,
|
||||
)}`,
|
||||
});
|
||||
}
|
||||
@@ -138,7 +138,7 @@ export default function StickyButton(props) {
|
||||
const matchNtrpReq = matchNtrpRequestment(
|
||||
ntrp_level,
|
||||
skill_level_min,
|
||||
skill_level_max
|
||||
skill_level_max,
|
||||
);
|
||||
|
||||
const gameManageRef = useRef();
|
||||
@@ -173,7 +173,7 @@ export default function StickyButton(props) {
|
||||
}, [getCommentCount]);
|
||||
|
||||
function generateTextAndAction(
|
||||
user_action_status: null | { [key: string]: boolean }
|
||||
user_action_status: null | { [key: string]: boolean },
|
||||
):
|
||||
| undefined
|
||||
| { text: string | React.FC; action?: () => void; available?: boolean } {
|
||||
@@ -271,7 +271,7 @@ export default function StickyButton(props) {
|
||||
const res = await OrderService.getUnpaidOrder(id);
|
||||
if (res.code === 0) {
|
||||
navto(
|
||||
`/order_pages/orderDetail/index?id=${res.data.order_info.order_id}`
|
||||
`/order_pages/orderDetail/index?id=${res.data.order_info.order_id}`,
|
||||
);
|
||||
}
|
||||
}),
|
||||
@@ -387,7 +387,7 @@ export default function StickyButton(props) {
|
||||
<View
|
||||
className={classnames(
|
||||
styles["detail-main-action"],
|
||||
available ? "" : styles.disabled
|
||||
available ? "" : styles.disabled,
|
||||
)}
|
||||
>
|
||||
<View
|
||||
|
||||
@@ -14,7 +14,11 @@ import WechatLogo from "@/static/detail/wechat_icon.svg";
|
||||
import WechatTimeline from "@/static/detail/wechat_timeline.svg";
|
||||
import { useUserActions } from "@/store/userStore";
|
||||
import { DayOfWeekMap } from "../detail/config";
|
||||
import { genNTRPRequirementText } from "@/utils/helper";
|
||||
import {
|
||||
genNTRPRequirementText,
|
||||
genGameLength,
|
||||
formatGameStartTime,
|
||||
} from "@/utils/helper";
|
||||
import { waitForAuthInit } from "@/utils/authInit";
|
||||
import { OSS_BASE } from "@/config/api";
|
||||
import styles from "./index.module.scss";
|
||||
@@ -53,7 +57,7 @@ function SharePoster(props) {
|
||||
const startTime = dayjs(start_time);
|
||||
const endTime = dayjs(end_time);
|
||||
const dayofWeek = DayOfWeekMap.get(startTime.day());
|
||||
const gameLength = `${endTime.diff(startTime, "hour")}小时`;
|
||||
const gameLength = genGameLength(startTime, endTime);
|
||||
Taro.showLoading({ title: "生成中..." });
|
||||
const qrCodeUrlRes = await DetailService.getQrCodeUrl({
|
||||
page: "game_pages/detail/index",
|
||||
@@ -77,7 +81,7 @@ function SharePoster(props) {
|
||||
title,
|
||||
locationName: location_name,
|
||||
date: `${startTime.format("M月D日")} (${dayofWeek})`,
|
||||
time: `${startTime.format("ah")}点 ${gameLength}`,
|
||||
time: `${formatGameStartTime(startTime)} ${gameLength}`,
|
||||
qrCodeUrl,
|
||||
});
|
||||
Taro.hideLoading();
|
||||
|
||||
@@ -424,6 +424,7 @@
|
||||
align-items: flex-end;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.orderNo {
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useState, useRef } from "react";
|
||||
import { View, Text, Button, Image } from "@tarojs/components";
|
||||
import { Dialog } from "@nutui/nutui-react-taro";
|
||||
import Taro, { useDidShow, useRouter } from "@tarojs/taro";
|
||||
import dayjs from "dayjs";
|
||||
import dayjs, { Dayjs } from "dayjs";
|
||||
import "dayjs/locale/zh-cn";
|
||||
import classnames from "classnames";
|
||||
import orderService, {
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
getOrderStatus,
|
||||
generateOrderActions,
|
||||
isPhoneNumber,
|
||||
genGameLength,
|
||||
} from "@/utils";
|
||||
import { getStorage, setStorage } from "@/store/storage";
|
||||
import { useGlobalStore } from "@/store/global";
|
||||
@@ -75,6 +76,17 @@ function genGameNotice(order_status, start_time) {
|
||||
return gameNoticeMap.get(key) || {};
|
||||
}
|
||||
|
||||
function genGameRange(startTime: Dayjs, endTime: Dayjs) {
|
||||
if (!startTime || !endTime) {
|
||||
return "";
|
||||
}
|
||||
// 如果跨天(自然日)
|
||||
if (!startTime.isSame(endTime, "day")) {
|
||||
return `${startTime.format("HH:mm")} - ${endTime.format("MM月DD日 HH:mm")}`;
|
||||
}
|
||||
return `${startTime.format("HH:mm")} - ${endTime.format("HH:mm")}`;
|
||||
}
|
||||
|
||||
function GameInfo(props) {
|
||||
const { detail, currentLocation, orderDetail, init } = props;
|
||||
const { order_status, refund_status, amount, refund_amount } = orderDetail;
|
||||
@@ -111,15 +123,17 @@ function GameInfo(props) {
|
||||
|
||||
const startTime = dayjs(start_time);
|
||||
const endTime = dayjs(end_time);
|
||||
const game_length = Number(
|
||||
(endTime.diff(startTime, "minutes") / 60).toFixed(),
|
||||
);
|
||||
// const game_length = Number(
|
||||
// (endTime.diff(startTime, "minutes") / 60).toFixed(),
|
||||
// );
|
||||
const game_length = genGameLength(startTime, endTime);
|
||||
|
||||
const startMonth = startTime.format("M");
|
||||
const startDay = startTime.format("D");
|
||||
const theDayOfWeek = startTime.format("dddd");
|
||||
const startDate = `${startMonth}月${startDay}日 ${theDayOfWeek}`;
|
||||
const gameRange = `${startTime.format("HH:mm")} - ${endTime.format("HH:mm")}`;
|
||||
// const gameRange = `${startTime.format("HH:mm")} - ${endTime.format("HH:mm")}`;
|
||||
const gameRange = genGameRange(startTime, endTime);
|
||||
|
||||
const orderStatus = getOrderStatus(orderDetail);
|
||||
|
||||
@@ -277,7 +291,7 @@ function GameInfo(props) {
|
||||
<View className={styles.gameInfoDateWeatherCalendarDateDate}>
|
||||
<View className={styles.date}>{startDate}</View>
|
||||
<View className={styles.venueTime}>
|
||||
{gameRange} ({game_length}小时)
|
||||
{gameRange} ({game_length})
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
@@ -5,6 +5,7 @@ import img from '@/config/images';
|
||||
import { FormFieldConfig } from '@/config/formSchema/publishBallFormSchema';
|
||||
import SelectStadium from '../SelectStadium/SelectStadium'
|
||||
import { Stadium } from '../SelectStadium/StadiumDetail'
|
||||
import { normalize_address } from '@/utils/locationUtils'
|
||||
import './FormBasicInfo.scss'
|
||||
|
||||
type PlayGame = {
|
||||
@@ -54,7 +55,7 @@ const FormBasicInfo: React.FC<FormBasicInfoProps> = ({
|
||||
onChange({...value,
|
||||
venue_id,
|
||||
location_name: name,
|
||||
location: address,
|
||||
location: normalize_address(address || ''),
|
||||
latitude,
|
||||
longitude,
|
||||
court_type,
|
||||
|
||||
@@ -4,7 +4,7 @@ import Taro from '@tarojs/taro'
|
||||
import { Loading } from '@nutui/nutui-react-taro'
|
||||
import StadiumDetail, { StadiumDetailRef } from './StadiumDetail'
|
||||
import { CommonPopup, CustomPopup } from '../../../../components'
|
||||
import { getLocation } from '@/utils/locationUtils'
|
||||
import { getLocation, normalize_address } from '@/utils/locationUtils'
|
||||
import PublishService from '@/services/publishService'
|
||||
import images from '@/config/images'
|
||||
import './SelectStadium.scss'
|
||||
@@ -100,7 +100,7 @@ const SelectStadium: React.FC<SelectStadiumProps> = ({
|
||||
success: (res) => {
|
||||
setSelectedStadium({
|
||||
name: res.name,
|
||||
address: res.address,
|
||||
address: normalize_address(res.address || ''),
|
||||
longitude: res.longitude,
|
||||
latitude: res.latitude
|
||||
})
|
||||
|
||||
@@ -7,6 +7,7 @@ import TextareaTag from '@/components/TextareaTag'
|
||||
import UploadCover, { type CoverImageValue } from '@/components/UploadCover'
|
||||
import { useKeyboardHeight } from '@/store/keyboardStore'
|
||||
import { useDictionaryActions } from '@/store/dictionaryStore'
|
||||
import { normalize_address } from '@/utils/locationUtils'
|
||||
|
||||
import './StadiumDetail.scss'
|
||||
|
||||
@@ -145,7 +146,7 @@ const StadiumDetail = forwardRef<StadiumDetailRef, StadiumDetailProps>(({
|
||||
setFormData({
|
||||
...formData,
|
||||
name: res.name,
|
||||
address: res.address,
|
||||
address: normalize_address(res.address || ''),
|
||||
latitude: res.latitude,
|
||||
longitude: res.longitude,
|
||||
istance: null
|
||||
|
||||
@@ -381,6 +381,7 @@ const PublishBall: React.FC = () => {
|
||||
image_list,
|
||||
wechat,
|
||||
id,
|
||||
title,
|
||||
...rest
|
||||
} = formData[0];
|
||||
const { min, max, organizer_joined } = players;
|
||||
@@ -389,6 +390,7 @@ const PublishBall: React.FC = () => {
|
||||
...activityInfo,
|
||||
...descriptionInfo,
|
||||
...timeRange,
|
||||
title: title?.replace(/\n/g, ''),
|
||||
max_players: max,
|
||||
min_players: min,
|
||||
organizer_joined: organizer_joined === true ? 1 : 0,
|
||||
@@ -453,6 +455,7 @@ const PublishBall: React.FC = () => {
|
||||
skill_level,
|
||||
is_substitute_supported,
|
||||
id,
|
||||
title,
|
||||
...rest
|
||||
} = item;
|
||||
const { min, max, organizer_joined } = players;
|
||||
@@ -461,6 +464,7 @@ const PublishBall: React.FC = () => {
|
||||
...activityInfo,
|
||||
...descriptionInfo,
|
||||
...timeRange,
|
||||
title: title?.replace(/\n/g, ' '),
|
||||
max_players: max,
|
||||
min_players: min,
|
||||
organizer_joined: organizer_joined === true ? 1 : 0,
|
||||
|
||||
@@ -1,11 +1,18 @@
|
||||
<svg width="24" height="32" viewBox="0 0 24 32" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_7504_18610)">
|
||||
<path d="M12.3076 0.0971837C12.7381 0.438102 12.2325 2.22445 12.328 2.76282C13.7134 2.51292 15.1145 2.01928 16.5062 1.81874C16.8928 1.76321 17.9933 1.57501 17.89 2.28307C17.8274 2.71346 16.6377 4.52912 16.73 4.62167C17.9667 4.78673 19.2128 4.97647 20.4214 5.28962C20.8346 5.39607 21.9226 5.57501 21.8209 6.15503C21.7223 6.71192 20.0394 8.18974 20.0848 8.37331C21.1211 9.25414 22.4017 9.9838 23.402 10.8909C23.712 11.1716 24.119 11.457 23.9671 11.926C23.8028 12.4366 22.0009 12.6541 21.5469 12.9965C21.525 13.1215 22.552 14.7351 22.7069 15.0204C22.8995 15.3752 23.8028 17.0613 23.7871 17.3236C23.726 18.2754 22.051 17.5827 21.4827 17.6383C21.6596 18.3648 21.8131 19.1408 21.8929 19.8843C21.9774 20.6679 22.2514 21.6753 21.0632 21.4932C21.237 29.4763 12.3624 34.5546 5.2928 30.6641C-0.183159 27.6514 -1.69069 20.6001 2.09614 15.6467C2.21199 15.494 2.76459 14.9402 2.78964 14.8801C2.81782 14.8122 2.73642 14.2831 2.75364 14.0902C2.80999 13.4624 3.15439 12.8824 3.58802 12.4366C2.80686 11.693 1.97874 10.8461 1.52945 9.85268C1.36977 9.50096 1.30559 9.0027 1.16 8.70189C1.04103 8.45661 0.72324 8.31623 0.593307 8.0216C0.190985 7.11762 0.835953 6.08561 1.87228 6.20902C2.38262 6.26919 2.4609 6.6317 3.13091 6.54069C4.43807 6.36637 5.06425 4.00154 5.53545 2.98804C5.73583 2.5592 6.59839 0.737369 6.94749 0.59082C7.976 0.161974 7.82102 2.05939 8.23899 2.54994C9.08747 1.94986 9.8702 1.2526 10.7281 0.664866C11.0991 0.410335 11.8724 -0.251447 12.3076 0.0925559V0.0971837ZM11.1993 6.0563C10.9629 6.20285 10.2944 5.55804 10.022 5.41149C8.99824 4.86232 7.73648 4.72348 6.62814 5.09988C5.22236 5.57809 5.13626 6.89394 3.68039 7.42923C3.52854 7.48477 3.02133 7.55418 2.9775 7.59738C2.94462 7.62977 2.87418 7.99846 2.75364 8.16814C2.6331 8.33475 2.4061 8.51832 2.19477 8.55071C2.40297 9.81874 3.62873 11.7146 5.15661 11.0189C5.63407 10.8014 5.73583 10.263 5.89707 10.1643C6.15694 10.0069 6.41367 10.1658 6.45437 10.4466C6.57178 11.258 5.30689 11.9676 4.57113 11.9213L5.26776 12.3702C6.99289 13.2865 8.93719 13.6429 10.8846 13.3575C10.9989 13.322 11.2165 12.5245 11.3605 12.3116C11.5515 12.0278 11.9178 11.8072 12.1182 11.5418C12.5033 11.0297 12.6598 9.76166 12.6066 9.13228C12.5847 8.87466 12.3452 8.2931 12.4297 8.13266C12.9792 7.84265 13.5897 7.80409 13.8793 7.14693C14.5384 5.64905 12.6035 4.40879 11.4904 5.55033C11.3777 5.66602 11.2259 6.03934 11.2008 6.05476L11.1993 6.0563ZM12.8665 12.2808C12.2513 12.418 11.6439 13.683 12.1511 14.1273C12.7882 14.6826 14.2582 13.5488 14.6981 13.049C14.4006 12.5183 13.4473 12.1512 12.8665 12.2808ZM6.45594 13.7802C6.16163 13.7324 5.8642 13.6645 5.58085 13.575C4.81847 13.3313 4.25647 12.7312 3.85572 13.7324C3.66786 14.1998 3.64751 14.823 4.27213 14.9387C4.7809 15.0328 6.34323 14.4142 6.45594 13.7817V13.7802ZM10.9973 13.8511C9.58215 14.1921 8.2343 14.1859 6.80817 13.919C6.76746 14.8091 5.6012 15.4477 4.79656 15.5526C4.52573 15.5881 4.07645 15.5156 3.87294 15.6066C3.74144 15.6653 3.02603 16.4165 2.89609 16.5708C0.767073 19.1192 0.635574 22.5885 2.06484 25.5118C2.36853 26.1319 2.43428 26.3756 3.20918 26.4512C5.43839 26.6672 6.16633 25.3606 7.9713 24.6016C11.4137 23.1562 15.7767 24.2237 17.6051 27.5526C20.7376 24.0617 20.4417 18.7906 17.2576 15.4323C16.9257 15.0837 15.7328 14.118 15.3117 13.9699C15.0675 13.8835 14.8123 14.297 14.6292 14.4296C13.3659 15.3521 11.3589 15.9105 10.9989 13.8527L10.9973 13.8511ZM3.59115 27.6915C3.55985 27.8103 3.64125 27.8288 3.69447 27.8982C4.0968 28.4103 4.98284 29.0305 5.55267 29.3729C8.98102 31.4354 13.5036 31.1145 16.5719 28.5553C15.415 25.5164 11.647 24.6232 8.74463 25.6429C6.98819 26.2599 5.62468 28.0972 3.59115 27.6915Z" fill="black"/>
|
||||
<path d="M7.69734 6.77362C8.84169 6.70883 9.28002 8.38257 8.18264 8.8361C6.57804 9.49788 6.06457 6.86463 7.69734 6.77362Z" fill="black"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_7504_18610">
|
||||
<rect width="24" height="32" fill="white"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="_图层_2" data-name="图层 2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 74.87 89.85">
|
||||
<defs>
|
||||
<style>
|
||||
.cls-1 {
|
||||
fill: #e6ff54;
|
||||
}
|
||||
</style>
|
||||
</defs>
|
||||
<g id="_图层_1-2" data-name=" 图层 1">
|
||||
<path class="cls-1" d="M39.79,82.22h0c-3.1,1.7-6.7,2.6-10.3,2.6-9.9,0-18.3-6.7-21-15.7,1.7,1.4,3.6,2.3,5.6,2.7,4.7,1,8.3,0,11.8-1,3.1-.8,5.9-1.6,9.7-1.2,3.9.5,6.6,2.6,7.3,5.7.6,2.7-.5,5.4-3,6.9h-.1Z"/>
|
||||
<path class="cls-1" d="M51.29,62.92c0,.9,0,1.9-.2,2.8-.5,3.7-1.8,7.2-4,10.2,0-.5,0-1-.2-1.5-1.1-4.9-5.3-8.3-10.9-9-4.5-.6-8.1.4-11.3,1.3-3.3,1-6.2,1.7-9.9,1-3.9-.8-7.6-4.7-6.6-10.4h0c0-.6.3-1.1.5-1.7,0-.4.3-.8.5-1.2,1.1.2,2.2.2,3.3,0h.4c2.6-.9,4.4-2.8,4.8-5.2v-.2c4.8,1.4,10.4,1.3,15.4,0h0c.2-.2.4-.2.6-.3,0,1,.5,2,1.1,2.9,1.1,1.6,2.9,2.6,5,2.8,1.1,0,2.2,0,3.3-.4h0c1-.2,2-.7,3-1.3.6-.4,1.1-.8,1.6-1.2,2.3,3.5,3.5,7.6,3.5,11.9v-.3l.1-.2Z"/>
|
||||
<g>
|
||||
<path d="M74.59,37.52c-2.1-6.1-6.4-11.7-12.2-15.9h0c1.7-2,2.6-3,4.5-4.6.5-.4.7-1,.6-1.6,0-.6-.4-1.1-1-1.4-6.5-3.2-12.1-4.7-18.9-5,.9-2.4,1.8-4.1,3-6.4.3-.6.3-1.3,0-1.9-.4-.6-1.1-.8-1.8-.7-7.6,1.7-13.8,4-20.9,8.1-1.9-2.4-4.1-4.3-6.8-6-.5-.3-1.2-.3-1.8,0s-.9.9-.9,1.5c0,5.6-1,9.9-3.2,14.4-1.6,3.3-3.3,5.7-4.4,7.4-1.3,1.9-2.1,2.9-3,3.4-1.35-1.86-4.14-2.86-6.42-.58-1.03,1.03-1.51,2.46-1.33,3.91.21,1.67,1.05,2.27,2.25,2.87.7,2.3,1.7,4.5,2.9,6.3-1.4,1.1-2.3,2.7-2.7,4.5-.6,2.7,0,5.3,1.9,7.2-1.2,3.1-1.8,6.4-1.8,9.8,0,14.9,13.39,27.65,27,27,6.31-.3,9.55-.58,15.79-5.21,1.57-1.16,3.02-2.5,4.26-4.01,3.31-4.03,5.89-8.65,6.65-13.38,1.2.4,2.4.9,3.3,1.3.4.2.8.2,1.3,0h.2c.5-.2.8-.6,1-1.1.9-2.9,1.4-7.5,1.6-10.6,1.5,0,3.1.3,5.2.7.5,0,1.1,0,1.5-.4s.6-.9.6-1.4c-.2-5.6-1-10-2.5-14.3,1.8-.8,3.3-1.4,5.1-1.8.5,0,.9-.4,1.1-.9.2-.4.3-.9,0-1.4v.2h-.1ZM44.09,41.82c.7,0,1.2.3,1.7.8l.17.17c.26.26.52,1.15.72,1.96.29,1.21-.08,2.48-.97,3.36,0,0-.01.01-.02.02-.4.4-.8.7-1.3,1-1.4.9-2.8,1.3-4.1,1.2-1,0-1.8-.5-2.3-1.2-.5-.8-.7-1.6-.5-2.4,0-.4.2-.8.4-1.2.2-.3.4-.6.6-.9h0c.2-.3.5-.6.8-.8s.6-.4.9-.6c.8-.5,1.6-.9,2.3-1.1.48-.09.65-.19,1.21-.27l.39-.03ZM7.09,34.12h.4c3.7-.5,5.6-3.2,7.3-5.8,1.3-1.8,2.6-3.8,4.8-5.3,3.7-2.5,8.6-2.6,12.6,0,.3.2.6.2,1,.2h.4c.5,0,.9-.5,1.1-.9.6-1.3,1.7-2.2,3-2.4,1.1-.2,2.1,0,2.8.7.8.7,1.2,1.8,1,2.9-.2,1.2-1.2,2.1-2.6,2.7-.6.2-.9.6-1.1,1.2-.2.6,0,1.2.3,1.6,2.1,2.7,2.9,6.5,2.1,9.5,0,.3-.2.6-.3.9-.6.3-1.1.6-1.7,1-1.6,1-2.8,2.2-3.5,3.6,0,0-.2.3-.2.5l-1.1.3c-1.1.4-2.2.7-3.4.9-2.7.5-5.5.6-8.2.2-1.2-.2-2.3-.4-3.4-.8h0c-.4,0-.8-.2-1.2-.4-.3,0-.5-.2-.8-.3h-.3c-.2,0-.4-.2-.7-.3-.2,0-.4-.2-.6-.3.2,0,.4-.2.6-.4,0,0,.2,0,.3-.2,1.1-.9,2.1-2.1,2.7-3.7.2-.5.2-1,0-1.5s-.6-.9-1.1-1c-1-.4-2.2,0-2.6,1.1-.6,1.4-1.5,2.3-2.6,2.4-.5,0-1.1,0-1.7-.3h0c-1.3-1.6-2.3-3.5-3-5.6v-.2h-.2l-.1-.3ZM7.79,49.72c-.2-.2-.3-.5-.5-.9h0c0-.4-.2-.8,0-1.4h0v-.5c.3-1.4,1.2-2,1.8-2.3h.7c.2,0,.3.3.5.4.2.2.5.3.7.5.4.2.7.5,1.1.7.5.3,1,.6,1.5.8,0,0,.2,0,.4.2h0v1.1c-.2,1.1-1.1,2-2.5,2.3h-.5c-.8,0-1.6,0-2.3-.3-.3-.2-.6-.4-.8-.6s0,0-.2-.2h.2l-.1.2ZM39.79,82.22h0c-3.1,1.7-6.7,2.6-10.3,2.6-9.9,0-18.3-6.7-21-15.7,1.7,1.4,3.6,2.3,5.6,2.7,4.7,1,8.3,0,11.8-1,3.1-.8,5.9-1.6,9.7-1.2,3.9.5,6.6,2.6,7.3,5.7.6,2.7-.5,5.4-3,6.9h-.1ZM47.09,75.92c0-.5,0-1-.2-1.5-1.1-4.9-5.3-8.3-10.9-9-4.5-.6-8.1.4-11.3,1.3-3.3,1-6.2,1.7-9.9,1-3.9-.8-7.6-4.7-6.6-10.4h0c0-.6.3-1.1.5-1.7,0-.4.3-.8.5-1.2,1.1.2,2.2.2,3.3,0h.4c2.6-.9,4.4-2.8,4.8-5.2v-.2c4.8,1.4,10.2,1.4,15.1,0,0,0,.6-.3.8-.4,0,1,.5,2,1.1,2.9,1.1,1.6,2.9,2.6,5,2.8,1.1,0,3.4-.3,3.4-.3,1-.3,2-.8,3-1.4.6-.4,1.1-.8,1.6-1.2,2.3,3.5,3.52,7.6,3.5,11.9-.01,2.59,0,1.9-.2,2.8,0,0-1.7,6.8-3.9,9.8Z"/>
|
||||
<path d="M24.69,34.92c-1.6.2-3.1-.9-3.3-2.5-.3-1.6.8-3.1,2.4-3.3h0c1.6-.2,3.1.9,3.3,2.5.3,1.6-.8,3.1-2.4,3.3Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.6 KiB |
@@ -1,6 +1,7 @@
|
||||
import Taro from "@tarojs/taro";
|
||||
import { check_login_status, get_user_info } from "@/services/loginService";
|
||||
import { useUser } from "@/store/userStore";
|
||||
import { Dayjs } from "dayjs";
|
||||
|
||||
// 普通函数,不调用 useLoad
|
||||
export const sceneRedirectLogic = (options, defaultPage: string) => {
|
||||
@@ -135,3 +136,40 @@ export function genNTRPRequirementText(min, max) {
|
||||
export function isPhoneNumber(str) {
|
||||
return /^1[3-9]\d{9}$/.test(str);
|
||||
}
|
||||
|
||||
export function genGameLength(startTime: Dayjs, endTime: Dayjs) {
|
||||
if (!startTime || !endTime) {
|
||||
return "";
|
||||
}
|
||||
const totalMinutes = endTime.diff(startTime, "minute");
|
||||
const totalHours = totalMinutes / 60;
|
||||
|
||||
if (totalHours >= 24) {
|
||||
const days = Math.floor(totalHours / 24);
|
||||
const remainingHours = totalHours % 24;
|
||||
|
||||
if (remainingHours === 0) {
|
||||
return `${days}天`;
|
||||
}
|
||||
|
||||
// 保留一位小数
|
||||
const displayHours = parseFloat(remainingHours.toFixed(1));
|
||||
return `${days}天${displayHours}小时`;
|
||||
}
|
||||
|
||||
// 如果是整数小时,不显示小数点
|
||||
if (Number.isInteger(totalHours)) {
|
||||
return `${totalHours}小时`;
|
||||
}
|
||||
// 保留一位小数,去除末尾的0
|
||||
return `${parseFloat(totalHours.toFixed(1))}小时`;
|
||||
}
|
||||
|
||||
export function formatGameStartTime(startTime: Dayjs) {
|
||||
if (!startTime || !startTime.isValid()) {
|
||||
return "";
|
||||
}
|
||||
const hour = startTime.hour();
|
||||
const minute = startTime.minute();
|
||||
return minute === 0 ? `${hour}点` : `${hour}点${minute}分`;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,20 @@ export interface LocationInfo {
|
||||
name?: string
|
||||
}
|
||||
|
||||
/** 规范化地址:去掉类似“上海市上海市...”的重复前缀 */
|
||||
export const normalize_address = (address: string): string => {
|
||||
if (!address) return ''
|
||||
// 去空格(包含全角空格)
|
||||
const trimmed = address.replace(/[\s\u3000]+/g, '')
|
||||
// 处理 “xx市xx市...” / “xx省xx省...” 等连续重复
|
||||
// 例:上海市上海市静安区... -> 上海市静安区...
|
||||
return trimmed.replace(/^(.{2,6}?[市省])\1+/, '$1')
|
||||
}
|
||||
|
||||
// 获取当前位置
|
||||
export const getCurrentLocation = (): Promise<LocationInfo> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.getLocation({
|
||||
;(Taro as any).getLocation({
|
||||
type: 'wgs84',
|
||||
success: (res) => {
|
||||
console.log('===获取地理位置', res)
|
||||
@@ -27,7 +37,7 @@ export const getCurrentLocation = (): Promise<LocationInfo> => {
|
||||
resolve({
|
||||
latitude: res.latitude,
|
||||
longitude: res.longitude,
|
||||
address
|
||||
address: normalize_address(address)
|
||||
})
|
||||
})
|
||||
.catch(() => {
|
||||
@@ -48,12 +58,12 @@ export const getCurrentLocation = (): Promise<LocationInfo> => {
|
||||
// 选择地图位置
|
||||
export const chooseLocation = (): Promise<LocationInfo> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.chooseLocation({
|
||||
;(Taro as any).chooseLocation({
|
||||
success: (res) => {
|
||||
resolve({
|
||||
latitude: res.latitude,
|
||||
longitude: res.longitude,
|
||||
address: res.address,
|
||||
address: normalize_address(res.address),
|
||||
name: res.name
|
||||
})
|
||||
},
|
||||
@@ -66,7 +76,7 @@ export const chooseLocation = (): Promise<LocationInfo> => {
|
||||
|
||||
export const getLocation = (): Promise<Location> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
Taro.getLocation({
|
||||
;(Taro as any).getLocation({
|
||||
success: (res) => {
|
||||
resolve({
|
||||
latitude: res.latitude,
|
||||
|
||||
@@ -106,19 +106,34 @@ const drawLabel = (ctx: any, x: number, y: number, width: number, height: number
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
/** 给图片 URL 加随机参数,避免同一链接二次加载不触发 onload */
|
||||
function with_cache_bust(url: string): string {
|
||||
const sep = url.includes('?') ? '&' : '?';
|
||||
return `${url}${sep}_t=${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
||||
}
|
||||
|
||||
// 工具函数 - OffscreenCanvas 下加载图片(使用 offscreen.createImage)
|
||||
const loadImage = (src: string): Promise<any> => {
|
||||
return new Promise((resolve, reject) => {
|
||||
let timer: ReturnType<typeof setTimeout> | null = null
|
||||
try {
|
||||
const off = runtime.offscreen
|
||||
if (!off || typeof off.createImage !== 'function') {
|
||||
throw new Error('OffscreenCanvas 未初始化或不支持 createImage')
|
||||
}
|
||||
const img = off.createImage()
|
||||
img.onload = () => resolve(img)
|
||||
img.onerror = reject
|
||||
img.src = src
|
||||
timer = setTimeout(() => reject(new Error(`图片加载超时: ${src}`)), 8000)
|
||||
img.onload = () => {
|
||||
if (timer) clearTimeout(timer)
|
||||
resolve(img)
|
||||
}
|
||||
img.onerror = (e: any) => {
|
||||
if (timer) clearTimeout(timer)
|
||||
reject(e)
|
||||
}
|
||||
img.src = with_cache_bust(src)
|
||||
} catch (e) {
|
||||
if (timer) clearTimeout(timer)
|
||||
reject(e)
|
||||
}
|
||||
})
|
||||
@@ -407,7 +422,7 @@ const drawShareCard = async (ctx: any, data: ShareCardData, offscreen: any): Pro
|
||||
ctx.restore()
|
||||
} catch (error) {
|
||||
// 如果头像加载失败,绘制默认头像
|
||||
ctx.setFillStyle('#CCCCCC')
|
||||
ctx.fillStyle = '#CCCCCC'
|
||||
ctx.beginPath()
|
||||
ctx.arc(avatarX + avatarSize / 2, avatarY + avatarSize / 2, avatarSize / 2, 0, 2 * Math.PI)
|
||||
ctx.fill()
|
||||
@@ -588,10 +603,12 @@ export async function generateShareImage(data: ShareCardData): Promise<string> {
|
||||
// 记录到 runtime(供 loadImage 使用)
|
||||
runtime.offscreen = offscreen
|
||||
isDrawing = true
|
||||
|
||||
const imagePath = await drawShareCard(ctx, data, offscreen)
|
||||
isDrawing = false
|
||||
return imagePath
|
||||
try {
|
||||
const imagePath = await drawShareCard(ctx, data, offscreen)
|
||||
return imagePath
|
||||
} finally {
|
||||
isDrawing = false
|
||||
}
|
||||
}
|
||||
|
||||
export default generateShareImage
|
||||
|
||||
Reference in New Issue
Block a user