<?php

namespace common\libs\export;

use common\helpers\Cache;
use common\helpers\Cache as CacheHelper;
use common\helpers\Date;
use common\helpers\Form;
use common\helpers\http\RemoteUploadApi;
use common\helpers\LoggerTool;
use common\helpers\Tool;
use common\helpers\user\Info;
use common\libs\dataList\DataList;
use common\models\ApproachOrder;
use common\models\ApproachOrderGoods;
use common\models\BaApproachOrder;
use common\models\BaApproachOrderGoods;
use common\models\BaOrder;
use common\models\BaOrderGoods;
use common\models\BaUser;
use common\models\Countries;
use common\models\Currency;
use common\models\DecOrder;
use common\models\Export;
use common\models\Order;
use common\models\OrderGoods;
use common\models\Region;
use common\models\ShopGoods;
use common\models\User;
use console\helpers\Logger;
use Yii;
use yii\base\Exception;
use yii\base\InvalidConfigException;
use yii\base\StaticInstanceTrait;
use yii\base\Component;
use yii\db\Query;

class BaseExport extends Component {
    use StaticInstanceTrait;
    public $moduleId;
    /**
     * @var string the model class name. This property must be set.
     */
    public $modelClass;
    /**
     * @var
     */
    public $listModelClass;
    /**
     * @var int
     */
    public $pageSize = 100;
    /**
     * @var int
     */
    public $totalCount = 0;
    /**
     * @var int
     */
    public $offset = 0;
    /**
     * @var int
     */
    public $limit = 100;
    /**
     * csv文件名称
     * @var null
     */
    public $fileName = null;
    /**
     * 保存的基本路径
     * @var null
     */
    public $saveBasePath = null;
    /**
     * 保存路径
     * @var null
     */
    public $savePath = null;
    /**
     * 正在导出的id
     * 来源于exporting_file表
     * @var null
     */
    public $exportId = null;
    /**
     * 操作人的id
     * @var null
     */
    public $userId = null;
    /**
     * 任务id
     * @var null
     */
    public $taskId = null;
    /**
     * 是否完成
     * @var bool
     */
    public $completed = false;
    /**
     * @var array
     */
    public $params = [];
    /**
     * 文件句柄
     * @var null
     */
    private $_fp = null;
    /**
     * 是否上传远程
     * @var bool
     */
    public $isRemote = true;

    /**
     * @var DataList
     */
    private $_listModel;

    public static function factory($taskId) {
        return new self([
                'taskId' => $taskId
            ]
        );
    }

    /**
     *
     */
    public function init() {
        parent::init();
        $this->isRemote = \Yii::$app->params['isRemoteUpload'];
    }

    /**
     * 生成复杂的路径
     * @return string
     */
    public function pathCreator(...$params) {
        $hash = md5(implode('_', $params));
        $first = substr($hash, 0, 3);
        $second = substr($hash, 3, 2);
        $dir = $first . __DS__ . $second . __DS__;
        return $dir;
    }

    /**
     * 获取文件名
     * @return string|null
     * @throws \Exception
     */
    public function getFileName($ext = '.csv') {
        $this->fileName = date('YmdHis', Date::nowTime()) . random_int(1000, 9999) . $ext;
        return $this->fileName;
    }

    /**
     * 获取保存的路径
     * @return array|null
     */
    public function getSavePath() {
        $this->savePath = $this->pathCreator(date('Ymd', Date::nowTime()));
        return trim((string)$this->savePath, __DS__);
    }

    /**
     * @return bool|string|null
     */
    public function getSaveBasePath() {
        $this->saveBasePath = Yii::getAlias('@backendApi') . __DS__ . 'web' . __DS__ . 'upload' . __DS__ . (isset(\Yii::$app->params['excelLocalDir']) ? \Yii::$app->params['excelLocalDir'] : '');
        return trim((string)$this->saveBasePath, __DS__);
    }

    /**
     * 创建目录(递归创建)
     *
     * @param $dir
     * @return string|false
     */
    public function mkdir($dir) {
        if (!is_dir($dir)) {
            $this->mkdir(dirname($dir));
            if (!mkdir($dir, 0777))
                return false;
            @exec('chown -R www:www /'.$dir);
            @exec('chmod -R 777 /'.$dir);
        }
        return $dir;
    }

    /**
     * @return array|mixed
     */
    public function getParams() {
        $this->params = CacheHelper::getAsyncParams($this->taskId);

        // 设置语言
        Yii::$app->language = $this->params['language'] ?? 'en-US';
        Yii::$app->sourceLanguage = Yii::$app->language == 'zh-CN' ? 'en-US' : 'zh-CN';

        return $this->params;
    }

    /**
     * @return mixed|null
     */
    public function getUserId() {
        $this->userId = isset($this->params['userId']) ? $this->params['userId'] : null;
        return $this->userId;
    }

    /**
     * @return |null
     */
    public function getExportId() {
        $this->exportId = isset($this->params['exportId']) ? $this->params['exportId'] : null;
        return $this->userId;
    }

    /**
     * 生成
     * @return bool
     * @throws Exception
     * @throws InvalidConfigException
     * @throws \yii\httpclient\Exception
     */
    public function generate() {
        $this->getParams();
        if (!$this->params) {
            throw new Exception('无法获取需要的参数');
        }
        $path = $this->getSaveBasePath() . __DS__ . $this->getSavePath();
        $path = __DS__ . $path;
        $realFile = $this->mkdir($path) . __DS__ . $this->getFileName();
        $this->completed = false;
        $this->getExportId();
        $this->getUserId();
        $fileNameUpdated = false;
        $this->_fp = fopen($realFile, 'w');
        @exec('chown -R www:www /'.$realFile);
        @exec('chmod -R 777 /'.$realFile);
        // 获取列表数据及表头
        $this->_listModel = new $this->listModelClass();
        $this->_listModel->isExport = true;
        if(method_exists($this->_listModel, 'getExportHeaders')){
            if(method_exists($this->_listModel, 'exportPrepare')) {//导出数据提前设置参数
                $this->_listModel->exportPrepare(['condition' => $this->params['condition'], 'params' => $this->params['params'], 'others' => isset($this->params['others']) ? $this->params['others'] : [], 'page' => 0, 'pageSize' => $this->pageSize, 'userId' => $this->userId]);
            }
            $headers = $this->_listModel->getExportHeaders($this->userId);
            fputcsv($this->_fp, $headers);
            unset($headers);
            $this->_updateFirst($realFile, 1);
        } else {
            throw new Exception($this->listModelClass.'的getExportHeaders方法不存在');
        }
        $this->_loopWriteData($realFile, $fileNameUpdated);
        $this->complete();
        return true;
    }

    /**
     * 循环写入数据
     * @param $realFile
     * @param $fileNameUpdated
     * @param int $page
     * @param int $counter
     * @return string
     * @throws Exception
     */
    private function _loopWriteData($realFile, &$fileNameUpdated, $page = 0, $counter = 0){
        if(method_exists($this->_listModel, 'getList')){
            $list = $this->_listModel->getList(['condition'=>$this->params['condition'], 'params'=> $this->params['params'] ?? [], 'others'=> $this->params['others'] ?? [], 'page'=>$page, 'pageSize'=>$this->pageSize, 'userId'=>$this->userId]);
        } else {
            throw new Exception($this->listModelClass.'的getList方法不存在');
        }
        if($page >= $list['totalPages']){
            return 'finish';
        }
        if(!empty($list['list'])){
            foreach($list['list'] as $columnData){
                fputcsv($this->_fp, Tool::arrTextConvert($columnData));
                $counter++;

                if ($list['totalCount'] < $counter) {
//                    $counter = $list['totalCount'];
                    return 'finish';
                }
                $percent = intval(($counter / $list['totalCount']) * 100);
                $this->_updatePercent($percent);
//                if (!$fileNameUpdated) {
//                    $this->_updateFirst($realFile, $percent);
//                } else {
//                    $this->_updatePercent($percent);
//                }
//                $fileNameUpdated = true;
                unset($percent, $columnData);
            }
            $page++;
            unset($list);
            return $this->_loopWriteData($realFile, $fileNameUpdated, $page, $counter);
        }
        unset($list);
        return 'finish';
    }

