删除 More/t.php.bak

This commit is contained in:
2025-10-17 23:32:12 +08:00
committed by cssfw
parent 917d269c83
commit 1f5ac5e0ca
79 changed files with 13493 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
nl01tnkt4t
lh6sr7t9sd
55irq9mt51hht8r
l6jbl3awye
0f7wilpmqlwrwb7
pfy5lwf18l
7tohfmfpf8k2x7m
mvirbu6hog
xm7x949ipbb0u4p
b10cxrewms
9x8w1pe9sssu17y
9ydyzcwap0
5lrxiq10snw2e4s
4456d5a8vv
z07lurkukdxho1j
w7o2w6vsva
f5sqqb01x66jjhn
1kwqp1bty6
sckk4u5e5iyu0cd
bmyvr14q3z
5mwf7jh2vwoezy1
hy25pbtvia
h13qspl8nfu38r2
i6b29cufv1
k7brk5as0zgro0f
9mwvjh1t01
sneg222cuhu06uh
y07mjuo1cf
oulpjda4h72bp9d
zvn19ce909
8qugxyavcgoaxm9
ojsrsgpy46
3u8a2hivbyxj947
gy3accf815
dohwpxuxu36f445
bm4h3na5xj
3jmwv9cv2o62j5h
8mvaysfctg
beqktcwt9g0n1bf
an3hydsfbb
cld06vc4ba2t9tr
nuy7sak0vp
c2wz01xoyw6xjpa
ac1ddtz5uz
s4ammf90ludjpxx
u3jocjlecs
mrm9h0qex58wnu4
jlgne3buvp
1cp744jvbvhyw07
3ywmpl50l2
ou84orvyac2q5ih
fmccgczjr2
c9qgnzhp367p7sk
845jp6o44u
ox9py3z8e41usol
gdfk38lg9q
c62dmgesi1ik6lo
x8jhc04f68
6iys03f3o1zxtp0
n1dmp5v1ou
2utduxhqu3m75tj
srtonx74oz
ajzrbq4mdw1tlsv

98
Main/BuyGoods/index.php Normal file
View File

@@ -0,0 +1,98 @@
<?php
require_once "../Hv4.Logged.php";
$产品标识 = @$_POST['product_id'];
$语句 = "SELECT * FROM products WHERE product_id = '$产品标识';";
$产品元数据 = @reset(@数据库运行($语句));
if (!$产品元数据) {
定义输出("code",100);
定义输出("msg","获取产品元数据失败");
终止并输出();
}
$产品模块 = $产品元数据["module"];
$产品周期 = $产品元数据["subscription_period"];
$模块路径 = "../ProductsModule/".$产品模块."/Main.php";
$产品名称 = $产品元数据["name"];
require_once $模块路径;
$产品唯一标识符 = @唯一字符串();
$价格 = $产品元数据["price"];
$货币 = $产品元数据["currency_type"];
$库存 = $产品元数据["stock"];
$限购 = $产品元数据["limit_per_user"];
$语句 = "SELECT * FROM purchases WHERE product_id = '$产品标识' AND user_id = $用户ID;";
$用户购买 = @count(@数据库运行($语句));
if ($限购 <= $用户购买) {
定义输出("code",100);
定义输出("msg","别买太多惹");
终止并输出();
}
if ($库存 <= 0) {
定义输出("code",100);
定义输出("msg","库存不足惹");
终止并输出();
}
if ($货币 == "score") {
$比较项 = $积分;
} else {
$比较项 = $余额;
}
$减后余额 = $比较项 - $价格;
if ($减后余额 < 0) {
定义输出("code",100);
定义输出("msg","余额不足惹");
终止并输出();
}
if ($货币 == "score") {
设置用户积分($减后余额);
} else {
设置用户余额($减后余额);
}
$结果 = @开通产品($产品元数据,$产品唯一标识符);
$储存数据 = @转JSON($结果["data"]);
if ($结果["code"] == 200) {
定义输出("code",$结果["code"]);
定义输出("msg","开通成功");
$产品状态 = "activated";
} else {
定义输出("code",$结果["code"]);
定义输出("msg","开通失败");
$产品状态 = "pending_activation";
}
$库存 = $库存 - 1;
$语句 = "UPDATE products
SET stock = $库存
WHERE product_id = '$产品标识';";
@数据库运行($语句);
$语句 = "INSERT INTO `purchases`
(`user_id`, `product_id`, `purchase_id`, `purchase_time`, `expiry_time`, `status`, `subscription_period`, `extra_data`, `name`)
VALUES
($用户ID, '$产品标识', '$产品唯一标识符', NOW(), DATE_ADD(NOW(), INTERVAL $产品周期 DAY), '$产品状态', $产品周期, '$储存数据', '$产品名称');";
//$definedVars = get_defined_vars();
//print_r($definedVars);
@数据库运行($语句);
终止并输出();

View File

@@ -0,0 +1,93 @@
<?php
require_once "../Hv4.Logged.php";
$产品标识 = @$_POST['product_id'];
$语句 = "SELECT * FROM products WHERE product_id = '$产品标识';";
$产品元数据 = @reset(@数据库运行($语句));
if (!$产品元数据) {
定义输出("code",100);
定义输出("msg","获取产品元数据失败");
终止并输出();
}
$产品模块 = $产品元数据["module"];
$产品周期 = $产品元数据["subscription_period"];
$模块路径 = "../ProductsModule/".$产品模块."/Main.php";
$产品名称 = $产品元数据["name"];
require_once $模块路径;
$产品唯一标识符 = @唯一字符串();
$价格 = $产品元数据["price"];
$货币 = $产品元数据["currency_type"];
$库存 = $产品元数据["stock"];
$限购 = $产品元数据["limit_per_user"];
$语句 = "SELECT * FROM purchases WHERE product_id = '$产品标识' AND user_id = $用户ID;";
$用户购买 = @数据库运行($语句);
print_r($用户购买);
if ($库存 <= 0) {
定义输出("code",100);
定义输出("msg","库存不足惹");
终止并输出();
}
if ($货币 == "score") {
$比较项 = $积分;
} else {
$比较项 = $余额;
}
$减后余额 = $比较项 - $价格;
if ($减后余额 < 0) {
定义输出("code",100);
定义输出("msg","余额不足惹");
终止并输出();
}
if ($货币 == "score") {
设置用户积分($减后余额);
} else {
设置用户余额($减后余额);
}
$结果 = @开通产品($产品元数据,$产品唯一标识符);
$储存数据 = @转JSON($结果["data"]);
if ($结果["code"] == 200) {
定义输出("code",$结果["code"]);
定义输出("msg","开通成功");
$产品状态 = "activated";
} else {
定义输出("code",$结果["code"]);
定义输出("msg","开通失败");
$产品状态 = "pending_activation";
}
$库存 = $库存 - 1;
$语句 = "UPDATE products
SET stock = $库存
WHERE product_id = '$产品标识';";
@数据库运行($语句);
$语句 = "INSERT INTO `purchases`
(`user_id`, `product_id`, `purchase_id`, `purchase_time`, `expiry_time`, `status`, `subscription_period`, `extra_data`, `name`)
VALUES
($用户ID, '$产品标识', '$产品唯一标识符', NOW(), DATE_ADD(NOW(), INTERVAL $产品周期 DAY), '$产品状态', $产品周期, '$储存数据', '$产品名称');";
//$definedVars = get_defined_vars();
//print_r($definedVars);
@数据库运行($语句);
终止并输出();

View File

@@ -0,0 +1,22 @@
FVE563ASY
QAN542WLC
KNV363EYM
AZL454TBN
UMF778BBF
XCR437DCQ
ATD274VBT
GRG432HXY
UNX238ALT
UJT689XHC
KWT876HWV
KUW648VDF
MAT899TQY
ULA589MBU
YUR377DRU
TEP894VRP
TTY527ZUE
VTT629AMQ
KQA857VAY
ZEZ853WFP
XZJ787EBL
LWC296XGX

17
Main/CheckIn/index.php Normal file
View File

@@ -0,0 +1,17 @@
<?php
include_once "../Hv4.Logged.php";
if (!$未签到) {
定义输出("msg","已经签到过啦");
定义输出("code",100);
终止并输出();
} else {
$获取积分 = mt_rand(80, 200);
$语句 = "UPDATE `users`
SET `last_sign_in_date` = CURRENT_DATE
WHERE `id` = $用户ID;";
@数据库运行($语句);
@设置用户积分($积分+$获取积分);
定义输出("msg","获得积分 ".$获取积分);
定义输出("code",200);
终止并输出();
}

View File

@@ -0,0 +1,17 @@
<?php
include_once "../Hv4.Logged.php";
if (!$未签到) {
定义输出("msg","已经签到过啦");
定义输出("code",100);
终止并输出();
} else {
$获取积分 = mt_rand(80, 200);
$语句 = "UPDATE `users`
SET `last_sign_in_date` = CURRENT_DATE
WHERE `id` = $用户ID;";
@数据库运行($语句);
@设置用户积分($积分+$获取积分);
定义输出("msg","获得积分 ".$获得积分);
定义输出("code",200);
终止并输出();
}

50
Main/GetGoods/index.php Normal file
View File

@@ -0,0 +1,50 @@
<?php
include_once "../Hv4.Function.php";
$语句 = "SELECT * FROM products WHERE status = 'visible';";
$商品元数据 = @数据库运行($语句);
// 原始数据
$data = $商品元数据;
// 用来存储分类结果的数组
$categories = [];
// 分类和整理数据
foreach ($data as $item) {
// 移除分类中的 [xxx] 数字部分
$category1 = preg_replace('/\[\d+\]$/', '', $item['category_1']);
$category2 = preg_replace('/\[\d+\]$/', '', $item['category_2']);
if ($item['currency_type'] == 'score') {
$item['currency_type'] = '积分';
} else {
$item['currency_type'] = '元';
}
// 分类1和分类2作为键来组织数据
if (!isset($categories[$category1])) {
$categories[$category1] = [];
}
// 确保分类2的存在并添加产品到分类2
if (!isset($categories[$category1][$category2])) {
$categories[$category1][$category2] = [];
}
// 将当前商品添加到相应的分类下
$categories[$category1][$category2][] = $item;
}
// 对每个分类内的数据进行排序
foreach ($categories as $category1 => &$category1Items) {
foreach ($category1Items as $category2 => &$category2Items) {
// 按照 sort_order 字段降序排序
usort($category2Items, function ($a, $b) {
return $b['sort_order'] - $a['sort_order'];
});
}
}
// 转换为 JSON 格式输出
echo 转JSON($categories);
?>

View File

@@ -0,0 +1,46 @@
<?php
include_once "../Hv4.Function.php";
$语句 = "SELECT * FROM products WHERE status = 'visible';";
$商品元数据 = @数据库运行($语句);
// 原始数据
$data = $商品元数据;
// 用来存储分类结果的数组
$categories = [];
// 分类和整理数据
foreach ($data as $item) {
// 移除分类中的 [xxx] 数字部分
$category1 = preg_replace('/\[\d+\]$/', '', $item['category_1']);
$category2 = preg_replace('/\[\d+\]$/', '', $item['category_2']);
// 分类1和分类2作为键来组织数据
if (!isset($categories[$category1])) {
$categories[$category1] = [];
}
// 确保分类2的存在并添加产品到分类2
if (!isset($categories[$category1][$category2])) {
$categories[$category1][$category2] = [];
}
// 将当前商品添加到相应的分类下
$categories[$category1][$category2][] = $item;
}
// 对每个分类内的数据进行排序
foreach ($categories as $category1 => &$category1Items) {
foreach ($category1Items as $category2 => &$category2Items) {
// 按照 sort_order 字段降序排序
usort($category2Items, function ($a, $b) {
return $b['sort_order'] - $a['sort_order'];
});
}
}
// 转换为 JSON 格式输出
echo 转JSON($categories);
?>

5
Main/GetInfo/index.php Normal file
View File

@@ -0,0 +1,5 @@
<?php
include_once "../Hv4.Logged.php";
定义输出("msg",$用户数据);
定义输出("code",200);
终止并输出();

View File

@@ -0,0 +1,5 @@
<?php
include_once "../Hv4.Logged.php";
定义输出("msg",$用户信息);
定义输出("code",200);
终止并输出();

View File

