Merge branch 'feat/liujie'
This commit is contained in:
@@ -228,11 +228,35 @@
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
& > .input {
|
||||
width: 100%;
|
||||
// height: 24px;
|
||||
}
|
||||
|
||||
.limit {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
color: #3c3c43;
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
font-feature-settings: "liga" off, "clig" off;
|
||||
font-family: "PingFang SC";
|
||||
// background: #fff;
|
||||
background: linear-gradient(
|
||||
90deg,
|
||||
rgba(255, 255, 255, 0.8) 0%,
|
||||
#fff 100%
|
||||
);
|
||||
z-index: 999;
|
||||
padding: 3px 4px 3px 4px;
|
||||
|
||||
&.red {
|
||||
color: red;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sendIcon {
|
||||
|
||||
@@ -100,6 +100,9 @@ const CommentInput = forwardRef<CommentInputRef, CommentInputProps>(function (
|
||||
toast("评论内容不得为空");
|
||||
return;
|
||||
}
|
||||
if (value.length > 200) {
|
||||
return;
|
||||
}
|
||||
onConfirm?.({ content: value, ...params });
|
||||
onClose();
|
||||
}
|
||||
@@ -139,10 +142,18 @@ const CommentInput = forwardRef<CommentInputRef, CommentInputProps>(function (
|
||||
confirmType="send"
|
||||
onConfirm={handleSend}
|
||||
focus
|
||||
maxlength={100}
|
||||
maxlength={-1}
|
||||
autoHeight
|
||||
showCount
|
||||
// showCount
|
||||
/>
|
||||
<View
|
||||
className={classnames(
|
||||
styles.limit,
|
||||
value.length > 200 ? styles.red : ""
|
||||
)}
|
||||
>
|
||||
<Text>{value.length}</Text>/<Text>200</Text>
|
||||
</View>
|
||||
</View>
|
||||
<View className={styles.sendIcon} onClick={handleSend}>
|
||||
<Image className={styles.sendImage} src={sendImg} />
|
||||
@@ -188,6 +199,8 @@ function CommentItem(props: {
|
||||
const currentUserInfo = useUserInfo();
|
||||
// 判断评论的作者是否是组织者
|
||||
const isGamePublisher = publisher_id === comment.user.id;
|
||||
// 当前用户是否是球局发布者
|
||||
const currentIsGamePublisher = publisher_id === currentUserInfo.id;
|
||||
// 判断当前登录用户是否是评论的作者
|
||||
const isCommentPublisher = currentUserInfo.id === comment.user.id;
|
||||
return (
|
||||
@@ -251,7 +264,7 @@ function CommentItem(props: {
|
||||
>
|
||||
<Text>回复</Text>
|
||||
</View>
|
||||
{(isGamePublisher || isCommentPublisher) && (
|
||||
{(currentIsGamePublisher || isCommentPublisher) && (
|
||||
<View
|
||||
className={styles.delete}
|
||||
onClick={() =>
|
||||
@@ -294,10 +307,15 @@ function CommentItem(props: {
|
||||
}
|
||||
|
||||
export default forwardRef(function Comments(
|
||||
props: { game_id: number; publisher_id: number; message_id?: number },
|
||||
props: {
|
||||
game_id: number;
|
||||
publisher_id: number;
|
||||
message_id?: number;
|
||||
onScrollTo: (id: string) => void;
|
||||
},
|
||||
ref
|
||||
) {
|
||||
const { game_id, publisher_id, message_id } = props;
|
||||
const { game_id, publisher_id, message_id, onScrollTo } = props;
|
||||
const [comments, setComments] = useState<Comment[]>([]);
|
||||
const inputRef = useRef<CommentInputRef>(null);
|
||||
const [blink_id, setBlinkId] = useState<number | undefined>();
|
||||
@@ -350,17 +368,22 @@ export default forwardRef(function Comments(
|
||||
if (item.id !== parent_id) return item;
|
||||
return {
|
||||
...item,
|
||||
replies: [res.data, ...item.replies],
|
||||
replies: [res.data, ...item.replies].sort((a, b) =>
|
||||
dayjs(a.create_time).isAfter(dayjs(b.create_time))
|
||||
? 1
|
||||
: -1
|
||||
),
|
||||
};
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
await delay(100);
|
||||
Taro.pageScrollTo({
|
||||
selector: `#comment_id_${res.data.id}`,
|
||||
duration: 300,
|
||||
});
|
||||
await delay(200);
|
||||
onScrollTo?.(`#comment_id_${res.data.id}`);
|
||||
// Taro.pageScrollTo({
|
||||
// selector: `#comment_id_${res.data.id}`,
|
||||
// duration: 300,
|
||||
// });
|
||||
setBlinkId(res.data.id);
|
||||
setTimeout(() => {
|
||||
setBlinkId(undefined);
|
||||
|
||||
@@ -24,13 +24,24 @@
|
||||
align-items: center;
|
||||
gap: 4px;
|
||||
border-radius: 12px;
|
||||
// border: 0.5px solid rgba(255, 255, 255, 0.08);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.08);
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
overflow: hidden;
|
||||
color: #fff;
|
||||
background: #536272;
|
||||
// background: #536272;
|
||||
flex-shrink: 0;
|
||||
font-family: "Quicksand";
|
||||
// opacity: 0;
|
||||
animation: intro 0.3s ease-in forwards;
|
||||
|
||||
@keyframes intro {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.month {
|
||||
width: 100%;
|
||||
@@ -44,6 +55,8 @@
|
||||
// border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
background: #7b828b;
|
||||
font-weight: 600;
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.08);
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
}
|
||||
|
||||
.day {
|
||||
@@ -144,13 +157,23 @@
|
||||
border-radius: 12px;
|
||||
padding: 14px;
|
||||
box-sizing: border-box;
|
||||
background: #4d5865;
|
||||
// background: #4d5865;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
// border: 0.5px solid rgba(255, 255, 255, 0.08);
|
||||
// background: rgba(255, 255, 255, 0.25);
|
||||
border: 0.5px solid rgba(255, 255, 255, 0.08);
|
||||
background: rgba(255, 255, 255, 0.25);
|
||||
animation: intro 0.3s ease-in forwards;
|
||||
|
||||
@keyframes intro {
|
||||
from {
|
||||
opacity: 0;
|
||||
}
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&-image {
|
||||
width: 20px;
|
||||
|
||||
@@ -189,6 +189,8 @@ function Index() {
|
||||
);
|
||||
}
|
||||
|
||||
const [scrollToTarget, setScrollToTarget] = useState("");
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
className={styles["detail-page"]}
|
||||
@@ -199,6 +201,8 @@ function Index() {
|
||||
}}
|
||||
enhanced
|
||||
showScrollbar={false}
|
||||
scrollIntoView={scrollToTarget}
|
||||
scroll-with-animation
|
||||
>
|
||||
{/* custom navbar */}
|
||||
<View
|
||||
@@ -278,6 +282,7 @@ function Index() {
|
||||
game_id={Number(detail.id)}
|
||||
message_id={message_id ? Number(message_id) : undefined}
|
||||
publisher_id={Number(detail.publisher_id)}
|
||||
onScrollTo={setScrollToTarget}
|
||||
/>
|
||||
{/* sticky bottom action bar */}
|
||||
<StickyBottom
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
// border-radius: 12px;
|
||||
// border: 1px solid rgba(0, 0, 0, 0.06);
|
||||
// background: lightgray 50% / cover no-repeat;
|
||||
box-shadow: 0 4px 36px 0 rgba(0, 0, 0, 0.16);
|
||||
// box-shadow: 0 4px 36px 0 rgba(0, 0, 0, 0.16);
|
||||
}
|
||||
|
||||
.qrcodeTip {
|
||||
@@ -74,12 +74,14 @@
|
||||
}
|
||||
|
||||
.listPage {
|
||||
background-color: #FAFAFA;
|
||||
background-color: #fafafa;
|
||||
font-family: "PingFang SC";
|
||||
transition: padding-top 0.3s ease-in-out; // 添加过渡动画,让布局变化更平滑
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100vh - var(--status-bar-height, 0px) - var(--nav-bar-height, 0px) - 112px); // 减去底部导航栏高度 112px
|
||||
height: calc(
|
||||
100vh - var(--status-bar-height, 0px) - var(--nav-bar-height, 0px) - 112px
|
||||
); // 减去底部导航栏高度 112px
|
||||
overflow: hidden;
|
||||
|
||||
.fixedHeader {
|
||||
@@ -190,4 +192,4 @@
|
||||
|
||||
.guideBarHighZIndex {
|
||||
z-index: 900 !important; // 正常状态,保持较高层级
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,15 +160,18 @@
|
||||
color: #000;
|
||||
font-feature-settings: "liga" off, "clig" off;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-family: "PingFang SC";
|
||||
font-size: 16px;
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
line-height: 24px; /* 150% */
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.payNum {
|
||||
width: 90px;
|
||||
width: 120px;
|
||||
font-feature-settings: "liga" off, "clig" off;
|
||||
font-family: "PingFang SC";
|
||||
font-size: 12px;
|
||||
@@ -176,6 +179,9 @@
|
||||
font-weight: 600;
|
||||
line-height: 26px;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 6px;
|
||||
&.paid {
|
||||
color: #000;
|
||||
}
|
||||
@@ -183,6 +189,10 @@
|
||||
&.pending {
|
||||
color: #ff3b30;
|
||||
}
|
||||
|
||||
.amount {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -336,7 +336,9 @@ const OrderList = () => {
|
||||
? "待支付"
|
||||
: refundTextMap.get(item.refund_status)}
|
||||
</Text>{" "}
|
||||
¥ <Text>{item.amount}</Text>
|
||||
<View className={styles.amount}>
|
||||
¥ <Text>{item.amount}</Text>
|
||||
</View>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
@@ -6,13 +6,14 @@ export function getOrderStatus(orderData) {
|
||||
return 'none'
|
||||
}
|
||||
const unPay = order_status === OrderStatus.PENDING && ([CancelType.NONE].includes(cancel_type));
|
||||
const refund = [RefundStatus.PENDING, RefundStatus.SUCCESS].includes(refund_status);
|
||||
const refund = [RefundStatus.SUCCESS].includes(refund_status);
|
||||
const refunding = [RefundStatus.PENDING].includes(refund_status);
|
||||
const expired =
|
||||
order_status === OrderStatus.FINISHED;
|
||||
|
||||
const canceled = [CancelType.TIMEOUT, CancelType.USER].includes(cancel_type);
|
||||
|
||||
return unPay ? 'unpay' : refund ? 'refund' : canceled ? 'canceled' : expired ? 'expired' : 'progress'
|
||||
return unPay ? 'unpay' : refund ? 'refund' : canceled ? 'canceled' : expired ? 'expired' : refunding ? 'refunding' : 'progress'
|
||||
}
|
||||
|
||||
// scene: list、detail
|
||||
@@ -59,6 +60,7 @@ export function generateOrderActions(orderData, actions, scene) {
|
||||
['expired', [deleteOrder, gameDetail]],
|
||||
['progress', [quitGame, gameDetail]],
|
||||
['refund', [deleteOrder, gameDetail]],
|
||||
['refunding', [gameDetail]],
|
||||
['unpay', [cancelOrder, payNow]]
|
||||
])
|
||||
return actionMap.get(key)
|
||||
@@ -70,6 +72,7 @@ export function generateOrderActions(orderData, actions, scene) {
|
||||
['expired', [gameDetail, deleteOrder]],
|
||||
['progress', [gameDetail, quitGame]],
|
||||
['refund', [deleteOrder, gameDetail]],
|
||||
['refunding', [gameDetail]],
|
||||
['unpay', [cancelOrder]]
|
||||
])
|
||||
return actionMap.get(key)
|
||||
|
||||
@@ -1,35 +1,48 @@
|
||||
import Taro from "@tarojs/taro";
|
||||
|
||||
export function saveImage(url) {
|
||||
Taro.getSetting().then(async (res) => {
|
||||
if (!res.authSetting["scope.writePhotosAlbum"]) {
|
||||
// 下载网络图片,返回本地 temp 文件
|
||||
const download = () => {
|
||||
return Taro.downloadFile({ url }).then(res => {
|
||||
if (res.statusCode === 200) {
|
||||
return res.tempFilePath
|
||||
}
|
||||
throw new Error("图片下载失败")
|
||||
})
|
||||
}
|
||||
|
||||
const save = async () => {
|
||||
try {
|
||||
const filePath = await download()
|
||||
await Taro.saveImageToPhotosAlbum({ filePath })
|
||||
Taro.showToast({ title: "保存成功" })
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
Taro.showToast({ title: "图片保存失败", icon: "none" })
|
||||
}
|
||||
}
|
||||
|
||||
Taro.getSetting().then(res => {
|
||||
const authorized = res.authSetting["scope.writePhotosAlbum"]
|
||||
|
||||
if (!authorized) {
|
||||
Taro.authorize({
|
||||
scope: "scope.writePhotosAlbum",
|
||||
success: async () => {
|
||||
try {
|
||||
Taro.saveImageToPhotosAlbum({ filePath: url });
|
||||
Taro.showToast({ title: "保存成功" });
|
||||
} catch (e) {
|
||||
Taro.showToast({ title: "图片保存失败", icon: "none" });
|
||||
}
|
||||
success: () => {
|
||||
save()
|
||||
},
|
||||
fail: () => {
|
||||
Taro.showModal({
|
||||
title: "提示",
|
||||
content: "需要开启相册权限才能保存图片",
|
||||
success: (r) => {
|
||||
if (r.confirm) Taro.openSetting();
|
||||
},
|
||||
});
|
||||
},
|
||||
});
|
||||
if (r.confirm) Taro.openSetting()
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
} else {
|
||||
try {
|
||||
Taro.saveImageToPhotosAlbum({ filePath: url });
|
||||
Taro.showToast({ title: "保存成功" });
|
||||
} catch (e) {
|
||||
Taro.showToast({ title: "图片保存失败", icon: "none" });
|
||||
}
|
||||
save()
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user