123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328 |
- <?php
- /**
- * 订单统计相关的
- * Created by PhpStorm.
- * User: phperstar
- * Date: 2021/04/19
- * Time: 11:40
- */
- namespace JinDouYun\Model\Order;
- use JinDouYun\Dao\Order\DOrder;
- use Mall\Framework\Core\StatusCode;
- use Mall\Framework\Core\ResultWrapper;
- use Mall\Framework\Core\ErrorCode;
- use Mall\Framework\Factory;
- use Jindouyun\Model\MBaseModel;
- use JinDouYun\Model\GoodsManage\MSku;
- use JinDouYun\Dao\Order\DOrderGoods;
- class MOrderStatistics extends MBaseModel
- {
- /**
- * @var int 单表数据量
- */
- private $cutTable = 200000;
- private $userCenterId;
- private $enterPriseId;
- private $objDOrderGoods;
- private $objDOrder;
- private $orderStatisticsTableName = 'order_statistics'; // 订单统计视图名字
- public function __construct($userCenterId, $enterPriseId)
- {
- parent::__construct($enterPriseId, $userCenterId);
- $this->userCenterId = $userCenterId;
- $this->enterPriseId = $enterPriseId;
- $this->objDOrder = new DOrder('default');
- $this->objDOrderGoods = new DOrderGoods('default');
- self::orderSubTable($enterPriseId, $userCenterId);
- }
- /**
- * 订单分表 分表规则:企业id_(客户/200000)
- * @param $enterpriseId (企业id)
- * @param $userId (用户id)
- * @throws \Exception
- */
- public function orderSubTable($enterpriseId, $userId)
- {
- $tableName = $this->objDOrder->getTableName('qianniao_order_' . $enterpriseId, $userId, $this->cutTable);
- self::existsTable($tableName);
- $this->objDOrder->setTable($tableName);
- }
- /**
- * 判断表是否存在
- * @param $tableName
- */
- public function existsTable($tableName)
- {
- $exists = $this->objDOrder->existsTable($tableName);
- if (!$exists) {
- //不存在删除视图
- self::dropView();
- }
- }
- /**
- * 删除订单视图
- */
- public function dropView()
- {
- $sql = 'DROP VIEW ' . $this->orderStatisticsTableName . '_' . $this->enterPriseId;
- $dbResult = $this->objDOrder->query($sql);
- if ($dbResult === false) {
- return ResultWrapper::fail($this->objDOrder->error(), ErrorCode::$dberror);
- }
- return ResultWrapper::success('删除成功');
- }
- /**
- * 订单汇总
- * @param $selectParams
- * @param $type
- * @return ResultWrapper
- * @throws \Exception
- */
- public function getAllOrderData($selectParams, $type, $export = 0)
- {
- $limit = $selectParams['limit'];
- unset($selectParams['limit']);
- $offset = $selectParams['offset'];
- unset($selectParams['offset']);
- if($export){
- $limit = 99999;
- $offset = 0;
- }
- $returnWhere = ' ';//查所有数据
- if ($selectParams['onReturn']) {//为真去除退货打开 查没退的数据
- $returnWhere = ' AND returnStatus != ' . StatusCode::$orderReturn['allReturn'] . ' AND detailsReturnStatus = ' . StatusCode::$orderReturn['notReturn'];//未退货
- }
- if ($type == 1) {//商品
- $groupBySql = ' GROUP BY goodsBasicId';
- } elseif ($type == 2) {//客户
- $groupBySql = ' GROUP BY customerId,goodsBasicId';
- } elseif ($type == 3) {//业务员
- $groupBySql = ' GROUP BY salesManId,goodsBasicId';
- } else {
- return ResultWrapper::fail('type参数错误', ErrorCode::$paramError);
- }
- $whereSql = '';
- $where = ' AND ';
- if (isset($selectParams['outStatus']) && !empty($selectParams['outStatus'])) {
- $whereSql .= $where . ' outStatus = ' . $selectParams['outStatus'];
- }
- if (isset($selectParams['goodsName']) && !empty($selectParams['goodsName'])) {
- $whereSql .= $where . ' goodsName LIKE "%' . $selectParams['goodsName'] . '%" ';
- }
- if (isset($selectParams['categoryId']) && !empty($selectParams['categoryId'])) {
- $whereSql .= $where . ' FIND_IN_SET(' . $selectParams['categoryId'] . ',categoryPath)';
- }
- if (isset($selectParams['customerId']) && !empty($selectParams['customerId'])) {
- $whereSql .= $where . ' customerId = ' . $selectParams['customerId'];
- }
- if (isset($selectParams['shopId']) && !empty($selectParams['shopId'])) {
- $whereSql .= $where . ' shopId = ' . $selectParams['shopId'];
- }
- if (isset($selectParams['start']) && !empty($selectParams['start']) && isset($selectParams['end']) && !empty($selectParams['end'])) {
- $whereSql .= $where . ' createTime BETWEEN ' . $selectParams['start'] . ' AND ' . $selectParams['end'];
- }
- //判断订单商品表是否存在
- $dbResult = $this->objDOrderGoods->existsTable('qianniao_order_goods_' . $this->enterPriseId . '_1');
- if (!$dbResult) {
- $return = [
- 'data' => [],
- 'total' => 0,
- ];
- return ResultWrapper::success($return);
- }
- $sql = "SELECT outStatus,customerId,customerName,salesManId,salesManName,goodsBasicId,goodsId,goodsCode,goodsName,skuId,unitName,shopId,shopName,SUM(detailsBuyNum) AS num,SUM(detailsTotalMoney) AS totalMoney,originPrice,SUM(outCostPrice * detailsBuyNum) AS totalCost, SUM(outCostPrice * detailsBuyNum) / SUM(detailsBuyNum) AS costPrice,SUM(detailsTotalMoney - (outCostPrice * detailsBuyNum)) AS totalProfit, SUM(detailsTotalMoney - (outCostPrice * detailsBuyNum)) / SUM(detailsBuyNum) AS profit, SUM(otherNum) AS otherNum "
- . "FROM " . $this->orderStatisticsTableName . '_' . $this->enterPriseId . ' '
- . 'WHERE deleteStatus = ' . StatusCode::$standard . ' AND detailsDeleteStatus = ' . StatusCode::$standard . ' AND outStatus = ' . StatusCode::$standard
- . $whereSql . ' '
- . $returnWhere
- . $groupBySql . ' '
- . 'ORDER BY detailsCreateTime DESC '
- . 'LIMIT ' . $offset . ',' . $limit;
- //判断视图是否存在
- $databaseName = Factory::config()->get('db')['default']['dbname'];
- $existsSql = "select table_name from information_schema.views where TABLE_SCHEMA = '" . $databaseName . "' and table_name = '" . $this->orderStatisticsTableName . "_" . $this->enterPriseId . "'";
- $dbResult = $this->objDOrderGoods->query($existsSql);
- if($dbResult === false) {
- return ResultWrapper::fail($this->objDOrderGoods->error(), ErrorCode::$dberror);
- }
- $existsView = array_shift($dbResult);
- unset($dbResult);
- if (empty($existsView['TABLE_NAME'])) {
- $modelResult = self::setOrderView();
- if (!$modelResult->isSuccess()) {
- return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
- }
- }
- if($export){
- $dbResult = $this->objDOrderGoods->exportQuery($sql);
- if ($dbResult === false) {
- return ResultWrapper::fail($this->objDOrderGoods->error(), ErrorCode::$dberror);
- }
- $modelResult = self::formatOrderStatistics($dbResult);
- if(!$modelResult->isSuccess()){
- return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
- }
- $orderData = $modelResult->getData();
- unset($modelResult);
- self::exportOrderStatistics($orderData);
- exit;
- }
- $dbResult = $this->objDOrderGoods->query($sql);
-
- if ($dbResult === false) {
- return ResultWrapper::fail($this->objDOrderGoods->error(), ErrorCode::$dberror);
- }
- $modelResult = self::formatOrderStatistics($dbResult);
- if(!$modelResult->isSuccess()){
- return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
- }
- $orderData = $modelResult->getData();
- unset($modelResult);
- $countSql = 'SELECT COUNT(*) AS `count` FROM (SELECT orderId FROM ' . $this->orderStatisticsTableName . '_' . $this->enterPriseId . ' WHERE deleteStatus = ' . StatusCode::$standard . ' AND detailsDeleteStatus = ' . StatusCode::$standard . ' AND outStatus = ' . StatusCode::$standard . $whereSql . ' ' . $returnWhere . $groupBySql . ') AS selectData';
- $dbResult = $this->objDOrderGoods->query($countSql);
- if ($dbResult === false) {
- return ResultWrapper::fail($this->objDOrderGoods->error(), ErrorCode::$dberror);
- }
- $totalData = array_shift($dbResult);
- unset($dbResult);
- $total = $totalData['count'];
- //查询结果需要格式化分类名称
- $return = [
- 'data' => $orderData,
- 'total' => ($total) ? intval($total) : 0,
- ];
- return ResultWrapper::success($return);
- }
- /**
- * 把所有的订单分包合并起来创建一个所有数据的视图
- * @throws \Exception
- */
- public function setOrderView()
- {
- $unionSql = '';
- $i = 1;
- while (true) {
- $orderTableName = 'qianniao_order_' . $this->enterPriseId . '_' . $i;
- $orderGoodsTableName = 'qianniao_order_goods_' . $this->enterPriseId . '_' . $i;
- $existsTable = $this->objDOrderGoods->existsTable($orderTableName);
- if (!$existsTable) {
- break;
- }
- //拼接sql
- $orderSql = "SELECT o.id AS orderId,o.no AS orderNo,o.shopId,o.shopName,o.outerTradeNo,o.totalMoney,o.payAmount,o.buyTotal,o.customerName,o.customerId,o.payStatus ,o.orderStatus,o.payType,o.deliveryType,o.source,o.remark,o.deleteStatus,o.auditStatus,o.returnStatus,o.outStatus,o.payTime,o.createTime,o.updateTime,o.preferentialActivityId AS orderPreferentialActivityId,o.salesManId,o.salesManName,o.customerType,o.userCenterId,g.id AS detailsId,g.goodsCode,g.goodsId,g.goodsName,g.originPrice,g.BuyNum AS detailsBuyNum,g.preferential,g.deliverNum,g.deleteStatus AS detailsDeleteStatus,g.returnStatus AS detailsReturnStatus,g.createTime AS detailsCreateTime,g.updateTime AS detailsUpdateTime,g.preferentialActivityId AS detailsPreferentialActivityId,g.totalMoney AS detailsTotalMoney,g.goodsBasicId,g.skuId,g.unitName,g.conversion,g.outCostPrice,g.categoryPath , JSON_EXTRACT(g.extends,'$.u_1_buy') AS otherNum FROM " . $orderTableName . ' o LEFT JOIN ' . $orderGoodsTableName . ' g ON o.id = g.orderId ';
- if (empty($unionSql)) {
- $unionSql = 'CREATE VIEW ' . $this->orderStatisticsTableName . '_' . $this->enterPriseId . ' AS ';
- } else {
- $unionSql .= ' UNION ALL ';
- }
- $unionSql .= $orderSql;
- $i++;
- }
- $dbResult = $this->objDOrderGoods->query($unionSql);
- if ($dbResult === false) {
- return ResultWrapper::fail($this->objDOrderGoods->error(), ErrorCode::$dberror);
- }
- return ResultWrapper::success('创建视图成功');
- }
- /**
- * 格式化销售报表
- * @param $params
- * @return ResultWrapper
- * @throws \Exception
- */
- public function formatOrderStatistics($params)
- {
- $skuIds = array_column($params, 'skuId');
- $skuData = [];
- if (!empty($skuIds)) {
- $objMSku = new MSku($this->userCenterId, $this->enterPriseId);
- $modelResult = $objMSku->getConversion($skuIds);
- if (!$modelResult->isSuccess()) {
- return ResultWrapper::fail($modelResult->getData(), $modelResult->getErrorCode());
- }
- $skuData = $modelResult->getData();
- unset($modelResult);
- }
- foreach ($params as &$value) {
- unset($value['unitId']);
- unset($value['unitName']);
- unset($value['skuName']);
- unset($value['skuBarCode']);
- $value['skuId'] = isset($skuData[$value['skuId']]['masterSkuId']) ? $skuData[$value['skuId']]['masterSkuId'] : $value['skuId'];
- }
- $return = parent::formatOrderMan($this->enterPriseId, $params);
- return ResultWrapper::success($return);
- }
- /**
- * 订单汇总导出方法
- * @param $result
- */
- public function exportOrderStatistics($result)
- {
- //导出到本地
- header("Content-type:application/vnd.ms-excel");
- header("Content-Disposition:filename=销售报表.csv");
- header('Cache-Control: max-age=0');
- $fp = fopen('php://output', 'a');
- $head = ['客户', '商品名称','商品规格', '店铺', '数量','其他单位', '销售收入', '成本', '总成本', '毛利', '总毛利']; //定义标题
- foreach ($head as $i => $v) {
- $head[$i] = mb_convert_encoding($v, 'GBK', 'utf-8'); //将中文标题转换编码,否则乱码
- }
- fputcsv($fp, $head);
- $limit = 10000;
- $num = 0;//计数器
- foreach ($result as $value) {//循环数据
- $num++;
- if ($num == $limit) {
- ob_flush();//释放内存
- flush();
- }
- $rows['customerName'] = isset($value['customerName']) ? $value['customerName'] : null;
- $rows['goodsName'] = isset($value['goodsName']) ? $value['goodsName'] : null;
- $rows['unitName'] = isset($value['unitName']) ? $value['skuName'].(!empty($value['skuName']) ? '_' : '').$value['unitName'] : null;
- $rows['shopName'] = isset($value['shopName']) ? $value['shopName'] : null;
- $rows['num'] = isset($value['num']) ? $value['num'] : null;
- $rows['otherNum'] = isset($value['otherNum']) ? $value['otherNum'] : null;
- $rows['totalMoney'] = isset($value['totalMoney']) ? $value['totalMoney'] : null;
- $rows['costPrice'] = isset($value['costPrice']) ? $value['costPrice'] : null;
- $rows['totalCost'] = isset($value['totalCost']) ? $value['totalCost'] : null;
- $rows['profit'] = isset($value['profit']) ? $value['profit'] : null;
- $rows['totalProfit'] = isset($value['totalProfit']) ? $value['totalProfit'] : null;
- foreach ($rows as $kk => $vv) {
- $rs[$kk] = mb_convert_encoding($vv, 'GBK', 'utf-8'); //转译编码
- }
- fputcsv($fp, $rs);
- $rows = [];
- }
- }
- }
|