208 lines
7.3 KiB
PHP
208 lines
7.3 KiB
PHP
<?php
|
|
// +----------------------------------------------------------------------
|
|
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
|
// +----------------------------------------------------------------------
|
|
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
|
// +----------------------------------------------------------------------
|
|
// | Author: ywxapp<admin@ywxapp.cn>
|
|
// +----------------------------------------------------------------------
|
|
declare (strict_types = 1);
|
|
|
|
namespace addon\wxchat\controller\api;
|
|
|
|
use addon\wxchat\model\WxchatTaskRecord;
|
|
use think\facade\Db;
|
|
use think\facade\Request;
|
|
use ywxapp\controller\FrontendBase;
|
|
use ywxapp\service\WalletService;
|
|
|
|
/**
|
|
* Task 类
|
|
*
|
|
* @author ywxapp <admin@ywxapp.cn>
|
|
*/
|
|
class Task extends FrontendBase
|
|
{
|
|
protected $noNeedLogin = [];
|
|
protected $noNeedVerify = ['*'];
|
|
|
|
|
|
protected function initialize()
|
|
{
|
|
if ($this->auth->isLogin) {
|
|
$this->uid = $this->auth->model->uid;
|
|
}
|
|
}
|
|
|
|
private $uid = 0;
|
|
|
|
/**
|
|
* 每日任务定义(硬编码;进度基于真实统计,领取记录防重复)
|
|
* status: 0 进行中 / 1 可领取 / 2 今日已领取
|
|
*/
|
|
private function definitions() : array
|
|
{
|
|
return [
|
|
['id' => 1, 'key' => 'login', 'title' => '每日登录', 'desc' => '每天登录 App 领取奖励', 'reward' => 5, 'target' => 1, 'icon' => 'calendar'],
|
|
['id' => 2, 'key' => 'publish', 'title' => '发布动态', 'desc' => '今日发布 1 条动态', 'reward' => 10, 'target' => 1, 'icon' => 'camera'],
|
|
['id' => 3, 'key' => 'like', 'title' => '点赞互动', 'desc' => '今日点赞 3 条动态', 'reward' => 8, 'target' => 3, 'icon' => 'heart'],
|
|
['id' => 4, 'key' => 'share', 'title' => '分享动态', 'desc' => '今日分享 1 条动态', 'reward' => 6, 'target' => 1, 'icon' => 'share'],
|
|
['id' => 5, 'key' => 'profile', 'title' => '完善资料', 'desc' => '完善个人交友资料', 'reward' => 20, 'target' => 1, 'icon' => 'person'],
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 任务列表(含真实进度 + 领取状态)
|
|
*/
|
|
public function index()
|
|
{
|
|
$uid = $this->uid;
|
|
$today = strtotime('today');
|
|
$tasks = $this->definitions();
|
|
$result = [];
|
|
foreach ($tasks as $t) {
|
|
$current = $this->calcProgress($t['key'], $uid);
|
|
$done = $current >= $t['target'];
|
|
$received = WxchatTaskRecord::where('uid', $uid)
|
|
->where('task_id', $t['id'])
|
|
->where('status', 2)
|
|
->where('update_at', '>=', $today)
|
|
->count();
|
|
$status = $received > 0 ? 2 : ($done ? 1 : 0);
|
|
$result[] = [
|
|
'id' => $t['id'],
|
|
'title' => $t['title'],
|
|
'desc' => $t['desc'],
|
|
'icon' => $t['icon'],
|
|
'reward' => $t['reward'],
|
|
'target' => $t['target'],
|
|
'current' => min($current, $t['target']),
|
|
'status' => $status,
|
|
];
|
|
}
|
|
$this->success([
|
|
'list' => $result,
|
|
'coins' => WalletService::getCoins($uid),
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* 领取任务奖励(金币发放,每日每任务一次)
|
|
*/
|
|
public function receive()
|
|
{
|
|
$uid = $this->uid;
|
|
$taskId = (int) Request::post('task_id');
|
|
$task = null;
|
|
foreach ($this->definitions() as $t) {
|
|
if ($t['id'] == $taskId) {
|
|
$task = $t;
|
|
break;
|
|
}
|
|
}
|
|
if (! $task) {
|
|
$this->error('任务不存在');
|
|
}
|
|
|
|
// 进度校验
|
|
$current = $this->calcProgress($task['key'], $uid);
|
|
if ($current < $task['target']) {
|
|
$this->error('任务未完成');
|
|
}
|
|
|
|
// 今日是否已领取
|
|
$today = strtotime('today');
|
|
$got = WxchatTaskRecord::where('uid', $uid)
|
|
->where('task_id', $taskId)
|
|
->where('status', 2)
|
|
->where('update_at', '>=', $today)
|
|
->count();
|
|
if ($got > 0) {
|
|
$this->error('今日已领取');
|
|
}
|
|
|
|
// 发放金币
|
|
WalletService::incCoins($uid, (int) $task['reward'], "任务奖励:{$task['title']}");
|
|
|
|
// 写领取记录;利用 UNIQUE(uid,task_id) 实现每日重置(次日触发冲突后更新)
|
|
try {
|
|
(new WxchatTaskRecord())->save([
|
|
'uid' => $uid,
|
|
'task_id' => $taskId,
|
|
'progress' => $task['target'],
|
|
'status' => 2,
|
|
'reward_coins' => $task['reward'],
|
|
'create_at' => time(),
|
|
'update_at' => time(),
|
|
]);
|
|
} catch (\Throwable $e) {
|
|
WxchatTaskRecord::where('uid', $uid)
|
|
->where('task_id', $taskId)
|
|
->update([
|
|
'progress' => $task['target'],
|
|
'status' => 2,
|
|
'reward_coins' => $task['reward'],
|
|
'update_at' => time(),
|
|
]);
|
|
}
|
|
|
|
$this->success([
|
|
'coins_left' => WalletService::getCoins($uid),
|
|
'reward' => $task['reward'],
|
|
], '领取成功');
|
|
}
|
|
|
|
/**
|
|
* 计算任务当前进度(基于真实业务统计)
|
|
*/
|
|
private function calcProgress(string $key, int $uid) : int
|
|
{
|
|
$today = strtotime('today');
|
|
try {
|
|
switch ($key) {
|
|
case 'login':
|
|
return 1;
|
|
case 'publish':
|
|
return (int) Db::name('wxchat_moments')
|
|
->where('user_id', $uid)
|
|
->where('create_at', '>=', $today)
|
|
->count();
|
|
case 'like':
|
|
return (int) Db::name('wxchat_moment_likes')
|
|
->where('user_id', $uid)
|
|
->where('create_at', '>=', $today)
|
|
->count();
|
|
case 'share':
|
|
return (int) Db::name('wxchat_moment_shares')
|
|
->where('user_id', $uid)
|
|
->where('create_at', '>=', $today)
|
|
->count();
|
|
case 'profile':
|
|
$user = Db::name('member')->where('uid', $uid)->field('nickname,avatar')->find();
|
|
$profile = Db::name('member_profile')->where('uid', $uid)
|
|
->field('bio,birthday,gender')->find();
|
|
$score = 0;
|
|
if (! empty($user['nickname'])) {
|
|
$score++;
|
|
}
|
|
if (! empty($user['avatar'])) {
|
|
$score++;
|
|
}
|
|
if (! empty($profile['bio'])) {
|
|
$score++;
|
|
}
|
|
if (! empty($profile['birthday'])) {
|
|
$score++;
|
|
}
|
|
if (! empty($profile['gender'])) {
|
|
$score++;
|
|
}
|
|
return $score >= 4 ? 1 : 0;
|
|
}
|
|
} catch (\Throwable $e) {
|
|
return 0;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|