<?php
declare(strict_types=1);
require __DIR__.'/src/bootstrap.php';
if(!cfg('installed'))redirect('install.php');
$page=$_GET['page']??'dashboard';
if($page==='login'){
 if(Auth::user())redirect('index.php');
 $err='';if($_SERVER['REQUEST_METHOD']==='POST'){require_csrf();if(Auth::login(trim($_POST['username']??''),$_POST['password']??''))redirect('index.php');$err='用户名或密码错误';}
 ?><!doctype html><html lang="zh-CN"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title>登录</title><link rel="stylesheet" href="assets/app.css"><body><main class="login"><section class="panel"><h1>支付宝账单中心</h1><p class="muted">使用管理员或核账员账号登录</p><?php if($err):?><div class="alert bad"><?=e($err)?></div><?php endif?><form method="post"><input type="hidden" name="_csrf" value="<?=csrf()?>"><label>用户名<input name="username" autocomplete="username" required autofocus></label><label>密码<input type="password" name="password" autocomplete="current-password" required></label><button class="primary">登录</button></form></section></main></body></html><?php exit;
}
if($page==='logout'){unset($_SESSION['uid']);session_regenerate_id(true);redirect('?page=login');}
$user=Auth::requireLogin();$admin=$user['role']==='admin';$allowed=Auth::accountIds($user);
function accountScope(array &$where,array &$args,string $alias='b'):void{global $user,$allowed;if($user['role']!=='admin'){if(!$allowed){$where[]='1=0';return;}$where[]=$alias.'.account_id IN ('.implode(',',array_fill(0,count($allowed),'?')).')';array_push($args,...$allowed);}}
function uploadText(string $field,int $max=1048576):?string{if(empty($_FILES[$field])||$_FILES[$field]['error']===UPLOAD_ERR_NO_FILE)return null;if($_FILES[$field]['error']!==UPLOAD_ERR_OK||$_FILES[$field]['size']>$max)throw new RuntimeException('证书上传失败或超过 1MB');$v=file_get_contents($_FILES[$field]['tmp_name']);if(!str_contains($v,'BEGIN CERTIFICATE'))throw new RuntimeException('上传内容不是 PEM 证书');return $v;}
if($_SERVER['REQUEST_METHOD']==='POST'){
 require_csrf();$action=$_POST['action']??'';
 try{
  if($action==='bill_mark'){
   $id=(int)$_POST['id'];$w=['id=?'];$a=[$id];accountScope($w,$a,'b');$s=db()->prepare('UPDATE bills b SET is_checked=?,checked_by=?,checked_at=IF(?=1,NOW(),NULL),check_note=?,is_abnormal=?,abnormal_note=?,updated_at=NOW() WHERE '.implode(' AND ',$w));$checked=isset($_POST['is_checked'])?1:0;$s->execute([$checked,$user['id'],$checked,trim($_POST['check_note']??''),isset($_POST['is_abnormal'])?1:0,trim($_POST['abnormal_note']??''),...$a]);flash('ok','核对状态已保存');redirect('?page=bill&id='.$id);
  }
  if(in_array($action,['account_save','account_test','account_sync','user_save','settings_save'],true)&&!$admin)throw new RuntimeException('无权执行此操作');
  if($action==='account_save'){
   $id=(int)($_POST['id']??0);$private=trim($_POST['private_key']??'');$old=null;if($id){$s=db()->prepare('SELECT * FROM alipay_accounts WHERE id=?');$s->execute([$id]);$old=$s->fetch();if(!$old)throw new RuntimeException('账号不存在');}
   if(!$private&&!$old)throw new RuntimeException('首次添加必须填写应用私钥');
   $appCert=uploadText('app_cert')??($old['app_cert']??null);$aliCert=uploadText('alipay_cert')??($old['alipay_cert']??null);$rootCert=uploadText('root_cert')??($old['root_cert']??null);$mode=$_POST['auth_mode']==='certificate'?'certificate':'public_key';
   if($mode==='certificate'&&(!$appCert||!$aliCert||!$rootCert))throw new RuntimeException('证书模式需要上传三份证书');
   $vals=[trim($_POST['name']),trim($_POST['app_id']),$mode,$private?Crypto::encrypt($private):$old['private_key_enc'],trim($_POST['alipay_public_key']??'')?:($old['alipay_public_key']??null),$appCert,$aliCert,$rootCert,isset($_POST['is_active'])?1:0];
   if($id){$q=db()->prepare('UPDATE alipay_accounts SET name=?,app_id=?,auth_mode=?,private_key_enc=?,alipay_public_key=?,app_cert=?,alipay_cert=?,root_cert=?,is_active=?,updated_at=NOW() WHERE id=?');$q->execute([...$vals,$id]);}else{$q=db()->prepare('INSERT INTO alipay_accounts(name,app_id,auth_mode,private_key_enc,alipay_public_key,app_cert,alipay_cert,root_cert,is_active,created_at,updated_at) VALUES(?,?,?,?,?,?,?,?,?,NOW(),NOW())');$q->execute($vals);$id=(int)db()->lastInsertId();}
   flash('ok','支付宝账号已保存；私钥不会在页面回显');redirect('?page=account&id='.$id);
  }
  if($action==='account_test'){$s=db()->prepare('SELECT * FROM alipay_accounts WHERE id=?');$s->execute([(int)$_POST['id']]);$a=$s->fetch();if(!$a)throw new RuntimeException('账号不存在');$r=(new AlipayClient($a))->test();flash('ok','连接成功，已取得 '.$r['date'].' 的账单下载地址');redirect('?page=accounts');}
  if($action==='account_sync'){$r=SyncService::account((int)$_POST['id'],$_POST['bill_date'],'manual');flash('ok',"同步完成：{$r['date']}，处理 {$r['rows']} 条");redirect('?page=logs');}
  if($action==='user_save'){
   $id=(int)($_POST['id']??0);$pass=$_POST['password']??'';$role=$_POST['role']==='admin'?'admin':'auditor';if(!$id&&strlen($pass)<10)throw new RuntimeException('新用户密码至少 10 位');
   if($id){$sql='UPDATE users SET username=?,display_name=?,role=?,is_active=?,updated_at=NOW()'.($pass?',password_hash=?':'').' WHERE id=?';$v=[trim($_POST['username']),trim($_POST['display_name']),$role,isset($_POST['is_active'])?1:0];if($pass)$v[]=password_hash($pass,PASSWORD_DEFAULT);$v[]=$id;db()->prepare($sql)->execute($v);}else{db()->prepare('INSERT INTO users(username,password_hash,display_name,role,is_active,created_at,updated_at) VALUES(?,?,?,?,1,NOW(),NOW())')->execute([trim($_POST['username']),password_hash($pass,PASSWORD_DEFAULT),trim($_POST['display_name']),$role]);$id=(int)db()->lastInsertId();}
   db()->prepare('DELETE FROM user_account_access WHERE user_id=?')->execute([$id]);if($role==='auditor')foreach($_POST['accounts']??[] as $aid)db()->prepare('INSERT IGNORE INTO user_account_access(user_id,account_id) VALUES(?,?)')->execute([$id,(int)$aid]);flash('ok','用户权限已保存');redirect('?page=users');
  }
  if($action==='settings_save'){if(!preg_match('/^\d{2}:\d{2}$/',$_POST['sync_time']))throw new RuntimeException('同步时间格式错误');save_setting('sync_time',$_POST['sync_time']);save_setting('sync_days_back',(string)max(1,min(7,(int)$_POST['sync_days_back'])));if(isset($_POST['rotate_token']))save_setting('cron_token',bin2hex(random_bytes(24)));flash('ok','系统设置已保存');redirect('?page=settings');}
 }catch(Throwable $e){flash('bad',$e->getMessage());redirect($_SERVER['HTTP_REFERER']??'index.php');}
}
$titles=['dashboard'=>'总览','bills'=>'账单查询','bill'=>'账单详情','accounts'=>'支付宝账号','account'=>'账号设置','logs'=>'同步日志','users'=>'用户与权限','user'=>'用户设置','settings'=>'系统设置'];$title=$titles[$page]??'账单中心';
?><!doctype html><html lang="zh-CN"><meta charset="utf-8"><meta name="viewport" content="width=device-width"><title><?=e($title)?> · 支付宝账单中心</title><link rel="stylesheet" href="assets/app.css"><body><div class="shell"><aside class="side"><div class="brand">支付宝账单中心</div><nav class="nav"><?php foreach(['dashboard'=>'总览','bills'=>'账单查询']+($admin?['accounts'=>'支付宝账号','logs'=>'同步日志','users'=>'用户权限','settings'=>'系统设置']:[]) as $k=>$v):?><a class="<?=$page===$k?'on':''?>" href="?page=<?=$k?>"><?=e($v)?></a><?php endforeach?><a href="?page=logout">退出登录</a></nav></aside><main class="content"><header class="top"><h1><?=e($title)?></h1><span><?=e($user['display_name'])?> · <?=$admin?'管理员':'核账员'?></span></header><?php if($f=$_SESSION['flash']??null):unset($_SESSION['flash']);?><div class="alert <?=e($f[0])?>"><?=e($f[1])?></div><?php endif?>
<?php if($page==='dashboard'):
 $start=$_GET['start']??date('Y-m-01');$end=$_GET['end']??date('Y-m-d',strtotime('-1 day'));$w=['b.bill_date BETWEEN ? AND ?'];$args=[$start,$end];accountScope($w,$args);$sql='SELECT COALESCE(SUM(IF(b.type="income",b.amount,0)),0) income,COALESCE(SUM(IF(b.type="refund",-b.amount,0)),0) refund,COALESCE(SUM(b.amount),0) net,COUNT(*) cnt,SUM(b.is_checked=0) pending,SUM(b.is_abnormal=1) abnormal FROM bills b WHERE '.implode(' AND ',$w);$s=db()->prepare($sql);$s->execute($args);$sum=$s->fetch();
 $w2=['b.bill_date BETWEEN ? AND ?'];$a2=[$start,$end];accountScope($w2,$a2);$s=db()->prepare('SELECT a.id,a.name,SUM(IF(b.type="income",b.amount,0)) income,SUM(IF(b.type="refund",-b.amount,0)) refund,COUNT(b.id) cnt,SUM(b.is_abnormal=1) abnormal FROM alipay_accounts a LEFT JOIN bills b ON b.account_id=a.id AND '.implode(' AND ',$w2).' GROUP BY a.id,a.name ORDER BY a.name');$s->execute($a2);$by=$s->fetchAll();?>
 <form class="panel actions"><label>开始<input type="date" name="start" value="<?=e($start)?>"></label><label>结束<input type="date" name="end" value="<?=e($end)?>"></label><input type="hidden" name="page" value="dashboard"><button class="primary">更新</button></form><div class="cards"><div class="card"><span class="muted">收入</span><b>¥<?=number_format((float)$sum['income'],2)?></b></div><div class="card"><span class="muted">退款</span><b>¥<?=number_format((float)$sum['refund'],2)?></b></div><div class="card"><span class="muted">净额</span><b>¥<?=number_format((float)$sum['net'],2)?></b></div><div class="card"><span class="muted">待核对 / 异常</span><b><?=number_format((int)$sum['pending'])?> / <?=number_format((int)$sum['abnormal'])?></b></div></div><section class="panel"><h3>账号汇总</h3><table><tr><th>支付宝账号</th><th>收入</th><th>退款</th><th>笔数</th><th>异常</th></tr><?php foreach($by as $r):?><tr><td><?=e($r['name'])?></td><td>¥<?=number_format((float)$r['income'],2)?></td><td>¥<?=number_format((float)$r['refund'],2)?></td><td><?=$r['cnt']?></td><td><?=$r['abnormal']?></td></tr><?php endforeach?></table></section>