    /**
     * 循环写入数据
     */
    private function _loopWriteDataOrder()
    {
        $orderQuery = Order::find()
            ->alias('O')
            ->where($this->params['condition'], $this->params['params'])
            ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV,OG.STANDARD_PRICE,CS.NAME AS COUNTRY,CY.CODE AS CURRENCY, O.DEC_USER_ID AS ORDER_DEC_ID')
            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->join('LEFT JOIN', Countries::tableName() . ' AS CS', 'CS.ID=O.COUNTRY_ID')
            ->join('LEFT JOIN', Currency::tableName() . ' AS CY', 'CY.ID=O.CURRENCY_ID')
            ->join('LEFT JOIN', DecOrder::tableName() . ' AS DO', 'DO.ORDER_SN=O.SN')
            ->orderBy('O.CREATED_AT DESC');

        // 订单中间表只查询待支付和支付失败的订单
        $this->params['params'][':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value'];   // 待支付
        $this->params['params'][':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value'];   // 支付失败
        $orderStandardQuery = ApproachOrder::find()
            ->alias('O')
            ->where($this->params['condition'] . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params['params'])
            ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV,OG.STANDARD_PRICE,CS.NAME AS COUNTRY,CY.CODE AS CURRENCY, O.DEC_USER_ID AS ORDER_DEC_ID')
            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', ApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->join('LEFT JOIN', Countries::tableName() . ' AS CS', 'CS.ID=O.COUNTRY_ID')
            ->join('LEFT JOIN', Currency::tableName() . ' AS CY', 'CY.ID=O.CURRENCY_ID')
            ->join('LEFT JOIN', DecOrder::tableName() . ' AS DO', 'DO.ORDER_SN=O.SN')
            ->orderBy('O.CREATED_AT DESC');

        $queryAll = $orderQuery->union($orderStandardQuery, true);
        $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]);
        $lists = $query->all();


        if(!empty($lists)){
            $regionConfig = Cache::getRegionConfig();
            foreach($lists as $columnData) {
                $CREATE_USER_ID = Info::getUserIdByUserName($columnData['CREATE_USER']);
                $createUserName = Info::getUserRealNameByUserId($CREATE_USER_ID);

                $columnAccept = [
                    'USER_NAME' => $columnData['USER_NAME'],
                    'DEC_USER_NAME' => $columnData['DEC_USER_ID'],
                    'CREATE_USER' => $columnData['CREATE_USER'],
                    'CREATE_USER_NAME' => $createUserName,
                    'SN' => $columnData['SN'],
                    'STATUS' => Tool::paramConvert(\Yii::$app->params['orderStatus'])[$columnData['STATUS']]['label'] ?? '',
                    'SKU_CODE' => $columnData['SKU_CODE'],
                    'GOODS_TITLE' => Tool::mbSignConvert($columnData['GOODS_TITLE']) ,
                    'CONSIGNEE' => $columnData['CONSIGNEE'],
                    'MOBILE' => "\t{$columnData['MOBILE']}",
                    'COUNTRY' => $columnData['COUNTRY'],
                    'CURRENCY' => $columnData['CURRENCY'],
                    'PROVINCE' => $regionConfig[$columnData['PROVINCE']]['REGION_NAME'] ?? '',
                    'CITY' => $regionConfig[$columnData['CITY']]['REGION_NAME'] ?? '',
                    'COUNTY' => $regionConfig[$columnData['COUNTY']]['REGION_NAME'] ?? '',
                    'ADDRESS' => $columnData['ADDRESS'],
                    'PERIOD_NUM' => $columnData['PERIOD_NUM'],
                    'ORDER_TYPE' => ($columnData['ORDER_TYPE'] == 'ZC') ? 'Welcome pack' : (in_array($columnData['PAY_TYPE'], ['cash', 'pay_stack']) ? 'Repeat Purchase': 'Points'),
                    // 'WAREHOUSE' => $columnData['WAREHOUSE'],
                    'CREATED_AT' => Date('Y-m-d H:i:s', $columnData['CREATED_AT']),
                    'PAY_TYPE' => ShopGoods::payTypes()[$columnData['PAY_TYPE']]['name'] ?? ShopGoods::payTypes()['cash']['name'],
                    'PAY_AT' => $columnData['PAY_AT'] > 0 ? Date('Y-m-d H:i:s', $columnData['PAY_AT']) : '',
//                    'DELIVERY_AT' => $columnData['DELIVERY_AT'] > 0 ? Date('Y-m-d H:i:s', $columnData['DELIVERY_AT']) : '',
                    'BUY_NUMS' => $columnData['BUY_NUMS'],
                    'REAL_PRICE' => $columnData['REAL_PRICE'],
                    'TOTAL_PRICE' => $columnData['REAL_PRICE'] * $columnData['BUY_NUMS'],
                    'REAL_PV' => $columnData['REAL_PV'] * $columnData['BUY_NUMS'],
                    'STANDARD_PRICE' => $columnData['STANDARD_PRICE'] * $columnData['BUY_NUMS'],
                    'PAY_FREIGHT' => $columnData['PAY_FREIGHT'],
                    'TAX_RATE' => $columnData['TAX_RATE'],
                    'TAX_AMOUNT' => Tool::calculateTax($columnData['REAL_PRICE'], $columnData['TAX_RATE'], $columnData['BUY_NUMS']),
//                    'EXPRESS_COMPANY' => $columnData['EXPRESS_COMPANY'],
//                    'ORDER_TRACK_NO' => $columnData['ORDER_TRACK_NO'],
                    'EXPRESS_TYPE' => $columnData['EXPRESS_TYPE'] == 0 ? 'mailing ':' auto pick',
                    'FRONT_REMARK' => $columnData['FRONT_REMARK'],
                    'DELIVERY_STATUS_NAME' => Tool::paramConvert(\Yii::$app->params['deliveryStatus'])[$columnData['DELIVERY_STATUS']]['label'] ?? '',
                    'AUTO_MAINTENANCE' => $columnData['AUTO_MAINTENANCE'] == 1 ? 'Yes' : 'No',
                ];

                fputcsv($this->_fp, Tool::arrTextConvert($columnAccept));
                unset($percent, $columnData, $columnAccept);
            }
            unset($list);
        }

        unset($list);
        return 'finish';
    }

    /**
     * 完成
     * @return bool
     * @throws Exception
     * @throws InvalidConfigException
     * @throws \yii\httpclient\Exception
     */
    public function complete() {
        $this->_updatePercent(100);
        if ($this->completed) {
            return true;
        }
        if ($this->_fp) {
            fclose($this->_fp);
        }
        // 把导出的文件上传至静态文件服务器
        if ($this->isRemote) {
            $realFile = $this->getSaveBasePath() . __DS__ . $this->getSavePath() . __DS__ . $this->getFileName();
            $remoteUploadApi = RemoteUploadApi::instance();
            if ($uploadResult = $remoteUploadApi->upload($realFile)) {
                Export::updateAll(['REMOTE_URL' => $uploadResult['url'], 'IS_EXPORTING' => 0, 'EXPORT_PERCENT' => 100, 'ENDED_AT' => Date::nowTime()], 'ID=:ID', [':ID' => $this->exportId]);
            } else {
                $this->_errorHandle();
                throw new Exception('文件远程上传失败');
            }
            // 删除本地临时文件
            unlink($realFile);
        } else {
            Export::updateAll(['IS_EXPORTING' => 0, 'EXPORT_PERCENT' => 100, 'ENDED_AT' => Date::nowTime()], 'ID=:ID', [':ID' => $this->exportId]);
        }

        \Yii::$app->swooleAsyncTimer->pushAsyncPercentToAdmin(100, ['MODEL' => 'EXPORT', 'ID' => $this->exportId, 'FIELD' => 'EXPORT_PERCENT']);
        CacheHelper::deleteAsyncParams($this->taskId);
        $this->completed = true;
    }

    /**
     * @param $message
     */
    private function _errorNotice($message) {
        Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($this->userId, $message, false);
    }

    /**
     * 首次更新
     * @param $exportId
     * @param $realName
     */
    private function _updateFirst($realName, $percent) {
        $fileName = str_replace($this->getSaveBasePath() . __DS__, '', $realName);
        Export::updateAll([
            'FILE_NAME' => str_replace(__DS__, '/', $fileName),
            'UPDATED_AT' => Date::nowTime(),
            'EXPORT_PERCENT' => $percent,
        ], 'ID=:ID', [':ID' => $this->exportId]);
    }

    /**
     * 更新百分比
     * @param $exportId
     * @param $percent
     */
    private function _updatePercent($percent) {
        // 把数据写入数据库中
        Export::updateAll(['EXPORT_PERCENT' => $percent], 'ID=:ID', [':ID' => $this->exportId]);
        \Yii::$app->swooleAsyncTimer->pushAsyncPercentToAdmin($percent, ['MODEL' => 'EXPORT', 'ID' => $this->exportId, 'FIELD' => 'EXPORT_PERCENT']);
    }

    /**
     * 发生错误处理
     * @param $exportId
     */
    private function _errorHandle() {
        Export::updateAll(['IS_EXPORTING' => 0], 'ID=:ID', [':ID' => $this->exportId]);
    }

    /**
     * 导出逻辑
     * @param $filter
     * @param $listName
     * @param null $consoleRouter
     * @param null remark
     * @throws Exception
     */
    public function exportHandle($filter, $listName, $consoleRouter = null,$remark = null){
        $params = [
            'moduleId' => $this->moduleId,
            'listName' => $listName,
            'action' => $consoleRouter ? $consoleRouter : Yii::$app->controller->id.'/'.Yii::$app->controller->action->id, // 这里这么写，是因为调用的异步路由和同步的控制器和方法是一样的，所以，只要不传默认调和同步一样的异步方法
            'userId' => Yii::$app->user->id,
            'remark' => $remark,
        ];
        $this->webToAsync($params,$filter);
    }

    /**
     * 页面到异步的请求
     * @param $params
     * @param array $extend
     * @return bool
     * @throws Exception
     */
    public function webToAsync($params, $extend = []) {
        $default = [
            'moduleId' => null,
            'listName' => null,
            'remark' => null,
            'action' => null,
            'userId' => null,
        ];
        $params = Tool::deepParse($params, $default);
        if (!$params['moduleId'] || !$params['listName'] || !$params['action']) {
            throw new Exception('请设置moduleId,listName和action');
        }

        // 把文件对应的相关资料存入数据库中
        $export = new Export();
        $export->EXPORT_NAME = $params['listName'] . '_' . date('Exp_y-m-d H:i:s', Date::nowTime());
        $export->MODULE_NAME = $params['moduleId'];
        $export->REMARK = $params['remark'];
        $export->IS_EXPORTING = 1;
        $export->ADMIN_ID = \Yii::$app->user->id;
        $export->STARTED_AT = Date::nowTime();
        $export->CREATED_AT = Date::nowTime();
        $export->EXPORT_PERCENT = 0;
        $export->ENDED_AT = 0;
        $export->UPDATED_AT = 0;
        if (!$export->save()) {
            throw new Exception(Form::formatErrorsForApi($export->getErrors()));
        }
        $extend = array_merge($extend, [
            'exportId' => $export->ID,
            'userId' => $params['userId'],
            'language' => Yii::$app->language,
        ]);
        // 异步处理添加任务
        $taskKey = \Yii::$app->swooleAsyncTimer->asyncHandle($params['action'], $extend);
        if($taskKey === false){
            // 删除刚刚添加的导出数据
            Export::deleteAll(['ID'=>$export->ID]);
            throw new Exception('导出失败，请求异步处理服务器失败');
        }
        return $taskKey;
    }

    /**
     * 生成
     * @return bool
     * @throws Exception
     * @throws InvalidConfigException
     * @throws \yii\httpclient\Exception
     */
    public function generateOrderExcel() {
        $this->getParams();
        if (!$this->params) {
            throw new Exception('无法获取需要的参数');
        }
        $path = $this->getSaveBasePath() . __DS__ . $this->getSavePath();
        $path = __DS__ . $path;
        $realFile = $this->mkdir($path) . __DS__ . $this->getFileName();
        $this->completed = false;
        $this->getExportId();
        $this->getUserId();
        $fileNameUpdated = false;
        $this->_fp = fopen($realFile, 'w');
        @exec('chown -R www:www /'.$realFile);
        @exec('chmod -R 777 /'.$realFile);
        // 获取列表数据及表头
        $this->_listModel = new $this->listModelClass();
        $this->_listModel->isExport = true;
        if(method_exists($this->_listModel, 'getExportHeaders')){
            if(method_exists($this->_listModel, 'exportPrepare')) {//导出数据提前设置参数
                $this->_listModel->exportPrepare(['condition' => $this->params['condition'], 'params' => $this->params['params'], 'others' => $this->params['others'] ?? [], 'page' => 0, 'pageSize' => 100000, 'userId' => $this->userId]);
            }
            $headers = $this->_listModel->getExportHeaders($this->userId);
            fputcsv($this->_fp, $headers);
            unset($headers);
            $this->_updateFirst($realFile, 1);
        } else {
            throw new Exception($this->listModelClass.'的getExportHeaders方法不存在');
        }
        $this->_loopWriteDataOrder();
        $this->complete();
        return true;
    }

    /**
     * 生成
     * @return bool
     * @throws Exception
     * @throws InvalidConfigException
     * @throws \yii\httpclient\Exception
     */
    public function generateOrderPDF() {
        $this->getParams();
        if (!$this->params) {
            throw new Exception('无法获取需要的参数');
        }
        $path = __DS__ . $this->getSaveBasePath() . __DS__ . $this->getSavePath();
        $realFile = $this->mkdir($path) . __DS__ . $this->getFileName('.pdf');

        $this->completed = false;
        $this->getExportId();
        $this->getUserId();
        $fileNameUpdated = false;

        // 获取列表数据及表头
        $this->_listModel = new $this->listModelClass();
        $this->_listModel->isExport = true;

        // 查询订单数据
//        $oderList = $this->_loopWriteDataPDF($realFile, $fileNameUpdated);
        $orderQuery = Order::find()
            ->alias('O')
            ->where($this->params['condition'], $this->params['params'])
            ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->orderBy('O.CREATED_AT DESC');

        // 订单中间表只查询待支付和支付失败的订单
        $this->params['params'][':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value'];   // 待支付
        $this->params['params'][':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value'];   // 支付失败
        $orderStandardQuery = ApproachOrder::find()
            ->alias('O')
            ->where($this->params['condition'] . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params['params'])
            ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', ApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->orderBy('O.CREATED_AT DESC');

        $queryAll = $orderQuery->union($orderStandardQuery, true);
        $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]);
        $oderList = $query->all();

        if ($oderList) {
            $userId = '';
            $userName = '';
            $address = '';
            $mobile = '';
            $orderAt = '';
            $orderDetails = '';
            $orderSn = '';
            $orderAmount = 0;  // 合计总额
            $orderNums = 0; // 合计总数
            $totalTaxAmount = 0; // 合计税额
            $totalAmount = 0;
            foreach ($oderList as $key => $value) {
                $provinceName = $value['PROVINCE'] ? Region::getCnName($value['PROVINCE']) : '';
                $cityName = $value['CITY'] ? Region::getCnName($value['CITY']) : '';
                $countyName = $value['COUNTY'] ? Region::getCnName($value['COUNTY']) : '';

                $userId = $value['USER_NAME'];
                $userName = $value['REAL_NAME'];
                $address = $provinceName . $cityName . $countyName . $value['ADDRESS'];
                $mobile = $value['MOBILE'];
                $orderAt = Date::convert($value['CREATED_AT'],'Y-m-d H:i:s');
                $orderSn = $value['SN'];
                // 总价
                $totalAmount = $value['BUY_NUMS'] * $value['REAL_PRICE'];
                $orderAmount += $totalAmount;
                $orderNums += $value['BUY_NUMS'];
                // 税额
                $taxAmount = Tool::calculateTax($value['REAL_PRICE'], $value['TAX_RATE'], $value['BUY_NUMS']);
                $totalTaxAmount += $taxAmount;
                $taxAmount = Tool::formatAmount($taxAmount);
                $totalAmount = Tool::formatAmount($totalAmount);
                // 订单详情
                $orderDetails .= <<<EOT
                <tr>
                    <td>{$value['SKU_CODE']}</td>
                    <td>{$value['GOODS_TITLE']}</td>
                    <td style="text-align: right;">{$value['REAL_PRICE']}</td>
                    <td>{$value['BUY_NUMS']}</td>
                    <td style="text-align: right;">{$value['TAX_RATE']}</td>
                    <td style="text-align: right;">{$taxAmount}</td>
                    <td style="text-align: right;">{$totalAmount}</td> 
                </tr>
EOT;
            }

            $memberCode = Yii::t('app', 'memberCode');
            $memberName = Yii::t('app', 'memberName');
            $memberAddress = Yii::t('app', 'memberAddress');
            $memberPhone = Yii::t('app', 'memberPhone');
            $orderCode = Yii::t('app', 'orderCode');
            $orderDetail = Yii::t('app', 'orderDetail');
            $productCode = Yii::t('app', 'productCode');
            $productName = Yii::t('app', 'productName');
            $productPrice = Yii::t('app', 'productPrice');
            $quantity = Yii::t('app', 'qty');
            $taxRate = Yii::t('app', 'taxRate');
            $totalTax = Yii::t('app', 'totalTax');
            $totalAmount = Yii::t('app', 'totalAmount');
            $total = Yii::t('app', 'total');
            $signature = Yii::t('app', 'signature');
            $date = Yii::t('app', 'date');
            $createAt = Yii::t('app', 'createAt');

            // 订单基本信息
            $orderBase = <<<ORDER
            <table border="1" style="table-layout: fixed; padding: 10px 20px;" width="100%">
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$memberCode}</td>
                    <td width="70%">{$userId}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$memberName}</td>
                    <td width="70%">{$userName}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$memberAddress}</td>
                    <td width="70%">{$address}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$memberPhone}</td>
                    <td width="70%">{$mobile}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$orderCode}</td>
                    <td width="70%">{$orderSn}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$createAt}</td>
                    <td width="70%">{$orderAt}</td>
                </tr>
                <tr>
                    <td class="bg" style="font-weight: bold; font-size: 14px; text-align: center;">{$orderDetail}</td>
                    <td class="bg"></td>
                </tr>
            </table>
