Browse Source

feat: EK-3320: [Order List]新增发票功能.

kevin 1 month ago
parent
commit
b7c9782a32

+ 3 - 5
backendApi/config/params.php

@@ -25,6 +25,7 @@ return [
         'v1/calc/auto-calc',
         'v1/shop/order-period-adjust-batch',
         'v1/shop/order-invoice-remark',
+        'v1/shop/order-invoice-export',
 //        'v1/site/countries'
     ],
     'noCheckPermissionActions' => [
@@ -84,10 +85,6 @@ return [
         'demo/ipayments',
         'article/detail',
         'admin/change-language',
-//        'currency/currencies-conversions',
-//        'currency/set-currencies-conversions',
-//        'transportation/transportation',
-//        'transportation/set-transportation',
         'bonus/auto-calc',
         'bonus/calc-period',
         'bonus/close-period',
@@ -96,6 +93,7 @@ return [
         'calc/record-list',
         'calc/auto-calc',
         'shop/order-period-adjust-batch',
-        'shop/order-invoice-remark'
+        'shop/order-invoice-remark',
+        'shop/order-invoice-export',
     ],
 ];

+ 1 - 0
backendApi/config/urlManagerRules.php

@@ -57,6 +57,7 @@ return [
             'POST delete-order' => 'delete-order',
             'GET order-list' => 'order-list',
             'POST order-invoice-remark' => 'order-invoice-remark',
+            'GET order-invoice-export/<orderSn>' => 'order-invoice-export',
             'GET order-list-export' => 'order-list-export',
             'POST order-delivery' => 'order-delivery',
             'POST order-refund' => 'order-refund',

+ 19 - 0
backendApi/modules/v1/controllers/ShopController.php

@@ -822,6 +822,25 @@ class ShopController extends BaseController {
         return static::notice(\Yii::t('ctx', 'startExporting')); // 导出开始,请到文件管理-导出文件查看
     }
 
+    public function actionOrderInvoiceExportPdf()
+    {
+        $orderSn = \Yii::$app->request->get('orderSn');
+
+        $filter = $this->filterCondition([
+            'SN'=> 'O.SN',
+        ]);
+
+        $filter['condition'] = ' O.IS_DELETE=0 AND O.SN=:SN';
+        $filter['params'] = [':SN' => $orderSn];
+
+        $form = new ShopExportForm();
+        $result = $form->run($filter, \Yii::t('ctx', 'shopOrderListExportPdf'));
+        if (!$result) {
+            return static::notice(Form::formatErrorsForApi($form->getErrors()), 400);
+        }
+        return static::notice(\Yii::t('ctx', 'startExporting')); // 导出开始,请到文件管理-导出文件查看
+    }
+
     /**
      * 报单表导出
      * @return mixed

+ 261 - 0
common/libs/export/BaseExport.php

@@ -1528,4 +1528,265 @@ ORDER;
         $this->complete();
         return true;
     }
+
+    /**
+     * 生成
+     * @return bool
+     * @throws Exception
+     * @throws InvalidConfigException
+     * @throws \yii\httpclient\Exception
+     */
+    public function generateOrderInvoicePDF() {
+        $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 = 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')
+            ->asArray();
+
+
+        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('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 . '/../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');
+            LoggerTool::debug(['result' => $result]);
+
+            $this->_updateFirst($realFile, 1);
+        }
+
+        $this->complete();
+        return true;
+    }
 }

+ 24 - 0
console/controllers/ShopController.php

@@ -109,6 +109,30 @@ class ShopController extends BaseController
         return false;
     }
 
+    /**
+     * 订单列表导出PDF
+     * @param $taskId
+     * @return bool
+     */
+    public function actionOrderInvoiceExportPdf($taskId)
+    {
+        $factory = ShopExport::factory($taskId);
+        $factory->listModelClass = OrderList::class;
+        try {
+            if ($factory->generateOrderInvoicePDF()) {
+                Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($factory->getUserId(), '导出成功');
+            }
+            unset($factory);
+            return true;
+        } catch (\Exception $e) {
+            echo '导出失败。详情:' . $e->getMessage();
+            Yii::$app->swooleAsyncTimer->pushAsyncResultToAdmin($factory->getUserId(), '导出失败。详情:' . $e->getMessage(), false);
+        }
+
+        unset($factory);
+        return false;
+    }
+
     /**
      * 订单列表导出PDF
      * @param $taskId