// +---------------------------------------------------------------------- declare(strict_types=1); namespace app\member\controller; use think\facade\Db; use think\facade\Log; use ywxapp\controller\MemberBase; use ywxapp\model\Card as CardModel; use app\member\validate\Card as CardValidate; /** * 会员卡密充值(充值中心 -> 卡密充值) * * 业务闭环: * 1) 会员在「卡密充值」页输入卡号 + 密码 * 2) redeem() 校验:卡密存在 / status=0或1(未用)/ 未删除 * 3) 事务内:钱包余额 += 面值、累计充值 += 面值;user_bill 记充值流水;卡密标记 status=2、use_time=now、绑定 uid * 4) 一次性用完即焚,重复兑换同一卡密会提示已使用 */ class Card extends MemberBase { protected $noNeedLogin = []; protected $noNeedVerify = ['*']; protected function initialize() { // 卡密表自愈(补齐 batch_no 等扩展列) \ywxapp\model\Card::ensureSchema(); } /** * 卡密充值页 */ public function exchange() { return $this->view->fetch(); } /** * 兑换卡密(Ajax POST) */ public function redeem() { if (!($this->request->isAjax() && $this->request->isPost())) { $this->result->error('访问错误'); } $user = $this->auth->model; if (empty($user)) { $this->result->error('请先登录', 401); } $post = $this->request->only(['cardno', 'password'], 'post'); $validate = new CardValidate(); if (!$validate->scene('redeem')->check($post)) { $this->result->error($validate->getError()); } try { $result = CardModel::redeem((int)$user->uid, trim($post['cardno']), trim($post['password'])); } catch (\Throwable $e) { Log::error('[Card] redeem failed: ' . $e->getMessage()); $this->result->error('兑换失败:' . $e->getMessage()); } if ($result['success']) { $this->result->success($result['data'] ?? [], $result['msg']); } $this->result->error($result['msg']); } /** * 我的兑换记录(Ajax GET,会员中心内页) */ public function records() { $user = $this->auth->model; if (empty($user)) { $this->result->error('请先登录', 401); } $page = $this->request->param('page/d', 1); $limit = $this->request->param('limit/d', 15); if ($this->request->isAjax()) { $list = CardModel::where('uid', (int)$user->uid) ->where('status', CardModel::STATUS_USED) ->where('delete_at', 0) ->order('use_time', 'desc') ->paginate(['page' => $page, 'list_rows' => $limit]); $items = $list->items(); foreach ($items as &$row) { $row['use_time_text'] = $row['use_time'] > 0 ? date('Y-m-d H:i:s', $row['use_time']) : ''; } unset($row); $this->result->setCount($list->total())->success($items); } return $this->view->fetch(); } }