ORDER;

            $l['a_meta_charset'] = 'UTF-8';
            $l['a_meta_dir'] = 'ltr';
            $l['a_meta_language'] = 'zh';
            $l['w_page'] = '页面';

            $orderAmount = Tool::formatAmount($orderAmount);
            $totalTaxAmount = Tool::formatAmount($totalTaxAmount);

            $context = <<<ORDER
            <!doctype html>
            <html lang="en">
            <head>
                <meta charset="UTF-8" />
                <title>{$orderDetail}</title>
                <style>
                    table {
                        border-collapse: collapse;
                    }
                    table td, table th {
                        border: 1px solid #ccc;
                        /*padding: 5px 5px;*/
                        border-collapse: collapse;
                    }
                    /*td {*/
                    /*    padding: 120px;*/
                    /*}*/
                    .bg {
                        background-color: #ccc;
                    }
                </style>
            </head>
            <body>
                <div class="content">
                    <p style="text-align: center; font-weight: bold; font-size: 22px;"><b>{$orderDetail}</b><br></p>
                    <div>
                        <div style="display: block; width: 100%;">
                            {$orderBase}
                            
                            <table border="1" width="100%" style="padding: 10px 5px; text-align: center;">
                                <tr>
                                    <th width="15%" style="font-size: 14px; font-weight: bold; text-align: center;">{$productCode}</th>
                                    <th width="20%" style="font-size: 14px; font-weight: bold; text-align: center;">{$productName}</th>
                                    <th width="15%" style="font-size: 14px; font-weight: bold; text-align: center;">{$productPrice}</th>
                                    <th width="10%" style="font-size: 14px; font-weight: bold; text-align: center;">{$quantity}</th>
                                    <th width="12%" style="font-size: 14px; font-weight: bold; text-align: center;">{$taxRate}</th>
                                    <th width="13%" style="font-size: 14px; font-weight: bold; text-align: center;">{$totalTax}</th>
                                    <th width="15%" style="font-size: 14px; font-weight: bold; text-align: center;">{$totalAmount}</th>
                                </tr>
                                {$orderDetails}
                                <tr>
                                    <td colspan="3">{$total}</td>
                                    <td style="text-align: right;">{$orderNums}</td>
                                    <td></td>
                                    <td style="text-align: right;">{$totalTaxAmount}</td>
                                    <td style="text-align: right;">{$orderAmount}</td>
                                </tr>
                            </table>
                        </div>
                        
                        <div style="width: 100%; margin-top: 50px; height: 30px;">
                            <table width="100%" style="border: none; padding: 10px 20px; text-align: center;">
                                <tr style="border: none;">
                                    <td width="70%" style="border: none;"></td>
                                    <td width="30%" style="font-weight: bold; text-align: left; font-size: 14px; border: none;">{$signature}：</td>
                                </tr>
                                <tr style="border: none;">
                                    <td width="70%" style="border: none;"></td>
                                    <td width="30%" style="font-weight: bold; text-align: left; font-size: 14px; border: none;">{$date}：</td>
                                </tr>
                            </table>
                        </div>
                    </div>
                </div>
            </body>
            </html>
