删除 More/t.php.bak
This commit is contained in:
63
Main/BuyGoods/generated_strings.txt
Normal file
63
Main/BuyGoods/generated_strings.txt
Normal 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
98
Main/BuyGoods/index.php
Normal 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);
|
||||
|
||||
@数据库运行($语句);
|
||||
终止并输出();
|
||||
93
Main/BuyGoods/index.php.bak
Normal file
93
Main/BuyGoods/index.php.bak
Normal 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);
|
||||
|
||||
@数据库运行($语句);
|
||||
终止并输出();
|
||||
22
Main/BuyGoods/product_codes.txt
Normal file
22
Main/BuyGoods/product_codes.txt
Normal 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
17
Main/CheckIn/index.php
Normal 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);
|
||||
终止并输出();
|
||||
}
|
||||
17
Main/CheckIn/index.php.bak
Normal file
17
Main/CheckIn/index.php.bak
Normal 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
50
Main/GetGoods/index.php
Normal 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);
|
||||
|
||||
|
||||
?>
|
||||
46
Main/GetGoods/index.php.bak
Normal file
46
Main/GetGoods/index.php.bak
Normal 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
5
Main/GetInfo/index.php
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
include_once "../Hv4.Logged.php";
|
||||
定义输出("msg",$用户数据);
|
||||
定义输出("code",200);
|
||||
终止并输出();
|
||||
5
Main/GetInfo/index.php.bak
Normal file
5
Main/GetInfo/index.php.bak
Normal file
@@ -0,0 +1,5 @@
|
||||
<?php
|
||||
include_once "../Hv4.Logged.php";
|
||||
定义输出("msg",$用户信息);
|
||||
定义输出("code",200);
|
||||
终止并输出();
|
||||
33
Main/GetProducts/index.php
Normal file
33
Main/GetProducts/index.php
Normal 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",$产品元数据);
|
||||
终止并输出();
|
||||
?>
|
||||
26
Main/GetProducts/index.php.bak
Normal file
26
Main/GetProducts/index.php.bak
Normal 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
234
Main/Hv4.Function.php
Normal 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
179
Main/Hv4.Function.php.bak
Normal 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
64
Main/Hv4.Logged.php
Normal 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
63
Main/Hv4.Logged.php.bak
Normal 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
31
Main/Login/CallBack.php
Normal 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>");
|
||||
}
|
||||
31
Main/Login/CallBack.php.bak
Normal file
31
Main/Login/CallBack.php.bak
Normal 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
53
Main/Login/index.php
Normal 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
53
Main/Login/index.php.bak
Normal 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>
|
||||
30
Main/Login/product_codes.txt
Normal file
30
Main/Login/product_codes.txt
Normal 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
|
||||
120
Main/ProductsModule/HK-FREE-EP/Main.php
Normal file
120
Main/ProductsModule/HK-FREE-EP/Main.php
Normal 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);
|
||||
}
|
||||
120
Main/ProductsModule/HK-FREE-EP/Main.php.bak
Normal file
120
Main/ProductsModule/HK-FREE-EP/Main.php.bak
Normal 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);
|
||||
}
|
||||
374
Main/ProductsModule/HK-FREE-EP/s.html
Normal file
374
Main/ProductsModule/HK-FREE-EP/s.html
Normal 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>
|
||||
375
Main/ProductsModule/HK-FREE-EP/s.html.bak
Normal file
375
Main/ProductsModule/HK-FREE-EP/s.html.bak
Normal 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>
|
||||
211
Main/System/ExpiredProductsCleaner.php
Normal file
211
Main/System/ExpiredProductsCleaner.php
Normal 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';
|
||||
";
|
||||
@数据库运行($语句);
|
||||
|
||||
日志写入("已更新业务状态","提示");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
日志写入("任务结束","提示");
|
||||
日志写入(">>>==================================>>>","结束");
|
||||
|
||||
?>
|
||||
211
Main/System/ExpiredProductsCleaner.php.bak
Normal file
211
Main/System/ExpiredProductsCleaner.php.bak
Normal 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';
|
||||
";
|
||||
@数据库运行($语句);
|
||||
|
||||
日志写入("已更新业务状态","提示");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
日志写入("任务结束","提示");
|
||||
日志写入(">>>==================================>>>","结束");
|
||||
|
||||
?>
|
||||
212
Main/System/ExpiryReminder.php
Normal file
212
Main/System/ExpiryReminder.php
Normal 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 {
|
||||
|
||||
日志写入("发送失败 " . $结果,"错误");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
日志写入("任务结束","提示");
|
||||
日志写入(">>>==================================>>>","结束");
|
||||
|
||||
?>
|
||||
202
Main/System/ExpiryReminder.php.bak
Normal file
202
Main/System/ExpiryReminder.php.bak
Normal 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 {
|
||||
|
||||
日志写入("发送失败 " . $结果,"错误");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
日志写入("任务结束","提示");
|
||||
日志写入(">>>==================================>>>","结束");
|
||||
|
||||
?>
|
||||
0
Main/System/Log/.last_clean
Normal file
0
Main/System/Log/.last_clean
Normal file
0
Main/System/Log/ExpiredProductsCleaner/.last_clean
Normal file
0
Main/System/Log/ExpiredProductsCleaner/.last_clean
Normal file
File diff suppressed because it is too large
Load Diff
0
Main/System/Log/ExpiryReminder/.last_clean
Normal file
0
Main/System/Log/ExpiryReminder/.last_clean
Normal file
1069
Main/System/Log/ExpiryReminder/ExpiryReminder_2025-03-01.log
Normal file
1069
Main/System/Log/ExpiryReminder/ExpiryReminder_2025-03-01.log
Normal file
File diff suppressed because it is too large
Load Diff
74
Main/System/Res/ExpiredProductsCleaner.html
Normal file
74
Main/System/Res/ExpiredProductsCleaner.html
Normal 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>
|
||||
73
Main/System/Res/ExpiredProductsCleaner.html.bak
Normal file
73
Main/System/Res/ExpiredProductsCleaner.html.bak
Normal 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>
|
||||
86
Main/System/Res/ExpiryReminder.html
Normal file
86
Main/System/Res/ExpiryReminder.html
Normal 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>
|
||||
117
Main/System/Res/ExpiryReminder.html.bak
Normal file
117
Main/System/Res/ExpiryReminder.html.bak
Normal 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
74
Main/System/try.php
Normal 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
74
Main/System/try.php.bak
Normal 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($结果);
|
||||
}
|
||||
28
Main/ViewProduct/index.php
Normal file
28
Main/ViewProduct/index.php
Normal 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 展示产品($业务元数据,$产品元数据);
|
||||
|
||||
?>
|
||||
28
Main/ViewProduct/index.php.bak
Normal file
28
Main/ViewProduct/index.php.bak
Normal 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 展示产品($业务元数据,$产品元数据);
|
||||
|
||||
?>
|
||||
Reference in New Issue
Block a user