feat(miniapp): 消息订阅设置页(模板 ID 占位,#11)

This commit is contained in:
weijuesen
2026-08-12 17:29:02 +08:00
parent 921b185da2
commit bdf0515f2a
6 changed files with 251 additions and 0 deletions
+126
View File
@@ -0,0 +1,126 @@
import React, { useCallback, useEffect, useState } from 'react';
import { Button, Text, View } from '@tarojs/components';
import Taro from '@tarojs/taro';
import styles from './index.module.scss';
import {
SUBSCRIBE_TEMPLATES,
bindWechat,
getWechatBinding,
updateWechatSubscribe,
type WechatBinding,
} from '@/api/wechat';
const NotificationPage: React.FC = () => {
const [binding, setBinding] = useState<WechatBinding | null>(null);
const [loading, setLoading] = useState(false);
const refresh = useCallback(async () => {
const data = await getWechatBinding().catch(() => ({ bound: false } as WechatBinding));
setBinding(data);
}, []);
useEffect(() => {
refresh();
}, [refresh]);
const handleBind = async () => {
setLoading(true);
try {
const { code } = await Taro.login();
if (!code) throw new Error('获取登录 code 失败');
await bindWechat(code);
Taro.showToast({ title: '微信绑定成功', icon: 'success' });
refresh();
} catch (err) {
Taro.showToast({
title: err instanceof Error ? err.message : '绑定失败',
icon: 'none',
});
} finally {
setLoading(false);
}
};
const handleSubscribe = async () => {
const configured = SUBSCRIBE_TEMPLATES.filter((t) => t.id);
if (configured.length === 0) {
Taro.showModal({
title: '模板未配置',
content: '订阅消息模板 ID 尚未配置,申请模板后填入 miniapp/src/api/wechat.ts 即可启用。',
showCancel: false,
confirmText: '知道了',
});
return;
}
setLoading(true);
try {
const res = await Taro.requestSubscribeMessage({
tmplIds: configured.map((t) => t.id),
});
for (const t of configured) {
if (res[t.id] === 'accept') {
await updateWechatSubscribe(t.key, true);
}
}
Taro.showToast({ title: '订阅设置已更新', icon: 'success' });
refresh();
} catch (err) {
Taro.showToast({
title: err instanceof Error ? err.message : '订阅失败',
icon: 'none',
});
} finally {
setLoading(false);
}
};
return (
<View className={styles.page}>
<View className={styles.card}>
<Text className={styles.cardTitle}></Text>
<Text className={styles.cardDesc}>
//
</Text>
<View className={styles.statusRow}>
<Text className={styles.statusLabel}></Text>
<Text className={binding?.bound ? styles.statusOk : styles.statusNo}>
{binding?.bound ? '已绑定' : '未绑定'}
</Text>
</View>
{binding?.bound && binding.openId ? (
<Text className={styles.openId}>openid{binding.openId}</Text>
) : null}
{binding?.bound && binding.authorized && binding.authorized.length > 0 ? (
<Text className={styles.openId}>{binding.authorized.join('、')}</Text>
) : null}
<Button
className={`${styles.btn} ${styles.btnPrimary}`}
loading={loading}
onClick={handleBind}
>
</Button>
<Button
className={`${styles.btn} ${styles.btnPrimary}`}
loading={loading}
onClick={handleSubscribe}
>
</Button>
</View>
<View className={styles.card}>
<Text className={styles.cardTitle}></Text>
{SUBSCRIBE_TEMPLATES.map((t) => (
<View key={t.key} className={styles.tplRow}>
<Text className={styles.tplLabel}>{t.label}</Text>
<Text className={t.id ? styles.tplReady : styles.tplPending}>
{t.id ? '已配置' : '待配置模板 ID'}
</Text>
</View>
))}
</View>
</View>
);
};
export default NotificationPage;