ORDER;

            require_once (\Yii::$app->vendorPath . '/tecnickcom/tcpdf/tcpdf.php');

            $pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
            // 设置打印模式
            $pdf->SetCreator(PDF_CREATOR);
            $pdf->SetAuthor('DaZe');
            $pdf->SetTitle($orderSn);
            $pdf->SetSubject('TCPDF Tutorial');
            $pdf->SetKeywords('TCPDF, PDF, example, test, guide');
            // 是否显示页眉
            $pdf->setPrintHeader(false);
            // 设置页眉字体
            $pdf->setHeaderFont(Array('dejavusans', '', '12'));
            // 页眉距离顶部的距离
            $pdf->SetHeaderMargin('5');
            // 是否显示页脚
            $pdf->setPrintFooter(false);
            // 设置默认等宽字体
            $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
            // 设置行高
            $pdf->setCellHeightRatio(1);
            // 设置左、上、右的间距
            $pdf->SetMargins('30', '70', '30');
            // 设置是否自动分页  距离底部多少距离时分页
            $pdf->SetAutoPageBreak(TRUE, '15');
            // 设置图像比例因子
            $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
            if (@file_exists(\Yii::$app->vendorPath . 'tecnickcom/tcpdf/examples/lang/eng.php')) {
                require_once(\Yii::$app->vendorPath . '/tecnickcom/tcpdf/examples/lang/eng.php');
                $pdf->setLanguageArray($l);
            }
            $pdf->setFontSubsetting(true);
            $pdf->AddPage();
            // 设置字体
            $pdf->SetFont('dejavusans', '', 10, '', true);
            //        $image_file = \Yii::$app->basePath . '/../frontendEle/src/static/img/ngds-logo.jpg';
//        if (!file_exists($image_file)) {
//            $image_file = \Yii::$app->runtimePath . '/../common/uploads/ngds-logo.jpg';
//        }
            // $image_file = \Yii::$app->basePath . '/../ngds-logo.jpg';
            // $image = file_get_contents($image_file);
            // 将图像放在右上角，根据页面宽度和边距计算位置
            // $pdf->Image('@' . $image, $pdf->getPageWidth() - 45, 25, 30, 10, 'JPG');
            $pdf->writeHTML($context);

            $result = $pdf->Output($realFile, 'F');
            LoggerTool::debug(['result' => $result]);

            $this->_updateFirst($realFile, 1);
        }

        $this->complete();
        return true;
    }

    /**
     * 生成
     * @return bool
     * @throws Exception
     * @throws InvalidConfigException
     * @throws \yii\httpclient\Exception
     */
    public function generateDecOrderPDF() {
        $this->getParams();
        if (!$this->params) {
            throw new Exception('无法获取需要的参数');
        }
        $path = __DS__ . $this->getSaveBasePath() . __DS__ . $this->getSavePath();
        $realFile = $path . __DS__ . $this->getFileName('.pdf');

        $this->completed = false;
        $this->getExportId();
        $this->getUserId();
        $fileNameUpdated = false;

        // 获取列表数据及表头
        $this->_listModel = new $this->listModelClass();
        $this->_listModel->isExport = true;

        // 查询订单数据
//        $oderList = $this->_loopWriteDataPDF($realFile, $fileNameUpdated);
        $orderQuery = Order::find()
            ->alias('O')
            ->where($this->params['condition'], $this->params['params'])
            ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', OrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->orderBy('O.CREATED_AT DESC');

        // 订单中间表只查询待支付和支付失败的订单
        $this->params['params'][':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value'];   // 待支付
        $this->params['params'][':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value'];   // 支付失败
        $orderStandardQuery = ApproachOrder::find()
            ->alias('O')
            ->where($this->params['condition'] . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params['params'])
            ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', ApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->orderBy('O.CREATED_AT DESC');

        $queryAll = $orderQuery->union($orderStandardQuery, true);
        $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]);
        $oderList = $query->all();

        if ($oderList) {
            $userId = '';
            $userName = '';
            $address = '';
            $mobile = '';
            $orderAt = '';
            $orderDetails = '';
            $orderSn = '';
            $orderAmount = 0;  // 合计总额
            $orderNums = 0; // 合计总数
            $totalTaxAmount = 0; // 合计税额
            $totalAmount = 0;
            foreach ($oderList as $key => $value) {
                $provinceName = $value['PROVINCE'] ? Region::getCnName($value['PROVINCE']) : '';
                $cityName = $value['CITY'] ? Region::getCnName($value['CITY']) : '';
                $countyName = $value['COUNTY'] ? Region::getCnName($value['COUNTY']) : '';

                $userId = $value['USER_NAME'];
                $userName = $value['REAL_NAME'];
                $address = $provinceName . $cityName . $countyName . $value['ADDRESS'];
                $mobile = $value['MOBILE'];
                $orderAt = Date::convert($value['CREATED_AT'],'Y-m-d H:i:s');
                $orderSn = $value['SN'];
                // 总价
                $totalAmount = $value['BUY_NUMS'] * $value['REAL_PRICE'];
                $orderAmount += $totalAmount;
                $orderNums += $value['BUY_NUMS'];
                // 税额
                $taxAmount = Tool::calculateTax($value['REAL_PRICE'], $value['TAX_RATE'], $value['BUY_NUMS']);
                $totalTaxAmount += $taxAmount;
                $taxAmount = Tool::formatAmount($taxAmount);
                $totalAmount = Tool::formatAmount($totalAmount);
                // 订单详情
                $orderDetails .= <<<EOT
                <tr>
                    <td>{$value['SKU_CODE']}</td>
                    <td>{$value['GOODS_TITLE']}</td>
                    <td style="text-align: right;">{$value['REAL_PRICE']}</td>
                    <td>{$value['BUY_NUMS']}</td>
                    <td style="text-align: right;">{$value['TAX_RATE']}</td>
                    <td style="text-align: right;">{$taxAmount}</td>
                    <td style="text-align: right;">{$totalAmount}</td> 
                </tr>
EOT;
            }

            $memberCode = Yii::t('app', 'memberCode');
            $memberName = Yii::t('app', 'memberName');
            $memberAddress = Yii::t('app', 'memberAddress');
            $memberPhone = Yii::t('app', 'memberPhone');
            $orderCode = Yii::t('app', 'orderCode');
            $orderDetail = Yii::t('app', 'orderDetail');
            $productCode = Yii::t('app', 'productCode');
            $productName = Yii::t('app', 'productName');
            $productPrice = Yii::t('app', 'productPrice');
            $quantity = Yii::t('app', 'qty');
            $taxRate = Yii::t('app', 'taxRate');
            $totalTax = Yii::t('app', 'totalTax');
            $totalAmount = Yii::t('app', 'totalAmount');
            $total = Yii::t('app', 'total');
            $signature = Yii::t('app', 'signature');
            $date = Yii::t('app', 'date');
            $createAt = Yii::t('app', 'createAt');

            // 订单基本信息
            $orderBase = <<<ORDER
            <table border="1" style="table-layout: fixed; padding: 10px 20px;" width="100%">
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$memberCode}</td>
                    <td width="70%">{$userId}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$memberName}</td>
                    <td width="70%">{$userName}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$memberAddress}</td>
                    <td width="70%">{$address}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$memberPhone}</td>
                    <td width="70%">{$mobile}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$orderCode}</td>
                    <td width="70%">{$orderSn}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">{$createAt}</td>
                    <td width="70%">{$orderAt}</td>
                </tr>
                <tr>
                    <td class="bg" style="font-weight: bold; font-size: 14px; text-align: center;">{$orderDetail}</td>
                    <td class="bg"></td>
                </tr>
            </table>
ORDER;

            $l['a_meta_charset'] = 'UTF-8';
            $l['a_meta_dir'] = 'ltr';
            $l['a_meta_language'] = 'zh';
            $l['w_page'] = '页面';

            $orderAmount = sprintf('%.2f', $orderAmount);
            $totalTaxAmount = sprintf('%.2f', $totalTaxAmount);

            $context = <<<ORDER
            <!doctype html>
            <html lang="en">
            <head>
                <meta charset="UTF-8" />
                <title>{$orderDetail}</title>
                <style>
                    table {
                        border-collapse: collapse;
                    }
                    table td, table th {
                        border: 1px solid #ccc;
                        /*padding: 5px 5px;*/
                        border-collapse: collapse;
                    }
                    /*td {*/
                    /*    padding: 120px;*/
                    /*}*/
                    .bg {
                        background-color: #ccc;
                    }
                </style>
            </head>
            <body>
                <div class="content">
                    <p style="text-align: center; font-weight: bold; font-size: 22px;"><b>{$orderDetail}</b><br></p>
                    <div>
                        <div style="display: block; width: 100%;">
                            {$orderBase}
                            
                            <table border="1" width="100%" style="padding: 10px 5px; text-align: center;">
                                <tr>
                                    <th width="15%" style="font-size: 14px; font-weight: bold; text-align: center;">{$productCode}</th>
                                    <th width="20%" style="font-size: 14px; font-weight: bold; text-align: center;">{$productName}</th>
                                    <th width="15%" style="font-size: 14px; font-weight: bold; text-align: center;">{$productPrice}</th>
                                    <th width="10%" style="font-size: 14px; font-weight: bold; text-align: center;">{$quantity}</th>
                                    <th width="12%" style="font-size: 14px; font-weight: bold; text-align: center;">{$taxRate}</th>
                                    <th width="13%" style="font-size: 14px; font-weight: bold; text-align: center;">{$totalTax}</th>
                                    <th width="15%" style="font-size: 14px; font-weight: bold; text-align: center;">{$totalAmount}</th>
                                </tr>
                                {$orderDetails}
                                <tr>
                                    <td colspan="3">{$total}</td>
                                    <td style="text-align: right;">{$orderNums}</td>
                                    <td></td>
                                    <td style="text-align: right;">{$totalTaxAmount}</td>
                                    <td style="text-align: right;">{$orderAmount}</td>
                                </tr>
                            </table>
                        </div>
                        
                        <div style="width: 100%; margin-top: 50px; height: 30px;">
                            <table width="100%" style="border: none; padding: 10px 20px; text-align: center;">
                                <tr style="border: none;">
                                    <td width="70%" style="border: none;"></td>
                                    <td width="30%" style="font-weight: bold; text-align: left; font-size: 14px; border: none;">{$signature}：</td>
                                </tr>
                                <tr style="border: none;">
                                    <td width="70%" style="border: none;"></td>
                                    <td width="30%" style="font-weight: bold; text-align: left; font-size: 14px; border: none;">{$date}：</td>
                                </tr>
                            </table>
                        </div>
                    </div>
                </div>
            </body>
            </html>
