's'
This commit is contained in:
@@ -125,7 +125,7 @@ const config = {
|
||||
},
|
||||
},
|
||||
// 允许特定域名访问
|
||||
allowedHosts: ["nomadro.com", "localhost", ".nomadro.com","hackrobot.cn",".hackrobot.cn"], // 允许所有 *.nomadyt.com 子域访问
|
||||
allowedHosts: ["nomadro.com", "localhost", ".nomadro.com","hackrobot.cn",".hackrobot.cn",".ngrok-free.app"], // 允许所有 *.nomadyt.com 子域访问
|
||||
},
|
||||
htmlPluginOption: {
|
||||
favicon: path.resolve(__dirname, "..", "src", "images", "avatar.jpg"), // 同样处理 favicon 路径
|
||||
|
||||
21501
pnpm-lock.yaml
generated
Normal file
21501
pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,7 @@
|
||||
<script>
|
||||
<%= htmlWebpackPlugin.options.script %>
|
||||
</script>
|
||||
<script src="https://unpkg.com/pocketbase/dist/pocketbase.umd.js"></script>
|
||||
<!-- 禁止缓存 -->
|
||||
<meta
|
||||
http-equiv="Cache-Control"
|
||||
|
||||
@@ -66,9 +66,19 @@ import planet from "../../images/avatar.jpg";
|
||||
|
||||
import book from "../../images/book.svg";
|
||||
import youtubesvg from "../../images/youtube.svg";
|
||||
|
||||
|
||||
// PocketBase 配置
|
||||
const PB_URL = 'https://pocketbase.hackrobot.cn';
|
||||
const pb = new PocketBase(PB_URL);
|
||||
|
||||
// export default class Index extends Component {
|
||||
const Index = () => {
|
||||
const [vip, setvip] = useState(window.localStorage.getItem("vip"));
|
||||
// const [vip, setvip] = useState(window.localStorage.getItem("vip"));
|
||||
const [paidType, setPaidType] = useState(null); // 新增:支付类型 'vip' | 'book' | null
|
||||
const [userName, setUserName] = useState(Taro.getStorageSync('userName') || null); // 新增
|
||||
const [loading, setLoading] = useState(true); // 新增:加载状态
|
||||
|
||||
const [current, setcurrent] = useState(0);
|
||||
const [openId, setopenId] = useState(null);
|
||||
const [wxid, setwxid] = useState(null);
|
||||
@@ -87,7 +97,7 @@ const Index = () => {
|
||||
const [bookpay, setbookpay] = useState(0);
|
||||
|
||||
const [isWeChat, setisWeChat] = useState(false);
|
||||
const [markText, setmarkText] = useState(vip == 1 ? index : index);
|
||||
const [markText, setmarkText] = useState(paidType ? index : index);
|
||||
const [headers, setHeaders] = useState([]); // 存储所有 <h1> 的内容
|
||||
const contentRef = useRef(null); // 用于获取渲染后的 DOM
|
||||
|
||||
@@ -181,7 +191,7 @@ const Index = () => {
|
||||
let nowUrl = window.location.href;
|
||||
window.localStorage.removeItem("openid");
|
||||
let payUrl = `https://payjs.cn/api/openid?mchid=1561724891&callback_url=${nowUrl}`;
|
||||
window.location.href = payUrl;
|
||||
// window.location.href = payUrl;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -201,7 +211,7 @@ const Index = () => {
|
||||
}
|
||||
}
|
||||
},
|
||||
complete: function (finy) {},
|
||||
complete: function (finy) { },
|
||||
});
|
||||
};
|
||||
|
||||
@@ -271,9 +281,9 @@ const Index = () => {
|
||||
header: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
success: function (res) {},
|
||||
fail: function (err) {},
|
||||
complete: function (finy) {},
|
||||
success: function (res) { },
|
||||
fail: function (err) { },
|
||||
complete: function (finy) { },
|
||||
});
|
||||
};
|
||||
|
||||
@@ -292,9 +302,9 @@ const Index = () => {
|
||||
header: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
success: function (res) {},
|
||||
fail: function (err) {},
|
||||
complete: function (finy) {},
|
||||
success: function (res) { },
|
||||
fail: function (err) { },
|
||||
complete: function (finy) { },
|
||||
});
|
||||
};
|
||||
|
||||
@@ -302,9 +312,8 @@ const Index = () => {
|
||||
const tgMessage = () => {
|
||||
Taro.request({
|
||||
method: "GET",
|
||||
url: `${
|
||||
process.env.TARO_API_API
|
||||
}/tgMessage?openid=${window.localStorage.getItem("openid")}`, //仅为示例,并非真实的接口地址
|
||||
url: `${process.env.TARO_API_API
|
||||
}/tgMessage?openid=${window.localStorage.getItem("openid")}`, //仅为示例,并非真实的接口地址
|
||||
// url: "https://pay.hackrobot.cn${process.env.TARO_API_API}/payh5", //仅为示例,并非真实的接口地址
|
||||
success: function (res) {
|
||||
console.log("访问提醒发送成功");
|
||||
@@ -312,16 +321,151 @@ const Index = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 入群申请
|
||||
|
||||
|
||||
// 保存 userName 到本地
|
||||
const saveUserName = (name) => {
|
||||
Taro.setStorageSync('userName', name);
|
||||
setUserName(name);
|
||||
};
|
||||
|
||||
// 获取本地 userName
|
||||
const getLocalUserName = () => {
|
||||
return Taro.getStorageSync('userName') || null;
|
||||
};
|
||||
|
||||
// 检查本地是否已有支付类型
|
||||
const getLocalPaidType = () => {
|
||||
return Taro.getStorageSync('paidType') || null;
|
||||
};
|
||||
|
||||
// 保存支付类型到本地
|
||||
const savePaidType = (type) => {
|
||||
Taro.setStorageSync('paidType', type);
|
||||
setPaidType(type);
|
||||
};
|
||||
|
||||
// 查询 PocketBase 是否支付过
|
||||
const checkPaymentFromPB = async (userId) => {
|
||||
// window.alert('查询pocketbase')
|
||||
try {
|
||||
// 查询 payments 表中该 user_id 的记录,按创建时间倒序(最新的一笔)
|
||||
const records = await pb.collection('payments').getList(1, 1, {
|
||||
filter: `user_id = "${userId}"`,
|
||||
sort: '-created', // 最新支付优先
|
||||
});
|
||||
|
||||
if (records.items.length > 0) {
|
||||
const latestType = records.items[0].type; // 取最新一笔的 type
|
||||
const dbUserId = records.items[0].user_id; // 数据库里的真实 user_id
|
||||
// window.alert('latestType', dbUserId)
|
||||
savePaidType(latestType);
|
||||
saveUserName(dbUserId); // ← 关键:缓存数据库里的 user_id 作为 userName
|
||||
console.log('从 PocketBase 查询到已支付:', latestType);
|
||||
return latestType;
|
||||
} else {
|
||||
// window.alert('未找到支付记录')
|
||||
|
||||
console.log('未找到支付记录');
|
||||
savePaidType(null);
|
||||
return null;
|
||||
}
|
||||
} catch (err) {
|
||||
// window.alert('查询 PocketBase 失败', err)
|
||||
console.error('查询 PocketBase 失败:', err);
|
||||
// 网络错误时不影响本地缓存,使用本地旧值
|
||||
return getLocalPaidType();
|
||||
} finally {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// useEffect(() => {
|
||||
// // 生成userId
|
||||
// getOrCreateUserId(); // ← 新增:获取 userId
|
||||
// let inwechat = isWeChatFun();
|
||||
// if (inwechat) {
|
||||
// // 获取openId
|
||||
// getOpenid();
|
||||
|
||||
// } else {
|
||||
// // window.alert('不在微信')
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
// 清空所有本地存储(测试专用)
|
||||
const clearAllStorage = () => {
|
||||
try {
|
||||
// 清空 Taro 的 storage(推荐方式)
|
||||
Taro.clearStorageSync();
|
||||
|
||||
// 同时清空 window.localStorage(H5 环境兼容)
|
||||
if (typeof window !== 'undefined' && window.localStorage) {
|
||||
window.localStorage.clear();
|
||||
}
|
||||
|
||||
// 可选:手动清除你知道的关键字段,防止残留
|
||||
Taro.removeStorageSync('userId');
|
||||
Taro.removeStorageSync('paidType');
|
||||
Taro.removeStorageSync('userName');
|
||||
Taro.removeStorageSync('openid');
|
||||
Taro.removeStorageSync('wxid');
|
||||
|
||||
// 状态重置
|
||||
setPaidType(null);
|
||||
setUserName(null);
|
||||
setLoading(false);
|
||||
|
||||
Taro.showToast({
|
||||
title: '本地存储已清空',
|
||||
icon: 'success',
|
||||
duration: 2000,
|
||||
});
|
||||
|
||||
// 可选:刷新页面让效果立即生效
|
||||
setTimeout(() => {
|
||||
// window.location.reload();
|
||||
}, 1000);
|
||||
|
||||
} catch (error) {
|
||||
console.error('清空存储失败:', error);
|
||||
Taro.showToast({
|
||||
title: '清空失败',
|
||||
icon: 'none',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
let inwechat = isWeChatFun();
|
||||
if (inwechat) {
|
||||
// 获取openId
|
||||
getOpenid();
|
||||
} else {
|
||||
// window.alert('不在微信')
|
||||
}
|
||||
// 判断是否在微信
|
||||
isWeChatFun()
|
||||
// 测试用=>清除缓存
|
||||
// clearAllStorage()
|
||||
|
||||
const init = async () => {
|
||||
getOrCreateUserId(); // 确保 userId 存在
|
||||
|
||||
const localType = getLocalPaidType();
|
||||
const localUserName = getLocalUserName();
|
||||
if (localType && localUserName) {
|
||||
setPaidType(localType);
|
||||
setUserName(localUserName);
|
||||
setLoading(false);
|
||||
console.log('使用本地缓存:', localType, localUserName);
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = Taro.getStorageSync('userId');
|
||||
if (userId) {
|
||||
await checkPaymentFromPB(userId);
|
||||
} else {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
init();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -363,7 +507,7 @@ const Index = () => {
|
||||
});
|
||||
};
|
||||
|
||||
const payh5 = (type, total_fee = 1000) => {
|
||||
const payh51111 = (type, total_fee = 1000) => {
|
||||
// console.log("111");
|
||||
Taro.request({
|
||||
method: "POST",
|
||||
@@ -408,7 +552,7 @@ const Index = () => {
|
||||
window.localStorage.setItem("password", "123456");
|
||||
WeixinJSBridge.call("closeWindow");
|
||||
} else {
|
||||
window.alert("支付取消/失败");
|
||||
// window.alert("支付取消/失败");
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -416,6 +560,81 @@ const Index = () => {
|
||||
});
|
||||
};
|
||||
|
||||
// 生成或获取 userId(修改为无下划线)
|
||||
const getOrCreateUserId = () => {
|
||||
let userId = Taro.getStorageSync("userId");
|
||||
if (!userId) {
|
||||
// 修改这里:去掉下划线
|
||||
userId = `user${Date.now()}`; // 示例:user1766043770158
|
||||
Taro.setStorageSync("userId", userId);
|
||||
console.log('新生成 userId:', userId);
|
||||
}
|
||||
return userId;
|
||||
};
|
||||
|
||||
const payh5 = (type, total_fee = 1000) => {
|
||||
const userId = getOrCreateUserId(); // ← 新增:获取 userId
|
||||
Taro.request({
|
||||
method: "POST",
|
||||
url: `${process.env.TARO_API_API}/payh5`,
|
||||
data: {
|
||||
total_fee: total_fee,
|
||||
type: type,
|
||||
// callback_url 临时不传
|
||||
user_id: userId, // ← 新增字段
|
||||
},
|
||||
header: {
|
||||
"content-type": "application/json",
|
||||
},
|
||||
success: (res) => {
|
||||
if (res.data?.status === "ok" && res.data?.xorpay_params) {
|
||||
// 1. 乐观更新:立即缓存 paidType,用户看到“加载中”或直接显示已支付
|
||||
// savePaidType(type);
|
||||
// saveUserName(userId); // ← 乐观缓存当前 userId
|
||||
// Taro.showToast({
|
||||
// title: "正在跳转支付,请稍后...",
|
||||
// icon: "loading",
|
||||
// duration: 2000,
|
||||
// });
|
||||
|
||||
// 创建隐藏 form POST 到 XorPay
|
||||
const form = document.createElement("form");
|
||||
form.method = "POST";
|
||||
form.action = res.data.xorpay_url;
|
||||
form.style.display = "none";
|
||||
|
||||
for (const key in res.data.xorpay_params) {
|
||||
const input = document.createElement("input");
|
||||
input.type = "hidden";
|
||||
input.name = key;
|
||||
input.value = res.data.xorpay_params[key];
|
||||
form.appendChild(input);
|
||||
}
|
||||
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
|
||||
// 2. 可选:提交后清理 form,避免内存泄漏
|
||||
setTimeout(() => {
|
||||
document.body.removeChild(form);
|
||||
}, 1000);
|
||||
|
||||
} else {
|
||||
Taro.showToast({
|
||||
title: "支付发起失败",
|
||||
icon: "none",
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: () => {
|
||||
Taro.showToast({
|
||||
title: "网络错误",
|
||||
icon: "none",
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const goRead = () => {
|
||||
Taro.navigateTo({
|
||||
url: "/pages/book/index",
|
||||
@@ -423,7 +642,9 @@ const Index = () => {
|
||||
};
|
||||
const handleCopyUsername = () => {
|
||||
Taro.setClipboardData({
|
||||
data: window.localStorage.getItem("username"), // 复制账号
|
||||
// data: window.localStorage.getItem("userId"), // 复制账号
|
||||
data: userName || '',
|
||||
|
||||
success: () => {
|
||||
Taro.showToast({
|
||||
title: "账号已复制",
|
||||
@@ -506,7 +727,6 @@ const Index = () => {
|
||||
<View className="cardItem_left">
|
||||
<Image className="cardItem_left_img" src={group}></Image>
|
||||
{/* <Image className="cardItem_left_img" src={planet}></Image> */}
|
||||
|
||||
</View>
|
||||
<View className="cardItem_right">
|
||||
<View className="cardItem_rightUp">不只云手机</View>
|
||||
@@ -519,22 +739,45 @@ const Index = () => {
|
||||
className="markdown-body markVip" // 添加 GitHub Markdown 主题类
|
||||
dangerouslySetInnerHTML={{
|
||||
// __html: marked(markText),
|
||||
__html: marked(vip == 1 ? index : index),
|
||||
__html: marked(paidType ? index : index),
|
||||
}}
|
||||
></View>
|
||||
|
||||
<View className="left_btn">
|
||||
{vip != 1 ? (
|
||||
{paidType === 'vip' ? (
|
||||
<View className="vipcode">
|
||||
<View
|
||||
onClick={() => {
|
||||
window.location.href = `https://qun.hackrobot.cn`;
|
||||
}}
|
||||
>
|
||||
{/* 👉星球地址: memos.hackrobot.org */}
|
||||
👉星球地址: qun.hackrobot.cn
|
||||
</View>
|
||||
<View>账号:{Taro.getStorageSync('userName')}</View>
|
||||
<Button onClick={handleCopyUsername}>复制账号</Button>
|
||||
<View>密码:{"123456"}</View>{" "}
|
||||
{/* <View>
|
||||
添加
|
||||
<span style={{ color: "green" }}>微信好友: hackrobot</span>
|
||||
</View> */}
|
||||
{/* <Image className="vipcodeImg" src={hackrobot}></Image> */}
|
||||
{/* <View>获取 账号</View> */}
|
||||
</View>
|
||||
) : (
|
||||
<AtButton
|
||||
onClick={() => {
|
||||
// md页面
|
||||
// goRead();
|
||||
if (vip == 1) {
|
||||
// window.alert("paidType---", paidType)
|
||||
|
||||
if (paidType) {
|
||||
return false;
|
||||
} else {
|
||||
// window.alert('isWeChat--', isWeChat)
|
||||
if (!!isWeChat) {
|
||||
//98元
|
||||
payh5("vip", 18800);
|
||||
payh5("vip", 10);
|
||||
} else {
|
||||
window.location.href = `https://mp.weixin.qq.com/s/16xcMIgxEEGBPY7fanNq0g`;
|
||||
}
|
||||
@@ -547,27 +790,6 @@ const Index = () => {
|
||||
>
|
||||
{`${"加 入 交 流"}`}
|
||||
</AtButton>
|
||||
) : (
|
||||
<View className="vipcode">
|
||||
<View
|
||||
onClick={() => {
|
||||
window.location.href = `https://qun.hackrobot.cn`;
|
||||
}}
|
||||
>
|
||||
{/* 👉星球地址: memos.hackrobot.org */}
|
||||
👉星球地址: qun.hackrobot.cn
|
||||
|
||||
</View>
|
||||
<View>账号:{window.localStorage.getItem("username")}</View>
|
||||
<Button onClick={handleCopyUsername}>复制账号</Button>
|
||||
<View>密码:{"123456"}</View>{" "}
|
||||
{/* <View>
|
||||
添加
|
||||
<span style={{ color: "green" }}>微信好友: hackrobot</span>
|
||||
</View> */}
|
||||
{/* <Image className="vipcodeImg" src={hackrobot}></Image> */}
|
||||
{/* <View>获取 账号</View> */}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
</View>
|
||||
@@ -576,7 +798,7 @@ const Index = () => {
|
||||
className="book_img"
|
||||
// style="width: 40%px;height:100%;background: #fff;"
|
||||
src={touxiang}
|
||||
// src={phone2}
|
||||
// src={phone2}
|
||||
/>
|
||||
</View>
|
||||
</View>
|
||||
@@ -588,7 +810,7 @@ const Index = () => {
|
||||
// style="width: 40%px;height:100%;background: #fff;"
|
||||
// src={book}
|
||||
src={laptop}
|
||||
// src={phone2}
|
||||
// src={phone2}
|
||||
/>
|
||||
<View className="bookImg_text">无人直播</View>
|
||||
</View>
|
||||
|
||||
Reference in New Issue
Block a user