@@ -0,0 +1,33 @@
<?php
require_once "../Hv4.Logged.php";
// 获取数据
$语句 = "SELECT * FROM purchases WHERE user_id = $用户ID";
$产品元数据 = @数据库运行($语句);
if (!$产品元数据) {
定义输出("code",100);
定义输出("msg","没有产品数据咩");
终止并输出();
}
// 先获取当前时间,转换成时间戳
$current_time = time();
// 使用 usort 对数据按 expiry_time 排序,越远的排前面
usort($产品元数据, function($a, $b) use ($current_time) {
$expiry_a = strtotime($a['expiry_time']);
$expiry_b = strtotime($b['expiry_time']);
// 计算距离当前时间的差值
$diff_a = abs($expiry_a - $current_time);
$diff_b = abs($expiry_b - $current_time);
// 越远的排前面
return $diff_b - $diff_a;
});
定义输出("code",200);
定义输出("msg",$产品元数据);
终止并输出();
?>

View File

@@ -0,0 +1,26 @@
<?php
require_once "../Hv4.Logged.php";
// 获取数据
$语句 = "SELECT * FROM purchases WHERE user_id = $用户ID";
$产品元数据 = @数据库运行($语句);
// 先获取当前时间,转换成时间戳
$current_time = time();
// 使用 usort 对数据按 expiry_time 排序,越远的排前面
usort($产品元数据, function($a, $b) use ($current_time) {
$expiry_a = strtotime($a['expiry_time']);
$expiry_b = strtotime($b['expiry_time']);
// 计算距离当前时间的差值
$diff_a = abs($expiry_a - $current_time);
$diff_b = abs($expiry_b - $current_time);
// 越远的排前面
return $diff_b - $diff_a;
});
// 输出数据
print_r($产品元数据);
?>

234
Main/Hv4.Function.php Normal file
View File