ORDER;

            require_once (\Yii::$app->vendorPath . '/tecnickcom/tcpdf/tcpdf.php');

            $pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
            // 设置打印模式
            $pdf->SetCreator(PDF_CREATOR);
            $pdf->SetAuthor('DaZe');
            $pdf->SetTitle($orderSn);
            $pdf->SetSubject('TCPDF Tutorial');
            $pdf->SetKeywords('TCPDF, PDF, example, test, guide');
            // 是否显示页眉
            $pdf->setPrintHeader(false);
            // 设置页眉字体
            $pdf->setHeaderFont(Array('dejavusans', '', '12'));
            // 页眉距离顶部的距离
            $pdf->SetHeaderMargin('5');
            // 是否显示页脚
            $pdf->setPrintFooter(false);
            // 设置默认等宽字体
            $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
            // 设置行高
            $pdf->setCellHeightRatio(1);
            // 设置左、上、右的间距
            $pdf->SetMargins('10', '10', '10');
            // 设置是否自动分页  距离底部多少距离时分页
            $pdf->SetAutoPageBreak(TRUE, '15');
            // 设置图像比例因子
            $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
            if (@file_exists(\Yii::$app->vendorPath . 'tecnickcom/tcpdf/examples/lang/eng.php')) {
                require_once(\Yii::$app->vendorPath . '/tecnickcom/tcpdf/examples/lang/eng.php');
                $pdf->setLanguageArray($l);
            }
            $pdf->setFontSubsetting(true);
            $pdf->AddPage();
            // 设置字体
            $pdf->SetFont('stsongstdlight', '', 10, '', true);
            $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
            //        $image_file = \Yii::$app->basePath . '/../frontendEle/src/static/img/ngds-logo.jpg';
