<?php
$nosecu = true;
include("./includes/common.php");
if($conf['forcelogin'] == 1 && !$islogin2) exit('{"code":-1,"msg":"请先登录后上传"}');
$act=isset($_GET['act'])?daddslashes($_GET['act']):null;

if(!checkRefererHost())exit('{"code":403}');

@header('Content-Type: application/json; charset=UTF-8');

if($islogin2 && $userrow['level']>0){
	$conf['upload_limit']=0;
	$conf['videoreview']=0;
	$conf['type_block']=null;
	$conf['name_block']=null;
}

switch($act){
case 'pre_upload':
	if(!$_POST['csrf_token'] || $_POST['csrf_token']!=$_SESSION['csrf_token'])exit('{"code":-1,"msg":"CSRF TOKEN ERROR"}');
	// 允许游客上传（uid=0），登录后自动关联到账号
	$name = trim(htmlspecialchars($_POST['name']));
	$hash = trim($_POST['hash']);
	$size = intval($_POST['size']);
	$show = isset($_POST['show']) ? intval($_POST['show']) : 1;
	$hide = ($show===1)?0:1;
	$ispwd = intval($_POST['ispwd']);
	$pwd = $ispwd==1?trim(htmlspecialchars($_POST['pwd'])):null;
	$folder_id = isset($_POST['folder_id']) ? intval($_POST['folder_id']) : 0;
	if($folder_id < 0) $folder_id = 0;
	if($folder_id > 0){
		if(!$islogin2) exit('{"code":-1,"msg":"请登录后选择文件夹"}');
		$folderRow = $DB->getRow("SELECT folder_id FROM pre_folder WHERE folder_id=:fid AND uid=:uid LIMIT 1", [':fid'=>$folder_id, ':uid'=>$uid]);
		if(!$folderRow) exit('{"code":-1,"msg":"目标文件夹不存在或无权限"}');
	}
	$name = str_replace(['/','\\',':','*','"','<','>','|','?'],'',$name);
	if(empty($name))exit('{"code":-1,"msg":"文件名不能为空"}');
	if(!preg_match('/^[0-9a-z]{32}$/i', $hash))exit('{"code":-1,"msg":"hash error"}');
	if($ispwd==1 && !empty($pwd)){
		if (!preg_match('/^[a-zA-Z0-9]+$/', $pwd)) {
			exit('{"code":-1,"msg":"文件密码只能为字母和数字"}');
		}
	}
	$ext=get_file_ext($name);
	if($conf['type_block']){
		$type_block = explode('|',$conf['type_block']);
		if(in_array($ext,$type_block)){
			exit('{"code":-1,"msg":"文件上传失败，不支持上传该格式文件","error":"block"}');
		}
	}
	if($conf['name_block']){
		$name_block = explode('|',$conf['name_block']);
		foreach($name_block as $row){
			if(strpos($name,$row)!==false){
				exit('{"code":-1,"msg":"文件上传失败","error":"block"}');
			}
		}
	}
	$limit_size = intval($conf['upload_size']);
	if($limit_size > 0 && $size > $limit_size * 1024 * 1024){
		exit('{"code":-1,"msg":"上传文件大小限制'.$limit_size.'MB"}');
	}
	if($islogin2){
		$user = $DB->getRow("SELECT * FROM pre_user WHERE uid=:uid LIMIT 1", [':uid'=>$uid]);
		if($user){
            $quota = check_user_quota($user);
            if($quota['code'] !== 0){
                exit('{"code":-1,"msg":"'.$quota['msg'].'，请联系管理员"}');
            }

            if ($user['storage_limit'] > 0 && ($user['storage_used'] + $size) > ($user['storage_limit'] * 1024 * 1024)) {
                exit('{"code":-1,"msg":"存储空间不足，无法上传该文件"}');
            }
		}
	}
	if($conf['upload_limit']>0){
		$thisday = date("Y-m-d 00:00:00");
		if($islogin2){
			$ipcount=$DB->getColumn("SELECT count(*) from pre_file WHERE uid='$uid' AND addtime>='".$thisday."'");
		}else{
			$ipcount=$DB->getColumn("SELECT count(*) from pre_file WHERE ip='$clientip' AND addtime>='".$thisday."'");
		}
		if($ipcount>$conf['upload_limit']){
			exit('{"code":-1,"msg":"你今天上传文件的数量已超过限制"}');
		}
	}
	if(!$islogin2){
		$guest_token = get_guest_token();
	}
	$row = $DB->getRow("SELECT * FROM pre_file WHERE hash=:hash", [':hash'=>$hash]);
	if($row){
		// 如果文件已存在，检查权限并更新显示状态
		$is_owner = false;
		if ($islogin2 && $row['uid'] == $uid) {
			$is_owner = true;
		} elseif (!$islogin2) {
			// 游客检查session中的fileids和cookie
			$session_ids = $_SESSION['fileids'] ?? [];
			$cookie_ids = get_guest_file_ids();
			// Check if file has guest_token
			$has_token = isset($row['guest_token']) && $row['guest_token'] === $guest_token;
			if (in_array($row['id'], $session_ids) || in_array($row['id'], $cookie_ids) || $has_token) {
				$is_owner = true;
			}
		}

		if ($is_owner && $row['hide'] != $hide) {
			$DB->exec("UPDATE pre_file SET hide=:hide WHERE id=:id", [':hide' => $hide, ':id' => $row['id']]);
		}
		

		if (!$islogin2 && $is_owner && empty($row['guest_token'])) {
			$DB->exec("UPDATE pre_file SET guest_token=:token WHERE id=:id", [':token'=>$guest_token, ':id'=>$row['id']]);
		}

		$_SESSION['fileids'][] = $row['id'];

		unset($_SESSION['csrf_token']);
		$result = ['code'=>1, 'msg'=>'本站已存在该文件', 'exists'=>1, 'hash'=>$hash, 'name'=>$name, 'size'=>$size, 'type'=>$ext, 'id'=>$row['id'], 'hide'=>$row['hide']];
		exit(json_encode($result));
	}

	if(\lib\StorHelper::is_cloud() && $conf['uploadfile_type'] == 1){
		$param = $stor->getUploadParam($hash, $name, $limit_size * 1024 * 1024);
		if(!$param)exit('{"code":-1,"msg":"获取上传参数失败","errmsg":"'.$stor->errmsg().'"}');
		$upload_data = [
			'chunks' => 1,
			'name' => $name,
			'hash' => $hash,
			'size' => $size,
			'ext' => $ext,
			'hide' => $hide,
			'pwd' => $pwd,
			'folder_id' => $folder_id,
			'guest_token' => $guest_token ?? null
		];
		$_SESSION['upload'] = $upload_data;
		$_SESSION['upload_sessions'][$hash] = $upload_data;
		$result = ['code'=>0, 'third'=>true, 'hash'=>$hash, 'url'=>$param['url'], 'post'=>$param['post']];
		exit(json_encode($result));
	}else{
		$chunksize = 8 * 1024 * 1024; //分块上传，每块大小
		$chunks = ceil($size / $chunksize);
		$upload_data = [
			'chunks' => $chunks,
			'name' => $name,
			'hash' => $hash,
			'size' => $size,
			'ext' => $ext,
			'hide' => $hide,
			'pwd' => $pwd,
			'folder_id' => $folder_id,
			'guest_token' => $guest_token ?? null
		];
		$_SESSION['upload'] = $upload_data;
		$_SESSION['upload_sessions'][$hash] = $upload_data;
		$result = ['code'=>0, 'third'=>false, 'hash'=>$hash, 'chunksize'=>$chunksize, 'chunks'=>$chunks];
		exit(json_encode($result));
	}
break;

case 'upload_part':
	if(!isset($_FILES['file']))exit('{"code":-1,"msg":"请选择文件"}');
	

    $is_mobile = false; 

    
	if((!isset($_POST['csrf_token']) || $_POST['csrf_token']!=$_SESSION['csrf_token'])){

        $hash = trim($_POST['hash']);
        $valid_session = false;
        if(isset($_SESSION['upload_sessions'][$hash]) || (isset($_SESSION['upload']) && $_SESSION['upload']['hash'] == $hash)){
            $valid_session = true;
        }
        
        if(!$valid_session){
            exit('{"code":-1,"msg":"CSRF TOKEN ERROR"}');
        }
    }
	// 允许游客上传（uid=0），登录后自动关联到账号
	$chunk = intval($_POST['chunk']);
	$hash = trim($_POST['hash']);
	
	$session_data = null;
	if(isset($_SESSION['upload_sessions'][$hash])) {
		$session_data = $_SESSION['upload_sessions'][$hash];
	} elseif(isset($_SESSION['upload']) && $_SESSION['upload']['hash'] == $hash) {
		$session_data = $_SESSION['upload'];
	}

	if(!$session_data){
		exit('{"code":-1,"msg":"参数校验失败，请刷新页面重试"}');
	}
	


	if(!preg_match('/^[0-9a-z]{32}$/i', $hash))exit('{"code":-1,"msg":"hash error"}');
	$chunks = intval($session_data['chunks']);
	$ext = $session_data['ext'];
    $guest_token = isset($session_data['guest_token']) ? $session_data['guest_token'] : null;
	if($chunks > 1){
		$tempFile = sys_get_temp_dir() . '/' . $hash. '.part'.$chunk;
		if(!move_uploaded_file($_FILES['file']['tmp_name'], $tempFile)){
			exit('{"code":-1,"msg":"文件第'.$chunk.'分块上传失败"}');
		}
		if($chunks == $chunk){
			$savePathTemp = file_part_merge($hash, $chunks);
			$real_hash = md5_file($savePathTemp);
			$real_size = filesize($savePathTemp);
			$result = $stor->savefile($hash, $savePathTemp, minetype($ext));
			if(!$result)exit('{"code":-1,"msg":"文件上传失败","error":"stor","errmsg":"'.$stor->errmsg().'"}');
		}else{
			$result = ['code'=>0, 'chunk'=>$chunk];
			exit(json_encode($result));
		}
	}else{
		$real_hash = md5_file($_FILES['file']['tmp_name']);
		$real_size = filesize($_FILES['file']['tmp_name']);
		$result = $stor->upload($hash, $_FILES['file']['tmp_name'], minetype($ext));
		if(!$result)exit('{"code":-1,"msg":"文件上传失败","error":"stor","errmsg":"'.$stor->errmsg().'"}');
	}

	$size = $session_data['size'];
	if($real_size != $size){
		exit('{"code":-1,"msg":"文件大小校验失败"}');
	}
	if($real_hash != $hash){
		exit('{"code":-1,"msg":"文件MD5校验失败"}');
	}



	$name = $session_data['name'];
	$hide = $session_data['hide'];
	$pwd = $session_data['pwd'];
	$folder_id = isset($session_data['folder_id']) ? intval($session_data['folder_id']) : 0;
	if($folder_id < 0) $folder_id = 0;
	if($folder_id > 0){
		if(!$islogin2) exit('{"code":-1,"msg":"请登录后选择文件夹"}');
		$folderRow = $DB->getRow("SELECT folder_id FROM pre_folder WHERE folder_id=:fid AND uid=:uid LIMIT 1", [':fid'=>$folder_id, ':uid'=>$uid]);
		if(!$folderRow) exit('{"code":-1,"msg":"目标文件夹不存在或无权限"}');
	}

	$row = $DB->getRow("SELECT * FROM pre_file WHERE hash=:hash", [':hash'=>$hash]);
	if($row){
		if(isset($_SESSION['upload_sessions'][$hash])) unset($_SESSION['upload_sessions'][$hash]);
		if(isset($_SESSION['upload']) && $_SESSION['upload']['hash']==$hash) unset($_SESSION['upload']);
		

        if ($guest_token && empty($row['guest_token']) && $row['uid'] == 0) {

            $session_ids = $_SESSION['fileids'] ?? [];
            $cookie_ids = get_guest_file_ids();
            if (in_array($row['id'], $session_ids) || in_array($row['id'], $cookie_ids)) {
                $DB->exec("UPDATE pre_file SET guest_token=:token WHERE id=:id", [':token'=>$guest_token, ':id'=>$row['id']]);
            }
        }
        
		$_SESSION['fileids'][] = $row['id'];

		$result = ['code'=>1, 'msg'=>'本站已存在该文件', 'exists'=>1, 'hash'=>$hash, 'name'=>$name, 'size'=>$size, 'type'=>$ext, 'id'=>$row['id']];
		exit(json_encode($result));
	}

	$sds = $DB->exec("INSERT INTO `pre_file` (`name`,`type`,`size`,`hash`,`addtime`,`ip`,`hide`,`pwd`,`uid`,`folder_id`,`guest_token`) values (:name,:type,:size,:hash,NOW(),:ip,:hide,:pwd,:uid,:folder_id,:guest_token)", [':name'=>$name, ':type'=>$ext, ':size'=>$size, ':hash'=>$hash, ':ip'=>$clientip, ':hide'=>$hide, ':pwd'=>$pwd, ':uid'=>($uid?$uid:0), ':folder_id'=>$folder_id, ':guest_token'=>$guest_token]);
	if(!$sds)exit('{"code":-1,"msg":"上传失败'.$DB->error().'","error":"database"}');
	$id = $DB->lastInsertId();
	
	if($uid){
		$DB->exec("UPDATE pre_user SET storage_used=storage_used+:size WHERE uid=:uid", [':size'=>$size, ':uid'=>$uid]);
	}

    $type_image = explode('|',$conf['type_image']);
    $type_video = explode('|',$conf['type_video']);
    if($conf['green_check']>0 && in_array($ext,$type_image)){
        if(checkImage($hash, $ext)){
            $DB->exec("UPDATE `pre_file` SET `block`=1 WHERE `id`='{$id}' LIMIT 1");
        }
    }
    if($conf['videoreview']==1 && in_array($ext,$type_video)){
        $DB->exec("UPDATE `pre_file` SET `block`=2 WHERE `id`='{$id}' LIMIT 1");
    }
    
    $_SESSION['fileids'][] = $id;
    if(isset($_SESSION['upload_sessions'][$hash])) unset($_SESSION['upload_sessions'][$hash]);
    if(isset($_SESSION['upload']) && $_SESSION['upload']['hash']==$hash) unset($_SESSION['upload']);
    
    $result = ['code'=>1, 'msg'=>'文件上传成功！', 'exists'=>0, 'hash'=>$hash, 'name'=>$name, 'size'=>$size, 'type'=>$ext, 'id'=>$id, 'hide'=>$hide];
    exit(json_encode($result));
break;

case 'complete_upload':
	// 允许游客上传（uid=0），登录后自动关联到账号
	$hash = trim($_POST['hash']);
    

	if((!isset($_POST['csrf_token']) || $_POST['csrf_token']!=$_SESSION['csrf_token'])){
        $valid_session = false;
        if(isset($_SESSION['upload_sessions'][$hash]) || (isset($_SESSION['upload']) && $_SESSION['upload']['hash'] == $hash)){
            $valid_session = true;
        }
        if(!$valid_session){
            exit('{"code":-1,"msg":"CSRF TOKEN ERROR"}');
        }
    }
	
	$session_data = null;
	if(isset($_SESSION['upload_sessions'][$hash])) {
		$session_data = $_SESSION['upload_sessions'][$hash];
	} elseif(isset($_SESSION['upload']) && $_SESSION['upload']['hash'] == $hash) {
		$session_data = $_SESSION['upload'];
	}

	if(!$session_data){
		exit('{"code":-1,"msg":"参数校验失败，请刷新页面重试"}');
	}
	if(!preg_match('/^[0-9a-z]{32}$/i', $hash))exit('{"code":-1,"msg":"hash error"}');
	
	if(!$stor->exists($hash)){
		exit('{"code":-1,"msg":"文件上传失败","error":"stor","errmsg":"'.$stor->errmsg().'"}');
	}

	$name = $session_data['name'];
	$size = $session_data['size'];
	$ext = $session_data['ext'];
	$hide = $session_data['hide'];
	$pwd = $session_data['pwd'];
	$folder_id = isset($session_data['folder_id']) ? intval($session_data['folder_id']) : 0;
	if($folder_id < 0) $folder_id = 0;
	if($folder_id > 0){
		if(!$islogin2) exit('{"code":-1,"msg":"请登录后选择文件夹"}');
		$folderRow = $DB->getRow("SELECT folder_id FROM pre_folder WHERE folder_id=:fid AND uid=:uid LIMIT 1", [':fid'=>$folder_id, ':uid'=>$uid]);
		if(!$folderRow) exit('{"code":-1,"msg":"目标文件夹不存在或无权限"}');
	}
    $guest_token = isset($session_data['guest_token']) ? $session_data['guest_token'] : null;

	$row = $DB->getRow("SELECT * FROM pre_file WHERE hash=:hash", [':hash'=>$hash]);
	if($row){
		if(isset($_SESSION['upload_sessions'][$hash])) unset($_SESSION['upload_sessions'][$hash]);
		if(isset($_SESSION['upload']) && $_SESSION['upload']['hash']==$hash) unset($_SESSION['upload']);
		

        if ($guest_token && empty($row['guest_token']) && $row['uid'] == 0) {
            $session_ids = $_SESSION['fileids'] ?? [];
            $cookie_ids = get_guest_file_ids();
            if (in_array($row['id'], $session_ids) || in_array($row['id'], $cookie_ids)) {
                $DB->exec("UPDATE pre_file SET guest_token=:token WHERE id=:id", [':token'=>$guest_token, ':id'=>$row['id']]);
            }
        }
        
		$_SESSION['fileids'][] = $row['id'];
		$result = ['code'=>1, 'msg'=>'本站已存在该文件', 'exists'=>1, 'hash'=>$hash, 'name'=>$name, 'size'=>$size, 'type'=>$ext, 'id'=>$row['id']];
		exit(json_encode($result));
	}

	$sds = $DB->exec("INSERT INTO `pre_file` (`name`,`type`,`size`,`hash`,`addtime`,`ip`,`hide`,`pwd`,`uid`,`folder_id`,`guest_token`) values (:name,:type,:size,:hash,NOW(),:ip,:hide,:pwd,:uid,:folder_id,:guest_token)", [':name'=>$name, ':type'=>$ext, ':size'=>$size, ':hash'=>$hash, ':ip'=>$clientip, ':hide'=>$hide, ':pwd'=>$pwd, ':uid'=>($uid?$uid:0), ':folder_id'=>$folder_id, ':guest_token'=>$guest_token]);
	if(!$sds)exit('{"code":-1,"msg":"上传失败'.$DB->error().'","error":"database"}');
	$id = $DB->lastInsertId();

	$type_image = explode('|',$conf['type_image']);
	$type_video = explode('|',$conf['type_video']);
	if($conf['green_check']>0 && in_array($ext,$type_image)){
		if(checkImage($hash, $ext)){
			$DB->exec("UPDATE `pre_file` SET `block`=1 WHERE `id`='{$id}' LIMIT 1");
		}
	}
	if($conf['videoreview']==1 && in_array($ext,$type_video)){
		$DB->exec("UPDATE `pre_file` SET `block`=2 WHERE `id`='{$id}' LIMIT 1");
	}
	
	$_SESSION['fileids'][] = $id;

    if(isset($_SESSION['upload_sessions'][$hash])) unset($_SESSION['upload_sessions'][$hash]);
    if(isset($_SESSION['upload']) && $_SESSION['upload']['hash']==$hash) unset($_SESSION['upload']);
    
    $result = ['code'=>1, 'msg'=>'文件上传成功！', 'exists'=>0, 'hash'=>$hash, 'name'=>$name, 'size'=>$size, 'type'=>$ext, 'id'=>$id, 'hide'=>$hide];
    exit(json_encode($result));
break;

case 'toggle_hide':
    if(!$_POST['csrf_token'] || $_POST['csrf_token']!=$_SESSION['csrf_token'])exit('{"code":-1,"msg":"CSRF TOKEN ERROR"}');
    $id = intval($_POST['id']);
    
    $row = $DB->getRow("SELECT * FROM pre_file WHERE id=:id", [':id'=>$id]);
    if(!$row) exit('{"code":-1,"msg":"文件不存在"}');
    

    $is_owner = false;
    if ($islogin2 && $row['uid'] == $uid) {
        $is_owner = true;
    } elseif (!$islogin2) {
        $session_ids = $_SESSION['fileids'] ?? [];
        $cookie_ids = get_guest_file_ids();
        $has_token = isset($row['guest_token']) && $row['guest_token'] === get_guest_token();
        if (in_array($row['id'], $session_ids) || in_array($row['id'], $cookie_ids) || $has_token) {
            $is_owner = true;
        }
    }
    
    if (!$is_owner) exit('{"code":-1,"msg":"无权限"}');
    
    $new_hide = $row['hide'] == 1 ? 0 : 1;
    $DB->exec("UPDATE pre_file SET hide=:hide WHERE id=:id", [':hide'=>$new_hide, ':id'=>$id]);
    
    exit(json_encode(['code'=>0, 'msg'=>'操作成功', 'hide'=>$new_hide]));
break;

case 'sync_guest_ids':
    $ids = isset($_POST['ids']) ? $_POST['ids'] : [];
    if (!is_array($ids)) exit('{"code":-1, "msg":"Invalid data"}');
    

    if (!isset($_SESSION['fileids'])) $_SESSION['fileids'] = [];
    $newIds = [];
    foreach($ids as $id) {
        $id = intval($id);
        if ($id > 0) {
            if (!in_array($id, $_SESSION['fileids'])) {
                $_SESSION['fileids'][] = $id;
            }
            $newIds[] = $id;
        }
    }
    

    if (count($newIds) > 0) {
        add_guest_file_id($newIds);
    }
    
    exit(json_encode(['code'=>0, 'msg'=>'同步成功', 'count'=>count($newIds)]));
break;

case 'deleteFile':
	$hash = isset($_POST['hash'])?trim($_POST['hash']):exit('{"code":-1,"msg":"no hash"}');
	if(!$_POST['csrf_token'] || $_POST['csrf_token']!=$_SESSION['csrf_token'])exit('{"code":-1,"msg":"CSRF TOKEN ERROR"}');
	if(!preg_match('/^[0-9a-z]{32}$/i', $hash))exit('{"code":-1,"msg":"hash error"}');
	$row = $DB->getRow("SELECT * FROM `pre_file` WHERE `hash`=:hash", [':hash'=>$hash]);
	if(!$row)exit('{"code":-1,"msg":"文件不存在"}');
    
    // Check permission
    $has_permission = false;
    if ($islogin2 && $row['uid'] == $uid) {
        $has_permission = true;
    } elseif (!$islogin2) {
        $has_token = isset($row['guest_token']) && $row['guest_token'] === get_guest_token();
        if ($has_token || (isset($_SESSION['fileids']) && in_array($row['id'], $_SESSION['fileids'])) || in_array($row['id'], get_guest_file_ids())) {
            $has_permission = true;
        }
    }
    
	if(!$has_permission)exit('{"code":-1,"msg":"无权限"}');
	if($row['block']==1)exit('{"code":-1,"msg":"文件已被冻结，无法删除"}');
	if(!$islogin2 && strtotime($row['addtime'])<strtotime("-7 days"))exit('{"code":-1,"msg":"无法删除7天前的文件"}');
	$result = $stor->delete($row['hash']);
	$sql = "DELETE FROM pre_file WHERE id=:id";
	if($DB->exec($sql, [':id'=>$row['id']])){
        if($row['uid']>0){
            $DB->exec("UPDATE pre_user SET storage_used=storage_used-:size WHERE uid=:uid AND storage_used>=:size", [':size'=>$row['size'], ':uid'=>$row['uid']]);
        }
        exit('{"code":0,"msg":"删除文件成功！"}');
    }
	else exit('{"code":-1,"msg":"删除文件失败['.$DB->error().']"}');
break;

case 'create_card':
	if(!$_POST['csrf_token'] || $_POST['csrf_token']!=$_SESSION['csrf_token'])exit('{"code":-1,"msg":"CSRF TOKEN ERROR"}');
	if(!$islogin)exit('{"code":-1,"msg":"请先登录"}');
	
	$card_type = isset($_POST['card_type']) ? $_POST['card_type'] : 'storage';
	$storage_quota = isset($_POST['storage_quota']) ? intval($_POST['storage_quota']) : 0;
	$traffic_quota = isset($_POST['traffic_quota']) ? intval($_POST['traffic_quota']) : 0;
	$expire_days = isset($_POST['expire_days']) ? intval($_POST['expire_days']) : 0;
	$remark = isset($_POST['remark']) ? trim(htmlspecialchars($_POST['remark'])) : null;
	$count = isset($_POST['count']) ? intval($_POST['count']) : 1;
	
	if($count < 1 || $count > 100) {
		exit('{"code":-1,"msg":"生成数量必须在1-100之间"}');
	}
	
	if($card_type == 'storage' && $storage_quota <= 0) {
		exit('{"code":-1,"msg":"存储空间卡密必须设置存储配额"}');
	}
	
	if($card_type == 'traffic' && $traffic_quota <= 0) {
		exit('{"code":-1,"msg":"流量配额卡密必须设置流量配额"}');
	}
	
	if($card_type == 'both' && ($storage_quota <= 0 || $traffic_quota <= 0)) {
		exit('{"code":-1,"msg":"存储+流量卡密必须同时设置存储和流量配额"}');
	}
	
	$success_count = 0;
	for($i = 0; $i < $count; $i++) {
		$card_id = create_card($card_type, $storage_quota, $traffic_quota, $expire_days, $remark, $uid);
		if($card_id) {
			$success_count++;
		}
	}
	
	exit('{"code":0,"msg":"成功生成'.$success_count.'张卡密"}');
break;

case 'disable_card':
	if(!$_POST['csrf_token'] || $_POST['csrf_token']!=$_SESSION['csrf_token'])exit('{"code":-1,"msg":"CSRF TOKEN ERROR"}');
	if(!$islogin)exit('{"code":-1,"msg":"请先登录"}');
	
	$card_id = isset($_POST['id']) ? intval($_POST['id']) : 0;
	if($card_id <= 0) {
		exit('{"code":-1,"msg":"卡密ID错误"}');
	}
	
	$result = disable_card($card_id, $uid);
	if($result) {
		exit('{"code":0,"msg":"禁用成功"}');
	} else {
		exit('{"code":-1,"msg":"禁用失败"}');
	}
break;

case 'enable_card':
	if(!$_POST['csrf_token'] || $_POST['csrf_token']!=$_SESSION['csrf_token'])exit('{"code":-1,"msg":"CSRF TOKEN ERROR"}');
	if(!$islogin)exit('{"code":-1,"msg":"请先登录"}');
	
	$card_id = isset($_POST['id']) ? intval($_POST['id']) : 0;
	if($card_id <= 0) {
		exit('{"code":-1,"msg":"卡密ID错误"}');
	}
	
	$result = $DB->exec("UPDATE `pre_card` SET `status`=0 WHERE `id`=:id", [':id'=>$card_id]);
	if($result) {
		exit('{"code":0,"msg":"启用成功"}');
	} else {
		exit('{"code":-1,"msg":"启用失败"}');
	}
break;

case 'delete_card':
	if(!$_POST['csrf_token'] || $_POST['csrf_token']!=$_SESSION['csrf_token'])exit('{"code":-1,"msg":"CSRF TOKEN ERROR"}');
	if(!$islogin)exit('{"code":-1,"msg":"请先登录"}');
	
	$card_id = isset($_POST['id']) ? intval($_POST['id']) : 0;
	if($card_id <= 0) {
		exit('{"code":-1,"msg":"卡密ID错误"}');
	}
	
	$result = delete_card($card_id);
	if($result) {
		exit('{"code":0,"msg":"删除成功"}');
	} else {
		exit('{"code":-1,"msg":"删除失败"}');
	}
break;

case 'card_statistics':
	$total = $DB->getColumn("SELECT COUNT(*) FROM pre_card");
	$unused = $DB->getColumn("SELECT COUNT(*) FROM pre_card WHERE status=0");
	$used = $DB->getColumn("SELECT COUNT(*) FROM pre_card WHERE status=1");
	$disabled = $DB->getColumn("SELECT COUNT(*) FROM pre_card WHERE status=2");
	
	exit(json_encode([
		'code' => 0,
		'total' => $total,
		'unused' => $unused,
		'used' => $used,
		'disabled' => $disabled
	]));
break;

case 'redeem_card':
	if(!$_POST['csrf_token'] || $_POST['csrf_token']!=$_SESSION['csrf_token'])exit('{"code":-1,"msg":"CSRF TOKEN ERROR"}');
	if(!$islogin2)exit('{"code":-1,"msg":"请先登录"}');
	
	$card_code = isset($_POST['card_code']) ? trim($_POST['card_code']) : '';
	if(empty($card_code)) {
		exit('{"code":-1,"msg":"请输入卡密代码"}');
	}
	
	$result = redeem_card($card_code, $uid);
	
	if($result['code'] === 0) {
		$resource_info = get_user_resource_info($uid);
		exit(json_encode([
			'code' => 0,
			'msg' => $result['msg'],
			'storage_added' => $result['storage_added'],
			'traffic_added' => $result['traffic_added'],
			'resource_info' => $resource_info
		]));
	} else {
		exit(json_encode([
			'code' => $result['code'],
			'msg' => $result['msg']
		]));
	}
break;

default:
	exit('{"code":-4,"msg":"No Act"}');
break;
}