<?php elseif($page==='bills'):
 $w=['1=1'];$args=[];accountScope($w,$args);foreach(['account_id'=>'b.account_id','type'=>'b.type','checked'=>'b.is_checked','abnormal'=>'b.is_abnormal'] as $k=>$col)if(isset($_GET[$k])&&$_GET[$k]!==''){$w[]="$col=?";$args[]=$_GET[$k];}if(!empty($_GET['start'])){$w[]='b.bill_date>=?';$args[]=$_GET['start'];}if(!empty($_GET['end'])){$w[]='b.bill_date<=?';$args[]=$_GET['end'];}if(isset($_GET['amount'])&&$_GET['amount']!==''){$w[]='ABS(b.amount)=?';$args[]=(float)$_GET['amount'];}if(!empty($_GET['q'])){$w[]='(b.alipay_trade_no LIKE ? OR b.merchant_order_no LIKE ?)';$args[]='%'.$_GET['q'].'%';$args[]='%'.$_GET['q'].'%';}$p=max(1,(int)($_GET['p']??1));$count=db()->prepare('SELECT COUNT(*) FROM bills b WHERE '.implode(' AND ',$w));$count->execute($args);$total=(int)$count->fetchColumn();$s=db()->prepare('SELECT b.*,a.name account_name FROM bills b JOIN alipay_accounts a ON a.id=b.account_id WHERE '.implode(' AND ',$w).' ORDER BY b.occurred_at DESC,b.id DESC LIMIT '.(($p-1)*50).',50');$s->execute($args);$rows=$s->fetchAll();$aw=['is_active=1'];$aa=[];if(!$admin){$aw[]=$allowed?'id IN ('.implode(',',array_fill(0,count($allowed),'?')).')':'1=0';$aa=$allowed;}$as=db()->prepare('SELECT id,name FROM alipay_accounts WHERE '.implode(' AND ',$aw));$as->execute($aa);$accounts=$as->fetchAll();?>
 <form class="panel filters"><input type="hidden" name="page" value="bills"><label>支付宝账号<select name="account_id"><option value="">全部</option><?php foreach($accounts as $a):?><option value="<?=$a['id']?>" <?=($_GET['account_id']??'')==$a['id']?'selected':''?>><?=e($a['name'])?></option><?php endforeach?></select></label><label>开始日期<input type="date" name="start" value="<?=e($_GET['start']??date('Y-m-01'))?>"></label><label>结束日期<input type="date" name="end" value="<?=e($_GET['end']??date('Y-m-d',strtotime('-1 day')))?>"></label><label>金额<input name="amount" value="<?=e($_GET['amount']??'')?>"></label><label>交易号 / 订单号<input name="q" value="<?=e($_GET['q']??'')?>"></label><label>类型<select name="type"><option value="">全部</option><?php foreach(['income'=>'收入','expense'=>'支出','refund'=>'退款','other'=>'其他'] as $k=>$v):?><option value="<?=$k?>" <?=($_GET['type']??'')===$k?'selected':''?>><?=$v?></option><?php endforeach?></select></label><label>核对<select name="checked"><option value="">全部</option><option value="0" <?=($_GET['checked']??'')==='0'?'selected':''?>>未核对</option><option value="1" <?=($_GET['checked']??'')==='1'?'selected':''?>>已核对</option></select></label><label>异常<select name="abnormal"><option value="">全部</option><option value="0" <?=($_GET['abnormal']??'')==='0'?'selected':''?>>正常</option><option value="1" <?=($_GET['abnormal']??'')==='1'?'selected':''?>>异常</option></select></label><button class="primary">筛选</button></form><section class="panel"><div class="muted">共 <?=number_format($total)?> 条，每页 50 条</div><table><tr><th>时间</th><th>账号</th><th>类型</th><th>金额</th><th>支付宝交易号 / 商户订单号</th><th>状态</th></tr><?php foreach($rows as $r):?><tr><td class="nowrap"><?=e($r['occurred_at'])?></td><td><?=e($r['account_name'])?></td><td><?=['income'=>'收入','expense'=>'支出','refund'=>'退款','other'=>'其他'][$r['type']]?></td><td class="money <?=$r['amount']>=0?'in':'out'?>"><?=number_format((float)$r['amount'],2)?></td><td><a href="?page=bill&id=<?=$r['id']?>"><?=e($r['alipay_trade_no']?:'—')?><br><span class="muted small"><?=e($r['merchant_order_no']?:'—')?></span></a></td><td><?=$r['is_checked']?'<span class="tag ok">已核对</span>':'<span class="tag">待核对</span>'?> <?=$r['is_abnormal']?'<span class="tag bad">异常</span>':''?></td></tr><?php endforeach?></table><div class="pager"><?php if($p>1):?><a class="button secondary" href="?<?=e(http_build_query(array_merge($_GET,['p'=>$p-1])))?>">上一页</a><?php endif?><?php if($p*50<$total):?><a class="button secondary" href="?<?=e(http_build_query(array_merge($_GET,['p'=>$p+1])))?>">下一页</a><?php endif?></div></section>