//        if (!file_exists($image_file)) {
//            $image_file = \Yii::$app->runtimePath . '/../common/uploads/ngds-logo.jpg';
//        }
            $image_file = \Yii::$app->basePath . '/../ngds-logo.jpg';
            $image = file_get_contents($image_file);
            $pdf->Image('@' . $image, 165, 5, 20, 10, 'JPG');
            $pdf->writeHTML($context);
            $pdf->Output($realFile, 'F');

            $this->_updateFirst($realFile, 1);
        }

        $this->complete();
        return true;
    }

    /**
     * 循环写入数据
     * @param $realFile
     * @param $fileNameUpdated
     * @param int $page
     * @param int $counter
     * @return array
     * @throws Exception
     */
    private function _loopWriteDataPDF($realFile, &$fileNameUpdated, $page = 0, $counter = 0){
        if(method_exists($this->_listModel, 'getList')){
            $list = $this->_listModel->getList(['condition'=>$this->params['condition'], 'params'=>isset($this->params['params']) ? $this->params['params'] : [], 'others'=>isset($this->params['others']) ? $this->params['others'] : [], 'page'=>$page, 'pageSize'=>$this->pageSize, 'userId'=>$this->userId]);
        } else {
            throw new Exception($this->listModelClass.'的getList方法不存在');
        }

        return $list['list'];
    }

    /**
     * 生成
     * @return bool
     * @throws Exception
     * @throws InvalidConfigException
     * @throws \yii\httpclient\Exception
     */
    public function generateBaOrderExcel() {
        $this->getParams();
        if (!$this->params) {
            throw new Exception('无法获取需要的参数');
        }
        $path = $this->getSaveBasePath() . __DS__ . $this->getSavePath();
        $path = __DS__ . $path;
        $realFile = $this->mkdir($path) . __DS__ . $this->getFileName();
        $this->completed = false;
        $this->getExportId();
        $this->getUserId();
        $this->_fp = fopen($realFile, 'w');
        @exec('chown -R www:www /'.$realFile);
        @exec('chmod -R 777 /'.$realFile);
        // 获取列表数据及表头
        $this->_listModel = new $this->listModelClass();
        $this->_listModel->isExport = true;
        if(method_exists($this->_listModel, 'getExportHeaders')){
            if(method_exists($this->_listModel, 'exportPrepare')) {//导出数据提前设置参数
                $this->_listModel->exportPrepare(['condition' => $this->params['condition'], 'params' => $this->params['params'], 'others' => $this->params['others'] ?? [], 'page' => 0, 'pageSize' => 100000, 'userId' => $this->userId]);
            }
            $headers = $this->_listModel->getExportHeaders($this->userId);
            fputcsv($this->_fp, $headers);
            unset($headers);
            $this->_updateFirst($realFile, 1);
        } else {
            throw new Exception($this->listModelClass.'的getExportHeaders方法不存在');
        }
        $this->_loopWriteDataBaOrder();
        $this->complete();
        return true;
    }

    /**
     * 循环写入数据
     */
    private function _loopWriteDataBaOrder()
    {
        $orderQuery = BaOrder::find()
            ->alias('O')
            ->where($this->params['condition'], $this->params['params'])
            ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
            ->join('LEFT JOIN', BaUser::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', BaOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->orderBy('O.CREATED_AT DESC');

        // 订单中间表只查询待支付和支付失败的订单
        $this->params['params'][':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value'];   // 待支付
        $this->params['params'][':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value'];   // 支付失败
        $orderStandardQuery = BaApproachOrder::find()
            ->alias('O')
            ->where($this->params['condition'] . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params['params'])
            ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
            ->join('LEFT JOIN', BaUser::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', BaApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->orderBy('O.CREATED_AT DESC');

        $queryAll = $orderQuery->union($orderStandardQuery, true);
        $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]);
        $lists = $query->all();

        if(!empty($lists)){
            $regionConfig = Cache::getRegionConfig();
            foreach($lists as $columnData) {
                $CREATE_USER_ID = Info::getBaUserIdByUserName($columnData['CREATE_USER']);
                $createUserName = Info::getBaUserRealNameByUserId($CREATE_USER_ID);
                $decUserName = Info::getBaUserNameByUserId($columnData['DEC_ID']);

                $columnAccept = [
                    'USER_NAME' => $columnData['USER_NAME'],
                    'DEC_USER_NAME' => $decUserName,
                    'CREATE_USER' => $columnData['CREATE_USER'],
                    'CREATE_USER_NAME' => $createUserName,
                    'SN' => $columnData['SN'],
                    'STATUS' => Tool::paramConvert(\Yii::$app->params['orderStatus'])[$columnData['STATUS']]['label'] ?? '',
                    'SKU_CODE' => $columnData['SKU_CODE'],
                    'GOODS_TITLE' => $columnData['GOODS_TITLE'],
                    'BUY_NUMS' => $columnData['BUY_NUMS'],
                    'CONSIGNEE' => $columnData['CONSIGNEE'],
                    'MOBILE' => "\t{$columnData['MOBILE']}",
                    'TEL' => "\t{$columnData['TEL']}",
                    'PROVINCE' => $regionConfig[$columnData['PROVINCE']]['REGION_NAME'] ?? '',
                    'CITY' => $regionConfig[$columnData['CITY']]['REGION_NAME'] ?? '',
                    'COUNTY' => $regionConfig[$columnData['COUNTY']]['REGION_NAME'] ?? '',
                    'ADDRESS' => $columnData['ADDRESS'],
                    'PERIOD_NUM' => $columnData['PERIOD_NUM'],
                    'ORDER_TYPE' => ($columnData['ORDER_TYPE'] == 'ZC') ? 'Welcome pack' : (in_array($columnData['PAY_TYPE'], ['cash', 'pay_stack']) ? 'Reselling': 'Points'),
                    'CREATED_AT' => Date('Y-m-d H:i:s', $columnData['CREATED_AT']),
                    'PAY_TYPE' => ShopGoods::payTypes()[$columnData['PAY_TYPE']]['name'] ?? ShopGoods::payTypes()['cash']['name'],
                    'PAY_AT' => $columnData['PAY_AT'] > 0 ? Date('Y-m-d H:i:s', $columnData['PAY_AT']) : '',
                    'DELIVERY_AT' => $columnData['DELIVERY_AT'] > 0 ? Date('Y-m-d H:i:s', $columnData['DELIVERY_AT']) : '',
                    'REAL_PRICE' => $columnData['REAL_PRICE'] ?? 0,
                    'REAL_PV' => $columnData['REAL_PV'] ?? 0,
                    'PAY_FREIGHT' => $columnData['PAY_FREIGHT'] ?? 0,
                    'TAX_RATE' => $columnData['TAX_RATE'],
                    'TAX_AMOUNT' => Tool::calculateTax($columnData['REAL_PRICE'], $columnData['TAX_RATE'], $columnData['BUY_NUMS']),
                    'EXPRESS_COMPANY' => $columnData['EXPRESS_COMPANY'],
                    'ORDER_TRACK_NO' => $columnData['ORDER_TRACK_NO'],
                    'EXPRESS_TYPE' => $columnData['EXPRESS_TYPE'] == 0 ? 'mailing ':' auto pick',
                    'FRONT_REMARK' => $columnData['FRONT_REMARK'],
                    'DELIVERY_STATUS_NAME' => Tool::paramConvert(\Yii::$app->params['deliveryStatus'])[$columnData['DELIVERY_STATUS']]['label'] ?? '',
                ];

                fputcsv($this->_fp, Tool::arrTextConvert($columnAccept));
                unset($percent, $columnData, $columnAccept);
            }
            unset($list);
        }

        unset($list);
        return 'finish';
    }

    /**
     * 生成
     * @return bool
     * @throws Exception
     * @throws InvalidConfigException
     * @throws \yii\httpclient\Exception
     */
    public function generateBaOrderPDF()
    {
        $this->getParams();
        if (!$this->params) {
            throw new Exception('无法获取需要的参数');
        }
        $path = __DS__ . $this->getSaveBasePath() . __DS__ . $this->getSavePath();
        $realFile = $path . __DS__ . $this->getFileName('.pdf');

        $this->completed = false;
        $this->getExportId();
        $this->getUserId();
        $fileNameUpdated = false;

        // 获取列表数据及表头
        $this->_listModel = new $this->listModelClass();
        $this->_listModel->isExport = true;

        // 查询订单数据
        $orderQuery = BaOrder::find()
            ->alias('O')
            ->where($this->params['condition'], $this->params['params'])
            ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
            ->join('LEFT JOIN', BaUser::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', BaOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->orderBy('O.CREATED_AT DESC');

        // 订单中间表只查询待支付和支付失败的订单
        $this->params['params'][':NOT_PAID'] = \Yii::$app->params['orderStatus']['notPaid']['value'];   // 待支付
        $this->params['params'][':FAIL_PAID'] = \Yii::$app->params['orderStatus']['failPaid']['value'];   // 支付失败
        $orderStandardQuery = BaApproachOrder::find()
            ->alias('O')
            ->where($this->params['condition'] . ' AND (O.STATUS = :NOT_PAID OR O.STATUS = :FAIL_PAID)', $this->params['params'])
            ->select('O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
            ->join('LEFT JOIN', BaUser::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', BaApproachOrderGoods::tableName() . ' AS OG', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->orderBy('O.CREATED_AT DESC');

        $queryAll = $orderQuery->union($orderStandardQuery, true);
        $query = (new Query())->from(['Q' => $queryAll])->select('Q.*')->distinct()->orderBy(['CREATED_AT' => SORT_DESC]);
        $oderList = $query->all();

        if ($oderList) {
            $userId = '';
            $userName = '';
            $address = '';
            $mobile = '';
            $orderAt = '';
            $orderDetails = '';
            $orderSn = '';
            $orderAmount = 0;  // 合计总额
            $orderNums = 0; // 合计总数
            $totalTaxAmount = 0; // 合计税额
            $totalAmount = 0;
            foreach ($oderList as $key => $value) {
                $provinceName = $value['PROVINCE'] ? Region::getCnName($value['PROVINCE']) : '';
                $cityName = $value['CITY'] ? Region::getCnName($value['CITY']) : '';
                $countyName = $value['COUNTY'] ? Region::getCnName($value['COUNTY']) : '';

                $userId = $value['USER_NAME'];
                $userName = $value['REAL_NAME'];
                $address = $provinceName . $cityName . $countyName . $value['ADDRESS'];
                $mobile = $value['MOBILE'];
                $orderAt = Date::convert($value['CREATED_AT'],'Y-m-d H:i:s');
                $orderSn = $value['SN'];
                // 总价
                $totalAmount = $value['BUY_NUMS'] * $value['REAL_PRICE'];
                $orderAmount += $totalAmount;
                $orderNums += $value['BUY_NUMS'];
                // 税额
                $taxAmount = Tool::calculateTax($value['REAL_PRICE'], $value['TAX_RATE'], $value['BUY_NUMS']);
                $totalTaxAmount += $taxAmount;
                $taxAmount = Tool::formatAmount($taxAmount);
                $totalAmount = Tool::formatAmount($totalAmount);
                // 订单详情
                $orderDetails .= <<<EOT
                <tr>
                    <td>{$value['SKU_CODE']}</td>
                    <td>{$value['GOODS_TITLE']}</td>
                    <td style="text-align: right;">{$value['REAL_PRICE']}</td>
                    <td>{$value['BUY_NUMS']}</td>
                    <td style="text-align: right;">{$value['TAX_RATE']}</td>
                    <td style="text-align: right;">{$taxAmount}</td>
                    <td style="text-align: right;">{$totalAmount}</td> 
                </tr>
EOT;
            }

            // 订单基本信息
            $orderBase = <<<ORDER
            <table border="1" style="table-layout: fixed; padding: 10px 20px;" width="100%">
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">Member Code</td>
                    <td width="70%">{$userId}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">Member Name</td>
                    <td width="70%">{$userName}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">Member Address</td>
                    <td width="70%">{$address}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">Member Phone</td>
                    <td width="70%">{$mobile}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">Order Code</td>
                    <td width="70%">{$orderSn}</td>
                </tr>
                <tr>
                    <td width="30%" style="font-weight: bold; text-align: center; font-size: 14px;">Creation Time</td>
                    <td width="70%">{$orderAt}</td>
                </tr>
                <tr>
                    <td class="bg" style="font-weight: bold; font-size: 14px; text-align: center;">Order Detail</td>
                    <td class="bg"></td>
                </tr>
            </table>
ORDER;

            $l['a_meta_charset'] = 'UTF-8';
            $l['a_meta_dir'] = 'ltr';
            $l['a_meta_language'] = 'zh';
            $l['w_page'] = '页面';

            $orderAmount = Tool::formatAmount($orderAmount);
            $totalTaxAmount = Tool::formatAmount($totalTaxAmount);

            $context = <<<ORDER
            <!doctype html>
            <html lang="en">
            <head>
                <meta charset="UTF-8" />
                <title>Order detail</title>
                <style>
                    table {
                        border-collapse: collapse;
                    }
                    table td, table th {
                        border: 1px solid #ccc;
                        padding: 5px 5px;
                        border-collapse: collapse;
                    }
                    /*td {*/
                    /*    padding: 120px;*/
                    /*}*/
                    .bg {
                        background-color: #ccc;
                    }
                </style>
            </head>
            <body>
                <div class="content">
                    <p style="text-align: center; font-weight: bold; font-size: 22px;"><b>Order detail</b><br></p>
                    <div>
                        <div style="display: block; width: 100%;">
                            {$orderBase}
                            
                            <table border="1" width="100%" style="padding: 10px 5px; text-align: center;">
                                <tr>
                                    <th width="15%" style="font-size: 14px; font-weight: bold; text-align: center;">Product Code</th>
                                    <th width="25%" style="font-size: 14px; font-weight: bold; text-align: center;">Product Name</th>
                                    <th width="15%" style="font-size: 14px; font-weight: bold; text-align: center;">Product Price</th>
                                    <th width="10%" style="font-size: 14px; font-weight: bold; text-align: center;">Qty</th>
                                    <th width="10%" style="font-size: 14px; font-weight: bold; text-align: center;">Tax Rate</th>
                                    <th width="10%" style="font-size: 14px; font-weight: bold; text-align: center;">Tax</th>
                                    <th width="15%" style="font-size: 14px; font-weight: bold; text-align: center;">Total Amount</th>
                                </tr>
                                {$orderDetails}
                                <tr>
                                    <td colspan="3">Total</td>
                                    <td>{$orderNums}</td>
                                    <td></td>
                                    <td style="text-align: right;">{$totalTaxAmount}</td>
                                    <td style="text-align: right;">{$orderAmount}</td>
                                </tr>
                            </table>
                        </div>
                        
                        <div style="width: 100%; margin-top: 50px; height: 30px;">
                            <table width="100%" style="border: none; padding: 10px 20px; text-align: center;">
                                <tr style="border: none;">
                                    <td width="70%" style="border: none;"></td>
                                    <td width="30%" style="font-weight: bold; text-align: left; font-size: 14px; border: none;">Signature：</td>
                                </tr>
                                <tr style="border: none;">
                                    <td width="70%" style="border: none;"></td>
                                    <td width="30%" style="font-weight: bold; text-align: left; font-size: 14px; border: none;">Date：</td>
                                </tr>
                            </table>
                        </div>
                    </div>
                </div>
            </body>
            </html>
ORDER;

            require_once (\Yii::$app->vendorPath . '/tecnickcom/tcpdf/tcpdf.php');

            $pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
            // 设置打印模式
            $pdf->SetCreator(PDF_CREATOR);
            $pdf->SetAuthor('DaZe');
            $pdf->SetTitle($orderSn);
            $pdf->SetSubject('TCPDF Tutorial');
            $pdf->SetKeywords('TCPDF, PDF, example, test, guide');
            // 是否显示页眉
            $pdf->setPrintHeader(false);
            // 设置页眉字体
            $pdf->setHeaderFont(Array('dejavusans', '', '12'));
            // 页眉距离顶部的距离
            $pdf->SetHeaderMargin('5');
            // 是否显示页脚
            $pdf->setPrintFooter(false);
            // 设置默认等宽字体
            $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
            // 设置行高
            $pdf->setCellHeightRatio(1);
            // 设置左、上、右的间距
            $pdf->SetMargins('10', '0', '10');
            // 设置是否自动分页  距离底部多少距离时分页
            $pdf->SetAutoPageBreak(TRUE, '15');
            // 设置图像比例因子
            $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
            if (@file_exists(\Yii::$app->vendorPath . 'tecnickcom/tcpdf/examples/lang/eng.php')) {
                require_once(\Yii::$app->vendorPath . '/tecnickcom/tcpdf/examples/lang/eng.php');
                $pdf->setLanguageArray($l);
            }
            $pdf->setFontSubsetting(true);
            $pdf->AddPage();
            // 设置字体
            $pdf->SetFont('stsongstdlight', '', 10, '', true);
            //        $image_file = \Yii::$app->basePath . '/../frontendEle/src/static/img/ngds-logo.jpg';
//        if (!file_exists($image_file)) {
//            $image_file = \Yii::$app->runtimePath . '/../common/uploads/ngds-logo.jpg';
//        }
            $image_file = \Yii::$app->basePath . '/../ngds-logo.jpg';
            $image = file_get_contents($image_file);
            $pdf->Image('@' . $image, 15, 12, 20, 7, 'JPG');
            $pdf->writeHTML($context);
            $pdf->Output($realFile, 'F');

            $this->_updateFirst($realFile, 1);
        }

        $this->complete();
        return true;
    }

    /**
     * 生成
     * @return bool
     * @throws Exception
     * @throws InvalidConfigException
     * @throws \yii\httpclient\Exception
     */
    public function actionOrderInvoiceExport() {
        $this->getParams();
        if (!$this->params) {
            throw new Exception('无法获取需要的参数');
        }
        $path = __DS__ . $this->getSaveBasePath() . __DS__ . $this->getSavePath();
        $realFile = $this->mkdir($path) . __DS__ . $this->getFileName('.pdf');

        $this->completed = false;
        $this->getExportId();
        $this->getUserId();
        $fileNameUpdated = false;

        // 获取列表数据及表头
        $this->_listModel = new $this->listModelClass();
        $this->_listModel->isExport = true;

        // 查询订单数据
        // 使用新的查询对象，禁用查询缓存，确保获取最新数据
        $query = OrderGoods::find()
            ->alias('OG')
            ->where($this->params['condition'], $this->params['params'])
            ->select('OG.ID AS AID,O.*,U.REAL_NAME,U.DEC_ID,SG.CATEGORY_TYPE,OG.REAL_PRICE,OG.TAX_RATE,OG.BUY_NUMS,OG.SKU_CODE,OG.GOODS_TITLE,OG.REAL_PV')
            ->join('LEFT JOIN', ORDER::tableName() . ' AS O', 'OG.ORDER_SN=O.SN')
            ->join('LEFT JOIN', User::tableName() . ' AS U', 'U.ID=O.USER_ID')
            ->join('LEFT JOIN', ShopGoods::tableName() . ' AS SG', 'SG.ID=OG.GOODS_ID')
            ->asArray()
            ->noCache(); // 禁用查询缓存

        // 添加详细的调试信息
        $rawSql = $query->createCommand()->getRawSql();
        $oderList = $query->all();

        $sn = $oderList[0]['SN'];
        // 同时使用原生SQL查询进行对比测试
        $nativeConnection = Yii::$app->db;
        $nativeQuery = "
            SELECT 
             `OG`.`ID` AS `AID`, 
             `O`.*, 
             `U`.`REAL_NAME`, 
             `U`.`DEC_ID`, 
             `SG`.`CATEGORY_TYPE`, 
             `OG`.`REAL_PRICE`, 
             `OG`.`TAX_RATE`, 
             `OG`.`BUY_NUMS`, 
             `OG`.`SKU_CODE`, 
             `OG`.`GOODS_TITLE`, 
             `OG`.`REAL_PV` 
        FROM 
             `AR_ORDER_GOODS` `OG` 
             LEFT JOIN `AR_ORDER` `O` ON OG.ORDER_SN = O.SN 
             LEFT JOIN `AR_USER` `U` ON U.ID = O.USER_ID 
             LEFT JOIN `AR_SHOP_GOODS` `SG` ON SG.ID = OG.GOODS_ID 
        WHERE 
             O.IS_DELETE = 0 
             AND O.SN = '{$sn}' 
        ORDER BY 
             `O`.`CREATED_AT` DESC";
        $nativeResults = $nativeConnection->createCommand($nativeQuery)->queryAll();

        // 如果原生查询有结果但Yii查询没有，使用原生查询结果
        if(count($nativeResults) > 0 && count($oderList) < count($nativeResults)) {
            $oderList = $nativeResults;
        }

        if ($oderList) {
            $userId = '';
            $userName = '';
            $address = '';
            $mobile = $oderList[0]['MOBILE'];
            $orderAt = Date::convert($oderList[0]['CREATED_AT'],'d/m/Y');
            $orderDetails = '';
            $orderDetails_bv = '';
            $orderSn = $oderList[0]['SN'];;
            $orderAmount = 0;  // 合计总额
            $orderNums = 0; // 合计总数
            $totalTaxAmount = 0; // 合计税额
            $totalAmount = 0;
            $paymentStatus = 'Paid'; // 支付状态
            $invoiceRemark = $oderList[0]['INVOICE_REMARK'];
            $paymentMethod = $oderList[0]['METHOD']??'Cash'; // 支付方式
            $currency = Currency::findOne($oderList[0]['CURRENCY_ID'])['CODE'] ?? '';;
            $invoiceNo = $oderList[0]['INVOICE_NO'];

            $provinceName = $oderList[0]['PROVINCE'] ? Region::getCnName($oderList[0]['PROVINCE']) : '';
            $cityName = $oderList[0]['CITY'] ? Region::getCnName($oderList[0]['CITY']) : '';
            $countyName = $oderList[0]['COUNTY'] ? Region::getCnName($oderList[0]['COUNTY']) : '';
            $address = $provinceName . $cityName . $countyName . $oderList[0]['ADDRESS'];

            $paymentStatus = \Yii::$app->params['orderStatus'][$oderList[0]['STATUS']]['label'] ?? 'Paid';

            $orderTotalBv = 0;
            $orderTotalTaxAmount = 0;
            $orderTotalAmount = 0;
            $orderTotal = 0;
            $orderTotalQuantity = count($oderList);

            $no = 0;
            foreach ($oderList as $key => $value) {
                $no += 1;

                $userId = $value['USER_NAME'];
                $userName = $value['REAL_NAME'];

                // 总价
                $totalAmount = $value['BUY_NUMS'] * $value['REAL_PRICE'];
                $orderAmount += $totalAmount;
                $orderNums += $value['BUY_NUMS'];
                // 税额
                $taxAmount = Tool::calculateTax($value['REAL_PRICE'], $value['TAX_RATE'], $value['BUY_NUMS']);
                $totalTaxAmount += $taxAmount;
                $totalBv = $value['BUY_NUMS'] * $value['REAL_PV'];
                $orderTotalBv += $totalBv;

                $orderTotalTaxAmount += $taxAmount;
                $orderTotalAmount += $totalAmount - $taxAmount;
                $orderTotal += $totalAmount;

                $totalBvFormat = Tool::formatAmount($totalBv);
                $taxableAmountFormat =Tool::formatAmount($taxAmount);
                $vatAmountFormat = Tool::formatAmount($totalAmount - $taxAmount);
                $totalFormat = Tool::formatAmount($totalAmount);
                $vatRateFormat = Tool::formatAmount($value['TAX_RATE']) . '%';
                $unitPriceFormat = Tool::formatAmount($value['REAL_PRICE']);
                $unitBvFormat = Tool::formatAmount($value['REAL_PV']);

                // 订单详情
                //ek-3391 Taxable Amount和VAT Amount字段取值错误（两个取值取反了），需要修改 (2025/11/25 13:35 Ryan)
                $orderDetails .= <<<EOT
                <tr style="text-align: left; font-weight: normal; font-size: 12px; width: 100%; padding: 5px 5px;">
                    <td style="white-space: nowrap;">{$no}</td>
                    <td>{$value['SKU_CODE']}</td>
                    <td>{$value['GOODS_TITLE']}</td>
                    <td>{$value['BUY_NUMS']}</td>
                    <td>{$unitPriceFormat}</td>
<!--                    <td>{$unitBvFormat}</td>-->
<!--                    <td>{$totalBvFormat}</td>-->
                    <td colspan="2">{$vatAmountFormat}</td> 
                    <td>{$vatRateFormat}</td>
                    <td colspan="2">{$taxableAmountFormat}</td>
                    <td>{$totalFormat}</td> 
                </tr>
EOT;
                $orderDetails_bv .= <<<EOT
                <tr style="text-align: left; font-weight: normal; font-size: 12px;">
                    <td colspan="7" class="table-noborder"></td>
                    <td>{$value['SKU_CODE']}</td>
                    <td>{$value['BUY_NUMS']}</td>
                    <td>{$unitBvFormat}</td>
                    <td>{$totalBvFormat}</td>
                </tr>
EOT;
            }

            $memberCode = Yii::t('app', 'memberCode');
            $memberName = Yii::t('app', 'memberName');
            $memberAddress = Yii::t('app', 'memberAddress');
            $memberPhone = Yii::t('app', 'memberPhone');
            $orderCode = Yii::t('app', 'orderCode');
            $taxInvoice = Yii::t('app', 'taxInvoice');
            $productCode = Yii::t('app', 'productCode');
            $productName = Yii::t('app', 'productName');
            $productPrice = Yii::t('app', 'productPrice');
            $quantity = Yii::t('app', 'qty');
            $taxRate = Yii::t('app', 'taxRate');
            $totalTax = Yii::t('app', 'totalTax');
            $totalAmount = Yii::t('app', 'totalAmount');
            $total = Yii::t('app', 'total');
            $signature = Yii::t('app', 'signature');
            $date = Yii::t('app', 'date');
            $createAt = Yii::t('app', 'createAt');

            $l['a_meta_charset'] = 'UTF-8';
            $l['a_meta_dir'] = 'ltr';
            $l['a_meta_language'] = 'zh';
            $l['w_page'] = '页面';

            $orderAmount = Tool::formatAmount($orderAmount);
            $totalTaxAmount = Tool::formatAmount($totalTaxAmount);

            $orderTotalBv = Tool::formatAmount($orderTotalBv);
            $orderTotalTaxAmount = Tool::formatAmount($orderTotalTaxAmount);
            $orderTotalAmount = Tool::formatAmount($orderTotalAmount);
            $orderTotal = Tool::formatAmount($orderTotal);

            $context = <<<ORDER
        <!doctype html>
        <html lang="en">
            <head>
                <meta charset="UTF-8" />
                <title>{$taxInvoice}</title>
                <style>
                    table {
                        border-collapse: collapse;
                    }
                    table td, table th {
                        border: 1px solid #ccc;
                        border-collapse: collapse;
                    }
                    .bg {
                        background-color: #ccc;
                    }
                    
                    /* 无边框表格样式类 */
                    .table-noborder {
                      border-collapse: collapse; /* 合并边框（避免残留间隙） */
                      border-spacing: 0; /* 清除单元格之间的默认间隙 */
                      empty-cells: show; /* 不影响空单元格（可选，避免意外显示） */
                    }
                    /* 清除 table、th、td 的所有边框 */
                    .table-noborder,
                    .table-noborder th,
                    .table-noborder td {
                      border: none !important; /* !important 可选，用于覆盖冲突样式 */
                      outline: none; /* 清除可能的默认轮廓（可选） */
                    }
                </style>
            </head>
            <body style="font-weight: normal; margin: 0; padding: 0; line-height: 1.3;">
                <div class="content" style="line-height: 1.3; font-weight: normal;">
                    <div style="display: flex; justify-content: space-between; align-items: flex-start; width: 100%;">
                        <div style="width: 70%;">
                            <p style="text-align: left; font-weight: bold; font-size: 16px; margin: 0 !important; padding: 0 !important; line-height: 1.3 !important;"><b>TAX INVOICE</b></p>
                            <p style="text-align: left; font-size: 14px; margin: 0 !important; padding: 0 !important; line-height: 1.3 !important;">ELKEN ARABIYA GENERAL TRADING CO. LLC</p>
                            <p style="text-align: left; font-size: 13px; margin: 0 !important; padding: 0 !important; line-height: 1.3 !important;">Shop No.2, Plot 356-1142, Juneirah Street, Umm Suqeim 1, Dubai, UAE</p>
                            <p style="text-align: left; font-size: 13px; margin: 0 !important; padding: 0 !important; line-height: 1.3 !important;">Phone: +971042296118</p>
                            <p style="text-align: left; font-size: 13px; margin: 0 !important; padding: 0 !important; line-height: 1.3 !important;">License No: 1314319</p>
                            <p style="text-align: left; font-size: 13px; margin: 0 !important; padding: 0 !important; line-height: 1.3 !important;">TRN No: 105034822400003</p>
                        </div>
                        <div style="width: 25%; text-align: right;">
                            <!-- 图像将通过TCPDF直接插入 -->
                        </div>
                    </div>
                    
                    <hr />
                    <br>
                    <br>
                    <div style="width: 100%; line-height: 15px; margin-left: 0; margin-right: 0; margin-top: 0; margin-bottom: 0; padding: 0;">
                        <table class="table-noborder" width="100%">
                            <tr style="text-align: left; font-size: 12px; font-weight: normal; height: 50px; vertical-align: middle;">
                                <td>
                                    Bill to
                                </td>
                                <td>
                                </td>
                            </tr>
                            <tr style="text-align: left; font-size: 12px; font-weight: normal; height: 50px; vertical-align: middle;">
                                <td>
                                    Name of Distributor: {$userName}
                                </td>   
                                <td>
                                    Invoice No.: {$invoiceNo}
                                </td>
                            </tr>
                            <tr style="text-align: left; font-size: 12px; font-weight: normal; height: 50px; vertical-align: middle;">
                                <td>
                                    Member ID: {$userId}
                                </td>
                                <td>
                                    Order No.: {$orderSn}
                                </td>
                            </tr>
                            <tr style="text-align: left; font-size: 12px; font-weight: normal; height: 50px; vertical-align: middle;">
                                <td>
                                    Address: {$address}
                                </td>
                                <td>
                                    Date: {$orderAt}
                                </td>
                            </tr>
                            <tr style="text-align: left; font-size: 12px; font-weight: normal; height: 50px; vertical-align: middle;">
                                <td>
                                    Contact: {$mobile}
                                </td>
                                <td>
                                    Payment status: {$paymentStatus}
                                </td>
                            </tr>
                        </table>
                        
                        <br />
                        <br />
                        <br />
                        
                        <table style="table-layout: fixed;" width="100%">
                            <tr style="text-align: left; font-weight: normal; font-size: 12px;">
                                <th style="width: 5%; white-space: nowrap;">No.</th>
                                <th style="width: 10%; white-space: normal; word-break: break-word;">Product Code</th>
                                <th style="width: 19%; white-space: normal; word-break: break-word;">Product Name</th>
                                <th style="width: 8%; white-space: nowrap;">Quantity</th>
                                <th style="width: 10%; white-space: normal; word-break: break-word;">Unit Price ({$currency})</th>
                                <th style="width: 14%; white-space: normal; word-break: break-word;" colspan="2">Taxable Amount ({$currency})</th>
                                <th style="width: 8%; white-space: normal; word-break: break-word;">VAT Rate</th>
                                <th style="width: 16%; white-space: normal; word-break: break-word;" colspan="2">VAT Amount ({$currency})</th>
                                <th style="width: 10%; white-space: normal; word-break: break-word;">Total ({$currency})</th>
                            </tr>
                            {$orderDetails}
                        </table>
                            
                        <table style="table-layout: fixed;" class="table-noborder">
                            <tr><td colspan="11"></td></tr>
                            <tr><td colspan="11"></td></tr>
                        </table>
                        
                        <table style="table-layout: fixed;">  
                            <tr style="text-align: left; font-weight: normal; font-size: 12px;">
                                <td class="table-noborder" style="width: 5%; white-space: nowrap;"></td>
                                <td style="width: 29%; text-align: left; background-color: lightslategray;" colspan="2">Grand Total</td>
                                <td style="width: 8%; text-align: left; background-color: lightslategray;">{$orderTotalQuantity}</td>
                                <td style="width: 10%; text-align: left; background-color: lightslategray;"></td>
                                <td style="width: 14%; text-align: left; background-color: lightslategray;" colspan="2">{$orderTotalAmount}</td>
                                <td style="width: 8%; text-align: left; background-color: lightslategray;"></td>
                                <td style="width: 16%; text-align: left; background-color: lightslategray;" colspan="2">{$orderTotalTaxAmount}</td>
                                <td style="width: 10%; text-align: left; background-color: lightslategray;">{$orderTotal}</td>
                            </tr>
                        </table>
                        
                        <table style="table-layout: fixed;" class="table-noborder">    
                            <tr>
                                <td colspan="11"></td>
                            </tr>
                        </table>    
                        
                        <table style="table-layout: fixed;" width="100%">
                            <tr style="text-align: left; font-weight: normal; font-size: 12px;">
                                <td colspan="7" class="table-noborder"></td>
                                <td style="text-align: left; background-color: lightgoldenrodyellow;" colspan="2" >Total Amount</td>
                                <td style="text-align: left; background-color: lightgoldenrodyellow;" colspan="2">{$currency}{$orderAmount}</td>
                            </tr>
                        </table>
                        
                        <table style="table-layout: fixed;" class="table-noborder">    
                            <tr>
                                <td colspan="11"></td>
                            </tr>
                        </table> 
                        
                        <table style="table-layout: fixed;" class="table-noborder">
                            <tr style="text-align: left; font-weight: normal; font-size: 12px;">
                                <td colspan="7"></td>
                                <td colspan="2">Method:</td>
                                <td colspan="2">{$paymentMethod}</td>
                            </tr>
                            <tr style="text-align: left; font-weight: normal; font-size: 12px;">
                                <td colspan="7"></td>
                                <td colspan="2" >Paid amount:</td>
                                <td colspan="2">{$currency}{$orderAmount}</td>
                            </tr>
                        </table>
                        
                        <table style="table-layout: fixed;" class="table-noborder">    
                            <tr>
                                <td colspan="11"></td>
                            </tr>
                        </table>
                        
                        <table style="table-layout: fixed;">
                            <tr style="text-align: left; font-weight: normal; font-size: 12px; margin-top: 15px;">
                                <td colspan="7" class="table-noborder"></td>
                                <td>Product Code</td>
                                <td>Quantity</td>
                                <td>Unit BV</td>
                                <td>Total BV</td>
                            </tr>
                            $orderDetails_bv
                        </table>
                            
                        <table style="table-layout: fixed;" class="table-noborder">
                            <tr><td colspan="11"></td></tr>
                            <tr><td colspan="11"></td></tr>
                        </table>
                        
                        <table style="table-layout: fixed;">  
                            <tr style="text-align: center; font-weight: normal; font-size: 12px;">
                                <td class="table-noborder" colspan="7"></td>
                                <td style="text-align: center; background-color: lightslategray;" colspan="2">Grand Total BV</td>
                                <td style="text-align: center; background-color: lightslategray;" colspan="2">{$orderTotalBv}</td>
                            </tr>
                        </table>
                        
                        <table style="table-layout: fixed;">
                            <tr style="text-align: left; font-weight: normal; font-size: 12px; margin-top: 15px;">
                                <td colspan="2" class="table-noborder">Remark:</td>
                                <td colspan="9" class="table-noborder"></td>
                            </tr>
                            <tr style="text-align: left; font-weight: normal; font-size: 12px;">
                                <td colspan="6" class="table-noborder">{$invoiceRemark}</td>
                            </tr>
                        </table>

                        
                        <table style="table-layout: fixed;" class="table-noborder">    
                            <tr>
                                <td colspan="11"></td>
                            </tr>
                            <tr>
                                <td colspan="11"></td>
                            </tr>
                            <tr>
                                <td colspan="11"></td>
                            </tr>
                            <tr>
                                <td colspan="11"></td>
                            </tr>
                        </table>
                        
                        <table style="table-layout: fixed;" class="table-noborder">    
                            <tr style="text-align: left; font-weight: normal; font-size: 12px; margin-top: 15px;">
                                <td colspan="4">Issued By:</td>
                                <td colspan="4">Picked By:</td>
                                <td colspan="3">Received By:</td>
                            </tr>
                            <tr>
                                <td colspan="11"></td>
                            </tr>
                        </table>
                    </div>
                </div>
            </body>
        </html>
ORDER;

            require_once (\Yii::$app->vendorPath . '/tecnickcom/tcpdf/tcpdf.php');

            $pdf = new \TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
            // 设置打印模式
            $pdf->SetCreator(PDF_CREATOR);
            $pdf->SetAuthor('DaZe');
            $pdf->SetTitle($orderSn);
            $pdf->SetSubject('TCPDF Tutorial');
            $pdf->SetKeywords('TCPDF, PDF, example, test, guide');
            // 是否显示页眉
            $pdf->setPrintHeader(false);
            // 设置页眉字体
            $pdf->setHeaderFont(Array('Helvetica', '', '12'));
            // 页眉距离顶部的距离
            $pdf->SetHeaderMargin('5');
            // 是否显示页脚
            $pdf->setPrintFooter(false);
            // 设置默认等宽字体
            $pdf->SetDefaultMonospacedFont(PDF_FONT_MONOSPACED);
            // 设置行高
//            $pdf->setCellHeightRatio(1);
            // 设置左、上、右的间距
            $pdf->SetMargins('10', '0', '10');
            // 设置是否自动分页  距离底部多少距离时分页
            $pdf->SetAutoPageBreak(TRUE, '15');
            // 设置图像比例因子
            $pdf->setImageScale(PDF_IMAGE_SCALE_RATIO);
            if (@file_exists(\Yii::$app->vendorPath . 'tecnickcom/tcpdf/examples/lang/eng.php')) {
                require_once(\Yii::$app->vendorPath . '/tecnickcom/tcpdf/examples/lang/eng.php');
                $pdf->setLanguageArray($l);
            }
            $pdf->setFontSubsetting(true);
            $pdf->AddPage();
            // 设置字体
            $pdf->SetFont('Helvetica', '', 10, '', true);
//            $image_file = \Yii::$app->basePath . '/../ngds-logo.jpg';
//            $image = file_get_contents($image_file);
//            $pdf->Image('@' . $image, 15, 12, 20, 7, 'JPG');
            $pdf->writeHTML($context);

            $result = $pdf->Output($realFile, 'F');

            $this->_updateFirst($realFile, 1);
        }

        $this->complete();
        return true;
    }
}
