存客宝应用接口初始化
This commit is contained in:
65
application/store/controller/BaseController.php
Normal file
65
application/store/controller/BaseController.php
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace app\store\controller;
|
||||
|
||||
use think\Controller;
|
||||
use think\facade\Config;
|
||||
use think\facade\Request;
|
||||
use think\facade\Response;
|
||||
use think\facade\Log;
|
||||
use app\common\controller\Api;
|
||||
use think\Db;
|
||||
use think\facade\Cache;
|
||||
|
||||
/**
|
||||
* 基础控制器
|
||||
*/
|
||||
class BaseController extends Api
|
||||
{
|
||||
protected $device = [];
|
||||
protected $userInfo = [];
|
||||
protected $cacheExpire = 3600; // 缓存过期时间:1小时
|
||||
|
||||
/**
|
||||
* 构造方法
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->userInfo = request()->userInfo;
|
||||
|
||||
// 生成缓存key
|
||||
$cacheKey = 'device_info_' . $this->userInfo['id'] . '_' . $this->userInfo['companyId'];
|
||||
|
||||
// 尝试从缓存获取设备信息
|
||||
$device = Cache::get($cacheKey);
|
||||
// 如果缓存不存在,则从数据库获取
|
||||
if (!$device) {
|
||||
$device = Db::name('device_user')
|
||||
->alias('du')
|
||||
->join('device d', 'd.id = du.deviceId','left')
|
||||
->join('device_wechat_login dwl', 'dwl.deviceId = du.deviceId','left')
|
||||
->join('wechat_account wa', 'dwl.wechatId = wa.wechatId','left')
|
||||
->where([
|
||||
'du.userId' => $this->userInfo['id'],
|
||||
'du.companyId' => $this->userInfo['companyId']
|
||||
])
|
||||
->field('d.*,wa.wechatId,wa.alias,wa.s2_wechatAccountId as wechatAccountId')
|
||||
->find();
|
||||
// 将设备信息存入缓存
|
||||
if ($device) {
|
||||
Cache::set($cacheKey, $device, $this->cacheExpire);
|
||||
}
|
||||
}
|
||||
$this->device = $device;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除设备信息缓存
|
||||
*/
|
||||
protected function clearDeviceCache()
|
||||
{
|
||||
$cacheKey = 'device_info_' . $this->userInfo['id'] . '_' . $this->userInfo['companyId'];
|
||||
Cache::rm($cacheKey);
|
||||
}
|
||||
}
|
||||
93
application/store/controller/CustomerController.php
Normal file
93
application/store/controller/CustomerController.php
Normal file
@@ -0,0 +1,93 @@
|
||||
<?php
|
||||
|
||||
namespace app\store\controller;
|
||||
|
||||
use app\common\controller\Api;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 客户管理控制器
|
||||
*/
|
||||
class CustomerController extends Api
|
||||
{
|
||||
protected $noNeedLogin = [];
|
||||
protected $noNeedRight = ['*'];
|
||||
|
||||
/**
|
||||
* 获取客户列表
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getList()
|
||||
{
|
||||
$params = $this->request->param();
|
||||
|
||||
// 获取分页参数
|
||||
$page = isset($params['page']) ? intval($params['page']) : 1;
|
||||
$pageSize = isset($params['pageSize']) ? intval($params['pageSize']) : 10;
|
||||
$userInfo = request()->userInfo;
|
||||
|
||||
$where = [];
|
||||
// 必要的查询条件
|
||||
$userId = $userInfo['id'];
|
||||
$companyId = $userInfo['companyId'];
|
||||
|
||||
if (empty($userId) || empty($companyId)) {
|
||||
return errorJson('缺少必要参数');
|
||||
}
|
||||
|
||||
// 构建查询条件
|
||||
$deviceIds = Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->order('id DESC')->column('deviceId');
|
||||
if (empty($deviceIds)) {
|
||||
return errorJson('设备不存在');
|
||||
}
|
||||
$wechatIds = [];
|
||||
foreach ($deviceIds as $deviceId) {
|
||||
$wechatIds[] = Db::name('device_wechat_login')
|
||||
->where(['deviceId' => $deviceId])
|
||||
->order('id DESC')
|
||||
->value('wechatId');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 搜索条件
|
||||
if (!empty($params['keyword'])) {
|
||||
$where['alias|nickname|wechatId'] = ['like', '%' . $params['keyword'] . '%'];
|
||||
}
|
||||
// if (!empty($params['email'])) {
|
||||
// $where['wa.bindEmail'] = ['like', '%' . $params['email'] . '%'];
|
||||
// }
|
||||
// if (!empty($params['name'])) {
|
||||
// $where['wa.accountRealName|wa.accountUserName|wa.nickname'] = ['like', '%' . $params['name'] . '%'];
|
||||
// }
|
||||
|
||||
// 构建查询
|
||||
$query = Db::table('s2_wechat_friend')
|
||||
->where($where)
|
||||
->whereIn('ownerWechatId',$wechatIds)
|
||||
->group('wechatId'); // 防止重复数据
|
||||
|
||||
// 克隆查询对象,用于计算总数
|
||||
$countQuery = clone $query;
|
||||
$total = $countQuery->count();
|
||||
|
||||
// 获取分页数据
|
||||
$list = $query->page($page, $pageSize)
|
||||
->order('id DESC')
|
||||
->select();
|
||||
|
||||
|
||||
// 格式化数据
|
||||
foreach ($list as &$item) {
|
||||
$item['labels'] = json_decode($item['labels'], true);
|
||||
$item['createTime'] = date('Y-m-d H:i:s', $item['createTime']);
|
||||
}
|
||||
unset($item);
|
||||
|
||||
return successJson([
|
||||
'list' => $list,
|
||||
'total' => $total
|
||||
], '获取成功');
|
||||
}
|
||||
}
|
||||
295
application/store/controller/FlowPackageController.php
Normal file
295
application/store/controller/FlowPackageController.php
Normal file
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
|
||||
namespace app\store\controller;
|
||||
|
||||
use app\common\controller\Api;
|
||||
use app\store\model\FlowPackageModel;
|
||||
use app\store\model\UserFlowPackageModel;
|
||||
use app\store\model\FlowPackageOrderModel;
|
||||
use think\facade\Config;
|
||||
|
||||
/**
|
||||
* 流量套餐控制器
|
||||
*/
|
||||
class FlowPackageController extends Api
|
||||
{
|
||||
protected $noNeedLogin = [];
|
||||
protected $noNeedRight = ['*'];
|
||||
|
||||
/**
|
||||
* 获取流量套餐列表
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getList()
|
||||
{
|
||||
$params = $this->request->param();
|
||||
|
||||
// 查询条件
|
||||
$where = [];
|
||||
|
||||
// 只获取未删除的数据
|
||||
$where[] = ['isDel', '=', 0];
|
||||
|
||||
// 套餐模型
|
||||
$model = new FlowPackageModel();
|
||||
|
||||
// 查询数据
|
||||
$list = $model->where($where)
|
||||
->field('id, name, tag, originalPrice, price, monthlyFlow, duration, privileges')
|
||||
->order('sort', 'asc')
|
||||
->select();
|
||||
|
||||
// 格式化返回数据,添加计算字段
|
||||
$result = [];
|
||||
foreach ($list as $item) {
|
||||
$result[] = [
|
||||
'id' => $item['id'],
|
||||
'name' => $item['name'],
|
||||
'tag' => $item['tag'],
|
||||
'originalPrice' => $item['originalPrice'],
|
||||
'price' => $item['price'],
|
||||
'monthlyFlow' => $item['monthlyFlow'],
|
||||
'duration' => $item['duration'],
|
||||
'discount' => $item->discount,
|
||||
'totalFlow' => $item->totalFlow,
|
||||
'privileges' => $item['privileges'],
|
||||
];
|
||||
}
|
||||
|
||||
return successJson($result, '获取成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取流量套餐详情
|
||||
*
|
||||
* @param int $id 套餐ID
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function detail($id)
|
||||
{
|
||||
if (empty($id)) {
|
||||
return errorJson('参数错误');
|
||||
}
|
||||
|
||||
// 套餐模型
|
||||
$model = new FlowPackageModel();
|
||||
|
||||
// 查询数据
|
||||
$info = $model->where('id', $id)->where('isDel', 0)->find();
|
||||
|
||||
if (empty($info)) {
|
||||
return errorJson('套餐不存在');
|
||||
}
|
||||
|
||||
// 格式化返回数据,添加计算字段
|
||||
$result = [
|
||||
'id' => $info['id'],
|
||||
'name' => $info['name'],
|
||||
'tag' => $info['tag'],
|
||||
'originalPrice' => $info['originalPrice'],
|
||||
'price' => $info['price'],
|
||||
'monthlyFlow' => $info['monthlyFlow'],
|
||||
'duration' => $info['duration'],
|
||||
'discount' => $info->discount,
|
||||
'totalFlow' => $info->totalFlow,
|
||||
'privileges' => $info['privileges'],
|
||||
];
|
||||
|
||||
return successJson($result, '获取成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示用户流量套餐使用情况
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function remainingFlow()
|
||||
{
|
||||
$params = $this->request->param();
|
||||
|
||||
$userInfo = request()->userInfo;
|
||||
// 获取用户ID,通常应该从会话或令牌中获取
|
||||
$userId = $userInfo['id'];
|
||||
|
||||
if (empty($userId)) {
|
||||
return errorJson('请先登录');
|
||||
}
|
||||
|
||||
// 获取用户当前有效的流量套餐
|
||||
$userPackage = UserFlowPackageModel::getUserActivePackage($userId);
|
||||
|
||||
if (empty($userPackage)) {
|
||||
return errorJson('您没有有效的流量套餐');
|
||||
}
|
||||
|
||||
// 获取套餐详情
|
||||
$packageId = $userPackage['packageId'];
|
||||
$flowPackage = FlowPackageModel::where('id', $packageId)->where('isDel', 0)->find();
|
||||
|
||||
if (empty($flowPackage)) {
|
||||
return errorJson('套餐信息不存在');
|
||||
}
|
||||
|
||||
// 计算剩余流量
|
||||
$totalFlow = $userPackage['totalFlow'] ?? $flowPackage->totalFlow; // 总流量
|
||||
$usedFlow = $userPackage['usedFlow'] ?? 0; // 已使用流量
|
||||
$remainingFlow = $totalFlow - $usedFlow; // 剩余流量
|
||||
$remainingFlow = $remainingFlow > 0 ? $remainingFlow : 0; // 确保不为负数
|
||||
|
||||
// 计算剩余天数
|
||||
$now = time();
|
||||
$expireTime = $userPackage['expireTime'];
|
||||
$remainingDays = ceil(($expireTime - $now) / 86400); // 向上取整,剩余天数
|
||||
$remainingDays = $remainingDays > 0 ? $remainingDays : 0; // 确保不为负数
|
||||
|
||||
// 剩余百分比
|
||||
$flowPercentage = $totalFlow > 0 ? round(($remainingFlow / $totalFlow) * 100, 1) : 0;
|
||||
$timePercentage = $userPackage['duration'] > 0 ?
|
||||
round(($remainingDays / ($userPackage['duration'] * 30)) * 100, 1) : 0;
|
||||
|
||||
// 返回数据
|
||||
$result = [
|
||||
'packageName' => $flowPackage['name'], // 套餐名称
|
||||
'remainingFlow' => $remainingFlow, // 剩余流量(人)
|
||||
'totalFlow' => $totalFlow, // 总流量(人)
|
||||
'flowPercentage' => $flowPercentage, // 剩余流量百分比
|
||||
'remainingDays' => $remainingDays, // 剩余天数
|
||||
'totalDays' => $userPackage['duration'] * 30, // 总天数(按30天/月计算)
|
||||
'timePercentage' => $timePercentage, // 剩余时间百分比
|
||||
'expireTime' => date('Y-m-d', $expireTime), // 到期日期
|
||||
'startTime' => date('Y-m-d', $userPackage['startTime']), // 开始日期
|
||||
];
|
||||
|
||||
return successJson($result, '获取成功');
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建流量采购订单
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function createOrder()
|
||||
{
|
||||
$params = $this->request->param();
|
||||
|
||||
$userInfo = request()->userInfo;
|
||||
// 获取用户ID,通常应该从会话或令牌中获取
|
||||
$userId = $userInfo['id'];
|
||||
|
||||
if (empty($userId)) {
|
||||
return errorJson('请先登录');
|
||||
}
|
||||
|
||||
// 获取套餐ID
|
||||
$packageId = isset($params['packageId']) ? intval($params['packageId']) : 0;
|
||||
|
||||
if (empty($packageId)) {
|
||||
return errorJson('请选择套餐');
|
||||
}
|
||||
|
||||
// 查询套餐信息
|
||||
$flowPackage = FlowPackageModel::where('id', $packageId)->where('isDel', 0)->find();
|
||||
|
||||
if (empty($flowPackage)) {
|
||||
return errorJson('套餐不存在');
|
||||
}
|
||||
|
||||
// 获取支付方式(可选)
|
||||
$payType = isset($params['payType']) ? $params['payType'] : 'wechat';
|
||||
|
||||
// 套餐价格和信息
|
||||
$amount = floatval($flowPackage['price']);
|
||||
$packageName = $flowPackage['name'];
|
||||
$duration = intval($flowPackage['duration']);
|
||||
$remark = isset($params['remark']) ? $params['remark'] : '';
|
||||
|
||||
// 处理金额为0的特殊情况
|
||||
if ($amount <= 0) {
|
||||
// 金额为0,无需支付,直接创建订单并设置为已支付
|
||||
$order = FlowPackageOrderModel::createOrder(
|
||||
$userId,
|
||||
$packageId,
|
||||
$packageName,
|
||||
0,
|
||||
$duration,
|
||||
'nopay',
|
||||
$remark
|
||||
);
|
||||
|
||||
if (!$order) {
|
||||
return errorJson('订单创建失败');
|
||||
}
|
||||
|
||||
// 创建用户流量套餐记录
|
||||
$this->createUserFlowPackage($userId, $packageId, $order['id']);
|
||||
|
||||
// 返回成功信息
|
||||
return successJson(['orderNo' => $order['orderNo'],'status' => 'success'], '购买成功');
|
||||
} else {
|
||||
// 创建正常需要支付的订单
|
||||
$order = FlowPackageOrderModel::createOrder(
|
||||
$userId,
|
||||
$packageId,
|
||||
$packageName,
|
||||
$amount,
|
||||
$duration,
|
||||
$payType,
|
||||
$remark
|
||||
);
|
||||
|
||||
if (!$order) {
|
||||
return errorJson('订单创建失败');
|
||||
}
|
||||
|
||||
// 返回订单信息,前端需要跳转到支付页面
|
||||
return successJson([
|
||||
'orderNo' => $order['orderNo'],
|
||||
'amount' => $amount,
|
||||
'payType' => $payType,
|
||||
'status' => 'pending'
|
||||
], '订单创建成功');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建用户流量套餐记录
|
||||
*
|
||||
* @param int $userId 用户ID
|
||||
* @param int $packageId 套餐ID
|
||||
* @param int $orderId 订单ID
|
||||
* @return bool
|
||||
*/
|
||||
private function createUserFlowPackage($userId, $packageId, $orderId)
|
||||
{
|
||||
// 获取套餐信息
|
||||
$flowPackage = FlowPackageModel::where('id', $packageId)->where('isDel', 0)->find();
|
||||
|
||||
if (empty($flowPackage)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 计算到期时间(当前时间 + 套餐时长(月) * 30天)
|
||||
$now = time();
|
||||
$expireTime = $now + (intval($flowPackage['duration']) * 30 * 86400);
|
||||
|
||||
// 用户流量套餐数据
|
||||
$data = [
|
||||
'userId' => $userId,
|
||||
'packageId' => $packageId,
|
||||
'orderId' => $orderId,
|
||||
'packageName' => $flowPackage['name'],
|
||||
'monthlyFlow' => $flowPackage['monthlyFlow'],
|
||||
'duration' => $flowPackage['duration'],
|
||||
'totalFlow' => $flowPackage->totalFlow, // 使用计算属性获取总流量
|
||||
'usedFlow' => 0,
|
||||
'startTime' => $now,
|
||||
'expireTime' => $expireTime,
|
||||
'status' => 1, // 1:有效 0:无效
|
||||
'isDel' => 0
|
||||
];
|
||||
|
||||
// 创建用户流量套餐记录
|
||||
return UserFlowPackageModel::create($data) ? true : false;
|
||||
}
|
||||
}
|
||||
43
application/store/controller/LoginController.php
Normal file
43
application/store/controller/LoginController.php
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
namespace app\store\controller;
|
||||
|
||||
use app\common\util\JwtUtil;
|
||||
use think\Db;
|
||||
use think\Controller;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
$deviceId = $this->request->param('deviceId', '');
|
||||
if (empty($deviceId)) {
|
||||
return errorJson('缺少必要参数');
|
||||
}
|
||||
|
||||
$user = Db::name('users')->alias('u')
|
||||
->field('u.*')
|
||||
->join('device_user du', 'u.id = du.userId and u.companyId = du.companyId')
|
||||
->join('device d', 'du.deviceId = d.id and u.companyId = du.companyId')
|
||||
->where(['d.deviceImei' => $deviceId, 'u.deleteTime' => 0, 'du.deleteTime' => 0, 'd.deleteTime' => 0])
|
||||
->find();
|
||||
if (empty($user)) {
|
||||
return errorJson('用户不存在');
|
||||
}
|
||||
$member = array_merge($user, [
|
||||
'lastLoginIp' => $this->request->ip(),
|
||||
'lastLoginTime' => time()
|
||||
]);
|
||||
|
||||
// 生成JWT令牌
|
||||
$token = JwtUtil::createToken($user, 86400 * 30);
|
||||
$token_expired = time() + 86400 * 30;
|
||||
|
||||
$data = [
|
||||
'member' => $member,
|
||||
'token' => $token,
|
||||
'token_expired' => $token_expired
|
||||
];
|
||||
return successJson($data, '登录成功');
|
||||
}
|
||||
}
|
||||
482
application/store/controller/StatisticsController.php
Normal file
482
application/store/controller/StatisticsController.php
Normal file
@@ -0,0 +1,482 @@
|
||||
<?php
|
||||
|
||||
namespace app\store\controller;
|
||||
|
||||
use app\store\model\WechatFriendModel;
|
||||
use app\store\model\WechatMessageModel;
|
||||
use app\store\model\TrafficOrderModel;
|
||||
use think\Db;
|
||||
|
||||
|
||||
/**
|
||||
* 数据统计控制器
|
||||
*/
|
||||
class StatisticsController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 获取数据概览
|
||||
*/
|
||||
public function getOverview()
|
||||
{
|
||||
try {
|
||||
$companyId = $this->userInfo['companyId'];
|
||||
$userId = $this->userInfo['id'];
|
||||
|
||||
// 构建查询条件
|
||||
$deviceIds = Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->order('id DESC')->column('deviceId');
|
||||
if (empty($deviceIds)) {
|
||||
return errorJson('设备不存在');
|
||||
}
|
||||
$ownerWechatIds = [];
|
||||
foreach ($deviceIds as $deviceId) {
|
||||
$ownerWechatIds[] = Db::name('device_wechat_login')
|
||||
->where(['deviceId' => $deviceId])
|
||||
->order('id DESC')
|
||||
->value('wechatId');
|
||||
}
|
||||
|
||||
$wechatAccountIds = Db::table('s2_wechat_account')->whereIn('wechatId', $ownerWechatIds)->column('id');
|
||||
|
||||
|
||||
// 获取时间范围
|
||||
$timeRange = $this->getTimeRange();
|
||||
$startTime = $timeRange['start_time'];
|
||||
$endTime = $timeRange['end_time'];
|
||||
$lastStartTime = $timeRange['last_start_time'];
|
||||
$lastEndTime = $timeRange['last_end_time'];
|
||||
|
||||
|
||||
// 1. 总客户数
|
||||
$totalCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('isDeleted', 0)
|
||||
->whereTime('createTime', '>=', $startTime)
|
||||
->whereTime('createTime', '<', $endTime)
|
||||
->count();
|
||||
|
||||
// 上期总客户数
|
||||
$lastTotalCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->whereTime('createTime', '>=', $lastStartTime)
|
||||
->whereTime('createTime', '<', $lastEndTime)
|
||||
->count();
|
||||
|
||||
// 2. 新增客户数
|
||||
$newCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->whereTime('createTime', '>=', $startTime)
|
||||
->whereTime('createTime', '<', $endTime)
|
||||
->count();
|
||||
|
||||
// 上期新增客户数
|
||||
$lastNewCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->whereTime('createTime', '>=', $lastStartTime)
|
||||
->whereTime('createTime', '<', $lastEndTime)
|
||||
->count();
|
||||
|
||||
//3. 互动次数
|
||||
$interactionCount = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->count();
|
||||
|
||||
// 上期互动次数
|
||||
$lastInteractionCount = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
|
||||
->where('createTime', '>=', $lastStartTime)
|
||||
->where('createTime', '<', $lastEndTime)
|
||||
->count();
|
||||
|
||||
// 4. RFM 平均值计算(不查询上期数据)
|
||||
$rfmStats = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('isDeleted', 0)
|
||||
->field('AVG(`R`) as avgR, AVG(`F`) as avgF, AVG(`M`) as avgM')
|
||||
->find();
|
||||
|
||||
// 处理查询结果,如果字段为null则默认为0
|
||||
$avgR = isset($rfmStats['avgR']) && $rfmStats['avgR'] !== null ? round((float)$rfmStats['avgR'], 2) : 0;
|
||||
$avgF = isset($rfmStats['avgF']) && $rfmStats['avgF'] !== null ? round((float)$rfmStats['avgF'], 2) : 0;
|
||||
$avgM = isset($rfmStats['avgM']) && $rfmStats['avgM'] !== null ? round((float)$rfmStats['avgM'], 2) : 0;
|
||||
|
||||
// 计算三者的平均值
|
||||
$avgRFM = ($avgR + $avgF + $avgM) / 3;
|
||||
$avgRFM = round($avgRFM, 2);
|
||||
|
||||
// 计算环比增长率
|
||||
$customerGrowth = $this->calculateGrowth($totalCustomers, $lastTotalCustomers);
|
||||
$newCustomerGrowth = $this->calculateGrowth($newCustomers, $lastNewCustomers);
|
||||
$interactionGrowth = $this->calculateGrowth($interactionCount, $lastInteractionCount);
|
||||
$data = [
|
||||
'total_customers' => [
|
||||
'value' => $totalCustomers,
|
||||
'growth' => $customerGrowth
|
||||
],
|
||||
'new_customers' => [
|
||||
'value' => $newCustomers,
|
||||
'growth' => $newCustomerGrowth
|
||||
],
|
||||
'interaction_count' => [
|
||||
'value' => $interactionCount,
|
||||
'growth' => $interactionGrowth
|
||||
],
|
||||
'conversion_rate' => [
|
||||
'value' => 10,
|
||||
'growth' => 15
|
||||
],
|
||||
'account_value' => [
|
||||
'avg_r' => $avgR,
|
||||
'avg_f' => $avgF,
|
||||
'avg_m' => $avgM,
|
||||
'avg_rfm' => $avgRFM
|
||||
]
|
||||
];
|
||||
|
||||
return successJson($data);
|
||||
} catch (\Exception $e) {
|
||||
return errorJson('获取数据概览失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取综合分析数据
|
||||
*/
|
||||
public function getComprehensiveAnalysis()
|
||||
{
|
||||
try {
|
||||
$companyId = $this->userInfo['companyId'];
|
||||
$userId = $this->userInfo['id'];
|
||||
|
||||
// 构建查询条件
|
||||
$deviceIds = Db::name('device_user')->where(['userId' => $userId, 'companyId' => $companyId])->order('id DESC')->column('deviceId');
|
||||
if (empty($deviceIds)) {
|
||||
return errorJson('设备不存在');
|
||||
}
|
||||
$ownerWechatIds = [];
|
||||
foreach ($deviceIds as $deviceId) {
|
||||
$ownerWechatIds[] = Db::name('device_wechat_login')
|
||||
->where(['deviceId' => $deviceId])
|
||||
->order('id DESC')
|
||||
->value('wechatId');
|
||||
}
|
||||
$wechatAccountIds = Db::table('s2_wechat_account')->whereIn('wechatId', $ownerWechatIds)->column('id');
|
||||
|
||||
// 获取时间范围
|
||||
$timeRange = $this->getTimeRange();
|
||||
$startTime = $timeRange['start_time'];
|
||||
$endTime = $timeRange['end_time'];
|
||||
$lastStartTime = $timeRange['last_start_time'];
|
||||
$lastEndTime = $timeRange['last_end_time'];
|
||||
|
||||
// ========== 1. 客户平均转化金额 ==========
|
||||
// 获取有订单的客户数(去重)
|
||||
$convertedCustomers = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->group('identifier')
|
||||
->column('identifier');
|
||||
$convertedCustomerCount = count($convertedCustomers);
|
||||
|
||||
// 总销售额
|
||||
$totalSales = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->sum('actualPay');
|
||||
$totalSales = $totalSales ?: 0;
|
||||
|
||||
// 客户平均转化金额
|
||||
$avgConversionAmount = $convertedCustomerCount > 0 ? round($totalSales / $convertedCustomerCount, 2) : 0;
|
||||
|
||||
// ========== 2. 价值指标 ==========
|
||||
// 销售总额(已计算)
|
||||
|
||||
// 平均订单金额(总订单数)
|
||||
$totalOrderCount = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->count();
|
||||
$avgOrderAmount = $totalOrderCount > 0 ? round($totalSales / $totalOrderCount, 2) : 0;
|
||||
|
||||
// 高价值客户(消费超过平均订单金额的客户)
|
||||
// 先获取每个客户的消费总额
|
||||
$customerTotalSpend = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->field('identifier, SUM(actualPay) as totalSpend')
|
||||
->group('identifier')
|
||||
->select();
|
||||
|
||||
$highValueCustomerCount = 0;
|
||||
$avgCustomerSpend = $convertedCustomerCount > 0 ? ($totalSales / $convertedCustomerCount) : 0;
|
||||
foreach ($customerTotalSpend as $customer) {
|
||||
if ($customer['totalSpend'] > $avgCustomerSpend) {
|
||||
$highValueCustomerCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// 高价值客户百分比
|
||||
$totalCustomersForCalc = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('isDeleted', 0)
|
||||
->count();
|
||||
$highValueCustomerPercent = $totalCustomersForCalc > 0 ? round(($highValueCustomerCount / $totalCustomersForCalc) * 100, 1) : 0;
|
||||
|
||||
// ========== 3. 增长趋势 ==========
|
||||
// 上期销售额
|
||||
$lastTotalSales = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('createTime', '>=', $lastStartTime)
|
||||
->where('createTime', '<', $lastEndTime)
|
||||
->sum('actualPay');
|
||||
$lastTotalSales = $lastTotalSales ?: 0;
|
||||
|
||||
// 周收益增长(金额差值)
|
||||
$weeklyRevenueGrowth = round($totalSales - $lastTotalSales, 2);
|
||||
|
||||
// 新客转化(新客户中有订单的人数)
|
||||
$newCustomers = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->column('wechatId');
|
||||
|
||||
// 获取新客户中有订单的(identifier 对应 wechatId)
|
||||
$newConvertedCustomers = 0;
|
||||
if (!empty($newCustomers)) {
|
||||
$newConvertedCustomers = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->whereIn('identifier', $newCustomers)
|
||||
->group('identifier')
|
||||
->count();
|
||||
}
|
||||
|
||||
// 活跃客户增长(有互动的客户)
|
||||
$activeCustomers = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->group('wechatFriendId')
|
||||
->count();
|
||||
|
||||
$lastActiveCustomers = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
|
||||
->where('createTime', '>=', $lastStartTime)
|
||||
->where('createTime', '<', $lastEndTime)
|
||||
->group('wechatFriendId')
|
||||
->count();
|
||||
|
||||
// 活跃客户增长(人数差值)
|
||||
$activeCustomerGrowth = $activeCustomers - $lastActiveCustomers;
|
||||
|
||||
// ========== 4. 客户活跃度 ==========
|
||||
// 按天统计每个客户的互动次数,然后分类
|
||||
// 高频互动用户数(平均每天3次以上)
|
||||
$days = max(1, ($endTime - $startTime) / 86400); // 计算天数
|
||||
$highFrequencyThreshold = $days * 3; // 高频阈值
|
||||
|
||||
$highFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->field('wechatFriendId, COUNT(*) as count')
|
||||
->group('wechatFriendId')
|
||||
->having('count > ' . $highFrequencyThreshold)
|
||||
->count();
|
||||
|
||||
// 中频互动用户数(平均每天1-3次)
|
||||
$midFrequencyThreshold = $days * 1;
|
||||
$midFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->field('wechatFriendId, COUNT(*) as count')
|
||||
->group('wechatFriendId')
|
||||
->having('count >= ' . $midFrequencyThreshold . ' AND count <= ' . $highFrequencyThreshold)
|
||||
->count();
|
||||
|
||||
// 低频互动用户数(少于平均每天1次)
|
||||
$lowFrequencyUsers = WechatMessageModel::whereIn('wechatAccountId', $wechatAccountIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->field('wechatFriendId, COUNT(*) as count')
|
||||
->group('wechatFriendId')
|
||||
->having('count < ' . $midFrequencyThreshold)
|
||||
->count();
|
||||
|
||||
$frequency_analysis = [
|
||||
['name' => '高频', 'value' => $highFrequencyUsers],
|
||||
['name' => '中频', 'value' => $midFrequencyUsers],
|
||||
['name' => '低频', 'value' => $lowFrequencyUsers]
|
||||
];
|
||||
|
||||
// ========== 5. 转化客户来源 ==========
|
||||
// 只统计有订单的客户来源(identifier 对应 wechatId)
|
||||
$convertedFriendIds = TrafficOrderModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->where('createTime', '>=', $startTime)
|
||||
->where('createTime', '<', $endTime)
|
||||
->group('identifier')
|
||||
->column('identifier');
|
||||
|
||||
$friendRecommend = 0;
|
||||
$wechatSearch = 0;
|
||||
$wechatGroup = 0;
|
||||
|
||||
if (!empty($convertedFriendIds)) {
|
||||
// 朋友推荐(有订单的)
|
||||
$friendRecommend = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->whereIn('wechatId', $convertedFriendIds)
|
||||
->whereIn('addFrom', [17, 1000017])
|
||||
->count();
|
||||
|
||||
// 微信搜索(有订单的)
|
||||
$wechatSearch = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->whereIn('wechatId', $convertedFriendIds)
|
||||
->whereIn('addFrom', [3, 15, 1000003, 1000015])
|
||||
->count();
|
||||
|
||||
// 微信群(有订单的)
|
||||
$wechatGroup = WechatFriendModel::whereIn('ownerWechatId', $ownerWechatIds)
|
||||
->whereIn('wechatId', $convertedFriendIds)
|
||||
->whereIn('addFrom', [14, 1000014])
|
||||
->count();
|
||||
}
|
||||
|
||||
$totalConvertedCustomers = $convertedCustomerCount;
|
||||
$otherSource = max(0, $totalConvertedCustomers - $friendRecommend - $wechatSearch - $wechatGroup);
|
||||
|
||||
// 计算百分比
|
||||
$calculatePercentage = function ($value) use ($totalConvertedCustomers) {
|
||||
if ($totalConvertedCustomers <= 0) return 0;
|
||||
return round(($value / $totalConvertedCustomers) * 100, 2);
|
||||
};
|
||||
|
||||
$sourceDistribution = [
|
||||
[
|
||||
'name' => '朋友推荐',
|
||||
'value' => $calculatePercentage($friendRecommend) . '%',
|
||||
'count' => $friendRecommend
|
||||
],
|
||||
[
|
||||
'name' => '微信搜索',
|
||||
'value' => $calculatePercentage($wechatSearch) . '%',
|
||||
'count' => $wechatSearch
|
||||
],
|
||||
[
|
||||
'name' => '微信群',
|
||||
'value' => $calculatePercentage($wechatGroup) . '%',
|
||||
'count' => $wechatGroup
|
||||
]
|
||||
];
|
||||
|
||||
// 构建返回数据
|
||||
$data = [
|
||||
'avg_conversion_amount' => $avgConversionAmount, // 客户平均转化金额
|
||||
'value_indicators' => [
|
||||
'total_sales' => round($totalSales, 2), // 销售总额
|
||||
'avg_order_amount' => $avgOrderAmount, // 平均订单金额
|
||||
'high_value_customers' => $highValueCustomerPercent . '%' // 高价值客户
|
||||
],
|
||||
'growth_trend' => [
|
||||
'weekly_revenue_growth' => $weeklyRevenueGrowth, // 周收益增长(金额)
|
||||
'new_customer_conversion' => $newConvertedCustomers, // 新客转化(人数)
|
||||
'active_customer_growth' => $activeCustomerGrowth // 活跃客户增长(人数差值)
|
||||
],
|
||||
'frequency_analysis' => $frequency_analysis, // 客户活跃度
|
||||
'source_distribution' => $sourceDistribution // 转化客户来源
|
||||
];
|
||||
|
||||
return successJson($data);
|
||||
} catch (\Exception $e) {
|
||||
return errorJson('获取互动分析数据失败:' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取时间范围
|
||||
*
|
||||
* @param bool $toTimestamp 是否将日期转为时间戳,默认为true
|
||||
* @return array 时间范围数组
|
||||
*/
|
||||
private function getTimeRange($toTimestamp = true)
|
||||
{
|
||||
// 可选:today, yesterday, this_week, last_week, this_month, this_quarter, this_year
|
||||
$timeType = input('time_type', 'this_week');
|
||||
|
||||
switch ($timeType) {
|
||||
case 'today': // 今日
|
||||
$startTime = date('Y-m-d');
|
||||
$endTime = date('Y-m-d', strtotime('+1 day'));
|
||||
$lastStartTime = date('Y-m-d', strtotime('-1 day')); // 昨日
|
||||
$lastEndTime = $startTime;
|
||||
break;
|
||||
|
||||
case 'yesterday': // 昨日
|
||||
$startTime = date('Y-m-d', strtotime('-1 day'));
|
||||
$endTime = date('Y-m-d');
|
||||
$lastStartTime = date('Y-m-d', strtotime('-2 day')); // 前日
|
||||
$lastEndTime = $startTime;
|
||||
break;
|
||||
|
||||
case 'this_week': // 本周
|
||||
$startTime = date('Y-m-d', strtotime('monday this week'));
|
||||
$endTime = date('Y-m-d', strtotime('monday next week'));
|
||||
$lastStartTime = date('Y-m-d', strtotime('monday last week')); // 上周一
|
||||
$lastEndTime = $startTime;
|
||||
break;
|
||||
|
||||
case 'last_week': // 上周
|
||||
$startTime = date('Y-m-d', strtotime('monday last week'));
|
||||
$endTime = date('Y-m-d', strtotime('monday this week'));
|
||||
$lastStartTime = date('Y-m-d', strtotime('monday last week', strtotime('last week'))); // 上上周一
|
||||
$lastEndTime = $startTime;
|
||||
break;
|
||||
|
||||
case 'this_month': // 本月
|
||||
$startTime = date('Y-m-01');
|
||||
$endTime = date('Y-m-d', strtotime(date('Y-m-01') . ' +1 month'));
|
||||
$lastStartTime = date('Y-m-01', strtotime('-1 month')); // 上月初
|
||||
$lastEndTime = $startTime;
|
||||
break;
|
||||
|
||||
case 'this_quarter': // 本季度
|
||||
$month = date('n');
|
||||
$quarter = ceil($month / 3);
|
||||
$startMonth = ($quarter - 1) * 3 + 1;
|
||||
$startTime = date('Y-') . str_pad($startMonth, 2, '0', STR_PAD_LEFT) . '-01';
|
||||
$endTime = date('Y-m-d', strtotime($startTime . ' +3 month'));
|
||||
// 上季度
|
||||
$lastStartTime = date('Y-m-d', strtotime($startTime . ' -3 month'));
|
||||
$lastEndTime = $startTime;
|
||||
break;
|
||||
|
||||
case 'this_year': // 本年度
|
||||
$startTime = date('Y-01-01');
|
||||
$endTime = (date('Y') + 1) . '-01-01';
|
||||
$lastStartTime = (date('Y') - 1) . '-01-01'; // 去年初
|
||||
$lastEndTime = $startTime;
|
||||
break;
|
||||
|
||||
default:
|
||||
$startTime = date('Y-m-d', strtotime('monday this week'));
|
||||
$endTime = date('Y-m-d', strtotime('monday next week'));
|
||||
$lastStartTime = date('Y-m-d', strtotime('monday last week'));
|
||||
$lastEndTime = $startTime;
|
||||
}
|
||||
|
||||
// 如果需要转换为时间戳
|
||||
if ($toTimestamp) {
|
||||
$startTime = strtotime($startTime);
|
||||
$endTime = strtotime($endTime);
|
||||
$lastStartTime = strtotime($lastStartTime);
|
||||
$lastEndTime = strtotime($lastEndTime);
|
||||
}
|
||||
|
||||
return [
|
||||
'start_time' => $startTime,
|
||||
'end_time' => $endTime,
|
||||
'last_start_time' => $lastStartTime,
|
||||
'last_end_time' => $lastEndTime
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算环比增长率
|
||||
*/
|
||||
private function calculateGrowth($current, $last)
|
||||
{
|
||||
if ($last == 0) {
|
||||
return $current > 0 ? 100 : 0;
|
||||
}
|
||||
return round((($current - $last) / $last) * 100, 1);
|
||||
}
|
||||
}
|
||||
151
application/store/controller/SystemConfigController.php
Normal file
151
application/store/controller/SystemConfigController.php
Normal file
@@ -0,0 +1,151 @@
|
||||
<?php
|
||||
|
||||
namespace app\store\controller;
|
||||
|
||||
use think\Db;
|
||||
use think\facade\Log;
|
||||
use app\store\controller\BaseController;
|
||||
|
||||
|
||||
/**
|
||||
* 系统设置控制器
|
||||
*/
|
||||
class SystemConfigController extends BaseController
|
||||
{
|
||||
protected $noNeedLogin = [];
|
||||
protected $noNeedRight = ['*'];
|
||||
|
||||
/**
|
||||
* 获取系统开关状态
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function getSwitchStatus()
|
||||
{
|
||||
try {
|
||||
// 获取设备ID
|
||||
$deviceId = $this->device['id'] ?? 0;
|
||||
if (!$deviceId) {
|
||||
return $this->error('设备不存在');
|
||||
}
|
||||
|
||||
// 从新表中获取配置
|
||||
$config = Db::name('device_taskconf')
|
||||
->where('deviceId', $deviceId)
|
||||
->field('id,autoLike,autoCustomerDev,groupMessageDeliver,autoGroup,contentSync,aiChat,autoReply,momentsSync')
|
||||
->find();
|
||||
|
||||
// 如果没有找到配置,创建默认配置
|
||||
if (empty($config)) {
|
||||
$taskConfig = [
|
||||
'deviceId' => $deviceId,
|
||||
'autoLike' => 0,
|
||||
'autoCustomerDev' => 0,
|
||||
'groupMessageDeliver' => 0,
|
||||
'autoGroup' => 0,
|
||||
'contentSync' => 0,
|
||||
'aiChat' => 0,
|
||||
'autoReply' => 0,
|
||||
'momentsSync' => 0,
|
||||
'companyId' => $this->device['companyId'] ?? 0,
|
||||
'createTime' => time(),
|
||||
'updateTime' => time()
|
||||
];
|
||||
|
||||
// 添加到数据库
|
||||
Db::name('device_taskconf')->insert($taskConfig);
|
||||
|
||||
// 返回默认配置
|
||||
return successJson($taskConfig);
|
||||
}
|
||||
|
||||
// 返回开关状态
|
||||
return successJson($config);
|
||||
|
||||
} catch (\Exception $e) {
|
||||
Log::error('获取开关状态异常:' . $e->getMessage());
|
||||
return $this->error('获取开关状态失败');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新系统开关状态
|
||||
*
|
||||
* @return \think\Response
|
||||
*/
|
||||
public function updateSwitchStatus()
|
||||
{
|
||||
try {
|
||||
// 获取参数
|
||||
if (empty($this->device)) {
|
||||
return errorJson('设备不存在');
|
||||
}
|
||||
|
||||
$switchName = $this->request->param('switchName');
|
||||
$deviceId = $this->device['id'];
|
||||
|
||||
if (empty($switchName)) {
|
||||
return errorJson('开关名称不能为空');
|
||||
}
|
||||
|
||||
// 验证开关名称是否有效
|
||||
$validSwitches = ['autoLike', 'autoCustomerDev', 'groupMessageDeliver', 'autoGroup', 'contentSync', 'aiChat', 'autoReply', 'momentsSync'];
|
||||
if (!in_array($switchName, $validSwitches)) {
|
||||
return errorJson('无效的开关名称');
|
||||
}
|
||||
|
||||
// 获取当前配置
|
||||
$taskConfig = Db::name('device_taskconf')
|
||||
->where('deviceId', $deviceId)
|
||||
->find();
|
||||
|
||||
// 如果没有找到配置,创建默认配置
|
||||
if (empty($taskConfig)) {
|
||||
$taskConfig = [
|
||||
'deviceId' => $deviceId,
|
||||
'autoLike' => 0,
|
||||
'autoCustomerDev' => 0,
|
||||
'groupMessageDeliver' => 0,
|
||||
'autoGroup' => 0,
|
||||
'contentSync' => 0,
|
||||
'aiChat' => 0,
|
||||
'autoReply' => 0,
|
||||
'momentsSync' => 0,
|
||||
'companyId' => $this->device['companyId'] ?? 0,
|
||||
'createTime' => time(),
|
||||
'updateTime' => time()
|
||||
];
|
||||
|
||||
// 设置要更新的开关
|
||||
$taskConfig[$switchName] = 1;
|
||||
|
||||
// 添加到数据库
|
||||
Db::name('device_taskconf')->insert($taskConfig);
|
||||
} else {
|
||||
// 更新指定开关状态
|
||||
$updateData = [
|
||||
$switchName => !$taskConfig[$switchName],
|
||||
'updateTime' => time()
|
||||
];
|
||||
|
||||
// 更新数据库
|
||||
$result = Db::name('device_taskconf')
|
||||
->where('deviceId', $deviceId)
|
||||
->update($updateData);
|
||||
|
||||
if ($result === false) {
|
||||
Log::error("更新设备{$switchName}开关状态失败,设备ID:{$deviceId}");
|
||||
return errorJson('更新失败');
|
||||
}
|
||||
}
|
||||
|
||||
// 清除缓存
|
||||
$this->clearDeviceCache();
|
||||
|
||||
return successJson([], '更新成功');
|
||||
|
||||
} catch (\Exception $e) {
|
||||
return errorJson('系统错误'. $e->getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
97
application/store/controller/TrafficPackage.php
Normal file
97
application/store/controller/TrafficPackage.php
Normal file
@@ -0,0 +1,97 @@
|
||||
<?php
|
||||
namespace app\store\controller;
|
||||
|
||||
use app\store\model\TrafficPackage as TrafficPackageModel;
|
||||
use think\Controller;
|
||||
|
||||
class TrafficPackage extends Controller
|
||||
{
|
||||
/**
|
||||
* 获取流量套餐列表
|
||||
*/
|
||||
public function getList()
|
||||
{
|
||||
$model = new TrafficPackageModel;
|
||||
|
||||
// 获取列表数据
|
||||
$list = $model->field([
|
||||
'id',
|
||||
'name',
|
||||
'tags',
|
||||
'originalPrice',
|
||||
'price',
|
||||
'monthlyTraffic',
|
||||
'duration',
|
||||
'privileges',
|
||||
'createTime'
|
||||
])->select();
|
||||
|
||||
// 处理数据
|
||||
$list = collection($list)->each(function($item) {
|
||||
// 添加计算字段
|
||||
$item['discount'] = $item->discount; // 折扣
|
||||
$item['totalTraffic'] = $item->totalTraffic; // 总流量
|
||||
// 确保特权是数组格式
|
||||
$item['privileges'] = $item->privileges; // 使用模型的获取器处理特权
|
||||
// 格式化时间
|
||||
$item['createTime'] = date('Y-m-d H:i:s', strtotime($item['createTime']));
|
||||
return $item;
|
||||
});
|
||||
return successJson($list,'获取成功');
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前套餐使用情况
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getUsage()
|
||||
{
|
||||
// 获取用户ID,可以从session或token中获取
|
||||
$userId = input('userId', 0, 'intval');
|
||||
if (empty($userId)) {
|
||||
return errorJson('请先登录');
|
||||
}
|
||||
|
||||
// 获取用户当前生效的套餐订单
|
||||
$order = model('TrafficPackageOrder')
|
||||
->where('userId', $userId)
|
||||
->where('status', 1) // 1表示生效中
|
||||
->where('expireTime', '>', time()) // 未过期
|
||||
->order('expireTime', 'desc') // 取最晚过期的
|
||||
->find();
|
||||
|
||||
if (empty($order)) {
|
||||
return errorJson('未找到有效的套餐');
|
||||
}
|
||||
|
||||
// 获取套餐详情
|
||||
$package = TrafficPackageModel::get($order['packageId']);
|
||||
if (empty($package)) {
|
||||
return errorJson('套餐信息不存在');
|
||||
}
|
||||
|
||||
// 计算套餐使用情况
|
||||
$totalUsers = $package['monthlyTraffic'] * $package['duration']; // 总人数
|
||||
$usedUsers = model('TrafficUsageLog')
|
||||
->where('orderId', $order['id'])
|
||||
->count(); // 已使用人数
|
||||
|
||||
// 计算剩余有效期(天数)
|
||||
$remainDays = ceil(($order['expireTime'] - time()) / (60 * 60 * 24));
|
||||
$remainDays = max(0, $remainDays); // 确保不会出现负数
|
||||
|
||||
$data = [
|
||||
'packageName' => $package['name'], // 套餐名称
|
||||
'totalUsers' => $totalUsers, // 总人数
|
||||
'usedUsers' => $usedUsers, // 已使用人数
|
||||
'remainUsers' => $totalUsers - $usedUsers, // 剩余可用人数
|
||||
'remainDays' => $remainDays, // 剩余有效期(天)
|
||||
'expireTime' => date('Y-m-d', $order['expireTime']), // 过期时间
|
||||
'usagePercent' => $totalUsers > 0 ? round(($usedUsers / $totalUsers) * 100, 1) : 0, // 使用百分比
|
||||
];
|
||||
|
||||
return successJson($data, '获取成功');
|
||||
}
|
||||
|
||||
}
|
||||
534
application/store/controller/VendorController.php
Normal file
534
application/store/controller/VendorController.php
Normal file
@@ -0,0 +1,534 @@
|
||||
<?php
|
||||
|
||||
namespace app\store\controller;
|
||||
|
||||
use app\store\model\VendorPackageModel;
|
||||
use app\store\model\VendorProjectModel;
|
||||
use app\store\model\VendorOrderModel;
|
||||
use think\facade\Log;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 套餐控制器
|
||||
*/
|
||||
class VendorController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 获取套餐列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getList()
|
||||
{
|
||||
try {
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$keyword = $this->request->param('keyword', '');
|
||||
$status = $this->request->param('status', '');
|
||||
|
||||
$where = [
|
||||
['isDel', '=', 0]
|
||||
];
|
||||
|
||||
// 关键词搜索
|
||||
if (!empty($keyword)) {
|
||||
$where[] = ['name', 'like', "%{$keyword}%"];
|
||||
}
|
||||
|
||||
// 状态筛选
|
||||
if ($status !== '') {
|
||||
$where[] = ['status', '=', $status];
|
||||
}
|
||||
|
||||
$list = VendorPackageModel::where($where)
|
||||
->order('id', 'desc')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
$total = VendorPackageModel::where($where)->count();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('获取套餐列表失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '获取失败:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取套餐详情
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
try {
|
||||
$id = $this->request->param('id', 0);
|
||||
|
||||
if (empty($id)) {
|
||||
return json(['code' => 400, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
// 查询套餐基本信息
|
||||
$package = VendorPackageModel::where([
|
||||
['id', '=', $id],
|
||||
['isDel', '=', 0]
|
||||
])->find();
|
||||
|
||||
if (empty($package)) {
|
||||
return json(['code' => 404, 'msg' => '套餐不存在']);
|
||||
}
|
||||
|
||||
// 查询项目列表
|
||||
$projects = VendorProjectModel::where([
|
||||
['packageId', '=', $id],
|
||||
['isDel', '=', 0]
|
||||
])->select();
|
||||
|
||||
$package['projects'] = $projects;
|
||||
|
||||
return json(['code' => 200, 'msg' => '获取成功', 'data' => $package]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('获取套餐详情失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '获取失败:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加套餐
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function add()
|
||||
{
|
||||
try {
|
||||
if (!$this->request->isPost()) {
|
||||
return json(['code' => 400, 'msg' => '请求方式错误']);
|
||||
}
|
||||
|
||||
$param = $this->request->post();
|
||||
|
||||
// 参数验证
|
||||
if (empty($param['name'])) {
|
||||
return json(['code' => 400, 'msg' => '套餐名称不能为空']);
|
||||
}
|
||||
|
||||
// 检查名称是否已存在
|
||||
$exists = VendorPackageModel::where([
|
||||
['name', '=', $param['name']],
|
||||
['isDel', '=', 0]
|
||||
])->find();
|
||||
|
||||
if ($exists) {
|
||||
return json(['code' => 400, 'msg' => '该套餐名称已存在']);
|
||||
}
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
// 创建套餐
|
||||
$package = new VendorPackageModel;
|
||||
$package->name = $param['name'];
|
||||
$package->originalPrice = $param['originalPrice'] ?? 0;
|
||||
$package->price = $param['price'] ?? 0;
|
||||
$package->discount = $param['discount'] ?? 0;
|
||||
$package->advancePayment = $param['advancePayment'] ?? 0;
|
||||
$package->tags = $param['tags'] ?? '';
|
||||
$package->description = $param['description'] ?? '';
|
||||
$package->cover = $param['cover'] ?? '';
|
||||
$package->status = $param['status'] ?? 1;
|
||||
$package->createTime = time();
|
||||
$package->updateTime = time();
|
||||
$package->save();
|
||||
|
||||
// 处理项目信息
|
||||
if (!empty($param['projects']) && is_array($param['projects'])) {
|
||||
foreach ($param['projects'] as $projectData) {
|
||||
if (empty($projectData['name'])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 创建项目
|
||||
$project = new VendorProjectModel;
|
||||
$project->packageId = $package->id;
|
||||
$project->name = $projectData['name'];
|
||||
$project->originalPrice = $projectData['originalPrice'] ?? 0;
|
||||
$project->price = $projectData['price'] ?? 0;
|
||||
$project->duration = $projectData['duration'] ?? 0;
|
||||
$project->image = $projectData['image'] ?? '';
|
||||
$project->detail = $projectData['detail'] ?? '';
|
||||
$project->createTime = time();
|
||||
$project->updateTime = time();
|
||||
$project->save();
|
||||
}
|
||||
}
|
||||
|
||||
Db::commit();
|
||||
return json(['code' => 200, 'msg' => '添加成功', 'data' => ['id' => $package->id]]);
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
Log::error('添加套餐失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '添加失败:' . $e->getMessage()]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('添加套餐异常:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '添加异常:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑套餐
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function edit()
|
||||
{
|
||||
try {
|
||||
if (!$this->request->isPost()) {
|
||||
return json(['code' => 400, 'msg' => '请求方式错误']);
|
||||
}
|
||||
|
||||
$param = $this->request->post();
|
||||
|
||||
// 参数验证
|
||||
if (empty($param['id'])) {
|
||||
return json(['code' => 400, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
if (empty($param['name'])) {
|
||||
return json(['code' => 400, 'msg' => '套餐名称不能为空']);
|
||||
}
|
||||
|
||||
// 检查套餐是否存在
|
||||
$package = VendorPackageModel::where([
|
||||
['id', '=', $param['id']],
|
||||
['isDel', '=', 0]
|
||||
])->find();
|
||||
|
||||
if (!$package) {
|
||||
return json(['code' => 404, 'msg' => '套餐不存在']);
|
||||
}
|
||||
|
||||
// 检查名称是否已存在
|
||||
$exists = VendorPackageModel::where([
|
||||
['name', '=', $param['name']],
|
||||
['id', '<>', $param['id']],
|
||||
['isDel', '=', 0]
|
||||
])->find();
|
||||
|
||||
if ($exists) {
|
||||
return json(['code' => 400, 'msg' => '该套餐名称已存在']);
|
||||
}
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
// 更新套餐
|
||||
$package->name = $param['name'];
|
||||
$package->originalPrice = $param['originalPrice'] ?? $package->originalPrice;
|
||||
$package->price = $param['price'] ?? $package->price;
|
||||
$package->discount = $param['discount'] ?? $package->discount;
|
||||
$package->advancePayment = $param['advancePayment'] ?? $package->advancePayment;
|
||||
$package->tags = $param['tags'] ?? $package->tags;
|
||||
$package->description = $param['description'] ?? $package->description;
|
||||
$package->cover = $param['cover'] ?? $package->cover;
|
||||
$package->status = $param['status'] ?? $package->status;
|
||||
$package->updateTime = time();
|
||||
$package->save();
|
||||
|
||||
Db::commit();
|
||||
return json(['code' => 200, 'msg' => '更新成功']);
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
Log::error('更新套餐失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '更新失败:' . $e->getMessage()]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('编辑套餐异常:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '编辑异常:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除套餐
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
try {
|
||||
$id = $this->request->param('id', 0);
|
||||
|
||||
if (empty($id)) {
|
||||
return json(['code' => 400, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
// 检查套餐是否存在
|
||||
$package = VendorPackageModel::where([
|
||||
['id', '=', $id],
|
||||
['isDel', '=', 0]
|
||||
])->find();
|
||||
|
||||
if (!$package) {
|
||||
return json(['code' => 404, 'msg' => '套餐不存在']);
|
||||
}
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
// 软删除套餐
|
||||
$package->isDel = 1;
|
||||
$package->updateTime = time();
|
||||
$package->save();
|
||||
|
||||
// 软删除关联的项目
|
||||
VendorProjectModel::where('packageId', $id)
|
||||
->update([
|
||||
'isDel' => 1,
|
||||
'updateTime' => time()
|
||||
]);
|
||||
|
||||
Db::commit();
|
||||
return json(['code' => 200, 'msg' => '删除成功']);
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
Log::error('删除套餐失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '删除失败:' . $e->getMessage()]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('删除套餐异常:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '删除异常:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加项目
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function addProject()
|
||||
{
|
||||
try {
|
||||
if (!$this->request->isPost()) {
|
||||
return json(['code' => 400, 'msg' => '请求方式错误']);
|
||||
}
|
||||
|
||||
$param = $this->request->post();
|
||||
|
||||
// 参数验证
|
||||
if (empty($param['packageId'])) {
|
||||
return json(['code' => 400, 'msg' => '套餐ID不能为空']);
|
||||
}
|
||||
|
||||
if (empty($param['name'])) {
|
||||
return json(['code' => 400, 'msg' => '项目名称不能为空']);
|
||||
}
|
||||
|
||||
// 检查套餐是否存在
|
||||
$package = VendorPackageModel::where([
|
||||
['id', '=', $param['packageId']],
|
||||
['isDel', '=', 0]
|
||||
])->find();
|
||||
|
||||
if (!$package) {
|
||||
return json(['code' => 404, 'msg' => '套餐不存在']);
|
||||
}
|
||||
|
||||
try {
|
||||
// 创建项目
|
||||
$project = new VendorProjectModel;
|
||||
$project->packageId = $param['packageId'];
|
||||
$project->name = $param['name'];
|
||||
$project->originalPrice = $param['originalPrice'] ?? 0;
|
||||
$project->price = $param['price'] ?? 0;
|
||||
$project->duration = $param['duration'] ?? 0;
|
||||
$project->image = $param['image'] ?? '';
|
||||
$project->detail = $param['detail'] ?? '';
|
||||
$project->createTime = time();
|
||||
$project->updateTime = time();
|
||||
$project->save();
|
||||
|
||||
return json(['code' => 200, 'msg' => '添加成功', 'data' => ['id' => $project->id]]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('添加项目失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '添加失败:' . $e->getMessage()]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('添加项目异常:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '添加异常:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑项目
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function editProject()
|
||||
{
|
||||
try {
|
||||
if (!$this->request->isPost()) {
|
||||
return json(['code' => 400, 'msg' => '请求方式错误']);
|
||||
}
|
||||
|
||||
$param = $this->request->post();
|
||||
|
||||
// 参数验证
|
||||
if (empty($param['id'])) {
|
||||
return json(['code' => 400, 'msg' => '项目ID不能为空']);
|
||||
}
|
||||
|
||||
if (empty($param['name'])) {
|
||||
return json(['code' => 400, 'msg' => '项目名称不能为空']);
|
||||
}
|
||||
|
||||
// 检查项目是否存在
|
||||
$project = VendorProjectModel::where([
|
||||
['id', '=', $param['id']],
|
||||
['isDel', '=', 0]
|
||||
])->find();
|
||||
|
||||
if (!$project) {
|
||||
return json(['code' => 404, 'msg' => '项目不存在']);
|
||||
}
|
||||
|
||||
try {
|
||||
// 更新项目
|
||||
$project->name = $param['name'];
|
||||
$project->originalPrice = $param['originalPrice'] ?? $project->originalPrice;
|
||||
$project->price = $param['price'] ?? $project->price;
|
||||
$project->duration = $param['duration'] ?? $project->duration;
|
||||
$project->image = $param['image'] ?? $project->image;
|
||||
$project->detail = $param['detail'] ?? $project->detail;
|
||||
$project->updateTime = time();
|
||||
$project->save();
|
||||
|
||||
return json(['code' => 200, 'msg' => '更新成功']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('更新项目失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '更新失败:' . $e->getMessage()]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('编辑项目异常:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '编辑异常:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除项目
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function deleteProject()
|
||||
{
|
||||
try {
|
||||
$id = $this->request->param('id', 0);
|
||||
|
||||
if (empty($id)) {
|
||||
return json(['code' => 400, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
// 检查项目是否存在
|
||||
$project = VendorProjectModel::where([
|
||||
['id', '=', $id],
|
||||
['isDel', '=', 0]
|
||||
])->find();
|
||||
|
||||
if (!$project) {
|
||||
return json(['code' => 404, 'msg' => '项目不存在']);
|
||||
}
|
||||
|
||||
try {
|
||||
// 软删除项目
|
||||
$project->isDel = 1;
|
||||
$project->updateTime = time();
|
||||
$project->save();
|
||||
|
||||
return json(['code' => 200, 'msg' => '删除成功']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('删除项目失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '删除失败:' . $e->getMessage()]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('删除项目异常:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '删除异常:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建订单
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function createOrder()
|
||||
{
|
||||
try {
|
||||
if (!$this->request->isPost()) {
|
||||
return json(['code' => 400, 'msg' => '请求方式错误']);
|
||||
}
|
||||
|
||||
$param = $this->request->post();
|
||||
|
||||
// 参数验证
|
||||
if (empty($param['packageId'])) {
|
||||
return json(['code' => 400, 'msg' => '套餐ID不能为空']);
|
||||
}
|
||||
|
||||
// 检查套餐是否存在
|
||||
$package = VendorPackageModel::where([
|
||||
['id', '=', $param['packageId']],
|
||||
['isDel', '=', 0],
|
||||
['status', '=', 1]
|
||||
])->find();
|
||||
|
||||
if (!$package) {
|
||||
return json(['code' => 404, 'msg' => '套餐不存在或已下架']);
|
||||
}
|
||||
|
||||
// 获取当前用户信息
|
||||
$userId = $this->request->userInfo['id'];
|
||||
|
||||
if (empty($userId)) {
|
||||
return json(['code' => 401, 'msg' => '请先登录']);
|
||||
}
|
||||
|
||||
Db::startTrans();
|
||||
try {
|
||||
// 生成订单
|
||||
$order = new VendorOrderModel;
|
||||
$order->orderNo = VendorOrderModel::generateOrderNo();
|
||||
$order->userId = $userId;
|
||||
$order->packageId = $package->id;
|
||||
$order->packageName = $package->name;
|
||||
$order->totalAmount = $package->price;
|
||||
$order->payAmount = $package->price;
|
||||
$order->advancePayment = $package->advancePayment;
|
||||
$order->status = VendorOrderModel::STATUS_UNPAID;
|
||||
$order->remark = $param['remark'] ?? '';
|
||||
$order->createTime = time();
|
||||
$order->updateTime = time();
|
||||
$order->save();
|
||||
|
||||
Db::commit();
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '订单创建成功',
|
||||
'data' => [
|
||||
'orderId' => $order->id,
|
||||
'orderNo' => $order->orderNo
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Db::rollback();
|
||||
Log::error('创建订单失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '创建订单失败:' . $e->getMessage()]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('创建订单异常:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '创建订单异常:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
229
application/store/controller/VendorOrderController.php
Normal file
229
application/store/controller/VendorOrderController.php
Normal file
@@ -0,0 +1,229 @@
|
||||
<?php
|
||||
|
||||
namespace app\store\controller;
|
||||
|
||||
use app\store\model\VendorPackageModel;
|
||||
use app\store\model\VendorProjectModel;
|
||||
use app\store\model\VendorOrderModel;
|
||||
use think\facade\Log;
|
||||
use think\Db;
|
||||
|
||||
/**
|
||||
* 订单控制器
|
||||
*/
|
||||
class VendorOrderController extends BaseController
|
||||
{
|
||||
/**
|
||||
* 获取订单列表
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function getList()
|
||||
{
|
||||
try {
|
||||
$page = $this->request->param('page', 1);
|
||||
$limit = $this->request->param('limit', 10);
|
||||
$status = $this->request->param('status', '');
|
||||
$keyword = $this->request->param('keyword', '');
|
||||
|
||||
// 获取当前用户信息
|
||||
$userId = $this->request->userInfo['id'];
|
||||
|
||||
$where = [
|
||||
['userId', '=', $userId]
|
||||
];
|
||||
|
||||
// 关键词搜索
|
||||
if (!empty($keyword)) {
|
||||
$where[] = ['orderNo|packageName', 'like', "%{$keyword}%"];
|
||||
}
|
||||
|
||||
// 状态筛选
|
||||
if ($status !== '') {
|
||||
$where[] = ['status', '=', $status];
|
||||
}
|
||||
|
||||
$list = VendorOrderModel::with(['package'])
|
||||
->where($where)
|
||||
->order('id', 'desc')
|
||||
->page($page, $limit)
|
||||
->select();
|
||||
|
||||
$total = VendorOrderModel::where($where)->count();
|
||||
|
||||
return json([
|
||||
'code' => 200,
|
||||
'msg' => '获取成功',
|
||||
'data' => [
|
||||
'list' => $list,
|
||||
'total' => $total,
|
||||
'page' => $page,
|
||||
'limit' => $limit
|
||||
]
|
||||
]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('获取订单列表失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '获取失败:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取订单详情
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function detail()
|
||||
{
|
||||
try {
|
||||
$id = $this->request->param('id', 0);
|
||||
|
||||
if (empty($id)) {
|
||||
return json(['code' => 400, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
// 获取当前用户信息
|
||||
$userId = $this->request->userInfo['id'];
|
||||
|
||||
// 查询订单
|
||||
$order = VendorOrderModel::with(['package'])
|
||||
->where([
|
||||
['id', '=', $id],
|
||||
['userId', '=', $userId]
|
||||
])->find();
|
||||
|
||||
if (empty($order)) {
|
||||
return json(['code' => 404, 'msg' => '订单不存在']);
|
||||
}
|
||||
|
||||
// 查询套餐项目
|
||||
if (!empty($order['package'])) {
|
||||
$projects = VendorProjectModel::where([
|
||||
['packageId', '=', $order['packageId']],
|
||||
['isDel', '=', 0]
|
||||
])->select();
|
||||
|
||||
$order['package']['projects'] = $projects;
|
||||
}
|
||||
|
||||
return json(['code' => 200, 'msg' => '获取成功', 'data' => $order]);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('获取订单详情失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '获取失败:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新订单状态
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function updateStatus()
|
||||
{
|
||||
try {
|
||||
if (!$this->request->isPost()) {
|
||||
return json(['code' => 400, 'msg' => '请求方式错误']);
|
||||
}
|
||||
|
||||
$param = $this->request->post();
|
||||
|
||||
// 参数验证
|
||||
if (empty($param['id'])) {
|
||||
return json(['code' => 400, 'msg' => '订单ID不能为空']);
|
||||
}
|
||||
|
||||
if (!isset($param['status'])) {
|
||||
return json(['code' => 400, 'msg' => '订单状态不能为空']);
|
||||
}
|
||||
|
||||
// 检查订单是否存在
|
||||
$order = VendorOrderModel::where('id', $param['id'])->find();
|
||||
|
||||
if (!$order) {
|
||||
return json(['code' => 404, 'msg' => '订单不存在']);
|
||||
}
|
||||
|
||||
// 检查状态是否有效
|
||||
$validStatus = [
|
||||
VendorOrderModel::STATUS_UNPAID,
|
||||
VendorOrderModel::STATUS_PAID,
|
||||
VendorOrderModel::STATUS_COMPLETED,
|
||||
VendorOrderModel::STATUS_CANCELED
|
||||
];
|
||||
|
||||
if (!in_array($param['status'], $validStatus)) {
|
||||
return json(['code' => 400, 'msg' => '无效的订单状态']);
|
||||
}
|
||||
|
||||
// 更新订单状态
|
||||
$updateData = [
|
||||
'status' => $param['status'],
|
||||
'updateTime' => time()
|
||||
];
|
||||
|
||||
// 如果订单状态为已支付,记录支付时间
|
||||
if ($param['status'] == VendorOrderModel::STATUS_PAID) {
|
||||
$updateData['payTime'] = time();
|
||||
}
|
||||
|
||||
try {
|
||||
$order->save($updateData);
|
||||
return json(['code' => 200, 'msg' => '更新成功']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('更新订单状态失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '更新失败:' . $e->getMessage()]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('更新订单状态异常:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '更新异常:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消订单
|
||||
*
|
||||
* @return \think\response\Json
|
||||
*/
|
||||
public function cancel()
|
||||
{
|
||||
try {
|
||||
if (!$this->request->isPost()) {
|
||||
return json(['code' => 400, 'msg' => '请求方式错误']);
|
||||
}
|
||||
|
||||
$id = $this->request->param('id', 0);
|
||||
|
||||
if (empty($id)) {
|
||||
return json(['code' => 400, 'msg' => '参数错误']);
|
||||
}
|
||||
|
||||
// 获取当前用户信息
|
||||
$userId = $this->request->userInfo['id'];
|
||||
|
||||
// 检查订单是否存在
|
||||
$order = VendorOrderModel::where([
|
||||
['id', '=', $id],
|
||||
['userId', '=', $userId],
|
||||
['status', '=', VendorOrderModel::STATUS_UNPAID]
|
||||
])->find();
|
||||
|
||||
if (!$order) {
|
||||
return json(['code' => 404, 'msg' => '订单不存在或状态不允许取消']);
|
||||
}
|
||||
|
||||
try {
|
||||
// 更新订单状态为已取消
|
||||
$order->status = VendorOrderModel::STATUS_CANCELED;
|
||||
$order->updateTime = time();
|
||||
$order->save();
|
||||
|
||||
return json(['code' => 200, 'msg' => '取消成功']);
|
||||
} catch (\Exception $e) {
|
||||
Log::error('取消订单失败:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '取消失败:' . $e->getMessage()]);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('取消订单异常:' . $e->getMessage());
|
||||
return json(['code' => 500, 'msg' => '取消异常:' . $e->getMessage()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user