chore: 重写初始提交(清空历史,整理后全量提交)

This commit is contained in:
ywxapp
2026-08-16 16:54:14 +08:00
commit 6c1a106bc1
1808 changed files with 238144 additions and 0 deletions
+136
View File
@@ -0,0 +1,136 @@
<?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\member;
use addon\wxchat\model\WxchatRealnameAuth;
use think\facade\Request;
use ywxapp\controller\FrontendBase;
/**
* 真人认证:多重认证 + AI 智能审核 + 人工复审
*/
class Auth extends FrontendBase
{
/**
* 提交认证资料
*/
public function submit()
{
$uid = $this->auth->uid;
$realName = trim((string) Request::post('real_name', ''));
$idCard = trim((string) Request::post('id_card', ''));
$frontImg = trim((string) Request::post('front_img', ''));
$backImg = trim((string) Request::post('back_img', ''));
$holdImg = trim((string) Request::post('hold_img', ''));
$faceImg = trim((string) Request::post('face_img', ''));
if (! $realName || strlen($idCard) < 15) {
$this->error('请填写真实姓名与证件号');
}
// 证件号脱敏存储(保留前4后4
$masked = substr($idCard, 0, 4) . str_repeat('*', max(0, strlen($idCard) - 8)) . substr($idCard, -4);
$data = [
'uid' => $uid,
'real_name' => $realName,
'id_card' => $masked,
'front_img' => $frontImg,
'back_img' => $backImg,
'hold_img' => $holdImg,
'face_img' => $faceImg,
'status' => 0,
'ai_result' => 0,
'ai_score' => 0,
'reject_reason' => '',
'update_at' => time(),
];
$exist = WxchatRealnameAuth::where('uid', $uid)->find();
if ($exist) {
$exist->save($data);
} else {
$data['create_at'] = time();
(new WxchatRealnameAuth())->save($data);
}
// 触发 AI 智能审核
$this->aiCheck($uid);
$this->success([], '已提交,审核中');
}
/**
* 我的认证状态(补充 AI 审核详情)
*/
public function status()
{
$uid = $this->auth->uid;
$auth = WxchatRealnameAuth::where('uid', $uid)->find();
$this->success([
'status' => $auth ? (int) $auth->status : -1,
'ai_result' => $auth ? (int) $auth->ai_result : 0,
'ai_score' => $auth ? (float) $auth->ai_score : 0,
'ai_detail' => $auth ? ($auth->ai_detail ?? '') : '',
'reject_reason' => $auth ? $auth->reject_reason : '',
]);
}
/**
* AI 智能审核(接入 AiAuditService:本地启发式 / 真实 HTTP 服务,可配置切换)
*/
private function aiCheck($uid)
{
$auth = WxchatRealnameAuth::where('uid', $uid)->find();
if (! $auth) {
return;
}
$result = \addon\wxchat\service\AiAuditService::audit([
'uid' => $uid,
'real_name' => $auth->real_name,
'id_card' => $auth->id_card,
'front_img' => $auth->front_img,
'back_img' => $auth->back_img,
'hold_img' => $auth->hold_img,
'face_img' => $auth->face_img,
]);
$auth->ai_score = $result['score'];
$auth->ai_result = $result['result']; // 1-通过初筛 2-不通过
$auth->ai_detail = $result['detail'] ?? '';
$auth->save();
}
/**
* 人工复审(后台调用,建议加管理员鉴权)
*/
public function review()
{
$id = (int) Request::post('id', 0);
$pass = (int) Request::post('pass', 0);
$reason = trim((string) Request::post('reason', ''));
$auth = WxchatRealnameAuth::find($id);
if (! $auth) {
$this->error('记录不存在');
}
$auth->status = $pass ? 1 : 2;
$auth->reject_reason = $pass ? '' : $reason;
$auth->reviewer_id = $this->auth->uid ?? 0;
$auth->review_at = time();
$auth->save();
// 审核通过 -> 标记资料真人认证
if ($pass) {
\ywxapp\model\MemberProfile::where('uid', $auth->uid)
->update(['is_realname' => 1]);
}
$this->success([], $pass ? '已通过' : '已驳回');
}
}
+133
View File
@@ -0,0 +1,133 @@
<?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\member;
use addon\wxchat\model\WxchatFamily;
use addon\wxchat\model\WxchatFamilyMember;
use think\facade\Db;
use think\facade\Request;
use ywxapp\controller\FrontendBase;
use ywxapp\model\MemberProfile as ProfileModel;
/**
* 家族:创建 / 加入 / 退出 / 成员 / 家族群聊(复用 group 消息通道)
*/
class Family extends FrontendBase
{
/**
* 创建家族
*/
public function create()
{
$uid = $this->auth->uid;
$name = trim((string) Request::post('name', ''));
$avatar = trim((string) Request::post('avatar', ''));
$notice = trim((string) Request::post('notice', ''));
if (! $name) {
$this->error('请填写家族名称');
}
$family = new WxchatFamily();
$family->name = $name;
$family->avatar = $avatar;
$family->owner_uid = $uid;
$family->notice = $notice;
$family->member_count = 1;
$family->status = 1;
$family->create_at = time();
$family->save();
$member = new WxchatFamilyMember();
$member->family_id = $family->id;
$member->uid = $uid;
$member->role = 2; // 族长
$member->join_at = time();
$member->save();
$this->success(['family_id' => $family->id], '创建成功');
}
/**
* 加入家族
*/
public function join()
{
$uid = $this->auth->uid;
$familyId = (int) Request::post('family_id', 0);
$family = WxchatFamily::where('id', $familyId)->where('status', 1)->find();
if (! $family) {
$this->error('家族不存在或已解散');
}
if (WxchatFamilyMember::where('family_id', $familyId)->where('uid', $uid)->find()) {
$this->error('你已在家族中');
}
$member = new WxchatFamilyMember();
$member->family_id = $familyId;
$member->uid = $uid;
$member->role = 0;
$member->join_at = time();
$member->save();
$family->where('id', $familyId)->inc('member_count')->update();
$this->success([], '已加入');
}
/**
* 退出家族(族长退出则解散家族)
*/
public function quit()
{
$uid = $this->auth->uid;
$familyId = (int) Request::post('family_id', 0);
$member = WxchatFamilyMember::where('family_id', $familyId)->where('uid', $uid)->find();
if (! $member) {
$this->error('你不在该家族');
}
if ($member->role == 2) {
// 族长退出 -> 解散
WxchatFamily::where('id', $familyId)->update(['status' => 0]);
WxchatFamilyMember::where('family_id', $familyId)->delete();
} else {
$member->delete();
WxchatFamily::where('id', $familyId)->where('member_count', '>', 0)->dec('member_count')->update();
}
$this->success([], '已退出');
}
/**
* 家族信息
*/
public function info()
{
$familyId = (int) Request::get('family_id', 0);
$family = WxchatFamily::where('id', $familyId)->where('status', 1)->find();
if (! $family) {
$this->error('家族不存在');
}
$this->success($family);
}
/**
* 成员列表(含昵称/头像)
*/
public function members()
{
$familyId = (int) Request::get('family_id', 0);
$list = Db::name('wxchat_family_members')->alias('m')
->join('user u', 'u.uid = m.uid')
->join('user_profile p', 'p.uid = m.uid', 'left')
->where('m.family_id', $familyId)
->field('m.uid,m.role,m.join_at,u.nickname,u.avatar,p.gender,p.residecity')
->order('m.role', 'desc')
->select();
$this->success($list);
}
}
+228
View File
@@ -0,0 +1,228 @@
<?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\member;
use addon\wxchat\model\WxchatRoom;
use addon\wxchat\model\WxchatRoomMember;
use addon\wxchat\model\WxchatRoomMic;
use think\facade\Db;
use think\facade\Request;
use ywxapp\controller\FrontendBase;
/**
* 语音 / 视频房:创建 / 加入 / 麦位管理 / 弹幕开关
* 房间公屏聊天复用 group 消息通道(session_id = room_id
*/
class Room extends FrontendBase
{
/**
* 房间列表(直播中按热度)
*/
public function lists()
{
$type = (int) Request::get('type', 0);
$query = WxchatRoom::where('status', 1);
if ($type) {
$query->where('type', $type);
}
$list = $query->order('hot', 'desc')->order('create_at', 'desc')
->paginate(20, false, ['page' => (int) Request::get('page', 1)]);
$this->success([
'list' => $list->items(),
'total' => $list->total(),
'pages' => $list->lastPage(),
]);
}
/**
* 创建房间(自动初始化麦位 + 房主上 0 号麦)
*/
public function create()
{
$uid = $this->auth->uid;
$title = trim((string) Request::post('title', ''));
$type = (int) Request::post('type', 1);
$cover = trim((string) Request::post('cover', ''));
$notice = trim((string) Request::post('notice', ''));
$micCount = max(2, min(20, (int) Request::post('mic_count', 8)));
if (! $title) {
$this->error('请填写房间标题');
}
$room = new WxchatRoom();
$room->title = $title;
$room->type = $type;
$room->owner_uid = $uid;
$room->cover = $cover;
$room->notice = $notice;
$room->mic_count = $micCount;
$room->danmaku_on = 1;
$room->status = 1;
$room->create_at = time();
$room->save();
// 初始化麦位
$mics = [];
for ($i = 0; $i < $micCount; $i++) {
$mics[] = [
'room_id' => $room->id,
'mic_index' => $i,
'uid' => $i == 0 ? $uid : 0,
'status' => $i == 0 ? 1 : 0,
'create_at' => time(),
];
}
(new WxchatRoomMic())->saveAll($mics);
// 房主进入
$member = new WxchatRoomMember();
$member->room_id = $room->id;
$member->uid = $uid;
$member->role = 1; // 主播
$member->join_at = time();
$member->save();
$this->success(['room_id' => $room->id], '开播成功');
}
/**
* 进入房间(观众)
*/
public function join()
{
$uid = $this->auth->uid;
$roomId = (int) Request::post('room_id', 0);
$room = WxchatRoom::where('id', $roomId)->where('status', 1)->find();
if (! $room) {
$this->error('房间不存在或已关闭');
}
if (! WxchatRoomMember::where('room_id', $roomId)->where('uid', $uid)->find()) {
$member = new WxchatRoomMember();
$member->room_id = $roomId;
$member->uid = $uid;
$member->role = 0;
$member->join_at = time();
$member->save();
$room->where('id', $roomId)->inc('hot')->update();
}
$mics = WxchatRoomMic::where('room_id', $roomId)->order('mic_index')->select();
$this->success([
'room' => $room,
'mics' => $mics,
]);
}
/**
* 离开房间
*/
public function leave()
{
$uid = $this->auth->uid;
$roomId = (int) Request::post('room_id', 0);
WxchatRoomMember::where('room_id', $roomId)->where('uid', $uid)->delete();
// 释放麦位
WxchatRoomMic::where('room_id', $roomId)->where('uid', $uid)->update(['uid' => 0, 'status' => 0]);
$room = WxchatRoom::find($roomId);
if ($room && $room->owner_uid == $uid) {
$room->status = 0;
$room->save();
}
$this->success([], '已离开');
}
/**
* 上麦
*/
public function micUp()
{
$uid = $this->auth->uid;
$roomId = (int) Request::post('room_id', 0);
$micIdx = (int) Request::post('mic_index', 0);
$mic = WxchatRoomMic::where('room_id', $roomId)->where('mic_index', $micIdx)->find();
if (! $mic) {
$this->error('麦位不存在');
}
if ($mic->status == 2) {
$this->error('该麦位已锁定');
}
if ($mic->status == 1 && $mic->uid != $uid) {
$this->error('麦位已被占用');
}
$mic->uid = $uid;
$mic->status = 1;
$mic->save();
$this->success([], '上麦成功');
}
/**
* 下麦
*/
public function micDown()
{
$uid = $this->auth->uid;
$roomId = (int) Request::post('room_id', 0);
$micIdx = (int) Request::post('mic_index', 0);
$mic = WxchatRoomMic::where('room_id', $roomId)->where('mic_index', $micIdx)->where('uid', $uid)->find();
if (! $mic) {
$this->error('你不在该麦位');
}
$mic->uid = 0;
$mic->status = 0;
$mic->save();
$this->success([], '下麦成功');
}
/**
* 锁定 / 解锁 / 禁麦(房主)
*/
public function micManage()
{
$uid = $this->auth->uid;
$roomId = (int) Request::post('room_id', 0);
$micIdx = (int) Request::post('mic_index', 0);
$op = (int) Request::post('op', 2); // 2锁定 0解锁 3禁麦
$room = WxchatRoom::find($roomId);
if (! $room || $room->owner_uid != $uid) {
$this->error('仅房主可操作');
}
WxchatRoomMic::where('room_id', $roomId)->where('mic_index', $micIdx)
->update(['status' => $op, 'uid' => $op == 0 ? 0 : Db::raw('uid')]);
$this->success([], '操作成功');
}
/**
* 弹幕开关(房主房间级 / 或用户快捷关闭)
*/
public function danmaku()
{
$uid = $this->auth->uid;
$roomId = (int) Request::post('room_id', 0);
$on = (int) Request::post('on', 1);
$room = WxchatRoom::find($roomId);
if (! $room) {
$this->error('房间不存在');
}
// 房主可切换房间弹幕总开关;普通用户仅对自己快捷关闭(落到个人设置)
if ($room->owner_uid == $uid) {
$room->danmaku_on = $on ? 1 : 0;
$room->save();
$this->success(['danmaku_on' => $room->danmaku_on], '房间弹幕已' . ($on ? '开启' : '关闭'));
}
// 非房主:更新个人弹幕总开关(设置-互动-弹幕管理)
$pc = \ywxapp\model\MemberProfile::where('uid', $uid)->value('privacy_config');
$pc = $pc ? json_decode($pc, true) : [];
$pc = is_array($pc) ? $pc : [];
$pc['danmaku_global'] = $on ? 1 : 0;
\ywxapp\model\MemberProfile::where('uid', $uid)
->update(['privacy_config' => json_encode($pc, JSON_UNESCAPED_UNICODE)]);
$this->success(['danmaku_global' => $on], '个人弹幕已' . ($on ? '开启' : '关闭'));
}
}
+147
View File
@@ -0,0 +1,147 @@
<?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\member;
use addon\wxchat\model\WxchatTask;
use addon\wxchat\model\WxchatTaskRecord;
use think\facade\Db;
use think\facade\Request;
use ywxapp\controller\FrontendBase;
use ywxapp\service\WalletService;
/**
* 任务赚钱体系:每日任务 / 邀请好友 / 完善资料 -> 领取金币
*/
class Task extends FrontendBase
{
/**
* 任务列表(附带我的进度)
*/
public function lists()
{
$uid = $this->auth->uid;
$tasks = WxchatTask::where('status', 1)
->order('sort', 'asc')
->select();
$records = WxchatTaskRecord::where('uid', $uid)->column('*', 'task_id');
$list = [];
foreach ($tasks as $t) {
$rec = $records[$t->id] ?? null;
$list[] = [
'task_id' => $t->id,
'title' => $t->title,
'type' => $t->type,
'desc' => $t->desc,
'reward_coins' => $t->reward_coins,
'target' => $t->target,
'progress' => $rec ? (int) $rec['progress'] : 0,
'status' => $rec ? (int) $rec['status'] : 0, // 0进行中 1待领 2已领
];
}
$this->success(['list' => $list, 'coins' => WalletService::getCoins($uid)]);
}
/**
* 进度上报(由业务事件调用:发布动态/完善资料/邀请成功等)
*/
public function progress()
{
$uid = $this->auth->uid;
$taskId = (int) Request::post('task_id', 0);
$step = max(1, (int) Request::post('step', 1));
$task = WxchatTask::where('id', $taskId)->where('status', 1)->find();
if (! $task) {
$this->error('任务不存在');
}
$rec = WxchatTaskRecord::where('uid', $uid)->where('task_id', $taskId)->find();
if (! $rec) {
$rec = new WxchatTaskRecord();
$rec->uid = $uid;
$rec->task_id = $taskId;
$rec->progress = 0;
$rec->status = 0;
$rec->reward_coins = 0;
$rec->create_at = time();
}
if ($rec->status == 2) {
$this->error('任务已领取');
}
$rec->progress = min($task->target, $rec->progress + $step);
if ($rec->progress >= $task->target) {
$rec->status = 1; // 完成待领
}
$rec->update_at = time();
$rec->save();
$this->success(['status' => $rec->status, 'progress' => $rec->progress], '进度已更新');
}
/**
* 领取奖励(发放金币)
*/
public function claim()
{
$uid = $this->auth->uid;
$taskId = (int) Request::post('task_id', 0);
$task = WxchatTask::where('id', $taskId)->find();
if (! $task) {
$this->error('任务不存在');
}
$rec = WxchatTaskRecord::where('uid', $uid)->where('task_id', $taskId)->find();
if (! $rec || $rec->status == 0) {
$this->error('任务未完成');
}
if ($rec->status == 2) {
$this->error('奖励已领取');
}
$reward = $task->reward_coins;
WalletService::incCoins($uid, $reward, '完成任务:' . $task->title);
$rec->status = 2;
$rec->reward_coins = $reward;
$rec->update_at = time();
$rec->save();
$this->success(['coins' => WalletService::getCoins($uid), 'reward' => $reward], '领取成功');
}
/**
* 邀请好友(模拟:记录一次有效邀请并推进邀请任务)
*/
public function invite()
{
$uid = $this->auth->uid;
$task = WxchatTask::where('type', 'invite')->where('status', 1)->order('id')->find();
if (! $task) {
$this->success([], '暂无邀请任务');
return;
}
// 上报一次邀请进度(真实环境应在被邀请人注册成功后触发)
$rec = WxchatTaskRecord::where('uid', $uid)->where('task_id', $task->id)->find();
if (! $rec) {
$rec = new WxchatTaskRecord();
$rec->uid = $uid;
$rec->task_id = $task->id;
$rec->progress = 0;
$rec->status = 0;
$rec->reward_coins = 0;
$rec->create_at = time();
}
if ($rec->status == 2) {
$this->success([], '邀请任务已完成');
return;
}
$rec->progress = min($task->target, $rec->progress + 1);
if ($rec->progress >= $task->target) {
$rec->status = 1;
}
$rec->update_at = time();
$rec->save();
$this->success(['progress' => $rec->progress, 'status' => $rec->status], '邀请成功');
}
}