<?php elseif($page==='bill'):
 $w=['b.id=?'];$args=[(int)$_GET['id']];accountScope($w,$args);$s=db()->prepare('SELECT b.*,a.name account_name,u.display_name checked_name FROM bills b JOIN alipay_accounts a ON a.id=b.account_id LEFT JOIN users u ON u.id=b.checked_by WHERE '.implode(' AND ',$w));$s->execute($args);$r=$s->fetch();if(!$r):http_response_code(404);echo '账单不存在';else:?>
 <section class="panel"><div class="grid"><div><span class="muted">账号</span><h3><?=e($r['account_name'])?></h3></div><div><span class="muted">金额</span><h3>¥<?=number_format((float)$r['amount'],2)?></h3></div><div><span class="muted">支付宝交易号</span><p><?=e($r['alipay_trade_no']?:'—')?></p></div><div><span class="muted">商户订单号</span><p><?=e($r['merchant_order_no']?:'—')?></p></div><div><span class="muted">发生时间</span><p><?=e($r['occurred_at'])?></p></div><div><span class="muted">对方 / 摘要</span><p><?=e($r['counterparty'])?> · <?=e($r['subject'])?></p></div></div></section><form method="post" class="panel"><input type="hidden" name="_csrf" value="<?=csrf()?>"><input type="hidden" name="action" value="bill_mark"><input type="hidden" name="id" value="<?=$r['id']?>"><label><input style="display:inline;width:auto" type="checkbox" name="is_checked" <?=$r['is_checked']?'checked':''?>> 已核对</label><label>核对备注<textarea name="check_note"><?=e($r['check_note'])?></textarea></label><label><input style="display:inline;width:auto" type="checkbox" name="is_abnormal" <?=$r['is_abnormal']?'checked':''?>> 标记异常</label><label>异常说明<textarea name="abnormal_note"><?=e($r['abnormal_note'])?></textarea></label><button class="primary">保存核对结果</button></form>
