初始化项目

This commit is contained in:
2026-09-01 22:15:50 +08:00
commit b5a26a8848
11217 changed files with 1710987 additions and 0 deletions
+155
View File
@@ -0,0 +1,155 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service;
use app\store\model\store\Api as ApiModel;
use app\store\model\store\MenuApi as MenuApiModel;
use app\store\model\store\UserRole as UserRoleModel;
use app\store\model\store\RoleMenu as RoleMenuModel;
use app\store\service\store\User as StoreUserService;
/**
* 商家后台权限业务
* Class Auth
* @package app\admin\service
*/
class Auth
{
// 实例句柄
static public $instance;
// 商家登录信息
private $store;
// 商家用户信息
private $user;
// 商家用户权限url
private $apiUrls = [];
/**
* 公有化获取实例方法
* @return Auth
*/
public static function getInstance()
{
if (!(self::$instance instanceof Auth)) {
self::$instance = new self;
}
return self::$instance;
}
/**
* 私有化构造方法
* Auth constructor.
*/
private function __construct()
{
// 商家登录信息
$this->store = StoreUserService::getLoginInfo();
// 当前用户信息
!empty($this->store) && $this->user = $this->store['user'];
}
/**
* 私有化克隆方法
*/
private function __clone()
{
}
/**
* 验证指定url是否有访问权限
* @param $url
* @param bool $strict 严格模式($url必须全部有权)
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function checkPrivilege($url, bool $strict = true)
{
if (!is_array($url)) {
return $this->checkAccess($url);
}
foreach ($url as $val) {
$status = $this->checkAccess($val);
if ($strict && !$status) return false;
if (!$strict && $status) return true;
}
return true;
}
/**
* 验证url的权限
* @param $url
* @return bool
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function checkAccess($url)
{
// 域名白名单
// config/allowapi.php
$allowApis = config('allowapi');
// 验证当前请求是否在白名单
if (in_array($url, $allowApis)) {
return true;
}
// 用户不存在 禁止访问
if (empty($this->user)) {
return false;
}
// 超级管理员无需验证
if ($this->user['is_super']) {
return true;
}
// 通配符支持
foreach ($allowApis as $action) {
if (strpos($action, '*') !== false
&& preg_match('/^' . str_replace('/', '\/', $action) . '/', $url)
) {
return true;
}
}
// 获取当前用户的权限url列表
if (!in_array($url, $this->getAccessUrls())) {
return false;
}
return true;
}
/**
* 获取当前用户的权限url列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private function getAccessUrls()
{
if (empty($this->apiUrls)) {
// 获取当前用户的角色ID集
$roleIds = UserRoleModel::getRoleIdsByUserId($this->user['store_user_id']);
// 获取已分配的菜单ID集
$menuIds = RoleMenuModel::getMenuIds($roleIds);
// 获取已分配的API的ID集
$apiIds = MenuApiModel::getApiIds($menuIds);
// 获取当前角色所有权限链接
$this->apiUrls = ApiModel::getApiUrls($apiIds);
}
return $this->apiUrls;
}
}
+44
View File
@@ -0,0 +1,44 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service;
use app\common\service\Goods as GoodsService;
use app\store\service\goods\Apply as GoodsApplyService;
/**
* 商品服务类
* Class Goods
* @package app\store\service
*/
class Goods extends GoodsService
{
/**
* 验证商品是否允许删除
* @param int $goodsId
* @return bool
*/
public static function checkIsAllowDelete(int $goodsId): bool
{
return GoodsApplyService::checkIsAllowDelete($goodsId);
}
/**
* 商品规格是否允许编辑
* @param int $goodsId
* @return bool
*/
public static function checkSpecLocked(int $goodsId): bool
{
return GoodsApplyService::checkSpecLocked($goodsId);
}
}
+245
View File
@@ -0,0 +1,245 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service;
use app\common\library\helper;
use app\common\service\BaseService;
use app\store\model\User as UserModel;
use app\store\model\Goods as GoodsModel;
use app\store\model\Order as OrderModel;
use app\store\model\OrderRefund as OrderRefundModel;
/**
* 商户数据服务类
* Class Store
* @package app\store\service
*/
class Home extends BaseService
{
/* @var GoodsModel $GoodsModel */
private $GoodsModel;
/* @var OrderModel $GoodsModel */
private $OrderModel;
/* @var UserModel $GoodsModel */
private $UserModel;
/**
* 构造方法
*/
public function __construct()
{
parent::__construct();
/* 初始化模型 */
$this->GoodsModel = new GoodsModel;
$this->OrderModel = new OrderModel;
$this->UserModel = new UserModel;
}
/**
* 后台首页数据
* @param array $user 管理员
* @return array
*/
public function getData($user): array
{
// 今天的日期
$today = date('Y-m-d');
// 昨天的日期
$yesterday = date('Y-m-d', strtotime('-1 day'));
// 最近七天日期
$lately7days = $this->getLately7days();
$data = [
// 实时概况
'overview' => [
// 销售额(元)
'orderTotalPrice' => [
'tday' => $this->getOrderTotalPrice($today, $user),
'ytd' => $this->getOrderTotalPrice($yesterday, $user)
],
// 支付订单数
'orderTotal' => [
'tday' => $this->getPayOrderTotal($today, $user),
'ytd' => $this->getPayOrderTotal($yesterday, $user)
],
// 新增会员数
'newUserTotal' => [
'tday' => $this->getUserTotal($today),
'ytd' => $this->getUserTotal($yesterday)
],
// 付款会员数
'consumeUserTotal' => [
'tday' => $this->getPayOrderUserTotal($today),
'ytd' => $this->getPayOrderUserTotal($yesterday)
]
],
// 数据统计
'statistics' => [
// 商品总数量
'goodsTotal' => $this->getGoodsTotal(),
// 会员总人数
'userTotal' => $this->getUserTotal(),
// 付款订单总量
'orderTotal' => $this->getPayOrderTotal(null),
// 付款订单总金额
'orderMoneyTotal' => $this->getOrderTotalPrice(null, $user),
// 消费总人数
'consumeUserTotal' => $this->getUserTotal(null, true)
],
// 待办事项
'pending' => [
// 待发货订单
'deliverOrderTotal' => $this->getNotDeliveredOrderTotal(),
// 待处理售后单
'refundTotal' => $this->getRefundTotal(),
// 待付款订单(笔)
'paidOrderTotal' => $this->getNotPayOrderTotal(),
// 已售罄商品数量
'soldoutGoodsTotal' => $this->getSoldoutGoodsTotal()
],
// 交易走势
'tradeTrend' => [
// 最近七天日期
'date' => $lately7days,
'orderTotal' => $this->getOrderTotalByDate($lately7days, $user),
'orderTotalPrice' => $this->getOrderTotalPriceByDate($lately7days, $user)
],
'power' => [
'super' => isset($user['is_super']) && $user['is_super'] == 1
]
];
return $data;
}
/**
* 最近七天日期
*/
private function getLately7days()
{
// 获取当前周几
$date = [];
for ($i = 0; $i < 7; $i++) {
$date[] = date('Y-m-d', strtotime('-' . $i . ' days'));
}
return array_reverse($date);
}
/**
* 获取商品总量
* @return string
*/
private function getGoodsTotal()
{
return number_format($this->GoodsModel->getGoodsTotal());
}
/**
* 会员总人数
* @param string $date 注册日期
* @param true $isConsume 是否已消费
* @return string
*/
private function getUserTotal(string $date = null, $isConsume = null)
{
return number_format($this->UserModel->getUserTotal(compact('date', 'isConsume')));
}
/**
* 获取已付款订单总量 (批量)
* @param array $days
* @param array $user
* @return array
*/
private function getOrderTotalByDate(array $days, $user = [])
{
$data = [];
foreach ($days as $day) {
$data[] = $this->getPayOrderTotal($day, $user);
}
return $data;
}
/**
* 获取订单总金额(指定日期)
* @param string $day
* @param array $user
* @return string
*/
private function getOrderTotalPrice(string $day = null, $user = [])
{
return helper::number2($this->OrderModel->getOrderTotalPrice($day, $day, $user));
}
/**
* 获取订单总金额 (批量)
* @param array $days
* @param array $user
* @return array
*/
private function getOrderTotalPriceByDate(array $days, $user = [])
{
$data = [];
foreach ($days as $day) {
$data[] = $this->getOrderTotalPrice($day, $user);
}
return $data;
}
/**
* 获取某天的下单用户数
* @param string $day
* @return float|int
*/
private function getPayOrderUserTotal(string $day)
{
return number_format($this->OrderModel->getPayOrderUserTotal($day));
}
/**
* 获取订单总量
* @param string $day
* @param array $user
* @return string
*/
private function getPayOrderTotal(string $day = null, $user = [])
{
return number_format($this->OrderModel->getPayOrderTotal($day, $day, $user));
}
// 获取未发货订单数量
private function getNotDeliveredOrderTotal()
{
return number_format($this->OrderModel->getNotDeliveredOrderTotal());
}
// 获取未付款订单数量
private function getNotPayOrderTotal()
{
return number_format($this->OrderModel->getNotPayOrderTotal());
}
// 获取已售罄的商品
private function getSoldoutGoodsTotal()
{
return number_format($this->GoodsModel->getSoldoutGoodsTotal());
}
// 获取待处理售后单数量
private function getRefundTotal()
{
$model = new OrderRefundModel;
return number_format($model->getRefundTotal());
}
}
@@ -0,0 +1,40 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service\goods;
use app\common\service\Goods as GoodsService;
class Apply extends GoodsService
{
/**
* 验证商品规格属性是否锁定
* @param int $goodsId
* @return bool
*/
public static function checkSpecLocked(int $goodsId): bool
{
// 这里实现业务判断
return false;
}
/**
* 验证商品是否允许删除
* @param int $goodsId
* @return bool
*/
public static function checkIsAllowDelete(int $goodsId): bool
{
// 这里实现业务判断
return true;
}
}
@@ -0,0 +1,260 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service\order;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
use app\store\model\{Order as OrderModel, order\Export as ExportModel, OrderAddress as OrderAddressModel};
use app\common\library\helper;
use app\common\service\BaseService;
use app\common\service\Goods as GoodsService;
use app\common\enum\order\{
PayType as PayTypeEnum,
PayStatus as PayStatusEnum,
OrderSource as OrderSourceEnum,
OrderStatus as OrderStatusEnum,
DeliveryType as DeliveryTypeEnum,
ReceiptStatus as ReceiptStatusEnum,
DeliveryStatus as DeliveryStatusEnum,
export\ExportStatus as ExportStatusEnum
};
use cores\exception\BaseException;
/**
* 服务层:订单导出Excel
* Class Export
* @package app\store\service\order
*/
class Export extends BaseService
{
// 表格文件标题名称
private $title = '订单导出结果';
/**
* 执行订单导出excel
* @param array $param
* @return bool
* @throws BaseException
*/
public function exportOrder(array $param): bool
{
// 根据条件查询订单列表
$orderList = $this->getOrderList($param);
// 格式化生成表格数据
$excelList = $this->getExcelList($orderList->toArray(), $param['columns']);
// 获取导出的记录列名集
$columns = $this->getColumns($param['columns']);
// 输出并写入到excel文件
$filePath = $this->outputExcel($columns, $excelList);
// 新增订单导出记录
$this->record($param, $filePath);
return true;
}
/**
* 根据条件查询订单列表
* @param array $param
* @return mixed
* @throws BaseException
*/
private function getOrderList(array $param)
{
// 根据条件查询订单列表
$model = new OrderModel;
$orderList = $model->getListAll(OrderModel::LIST_TYPE_ALL, $param);
if ($orderList->isEmpty()) {
throwError('很抱歉,没有查询到订单数据');
}
return $orderList;
}
/**
* 输出并写入到excel文件
* @param array $columns 列名
* @param array $excelList 表格内容
* @return string
* @throws BaseException
*/
private function outputExcel(array $columns, array $excelList): string
{
// 生成工作表
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet()->setTitle($this->title);
// 列宽
$sheet->getDefaultColumnDimension()->setWidth(24);
// 默认行高
$sheet->getDefaultRowDimension()->setRowHeight(20);
// 字体加粗(第一行)
$sheet->getStyle('1')->getFont()->setBold(true);
// 写入标题数据
foreach ($columns as $key => $val) {
$sheet->setCellValueByColumnAndRow($key + 1, 1, $val);
}
// 写入内容数据
foreach ($excelList as $key => $item) {
$row = $key + 2;
foreach (array_values($item) as $k => $val) {
$sheet->setCellValueByColumnAndRow($k + 1, $row, $val);
}
}
// 生成文件路径
$fileName = 'order-' . time() . '.xlsx';
$filePath = $this->getExportPath();
// 保存到文件
try {
$writer = new Xlsx($spreadsheet);
$writer->save(public_path() . $filePath . $fileName);
} catch (\PhpOffice\PhpSpreadsheet\Writer\Exception $e) {
throwError($e->getMessage());
}
return $filePath . $fileName;
}
/**
* 获取导出的文件夹路径
* @return string
*/
private function getExportPath(): string
{
$filePath = 'downloads/' . $this->getStoreId() . '/';
!is_dir($filePath) && mkdir($filePath, 0755, true);
return $filePath;
}
/**
* 写入订单导出记录
* @param array $param
* @param string $filePath
* @return void
*/
private function record(array $param, string $filePath): void
{
// 生成记录数据
$data = [
'file_path' => $filePath,
'status' => ExportStatusEnum::COMPLETED,
'store_id' => $this->getStoreId(),
];
// 起止时间
if (!empty($param['betweenTime'])) {
$times = between_time($param['betweenTime']);
$data['start_time'] = $times['start_time'];
$data['end_time'] = $times['end_time'];
}
// 新增记录
$model = new ExportModel;
$model->add($data);
}
/**
* 获取导出的记录列名集
* @param array $onlyFields
* @return array
*/
private function getColumns(array $onlyFields): array
{
return array_values(helper::pick($this->dictionary(), $onlyFields));
}
/**
* 订单记录字典
* @return string[]
*/
private function dictionary(): array
{
return [
'order_no_sn' => '平台订单号',
'order_no' => '订单号',
'passageway' => '通道',
'shop' => '店铺',
'merchant' => '商户',
'pay_price' => '支付金额',
'order_status' => '订单状态',
'create_time' => '订单生成时间',
'pay_time' => '订单支付时间'
];
}
/**
* 格式化生成表格数据
* @param array $orderList
* @param array $onlyFields
* @return array
*/
private function getExcelList(array $orderList, array $onlyFields): array
{
// 获取订单表格数据
$excelList = $this->getOrderDataForExcel($orderList);
// 仅输出用户设置的字段
$data = [];
foreach ($excelList as $item) {
$data[] = helper::pick($item, $onlyFields);
}
return $data;
}
/**
* 获取订单列表数据(用于生成Excel)
* @param $orderList
* @return array
*/
private function getOrderDataForExcel($orderList): array
{
// 表格内容
$dataArray = [];
foreach ($orderList as $order) {
$dataArray[] = [
'order_no_sn' => $this->filterValue($order['order_no_sn']),
'order_no' => $this->filterValue($order['order_no']),
'passageway' => $this->filterValue($order['passageway']),
'shop' => $this->filterValue($order['shop']['shop_name']),
'merchant' => $this->filterValue($order['merchant']['name']),
'pay_price' => $this->filterValue($order['pay_price']) . '元',
'order_status' => PayStatusEnum::data()[$order['pay_status']]['name'],
'create_time' => $this->filterValue($order['create_time']),
'pay_time' => $order['pay_time'] . '元',
];
}
return $dataArray;
}
/**
* 格式化商品信息
* @param $order
* @return string
*/
private function filterGoodsInfo($order): string
{
$content = '';
foreach ($order['goods'] as $key => $goods) {
$content .= ($key + 1) . ".商品名称:{$goods['goods_name']}\n";
if (!empty($goods['goods_props'])) {
$goodsAttr = GoodsService::goodsPropsToAttr($goods['goods_props']);
$content .= " 商品规格:{$goodsAttr}\n";
}
$content .= " 购买数量:{$goods['total_num']}\n";
$content .= " 商品总价:{$goods['total_price']}元\n\n";
}
return $content;
}
/**
* 表格值过滤
* @param $value
* @return string
*/
private function filterValue($value): string
{
return "\t{$value}\t";
}
}
@@ -0,0 +1,142 @@
<?php
namespace app\store\service\setting;
use app\common\library\helper;
use app\common\service\BaseService;
use think\facade\Cache as CacheDrive;
/**
* 清理后台缓存服务
* Class Clear
* @package app\store\service\setting
*/
class Clear extends BaseService
{
const ITEM_TYPE_CACHE = 'cache';
const ITEM_TYPE_FILE = 'file';
/**
* 数据缓存项目(只显示key和name)
* @return array
*/
public function items(): array
{
$items = [];
foreach ($this->getItems() as $key => $item) {
$items[] = [
'key' => $key,
'name' => $item['name']
];
}
return $items;
}
/**
* 数据缓存项目
* @return array
*/
private function getItems(): array
{
$storeId = $this->getStoreId();
return [
'category' => [
'type' => self::ITEM_TYPE_CACHE,
'key' => "category_{$storeId}",
'name' => '商品分类'
],
'setting' => [
'type' => self::ITEM_TYPE_CACHE,
'key' => "setting_{$storeId}",
'name' => '商城设置'
],
'wxapp' => [
'type' => self::ITEM_TYPE_CACHE,
'key' => "wxapp_setting_{$storeId}",
'name' => '微信小程序设置'
],
'h5' => [
'type' => self::ITEM_TYPE_CACHE,
'key' => "wxapp_h5_{$storeId}",
'name' => 'H5端设置'
],
'temp' => [
'type' => self::ITEM_TYPE_FILE,
'name' => '临时图片',
'dirPath' => [
'web' => web_path() . "temp/{$storeId}/",
'runtime' => runtime_root_path() . "/image/{$storeId}/",
]
],
'local' => [
'type' => self::ITEM_TYPE_FILE,
'name' => '临时文件',
'dirPath' => [
'batch-delivery' => runtime_root_path() . "local/batch-delivery/{$storeId}/",
'batch-goods' => runtime_root_path() . "local/batch-goods/{$storeId}/",
]
],
];
}
/**
* 删除缓存
* @param array $keys
*/
public function rmCache(array $keys)
{
$cacheList = $this->getItems();
$keys = array_intersect(array_keys($cacheList), $keys);
foreach ($keys as $key) {
$item = $cacheList[$key];
if ($item['type'] === self::ITEM_TYPE_CACHE) {
CacheDrive::has($item['key']) && CacheDrive::delete($item['key']);
} elseif ($item['type'] === 'file') {
$this->deltree($item['dirPath']);
}
}
}
/**
* 删除目录下所有文件
* @param string|array $dirPath
*/
private function deltree($dirPath)
{
if (!is_array($dirPath)) {
$this->deleteFolder($dirPath);
return;
}
foreach ($dirPath as $path) {
$this->deleteFolder($path);
}
}
/**
* 递归删除指定目录下所有文件
* @param string $path
* @return void
*/
private function deleteFolder(string $path): void
{
if (!is_dir($path)) {
return;
}
// 扫描一个文件夹内的所有文件夹和文件
foreach (scandir($path) as $val) {
// 排除目录中的.和..
if (!in_array($val, ['.', '..'])) {
// 如果是目录则递归子目录,继续操作
if (is_dir("{$path}{$val}")) {
// 子目录中操作删除文件夹和文件
$this->deleteFolder("{$path}{$val}/");
// 目录清空后删除空文件夹
rmdir("{$path}{$val}/");
} else {
// 如果是文件直接删除
unlink("{$path}{$val}");
}
}
}
}
}
@@ -0,0 +1,69 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service\statistics;
use app\common\service\BaseService;
use app\store\service\statistics\data\Survey;
use app\store\service\statistics\data\Trade7days;
use app\store\service\statistics\data\GoodsRanking;
use app\store\service\statistics\data\UserExpendRanking;
/**
* 数据概况服务类
* Class Data
* @package app\store\service\statistics
*/
class Data extends BaseService
{
/**
* 获取数据概况
* @param null $startDate
* @param null $endDate
* @return array
*/
public function getSurveyData($startDate = null, $endDate = null)
{
return (new Survey)->getSurveyData($startDate, $endDate);
}
/**
* 近7日走势
* @return array
*/
public function getTransactionTrend()
{
return (new Trade7days)->getTransactionTrend();
}
/**
* 商品销售榜
* @return mixed
*/
public function getGoodsRanking()
{
return (new GoodsRanking)->getGoodsRanking();
}
/**
* 用户消费榜
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function geUserExpendRanking()
{
return (new UserExpendRanking)->getUserExpendRanking();
}
}
@@ -0,0 +1,52 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service\statistics\data;
use app\common\service\BaseService;
use app\store\model\OrderGoods as OrderGoodsModel;
use app\common\enum\order\OrderStatus as OrderStatusEnum;
use app\common\enum\order\PayStatus as OrderPayStatusEnum;
/**
* 数据统计-商品销售榜
* Class GoodsRanking
* @package app\store\service\statistics\data
*/
class GoodsRanking extends BaseService
{
/**
* 商品销售榜
* @return mixed
*/
public function getGoodsRanking()
{
return (new OrderGoodsModel)->alias('o_goods.o_goods')
->field([
'o_goods.goods_id',
// 这里采用聚合函数获取goods_name, 因为mysql5.7使用group的报错问题
'MAX(goods_name) AS goods_name',
'SUM(total_pay_price) AS sales_volume',
'SUM(total_num) AS total_sales_num'
])
->join('order', 'order.order_id = o_goods.order_id')
->where('order.pay_status', '=', OrderPayStatusEnum::SUCCESS)
->where('order.order_status', '<>', OrderStatusEnum::FAIL)
// 这里如果写入goods_name的话,会出现同商品ID不同name的数据
->group('o_goods.goods_id')
// order:此处按总销售额排序,如需按销量改为total_sales_num
->order(['sales_volume' => 'DESC'])
->limit(10)
->select();
}
}
@@ -0,0 +1,165 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service\statistics\data;
use app\common\library\helper;
use app\common\service\BaseService;
use app\store\model\User as UserModel;
use app\store\model\Order as OrderModel;
use app\store\model\Goods as GoodsModel;
use app\store\model\recharge\Order as RechargeOrderModel;
use app\common\enum\order\PayStatus as PayStatusEnum;
use app\common\enum\recharge\order\PayStatus as RechargePayStatusEnum;
/**
* 数据概况
* Class Survey
* @package app\store\service\statistics\data
*/
class Survey extends BaseService
{
/**
* 获取数据概况
* @param null $startDate
* @param null $endDate
* @return array
*/
public function getSurveyData($startDate = null, $endDate = null)
{
return [
// 用户数量
'userTotal' => $this->getUserTotal($startDate, $endDate),
// 消费人数
'consumeUsers' => $this->getConsumeUsers($startDate, $endDate),
// 支付订单数
'orderTotal' => $this->getOrderTotal($startDate, $endDate),
// 销售额(元)
'orderTotalPrice' => $this->getOrderTotalPrice($startDate, $endDate),
// 商品总量
'goodsTotal' => $this->getGoodsTotal($startDate, $endDate),
// 用户充值总额
'rechargeTotalMoney' => $this->getRechargeTotalMoney($startDate, $endDate),
];
}
/**
* 获取用户总量
* @param null $startDate
* @param null $endDate
* @return string
*/
private function getUserTotal($startDate = null, $endDate = null)
{
// 检索查询条件
$filter = [];
if (!is_null($startDate) && !is_null($endDate)) {
$filter[] = ['create_time', '>=', strtotime($startDate)];
$filter[] = ['create_time', '<', strtotime($endDate) + 86400];
}
// 查询总记录
$value = (new UserModel)->where($filter)
->where('is_delete', '=', '0')
->count();
return number_format($value);
}
/**
* 消费人数
* @param null $startDate
* @param null $endDate
* @return string
*/
public function getConsumeUsers($startDate = null, $endDate = null)
{
// 检索查询条件
$filter = [];
if (!is_null($startDate) && !is_null($endDate)) {
$filter[] = ['pay_time', '>=', strtotime($startDate)];
$filter[] = ['pay_time', '<', strtotime($endDate) + 86400];
}
// 查询总记录
$value = (new OrderModel)->field('user_id')
->where($filter)
->where('pay_status', '=', PayStatusEnum::SUCCESS)
// ->where('order_status', '<>', OrderStatusEnum::CANCELLED)
->where('is_delete', '=', '0')
->group('user_id')
->count();
return number_format($value);
}
/**
* 获取订单总量
* @param null $startDate
* @param null $endDate
* @return string
*/
private function getOrderTotal($startDate = null, $endDate = null)
{
return number_format((new OrderModel)->getPayOrderTotal($startDate, $endDate));
}
/**
* 付款订单总额
* @param null $startDate
* @param null $endDate
* @return string
*/
private function getOrderTotalPrice($startDate = null, $endDate = null)
{
return helper::number2((new OrderModel)->getOrderTotalPrice($startDate, $endDate));
}
/**
* 获取商品总量
* @param null $startDate
* @param null $endDate
* @return string
*/
private function getGoodsTotal($startDate = null, $endDate = null)
{
// 检索查询条件
$filter = [];
if (!is_null($startDate) && !is_null($endDate)) {
$filter[] = ['create_time', '>=', strtotime($startDate)];
$filter[] = ['create_time', '<', strtotime($endDate) + 86400];
}
// 查询总记录
$value = (new GoodsModel)->where($filter)
->where('is_delete', '=', 0)
->count();
return number_format($value);
}
/**
* 用户充值总额
* @param null $startDate
* @param null $endDate
* @return float|int
*/
private function getRechargeTotalMoney($startDate = null, $endDate = null)
{
// 检索查询条件
$filter = [];
if (!is_null($startDate) && !is_null($endDate)) {
$filter[] = ['pay_time', '>=', strtotime($startDate)];
$filter[] = ['pay_time', '<', strtotime($endDate) + 86400];
}
// 查询总记录
$value = (new RechargeOrderModel)->where($filter)
->where('pay_status', '=', RechargePayStatusEnum::SUCCESS)
->sum('actual_money');
return helper::number2($value);
}
}
@@ -0,0 +1,91 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service\statistics\data;
use app\common\service\BaseService;
use app\store\model\Order as OrderModel;
use app\common\library\helper;
/**
* 近7日走势
* Class Trade7days
* @package app\store\service\statistics\data
*/
class Trade7days extends BaseService
{
/* @var OrderModel $GoodsModel */
private $OrderModel;
/**
* 构造方法
*/
public function __construct()
{
parent::__construct();
/* 初始化模型 */
$this->OrderModel = new OrderModel;
}
/**
* 近7日走势
* @return array
*/
public function getTransactionTrend()
{
// 最近七天日期
$lately7days = $this->getLately7days();
return [
'date' => $lately7days,
'orderTotal' => $lately7days,
'orderTotalPrice' => $this->getOrderTotalPriceByDate($lately7days)
];
}
/**
* 最近七天日期
*/
private function getLately7days()
{
// 获取当前周几
$date = [];
for ($i = 0; $i < 7; $i++) {
$date[] = date('Y-m-d', strtotime('-' . $i . ' days'));
}
return array_reverse($date);
}
/**
* 获取某天的总销售额
* @param null $day
* @return string
*/
private function getOrderTotalPrice($day = null)
{
return helper::number2($this->OrderModel->getOrderTotalPrice($day, $day));
}
/**
* 获取订单总量 (指定日期)
* @param $days
* @return array
*/
private function getOrderTotalPriceByDate($days)
{
$data = [];
foreach ($days as $day) {
$data[] = $this->getOrderTotalPrice($day);
}
return $data;
}
}
@@ -0,0 +1,41 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service\statistics\data;
use app\store\model\User as UserModel;
use app\common\service\BaseService;
/**
* 数据统计-用户消费榜
* Class UserExpendRanking
* @package app\store\service\statistics\data
*/
class UserExpendRanking extends BaseService
{
/**
* 用户消费榜
* @return \think\Collection
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function getUserExpendRanking()
{
return (new UserModel)->field(['user_id', 'nick_name', 'expend_money'])
->where('is_delete', '=', 0)
->order(['expend_money' => 'DESC'])
->limit(10)
->select();
}
}
+131
View File
@@ -0,0 +1,131 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service\store;
use app\common\service\BaseService;
use app\store\model\store\Menu as MenuModel;
use app\store\model\store\UserRole as UserRoleModel;
use app\store\model\store\RoleMenu as RoleMenuModel;
use app\store\service\store\User as UserService;
/**
* 商家后台角色服务类
* Class Role
* @package app\store\service\store
*/
class Role extends BaseService
{
/**
* 获取当前登录用户菜单权限
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public static function getLoginPermissions()
{
// 获取当前登录用户的ID
$userInfo = UserService::getLoginInfo();
// 根据当前用户ID获取有权限的菜单列表
$permittedMenuList = static::getPermittedMenuList((int)$userInfo['user']['store_user_id']);
// 生成权限列表
$permissions = static::buildPermissions($permittedMenuList);
return [
// 是否为超级管理员, 拥有所有权限
'isSuper' => $userInfo['user']['is_super'],
// 权限列表
'permissions' => $permissions
];
}
/**
* 生成权限列表
* @param $menuList
* @return array
*/
private static function buildPermissions($menuList)
{
$data = [];
foreach ($menuList as $menu) {
$data[] = [
// 菜单唯一标示
'permissionId' => $menu['path'],
// 菜单名称
'name' => $menu['name'],
// 页面操作项 例如: 新增 编辑 删除
'actionEntitySet' => static::getActionEntitySet($menu)
];
!empty($menu['children']) && $data = array_merge($data, static::buildPermissions($menu['children']));
}
return $data;
}
/**
* 整理页面操作项
* @param $menu
* @return array
*/
private static function getActionEntitySet($menu)
{
if (!isset($menu['actions']) || empty($menu['actions'])) {
return [];
}
$actionEntitySet = [];
foreach ($menu['actions'] as $action) {
$actionEntitySet[] = [
'describe' => $action['name'],
'action' => $action['action_mark'],
];
}
return $actionEntitySet;
}
private static function filterChildrenAction($menuList)
{
$list = [];
foreach ($menuList as $item) {
if ($item['module'] != 10) continue;
if (!empty($item['children'])) {
// 整理actions
$item['actions'] = array_filter($item['children'], function ($val) {
return $val['module'] == 20;
});
// 整理children
$item['children'] = static::filterChildrenAction($item['children']);
}
$list[] = $item;
}
return $list;
}
/**
* 根据指定用户ID获取有权限的菜单列表
* @param $storeUserId
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
private static function getPermittedMenuList(int $storeUserId)
{
// 获取指定用户的所有角色ID
$roleIds = UserRoleModel::getRoleIdsByUserId($storeUserId);
// 根据角色ID集获取菜单列表集
$menuIds = RoleMenuModel::getMenuIds($roleIds);
// 获取指定角色ID的菜单列表
$menuList = MenuModel::getListByIds($menuIds);
// 整理菜单列表的actions
return static::filterChildrenAction($menuList);
}
}
@@ -0,0 +1,24 @@
<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务,帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2023 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件,不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);
namespace app\store\service\store;
use app\common\service\store\User as UserService;
/**
* 商家用户服务类
* Class User
*/
class User extends UserService
{
}