Commit edc7bf62 authored by 董先生's avatar 董先生

stock项目创建

parent 60d52e35
ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)
All rights reserved。
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
Apache Licence是著名的非盈利开源组织Apache采用的协议。
该协议和BSD类似,鼓励代码共享和尊重原作者的著作权,
允许代码修改,再作为开源或商业软件发布。需要满足
的条件:
1. 需要给代码的用户一份Apache Licence ;
2. 如果你修改了代码,需要在被修改的文件中说明;
3. 在延伸的代码中(修改和有源代码衍生的代码中)需要
带有原来代码中的协议,商标,专利声明和其他原来作者规
定需要包含的说明;
4. 如果再发布的产品中包含一个Notice文件,则在Notice文
件中需要带有本协议内容。你可以在Notice中增加自己的
许可,但不可以表现为对Apache Licence构成更改。
具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
# stock ThinkPHP 6.0
===============
gupiaopeizi > 运行环境要求PHP7.2+,兼容PHP8.1
\ No newline at end of file
[官方应用服务市场](https://market.topthink.com) | [`ThinkAPI`——官方统一API服务](https://docs.topthink.com/think-api)
ThinkPHPV6.0版本由[亿速云](https://www.yisu.com/)独家赞助发布。
## 主要新特性
* 采用`PHP7`强类型(严格模式)
* 支持更多的`PSR`规范
* 原生多应用支持
* 更强大和易用的查询
* 全新的事件系统
* 模型事件和数据库事件统一纳入事件系统
* 模板引擎分离出核心
* 内部功能中间件化
* SESSION/Cookie机制改进
* 对Swoole以及协程支持改进
* 对IDE更加友好
* 统一和精简大量用法
## 安装
~~~
composer create-project topthink/think tp 6.0.*
~~~
如果需要更新框架使用
~~~
composer update topthink/framework
~~~
## 文档
[完全开发手册](https://www.kancloud.cn/manual/thinkphp6_0/content)
## 参与开发
请参阅 [ThinkPHP 核心框架包](https://github.com/top-think/framework)
## 版权信息
ThinkPHP遵循Apache2开源协议发布,并提供免费使用。
本项目包含的第三方源码和二进制文件之版权信息另行标注。
版权所有Copyright © 2006-2021 by ThinkPHP (http://thinkphp.cn)
All rights reserved。
ThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。
更多细节参阅 [LICENSE.txt](LICENSE.txt)
deny from all
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app;
use think\Service;
/**
* 应用服务类
*/
class AppService extends Service
{
public function register()
{
// 服务注册
}
public function boot()
{
// 服务启动
}
}
<?php
namespace app;
use think\db\exception\DataNotFoundException;
use think\db\exception\ModelNotFoundException;
use think\exception\Handle;
use think\exception\HttpException;
use think\exception\HttpResponseException;
use think\exception\ValidateException;
use think\Response;
use Throwable;
/**
* 应用异常处理类
*/
class ExceptionHandle extends Handle
{
/**
* 不需要记录信息(日志)的异常类列表
* @var array
*/
protected $ignoreReport = [
HttpException::class,
HttpResponseException::class,
ModelNotFoundException::class,
DataNotFoundException::class,
ValidateException::class,
];
/**
* 记录异常信息(包括日志或者其它方式记录)
*
* @access public
* @param Throwable $exception
* @return void
*/
public function report(Throwable $exception): void
{
// 使用内置的方式记录异常日志
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @access public
* @param \think\Request $request
* @param Throwable $e
* @return Response
*/
public function render($request, Throwable $e): Response
{
// 添加自定义异常处理机制
// 其他错误交给系统处理
return parent::render($request, $e);
}
}
<?php
namespace app;
// 应用请求对象类
class Request extends \think\Request
{
}
<?php
use think\facade\Db;
use app\admin\model\User;
use app\apicom\model\JWT;
use think\request;
use util\RedisUtil;
use util\SystemRedis;
// 这是系统自动生成的公共文件
/*
* 输出JSON
*/
if (!function_exists('ajaxmsg')) {
function ajaxmsg($msg = "", $type = 200,$data = '',$is_end = true)
{
$json['status'] = $type;
if (is_array($msg)) {
foreach ($msg as $key => $v) {
$json[$key] = $v;
}
} elseif (!empty($msg)) {
$json['msg'] = $msg;
}
if($data) $json['data'] = $data;
if ($is_end) {
return json($json);
} else {
return json($json);
}
}
}
if (!function_exists('data_auth_sign')) {
/*
* 数据签名认证
* @param array $data 被认证的数据
* @return string
*/
function data_auth_sign($data = [])
{
// 数据类型检测
if(!is_array($data)){
$data = (array)$data;
}
// 排序
ksort($data);
// url编码并生成query字符串
$code = http_build_query($data);
// 生成签名
$sign = sha1($code);
return $sign;
}
}
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use think\App;
use think\exception\ValidateException;
use think\Validate;
use think\Controller;
use think\facade\Request;
use util\RedisUtil;
/**
* 控制器基础类
*/
abstract class AdminBase
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
// 当前用户的ID
public $userId = 0;
// 当前用户的手机号
public $mobile = '';
// 上级代理商
public $adminId = 0;
// token
public $token = null;
/**
* 设置无需登陆的action
* 格式:[
* '控制器名称(驼峰)' => ['action1', 'action2', ...],
* ...
* ]
*/
protected $noLogin = [
'Index' => ['welcome'],
'Login' => ['index', 'info', 'verify'],
];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
public function initialize()
{
$this->token = $this->request->header('Access-Token', '');//['Access-Token'];
$this->adminId = input('aid','');
// 根据token获取用户的数据
if(!$this->adminId || $this->token) {
// 获取当前用户数据
$adminData = $this->token ? RedisUtil::getAdminToken($this->token) : [];
// 当前用户的ID
if(empty($adminData) || !$adminData['aid'] || $adminData['role'] !== '1'){
$this->adminId = '';
}
$this->adminId = isset($adminData['aid']) ? $adminData['aid'] : '';
}
/**
* @var string $controller 当前控制器
* @var string $action 当前方法(action)
*/
$controller = Request::controller();
$action = Request::action();
// 验证用户是否登录,排除无需登录的action
if (!(isset($this->noLogin[$controller]) && in_array($action, $this->noLogin[$controller]))) {
if ($this->adminId == '') {
if(php_sapi_name() == 'cli'){
//echo json_encode(['aid' => $this->adminId, 'status' => 200, 'msg' => '请登陆'],JSON_UNESCAPED_UNICODE);
return false;
}else{
echo json_encode(['aid' => $this->adminId, 'status' => 200, 'msg' => '请登陆'],JSON_UNESCAPED_UNICODE);
exit;
}
}
}
}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
return $v->failException(true)->check($data);
}
}
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use app\admin\model\AdminUser as AdminModel;
use think\facade\Db;
/**
* 文档控制器
* @package app\apicom\home
*/
class AdminUser extends AdminBase
{
/*
* 获取管理员列表
*/
public function getList()
{
$name = input('name', '');
$mobile = input('mobile', '');
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'id desc';
$where = [];
if(!empty($name)) $where[] = ['username','=', $name];
if(!empty($mobile))$where[] = ['mobile','=', $mobile];
$res = AdminModel::getList($where,$order,$offset);
if($res){
return ajaxmsg('操作成功',200, $res);
}else {
return ajaxmsg('操作失败',0);
}
}
/*
* 启用/禁用 状态
*/
public function doDisable()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$res = AdminModel::where('id', $id)->save(['status'=> $status]);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 删除管理员
*/
public function delAdmin()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$count = AdminModel::count();
//print_r($count);exit;
if($count == 1) return ajaxmsg('最后一个不能删除',0);
Db::startTrans();
$res = AdminModel::where('id', $id)->delete();
if ($res) {
Db::commit();
return ajaxmsg('操作成功',200);
} else {
Db::rollback();
return ajaxmsg('操作失败',0);
}
}
/*
* 修改/新增 管理员
*/
public function editAdmin()
{
$data = input();
if (isset($data['id']) && !empty($data['id'])) {
// 验证数据
$result = $this->validate($data, 'AdminUser.edit');
if ($result !== true) return ajaxmsg($result,0);
if (!empty($data['password'])) $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
$res = AdminModel::strict(false)->where(['id'=>$data['id']])->save($data);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
} else {
// 验证数据
$result = $this->validate($data, 'AdminUser.create');
if ($result !== true) return ajaxmsg($result,0);
//print_r($data);exit;
if (AdminModel::saveData($data)) return ajaxmsg('操作成功',200);
return ajaxmsg('操作失败',0);
}
}
}
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use app\admin\model\Agent as AgentModel;
use think\facade\Db;
class Agent extends AdminBase
{
public function index()
{
return '您好!这是一个[Agent]示例应用';
}
/*
* 获取代理列表
*/
public function getAgentList()
{
$name = input('name', '');
$mobile = input('mobile','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'id desc';
if(!empty($name)) $where[] = ['name' ,'=', $name];
if(!empty($mobile)) $where[] = ['mobile','=', $mobile];
$where[] = ['is_del' ,'=', 0];
$where[] = ['agent_id' ,'=', 1];
$res = AgentModel::getAgentList($where,$order,$offset);
if($res){
return ajaxmsg('操作成功',200, $res);
}else {
return ajaxmsg('操作失败',0);
}
}
/*
* 修改代理信息
*/
public function editAgent()
{
$data = input();
unset($data['id']);
unset($data['create_time']);
unset($data['agent_time']);
if(empty($data['id'])) $data['agent_id'] = 1;
$res = AgentModel::strict(false)->where(['mobile'=>$data['mobile']])->save($data);
if($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 禁用代理
*/
public function doDisable()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('agent_pro','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$res = AgentModel::where('id', $id)->save(['agent_pro'=> $status]);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 删除会员
*/
public function delAgent()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$agent = AgentModel::where(['id' => $id,'agent_id' => 1,'agent_pro' => 1])->find();
if(empty($agent)) return ajaxmsg('查询失败',0);
$member = AgentModel::where(['agent_far' => $id, 'is_del' => 0])->find();
//print_r($member);exit;
if(!empty($member)) {
return ajaxmsg('操作失败,请先转移该代理的下级会员',0);
}
$result = AgentModel::where('id', $id)->save(['agent_id' => 0,'agent_pro'=> 0]);
if($result) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
}
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use app\apicom\model\Column as ColumnModel;
use app\apicom\model\Document as DocumentModel;
use think\facade\Db;
/**
* 文档控制器
* @package app\apicom\home
*/
class Document extends AdminBase
{
/*
* 获取文档列表
*/
public function getList()
{
$title = input('title', '');
$column = input('column', '');
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'd.id desc';
if(!empty($title)) $where[] = ['d.title','like', "%{$title}%"];
if(!empty($column)) $where[] = ['c.name' ,'like', "%{$column}%"];
$where[] = ['d.trash' ,'=', 0];
$res = DocumentModel::getList($where,$order,$offset);
if($res){
return ajaxmsg('操作成功',200, $res);
}else {
return ajaxmsg('操作失败',0);
}
}
/*
* 新增文档
*/
public function addDoc()
{
$data = input();
$data['cid'] = isset($data['cid'][0]) ? $data['cid'][0] : '';
$data['uid'] = 1;
$data['model'] = 2;
$data['create_time'] = time();
$data['update_time'] = time();
$data['trash'] = 0;
// 验证数据
$result = $this->validate($data, 'Document.create');
if ($result !== true) return ajaxmsg($result,0);
Db::startTrans();
$res = DocumentModel::strict(false)->insertGetId($data);
//print_r($res);exit;
if(!$res){
Db::rollback();
return ajaxmsg('发布对应栏目失败',0);
}
$con = Db::name('cms_document_content')->insert(['aid'=>$res,'content'=>$data['content']]);
if ($con) {
Db::commit();
return ajaxmsg('发布成功',200);
} else {
Db::rollback();
return ajaxmsg('发布失败',0);
}
}
public function editDoc()
{
$data = input();
$data['update_time'] = time();
$con_id = $data['con_id'] ?? null;
$content = $data['content'] ?? '';
unset($data['con_id']);
unset($data['content']);
// 验证数据
Db::startTrans();
$res = DocumentModel::where('id',$data['id'])->update($data);
$con = Db::name('cms_document_content')->where('aid',$data['id'])->update(['content'=>$content]);
if ($res || $con) {
Db::commit();
return ajaxmsg('发布成功',200);
} else {
Db::rollback();
return ajaxmsg('发布失败',0);
}
}
/*
* 启用/禁用 文档状态
*/
public function doDisable()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$res = DocumentModel::where('id', $id)->save(['status'=> $status]);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 删除文档
*/
public function delDoc()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$doc = DocumentModel::where('id', $id)->find();
if(empty($doc)) return ajaxmsg('查询失败',0);
Db::startTrans();
$res = DocumentModel::where('id', $id)->delete();
$doc = Db::name('cms_document_content')->where('aid', $id)->delete();
if ($res) {
Db::commit();
return ajaxmsg('操作成功',200);
} else {
Db::rollback();
return ajaxmsg('操作失败',0);
}
}
/*
* 获取栏目
*/
public function getColumns()
{
$res = ColumnModel::where(['status'=>1])->field('id,name')->select()->toArray();
$datas = [];
foreach ($res as $k => $val){
$datas[$k]['value'] = $val['id'];
$datas[$k]['label'] = $val['name'];
}
if($res){
return ajaxmsg('操作成功',200, $datas);
}else {
return ajaxmsg('操作失败',0);
}
}
/**
* 文档详情页
*/
public function getDetail()
{
$id = input('id', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
if (!$id) return ajaxmsg("缺少参数",0);
// 获取文章内容
$info = DocumentModel::getOne($id);
if(!$info) return ajaxmsg('查询失败',0);
return ajaxmsg('获取成功',200,$info);
}
}
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use app\admin\model\Slider as SliderModel;
use app\admin\model\Attachment;
use think\facade\Db;
use think\facade\Filesystem;
use think\facade\Env;
/**
* 上传控制器
*/
class File extends AdminBase
{
/**
* 图片上传
* @param int $upload_type
* @param int $type
* @return mixed
*/
public function upload($upload_type = 0, $type = 0)
{
$file = $this->request->file('file');
$name = $file->getOriginalName();
//dump($mime);exit;
// 获取附件信息
$file_info = [
'uid' => $this->adminId,
'name' => $name,
'mime' => $file->getMime(),
'ext' => self::getExtension($name),
'size' => $file->getSize(),
'md5' => explode('.',$name)[0],
];
$exist = Attachment::where(['md5' => $file_info['md5']])->find();
if(!$exist){
$save = Filesystem::disk('public')->putFile( 'images', $file);
if($save){
$file_info['path'] = "/uploads/".$save;
if($add = Attachment::create($file_info)) {
$data['img_url'] = sysConfig('app_url')."/uploads/".$save;
return ajaxmsg('上传成功',200, $data);
}
}else {
return ajaxmsg('上传失败',0);
}
}else{
$data['img_url'] = sysConfig('app_url')."/".$exist['path'];
return ajaxmsg('文件已存在',200,$data);
}
}
public function getExtension($filename){
$myext = substr($filename, strrpos($filename, '.'));
return str_replace('.','',$myext);
}
}
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use think\facade\Db;
use think\facade\App;
use think\facade\Config;
use util\RedisUtil;
use util\QuotationRedis;
class Index extends AdminBase
{
public function index()
{
$data = [];
//当日交易会员数
//$trade = Db::name('stock_trust')->whereDay('trust_date')->group('sub_id')->count();
//累计配资总数
//$borrows = Db::name('stock_borrow')->where(['status'=>1])->group('member_id')->count();
$borrows = Db::name('stock_borrow')->where(['status'=>1])->count();
//代理商总数
$agents = Db::name('member')->where('agent_id','>',0)->where(['status'=>1])->count();
//累计充值总额
$r_total = money_convert(Db::name('money_recharge')->where(['status'=>1])->sum('money'));
//累计提现总额
$w_total = money_convert(Db::name('money_withdraw')->where(['status'=>1])->sum('money'));
//累计操盘余额
$account = money_convert(Db::name('money')->where('status=1')->sum('operate_account'));
//总配资单
$allCount = Db::name('stock_borrow')->count();
//免费体验
$tryCount = Db::name('stock_borrow')->where('type','4')->count();
//按天配资
$dayCount = Db::name('stock_borrow')->where('type','1')->count();
//按周配资
$weekCount = Db::name('stock_borrow')->where('type','2')->count();
//按月配资
$monthCount = Db::name('stock_borrow')->where('type','3')->count();
//免息配资
$freeCount = Db::name('stock_borrow')->where('type','5')->count();
//模拟操盘
$mockCount = Db::name('stock_borrow')->where('type','6')->count();
//当日注册会员
$m_today = Db::name('member')->where(['is_del'=>0])->whereDay('create_time')->count();
//昨日注册会员
$m_ysday = Db::name('member')->where(['is_del'=>0])->whereDay('create_time','yesterday')->count();
//本周注册会员
$m_weeks = Db::name('member')->where(['is_del'=>0])->whereWeek('create_time')->count();
//本月注册会员
$m_month = Db::name('member')->where(['is_del'=>0])->whereMonth('create_time')->count();
//今年注册会员
$m_years = Db::name('member')->where(['is_del'=>0])->whereYear('create_time')->count();
//注册会员总数
$m_total = Db::name('member')->where(['is_del'=>0])->count();
//获取活跃股票
$alivestocks = QuotationRedis::aliveStockList();
$alivestocks = $alivestocks[0] ?: [];
$data['alivecounts'] = count($alivestocks);
foreach ($alivestocks as $key => $val){
$item = explode("_", $val);
$Qdata = RedisUtil::getQuotationData($item[0],$item[1],true);
if(!$Qdata['code']) continue;
$data['alive'][] = $Qdata;
}
$data['rowlist'][] = ['name'=>'当前会员总数','value'=>$m_total,'icon'=>'el-icon-user-solid grid-con-1'];
$data['rowlist'][] = ['name'=>'有效配资总数','value'=>$borrows,'icon'=>'el-icon-s-marketing grid-con-2'];
$data['rowlist'][] = ['name'=>'有效代理总数','value'=>$agents ,'icon'=>'el-icon-s-custom grid-con-3'];
$data['rowlist'][] = ['name'=>'累计充值总额','value'=>$r_total,'icon'=>'el-icon-s-finance grid-con-1'];
$data['rowlist'][] = ['name'=>'累计提现总额','value'=>$w_total,'icon'=>'el-icon-wallet grid-con-2'];
$data['rowlist'][] = ['name'=>'累计操盘余额','value'=>$account,'icon'=>'el-icon-money grid-con-3'];
/*
$data['borrow']['labels'] = ["免费体验","按天配资","按周配资","按月配资","免息配资","模拟操盘"];
$data['borrow']['datasets'][] = [
'data' => [$tryCount,$dayCount,$weekCount,$monthCount,$freeCount,$mockCount]
];
*/
$data['borrow']['labels'] = ["按天配资","按周配资","按月配资","免息配资"];
$data['borrow']['datasets'][] = [
'data' => [$dayCount,$weekCount,$monthCount,$freeCount]
];
$data['member']['labels'] = ["当日注册","昨日注册","本周注册","本月注册","今年注册"];
$data['member']['datasets'][] = [
'label' => '注册会员',
'data' => [$m_today,$m_ysday,$m_weeks,$m_month,$m_years]
];
$data['serinfo'] = $this->getServersInfo();
return ajaxmsg('操作成功',200,$data);
}
public function welcome()
{
return ajaxmsg('操作成功',200,$this->request->server());
}
private function getServersInfo()
{
$info = [
'操作系统' => PHP_OS,
'PHP运行方式' => php_sapi_name(),
'PHP版本' => PHP_VERSION,
'数据库版本' => Config::get('database.default') .' '. $this->MysqlVersion(),
'ThinkPHP版本' => App::version(),
'SWOOLE版本' => SWOOLE_VERSION,
//'上传附件限制' => ini_get('upload_max_filesize'),
//'执行时间限制' => ini_get('max_execution_time').'秒',
'服务器时间' => date("Y年n月j日 H:i:s"),
'服务器地址' => $this->request->server('HTTP_HOST'),
//'服务器IP地址' => $this->request->server('REMOTE_ADDR'),
];
return $info;
}
private function MysqlVersion()
{
$version = Db::query("select version() as ver");
return $version[0]['ver'];
}
}
<?php
declare (strict_types = 1);
namespace app\admin\controller;
//use think\captcha\facade\Captcha;
use app\admin\model\User as UserModel;
use think\facade\Session;
use util\Captcha;
class Login extends AdminBase
{
public function index()
{
// 获取post数据
$data['username'] = input('username', '');
$data['password'] = input('password', '');
$data['captcha'] = input('captcha' , '');
$data['remember'] = input('remember', '');
if(!$data['username']) return ajaxmsg('用户名不能为空',400);
if(!$data['password']) return ajaxmsg('请输入登录密码',400);
$rememberme = isset($data['remember']) ? true : false;//记住账号功能 已经写入redis缓存,暂不需要
// 验证码
if(sysConfig('captcha_signin')) {
if(!$data['captcha']) return ajaxmsg('验证码不能为空',400);
if(!app()->make(Captcha::class)->check($data['captcha'])){
//验证失败
return ajaxmsg('验证码错误或失效',400);
}
}
// 验证数据
$result = $this->validate($data, 'AdminUser.signin');
if($result !== true) return ajaxmsg($result,400);
// 登录
$res_admin = UserModel::login($data['username'], $data['password'], $rememberme);
//print_r($res_admin);return;
if($res_admin && $res_admin['status'] == 1){
// 记录行为
//action_log('user_signin', 'admin_user', $uid, $uid);
return ajaxmsg('登录成功!',200, $res_admin['data']);
}
return ajaxmsg($res_admin['message'],400);
}
public function verify()
{
return app()->make(Captcha::class)->create();
}
}
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use app\apicom\model\Member as MemberModel;
use app\apicom\model\Record as RecordModel;
use app\apicom\model\Recharge;
use app\apicom\model\Withdraw;
use think\facade\Db;
class Member extends AdminBase
{
public function index()
{
return '您好!这是一个[admin]示例应用';
}
/*
* 获取会员列表
*/
public function getList()
{
$name = input('name', '');
$mobile = input('mobile','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$agent = input('agent','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'id desc';
if(!empty($name)) $where[] = ['a.name' ,'=', $name];
if(!empty($mobile)) $where[] = ['a.mobile','=', $mobile];
if(!empty($agent)) $where[] = ['a.agent_far','=', $agent];
$where[] = ['a.is_del' ,'=', 0];
$data_list = MemberModel::view('member a')
->view('money b','account,freeze,operate_account,bond_account','a.id=b.mid')
->where($where)
->order($order)
->paginate($offset, false, ['query' => request()->param()]);
if(!$data_list) return ajaxmsg('没有数据',0);
return ajaxmsg('操作成功',200,$data_list);
}
/*
* 删除会员
*/
public function delMember()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$member = MemberModel::where('id', $id)->field('mobile, agent_id')->find();
if(empty($member)) return ajaxmsg('查询失败',0);
if ($member['agent_id'] > 0) {
return ajaxmsg('操作失败,用户['. $member['mobile'].']是代理,请先取消代理资格',0);
}
$result = MemberModel::where('id', $id)->save(['is_del'=> 1]);
if ($result) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 禁用会员
*/
public function doDisable()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
if($status == '') return ajaxmsg('缺少参数',0);
$res = MemberModel::where('id', $id)->save(['status'=> $status]);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 新增会员
*/
public function addMember()
{
$data = input();
$data['agent_far']= isset($data['agent_far'][0]) ? $data['agent_far'][0] : '';
//print_r($data);exit;
// 验证数据
$result = $this->validate($data, 'Member.create');
if ($result !== true) return ajaxmsg($result,0);
if (empty($data['mobile']))
return ajaxmsg('请输入您的手机号!',0);
$userExist = MemberModel::where('mobile|name', '=', $data['mobile'])->column('mobile', 'id');
if ($userExist)
return ajaxmsg('该手机号已经注册',0);
if (!in_array(strlen($data['mobile']), [8, 9, 11]))
return ajaxmsg('您输入的手机号码有误!',0);
$res = MemberModel::saveData($data);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 编辑用户
*/
public function editMember()
{
$data = input();
$data['agent_id'] = $data['agent_id'];
$data['status'] = $data['status'];
$data['agent_far']= isset($data['agent_far'][0]) ? $data['agent_far'][0] : '';
if(isset($data['agent_far'][0])){
$data['agent_far'] = $data['agent_pro'] = $data['agent_far'][0];
}else{
$data['agent_far'] = $data['agent_pro'] = 0;
}
if($data['passwd']) $data['passwd'] = password_hash($data['passwd'], PASSWORD_DEFAULT);
if($data['paywd'] ) $data['paywd'] = password_hash($data['paywd'] , PASSWORD_DEFAULT);
if (empty($data['id'])) return ajaxmsg('缺少ID参数!',0);
if (empty($data['passwd'])) unset($data['passwd']);
if (empty($data['paywd'])) unset($data['paywd']);
//print_r($data);exit;
$res = MemberModel::strict(false)->where(['id'=>$data['id']])->save($data);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 根据ID获取会员
*/
public function getInfo()
{
$id = input('id', '');
$member = MemberModel::where('id', $id)->find()->toArray();
$agents = MemberModel::where('agent_id', 1)->field('id,name,mobile')->select()->toArray();
foreach ($agents as $k => $val){
$datas[$k]['value'] = $val['id'];
$datas[$k]['label'] = $val['name']." ".$val['mobile'];
}
$member['agents'] = $datas;
return ajaxmsg('操作成功',200,$member);
}
/*
* 获取代理列表
*/
public function getAgents()
{
$res = MemberModel::where(['agent_id'=>1,'agent_pro'=>1])->field('id,name,mobile')->select()->toArray();
$datas = [];
foreach ($res as $k => $val){
$datas[$k]['value'] = $val['id'];
$datas[$k]['label'] = $val['name']." ".$val['mobile'];
}
if($res){
return ajaxmsg('操作成功',200, $datas);
}else {
return ajaxmsg('操作失败',0);
}
}
}
This diff is collapsed.
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use app\admin\model\Order as OrderModel;
use app\apicom\model\Borrow as BorrowModel;
use think\facade\Db;
use util\RedisUtil;
class Order extends AdminBase
{
/*
* 获取订单列表
*/
public function getOrderList()
{
$path = input('path','');
$name = input('name','');
$code = input('code','' , ['trim', FILTER_SANITIZE_NUMBER_INT]);
$subid = input('subid','' , ['trim', FILTER_SANITIZE_NUMBER_INT]);
$mobile = input('mobile','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'id desc';
$where = [];
if(!$path) return ajaxmsg('缺少参数',0);
if(!empty($name)) $where[] = ['m.name','=', $name];
if(!empty($code)) $where[] = ['s.gupiao_code','=', $code];
if(!empty($subid)) $where[] = ['sub.sub_account','=', $subid];
if(!empty($mobile))$where[] = ['m.mobile','=', $mobile];
$data_list = OrderModel::getAllList($path,$where,$order,$offset);
if(!$data_list) return ajaxmsg('没有数据',0);
return ajaxmsg('操作成功',200,$data_list);
}
/*
* 修改新股申购
*/
public function doIpoEdit()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status','');
$res = Db::name('stock_trust_ipo')->where(['id'=>$id,'status'=>'申购中'])->save(['status'=> $status]);
//这里要做委托和撤单判断
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 强制平仓
*/
public function handleClose()
{
if(!checkTradeTime()) return ajaxmsg('非交易时间',0);
$data = [
"subid" => input('sub_id',''),//子账户ID,
"code" => input('gupiao_code' ,''),//股票代码
"name" => input('gupiao_name' ,''),//股票名称
"market" => input('market',''),//交易所代码
"count" => input('canbuy_count' , 0),//买卖数量
'model' => input('model' , 2),//1:是委托状态
];
$price = input('now_price',0);//手动设置价格
$res = BorrowModel::saveSell($data,$sys=1,$price);
//return $res;
if(isset($res['status'])){
if(!$res['status']) return ajaxmsg($res['message'],0);
return ajaxmsg('强平操作成功!',200);
}else{
return ajaxmsg('操作失败!',0);
}
}
}
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use think\facade\Db;
use util\RedisUtil;
class Report extends AdminBase
{
public function index()
{
//会员数量统计
$data[] = self::MemberReport();
//充值提现统计
$data[] = self::MoneyReport();
//股票持仓统计
$data[] = self::StocksReport();
//配资管理统计
$data[] = self::BorrowReport();
return ajaxmsg('操作成功',200,$data);
}
//会员数量统计
public function MemberReport()
{
$data = [
'title' => '会员数量统计',
'infos' => [
[ 'name' => '注册会员总数', 'value' => Db::name('member')->where(['is_del'=>0])->count() ],
[ 'name' => '一级代理总数', 'value' => Db::name('member')->where(['status'=>1,'agent_id'=>2])->count() ],
[ 'name' => '二级代理总数', 'value' => Db::name('member')->where(['status'=>1,'agent_id'=>3])->count() ],
[ 'name' => '三级代理总数', 'value' => Db::name('member')->where(['status'=>1,'agent_id'=>4])->count() ],
[ 'name' => '当前代理总数', 'value' => Db::name('member')->where('agent_id','>',0)->where('status',1)->count() ]
]
];
return $data ?? [];
}
//充值提现统计
public function MoneyReport()
{
$data = [
'title' => '充值提现统计',
'infos' => [
[ 'name' => '累计充值总额', 'value' => money_convert(Db::name('money_recharge')->where('status','1')->sum('money')) ],
[ 'name' => '今日充值金额', 'value' => money_convert(Db::name('money_recharge')->where('status','1')->whereDay('create_time')->sum('money')) ],
[ 'name' => '累计提现总额', 'value' => money_convert(Db::name('money_withdraw')->where('status','1')->sum('money'))],
[ 'name' => '今日提现金额', 'value' => money_convert(Db::name('money_withdraw')->where('status','1')->whereDay('create_time')->sum('money')) ],
]
];
return $data ?? [];
}
//股票持仓统计
public function StocksReport()
{
$position = self::position();
$data = [
'title' => '股票持仓统计',
'infos' => [
[ 'name' => '持仓股票总额', 'value' => round($position['Total'],2) ],
[ 'name' => '今日委托金额', 'value' => money_convert(Db::name('stock_trust')->whereDay('trust_date')->sum('amount')) ],
[ 'name' => '今日委托总数', 'value' => Db::name('stock_trust')->whereDay('trust_date')->count()],
[ 'name' => '今日成交金额', 'value' => money_convert(Db::name('stock_deal_stock')->whereDay('deal_date')->where('status','<>','0')->sum('amount')) ],
[ 'name' => '今日成交总数', 'value' => Db::name('stock_deal_stock')->whereDay('deal_date')->where('status','<>','0')->count() ],
[ 'name' => '持仓盈亏总额', 'value' => round($position['Profit'],2) ],
]
];
return $data ?? [];
}
//配资管理统计
public function BorrowReport()
{
$data = [
'title' => '配资管理统计',
'infos' => [
[ 'name' => '累计总管理费', 'value' => money_convert(Db::name('stock_borrow')->where('status','>=',1)->sum('borrow_interest')) ],
[ 'name' => '累计返佣金额', 'value' => round(Db::name('agents_back_money')->sum('affect'), 2) ],
[ 'name' => '保证金总金额', 'value' => money_convert(Db::name('stock_borrow')->where(['status'=>1])->sum('deposit_money')) ],
[ 'name' => '总追加保证金', 'value' => money_convert(Db::name('stock_addmoney')->where(['status'=>1])->sum('money')) ],
[ 'name' => '累计提盈总额', 'value' => round(Db::name('stock_drawprofit ')->where(['status'=>1])->sum('money'),2) ],
[ 'name' => '累计操盘总额', 'value' => money_convert(Db::name('money')->where('status=1')->sum('operate_account')) ],
]
];
return $data ?? [];
}
/*********************************************************************/
public function position()
{
//持仓总额
$Total = $Profit = 0;
$Stock = Db::name('stock_position')->where('stock_count','>',0)->where(['buying'=>0])->select();
foreach ($Stock as $k=>$v){
//查询股票最新行情
$Qdata = RedisUtil::getQuotationData($v["gupiao_code"],$v["market"],true);
$Price = $Qdata['Price'] ?: 0;
//持仓总额
$Total += ($v['stock_count']*$Price);
//盈亏总额
$Profit += round(($Price-self::calculate($v["gupiao_code"],'average'))*$v['stock_count'], 2);
}
return ['Total'=>$Total,'Profit'=>$Profit];
}
public function calculate($code,$variable)
{
if(!$code || !$variable) return 0;
switch ($variable) {
case 'price':
$order = Db::name('stock_delivery_order')->where(['gupiao_code' => $code,'status' => 1,'business_name' => '证券买入']);
$amount = $order->sum('liquidation_amount');
$volume = $order->sum('volume');
$result = bcdiv(strval($amount),strval($volume),3);
break;
case 'average':
$order = Db::name('stock_delivery_order')->where(['gupiao_code' => $code,'status' => 1,'business_name' => '证券买入']);
$amount = $order->sum('residual_quantity');
$volume = $order->sum('volume');
$result = bcdiv(strval($amount),strval($volume),3);
break;
default:
$result = 0;
break;
}
return $result;
}
}
\ No newline at end of file
This diff is collapsed.
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use app\admin\model\AdminConfig;
use util\SystemRedis;
use think\facade\Db;
class Setting extends AdminBase
{
/*
* 获取网站设置列表
*/
public function getConfigs()
{
$group = input('group','');
if(!$group) return ajaxmsg('缺少参数',0);
$data_list = AdminConfig::getAdminConfig($group);
if(!$data_list) return ajaxmsg('没有数据',0);
foreach ($data_list as $key => $val){
if($val['type']=='image'){
$data_list[$key]['value'] = sysConfig('app_url').getFilePath($val['value']);
}
}
return ajaxmsg('操作成功',200,$data_list);
}
/*
* 修改网站设置列表
*/
public function editConfigs()
{
$data = input();
if(is_array($data)){
$AdminConfig = new AdminConfig;
$res = $AdminConfig->saveAll($data);
$ret = SystemRedis::cacheConfig();
cache('festival_' . date('Y', time()), '');
if(!$res || !$ret) return ajaxmsg('操作失败',0);
return ajaxmsg('操作成功',200);
}
return ajaxmsg('操作失败',0);
}
}
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use app\admin\model\Slider as SliderModel;
use think\facade\Db;
/**
* 文档控制器
* @package app\apicom\home
*/
class Slider extends AdminBase
{
/*
* 获取轮播列表
*/
public function getList()
{
$title = input('title', '');
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'id desc';
$where = [];
if(!empty($title)) $where[] = ['title','like', "%{$title}%"];
$res = SliderModel::getList($where,$order,$offset);
if($res){
return ajaxmsg('操作成功',200, $res);
}else {
return ajaxmsg('操作失败',0);
}
}
/*
* 启用/禁用 状态
*/
public function doDisable()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$res = SliderModel::where('id', $id)->save(['status'=> $status]);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 删除轮播
*/
public function delSlider()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$sli = SliderModel::where('id', $id)->find();
if(empty($sli)) return ajaxmsg('查询失败',0);
Db::startTrans();
$res = SliderModel::where('id', $id)->delete();
if ($res) {
Db::commit();
return ajaxmsg('操作成功',200);
} else {
Db::rollback();
return ajaxmsg('操作失败',0);
}
}
/**
* 轮播详情页
*/
public function getDetail()
{
$id = input('id', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
if (!$id) return ajaxmsg("缺少参数",0);
// 获取文章内容
$info = SliderModel::where(['id'=> $id,'status' => 1])->find();
$info['img_url'] = sysConfig('app_url').getFilePath($info['cover']);
if(!$info) return ajaxmsg('查询失败',0);
return ajaxmsg('获取成功',200,$info);
}
/*
* 新增广告
*/
public function addSlider()
{
$data = input();
$data['create_time'] = time();
// 验证数据
$result = $this->validate($data, 'Slider.create');
if ($result !== true) return ajaxmsg($result,0);
//dump($data);exit;
$res = SliderModel::saveData($data);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
}
\ No newline at end of file
<?php
// 这是系统自动生成的event定义文件
return [
];
<?php
// 这是系统自动生成的middleware定义文件
return [
// Session初始化
\think\middleware\SessionInit::class,
//跨域请求
\think\middleware\AllowCrossDomain::class,
];
<?php
namespace app\admin\model;
use think\Model;
use think\facade\Db;
use util\SystemRedis;
/**
* 后台用户模型
* @package app\admin\model
*/
class AdminConfig extends Model
{
// 设置当前模型对应的完整数据表名称
protected $name = 'admin_config';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
public static function getAdminConfig($group)
{
$data_list = self::where(['group'=>$group, 'status'=>1])
->order('sort asc')
->select()
->each( function($item, $key){
//return $item;
});
SystemRedis::cacheConfig();
return $data_list;
}
}
\ No newline at end of file
<?php
namespace app\admin\model;
use think\Model;
use think\facade\Db;
/**
* 后台用户模型
* @package app\admin\model
*/
class AdminUser extends Model
{
// 设置当前模型对应的完整数据表名称
protected $name = 'admin_user';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
public static function getList($map=[],$order='',$offset=20)
{
$data_list = self::where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['last_time'] = date('Y-m-d H:i:s',$item['last_time']);
});
return $data_list;
}
/**
* 保存注册数据
* @param [type] $data [description]
*/
public static function saveData($data)
{
$sdata['mobile'] = $data['mobile'];
$sdata['username'] = $data['username'];
$sdata['nickname'] = $data['nickname'];
$sdata['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
$sdata['pid'] = 0;
$sdata['status'] = 1;
$sdata['create_time'] = time();
$sdata['last_login_ip'] = getClientIp();
if(self::create($sdata)) return true;
return false;
}
}
\ No newline at end of file
<?php
namespace app\admin\model;
use think\Model;
use think\facade\Db;
/**
* 后台用户模型
* @package app\admin\model
*/
class Agent extends Model
{
// 设置当前模型对应的完整数据表名称
protected $name = 'member';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
public static function getAgentList($map=[],$order='',$offset=20)
{
$data_list = self::where($map)
->field('id,name,mobile,agent_far,agent_pro,agent_id,agent_rate,agent_time,create_time')
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
//return self::getMarketValue($item);
});
return $data_list;
}
}
\ No newline at end of file
<?php
namespace app\admin\model;
use think\Model;
/**
* 附件模型
* @package app\admin\model
*/
class Attachment extends Model
{
// 设置当前模型对应的完整数据表名称
protected $name = 'admin_attachment';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
/**
* 根据附件id获取路径
* @param string|array $id 附件id
* @param int $type 类型:0-补全目录,1-直接返回数据库记录的地址
* @return string|array 路径
*/
public function getFilePath($id = '', $type = 0)
{
if (is_array($id)) {
$data_list = $this->where('id', 'in', $id)->select();
$paths = [];
foreach ($data_list as $key => $value) {
if ($value['driver'] == 'local') {
$paths[$key] = ($type == 0 ? PUBLIC_PATH : '').$value['path'];
} else {
$paths[$key] = $value['path'];
}
}
return $paths;
} else {
$data = $this->where('id', $id)->find();
if ($data) {
if ($data['driver'] == 'local') {
return ($type == 0 ? PUBLIC_PATH : '').$data['path'];
} else {
return $data['path'];
}
} else {
return false;
}
}
}
/**
* 根据图片id获取缩略图路径,如果缩略图不存在,则返回原图路径
* @param string $id 图片id
* @author 路人甲乙
* @return mixed
*/
public function getThumbPath($id = '')
{
$result = $this->where('id', $id)->field('path,driver,thumb')->find();
if ($result) {
if ($result['driver'] == 'local') {
return $result['thumb'] != '' ? PUBLIC_PATH.$result['thumb'] : PUBLIC_PATH.$result['path'];
} else {
return $result['thumb'] != '' ? $result['thumb'] : $result['path'];
}
} else {
return $result;
}
}
/**
* 根据附件id获取名称
* @param string $id 附件id
* @return string 名称
*/
public function getFileName($id = '')
{
return $this->where('id', $id)->value('name');
}
}
<?php
namespace app\admin\model;
use app\admin\model\Role as RoleModel;
use think\Model;
use think\Exception;
use util\Tree;
/**
* 节点模型
* @package app\admin\model
*/
class Menu extends Model
{
// 设置当前模型对应的完整数据表名称
protected $table = 'admin_menu';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
// 将节点url转为小写
public function setUrlValueAttr($value)
{
return strtolower(trim($value));
}
/**
* 递归修改所属模型
* @param int $id 父级节点id
* @param string $module 模型名称
* @return bool
*/
public static function changeModule($id = 0, $module = '')
{
if ($id > 0) {
$ids = self::where('pid', $id)->column('id');
if ($ids) {
foreach ($ids as $id) {
self::where('id', $id)->setField('module', $module);
self::changeModule($id, $module);
}
}
}
return true;
}
/**
* 获取树形节点
* @param int $id 需要隐藏的节点id
* @param string $default 默认第一个节点项,默认为“顶级节点”,如果为false则不显示,也可传入其他名称
* @param string $module 模型名
* @return mixed
*/
public static function getMenuTree($id = 0, $default = '', $module = '')
{
$result[0] = '顶级节点';
$where['status'] = ['egt', 0];
if ($module != '') {
$where['module'] = $module;
}
// 排除指定节点及其子节点
if ($id !== 0) {
$hide_ids = array_merge([$id], self::getChildsId($id));
$where['id'] = ['notin', $hide_ids];
}
// 获取节点
$menus = Tree::toList(self::where($where)->order('pid,id')->column('id,pid,title'));
foreach ($menus as $menu) {
$result[$menu['id']] = $menu['title_display'];
}
// 设置默认节点项标题
if ($default != '') {
$result[0] = $default;
}
// 隐藏默认节点项
if ($default === false) {
unset($result[0]);
}
return $result;
}
/**
* 获取顶部节点
* @param string $max 最多返回多少个
* @param string $cache_tag 缓存标签
* @return array
*/
public static function getTopMenu($max = '', $cache_tag = '')
{
$cache_tag .= '_role_'.session('user_auth.role');
$menus = cache($cache_tag);
if (!$menus) {
// 非开发模式,只显示可以显示的菜单
if (config('develop_mode') == 0) {
$map['online_hide'] = 0;
}
$map['status'] = 1;
$map['pid'] = 0;
$menus = self::where($map)->order('sort,id')->limit($max)->column('id,pid,module,title,url_value,url_type,url_target,icon,params');
foreach ($menus as $key => &$menu) {
// 没有访问权限的节点不显示
if (!RoleModel::checkAuth($menu['id'])) {
unset($menus[$key]);
continue;
}
if ($menu['url_value'] != '' && ($menu['url_type'] == 'module_admin' || $menu['url_type'] == 'module_home')) {
$url = explode('/', $menu['url_value']);
$menu['controller'] = $url[1];
$menu['action'] = $url[2];
$menu['url_value'] = $menu['url_type'] == 'module_admin' ? admin_url($menu['url_value'], $menu['params']) : home_url($menu['url_value'], $menu['params']);
}
}
// 非开发模式,缓存菜单
if (config('develop_mode') == 0) {
cache($cache_tag, $menus);
}
}
return $menus;
}
/**
* 获取侧栏节点
* @param string $id 模块id
* @param string $module 模块名
* @param string $controller 控制器名
* @return array|mixed
*/
public static function getSidebarMenu($id = '', $module = '', $controller = '')
{
$module = $module == '' ? request()->module() : $module;
$controller = $controller == '' ? request()->controller() : $controller;
$cache_tag = strtolower('_sidebar_menus_' . $module . '_' . $controller).'_role_'.session('user_auth.role');
$menus = cache($cache_tag);
if (!$menus) {
// 获取当前节点地址
$location = self::getLocation($id);
// 当前顶级节点id
$top_id = $location[0]['id'];
// 获取顶级节点下的所有节点
$map = [
'status' => 1,
'module' => $module
];
// 非开发模式,只显示可以显示的菜单
if (config('develop_mode') == 0) {
$map['online_hide'] = 0;
}
$menus = self::where($map)->order('sort,id')->column('id,pid,module,title,url_value,url_type,url_target,icon,params');
// 解析模块链接
foreach ($menus as $key => &$menu) {
// 没有访问权限的节点不显示
if (!RoleModel::checkAuth($menu['id'])) {
unset($menus[$key]);
continue;
}
if ($menu['url_value'] != '' && ($menu['url_type'] == 'module_admin' || $menu['url_type'] == 'module_home')) {
$menu['url_value'] = $menu['url_type'] == 'module_admin' ? admin_url($menu['url_value'], $menu['params']) : home_url($menu['url_value'], $menu['params']);
}
}
$menus = Tree::toLayer($menus, $top_id, 2);
// 非开发模式,缓存菜单
if (config('develop_mode') == 0) {
cache($cache_tag, $menus);
}
}
return $menus;
}
/**
* 获取指定节点ID的位置
* @param string $id 节点id,如果没有指定,则取当前节点id
* @param bool $del_last_url 是否删除最后一个节点的url地址
* @param bool $check 检查节点是否存在,不存在则抛出错误
* @return array
* @throws \think\Exception
*/
public static function getLocation($id = '', $del_last_url = false, $check = true)
{
$model = request()->module();
$controller = request()->controller();
$action = request()->action();
if ($id != '') {
$cache_name = 'location_menu_'.$id;
} else {
$cache_name = 'location_'.$model.'_'.$controller.'_'.$action;
}
$location = cache($cache_name);
if (!$location) {
$map['pid'] = ['<>', 0];
$map['url_value'] = strtolower($model.'/'.trim(preg_replace("/[A-Z]/", "_\\0", $controller), "_").'/'.$action);
// 当前操作对应的节点ID
$curr_id = $id == '' ? self::where($map)->value('id') : $id;
// 获取节点ID是所有父级节点
$location = Tree::getParents(self::column('id,pid,title,url_value'), $curr_id);
// if ($check && empty($location)) {
// throw new Exception('获取不到当前节点地址,可能未添加节点', 9001);
// }
// 剔除最后一个节点url
if ($del_last_url) {
$location[count($location) - 1]['url_value'] = '';
}
// 非开发模式,缓存菜单
if (config('develop_mode') == 0) {
cache($cache_name, $location);
}
}
return $location;
}
/**
* 根据分组获取节点
* @param string $group 分组名称
* @param bool|string $fields 要返回的字段
* @param array $map 查找条件
* @author 路人甲乙
* @return array
*/
public static function getMenusByGroup($group = '', $fields = true, $map = [])
{
$map['module'] = $group;
return self::where($map)->order('sort,id')->column($fields, 'id');
}
/**
* 获取节点分组
* @return array
*/
public static function getGroup()
{
$map['status'] = 1;
$map['pid'] = 0;
$menus = self::where($map)->order('id,sort')->column('module,title');
return $menus;
}
/**
* 获取所有子节点id
* @param int $pid 父级id
* @author 路人甲乙
* @return array
*/
public static function getChildsId($pid = 0)
{
$ids = self::where('pid', $pid)->column('id');
foreach ($ids as $value) {
$ids = array_merge($ids, self::getChildsId($value));
}
return $ids;
}
/**
* 获取所有父节点id
* @param int $id 节点id
* @author 路人甲乙
* @return array
*/
public static function getParentsId($id = 0)
{
$pid = self::where('id', $id)->value('pid');
$pids = [];
if ($pid != 0) {
$pids[] = $pid;
$pids = array_merge($pids, self::getParentsId($pid));
}
return $pids;
}
/**
* 根据节点id获取上下级的所有id
* @param int $id 节点id
* @author 路人甲乙
* @return array
*/
public static function getLinkIds($id = 0)
{
$childs = self::getChildsId($id);
$parents = self::getParentsId($id);
return array_merge((array)(int)$id, $childs, $parents);
}
}
<?php
namespace app\admin\model;
use think\Model;
use think\facade\Db;
/**
* 后台用户模型
* @package app\admin\model
*/
class Money extends Model
{
// 设置当前模型对应的完整数据表名称
protected $name = 'admin_bank';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
public static function getBanks($map=[],$order='',$offset=20)
{
$data_list = self::name('admin_bank')->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
//return $item;
});
return $data_list;
}
}
\ No newline at end of file
<?php
namespace app\admin\model;
use app\apicom\model\StockPosition;
use think\Model;
use think\facade\Db;
use util\RedisUtil;
/**
* 后台用户模型
* @package app\admin\model
*/
class Order extends Model
{
// 交割订单状态获取器
public static function getStatusName($value)
{
$status = ['0'=>'未交割','1'=>'已交割'];
return $status[$value];
}
/*
* 获取 持仓*委托*成交*撤单*交割 列表
*/
public static function getAllList($path,$map=[],$order='',$offset=20)
{
switch ($path) {
case 'position':
$data_list = Db::view('stock_position s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where($map)
->where('s.stock_count','>',0)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
return self::getMarketValue($item);
});
break;
case 'trust':
$data_list = Db::view('stock_trust s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where('s.status','<>','已撤')
->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['trust_count'] = intval($item['trust_count']);
$item['add_time'] = date('Y-m-d H:i:s' ,$item['add_time']);
return $item;
});
break;
case 'deal':
$data_list = Db::view('stock_deal_stock s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['trust_count'] = intval($item['trust_count']);
return $item;
});
break;
case 'cancel':
$data_list = Db::view('stock_trust s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where('s.status','=','已撤')
->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['trust_count'] = intval($item['trust_count']);
$item['add_time'] = date('Y-m-d H:i:s' ,$item['add_time']);
return $item;
});
break;
case 'delivery':
$data_list = Db::view('stock_delivery_order s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['status_n'] = self::getStatusName($item['status']);
//$item['add_time'] = date('Y-m-d H:i:s' ,$item['add_time']);
return $item;
});
break;
case 'ipolist':
$data_list = Db::view('stock_trust_ipo s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where('s.status','<>','')
->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['trust_count'] = intval($item['trust_count']);
$item['add_time'] = date('Y-m-d H:i:s' ,$item['add_time']);
return $item;
});
break;
default:
$data_list = [];
break;
}
return $data_list;
}
public static function getMarketValue($item=[]) { //查询股票最新行情
$Qdata = RedisUtil::getQuotationData($item["gupiao_code"],$item["market"],true);
//提取当前价格
$item['now_price'] = $Qdata['Price'] ?: 0;
//市值 = 当前价格*数量
$item['market_value'] = round($item['now_price']*$item['stock_count'], 2);
//参考成本价
$item['ck_price'] = StockPosition::calculate($item['sub_id'],$item["gupiao_code"],'price');
//买入均价
$item['buy_average_price'] = StockPosition::calculate($item['sub_id'],$item["gupiao_code"],'average');
//参考盈亏
$item['ck_profit'] = $item['stock_count'] > 0 ? bcmul(strval($item['now_price']-$item['buy_average_price']),strval($item['stock_count']),2) : 0;
//盈亏比例
$item['profit_rate'] = $item['stock_count'] > 0 ? bcdiv(strval($item['ck_profit']),strval($item['buy_average_price']*$item['stock_count']*100),2) : 0;
//当天可卖数量计算
$item['canbuy_count'] = StockPosition::getCanbuyCount($item['sub_id'],$item["gupiao_code"]);
return $item;
}}
\ No newline at end of file
<?php
namespace app\admin\model;
use think\Model;
use util\Tree;
use app\admin\model\Menu as MenuModel;
/**
* 角色模型
* @package app\admin\model
*/
class Role extends Model
{
// 设置当前模型对应的完整数据表名称
protected $name = 'admin_role';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
// 写入时,将菜单id转成json格式
public function setMenuAuthAttr($value)
{
return json_encode($value);
}
// 读取时,将菜单id转为数组
public function getMenuAuthAttr($value)
{
return json_decode($value, true);
}
/**
* 获取树形角色
* @param null $id 需要隐藏的角色id
* @param string $default 默认第一个菜单项,默认为“顶级角色”,如果为false则不显示,也可传入其他名称
* @author 路人甲乙
* @return mixed
*/
public static function getTree($id = null, $default = '')
{
$result[0] = '顶级角色';
$where['status'] = ['egt', 0];
// 排除指定菜单及其子菜单
if ($id !== null) {
$hide_ids = array_merge([$id], self::getChildsId($id));
$where['id'] = ['notin', $hide_ids];
}
// 获取菜单
$roles = Tree::config(['title' => 'name'])->toList(self::where($where)->column('id,pid,name'));
foreach ($roles as $role) {
$result[$role['id']] = $role['title_display'];
}
// 设置默认菜单项标题
if ($default != '') {
$result[0] = $default;
}
// 隐藏默认菜单项
if ($default === false) {
unset($result[0]);
}
return $result;
}
/**
* 获取所有子角色id
* @param string $pid 父级id
* @author 路人甲乙
* @return array
*/
public static function getChildsId($pid = '')
{
$ids = self::where('pid', $pid)->column('id');
foreach ($ids as $value) {
$ids = array_merge($ids, self::getChildsId($value));
}
return $ids;
}
/**
* 检查访问权限
* @param int $id 需要检查的节点ID,默认检查当前操作节点
* @param bool $url 是否为节点url,默认为节点id
* @author 路人甲乙
* @return bool
*/
public static function checkAuth($id = 0, $url = false)
{
// 当前用户的角色
$role = session('user_auth.role');
// id为1的是超级管理员,或者角色为1的,拥有最高权限
if (session('user_auth.uid') == '1' || $role == '1') {
return true;
}
// 获取当前用户的权限
$menu_auth = session('role_menu_auth');
// 检查权限
if ($menu_auth) {
if ($id !== 0) {
return $url === false ? isset($menu_auth[$id]) : in_array($id, $menu_auth);
}
// 获取当前操作的id
$location = MenuModel::getLocation();
$action = end($location);
return $url === false ? isset($menu_auth[$action['id']]) : in_array($action['url_value'], $menu_auth);
}
// 其他情况一律没有权限
return false;
}
/**
* 读取当前角色权限
* @author 路人甲乙
* @return mixed
*/
public function roleAuth()
{
$menu_auth = cache('role_menu_auth_'.session('user_auth.role'));
if (!$menu_auth) {
$menu_auth = self::where('id', session('user_auth.role'))->value('menu_auth');
$menu_auth = json_decode($menu_auth, true);
$menu_auth = MenuModel::where('id', 'in', $menu_auth)->column('id,url_value');
}
// 非开发模式,缓存数据
if (config('develop_mode') == 0) {
cache('role_menu_auth_'.session('user_auth.role'), $menu_auth);
}
return $menu_auth;
}
/**
* 根据节点id获取所有角色id和权限
* @param string $menu_id 节点id
* @param bool $menu_auth 是否返回所有节点权限
* @author 路人甲乙
* @return array
*/
public static function getRoleWithMenu($menu_id = '', $menu_auth = false)
{
if ($menu_auth) {
return self::where('menu_auth', 'like', '%"'.$menu_id.'"%')->column('id,menu_auth');
} else {
return self::where('menu_auth', 'like', '%"'.$menu_id.'"%')->column('id');
}
}
/**
* 根据角色id获取权限
* @param array $role 角色id
* @author 路人甲乙
* @return array
*/
public static function getAuthWithRole($role = [])
{
return self::where('id', 'in', $role)->column('id,menu_auth');
}
/**
* 根据权限id获取角色名称
* @param array $auth 权限id
* @author 路人甲乙
* @return array
*/
public static function getNameWithAuth($auth = [])
{
return self::where('id', 'in', $auth)->column('id,name');
}
}
\ No newline at end of file
<?php
namespace app\admin\model;
use app\admin\model\Attachment;
use think\Model;
use think\facade\Db;
/**
* 后台用户模型
* @package app\admin\model
*/
class Slider extends Model
{
// 设置当前模型对应的完整数据表名称
protected $name = 'cms_slider';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
public static function getList($map=[],$order='',$offset=20)
{
$data_list = self::where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['img_url'] = sysConfig('app_url').getFilePath($item['cover']);
});
return $data_list;
}
/*
* 保存数据
*/
public static function saveData($data)
{
$exist = Attachment::where(['name' => $data['name']])->find();
if($exist){
$data['cover'] = $exist['id'];
$add = self::create($data);
if($add) return true;
}
return false;
}
}
\ No newline at end of file
<?php
namespace app\admin\model;
use think\Model;
use think\facade\Db;
use util\RedisUtil;
/**
* 后台股票列表模型
* @package app\admin\model
*/
class StockList extends Model
{
// 设置当前模型对应的完整数据表名称
protected $name = 'stock_list';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
public static function intStockList($data)
{
if(!$data) return false;
$list = [];
foreach ($data as $key => $item) {
$list[$key]['title'] = $item['name'];
$list[$key]['market'] = $item['market'];
$list[$key]['code'] = $item['code'];
$list[$key]['pinyin'] = $item['pinyin'];
$list[$key]['status'] = 1;
$list[$key]['add_time'] = time();
$list[$key]['edit_time'] = time();
$list[$key]['target_uid'] = 1;
$list[$key]['target_name'] = 'admin';
}
Db::startTrans();
$ret = Db::execute('truncate '. config('database.connections.mysql.prefix').'stock_list');
try {
$res = self::insertAll($list);
if($res){
Db::commit();
return true;
}
} catch (Exception $e) {
Db::rollback();
return false;
}
}
}
\ No newline at end of file
<?php
namespace app\admin\model;
use think\Model;
use app\admin\model\Role as RoleModel;
use app\apicom\model\JWT;
use think\facade\Db;
use util\RedisUtil;
/**
* 后台用户模型
* @package app\admin\model
*/
class User extends Model
{
// 设置当前模型对应的完整数据表名称
protected $name = 'admin_user';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
// 对密码进行加密
public function setPasswordAttr($value)
{
return password_hash(strval($value),PASSWORD_DEFAULT);
}
// 获取注册ip
public function setSignupIpAttr()
{
return getClientIp();
}
/**
* 用户登录
* @param string $username 用户名
* @param string $password 密码
* @param bool $rememberme 记住登录
* @author 路人甲乙
* @return bool|mixed
*/
public static function login($username = '', $password = '', $rememberme = false)
{
$username = trim($username);
$password = trim($password);
// 匹配登录方式
if (preg_match("/^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/", $username)) {
// 邮箱登录
$map['email'] = $username;
} elseif (preg_match("/^1\d{10}$/", $username)) {
// 手机号登录
$map['mobile'] = $username;
} else {
// 用户名登录
$map['username'] = $username;
}
$map['status'] = 1;
// 查找用户
$user = self::where($map)->find()->toArray();
if (!$user) return ['status'=>0, 'message'=>'用户不存在或被禁用'];
// 检查是否分配用户组
if ($user['role'] == 0) {
return ['status'=>0, 'message'=>'禁止访问,原因:未分配角色!'];
}
// 检查是可登录后台
if (!RoleModel::where('id', $user['role'])->value('access')) {
return ['status'=>0, 'message'=>'禁止访问,原因:用户所在角色禁止访问后台!'];
}
//print_r(password_hash($password,PASSWORD_DEFAULT));return;
if ($user && password_verify($password, $user['password'])) {
// 更新登录信息
$user['create_time'] = time();
$user['update_time'] = time();
$user['last_time'] = time();
$user['last_login_ip'] = getClientIp();
if ($res = self::strict(false)->save($user)) {
$token = array(
"aid" => $user['id'],
"pid" => $user['pid'],
"name" => $user['username'],
"nick" => $user['nickname'],
"role" => $user['role'],
'time' => time(),
);
$jwt = JWT::encode($token,LOCAL_TRADING_TOKEN);
RedisUtil::cacheAdminToken($jwt, $token);
$datas['aid'] = $user['id'];
$datas['token'] = $jwt;
$datas['name'] = $user['username'];
$datas['nick'] = $user['nickname'];
// 自动登录
//$login = $this->autoLogin($user, $rememberme);
return ['status'=>1, 'message'=>'登陆成功!','data'=>$datas];
} else {
// 更新登录信息失败
return ['status'=>0, 'message'=>'登录信息更新失败,请重新登录'];
}
} else {
return ['status'=>0, 'message'=>'密码错误!'];
}
}
/**
* 自动登录
* @param object $user 用户对象
* @param bool $rememberme 是否记住登录,默认7天
* @author 路人甲乙
* @return bool|int
*/
public function autoLogin($user, $rememberme = false)
{
// 记录登录SESSION和COOKIES
$auth = array(
'uid' => $user['id'],
'group' => $user['group'],
'role' => $user['role'],
'role_name' => Db::name('admin_role')->where('id', $user['role'])->value('name'),
'avatar' => $user['avatar'],
'username' => $user['username'],
'nickname' => $user['nickname'],
'last_login_time' => $user['last_login_time'],
'last_login_ip' => getClientIp(),
);
session('user_auth', $auth);
session('user_auth_sign', data_auth_sign($auth));
// 保存用户节点权限
if ($user['role'] != 1) {
$menu_auth = Db::name('admin_role')->where('id', session('user_auth.role'))->value('menu_auth');
$menu_auth = json_decode($menu_auth, true);
if (!$menu_auth) {
session('user_auth', null);
session('user_auth_sign', null);
return false;
}
}
// 记住登录
if ($rememberme) {
$signin_token = $user['username'].$user['id'].$user['last_login_time'];
cookie('uid', $user['id'], 24 * 3600 * 7);
cookie('signin_token', data_auth_sign($signin_token), 24 * 3600 * 7);
}
return $user['id'];
}
}
<?php
namespace app\admin\validate;
use think\Validate;
/**
* 用户验证器
* @package app\admin\validate
*/
class AdminUser extends Validate
{
//定义验证规则
protected $rule = [
'username|用户名' => 'require|alphaNum|unique:admin_user',
'nickname|角色名' => 'require',
'role|角色' => 'require',
'email|邮箱' => 'email|unique:admin_user',
'password|密码' => 'require|length:6,20',
'confirm|重复密码'=> 'require|confirm:password',
'mobile|手机号' => 'regex:^1\d{10}|unique:admin_user',
'captcha|验证码' => 'require',
];
//定义验证提示
protected $message = [
'username.require' => '请输入用户名',
'nickname.require' => '请输入角色名',
'email.require' => '邮箱不能为空',
'email.email' => '邮箱格式不正确',
'email.unique' => '该邮箱已存在',
'password.require' => '密码不能为空',
'password.length' => '密码长度6-20位',
'confirm.require' => '请输入确认密码',
'confirm.confirm' => '您两次输入的密码不一致',
'mobile.regex' => '手机号不正确',
'captcha.require' => '验证码不能为空',
];
//定义验证场景
protected $scene = [
//更新
'update' => ['email', 'password' => 'length:6,20', 'mobile', 'role'],
//登录
'signin' => ['username'=>'require', 'password'=>'require', 'captcha'=>'require'],
//新建
'create' => ['username', 'mobile', 'nickname', 'password', 'confirm'],
//编辑
'edit' => ['username', 'mobile', 'nickname'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Bank extends Validate
{
protected $rule = [
'bank_name' => 'require',
'type' => 'require',
'open_bank' => 'require',
'card' => 'require',
];
protected $message = [
'bank_name.require' => '请输入收款银行',
'type.require' => '请选择银行类型',
'open_bank.require' => '请填写开户支行名称',
'card.require' => '请填写银行卡号',
];
/**
* 新增收款银行卡信息的验证
* @return UserBankCard
*/
//定义验证场景
protected $scene = [
'create' => ['bank_name', 'type', 'open_bank','card'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Document extends Validate
{
// 定义验证规则
protected $rule = [
'cid|文档栏目' => 'require',
'title|文档标题' => 'require|length:1,30',
'content|文档内容' => 'require|length:10,9999',
];
//定义验证场景
protected $scene = [
'create' => ['title', 'content', 'cid'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Member extends Validate
{
//定义验证规则
protected $rule = [
'mobile|用户名/手机号' => 'require|regex:^1\d{10}|unique:member',
'name|姓名' => 'require',
'id_card|身份证号码' => 'require|regex:/^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|31)|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}([0-9]|x|X)$/|unique:member',
'passwd|密码' => 'require|regex:^[a-zA-Z\d_]{6,16}$',
'paywd|支付密码' => 'require|regex:^[0-9]{6}',
];
//定义验证提示
protected $message = [
'name.require' => '请输入姓名',
'id_card.require' => '请输入身份证号码',
'id_card.unique' => '身份证已存在',
'id_card.regex' => '身份证格式错误',
'passwd.regex' => '密码格式有误(a-zA-Z0-9_) 6-16个字符',
'paywd.regex' => '支付密码格式有误(0-9)6个字符',
'mobile.regex' => '手机号不正确',
'mobile.unique' => '手机已存在',
'mobile.require' => '请输入手机号',
];
//定义验证场景
protected $scene = [
//更新
'update' => [ 'passwd' => 'length:6,8','mobile'],
'passwd' => [ 'passwd'],
'realname' => [ 'name','id_card'],
// 身份证审核
'update_card' => ['mobile', 'id_card'],
'create' => ['mobile', 'passwd', 'paywd'],
'editMoblie' => ['mobile'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Risk extends Validate
{
//定义验证规则
protected $rule = [
'stockjobber|证券公司' => 'require',
'lid|证券账户' => 'require',
'user|交易账户' => 'require',
'pwd|交易密码' => 'require',
];
//定义验证提示
protected $message = [
'stockjobber.require' => '请输入证券公司',
'lid.require' => '请输入证券账户',
'user.require' => '请输入交易账户',
'pwd.regex' => '请输入账户密码',
];
//定义验证场景
protected $scene = [
'create' => ['stockjobber','lid', 'pwd', 'user'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Slider extends Validate
{
// 定义验证规则
protected $rule = [
'title|标题' => 'require|length:1,30',
'img_url|图片' => 'require',
];
//定义验证场景
protected $scene = [
'create' => ['title', 'img_url'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Stock extends Validate
{
protected $rule = [
'code' => 'require',
'title' => 'require',
'market' => 'require',
'pinyin' => 'require',
];
protected $message = [
'code.require' => '股票代码不能为空',
'title.require' => '股票名称不能为空',
'pinyin.require' => '股票简拼不能为空',
'market.require' => '市场代码不能为空',
];
protected $scene = [
'saveStock' => ['code', 'title', 'market', 'pinyin'],
];
}
<?php
use think\facade\Db;
use app\admin\model\User;
use app\apicom\model\JWT;
use think\request;
use util\RedisUtil;
use util\SystemRedis;
// 这是系统自动生成的公共文件
/*
* 输出JSON
*/
if (!function_exists('ajaxmsg')) {
function ajaxmsg($msg = "", $type = 200,$data = '',$is_end = true)
{
$json['status'] = $type;
if (is_array($msg)) {
foreach ($msg as $key => $v) {
$json[$key] = $v;
}
} elseif (!empty($msg)) {
$json['msg'] = $msg;
}
if($data) $json['data'] = $data;
if ($is_end) {
return json($json);
} else {
return json($json);
}
}
}
if (!function_exists('data_auth_sign')) {
/*
* 数据签名认证
* @param array $data 被认证的数据
* @return string
*/
function data_auth_sign($data = [])
{
// 数据类型检测
if(!is_array($data)){
$data = (array)$data;
}
// 排序
ksort($data);
// url编码并生成query字符串
$code = http_build_query($data);
// 生成签名
$sign = sha1($code);
return $sign;
}
}
<?php
declare (strict_types = 1);
namespace app\agent\controller;
use think\App;
use think\exception\ValidateException;
use think\Validate;
use think\Controller;
use think\facade\Request;
use util\RedisUtil;
/**
* 控制器基础类
*/
abstract class AgentBase
{
/**
* Request实例
* @var \think\Request
*/
protected $request;
/**
* 应用实例
* @var \think\App
*/
protected $app;
/**
* 是否批量验证
* @var bool
*/
protected $batchValidate = false;
/**
* 控制器中间件
* @var array
*/
protected $middleware = [];
// 当前用户的ID
public $userId = 0;
// 当前用户的手机号
public $mobile = '';
// 上级代理商
public $agentId = 0;
// token
public $token = null;
/**
* 设置无需登陆的action
* 格式:[
* '控制器名称(驼峰)' => ['action1', 'action2', ...],
* ...
* ]
*/
protected $noLogin = [
'Index' => ['welcome'],
'Login' => ['index', 'info', 'verify'],
];
/**
* 构造方法
* @access public
* @param App $app 应用对象
*/
public function __construct(App $app)
{
$this->app = $app;
$this->request = $this->app->request;
// 控制器初始化
$this->initialize();
}
// 初始化
public function initialize()
{
$this->token = $this->request->header('Access-Token', '');//['Access-Token'];
$this->agentId = input('uid','');
// 根据token获取用户的数据
if(!$this->agentId || $this->token) $userData = $this->token ? RedisUtil::getToken($this->token) : [];
// 当前用户的ID
if(!$this->agentId || $this->token) $this->agentId = $userData['uid'] ?? '';
// 当前用户的手机号
$this->mobile = isset($userData['mobile']) ? $userData['mobile'] : '';
/**
* @var string $controller 当前控制器
* @var string $action 当前方法(action)
*/
$controller = Request::controller();
$action = Request::action();
// 验证用户是否登录,排除无需登录的action
if (!(isset($this->noLogin[$controller]) && in_array($action, $this->noLogin[$controller]))) {
if ($this->agentId == '') {
if(php_sapi_name() == 'cli'){
//echo json_encode(['uid' => $this->agentId, 'status' => 200, 'msg' => '请登陆'],JSON_UNESCAPED_UNICODE);
return false;
}else{
echo json_encode(['uid' => $this->agentId, 'status' => 200, 'msg' => '请登陆'],JSON_UNESCAPED_UNICODE);
exit;
}
}
}
}
/**
* 验证数据
* @access protected
* @param array $data 数据
* @param string|array $validate 验证器名或者验证规则数组
* @param array $message 提示信息
* @param bool $batch 是否批量验证
* @return array|string|true
* @throws ValidateException
*/
protected function validate(array $data, $validate, array $message = [], bool $batch = false)
{
if (is_array($validate)) {
$v = new Validate();
$v->rule($validate);
} else {
if (strpos($validate, '.')) {
// 支持场景
[$validate, $scene] = explode('.', $validate);
}
$class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
$v = new $class();
if (!empty($scene)) {
$v->scene($scene);
}
}
$v->message($message);
// 是否批量验证
if ($batch || $this->batchValidate) {
$v->batch(true);
}
return $v->failException(true)->check($data);
}
}
<?php
declare (strict_types = 1);
namespace app\agent\controller;
use app\agent\model\AgentUser as AgentModel;
use think\facade\Db;
/**
* 文档控制器
* @package app\apicom\home
*/
class AgentUser extends AgentBase
{
/*
* 获取管理员列表
*/
public function getList()
{
$name = input('name', '');
$mobile = input('mobile', '');
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'id desc';
$where = [];
if(!empty($name)) $where[] = ['username','=', $name];
if(!empty($mobile))$where[] = ['mobile','=', $mobile];
$res = AgentModel::getList($where,$order,$offset);
if($res){
return ajaxmsg('操作成功',200, $res);
}else {
return ajaxmsg('操作失败',0);
}
}
/*
* 启用/禁用 状态
*/
public function doDisable()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$res = AgentModel::where('id', $id)->save(['status'=> $status]);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 删除管理员
*/
public function delAdmin()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$count = AgentModel::count();
//print_r($count);exit;
if($count == 1) return ajaxmsg('最后一个不能删除',0);
Db::startTrans();
$res = AgentModel::where('id', $id)->delete();
if ($res) {
Db::commit();
return ajaxmsg('操作成功',200);
} else {
Db::rollback();
return ajaxmsg('操作失败',0);
}
}
/*
* 修改/新增 管理员
*/
public function editAdmin()
{
$data = input();
if (isset($data['id']) && !empty($data['id'])) {
// 验证数据
$result = $this->validate($data, 'AdminUser.edit');
if ($result !== true) return ajaxmsg($result,0);
if (!empty($data['password'])) $data['password'] = password_hash($data['password'], PASSWORD_DEFAULT);
$res = AgentModel::strict(false)->where(['id'=>$data['id']])->save($data);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
} else {
// 验证数据
$result = $this->validate($data, 'AdminUser.create');
if ($result !== true) return ajaxmsg($result,0);
//print_r($data);exit;
if (AgentModel::saveData($data)) return ajaxmsg('操作成功',200);
return ajaxmsg('操作失败',0);
}
}
}
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\agent\controller;
use app\agent\model\Order as OrderModel;
use app\agent\model\Borrow as BorrowModel;
use think\facade\Db;
use think\facade\App;
use think\facade\Config;
class Index extends AgentBase
{
public function index()
{
$data = [];
//下级配资总数
$borrows = strval(self::getStockBorrow($this->agentId));
//下级持仓总数
$pos_all = strval(self::getPosition($this->agentId));
//累计充值总额
//$r_total = money_convert(Db::name('money_recharge')->where(['status'=>1])->sum('money'));
//累计提现总额
//$w_total = money_convert(Db::name('money_withdraw')->where(['status'=>1])->sum('money'));
//累计操盘余额
//$account = money_convert(Db::name('money')->where('status=1')->sum('operate_account'));
//按天配资
$dayCount = self::getStockBorrow($this->agentId,'1');
//按周配资
$weekCount = self::getStockBorrow($this->agentId,'2');
//按月配资
$monthCount = self::getStockBorrow($this->agentId,'3');
//免费体验
$tryCount = self::getStockBorrow($this->agentId,'4');
//免息配资
$freeCount = self::getStockBorrow($this->agentId,'5');
//模拟操盘
$mockCount = self::getStockBorrow($this->agentId,'6');
//当日注册会员
$m_today = strval(Db::name('member')->where(['is_del'=>0,'agent_far'=>$this->agentId])->whereDay('create_time')->count());
//昨日注册会员
$m_ysday = strval(Db::name('member')->where(['is_del'=>0,'agent_far'=>$this->agentId])->whereDay('create_time','yesterday')->count());
//本周注册会员
$m_weeks = strval(Db::name('member')->where(['is_del'=>0,'agent_far'=>$this->agentId])->whereWeek('create_time')->count());
//本月注册会员
$m_month = strval(Db::name('member')->where(['is_del'=>0,'agent_far'=>$this->agentId])->whereMonth('create_time')->count());
//今年注册会员
$m_years = strval(Db::name('member')->where(['is_del'=>0,'agent_far'=>$this->agentId])->whereYear('create_time')->count());
//注册会员总数
$m_total = strval(Db::name('member')->where(['is_del'=>0,'agent_far'=>$this->agentId])->count());
$data['rowlist'][] = ['name'=>'下级会员总数','value'=>$m_total,'icon'=>'el-icon-user-solid grid-con-1'];
$data['rowlist'][] = ['name'=>'下级配资总数','value'=>$borrows,'icon'=>'el-icon-s-marketing grid-con-2'];
$data['rowlist'][] = ['name'=>'下级持仓总数','value'=>$pos_all,'icon'=>'el-icon-s-custom grid-con-3'];
//$data['rowlist'][] = ['name'=>'累计充值总额','value'=>$r_total,'icon'=>'el-icon-s-finance grid-con-1'];
//$data['rowlist'][] = ['name'=>'累计提现总额','value'=>$w_total,'icon'=>'el-icon-wallet grid-con-2'];
//$data['rowlist'][] = ['name'=>'累计操盘余额','value'=>$account,'icon'=>'el-icon-money grid-con-3'];
$data['borrow']['labels'] = ["按天配资","按周配资","按月配资","免息配资"];
$data['borrow']['datasets'][] = [
'data' => [$dayCount,$weekCount,$monthCount,$freeCount]
];
$data['member']['labels'] = ["当日注册","昨日注册","本周注册","本月注册","今年注册"];
$data['member']['datasets'][] = [
'label' => '注册会员',
'data' => [$m_today,$m_ysday,$m_weeks,$m_month,$m_years]
];
return ajaxmsg('操作成功',200,$data);
}
public function welcome()
{
return ajaxmsg('操作成功',200,$this->request->server());
}
//获取下级配资列表
public function getStockBorrow($agent,$type = '')
{
$where[] = ['m.agent_far' ,'=', $agent];
//$where[] = ['b.status','=','1'];
$borrows = BorrowModel::getBorrowCount($where);
//print_r($borrows);exit;
return $borrows ? $borrows : 0;
}
//获取下级持仓列表
public function getPosition($agent)
{
$where[] = ['m.agent_far' ,'=', $agent];
$position = OrderModel::getOrderCount('position',$where);
return $position ? $position : 0;
}
}
<?php
declare (strict_types = 1);
namespace app\agent\controller;
use app\apicom\model\Member;
use app\apicom\model\JWT;
use think\facade\Session;
use util\Captcha;
use think\facade\Db;
use util\RedisUtil;
class Login extends AgentBase
{
public function index()
{
if (!sysConfig("web_site_status")) return ajaxmsg('站点已经关闭',0);
// 用户参数
$data['mobile'] = input('username', '');
$data['password'] = input('password', '');
// 查询用户
$user = Member::where('mobile', $data['mobile'])->find();
// 是否被禁止登录
if($user) {
if($user['status'] !== 1) return ajaxmsg('禁止登陆',0);
if($user['agent_id'] != 1) return ajaxmsg('不是代理',0);
if(!password_verify($data['password'], $user['passwd'])) return ajaxmsg('密码错误',0);
$datas = self::doLogin($user);
if(!$datas) return ajaxmsg('登录失败',0);
return ajaxmsg('登录成功',200,$datas);
}
return ajaxmsg('手机号或密码错误',0);
}
public function doLogin($user)
{
$ret = Member::where('id',$user['id'])->update(['last_login_time'=>date('Y-m-d H:i:s'),'last_login_ip'=>getClientIp()]);
if($ret){
$token = array(
"uid" => $user['id'],
"name" => $user['name'],
'doHost' => WS_SERVER_IP,
'doTime' => time(),
"mobile" => $user['mobile'],
);
$jwt = JWT::encode($token,LOCAL_TRADING_TOKEN);
RedisUtil::cacheToken($jwt, $token);
$datas['token'] = $jwt;
$datas['mobile'] = $user['mobile'];
$datas['uid'] = $user['id'];
return $datas;
}
return false;
}
/*
* 退出登录
*/
public function signout()
{
if ($this->token != '') {
RedisUtil::deleteToken($this->token);
}
return ajaxmsg('退出登录成功',1);
}
}
<?php
declare (strict_types = 1);
namespace app\agent\controller;
use app\apicom\model\Member as MemberModel;
use app\apicom\model\Record as RecordModel;
use app\apicom\model\Recharge;
use app\apicom\model\Withdraw;
use think\facade\Db;
class Member extends AgentBase
{
public function index()
{
return '您好!';
}
/*
* 获取会员列表
*/
public function getList()
{
$name = input('name', '');
$mobile = input('mobile','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$agent = $this->agentId;
$order = 'id desc';
if(!empty($name)) $where[] = ['a.name' ,'=', $name];
if(!empty($mobile)) $where[] = ['a.mobile','=', $mobile];
if(!empty($agent)) $where[] = ['a.agent_far','=', $agent];
$where[] = ['a.is_del' ,'=', 0];
$data_list = MemberModel::view('member a')
->view('money b','account,freeze,operate_account,bond_account','a.id=b.mid')
->where($where)
->order($order)
->paginate($offset, false, ['query' => request()->param()]);
if(!$data_list) return ajaxmsg('没有数据',0);
return ajaxmsg('操作成功',200,$data_list);
}
/*
* 禁用会员
*/
public function doDisable()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
if($status == '') return ajaxmsg('缺少参数',0);
$where[] = ['id' ,'=', $id];
$where[] = ['agent_far' ,'=', $this->agentId];
$res = MemberModel::where($where)->save(['status'=> $status]);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 新增会员
*/
public function addMember()
{
$data = input();
$data['agent_far']= $this->agentId;
//print_r($data);exit;
// 验证数据
$result = $this->validate($data, 'Member.create');
if ($result !== true) return ajaxmsg($result,0);
if (empty($data['mobile']))
return ajaxmsg('请输入您的手机号!',0);
$userExist = MemberModel::where('mobile|name', '=', $data['mobile'])->column('mobile', 'id');
if ($userExist)
return ajaxmsg('该手机号已经注册',0);
if (!in_array(strlen($data['mobile']), [8, 9, 11]))
return ajaxmsg('您输入的手机号码有误!',0);
$res = MemberModel::saveData($data);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 编辑用户
*/
public function editMember()
{
$data = input();
$data['agent_id'] = $data['agent_id'];
$data['status'] = $data['status'];
$data['agent_far']= $this->agentId;
if(isset($data['agent_far'][0])){
$data['agent_far'] = $data['agent_pro'] = $data['agent_far'][0];
}else{
$data['agent_far'] = $data['agent_pro'] = 0;
}
if($data['passwd']) $data['passwd'] = password_hash($data['passwd'], PASSWORD_DEFAULT);
if($data['paywd'] ) $data['paywd'] = password_hash($data['paywd'] , PASSWORD_DEFAULT);
if (empty($data['id'])) return ajaxmsg('缺少ID参数!',0);
if (empty($data['passwd'])) unset($data['passwd']);
if (empty($data['paywd'])) unset($data['paywd']);
//print_r($data);exit;
$res = MemberModel::strict(false)->where(['id'=>$data['id']])->save($data);
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
}
<?php
declare (strict_types = 1);
namespace app\agent\controller;
use app\apicom\model\Money as MoneyModel;
use app\apicom\model\Member as MemberModel;
use app\apicom\model\Record as RecordModel;
use app\apicom\model\Recharge;
use app\apicom\model\Withdraw;
use app\admin\model\Money as AdminBank;
use think\facade\Db;
class Money extends AgentBase
{
/*
* 获取资金明细
*/
public function getMoneyRecord()
{
$name = input('name', '');
$mobile = input('mobile','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'create_time desc';
if(!empty($name)) $where[] = ['m.name' ,'=', $name];
if(!empty($mobile)) $where[] = ['m.mobile' ,'=', $mobile];
$where[] = ['m.is_del' ,'=', 0];
$where[] = ['m.agent_far' ,'=', $this->agentId];
$res = RecordModel::getAll($where,$order,$offset);
if(!$res) return ajaxmsg('没有数据',0);
return ajaxmsg('操作成功',200,$res);
}
}
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\agent\controller;
use app\admin\model\Order as OrderModel;
use app\apicom\model\Borrow as BorrowModel;
use think\facade\Db;
use util\RedisUtil;
class Order extends AgentBase
{
/*
* 获取订单列表
*/
public function getOrderList()
{
$path = input('path','');
$name = input('name','');
$code = input('code','' , ['trim', FILTER_SANITIZE_NUMBER_INT]);
$subid = input('subid','' , ['trim', FILTER_SANITIZE_NUMBER_INT]);
$mobile = input('mobile','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'id desc';
$where[] = ['m.agent_far' ,'=', $this->agentId];
if(!$path) return ajaxmsg('缺少参数',0);
if(!empty($name)) $where[] = ['m.name','=', $name];
if(!empty($code)) $where[] = ['s.gupiao_code','=', $code];
if(!empty($subid)) $where[] = ['sub.sub_account','=', $subid];
if(!empty($mobile))$where[] = ['m.mobile','=', $mobile];
$data_list = OrderModel::getAllList($path,$where,$order,$offset);
if(!$data_list) return ajaxmsg('没有数据',0);
return ajaxmsg('操作成功',200,$data_list);
}
/*
* 修改新股申购
*/
public function doIpoEdit()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status','');
$res = Db::name('stock_trust_ipo')->where(['id'=>$id,'status'=>'申购中'])->save(['status'=> $status]);
//这里要做委托和撤单判断
if ($res) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/*
* 强制平仓
*/
public function handleClose()
{
if(!checkTradeTime()) return ajaxmsg('非交易时间',0);
$data = [
"subid" => input('sub_id',''),//子账户ID,
"code" => input('gupiao_code' ,''),//股票代码
"name" => input('gupiao_name' ,''),//股票名称
"market" => input('market',''),//交易所代码
"count" => input('canbuy_count' , 0),//买卖数量
'model' => input('model' , 2),//1:是委托状态
];
$price = input('now_price',0);//手动设置价格
$res = BorrowModel::saveSell($data,$sys=1,$price);
//return $res;
if(isset($res['status'])){
if(!$res['status']) return ajaxmsg($res['message'],0);
return ajaxmsg('强平操作成功!',200);
}else{
return ajaxmsg('操作失败!',0);
}
}
}
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\admin\controller;
use think\facade\Db;
use util\RedisUtil;
class Report extends AdminBase
{
public function index()
{
//会员数量统计
$data[] = self::MemberReport();
//充值提现统计
$data[] = self::MoneyReport();
//股票持仓统计
$data[] = self::StocksReport();
//配资管理统计
$data[] = self::BorrowReport();
return ajaxmsg('操作成功',200,$data);
}
//会员数量统计
public function MemberReport()
{
$data = [
'title' => '会员数量统计',
'infos' => [
[ 'name' => '注册会员总数', 'value' => Db::name('member')->where(['is_del'=>0])->count() ],
[ 'name' => '一级代理总数', 'value' => Db::name('member')->where(['status'=>1,'agent_id'=>2])->count() ],
[ 'name' => '二级代理总数', 'value' => Db::name('member')->where(['status'=>1,'agent_id'=>3])->count() ],
[ 'name' => '三级代理总数', 'value' => Db::name('member')->where(['status'=>1,'agent_id'=>4])->count() ],
[ 'name' => '当前代理总数', 'value' => Db::name('member')->where('agent_id','>',0)->where('status',1)->count() ]
]
];
return $data ?? [];
}
//充值提现统计
public function MoneyReport()
{
$data = [
'title' => '充值提现统计',
'infos' => [
[ 'name' => '累计充值总额', 'value' => money_convert(Db::name('money_recharge')->where('status','1')->sum('money')) ],
[ 'name' => '今日充值金额', 'value' => money_convert(Db::name('money_recharge')->where('status','1')->whereDay('create_time')->sum('money')) ],
[ 'name' => '累计提现总额', 'value' => money_convert(Db::name('money_withdraw')->where('status','1')->sum('money'))],
[ 'name' => '今日提现金额', 'value' => money_convert(Db::name('money_withdraw')->where('status','1')->whereDay('create_time')->sum('money')) ],
]
];
return $data ?? [];
}
//股票持仓统计
public function StocksReport()
{
$position = self::position();
$data = [
'title' => '股票持仓统计',
'infos' => [
[ 'name' => '持仓股票总额', 'value' => round($position['Total'],2) ],
[ 'name' => '今日委托金额', 'value' => money_convert(Db::name('stock_trust')->whereDay('trust_date')->sum('amount')) ],
[ 'name' => '今日委托总数', 'value' => Db::name('stock_trust')->whereDay('trust_date')->count()],
[ 'name' => '今日成交金额', 'value' => money_convert(Db::name('stock_deal_stock')->whereDay('deal_date')->where('status','<>','0')->sum('amount')) ],
[ 'name' => '今日成交总数', 'value' => Db::name('stock_deal_stock')->whereDay('deal_date')->where('status','<>','0')->count() ],
[ 'name' => '持仓盈亏总额', 'value' => round($position['Profit'],2) ],
]
];
return $data ?? [];
}
//配资管理统计
public function BorrowReport()
{
$data = [
'title' => '配资管理统计',
'infos' => [
[ 'name' => '累计总管理费', 'value' => money_convert(Db::name('stock_borrow')->where('status','>=',1)->sum('borrow_interest')) ],
[ 'name' => '累计返佣金额', 'value' => round(Db::name('agents_back_money')->sum('affect'), 2) ],
[ 'name' => '保证金总金额', 'value' => money_convert(Db::name('stock_borrow')->where(['status'=>1])->sum('deposit_money')) ],
[ 'name' => '总追加保证金', 'value' => money_convert(Db::name('stock_addmoney')->where(['status'=>1])->sum('money')) ],
[ 'name' => '累计提盈总额', 'value' => round(Db::name('stock_drawprofit ')->where(['status'=>1])->sum('money'),2) ],
[ 'name' => '累计操盘总额', 'value' => money_convert(Db::name('money')->where('status=1')->sum('operate_account')) ],
]
];
return $data ?? [];
}
/*********************************************************************/
public function position()
{
//持仓总额
$Total = $Profit = 0;
$Stock = Db::name('stock_position')->where('stock_count','>',0)->where(['buying'=>0])->select();
foreach ($Stock as $k=>$v){
//查询股票最新行情
$Qdata = RedisUtil::getQuotationData($v["gupiao_code"],$v["market"],true);
$Price = $Qdata['Price'] ?: 0;
//持仓总额
$Total += ($v['stock_count']*$Price);
//盈亏总额
$Profit += round(($Price-self::calculate($v["gupiao_code"],'average'))*$v['stock_count'], 2);
}
return ['Total'=>$Total,'Profit'=>$Profit];
}
public function calculate($code,$variable)
{
if(!$code || !$variable) return 0;
switch ($variable) {
case 'price':
$order = Db::name('stock_delivery_order')->where(['gupiao_code' => $code,'status' => 1,'business_name' => '证券买入']);
$amount = $order->sum('liquidation_amount');
$volume = $order->sum('volume');
$result = bcdiv(strval($amount),strval($volume),3);
break;
case 'average':
$order = Db::name('stock_delivery_order')->where(['gupiao_code' => $code,'status' => 1,'business_name' => '证券买入']);
$amount = $order->sum('residual_quantity');
$volume = $order->sum('volume');
$result = bcdiv(strval($amount),strval($volume),3);
break;
default:
$result = 0;
break;
}
return $result;
}
}
\ No newline at end of file
<?php
declare (strict_types = 1);
namespace app\agent\controller;
use app\apicom\model\StockAccount;
use app\apicom\model\Stock as StockModel;
use app\apicom\model\Borrow as BorrowModel;
use app\apicom\model\SubAccount;
use app\apicom\model\SubAccountMoney;
use app\apicom\model\Renewal;
use app\admin\model\StockList;
use think\facade\Db;
use util\RedisUtil;
class Risk extends AgentBase
{
public function index()
{
return '您好!';
}
/******************************************************************************************************************************/
/*
* 获取配资列表
*/
public function getBorrowList()
{
$name = input('name', '');
$mobile = input('mobile','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$orderid = input('orderid','',['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status','');
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$where[] = ['member.agent_far' ,'=', $this->agentId];
$order = 'b.create_time desc';
$stat_n = ['全部'=>'','待审核'=>-1,'未通过'=>0,'使用中'=>1,'已结束'=>2,'已逾期'=>3];
if($status && isset($stat_n[$status]) && $stat_n[$status]!=='') $where[] = ['b.status','=',$stat_n[$status]];
if(!empty($name)) $where[] = ['member.name' ,'=', $name];
if(!empty($mobile)) $where[] = ['member.mobile','=', $mobile];
if(!empty($orderid))$where[] = ['b.order_id','=', $orderid];
$data_list = BorrowModel::getListAll($where,$order,$offset);
if(!$data_list) return ajaxmsg('没有数据',0);
return ajaxmsg('操作成功',200,$data_list);
}
/*
* 获取子账户列表
*/
public function getSubList()
{
$subcode = input('subcode','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status' ,'');
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'id asc';
$where = [];
if(!empty($subcode)) $where[] = ['sub_account','=', $subcode];
$data_list = SubAccount::getAllList($where,$order,$offset);
if(!$data_list) return ajaxmsg('没有数据',0);
return ajaxmsg('操作成功',200,$data_list);
}
/*
* 修改子账户列表
*/
public function editSubList()
{
$data = input();
$count = $data['nums'] > 100 ? 100 : $data['nums'];
$subAccount = Db::name('stock_subaccount')->order('id desc')->value('sub_account') ?? 60753103;
for ($i = 0 ; $i < $count; $i ++) {
$datas[] = [
'uid' => null,
'sub_account' => $subAccount+$i+1,
'sub_pwd' => '123456',
'agent_id' => 1,
'account_id' => $data['account_id'][0],
'create_time' => time(),
];
}
//print_r($datas);exit;
Db::startTrans();
$sub = Db::name('stock_subaccount')->insertAll($datas);
if($sub){
Db::commit();
return ajaxmsg('操作成功',200);
}
Db::rollback();
return ajaxmsg('操作失败',0);
}
/*
* 通过账户号码获取子账户完整数据
*/
public function getSubInfo()
{
$sub = input('sub','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
if(empty($sub)) return ajaxmsg('缺少SUBID参数',0);
$where = ['s.sub_account' => $sub];
$data = SubAccount::getSubInfo($where);
if(!$data) return ajaxmsg('没有数据',0);
return ajaxmsg('操作成功',200,$data);
}
/*
* 修改子账号数据 并一起修改配资列表的对应设置
*/
public function editSubInfo()
{
$data = input();
if(empty($data['id'])) return ajaxmsg('缺少ID参数',0);
$risk = [
'loss_warn' => $data['loss_warn'] ?? '50.00',
'loss_close' => $data['loss_close'] ?? '20.00',
'position' => $data['position'] ?? 100,
'prohibit_open' => $data['prohibit_open'],
'prohibit_close' => $data['prohibit_close'],
'prohibit_back' => $data['prohibit_back'],
'renewal' => $data['renewal'],
'autoclose' => $data['autoclose'],
'update_time' => time(),
];
$borrow = [
'loss_warn' => $data['loss_warn'] ?? '50.00',
'loss_close' => $data['loss_close'] ?? '20.00',
'position' => $data['position'] ?? 100,
];
Db::startTrans();
$res = Db::name('stock_subaccount_risk')->where(['stock_subaccount_id' => $data['id']])->update($risk);
$bor = Db::name('stock_borrow')->where(['stock_subaccount_id' => $data['id']])->update($borrow);
if($res && $bor){
Db::commit();
return ajaxmsg('操作成功',200);
}
Db::rollback();
return ajaxmsg('操作失败',0);
}
/*
* 删除子账户
*/
public function delSubac()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$sub = SubAccount::where('id', $id)->find();
if(empty($sub)) return ajaxmsg('查询失败',0);
$bor = Db::name('stock_borrow')->where(['stock_subaccount_id' => $sub['id']])->where('status','in',[1,3])->find();
if ($bor) {
return ajaxmsg('操作失败,该子账户下有配资未清空',0);
}
$result = SubAccount::where('id', $id)->delete();
if ($result) {
return ajaxmsg('操作成功',200);
} else {
return ajaxmsg('操作失败',0);
}
}
/******************************************************************************************************************************/
/*
* 获取配资审核列表
*/
public function getAuditList()
{
$path = input('path','');
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'id desc';
$where = [];
if(!$path) return ajaxmsg('缺少参数',0);
$data_list = BorrowModel::getAuditAll($path,$where,$order,$offset);
if(!$data_list) return ajaxmsg('没有数据',0);
return ajaxmsg('操作成功',200,$data_list);
}
/*
* 人工审核提前终止操盘
*/
public function editStopBorr()
{
$id = input('id','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$status = input('status','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
if(!$id || $status == '') return ajaxmsg('缺少参数',0);
$info = !empty($id) ? Renewal::getStopById($id) : 0;
if(!$info) return ajaxmsg('没有申请记录',0);
//*******************下面操作终止操盘审核*******************//
if($status == 1){
//检测配资申请和持仓情况
$check_res = BorrowModel::checkApply($info['borrow_id'],$info['uid'],$info['stock_subaccount_id']);
if($check_res['status'] === 0) return ajaxmsg($check_res['msg'],0);
//检测子账户资金情况
$submoney_info = SubaccountMoney::getMoneyByID($info['stock_subaccount_id']);
if($submoney_info['freeze_amount'] > 0.1){
return ajaxmsg('该子账户还有资金未解冻,请等资金解冻后再审核',0);
}
$surplus_money = $submoney_info['avail'];//返回的可用余额
$addmoney = $submoney_info['stock_addmoney'];//累计追加保证金
$drawprofit = $submoney_info['stock_drawprofit'];//累计提取盈利
$ret = Renewal::saveStop($id,$status,$info,$surplus_money,$addmoney,$drawprofit);
}
if($ret['status'] == 1){
return ajaxmsg("审核成功!",200);
}else{
return ajaxmsg("审核失败!",0);
}
}
/*
* 修正子账户冻结金额和可用于我等信息
*/
public function editBorrowAmount()
{
$data = input();
$status = input('status','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
if(empty($data['id'])) return ajaxmsg('缺少ID参数',0);
//$status = 1 为解冻到可用余额,$status = 0 为直接抹除冻结资金
$risk = [
'freeze_amount' => '0.00',
'avail' => $status == 1 ? $data['avail'] + $data['freeze_amount'] : $data['avail'],
];
//print_r($risk);exit;
Db::startTrans();
$res = Db::name('stock_subaccount_money')->where(['id' => $data['id']])->update($risk);
if($res){
Db::commit();
return ajaxmsg('操作成功',200);
}
Db::rollback();
return ajaxmsg('操作失败',0);
}
/*
* 查询配资子账户交易明细
*/
public function getSubRecord()
{
$name = input('name', '');
$mobile = input('mobile','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$account = input('account','', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$offset = input('pageSize',20, ['trim', FILTER_SANITIZE_NUMBER_INT]);
$order = 'r.create_time desc';
if(!empty($name)) $where[] = ['m.name' ,'=', $name];
if(!empty($mobile)) $where[] = ['m.mobile' ,'=', $mobile];
if(!empty($account)) $where[] = ['s.sub_account ' ,'=', $account];
$where[] = ['s.status' ,'=', 1];
$data_list = SubAccount::getSubRecordList($where,$order,$offset);
if(!$data_list) return ajaxmsg('没有数据',0);
return ajaxmsg('操作成功',200,$data_list);
}
}
\ No newline at end of file
<?php
// 这是系统自动生成的event定义文件
return [
];
<?php
// 这是系统自动生成的middleware定义文件
return [
// Session初始化
\think\middleware\SessionInit::class,
//跨域请求
\think\middleware\AllowCrossDomain::class,
];
<?php
namespace app\agent\model;
use think\facade\Db;
use think\Model;
use think\Exception;
/**
* 配资管理模型
*/
class Borrow extends Model
{
// 设置当前模型对应的完整数据表名称
protected $name = 'stock_borrow';
public static function getBorrowCount($map=[])
{
//print_r($map);exit;
$counts = self::view('stock_borrow b', true)
->view('member m', 'mobile,name', 'm.id=b.member_id', 'left')
->view('stock_subaccount s','sub_account','s.id=b.stock_subaccount_id','left')
->view('st_stock_subaccount_money sm','avail,freeze_amount,return_money,stock_addfinancing,stock_addmoney','sm.stock_subaccount_id=b.stock_subaccount_id','left')
->where($map)
->count();
return $counts;
}
}
<?php
namespace app\agent\model;
use app\apicom\model\StockPosition;
use think\Model;
use think\facade\Db;
use util\RedisUtil;
/**
* 后台用户模型
* @package app\admin\model
*/
class Order extends Model
{
// 交割订单状态获取器
public static function getStatusName($value)
{
$status = ['0'=>'未交割','1'=>'已交割'];
return $status[$value];
}
/*
* 获取 持仓*委托*成交*撤单*交割 数量
*/
public static function getOrderCount($path,$map=[])
{
switch ($path) {
case 'position':
$data_count = Db::view('stock_position s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where($map)
->where('s.stock_count','>',0)
->count();
break;
case 'trust':
$data_count = Db::view('stock_trust s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where('s.status','<>','已撤')
->where($map)
->count();
break;
case 'deal':
$data_count = Db::view('stock_deal_stock s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where($map)
->count();
break;
case 'cancel':
$data_count = Db::view('stock_trust s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where('s.status','=','已撤')
->where($map)
->count();
break;
case 'delivery':
$data_count = Db::view('stock_delivery_order s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where($map)
->count();
break;
case 'ipolist':
$data_count = Db::view('stock_trust_ipo s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where('s.status','<>','')
->where($map)
->count();
break;
default:
$data_count = [];
break;
}
return $data_count;
}
/*
* 获取 持仓*委托*成交*撤单*交割 列表
*/
public static function getAllList($path,$map=[],$order='',$offset=20)
{
switch ($path) {
case 'position':
$data_list = Db::view('stock_position s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where($map)
->where('s.stock_count','>',0)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
return self::getMarketValue($item);
});
break;
case 'trust':
$data_list = Db::view('stock_trust s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where('s.status','<>','已撤')
->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['trust_count'] = intval($item['trust_count']);
$item['add_time'] = date('Y-m-d H:i:s' ,$item['add_time']);
return $item;
});
break;
case 'deal':
$data_list = Db::view('stock_deal_stock s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['trust_count'] = intval($item['trust_count']);
return $item;
});
break;
case 'cancel':
$data_list = Db::view('stock_trust s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where('s.status','=','已撤')
->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['trust_count'] = intval($item['trust_count']);
$item['add_time'] = date('Y-m-d H:i:s' ,$item['add_time']);
return $item;
});
break;
case 'delivery':
$data_list = Db::view('stock_delivery_order s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['status_n'] = self::getStatusName($item['status']);
//$item['add_time'] = date('Y-m-d H:i:s' ,$item['add_time']);
return $item;
});
break;
case 'ipolist':
$data_list = Db::view('stock_trust_ipo s',true)
->view('stock_subaccount sub', 'sub_account', 'sub.id=s.sub_id', 'left')
->view('member m', 'mobile,name', 'm.id=sub.uid', 'left')
->where('s.status','<>','')
->where($map)
->order($order)
->paginate($offset, false, ['query' => request()->param()])
->each( function($item, $key){
$item['trust_count'] = intval($item['trust_count']);
$item['add_time'] = date('Y-m-d H:i:s' ,$item['add_time']);
return $item;
});
break;
default:
$data_list = [];
break;
}
return $data_list;
}
public static function getMarketValue($item=[]) { //查询股票最新行情
$Qdata = RedisUtil::getQuotationData($item["gupiao_code"],$item["market"],true);
//提取当前价格
$item['now_price'] = $Qdata['Price'] ?: 0;
//市值 = 当前价格*数量
$item['market_value'] = round($item['now_price']*$item['stock_count'], 2);
//参考成本价
$item['ck_price'] = StockPosition::calculate($item['sub_id'],$item["gupiao_code"],'price');
//买入均价
$item['buy_average_price'] = StockPosition::calculate($item['sub_id'],$item["gupiao_code"],'average');
//参考盈亏
$item['ck_profit'] = $item['stock_count'] > 0 ? bcmul(strval($item['now_price']-$item['buy_average_price']),strval($item['stock_count']),2) : 0;
//盈亏比例
$item['profit_rate'] = $item['stock_count'] > 0 ? bcdiv(strval($item['ck_profit']),strval($item['buy_average_price']*$item['stock_count']*100),2) : 0;
//当天可卖数量计算
$item['canbuy_count'] = StockPosition::getCanbuyCount($item['sub_id'],$item["gupiao_code"]);
return $item;
}}
\ No newline at end of file
<?php
namespace app\agent\validate;
use think\Validate;
/**
* 用户验证器
* @package app\agent\validate
*/
class AgentUser extends Validate
{
//定义验证规则
protected $rule = [
'username|用户名' => 'require|alphaNum|unique:admin_user',
'nickname|角色名' => 'require',
'role|角色' => 'require',
'email|邮箱' => 'email|unique:admin_user',
'password|密码' => 'require|length:6,20',
'confirm|重复密码'=> 'require|confirm:password',
'mobile|手机号' => 'regex:^1\d{10}|unique:admin_user',
'captcha|验证码' => 'require',
];
//定义验证提示
protected $message = [
'username.require' => '请输入用户名',
'nickname.require' => '请输入角色名',
'email.require' => '邮箱不能为空',
'email.email' => '邮箱格式不正确',
'email.unique' => '该邮箱已存在',
'password.require' => '密码不能为空',
'password.length' => '密码长度6-20位',
'confirm.require' => '请输入确认密码',
'confirm.confirm' => '您两次输入的密码不一致',
'mobile.regex' => '手机号不正确',
'captcha.require' => '验证码不能为空',
];
//定义验证场景
protected $scene = [
//更新
'update' => ['email', 'password' => 'length:6,20', 'mobile', 'role'],
//登录
'signin' => ['username'=>'require', 'password'=>'require', 'captcha'=>'require'],
//新建
'create' => ['username', 'mobile', 'nickname', 'password', 'confirm'],
//编辑
'edit' => ['username', 'mobile', 'nickname'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Bank extends Validate
{
protected $rule = [
'bank_name' => 'require',
'type' => 'require',
'open_bank' => 'require',
'card' => 'require',
];
protected $message = [
'bank_name.require' => '请输入收款银行',
'type.require' => '请选择银行类型',
'open_bank.require' => '请填写开户支行名称',
'card.require' => '请填写银行卡号',
];
/**
* 新增收款银行卡信息的验证
* @return UserBankCard
*/
//定义验证场景
protected $scene = [
'create' => ['bank_name', 'type', 'open_bank','card'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Document extends Validate
{
// 定义验证规则
protected $rule = [
'cid|文档栏目' => 'require',
'title|文档标题' => 'require|length:1,30',
'content|文档内容' => 'require|length:10,9999',
];
//定义验证场景
protected $scene = [
'create' => ['title', 'content', 'cid'],
];
}
<?php
namespace app\agent\validate;
use think\Validate;
class Member extends Validate
{
//定义验证规则
protected $rule = [
'mobile|用户名/手机号' => 'require|regex:^1\d{10}|unique:member',
'name|姓名' => 'require',
'id_card|身份证号码' => 'require|regex:/^[1-9][0-9]{5}(19|20)[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|31)|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}([0-9]|x|X)$/|unique:member',
'passwd|密码' => 'require|regex:^[a-zA-Z\d_]{6,16}$',
'paywd|支付密码' => 'require|regex:^[0-9]{6}',
];
//定义验证提示
protected $message = [
'name.require' => '请输入姓名',
'id_card.require' => '请输入身份证号码',
'id_card.unique' => '身份证已存在',
'id_card.regex' => '身份证格式错误',
'passwd.regex' => '密码格式有误(a-zA-Z0-9_) 6-16个字符',
'paywd.regex' => '支付密码格式有误(0-9)6个字符',
'mobile.regex' => '手机号不正确',
'mobile.unique' => '手机已存在',
'mobile.require' => '请输入手机号',
];
//定义验证场景
protected $scene = [
//更新
'update' => [ 'passwd' => 'length:6,8','mobile'],
'passwd' => [ 'passwd'],
'realname' => [ 'name','id_card'],
// 身份证审核
'update_card' => ['mobile', 'id_card'],
'create' => ['mobile', 'passwd', 'paywd'],
'editMoblie' => ['mobile'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Risk extends Validate
{
//定义验证规则
protected $rule = [
'stockjobber|证券公司' => 'require',
'lid|证券账户' => 'require',
'user|交易账户' => 'require',
'pwd|交易密码' => 'require',
];
//定义验证提示
protected $message = [
'stockjobber.require' => '请输入证券公司',
'lid.require' => '请输入证券账户',
'user.require' => '请输入交易账户',
'pwd.regex' => '请输入账户密码',
];
//定义验证场景
protected $scene = [
'create' => ['stockjobber','lid', 'pwd', 'user'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Slider extends Validate
{
// 定义验证规则
protected $rule = [
'title|标题' => 'require|length:1,30',
'img_url|图片' => 'require',
];
//定义验证场景
protected $scene = [
'create' => ['title', 'img_url'],
];
}
<?php
namespace app\admin\validate;
use think\Validate;
class Stock extends Validate
{
protected $rule = [
'code' => 'require',
'title' => 'require',
'market' => 'require',
'pinyin' => 'require',
];
protected $message = [
'code.require' => '股票代码不能为空',
'title.require' => '股票名称不能为空',
'pinyin.require' => '股票简拼不能为空',
'market.require' => '市场代码不能为空',
];
protected $scene = [
'saveStock' => ['code', 'title', 'market', 'pinyin'],
];
}
<?php
// 引入常量定义
include_once dirname(__DIR__) . DIRECTORY_SEPARATOR . 'define.php';
use think\facade\Db;
use util\RedisUtil;
use util\SystemRedis;
// 应用公共文件
/*
* 输出JSON
*/
if (!function_exists('ajaxmsg')) {
function ajaxmsg($msg = "", $type = 1,$data = '',$is_end = true)
{
$json['status'] = $type.'';
if (is_array($msg)) {
foreach ($msg as $key => $v) {
$json[$key] = $v;
}
} elseif (!empty($msg)) {
$json['message'] = $msg;
}
if($data) $json['data'] = $data;
if ($is_end) {
return json($json);
} else {
return json($json);
}
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?php
declare (strict_types = 1);
namespace app\apicom\controller;
use app\apicom\model\Column as ColumnModel;
use app\apicom\model\Document as DocumentModel;
use think\facade\Db;
/**
* 文档控制器
* @package app\apicom\home
*/
class Document extends BaseController
{
/**
* 文档详情页
* @param null $id 文档id
* @param string $model 独立模型id
* @author 路人甲乙
* @return mixed
*/
public function detail($id = null, $model = '')
{
$id = input('id', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
$model = input('model', '', ['trim', FILTER_SANITIZE_NUMBER_INT]);
if (!$id || !$model) return ajaxmsg("缺少参数",0);
// 获取文章内容
$info = DocumentModel::getOne($id, $model);
return ajaxmsg('获取成功',1,$info);
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
<?php
// 这是系统自动生成的event定义文件
return [
];
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment