This commit is contained in:
commie
2026-02-21 08:21:05 +08:00
parent 1a7f4bc98a
commit 6586f27c9e
21 changed files with 245 additions and 967 deletions
@@ -43,6 +43,7 @@ class BalanceLogController extends BaseController{
} }
$item->_type= $item->type; $item->_type= $item->type;
$item->type= $BalanceTypeList[$item->type]; $item->type= $BalanceTypeList[$item->type];
return $item;
}); });
return $this->success(__('successful'),$list); return $this->success(__('successful'),$list);
} }
+88
View File
@@ -0,0 +1,88 @@
<?php
namespace app\api\controller;
use app\model\User as UserModel;
use app\model\UserRemark as UserRemarkModel;
use app\model\GroupRemark as GroupRemarkModel;
use support\Request;
use support\Response;
use taoser\facade\Validate;
use support\think\Db;
use hg\apidoc\annotation as Apidoc;
/**
* 通讯录
*/
class ContactController extends BaseController{
/**
* 不需要鉴权的方法
* @var array
*/
public $noNeedAuth = ['*'];
/**
* 无需登录及鉴权的方法
* @var array
*/
public $noNeedLogin = [];
/**
* @Apidoc\Title("获取用户好友列表")
* @Apidoc\Method("GET")
*/
function get_friend_list(Request $request): Response
{
$current_user = \support\Jwt::getUser();
$user_id = $current_user->id;
$userID = idEncode($user_id);
$res = $request->IM->friend()->getFriendList($userID,1,10000);
return $this->success('ok',$res['data']['friendsInfo']);
}
/**
* @Apidoc\Title("好友信息")
* @Apidoc\Method("GET")
* @Apidoc\Param("userID", type="string",require=true, desc="用户ID")
*/
function get_friend_info(Request $request): Response
{
$userID = Input('userID');
if(!$userID){
return $this->error('UserID is Empty');
}
$userID = idDecode($userID);
$res = \app\model\User::where('id',$userID)->find();
return $this->success('ok',$res);
}
/**
* @Apidoc\Title("批量查询好友信息")
* @Apidoc\Method("GET")
* @Apidoc\Param("userIDs", type="string",require=true, desc="用户ID列表,逗号分隔")
*/
function get_friends_info(Request $request): Response
{
$userIDs = Input('userIDs');
if(!$userIDs){
return $this->error('UserID is Empty');
}
//$userIDs = explode(',',$userIDs);
//$userIDs = idDecode($userIDs);
//$current_user = \support\Jwt::getUser();
//$user_id = $current_user->id;
//$userID = idEncode($user_id);
$res = \app\model\User::whereIn('userID',$userIDs)->select();
return $this->success('ok',$res);
}
/**
* @Apidoc\Title("批量查询好友信息")
* @Apidoc\Method("GET")
* @Apidoc\Param("userIDs", type="string",require=true, desc="用户ID列表,逗号分隔")
*/
function get_friends_roles(Request $request): Response
{
$userIDs = Input('userIDs');
if(!$userIDs){
return $this->error('UserID is Empty');
}
$res = Db::name('user')->whereIn('userID',$userIDs)->column('role_id','userID');
return $this->success('ok',$res);
}
}
@@ -10,6 +10,8 @@ use hg\apidoc\annotation as Apidoc;
/** /**
* 我的产品 * 我的产品
* @Apidoc\NotParse()
* @Apidoc\NotDebug()
*/ */
class ProductOrderController extends BaseController{ class ProductOrderController extends BaseController{
/** /**
@@ -1,253 +0,0 @@
<?php
namespace app\api\controller;
use app\model\WorkRecord as WorkRecordModel;
use app\model\Questionnaire as QuestionnaireModel;
use app\model\Product as ProductModel;
use app\model\ProductOrder as ProductOrderModel;
use app\model\BalanceLog;
use support\think\Db;
use taoser\facade\Validate;
use hg\apidoc\annotation as Apidoc;
/**
* 问卷
* @Apidoc\NotParse()
* @Apidoc\NotDebug()
*/
class QuestionnaireController extends BaseController{
/**
* 不需要鉴权的方法
* @var array
*/
public $noNeedAuth = ['*'];
public $noNeedLogin = [];
/**
* 简介
* @Apidoc\Method("GET")
*/
public function info(){
$user = \support\Jwt::getUser();
return $this->success(__('successful'),[
'success_count' => WorkRecordModel::where('status',\app\enum\ServerStatus::COMPLETE->value)
->where('user_id',$user->id)
->count('id'),
'audit_count' => WorkRecordModel::where('status',\app\enum\ServerStatus::AUDITING->value)
->where('user_id',$user->id)
->count('id'),
]);
}
/**
* 列表
* @Apidoc\Query("kw", type="string", require=false, desc="搜索关键字")
* @Apidoc\Query("country", type="string", require=false, desc="国家,i18n编码")
* @Apidoc\Query("category_id", type="int", require=false, desc="分类")
* @Apidoc\Query("page", type="int", require=true, desc="页码",default=1)
* @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10)
*/
public function list(){
$limit = (int)input('limit',10);
$model = QuestionnaireModel::with(['category'])->where('status',1);
if($category_id = input('category_id')){
$model = $model->where('category_id', $category_id);
}
if($country = input('country')){
$model = $model->where('country', $country);
}
$list = $model->order('id desc')->paginate($limit);
$list = $list->toArray();
foreach($list['data'] as $k=>$item){
$list['data'][$k]['id'] = idEncode($item['id']);
}
return $this->success(__('successful'),$list);
}
/**
* 问卷详情
* @Apidoc\Query("id", type="int", require=true, desc="ID")
*/
public function detail(){
try{
$user = \support\Jwt::getUser();
}catch(\Exception $e){
$user = ['id'=>0,'role_id'=>0];
}
$appid = input('id');
if(!$appid){
return $this->error(__("Product does not exist"));
}
/** @var ProductModel $product */
$product = ProductModel::where('id',$appid)->find();
//->cache(true,86400,'product_detail')
if(!$product) {
return $this->error(__("Product does not exist"));
}
if($user['id']){
$total_quantity_user = ProductOrderModel::where('product_id',$product->id)->where('user_id',$user['id'])->sum('quantity');
$total_quantity_system = $product->user_quantity ?: 99999999;
$max_quantity = $total_quantity_system-$total_quantity_user;
$max_quantity= $max_quantity < 0 ? 0: $max_quantity;
$product->max_quantity = $max_quantity;
$product->total_quantity_user = $total_quantity_user;
}else{
$product->total_quantity_user = 0;
$product->max_quantity = 0;
}
return $this->success(__('successful'),$product->toArray());
}
/**
* 领取问卷
* @Apidoc\Method("GET")
*/
function claim(){
$user = \support\Jwt::getUser();
//判断是否有问卷可领取
if($user->currency6<=0){
return $this->success(__('successful'));
}
//产生工作记录
$datas = [];
$questionnaire_ids = QuestionnaireModel::where('status',1)
->whereTime('start_time','<',time())
->whereTime('end_time','>',time())
->column('id');
$time = time();
for ($i=0; $i < $user->currency6; $i++) {
//随机选取一份问卷
$questionnaire_id = $questionnaire_ids[array_rand($questionnaire_ids)];
/** @var QuestionnaireModel $questionnaire */
$questionnaire = QuestionnaireModel::field('id,score')->find($questionnaire_id);
array_push($datas,[
"user_id" => $user->id,
"product_id" => null,
"questionnaire_id" => $questionnaire->id,
"order_id" => null,
"income" => $questionnaire->score,
"start_time" => 0,
"end_time" => 0,
"status" => 0, //自动开始
"created_at" => $time,
]);
}
Db::startTrans();
try {
(new WorkRecordModel)->saveAll($datas);
//领取完成,待领取清0;
$logData = [
'user_id' => $user->id.'',
'currency' => 'currency6',
'amount' => (0-$user->currency6).'',
'before' => $user->currency6.'',
'after' => '0',
'type' => \app\enum\BalanceType::CLAIM->value,
'created_at' => $time.'',
'memo' => ''
];
// 写入日志
BalanceLog::create($logData);
$user->currency6 = 0;
$user->save();
Db::commit();
} catch (\Exception $e) {
Db::rollback();
return $this->error($e->getMessage());
}
return $this->success(__('successful'));
}
/**
* 用户参与的问卷列表
* @Apidoc\Query("order_id", type="string", require=false, desc="订单号")
* @Apidoc\Query("step", type="string", require=false, desc="类型,progress,done")
* @Apidoc\Query("page", type="int", require=true, desc="页码",default=1)
* @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10)
*/
public function record(){
$limit = (int)input('limit',10);
$type = input('type','all');
$user_id = \support\Jwt\JwtToken::getCurrentId();
$step = input('step');
$order_id = input('order_id');
$model = WorkRecordModel::withJoin([
'questionnaire' => function($query) {
$query->field('title,category_id,country');
},
// 'product' => function($query) {
// $query->field('title');
// }
])->where('work_record.user_id',$user_id);
if($type && $type !='all'){
$model = $model->where('work_record.status', $type);
}
if($order_id){
$model = $model->where('work_record.order_id',$order_id);
}
if($step){
if($step=='done'){
$model = $model->where('work_record.status',\app\enum\ServerStatus::COMPLETE->value);
}
if($step=='progress'){
$model = $model->whereBetween('work_record.status',[1,\app\enum\ServerStatus::AUDITING->value,\app\enum\ServerStatus::SETTLEMENT->value]);
}
}
$list = $model->order('work_record.id desc')
->paginate($limit);
$list->each(function($item){
$item->questionnaire->country = Config('site.questionnaire_country')[$item->questionnaire->country];
$item->category = Db::name('category')->where('id',$item->questionnaire->category_id)->value('name');
return $item;
});
return $this->success(__('successful'),$list->toArray());
}
/**
* 开始任务
* @Apidoc\Method("POST")
* @Apidoc\Param("server_id", type="string", require=true, desc="产品ID")
*/
public function start()
{
$server_id = input('server_id');
$user = \support\Jwt::getUser();
if(!$server_id){
return $this->error(__('Incorrect parameter'));
}
if($server_id === 'all'){
$work_records = WorkRecordModel::where('user_id',$user->id)
->where('status',\app\enum\ServerStatus::WAITING->value)
->select();
}else{
$work_records = WorkRecordModel::where('user_id',$user->id)
->where('status',\app\enum\ServerStatus::WAITING->value)
->where('id',$server_id)->select();
if(count($work_records) === 0){
return $this->error(__('Server is not exist'));
}
}
/** @var WorkRecordModel $server */
foreach($work_records as $server){
$server->start();
}
return $this->success(__('successful'));
}
/**
* 用户参与的问卷详情
* @Apidoc\Method("POST")
* @Apidoc\Param("server_id", type="string", require=true, desc="产品ID")
*/
function progress(){
$server_id = (int)input('server_id',1);
$user = \support\Jwt::getUser();
/** @var WorkRecordModel $work_record */
$work_record = WorkRecordModel::with(['questionnaire'])->where('id',$server_id)->find();
if(!$work_record){
return $this->error(__('Server is not exist %sadds_f%',["%sadds_f%"=>'']));
}
$work_record->step_text = $work_record->getStep();
return $this->success(__('successful'),$work_record->toArray());
}
}
+4 -4
View File
@@ -324,8 +324,8 @@ class RechargeController extends BaseController{
UserModel::money($vo->user_id,$money,\app\enum\BalanceType::RECHARGE,$vo->id); UserModel::money($vo->user_id,$money,\app\enum\BalanceType::RECHARGE,$vo->id);
Hook('recharge.success',$vo); Hook('recharge.success',$vo);
}catch(\Exception $e){ }catch(\Exception $e){
log_write('充值回调失败:'.$e->getMessage()); log_alert('充值回调失败:'.$e->getMessage());
log_write($data); log_alert($data);
} }
} }
}else{ }else{
@@ -363,8 +363,8 @@ class RechargeController extends BaseController{
UserModel::money($vo->user_id,$money,\app\enum\BalanceType::RECHARGE,$vo->id); UserModel::money($vo->user_id,$money,\app\enum\BalanceType::RECHARGE,$vo->id);
Hook('recharge.success',$vo); Hook('recharge.success',$vo);
}catch(\Exception $e){ }catch(\Exception $e){
log_write('充值回调失败:'.$e->getMessage()); log_alert('充值回调失败:'.$e->getMessage());
log_write($data); log_alert($data);
return response("FAIL"); return response("FAIL");
} }
} }
@@ -6,11 +6,9 @@ use support\think\Db;
use hg\apidoc\annotation as Apidoc; use hg\apidoc\annotation as Apidoc;
/** /**
* 用户角色 * VIP
* @Apidoc\NotParse()
* @Apidoc\NotDebug()
*/ */
class RoleController extends BaseController{ class ThaliController extends BaseController{
/** /**
* 不需要鉴权的方法 * 不需要鉴权的方法
* @var array * @var array
@@ -20,17 +18,8 @@ class RoleController extends BaseController{
* 无需登录及鉴权的方法 * 无需登录及鉴权的方法
* @var array * @var array
*/ */
public $noNeedLogin = ['recent']; public $noNeedLogin = ['recent','list'];
/**
* @Apidoc\Title("当前角色信息")
* @Apidoc\Method("GET")
*/
function detail(){
$user = \support\Jwt::getUser();
$data = \app\model\UserRole::where('id',$user->role_id)->field('name,id,price')->find();
return $this->success(__('successful'),$data);
}
/** /**
* @Apidoc\Title("列表") * @Apidoc\Title("列表")
* @Apidoc\Method("GET") * @Apidoc\Method("GET")
@@ -38,13 +27,10 @@ class RoleController extends BaseController{
* @Apidoc\Param("limit", type="int",require=false, desc="分页大小") * @Apidoc\Param("limit", type="int",require=false, desc="分页大小")
*/ */
public function list(Request $request){ public function list(Request $request){
$user = \support\Jwt::getUser();
$limit = $request->get('limit',10); $limit = $request->get('limit',10);
$page = $request->get('page',1);
$kw = $request->get('kw'); $kw = $request->get('kw');
$model = \app\model\UserRole::where('id','>',0)->field('id,name,price') $model = \app\model\Thali::with(['Role'])->where('status',1)->order('id asc');
->order('id asc');
if($limit == 'all' || $limit >= 999999){ if($limit == 'all' || $limit >= 999999){
$result = $model->select(); $result = $model->select();
@@ -54,14 +40,29 @@ class RoleController extends BaseController{
} }
return $this->success(__('successful'),$result); return $this->success(__('successful'),$result);
} }
/**
* @Apidoc\Title("当前角色信息")
* @Apidoc\Method("GET")
* @Apidoc\NotParse()
* @Apidoc\NotDebug()
*/
function detail(){
$user = \support\Jwt::getUser();
$data = \app\model\UserRole::where('id',$user->role_id)->field('name,id,price')->find();
return $this->success(__('successful'),$data);
}
/** /**
* @Apidoc\Title("最近购买列表") * @Apidoc\Title("最近购买列表")
* @Apidoc\Method("GET") * @Apidoc\Method("GET")
*/ */
public function recent(Request $request){ public function recent(Request $request){
$list = (new \app\model\BalanceLog)->setSuffix('_money')->where('type',\app\enum\BalanceType::PURCHASE_ROLE->value) $list = (new \app\model\BalanceLog)->setSuffix('_score')
->order('created_at','desc')->limit(0,10)->field('user_id,created_at,memo')->select(); ->where('type',\app\enum\BalanceType::PURCHASE_ROLE->value)
->order('created_at','desc')
->limit(0,10)
->field('user_id,created_at,memo')
->select();
$list = $list->toArray(); $list = $list->toArray();
$data = []; $data = [];
$role_list = \app\model\UserRole::where('id', '>',1) $role_list = \app\model\UserRole::where('id', '>',1)
@@ -81,44 +82,61 @@ class RoleController extends BaseController{
/** /**
* @Apidoc\Title("购买") * @Apidoc\Title("购买")
* @Apidoc\Method("POST") * @Apidoc\Method("POST")
* @Apidoc\Param("role_id", type="string",require=true, desc="要购买的角色ID") * @Apidoc\Param("id", type="string",require=true, desc="要购买的ID")
* @Apidoc\Param("quantity", type="string",require=true, desc="要购买的数量(单位月)")
* @Apidoc\Param("trade_password", type="string",require=true, desc="交易密码") * @Apidoc\Param("trade_password", type="string",require=true, desc="交易密码")
*/ */
function buy(Request $request): Response{ function buy(Request $request): Response{
$user = \support\Jwt::getUser(); $user = \support\Jwt::getUser();
$role_id = (int)$request->post('role_id'); $id = (int)$request->post('id');
if($user->role_id > $role_id){ //数量
return $this->fail(__('Your level is too high to purchase this character')); $quantity = (int)$request->post('quantity',1);
} /**
if(abs($role_id - $user->role_id) !== 1 && $role_id !==6){ * @var \app\model\Thali $thali
return $this->fail(__('Your level is too high to purchase this character')); */
} $thali = \app\model\Thali::where('id',$id)->find();
$role = \app\model\UserRole::where('id',$role_id)->find(); if(!$thali){
if(!$role){
return $this->fail(__('Role does not exist')); return $this->fail(__('Role does not exist'));
} }
if($role->price <=0){ $role_id = $thali->role_id;
if($user->role_id >= $role_id){
return $this->fail(__('Your level is too high to purchase this character'));
}
$price = $thali->price;
if($quantity == 1){
$price = $thali->month_price;
}
if($quantity == 3){
$price = $thali->quarter_price;
}
if($quantity == 12){
$price = $thali->year_price;
}
$amount = $price * $quantity;
if($amount <=0){
return $this->fail(__('This character group is not allowed to be sold')); return $this->fail(__('This character group is not allowed to be sold'));
} }
if($user->money < $role->price){ if($user->score < $amount){
return $this->fail(__('Insufficient balance')); return $this->fail(__('Insufficient balance'));
} }
\support\Jwt::verify_trade_password($request->post('trade_password')); \support\Jwt::verify_trade_password($request->post('trade_password'));
$amount = $role->price; $user = \support\Jwt::getUser();
$power = bcmul($amount,config('site.suanli_rate'),4); $user->role_id = $role_id;
\app\model\User::where('id',$user->id)->save(['role_id'=>$role_id]); $user->expire_at = ($user->expire_at>time() ? $user->expire_at : time())+86400* $quantity * 30;
\app\model\User::money($user->id,-$amount,\app\enum\BalanceType::PURCHASE_ROLE,'购买用户组:'.$role_id); $user->save();
\app\model\User::score($user->id,$power,\app\enum\BalanceType::POWER_ADD,'购买用户组:'.$role_id); cache('user_role_'.$user->userID,[
'role_id'=>$role_id,'expire_at'=>$user->expire_at
cache_add('user_power_total_'.$user->id,$power); ],$user->expire_at-time());
Hook('user.roleup', $user);
$data = [ \app\model\User::score($user->id,-$amount,\app\enum\BalanceType::PURCHASE_ROLE,$role_id);
'role_id' => $role_id, //Hook('user.roleup', $user);
'user_id' => $user->id, // $data = [
'parent_id' => $user->parent_id, // 'role_id' => $role_id,
'amount' => $amount, // 'user_id' => $user->id,
]; // 'parent_id' => $user->parent_id,
Hook('role.buy', $data); // 'amount' => $amount,
return $this->success(__('successful')); // ];
// Hook('role.buy', $data);
return $this->success(__('successful'),$user);
} }
} }
-90
View File
@@ -37,22 +37,10 @@ enum BalanceType: int
* 兑换 * 兑换
*/ */
case EXCHANGE = 301; case EXCHANGE = 301;
/**
* 领取问卷
*/
case CLAIM = 306;
/** /**
* 签到 * 签到
*/ */
case SIGNIN = 302; case SIGNIN = 302;
/**
* 发布朋友圈
*/
case POSTPYQ = 303;
/**
* 发布QQ群
*/
case POSTGROUP = 304;
/** /**
* 邀请新用户注册 * 邀请新用户注册
*/ */
@@ -66,71 +54,11 @@ enum BalanceType: int
* 购买角色 * 购买角色
*/ */
case PURCHASE_ROLE = 402; case PURCHASE_ROLE = 402;
/**
* VIP奖励
*/
case OUTPUT_REWARD = 403;
/**
* 渠道商奖励
*/
case WITHDRAW_REWARD = 404;
/**
* 会员奖励
*/
case MEMBER_REWARD = 405;
/**
* 销售奖励
*/
case SALES_REWARD = 406;
/** /**
* 购买积分卡 * 购买积分卡
*/ */
case GIFT_BUY = 407; case GIFT_BUY = 407;
/**
* 问卷收益
*/
case PRODUCT_INCOME = 501;
/**
* 分配问卷指标
*/
case ASSIGN_QUOTA=502;
/**
* 问卷A收益:购买产品后代理收益
*/
case AGENT_COMMISSION=504;
/**
* 问卷B收益:购买产品后级差佣金
*/
case DIFFERENTIAL_COMMISSION=505;
/**
* 添加算力
*/
case POWER_ADD = 600;
/**
* 算力减少
*/
case POWER_SUB = 601;
/**
* 算力失效
*/
case POWER_EXPRIS = 602;
/**
* 算力释放
*/
case POWER_REALESE = 603;
/**
* 工作室奖励
*/
case STUDIO_REWARD = 700;
/**
* 工作室奖励结算
*/
case STUDIO_REALESE = 703;
/** /**
* 获取所有类型映射数组 * 获取所有类型映射数组
*/ */
@@ -144,31 +72,13 @@ enum BalanceType: int
self::CDKEY->value => __('购买卡密'), self::CDKEY->value => __('购买卡密'),
self::TRANSFER->value => __('站内转账'), self::TRANSFER->value => __('站内转账'),
self::EXCHANGE->value => __('兑换'), self::EXCHANGE->value => __('兑换'),
self::CLAIM->value => __('领取问卷'),
self::SIGNIN->value => __('签到'), self::SIGNIN->value => __('签到'),
self::POSTPYQ->value => __('发布朋友圈'),
self::POSTGROUP->value => __('发布QQ群'),
self::INVITE_NEW_USER->value => __('邀请新用户注册'), self::INVITE_NEW_USER->value => __('邀请新用户注册'),
self::PRODUCT_BUY->value => __('购买产品'), self::PRODUCT_BUY->value => __('购买产品'),
self::PRODUCT_INCOME->value => __('问卷收益'),
self::ASSIGN_QUOTA->value => __('分配问卷指标'),
self::AGENT_COMMISSION->value => __('问卷A收益'),
self::DIFFERENTIAL_COMMISSION->value => __('问卷B收益'),
self::PURCHASE_ROLE->value => __('购买角色'), self::PURCHASE_ROLE->value => __('购买角色'),
self::OUTPUT_REWARD->value => __('产值奖励'),
self::WITHDRAW_REWARD->value => __('提现奖励'),
self::SALES_REWARD->value => __('销售奖励'),
self::MEMBER_REWARD->value => __('会员奖励'),
self::GIFT_BUY->value => __('购买积分卡'), self::GIFT_BUY->value => __('购买积分卡'),
self::POWER_ADD->value => __('添加算力'),
self::POWER_SUB->value => __('算力减少'),
self::POWER_EXPRIS->value => __('算力过期'),
self::POWER_REALESE->value => __('算力释放'),
self::STUDIO_REWARD->value => __('工作室奖励'),
self::STUDIO_REALESE->value => __('工作室奖励结算'),
]; ];
} }
+2 -1
View File
@@ -8,7 +8,8 @@ class User{
$date = date('Y-m-d'); $date = date('Y-m-d');
cache_add('statistics_register_'.$date,1); cache_add('statistics_register_'.$date,1);
$saveData = [ $saveData = [
'invite_code' => build_invite_code($user->id) 'invite_code' => build_invite_code($user->id),
'userID' => idEncode($user->id)
]; ];
//管理直推人数和团队人数 //管理直推人数和团队人数
if($user->parent_id){ if($user->parent_id){
+5 -2
View File
@@ -170,12 +170,15 @@ class BalanceLog extends Base
public static function queryLogs($userId, $currency, $type = null, $startTime = null, $endTime = null) public static function queryLogs($userId, $currency, $type = null, $startTime = null, $endTime = null)
{ {
$model = new static; $model = new static;
$query = $model->setSuffix('_'.strtolower($currency))->where('currency', $currency) $query = $model->setSuffix('_'.strtolower($currency))
//->where('currency', $currency)
->where('user_id', intval($userId)) ->where('user_id', intval($userId))
->order('created_at', 'desc'); ->order('created_at', 'desc');
if ($type) { if ($type) {
$query->whereIn('type', $type); $temp_arr = explode(',', $type); // 得到 ["1", "2", "3", "4"]
$arr = array_map('intval', $temp_arr); // 得到 [1, 2, 3, 4]
$query->whereIn('type', $arr);
} }
if ($startTime) { if ($startTime) {
-67
View File
@@ -1,67 +0,0 @@
<?php
namespace app\model;
use app\model\Base;
/**
* @property integer $id 主键(ID) - 无注释
* @property integer $category_id 分类ID
* @property string $country 国别
* @property integer $score 积分
* @property integer $start_time 开始时间
* @property integer $end_time 结束时间
* @property string $title 标题
* @property integer $total 题目数量
* @property string $body 题目详情
* @property integer $created_at 创建时间
* @property integer $updated_at 更新时间
* @property integer $status 状态
*/
class Questionnaire extends Base
{
function setBodyAttr($v='',$row=[]){
if(is_array($v) || is_object($v)){
return json_encode($v,JSON_UNESCAPED_UNICODE);
}
return '[]';
}
function setStartTimeAttr($v='',$row=[]){
if($v){
return strtotime($v);
}
return $v;
}
// function getStartTimeAttr($v='',$row=[]){
// if($v){
// return is_numeric($v) ? date('Y-m-d H:i:s',$v) : $v;
// }
// return '';
// }
function setEndTimeAttr($v='',$row=[]){
if($v){
return strtotime($v);
}
return $v;
}
// function getEndTimeAttr($v='',$row=[]){
// if($v){
// return is_numeric($v) ? date('Y-m-d H:i:s',$v) : $v;
// }
// return '';
// }
public function getCategoryOptions(){
return Category::where('status','1')->where('type','questionnaire')->column('id,title');
}
function getBodyAttr($v='',$row=[]){
if($v){
return json_decode($v,true);
}
return [];
}
public function category()
{
return $this->belongsTo('Category', 'category_id', 'id');//->setEagerlyType(0);
}
}
+42 -3
View File
@@ -6,8 +6,13 @@ use app\model\Base;
* @property integer $id 主键(ID) - 无注释 * @property integer $id 主键(ID) - 无注释
* @property string $title 名称 * @property string $title 名称
* @property float $price 价格 * @property float $price 价格
* @property float $org_price 原价 * @property number $role_id 关联角色
* @property integer $duration 时长 * @property number $month_discount 月折扣
* @property number $quarter_discount 季折扣
* @property number $year_discount 年折扣
* @property number $month_price 月价
* @property number $quarter_price 季价
* @property number $year_price 年价
* @property string $label 标签 * @property string $label 标签
* @property integer $status 0:禁用,1启用 * @property integer $status 0:禁用,1启用
* @property integer $created_at 创建时间 * @property integer $created_at 创建时间
@@ -20,7 +25,41 @@ class Thali extends Base
{ {
// 所有的参数配置统一返回 // 所有的参数配置统一返回
return array_merge(parent::getOptions(),[ return array_merge(parent::getOptions(),[
'append' => [] 'append' => [
'month_price',
'quarter_price',
'year_price'
],
]);
}
/**
* 月价
*/
public function getMonthPriceAttr($value,$row)
{
return bcmul($row['price'],$row['month_discount'],2);
}
/**
* 季价
*/
public function getQuarterPriceAttr($value,$row)
{
return bcmul($row['price'],$row['quarter_discount'],2);
}
/**
* 年价
*/
public function getYearPriceAttr($value,$row)
{
return bcmul($row['price'],$row['year_discount'],2);
}
function Role(){
return $this->hasOne('UserRole','id','role_id')->bind([
'name'=>'role_name',
'max_send_msg_count'=>'max_send_msg_count',
'max_friend_count'=>'max_friend_count',
'max_group_join_count'=>'max_group_join_count',
'max_gourp_create_count'=>'max_gourp_create_count'
]); ]);
} }
-53
View File
@@ -1,53 +0,0 @@
<?php
namespace app\model;
/**
* @property integer $id 主键(ID) - 无注释
* @property integer $user_id 用户ID
* @property string $files 文件列表
* @property string $type 类型
* @property string $memo 原因
* @property integer $created_at 创建时间
* @property integer $updated_at 更新时间
* @property integer $status 状态
*/
class UserXuanchuan extends Base{
protected $name = 'user_xuanzhuan';
protected $autoWriteTimestamp = true;
protected function getOptions(): array{
return array_merge(parent::getOptions(),[
'insert' => [
'status' => 0
],
]);
}
public static function onAfterUpdate($row)
{
$changedData = $row->getChangedData();
if (isset($changedData['status']) && $changedData['status']==1) {
if($row->type == 'pyq'){
\app\model\User::currency1($row->user_id,70,\app\enum\BalanceType::POSTPYQ);
}else{
\app\model\User::currency1($row->user_id,70,\app\enum\BalanceType::POSTGROUP);
}
}
}
function getStatusList(){
return [
'0' => '等待审核',
'1' => '审核通过',
'-1' => '审核失败',
];
}
function getTypeList(){
return [
'pyq' => '朋友圈',
'group' => 'QQ群'
];
}
public function user()
{
return $this->belongsTo('User', 'user_id', 'id');//->setEagerlyType(0);
}
}
-121
View File
@@ -1,121 +0,0 @@
<?php
namespace app\queue\single;
use app\model\BalanceLog;
use Webman\RedisQueue\Consumer;
use app\model\WorkRecord;
use think\facade\Db;
class Power implements Consumer
{
// 要消费的队列名
public $queue = 'Power';
public $connection = 'default';
// 消费Notify
public function consume($data)
{
return false;
try {
if($data['action'] == 'power_expris'){
$this->log('开始失效算力:'.json_encode($data));
$log = (new \app\model\BalanceLog)->setSuffix('_currency1')
->where('id',$data['id'])
->where('status',1)
->find();
if(!$log){
return ;
}
Db::startTrans();
try {
$log->status = 2;
$log->save();
\app\model\User::transform(
'currency1',
'currency2',
$log->user_id,
$log->amount,
\app\enum\BalanceType::POWER_EXPRIS,
$log->_id?:$log->id
);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$this->log($e->getMessage());
throw $e;
}
}elseif($data['action'] == 'realese'){
$this->log('开始释放算力:'.json_encode($data));
$user = \app\model\User::find($data['user_id']);
$list = (new BalanceLog)->setSuffix('_currency1')
->where('user_id',intval($data['user_id']))
->where('status','<>',2)
->where('amount','>',0)
->order('created_at','asc')
->select();
$this->log($list->toArray());
//需要结算的记录
$_calcs = [];
//用户的待结算余额
$_currency1 = $user->currency1;
//用户的算力余额
$_score = $user->score;
foreach ($list as $key => $vo) {
//如果用户的待结算余额和算力都大于本记录的金额,就结算本条否则就结束计算
if($_currency1 - $vo->amount >= 0 && $_score-$vo->amount>=0){
//更新剩余货币
$_currency1-=$vo->amount;
$_score-=$vo->amount;
$_calcs[]=$vo;
continue;
}else{
break;
}
}
Db::startTrans();
try {
$transfrom_amount = 0;
foreach($_calcs as $k=>$log){
$transfrom_amount += $log->amount;
$log->status = 2;
$log->save();
}
if($transfrom_amount != 0){
\app\model\User::transform('score','money',$user->id,$transfrom_amount,\app\enum\BalanceType::POWER_REALESE);
\app\model\User::currency1($user->id,-$transfrom_amount,\app\enum\BalanceType::POWER_REALESE);
cache_add('user_income_total_'.$user->user_id,$transfrom_amount);
}
Db::commit();
} catch (\Exception $e) {
$this->log($e->getMessage());
Db::rollback();
}
}
}
catch(\Exception $e)
{
$this->log($e->getMessage());
}
}
function log($msg = ''){
log_alert($msg,'power');
}
// 消费失败回调
/*
$package = [
'id' => 1357277951, // 消息ID
'time' => 1709170510, // 消息时间
'delay' => 0, // 延迟时间
'attempts' => 2, // 消费次数
'queue' => 'send-mail', // 队列名
'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
'max_attempts' => 5, // 最大重试次数
'error' => '错误信息' // 错误信息
]
*/
public function onConsumeFailure(\Throwable $e, $package)
{
$this->log('consume failure:'.$e->getMessage());
}
}
-246
View File
@@ -1,246 +0,0 @@
<?php
namespace app\queue\single;
use Webman\RedisQueue\Consumer;
use app\model\WorkRecord;
use app\model\User as UserModel;
use think\facade\Db;
use app\model\BalanceLog;
class Questionnaire implements Consumer
{
// 要消费的队列名
public $queue = 'Questionnaire';
public $connection = 'default';
// 消费Notify
public function consume($data)
{
try {
$this->log("云主机:".json_encode($data));
if($data['action'] == 'assign'){
$time = time();
if( !isset($data['user_id']) || !$data['user_id']){
$this->log('user_id==null' );
return ;
}
if( !isset($data['order_id']) || !$data['order_id']){
$this->log('order_id==null' );
return ;
}
/**
* @var \app\model\ProductOrder $order
*/
$order = \app\model\ProductOrder::with(['product'])
->where('id',$data['order_id'])
->where('user_id',$data['user_id'])
->whereColumn('assigned','<','total')
->lock(true)
->find();
if(!$order){
$this->log('订单不存在:'.$data['order_id'] );
return ;
}
/**
* @var \app\model\Product $product
*/
$product = $order->product;
// if($order->assigned >= $order->total){
// $this->log('订单已分配完:'.$order->id );
// return ;
// }
$amount = $product->assign_count;
if($order->accelerate && $order->accelerate_times > $order->accelerate_used){
$amount = $product->accelerate_assign_count;
}
$amount *= $order->quantity;
//每次分配不超过订单剩余量
$_amount = min($amount,($order->total - $order->assigned));
if($_amount <= 0 ){
return;
}
$user = UserModel::find($data['user_id']);
if($_amount > $user->currency7 ){
return;
}
//分配问卷
Db::startTrans();
try {
$currency6_logData = [
'user_id' => $data['user_id'].'',
'currency' => 'currency6',
'amount' => ''.$_amount,
'before' => $user->currency6.'',
'after' => ($user->currency6+$_amount).'',
'type' => \app\enum\BalanceType::ASSIGN_QUOTA->value,
'created_at' => $time.'',
'memo' => $order->id.''
];
$currency7_logData = [
'user_id' => $data['user_id'].'',
'currency' => 'currency7',
'amount' => '-'.$_amount,
'before' => $user->currency7.'',
'after' => ($user->currency7-$_amount).'',
'type' => \app\enum\BalanceType::ASSIGN_QUOTA->value,
'created_at' => $time.'',
'memo' => $order->id.''
];
$currency8_logData = [
'user_id' => $data['user_id'].'',
'currency' => 'currency8',
'amount' => ''.$_amount,
'before' => $user->currency8.'',
'after' => ($user->currency8+$_amount).'',
'type' => \app\enum\BalanceType::ASSIGN_QUOTA->value,
'created_at' => $time.'',
'memo' => $order->id.''
];
BalanceLog::create($currency6_logData);
BalanceLog::create($currency7_logData);
BalanceLog::create($currency8_logData);
$user->currency6+=$_amount; //可领取
$user->currency7-=$_amount; //待分配
$user->currency8+=$_amount; //已分配
$user->save();
$order->assigned += $_amount;
$order->accelerate_used +=1;
$order->save();
Db::commit();
if($order->total > $order->assigned){
//addJob($data,'Questionnaire',86400);
$nextday = strtotime('+1 days');
$nexttime = strtotime(datetime($nextday,'Y-m-d'))+$order->id-2000;
$nextdelay = $nexttime - time();
addJob($data,'Questionnaire',$nextdelay);
}
}catch(\Exception $e){
Db::rollback();
$this->log($e->getMessage());
throw $e;
}
}elseif($data['action'] == 'workcomplete'){
if( !isset($data['server_id']) || !$data['server_id']){
$this->log('server_id==null' );
return ;
}
$server = WorkRecord::find($data['server_id']);
if($server->status != \app\enum\ServerStatus::WORKING->value){
return ;
}
$auditing_time = rand(3600,10800); //1-3小时随机审核
$server->status = \app\enum\ServerStatus::AUDITING->value;
$server->save();
addJob(['server_id'=>$server->id,'action'=>'settlement'],'Questionnaire',$auditing_time);
}elseif($data['action'] == 'settlement'){
if( !isset($data['server_id']) || !$data['server_id']){
$this->log('server_id==null' );
return ;
}
$server = WorkRecord::find($data['server_id']);
if($server->status != \app\enum\ServerStatus::AUDITING->value){
return ;
}
Db::startTrans();
try {
//几率失败,最低5%-最高10%的几率失败
$success = true;
$failRate = rand(5, 10); // 随机选择失败率
$rand = rand(0, 99); // 0-99 共100个数
if ($rand < $failRate) {
$success = false;
}
$success = true;
if(!$success){
//失败的处理
$server->status = \app\enum\ServerStatus::FAILED->value;
$server->save();
$user = UserModel::find($server->user_id);
$time = time();
$currency6_logData = [
'user_id' => $server->user_id.'',
'currency' => 'currency6',
'amount' => '1',
'before' => $user->currency6.'',
'after' => ($user->currency6+1).'',
'type' => \app\enum\BalanceType::DIFFERENTIAL_COMMISSION,
'created_at' => $time.'',
'memo' => ''
];
$currency9_logData = [
'user_id' => $server->user_id.'',
'currency' => 'currency9',
'amount' => '1',
'before' => $user->currency9.'',
'after' => ($user->currency9+1).'',
'type' => \app\enum\BalanceType::DIFFERENTIAL_COMMISSION,
'created_at' => $time.'',
'memo' => ''
];
BalanceLog::create($currency6_logData);
BalanceLog::create($currency9_logData);
$user->currency6+=1; //可领取
$user->currency9+=1; //未通过
$user->save();
Db::commit();
}else{
//给用户付钱
UserModel::score($server->user_id,$server->income,\app\enum\BalanceType::PRODUCT_INCOME,$server->id);
$server->status = \app\enum\ServerStatus::COMPLETE->value;
$server->save();
cache_add('user_today_income_'.date('Ymd').'_'.$server->user_id,$server->income);
cache_add('user_month_income_'.date('Ym').'_'.$server->user_id,$server->income);
cache_add('user_income_total_'.$server->user_id,$server->income);
// $parent_info = parent_info($server->user_id);
// $parent_id = $parent_info['id'];
// // 产值奖励(直推)
// if(UserModel::where('id',$parent_id)->value('group') == 1){
// //只有渠道用户才能活得
// $reward = bcmul($data['amount'] ,0.05,4);
// UserModel::score($parent_id ,$reward,\app\enum\BalanceType::OUTPUT_REWARD,$data['id']);
// }
// //产值奖励
// $distributed_users = jicha($server->user_id,$server->income,[0,0.01,0.02,0.03,0.05,0.05]);
// foreach($distributed_users as $k=>$v){
// UserModel::money($v['user_id'],$v['amount'],\app\enum\BalanceType::OUTPUT_REWARD,$server->id);
// cache_add('user_income_total_'.$v['user_id'],$v['amount']);
// cache_add('user_output_reward_'.$v['user_id'],$v['amount']);
// }
Db::commit();
}
} catch (\Exception $e) {
Db::rollback();
$this->log($e->getMessage());
throw $e;
}
}else{
$this->log('未知状态');
}
}
catch(\Exception $e)
{
$this->log($e->getMessage());
}
}
function log($msg = ''){
\support\Log::channel('server')->alert($msg);
}
// 消费失败回调
/*
$package = [
'id' => 1357277951, // 消息ID
'time' => 1709170510, // 消息时间
'delay' => 0, // 延迟时间
'attempts' => 2, // 消费次数
'queue' => 'send-mail', // 队列名
'data' => ['to' => 'tom@gmail.com', 'content' => 'hello'], // 消息内容
'max_attempts' => 5, // 最大重试次数
'error' => '错误信息' // 错误信息
]
*/
public function onConsumeFailure(\Throwable $e, $package)
{
$this->log('consume failure:'.$e->getMessage());
}
}
-57
View File
@@ -1,57 +0,0 @@
<?php
namespace app\queue\single;
use Webman\RedisQueue\Consumer;
use app\model\WorkRecord;
use think\facade\Db;
class Studio implements Consumer
{
// 要消费的队列名
public $queue = 'Studio';
public $connection = 'default';
// 消费Notify
public function consume($data)
{
return false;
$this->log('开始结算:');
$list = (new \app\model\BalanceLog)->setSuffix('_currency3')
->where('status',1)
->order('created_at','asc')
->select();
if(!$list){
return ;
}
foreach($list as $log){
Db::startTrans();
try {
$log->status = 2;
$log->save();
\app\model\User::transform(
'currency3',
'money',
$log->user_id,
$log->amount,
\app\enum\BalanceType::STUDIO_REALESE,
$log->id
);
\app\model\User::currency4($log->user_id,$log->amount,\app\enum\BalanceType::STUDIO_REALESE,$log->id);
Db::commit();
} catch (\Exception $e) {
Db::rollback();
$this->log($e->getMessage());
throw $e;
}
}
}
function log($msg = ''){
\support\Log::channel('studio')->alert($msg);
}
// 消费失败回调
public function onConsumeFailure(\Throwable $e, $package)
{
$this->log('consume failure:'.$e->getMessage());
}
}
@@ -30,5 +30,8 @@ class ThaliController extends Crud
$statusList = $this->model->getStatusList(); $statusList = $this->model->getStatusList();
$this->assign("statusList", $statusList); $this->assign("statusList", $statusList);
$this->assignconfig("statusList", $statusList); $this->assignconfig("statusList", $statusList);
$roleList = \think\facade\Db::name('user_role')->where('id','>',1)->field('id,name')->order('id','asc')->select();
$this->assign("roleList", $roleList);
$this->assignconfig("roleList", $roleList);
} }
} }
@@ -126,7 +126,7 @@ class UserRoleController extends Crud
} else { } else {
$pid = $role->pid; $pid = $role->pid;
} }
$this->checkRules($pid, $data['rules'] ?? ''); //$this->checkRules($pid, $data['rules'] ?? '');
$this->doUpdate($id, $data); $this->doUpdate($id, $data);
// 删除所有子角色组中已经不存在的权限 // 删除所有子角色组中已经不存在的权限
+20 -4
View File
@@ -9,6 +9,16 @@
<input id="c-title" class="form-control" name="title" type="text" value="{$row.title|null}"> <input id="c-title" class="form-control" name="title" type="text" value="{$row.title|null}">
</div> </div>
</div> </div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">关联角色:</label>
<div class="col-xs-12 col-sm-8">
<select id="c-role_id" class="form-control" name="role_id">
{foreach $roleList as $role}
<option value="{$role.id}" {if $row.role_id == $role.id}selected{/if}>{$role.name}</option>
{/foreach}
</select>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-xs-12 col-sm-2">价格:</label> <label class="control-label col-xs-12 col-sm-2">价格:</label>
<div class="col-xs-12 col-sm-8"> <div class="col-xs-12 col-sm-8">
@@ -16,15 +26,21 @@
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-xs-12 col-sm-2">原价:</label> <label class="control-label col-xs-12 col-sm-2">月折扣:</label>
<div class="col-xs-12 col-sm-8"> <div class="col-xs-12 col-sm-8">
<input id="c-org_price" class="form-control" step="0.01" name="org_price" type="number" value="{$row.org_price|default=0}"> <input id="c-month_discount" class="form-control" step="0.01" name="month_discount" type="number" value="{$row.month_discount|default=1}">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label class="control-label col-xs-12 col-sm-2">时间:</label> <label class="control-label col-xs-12 col-sm-2">季折扣:</label>
<div class="col-xs-12 col-sm-8"> <div class="col-xs-12 col-sm-8">
<input id="c-duration" min="0" class="form-control" name="duration" type="number" value="{$row.duration|default=30}"> <input id="c-quarter_discount" min="0" class="form-control" name="quarter_discount" type="number" value="{$row.quarter_discount|default=1}">
</div>
</div>
<div class="form-group">
<label class="control-label col-xs-12 col-sm-2">年折扣:</label>
<div class="col-xs-12 col-sm-8">
<input id="c-year_discount" min="0" class="form-control" name="year_discount" type="number" value="{$row.year_discount|default=1}">
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
+1 -1
View File
@@ -5,7 +5,7 @@
<form class="form-horizontal" action="__SELF__" method="post"> <form class="form-horizontal" action="__SELF__" method="post">
<input type="hidden" name="id" value="{$row.id|null}" /> <input type="hidden" name="id" value="{$row.id|null}" />
<div class="form-group"> <div class="form-group">
<label for="type" class="control-label col-xs-12 col-sm-2">角色{$row.role_id}</label> <label for="type" class="control-label col-xs-12 col-sm-2">角色</label>
<div class="col-xs-12 col-sm-8 col-md-6"> <div class="col-xs-12 col-sm-8 col-md-6">
<select name="role_id" id="role_id" class="form-control"> <select name="role_id" id="role_id" class="form-control">
{volist name="roleList" id="rvo"} {volist name="roleList" id="rvo"}
+1 -1
View File
@@ -112,7 +112,7 @@ define(['table', 'upload','form'], function (Table,Upload,Form) {
$(this).addClass('active'); $(this).addClass('active');
$.fn.bootstrapTable.defaults.extend.del_url = 'balancelog/delete?currency='+currency $.fn.bootstrapTable.defaults.extend.del_url = 'balancelog/delete?currency='+currency
window.filterData['currency']['value1'] = currency; window.filterData['currency']['value1'] = currency;
table.bootstrapTable('selectPage', 1); table.bootstrapTable('refreshOptions', {pageNumber:1});
}); });
}, },
update:function(){ update:function(){
+9 -15
View File
@@ -46,25 +46,19 @@ define(['table', 'upload','form'], function (Table,Upload,Form) {
} }
}, },
{ {
title: "原价", title: "月折扣",
field: "org_price", field: "month_discount",
filter: "number", filter: "number"
formatter:function(v){
return Table.api.formatter.number(v)+'元';
}
}, },
{ {
title: "时长", title: "季折扣",
field: "duration", field: "quarter_discount",
filter: "number", filter: "number"
formatter:function(v){
return v+'天';
}
}, },
{ {
title: "标签", title: "年折扣",
field: "label", field: "year_discount",
filter: "string" filter: "number"
}, },
{ {
title: "状态", title: "状态",