提交服务端基础框架
This commit is contained in:
1
Server/application/.htaccess
Executable file
1
Server/application/.htaccess
Executable file
@@ -0,0 +1 @@
|
||||
deny from all
|
||||
72
Server/application/api/controller/BaseController.php
Normal file
72
Server/application/api/controller/BaseController.php
Normal file
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
use think\Controller;
|
||||
|
||||
class BaseController extends Controller {
|
||||
|
||||
/**
|
||||
* 令牌
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
protected $token = NULL;
|
||||
|
||||
protected function initialize() {
|
||||
parent::initialize();
|
||||
|
||||
// 允许跨域
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: *');
|
||||
header('Access-Control-Allow-Headers: *');
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口调用成功 JSON
|
||||
*
|
||||
* @param null $data
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
protected function jsonSucc($data = NULL) {
|
||||
return json([
|
||||
'code' => 0,
|
||||
'msg' => '操作成功',
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口调用错误 JSON
|
||||
*
|
||||
* @param $error
|
||||
* @param int $code
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
protected function jsonFail($error, $code = 500) {
|
||||
return json([
|
||||
'code' => $code,
|
||||
'msg' => $error,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取URL
|
||||
*
|
||||
* @param $url
|
||||
* @return string
|
||||
*/
|
||||
protected function absoluteUrl($url) {
|
||||
return (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . ($url{0} === '/' ? $url : '/' . $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 小数格式化
|
||||
*
|
||||
* @param $float
|
||||
* @return float
|
||||
*/
|
||||
protected function floatFormat($float) {
|
||||
return floatval($float);
|
||||
}
|
||||
}
|
||||
10
Server/application/api/controller/BaseLoginController.php
Normal file
10
Server/application/api/controller/BaseLoginController.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace app\api\controller;
|
||||
|
||||
class BaseLoginController extends BaseController {
|
||||
|
||||
protected function initialize() {
|
||||
parent::initialize();
|
||||
}
|
||||
}
|
||||
128
Server/application/backend/controller/BaseController.php
Executable file
128
Server/application/backend/controller/BaseController.php
Executable file
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\UserModel;
|
||||
use app\common\model\UserTokenModel;
|
||||
use think\Controller;
|
||||
|
||||
class BaseController extends Controller {
|
||||
|
||||
/**
|
||||
* 用户对象
|
||||
*
|
||||
* @var UserModel
|
||||
*/
|
||||
protected $userModel = NULL;
|
||||
|
||||
/**
|
||||
* 令牌对象
|
||||
*
|
||||
* @var UserTokenModel
|
||||
*/
|
||||
protected $tokenModel = NULL;
|
||||
|
||||
/**
|
||||
* 令牌
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $token = '';
|
||||
|
||||
protected function initialize() {
|
||||
parent::initialize();
|
||||
// 允许跨域
|
||||
header('Access-Control-Allow-Origin: *');
|
||||
header('Access-Control-Allow-Methods: *');
|
||||
header('Access-Control-Allow-Headers: *');
|
||||
|
||||
$this->token = !empty($_SERVER['HTTP_TOKEN'])
|
||||
? trim($_SERVER['HTTP_TOKEN'])
|
||||
: trim($this->request->param('token'));
|
||||
if (!empty($this->token)) {
|
||||
$this->tokenModel = UserTokenModel::get(['token' => $this->token]);
|
||||
if (!empty($this->tokenModel)) {
|
||||
$this->userModel = UserModel::get($this->tokenModel->user_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会员JSON
|
||||
*
|
||||
* @param UserModel $model
|
||||
* @return array
|
||||
*/
|
||||
protected function userJson(UserModel $model) {
|
||||
return array_merge($model->toArray(), [
|
||||
'password' => '',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口调用成功 JSON
|
||||
*
|
||||
* @param null $data
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function jsonSucc($data = NULL) {
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '操作成功',
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接口调用错误 JSON
|
||||
*
|
||||
* @param $error
|
||||
* @param int $code
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function jsonFail($error, $code = 500) {
|
||||
return json([
|
||||
'code' => $code,
|
||||
'msg' => $error,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取URL
|
||||
*
|
||||
* @param $url
|
||||
* @return string
|
||||
*/
|
||||
protected function absoluteUrl($url) {
|
||||
return (!empty($_SERVER['HTTPS']) ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST'] . ($url{0} === '/' ? $url : '/' . $url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 小数格式化
|
||||
*
|
||||
* @param $float
|
||||
* @return float
|
||||
*/
|
||||
protected function floatFormat($float) {
|
||||
return floatval($float);
|
||||
}
|
||||
|
||||
/**
|
||||
* 关联数组转列表
|
||||
*
|
||||
* @param array $assoc
|
||||
* @param string $valueKey
|
||||
* @param string $labelKey
|
||||
* @return array
|
||||
*/
|
||||
protected function assocToList(array $assoc, $valueKey = 'value', $labelKey = 'label') {
|
||||
$list = [];
|
||||
foreach ($assoc as $value => $label) {
|
||||
$list[] = [
|
||||
$valueKey => $value,
|
||||
$labelKey => $label,
|
||||
];
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
class BaseLoginController extends BaseController {
|
||||
|
||||
/**
|
||||
* 初始化
|
||||
*
|
||||
*/
|
||||
protected function initialize() {
|
||||
parent::initialize();
|
||||
|
||||
if (empty($this->userModel)) {
|
||||
exit($this->jsonFail('尚未登录', 401)->send());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,157 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\CollectProductModel;
|
||||
use app\common\model\ProductGroupModel;
|
||||
use think\db\Query;
|
||||
|
||||
class CollectProductController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index() {
|
||||
$parentId = intval($this->request->param('parent_id'));
|
||||
$type = trim($this->request->param('type'));
|
||||
$video = trim($this->request->param('video'));
|
||||
$repeat = trim($this->request->param('repeat'));
|
||||
$groupId = intval($this->request->param('group_id'));
|
||||
$status = trim($this->request->param('status'));
|
||||
$keywords = trim($this->request->param('keywords'));
|
||||
$pageNo = intval($this->request->param('page'));
|
||||
$pageSize = intval($this->request->param('pageSize'));
|
||||
if ($pageNo <= 0) {
|
||||
$pageNo = 1;
|
||||
}
|
||||
if ($pageSize <= 0) {
|
||||
$pageSize = 30;
|
||||
}
|
||||
|
||||
$query = CollectProductModel::where(1);
|
||||
if (!empty($parentId)) {
|
||||
$query->where('parent_id', $parentId);
|
||||
} else {
|
||||
$query->where('parent_id', 0);
|
||||
}
|
||||
if (isset(CollectProductModel::typeAssoc()[$type])) {
|
||||
$query->where('type', $type);
|
||||
}
|
||||
if (isset(CollectProductModel::videoAssoc()[$video])) {
|
||||
$query->where('video', $video);
|
||||
}
|
||||
if (isset(CollectProductModel::repeatAssoc()[$repeat])) {
|
||||
$query->where('repeat', $repeat);
|
||||
}
|
||||
if (isset(CollectProductModel::statusAssoc()[$status])) {
|
||||
$query->where('status', $status);
|
||||
}
|
||||
if (!empty($groupId)) {
|
||||
$query->where('group_id', $groupId);
|
||||
}
|
||||
if (!empty($keywords)) {
|
||||
$query->where(function (Query $q) use ($keywords) {
|
||||
$q->whereLike('src_url', '%' . $keywords . '%', 'OR');
|
||||
$q->whereLike('title', '%' . $keywords . '%', 'OR');
|
||||
});
|
||||
}
|
||||
|
||||
$totalCount = $query->count();
|
||||
$pageCount = $totalCount > 0 ? ceil($totalCount / $pageSize) : 1;
|
||||
if ($pageNo > $pageCount) {
|
||||
$pageNo = $pageCount;
|
||||
}
|
||||
|
||||
$query->order('id', 'DESC');
|
||||
$query->limit(($pageNo - 1) * $pageSize, $pageSize);
|
||||
|
||||
$list = [];
|
||||
foreach ($query->select() as $model) {
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
'product_num' => $model->productNum(),
|
||||
'status_name' => CollectProductModel::statusAssoc()[$model->status],
|
||||
'video_name' => CollectProductModel::videoAssoc()[$model->video],
|
||||
'repeat_name' => CollectProductModel::repeatAssoc()[$model->repeat],
|
||||
'platform_name' => CollectProductModel::platformAssoc()[$model->platform],
|
||||
'mark_up_rate' => floatval($model->mark_up_rate),
|
||||
'mark_up_val' => floatval($model->mark_up_val),
|
||||
'start_time' => $model->start_time > 0 ? date('Y-m-d H:i:s', $model->start_time) : '',
|
||||
'stop_time' => $model->stop_time > 0 ? date('Y-m-d H:i:s', $model->stop_time) : '',
|
||||
'group_name' => isset(ProductGroupModel::assoc()[$model->group_id])
|
||||
? ProductGroupModel::assoc()[$model->group_id]
|
||||
: '',
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $list,
|
||||
'page' => $pageNo,
|
||||
'pageCount' => $pageCount,
|
||||
'totalCount' => $totalCount,
|
||||
'statuses' => $this->assocToList(CollectProductModel::statusAssoc()),
|
||||
'platforms' => $this->assocToList(CollectProductModel::platformAssoc()),
|
||||
'videos' => $this->assocToList(CollectProductModel::videoAssoc()),
|
||||
'repeats' => $this->assocToList(CollectProductModel::repeatAssoc()),
|
||||
'groups' => $this->assocToList(ProductGroupModel::assoc()),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function save() {
|
||||
//$id = intval($this->request->param('id'));
|
||||
$type = trim($this->request->param('type'));
|
||||
$srcUrl = trim($this->request->param('src_url'));
|
||||
$video = intval($this->request->param('video'));
|
||||
$repeat = intval($this->request->param('repeat'));
|
||||
$markUpRate = intval($this->request->param('mark_up_rate'));
|
||||
$markUpVal = intval($this->request->param('mark_up_val'));
|
||||
$groupId = intval($this->request->param('group_id'));
|
||||
if (empty($srcUrl)
|
||||
OR !isset(CollectProductModel::typeAssoc()[$type])
|
||||
OR !isset(CollectProductModel::videoAssoc()[$video])
|
||||
OR !isset(CollectProductModel::repeatAssoc()[$repeat])) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
if (!empty($id)) {
|
||||
$model = CollectProductModel::get($id);
|
||||
if (empty($model)) {
|
||||
return $this->jsonFail('对象未找到');
|
||||
}
|
||||
} else {
|
||||
$model = new CollectProductModel();
|
||||
}
|
||||
|
||||
$platform = '';
|
||||
if ($type === CollectProductModel::TYPE_PRODUCT
|
||||
AND preg_match('#^https\:\/\/www\.goofish\.com\/item#', $srcUrl)) {
|
||||
$platform = CollectProductModel::PLATFORM_XIANYU;
|
||||
} elseif ($type === CollectProductModel::TYPE_SHOP
|
||||
AND preg_match('#^https\:\/\/www\.goofish\.com\/personal#', $srcUrl)) {
|
||||
$platform = CollectProductModel::PLATFORM_XIANYU;
|
||||
} else {
|
||||
return $this->jsonFail('采集链接错误');
|
||||
}
|
||||
|
||||
$model = new CollectProductModel();
|
||||
$model->type = $type;
|
||||
$model->src_url = $srcUrl;
|
||||
$model->platform = $platform;
|
||||
$model->target = CollectProductModel::TARGET_PRODUCT;
|
||||
$model->video = $video;
|
||||
$model->repeat = $repeat;
|
||||
$model->mark_up_rate = $markUpRate;
|
||||
$model->mark_up_val = $markUpVal;
|
||||
$model->group_id = $groupId;
|
||||
$model->user_id = $this->userModel->id;
|
||||
$model->save();
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
}
|
||||
92
Server/application/backend/controller/DeviceController.php
Normal file
92
Server/application/backend/controller/DeviceController.php
Normal file
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\DeviceModel;
|
||||
use think\db\Query;
|
||||
|
||||
class DeviceController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index() {
|
||||
$isOnline = intval($this->request->param('is_online'));
|
||||
$status = trim($this->request->param('status'));
|
||||
$keywords = trim($this->request->param('keywords'));
|
||||
$pageNo = intval($this->request->param('page'));
|
||||
$pageSize = intval($this->request->param('pageSize'));
|
||||
if ($pageNo <= 0) {
|
||||
$pageNo = 1;
|
||||
}
|
||||
if ($pageSize <= 0) {
|
||||
$pageSize = 30;
|
||||
}
|
||||
|
||||
$onlines = [
|
||||
1 => '在线',
|
||||
2 => '离线',
|
||||
];
|
||||
|
||||
$query = DeviceModel::where(1);
|
||||
if (isset(DeviceModel::statusAssoc()[$status])) {
|
||||
$query->where('status', $status);
|
||||
}
|
||||
|
||||
if ($isOnline == 1) {
|
||||
$query->where('is_online', DeviceModel::IS_ONLINE_YES);
|
||||
$query->where('active_time', '>=', time() - DeviceModel::ACTIVE_TIME);
|
||||
} elseif ($isOnline == 2) {
|
||||
$query->where(function (Query $q) {
|
||||
$q->whereOr('is_online', DeviceModel::IS_ONLINE_NO);
|
||||
$q->whereOr('active_time', '<', time() - DeviceModel::ACTIVE_TIME);
|
||||
});
|
||||
}
|
||||
|
||||
if (!empty($keywords)) {
|
||||
$query->where(function (Query $q) use ($keywords) {
|
||||
$q->whereLike('number', '%' . $keywords . '%', 'OR');
|
||||
$q->whereLike('ip', '%' . $keywords . '%', 'OR');
|
||||
});
|
||||
}
|
||||
|
||||
$totalCount = $query->count();
|
||||
$pageCount = $totalCount > 0 ? ceil($totalCount / $pageSize) : 1;
|
||||
if ($pageNo > $pageCount) {
|
||||
$pageNo = $pageCount;
|
||||
}
|
||||
|
||||
$query->order('id', 'DESC');
|
||||
$query->limit(($pageNo - 1) * $pageSize, $pageSize);
|
||||
|
||||
$list = [];
|
||||
foreach ($query->select() as $model) {
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
'is_online' => $model->isOnline() ? 1 : 2,
|
||||
'is_online_name' => $onlines[$model->isOnline() ? 1 : 2],
|
||||
'status_name' => DeviceModel::statusAssoc()[$model->status],
|
||||
'active_time' => date('Y-m-d H:i:s', $model->active_time),
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $list,
|
||||
'page' => $pageNo,
|
||||
'pageCount' => $pageCount,
|
||||
'totalCount' => $totalCount,
|
||||
'statuses' => $this->assocToList(DeviceModel::statusAssoc()),
|
||||
'onlines' => $this->assocToList($onlines),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取关联数组
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function assoc() {
|
||||
return $this->jsonSucc($this->assocToList(DeviceModel::assoc()));
|
||||
}
|
||||
}
|
||||
151
Server/application/backend/controller/DeviceStatController.php
Normal file
151
Server/application/backend/controller/DeviceStatController.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use think\db\Query;
|
||||
|
||||
class DeviceStatController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index() {
|
||||
$keywords = trim($this->request->param('keywords'));
|
||||
$pageNo = intval($this->request->param('page'));
|
||||
$pageSize = intval($this->request->param('pageSize'));
|
||||
if ($pageNo <= 0) {
|
||||
$pageNo = 1;
|
||||
}
|
||||
if ($pageSize <= 0) {
|
||||
$pageSize = 30;
|
||||
}
|
||||
|
||||
$query = DeviceStatModel::where(1);
|
||||
if (!empty($keywords)) {
|
||||
$query->where(function (Query $q) use ($keywords) {
|
||||
$q->whereLike('days', '%' . $keywords . '%', 'OR');
|
||||
});
|
||||
}
|
||||
|
||||
$totalCount = $query->count();
|
||||
$pageCount = $totalCount > 0 ? ceil($totalCount / $pageSize) : 1;
|
||||
if ($pageNo > $pageCount) {
|
||||
$pageNo = $pageCount;
|
||||
}
|
||||
|
||||
$query->order('id', 'DESC');
|
||||
$query->limit(($pageNo - 1) * $pageSize, $pageSize);
|
||||
|
||||
$list = [];
|
||||
if ($pageNo <= 1) {
|
||||
$num = DeviceQqModel::where(1)
|
||||
->where('create_time', '>=', 1724860800)
|
||||
->count();
|
||||
$succNum = DeviceQqModel::where(1)
|
||||
->where('create_time', '>=', 1724860800)
|
||||
->where('status', DeviceQqModel::STATUS_SUCC)
|
||||
->count();
|
||||
$rewardTotal = floatval(DeviceQqModel::where(1)
|
||||
->where('create_time', '>=', 1724860800)
|
||||
->where('status', DeviceQqModel::STATUS_SUCC)
|
||||
->sum('reward'));
|
||||
$rewardPrice = 0;
|
||||
if ($succNum > 0) {
|
||||
$rewardPrice = round($rewardTotal / $succNum, 2);
|
||||
}
|
||||
$finishTime = intval(DeviceQqModel::where(1)
|
||||
->where('create_time', '>=', 1724860800)
|
||||
->where('finish_time', '>', 0)
|
||||
->avg('finish_time'));
|
||||
$createTime = intval(DeviceQqModel::where(1)
|
||||
->where('create_time', '>=', 1724860800)
|
||||
->where('finish_time', '>', 0)
|
||||
->avg('create_time'));
|
||||
$succFinishTime = intval(DeviceQqModel::where(1)
|
||||
->where('create_time', '>=', 1724860800)
|
||||
->where('status', DeviceQqModel::STATUS_SUCC)
|
||||
->where('finish_time', '>', 0)
|
||||
->avg('finish_time'));
|
||||
$succCreateTime = intval(DeviceQqModel::where(1)
|
||||
->where('create_time', '>=', 1724860800)
|
||||
->where('status', DeviceQqModel::STATUS_SUCC)
|
||||
->where('finish_time', '>', 0)
|
||||
->avg('create_time'));
|
||||
|
||||
$succRate = $num > 0 ? round($succNum / $num * 100, 2) : 0;
|
||||
$failNum = $num - $succNum;
|
||||
$failRate = $num > 0 ? round($failNum / $num * 100, 2) : 0;
|
||||
$succFailRate = 0;
|
||||
if ($num > $succNum) {
|
||||
$succFailRate = $succNum / ($num - $succNum);
|
||||
$succFailRate = round($succFailRate * 100, 2);
|
||||
}
|
||||
|
||||
$failInfo = [];
|
||||
foreach (DeviceQqModel::where(1)
|
||||
->field('remark, COUNT(id) AS num')
|
||||
->where('create_time', '>=', 1724860800)
|
||||
->whereNotIn('status', [DeviceQqModel::STATUS_REG, DeviceQqModel::STATUS_SUCC])
|
||||
->group('remark')
|
||||
->select() as $infoModel) {
|
||||
if ($infoModel->remark) {
|
||||
|
||||
$failInfo[] = [
|
||||
'title' => $infoModel->remark,
|
||||
'num' => $infoModel->num,
|
||||
'rate' => $num > 0 ? round($infoModel->num / $num * 100, 2) : 0,
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$list[] = [
|
||||
'days' => '合计',
|
||||
'num' => $num,
|
||||
'succ_num' => $succNum,
|
||||
'reward_price' => $rewardPrice,
|
||||
'reward_total' => $rewardTotal,
|
||||
'avg_time' => $finishTime > $createTime ? $finishTime - $createTime : 0,
|
||||
'avg_succ_time' => $succFinishTime > $succCreateTime ? $succFinishTime - $succCreateTime : 0,
|
||||
'succ_fail_rate' => $succFailRate,
|
||||
'succ_rate' => $succRate,
|
||||
'fail_num' => $failNum,
|
||||
'fail_rate' => $failRate,
|
||||
'fail_info' => $failInfo,
|
||||
];
|
||||
}
|
||||
foreach ($query->select() as $model) {
|
||||
$succRate = 0;
|
||||
$failNum = $model->num > $model->succ_num ? $model->num - $model->succ_num : 0;
|
||||
$failRate = 0;
|
||||
$succFailRate = 0;
|
||||
if ($model->num > 0) {
|
||||
$succRate = $model->succ_num / $model->num;
|
||||
$succRate = round($succRate * 100, 2);
|
||||
$failRate = $failNum / $model->num;
|
||||
$failRate = round($failRate * 100, 2);
|
||||
}
|
||||
if ($model->num > $model->succ_num) {
|
||||
$succFailRate = $model->succ_num / ($model->num - $model->succ_num);
|
||||
$succFailRate = round($succFailRate * 100, 2);
|
||||
}
|
||||
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
'reward_price' => floatval($model->reward_price),
|
||||
'reward_total' => floatval($model->reward_total),
|
||||
'succ_fail_rate' => $succFailRate,
|
||||
'fail_num' => $failNum,
|
||||
'succ_rate' => $succRate,
|
||||
'fail_rate' => $failRate,
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $list,
|
||||
'page' => $pageNo,
|
||||
'pageCount' => $pageCount,
|
||||
'totalCount' => $totalCount,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\TaskModel;
|
||||
|
||||
class MessageReplyController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 关闭
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function close() {
|
||||
$devices = $this->request->param('devices');
|
||||
if (empty($devices) OR !is_array($devices)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
TaskModel::where(1)
|
||||
->whereIn('device_id', $devices)
|
||||
->where('platform', TaskModel::PLATFORM_XIANYU)
|
||||
->whereIn('status', [TaskModel::STATUS_AWAIT, TaskModel::STATUS_ALLOC])
|
||||
->where('is_deleted', TaskModel::IS_DELETED_NO)
|
||||
->update([
|
||||
'is_deleted' => TaskModel::IS_DELETED_YES,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\ProductContentPoolModel;
|
||||
|
||||
class ProductContentPoolController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 获取关联数组
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function assoc() {
|
||||
return $this->jsonSucc(ProductContentPoolModel::assoc());
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @return \think\response\Json
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function save() {
|
||||
$contents = $this->request->param('contents');
|
||||
if (!is_array($contents)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
for ($i = 1; $i <= 6; $i ++) {
|
||||
if (isset($contents[$i])) {
|
||||
$content = trim($contents[$i]);
|
||||
$content = trim($content, '-');
|
||||
$content = trim($content);
|
||||
if (!empty($content)) {
|
||||
$model = ProductContentPoolModel::where(1)
|
||||
->where('number', $i)
|
||||
->find();
|
||||
if (empty($model)) {
|
||||
$model = new ProductContentPoolModel();
|
||||
}
|
||||
$model->number = $i;
|
||||
$model->content = trim($content);
|
||||
$model->save();
|
||||
} else {
|
||||
ProductContentPoolModel::where(1)
|
||||
->where('number', $i)
|
||||
->delete();
|
||||
}
|
||||
} else {
|
||||
ProductContentPoolModel::where(1)
|
||||
->where('number', $i)
|
||||
->delete();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
}
|
||||
361
Server/application/backend/controller/ProductController.php
Normal file
361
Server/application/backend/controller/ProductController.php
Normal file
@@ -0,0 +1,361 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\ProductGroupModel;
|
||||
use app\common\model\ProductModel;
|
||||
use think\db\Query;
|
||||
|
||||
class ProductController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index() {
|
||||
$groupId = trim($this->request->param('group_id'));
|
||||
$isUsed = trim($this->request->param('is_used'));
|
||||
$keywords = trim($this->request->param('keywords'));
|
||||
$pageNo = intval($this->request->param('page'));
|
||||
$pageSize = intval($this->request->param('pageSize'));
|
||||
if ($pageNo <= 0) {
|
||||
$pageNo = 1;
|
||||
}
|
||||
if ($pageSize <= 0) {
|
||||
$pageSize = 30;
|
||||
}
|
||||
|
||||
$query = ProductModel::where(1);
|
||||
if (strlen($groupId) > 0) {
|
||||
$query->where('group_id', $groupId);
|
||||
}
|
||||
if (isset(ProductModel::isUsedAssoc()[$isUsed])) {
|
||||
$query->where('is_used', $isUsed);
|
||||
}
|
||||
if (!empty($keywords)) {
|
||||
$query->where(function (Query $q) use ($keywords) {
|
||||
$q->whereLike('title', '%' . $keywords . '%', 'OR');
|
||||
});
|
||||
}
|
||||
|
||||
$totalCount = $query->count();
|
||||
$pageCount = $totalCount > 0 ? ceil($totalCount / $pageSize) : 1;
|
||||
if ($pageNo > $pageCount) {
|
||||
$pageNo = $pageCount;
|
||||
}
|
||||
|
||||
$query->order('id', 'DESC');
|
||||
$query->limit(($pageNo - 1) * $pageSize, $pageSize);
|
||||
|
||||
$list = [];
|
||||
foreach ($query->select() as $model) {
|
||||
$images = [];
|
||||
foreach ($model->images as $image) {
|
||||
$images[] = array_merge($image, [
|
||||
'url' => $this->absoluteUrl($image['path']),
|
||||
]);
|
||||
}
|
||||
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
'images' => $images,
|
||||
'is_used_name' => ProductModel::isUsedAssoc()[$model->is_used],
|
||||
'group_name' => isset(ProductGroupModel::assoc()[$model->group_id])
|
||||
? ProductGroupModel::assoc()[$model->group_id]
|
||||
: '',
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $list,
|
||||
'page' => $pageNo,
|
||||
'pageCount' => $pageCount,
|
||||
'totalCount' => $totalCount,
|
||||
'groups' => $this->assocToList(ProductGroupModel::assoc()),
|
||||
'isUseds' => $this->assocToList(ProductModel::isUsedAssoc()),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改主题
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function theme() {
|
||||
$checked = $this->request->param('checked');
|
||||
$themes = $this->request->param('themes');
|
||||
if (empty($checked)
|
||||
OR !is_array($checked)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
if (empty($themes) OR !is_array($themes)) {
|
||||
$themes = [];
|
||||
}
|
||||
|
||||
ProductModel::where(1)
|
||||
->whereIn('id', $checked)
|
||||
->update([
|
||||
'themes' => json_encode($themes, JSON_UNESCAPED_UNICODE),
|
||||
'update_time' => time(),
|
||||
]);
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改标签
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function label() {
|
||||
$checked = $this->request->param('checked');
|
||||
$labels = $this->request->param('labels');
|
||||
if (empty($checked)
|
||||
OR !is_array($checked)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
if (empty($labels) OR !is_array($labels)) {
|
||||
$labels = [];
|
||||
}
|
||||
|
||||
ProductModel::where(1)
|
||||
->whereIn('id', $checked)
|
||||
->update([
|
||||
'labels' => json_encode($labels, JSON_UNESCAPED_UNICODE),
|
||||
'update_time' => time(),
|
||||
]);
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改标题
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function title() {
|
||||
$checked = $this->request->param('checked');
|
||||
$type = intval($this->request->param('type'));
|
||||
$title = trim($this->request->param('title'));
|
||||
if (empty($checked)
|
||||
OR !is_array($checked)
|
||||
OR !in_array($type, [0, 1])
|
||||
OR empty($title)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
foreach (ProductModel::where(1)
|
||||
->whereIn('id', $checked)
|
||||
->select() as $model) {
|
||||
if ($type == 0) {
|
||||
$model->title = $model->title . $title;
|
||||
} else {
|
||||
$model->title = $title . $model->title;
|
||||
}
|
||||
$model->save();
|
||||
}
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改描述
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function content() {
|
||||
$checked = $this->request->param('checked');
|
||||
$type = intval($this->request->param('type'));
|
||||
$content = trim($this->request->param('content'));
|
||||
if (empty($checked)
|
||||
OR !is_array($checked)
|
||||
OR !in_array($type, [0, 1])
|
||||
OR empty($content)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
foreach (ProductModel::where(1)
|
||||
->whereIn('id', $checked)
|
||||
->select() as $model) {
|
||||
if ($type == 0) {
|
||||
$model->content = $model->content . "\n" . $content;
|
||||
} else {
|
||||
$model->content = $content . "\n" . $model->content;
|
||||
}
|
||||
$model->save();
|
||||
}
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改库存
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function stock() {
|
||||
$checked = $this->request->param('checked');
|
||||
$stock = intval($this->request->param('stock'));
|
||||
if (empty($checked)
|
||||
OR !is_array($checked)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
if ($stock <= 0) {
|
||||
return $this->jsonFail('库存不可小于1');
|
||||
}
|
||||
|
||||
ProductModel::where(1)
|
||||
->whereIn('id', $checked)
|
||||
->update([
|
||||
'stock' => $stock,
|
||||
'update_time' => time(),
|
||||
]);
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量修改价格
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function price() {
|
||||
$checked = $this->request->param('checked');
|
||||
$type = intval($this->request->param('type'));
|
||||
$rate = floatval($this->request->param('rate'));
|
||||
$val = floatval($this->request->param('val'));
|
||||
$price = floatval($this->request->param('price'));
|
||||
if (empty($checked)
|
||||
OR !is_array($checked)
|
||||
OR !in_array($type, [0, 1, 2])) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
if ($type == 0 OR $type == 1) {
|
||||
if ($rate <= 0 AND $val <= 0) {
|
||||
return $this->jsonFail('请输入比例或数值');
|
||||
}
|
||||
} elseif ($type == 2) {
|
||||
if ($price <= 0) {
|
||||
return $this->jsonFail('请输入金额');
|
||||
}
|
||||
}
|
||||
|
||||
foreach (ProductModel::where(1)
|
||||
->whereIn('id', $checked)
|
||||
->select() as $model) {
|
||||
if ($type == 0) {
|
||||
if ($rate > 0) {
|
||||
$model->price -= $model->price * $rate / 100;
|
||||
} else {
|
||||
$model->price -= $val;
|
||||
}
|
||||
} elseif ($type == 1) {
|
||||
if ($rate > 0) {
|
||||
$model->price += $model->price * $rate / 100;
|
||||
} else {
|
||||
$model->price += $val;
|
||||
}
|
||||
} elseif ($type == 2) {
|
||||
$model->price = $price;
|
||||
}
|
||||
$model->price = round($model->price, 2);
|
||||
if ($model->price > 0) {
|
||||
$model->save();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function save() {
|
||||
$id = intval($this->request->param('id'));
|
||||
$groupId = intval($this->request->param('group_id'));
|
||||
$title = trim($this->request->param('title'));
|
||||
$content = trim($this->request->param('content'));
|
||||
$cb = $this->request->param('cb');
|
||||
$images = $this->request->param('images');
|
||||
$labels = $this->request->param('labels');
|
||||
$themes = $this->request->param('themes');
|
||||
$opts = $this->request->param('opts');
|
||||
$address = trim($this->request->param('address'));
|
||||
$price = floatval($this->request->param('price'));
|
||||
$stock = intval($this->request->param('stock'));
|
||||
$shippingFee = floatval($this->request->param('shipping_fee'));
|
||||
$video = trim($this->request->param('video'));
|
||||
if (empty($title)
|
||||
OR $groupId < 0
|
||||
OR empty($content)
|
||||
OR !is_array($cb)
|
||||
OR !is_array($images)
|
||||
OR empty($images)
|
||||
OR !is_array($labels)
|
||||
OR !is_array($themes)
|
||||
OR !is_array($opts)
|
||||
OR $price < 0
|
||||
OR $stock < 0
|
||||
OR $shippingFee < 0) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
foreach ($images as $i => $image) {
|
||||
unset($images[$i]['url']);
|
||||
}
|
||||
|
||||
if (!empty($id)) {
|
||||
$model = ProductModel::get($id);
|
||||
if (empty($model)) {
|
||||
return $this->jsonFail('对象未找到');
|
||||
}
|
||||
} else {
|
||||
$model = new ProductModel();
|
||||
}
|
||||
|
||||
$model->group_id = $groupId;
|
||||
$model->title = $title;
|
||||
$model->content = $content;
|
||||
$model->cb = $cb;
|
||||
$model->video = $video;
|
||||
$model->images = $images;
|
||||
$model->labels = $labels;
|
||||
$model->themes = $themes;
|
||||
$model->address = $address;
|
||||
$model->price = $price;
|
||||
$model->stock = $stock;
|
||||
$model->shipping_fee = $shippingFee;
|
||||
$model->opts = $opts;
|
||||
$model->save();
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @return \think\response\Json
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete() {
|
||||
$id = intval($this->request->param('id'));
|
||||
if (empty($id)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
$model = ProductModel::get($id);
|
||||
if (empty($model)) {
|
||||
return $this->jsonFail('对象未找到');
|
||||
}
|
||||
|
||||
$model->delete();
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
}
|
||||
118
Server/application/backend/controller/ProductGroupController.php
Normal file
118
Server/application/backend/controller/ProductGroupController.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\CollectProductModel;
|
||||
use app\common\model\ProductGroupModel;
|
||||
use app\common\model\ProductModel;
|
||||
use think\db\Query;
|
||||
|
||||
class ProductGroupController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index() {
|
||||
$keywords = trim($this->request->param('keywords'));
|
||||
$pageNo = intval($this->request->param('page'));
|
||||
$pageSize = intval($this->request->param('pageSize'));
|
||||
if ($pageNo <= 0) {
|
||||
$pageNo = 1;
|
||||
}
|
||||
if ($pageSize <= 0) {
|
||||
$pageSize = 30;
|
||||
}
|
||||
|
||||
$query = ProductGroupModel::where(1);
|
||||
if (!empty($keywords)) {
|
||||
$query->where(function (Query $q) use ($keywords) {
|
||||
$q->whereLike('name', '%' . $keywords . '%', 'OR');
|
||||
});
|
||||
}
|
||||
|
||||
$totalCount = $query->count();
|
||||
$pageCount = $totalCount > 0 ? ceil($totalCount / $pageSize) : 1;
|
||||
if ($pageNo > $pageCount) {
|
||||
$pageNo = $pageCount;
|
||||
}
|
||||
|
||||
$query->order('id', 'DESC');
|
||||
$query->limit(($pageNo - 1) * $pageSize, $pageSize);
|
||||
|
||||
$list = [];
|
||||
foreach ($query->select() as $model) {
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
'product_num' => $model->productNum(),
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $list,
|
||||
'page' => $pageNo,
|
||||
'pageCount' => $pageCount,
|
||||
'totalCount' => $totalCount,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function save() {
|
||||
$id = intval($this->request->param('id'));
|
||||
$name = trim($this->request->param('name'));
|
||||
if (empty($name)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
if (!empty($id)) {
|
||||
$model = ProductGroupModel::get($id);
|
||||
if (empty($model)) {
|
||||
return $this->jsonFail('对象未找到');
|
||||
}
|
||||
} else {
|
||||
$model = new ProductGroupModel();
|
||||
}
|
||||
|
||||
$model->name = $name;
|
||||
$model->save();
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @return \think\response\Json
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function delete() {
|
||||
$id = intval($this->request->param('id'));
|
||||
if (empty($id)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
$model = ProductGroupModel::get($id);
|
||||
if (empty($model)) {
|
||||
return $this->jsonFail('对象未找到');
|
||||
}
|
||||
|
||||
CollectProductModel::where(1)
|
||||
->where('group_id', $model->id)
|
||||
->update([
|
||||
'group_id' => 0,
|
||||
]);
|
||||
ProductModel::where(1)
|
||||
->where('group_id', $model->id)
|
||||
->update([
|
||||
'group_id' => 0,
|
||||
]);
|
||||
|
||||
$model->delete();
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\ProductModel;
|
||||
use app\common\model\ProductUseModel;
|
||||
use app\common\model\TaskModel;
|
||||
use app\common\task\ProductReleaseTask;
|
||||
|
||||
class ProductReleaseController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function save() {
|
||||
$devices = $this->request->param('devices');
|
||||
$params = ProductReleaseTask::params($this->request);
|
||||
if (empty($devices)
|
||||
OR !is_array($devices)
|
||||
OR is_null($params)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
foreach ($devices as $deviceId) {
|
||||
$pdts = [];
|
||||
for ($i = 0; $i < $params['release_num']; $i ++) {
|
||||
$product = array_shift($params['products']);
|
||||
if (!empty($product)) {
|
||||
$pdts[] = $product;
|
||||
}
|
||||
}
|
||||
if (!empty($pdts)) {
|
||||
$model = new TaskModel();
|
||||
$model->device_id = $deviceId;
|
||||
$model->platform = TaskModel::PLATFORM_XIANYU;
|
||||
$model->type = TaskModel::TYPE_PRODUCT_RELEASE;
|
||||
$model->params = array_merge($params, ['products' => $pdts]);
|
||||
$model->run_type = TaskModel::RUN_TYPE_ONCE;
|
||||
$model->run_time = '';
|
||||
if ($model->save()) {
|
||||
foreach ($pdts as $pdt) {
|
||||
$useModel = new ProductUseModel();
|
||||
$useModel->device_id = $deviceId;
|
||||
$useModel->release_id = $model->id;
|
||||
$useModel->product_id = $pdt['id'];
|
||||
$useModel->use_type = $model->platform;
|
||||
$useModel->save();
|
||||
|
||||
ProductModel::where(1)
|
||||
->where('id', $pdt['id'])
|
||||
->update([
|
||||
'is_used' => ProductModel::IS_USED_YES,
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
}
|
||||
795
Server/application/backend/controller/StatController.php
Normal file
795
Server/application/backend/controller/StatController.php
Normal file
@@ -0,0 +1,795 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\CloneInfo;
|
||||
use app\common\model\MemberModel;
|
||||
use app\common\model\MemberMoneyModel;
|
||||
use app\common\model\MemberQrcodeModel;
|
||||
use app\common\model\MemberWithdrawModel;
|
||||
use app\common\model\StatisticsModel;
|
||||
use app\common\Utils;
|
||||
|
||||
class StatController extends BaseLoginController {
|
||||
|
||||
protected $chartColumns = [
|
||||
'register' => '用户注册',
|
||||
'qr_number' => '扫码企点号',
|
||||
'qr_member' => '扫码人数',
|
||||
'qrcode' => '取码次数',
|
||||
'qrcode_succ' => '取码成功',
|
||||
'clone_succ' => '克隆成功',
|
||||
'clone_error' => '克隆错误',
|
||||
'clone_timeout' => '克隆超时',
|
||||
'xinyue_select' => '选择克隆心悦数',
|
||||
'xinyue_clone' => '克隆成功心悦数',
|
||||
'reward_clone' => '克隆奖励笔数',
|
||||
'reward_invite1' => '一级奖励笔数',
|
||||
'reward_invite2' => '二级奖励笔数',
|
||||
'money_clone' => '克隆奖励金额',
|
||||
'money_invite1' => '一级奖励金额',
|
||||
'money_invite2' => '二级奖励金额',
|
||||
'withdraw' => '申请提现笔数',
|
||||
'withdraw_check' => '检测通过笔数',
|
||||
'withdraw_money' => '申请提现金额',
|
||||
'withdraw_money_check' => '检测通过金额',
|
||||
'withdraw_succ' => '提现成功笔数',
|
||||
'withdraw_succ_money' => '提现成功金额',
|
||||
'withdraw_fail' => '提现失败笔数',
|
||||
'withdraw_fail_money' => '提现失败金额',
|
||||
];
|
||||
|
||||
public function dayChartView() {
|
||||
$day = trim($this->request->param('day'));
|
||||
$columns = trim($this->request->param('columns'));
|
||||
$columns = explode('|', $columns);
|
||||
if (empty($day) OR empty($columns)) {
|
||||
exit('Page not found.');
|
||||
}
|
||||
|
||||
$legend = [];
|
||||
$xAxis = [];
|
||||
$series = [];
|
||||
for ($i = 0; $i <= 23; $i ++) {
|
||||
$xAxis[] = $i . '时';
|
||||
}
|
||||
foreach ($columns as $i => $column) {
|
||||
if (isset($this->chartColumns[$column])) {
|
||||
$legend[] = $this->chartColumns[$column];
|
||||
$series[$column] = [
|
||||
'name' => $this->chartColumns[$column],
|
||||
'type' => 'line',
|
||||
'stack' => 'Total',
|
||||
'data' => [],
|
||||
];
|
||||
} else {
|
||||
unset($columns[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$list = $this->getDayData($day);
|
||||
$rows = [];
|
||||
foreach ($list as $row) {
|
||||
$rows[$row['hour']] = $row;
|
||||
}
|
||||
|
||||
foreach ($xAxis as $axi) {
|
||||
if (isset($rows[$axi])) {
|
||||
foreach ($columns as $column) {
|
||||
$series[$column]['data'][] = $rows[$axi][$column];
|
||||
}
|
||||
} else {
|
||||
foreach ($columns as $column) {
|
||||
$series[$column]['data'][] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fetch('/chart-day', [
|
||||
'legend' => $legend,
|
||||
'xAxis' => $xAxis,
|
||||
'series' => array_values($series),
|
||||
]);
|
||||
}
|
||||
|
||||
public function monthChartView() {
|
||||
$month = trim($this->request->param('month'));
|
||||
$columns = trim($this->request->param('columns'));
|
||||
$columns = explode('|', $columns);
|
||||
if (empty($month) OR empty($columns)) {
|
||||
exit('Page not found.');
|
||||
}
|
||||
|
||||
$time = strtotime($month . '01');
|
||||
if ($time === FALSE) {
|
||||
exit('Page not found.');
|
||||
}
|
||||
|
||||
$days = date('t', $time);
|
||||
$legend = [];
|
||||
$xAxis = [];
|
||||
$series = [];
|
||||
for ($i = 1; $i <= $days; $i ++) {
|
||||
$xAxis[] = $i . '日';
|
||||
}
|
||||
foreach ($columns as $i => $column) {
|
||||
if (isset($this->chartColumns[$column])) {
|
||||
$legend[] = $this->chartColumns[$column];
|
||||
$series[$column] = [
|
||||
'name' => $this->chartColumns[$column],
|
||||
'type' => 'line',
|
||||
'stack' => 'Total',
|
||||
'data' => [],
|
||||
];
|
||||
} else {
|
||||
unset($columns[$i]);
|
||||
}
|
||||
}
|
||||
|
||||
$list = $this->getMonthData($month);
|
||||
$rows = [];
|
||||
foreach ($list as $row) {
|
||||
$row['day'] = str_replace(['年', '月'], '-', $row['day']);
|
||||
$row['day'] = str_replace(['日'], '', $row['day']);
|
||||
$row['day'] = intval(date('d', strtotime($row['day']))) . '日';
|
||||
|
||||
$rows[$row['day']] = $row;
|
||||
}
|
||||
|
||||
foreach ($xAxis as $axi) {
|
||||
if (isset($rows[$axi])) {
|
||||
foreach ($columns as $column) {
|
||||
$series[$column]['data'][] = $rows[$axi][$column];
|
||||
}
|
||||
} else {
|
||||
foreach ($columns as $column) {
|
||||
$series[$column]['data'][] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->fetch('/chart-day', [
|
||||
'legend' => $legend,
|
||||
'xAxis' => $xAxis,
|
||||
'series' => array_values($series),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日统计图表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function dayChart() {
|
||||
$day = trim($this->request->param('day'));
|
||||
$columns = $this->request->param('columns');
|
||||
if (empty($day)) {
|
||||
$day = date('Y-m-d');
|
||||
}
|
||||
if (strtotime($day) === FALSE) {
|
||||
return $this->jsonFail('日期错误');
|
||||
}
|
||||
if (empty($columns)) {
|
||||
$columns = ['xinyue_select', 'xinyue_clone', 'money_clone'];
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'day' => $day,
|
||||
'columns' => $columns,
|
||||
'chartColumns' => $this->assocToList($this->chartColumns),
|
||||
'url' => $this->absoluteUrl('/backend/stat/dayChartView?token=' . $this->token . '&day=' . $day . '&columns=' . implode('|', $columns)),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 月统计图表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function monthChart() {
|
||||
$month = trim($this->request->param('month'));
|
||||
$columns = $this->request->param('columns');
|
||||
if (empty($month)) {
|
||||
$month = date('Ym');
|
||||
}
|
||||
if (empty($columns)) {
|
||||
$columns = ['xinyue_select', 'xinyue_clone', 'money_clone'];
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'month' => $month,
|
||||
'months' => $this->assocToList($this->getMonths()),
|
||||
'columns' => $columns,
|
||||
'chartColumns' => $this->assocToList($this->chartColumns),
|
||||
'url' => $this->absoluteUrl('/backend/stat/monthChartView?token=' . $this->token . '&month=' . $month . '&columns=' . implode('|', $columns)),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日统计列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function dayIndex() {
|
||||
$day = trim($this->request->param('day'));
|
||||
if (empty($day)) {
|
||||
$day = date('Y-m-d');
|
||||
}
|
||||
if (strtotime($day) === FALSE) {
|
||||
return $this->jsonFail('日期错误');
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $this->getDayData($day),
|
||||
'day' => $day,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 月统计
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function monthIndex() {
|
||||
$month = trim($this->request->param('month'));
|
||||
if (empty($month)) {
|
||||
$month = date('Ym');
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $this->getMonthData($month),
|
||||
'month' => $month,
|
||||
'months' => $this->assocToList($this->getMonths()),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取统计信息
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function get() {
|
||||
$weekTime = time() - 7 * 24 * 3600;
|
||||
$monthTime = time() - 30 * 24 * 3600;
|
||||
|
||||
$memberTotal = MemberModel::where(1)
|
||||
->count();
|
||||
$memberToday = MemberModel::where(1)
|
||||
->where('create_time', '>=', strtotime(date('Y-m-d')))
|
||||
->count();
|
||||
$memberYesterday = MemberModel::where(1)
|
||||
->where('create_time', '>=', strtotime(date('Y-m-d')) - 24 * 3600)
|
||||
->where('create_time', '<', strtotime(date('Y-m-d')))
|
||||
->count();
|
||||
$memberWeek = MemberModel::where(1)
|
||||
->where('create_time', '>=', $weekTime)
|
||||
->count();
|
||||
$memberMonth = MemberModel::where(1)
|
||||
->where('create_time', '>=', $monthTime)
|
||||
->count();
|
||||
|
||||
/*$xinyueTotal = MemberQrcodeModel::where(1)
|
||||
->where('status', MemberQrcodeModel::STATUS_SUCCESS)
|
||||
->sum('select_xinyue_count');
|
||||
$xinyueToday = MemberQrcodeModel::where(1)
|
||||
->where('status', MemberQrcodeModel::STATUS_SUCCESS)
|
||||
->where('create_time', '>=', strtotime(date('Y-m-d')))
|
||||
->sum('select_xinyue_count');
|
||||
$xinyueYesterday = MemberQrcodeModel::where(1)
|
||||
->where('status', MemberQrcodeModel::STATUS_SUCCESS)
|
||||
->where('create_time', '>=', strtotime(date('Y-m-d')) - 24 * 3600)
|
||||
->where('create_time', '<', strtotime(date('Y-m-d')))
|
||||
->sum('select_xinyue_count');
|
||||
$xinyueWeek = MemberQrcodeModel::where(1)
|
||||
->where('status', MemberQrcodeModel::STATUS_SUCCESS)
|
||||
->where('create_time', '>=', $weekTime)
|
||||
->sum('select_xinyue_count');
|
||||
$xinyueMonth = MemberQrcodeModel::where(1)
|
||||
->where('status', MemberQrcodeModel::STATUS_SUCCESS)
|
||||
->where('create_time', '>=', $monthTime)
|
||||
->sum('select_xinyue_count');*/
|
||||
|
||||
$xinyueTotal = StatisticsModel::where(1)
|
||||
->sum('xinyue_select');
|
||||
$xinyueToday = StatisticsModel::where(1)
|
||||
->where('day', date('Ymd'))
|
||||
->sum('xinyue_select');
|
||||
$xinyueYesterday = StatisticsModel::where(1)
|
||||
->where('day', date('Ymd', time() - 24 * 3600))
|
||||
->sum('xinyue_select');
|
||||
$xinyueWeek = StatisticsModel::where(1)
|
||||
->where('day', '>=', date('Ymd', time() - 7 * 24 * 3600))
|
||||
->sum('xinyue_select');
|
||||
$xinyueMonth = StatisticsModel::where(1)
|
||||
->where('day', '>=', date('Ymd', time() - 30 * 24 * 3600))
|
||||
->sum('xinyue_select');
|
||||
|
||||
$moneyTotal = MemberMoneyModel::where(1)
|
||||
->where('money', '>', 0)
|
||||
->where('status', MemberMoneyModel::STATUS_SUCC)
|
||||
->sum('money');
|
||||
$moneyToday = MemberMoneyModel::where(1)
|
||||
->where('money', '>', 0)
|
||||
->where('status', MemberMoneyModel::STATUS_SUCC)
|
||||
->where('create_time', '>=', strtotime(date('Y-m-d')))
|
||||
->sum('money');
|
||||
$moneyYesterday = MemberMoneyModel::where(1)
|
||||
->where('money', '>', 0)
|
||||
->where('status', MemberMoneyModel::STATUS_SUCC)
|
||||
->where('create_time', '>=', strtotime(date('Y-m-d')) - 24 * 3600)
|
||||
->where('create_time', '<', strtotime(date('Y-m-d')))
|
||||
->sum('money');
|
||||
$moneyWeek = MemberMoneyModel::where(1)
|
||||
->where('money', '>', 0)
|
||||
->where('status', MemberMoneyModel::STATUS_SUCC)
|
||||
->where('create_time', '>=', $weekTime)
|
||||
->sum('money');
|
||||
$moneyMonth = MemberMoneyModel::where(1)
|
||||
->where('money', '>', 0)
|
||||
->where('status', MemberMoneyModel::STATUS_SUCC)
|
||||
->where('create_time', '>=', $monthTime)
|
||||
->sum('money');
|
||||
|
||||
$withdrawTotal = MemberMoneyModel::where(1)
|
||||
->whereIn('type', MemberMoneyModel::withdrawTypes())
|
||||
->whereIn('status', [MemberMoneyModel::STATUS_SUCC, MemberMoneyModel::STATUS_AWAIT])
|
||||
->sum('money');
|
||||
$withdrawToday = MemberMoneyModel::where(1)
|
||||
->whereIn('type', MemberMoneyModel::withdrawTypes())
|
||||
->whereIn('status', [MemberMoneyModel::STATUS_SUCC, MemberMoneyModel::STATUS_AWAIT])
|
||||
->where('create_time', '>=', strtotime(date('Y-m-d')))
|
||||
->sum('money');
|
||||
$withdrawYesterday = MemberMoneyModel::where(1)
|
||||
->whereIn('type', MemberMoneyModel::withdrawTypes())
|
||||
->whereIn('status', [MemberMoneyModel::STATUS_SUCC, MemberMoneyModel::STATUS_AWAIT])
|
||||
->where('create_time', '>=', strtotime(date('Y-m-d')) - 24 * 3600)
|
||||
->where('create_time', '<', strtotime(date('Y-m-d')))
|
||||
->sum('money');
|
||||
$withdrawWeek = MemberMoneyModel::where(1)
|
||||
->whereIn('type', MemberMoneyModel::withdrawTypes())
|
||||
->whereIn('status', [MemberMoneyModel::STATUS_SUCC, MemberMoneyModel::STATUS_AWAIT])
|
||||
->where('create_time', '>=', $weekTime)
|
||||
->sum('money');
|
||||
$withdrawMonth = MemberMoneyModel::where(1)
|
||||
->whereIn('type', MemberMoneyModel::withdrawTypes())
|
||||
->whereIn('status', [MemberMoneyModel::STATUS_SUCC, MemberMoneyModel::STATUS_AWAIT])
|
||||
->where('create_time', '>=', $monthTime)
|
||||
->sum('money');
|
||||
|
||||
$remitTotal = MemberWithdrawModel::where(1)
|
||||
//->whereIn('type', MemberMoneyModel::withdrawTypes())
|
||||
->whereIn('status', [MemberWithdrawModel::STATUS_SUCC, MemberWithdrawModel::STATUS_AUTO_SUCC])
|
||||
->sum('money');
|
||||
$remitToday = MemberWithdrawModel::where(1)
|
||||
//->whereIn('type', MemberMoneyModel::withdrawTypes())
|
||||
->whereIn('status', [MemberWithdrawModel::STATUS_SUCC, MemberWithdrawModel::STATUS_AUTO_SUCC])
|
||||
->where('verify_time', '>=', strtotime(date('Y-m-d')))
|
||||
->sum('money');
|
||||
$remitYesterday = MemberWithdrawModel::where(1)
|
||||
//->whereIn('type', MemberMoneyModel::withdrawTypes())
|
||||
->whereIn('status', [MemberWithdrawModel::STATUS_SUCC, MemberWithdrawModel::STATUS_AUTO_SUCC])
|
||||
->where('verify_time', '>=', strtotime(date('Y-m-d')) - 24 * 3600)
|
||||
->where('verify_time', '<', strtotime(date('Y-m-d')))
|
||||
->sum('money');
|
||||
$remitWeek = MemberWithdrawModel::where(1)
|
||||
//->whereIn('type', MemberMoneyModel::withdrawTypes())
|
||||
->whereIn('status', [MemberWithdrawModel::STATUS_SUCC, MemberWithdrawModel::STATUS_AUTO_SUCC])
|
||||
->where('verify_time', '>=', $weekTime)
|
||||
->sum('money');
|
||||
$remitMonth = MemberWithdrawModel::where(1)
|
||||
//->whereIn('type', MemberMoneyModel::withdrawTypes())
|
||||
->whereIn('status', [MemberWithdrawModel::STATUS_SUCC, MemberWithdrawModel::STATUS_AUTO_SUCC])
|
||||
->where('verify_time', '>=', $monthTime)
|
||||
->sum('money');
|
||||
|
||||
return $this->jsonSucc([
|
||||
'member_total' => $memberTotal,
|
||||
'member_today' => $memberToday,
|
||||
'member_yesterday' => $memberYesterday,
|
||||
'member_week' => $memberWeek,
|
||||
'member_month' => $memberMonth,
|
||||
'xinyue_total' => $xinyueTotal,
|
||||
'xinyue_today' => $xinyueToday,
|
||||
'xinyue_yesterday' => $xinyueYesterday,
|
||||
'xinyue_week' => $xinyueWeek,
|
||||
'xinyue_month' => $xinyueMonth,
|
||||
'money_total' => $moneyTotal,
|
||||
'money_today' => $moneyToday,
|
||||
'money_yesterday' => $moneyYesterday,
|
||||
'money_week' => $moneyWeek,
|
||||
'money_month' => $moneyMonth,
|
||||
'withdraw' => round($moneyTotal + $withdrawTotal, 2),
|
||||
'withdraw_total' => abs($withdrawTotal),
|
||||
'withdraw_today' => abs($withdrawToday),
|
||||
'withdraw_yesterday' => abs($withdrawYesterday),
|
||||
'withdraw_week' => abs($withdrawWeek),
|
||||
'withdraw_month' => abs($withdrawMonth),
|
||||
'remit_total' => abs($remitTotal),
|
||||
'remit_today' => abs($remitToday),
|
||||
'remit_yesterday' => abs($remitYesterday),
|
||||
'remit_week' => abs($remitWeek),
|
||||
'remit_month' => abs($remitMonth),
|
||||
'clone_total' => 'Loading...',
|
||||
'clone_today' => '-',
|
||||
'clone_today_nr' => '-',
|
||||
'clone_today_r' => '-',
|
||||
'clone_yesterday' => '-',
|
||||
'clone_week' => '-',
|
||||
'clone_month' => '-',
|
||||
'clone_today_pay' => '-',
|
||||
'clone_today_unpay' => '-',
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取克隆统计信息
|
||||
*
|
||||
* @return \think\response\Json
|
||||
* @throws \think\Exception
|
||||
* @throws \think\db\exception\DataNotFoundException
|
||||
* @throws \think\db\exception\ModelNotFoundException
|
||||
* @throws \think\exception\DbException
|
||||
*/
|
||||
public function getClone() {
|
||||
$cloneTotal = StatisticsModel::where(1)
|
||||
->sum('xinyue_clone');
|
||||
$cloneToday = StatisticsModel::where(1)
|
||||
->where('day', date('Ymd'))
|
||||
->sum('xinyue_clone');
|
||||
$cloneTodayNr = StatisticsModel::where(1)
|
||||
->where('day', date('Ymd'))
|
||||
->sum('xinyue_clone_nr');
|
||||
$cloneYesterday = StatisticsModel::where(1)
|
||||
->where('day', date('Ymd', time() - 24 * 3600))
|
||||
->sum('xinyue_clone');
|
||||
$cloneWeek = StatisticsModel::where(1)
|
||||
->where('day', '>=', date('Ymd', time() - 7 * 24 * 3600))
|
||||
->sum('xinyue_clone');
|
||||
$cloneMonth = StatisticsModel::where(1)
|
||||
->where('day', '>=', date('Ymd', time() - 30 * 24 * 3600))
|
||||
->sum('xinyue_clone');
|
||||
$cloneTodayUnpay = CloneInfo::getCloneSuccUnpayByTime(strtotime(date('Ymd')), time());
|
||||
$cloneTodayPay = CloneInfo::getCloneSuccPayByTime(strtotime(date('Ymd')), time());
|
||||
|
||||
return $this->jsonSucc([
|
||||
'clone_total' => $cloneTotal,
|
||||
'clone_today' => $cloneToday,
|
||||
'clone_today_nr' => $cloneTodayNr,
|
||||
'clone_today_r' => $cloneToday - $cloneTodayNr,
|
||||
'clone_yesterday' => $cloneYesterday,
|
||||
'clone_week' => $cloneWeek,
|
||||
'clone_month' => $cloneMonth,
|
||||
'clone_today_pay' => $cloneTodayPay,
|
||||
'clone_today_unpay' => $cloneTodayUnpay,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取日统计数据
|
||||
*
|
||||
* @param $day
|
||||
* @return array
|
||||
*/
|
||||
protected function getDayData($day) {
|
||||
$list = [];
|
||||
foreach (StatisticsModel::where(1)
|
||||
->where('day', date('Ymd', strtotime($day)))
|
||||
->order('hour', 'DESC')
|
||||
->select() as $model) {
|
||||
$xinyueClone = $model->xinyue_clone;
|
||||
$moneyTotal = $model->money_clone
|
||||
+ $model->money_invite1
|
||||
+ $model->money_invite2
|
||||
+ $model->money_jm
|
||||
+ $model->money_point;
|
||||
|
||||
$scan1CloneCount = $model->scan1_clone_count;
|
||||
$scan2CloneCount = $model->scan2_clone_count;
|
||||
$scan3CloneCount = $model->scan3_clone_count;
|
||||
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
'day' => date('Y年m月d日', strtotime($model->day)),
|
||||
'hour' => $model->hour . '时',
|
||||
'reward_price' => $xinyueClone > 0 ? round($moneyTotal / $xinyueClone, 2) : 0,
|
||||
'scan1_price' => $scan1CloneCount > 0 ? round($model->scan1_money / $scan1CloneCount, 2) : 0,
|
||||
'scan2_price' => $scan2CloneCount > 0 ? round($model->scan2_money / $scan2CloneCount, 2) : 0,
|
||||
'scan3_price' => $scan3CloneCount > 0 ? round($model->scan3_money / $scan3CloneCount, 2) : 0,
|
||||
]);
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取月份
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function getMonths() {
|
||||
$begin = 20240301;
|
||||
$months = [];
|
||||
$nowTime = time();
|
||||
while ($nowTime >= strtotime($begin)) {
|
||||
if (!isset($months[date('Ym', $nowTime)])) {
|
||||
$months[date('Ym', $nowTime)] = date('Y年m月', $nowTime);
|
||||
}
|
||||
|
||||
$nowTime -= 24 * 3600;
|
||||
}
|
||||
return $months;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取月统计数据
|
||||
*
|
||||
* @param $month
|
||||
* @return array|\think\response\Json
|
||||
*/
|
||||
protected function getMonthData($month) {
|
||||
$time = strtotime($month . '01');
|
||||
if ($time === FALSE) {
|
||||
return $this->jsonFail('月份错误');
|
||||
}
|
||||
|
||||
$today = date('Ymd');
|
||||
$days = [];
|
||||
for ($i = date('t', $time); $i >= 1; $i --) {
|
||||
$day = date('Ymd', strtotime(date('Y', $time) . '-' . date('m', $time) . '-' . $i));
|
||||
if ($day <= $today) {
|
||||
$days[] = $day;
|
||||
}
|
||||
}
|
||||
|
||||
$list = [];
|
||||
foreach ($days as $day) {
|
||||
$row = [
|
||||
'day' => date('Y年m月d日', strtotime($day)),
|
||||
'register' => 0,
|
||||
'qr_number' => 0,
|
||||
'qr_member' => 0,
|
||||
'qrcode' => 0,
|
||||
'qrcode_succ' => 0,
|
||||
'clone_succ' => 0,
|
||||
'clone_error' => 0,
|
||||
'clone_timeout' => 0,
|
||||
'xinyue_select' => 0,
|
||||
'xinyue_clone' => 0,
|
||||
'reward_clone' => 0,
|
||||
'reward_invite1' => 0,
|
||||
'reward_invite2' => 0,
|
||||
'money_clone' => 0,
|
||||
'money_invite1' => 0,
|
||||
'money_invite2' => 0,
|
||||
'money_jm' => 0,
|
||||
'money_point' => 0,
|
||||
'withdraw' => 0,
|
||||
'withdraw_check' => 0,
|
||||
'withdraw_money' => 0,
|
||||
'withdraw_money_check' => 0,
|
||||
'withdraw_succ' => 0,
|
||||
'withdraw_succ_money' => 0,
|
||||
'withdraw_fail' => 0,
|
||||
'withdraw_fail_money' => 0,
|
||||
'scan1_num' => 0,
|
||||
'scan2_num' => 0,
|
||||
'scan3_num' => 0,
|
||||
'scan1_xinyue_count' => 0,
|
||||
'scan2_xinyue_count' => 0,
|
||||
'scan3_xinyue_count' => 0,
|
||||
'scan1_clone_count' => 0,
|
||||
'scan2_clone_count' => 0,
|
||||
'scan3_clone_count' => 0,
|
||||
'scan1_money' => 0,
|
||||
'scan2_money' => 0,
|
||||
'scan3_money' => 0,
|
||||
'scan1_price' => 0,
|
||||
'scan2_price' => 0,
|
||||
'scan3_price' => 0,
|
||||
'first_settlement_count' => 0,
|
||||
'repeat_settlement_count' => 0,
|
||||
'first_reward_money' => 0,
|
||||
'repeat_reward_money' => 0,
|
||||
'first_clone_succ' => 0,
|
||||
'repeat_clone_succ' => 0,
|
||||
'first_price' => 0,
|
||||
'repeat_price' => 0,
|
||||
];
|
||||
|
||||
foreach (StatisticsModel::where(1)
|
||||
->where('day', $day)
|
||||
->select() as $model) {
|
||||
$row['register'] += $model->register;
|
||||
$row['qr_number'] += $model->qr_number;
|
||||
$row['qr_member'] += $model->qr_member;
|
||||
$row['qrcode'] += $model->qrcode;
|
||||
$row['qrcode_succ'] += $model->qrcode_succ;
|
||||
$row['clone_succ'] += $model->clone_succ;
|
||||
$row['clone_error'] += $model->clone_error;
|
||||
$row['clone_timeout'] += $model->clone_timeout;
|
||||
$row['xinyue_select'] += $model->xinyue_select;
|
||||
$row['xinyue_clone'] += $model->xinyue_clone;
|
||||
$row['reward_clone'] += $model->reward_clone;
|
||||
$row['reward_invite1'] += $model->reward_invite1;
|
||||
$row['reward_invite2'] += $model->reward_invite2;
|
||||
$row['money_clone'] += $model->money_clone;
|
||||
$row['money_invite1'] += $model->money_invite1;
|
||||
$row['money_invite2'] += $model->money_invite2;
|
||||
$row['money_jm'] += $model->money_jm;
|
||||
$row['money_point'] += $model->money_point;
|
||||
$row['withdraw'] += $model->withdraw;
|
||||
$row['withdraw_check'] += $model->withdraw_check;
|
||||
$row['withdraw_money'] += $model->withdraw_money;
|
||||
$row['withdraw_money_check'] += $model->withdraw_money_check;
|
||||
$row['withdraw_succ'] += $model->withdraw_succ;
|
||||
$row['withdraw_succ_money'] += $model->withdraw_succ_money;
|
||||
$row['withdraw_fail'] += $model->withdraw_fail;
|
||||
$row['withdraw_fail_money'] += $model->withdraw_fail_money;
|
||||
|
||||
$row['first_settlement_count'] += $model->first_settlement_count;
|
||||
$row['repeat_settlement_count'] += $model->repeat_settlement_count;
|
||||
$row['first_reward_money'] += $model->first_reward_money;
|
||||
$row['repeat_reward_money'] += $model->repeat_reward_money;
|
||||
$row['first_clone_succ'] += $model->first_clone_succ;
|
||||
$row['repeat_clone_succ'] += $model->repeat_clone_succ;
|
||||
/*$row['scan1_num'] += $model->scan1_num;
|
||||
$row['scan2_num'] += $model->scan2_num;
|
||||
$row['scan3_num'] += $model->scan3_num;
|
||||
$row['scan1_xinyue_count'] += $model->scan1_xinyue_count;
|
||||
$row['scan2_xinyue_count'] += $model->scan2_xinyue_count;
|
||||
$row['scan3_xinyue_count'] += $model->scan3_xinyue_count;
|
||||
$row['scan1_clone_count'] += $model->scan1_clone_count;
|
||||
$row['scan2_clone_count'] += $model->scan2_clone_count;
|
||||
$row['scan3_clone_count'] += $model->scan3_clone_count;
|
||||
$row['scan1_money'] += $model->scan1_money;
|
||||
$row['scan2_money'] += $model->scan2_money;
|
||||
$row['scan3_money'] += $model->scan3_money;*/
|
||||
}
|
||||
|
||||
$xinyueClone = $row['xinyue_clone'];
|
||||
$moneyTotal = $row['money_clone']
|
||||
+ $row['money_invite1']
|
||||
+ $row['money_invite2']
|
||||
+ $row['money_jm']
|
||||
+ $row['money_point'];
|
||||
|
||||
//$scan1CloneCount = $row['scan1_clone_count'];
|
||||
//$scan2CloneCount = $row['scan2_clone_count'];
|
||||
//$scan3CloneCount = $row['scan3_clone_count'];
|
||||
|
||||
$row['reward_price'] = $xinyueClone > 0 ? round($moneyTotal / $xinyueClone, 2) : 0;
|
||||
//$row['scan1_price'] = $scan1CloneCount > 0 ? round($row['scan1_money'] / $scan1CloneCount, 2) : 0;
|
||||
//$row['scan2_price'] = $scan2CloneCount > 0 ? round($row['scan2_money'] / $scan2CloneCount, 2) : 0;
|
||||
//$row['scan3_price'] = $scan3CloneCount > 0 ? round($row['scan3_money'] / $scan3CloneCount, 2) : 0;
|
||||
|
||||
$row['first_reward_money'] = round($row['first_reward_money'], 2);
|
||||
$row['repeat_reward_money'] = round($row['repeat_reward_money'], 2);
|
||||
if ($row['first_clone_succ'] > 0) {
|
||||
$row['first_price'] = round($row['first_reward_money'] / $row['first_clone_succ'], 2);
|
||||
}
|
||||
if ($row['repeat_clone_succ'] > 0) {
|
||||
$row['repeat_price'] = round($row['repeat_reward_money'] / $row['repeat_clone_succ'], 2);
|
||||
}
|
||||
|
||||
$list[] = $row;
|
||||
}
|
||||
|
||||
return $list;
|
||||
}
|
||||
|
||||
public function scan() {
|
||||
$time = time();// - 24 * 3600;
|
||||
$ids0 = MemberQrcodeModel::where(1)
|
||||
->field('id')
|
||||
->where('create_time', '>=', strtotime(date('Ymd', $time)))
|
||||
->where('status', MemberQrcodeModel::STATUS_SUCCESS)
|
||||
->where('settlement_count1', '>', 0)
|
||||
->select()
|
||||
->column('id');
|
||||
$ids1 = MemberQrcodeModel::where(1)
|
||||
->field('id')
|
||||
->where('create_time', '>=', strtotime(date('Ymd', $time)))
|
||||
->where('status', MemberQrcodeModel::STATUS_SUCCESS)
|
||||
->where('settlement_count2', '>', 0)
|
||||
->select()
|
||||
->column('id');
|
||||
|
||||
$money0 = 0;
|
||||
$price0 = 0;
|
||||
$xinyue0 = 0;
|
||||
$cloneSucc0 = 0;
|
||||
$cloneFailRate0 = 0;
|
||||
if (!empty($ids0)) {
|
||||
$money0 = MemberQrcodeModel::where(1)
|
||||
->field('reward_price * reward_count AS reward_money0')
|
||||
->whereIn('id', $ids0)
|
||||
->select()
|
||||
->reduce(function ($money, $item) {
|
||||
return $money + $item['reward_money0'];
|
||||
});
|
||||
$xinyue0 = MemberQrcodeModel::where(1)
|
||||
->whereIn('id', $ids0)
|
||||
->sum('settlement_count1');
|
||||
$qrIds0 = MemberQrcodeModel::where(1)
|
||||
->field('qr_id')
|
||||
->whereIn('id', $ids0)
|
||||
->where('qr_id', '>', 0)
|
||||
->select()
|
||||
->column('qr_id');
|
||||
if (!empty($qrIds0)) {
|
||||
$cloneSucc0 = CloneInfo::getCloneSuccCount1ByQrIds($qrIds0);
|
||||
}
|
||||
|
||||
if ($xinyue0 > 0) {
|
||||
$cloneFailRate0 = round(($xinyue0 - $cloneSucc0) / $xinyue0, 4) * 100;
|
||||
}
|
||||
}
|
||||
|
||||
$money1 = 0;
|
||||
$price1 = 0;
|
||||
$xinyue1 = 0;
|
||||
$cloneSucc1 = 0;
|
||||
$cloneFailRate1 = 0;
|
||||
if (!empty($ids1)) {
|
||||
$money1 = MemberQrcodeModel::where(1)
|
||||
->field('reward_price2 * reward_count2 AS reward_money0')
|
||||
->whereIn('id', $ids1)
|
||||
->select()
|
||||
->reduce(function ($money, $item) {
|
||||
return $money + $item['reward_money0'];
|
||||
});
|
||||
$xinyue1 = MemberQrcodeModel::where(1)
|
||||
->whereIn('id', $ids1)
|
||||
->sum('settlement_count2');
|
||||
if ($cloneSucc1 > 0) {
|
||||
$price1 = floatval(round($money1 / $cloneSucc1, 2));
|
||||
}
|
||||
|
||||
$qrIds1 = MemberQrcodeModel::where(1)
|
||||
->field('qr_id')
|
||||
->whereIn('id', $ids1)
|
||||
->where('qr_id', '>', 0)
|
||||
->select()
|
||||
->column('qr_id');
|
||||
if (!empty($qrIds1)) {
|
||||
$cloneSucc1 = CloneInfo::getCloneSuccCount2ByQrIds($qrIds1);
|
||||
}
|
||||
|
||||
if ($xinyue1 > 0) {
|
||||
$cloneFailRate1 = round(($xinyue1 - $cloneSucc1) / $xinyue1, 4) * 100;
|
||||
}
|
||||
}
|
||||
|
||||
$total = floatval(MemberMoneyModel::where(1)
|
||||
->where('create_time', '>=', strtotime(date('Ymd', $time)))
|
||||
->whereIn('type', MemberMoneyModel::rewardTypes())
|
||||
->sum('money'));
|
||||
|
||||
Utils::allocNumber($total, $money0, $money1);
|
||||
|
||||
if ($cloneSucc0 > 0) {
|
||||
$price0 = floatval(round($money0 / $cloneSucc0, 2));
|
||||
}
|
||||
if ($cloneSucc1 > 0) {
|
||||
$price1 = floatval(round($money1 / $cloneSucc1, 2));
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'scan0' => [
|
||||
'num' => count($ids0),
|
||||
'money' => floatval(round($money0, 2)),
|
||||
'price' => $price0,
|
||||
'xinyue' => $xinyue0,
|
||||
'clone_succ' => $cloneSucc0,
|
||||
'rate_clone_fail' => $cloneFailRate0,
|
||||
],
|
||||
'scan1' => [
|
||||
'num' => count($ids1),
|
||||
'money' => floatval(round($money1, 2)),
|
||||
'price' => $price1,
|
||||
'xinyue' => $xinyue1,
|
||||
'clone_succ' => $cloneSucc1,
|
||||
'rate_clone_fail' => $cloneFailRate1,
|
||||
],
|
||||
]);
|
||||
|
||||
}
|
||||
}
|
||||
228
Server/application/backend/controller/TaskController.php
Normal file
228
Server/application/backend/controller/TaskController.php
Normal file
@@ -0,0 +1,228 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\DeviceModel;
|
||||
use app\common\model\LogModel;
|
||||
use app\common\model\TaskDetailModel;
|
||||
use app\common\model\TaskModel;
|
||||
|
||||
class TaskController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 获取列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index() {
|
||||
$deviceId = intval($this->request->param('device_id'));
|
||||
$type = trim($this->request->param('type'));
|
||||
$runType = trim($this->request->param('run_type'));
|
||||
$status = trim($this->request->param('status'));
|
||||
$keywords = trim($this->request->param('keywords'));
|
||||
$pageNo = intval($this->request->param('page'));
|
||||
$pageSize = intval($this->request->param('pageSize'));
|
||||
if ($pageNo <= 0) {
|
||||
$pageNo = 1;
|
||||
}
|
||||
if ($pageSize <= 0) {
|
||||
$pageSize = 30;
|
||||
}
|
||||
|
||||
$query = TaskModel::where(1)
|
||||
->alias('t1')
|
||||
->field('t1.*')
|
||||
->leftJoin(
|
||||
DeviceModel::where(1)->getTable() . ' t2',
|
||||
't2.id = t1.device_id')
|
||||
->where('t1.is_deleted', TaskModel::IS_DELETED_NO);
|
||||
if (!empty($deviceId)) {
|
||||
$query->where('t1.device_id', $deviceId);
|
||||
}
|
||||
if (isset(TaskModel::typeAssoc()[$type])) {
|
||||
$query->where('t1.type', $type);
|
||||
}
|
||||
if (isset(TaskModel::statusAssoc()[$status])) {
|
||||
$query->where('t1.status', $status);
|
||||
}
|
||||
if (isset(TaskModel::runTypeAssoc()[$runType])) {
|
||||
$query->where('t1.run_type', $runType);
|
||||
}
|
||||
if (!empty($keywords)) {
|
||||
$query->whereLike('t2.number', '%' . $keywords . '%');
|
||||
}
|
||||
|
||||
$totalCount = $query->count();
|
||||
$pageCount = $totalCount > 0 ? ceil($totalCount / $pageSize) : 1;
|
||||
if ($pageNo > $pageCount) {
|
||||
$pageNo = $pageCount;
|
||||
}
|
||||
|
||||
$query->order('t1.id', 'DESC');
|
||||
$query->limit(($pageNo - 1) * $pageSize, $pageSize);
|
||||
|
||||
$list = [];
|
||||
foreach ($query->select() as $model) {
|
||||
$device = $model->device();
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
'device_number' => $device ? $device->number : '',
|
||||
'device_name' => $device ? $device->name : '',
|
||||
'device_online' => ($device AND $device->isOnline()) ? '在线' : '离线',
|
||||
'type_name' => TaskModel::typeAssoc()[$model->type],
|
||||
'run_type_name' => TaskModel::runTypeAssoc()[$model->run_type],
|
||||
'status_name' => TaskModel::statusAssoc()[$model->status],
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $list,
|
||||
'page' => $pageNo,
|
||||
'pageCount' => $pageCount,
|
||||
'totalCount' => $totalCount,
|
||||
'platforms' => $this->assocToList(TaskModel::platformAssoc()),
|
||||
'types' => $this->assocToList(TaskModel::typeAssoc()),
|
||||
'runTypes' => $this->assocToList(TaskModel::runTypeAssoc()),
|
||||
'statuses' => $this->assocToList(TaskModel::statusAssoc()),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 日志
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function log() {
|
||||
$id = intval($this->request->param('id'));
|
||||
if (empty($id)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
$detail = TaskDetailModel::where(1)
|
||||
->where('task_id', $id)
|
||||
->order('id', 'DESC')
|
||||
->find();
|
||||
if (empty($detail)) {
|
||||
return $this->jsonSucc([]);
|
||||
}
|
||||
|
||||
$list = [];
|
||||
foreach (LogModel::where(1)
|
||||
->where('task_id', $detail->id)
|
||||
->order('id', 'ASC')
|
||||
->select() as $model) {
|
||||
$list[] = [
|
||||
'id' => $model->id,
|
||||
'type' => $model->type,
|
||||
'message' => $model->message,
|
||||
'create_time' => $model->create_time,
|
||||
];
|
||||
}
|
||||
return $this->jsonSucc($list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function save() {
|
||||
$devices = $this->request->param('devices');
|
||||
$platform = trim($this->request->param('platform'));
|
||||
$type = trim($this->request->param('type'));
|
||||
$runType = trim($this->request->param('run_type'));
|
||||
$runTime = trim($this->request->param('run_time'));
|
||||
if (empty($devices)
|
||||
OR !is_array($devices)
|
||||
OR !isset(TaskModel::platformAssoc()[$platform])
|
||||
OR !isset(TaskModel::typeAssoc()[$type])
|
||||
OR !isset(TaskModel::runTypeAssoc()[$runType])) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
$timeTypes = [TaskModel::RUN_TYPE_TIMER, TaskModel::RUN_TYPE_DAILY];
|
||||
if (in_array($runType, $timeTypes)
|
||||
AND empty($runTime)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
$params = call_user_func_array(TaskModel::taskClasses()[$type] . '::params', [$this->request]);
|
||||
if (is_null($params)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
foreach ($devices as $deviceId) {
|
||||
$model = new TaskModel();
|
||||
$model->platform = $platform;
|
||||
$model->type = $type;
|
||||
$model->device_id = $deviceId;
|
||||
$model->params = $params;
|
||||
$model->run_type = $runType;
|
||||
$model->run_time = in_array($runType, $timeTypes) ? $runTime : '';
|
||||
$model->save();
|
||||
}
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function delete() {
|
||||
$id = intval($this->request->param('id'));
|
||||
if (empty($id)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
$model = TaskModel::get($id);
|
||||
if (empty($model)) {
|
||||
return $this->jsonFail('对象未找到');
|
||||
}
|
||||
|
||||
TaskDetailModel::where(1)
|
||||
->where('task_id', $model->id)
|
||||
->update([
|
||||
'is_deleted' => TaskModel::IS_DELETED_YES,
|
||||
]);
|
||||
|
||||
$model->is_deleted = TaskModel::IS_DELETED_YES;
|
||||
$model->save();
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量删除
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function batchDelete() {
|
||||
$ids = $this->request->param('ids');
|
||||
if (empty($ids) OR !is_array($ids)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
TaskDetailModel::where(1)
|
||||
->whereIn('task_id', $ids)
|
||||
->update([
|
||||
'is_deleted' => TaskModel::IS_DELETED_YES,
|
||||
]);
|
||||
|
||||
TaskModel::where(1)
|
||||
->whereIn('id', $ids)
|
||||
->update([
|
||||
'is_deleted' => TaskModel::IS_DELETED_YES,
|
||||
]);
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取执行方式
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function runTypeAssoc() {
|
||||
return $this->jsonSucc($this->assocToList(TaskModel::runTypeAssoc()));
|
||||
}
|
||||
}
|
||||
54
Server/application/backend/controller/UploadController.php
Normal file
54
Server/application/backend/controller/UploadController.php
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
class UploadController extends BaseLoginController {
|
||||
|
||||
// 上传图片
|
||||
public function index() {
|
||||
if (!empty($_FILES)
|
||||
AND !empty($_FILES['file'])
|
||||
AND is_uploaded_file($_FILES['file']['tmp_name'])) {
|
||||
$ext = strtolower(trim(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION)));
|
||||
$dir = ROOT_PATH . DS . 'public' . DS;
|
||||
$path = 'upload/' . $ext . '/' . date('Y-m-d') . '/' . time() . '-' . uniqid() . '.' . $ext;
|
||||
if (is_dir(dirname($dir . $path)) OR @mkdir(dirname($dir . $path), 0777, TRUE)) {
|
||||
if (move_uploaded_file($_FILES['file']['tmp_name'], $dir . $path)) {
|
||||
return json([
|
||||
'name' => $_FILES['file']['name'],
|
||||
'path' => $path,
|
||||
'url' => $this->absoluteUrl($path),
|
||||
], 200);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!empty($_FILES)) {
|
||||
return json([
|
||||
'url' => '',
|
||||
], 500);
|
||||
}
|
||||
}
|
||||
|
||||
public function editor() {
|
||||
if (!empty($_FILES)
|
||||
AND !empty($_FILES['upload'])
|
||||
AND is_uploaded_file($_FILES['upload']['tmp_name'])) {
|
||||
$ext = strtolower(trim(pathinfo($_FILES['upload']['name'], PATHINFO_EXTENSION)));
|
||||
$dir = ROOT_PATH . DS . 'public' . DS;
|
||||
$path = 'upload/' . $ext . '/' . date('Y-m-d') . '/' . time() . '-' . uniqid() . '.' . $ext;
|
||||
if (is_dir(dirname($dir . $path)) OR @mkdir(dirname($dir . $path), 0777, TRUE)) {
|
||||
if (move_uploaded_file($_FILES['upload']['tmp_name'], $dir . $path)) {
|
||||
return json([
|
||||
'uploaded' => true,
|
||||
'url' => $this->absoluteUrl($path),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return json([
|
||||
'uploaded' => false,
|
||||
'url' => '',
|
||||
]);
|
||||
}
|
||||
}
|
||||
114
Server/application/backend/controller/UserController.php
Executable file
114
Server/application/backend/controller/UserController.php
Executable file
@@ -0,0 +1,114 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\UserModel;
|
||||
use app\common\model\UserTokenModel;
|
||||
|
||||
class UserController extends BaseController {
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function login() {
|
||||
$username = trim($this->request->param('username'));
|
||||
$password = trim($this->request->param('password'));
|
||||
if (empty($username)
|
||||
OR empty($password)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
$user = UserModel::get([
|
||||
'username' => $username,
|
||||
'password' => md5($password),
|
||||
]);
|
||||
if (empty($user)) {
|
||||
return $this->jsonFail('账号/密码错误');
|
||||
}
|
||||
if ($user->status != UserModel::STATUS_ACTIVE) {
|
||||
return $this->jsonFail('账号不可用');
|
||||
}
|
||||
|
||||
$tokenModel = new UserTokenModel();
|
||||
$tokenModel->token = md5(time() . uniqid());
|
||||
$tokenModel->user_id = $user->id;
|
||||
if ($tokenModel->save()) {
|
||||
$user->login_time = time();
|
||||
$user->login_count += 1;
|
||||
$user->login_ip = $this->request->ip();
|
||||
if ($user->save()) {
|
||||
return $this->jsonSucc([
|
||||
'logged' => TRUE,
|
||||
'token' => $tokenModel->token,
|
||||
'token_expired' => 365 * 24 * 3600,
|
||||
'user' => $this->userJson($user),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->jsonFail('登录失败');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前登录用户
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function get() {
|
||||
if (!empty($this->userModel)) {
|
||||
return $this->jsonSucc([
|
||||
'logged' => TRUE,
|
||||
'user' => $this->userJson($this->userModel),
|
||||
]);
|
||||
} else {
|
||||
return $this->jsonSucc([
|
||||
'logged' => FALSE,
|
||||
'user' => NULL,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置密码
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function password() {
|
||||
if (empty($this->userModel)) {
|
||||
return $this->jsonFail('未登录');
|
||||
}
|
||||
|
||||
$oldPassword = trim($this->request->param('oldPassword'));
|
||||
$newPassword = trim($this->request->param('newPassword'));
|
||||
if (empty($oldPassword)
|
||||
OR empty($newPassword)
|
||||
OR strlen($newPassword) < 6
|
||||
OR strlen($newPassword) > 16) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
if (md5($oldPassword) != $this->userModel->password) {
|
||||
return $this->jsonFail('原密码输入错误');
|
||||
}
|
||||
|
||||
$this->userModel->password = md5($newPassword);
|
||||
$this->userModel->save();
|
||||
|
||||
return $this->jsonSucc([]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 登出
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function logout() {
|
||||
if (!empty($this->tokenModel)) {
|
||||
$this->tokenModel->delete();
|
||||
}
|
||||
|
||||
return $this->jsonSucc([]);
|
||||
}
|
||||
}
|
||||
85
Server/application/backend/controller/XianyuController.php
Normal file
85
Server/application/backend/controller/XianyuController.php
Normal file
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\XianyuModel;
|
||||
use think\db\Query;
|
||||
|
||||
class XianyuController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 闲鱼列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index() {
|
||||
$keywords = trim($this->request->param('keywords'));
|
||||
$pageNo = intval($this->request->param('page'));
|
||||
$pageSize = intval($this->request->param('pageSize'));
|
||||
if ($pageNo <= 0) {
|
||||
$pageNo = 1;
|
||||
}
|
||||
if ($pageSize <= 0) {
|
||||
$pageSize = 30;
|
||||
}
|
||||
|
||||
$query = XianyuModel::where(1);
|
||||
if (!empty($keywords)) {
|
||||
$query->where(function (Query $q) use ($keywords) {
|
||||
$q->whereLike('username', '%' . $keywords . '%', 'OR');
|
||||
$q->whereLike('nickname', '%' . $keywords . '%', 'OR');
|
||||
$q->whereLike('remark', '%' . $keywords . '%', 'OR');
|
||||
});
|
||||
}
|
||||
|
||||
$totalCount = $query->count();
|
||||
$pageCount = $totalCount > 0 ? ceil($totalCount / $pageSize) : 1;
|
||||
if ($pageNo > $pageCount) {
|
||||
$pageNo = $pageCount;
|
||||
}
|
||||
|
||||
$query->order('id', 'DESC');
|
||||
$query->limit(($pageNo - 1) * $pageSize, $pageSize);
|
||||
|
||||
$list = [];
|
||||
foreach ($query->select() as $model) {
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $list,
|
||||
'page' => $pageNo,
|
||||
'pageCount' => $pageCount,
|
||||
'totalCount' => $totalCount,
|
||||
]);
|
||||
}
|
||||
|
||||
public function update() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function remark() {
|
||||
$id = intval($this->request->param('id'));
|
||||
$remark = trim($this->request->param('remark'));
|
||||
if (empty($id)) {
|
||||
return $this->jsonFail('参数错误');
|
||||
}
|
||||
|
||||
$model = XianyuModel::get($id);
|
||||
if (empty($model)) {
|
||||
return $this->jsonFail('对象未找到');
|
||||
}
|
||||
|
||||
$model->remark = $remark;
|
||||
$model->save();
|
||||
|
||||
return $this->jsonSucc();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\DeviceModel;
|
||||
use app\common\model\XianyuProductModel;
|
||||
use app\common\model\XianyuModel;
|
||||
use think\db\Query;
|
||||
|
||||
class XianyuProductController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index() {
|
||||
$username = trim($this->request->param('username'));
|
||||
$onSale = trim($this->request->param('on_sale'));
|
||||
$keywords = trim($this->request->param('keywords'));
|
||||
$pageNo = intval($this->request->param('page'));
|
||||
$pageSize = intval($this->request->param('pageSize'));
|
||||
if ($pageNo <= 0) {
|
||||
$pageNo = 1;
|
||||
}
|
||||
if ($pageSize <= 0) {
|
||||
$pageSize = 30;
|
||||
}
|
||||
|
||||
$query = XianyuProductModel::where(1);
|
||||
if (!empty($username)) {
|
||||
$query->where('username', $username);
|
||||
}
|
||||
if (isset(XianyuProductModel::onSaleAssoc()[$onSale])) {
|
||||
$query->where('on_sale', $onSale);
|
||||
}
|
||||
|
||||
if (!empty($keywords)) {
|
||||
$query->where(function (Query $q) use ($keywords) {
|
||||
$q->whereLike('title', '%' . $keywords . '%', 'OR');
|
||||
});
|
||||
}
|
||||
|
||||
$totalCount = $query->count();
|
||||
$pageCount = $totalCount > 0 ? ceil($totalCount / $pageSize) : 1;
|
||||
if ($pageNo > $pageCount) {
|
||||
$pageNo = $pageCount;
|
||||
}
|
||||
|
||||
$query->order('id', 'DESC');
|
||||
$query->limit(($pageNo - 1) * $pageSize, $pageSize);
|
||||
|
||||
$list = [];
|
||||
foreach ($query->select() as $model) {
|
||||
$device = DeviceModel::get($model->device_id);
|
||||
$xianyu = XianyuModel::get(['username' => $model->username]);
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
'device_number' => $device ? $device->number : '',
|
||||
'on_sale_name' => XianyuProductModel::onSaleAssoc()[$model->on_sale],
|
||||
'nickname' => $xianyu ? $xianyu->nickname : '',
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $list,
|
||||
'page' => $pageNo,
|
||||
'pageCount' => $pageCount,
|
||||
'totalCount' => $totalCount,
|
||||
'xianyus' => $this->assocToList(XianyuModel::assoc()),
|
||||
'onSales' => $this->assocToList(XianyuProductModel::onSaleAssoc()),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\DeviceModel;
|
||||
use app\common\model\XianyuModel;
|
||||
use app\common\model\XianyuShopModel;
|
||||
use think\db\Query;
|
||||
|
||||
class XianyuShopController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index() {
|
||||
$username = trim($this->request->param('username'));
|
||||
$keywords = trim($this->request->param('keywords'));
|
||||
$pageNo = intval($this->request->param('page'));
|
||||
$pageSize = intval($this->request->param('pageSize'));
|
||||
if ($pageNo <= 0) {
|
||||
$pageNo = 1;
|
||||
}
|
||||
if ($pageSize <= 0) {
|
||||
$pageSize = 30;
|
||||
}
|
||||
|
||||
$query = XianyuShopModel::where(1);
|
||||
if (!empty($username)) {
|
||||
$query->where('username', $username);
|
||||
}
|
||||
if (!empty($keywords)) {
|
||||
$query->where(function (Query $q) use ($keywords) {
|
||||
//$q->whereLike('title', '%' . $keywords . '%', 'OR');
|
||||
});
|
||||
}
|
||||
|
||||
$totalCount = $query->count();
|
||||
$pageCount = $totalCount > 0 ? ceil($totalCount / $pageSize) : 1;
|
||||
if ($pageNo > $pageCount) {
|
||||
$pageNo = $pageCount;
|
||||
}
|
||||
|
||||
$query->order('id', 'DESC');
|
||||
$query->limit(($pageNo - 1) * $pageSize, $pageSize);
|
||||
|
||||
$list = [];
|
||||
foreach ($query->select() as $model) {
|
||||
$device = DeviceModel::get($model->device_id);
|
||||
$xianyu = XianyuModel::get(['username' => $model->username]);
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
'device_number' => $device ? $device->number : '',
|
||||
'nickname' => $xianyu ? $xianyu->nickname : '',
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $list,
|
||||
'page' => $pageNo,
|
||||
'pageCount' => $pageCount,
|
||||
'totalCount' => $totalCount,
|
||||
'xianyus' => $this->assocToList(XianyuModel::assoc()),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\controller;
|
||||
|
||||
use app\common\model\DeviceModel;
|
||||
use app\common\model\XianyuModel;
|
||||
use app\common\model\XianyuShopProductModel;
|
||||
use think\db\Query;
|
||||
|
||||
class XianyuShopProductController extends BaseLoginController {
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function index() {
|
||||
$username = trim($this->request->param('username'));
|
||||
$pay = trim($this->request->param('pay'));
|
||||
$keywords = trim($this->request->param('keywords'));
|
||||
$pageNo = intval($this->request->param('page'));
|
||||
$pageSize = intval($this->request->param('pageSize'));
|
||||
if ($pageNo <= 0) {
|
||||
$pageNo = 1;
|
||||
}
|
||||
if ($pageSize <= 0) {
|
||||
$pageSize = 30;
|
||||
}
|
||||
|
||||
$query = XianyuShopProductModel::where(1);
|
||||
if (!empty($username)) {
|
||||
$query->where('username', $username);
|
||||
}
|
||||
if (isset(XianyuShopProductModel::payAssoc()[$pay])) {
|
||||
$query->where('pay', $pay);
|
||||
}
|
||||
|
||||
if (!empty($keywords)) {
|
||||
$query->where(function (Query $q) use ($keywords) {
|
||||
$q->whereLike('title', '%' . $keywords . '%', 'OR');
|
||||
});
|
||||
}
|
||||
|
||||
$totalCount = $query->count();
|
||||
$pageCount = $totalCount > 0 ? ceil($totalCount / $pageSize) : 1;
|
||||
if ($pageNo > $pageCount) {
|
||||
$pageNo = $pageCount;
|
||||
}
|
||||
|
||||
$query->order('id', 'DESC');
|
||||
$query->limit(($pageNo - 1) * $pageSize, $pageSize);
|
||||
|
||||
$list = [];
|
||||
foreach ($query->select() as $model) {
|
||||
$device = DeviceModel::get($model->device_id);
|
||||
$xianyu = XianyuModel::get(['username' => $model->username]);
|
||||
$list[] = array_merge($model->toArray(), [
|
||||
'device_number' => $device ? $device->number : '',
|
||||
'pay_name' => XianyuShopProductModel::payAssoc()[$model->pay],
|
||||
'nickname' => $xianyu ? $xianyu->nickname : '',
|
||||
]);
|
||||
}
|
||||
|
||||
return $this->jsonSucc([
|
||||
'list' => $list,
|
||||
'page' => $pageNo,
|
||||
'pageCount' => $pageCount,
|
||||
'totalCount' => $totalCount,
|
||||
'xianyus' => $this->assocToList(XianyuModel::assoc()),
|
||||
'pays' => $this->assocToList(XianyuShopProductModel::payAssoc()),
|
||||
]);
|
||||
}
|
||||
}
|
||||
54
Server/application/backend/model/TimeRangeModel.php
Executable file
54
Server/application/backend/model/TimeRangeModel.php
Executable file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace app\backend\model;
|
||||
|
||||
class TimeRangeModel {
|
||||
|
||||
/**
|
||||
* 获取年
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function getYears() {
|
||||
$years = [];
|
||||
$timeS = strtotime(date('Y') . '-01-01');
|
||||
$timeE = strtotime((date('Y', $timeS) + 1) . '-01-01') - 1;
|
||||
for ($i = 0; $i > -3; $i --) {
|
||||
$years[] = [
|
||||
'key' => $i,
|
||||
'label' => date('Y 年', $timeS),
|
||||
'timeS' => $timeS,
|
||||
'timeE' => $timeE,
|
||||
];
|
||||
|
||||
$timeE = $timeS - 1;
|
||||
$timeS = strtotime(date('Y', $timeE) . '-01-01');
|
||||
}
|
||||
|
||||
return $years;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取月份
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function getMonths() {
|
||||
$months = [];
|
||||
$timeS = strtotime(date('Y-m') . '-01');
|
||||
$timeE = $timeS + date('t', $timeS) * 24 * 3600 - 1;
|
||||
for ($i = 0; $i > -24; $i --) {
|
||||
$months[] = [
|
||||
'key' => $i,
|
||||
'label' => date('Y 年 m 月', $timeS) . ' (' . date('Y.m.d', $timeS) . '-' . date('Y.m.d', $timeE) . ')',
|
||||
'timeS' => $timeS,
|
||||
'timeE' => $timeE,
|
||||
];
|
||||
|
||||
$timeS = strtotime(date('Y-m', $timeS - 1) . '-01');
|
||||
$timeE = $timeS + date('t', $timeS) * 24 * 3600 - 1;
|
||||
}
|
||||
|
||||
return $months;
|
||||
}
|
||||
}
|
||||
57
Server/application/backend/view/chart-day.php
Normal file
57
Server/application/backend/view/chart-day.php
Normal file
@@ -0,0 +1,57 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
|
||||
<style type="text/css">
|
||||
html, body {
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#main {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="main"></div>
|
||||
</body>
|
||||
<script type="text/javascript" src="/static/echarts/echarts.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
var chartDom = document.getElementById('main');
|
||||
var myChart = echarts.init(chartDom);
|
||||
var option = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {
|
||||
data: <?php echo json_encode($legend); ?>
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
},
|
||||
toolbox: {
|
||||
feature: {
|
||||
saveAsImage: {}
|
||||
}
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: <?php echo json_encode($xAxis); ?>
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value'
|
||||
},
|
||||
series: <?php echo json_encode($series); ?>
|
||||
};
|
||||
|
||||
option && myChart.setOption(option);
|
||||
</script>
|
||||
</html>
|
||||
14
Server/application/command.php
Executable file
14
Server/application/command.php
Executable file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: yunwuxin <448901948@qq.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
return [
|
||||
'test' => 'app\common\command\TestCommand',
|
||||
];
|
||||
12
Server/application/common.php
Executable file
12
Server/application/common.php
Executable file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: 流年 <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 应用公共文件
|
||||
65
Server/application/common/AliyunSMS.php
Executable file
65
Server/application/common/AliyunSMS.php
Executable file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace app\common;
|
||||
|
||||
use Darabonba\OpenApi\Models\Config;
|
||||
use AlibabaCloud\SDK\Dysmsapi\V20170525\Dysmsapi;
|
||||
use AlibabaCloud\SDK\Dysmsapi\V20170525\Models\SendSmsRequest;
|
||||
use AlibabaCloud\Tea\Utils\Utils\RuntimeOptions;
|
||||
|
||||
class AliyunSMS {
|
||||
|
||||
const ACCESS_KEY_ID = 'LTAI5tFjVRYAFmo6fayvv2Te';
|
||||
const ACCESS_KEY_SECRET = 'mdc7KETPGVon8PiA2kfM47rAOpJne8';
|
||||
const SIGN_NAME = '广州宏科网络';
|
||||
|
||||
const TC_VCODE = 'SMS_464445466';
|
||||
|
||||
static public function createClient() {
|
||||
$config = new Config([
|
||||
// AccessKey ID
|
||||
'accessKeyId' => static::ACCESS_KEY_ID,
|
||||
// AccessKey Secret
|
||||
'accessKeySecret' => static::ACCESS_KEY_SECRET
|
||||
]);
|
||||
|
||||
// 访问的域名
|
||||
$config->endpoint = 'dysmsapi.aliyuncs.com';
|
||||
|
||||
return new Dysmsapi($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送验证码
|
||||
*
|
||||
* @param $phoneNumbers
|
||||
* @param $templateCode
|
||||
* @param array $templateParam
|
||||
* @return bool
|
||||
*/
|
||||
static public function send($phoneNumbers, $templateCode, array $templateParam = array()) {
|
||||
$client = static::createClient();
|
||||
$sendSmsRequest = new SendSmsRequest([
|
||||
'phoneNumbers' => $phoneNumbers,
|
||||
'signName' => static::SIGN_NAME,
|
||||
'templateCode' => $templateCode,
|
||||
'templateParam' => json_encode($templateParam)
|
||||
]);
|
||||
$runtime = new RuntimeOptions([]);
|
||||
$logFile = ROOT_PATH . DS . 'aliyun-sms.txt';
|
||||
try {
|
||||
$data = $client->sendSmsWithOptions($sendSmsRequest, $runtime);
|
||||
if ($data->body->code === 'OK') {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
$logData = print_r($data, TRUE);
|
||||
} catch (\Exception $ex) {
|
||||
$logData = print_r($ex, TRUE);
|
||||
}
|
||||
|
||||
file_put_contents($logFile, '[' . date('Y-m-d H:i:s') . ']' . PHP_EOL . $logData . PHP_EOL . PHP_EOL, FILE_APPEND);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
122
Server/application/common/Fork.php
Normal file
122
Server/application/common/Fork.php
Normal file
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
|
||||
namespace app\common;
|
||||
|
||||
class Fork {
|
||||
|
||||
/**
|
||||
* 执行多条任务并等待所有任务执行完成后结束
|
||||
*
|
||||
* @param array $taskFuncs
|
||||
*/
|
||||
static public function wait(array $taskFuncs) {
|
||||
foreach ($taskFuncs as $i => $taskFunc) {
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == -1) {
|
||||
exit('Could not fork.');
|
||||
} elseif ($pid == 0) {
|
||||
call_user_func_array($taskFunc, [$i]);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
foreach ($taskFuncs as $taskFunc) {
|
||||
pcntl_wait($status);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 并发执行多条任务
|
||||
*
|
||||
* @param array $taskFuncs
|
||||
*/
|
||||
static public function invoke(array $taskFuncs) {
|
||||
$taskRuns = [];
|
||||
$signal = FALSE;
|
||||
if (function_exists('pcntl_async_signals')) {
|
||||
pcntl_async_signals(TRUE);
|
||||
}
|
||||
while (TRUE) {
|
||||
foreach ($taskFuncs as $i => $taskFunc) {
|
||||
if (!in_array($i, $taskRuns)) {
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == -1) {
|
||||
exit('Could not fork.');
|
||||
} elseif ($pid > 0) {
|
||||
$taskRuns[$pid] = $i;
|
||||
if (!$signal) {
|
||||
$signal = TRUE;
|
||||
static::signalHandler();
|
||||
}
|
||||
} else {
|
||||
call_user_func_array($taskFunc, [$i]);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($pid = pcntl_wait($status, WNOHANG)) {
|
||||
unset($taskRuns[$pid]);
|
||||
} else {
|
||||
sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 按指定数量并发执行相同任务
|
||||
*
|
||||
* @param $count
|
||||
* @param $taskFunc
|
||||
* @param int $destroy
|
||||
*/
|
||||
static public function execute($count, $taskFunc, $destroy = 100) {
|
||||
$runSum = 0;
|
||||
$runNum = 0;
|
||||
$signal = FALSE;
|
||||
if (function_exists('pcntl_async_signals')) {
|
||||
pcntl_async_signals(TRUE);
|
||||
}
|
||||
while (TRUE) {
|
||||
if ($runNum >= $count) {
|
||||
if (pcntl_wait($status, WNOHANG) > 0) {
|
||||
$runNum --;
|
||||
} else {
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
$pid = pcntl_fork();
|
||||
if ($pid == -1) {
|
||||
exit('Could not fork.');
|
||||
} elseif ($pid > 0) {
|
||||
$runSum ++;
|
||||
$runNum ++;
|
||||
if (!$signal) {
|
||||
$signal = TRUE;
|
||||
static::signalHandler();
|
||||
}
|
||||
} else {
|
||||
for ($i = 0; $i < $destroy; $i ++) {
|
||||
call_user_func_array($taskFunc, [$runSum % $count]);
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置信息处理器
|
||||
*
|
||||
*/
|
||||
static public function signalHandler() {
|
||||
$handler = function () {
|
||||
posix_kill(0, SIGKILL);
|
||||
exit(0);
|
||||
};
|
||||
pcntl_signal(SIGINT, $handler);
|
||||
pcntl_signal(SIGTERM, $handler);
|
||||
pcntl_signal(SIGUSR1, $handler);
|
||||
pcntl_signal(SIGUSR2, $handler);
|
||||
}
|
||||
}
|
||||
90
Server/application/common/Logger.php
Normal file
90
Server/application/common/Logger.php
Normal file
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace app\common;
|
||||
|
||||
class Logger {
|
||||
|
||||
const INFO = 'INFO';
|
||||
const WARN = 'WARN';
|
||||
const ERROR = 'ERROR';
|
||||
|
||||
static protected $loggers = [];
|
||||
|
||||
/**
|
||||
* 获取日志对象
|
||||
*
|
||||
* @param $name
|
||||
* @return Logger
|
||||
*/
|
||||
static public function _($name) {
|
||||
$lower = strtolower($name);
|
||||
if (!isset(static::$loggers[$lower])) {
|
||||
static::$loggers[$lower] = new Logger($name);
|
||||
}
|
||||
return static::$loggers[$lower];
|
||||
}
|
||||
|
||||
protected $name;
|
||||
protected $print = TRUE;
|
||||
|
||||
/**
|
||||
* Logger constructor.
|
||||
*
|
||||
* @param $name
|
||||
*/
|
||||
protected function __construct($name) {
|
||||
$this->name = $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入信息
|
||||
*
|
||||
* @param $message
|
||||
* @param array $params
|
||||
*/
|
||||
public function info($message, array $params = []) {
|
||||
$this->write(static::INFO, $message, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入警告
|
||||
*
|
||||
* @param $message
|
||||
* @param array $params
|
||||
*/
|
||||
public function warn($message, array $params = []) {
|
||||
$this->write(static::WARN, $message, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入错误
|
||||
*
|
||||
* @param $message
|
||||
* @param array $params
|
||||
*/
|
||||
public function error($message, array $params = []) {
|
||||
$this->write(static::ERROR, $message, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入日志
|
||||
*
|
||||
* @param $type
|
||||
* @param $message
|
||||
* @param array $params
|
||||
*/
|
||||
public function write($type, $message, array $params = []) {
|
||||
foreach ($params as $key => $value) {
|
||||
$message = str_replace('{' . $key . '}', $value, $message);
|
||||
}
|
||||
|
||||
$data = '[' . date('Y-m-d H:i:s') . '][' . $type . '] ' . $message . PHP_EOL;
|
||||
$file = ROOT_PATH . DS . 'runtime' . DS . $this->name . '_' . date('Ymd') . '.txt';
|
||||
|
||||
file_put_contents($file, $data, FILE_APPEND);
|
||||
|
||||
if ($this->print) {
|
||||
echo '[' . date('Y-m-d H:i:s') . '][' . $this->name . '][' . $type . '] ' . $message . PHP_EOL;;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Server/application/common/Utils.php
Normal file
36
Server/application/common/Utils.php
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
namespace app\common;
|
||||
|
||||
class Utils {
|
||||
|
||||
/**
|
||||
* 获取URL
|
||||
*
|
||||
* @param $url
|
||||
* @return string
|
||||
*/
|
||||
static public function absoluteUrl($url) {
|
||||
if (!empty($_SERVER['HTTP_HOST'])) {
|
||||
return (!empty($_SERVER['HTTPS']) ? 'https' : 'http')
|
||||
. '://' . $_SERVER['HTTP_HOST']
|
||||
. ($url{0} === '/' ? $url : '/' . $url);
|
||||
} else {
|
||||
return config('config.domain') . ($url{0} === '/' ? $url : '/' . $url);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算熟知
|
||||
*
|
||||
* @param $total
|
||||
* @param $number1
|
||||
* @param $number2
|
||||
*/
|
||||
static public function allocNumber($total, & $number1, & $number2) {
|
||||
if ($number1 > 0 OR $number2 > 0) {
|
||||
$number1 = $total * ($number1 / ($number1 + $number2));
|
||||
$number2 = $total - $number1;
|
||||
}
|
||||
}
|
||||
}
|
||||
101
Server/application/common/Video.php
Normal file
101
Server/application/common/Video.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
namespace app\common;
|
||||
|
||||
class Video {
|
||||
|
||||
/**
|
||||
* 图片合成视频
|
||||
*
|
||||
* @param array $images
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
*/
|
||||
static public function compositing(array $images) {
|
||||
if (empty($images)) {
|
||||
throw new \Exception('图片列表不能为空');
|
||||
}
|
||||
|
||||
// 设置视频参数
|
||||
$width = 800;
|
||||
$height = 600; // 4:3 比例
|
||||
$frameRate = 30; // 调整帧率为30fps,使动画更流畅
|
||||
|
||||
// 创建临时文件夹
|
||||
$tempDir = ROOT_PATH . DS . 'runtime' . DS . 'video_temp';
|
||||
if (!is_dir($tempDir)) {
|
||||
mkdir($tempDir, 0777, true);
|
||||
}
|
||||
|
||||
// 生成唯一的输出文件名
|
||||
$outputFile = $tempDir . DS . uniqid() . '.mp4';
|
||||
|
||||
// 准备图片列表文件
|
||||
$listFile = $tempDir . DS . uniqid() . '.txt';
|
||||
$content = '';
|
||||
|
||||
// 生成临时图片序列目录
|
||||
$tempImagesDir = $tempDir . DS . uniqid();
|
||||
if (!is_dir($tempImagesDir)) {
|
||||
mkdir($tempImagesDir, 0777, true);
|
||||
}
|
||||
|
||||
// 处理每张图片,生成临时文件
|
||||
$tempImages = [];
|
||||
foreach ($images as $index => $image) {
|
||||
if (!file_exists($image)) {
|
||||
throw new \Exception('图片不存在:' . $image);
|
||||
}
|
||||
$tempImage = $tempImagesDir . DS . sprintf('%04d.jpg', $index);
|
||||
copy($image, $tempImage);
|
||||
$tempImages[] = $tempImage;
|
||||
}
|
||||
|
||||
// 构建 FFmpeg 命令
|
||||
$filterComplex = [];
|
||||
|
||||
// 处理所有输入流的格式和缩放
|
||||
foreach ($tempImages as $i => $image) {
|
||||
$filterComplex[] = sprintf('[%d:v]format=yuv420p,scale=%d:%d:force_original_aspect_ratio=decrease,pad=%d:%d:(ow-iw)/2:(oh-ih)/2[v%d]',
|
||||
$i, $width, $height, $width, $height, $i);
|
||||
}
|
||||
|
||||
// 构建转场效果链
|
||||
$lastOutput = 'v0';
|
||||
for ($i = 1; $i < count($tempImages); $i++) {
|
||||
$filterComplex[] = sprintf('[%s][v%d]xfade=transition=fade:duration=1:offset=%d[fade%d]',
|
||||
$lastOutput, $i, ($i * 3) - 1, $i);
|
||||
$lastOutput = sprintf('fade%d', $i);
|
||||
}
|
||||
|
||||
$inputFiles = '';
|
||||
foreach ($tempImages as $image) {
|
||||
$inputFiles .= sprintf('-loop 1 -t %d -i "%s" ', count($tempImages) * 3, $image);
|
||||
}
|
||||
|
||||
$duration = count($tempImages) * 3 - (count($tempImages) - 1); // 总时长计算
|
||||
|
||||
$cmd = sprintf(
|
||||
'ffmpeg5 %s -filter_complex "%s" -map "[%s]" -t %d -c:v libx264 -pix_fmt yuv420p -r %d "%s" 2>&1',
|
||||
$inputFiles,
|
||||
implode(';', $filterComplex),
|
||||
$lastOutput,
|
||||
$duration,
|
||||
$frameRate,
|
||||
$outputFile
|
||||
);
|
||||
|
||||
// 执行命令
|
||||
exec($cmd, $output, $returnCode);
|
||||
|
||||
// 清理临时文件
|
||||
array_map('unlink', glob($tempImagesDir . DS . '*'));
|
||||
rmdir($tempImagesDir);
|
||||
|
||||
if ($returnCode !== 0) {
|
||||
throw new \Exception('视频生成失败:' . implode("\n", $output));
|
||||
}
|
||||
|
||||
return $outputFile;
|
||||
}
|
||||
}
|
||||
31
Server/application/common/command/BaseCommand.php
Executable file
31
Server/application/common/command/BaseCommand.php
Executable file
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\command;
|
||||
|
||||
use think\console\Command;
|
||||
|
||||
class BaseCommand extends Command {
|
||||
|
||||
protected $logSave = 1; // 1: 文件,2: 打印
|
||||
|
||||
/**
|
||||
* 写入日志
|
||||
*
|
||||
* @param $type
|
||||
* @param $message
|
||||
*/
|
||||
public function log($type, $message) {
|
||||
$data = '[' . date('Y-m-d H:i:s') . ']' . PHP_EOL;
|
||||
$data .= '[' . $type . '] ' . $message . PHP_EOL . PHP_EOL;
|
||||
|
||||
if ($this->logSave === 1) {
|
||||
$name = get_class($this);
|
||||
$name = substr($name, strrpos($name, '\\') + 1);
|
||||
$file = ROOT_PATH . DS . 'runtime' . DS . $name . '_' . date('Ymd') . '.txt';
|
||||
|
||||
file_put_contents($file, $data, FILE_APPEND);
|
||||
} else {
|
||||
echo $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
20
Server/application/common/command/TestCommand.php
Executable file
20
Server/application/common/command/TestCommand.php
Executable file
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\command;
|
||||
|
||||
use think\console\Input;
|
||||
use think\console\Output;
|
||||
|
||||
class TestCommand extends BaseCommand {
|
||||
|
||||
protected $logSave = 2;
|
||||
|
||||
protected function configure() {
|
||||
$this->setName('Test')
|
||||
->setDescription('command test.');
|
||||
}
|
||||
|
||||
protected function execute(Input $input, Output $output) {
|
||||
print_r('hello test.');
|
||||
}
|
||||
}
|
||||
69
Server/application/common/model/DeviceModel.php
Normal file
69
Server/application/common/model/DeviceModel.php
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class DeviceModel extends Model {
|
||||
|
||||
const ACTIVE_TIME = 60;
|
||||
|
||||
const IS_ONLINE_NO = 0;
|
||||
const IS_ONLINE_YES = 10;
|
||||
|
||||
const STATUS_ACTIVE = 0;
|
||||
const STATUS_DISABLE = 99;
|
||||
|
||||
/**
|
||||
* 获取关联数组
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function assoc() {
|
||||
static $assoc = NULL;
|
||||
if (is_null($assoc)) {
|
||||
$assoc = [];
|
||||
foreach (static::where(1)
|
||||
->order('id', 'DESC')
|
||||
->select() as $model) {
|
||||
$assoc[$model->getAttr('id')] = $model->getAttr('number')
|
||||
. ($model->isOnline() ? '[在线]' : '[离线]');
|
||||
}
|
||||
}
|
||||
return $assoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否在线
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
static public function isOnlineAssoc() {
|
||||
return [
|
||||
static::IS_ONLINE_YES => '在线',
|
||||
static::IS_ONLINE_NO => '离线',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取状态
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
static public function statusAssoc() {
|
||||
return [
|
||||
static::STATUS_ACTIVE => '正常',
|
||||
static::STATUS_DISABLE => '停用',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备是否在线
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isOnline() {
|
||||
return $this->getAttr('is_online') == static::IS_ONLINE_YES
|
||||
AND time() - $this->getAttr('active_time') <= static::ACTIVE_TIME;
|
||||
}
|
||||
}
|
||||
16
Server/application/common/model/TaskDetailModel.php
Normal file
16
Server/application/common/model/TaskDetailModel.php
Normal file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class TaskDetailModel extends Model {
|
||||
|
||||
const STATUS_AWAIT = 0;
|
||||
const STATUS_RUNNING = 10;
|
||||
const STATUS_SUCC = 20;
|
||||
const STATUS_FAIL = 99;
|
||||
|
||||
protected $json = ['params', 'info'];
|
||||
protected $jsonAssoc = TRUE;
|
||||
}
|
||||
159
Server/application/common/model/TaskModel.php
Normal file
159
Server/application/common/model/TaskModel.php
Normal file
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class TaskModel extends Model {
|
||||
|
||||
const PLATFORM_XIANYU = 'XIANYU';
|
||||
|
||||
const TYPE_PRODUCT_RELEASE = 'PRODUCT_RELEASE';
|
||||
const TYPE_PRODUCT_POLISH = 'PRODUCT_POLISH';
|
||||
const TYPE_PRODUCT_ON = 'PRODUCT_ON';
|
||||
const TYPE_PRODUCT_OFF = 'PRODUCT_OFF';
|
||||
const TYPE_COIN_SIGN = 'COIN_SIGN';
|
||||
const TYPE_COIN_DEDUCT = 'COIN_DEDUCT';
|
||||
const TYPE_PRICE_CUT = 'PRICE_CUT';
|
||||
const TYPE_COMMENT_REMOVE = 'COMMENT_REMOVE';
|
||||
const TYPE_PRODUCT_RE_RELEASE = 'PRODUCT_RE_RELEASE';
|
||||
const TYPE_RAISE_XY = 'RAISE_XY';
|
||||
const TYPE_RAISE_XY_TZ = 'RAISE_XY_TZ';
|
||||
const TYPE_RAISE_XY_UNITY = 'RAISE_XY_UNITY';
|
||||
const TYPE_SYNC_USER = 'SYNC_USER';
|
||||
const TYPE_SYNC_SHOP = 'SYNC_SHOP';
|
||||
const TYPE_UPDATE_USER = 'UPDATE_USER';
|
||||
const TYPE_PRODUCT_WELFARE = 'PRODUCT_WELFARE';
|
||||
const TYPE_MESSAGE_REPLY = 'MESSAGE_REPLY';
|
||||
|
||||
const RUN_TYPE_ONCE = 'ONCE';
|
||||
const RUN_TYPE_TIMER = 'TIMER';
|
||||
const RUN_TYPE_DAILY = 'DAILY';
|
||||
|
||||
const STATUS_AWAIT = 0;
|
||||
const STATUS_ALLOC = 10;
|
||||
const STATUS_COMPLETE = 20;
|
||||
|
||||
const IS_DELETED_NO = 0;
|
||||
const IS_DELETED_YES = 10;
|
||||
|
||||
protected $json = ['params'];
|
||||
protected $jsonAssoc = TRUE;
|
||||
|
||||
/**
|
||||
* 获取类型
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
static public function typeAssoc() {
|
||||
return [
|
||||
static::TYPE_PRODUCT_RELEASE => '[闲鱼]发布商品',
|
||||
static::TYPE_PRODUCT_POLISH => '[闲鱼]擦亮商品',
|
||||
static::TYPE_PRODUCT_ON => '[闲鱼]上架商品',
|
||||
static::TYPE_PRODUCT_OFF => '[闲鱼]下架商品',
|
||||
static::TYPE_COIN_SIGN => '[闲鱼]签到鱼币',
|
||||
static::TYPE_COIN_DEDUCT => '[闲鱼]鱼币抵扣',
|
||||
static::TYPE_PRICE_CUT => '[闲鱼]一键降价',
|
||||
static::TYPE_COMMENT_REMOVE => '[闲鱼]删除留言',
|
||||
static::TYPE_PRODUCT_RE_RELEASE => '[闲鱼]编辑重复',
|
||||
static::TYPE_RAISE_XY => '[闲鱼]养号',
|
||||
static::TYPE_RAISE_XY_UNITY => '[闲鱼]互助养号',
|
||||
static::TYPE_RAISE_XY_TZ => '[闲鱼]会玩养号',
|
||||
static::TYPE_SYNC_USER => '[闲鱼]采集账号信息',
|
||||
static::TYPE_SYNC_SHOP => '[闲鱼]采集店铺信息',
|
||||
static::TYPE_UPDATE_USER => '[闲鱼]修改账号信息',
|
||||
static::TYPE_PRODUCT_WELFARE => '[闲鱼]公益宝贝',
|
||||
static::TYPE_MESSAGE_REPLY => '[闲鱼]消息回复',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取状态
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
static public function statusAssoc() {
|
||||
return [
|
||||
static::STATUS_AWAIT => '加入队列',
|
||||
static::STATUS_ALLOC => '准备运行',
|
||||
static::STATUS_COMPLETE => '运行成功',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取执行方式
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
static public function runTypeAssoc() {
|
||||
return [
|
||||
static::RUN_TYPE_ONCE => '立刻执行',
|
||||
static::RUN_TYPE_TIMER => '定时执行',
|
||||
static::RUN_TYPE_DAILY => '每天执行',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 平台
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
static public function platformAssoc() {
|
||||
return [
|
||||
static::PLATFORM_XIANYU => '闲鱼',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务类
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
static public function taskClasses() {
|
||||
return [
|
||||
static::TYPE_PRODUCT_RELEASE => '\app\common\task\ProductReleaseTask',
|
||||
static::TYPE_PRODUCT_POLISH => '\app\common\task\ProductPolishTask',
|
||||
static::TYPE_PRODUCT_ON => '\app\common\task\ProductOnTask',
|
||||
static::TYPE_PRODUCT_OFF => '\app\common\task\ProductOffTask',
|
||||
static::TYPE_COIN_SIGN => '\app\common\task\CoinSignTask',
|
||||
static::TYPE_COIN_DEDUCT => '\app\common\task\CoinDeductTask',
|
||||
static::TYPE_PRICE_CUT => '\app\common\task\PriceCutTask',
|
||||
static::TYPE_COMMENT_REMOVE => '\app\common\task\CommentRemoveTask',
|
||||
static::TYPE_PRODUCT_RE_RELEASE => '\app\common\task\ProductReReleaseTask',
|
||||
static::TYPE_RAISE_XY => '\app\common\task\RaiseXyTask',
|
||||
static::TYPE_RAISE_XY_UNITY => '\app\common\task\RaiseXyUnityTask',
|
||||
static::TYPE_RAISE_XY_TZ => '\app\common\task\RaiseXyTzTask',
|
||||
static::TYPE_SYNC_USER => '\app\common\task\SyncUserTask',
|
||||
static::TYPE_SYNC_SHOP => '\app\common\task\SyncShopTask',
|
||||
static::TYPE_UPDATE_USER => '\app\common\task\UpdateUserTask',
|
||||
static::TYPE_PRODUCT_WELFARE => '\app\common\task\ProductWelfareTask',
|
||||
static::TYPE_MESSAGE_REPLY => '\app\common\task\MessageReplyTask',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配到详情
|
||||
*
|
||||
* @param TaskModel $model
|
||||
* @return bool
|
||||
*/
|
||||
static public function toDetail(TaskModel $model) {
|
||||
$detail = new TaskDetailModel();
|
||||
$detail->setAttr('task_id', $model->getAttr('id'));
|
||||
$detail->setAttr('device_id', $model->getAttr('device_id'));
|
||||
$detail->setAttr('platform', $model->getAttr('platform'));
|
||||
$detail->setAttr('type', $model->getAttr('type'));
|
||||
$detail->setAttr('params', $model->getAttr('params'));
|
||||
$detail->setAttr('info', new \stdClass());
|
||||
return $detail->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取设备
|
||||
*
|
||||
* @return DeviceModel
|
||||
*/
|
||||
public function device() {
|
||||
return DeviceModel::get($this->getAttr('device_id'));
|
||||
}
|
||||
}
|
||||
39
Server/application/common/model/UserModel.php
Normal file
39
Server/application/common/model/UserModel.php
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class UserModel extends Model {
|
||||
|
||||
const STATUS_ACTIVE = 0; // 正常
|
||||
const STATUS_DISABLE = 99; // 禁用
|
||||
|
||||
/**
|
||||
* 获取状态
|
||||
*
|
||||
* @return string[]
|
||||
*/
|
||||
public static function statusAssoc() {
|
||||
return [
|
||||
static::STATUS_ACTIVE => '正常',
|
||||
static::STATUS_DISABLE => '禁用',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 只读
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $readonly = ['username'];
|
||||
|
||||
/**
|
||||
* JSON 字段
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $json = ['roles'];
|
||||
|
||||
protected $jsonAssoc = TRUE;
|
||||
}
|
||||
9
Server/application/common/model/UserTokenModel.php
Normal file
9
Server/application/common/model/UserTokenModel.php
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\model;
|
||||
|
||||
use think\Model;
|
||||
|
||||
class UserTokenModel extends Model {
|
||||
|
||||
}
|
||||
126
Server/application/common/socket/Events.php
Normal file
126
Server/application/common/socket/Events.php
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
namespace app\common\socket;
|
||||
|
||||
use app\common\Logger;
|
||||
use app\common\model\DeviceModel;
|
||||
use \GatewayWorker\Lib\Gateway;
|
||||
use Workerman\Worker;
|
||||
|
||||
/**
|
||||
* Worker 命令行服务类
|
||||
*/
|
||||
class Events {
|
||||
|
||||
const LOGGER = 'WS';
|
||||
|
||||
/**
|
||||
* onConnect 事件回调
|
||||
* 当客户端连接上gateway进程时(TCP三次握手完毕时)触发
|
||||
*
|
||||
* @access public
|
||||
* @param int $client_id
|
||||
* @return void
|
||||
*/
|
||||
public static function onConnect($client_id) {
|
||||
//echo '---------';
|
||||
}
|
||||
|
||||
/**
|
||||
* onWebSocketConnect 事件回调
|
||||
* 当客户端连接上gateway完成websocket握手时触发
|
||||
*
|
||||
* @param integer $client_id 断开连接的客户端client_id
|
||||
* @param mixed $data
|
||||
* @return void
|
||||
*/
|
||||
public static function onWebSocketConnect($clientId, $data) {
|
||||
try {
|
||||
// 清除原会话数据
|
||||
Gateway::setSession($clientId, []);
|
||||
|
||||
// 设置会话数据
|
||||
//Gateway::setSession($clientId, $client);
|
||||
|
||||
Logger::_(static::LOGGER)->info('连接成功: {id}', [
|
||||
'id' => $clientId,
|
||||
]);
|
||||
} catch (\Exception $ex) {
|
||||
Gateway::closeClient($clientId);
|
||||
|
||||
Logger::_(static::LOGGER)->info('连接错误: {id}|{error}', [
|
||||
'id' => $clientId,
|
||||
'error' => $ex->getMessage() . '<' . $ex->getCode() . '>',
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* onMessage 事件回调
|
||||
* 当客户端发来数据(Gateway进程收到数据)后触发
|
||||
*
|
||||
* @access public
|
||||
* @param int $client_id
|
||||
* @param mixed $data
|
||||
* @return void
|
||||
*/
|
||||
public static function onMessage($clientId, $data) {
|
||||
$json = @json_decode($data, TRUE);
|
||||
if (!empty($json)
|
||||
AND !empty($json['type'])
|
||||
AND is_array($json['data'])) {
|
||||
$session = Gateway::getSession($clientId);
|
||||
if (empty($session)) {
|
||||
throw new \Exception('获取SESSION失败: ' . $clientId);
|
||||
}
|
||||
|
||||
} else {
|
||||
Gateway::closeClient($clientId);
|
||||
|
||||
Logger::_(static::LOGGER)->error('消息错误: {id}|{data}', [
|
||||
'id' => $clientId,
|
||||
'data' => $data,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* onClose 事件回调 当用户断开连接时触发的方法
|
||||
*
|
||||
* @param integer $clientId 断开连接的客户端client_id
|
||||
* @return void
|
||||
*/
|
||||
public static function onClose($clientId) {
|
||||
Gateway::setSession($clientId, []);
|
||||
Logger::_(static::LOGGER)->info('连接关闭: {id}', [
|
||||
'id' => $clientId,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* onWorkerStart 事件回调
|
||||
* 当businessWorker进程启动时触发。每个进程生命周期内都只会触发一次
|
||||
*
|
||||
* @access public
|
||||
* @param \Workerman\Worker $businessWorker
|
||||
* @return void
|
||||
*/
|
||||
public static function onWorkerStart(Worker $businessWorker) {
|
||||
Logger::_(static::LOGGER)->info('进程启动: {id}', [
|
||||
'id' => $businessWorker->id,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* onWorkerStop 事件回调
|
||||
* 当businessWorker进程退出时触发。每个进程生命周期内都只会触发一次。
|
||||
*
|
||||
* @param \Workerman\Worker $businessWorker
|
||||
* @return void
|
||||
*/
|
||||
public static function onWorkerStop(Worker $businessWorker) {
|
||||
Logger::_(static::LOGGER)->info('进程关闭: {id}', [
|
||||
'id' => $businessWorker->id,
|
||||
]);
|
||||
}
|
||||
}
|
||||
16
Server/application/frontend/controller/IndexController.php
Executable file
16
Server/application/frontend/controller/IndexController.php
Executable file
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace app\frontend\controller;
|
||||
|
||||
use think\Controller;
|
||||
|
||||
class IndexController extends Controller {
|
||||
|
||||
/**
|
||||
* 跳转至后台登录页
|
||||
*
|
||||
*/
|
||||
public function index() {
|
||||
return $this->redirect('/admin/');
|
||||
}
|
||||
}
|
||||
14
Server/application/provider.php
Executable file
14
Server/application/provider.php
Executable file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 应用容器绑定定义
|
||||
return [
|
||||
];
|
||||
28
Server/application/tags.php
Executable file
28
Server/application/tags.php
Executable file
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2006~2018 http://thinkphp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: liu21st <liu21st@gmail.com>
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
// 应用行为扩展定义文件
|
||||
return [
|
||||
// 应用初始化
|
||||
'app_init' => [],
|
||||
// 应用开始
|
||||
'app_begin' => [],
|
||||
// 模块初始化
|
||||
'module_init' => [],
|
||||
// 操作开始执行
|
||||
'action_begin' => [],
|
||||
// 视图内容过滤
|
||||
'view_filter' => [],
|
||||
// 日志写入
|
||||
'log_write' => [],
|
||||
// 应用结束
|
||||
'app_end' => [],
|
||||
];
|
||||
Reference in New Issue
Block a user