<?php endif;?>
<?php elseif($page==='accounts'&&$admin):$rows=db()->query('SELECT * FROM alipay_accounts ORDER BY id')->fetchAll();?><div class="actions"><a class="button primary" href="?page=account">新增支付宝账号</a></div><section class="panel"><table><tr><th>名称 / APPID</th><th>模式</th><th>最近同步</th><th>状态</th><th>操作</th></tr><?php foreach($rows as $r):?><tr><td><?=e($r['name'])?><br><span class="muted"><?=e($r['app_id'])?></span></td><td><?=$r['auth_mode']==='certificate'?'证书':'公钥'?></td><td><?=e($r['last_sync_at']?:'尚未同步')?><br><span class="small muted"><?=e($r['last_sync_message'])?></span></td><td><span class="tag <?=$r['is_active']?'ok':''?>"><?=$r['is_active']?'启用':'停用'?></span></td><td><div class="actions"><a class="button secondary" href="?page=account&id=<?=$r['id']?>">编辑</a><form method="post"><input type="hidden" name="_csrf" value="<?=csrf()?>"><input type="hidden" name="action" value="account_test"><input type="hidden" name="id" value="<?=$r['id']?>"><button>测试</button></form><form method="post"><input type="hidden" name="_csrf" value="<?=csrf()?>"><input type="hidden" name="action" value="account_sync"><input type="hidden" name="id" value="<?=$r['id']?>"><input type="date" name="bill_date" value="<?=date('Y-m-d',strtotime('-1 day'))?>" max="<?=date('Y-m-d',strtotime('-1 day'))?>"><button class="primary">立即同步</button></form></div></td></tr><?php endforeach?></table></section>
<?php elseif($page==='account'&&$admin):$r=['id'=>0,'name'=>'','app_id'=>'','auth_mode'=>'public_key','alipay_public_key'=>'','is_active'=>1];if(!empty($_GET['id'])){$s=db()->prepare('SELECT * FROM alipay_accounts WHERE id=?');$s->execute([(int)$_GET['id']]);$r=$s->fetch()?:$r;}?><form method="post" enctype="multipart/form-data" class="panel"><input type="hidden" name="_csrf" value="<?=csrf()?>"><input type="hidden" name="action" value="account_save"><input type="hidden" name="id" value="<?=$r['id']?>"><div class="grid"><label>账号名称<input name="name" value="<?=e($r['name'])?>" required></label><label>APPID<input name="app_id" value="<?=e($r['app_id'])?>" required></label><label>加签模式<select name="auth_mode"><option value="public_key" <?=$r['auth_mode']==='public_key'?'selected':''?>>普通公钥</option><option value="certificate" <?=$r['auth_mode']==='certificate'?'selected':''?>>证书</option></select></label><label><input style="display:inline;width:auto" type="checkbox" name="is_active" <?=$r['is_active']?'checked':''?>> 启用账号</label></div><label>应用私钥<textarea name="private_key" placeholder="<?=$r['id']?'已加密保存；留空表示不修改':'粘贴应用私钥'?>"></textarea><span class="small muted">保存后永不回显明文，只能重新填写。</span></label><label>支付宝公钥（普通公钥模式）<textarea name="alipay_public_key"><?=e($r['alipay_public_key'])?></textarea></label><div class="grid"><label>应用公钥证书（.crt / PEM）<input type="file" name="app_cert" accept=".crt,.pem"></label><label>支付宝公钥证书<input type="file" name="alipay_cert" accept=".crt,.pem"></label><label>支付宝根证书<input type="file" name="root_cert" accept=".crt,.pem"></label></div><p class="muted">已保存证书：应用 <?=$r['id']&&!empty($r['app_cert'])?'✓':'—'?>　支付宝 <?=$r['id']&&!empty($r['alipay_cert'])?'✓':'—'?>　根证书 <?=$r['id']&&!empty($r['root_cert'])?'✓':'—'?></p><button class="primary">保存账号</button></form>
<?php elseif($page==='logs'&&$admin):$rows=db()->query('SELECT l.*,a.name FROM sync_logs l JOIN alipay_accounts a ON a.id=l.account_id ORDER BY l.id DESC LIMIT 200')->fetchAll();?><section class="panel"><table><tr><th>开始时间</th><th>账号 / 日期</th><th>触发</th><th>结果</th><th>消息</th></tr><?php foreach($rows as $r):?><tr><td><?=e($r['started_at'])?></td><td><?=e($r['name'])?><br><?=e($r['bill_date'])?></td><td><?=e($r['trigger_type'])?></td><td><span class="tag <?=$r['status']==='success'?'ok':'bad'?>"><?=e($r['status'])?></span> <?=$r['rows_imported']?> 条</td><td><?=e($r['message'])?></td></tr><?php endforeach?></table></section>
<?php elseif($page==='users'&&$admin):$rows=db()->query('SELECT * FROM users ORDER BY id')->fetchAll();?><a class="button primary" href="?page=user">新增用户</a><section class="panel"><table><tr><th>用户名</th><th>显示名称</th><th>角色</th><th>状态</th><th></th></tr><?php foreach($rows as $r):?><tr><td><?=e($r['username'])?></td><td><?=e($r['display_name'])?></td><td><?=$r['role']==='admin'?'管理员':'核账员'?></td><td><?=$r['is_active']?'启用':'停用'?></td><td><a href="?page=user&id=<?=$r['id']?>">编辑</a></td></tr><?php endforeach?></table></section>
<?php elseif($page==='user'&&$admin):$r=['id'=>0,'username'=>'','display_name'=>'','role'=>'auditor','is_active'=>1];$selected=[];if(!empty($_GET['id'])){$s=db()->prepare('SELECT * FROM users WHERE id=?');$s->execute([(int)$_GET['id']]);$r=$s->fetch()?:$r;$s=db()->prepare('SELECT account_id FROM user_account_access WHERE user_id=?');$s->execute([$r['id']]);$selected=$s->fetchAll(PDO::FETCH_COLUMN);}$accounts=db()->query('SELECT id,name FROM alipay_accounts ORDER BY name')->fetchAll();?><form method="post" class="panel"><input type="hidden" name="_csrf" value="<?=csrf()?>"><input type="hidden" name="action" value="user_save"><input type="hidden" name="id" value="<?=$r['id']?>"><div class="grid"><label>用户名<input name="username" value="<?=e($r['username'])?>" required></label><label>显示名称<input name="display_name" value="<?=e($r['display_name'])?>" required></label><label>角色<select name="role"><option value="auditor" <?=$r['role']==='auditor'?'selected':''?>>核账员</option><option value="admin" <?=$r['role']==='admin'?'selected':''?>>管理员</option></select></label><label><input style="display:inline;width:auto" type="checkbox" name="is_active" <?=$r['is_active']?'checked':''?>> 启用</label></div><label>密码<input type="password" name="password" placeholder="<?=$r['id']?'留空表示不修改':'至少 10 位'?>"></label><h3>核账员可查看的支付宝账号</h3><?php foreach($accounts as $a):?><label><input style="display:inline;width:auto" type="checkbox" name="accounts[]" value="<?=$a['id']?>" <?=in_array($a['id'],$selected)?'checked':''?>> <?=e($a['name'])?></label><?php endforeach?><button class="primary">保存用户</button></form>
<?php elseif($page==='settings'&&$admin):$token=setting('cron_token');$cronUrl=rtrim(cfg('base_url'),'/').'/cron.php?token='.$token;?><form method="post" class="panel"><input type="hidden" name="_csrf" value="<?=csrf()?>"><input type="hidden" name="action" value="settings_save"><div class="grid"><label>每日同步时间<input type="time" name="sync_time" value="<?=e(setting('sync_time','03:20'))?>"></label><label>同步几天前账单<select name="sync_days_back"><?php for($i=1;$i<=7;$i++):?><option value="<?=$i?>" <?=setting('sync_days_back','1')==$i?'selected':''?>><?=$i?> 天前</option><?php endfor?></select></label></div><label><input style="display:inline;width:auto" type="checkbox" name="rotate_token"> 重新生成定时任务密钥（旧地址会立即失效）</label><button class="primary">保存设置</button></form><section class="panel"><h3>宝塔计划任务（只配置一次）</h3><p>类型选择“访问 URL”，执行周期设为每 5 分钟：</p><input readonly value="<?=e($cronUrl)?>"><p class="small muted">系统仅在设定时间前后 10 分钟执行，并使用文件锁防止重复任务。请妥善保管此地址。</p></section>
<?php else:http_response_code(404);?><section class="panel">页面不存在或无权访问。</section><?php endif?>
</main></div></body></html>