@@ -0,0 +1,234 @@
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
session_start();
// 自动将 JSON 请求体转为 $_POST
if ($_SERVER['CONTENT_TYPE'] === 'application/json') {
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if ($data) {
$_POST = array_merge($_POST, $data);
}
}
//祖传适配CDN
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// 获取 'X-Forwarded-For' 中的第一个 IP 地址
$ipArray = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = trim($ipArray[0]); // 更新 REMOTE_ADDR
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
// 如果 'X-Forwarded-For' 不存在,则尝试使用 'HTTP_CLIENT_IP'
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CLIENT_IP'];
}
//祖传输出
$Out = "{}";
function 定义输出($key,$value) {
global $Out;
$Out = json_decode($Out, true);
$Out[$key] = $value;
$Out = json_encode($Out, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
function 终止并输出() {
global $Out;
die($Out);
}
//祖传数据库函数
function 数据库运行($sql) {
// 数据库连接参数
$servername = "110.40.52.75";
$username = "fuxstohostv4";
$password = "yxh20080130";
$dbname = "fuxstohostv4";
// 创建数据库连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检查连接是否成功
if ($conn->connect_error) {
return "连接失败: " . $conn->connect_error;
}
// 执行 SQL 查询
$result = $conn->query($sql);
// 查询失败,返回错误信息
if ($result === FALSE) {
$conn->close();
return "查询失败: " . $conn->error;
}
// 如果是 SELECT 查询,自动处理并返回结果
if (stripos($sql, 'SELECT') === 0) {
// 创建一个数组存储所有的查询结果
$data = [];
while ($row = $result->fetch_assoc()) {
$data[] = $row; // 将每一行的数据加入结果数组
}
$conn->close();
return $data; // 返回查询结果
}
// 对于非 SELECT 查询INSERT, UPDATE, DELETE直接返回 true
$conn->close();
return true;
}
// 生成随机字符串的函数
function 生成随机字符串($长度, $字符集, $字符集长度) {
$随机字符串 = '';
for ($i = 0; $i < $长度; $i++) {
$随机字符串 .= $字符集[rand(0, $字符集长度 - 1)];
}
return $随机字符串;
}
function 唯一随机字符串($长度) {
// 定义字符集
$字符集 = 'abcdefghijklmnopqrstuvwxyz0123456789';
$字符集长度 = strlen($字符集);
// 文件路径,用来存储已生成的字符串
$文件路径 = 'generated_strings.txt';
// 检查文件是否存在,如果不存在则创建
if (!file_exists($文件路径)) {
file_put_contents($文件路径, ''); // 创建一个空文件
}
// 生成唯一字符串
do {
$随机字符串 = 生成随机字符串($长度, $字符集, $字符集长度);
$已生成的字符串 = file($文件路径, FILE_IGNORE_NEW_LINES);
} while (in_array($随机字符串, $已生成的字符串));
// 将新生成的字符串保存到文件
file_put_contents($文件路径, $随机字符串 . PHP_EOL, FILE_APPEND);
return $随机字符串;
}
function JSON解析($json) {
return @json_decode($json,true);
}
function 转JSON($json) {
return @json_encode($json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
/**
* 生成高颜值不重复产品编号
* 特点:排除易混淆字符、智能查重、自动保存记录、美观格式化
*/
function 唯一字符串() {
// 配置参数(可自行调整)
$charSet = [
'letters' => 'ABCDEFGHJKLMNPQRSTUVWXYZ', // 24个大写字母排除I/O
'digits' => '23456789', // 8个数字排除0/1
];
$pattern = 'AAA-111-AAA'; // 定义编号格式3字母 + 3数字 + 3字母
$storageFile = 'product_codes.txt'; // 存储文件
do {
// 根据格式生成各部分
$codeParts = [];
foreach (explode('-', $pattern) as $segment) {
$type = preg_match('/^A+$/', $segment) ? 'letters' : 'digits';
$codeParts[] = generateSegment($charSet[$type], strlen($segment));
}
// 组合完整编码去掉分隔符后确保10位
$fullCode = str_replace('-', '', implode('', $codeParts));
// 检查是否已存在(使用内存加速查询)
$existingCodes = file_exists($storageFile)
? array_flip(file($storageFile, FILE_IGNORE_NEW_LINES))
: [];
} while (isset($existingCodes[$fullCode]));
// 保存新编码并返回格式化版本
file_put_contents($storageFile, $fullCode.PHP_EOL, FILE_APPEND);
return implode('-', $codeParts);
}
/**
* 生成指定长度的字符段
*/
function generateSegment($characters, $length) {
$segment = '';
$maxIndex = strlen($characters) - 1;
for ($i = 0; $i < $length; $i++) {
$segment .= $characters[random_int(0, $maxIndex)];
}
return $segment;
}
function 发送邮件接口($收件人, $主题, $内容, $接口地址 = 'https://hv3.fuxsto.cn/user/OpenEmailApi.php')
{
// 参数有效性验证
if (!filter_var($收件人, FILTER_VALIDATE_EMAIL)) {
return "收件人邮箱格式无效";
}
// 准备请求参数(自动编码处理)
$请求数据 = http_build_query([
'to' => $收件人,
'subject' => $主题,
'msg' => $内容
]);
// 初始化cURL
$ch = curl_init();
// 配置cURL选项
curl_setopt_array($ch, [
CURLOPT_URL => $接口地址,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true, // 验证SSL证书
CURLOPT_TIMEOUT => 15, // 15秒超时
CURLOPT_CONNECTTIMEOUT => 5, // 5秒连接超时
CURLOPT_POSTFIELDS => $请求数据,
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8'
]
]);
// 执行请求
$响应 = curl_exec($ch);
// 错误处理
if (curl_errno($ch)) {
$错误信息 = '网络请求失败: ' . curl_error($ch);
curl_close($ch);
return $错误信息;
}
// 获取HTTP状态码
$状态码 = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// 处理响应
if ($状态码 !== 200) {
return "接口响应异常 (HTTP {$状态码})";
}
// 验证响应内容
return ($响应 === '200') ? 200 : trim($响应);
}

179
Main/Hv4.Function.php.bak Normal file
View File

@@ -0,0 +1,179 @@
<?php
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST');
header('Access-Control-Allow-Headers: Content-Type');
session_start();
// 自动将 JSON 请求体转为 $_POST
if ($_SERVER['CONTENT_TYPE'] === 'application/json') {
$input = file_get_contents('php://input');
$data = json_decode($input, true);
if ($data) {
$_POST = array_merge($_POST, $data);
}
}
//祖传适配CDN
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
// 获取 'X-Forwarded-For' 中的第一个 IP 地址
$ipArray = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
$_SERVER['REMOTE_ADDR'] = trim($ipArray[0]); // 更新 REMOTE_ADDR
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
// 如果 'X-Forwarded-For' 不存在,则尝试使用 'HTTP_CLIENT_IP'
$_SERVER['REMOTE_ADDR'] = $_SERVER['HTTP_CLIENT_IP'];
}
//祖传输出
$Out = "{}";
function 定义输出($key,$value) {
global $Out;
$Out = json_decode($Out, true);
$Out[$key] = $value;
$Out = json_encode($Out, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
function 终止并输出() {
global $Out;
die($Out);
}
//祖传数据库函数
function 数据库运行($sql) {
// 数据库连接参数
$servername = "110.40.52.75";
$username = "fuxstohostv4";
$password = "yxh20080130";
$dbname = "fuxstohostv4";
// 创建数据库连接
$conn = new mysqli($servername, $username, $password, $dbname);
// 检查连接是否成功
if ($conn->connect_error) {
return "连接失败: " . $conn->connect_error;
}
// 执行 SQL 查询
$result = $conn->query($sql);
// 查询失败,返回错误信息
if ($result === FALSE) {
$conn->close();
return "查询失败: " . $conn->error;
}
// 如果是 SELECT 查询,自动处理并返回结果
if (stripos($sql, 'SELECT') === 0) {
// 创建一个数组存储所有的查询结果
$data = [];
while ($row = $result->fetch_assoc()) {
$data[] = $row; // 将每一行的数据加入结果数组
}
$conn->close();
return $data; // 返回查询结果
}
// 对于非 SELECT 查询INSERT, UPDATE, DELETE直接返回 true
$conn->close();
return true;
}
// 生成随机字符串的函数
function 生成随机字符串($长度, $字符集, $字符集长度) {
$随机字符串 = '';
for ($i = 0; $i < $长度; $i++) {
$随机字符串 .= $字符集[rand(0, $字符集长度 - 1)];
}
return $随机字符串;
}
function 唯一随机字符串($长度) {
// 定义字符集
$字符集 = 'abcdefghijklmnopqrstuvwxyz0123456789';
$字符集长度 = strlen($字符集);
// 文件路径,用来存储已生成的字符串
$文件路径 = 'generated_strings.txt';
// 检查文件是否存在,如果不存在则创建
if (!file_exists($文件路径)) {
file_put_contents($文件路径, ''); // 创建一个空文件
}
// 生成唯一字符串
do {
$随机字符串 = 生成随机字符串($长度, $字符集, $字符集长度);
$已生成的字符串 = file($文件路径, FILE_IGNORE_NEW_LINES);
} while (in_array($随机字符串, $已生成的字符串));
// 将新生成的字符串保存到文件
file_put_contents($文件路径, $随机字符串 . PHP_EOL, FILE_APPEND);
return $随机字符串;
}
function JSON解析($json) {
return @json_decode($json,true);
}
function 转JSON($json) {
return @json_encode($json, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
}
/**
* 生成高颜值不重复产品编号
* 特点:排除易混淆字符、智能查重、自动保存记录、美观格式化
*/
function 唯一字符串() {
// 配置参数(可自行调整)
$charSet = [
'letters' => 'ABCDEFGHJKLMNPQRSTUVWXYZ', // 24个大写字母排除I/O
'digits' => '23456789', // 8个数字排除0/1
];
$pattern = 'AAA-111-AAA'; // 定义编号格式3字母 + 3数字 + 3字母
$storageFile = 'product_codes.txt'; // 存储文件
do {
// 根据格式生成各部分
$codeParts = [];
foreach (explode('-', $pattern) as $segment) {
$type = preg_match('/^A+$/', $segment) ? 'letters' : 'digits';
$codeParts[] = generateSegment($charSet[$type], strlen($segment));
}
// 组合完整编码去掉分隔符后确保10位
$fullCode = str_replace('-', '', implode('', $codeParts));
// 检查是否已存在(使用内存加速查询)
$existingCodes = file_exists($storageFile)
? array_flip(file($storageFile, FILE_IGNORE_NEW_LINES))
: [];
} while (isset($existingCodes[$fullCode]));
// 保存新编码并返回格式化版本
file_put_contents($storageFile, $fullCode.PHP_EOL, FILE_APPEND);
return implode('-', $codeParts);
}
/**
* 生成指定长度的字符段
*/
function generateSegment($characters, $length) {
$segment = '';
$maxIndex = strlen($characters) - 1;
for ($i = 0; $i < $length; $i++) {
$segment .= $characters[random_int(0, $maxIndex)];
}
return $segment;
}

64
Main/Hv4.Logged.php Normal file
View File

@@ -0,0 +1,64 @@
<?php
require_once($_SERVER['DOCUMENT_ROOT'] . '/Main/Hv4.Function.php');
if (!$_SESSION['username']) {
定义输出('msg', '未登录');
定义输出('code', 100);
终止并输出();
}
$用户名 = $_SESSION['username'];
$语句 = "SELECT * FROM users WHERE username = '$用户名';";
$用户数据 = @数据库运行($语句);
$用户数据 = @reset($用户数据);
if (!$用户数据["id"]) {
定义输出('msg', '数据错误');
定义输出('code', 100);
终止并输出();
}
$积分 = $用户数据["score"];
$余额 = $用户数据["balance"];
$用户ID = $用户数据["id"];
$语句 = "SELECT *
FROM `users`
WHERE `id` = $用户ID
AND `last_sign_in_date` < CURRENT_DATE;";
if (@数据库运行($语句)) {
$未签到 = true;
} else {
$未签到 = false;
}
$用户数据["can_check"] = $未签到;
function 设置用户积分($a) {
global $用户名;
$语句 = "UPDATE users
SET score = $a
WHERE username = '$用户名';";
return @数据库运行($语句);
}
function 设置用户余额($a) {
global $用户名;
$语句 = "UPDATE users
SET balance = $a
WHERE username = '$用户名';";
return @数据库运行($语句);
}

63
Main/Hv4.Logged.php.bak Normal file
View File

@@ -0,0 +1,63 @@
<?php
require_once($_SERVER['DOCUMENT_ROOT'] . '/Main/Hv4.Function.php');
if (!$_SESSION['username']) {
定义输出('msg', '未登录');
定义输出('code', 100);
终止并输出();
}
$用户名 = $_SESSION['username'];
$语句 = "SELECT * FROM users WHERE username = '$用户名';";
$用户数据 = @数据库运行($语句);
$用户数据 = @reset($用户数据);
if (!$用户数据["id"]) {
定义输出('msg', '数据错误');
定义输出('code', 100);
终止并输出();
}
$积分 = $用户数据["score"];
$余额 = $用户数据["balance"];
$用户ID = $用户数据["id"];
$语句 = "SELECT *
FROM `users`
WHERE `id` = $用户ID
AND `last_sign_in_date` < CURRENT_DATE;";
if (@数据库运行($语句)) {
$未签到 = true;
} else {
$未签到 = false;
}
function 设置用户积分($a) {
global $用户名;
$语句 = "UPDATE users
SET score = $a
WHERE username = '$用户名';";
return @数据库运行($语句);
}
function 设置用户余额($a) {
global $用户名;
$语句 = "UPDATE users
SET balance = $a
WHERE username = '$用户名';";
return @数据库运行($语句);
}

31
Main/Login/CallBack.php Normal file
View File

@@ -0,0 +1,31 @@
<?php
include_once "../Hv4.Function.php";
// 设置目标 URL
$链接 = "https://auth.fuxsto.cn/Main/LoginApp/?act=CallBack&task=".$_GET["task"];
$数据 = JSON解析(file_get_contents($链接));
if ($数据["code"] == 200) {
$数据 = $数据["msg"];
$QQ = $数据["qq"];
$密码 = @唯一字符串();
$用户名 = $数据["username"];
$语句 = "SELECT `id`, `username`, `qq`, `score`, `balance`, `status`
FROM `users`
WHERE `username` = '$用户名';";
$结果 = reset(数据库运行($语句));
if (!$结果) {
$语句 = "INSERT INTO `users` (`username`, `password`, `qq`, `score`, `balance`, `status`, `last_sign_in_date`)
VALUES ('$用户名', '$密码', '$QQ', 100, 0.00, 'active', CURRENT_DATE);";
if (!@数据库运行($语句)) {
die("Error:系统错误");
die("<script>window.location.href = '/';</script>");
} else {
$_SESSION["username"] = $用户名;
die("<script>window.location.href = '/Dashboard';</script>");
}
} else {
$_SESSION["username"] = $用户名;
die("<script>window.location.href = '/Dashboard';</script>");
}
} else {
die("<script>window.location.href = '/';</script>");
}

View File

@@ -0,0 +1,31 @@
<?php
include_once "../Hv4.Function.php";
// 设置目标 URL
$链接 = "https://auth.fuxsto.cn/Main/LoginApp/?act=CallBack&task=".$_GET["task"];
$数据 = JSON解析(file_get_contents($链接));
if ($数据["code"] == 200) {
$数据 = $数据["msg"];
$QQ = $数据["qq"];
$密码 = @唯一字符串();
$用户名 = $数据["username"];
$语句 = "SELECT `id`, `username`, `qq`, `score`, `balance`, `status`
FROM `users`
WHERE `username` = '$用户名';";
$结果 = reset(数据库运行($语句));
if (!$结果) {
$语句 = "INSERT INTO `users` (`username`, `password`, `qq`, `score`, `balance`, `status`, `last_sign_in_date`)
VALUES ('$用户名', '$密码', '$QQ', 100, 0.00, 'active', CURRENT_DATE);";
if (!@数据库运行($语句)) {
die("Error:系统错误");
die("<script>window.location.href = '/';</script>");
} else {
$_SESSION["username"] = $用户名;
die("<script>window.location.href = '/';</script>");
}
} else {
$_SESSION["username"] = $用户名;
die("<script>window.location.href = '/';</script>");
}
} else {
die("<script>window.location.href = '/';</script>");
}

53
Main/Login/index.php Normal file
View File

@@ -0,0 +1,53 @@
<?php
include_once "../Hv4.Function.php";
// 设置目标 URL
$url = "https://auth.fuxsto.cn/Main/LoginApp/?act=NewTask"; // 替换为你的目标 URL
$AppName = "Fuxsto Host V5";
$AppLogo = "https://hv4.fuxsto.cn/favicon.ico";
$AppInfo = "未注册的账号会自动注册!请提前注册Auth账号!";
$AppUrl = "https://hv4.fuxsto.cn";
$AppCallBackUrl = "https://hv4.fuxsto.cn/Main/Login/CallBack.php";
$AppField = array("qq","id","username","password","register_time","register_ip");
$AppField = json_encode($AppField);
$headers = [
'TASK-APP-NAME: ' . $AppName,
'TASK-APP-LOGO: ' . $AppLogo,
'TASK-APP-INFO: ' . $AppInfo,
'TASK-APP-URL: ' . $AppUrl,
'TASK-APP-FIELD: ' . $AppField,
'TASK-APP-CALLBACKURL: ' . $AppCallBackUrl,
'TASK-APP-KEY: ' . "FuxstoHostV3-1144568790543508946461",
];
// 创建请求的上下文
$options = [
'http' => [
'method' => 'POST', // 使用 POST 请求
'header' => implode("\r\n", $headers), // 设置请求头
'ignore_errors' => true, // 即使请求失败,也返回响应内容
],
'ssl' => [
'verify_peer' => false, // 禁用 SSL 验证 (如果目标地址使用自签名证书,可以考虑启用)
'verify_peer_name' => false,
],
];
// 创建上下文
$context = stream_context_create($options);
// 发起请求并获取响应
$response = file_get_contents($url, false, $context);
$Task = json_decode($response,true)["msg"];
?>
<script>
window.location.href = 'https://auth.fuxsto.cn/Main/LoginApp/?act=ViewTask&task=<?= $Task ?>';
</script>

53
Main/Login/index.php.bak Normal file
View File

@@ -0,0 +1,53 @@
<?php
include_once "../Hv4.Function.php";
// 设置目标 URL
$url = "https://auth.fuxsto.cn/Main/LoginApp/?act=NewTask"; // 替换为你的目标 URL
$AppName = "Fuxsto Host V4";
$AppLogo = "https://hv4.fuxsto.cn/favicon.ico";
$AppInfo = "未注册的账号会自动注册!请提前注册Auth账号!";
$AppUrl = "https://hv4.fuxsto.cn";
$AppCallBackUrl = "https://hv4.fuxsto.cn/Main/Login/CallBack.php";
$AppField = array("qq","id","username","password","register_time","register_ip");
$AppField = json_encode($AppField);
$headers = [
'TASK-APP-NAME: ' . $AppName,
'TASK-APP-LOGO: ' . $AppLogo,
'TASK-APP-INFO: ' . $AppInfo,
'TASK-APP-URL: ' . $AppUrl,
'TASK-APP-FIELD: ' . $AppField,
'TASK-APP-CALLBACKURL: ' . $AppCallBackUrl,
'TASK-APP-KEY: ' . "FuxstoHostV3-1144568790543508946461",
];
// 创建请求的上下文
$options = [
'http' => [
'method' => 'POST', // 使用 POST 请求
'header' => implode("\r\n", $headers), // 设置请求头
'ignore_errors' => true, // 即使请求失败,也返回响应内容
],
'ssl' => [
'verify_peer' => false, // 禁用 SSL 验证 (如果目标地址使用自签名证书,可以考虑启用)
'verify_peer_name' => false,
],
];
// 创建上下文
$context = stream_context_create($options);
// 发起请求并获取响应
$response = file_get_contents($url, false, $context);
$Task = json_decode($response,true)["msg"];
?>
<script>
window.location.href = 'https://auth.fuxsto.cn/Main/LoginApp/?act=ViewTask&task=<?= $Task ?>';
</script>

View File

@@ -0,0 +1,30 @@
GZZ242HHB
RHW483HGU
GUF299UVB
HSS245YXC
AUQ924HZF
RSN975RCB
XMS622TNH
PAQ832MFQ
VNY422EDJ
ZSY355CBW
TQL298LRK
LLL653JNQ
UHL926WAR
LTR252ECM
LMP863RDB
JTZ287MGC
YNC968LSP
AWL859EJQ
XZJ755RAJ
YKD357UAN
DFB956HBN
UGZ298BEN
EFV762GLD
NVE522XGG
SCU359CGD
FEE855MLH
ZVY632QKL
UQS923YDT
KYZ269EFJ
DJP294LAN

View File

@@ -0,0 +1,120 @@
<?php
function kanglehost_CreateSign($a, $r)
{
return md5($a . "hsxKjJeampw7AJtw" . $r);
}
function kanglehost_GetUrl($info, $skey, $r)
{
$url = "";
foreach ($info as $k => $v) {
$url .= $k . "=" . $v . "&";
}
return "http://38.55.233.203:3312/api/index.php?" . $url . "r=" . $r . "&s=" . $skey . "&json=1";
}
function 展示产品($业务元数据,$产品元数据) {
$Page = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/Main/ProductsModule/HK-FREE-EP/s.html');
$Page = @str_replace("<业务元数据>", 转JSON($业务元数据), $Page);
$Page = @str_replace("<产品元数据>", 转JSON($产品元数据), $Page);
$Page = @str_replace("<登录元数据>", 转JSON($业务元数据["extra_data"]), $Page);
return $Page;
}
function 开通产品($产品元数据,$产品唯一标识符) {
$a = "add_vh";
$r = rand(100000, 999999);
$user = 唯一随机字符串(10); // 随机生成用户名
$pass = 唯一随机字符串(15); // 随机生成密码
$currentDate = date('Y-m-d'); // 获取当前日期
$futureDate = date('Y-m-d', strtotime($currentDate . ' +30 days')); // 计算30天后的日期
$info = [
"c" => "whm",
"a" => $a,
"init" => 1,
"name" => $user,
"passwd" => $pass,
"product_id" => $产品元数据["extra_info"]
];
$skey = kanglehost_CreateSign($a, $r); // 修正函数名称大小写
$url = kanglehost_GetUrl($info, $skey, $r); // 修正函数名称大小写
$re = @file_get_contents($url);
$re = json_decode($re, true);
if (!isset($re['result'])) {
$code = 100; // 错误处理如果result不存在设为100
} else {
$code = $re['result'];
}
$储存数据 = [];
$储存数据["username"] = $user;
$储存数据["password"] = $pass;
$data["data"] = $储存数据;
if ($code == 200) {
$data['msg'] = $re;
$data['code'] = 200;
} else {
$data['msg'] = $re;
$data['code'] = 100;
}
return $data;
}
function show_product($data) {
$templatePath = './mods/us_m/index.html'; // 模板路径
$variables = $data;
return h_t($templatePath, $variables);
}
function long_product($data) {
$date = new DateTime($data['dqtime']);
$date->modify('+' . $data['Today'] . ' days'); // 假设'Today'是$data数组中的一个键
$data['dqtime'] = $date->format('Y-m-d');
return $data;
}
function 删除业务($业务元数据,$产品元数据) {
$username = @JSON解析($业务元数据["extra_data"])["username"];
$a = "del_vh";
$r = rand(100000, 999999);
$info = ["c" => "whm", "a" => $a, "name" => $username];
$skey = kanglehost_CreateSign($a, $r); // 修正函数名称大小写
$url = kanglehost_GetUrl($info, $skey, $r); // 修正函数名称大小写
$re = @file_get_contents($url);
$data['msg'] = $re;
$re = json_decode($re, true);
$data['code'] = $re["result"];
return $data;
}
function ready_products($data) {
$templatePath = './mods/us_m/ready.html'; // 模板路径
$variables = $data;
$variables["id"] = $_GET["id"];
return h_t($templatePath, $variables);
}

View File

@@ -0,0 +1,120 @@
<?php
function kanglehost_CreateSign($a, $r)
{
return md5($a . "hsxKjJeampw7AJtw" . $r);
}
function kanglehost_GetUrl($info, $skey, $r)
{
$url = "";
foreach ($info as $k => $v) {
$url .= $k . "=" . $v . "&";
}
return "http://38.55.233.203:3312/api/index.php?" . $url . "r=" . $r . "&s=" . $skey . "&json=1";
}
function 展示产品($业务元数据,$产品元数据) {
$Page = file_get_contents($_SERVER['DOCUMENT_ROOT'] . '/Main/ProductsModule/HK-FREE-EP/s.html');
$Page = @str_replace("<业务元数据>", 转JSON($业务元数据), $Page);
$Page = @str_replace("<产品元数据>", 转JSON($产品元数据), $Page);
$Page = @str_replace("<登录元数据>", 转JSON($业务元数据["extra_data"]), $Page);
return $Page;
}
function 开通产品($产品元数据,$产品唯一标识符) {
$a = "add_vh";
$r = rand(100000, 999999);
$user = 唯一随机字符串(10); // 随机生成用户名
$pass = 唯一随机字符串(15); // 随机生成密码
$currentDate = date('Y-m-d'); // 获取当前日期
$futureDate = date('Y-m-d', strtotime($currentDate . ' +30 days')); // 计算30天后的日期
$info = [
"c" => "whm",
"a" => $a,
"init" => 1,
"name" => $user,
"passwd" => $pass,
"product_id" => $产品元数据["extra_info"]
];
$skey = kanglehost_CreateSign($a, $r); // 修正函数名称大小写
$url = kanglehost_GetUrl($info, $skey, $r); // 修正函数名称大小写
$re = @file_get_contents($url);
$re = json_decode($re, true);
if (!isset($re['result'])) {
$code = 100; // 错误处理如果result不存在设为100
} else {
$code = $re['result'];
}
$储存数据 = [];
$储存数据["username"] = $user;
$储存数据["password"] = $pass;
$data["data"] = $储存数据;
if ($code == 200) {
$data['msg'] = $re;
$data['code'] = 200;
} else {
$data['msg'] = $re;
$data['code'] = 100;
}
return $data;
}
function show_product($data) {
$templatePath = './mods/us_m/index.html'; // 模板路径
$variables = $data;
return h_t($templatePath, $variables);
}
function long_product($data) {
$date = new DateTime($data['dqtime']);
$date->modify('+' . $data['Today'] . ' days'); // 假设'Today'是$data数组中的一个键
$data['dqtime'] = $date->format('Y-m-d');
return $data;
}
function 删除业务($业务元数据,$产品元数据) {
$data['status'] = '已到期';
$a = "del_vh";
$r = rand(100000, 999999);
$info = ["c" => "whm", "a" => $a, "name" => $data['username']];
$skey = kanglehost_CreateSign($a, $r); // 修正函数名称大小写
$url = kanglehost_GetUrl($info, $skey, $r); // 修正函数名称大小写
$re = @file_get_contents($url);
$data['msg'] = $re;
$re = json_decode($re, true);
$data['code'] = $re["result"];
return $data;
}
function ready_products($data) {
$templatePath = './mods/us_m/ready.html'; // 模板路径
$variables = $data;
$variables["id"] = $_GET["id"];
return h_t($templatePath, $variables);
}

View File

@@ -0,0 +1,374 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>虚拟主机详情 - Fuxsto Host V4</title>
<script src="https://cdn.fss.fuxsto.cn/d/vue@3/dist/vue.global.js"></script>
<style>
:root {
--primary: #2A5EE5;
--secondary: #00C9B8;
--dark: #1A1F36;
--light: #F8F9FE;
}
button {
background: none; /* 去除背景色 */
border: none; /* 去除边框 */
padding: 0; /* 去除内边距 */
font: inherit; /* 继承父元素字体 */
color: inherit; /* 继承父元素字体颜色 */
cursor: pointer; /* 保持鼠标指针样式 */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Segoe UI', system-ui, sans-serif;
}
body {
color: var(--dark);
line-height: 1.6;
overflow-x: hidden;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
.header {
text-align: center;
padding: 3rem 0;
background: linear-gradient(135deg, var(--primary), #1A3D8C);
color: white;
border-radius: 0 0 2rem 2rem;
margin-bottom: 2rem;
animation: slideDown 0.8s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
opacity: 0;
}
.status-badge {
background: #2ECC71;
color: white;
padding: 0.5rem 1.5rem;
border-radius: 2rem;
display: inline-block;
font-weight: bold;
text-transform: uppercase;
font-size: 0.9rem;
letter-spacing: 1px;
animation: scaleIn 0.6s 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
opacity: 0;
}
.metrics-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.metric-card {
background: white;
padding: 2rem;
border-radius: 1rem;
box-shadow: 0 10px 20px rgba(0,0,0,0.05);
transition: transform 0.3s, box-shadow 0.3s;
opacity: 0;
animation: fadeInUp 0.6s cubic-bezier(0.23, 1, 0.32, 1) forwards;
}
.metric-card:nth-child(1) { animation-delay: 0.4s; }
.metric-card:nth-child(2) { animation-delay: 0.6s; }
.metric-card:nth-child(3) { animation-delay: 0.8s; }
.metric-card:hover {
transform: translateY(-8px);
box-shadow: 0 15px 30px rgba(0,0,0,0.1);
}
.metric-value {
font-size: 2.5rem;
font-weight: 800;
color: var(--primary);
margin: 1rem 0;
transition: color 0.3s;
}
.detail-section {
background: white;
border-radius: 1rem;
padding: 2rem;
margin: 2rem 0;
box-shadow: 0 10px 20px rgba(0,0,0,0.05);
opacity: 0;
animation: fadeInUp 0.6s 1s cubic-bezier(0.23, 1, 0.32, 1) forwards;
}
.grid-2col {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.detail-item {
padding: 1rem 0;
border-bottom: 1px solid #EEE;
display: flex;
justify-content: space-between;
align-items: center;
transition: transform 0.3s;
}
.detail-item:hover {
transform: translateX(10px);
}
.tag {
background: #FFD70020;
color: #FFA500;
padding: 0.3rem 1rem;
border-radius: 0.5rem;
font-size: 0.9rem;
transition: all 0.3s;
}
.tag:hover {
transform: scale(1.05);
box-shadow: 0 4px 12px rgba(255, 165, 0, 0.2);
}
.icon {
width: 24px;
height: 24px;
margin-right: 1rem;
color: var(--primary);
transition: transform 0.3s;
}
.metric-card:hover .icon {
transform: rotate(15deg) scale(1.1);
}
@media (max-width: 768px) {
.container {
padding: 1rem;
}
.metric-value {
font-size: 2rem;
}
}
</style>
</head>
<body id="app">
<div class="header">
<div class="container">
<h1>{{a.name}}</h1>
<p class="status-badge">{{a.status}}</p>
</div>
</div>
<div class="container">
<div class="metrics-grid">
<div class="metric-card">
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
</svg>
<div class="metric-value">4 vCPU</div>
<div class="metric-label">计算核心</div>
</div>
<div class="metric-card">
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>
</svg>
<div class="metric-value">4 GB</div>
<div class="metric-label">内存容量</div>
</div>
<div class="metric-card">
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M12 2v20M2 12h20"/>
</svg>
<div class="metric-value">7 M</div>
<div class="metric-label">带宽</div>
</div>
</div>
<div class="detail-section">
<h2>主机详情</h2>
<div class="grid-2col">
<div>
<div class="detail-item">
<span>主机区域</span>
<span class="tag">香港🇭🇰</span>
</div>
<div class="detail-item">
<span>业务ID</span>
<span>{{a.purchase_id}}</span>
</div>
<div class="detail-item">
<span>控制面板</span>
<span>Kangle EasyPanel</span>
</div>
</div>
<div>
<div class="detail-item">
<span>创建时间</span>
<span>{{a.purchase_time}}</span>
</div>
<div class="detail-item">
<span>到期时间</span>
<span>{{a.expiry_time}}</span>
</div>
<div class="detail-item">
<span>网络类型</span>
<span class="tag">CN2 Max</span>
</div>
</div>
</div>
</div>
<div class="detail-section">
<h2>账号配置</h2>
<div class="detail-item">
<span>登陆地址</span>
<span>38.55.233.203:3312</span>
</div>
<div class="detail-item">
<span>登陆账号</span>
<span class="tag">{{ username }}</span>
</div>
<div class="detail-item">
<span>登陆密码</span>
<span class="tag">{{ password }}</span>
</div>
<div class="detail-item">
<span>一键登陆</span>
<span><form normal action="http://38.55.233.203:3312/vhost/index.php?c=session&a=login" method="post" target="_blank">
<input type="hidden" name="username" :value="username" />
<input type="hidden" name="passwd" :value="password" />
<button type="submit" class="tag">登录面板</button>
</form></span>
</div>
</div>
</div>
</body>
<script>
const { createApp } = Vue;
// 自定义主题
const customTheme = {
"--hsl-primary": "212, 100%, 38%",
"--color-primary": "hsla(var(--hsl-primary), 1)",
"--hsl-on-primary": "0, 0%, 100%",
"--color-on-primary": "hsla(var(--hsl-on-primary), 1)",
"--hsl-primary-container": "225, 100%, 92%",
"--color-primary-container": "hsla(var(--hsl-primary-container), 1)",
"--hsl-on-primary-container": "216, 100%, 13%",
"--color-on-primary-container": "hsla(var(--hsl-on-primary-container), 1)",
"--hsl-info": "224, 13%, 39%",
"--color-info": "hsla(var(--hsl-info), 1)",
"--hsl-on-info": "0, 0%, 100%",
"--color-on-info": "hsla(var(--hsl-on-info), 1)",
"--hsl-info-container": "226, 71%, 92%",
"--color-info-container": "hsla(var(--hsl-info-container), 1)",
"--hsl-on-info-container": "223, 38%, 13%",
"--color-on-info-container": "hsla(var(--hsl-on-info-container), 1)",
"--hsl-warning": "296, 15%, 39%",
"--color-warning": "hsla(var(--hsl-warning), 1)",
"--hsl-on-warning": "0, 0%, 100%",
"--color-on-warning": "hsla(var(--hsl-on-warning), 1)",
"--hsl-warning-container": "298, 86%, 92%",
"--color-warning-container": "hsla(var(--hsl-warning-container), 1)",
"--hsl-on-warning-container": "291, 41%, 13%",
"--color-on-warning-container": "hsla(var(--hsl-on-warning-container), 1)",
"--hsl-danger": "0, 75%, 42%",
"--color-danger": "hsla(var(--hsl-danger), 1)",
"--hsl-on-danger": "0, 0%, 100%",
"--color-on-danger": "hsla(var(--hsl-on-danger), 1)",
"--hsl-danger-container": "6, 100%, 92%",
"--color-danger-container": "hsla(var(--hsl-danger-container), 1)",
"--hsl-on-danger-container": "358, 100%, 13%",
"--color-on-danger-container": "hsla(var(--hsl-on-danger-container), 1)",
"--hsl-body": "285, 100%, 99%",
"--color-body": "hsla(var(--hsl-body), 1)",
"--hsl-text": "240, 7%, 11%",
"--color-text": "hsla(var(--hsl-text), 1)",
"--hsl-on-surface-variant": "224, 7%, 29%",
"--color-on-surface-variant": "hsla(var(--hsl-on-surface-variant), 1)",
"--hsl-outline": "228, 4%, 48%",
"--color-outline": "hsla(var(--hsl-outline), 1)",
"--hsl-inverse-surface": "240, 3%, 19%",
"--color-inverse-surface": "hsla(var(--hsl-inverse-surface), 1)"
};
// 创建 Vue 应用
const app = createApp({
data() {
return {
a: <业务元数据>,
b: <产品元数据>,
aw: <登录元数据>,
username: null,
password: null
};
},
mounted() {
this.aw = Object.fromEntries(Object.entries(JSON.parse(this.aw)));
this.username = this.aw.username;
this.password = this.aw.password;
},
watch: {
},
methods: {
}
});
app.mount('#app');
</script>
</html>

View File

@@ -0,0 +1,375 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>虚拟主机详情 - Fuxsto Host V4</title>
<script src="https://cdn.fss.fuxsto.cn/d/vue@3/dist/vue.global.js"></script>
<style>
:root {
--primary: #2A5EE5;
--secondary: #00C9B8;
--dark: #1A1F36;
--light: #F8F9FE;
}
button {
background: none; /* 去除背景色 */
border: none; /* 去除边框 */
padding: 0; /* 去除内边距 */
font: inherit; /* 继承父元素字体 */
color: inherit; /* 继承父元素字体颜色 */
cursor: pointer; /* 保持鼠标指针样式 */
}
* {
box-sizing: border-box;
margin: 0;
padding: 0;
font-family: 'Segoe UI', system-ui, sans-serif;
}
body {
background: var(--light);
color: var(--dark);
line-height: 1.6;
overflow-x: hidden;
}
@keyframes slideDown {
from {
opacity: 0;
transform: translateY(-20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes fadeInUp {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@keyframes scaleIn {
from {
opacity: 0;
transform: scale(0.95);
}
to {
opacity: 1;
transform: scale(1);
}
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
.header {
text-align: center;
padding: 3rem 0;
background: linear-gradient(135deg, var(--primary), #1A3D8C);
color: white;
border-radius: 0 0 2rem 2rem;
margin-bottom: 2rem;
animation: slideDown 0.8s cubic-bezier(0.22, 0.61, 0.36, 1) forwards;
opacity: 0;
}
.status-badge {
background: #2ECC71;
color: white;
padding: 0.5rem 1.5rem;
border-radius: 2rem;
display: inline-block;
font-weight: bold;
text-transform: uppercase;
font-size: 0.9rem;
letter-spacing: 1px;
animation: scaleIn 0.6s 0.3s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
opacity: 0;
}
.metrics-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1.5rem;
margin: 2rem 0;
}
.metric-card {
background: white;
padding: 2rem;
border-radius: 1rem;
box-shadow: 0 10px 20px rgba(0,0,0,0.05);
transition: transform 0.3s, box-shadow 0.3s;
opacity: 0;
animation: fadeInUp 0.6s cubic-bezier(0.23, 1, 0.32, 1) forwards;
}
.metric-card:nth-child(1) { animation-delay: 0.4s; }
.metric-card:nth-child(2) { animation-delay: 0.6s; }
.metric-card:nth-child(3) { animation-delay: 0.8s; }
.metric-card:hover {
transform: translateY(-8px);
box-shadow: 0 15px 30px rgba(0,0,0,0.1);
}
.metric-value {
font-size: 2.5rem;
font-weight: 800;
color: var(--primary);
margin: 1rem 0;
transition: color 0.3s;
}
.detail-section {
background: white;
border-radius: 1rem;
padding: 2rem;
margin: 2rem 0;
box-shadow: 0 10px 20px rgba(0,0,0,0.05);
opacity: 0;
animation: fadeInUp 0.6s 1s cubic-bezier(0.23, 1, 0.32, 1) forwards;
}
.grid-2col {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 2rem;
}
.detail-item {
padding: 1rem 0;
border-bottom: 1px solid #EEE;
display: flex;
justify-content: space-between;
align-items: center;
transition: transform 0.3s;
}
.detail-item:hover {
transform: translateX(10px);
}
.tag {
background: #FFD70020;
color: #FFA500;
padding: 0.3rem 1rem;
border-radius: 0.5rem;
font-size: 0.9rem;
transition: all 0.3s;
}
.tag:hover {
transform: scale(1.05);
box-shadow: 0 4px 12px rgba(255, 165, 0, 0.2);
}
.icon {
width: 24px;
height: 24px;
margin-right: 1rem;
color: var(--primary);
transition: transform 0.3s;
}
.metric-card:hover .icon {
transform: rotate(15deg) scale(1.1);
}
@media (max-width: 768px) {
.container {
padding: 1rem;
}
.metric-value {
font-size: 2rem;
}
}
</style>
</head>
<body id="app">
<div class="header">
<div class="container">
<h1>{{a.name}}</h1>
<p class="status-badge">{{a.status}}</p>
</div>
</div>
<div class="container">
<div class="metrics-grid">
<div class="metric-card">
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"/>
</svg>
<div class="metric-value">4 vCPU</div>
<div class="metric-label">计算核心</div>
</div>
<div class="metric-card">
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M22 12h-4l-3 9L9 3l-3 9H2"/>
</svg>
<div class="metric-value">4 GB</div>
<div class="metric-label">内存容量</div>
</div>
<div class="metric-card">
<svg class="icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
<path d="M12 2v20M2 12h20"/>
</svg>
<div class="metric-value">7 M</div>
<div class="metric-label">带宽</div>
</div>
</div>
<div class="detail-section">
<h2>主机详情</h2>
<div class="grid-2col">
<div>
<div class="detail-item">
<span>主机区域</span>
<span class="tag">香港🇭🇰</span>
</div>
<div class="detail-item">
<span>业务ID</span>
<span>{{a.purchase_id}}</span>
</div>
<div class="detail-item">
<span>控制面板</span>
<span>Kangle EasyPanel</span>
</div>
</div>
<div>
<div class="detail-item">
<span>创建时间</span>
<span>{{a.purchase_time}}</span>
</div>
<div class="detail-item">
<span>到期时间</span>
<span>{{a.expiry_time}}</span>
</div>
<div class="detail-item">
<span>网络类型</span>
<span class="tag">CN2 Max</span>
</div>
</div>
</div>
</div>
<div class="detail-section">
<h2>账号配置</h2>
<div class="detail-item">
<span>登陆地址</span>
<span>38.55.233.203:3312</span>
</div>
<div class="detail-item">
<span>登陆账号</span>
<span class="tag">{{ username }}</span>
</div>
<div class="detail-item">
<span>登陆密码</span>
<span class="tag">{{ password }}</span>
</div>
<div class="detail-item">
<span>一键登陆</span>
<span><form normal action="http://38.55.233.203:3312/vhost/index.php?c=session&a=login" method="post" target="_blank">
<input type="hidden" name="username" :value="username" />
<input type="hidden" name="passwd" :value="password" />
<button type="submit" class="tag">登录面板</button>
</form></span>
</div>
</div>
</div>
</body>
<script>
const { createApp } = Vue;
// 自定义主题
const customTheme = {
"--hsl-primary": "212, 100%, 38%",
"--color-primary": "hsla(var(--hsl-primary), 1)",
"--hsl-on-primary": "0, 0%, 100%",
"--color-on-primary": "hsla(var(--hsl-on-primary), 1)",
"--hsl-primary-container": "225, 100%, 92%",
"--color-primary-container": "hsla(var(--hsl-primary-container), 1)",
"--hsl-on-primary-container": "216, 100%, 13%",
"--color-on-primary-container": "hsla(var(--hsl-on-primary-container), 1)",
"--hsl-info": "224, 13%, 39%",
"--color-info": "hsla(var(--hsl-info), 1)",
"--hsl-on-info": "0, 0%, 100%",
"--color-on-info": "hsla(var(--hsl-on-info), 1)",
"--hsl-info-container": "226, 71%, 92%",
"--color-info-container": "hsla(var(--hsl-info-container), 1)",
"--hsl-on-info-container": "223, 38%, 13%",
"--color-on-info-container": "hsla(var(--hsl-on-info-container), 1)",
"--hsl-warning": "296, 15%, 39%",
"--color-warning": "hsla(var(--hsl-warning), 1)",
"--hsl-on-warning": "0, 0%, 100%",
"--color-on-warning": "hsla(var(--hsl-on-warning), 1)",
"--hsl-warning-container": "298, 86%, 92%",
"--color-warning-container": "hsla(var(--hsl-warning-container), 1)",
"--hsl-on-warning-container": "291, 41%, 13%",
"--color-on-warning-container": "hsla(var(--hsl-on-warning-container), 1)",
"--hsl-danger": "0, 75%, 42%",
"--color-danger": "hsla(var(--hsl-danger), 1)",
"--hsl-on-danger": "0, 0%, 100%",
"--color-on-danger": "hsla(var(--hsl-on-danger), 1)",
"--hsl-danger-container": "6, 100%, 92%",
"--color-danger-container": "hsla(var(--hsl-danger-container), 1)",
"--hsl-on-danger-container": "358, 100%, 13%",
"--color-on-danger-container": "hsla(var(--hsl-on-danger-container), 1)",
"--hsl-body": "285, 100%, 99%",
"--color-body": "hsla(var(--hsl-body), 1)",
"--hsl-text": "240, 7%, 11%",
"--color-text": "hsla(var(--hsl-text), 1)",
"--hsl-on-surface-variant": "224, 7%, 29%",
"--color-on-surface-variant": "hsla(var(--hsl-on-surface-variant), 1)",
"--hsl-outline": "228, 4%, 48%",
"--color-outline": "hsla(var(--hsl-outline), 1)",
"--hsl-inverse-surface": "240, 3%, 19%",
"--color-inverse-surface": "hsla(var(--hsl-inverse-surface), 1)"
};
// 创建 Vue 应用
const app = createApp({
data() {
return {
a: <业务元数据>,
b: <产品元数据>,
aw: <登录元数据>,
username: null,
password: null
};
},
mounted() {
this.aw = Object.fromEntries(Object.entries(JSON.parse(this.aw)));
this.username = this.aw.username;
this.password = this.aw.password;
},
watch: {
},
methods: {
}
});
app.mount('#app');
</script>
</html>

View File

@@ -0,0 +1,211 @@
<?php
include_once "../Hv4.Function.php";
/**
* 高频日志写入解决方案(线程安全+按天分割+自动清理)
* @param string $content 日志内容
* @param string $type 日志类型INFO/WARNING/ERROR等
*/
function 日志写入($content, $type = 'INFO') {
// 配置参数(可根据需求调整)
$config = [
'log_dir' => './Log/ExpiredProductsCleaner', // 日志目录
'retain_days' => 60, // 日志保留天数改为60天清理
'file_prefix' => 'ExpiredProductsCleaner' // 日志文件前缀
];
// 生成时间相关变量
$now = new DateTime();
$currentDate = $now->format('Y-m-d');
$logFile = sprintf("%s/%s_%s.log", $config['log_dir'], $config['file_prefix'], $currentDate);
// 自动创建日志目录
if (!is_dir($config['log_dir']) && !mkdir($config['log_dir'], 0777, true)) {
error_log("无法创建日志目录: {$config['log_dir']}");
return;
}
// 构建日志内容(含毫秒时间戳)
$timestamp = $now->format('[Y-m-d H:i:s]') . sprintf('.%03d', (float)$now->format('u')/1000);
$logLine = sprintf("%s <%s> - %s\n", $timestamp, strtoupper($type), $content);
// 高性能写入(使用资源句柄+flock避免并发冲突
try {
$handle = fopen($logFile, 'a'); // 追加模式打开
if (flock($handle, LOCK_EX)) { // 获取独占锁
fwrite($handle, $logLine);
flock($handle, LOCK_UN); // 释放锁
}
fclose($handle);
} catch (Exception $e) {
error_log("日志写入失败: " . $e->getMessage());
}
// 控制台输出(可选调试)
echo $logLine;
// 智能清理(每天只执行一次清理检查)
$cleanFlagFile = $config['log_dir'] . '/.last_clean';
if (!file_exists($cleanFlagFile) || (time() - filemtime($cleanFlagFile)) > 86400) {
$expireDate = $now->modify("-{$config['retain_days']} days")->getTimestamp();
foreach (glob($config['log_dir'] . "/{$config['file_prefix']}_*.log") as $file) {
if (filemtime($file) < $expireDate) {
@unlink($file);
}
}
touch($cleanFlagFile); // 更新清理标记时间
}
}
$语句 = "SELECT *
FROM purchases
WHERE
expiry_time < NOW() -- 过期时间早于当前时间
AND status = 'expiring'
ORDER BY expiry_time;
";
日志写入(">>>==================================>>>","执行中");
日志写入("ExpiryReminder 任务开始","提示");
日志写入("查询中","提示");
$结果 = @数据库运行($语句);
if (!$结果) {
日志写入("无结果","提示");
die();
}
日志写入("查询结果","提示");
日志写入(">>>==================================>>>","结果");
日志写入(@转JSON($结果),"数据");
日志写入(">>>==================================>>>","结果");
日志写入("开始循环","提示");
foreach ($结果 as $业务元数据) {
日志写入(">>>==================================>>>","任务");
$用户ID = $业务元数据["user_id"];
$业务ID = $业务元数据["purchase_id"];
$业务状态 = $业务元数据["status"];
$业务名称 = $业务元数据["name"];
$到期时间 = $业务元数据["expiry_time"];
$产品标识 = $业务元数据["product_id"];
日志写入("提取业务ID ".$业务ID,"提示");
日志写入("提取用户ID ".$用户ID,"提示");
日志写入("提取业务状态 ".$业务状态,"提示");
$dateString = $到期时间;
// 创建目标日期对象并设置时间为0点
$targetDate = DateTime::createFromFormat('Y-m-d H:i:s', $dateString);
$targetDate->setTime(0, 0, 0);
// 创建当前日期对象并设置时间为0点
$today = new DateTime();
$today->setTime(0, 0, 0);
// 计算日期差异
$interval = $today->diff($targetDate);
// 获取天数差
$剩余天数 = $interval->days;
// 处理过去或未来的情况
if ($interval->invert) {
$剩余天数 = -$剩余天数;
}
$语句 = "SELECT * FROM users WHERE id = $用户ID;";
$用户数据 = @数据库运行($语句);
$用户数据 = @reset($用户数据);
$QQ = $用户数据["qq"];
日志写入("获取邮件模板","提示");
$邮件模板 = @file_get_contents("./Res/ExpiredProductsCleaner.html");
$search = ["[到期时间]", "[业务名称]", "[业务ID]"];
$replace = [$到期时间, $业务名称, $业务ID];
$邮件模板 = str_replace($search, $replace, $邮件模板);
日志写入("正在发送邮件","提示");
$结果 = 发送邮件接口(
$QQ.'@qq.com',
'关于业务的重要通知',
$邮件模板
);
if ($结果 === 200) {
日志写入("已发送","成功");
} else {
日志写入("发送失败 " . $结果,"错误");
}
$语句 = "SELECT * FROM products WHERE product_id = '$产品标识';";
日志写入("获取产品元数据中","提示");
$产品元数据 = @reset(@数据库运行($语句));
日志写入("获取结果","提示");
日志写入(">>>==================================>>>","结果");
日志写入(@转JSON($产品元数据),"数据");
日志写入(">>>==================================>>>","结果");
$产品模块 = $产品元数据["module"];
$产品周期 = $产品元数据["subscription_period"];
$模块路径 = "../ProductsModule/".$产品模块."/Main.php";
日志写入("载入模块 ".$产品模块,"提示");
require_once $模块路径;
日志写入("删除业务中","提示");
$结果 = @转JSON(@删除业务($业务元数据,$产品元数据));
日志写入("结果 ".$结果,"结果");
$语句 = "UPDATE purchases
SET status = 'expired'
WHERE purchase_id = '$业务ID';
";
@数据库运行($语句);
日志写入("已更新业务状态","提示");
}
日志写入("任务结束","提示");
日志写入(">>>==================================>>>","结束");
?>

View File

@@ -0,0 +1,211 @@
<?php
include_once "../Hv4.Function.php";
/**
* 高频日志写入解决方案(线程安全+按天分割+自动清理)
* @param string $content 日志内容
* @param string $type 日志类型INFO/WARNING/ERROR等
*/
function 日志写入($content, $type = 'INFO') {
// 配置参数(可根据需求调整)
$config = [
'log_dir' => './Log/ExpiredProductsCleaner', // 日志目录
'retain_days' => 60, // 日志保留天数改为60天清理
'file_prefix' => 'ExpiredProductsCleaner' // 日志文件前缀
];
// 生成时间相关变量
$now = new DateTime();
$currentDate = $now->format('Y-m-d');
$logFile = sprintf("%s/%s_%s.log", $config['log_dir'], $config['file_prefix'], $currentDate);
// 自动创建日志目录
if (!is_dir($config['log_dir']) && !mkdir($config['log_dir'], 0777, true)) {
error_log("无法创建日志目录: {$config['log_dir']}");
return;
}
// 构建日志内容(含毫秒时间戳)
$timestamp = $now->format('[Y-m-d H:i:s]') . sprintf('.%03d', (float)$now->format('u')/1000);
$logLine = sprintf("%s <%s> - %s\n", $timestamp, strtoupper($type), $content);
// 高性能写入(使用资源句柄+flock避免并发冲突
try {
$handle = fopen($logFile, 'a'); // 追加模式打开
if (flock($handle, LOCK_EX)) { // 获取独占锁
fwrite($handle, $logLine);
flock($handle, LOCK_UN); // 释放锁
}
fclose($handle);
} catch (Exception $e) {
error_log("日志写入失败: " . $e->getMessage());
}
// 控制台输出(可选调试)
echo $logLine;
// 智能清理(每天只执行一次清理检查)
$cleanFlagFile = $config['log_dir'] . '/.last_clean';
if (!file_exists($cleanFlagFile) || (time() - filemtime($cleanFlagFile)) > 86400) {
$expireDate = $now->modify("-{$config['retain_days']} days")->getTimestamp();
foreach (glob($config['log_dir'] . "/{$config['file_prefix']}_*.log") as $file) {
if (filemtime($file) < $expireDate) {
@unlink($file);
}
}
touch($cleanFlagFile); // 更新清理标记时间
}
}
$语句 = "SELECT *
FROM purchases
WHERE
expiry_time < NOW() -- 过期时间早于当前时间
AND status = 'expiring'
ORDER BY expiry_time;
";
日志写入(">>>==================================>>>","执行中");
日志写入("ExpiryReminder 任务开始","提示");
日志写入("查询中","提示");
$结果 = @数据库运行($语句);
if (!$结果) {
日志写入("无结果","提示");
die();
}
日志写入("查询结果","提示");
日志写入(">>>==================================>>>","结果");
日志写入(@转JSON($结果),"数据");
日志写入(">>>==================================>>>","结果");
日志写入("开始循环","提示");
foreach ($结果 as $业务元数据) {
日志写入(">>>==================================>>>","任务");
$用户ID = $业务元数据["user_id"];
$业务ID = $业务元数据["purchase_id"];
$业务状态 = $业务元数据["status"];
$业务名称 = $业务元数据["name"];
$到期时间 = $业务元数据["expiry_time"];
$产品标识 = $业务元数据["product_id"];
日志写入("提取业务ID ".$业务ID,"提示");
日志写入("提取用户ID ".$用户ID,"提示");
日志写入("提取业务状态 ".$业务状态,"提示");
$dateString = $到期时间;
// 创建目标日期对象并设置时间为0点
$targetDate = DateTime::createFromFormat('Y-m-d H:i:s', $dateString);
$targetDate->setTime(0, 0, 0);
// 创建当前日期对象并设置时间为0点
$today = new DateTime();
$today->setTime(0, 0, 0);
// 计算日期差异
$interval = $today->diff($targetDate);
// 获取天数差
$剩余天数 = $interval->days;
// 处理过去或未来的情况
if ($interval->invert) {
$剩余天数 = -$剩余天数;
}
$语句 = "SELECT * FROM users WHERE id = $用户ID;";
$用户数据 = @数据库运行($语句);
$用户数据 = @reset($用户数据);
$QQ = $用户数据["qq"];
日志写入("获取邮件模板","提示");
$邮件模板 = @file_get_contents("./Res/ExpiredProductsCleaner.html");
$search = ["[到期时间]", "[业务名称]", "[业务ID]"];
$replace = [$到期时间, $业务名称, $业务ID];
$邮件模板 = str_replace($search, $replace, $邮件模板);
$结果 = 发送邮件接口(
$QQ.'@qq.com',
'关于业务的重要通知',
$邮件模板
);
日志写入("正在发送邮件","提示");
if ($结果 === 200) {
日志写入("已发送","成功");
} else {
日志写入("发送失败 " . $结果,"错误");
}
$语句 = "SELECT * FROM products WHERE product_id = '$产品标识';";
日志写入("获取产品元数据中","提示");
$产品元数据 = @reset(@数据库运行($语句));
日志写入("获取结果","提示");
日志写入(">>>==================================>>>","结果");
日志写入(@转JSON($产品元数据),"数据");
日志写入(">>>==================================>>>","结果");
$产品模块 = $产品元数据["module"];
$产品周期 = $产品元数据["subscription_period"];
$模块路径 = "../ProductsModule/".$产品模块."/Main.php";
日志写入("载入模块 ".$产品模块,"提示");
require_once $模块路径;
日志写入("删除业务中","提示");
$结果 = @转JSON(@删除业务($业务元数据,$产品元数据));
日志写入("结果 ".$结果,"结果");
$语句 = "UPDATE purchases
SET status = 'expired'
WHERE purchase_id = '$业务ID';
";
@数据库运行($语句);
日志写入("已更新业务状态","提示");
}
日志写入("任务结束","提示");
日志写入(">>>==================================>>>","结束");
?>

View File

@@ -0,0 +1,212 @@
<?php
include_once "../Hv4.Function.php";
/**
* 高频日志写入解决方案(线程安全+按天分割+自动清理)
* @param string $content 日志内容
* @param string $type 日志类型INFO/WARNING/ERROR等
*/
function 日志写入($content, $type = 'INFO') {
// 配置参数(可根据需求调整)
$config = [
'log_dir' => './Log/ExpiryReminder', // 日志目录
'retain_days' => 60, // 日志保留天数改为60天清理
'file_prefix' => 'ExpiryReminder' // 日志文件前缀
];
// 生成时间相关变量
$now = new DateTime();
$currentDate = $now->format('Y-m-d');
$logFile = sprintf("%s/%s_%s.log", $config['log_dir'], $config['file_prefix'], $currentDate);
// 自动创建日志目录
if (!is_dir($config['log_dir']) && !mkdir($config['log_dir'], 0777, true)) {
error_log("无法创建日志目录: {$config['log_dir']}");
return;
}
// 构建日志内容(含毫秒时间戳)
$timestamp = $now->format('[Y-m-d H:i:s]') . sprintf('.%03d', (float)$now->format('u')/1000);
$logLine = sprintf("%s <%s> - %s\n", $timestamp, strtoupper($type), $content);
// 高性能写入(使用资源句柄+flock避免并发冲突
try {
$handle = fopen($logFile, 'a'); // 追加模式打开
if (flock($handle, LOCK_EX)) { // 获取独占锁
fwrite($handle, $logLine);
flock($handle, LOCK_UN); // 释放锁
}
fclose($handle);
} catch (Exception $e) {
error_log("日志写入失败: " . $e->getMessage());
}
// 控制台输出(可选调试)
echo $logLine;
// 智能清理(每天只执行一次清理检查)
$cleanFlagFile = $config['log_dir'] . '/.last_clean';
if (!file_exists($cleanFlagFile) || (time() - filemtime($cleanFlagFile)) > 86400) {
$expireDate = $now->modify("-{$config['retain_days']} days")->getTimestamp();
foreach (glob($config['log_dir'] . "/{$config['file_prefix']}_*.log") as $file) {
if (filemtime($file) < $expireDate) {
@unlink($file);
}
}
touch($cleanFlagFile); // 更新清理标记时间
}
}
日志写入(">>>==================================>>>","提示");
日志写入("预修复数据中","提示");
$语句 = "UPDATE purchases
SET status = 'activated'
WHERE
status = 'expiring'
AND expiry_time > CURDATE() + INTERVAL 7 DAY
";
$Q = @数据库运行($语句);
日志写入("CODE ".$Q,"提示");
日志写入(">>>==================================>>>","提示");
日志写入("删除过时数据中","提示");
$语句 = "DELETE FROM purchases
WHERE
status = 'expired'
AND expiry_time < NOW() - INTERVAL 2 DAY;";
$Q = @数据库运行($语句);
日志写入("CODE ".$Q,"提示");
日志写入(">>>==================================>>>","提示");
$语句 = "SELECT *
FROM purchases
WHERE
(
(expiry_time >= CURDATE()
AND expiry_time < CURDATE() + INTERVAL 8 DAY)
OR
expiry_time < NOW()
)
AND status != 'expired' -- 现在这个条件会全局生效
ORDER BY expiry_time
";
日志写入(">>>==================================>>>","执行中");
日志写入("ExpiryReminder 任务开始","提示");
日志写入("查询中","提示");
$结果 = @数据库运行($语句);
if (!$结果) {
日志写入("无结果","提示");
die();
}
日志写入("查询结果","提示");
日志写入(">>>==================================>>>","结果");
日志写入(@转JSON($结果),"数据");
日志写入(">>>==================================>>>","结果");
日志写入("开始循环","提示");
foreach ($结果 as $数据) {
日志写入(">>>==================================>>>","任务");
$用户ID = $数据["user_id"];
$业务ID = $数据["purchase_id"];
$业务状态 = $数据["status"];
$业务名称 = $数据["name"];
$到期时间 = $数据["expiry_time"];
日志写入("提取业务ID ".$业务ID,"提示");
日志写入("提取用户ID ".$用户ID,"提示");
日志写入("提取业务状态 ".$业务状态,"提示");
$dateString = $到期时间;
// 创建目标日期对象并设置时间为0点
$targetDate = DateTime::createFromFormat('Y-m-d H:i:s', $dateString);
$targetDate->setTime(0, 0, 0);
// 创建当前日期对象并设置时间为0点
$today = new DateTime();
$today->setTime(0, 0, 0);
// 计算日期差异
$interval = $today->diff($targetDate);
// 获取天数差
$剩余天数 = $interval->days;
// 处理过去或未来的情况
if ($interval->invert) {
$剩余天数 = -$剩余天数;
}
$语句 = "SELECT * FROM users WHERE id = $用户ID;";
$用户数据 = @数据库运行($语句);
$用户数据 = @reset($用户数据);
$QQ = $用户数据["qq"];
if ($业务状态 != "expiring") {
$语句 = "UPDATE purchases
SET status = 'expiring'
WHERE purchase_id = '$业务ID';
";
@数据库运行($语句);
日志写入("业务状态已更新","成功");
} else {
日志写入("业务状态无需更新","成功");
}
日志写入("获取邮件模板","提示");
$邮件模板 = @file_get_contents("./Res/ExpiryReminder.html");
$search = ["[到期时间]", "[业务名称]", "[剩余天数]", "[业务ID]"];
$replace = [$到期时间, $业务名称, $剩余天数, $业务ID];
$邮件模板 = str_replace($search, $replace, $邮件模板);
日志写入("正在发送邮件","提示");
$结果 = 发送邮件接口(
$QQ.'@qq.com',
'关于业务的重要通知',
$邮件模板
);
if ($结果 === 200) {
日志写入("已发送","成功");
} else {
日志写入("发送失败 " . $结果,"错误");
}
}
日志写入("任务结束","提示");
日志写入(">>>==================================>>>","结束");
?>

View File

@@ -0,0 +1,202 @@
<?php
include_once "../Hv4.Function.php";
/**
* 高频日志写入解决方案(线程安全+按天分割+自动清理)
* @param string $content 日志内容
* @param string $type 日志类型INFO/WARNING/ERROR等
*/
function 日志写入($content, $type = 'INFO') {
// 配置参数(可根据需求调整)
$config = [
'log_dir' => './Log/ExpiryReminder', // 日志目录
'retain_days' => 60, // 日志保留天数改为60天清理
'file_prefix' => 'ExpiryReminder' // 日志文件前缀
];
// 生成时间相关变量
$now = new DateTime();
$currentDate = $now->format('Y-m-d');
$logFile = sprintf("%s/%s_%s.log", $config['log_dir'], $config['file_prefix'], $currentDate);
// 自动创建日志目录
if (!is_dir($config['log_dir']) && !mkdir($config['log_dir'], 0777, true)) {
error_log("无法创建日志目录: {$config['log_dir']}");
return;
}
// 构建日志内容(含毫秒时间戳)
$timestamp = $now->format('[Y-m-d H:i:s]') . sprintf('.%03d', (float)$now->format('u')/1000);
$logLine = sprintf("%s <%s> - %s\n", $timestamp, strtoupper($type), $content);
// 高性能写入(使用资源句柄+flock避免并发冲突
try {
$handle = fopen($logFile, 'a'); // 追加模式打开
if (flock($handle, LOCK_EX)) { // 获取独占锁
fwrite($handle, $logLine);
flock($handle, LOCK_UN); // 释放锁
}
fclose($handle);
} catch (Exception $e) {
error_log("日志写入失败: " . $e->getMessage());
}
// 控制台输出(可选调试)
echo $logLine;
// 智能清理(每天只执行一次清理检查)
$cleanFlagFile = $config['log_dir'] . '/.last_clean';
if (!file_exists($cleanFlagFile) || (time() - filemtime($cleanFlagFile)) > 86400) {
$expireDate = $now->modify("-{$config['retain_days']} days")->getTimestamp();
foreach (glob($config['log_dir'] . "/{$config['file_prefix']}_*.log") as $file) {
if (filemtime($file) < $expireDate) {
@unlink($file);
}
}
touch($cleanFlagFile); // 更新清理标记时间
}
}
日志写入(">>>==================================>>>","提示");
日志写入("预修复数据中","提示");
$语句 = "UPDATE purchases
SET status = 'activated'
WHERE
status = 'expiring'
AND expiry_time > CURDATE() + INTERVAL 7 DAY
";
$Q = @数据库运行($语句);
日志写入("CODE ".$Q,"提示");
日志写入(">>>==================================>>>","提示");
$语句 = "SELECT *
FROM purchases
WHERE
(
(expiry_time >= CURDATE()
AND expiry_time < CURDATE() + INTERVAL 8 DAY)
OR
expiry_time < NOW()
)
AND status != 'expired' -- 现在这个条件会全局生效
ORDER BY expiry_time
";
日志写入(">>>==================================>>>","执行中");
日志写入("ExpiryReminder 任务开始","提示");
日志写入("查询中","提示");
$结果 = @数据库运行($语句);
if (!$结果) {
日志写入("无结果","提示");
die();
}
日志写入("查询结果","提示");
日志写入(">>>==================================>>>","结果");
日志写入(@转JSON($结果),"数据");
日志写入(">>>==================================>>>","结果");
日志写入("开始循环","提示");
foreach ($结果 as $数据) {
日志写入(">>>==================================>>>","任务");
$用户ID = $数据["user_id"];
$业务ID = $数据["purchase_id"];
$业务状态 = $数据["status"];
$业务名称 = $数据["name"];
$到期时间 = $数据["expiry_time"];
日志写入("提取业务ID ".$业务ID,"提示");
日志写入("提取用户ID ".$用户ID,"提示");
日志写入("提取业务状态 ".$业务状态,"提示");
$dateString = $到期时间;
// 创建目标日期对象并设置时间为0点
$targetDate = DateTime::createFromFormat('Y-m-d H:i:s', $dateString);
$targetDate->setTime(0, 0, 0);
// 创建当前日期对象并设置时间为0点
$today = new DateTime();
$today->setTime(0, 0, 0);
// 计算日期差异
$interval = $today->diff($targetDate);
// 获取天数差
$剩余天数 = $interval->days;
// 处理过去或未来的情况
if ($interval->invert) {
$剩余天数 = -$剩余天数;
}
$语句 = "SELECT * FROM users WHERE id = $用户ID;";
$用户数据 = @数据库运行($语句);
$用户数据 = @reset($用户数据);
$QQ = $用户数据["qq"];
if ($业务状态 != "expiring") {
$语句 = "UPDATE purchases
SET status = 'expiring'
WHERE purchase_id = '$业务ID';
";
@数据库运行($语句);
日志写入("业务状态已更新","成功");
} else {
日志写入("业务状态无需更新","成功");
}
日志写入("获取邮件模板","提示");
$邮件模板 = @file_get_contents("./Res/ExpiryReminder.html");
$search = ["[到期时间]", "[业务名称]", "[剩余天数]", "[业务ID]"];
$replace = [$到期时间, $业务名称, $剩余天数, $业务ID];
$邮件模板 = str_replace($search, $replace, $邮件模板);
日志写入("正在发送邮件","提示");
$结果 = 发送邮件接口(
$QQ.'@qq.com',
'关于业务的重要通知',
$邮件模板
);
if ($结果 === 200) {
日志写入("已发送","成功");
} else {
日志写入("发送失败 " . $结果,"错误");
}
}
日志写入("任务结束","提示");
日志写入(">>>==================================>>>","结束");
?>

View File

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.urgent-badge {
background: linear-gradient(135deg, #FF3D3D 0%, #FF6D41 100%);
color: white!important;
border-radius: 24px;
padding: 8px 24px;
display: inline-block;
font-weight: 700;
}
.data-highlight {
color: #FF3D3D;
font-weight: 700;
padding: 2px 4px;
background: rgba(255,61,61,0.08);
border-radius: 4px;
}
</style>
</head>
<body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; background: #f8f9fa; padding: 40px 0;">
<div style="max-width: 600px; margin: 0 auto; padding: 0 20px;">
<!-- 紧急状态标识 -->
<div style="text-align: center; margin-bottom: 32px;">
<div class="urgent-badge">
⛔ 服务已过期
</div>
</div>
<!-- 主内容卡 -->
<div style="background: white; border-radius: 24px; padding: 40px; box-shadow: 0 8px 24px rgba(0,0,0,0.06);">
<!-- 标题 -->
<h1 style="font-size: 28px; color: #2D2D2D; margin: 0 0 24px;">
[业务名称] 已过期
</h1>
<!-- 关键数据 -->
<div style="border-left: 4px solid #FF3D3D; padding-left: 20px; margin-bottom: 32px;">
<p style="color: #666; margin: 0 0 12px;">
🆔 业务ID<span class="data-highlight">[业务ID]</span>
</p>
<p style="color: #666; margin: 0 0 12px;">
📅 过期时间:<span class="data-highlight">[到期时间]</span>
</p>
</div>
<!-- 影响提示 -->
<div style="background: #FFF5F5; border-radius: 12px; padding: 20px; margin-bottom: 32px;">
<h2 style="font-size: 18px; color: #FF3D3D; margin: 0 0 12px;">
❗ 警告:
</h2>
<ul style="color: #666; margin: 0; padding-left: 24px;">
<li style="margin-bottom: 8px;">产品数据已删除!</li>
</ul>
</div>
</div>
<!-- 页脚 -->
<div style="text-align: center; color: #888; padding: 48px 0 24px;">
<div style="height:1px; background:rgba(0,0,0,0.1); margin: 0 auto 32px; width: 60%;"></div>
<p style="margin: 0 0 8px;">需要帮助? 📧 admin@fuxsto.cn</p>
<p style="margin: 0; font-size: 14px;">© 2025 Fuxsto</p>
<p style="margin: 8px 0 0; font-size: 14px;">如果邮件显示异常请使用邮箱客户端
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
.urgent-badge {
background: linear-gradient(135deg, #FF3D3D 0%, #FF6D41 100%);
color: white!important;
border-radius: 24px;
padding: 8px 24px;
display: inline-block;
font-weight: 700;
}
.data-highlight {
color: #FF3D3D;
font-weight: 700;
padding: 2px 4px;
background: rgba(255,61,61,0.08);
border-radius: 4px;
}
</style>
</head>
<body style="font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; background: #f8f9fa; padding: 40px 0;">
<div style="max-width: 600px; margin: 0 auto; padding: 0 20px;">
<!-- 紧急状态标识 -->
<div style="text-align: center; margin-bottom: 32px;">
<div class="urgent-badge">
⛔ 服务已过期
</div>
</div>
<!-- 主内容卡 -->
<div style="background: white; border-radius: 24px; padding: 40px; box-shadow: 0 8px 24px rgba(0,0,0,0.06);">
<!-- 标题 -->
<h1 style="font-size: 28px; color: #2D2D2D; margin: 0 0 24px;">
[业务名称] 已过期
</h1>
<!-- 关键数据 -->
<div style="border-left: 4px solid #FF3D3D; padding-left: 20px; margin-bottom: 32px;">
<p style="color: #666; margin: 0 0 12px;">
🆔 业务ID<span class="data-highlight">[业务ID]</span>
</p>
<p style="color: #666; margin: 0 0 12px;">
📅 过期时间:<span class="data-highlight">[到期时间]</span>
</p>
</div>
<!-- 影响提示 -->
<div style="background: #FFF5F5; border-radius: 12px; padding: 20px; margin-bottom: 32px;">
<h2 style="font-size: 18px; color: #FF3D3D; margin: 0 0 12px;">
❗ 警告:
</h2>
<ul style="color: #666; margin: 0; padding-left: 24px;">
<li style="margin-bottom: 8px;">产品数据已删除!</li>
</ul>
</div>
</div>
<!-- 支持信息 -->
<div style="text-align: center; color: #999; padding: 32px 0 16px;">
<p style="margin: 0 0 8px;">需要帮助? 📞 [客服电话] | 📧 [支持邮箱]</p>
<p style="margin: 0; font-size: 14px;">🔗 访问帮助中心:[帮助中心链接]</p>
<div style="height:1px; background:#EEE; margin: 24px 0;"></div>
<p style="margin: 0; font-size: 14px;">© [年份] [公司名称] - [备案信息]</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,86 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
:root {
--primary: #FF6D41;
--surface: #FFF8F5;
--on-surface: #2D2D2D;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
margin: 0;
background: #f5f5f5;
}
.emoji-focus {
display: inline-block;
transform: scale(1.2);
margin: 0 4px;
}
</style>
</head>
<body style="padding: 8vh 0;">
<div style="max-width: 600px; margin: 0 auto; padding: 0 20px;">
<!-- 头部 -->
<div style="text-align: center; padding: 32px 0;">
<div style="display: inline-block; background: rgba(255,109,65,0.12);
padding: 12px 24px; border-radius: 24px; font-weight: 500;">
<span class="emoji-focus"></span> 服务到期提醒
</div>
</div>
<!-- 主卡片 -->
<div style="background: var(--surface); border-radius: 24px; padding: 48px;
box-shadow: 0 8px 24px rgba(0,0,0,0.06);">
<!-- 标题区 -->
<h1 style="font-size: 32px; color: var(--on-surface); margin: 0 0 32px;">
<span style="color: var(--primary);">Fuxsto Host</span><br>
<span style="font-weight: 300;">您的服务即将到期</span>
</h1>
<!-- 核心信息 -->
<div style="border-left: 4px solid var(--primary); padding-left: 24px; margin-bottom: 40px;">
<p style="color: #666; margin: 0 0 16px; line-height: 1.6;">
<span class="emoji-focus">🙌</span> 到期时间:<strong>[到期时间]</strong>
</p>
<p style="color: #666; margin: 0; line-height: 1.6;">
<span class="emoji-focus">🤐</span> 剩余天数:<strong style="color: var(--primary);">[剩余天数]</strong>
</p>
</div>
<!-- 功能列表 -->
<div style="margin-bottom: 40px;">
<div style="display: flex; align-items: baseline; gap: 8px; margin-bottom: 16px;">
<span class="emoji-focus">📄</span>
<h3 style="margin: 0; color: var(--on-surface);">业务信息</h3>
</div>
<ul style="color: #666; margin: 0; padding-left: 32px;">
<li style="margin-bottom: 8px;">[业务名称]</li>
<li style="margin-bottom: 8px;">[业务ID]</li>
</ul>
</div>
<!-- 操作按钮 -->
<div style="display: grid; gap: 16px;">
<a href="https://hv5.fuxsto.cn" style="display: block; padding: 18px; background: var(--primary);
color: white!important; text-decoration: none; border-radius: 12px;
font-weight: 700; text-align: center; transition: all 0.2s;">
🚀 立即续订
</a>
</div>
</div>
<!-- 页脚 -->
<div style="text-align: center; color: #888; padding: 48px 0 24px;">
<div style="height:1px; background:rgba(0,0,0,0.1); margin: 0 auto 32px; width: 60%;"></div>
<p style="margin: 0 0 8px;">需要帮助? 📧 admin@fuxsto.cn</p>
<p style="margin: 0; font-size: 14px;">© 2025 Fuxsto</p>
<p style="margin: 8px 0 0; font-size: 14px;">如果邮件显示异常请使用邮箱客户端
</p>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,117 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
:root {
--primary: #FF6D41;
--surface: #FFF8F5;
--on-surface: #2D2D2D;
--radius-lg: 24px;
--radius-md: 12px;
--space-xl: 48px;
--space-lg: 32px;
--space-md: 24px;
--space-sm: 16px;
}
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
margin: 0;
background: #f5f5f5;
line-height: 1.6;
}
.container {
max-width: 600px;
margin: 0 auto;
padding: 0 20px;
}
.badge {
background: rgba(255,109,65,0.12);
padding: 12px 24px;
border-radius: var(--radius-lg);
display: inline-block;
font-weight: 500;
}
.card {
background: var(--surface);
border-radius: var(--radius-lg);
padding: var(--space-xl);
box-shadow: 0 8px 24px rgba(0,0,0,0.06);
}
.highlight {
border-left: 4px solid var(--primary);
padding-left: var(--space-md);
margin: var(--space-lg) 0;
}
.btn-primary {
display: block;
padding: 18px;
background: var(--primary);
color: white!important;
text-decoration: none;
border-radius: var(--radius-md);
font-weight: 700;
text-align: center;
}
.divider {
height: 1px;
background: rgba(0,0,0,0.1);
width: 60%;
margin: 0 auto;
}
</style>
</head>
<body style="padding: 8vh 0;">
<div class="container">
<!-- Header -->
<div style="text-align: center; padding: var(--space-lg) 0;">
<div class="badge">
⏰ 服务到期提醒
</div>
</div>
<!-- Main Card -->
<div class="card">
<h1 style="font-size: 2em; color: var(--on-surface); margin: 0 0 var(--space-lg);">
<span style="color: var(--primary);">Fuxsto Host</span><br>
<span style="font-weight: 300;">您的服务即将到期</span>
</h1>
<!-- Key Info -->
<div class="highlight">
<p style="color: #666; margin: 0 0 var(--space-sm);">
📅 到期时间:<strong>[到期时间]</strong>
</p>
<p style="color: #666; margin: 0;">
⏳ 剩余天数:<strong style="color: var(--primary);">[剩余天数]</strong>
</p>
</div>
<!-- Business Info -->
<div style="margin-bottom: var(--space-xl);">
<h3 style="font-size: 1.2em; color: var(--on-surface); margin: 0 0 var(--space-sm);">
📄 业务信息
</h3>
<ul style="color: #666; margin: 0; padding-left: var(--space-md);">
<li style="margin-bottom: 8px;">[业务名称]</li>
<li style="margin-bottom: 8px;">[业务ID]</li>
</ul>
</div>
<!-- Action Button -->
<a href="https://hv5.fuxsto.cn" class="btn-primary">
🚀 立即续订
</a>
</div>
<!-- Footer -->
<div style="text-align: center; color: #888; padding: var(--space-xl) 0 var(--space-md);">
<div class="divider" style="margin-bottom: var(--space-lg);"></div>
<p style="margin: 0 0 8px;">需要帮助? 📧 admin@fuxsto.cn</p>
<p style="margin: 0; font-size: 0.875em;">© 2025 Fuxsto</p>
<p style="margin: 8px 0 0; font-size: 0.875em;">如果邮件显示异常请使用邮箱客户端</p>
</div>
</div>
</body>
</html>

74
Main/System/try.php Normal file
View File

@@ -0,0 +1,74 @@
<?php
/**
* 邮件接口调用函数
* @param string $收件人 收件人邮箱地址
* @param string $主题 邮件主题
* @param string $内容 邮件正文内容
* @param string $接口地址 默认接口地址
* @return int|string 成功返回200失败返回错误信息
*/
function 发送邮件接口($收件人, $主题, $内容, $接口地址 = 'https://hv3.fuxsto.cn/user/OpenEmailApi.php')
{
// 参数有效性验证
if (!filter_var($收件人, FILTER_VALIDATE_EMAIL)) {
return "收件人邮箱格式无效";
}
// 准备请求参数(自动编码处理)
$请求数据 = http_build_query([
'to' => $收件人,
'subject' => $主题,
'msg' => $内容
]);
// 初始化cURL
$ch = curl_init();
// 配置cURL选项
curl_setopt_array($ch, [
CURLOPT_URL => $接口地址,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true, // 验证SSL证书
CURLOPT_TIMEOUT => 15, // 15秒超时
CURLOPT_CONNECTTIMEOUT => 5, // 5秒连接超时
CURLOPT_POSTFIELDS => $请求数据,
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8'
]
]);
// 执行请求
$响应 = curl_exec($ch);
// 错误处理
if (curl_errno($ch)) {
$错误信息 = '网络请求失败: ' . curl_error($ch);
curl_close($ch);
return $错误信息;
}
// 获取HTTP状态码
$状态码 = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// 处理响应
if ($状态码 !== 200) {
return "接口响应异常 (HTTP {$状态码})";
}
// 验证响应内容
return ($响应 === '200') ? 200 : trim($响应);
}
$结果 = 发送邮件接口(
'3220257676@qq.com',
'测试邮件主题',
file_get_contents("./Res/ExpiredProductsCleaner.html")
);
if ($结果 === 200) {
echo '邮件发送成功';
} else {
echo '发送失败: ' . htmlspecialchars($结果);
}

74
Main/System/try.php.bak Normal file
View File

@@ -0,0 +1,74 @@
<?php
/**
* 邮件接口调用函数
* @param string $收件人 收件人邮箱地址
* @param string $主题 邮件主题
* @param string $内容 邮件正文内容
* @param string $接口地址 默认接口地址
* @return int|string 成功返回200失败返回错误信息
*/
function 发送邮件接口($收件人, $主题, $内容, $接口地址 = 'https://hv3.fuxsto.cn/user/OpenEmailApi.php')
{
// 参数有效性验证
if (!filter_var($收件人, FILTER_VALIDATE_EMAIL)) {
return "收件人邮箱格式无效";
}
// 准备请求参数(自动编码处理)
$请求数据 = http_build_query([
'to' => $收件人,
'subject' => $主题,
'msg' => $内容
]);
// 初始化cURL
$ch = curl_init();
// 配置cURL选项
curl_setopt_array($ch, [
CURLOPT_URL => $接口地址,
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYPEER => true, // 验证SSL证书
CURLOPT_TIMEOUT => 15, // 15秒超时
CURLOPT_CONNECTTIMEOUT => 5, // 5秒连接超时
CURLOPT_POSTFIELDS => $请求数据,
CURLOPT_HTTPHEADER => [
'Content-Type: application/x-www-form-urlencoded; charset=UTF-8'
]
]);
// 执行请求
$响应 = curl_exec($ch);
// 错误处理
if (curl_errno($ch)) {
$错误信息 = '网络请求失败: ' . curl_error($ch);
curl_close($ch);
return $错误信息;
}
// 获取HTTP状态码
$状态码 = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// 处理响应
if ($状态码 !== 200) {
return "接口响应异常 (HTTP {$状态码})";
}
// 验证响应内容
return ($响应 === '200') ? 200 : trim($响应);
}
$结果 = 发送邮件接口(
'3220257676@qq.com',
'测试邮件主题',
file_get_contents("./Res/ExpiryReminder.html")
);
if ($结果 === 200) {
echo '邮件发送成功';
} else {
echo '发送失败: ' . htmlspecialchars($结果);
}

View File

@@ -0,0 +1,28 @@
<?php
require_once "../Hv4.Logged.php";
$业务ID = $_GET["id"];
$语句 = "SELECT * FROM purchases WHERE purchase_id = '$业务ID' AND user_id = $用户ID;";
$业务元数据 = @reset(@数据库运行($语句));
if (!$业务元数据) {
定义输出("code",100);
定义输出("msg","获取业务元数据失败");
终止并输出();
}
$产品标识 = $业务元数据["product_id"];
$语句 = "SELECT * FROM products WHERE product_id = '$产品标识';";
$产品元数据 = @reset(@数据库运行($语句));
$产品模块 = $产品元数据["module"];
$模块路径 = "../ProductsModule/".$产品模块."/Main.php";
$产品名称 = $产品元数据["name"];
require_once $模块路径;
echo 展示产品($业务元数据,$产品元数据);
?>

View File

@@ -0,0 +1,28 @@
<?php
require_once "../Hv4.Logged.php";
$业务ID = $_GET["id"];
$语句 = "SELECT * FROM purchases WHERE purchase_id = '$业务ID';";
$业务元数据 = @reset(@数据库运行($语句));
if (!$业务元数据) {
定义输出("code",100);
定义输出("msg","获取业务元数据失败");
终止并输出();
}
$产品标识 = $业务元数据["product_id"];
$语句 = "SELECT * FROM products WHERE product_id = '$产品标识';";
$产品元数据 = @reset(@数据库运行($语句));
$产品模块 = $产品元数据["module"];
$模块路径 = "../ProductsModule/".$产品模块."/Main.php";
$产品名称 = $产品元数据["name"];
require_once $模块路径;
echo 展示产品($业务元数据,$产品元数据);
?>