Files
silk/miniapp/src/pages/notification/index.tsx
T
2026-08-13 22:18:35 +08:00

128 lines
4.0 KiB
TypeScript
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.
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),
entityIds: 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;