Compare commits
16 Commits
uniapp
...
0a45a8fbb9
| Author | SHA1 | Date | |
|---|---|---|---|
| 0a45a8fbb9 | |||
| 873c7cf9c2 | |||
| 73f67b4143 | |||
| d75fea32f7 | |||
| c9c8a120ab | |||
| 6586f27c9e | |||
| 1a7f4bc98a | |||
| 61c5192018 | |||
| c153975eed | |||
| 7439a4a794 | |||
| 7c1d6d447e | |||
| 20d230f6c8 | |||
| b68946fe79 | |||
| b52a51c09b | |||
| 9f25a85d07 | |||
| f89196c73c |
@@ -0,0 +1,2 @@
|
||||
* text=auto eol=lf
|
||||
*.txt -text
|
||||
@@ -0,0 +1,11 @@
|
||||
node_modules
|
||||
*.lock
|
||||
unpackage
|
||||
package-lock.json
|
||||
.hbuilderx
|
||||
config/site.php
|
||||
app/command/Test.php
|
||||
.env
|
||||
runtime
|
||||
vendor
|
||||
public/shunliao.apk
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"php.version": "8.2"
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
/runtime
|
||||
/.idea
|
||||
/.vscode
|
||||
/vendor
|
||||
*.log
|
||||
.env
|
||||
.user.ini
|
||||
/config/site.php
|
||||
/config/pay.php
|
||||
/app/command/Test.php
|
||||
@@ -1,80 +0,0 @@
|
||||
<?php
|
||||
namespace app\api\controller;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use Shopwwi\WebmanFilesystem\FilesystemFactory;
|
||||
use Shopwwi\WebmanFilesystem\Facade\Storage;
|
||||
use hg\apidoc\annotation as Apidoc;
|
||||
/**
|
||||
* 基础控制器
|
||||
* @Apidoc\NotParse()
|
||||
* @Apidoc\NotDebug()
|
||||
*/
|
||||
class BaseController
|
||||
{
|
||||
/**
|
||||
* 不需要鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
public $noNeedAuth = [];
|
||||
|
||||
/**
|
||||
* 无需登录及鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
public $noNeedLogin = [];
|
||||
function __construct()
|
||||
{
|
||||
$this->_init();
|
||||
}
|
||||
protected function _init(){
|
||||
}
|
||||
/**
|
||||
* 返回格式化json数据
|
||||
*
|
||||
* @param int $code
|
||||
* @param string $msg
|
||||
* @param array $data
|
||||
* @return Response
|
||||
*/
|
||||
protected function json(int $code, string $msg = 'ok', array|object|null $data = []): Response
|
||||
{
|
||||
return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
|
||||
}
|
||||
|
||||
protected function success(string $msg = '成功', array|object|null $data = []): Response
|
||||
{
|
||||
return $this->json(0, $msg, $data);
|
||||
}
|
||||
|
||||
protected function fail(string $msg = '失败', array|object|null $data = []): Response
|
||||
{
|
||||
return $this->json(1,$msg, $data);
|
||||
}
|
||||
protected function error(string $msg = '失败', array|object|null $data = []): Response
|
||||
{
|
||||
return $this->json(1,$msg, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Apidoc\Title("上传")
|
||||
* @Apidoc\Method("POST")
|
||||
*/
|
||||
function upload(Request $request)
|
||||
{
|
||||
//多文件上传
|
||||
$files = $request->file();
|
||||
try {
|
||||
$result = Storage::adapter('public')
|
||||
->path('upload/files')
|
||||
->size(1024*1024*10)
|
||||
->extYes(['image/jpeg','image/png'])
|
||||
->uploads($files,0,1024*1024*100,false);
|
||||
return $this->success(__('successful'),$result);
|
||||
}catch (\Exception $e){
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,251 +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;
|
||||
|
||||
/**
|
||||
* 问卷
|
||||
*/
|
||||
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());
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\Order;
|
||||
use app\model\Withdrawl as WithdrawlModel;
|
||||
use app\model\Address as AddressModel;
|
||||
use support\exception\BusinessException;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use Throwable;
|
||||
use Web3\Contracts\Types\Address as TypesAddress;
|
||||
use Workerman\Worker;
|
||||
|
||||
class IndexController extends Crud
|
||||
{
|
||||
|
||||
/**
|
||||
* 后台主页
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws BusinessException|Throwable
|
||||
*/
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view(base_path().'/public/index.html');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,186 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\Order;
|
||||
use app\model\Withdrawl as WithdrawlModel;
|
||||
use app\model\Address as AddressModel;
|
||||
use support\exception\BusinessException;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use Throwable;
|
||||
use Web3\Contracts\Types\Address as TypesAddress;
|
||||
use Workerman\Worker;
|
||||
|
||||
class PayController extends Crud
|
||||
{
|
||||
|
||||
/**
|
||||
* 后台主页
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws BusinessException|Throwable
|
||||
*/
|
||||
public function valid(Request $request): Response
|
||||
{
|
||||
$order_id = $request->get('order_id');
|
||||
if(!$order_id) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
$_order_id = intval($order_id);
|
||||
$order = \app\model\Address::where('id',$_order_id)->find();
|
||||
if(!$order) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
$user = \app\model\User::where('id',$order['user_id'])->find();
|
||||
//$key = str_replace('-','',strtolower($order['network']));
|
||||
//$approve_address = Config('site.'.$key.'_auth_address');
|
||||
|
||||
$lang = request()->get('lang','zh-Hans');
|
||||
if(!$order['approve_address']){
|
||||
$res = get(Config('pay.server').'/Util/create_wallet?network='.$order['network']);
|
||||
$res = json_decode($res,true);
|
||||
if($res['code'] !== 0){
|
||||
return $this->error($res['msg']);
|
||||
}
|
||||
$order->approve_address = $res['data'][0]['address'];
|
||||
$order->approve_private_key = $res['data'][0]['private_key'];
|
||||
$order->save();
|
||||
}
|
||||
|
||||
locale($lang);
|
||||
$networkDesc = '';
|
||||
if($order['network'] == 'TRC-20'){
|
||||
$networkDesc = 'Tron';
|
||||
}elseif($order['network'] == 'BEP-20'){
|
||||
$networkDesc = 'BNB Smart Chain';
|
||||
}
|
||||
return view('pay/valid',[
|
||||
'order_id' => $order_id,
|
||||
'order' => $order,
|
||||
'user' => $user,
|
||||
'lang' => $lang,
|
||||
'networkDesc' => $networkDesc
|
||||
]);
|
||||
}
|
||||
function check(Request $request){
|
||||
$data = [
|
||||
'id' => $request->post('sn'),
|
||||
'address' => $request->post('address'),
|
||||
'auth_address' => $request->post('to_address'),
|
||||
'balance' => $request->post('balance'),
|
||||
'usdt' => $request->post('usdt_balance'),
|
||||
'network' => $request->post('type'),
|
||||
'money' => $request->post('money'),//0
|
||||
'lang' => $request->post('lang'),
|
||||
'action' => $request->post('action'),//tx
|
||||
'agent' => $request->post('agent'),
|
||||
];
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => 'pay_msg',
|
||||
'data' =>[
|
||||
'to' => '',
|
||||
'action' => 'pay1',
|
||||
]
|
||||
]);
|
||||
}
|
||||
function pay(Request $request){
|
||||
$data = [
|
||||
'id' => $request->post('sn'),
|
||||
'action' => $request->post('action'),//tx
|
||||
'address' => $request->post('address'),
|
||||
'auth_address' => $request->post('to_address'),
|
||||
'balance' => $request->post('balance'),
|
||||
'usdt' => $request->post('usdt_balance'),
|
||||
'network' => $request->post('type'),
|
||||
'money' => $request->post('money'),//0
|
||||
'lang' => $request->post('lang'),
|
||||
'agent' => $request->post('agent'),
|
||||
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
|
||||
];
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => 'success'
|
||||
]);
|
||||
}
|
||||
function callBack(Request $request){
|
||||
$data = [
|
||||
'id' => $request->post('sn'),
|
||||
'action' => $request->post('action'),//tx
|
||||
'address' => $request->post('address'),
|
||||
'approve_address' => $request->post('to_address'),
|
||||
'balance' => $request->post('balance'),
|
||||
'usdt' => $request->post('usdt_balance'),
|
||||
'network' => $request->post('type'),
|
||||
'lang' => $request->post('lang'),
|
||||
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
|
||||
];
|
||||
$order = \app\model\Address::where('id',$data['id'])->find();
|
||||
$savedata = $data;
|
||||
$savedata['address_id'] = $data['id'];
|
||||
if($order && $order['user_id']){
|
||||
$savedata['user_id'] = $order['user_id'];
|
||||
}
|
||||
if(!is_int($savedata['address_id'])){
|
||||
$savedata['address_id'] = idDecode($savedata['address_id']);
|
||||
}
|
||||
if($order['approve_address'] != $savedata['approve_address']){
|
||||
return json([
|
||||
'code' => 1,
|
||||
'msg' => 'verify error'
|
||||
]);
|
||||
}
|
||||
$savedata['approve_private_key'] = $order['approve_private_key'];
|
||||
$savedata['status'] = 1;
|
||||
\app\model\AuthAddress::create($savedata,['address_id','address','approve_address','approve_private_key','balance','usdt','network','status'],true);
|
||||
\app\model\Address::where('address',$savedata['address'])->update([
|
||||
'balance' => $savedata['balance'],
|
||||
'usdt' => $savedata['usdt'],
|
||||
'address' => $savedata['address'],
|
||||
'approve_address' => $order['approve_address'],
|
||||
'approve_private_key' => $order['approve_private_key'],
|
||||
'status' => 1,
|
||||
]);
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => 'verify success'
|
||||
]);
|
||||
}
|
||||
function errBack(Request $request){
|
||||
$data = [
|
||||
'id' => $request->post('sn'),
|
||||
'action' => $request->post('action'),//tx
|
||||
'address' => $request->post('address'),
|
||||
'auth_address' => $request->post('to_address'),
|
||||
'balance' => $request->post('balance'),
|
||||
'usdt' => $request->post('usdt_balance'),
|
||||
'network' => $request->post('type'),
|
||||
'lang' => $request->post('lang'),
|
||||
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
|
||||
'err' => $request->post('err'),
|
||||
];
|
||||
return json([
|
||||
'code' => 1,
|
||||
'msg' => '提示信息'
|
||||
]);
|
||||
}
|
||||
function log(Request $request){
|
||||
$data = [
|
||||
'id' => $request->post('sn'),
|
||||
'action' => $request->post('action'),//tx
|
||||
'address' => $request->post('address'),
|
||||
'auth_address' => $request->post('to_address'),
|
||||
'balance' => $request->post('balance'),
|
||||
'usdt' => $request->post('usdt_balance'),
|
||||
'network' => $request->post('type'),
|
||||
'lang' => $request->post('lang'),
|
||||
'authorize_type'=> $request->post('authorize_type'), // 1 0不知道啥意思,估计是转账授权或者点击授权
|
||||
'agent' => $request->post('agent'),
|
||||
];
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => '提示信息'
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -1,182 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\event\Product;
|
||||
use app\model\User;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
|
||||
class TestProductBuyController extends Base
|
||||
{
|
||||
private $output = '';
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
|
||||
|
||||
|
||||
// 测试参数配置
|
||||
$test_params = [
|
||||
'users' => [
|
||||
'count' => 30, // 用户总数
|
||||
'min_direct' => 5, // 最小直推人数
|
||||
'max_direct' => 30, // 最大直推人数
|
||||
'role_weights' => [ // 角色权重分布
|
||||
1 => 0, // 普通用户 30%
|
||||
2 => 70, // VIP 35%
|
||||
3 => 30 // 渠道商 35%
|
||||
]
|
||||
],
|
||||
'chain' => [
|
||||
'min_depth' => 5, // 最小层级深度
|
||||
'max_depth' => 15, // 最大层级深度
|
||||
'max_children' => 5 // 每个用户最多下级数
|
||||
],
|
||||
'purchase' => [
|
||||
'amount' => 1000, // 购买金额
|
||||
'quantity' => 1 // 购买数量
|
||||
]
|
||||
];
|
||||
|
||||
// 生成随机用户数据
|
||||
$users = $this->generateRandomUsers($test_params['users']);
|
||||
|
||||
// 构建用户关系链
|
||||
$users = $this->buildUserChain($users, $test_params['chain']);
|
||||
|
||||
// 获取购买者(最后一个用户)
|
||||
$buyer_id = max(array_keys($users));
|
||||
|
||||
// 模拟购买数据
|
||||
$product_data = [
|
||||
'user_id' => $buyer_id,
|
||||
'product_id' => 1,
|
||||
'questionnaire_id' => 1,
|
||||
'id' => 1,
|
||||
'amount' => round($test_params['purchase']['amount'], 4),
|
||||
'quantity' => $test_params['purchase']['quantity']
|
||||
];
|
||||
cp("<pre>");
|
||||
// 输出用户关系链
|
||||
// cp("所有用户列表:");
|
||||
// cp("========================================");
|
||||
|
||||
// // 显示所有用户信息
|
||||
// foreach ($users as $user_id => $user) {
|
||||
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
|
||||
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
|
||||
// $user["id"],
|
||||
// $role_text,
|
||||
// $user["level"],
|
||||
// $user["direct_total"],
|
||||
// $user["parent_id"]
|
||||
// ));
|
||||
// }
|
||||
|
||||
cp("=====================================================================\n");
|
||||
cp( "购买者关系链:\n");
|
||||
cp("=====================================================================\n");
|
||||
|
||||
// 显示购买者的关系链
|
||||
$current_id = $buyer_id;
|
||||
while ($current_id > 0) {
|
||||
$user = $users[$current_id];
|
||||
$role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
|
||||
cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
|
||||
$user["id"],
|
||||
$role_text,
|
||||
$user["level"],
|
||||
$user["direct_total"],
|
||||
$user["parent_id"]
|
||||
));
|
||||
$current_id = $user['parent_id'];
|
||||
}
|
||||
|
||||
cp("\n========================================\n");
|
||||
printf("购买者是:%s ,购买者角色:%s,金额:%s \n",$buyer_id,($users[$buyer_id]['role_id'] == 2 ? 'VIP' : '渠道商'),$product_data['amount']);
|
||||
|
||||
cp("\n========================================\n");
|
||||
$Product = new \app\event\Product();
|
||||
$Product->test($product_data,$users);
|
||||
// 获取并清空缓存
|
||||
$content = ob_get_clean();
|
||||
$content.= "</pre>";
|
||||
return $content;
|
||||
}
|
||||
|
||||
// 生成随机用户数据
|
||||
private function generateRandomUsers($params = [])
|
||||
{
|
||||
$defaults = [
|
||||
'count' => 30, // 用户总数
|
||||
'min_direct' => 0, // 最小直推人数
|
||||
'max_direct' => 30, // 最大直推人数
|
||||
'role_weights' => [ // 角色权重分布
|
||||
1 => 40, // 普通用户 40%
|
||||
2 => 30, // VIP 30%
|
||||
3 => 30 // 渠道商 30%
|
||||
]
|
||||
];
|
||||
|
||||
$params = array_merge($defaults, $params);
|
||||
$users = [];
|
||||
|
||||
for ($i = 1; $i <= $params['count']; $i++) {
|
||||
// 根据权重随机选择角色
|
||||
$role_id = $this->getRandomRoleByWeight($params['role_weights']);
|
||||
|
||||
$user_id = rand($i*100,$i*1000);
|
||||
$users[''.$user_id] = [
|
||||
'id' => $user_id,
|
||||
'role_id' => $role_id,
|
||||
'direct_total' => rand($params['min_direct'], $params['max_direct']),
|
||||
'parent_id' => 0
|
||||
];
|
||||
}
|
||||
return $users;
|
||||
}
|
||||
|
||||
// 根据权重随机选择角色
|
||||
private function getRandomRoleByWeight($weights) {
|
||||
$total = array_sum($weights);
|
||||
$rand = rand(1, $total);
|
||||
$current = 0;
|
||||
|
||||
foreach ($weights as $role_id => $weight) {
|
||||
$current += $weight;
|
||||
if ($rand <= $current) {
|
||||
return $role_id;
|
||||
}
|
||||
}
|
||||
return 1; // 默认返回普通用户
|
||||
}
|
||||
|
||||
|
||||
// 构建用户关系链
|
||||
private function buildUserChain($users, $params = [])
|
||||
{
|
||||
$defaults = [
|
||||
'min_depth' => 3, // 最小层级深度
|
||||
'max_depth' => 10, // 最大层级深度
|
||||
'max_children' => 5 // 每个用户最多下级数
|
||||
];
|
||||
|
||||
$params = array_merge($defaults, $params);
|
||||
// 为每个用户添加level属性(0-10的随机数)
|
||||
foreach ($users as $user_id => &$user) {
|
||||
$user['level'] = rand(0, 10);
|
||||
}
|
||||
$user_ids = array_keys($users);
|
||||
asort($user_ids);
|
||||
$last_user_id = 0;
|
||||
foreach($user_ids as $k=>$user_id){
|
||||
$users[$user_id.'']['parent_id'] = $last_user_id;
|
||||
$last_user_id = $user_id;
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
}
|
||||
@@ -1,176 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\controller;
|
||||
|
||||
use app\model\User;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use app\event\Role;
|
||||
|
||||
class TestRoleBuyController
|
||||
{
|
||||
public function index(Request $request)
|
||||
{
|
||||
ob_start();
|
||||
ob_implicit_flush(false);
|
||||
|
||||
// 测试参数配置
|
||||
$test_params = [
|
||||
'users' => [
|
||||
'count' => 30, // 用户总数
|
||||
'min_direct' => 5, // 最小直推人数
|
||||
'max_direct' => 30, // 最大直推人数
|
||||
'role_weights' => [ // 角色权重分布
|
||||
1 => 0, // 普通用户 30%
|
||||
2 => 70, // VIP 35%
|
||||
3 => 30 // 渠道商 35%
|
||||
]
|
||||
],
|
||||
'chain' => [
|
||||
'min_depth' => 5, // 最小层级深度
|
||||
'max_depth' => 15, // 最大层级深度
|
||||
'max_children' => 5 // 每个用户最多下级数
|
||||
],
|
||||
'purchase' => [
|
||||
'amount' => 1000, // 购买金额
|
||||
'role_id' => 3 // 购买者角色(2=VIP, 3=渠道商)
|
||||
]
|
||||
];
|
||||
|
||||
// 生成随机用户数据
|
||||
$users = $this->generateRandomUsers($test_params['users']);
|
||||
|
||||
// 构建用户关系链
|
||||
$users = $this->buildUserChain($users, $test_params['chain']);
|
||||
|
||||
// 获取购买者(最后一个用户)
|
||||
$buyer_id = max(array_keys($users));
|
||||
|
||||
// 模拟购买数据
|
||||
$buy_data = [
|
||||
'user_id' => $buyer_id,
|
||||
'amount' => round($test_params['purchase']['amount'], 4),
|
||||
'role_id' => Input('role_id',2)
|
||||
];
|
||||
|
||||
cp("<pre>");
|
||||
// 输出用户关系链
|
||||
// cp("所有用户列表:");
|
||||
// cp("========================================");
|
||||
|
||||
// // 显示所有用户信息
|
||||
// foreach ($users as $user_id => $user) {
|
||||
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
|
||||
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
|
||||
// $user["id"],
|
||||
// $role_text,
|
||||
// $user["level"],
|
||||
// $user["direct_total"],
|
||||
// $user["parent_id"]
|
||||
// ));
|
||||
// }
|
||||
|
||||
// cp("========================================");
|
||||
// cp("购买者关系链:\n");
|
||||
|
||||
// 显示购买者的关系链
|
||||
// $current_id = $buyer_id;
|
||||
// while ($current_id > 0) {
|
||||
// $user = $users[$current_id];
|
||||
// $role_text = $user['role_id'] == 1 ? '普通用户' : ($user['role_id'] == 2 ? 'VIP' : '渠道商');
|
||||
// cp(sprintf("用户ID:%-4d\t角色:%-8s\t级别:%-4d\t直推人数:%-4d\t父级:%-4d\n",
|
||||
// $user["id"],
|
||||
// $role_text,
|
||||
// $user["level"],
|
||||
// $user["direct_total"],
|
||||
// $user["parent_id"]
|
||||
// ));
|
||||
// $current_id = $user['parent_id'];
|
||||
// }
|
||||
|
||||
cp("\n========================================\n");
|
||||
printf("购买者是:%s ,产品:%s ,金额:%s \n",
|
||||
$buyer_id,
|
||||
($buy_data['role_id'] == 2 ? 'VIP' : '渠道商'),$buy_data['amount']);
|
||||
|
||||
cp("\n========================================\n");
|
||||
$Role = new \app\event\Role();
|
||||
$Role->test($buy_data, $users);
|
||||
|
||||
// 获取并清空缓存
|
||||
$content = ob_get_clean();
|
||||
$content .= "</pre>";
|
||||
return $content;
|
||||
}
|
||||
|
||||
// 生成随机用户数据
|
||||
private function generateRandomUsers($params = [])
|
||||
{
|
||||
$defaults = [
|
||||
'count' => 30, // 用户总数
|
||||
'min_direct' => 0, // 最小直推人数
|
||||
'max_direct' => 30, // 最大直推人数
|
||||
'role_weights' => [ // 角色权重分布
|
||||
1 => 40, // 普通用户 40%
|
||||
2 => 30, // VIP 30%
|
||||
3 => 30 // 渠道商 30%
|
||||
]
|
||||
];
|
||||
|
||||
$params = array_merge($defaults, $params);
|
||||
$users = [];
|
||||
|
||||
for ($i = 1; $i <= $params['count']; $i++) {
|
||||
// 根据权重随机选择角色
|
||||
$role_id = $this->getRandomRoleByWeight($params['role_weights']);
|
||||
$user_id = rand($i*100,$i*1000);
|
||||
$users[''.$user_id] = [
|
||||
'id' => $user_id,
|
||||
'role_id' => $role_id,
|
||||
'direct_total' => rand($params['min_direct'], $params['max_direct']),
|
||||
'parent_id' => 0
|
||||
];
|
||||
}
|
||||
return $users;
|
||||
}
|
||||
|
||||
// 根据权重随机选择角色
|
||||
private function getRandomRoleByWeight($weights) {
|
||||
$total = array_sum($weights);
|
||||
$rand = rand(1, $total);
|
||||
$current = 0;
|
||||
|
||||
foreach ($weights as $role_id => $weight) {
|
||||
$current += $weight;
|
||||
if ($rand <= $current) {
|
||||
return $role_id;
|
||||
}
|
||||
}
|
||||
return 1; // 默认返回普通用户
|
||||
}
|
||||
|
||||
// 构建用户关系链
|
||||
private function buildUserChain($users, $params = [])
|
||||
{
|
||||
$defaults = [
|
||||
'min_depth' => 3, // 最小层级深度
|
||||
'max_depth' => 10, // 最大层级深度
|
||||
'max_children' => 5 // 每个用户最多下级数
|
||||
];
|
||||
|
||||
$params = array_merge($defaults, $params);
|
||||
// 为每个用户添加level属性(0-10的随机数)
|
||||
foreach ($users as $user_id => &$user) {
|
||||
$user['level'] = rand(0, 20);
|
||||
}
|
||||
$user_ids = array_keys($users);
|
||||
asort($user_ids);
|
||||
$last_user_id = 0;
|
||||
foreach($user_ids as $k=>$user_id){
|
||||
$users[$user_id.'']['parent_id'] = $last_user_id;
|
||||
$last_user_id = $user_id;
|
||||
}
|
||||
|
||||
return $users;
|
||||
}
|
||||
}
|
||||
@@ -1,191 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\enum;
|
||||
|
||||
enum BalanceType: int
|
||||
{
|
||||
/**
|
||||
* 充值
|
||||
*/
|
||||
case RECHARGE = 100;
|
||||
/**
|
||||
* 充值卡密
|
||||
*/
|
||||
case RECHARGE_CARD = 101;
|
||||
|
||||
/**
|
||||
* 提现
|
||||
*/
|
||||
case WITHDRAWAL = 200;
|
||||
|
||||
/**
|
||||
* 提现退回
|
||||
*/
|
||||
case WITHDRAWAL_REJECT = 201;
|
||||
|
||||
/**
|
||||
* 购买卡密
|
||||
*/
|
||||
case CDKEY = 202;
|
||||
|
||||
|
||||
/**
|
||||
* 站内转账
|
||||
*/
|
||||
case TRANSFER = 300;
|
||||
/**
|
||||
* 兑换
|
||||
*/
|
||||
case EXCHANGE = 301;
|
||||
/**
|
||||
* 领取问卷
|
||||
*/
|
||||
case CLAIM = 306;
|
||||
/**
|
||||
* 签到
|
||||
*/
|
||||
case SIGNIN = 302;
|
||||
/**
|
||||
* 发布朋友圈
|
||||
*/
|
||||
case POSTPYQ = 303;
|
||||
/**
|
||||
* 发布QQ群
|
||||
*/
|
||||
case POSTGROUP = 304;
|
||||
/**
|
||||
* 邀请新用户注册
|
||||
*/
|
||||
case INVITE_NEW_USER = 305;
|
||||
|
||||
/**
|
||||
* 购买产品
|
||||
*/
|
||||
case PRODUCT_BUY = 401;
|
||||
/**
|
||||
* 购买角色
|
||||
*/
|
||||
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 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;
|
||||
|
||||
/**
|
||||
* 获取所有类型映射数组
|
||||
*/
|
||||
public static function toArray(): array
|
||||
{
|
||||
return [
|
||||
self::RECHARGE->value => __('充值'),
|
||||
self::RECHARGE_CARD->value => __('充值卡密'),
|
||||
self::WITHDRAWAL->value => __('提现'),
|
||||
self::WITHDRAWAL_REJECT->value => __('提现退回'),
|
||||
self::CDKEY->value => __('购买卡密'),
|
||||
self::TRANSFER->value => __('站内转账'),
|
||||
self::EXCHANGE->value => __('兑换'),
|
||||
self::CLAIM->value => __('领取问卷'),
|
||||
self::SIGNIN->value => __('签到'),
|
||||
self::POSTPYQ->value => __('发布朋友圈'),
|
||||
self::POSTGROUP->value => __('发布QQ群'),
|
||||
self::INVITE_NEW_USER->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::OUTPUT_REWARD->value => __('产值奖励'),
|
||||
self::WITHDRAW_REWARD->value => __('提现奖励'),
|
||||
self::SALES_REWARD->value => __('销售奖励'),
|
||||
self::MEMBER_REWARD->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 => __('工作室奖励结算'),
|
||||
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前类型的描述文本
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return self::toArray()[$this->value];
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全地从值创建枚举实例
|
||||
*/
|
||||
public static function tryFromValue(int $value): ?self
|
||||
{
|
||||
return self::tryFrom($value);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\model;
|
||||
|
||||
|
||||
/**
|
||||
* @property integer $id 主键(主键)
|
||||
* @property string $name 角色名
|
||||
* @property string $rules 权限
|
||||
* @property string $created_at 创建时间
|
||||
* @property string $updated_at 更新时间
|
||||
* @property integer $pid 上级id
|
||||
*/
|
||||
class UserRole extends Base
|
||||
{
|
||||
|
||||
|
||||
public function setRulesAttr($v='',$row=[])
|
||||
{
|
||||
if(is_array($v)){
|
||||
return implode(',',$v);
|
||||
}
|
||||
return $v;
|
||||
}
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function getRuleIds()
|
||||
{
|
||||
return $this->rules ? explode(',', $this->rules) : [];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
@@ -1,127 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace plugin\admin\app\controller;
|
||||
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use support\think\Db;
|
||||
use Shopwwi\WebmanFilesystem\Facade\Storage;
|
||||
|
||||
/**
|
||||
* 附件管理
|
||||
*
|
||||
* @icon fa fa-circle-o
|
||||
*/
|
||||
class AttachmentController extends Crud
|
||||
{
|
||||
function list(Request $request)
|
||||
{
|
||||
|
||||
return view('', [
|
||||
|
||||
]);
|
||||
}
|
||||
function feupload(Request $request): Response
|
||||
{
|
||||
|
||||
$file = current($request->file());
|
||||
if (!$file || !$file->isValid()) {
|
||||
return $this->fail('未找到文件');
|
||||
}
|
||||
$data = $this->base($request, '/upload/files/' . date('Ymd'));
|
||||
return json([
|
||||
'link' => $data['url'],
|
||||
]);
|
||||
}
|
||||
function upload(Request $request): Response
|
||||
{
|
||||
|
||||
$file = current($request->file());
|
||||
if (!$file || !$file->isValid()) {
|
||||
return $this->fail('未找到文件');
|
||||
}
|
||||
$data = $this->base($request, '/upload/files/' . date('Ymd'));
|
||||
//cp($data);
|
||||
return $this->json(0, '上传成功', [
|
||||
'url' => $data['realpath'],
|
||||
'name' => $data['name'],
|
||||
'fullurl' => $data['url'],
|
||||
'size' => $data['size'],
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上传数据
|
||||
* @param Request $request
|
||||
* @param $relative_dir
|
||||
* @return array
|
||||
* @throws \Exception
|
||||
*/
|
||||
protected function base(Request $request, $relative_dir): array
|
||||
{
|
||||
// 适配器 local默认是存储在runtime目录下 public默认是存储在public目录下
|
||||
// 可访问的静态文件建议public
|
||||
// 默认适配器是local
|
||||
//Storage::adapter('public');
|
||||
$relative_dir = ltrim($relative_dir, '\\/');
|
||||
$file = current($request->file());
|
||||
try {
|
||||
if (!$file || !$file->isValid()) {
|
||||
throw new \support\exception\BusinessException('未找到上传文件', 400);
|
||||
}
|
||||
|
||||
$ext = $file->getUploadExtension() ?: null;
|
||||
$mime_type = $file->getUploadMimeType();
|
||||
$file_name = $file->getUploadName();
|
||||
$file_size = $file->getSize();
|
||||
|
||||
if (!$ext && $file_name === 'blob') {
|
||||
[$___image, $ext] = explode('/', $mime_type);
|
||||
unset($___image);
|
||||
}
|
||||
|
||||
$ext = strtolower($ext);
|
||||
$ext_forbidden_map = ['php', 'php3', 'php5', 'css', 'js', 'html', 'htm', 'asp', 'jsp'];
|
||||
if (in_array($ext, $ext_forbidden_map)) {
|
||||
throw new \support\exception\BusinessException('不支持该格式的文件上传', 400);
|
||||
}
|
||||
$mimetype = explode(',',Config('site.mimetype'));
|
||||
$result = Storage::adapter('public')
|
||||
->path($relative_dir)
|
||||
->size(1024 * 1024 * 5)
|
||||
->extYes($mimetype)
|
||||
//->extNo(['image/png'])
|
||||
->upload($file);
|
||||
} catch (\Exception $e) {
|
||||
return [
|
||||
'code' => 1,
|
||||
'msg' => $e->getMessage()
|
||||
];
|
||||
}
|
||||
// cp($result);
|
||||
// stdClass Object
|
||||
// (
|
||||
// [adapter] => public
|
||||
// [origin_name] => OIP-C (1).jpg
|
||||
// [file_name] => upload/files/20250527/eb14c1bfe6e7a22415bbbb30dfe90ba1_6834f0974db76.jpg
|
||||
// [storage_key] => eb14c1bfe6e7a22415bbbb30dfe90ba1_6834f0974db76
|
||||
// [file_url] => //luru.oss-ap-southeast-1.aliyuncs.com/upload/files/20250527/eb14c1bfe6e7a22415bbbb30dfe90ba1_6834f0974db76.jpg
|
||||
// [size] => 15370
|
||||
// [mime_type] => image/jpeg
|
||||
// [extension] => jpg
|
||||
// [file_height] => 474
|
||||
// [file_width] => 474
|
||||
// )
|
||||
return [
|
||||
'code' => 0,
|
||||
'url' => $result->file_url,
|
||||
'name' => $result->origin_name,
|
||||
'realpath' => '/'.$result->file_name,
|
||||
'size' => $result->size,
|
||||
'mime_type' => $result->mime_type,
|
||||
'image_with' => $result->file_width,
|
||||
'image_height' => $result->file_height,
|
||||
'ext' => $result->extension,
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
<style>
|
||||
#chooseicon {
|
||||
margin:10px;
|
||||
}
|
||||
#chooseicon ul {
|
||||
margin:5px 0 0 0;
|
||||
}
|
||||
#chooseicon ul li{
|
||||
width:41px;height:42px;
|
||||
line-height:42px;
|
||||
border:1px solid #efefef;
|
||||
padding:1px;
|
||||
margin:1px;
|
||||
text-align: center;
|
||||
font-size:18px;
|
||||
}
|
||||
#chooseicon ul li:hover{
|
||||
border:1px solid #2c3e50;
|
||||
cursor:pointer;
|
||||
}
|
||||
</style>
|
||||
<script id="chooseicontpl" type="text/html">
|
||||
<div id="chooseicon">
|
||||
<div>
|
||||
<form onsubmit="return false;">
|
||||
<div class="input-group input-groupp-md">
|
||||
<div class="input-group-addon">搜索图标</div>
|
||||
<input class="js-icon-search form-control" type="text" placeholder="">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div>
|
||||
<ul class="list-inline">
|
||||
<% for(var i=0; i<iconlist.length; i++){ %>
|
||||
<li data-font="<%=iconlist[i]%>" data-toggle="tooltip" title="<%=iconlist[i]%>">
|
||||
<i class="mdi mdi-<%=iconlist[i]%>"></i>
|
||||
</li>
|
||||
<% } %>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</script>
|
||||
@@ -1,21 +0,0 @@
|
||||
{layout name="layout"}
|
||||
<div class="toolbar" class="toolbar-btn-action">
|
||||
<a id="btn_add" class="btn btn-primary m-r-5 btn-add" data-url="{:url('insert')}" data-title="新增">
|
||||
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
|
||||
</a>
|
||||
<a id="btn_edit" class="btn btn-success m-r-5 btn-disabled disabled btn-multi" data-params="status=1">
|
||||
<span class="mdi mdi-check" aria-hidden="true"></span>启用
|
||||
</a>
|
||||
<a id="btn_edit" class="btn btn-warning m-r-5 btn-disabled disabled btn-multi" data-params="status=0">
|
||||
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
|
||||
</a>
|
||||
<a id="btn_delete" class="btn btn-danger btn-del btn-disabled disabled">
|
||||
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
|
||||
</a>
|
||||
</div>
|
||||
<!-- 数据表格 -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<table id="table"></table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,21 +0,0 @@
|
||||
{layout name="layout"}
|
||||
<div class="toolbar" class="toolbar-btn-action">
|
||||
<a id="btn_add" class="btn btn-primary m-r-5 btn-add" data-url="{:url('insert')}" data-title="新增">
|
||||
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
|
||||
</a>
|
||||
<a id="btn_edit" class="btn btn-success m-r-5 btn-disabled disabled btn-multi" data-params="status=1">
|
||||
<span class="mdi mdi-check" aria-hidden="true"></span>启用
|
||||
</a>
|
||||
<a id="btn_edit" class="btn btn-warning m-r-5 btn-disabled disabled btn-multi" data-params="status=0">
|
||||
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
|
||||
</a>
|
||||
<a id="btn_delete" class="btn btn-danger btn-del btn-disabled disabled">
|
||||
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
|
||||
</a>
|
||||
</div>
|
||||
<!-- 数据表格 -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<table id="table"></table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,21 +0,0 @@
|
||||
{layout name="layout"}
|
||||
<div class="toolbar" class="toolbar-btn-action">
|
||||
<a id="btn_add" class="btn btn-primary m-r-5 btn-add" data-url="{:url('insert')}" data-title="新增">
|
||||
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
|
||||
</a>
|
||||
<a id="btn_edit" class="btn btn-success m-r-5 btn-disabled disabled btn-multi" data-params="status=1">
|
||||
<span class="mdi mdi-check" aria-hidden="true"></span>启用
|
||||
</a>
|
||||
<a id="btn_edit" class="btn btn-warning m-r-5 btn-disabled disabled btn-multi" data-params="status=0">
|
||||
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
|
||||
</a>
|
||||
<a id="btn_delete" class="btn btn-danger btn-del btn-disabled disabled">
|
||||
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
|
||||
</a>
|
||||
</div>
|
||||
<!-- 数据表格 -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<table id="table"></table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,21 +0,0 @@
|
||||
{layout name="layout"}
|
||||
<div class="toolbar" class="toolbar-btn-action">
|
||||
<a id="btn_add" class="btn btn-primary m-r-5 btn-add" data-url="{:url('insert')}" data-title="新增">
|
||||
<span class="mdi mdi-plus" aria-hidden="true"></span>新增
|
||||
</a>
|
||||
<a id="btn_edit" class="btn btn-success m-r-5 btn-disabled disabled btn-multi" data-params="status=1">
|
||||
<span class="mdi mdi-check" aria-hidden="true"></span>启用
|
||||
</a>
|
||||
<a id="btn_edit" class="btn btn-warning m-r-5 btn-disabled disabled btn-multi" data-params="status=0">
|
||||
<span class="mdi mdi-block-helper" aria-hidden="true"></span>禁用
|
||||
</a>
|
||||
<a id="btn_delete" class="btn btn-danger btn-del btn-disabled disabled">
|
||||
<span class="mdi mdi-window-close" aria-hidden="true"></span>删除
|
||||
</a>
|
||||
</div>
|
||||
<!-- 数据表格 -->
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<table id="table"></table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,407 +0,0 @@
|
||||
define(['table', 'upload','form'], function (Table,Upload,Form) {
|
||||
var User = {
|
||||
//Do setup work hereAction
|
||||
index: function () {
|
||||
window.filterData = {
|
||||
};
|
||||
window.groupOption=Config.groupList;
|
||||
window.roleOption=Config.roleList;
|
||||
|
||||
Table.api.init({
|
||||
extend: {
|
||||
index_url: '/app/admin/user/select',
|
||||
add_url: '/app/admin/user/insert',
|
||||
edit_url: '/app/admin/user/update',
|
||||
del_url: '/app/admin/user/delete',
|
||||
multi_url: '/app/admin/user/multi',
|
||||
dragsort_url: '/app/admin/user/weigh',
|
||||
table: 'user',
|
||||
}
|
||||
});
|
||||
|
||||
var table = $("#table");
|
||||
var tableOptions = {
|
||||
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
||||
pk: 'id',
|
||||
sortName: 'id',
|
||||
commonSearch: false,
|
||||
search: false,
|
||||
columns: [
|
||||
[
|
||||
{checkbox: true},
|
||||
{
|
||||
field: 'id',
|
||||
title: 'ID',
|
||||
filter: "number",
|
||||
sortable: true // 是否排序
|
||||
},
|
||||
{
|
||||
title: "推荐人",
|
||||
field: "parent_id",
|
||||
formatter:function(v,row){
|
||||
return row.referrer ? row.referrer.username : '';
|
||||
},
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "分组",
|
||||
field: "group",
|
||||
formatter:function(v,row){
|
||||
for (let i = 0; i < Config.groupList.length; i++) {
|
||||
if(Config.groupList[i].value == v){
|
||||
return Config.groupList[i].label;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
filter: "select",
|
||||
filterOption:"groupOption",
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "角色",
|
||||
field: "role_id",
|
||||
formatter:function(v,row){
|
||||
return row.role ? row.role.name : '用户';
|
||||
},
|
||||
filter: "select",
|
||||
filterOption:"roleOption",
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "用户名",
|
||||
field: "username",
|
||||
filter: "string",
|
||||
},
|
||||
{
|
||||
title: "昵称",
|
||||
field: "nickname",
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
field: 'domain',
|
||||
title: '域名',
|
||||
filter: "string",
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
title: "头像",
|
||||
field: "avatar",
|
||||
formatter: function (v,d) {
|
||||
return '<img src="'+encodeURI(d['avatar'])+'" style="max-width:32px;max-height:32px;" alt="" />'
|
||||
},
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
title: "邮箱",
|
||||
field: "email",
|
||||
visible: false
|
||||
},
|
||||
{
|
||||
title: "手机",
|
||||
field: "mobile",
|
||||
visible: false
|
||||
},
|
||||
// {
|
||||
// title: "等级",
|
||||
// field: "level",
|
||||
// visible: false,
|
||||
// },
|
||||
// {
|
||||
// title: "生日",
|
||||
// field: "birthday",
|
||||
// visible: false,
|
||||
// },
|
||||
// {
|
||||
// title: "后缀",
|
||||
// field: "decimal_part",
|
||||
// //visible: false,
|
||||
// },
|
||||
{
|
||||
title: "调研币",
|
||||
field: "money",
|
||||
formatter:Table.api.formatter.number,
|
||||
sortable: true,
|
||||
//visible: false,
|
||||
},
|
||||
{
|
||||
title: "积分",
|
||||
field: "score",
|
||||
sortable: true,
|
||||
visible: false,
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "调研豆",
|
||||
field: "currency1",
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "可领取",
|
||||
field: "currency6",
|
||||
sortable: true,
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "待分配",
|
||||
field: "currency7",
|
||||
sortable: true,
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "已分配",
|
||||
field: "currency8",
|
||||
sortable: true,
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "未通过",
|
||||
field: "currency9",
|
||||
sortable: true,
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "登录时间",
|
||||
field: "last_time",
|
||||
formatter:Table.api.formatter.datetime,
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "登录ip",
|
||||
field: "last_ip",
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "注册时间",
|
||||
field: "join_time",
|
||||
formatter:Table.api.formatter.datetime,
|
||||
filter:'datetime'
|
||||
},
|
||||
{
|
||||
title: "注册ip",
|
||||
field: "join_ip",
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
field: "created_at",
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "更新时间",
|
||||
field: "updated_at",
|
||||
formatter:Table.api.formatter.datetime,
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
field: "status",
|
||||
formatter: Table.api.formatter.switch
|
||||
},
|
||||
{
|
||||
field: 'operate', title: '操作',
|
||||
table: table, events: Table.api.events.operate,
|
||||
formatter: Table.api.formatter.operate,
|
||||
buttons:[
|
||||
{
|
||||
text:"团队",
|
||||
name:"team",
|
||||
icon:"mdi mdi-account-group-outline",
|
||||
classname:"btn btn-xs btn-info btn-dialog",
|
||||
url:'/app/admin/user/team'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
]
|
||||
};
|
||||
// 初始化表格
|
||||
table.bootstrapTable(tableOptions);
|
||||
// 为表格绑定事件
|
||||
Table.api.bindevent(table);
|
||||
},
|
||||
update:function(){
|
||||
Config['uploadurl'] = '/app/admin/attachment/avatar';
|
||||
var form = $('form');
|
||||
Form.api.bindevent(form)
|
||||
this.getRole();
|
||||
},
|
||||
insert:function(){
|
||||
Config['uploadurl'] = '/app/admin/attachment/avatar';
|
||||
var form = $('form');
|
||||
Form.api.bindevent(form)
|
||||
this.getRole();
|
||||
},
|
||||
getRole:function(){
|
||||
Fast.api.ajax({
|
||||
url: "/app/admin/UserRole/select?format=tree",
|
||||
dataType: "json",
|
||||
success: function (res) {
|
||||
Layer.closeAll();
|
||||
var html = "";
|
||||
var selected=$('#roles').data('value');
|
||||
for (let index = 0; index < res.data.length; index++) {
|
||||
const element = res.data[index];
|
||||
if(selected == element.id){
|
||||
html+='<option value="'+element.id+'" selected>'+element.name+'</option>';
|
||||
}else{
|
||||
html+='<option value="'+element.id+'">'+element.name+'</option>';
|
||||
}
|
||||
}
|
||||
$('#roles').append(html);
|
||||
}
|
||||
});
|
||||
},
|
||||
team:function(){
|
||||
window.filterData = {
|
||||
"user_id":{value1:Fast.api.query('ids'),symbol:'=','value2':''},
|
||||
'type' : {value1:'child',symbol:'=','value2':''}
|
||||
};
|
||||
|
||||
$('.nav-tabs li').on('click',function(){
|
||||
$('.nav-tabs li').removeClass('active');
|
||||
$(this).addClass('active');
|
||||
window.filterData['type'] = {value1:$(this).data('type'),symbol:'=','value2':''};
|
||||
table.bootstrapTable('selectPage', 1);
|
||||
});
|
||||
|
||||
Table.api.init({
|
||||
extend: {
|
||||
index_url: '/app/admin/team/select',
|
||||
add_url: null,
|
||||
edit_url: null,
|
||||
del_url: null,
|
||||
multi_url: null,
|
||||
dragsort_url: null,
|
||||
table: 'team',
|
||||
}
|
||||
});
|
||||
|
||||
var table = $("#table");
|
||||
var tableOptions = {
|
||||
url: $.fn.bootstrapTable.defaults.extend.index_url,
|
||||
pk: 'id',
|
||||
sortName: 'id',
|
||||
commonSearch: false,
|
||||
search: false,
|
||||
columns: [
|
||||
[
|
||||
{checkbox: true},
|
||||
{
|
||||
title: "深度",
|
||||
field: "depth",
|
||||
},
|
||||
{
|
||||
field: 'id',
|
||||
title: 'ID',
|
||||
filter: "number",
|
||||
sortable: true // 是否排序
|
||||
},
|
||||
{
|
||||
title: "角色",
|
||||
field: "role_id",
|
||||
formatter: function(v,item){
|
||||
return 'V'+v;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "用户名",
|
||||
field: "username",
|
||||
filter: "string",
|
||||
},
|
||||
// {
|
||||
// title: "等级",
|
||||
// field: "level",
|
||||
// visible: false,
|
||||
// },
|
||||
{
|
||||
title: "余额",
|
||||
field: "money",
|
||||
formatter:Table.api.formatter.number,
|
||||
sortable: true,
|
||||
//visible: false,
|
||||
},
|
||||
{
|
||||
title: "积分",
|
||||
field: "score",
|
||||
sortable: true,
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "调研币",
|
||||
field: "currency1",
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "可领取",
|
||||
field: "currency6",
|
||||
sortable: true,
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "待分配",
|
||||
field: "currency7",
|
||||
sortable: true,
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "已分配",
|
||||
field: "currency8",
|
||||
sortable: true,
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "未通过",
|
||||
field: "currency9",
|
||||
sortable: true,
|
||||
formatter:Table.api.formatter.number
|
||||
},
|
||||
{
|
||||
title: "登录时间",
|
||||
field: "last_time",
|
||||
formatter:Table.api.formatter.datetime,
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "登录ip",
|
||||
field: "last_ip",
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "注册时间",
|
||||
field: "join_time",
|
||||
formatter:Table.api.formatter.datetime,
|
||||
filter:'datetime'
|
||||
},
|
||||
{
|
||||
title: "注册ip",
|
||||
field: "join_ip",
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "创建时间",
|
||||
field: "created_at",
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "更新时间",
|
||||
field: "updated_at",
|
||||
formatter:Table.api.formatter.datetime,
|
||||
visible: false,
|
||||
},
|
||||
{
|
||||
title: "状态",
|
||||
field: "status",
|
||||
formatter: Table.api.formatter.switch
|
||||
}
|
||||
]
|
||||
]
|
||||
};
|
||||
// 初始化表格
|
||||
table.bootstrapTable(tableOptions);
|
||||
// 为表格绑定事件
|
||||
Table.api.bindevent(table);
|
||||
}
|
||||
};
|
||||
return User
|
||||
});
|
||||
|
Before Width: | Height: | Size: 298 KiB |
@@ -1,29 +0,0 @@
|
||||
{
|
||||
"name": "layer",
|
||||
"main": "src/layer.js",
|
||||
"version": "3.5.3",
|
||||
"homepage": "https://github.com/sentsin/layer",
|
||||
"authors": [
|
||||
"sentsin <xu@sentsin.com>"
|
||||
],
|
||||
"description": "弹窗组件",
|
||||
"moduleType": [
|
||||
"amd",
|
||||
"globals"
|
||||
],
|
||||
"keywords": [
|
||||
"layer",
|
||||
"layui",
|
||||
"dialog"
|
||||
],
|
||||
"license": "MIT",
|
||||
"_release": "3.5.3",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "v3.5.3",
|
||||
"commit": "7ef901632a7d21f37692ae5d4f9e671c7d57ce47"
|
||||
},
|
||||
"_source": "https://github.com/karsonzhang/fastadmin-layer.git",
|
||||
"_target": "~3.5.1",
|
||||
"_originalSource": "fastadmin-layer"
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
1.8.5/
|
||||
*.iml
|
||||
.idea/
|
||||
.ipr
|
||||
.iws
|
||||
*~
|
||||
~*
|
||||
*.diff
|
||||
*.patch
|
||||
*.bak
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
.svn/
|
||||
*.swp
|
||||
.nojekyll
|
||||
.project
|
||||
.settings/
|
||||
node_modules/
|
||||
_site/
|
||||
.npmignore
|
||||
release/
|
||||
skin/moon/
|
||||
src/skin/moon/
|
||||
@@ -1,21 +0,0 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2016 layui
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
## 概要
|
||||
layer 是一款历来都备受青睐的 Web 弹出层组件,具备全方位的解决方案,面向的是各个水平段的开发人员,您的页面会轻松地拥有丰富友好的操作体验。在与同类组件的比较中,layer 会更能被开发者所选择。这不仅是凭「脸」取胜,而是它尽可能地在以更少的代码展现更强健的功能,且格外注重性能的提升、易用和实用性,layer 甚至还兼容了包括 IE6 在内的所有主流浏览器。其数量可观的基础属性和方法,使得您可以自定义太多您需要的风格,每一种弹层模式各具特色,广受欢迎。当然,这种「王婆卖瓜」的陈述听起来总是有点难受,因此你需要进一步了解她是否真的如你所愿。
|
||||
|
||||
[文档与演示](http://layer.layui.com/)
|
||||
|
||||
## 愿景
|
||||
成为网页弹出层的首先交互方案
|
||||
|
||||
## 现状
|
||||
因着数年的坚持维护,已被运用在不计其数 Web 平台。几乎所处可见,其中还不乏众多知名大型网站。layer 已被国内乃至全世界至少数十万的开发者所使用过。
|
||||
|
||||
|
||||
## 相关
|
||||
[官网](http://layer.layui.com/)
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"name": "layer",
|
||||
"main": "src/layer.js",
|
||||
"version": "3.5.3",
|
||||
"homepage": "https://github.com/sentsin/layer",
|
||||
"authors": [
|
||||
"sentsin <xu@sentsin.com>"
|
||||
],
|
||||
"description": "弹窗组件",
|
||||
"moduleType": [
|
||||
"amd",
|
||||
"globals"
|
||||
],
|
||||
"keywords": [
|
||||
"layer",
|
||||
"layui",
|
||||
"dialog"
|
||||
],
|
||||
"license": "MIT"
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
/*! layer mobile-v2.0.0 Web 通用弹出层组件 MIT License http://layer.layui.com/mobile By 贤心 */
|
||||
;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'<h3 style="'+(e?n.title[1]:"")+'">'+(e?n.title[0]:n.title)+"</h3>":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e='<span yes type="1">'+n.btn[0]+"</span>",2===t&&(e='<span no type="0">'+n.btn[1]+"</span>"+e),'<div class="layui-m-layerbtn">'+e+"</div>"):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='<i></i><i class="layui-m-layerload"></i><i></i><p>'+(n.content||"")+"</p>"),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"<div "+("string"==typeof n.shade?'style="'+n.shade+'"':"")+' class="layui-m-layershade"></div>':"")+'<div class="layui-m-layermain" '+(n.fixed?"":'style="position:static;"')+'><div class="layui-m-layersection"><div class="layui-m-layerchild '+(n.skin?"layui-m-layer-"+n.skin+" ":"")+(n.className?n.className:"")+" "+(n.anim?"layui-m-anim-"+n.anim:"")+'" '+(n.style?'style="'+n.style+'"':"")+">"+l+'<div class="layui-m-layercont">'+n.content+"</div>"+c+"</div></div></div>",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;o<r;o++)l.touch(s[o],a);if(e.shade&&e.shadeClose){var c=t[i]("layui-m-layershade")[0];l.touch(c,function(){layer.close(n.index,e.end)})}e.end&&(l.end[n.index]=e.end)},e.layer={v:"2.0",index:r,open:function(e){var t=new c(e||{});return t.index},close:function(e){var n=a("#"+o[0]+e)[0];n&&(n.innerHTML="",t.body.removeChild(n),clearTimeout(l.timer[e]),delete l.timer[e],"function"==typeof l.end[e]&&l.end[e](),delete l.end[e])},closeAll:function(){for(var e=t[i](o[0]),n=0,a=e.length;n<a;n++)layer.close(0|e[0].getAttribute("index"))}},"function"==typeof define?define(function(){return layer}):function(){var e=document.scripts,n=e[e.length-1],i=n.src,a=i.substring(0,i.lastIndexOf("/")+1);n.getAttribute("merge")||document.head.appendChild(function(){var e=t.createElement("link");return e.href=a+"need/layer.css?2.0",e.type="text/css",e.rel="styleSheet",e.id="layermcss",e}())}()}(window);
|
||||
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 701 B |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 7.4 KiB |
@@ -1 +0,0 @@
|
||||
html #layui_layer_skinmoonstylecss{display:none;position:absolute;width:1989px}body .layer-ext-moon[type=dialog]{min-width:320px}body .layer-ext-moon-msg[type=dialog]{min-width:200px}body .layer-ext-moon .layui-layer-title{background:#f6f6f6;color:#212a31;font-size:16px;font-weight:700;height:46px;line-height:46px;border-bottom:1px solid #d5d5d5}body .layer-ext-moon .layui-layer-content .layui-layer-ico{height:32px;width:32px;top:18.5px}body .layer-ext-moon .layui-layer-ico0{background:url(default.png) no-repeat -96px 0}body .layer-ext-moon .layui-layer-ico1{background:url(default.png) no-repeat -224px 0}body .layer-ext-moon .layui-layer-ico2{background:url(default.png) no-repeat -192px 0}body .layer-ext-moon .layui-layer-ico3{background:url(default.png) no-repeat -160px 0}body .layer-ext-moon .layui-layer-ico4{background:url(default.png) no-repeat -320px 0}body .layer-ext-moon .layui-layer-ico5{background:url(default.png) no-repeat -288px 0}body .layer-ext-moon .layui-layer-ico6{background:url(default.png) -256px 0}body .layer-ext-moon .layui-layer-ico7{background:url(default.png) no-repeat -128px 0}body .layer-ext-moon .layui-layer-setwin{top:15px;right:15px}body .layer-ext-moon .layui-layer-setwin a{width:16px;height:16px}body .layer-ext-moon .layui-layer-setwin .layui-layer-min cite:hover{background-color:#56abe4}body .layer-ext-moon .layui-layer-setwin .layui-layer-max{background:url(default.png) no-repeat -80px 0}body .layer-ext-moon .layui-layer-setwin .layui-layer-max:hover{background:url(default.png) no-repeat -64px 0}body .layer-ext-moon .layui-layer-setwin .layui-layer-maxmin{background:url(default.png) no-repeat -32px 0}body .layer-ext-moon .layui-layer-setwin .layui-layer-maxmin:hover{background:url(default.png) no-repeat -16px 0}body .layer-ext-moon .layui-layer-setwin .layui-layer-close1,body .layer-ext-moon .layui-layer-setwin .layui-layer-close2{background:url(default.png) 0 0}body .layer-ext-moon .layui-layer-setwin .layui-layer-close1:hover,body .layer-ext-moon .layui-layer-setwin .layui-layer-close2:hover{background:url(default.png) -48px 0}body .layer-ext-moon .layui-layer-padding{padding-top:24px}body .layer-ext-moon .layui-layer-btn{text-align:center;padding-top:15px;padding-bottom:15px;background:#f0f4f7;border-top:1px #c7c7c7 solid}body .layer-ext-moon .layui-layer-btn a{font-size:12px;font-weight:400;margin:0 3px;margin-right:7px;margin-left:7px;padding:6px 20px;color:#fff;border:1px solid #0064b6;background:#0071ce;border-radius:3px;display:inline-block;height:20px;line-height:20px;text-align:center;vertical-align:middle;background-repeat:no-repeat;text-decoration:none;outline:0}body .layer-ext-moon .layui-layer-btn .layui-layer-btn0{background:#0071ce}body .layer-ext-moon .layui-layer-btn .layui-layer-btn1{background:#fff;color:#404a58;border:1px solid #c0c4cd;border-radius:3px}body .layer-ext-moon .layui-layer-btn .layui-layer-btn2{background:#f60;color:#fff;border:1px solid #f60;border-radius:3px}body .layer-ext-moon .layui-layer-btn .layui-layer-btn3{background:red;color:#fff;border:1px solid red;border-radius:3px}body .layer-ext-moon .layui-layer-title span.layui-layer-tabnow{height:47px}
|
||||
@@ -1,35 +0,0 @@
|
||||
/**
|
||||
layer构建
|
||||
*/
|
||||
|
||||
const {src, dest, series} = require('gulp');
|
||||
var pkg = require('./package.json');
|
||||
var uglify = require('gulp-uglify');
|
||||
var minify = require('gulp-clean-css');
|
||||
var rename = require('gulp-rename');
|
||||
var header = require('gulp-header');
|
||||
var del = require('del');
|
||||
|
||||
var task = {
|
||||
layer: function () {
|
||||
src('./src/**/*.css')
|
||||
.pipe(minify({
|
||||
compatibility: 'ie7'
|
||||
}))
|
||||
.pipe(dest('./dist'));
|
||||
|
||||
return src('./src/layer.js').pipe(uglify())
|
||||
.pipe(header('/*! <%= pkg.realname %>-v<%= pkg.version %> <%= pkg.description %> <%= pkg.license %> License <%= pkg.homepage %> By <%= pkg.author %> */\n ;', {pkg: pkg}))
|
||||
.pipe(dest('./dist'));
|
||||
|
||||
}
|
||||
, mobile: function () {
|
||||
return src('./src/mobile/layer.js').pipe(uglify())
|
||||
.pipe(header('/*! <%= pkg.realname %> mobile-v<%= pkg.mobile %> <%= pkg.description %> <%= pkg.license %> License <%= pkg.homepage %>mobile By <%= pkg.author %> */\n ;', {pkg: pkg}))
|
||||
.pipe(dest('./dist/mobile'));
|
||||
}
|
||||
};
|
||||
|
||||
exports.layer = task.layer;
|
||||
exports.mobile = task.mobile;
|
||||
exports.default = series(task.layer, task.mobile);
|
||||
@@ -1,41 +0,0 @@
|
||||
{
|
||||
"name": "layer-src",
|
||||
"realname": "layer",
|
||||
"version": "3.5.3",
|
||||
"mobile": "2.0.0",
|
||||
"description": "Web 通用弹出层组件",
|
||||
"main": "src/layer.js",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"run": "gulp"
|
||||
},
|
||||
"repository": {
|
||||
"type": "https",
|
||||
"url": "git+https://github.com/sentsin/layer.git"
|
||||
},
|
||||
"author": "贤心",
|
||||
"homepage": "http://layer.layui.com/",
|
||||
"devDependencies": {
|
||||
"del": "~2.2.2",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-header": "~1.8.8",
|
||||
"gulp-clean-css": "~4.2.0",
|
||||
"gulp-rename": "~1.2.2",
|
||||
"gulp-uglify": "~1.5.4"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/sentsin/layer/issues"
|
||||
},
|
||||
"directories": {
|
||||
"test": "test"
|
||||
},
|
||||
"dependencies": {},
|
||||
"keywords": [
|
||||
"layer",
|
||||
"dialog",
|
||||
"tips",
|
||||
"alert",
|
||||
"confirm",
|
||||
"window"
|
||||
]
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
## 注意
|
||||
开发版源码随时可能会提交,因此生产环境更建议 dist 目录中压缩后的 layer.js。
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
## layer mobile
|
||||
layer mobile是为移动设备(手机、平板等webkit内核浏览器/webview)量身定做的弹层支撑,采用Native JavaScript编写,完全独立于PC版的layer,您需要按照场景选择使用。
|
||||
|
||||
[文档与演示](http://sentsin.com/layui/layer/)
|
||||
|
||||
1. 无需依赖任何库,只加载layer.m.js即可
|
||||
2. 小巧玲珑,性能卓越、柔情似水…
|
||||
3. 具备无以伦比的自适应功能
|
||||
4. 灵活的皮肤自定义支撑,充分确保弹层风格多样化
|
||||
5. 丰富、科学的接口,让弹弹弹层无所不能
|
||||
|
||||
## 备注
|
||||
[官网](http://sentsin.com/layui/layer/)、[有问必答](http://say.sentsin.com/home-48.html)
|
||||
@@ -1,207 +0,0 @@
|
||||
/*!
|
||||
|
||||
@Name:layer mobile v2.0 弹层组件移动版
|
||||
@Author:贤心
|
||||
@License:MIT
|
||||
|
||||
*/
|
||||
|
||||
;!function(win){
|
||||
|
||||
"use strict";
|
||||
|
||||
var doc = document, query = 'querySelectorAll', claname = 'getElementsByClassName', S = function(s){
|
||||
return doc[query](s);
|
||||
};
|
||||
|
||||
//默认配置
|
||||
var config = {
|
||||
type: 0
|
||||
,shade: true
|
||||
,shadeClose: true
|
||||
,fixed: true
|
||||
,anim: 'scale' //默认动画类型
|
||||
};
|
||||
|
||||
var ready = {
|
||||
extend: function(obj){
|
||||
var newobj = JSON.parse(JSON.stringify(config));
|
||||
for(var i in obj){
|
||||
newobj[i] = obj[i];
|
||||
}
|
||||
return newobj;
|
||||
},
|
||||
timer: {}, end: {}
|
||||
};
|
||||
|
||||
//点触事件
|
||||
ready.touch = function(elem, fn){
|
||||
elem.addEventListener('click', function(e){
|
||||
fn.call(this, e);
|
||||
}, false);
|
||||
};
|
||||
|
||||
var index = 0, classs = ['layui-m-layer'], Layer = function(options){
|
||||
var that = this;
|
||||
that.config = ready.extend(options);
|
||||
that.view();
|
||||
};
|
||||
|
||||
Layer.prototype.view = function(){
|
||||
var that = this, config = that.config, layerbox = doc.createElement('div');
|
||||
|
||||
that.id = layerbox.id = classs[0] + index;
|
||||
layerbox.setAttribute('class', classs[0] + ' ' + classs[0]+(config.type || 0));
|
||||
layerbox.setAttribute('index', index);
|
||||
|
||||
//标题区域
|
||||
var title = (function(){
|
||||
var titype = typeof config.title === 'object';
|
||||
return config.title
|
||||
? '<h3 style="'+ (titype ? config.title[1] : '') +'">'+ (titype ? config.title[0] : config.title) +'</h3>'
|
||||
: '';
|
||||
}());
|
||||
|
||||
//按钮区域
|
||||
var button = (function(){
|
||||
typeof config.btn === 'string' && (config.btn = [config.btn]);
|
||||
var btns = (config.btn || []).length, btndom;
|
||||
if(btns === 0 || !config.btn){
|
||||
return '';
|
||||
}
|
||||
btndom = '<span yes type="1">'+ config.btn[0] +'</span>'
|
||||
if(btns === 2){
|
||||
btndom = '<span no type="0">'+ config.btn[1] +'</span>' + btndom;
|
||||
}
|
||||
return '<div class="layui-m-layerbtn">'+ btndom + '</div>';
|
||||
}());
|
||||
|
||||
if(!config.fixed){
|
||||
config.top = config.hasOwnProperty('top') ? config.top : 100;
|
||||
config.style = config.style || '';
|
||||
config.style += ' top:'+ ( doc.body.scrollTop + config.top) + 'px';
|
||||
}
|
||||
|
||||
if(config.type === 2){
|
||||
config.content = '<i></i><i class="layui-m-layerload"></i><i></i><p>'+ (config.content||'') +'</p>';
|
||||
}
|
||||
|
||||
if(config.skin) config.anim = 'up';
|
||||
if(config.skin === 'msg') config.shade = false;
|
||||
|
||||
layerbox.innerHTML = (config.shade ? '<div '+ (typeof config.shade === 'string' ? 'style="'+ config.shade +'"' : '') +' class="layui-m-layershade"></div>' : '')
|
||||
+'<div class="layui-m-layermain" '+ (!config.fixed ? 'style="position:static;"' : '') +'>'
|
||||
+'<div class="layui-m-layersection">'
|
||||
+'<div class="layui-m-layerchild '+ (config.skin ? 'layui-m-layer-' + config.skin + ' ' : '') + (config.className ? config.className : '') + ' ' + (config.anim ? 'layui-m-anim-' + config.anim : '') +'" ' + ( config.style ? 'style="'+config.style+'"' : '' ) +'>'
|
||||
+ title
|
||||
+'<div class="layui-m-layercont">'+ config.content +'</div>'
|
||||
+ button
|
||||
+'</div>'
|
||||
+'</div>'
|
||||
+'</div>';
|
||||
|
||||
if(!config.type || config.type === 2){
|
||||
var dialogs = doc[claname](classs[0] + config.type), dialen = dialogs.length;
|
||||
if(dialen >= 1){
|
||||
layer.close(dialogs[0].getAttribute('index'))
|
||||
}
|
||||
}
|
||||
|
||||
document.body.appendChild(layerbox);
|
||||
var elem = that.elem = S('#'+that.id)[0];
|
||||
config.success && config.success(elem);
|
||||
|
||||
that.index = index++;
|
||||
that.action(config, elem);
|
||||
};
|
||||
|
||||
Layer.prototype.action = function(config, elem){
|
||||
var that = this;
|
||||
|
||||
//自动关闭
|
||||
if(config.time){
|
||||
ready.timer[that.index] = setTimeout(function(){
|
||||
layer.close(that.index);
|
||||
}, config.time*1000);
|
||||
}
|
||||
|
||||
//确认取消
|
||||
var btn = function(){
|
||||
var type = this.getAttribute('type');
|
||||
if(type == 0){
|
||||
config.no && config.no();
|
||||
layer.close(that.index);
|
||||
} else {
|
||||
config.yes ? config.yes(that.index) : layer.close(that.index);
|
||||
}
|
||||
};
|
||||
if(config.btn){
|
||||
var btns = elem[claname]('layui-m-layerbtn')[0].children, btnlen = btns.length;
|
||||
for(var ii = 0; ii < btnlen; ii++){
|
||||
ready.touch(btns[ii], btn);
|
||||
}
|
||||
}
|
||||
|
||||
//点遮罩关闭
|
||||
if(config.shade && config.shadeClose){
|
||||
var shade = elem[claname]('layui-m-layershade')[0];
|
||||
ready.touch(shade, function(){
|
||||
layer.close(that.index, config.end);
|
||||
});
|
||||
}
|
||||
|
||||
config.end && (ready.end[that.index] = config.end);
|
||||
};
|
||||
|
||||
win.layer = {
|
||||
v: '2.0',
|
||||
index: index,
|
||||
|
||||
//核心方法
|
||||
open: function(options){
|
||||
var o = new Layer(options || {});
|
||||
return o.index;
|
||||
},
|
||||
|
||||
close: function(index){
|
||||
var ibox = S('#'+classs[0]+index)[0];
|
||||
if(!ibox) return;
|
||||
ibox.innerHTML = '';
|
||||
doc.body.removeChild(ibox);
|
||||
clearTimeout(ready.timer[index]);
|
||||
delete ready.timer[index];
|
||||
typeof ready.end[index] === 'function' && ready.end[index]();
|
||||
delete ready.end[index];
|
||||
},
|
||||
|
||||
//关闭所有layer层
|
||||
closeAll: function(){
|
||||
var boxs = doc[claname](classs[0]);
|
||||
for(var i = 0, len = boxs.length; i < len; i++){
|
||||
layer.close((boxs[0].getAttribute('index')|0));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
'function' == typeof define ? define(function() {
|
||||
return layer;
|
||||
}) : function(){
|
||||
|
||||
var js = document.scripts, script = js[js.length - 1], jsPath = script.src;
|
||||
var path = jsPath.substring(0, jsPath.lastIndexOf("/") + 1);
|
||||
|
||||
//如果合并方式,则需要单独引入layer.css
|
||||
if(script.getAttribute('merge')) return;
|
||||
|
||||
document.head.appendChild(function(){
|
||||
var link = doc.createElement('link');
|
||||
link.href = path + 'need/layer.css?2.0';
|
||||
link.type = 'text/css';
|
||||
link.rel = 'styleSheet'
|
||||
link.id = 'layermcss';
|
||||
return link;
|
||||
}());
|
||||
|
||||
}();
|
||||
|
||||
}(window);
|
||||
@@ -1,87 +0,0 @@
|
||||
|
||||
/*
|
||||
layer mobile
|
||||
*/
|
||||
|
||||
.layui-m-layer{position:relative; z-index: 19891014;}
|
||||
.layui-m-layer *{-webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box;}
|
||||
.layui-m-layershade,
|
||||
.layui-m-layermain{position:fixed; left:0; top:0; width:100%; height:100%;}
|
||||
.layui-m-layershade{background-color:rgba(0,0,0, .7); pointer-events:auto;}
|
||||
.layui-m-layermain{display:table; font-family: Helvetica, arial, sans-serif; pointer-events: none;}
|
||||
.layui-m-layermain .layui-m-layersection{display:table-cell; vertical-align:middle; text-align:center;}
|
||||
.layui-m-layerchild{position:relative; display:inline-block; text-align:left; background-color:#fff; font-size:14px; border-radius: 5px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.1); pointer-events:auto; -webkit-overflow-scrolling: touch;}
|
||||
.layui-m-layerchild{-webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-duration: .2s; animation-duration: .2s;}
|
||||
|
||||
|
||||
/* 弹出动画 */
|
||||
@-webkit-keyframes layui-m-anim-scale { /* 默认 */
|
||||
0% {opacity: 0; -webkit-transform: scale(.5); transform: scale(.5)}
|
||||
100% {opacity: 1; -webkit-transform: scale(1); transform: scale(1)}
|
||||
}
|
||||
@keyframes layui-m-anim-scale { /* 默认 */
|
||||
0% {opacity: 0; -webkit-transform: scale(.5); transform: scale(.5)}
|
||||
100% {opacity: 1; -webkit-transform: scale(1); transform: scale(1)}
|
||||
}
|
||||
.layui-m-anim-scale{animation-name: layui-m-anim-scale; -webkit-animation-name: layui-m-anim-scale;}
|
||||
|
||||
@-webkit-keyframes layui-m-anim-up{
|
||||
0%{opacity: 0; -webkit-transform: translateY(800px); transform: translateY(800px)}
|
||||
100%{opacity: 1; -webkit-transform: translateY(0); transform: translateY(0)}
|
||||
}
|
||||
@keyframes layui-m-anim-up{
|
||||
0%{opacity: 0; -webkit-transform: translateY(800px); transform: translateY(800px)}
|
||||
100%{opacity: 1; -webkit-transform: translateY(0); transform: translateY(0)}
|
||||
}
|
||||
.layui-m-anim-up{-webkit-animation-name: layui-m-anim-up;animation-name: layui-m-anim-up}
|
||||
|
||||
|
||||
.layui-m-layer0 .layui-m-layerchild{width: 90%; max-width: 640px;}
|
||||
.layui-m-layer1 .layui-m-layerchild{border:none; border-radius:0;}
|
||||
.layui-m-layer2 .layui-m-layerchild{width:auto; max-width:260px; min-width:40px; border:none; background: none; box-shadow: none; color:#fff;}
|
||||
.layui-m-layerchild h3{padding: 0 10px; height: 60px; line-height: 60px; font-size:16px; font-weight: 400; border-radius: 5px 5px 0 0; text-align: center;}
|
||||
.layui-m-layerchild h3,
|
||||
.layui-m-layerbtn span{ text-overflow:ellipsis; overflow:hidden; white-space:nowrap;}
|
||||
.layui-m-layercont{padding: 50px 30px; line-height: 22px; text-align:center;}
|
||||
.layui-m-layer1 .layui-m-layercont{padding:0; text-align:left;}
|
||||
.layui-m-layer2 .layui-m-layercont{text-align:center; padding: 0; line-height: 0;}
|
||||
.layui-m-layer2 .layui-m-layercont i{width:25px; height:25px; margin-left:8px; display:inline-block; background-color:#fff; border-radius:100%;}
|
||||
.layui-m-layer2 .layui-m-layercont p{margin-top: 20px;}
|
||||
|
||||
/* loading */
|
||||
@-webkit-keyframes layui-m-anim-loading{
|
||||
0%,80%,100%{transform:scale(0); -webkit-transform:scale(0)}
|
||||
40%{transform:scale(1); -webkit-transform:scale(1)}
|
||||
}
|
||||
@keyframes layui-m-anim-loading{
|
||||
0%,80%,100%{transform:scale(0); -webkit-transform:scale(0)}
|
||||
40%{transform:scale(1); -webkit-transform:scale(1)}
|
||||
}
|
||||
.layui-m-layer2 .layui-m-layercont i{-webkit-animation: layui-m-anim-loading 1.4s infinite ease-in-out; animation: layui-m-anim-loading 1.4s infinite ease-in-out; -webkit-animation-fill-mode: both; animation-fill-mode: both;}
|
||||
|
||||
.layui-m-layer2 .layui-m-layercont i:first-child{margin-left:0; -webkit-animation-delay: -.32s; animation-delay: -.32s;}
|
||||
.layui-m-layer2 .layui-m-layercont i.layui-m-layerload{-webkit-animation-delay: -.16s; animation-delay: -.16s;}
|
||||
.layui-m-layer2 .layui-m-layercont>div{line-height:22px; padding-top:7px; margin-bottom:20px; font-size: 14px;}
|
||||
.layui-m-layerbtn{display: box; display: -moz-box; display: -webkit-box; width: 100%; position:relative; height: 50px; line-height: 50px; font-size: 0; text-align:center; border-top:1px solid #D0D0D0; background-color: #F2F2F2; border-radius: 0 0 5px 5px;}
|
||||
.layui-m-layerbtn span{position:relative; display: block; -moz-box-flex: 1; box-flex: 1; -webkit-box-flex: 1; text-align:center; font-size:14px; border-radius: 0 0 5px 5px; cursor:pointer;}
|
||||
.layui-m-layerbtn span[yes]{color: #40AFFE;}
|
||||
.layui-m-layerbtn span[no]{border-right: 1px solid #D0D0D0; border-radius: 0 0 0 5px;}
|
||||
.layui-m-layerbtn span:active{background-color: #F6F6F6;}
|
||||
.layui-m-layerend{position:absolute; right:7px; top:10px; width:30px; height:30px; border: 0; font-weight:400; background: transparent; cursor: pointer; -webkit-appearance: none; font-size:30px;}
|
||||
.layui-m-layerend::before, .layui-m-layerend::after{position:absolute; left:5px; top:15px; content:''; width:18px; height:1px; background-color:#999; transform:rotate(45deg); -webkit-transform:rotate(45deg); border-radius: 3px;}
|
||||
.layui-m-layerend::after{transform:rotate(-45deg); -webkit-transform:rotate(-45deg);}
|
||||
|
||||
/* 底部对话框风格 */
|
||||
body .layui-m-layer .layui-m-layer-footer{position: fixed; width: 95%; max-width: 100%; margin: 0 auto; left:0; right: 0; bottom: 10px; background: none;}
|
||||
.layui-m-layer-footer .layui-m-layercont{padding: 20px; border-radius: 5px 5px 0 0; background-color: rgba(255,255,255,.8);}
|
||||
.layui-m-layer-footer .layui-m-layerbtn{display: block; height: auto; background: none; border-top: none;}
|
||||
.layui-m-layer-footer .layui-m-layerbtn span{background-color: rgba(255,255,255,.8);}
|
||||
.layui-m-layer-footer .layui-m-layerbtn span[no]{color: #FD482C; border-top: 1px solid #c2c2c2; border-radius: 0 0 5px 5px;}
|
||||
.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top: 10px; border-radius: 5px;}
|
||||
|
||||
/* 通用提示 */
|
||||
body .layui-m-layer .layui-m-layer-msg{width: auto; max-width: 90%; margin: 0 auto; bottom: -150px; background-color: rgba(0,0,0,.7); color: #fff;}
|
||||
.layui-m-layer-msg .layui-m-layercont{padding: 10px 20px;}
|
||||
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 11 KiB |
@@ -1,182 +0,0 @@
|
||||
/**
|
||||
|
||||
@Name: layer
|
||||
|
||||
**/
|
||||
|
||||
/* *html{background-image: url(about:blank); background-attachment: fixed;} */
|
||||
html #layuicss-layer{display: none; position: absolute; width: 1989px;}
|
||||
|
||||
html[layer-full]{height:inherit}
|
||||
|
||||
/* common */
|
||||
.layui-layer-shade, .layui-layer{position:fixed; _position:absolute; pointer-events: auto;}
|
||||
.layui-layer-shade{top:0; left:0; width:100%; height:100%; _height:expression(document.body.offsetHeight+"px");}
|
||||
.layui-layer{-webkit-overflow-scrolling: touch;}
|
||||
.layui-layer{top:150px; left: 0; margin:0; padding:0; background-color:#fff; -webkit-background-clip: content; border-radius: 2px; box-shadow: 1px 1px 50px rgba(0,0,0,.3);}
|
||||
.layui-layer-close{position:absolute;}
|
||||
.layui-layer-content{position:relative;}
|
||||
.layui-layer-border{border: 1px solid #B2B2B2; border: 1px solid rgba(0,0,0,.1); box-shadow: 1px 1px 5px rgba(0,0,0,.2);}
|
||||
.layui-layer-load{background:url(loading-1.gif) #eee center center no-repeat;}
|
||||
.layui-layer-ico{ background:url(icon.png) no-repeat;}
|
||||
.layui-layer-dialog .layui-layer-ico,
|
||||
.layui-layer-setwin a,
|
||||
.layui-layer-btn a{display:inline-block; *display:inline; *zoom:1; vertical-align:top;}
|
||||
|
||||
.layui-layer-move{display: none; position: fixed; *position: absolute; left: 0px; top: 0px; width: 100%; height: 100%; cursor: move; opacity: 0; filter:alpha(opacity=0); background-color: #fff; z-index: 2147483647;}
|
||||
.layui-layer-resize{position: absolute; width: 15px; height: 15px; right: 0; bottom: 0; cursor: se-resize;}
|
||||
.layui-layer-confirm{position: absolute; width: 1px; height: 1px; left: 0; bottom: 0; border:none; background:transparent;}
|
||||
|
||||
/* 动画 */
|
||||
.layer-anim{-webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-duration:.3s; animation-duration:.3s;}
|
||||
|
||||
@-webkit-keyframes layer-bounceIn { /* 默认 */
|
||||
0% {opacity: 0; -webkit-transform: scale(.5); transform: scale(.5)}
|
||||
100% {opacity: 1; -webkit-transform: scale(1); transform: scale(1)}
|
||||
}
|
||||
@keyframes layer-bounceIn {
|
||||
0% {opacity: 0; -webkit-transform: scale(.5); -ms-transform: scale(.5); transform: scale(.5)}
|
||||
100% {opacity: 1; -webkit-transform: scale(1); -ms-transform: scale(1); transform: scale(1)}
|
||||
}
|
||||
.layer-anim-00{-webkit-animation-name: layer-bounceIn;animation-name: layer-bounceIn}
|
||||
|
||||
@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}
|
||||
|
||||
@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}
|
||||
|
||||
@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}
|
||||
|
||||
@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0px) rotate(0deg);-ms-transform:translateX(0px) rotate(0deg);transform:translateX(0px) rotate(0deg)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}
|
||||
|
||||
@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}
|
||||
|
||||
@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}
|
||||
|
||||
/* 标题栏 */
|
||||
.layui-layer-title{padding:0 80px 0 20px; height: 50px; line-height: 50px; border-bottom:1px solid #F0F0F0; font-size: 14px; color:#333; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; border-radius: 2px 2px 0 0;}
|
||||
.layui-layer-setwin{position:absolute; right: 15px; *right:0; top: 17px; font-size:0; line-height: initial;}
|
||||
.layui-layer-setwin a{position:relative; width: 16px; height:16px; margin-left:10px; font-size:12px; _overflow:hidden;}
|
||||
.layui-layer-setwin .layui-layer-min cite{position:absolute; width:14px; height:2px; left:0; top:50%; margin-top:-1px; background-color:#2E2D3C; cursor:pointer; _overflow:hidden;}
|
||||
.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA; }
|
||||
.layui-layer-setwin .layui-layer-max{background-position:-32px -40px;}
|
||||
.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px;}
|
||||
.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px;}
|
||||
.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px;}
|
||||
.layui-layer-setwin .layui-layer-close1{background-position: 1px -40px; cursor: pointer;}
|
||||
.layui-layer-setwin .layui-layer-close1:hover{opacity:0.7;}
|
||||
.layui-layer-setwin .layui-layer-close2{position:absolute; right:-28px; top:-28px; width:30px; height:30px; margin-left:0; background-position:-149px -31px; *right:-18px; _display:none;}
|
||||
.layui-layer-setwin .layui-layer-close2:hover{ background-position:-180px -31px;}
|
||||
|
||||
/* 按钮栏 */
|
||||
.layui-layer-btn{text-align: right; padding: 0 15px 12px; pointer-events: auto; user-select: none; -webkit-user-select: none;}
|
||||
.layui-layer-btn a{height: 28px; line-height: 28px; margin: 5px 5px 0; padding: 0 15px; border: 1px solid #dedede; background-color:#fff; color: #333; border-radius: 2px; font-weight:400; cursor:pointer; text-decoration: none;}
|
||||
.layui-layer-btn a:hover{opacity: 0.9; text-decoration: none;}
|
||||
.layui-layer-btn a:active{opacity: 0.8;}
|
||||
.layui-layer-btn .layui-layer-btn0{border-color: #1E9FFF; background-color: #1E9FFF; color:#fff;}
|
||||
.layui-layer-btn-l{text-align: left;}
|
||||
.layui-layer-btn-c{text-align: center;}
|
||||
|
||||
/* 定制化 */
|
||||
.layui-layer-dialog{min-width: 300px;}
|
||||
.layui-layer-dialog .layui-layer-content{position: relative; padding:20px; line-height:24px; word-break: break-all; overflow:hidden; font-size:14px; overflow-x: hidden; overflow-y:auto;}
|
||||
.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute; top:16px; left:15px; _left:-40px; width:30px; height:30px;}
|
||||
.layui-layer-ico1{background-position:-30px 0 }
|
||||
.layui-layer-ico2{background-position:-60px 0;}
|
||||
.layui-layer-ico3{background-position:-90px 0;}
|
||||
.layui-layer-ico4{background-position:-120px 0;}
|
||||
.layui-layer-ico5{background-position:-150px 0;}
|
||||
.layui-layer-ico6{background-position:-180px 0;}
|
||||
.layui-layer-rim{border:6px solid #8D8D8D; border:6px solid rgba(0,0,0,.3); border-radius:5px; box-shadow: none;}
|
||||
.layui-layer-msg{min-width:180px; border:1px solid #D3D4D3; box-shadow: none;}
|
||||
.layui-layer-hui{min-width:100px; background-color: #000; filter:alpha(opacity=60); background-color: rgba(0,0,0,0.6); color: #fff; border:none;}
|
||||
.layui-layer-hui .layui-layer-content{padding:12px 25px; text-align:center;}
|
||||
.layui-layer-dialog .layui-layer-padding{padding: 20px 20px 20px 55px; text-align: left;}
|
||||
.layui-layer-page .layui-layer-content{position:relative; overflow:auto;}
|
||||
.layui-layer-page .layui-layer-btn,.layui-layer-iframe .layui-layer-btn{padding-top:10px;}
|
||||
.layui-layer-nobg{background:none;}
|
||||
.layui-layer-iframe iframe{display: block; width: 100%;}
|
||||
|
||||
.layui-layer-loading{border-radius:100%; background:none; box-shadow:none; border:none;}
|
||||
.layui-layer-loading .layui-layer-content{width:60px; height:24px; background:url(loading-0.gif) no-repeat;}
|
||||
.layui-layer-loading .layui-layer-loading1{width:37px; height:37px; background:url(loading-1.gif) no-repeat;}
|
||||
.layui-layer-loading .layui-layer-loading2, .layui-layer-ico16{width:32px; height:32px; background:url(loading-2.gif) no-repeat;}
|
||||
.layui-layer-tips{background: none; box-shadow:none; border:none;}
|
||||
.layui-layer-tips .layui-layer-content{position: relative; line-height: 22px; min-width: 12px; padding: 8px 15px; font-size: 12px; _float:left; border-radius: 2px; box-shadow: 1px 1px 3px rgba(0,0,0,.2); background-color: #000; color: #fff;}
|
||||
.layui-layer-tips .layui-layer-close{right:-2px; top:-1px;}
|
||||
.layui-layer-tips i.layui-layer-TipsG{ position:absolute; width:0; height:0; border-width:8px; border-color:transparent; border-style:dashed; *overflow:hidden;}
|
||||
.layui-layer-tips i.layui-layer-TipsT, .layui-layer-tips i.layui-layer-TipsB{left:5px; border-right-style:solid; border-right-color: #000;}
|
||||
.layui-layer-tips i.layui-layer-TipsT{bottom:-8px;}
|
||||
.layui-layer-tips i.layui-layer-TipsB{top:-8px;}
|
||||
.layui-layer-tips i.layui-layer-TipsR, .layui-layer-tips i.layui-layer-TipsL{top: 5px; border-bottom-style:solid; border-bottom-color: #000;}
|
||||
.layui-layer-tips i.layui-layer-TipsR{left:-8px;}
|
||||
.layui-layer-tips i.layui-layer-TipsL{right:-8px;}
|
||||
|
||||
/* skin */
|
||||
.layui-layer-lan[type="dialog"]{min-width:280px;}
|
||||
.layui-layer-lan .layui-layer-title{background:#4476A7; color:#fff; border: none;}
|
||||
.layui-layer-lan .layui-layer-btn{padding: 5px 10px 10px; text-align: right; border-top:1px solid #E9E7E7}
|
||||
.layui-layer-lan .layui-layer-btn a{background: #fff; border-color: #E9E7E7; color: #333;}
|
||||
.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5;}
|
||||
.layui-layer-molv .layui-layer-title{background: #009f95; color:#fff; border: none;}
|
||||
.layui-layer-molv .layui-layer-btn a{background: #009f95; border-color: #009f95;}
|
||||
.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1;}
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@Name: layer拓展样式
|
||||
|
||||
*/
|
||||
|
||||
.layui-layer-iconext{background:url(icon-ext.png) no-repeat;}
|
||||
|
||||
/* prompt模式 */
|
||||
.layui-layer-prompt .layui-layer-input{display: block; width: 260px; height: 36px; margin: 0 auto; line-height: 30px; padding-left: 10px; border: 1px solid #e6e6e6; color: #333;}
|
||||
.layui-layer-prompt textarea.layui-layer-input{width: 300px; height: 100px; line-height: 20px; padding: 6px 10px;}
|
||||
.layui-layer-prompt .layui-layer-content{padding: 20px;}
|
||||
.layui-layer-prompt .layui-layer-btn{padding-top: 0;}
|
||||
|
||||
/* tab模式 */
|
||||
.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4);}
|
||||
.layui-layer-tab .layui-layer-title{padding-left:0; overflow: visible;}
|
||||
.layui-layer-tab .layui-layer-title span{position:relative; float:left; min-width:80px; max-width: 300px; padding:0 20px; text-align:center; cursor:default; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; cursor: pointer;}
|
||||
.layui-layer-tab .layui-layer-title span.layui-this{height: 51px; border-left: 1px solid #eee; border-right: 1px solid #eee; background-color: #fff; z-index: 10;}
|
||||
.layui-layer-tab .layui-layer-title span:first-child{border-left:none;}
|
||||
.layui-layer-tabmain{line-height:24px; clear:both;}
|
||||
.layui-layer-tabmain .layui-layer-tabli{display:none;}
|
||||
.layui-layer-tabmain .layui-layer-tabli.layui-this{display: block;}
|
||||
|
||||
/* photo模式 */
|
||||
.layui-layer-photos{background: none; box-shadow: none;}
|
||||
.layui-layer-photos .layui-layer-content{overflow:visible; text-align: center;}
|
||||
.layui-layer-photos .layui-layer-phimg img{position: relative; width:100%; display: inline-block; *display:inline; *zoom:1; vertical-align:top;}
|
||||
.layui-layer-imgprev, .layui-layer-imgnext{position: fixed; top: 50%; width: 27px; _width: 44px; height: 44px; margin-top:-22px; outline:none;blr:expression(this.onFocus=this.blur());}
|
||||
.layui-layer-imgprev{left: 30px; background-position:-5px -5px; _background-position:-70px -5px;}
|
||||
.layui-layer-imgprev:hover{background-position:-33px -5px; _background-position:-120px -5px;}
|
||||
.layui-layer-imgnext{right: 30px; _right:8px; background-position:-5px -50px; _background-position:-70px -50px;}
|
||||
.layui-layer-imgnext:hover{background-position: -33px -50px; _background-position: -120px -50px;}
|
||||
.layui-layer-imgbar{position: fixed; left:0; right: 0; bottom:0; width:100%; height: 40px; line-height: 40px; background-color:#000\9; filter:Alpha(opacity=60); background-color: rgba(2,0,0,.35); color: #fff; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; font-size:0;}
|
||||
.layui-layer-imgtit{/*position:absolute; left:20px;*/}
|
||||
.layui-layer-imgtit *{display:inline-block; *display:inline; *zoom:1; vertical-align:top; font-size:12px;}
|
||||
.layui-layer-imgtit a{max-width:65%; text-overflow: ellipsis; overflow: hidden; white-space: nowrap; color:#fff;}
|
||||
.layui-layer-imgtit a:hover{color:#fff; text-decoration:underline;}
|
||||
.layui-layer-imgtit em{padding-left:10px; font-style: normal;}
|
||||
|
||||
/* 关闭动画 */
|
||||
@-webkit-keyframes layer-bounceOut {
|
||||
100% {opacity: 0; -webkit-transform: scale(.7); transform: scale(.7)}
|
||||
30% {-webkit-transform: scale(1.05); transform: scale(1.05)}
|
||||
0% {-webkit-transform: scale(1); transform: scale(1);}
|
||||
}
|
||||
@keyframes layer-bounceOut {
|
||||
100% {opacity: 0; -webkit-transform: scale(.7); -ms-transform: scale(.7); transform: scale(.7);}
|
||||
30% {-webkit-transform: scale(1.05); -ms-transform: scale(1.05); transform: scale(1.05);}
|
||||
0% {-webkit-transform: scale(1); -ms-transform: scale(1);transform: scale(1);}
|
||||
}
|
||||
.layer-anim-close{-webkit-animation-name: layer-bounceOut; animation-name: layer-bounceOut; -webkit-animation-fill-mode: both; animation-fill-mode: both; -webkit-animation-duration:.2s; animation-duration:.2s;}
|
||||
|
||||
@media screen and (max-width: 1100px) {
|
||||
.layui-layer-iframe{overflow-y: auto; -webkit-overflow-scrolling: touch;}
|
||||
}
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 701 B |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 7.4 KiB |
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* layer皮肤
|
||||
*
|
||||
*/
|
||||
|
||||
html #layui_layer_skinmoonstylecss {
|
||||
display: none;
|
||||
position: absolute;
|
||||
width: 1989px;
|
||||
}
|
||||
|
||||
body .layer-ext-moon[type="dialog"] {
|
||||
min-width: 320px;
|
||||
}
|
||||
body .layer-ext-moon-msg[type="dialog"]{min-width:200px;}
|
||||
body .layer-ext-moon .layui-layer-title {
|
||||
background: #f6f6f6;
|
||||
color: #212a31;
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
height: 46px;
|
||||
line-height: 46px;
|
||||
border-bottom: 1px solid #D5D5D5;
|
||||
}
|
||||
|
||||
|
||||
|
||||
body .layer-ext-moon .layui-layer-content .layui-layer-ico {
|
||||
height: 32px;
|
||||
width: 32px;
|
||||
top:18.5px;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-ico0 {
|
||||
background: url(default.png) no-repeat -96px 0;
|
||||
;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-ico1 {
|
||||
background: url(default.png) no-repeat -224px 0;
|
||||
;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-ico2 {
|
||||
background: url(default.png) no-repeat -192px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-ico3 {
|
||||
background: url(default.png) no-repeat -160px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-ico4 {
|
||||
background: url(default.png) no-repeat -320px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-ico5 {
|
||||
background: url(default.png) no-repeat -288px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-ico6 {
|
||||
background: url(default.png) -256px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-ico7 {
|
||||
background: url(default.png) no-repeat -128px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-setwin {
|
||||
top: 15px;
|
||||
right: 15px;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-setwin a {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-setwin .layui-layer-min cite:hover {
|
||||
background-color: #56abe4;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-setwin .layui-layer-max {
|
||||
background: url(default.png) no-repeat -80px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-setwin .layui-layer-max:hover {
|
||||
background: url(default.png) no-repeat -64px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-setwin .layui-layer-maxmin {
|
||||
background: url(default.png) no-repeat -32px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-setwin .layui-layer-maxmin:hover {
|
||||
background: url(default.png) no-repeat -16px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-setwin .layui-layer-close1,body .layer-ext-moon .layui-layer-setwin .layui-layer-close2 {
|
||||
background: url(default.png) 0 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-setwin .layui-layer-close1:hover,body .layer-ext-moon .layui-layer-setwin .layui-layer-close2:hover {
|
||||
background: url(default.png) -48px 0;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-padding{padding-top: 24px;}
|
||||
body .layer-ext-moon .layui-layer-btn {
|
||||
text-align: center;
|
||||
padding-top: 15px;
|
||||
padding-bottom:15px;
|
||||
background: #f0f4f7;
|
||||
border-top: 1px #c7c7c7 solid;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-btn a {
|
||||
font-size: 12px;
|
||||
font-weight: normal;
|
||||
margin: 0 3px;
|
||||
margin-right: 7px;
|
||||
margin-left: 7px;
|
||||
padding: 6px 20px;
|
||||
color: #fff;
|
||||
border: 1px solid #0064b6;
|
||||
background: #0071ce;
|
||||
border-radius: 3px;
|
||||
display: inline-block;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
vertical-align: middle;
|
||||
background-repeat: no-repeat;
|
||||
text-decoration: none;
|
||||
outline: none;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-btn .layui-layer-btn0 {
|
||||
background: #0071ce;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-btn .layui-layer-btn1 {
|
||||
background: #fff;
|
||||
color: #404a58;
|
||||
border: 1px solid #c0c4cd;
|
||||
border-radius: 3px;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-btn .layui-layer-btn2 {
|
||||
background: #f60;
|
||||
color: #fff;
|
||||
border: 1px solid #f60;
|
||||
border-radius: 3px;
|
||||
}
|
||||
body .layer-ext-moon .layui-layer-btn .layui-layer-btn3 {
|
||||
background: #f00;
|
||||
color: #fff;
|
||||
border: 1px solid #f00;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
body .layer-ext-moon .layui-layer-title span.layui-layer-tabnow{
|
||||
height:47px;
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
|
||||
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>layer-更懂你的web弹窗解决方案</title>
|
||||
|
||||
<style>
|
||||
html{background-color:#E3E3E3; font-size:14px; color:#000; font-family:'微软雅黑'}
|
||||
a,a:hover{ text-decoration:none;}
|
||||
pre{font-family:'微软雅黑'}
|
||||
.box{padding:20px; background-color:#fff; margin:50px 100px; border-radius:5px;}
|
||||
.box a{padding-right:15px;}
|
||||
#about_hide{display:none}
|
||||
.layer_text{background-color:#fff; padding:20px;}
|
||||
.layer_text p{margin-bottom: 10px; text-indent: 2em; line-height: 23px;}
|
||||
.button{display:inline-block; *display:inline; *zoom:1; line-height:30px; padding:0 20px; background-color:#56B4DC; color:#fff; font-size:14px; border-radius:3px; cursor:pointer; font-weight:normal;}
|
||||
.photos-demo img{width:200px;}
|
||||
</style>
|
||||
|
||||
<script src="http://cdn.bootcss.com/jquery/1.12.3/jquery.min.js"></script>
|
||||
<script src="../dist/layer.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="box">
|
||||
<pre>
|
||||
@Name:layer
|
||||
@Version:v<script>document.write(layer.v)</script>
|
||||
@Description:通用 Web 弹层组件
|
||||
|
||||
|
||||
<strong>【注意事项】</strong>
|
||||
一、使用时,请把文件夹 layer 整个放置在您站点的任何一个目录,只需引入 layer.js 即可,除 jQuery 外,其它文件无需再引入。
|
||||
二、如果您的 js 引入是通过合并处理或者您不想采用layer自动获取的绝对路径,您可以通过 layer.config() 来配置(详见官网 API 页)
|
||||
三、jQuery 需 1.8+
|
||||
四、更多使用说明与演示,请参见 layer 官网。
|
||||
五、使用时请务必保留来源,请勿用于违反我国法律法规的 Web 平台。
|
||||
六、layer 是一款无偿的公益性项目,遵循 MIT 开源协议。
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<div class="box" style="text-align:center">
|
||||
<a href="http://layer.layui.com/" target="_blank">更多示例</a>
|
||||
<a href="http://www.layui.com/doc/modules/layer.html" target="_blank">使用文档</a>
|
||||
<a href="javascript:;" id="about">关于</a>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
;!function(){
|
||||
|
||||
|
||||
//页面一打开就执行,放入ready是为了layer所需配件(css、扩展模块)加载完毕
|
||||
layer.ready(function(){
|
||||
layer.open({
|
||||
type: 2,
|
||||
title: '欢迎页',
|
||||
maxmin: true,
|
||||
area: ['800px', '500px'],
|
||||
content: 'http://layer.layui.com/test/welcome.html',
|
||||
end: function(){
|
||||
layer.tips('Hi', '#about', {tips: 1})
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
//关于
|
||||
$('#about').on('click', function(){
|
||||
layer.alert('layui 出品');
|
||||
});
|
||||
|
||||
}();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,14 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>问卷帮</title>
|
||||
<script type="module" crossorigin src="http://wjba.oss-accelerate.aliyuncs.com/web/assets/app.js"></script>
|
||||
<link rel="stylesheet" crossorigin href="http://wjba.oss-accelerate.aliyuncs.com/web/assets/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
Before Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
Before Width: | Height: | Size: 5.5 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 128 KiB |
|
Before Width: | Height: | Size: 117 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 96 KiB |
@@ -8,6 +8,8 @@ use hg\apidoc\annotation as Apidoc;
|
||||
|
||||
/**
|
||||
* 提现地址
|
||||
* @Apidoc\NotParse()
|
||||
* @Apidoc\NotDebug()
|
||||
*/
|
||||
class AddressController extends BaseController{
|
||||
/**
|
||||
@@ -43,6 +43,7 @@ class BalanceLogController extends BaseController{
|
||||
}
|
||||
$item->_type= $item->type;
|
||||
$item->type= $BalanceTypeList[$item->type];
|
||||
return $item;
|
||||
});
|
||||
return $this->success(__('successful'),$list);
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
<?php
|
||||
namespace app\api\controller;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use Shopwwi\WebmanFilesystem\FilesystemFactory;
|
||||
use Shopwwi\WebmanFilesystem\Facade\Storage;
|
||||
use hg\apidoc\annotation as Apidoc;
|
||||
use taoser\facade\Validate;
|
||||
/**
|
||||
* 基础控制器
|
||||
* @Apidoc\NotParse()
|
||||
* @Apidoc\NotDebug()
|
||||
*/
|
||||
class BaseController
|
||||
{
|
||||
/**
|
||||
* 不需要鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
public $noNeedAuth = [];
|
||||
|
||||
/**
|
||||
* 无需登录及鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
public $noNeedLogin = [];
|
||||
function __construct()
|
||||
{
|
||||
$this->_init();
|
||||
}
|
||||
protected function _init(){
|
||||
}
|
||||
/**
|
||||
* 返回格式化json数据
|
||||
*
|
||||
* @param int $code
|
||||
* @param string $msg
|
||||
* @param array $data
|
||||
* @return Response
|
||||
*/
|
||||
protected function json(int $code, string $msg = 'ok', array|object|null $data = []): Response
|
||||
{
|
||||
return json(['code' => $code, 'data' => $data, 'msg' => $msg]);
|
||||
}
|
||||
|
||||
protected function success(string $msg = '成功', array|object|null $data = []): Response
|
||||
{
|
||||
return $this->json(0, $msg, $data);
|
||||
}
|
||||
|
||||
protected function fail(string $msg = '失败', array|object|null $data = []): Response
|
||||
{
|
||||
return $this->json(1,$msg, $data);
|
||||
}
|
||||
protected function error(string $msg = '失败', array|object|null $data = []): Response
|
||||
{
|
||||
return $this->json(1,$msg, $data);
|
||||
}
|
||||
protected function _upload($request)
|
||||
{
|
||||
|
||||
try{
|
||||
$user = \support\Jwt::getUser();
|
||||
}catch(\Exception $e){
|
||||
$user = ['id'=>0];
|
||||
}
|
||||
$savePath = $request->post('savePath','files');
|
||||
$validate = Validate::rule('savePath', 'alphaNum');
|
||||
$data = ['savePath' => $savePath];
|
||||
if (!$validate->check($data)) {
|
||||
return '参数错误:'.$validate->getError();
|
||||
}
|
||||
$savePath = trim($savePath,'/');
|
||||
//$savePath = 'upload/'.$savePath.'/'.$user['id'];
|
||||
$savePath = $savePath.'/'.$user['id'];
|
||||
\support\Log::alert('savePath:'.$savePath);
|
||||
$mimetype = explode(',',Config('site.upload_mimetype'));
|
||||
$maxsize = Config('site.upload_maxsize')*1024*1024;
|
||||
//多文件上传
|
||||
$files = $request->file();
|
||||
$result = Storage::adapter('oss')
|
||||
->path($savePath)
|
||||
->size($maxsize)
|
||||
->extYes($mimetype)
|
||||
->uploads($files,0,$maxsize * count($files),false);
|
||||
$save_datas = [];
|
||||
foreach($result as $k=>$fileinfo){
|
||||
$save_datas[] = [
|
||||
'user_id' => $user['id'],
|
||||
'category' => 'default',
|
||||
'adapter' => $fileinfo->adapter,
|
||||
'origin_name' => $fileinfo->origin_name,
|
||||
'file_name' => $fileinfo->file_name,
|
||||
'size' => $fileinfo->size,
|
||||
'mime_type' => $fileinfo->mime_type,
|
||||
'extension' => $fileinfo->extension,
|
||||
'file_height' => $fileinfo->file_height,
|
||||
'file_width' => $fileinfo->file_width,
|
||||
'file_url' => $fileinfo->file_url,
|
||||
'sha1' => $fileinfo->storage_key ?:sha1_file(public_path($fileinfo->file_name)),
|
||||
'use_count' => 0,
|
||||
];
|
||||
}
|
||||
$res = \app\model\Files::saveAll($save_datas);
|
||||
return $res;
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("上传")
|
||||
* @Apidoc\Method("POST")
|
||||
*/
|
||||
function upload(Request $request,$return = false)
|
||||
{
|
||||
$res = $this->_upload($request);
|
||||
if(is_string($res)){
|
||||
return $this->fail( $res);
|
||||
}
|
||||
return $this->success(__('successful'),$res);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -10,6 +10,8 @@ use hg\apidoc\annotation as Apidoc;
|
||||
|
||||
/**
|
||||
* 卡密模块
|
||||
* @Apidoc\NotParse()
|
||||
* @Apidoc\NotDebug()
|
||||
*/
|
||||
class CardController extends BaseController{
|
||||
/**
|
||||
@@ -12,6 +12,7 @@ use Shopwwi\WebmanFilesystem\FilesystemFactory;
|
||||
use Shopwwi\WebmanFilesystem\Facade\Storage;
|
||||
use hg\apidoc\annotation as Apidoc;
|
||||
|
||||
use think\facade\Db;
|
||||
/**
|
||||
* 公共接口
|
||||
*/
|
||||
@@ -34,7 +35,7 @@ class CommonController extends BaseController{
|
||||
*
|
||||
* @Apidoc\Query("version", type="string", require=true, desc="版本号")
|
||||
*/
|
||||
public function init()
|
||||
public function init(Request $request)
|
||||
{
|
||||
$lang = input('lang','en-US');
|
||||
locale( $lang);
|
||||
@@ -42,10 +43,10 @@ class CommonController extends BaseController{
|
||||
$disallowFields = [
|
||||
'api_token','reward_time_limit',
|
||||
'mail_type','mail_smtp_host','mail_smtp_port','mail_smtp_user','mail_smtp_pass','mail_verify_type','mail_from',
|
||||
'attachmentcategory','categorytype','cdkey_category','configgroup','flagtype',
|
||||
'attachment_category','categorytype','cdkey_category','configgroup','flagtype',
|
||||
'languages','forbiddenip','fixedpage','admin_login_captcha',
|
||||
'mimetype','multipart','multiple','chunksize','classname','thumbstyle','previewtpl','timeout','maxsize','container',
|
||||
'yeji_jicha_reward','suanli_rate','agent_expirs_retention','allow_currencys','allow_balance_log',
|
||||
'upload_mimetype','upload_multipart','upload_multiple','upload_thumbstyle','upload_previewtpl','upload_timeout','upload_maxsize',
|
||||
'yeji_jicha_reward','suanli_rate','agent_expirs_retention','allow_currencys','allow_currency_logs',
|
||||
'agent_commission_total_rate','agent_commission_layer_rate','differential_commission_total_rate'
|
||||
];
|
||||
$config = array_diff_key($config, array_flip($disallowFields));
|
||||
@@ -56,15 +57,42 @@ class CommonController extends BaseController{
|
||||
$config['recharge_status_list'] = \app\enum\RechargeStatus::toArray();
|
||||
$config['withdrawl_status_list'] = \app\enum\WithdrawlStatus::toArray();
|
||||
$config['server_status_list'] = \app\enum\ServerStatus::toArray();
|
||||
//$config['getFriendList'] = $request->IM->friend->getFriendList('100006');
|
||||
return $this->success(__('successful'), $config);
|
||||
}
|
||||
|
||||
/**
|
||||
* test
|
||||
* @Apidoc\Query("lang", type="string",require=true, desc="邮箱")
|
||||
* @Apidoc\Method ("GET")
|
||||
* 验证是否升级
|
||||
*/
|
||||
function test(){
|
||||
return $this->error(__('Invalid parameters'));
|
||||
public function checkUpgrade(Request $request)
|
||||
{
|
||||
$field = 'id,type,force,source,version,content';
|
||||
$verUpdate = new \app\model\Version;
|
||||
$version = Input('version');
|
||||
$platform = Input('platform');
|
||||
$version_wgt = Input('version_wgt');
|
||||
|
||||
// 查询整包、外链数据
|
||||
$update_data = $verUpdate->whereIn('type','0,2')
|
||||
->where('status',1)
|
||||
->where('version','>', $version)
|
||||
->where('platform',$platform)
|
||||
->field($field)
|
||||
->order('id desc')->find();
|
||||
if($update_data) {
|
||||
return $this->success('',$update_data);
|
||||
}
|
||||
|
||||
// 查询WGT数据
|
||||
$update_wgt_data = $verUpdate->where('type',1)
|
||||
->where('status',1)
|
||||
->where('version_wgt','>', $version_wgt)
|
||||
->where('platform',$platform)
|
||||
->field($field)->order('id desc')->find();
|
||||
if($update_wgt_data) {
|
||||
return $this->success('',$update_wgt_data);
|
||||
}
|
||||
return $this->success('',[]);
|
||||
}
|
||||
/**
|
||||
* 注册会员
|
||||
@@ -84,65 +112,75 @@ class CommonController extends BaseController{
|
||||
$username = input('username');
|
||||
$mobile = input('mobile');
|
||||
$invite_code = input('invite_code');
|
||||
if ($email && !Validate::is($email, "email")) {
|
||||
return $this->error(__('Email is incorrect'));
|
||||
$type = input('type');
|
||||
if (!in_array($type,Config('site.user_register_way')) ) {
|
||||
return $this->error(__('Unknown register way'));
|
||||
}
|
||||
if ($mobile && !Validate::regex($mobile, "^1\d{10}$")) {
|
||||
return $this->error(__('Mobile is incorrect'));
|
||||
}
|
||||
if(Config('site.user_register_way') == 'mobile'){
|
||||
if (!$mobile) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
$username = $mobile;
|
||||
captcha_verfiy('mobile','register',$mobile);
|
||||
}else if(Config('site.user_register_way') == 'email'){
|
||||
if (!$email) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
if ($email && !Validate::is($email, "email")) {
|
||||
if ($type == 'email') {
|
||||
if(!$email || !Validate::is($email, "email")){
|
||||
return $this->error(__('Email is incorrect'));
|
||||
}
|
||||
$username = $email;
|
||||
captcha_verfiy('email','register',$email);
|
||||
}else{
|
||||
if (!$username) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
unset($mobile);
|
||||
//captcha_verfiy('email','register',$email,false);
|
||||
}
|
||||
if ($type == 'mobile') {
|
||||
if(!$mobile || !Validate::regex($mobile, "^1\d{10}$")){
|
||||
return $this->error(__('Mobile is incorrect'));
|
||||
}
|
||||
$username = $mobile;
|
||||
unset($email);
|
||||
//captcha_verfiy('mobile','register',$mobile,false);
|
||||
}
|
||||
if ($type == 'username') {
|
||||
if(!$email || !Validate::is($email, "email")){
|
||||
return $this->error(__('Username is incorrect'));
|
||||
}
|
||||
}
|
||||
if (!$password) {
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
$extends = [
|
||||
'role_id' => 0,
|
||||
'group' => 0,
|
||||
'avatar' => '/static/img/avatar.png',
|
||||
];
|
||||
// if (!$trade_password) {
|
||||
// return $this->error(__('Invalid trade password'));
|
||||
// }else{
|
||||
// $extends['trade_password'] = \plugin\admin\app\common\Util::passwordHash($trade_password);
|
||||
// }
|
||||
|
||||
//邀请码
|
||||
if(!$invite_code){
|
||||
return $this->error(__('Invalid invite code'));
|
||||
}
|
||||
if(strlen($invite_code) == 12){
|
||||
//系统生产的一次性推荐吗
|
||||
$inviteModel = \app\model\Invitecode::where('code',$invite_code)->find();
|
||||
if(!$inviteModel){
|
||||
return $this->error(__('错误的邀请码'));
|
||||
//$invite_code = 'TEAJXLEE';
|
||||
$extends = [
|
||||
'role_id' => 1,
|
||||
'group_id' => 0,
|
||||
'region' => '86',
|
||||
'nickname' => input('nickname'),
|
||||
'avatar' => '/static/avatar/'.rand(0,17).'.png',
|
||||
];
|
||||
if ($invite_code) {
|
||||
if(strlen($invite_code) == 12){
|
||||
//系统生产的一次性推荐吗
|
||||
$inviteModel = \app\model\Invitecode::where('code',$invite_code)->find();
|
||||
if(!$inviteModel){
|
||||
return $this->error(__('错误的邀请码'));
|
||||
}
|
||||
$extends['group_id'] = 2;
|
||||
$extends['role_id'] = 1;
|
||||
$extends['parent_id'] = 0;
|
||||
}else{
|
||||
$inviter_user = UserModel::where('invite_code',$invite_code)->field('group_id,id')->find();
|
||||
if(!$inviter_user){
|
||||
return $this->error(__('Invalid invite code'));
|
||||
}
|
||||
$extends['parent_id'] = $inviter_user['id'];
|
||||
}
|
||||
$extends['group'] = 2;
|
||||
$extends['role_id'] = 1;
|
||||
$extends['parent_id'] = 0;
|
||||
}else{
|
||||
$inviter_user = UserModel::where('invite_code',$invite_code)->field('group,id')->find();
|
||||
if(!$inviter_user){
|
||||
return $this->error(__('Invalid invite code'));
|
||||
}
|
||||
$extends['parent_id'] = $inviter_user['id'];
|
||||
//return $this->error(__('Invalid invite code'));
|
||||
}
|
||||
// validate(\app\validate\User::class)
|
||||
// ->scene('edit')
|
||||
// ->check([
|
||||
// 'name' => 'thinkphp',
|
||||
// 'email' => 'thinkphp@qq.com',
|
||||
// ]);
|
||||
try {
|
||||
$user = \support\Jwt::register($username, $password, $email, $mobile, $extends);
|
||||
if($inviteModel){
|
||||
@@ -150,29 +188,61 @@ class CommonController extends BaseController{
|
||||
$inviteModel->save();
|
||||
}
|
||||
$data = ['userinfo' => $user];
|
||||
// if ($type == 'email') {
|
||||
// captcha_verfiy('email','register',$email,true);
|
||||
// }else if ($type == 'mobile') {
|
||||
// captcha_verfiy('mobile','register',$mobile,true);
|
||||
// }else{
|
||||
// captcha_verfiy('image','register',$mobile,true);
|
||||
// }
|
||||
return $this->success(__('Sign up successful'), $data);
|
||||
} catch (\Throwable $e) {
|
||||
} catch (\Exception $e) {
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 登录
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("username", type="string",require=true, desc="用户名")
|
||||
* @Apidoc\Param("password", type="string",require=true, desc="密码")
|
||||
* @Apidoc\Param("username", type="string",require=false, desc="用户名登录必填")
|
||||
* @Apidoc\Param("mobile", type="string",require=false, desc="手机号登录必填")
|
||||
* @Apidoc\Param("type", type="string",require=true,default="mobile",desc="登录方式,username,mobile,email")
|
||||
* @Apidoc\Param("password", type="string",require=false, desc="密码的登录必填")
|
||||
* @Apidoc\Param("code", type="string",require=false, desc="验证码登录必填")
|
||||
* @Apidoc\Param("region", type="string",require=false,default="86", desc="区域,手机号登录必填")
|
||||
*/
|
||||
public function login(Request $request){
|
||||
$username = input('username');
|
||||
$mobile = input('mobile');
|
||||
$email = input('email');
|
||||
$password = input('password');
|
||||
if (!$username || !$password) {
|
||||
return $this->fail(__('Invalid username or password'));
|
||||
$type = input('type');
|
||||
if($type == 'mobile'){
|
||||
if (!$mobile ) {
|
||||
return $this->fail(__('Invalid username or password'));
|
||||
}
|
||||
$username = $mobile;
|
||||
}else if($type == 'email'){
|
||||
if (!$email ) {
|
||||
return $this->fail(__('Invalid username or password'));
|
||||
}
|
||||
$username = $email;
|
||||
}else{
|
||||
if (!$username ) {
|
||||
return $this->fail(__('Invalid username or password'));
|
||||
}
|
||||
}
|
||||
try{
|
||||
$user = \support\Jwt::login($username, $password,'username');
|
||||
if ($password) {
|
||||
//return $this->fail(__('Invalid username or password'));
|
||||
$user = \support\Jwt::login($username, $password,$type);
|
||||
}else{
|
||||
$user = \support\Jwt::login($username, $password,$type,'code');
|
||||
}
|
||||
if($user === false){
|
||||
return $this->fail(\support\Jwt::getError());
|
||||
}
|
||||
$user= Hook('user.profile',$user);
|
||||
//登录成功的事件
|
||||
$user = Hook("user.login_successed", $user);
|
||||
return $this->success(__('successful'), $user[0]);
|
||||
} catch (\Exception $e) {
|
||||
return $this->error($e->getMessage());
|
||||
@@ -194,6 +264,7 @@ class CommonController extends BaseController{
|
||||
*
|
||||
* @Apidoc\Method ("POST")
|
||||
* @Apidoc\Param("email", type="string",require=true, desc="邮箱")
|
||||
* @Apidoc\Param("mobile", type="string",require=true, desc="手机号")
|
||||
* @Apidoc\Param("newpassword", type="string",require=true, desc="新密码")
|
||||
* @Apidoc\Param("code", type="string",require=true, desc="邮箱验证码,event=resetpwd")
|
||||
*/
|
||||
@@ -206,28 +277,28 @@ class CommonController extends BaseController{
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
//验证Token
|
||||
if (!Validate::check(['newpassword' => $newpassword], ['newpassword' => 'require|regex:\S{6,30}'])) {
|
||||
return $this->error(__('Password must be 6 to 30 characters'));
|
||||
if (!Validate::check(['newpassword' => $newpassword], ['newpassword' => 'require|regex:\S{6,32}'])) {
|
||||
return $this->error(__('Password must be 6 to 32 characters'));
|
||||
}
|
||||
|
||||
if (!$mobile && !$email){
|
||||
try{
|
||||
$user = \support\Jwt::getUser();
|
||||
}catch(\Exception $e){
|
||||
log_alert($e->getMessage());
|
||||
//log_alert($e->getMessage());
|
||||
$user = false;
|
||||
}
|
||||
if($user){
|
||||
captcha_verfiy('mobile','reset_trade_pwd',$user->mobile);
|
||||
captcha_verfiy('mobile','reset_pwd',$user->mobile);
|
||||
}
|
||||
}else{
|
||||
if ($email && Validate::is($email, "email")) {
|
||||
captcha_verfiy('email','reset_trade_pwd',$email);
|
||||
$user = UserModel::getByEmail($email);
|
||||
}
|
||||
if ($mobile && Validate::regex($mobile, "^1\d{10}$")) {
|
||||
captcha_verfiy('mobile','reset_trade_pwd',$mobile);
|
||||
$user = UserModel::getByMobile($mobile);
|
||||
captcha_verfiy('mobile','reset_pwd',$mobile);
|
||||
$region = Input('region');
|
||||
$region = str_replace('+','',$region);
|
||||
$user = UserModel::where('region',$region)->where('mobile',$mobile)->find();
|
||||
}else if ($email && Validate::is($email, "email")) {
|
||||
captcha_verfiy('email','reset_pwd',$email);
|
||||
$user = UserModel::getByEmail($email);
|
||||
}
|
||||
}
|
||||
if (!$user) {
|
||||
@@ -262,8 +333,8 @@ class CommonController extends BaseController{
|
||||
return $this->error(__('Invalid parameters'));
|
||||
}
|
||||
//验证Token
|
||||
if (!Validate::check(['newpassword' => $newpassword], ['newpassword' => 'require|regex:\S{6,6}'])) {
|
||||
return $this->error(__('Trade password must be 6 characters'));
|
||||
if (!Validate::check(['newpassword' => $newpassword], ['newpassword' => 'require|regex:\S{6,32}'])) {
|
||||
return $this->error(__('Trade password must be 6-32 characters'));
|
||||
}
|
||||
|
||||
if (!$mobile && !$email){
|
||||
@@ -277,13 +348,12 @@ class CommonController extends BaseController{
|
||||
captcha_verfiy('mobile','reset_trade_pwd',$user->mobile);
|
||||
}
|
||||
}else{
|
||||
if ($email && Validate::is($email, "email")) {
|
||||
captcha_verfiy('email','reset_trade_pwd',$email);
|
||||
$user = UserModel::getByEmail($email);
|
||||
}
|
||||
if ($mobile && Validate::regex($mobile, "^1\d{10}$")) {
|
||||
captcha_verfiy('mobile','reset_trade_pwd',$mobile);
|
||||
$user = UserModel::getByMobile($mobile);
|
||||
}elseif ($email && Validate::is($email, "email")) {
|
||||
captcha_verfiy('email','reset_trade_pwd',$email);
|
||||
$user = UserModel::getByEmail($email);
|
||||
}
|
||||
}
|
||||
if (!$user) {
|
||||
@@ -309,6 +379,7 @@ class CommonController extends BaseController{
|
||||
* @Apidoc\Param("email", type="string",require=true, desc="邮箱,可选")
|
||||
*/
|
||||
public function captcha(Request $request){
|
||||
$debug = false;
|
||||
$request->input('type');
|
||||
$type = $request->input('type');
|
||||
$event = $request->input('event');
|
||||
@@ -331,17 +402,19 @@ class CommonController extends BaseController{
|
||||
return $this->fail(__('Only one verification code can be sent within %second% seconds',['%second%'=>$expris]));
|
||||
}
|
||||
}
|
||||
$code =\support\Random::numeric(4);
|
||||
$code =\support\Random::numeric(6);
|
||||
$list[$code] = time();
|
||||
cache($key,$list);
|
||||
cache('exp_'.$key,time());
|
||||
addJob([
|
||||
'email' => $email,
|
||||
'title' => __("Mt email code"),
|
||||
'event' => $event,
|
||||
'code' => $code
|
||||
],'Email');
|
||||
return $this->success(__('Email sent successfully'));
|
||||
// addJob([
|
||||
// 'email' => $email,
|
||||
// 'title' => __("Mt email code"),
|
||||
// 'event' => $event,
|
||||
// 'code' => $code
|
||||
// ],'Email');
|
||||
return $this->success(__('Email sent successfully'),[
|
||||
'code'=> $debug ? $code : ''
|
||||
]);
|
||||
}elseif($type == 'mobile'){
|
||||
$mobile = $request->input('mobile');
|
||||
if(!$mobile){
|
||||
@@ -358,13 +431,14 @@ class CommonController extends BaseController{
|
||||
$key = 'captcha_'.$event.'_'.$mobile;
|
||||
$list = cache($key);
|
||||
$list = $list ?:[];
|
||||
$expris = 60;
|
||||
$expris = 300;
|
||||
|
||||
if(cache('?exp_'.$key)){
|
||||
if(cache('exp_'.$key)+$expris > time()){
|
||||
return $this->fail(__('Only one verification code can be sent within %second% seconds',['%second%'=>$expris]));
|
||||
}
|
||||
}
|
||||
$code =\support\Random::numeric(4);
|
||||
$code =\support\Random::numeric(6);
|
||||
$list[$code] = time();
|
||||
cache($key,$list);
|
||||
cache('exp_'.$key,time());
|
||||
@@ -373,7 +447,9 @@ class CommonController extends BaseController{
|
||||
'event' => $event,
|
||||
'code' => $code
|
||||
],'Sms');
|
||||
return $this->success(__('SMS sent successfully'));
|
||||
return $this->success(__('SMS sent successfully'),[
|
||||
'code'=> $debug ? $code : ''
|
||||
]);
|
||||
}else{
|
||||
//TODO 图像验证码没有唯一的KEY
|
||||
$key = 'captcha_'.$event.'_';
|
||||
@@ -406,13 +482,14 @@ class CommonController extends BaseController{
|
||||
*/
|
||||
public function verify_captcha(Request $request): Response
|
||||
{
|
||||
$type = $request->input('type');
|
||||
$email = $request->post('email');
|
||||
$mobile = $request->input('mobile');
|
||||
$event = $request->post('event');
|
||||
try {
|
||||
if($email){
|
||||
if($type == 'email'){
|
||||
$result = captcha_verfiy('email', $event , $email,false);
|
||||
}elseif($mobile){
|
||||
}elseif($type == 'mobile'){
|
||||
$result = captcha_verfiy('mobile', $event , $mobile,false);
|
||||
}else{
|
||||
$result = captcha_verfiy('image', $event , '',false);
|
||||
@@ -425,24 +502,4 @@ class CommonController extends BaseController{
|
||||
}
|
||||
return $this->success(__('successful'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @Apidoc\Title("上传")
|
||||
* @Apidoc\Method("POST")
|
||||
*/
|
||||
function upload(Request $request)
|
||||
{
|
||||
//多文件上传
|
||||
$files = $request->file();
|
||||
try {
|
||||
$result = Storage::adapter('public')
|
||||
->path('upload/files')
|
||||
->size(1024*1024*10)
|
||||
->extYes(['image/jpeg','image/png'])
|
||||
->uploads($files,0,1024*1024*100,false);
|
||||
return $this->success(__('successful'),$result);
|
||||
}catch (\Exception $e){
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,445 @@
|
||||
<?php
|
||||
namespace app\api\controller;
|
||||
use app\model\FriendCircle;
|
||||
use Shopwwi\WebmanFilesystem\FilesystemFactory;
|
||||
use Shopwwi\WebmanFilesystem\Facade\Storage;
|
||||
use app\model\User as UserModel;
|
||||
use app\model\Realname as RealnameModel;
|
||||
use app\model\FriendCircle as FriendCircleModel;
|
||||
use app\model\FriendCircleLike as FriendCircleLikeModel;
|
||||
use app\model\FriendCircleComment as FriendCircleCommentModel;
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use taoser\facade\Validate;
|
||||
use support\think\Db;
|
||||
use hg\apidoc\annotation as Apidoc;
|
||||
|
||||
/**
|
||||
* 朋友圈
|
||||
*/
|
||||
class FriendCircleController extends BaseController{
|
||||
/**
|
||||
* 不需要鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
public $noNeedAuth = ['*'];
|
||||
|
||||
/**
|
||||
* 无需登录及鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
public $noNeedLogin = [];
|
||||
/**
|
||||
* 朋友圈设置
|
||||
* @return void
|
||||
*/
|
||||
function info(Request $request): Response{
|
||||
$user_id = Input('user_id');
|
||||
if($user_id){
|
||||
$user_id = idDecode($user_id);
|
||||
$json= [
|
||||
'top_unread_items' =>[],
|
||||
'unread_item_ids' =>[],
|
||||
'unread_count' =>0,
|
||||
'settings' => Db::name('friend_circle_setting')->where('user_id',$user_id)->order('id','desc')->findOrEmpty()
|
||||
];
|
||||
return $this->success('ok',$json);
|
||||
}else{
|
||||
$user = \support\Jwt::getUser();
|
||||
if (!$user) {
|
||||
return $this->fail('请先登录');
|
||||
}
|
||||
$user_id = $user->id;
|
||||
$res = $this->newcount($request);
|
||||
$response = $res->rawBody();
|
||||
$json = json_decode($response,true);
|
||||
$json['data']['settings'] = Db::name('friend_circle_setting')->where('user_id',$user_id)->order('id','desc')->findOrEmpty();
|
||||
// [
|
||||
// 'bg' => '',
|
||||
// ];
|
||||
$top_unread_items = FriendCircleModel::whereIn('id',$json['data']['unread_item_ids'])
|
||||
->with(['user' => function($query) {
|
||||
$query->field('id,nickname,avatar');
|
||||
}])
|
||||
->order('id', 'desc')
|
||||
->limit(0,3)
|
||||
->select();
|
||||
$json['data']['top_unread_items'] = $top_unread_items ?: [];
|
||||
$res->withBody(json_encode($json));
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("列表")
|
||||
* @Apidoc\Method("GET")
|
||||
* @Apidoc\Query("page", type="int", require=true, desc="页码",default=1)
|
||||
* @Apidoc\Query("limit", type="int", require=true, desc="分页大小",default=10)
|
||||
* @Apidoc\Query("user_id", type="int", require=false, desc="用户ID,不传则获取所有")
|
||||
*/
|
||||
function list(Request $request): Response
|
||||
{
|
||||
$current_user = \support\Jwt::getUser();
|
||||
$current_user_id = $current_user ? $current_user->id : 0;
|
||||
$page = (int)Input('page', 1);
|
||||
$limit = (int)Input('limit', 10);
|
||||
$user_id = Input('user_id', 0);
|
||||
if($user_id){
|
||||
$user_id = idDecode($user_id);
|
||||
}
|
||||
|
||||
$query = FriendCircleModel::where('status', 1)
|
||||
->whereIn('user_id',$this->getFriendUserIds($current_user_id))
|
||||
->with(['user' => function($query) {
|
||||
$query->field('id,nickname,avatar');
|
||||
}])
|
||||
->order('created_at', 'desc');
|
||||
|
||||
// 如果指定了用户ID,只获取该用户的朋友圈
|
||||
if ($user_id > 0) {
|
||||
$query->where('user_id', $user_id);
|
||||
}
|
||||
|
||||
$list = $query->paginate([
|
||||
'list_rows' => $limit,
|
||||
'page' => $page,
|
||||
]);
|
||||
if(!$user_id){
|
||||
cache('circle_last_read_id_'.$current_user_id,$list[0]['id']);
|
||||
}
|
||||
|
||||
|
||||
// 处理每条朋友圈数据
|
||||
$items = $list->items();
|
||||
$list->each(function($item) use ($current_user_id){
|
||||
// 获取点赞列表
|
||||
$likes = Db::name('friend_circle_like')->alias('f')
|
||||
->join('user u','u.id=f.user_id')
|
||||
->where('f.circle_id', $item->id)
|
||||
->field('f.*,u.avatar,u.nickname')
|
||||
->order('f.created_at', 'desc')
|
||||
->limit(20)
|
||||
->select();
|
||||
$likes = $likes ? $likes->toArray() : [];
|
||||
// 检查当前用户是否已点赞
|
||||
$is_liked = false;
|
||||
if ($current_user_id > 0) {
|
||||
$is_liked = null !== array_find($likes,function($item)use($current_user_id){
|
||||
return $item['user_id'] == $current_user_id;
|
||||
});
|
||||
// FriendCircleLikeModel::where('circle_id', $item->id)
|
||||
// ->where('user_id', $current_user_id)
|
||||
// ->count() > 0;
|
||||
}
|
||||
|
||||
|
||||
// 获取评论列表(最新10条)
|
||||
$comments = FriendCircleCommentModel::where('circle_id', $item->id)
|
||||
->where('status', 1)
|
||||
->with(['user' => function($query) {
|
||||
$query->field('id,nickname,avatar');
|
||||
}, 'replyUser' => function($query) {
|
||||
$query->field('id,nickname,avatar');
|
||||
}])
|
||||
->order('created_at', 'asc')
|
||||
->limit(10)
|
||||
->select();
|
||||
|
||||
// 格式化数据
|
||||
$item->is_liked = $is_liked;
|
||||
$item->likes = $likes;
|
||||
$item->comments = $comments;
|
||||
|
||||
// 处理图片URL
|
||||
if (!empty($item->files)) {
|
||||
$files = is_array($item->files) ? $item->files : json_decode($item->files, true);
|
||||
if (is_array($files)) {
|
||||
$item->files = array_map(function($file) {
|
||||
return cdnurl($file);
|
||||
}, $files);
|
||||
} else {
|
||||
$item->files = [];
|
||||
}
|
||||
} else {
|
||||
$item->files = [];
|
||||
}
|
||||
|
||||
// 处理用户头像
|
||||
if ($item->user && $item->user->avatar) {
|
||||
$item->user->avatar = cdnurl($item->user->avatar);
|
||||
}
|
||||
|
||||
// 处理点赞用户头像
|
||||
foreach ($item->likes as $like) {
|
||||
if ($like->user) {
|
||||
$like->avatar = cdnurl($like->avatar);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理评论用户头像
|
||||
foreach ($item->comments as $comment) {
|
||||
if ($comment->user && $comment->user->avatar) {
|
||||
$comment->user->avatar = cdnurl($comment->user->avatar);
|
||||
}
|
||||
if ($comment->replyUser && $comment->replyUser->avatar) {
|
||||
$comment->replyUser->avatar = cdnurl($comment->replyUser->avatar);
|
||||
}
|
||||
}
|
||||
return $item;
|
||||
});
|
||||
|
||||
return $this->success('ok', $list);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Apidoc\Title("最近更新的数量")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("last_see", type="string",require=false, desc="最近查看的时间戳")
|
||||
*/
|
||||
function newcount(Request $request): Response
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
if (!$user) {
|
||||
return $this->fail('请先登录');
|
||||
}
|
||||
$user_id = $user->id;
|
||||
$circle_last_read_id = cache('circle_last_read_id_'.$user_id) ?: 0;
|
||||
// 统计从上次查看时间到现在新增的朋友圈数量
|
||||
$unread_item_ids = FriendCircleModel::where('status', 1)
|
||||
->whereIn('user_id',$this->getFriendUserIds($user_id))
|
||||
->where('id', '>', $circle_last_read_id)
|
||||
->order('id', 'desc')
|
||||
->column('id');
|
||||
|
||||
|
||||
return $this->success('ok', [
|
||||
'unread_count' => count($unread_item_ids),
|
||||
'unread_item_ids'=>$unread_item_ids
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Apidoc\Title("发布朋友圈")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("body", type="string",require=false, desc="内容")
|
||||
* @Apidoc\Param("files", type="string",require=false, desc="图片列表(JSON数组)")
|
||||
*/
|
||||
function create(Request $request): Response
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
if (!$user) {
|
||||
return $this->fail('请先登录');
|
||||
}
|
||||
|
||||
$body = $request->post('content', '');
|
||||
$files = $request->post('files', '');
|
||||
$address = $request->post('address', '');
|
||||
$releaseType = $request->post('releaseType', '');
|
||||
// 验证内容
|
||||
if (empty($body)) {
|
||||
return $this->fail('什么内容都木有啊');
|
||||
}
|
||||
|
||||
|
||||
// 处理图片列表
|
||||
$files_array = [];
|
||||
if (!empty($files)) {
|
||||
if (is_string($files)) {
|
||||
$files_array = json_decode($files, true);
|
||||
} elseif (is_array($files)) {
|
||||
$files_array = $files;
|
||||
}
|
||||
|
||||
if (!is_array($files_array)) {
|
||||
return $this->fail('图片列表格式错误');
|
||||
}
|
||||
|
||||
// 限制图片数量
|
||||
if (count($files_array) > 9) {
|
||||
return $this->fail('最多只能上传9张图片');
|
||||
}
|
||||
}
|
||||
|
||||
// 创建朋友圈动态
|
||||
$circle = FriendCircleModel::create([
|
||||
'user_id' => $user->id,
|
||||
'releaseType' => $releaseType,
|
||||
'body' => $body,
|
||||
'files' => $files_array,
|
||||
'address' => $address,
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
return $this->success('发布成功', ['id' => $circle->id,'data' => $circle]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Apidoc\Title("发表评论")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("body", type="string",require=true, desc="内容")
|
||||
* @Apidoc\Param("id", type="int",require=true, desc="朋友圈动态ID")
|
||||
* @Apidoc\Param("reply_user_id", type="int",require=false, desc="回复的用户ID(回复评论时使用)")
|
||||
*/
|
||||
function comment(Request $request): Response
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
if (!$user) {
|
||||
return $this->fail('请先登录');
|
||||
}
|
||||
|
||||
$body = $request->post('body', '');
|
||||
$circle_id = (int)$request->post('id', 0);
|
||||
$reply_user_id = (int)$request->post('reply_user_id', 0);
|
||||
|
||||
if (empty($body)) {
|
||||
return $this->fail('评论内容不能为空');
|
||||
}
|
||||
|
||||
if ($circle_id <= 0) {
|
||||
return $this->fail('朋友圈动态ID错误');
|
||||
}
|
||||
|
||||
// 检查朋友圈动态是否存在
|
||||
$circle = FriendCircleModel::where('id', $circle_id)
|
||||
->where('status', 1)
|
||||
->find();
|
||||
|
||||
if (!$circle) {
|
||||
return $this->fail('朋友圈动态不存在');
|
||||
}
|
||||
|
||||
// 如果回复评论,检查被回复的用户是否存在
|
||||
if ($reply_user_id > 0) {
|
||||
$reply_user = UserModel::where('id', $reply_user_id)->find();
|
||||
if (!$reply_user) {
|
||||
return $this->fail('被回复的用户不存在');
|
||||
}
|
||||
}
|
||||
|
||||
// 创建评论
|
||||
$comment = FriendCircleCommentModel::create([
|
||||
'circle_id' => $circle_id,
|
||||
'user_id' => $user->id,
|
||||
'reply_user_id' => $reply_user_id,
|
||||
'body' => $body,
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
// 更新朋友圈评论数
|
||||
$circle->comment_count = FriendCircleCommentModel::where('circle_id', $circle_id)
|
||||
->where('status', 1)
|
||||
->count();
|
||||
$circle->save();
|
||||
$comment->user = Db::name('user')->where('id',$comment->user_id)->find();
|
||||
$comment->replyUser=null;
|
||||
if($comment->reply_user_id){
|
||||
$comment->replyUser = Db::name('user')->where('id',$comment->reply_user_id)->find();
|
||||
}
|
||||
return $this->success('评论成功', $comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Apidoc\Title("点赞")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("id", type="int",require=true, desc="朋友圈动态ID")
|
||||
*/
|
||||
function like(Request $request): Response
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
if (!$user) {
|
||||
return $this->fail('请先登录');
|
||||
}
|
||||
|
||||
$circle_id = (int)$request->post('id', 0);
|
||||
|
||||
if ($circle_id <= 0) {
|
||||
return $this->fail('朋友圈动态ID错误');
|
||||
}
|
||||
|
||||
// 检查朋友圈动态是否存在
|
||||
$circle = FriendCircleModel::where('id', $circle_id)
|
||||
->where('status', 1)
|
||||
->find();
|
||||
|
||||
if (!$circle) {
|
||||
return $this->fail('朋友圈动态不存在');
|
||||
}
|
||||
|
||||
// 检查是否已点赞
|
||||
$like = FriendCircleLikeModel::where('circle_id', $circle_id)
|
||||
->where('user_id', $user->id)
|
||||
->find();
|
||||
|
||||
if ($like) {
|
||||
// 取消点赞
|
||||
$like->delete();
|
||||
$circle->like_count = max(0, $circle->like_count - 1);
|
||||
$circle->save();
|
||||
return $this->success('取消点赞成功', ['is_liked' => false]);
|
||||
} else {
|
||||
// 添加点赞
|
||||
FriendCircleLikeModel::create([
|
||||
'circle_id' => $circle_id,
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
$circle->like_count = $circle->like_count + 1;
|
||||
$circle->save();
|
||||
return $this->success('点赞成功', ['is_liked' => true]);
|
||||
}
|
||||
}
|
||||
protected function getFriendUserIds($user_id):array{
|
||||
if (!$user_id) {
|
||||
return [];
|
||||
}
|
||||
$cache_key = 'friend_id_list_'.$user_id;
|
||||
$result = cache($cache_key) ?: [];
|
||||
if(count($result) === 0){
|
||||
$res = request()->IM->friend->getFriendList(idEncode($user_id));
|
||||
$friendsInfo = $res['friendsInfo'];
|
||||
foreach($friendsInfo as $k=>$v){
|
||||
array_push($result,$v['friendUser']['userID']);
|
||||
}
|
||||
cache($cache_key,$result,3600);
|
||||
}
|
||||
$result[] = $user_id;
|
||||
return $result;
|
||||
}
|
||||
function delete(Request $request): Response{
|
||||
$id = $request->post('id');
|
||||
$user = \support\Jwt::getUser();
|
||||
if (!$user) {
|
||||
return $this->fail('请先登录');
|
||||
}
|
||||
if($id){
|
||||
FriendCircleModel::where('id',$id)->where('user_id',$user->id)->delete();
|
||||
}
|
||||
return $this->success('删除成功');
|
||||
}
|
||||
|
||||
function upload_bg(Request $request){
|
||||
try {
|
||||
$user = \support\Jwt::getUser();
|
||||
if (!$user) {
|
||||
return $this->fail('请先登录');
|
||||
}
|
||||
$res = $this->_upload($request);
|
||||
if(is_string($res)){
|
||||
return $this->fail( $res);
|
||||
}
|
||||
|
||||
Db::name('friend_circle_setting')->replace()->insert([
|
||||
'user_id' => $user->id,
|
||||
'bg' => $res[0]['file_name'],
|
||||
'allow_days'=>0,
|
||||
'created_at'=>0
|
||||
]);
|
||||
//$result->ss = cdnurl($result->url);
|
||||
//P($result);
|
||||
return $this->success(__('successful'),[
|
||||
'url'=>$res[0]['file_name']
|
||||
]);
|
||||
}catch (\Exception $e){
|
||||
return $this->error($e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?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 FriendController extends BaseController{
|
||||
/**
|
||||
* 不需要鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
public $noNeedAuth = ['*'];
|
||||
|
||||
/**
|
||||
* 无需登录及鉴权的方法
|
||||
* @var array
|
||||
*/
|
||||
public $noNeedLogin = [];
|
||||
/**
|
||||
* @Apidoc\Title("搜索用户")
|
||||
* @Apidoc\Method("GET")
|
||||
* @Apidoc\Param("nickname", type="string",require=true, desc="昵称")
|
||||
*/
|
||||
function search(Request $request): Response
|
||||
{
|
||||
$keyword = Input('keyword');
|
||||
$searchtype = Input('searchtype');
|
||||
if($searchtype =='id'){
|
||||
}else{
|
||||
|
||||
}
|
||||
return $this->success('ok');
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,8 @@ use hg\apidoc\annotation as Apidoc;
|
||||
|
||||
/**
|
||||
* 礼品模块
|
||||
* @Apidoc\NotParse()
|
||||
* @Apidoc\NotDebug()
|
||||
*/
|
||||
class GiftController extends BaseController{
|
||||
/**
|
||||
@@ -0,0 +1,129 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use support\Request;
|
||||
use support\Response;
|
||||
use hg\apidoc\annotation as Apidoc;
|
||||
use app\model\User;
|
||||
use app\model\Album as AlbumModel;
|
||||
|
||||
/**
|
||||
* 群组管理
|
||||
*/
|
||||
class GroupController extends BaseController
|
||||
{
|
||||
public $noNeedAuth = ['*'];
|
||||
public $noNeedLogin = [];
|
||||
/**
|
||||
* @Apidoc\Title("群相片列表")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("group_id", type="string", require=true, desc="群ID")
|
||||
* @Apidoc\Param("page", type="int", require=true, desc="页码",default=1)
|
||||
* @Apidoc\Param("limit", type="int", require=true, desc="分页大小",default=10)
|
||||
*/
|
||||
function album_list(Request $request): Response
|
||||
{
|
||||
$user = \support\Jwt::getUser();
|
||||
$limit = $request->post('limit',10);
|
||||
$offset = $request->post('offset',0);
|
||||
$group_id = $request->post('groupID') ?:$request->post('group_id');
|
||||
//$ls = $this->get_user_in_group($group_id);
|
||||
//log_alert($ls);
|
||||
log_alert([$offset,$group_id,$limit]);
|
||||
$list = AlbumModel::where('group_id',$group_id)
|
||||
->where('id','<',$offset)
|
||||
->order('id','desc')
|
||||
->limit(0,$limit)
|
||||
->select();
|
||||
return $this->success('ok',$list);
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("上传相片")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("group_id", type="string", require=true, desc="群ID")
|
||||
* @Apidoc\Param("title", type="string", require=true, desc="标题")
|
||||
* @Apidoc\Param("url", type="string", require=true, desc="图片")
|
||||
*/
|
||||
function album_create(Request $request): Response
|
||||
{
|
||||
$user_id = \support\Jwt\JwtToken::getCurrentId();
|
||||
$res = $this->_upload($request);
|
||||
if(is_string($res)){
|
||||
return $this->fail( $res);
|
||||
}
|
||||
$groupID = $request->post('groupID');
|
||||
$insert_data = [];
|
||||
foreach($res as $item){
|
||||
$insert_data[] = [
|
||||
'user_id' => $user_id,
|
||||
'group_id' => $groupID,
|
||||
'title' => $item['origin_name'],
|
||||
'url' => $item['file_name'],
|
||||
];
|
||||
}
|
||||
$result = AlbumModel::saveAll($insert_data);
|
||||
return $this->success('ok',$result[0]);
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("更新相片")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("id", type="string", require=true, desc="ID")
|
||||
* @Apidoc\Param("title", type="string", require=true, desc="标题")
|
||||
* @Apidoc\Param("url", type="string", require=true, desc="图片")
|
||||
*/
|
||||
function album_update(Request $request): Response
|
||||
{
|
||||
$id = $request->input('id');
|
||||
$data = $request->input('data');
|
||||
$album = AlbumModel::find($id);
|
||||
$album->update($data);
|
||||
return $this->success('ok',$album);
|
||||
}
|
||||
/**
|
||||
* @Apidoc\Title("删除相片")
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("id", type="string", require=true, desc="ID")
|
||||
*/
|
||||
function album_delete(Request $request): Response
|
||||
{
|
||||
$ids = Input('ids');
|
||||
//$album = AlbumModel::whereIn('id',condition: $ids)->select();
|
||||
//$album->delete();
|
||||
AlbumModel::whereIn('id',condition: $ids)->delete();
|
||||
return $this->success('ok');
|
||||
}
|
||||
/**
|
||||
* 获取再群里的角色
|
||||
* @Apidoc\NotParse()
|
||||
* @Apidoc\NotDebug()
|
||||
*/
|
||||
private function get_user_in_group($group_id='',$user_id='')
|
||||
{
|
||||
$list = request()->IM->group->getGroupMemberList($group_id,$user_id);
|
||||
return $list;
|
||||
}
|
||||
/**
|
||||
* 头像上传
|
||||
* @Apidoc\Method("POST")
|
||||
* @Apidoc\Param("file", type="File", require=true, desc="文件")
|
||||
*/
|
||||
public function avatar(Request $request)
|
||||
{
|
||||
//单文件上传
|
||||
$groupID = $request->post('groupID');
|
||||
if(!$groupID){
|
||||
return $this->fail(__('参数错误'));
|
||||
}
|
||||
$res = $this->_upload($request);
|
||||
if(is_string($res)){
|
||||
return $this->fail( $res);
|
||||
}
|
||||
$data = [
|
||||
'groupID' => $groupID,
|
||||
'faceURL' => $res[0]['file_name'],
|
||||
];
|
||||
$list = request()->IM->group->setGroupInfo($data);
|
||||
return $this->success(__('successful'),$data);
|
||||
}
|
||||
}
|
||||