Explorar el Código

糊盒报工优化

unknown hace 1 semana
padre
commit
903e2dec5a
Se han modificado 2 ficheros con 613 adiciones y 73 borrados
  1. 149 68
      application/api/controller/Aicompute.php
  2. 464 5
      application/api/controller/GluingReport.php

+ 149 - 68
application/api/controller/Aicompute.php

@@ -13,92 +13,143 @@ class Aicompute extends Api
     /**
      * AI计算产品计件单价
      */
-    public function salarybatchcalc()
+    public function salarybatchcalc($gdbh, $jtbh)
     {
-        //1、接受参数
-        $param = $this->request->param();
-        if (empty($param['Gd_gdbh'])) {
+        if (empty($gdbh)) {
             $this->error('工单编号错误');
         }
-        $gdGdbh = trim($param['Gd_gdbh']);
+        if (empty($jtbh)) {
+            $this->error('机台编号错误');
+        }
 
-        //2、查询工单_基本资料
-        $OrderList = Db::name('工单_基本资料')
-            ->field('Gd_gdbh,Gd_cpmc')
-            ->where('Gd_gdbh', $gdGdbh)
-            ->find();
-        if (!$OrderList || empty(trim($OrderList['Gd_cpmc']))) {
+        $orderProductName = $this->getOrderProductName(trim($gdbh));
+        if ($orderProductName === '') {
             $this->error('未找到对应工单编号或产品名称为空');
         }
-        $orderProductName = trim($OrderList['Gd_cpmc']);
-        // 去除括号、空格用于匹配
-        $orderMatchName = preg_replace('/[()()\s]/u', '', $orderProductName);
 
-        // 3、读取单价库
-        $allRates = Db::name('workshop_box_piece_rate_final')
-            ->field('
-                id,product_name,piece_price
-            ')
+        $finalPrice = $this->resolvePiecePriceByAi(trim($gdbh), trim($jtbh));
+        if ($finalPrice === null) {
+            $this->error('AI估算单价失败');
+        }
+
+        $this->success('计算成功', [
+            'product_name' => $orderProductName,
+            'piece_price'  => $finalPrice,
+        ]);
+    }
+
+    /**
+     * 按机台编号获取车间单价库数据
+     * @param string $jtbh
+     * @return array
+     */
+    public function fetchWorkshopRatesByMachine($jtbh)
+    {
+        $jtbh = trim((string)$jtbh);
+        if ($jtbh === '') {
+            return [];
+        }
+
+        return Db::name('workshop_box_piece_rate_final')
+            ->field('id,product_name,piece_price,machine_code')
             ->where('product_name', '<>', '')
             ->where('piece_price', '>', 0)
+            ->where('machine_code', $jtbh)
             ->order('id desc')
-            ->limit(20)
-            ->select();
+            ->select() ?: [];
+    }
 
-        // 4、关键字匹配筛选候选数据
-        $list = [];
-        foreach ($allRates as $row) {
+    /**
+     * 按产品名称匹配车间单价
+     * @param array $rates
+     * @param string $productName
+     * @return array|null
+     */
+    public function matchWorkshopRateByProductName(array $rates, $productName)
+    {
+        $productName = trim((string)$productName);
+        if ($productName === '' || empty($rates)) {
+            return null;
+        }
+
+        $orderMatchName = preg_replace('/[()()\s]/u', '', $productName);
+        foreach ($rates as $row) {
             $keywords = $this->extractRateKeywords($row['product_name']);
-            // 关键字按长度倒序,优先精准长词匹配
             usort($keywords, function ($a, $b) {
                 return mb_strlen($b, 'UTF-8') - mb_strlen($a, 'UTF-8');
             });
             foreach ($keywords as $kw) {
-                if ($kw === '') continue;
-                // 原始名称 / 清洗后名称任一匹配即命中
-                if (mb_strpos($orderProductName, $kw) !== false
+                if ($kw === '') {
+                    continue;
+                }
+                if (mb_strpos($productName, $kw) !== false
                     || mb_strpos($orderMatchName, $kw) !== false) {
-                    $list[] = $row;
-                    break;
+                    return $row;
                 }
             }
         }
-        $candidateList = !empty($list) ? $list : $allRates;
 
-        // 5、组装AI提示词,去除格式化空格减少token
+        return null;
+    }
+
+    /**
+     * AI对照估算计件单价
+     * @param string $gdbh
+     * @param string $jtbh
+     * @return float|null
+     */
+    public function resolvePiecePriceByAi($gdbh, $jtbh)
+    {
+        $gdbh = trim((string)$gdbh);
+        $jtbh = trim((string)$jtbh);
+        if ($gdbh === '' || $jtbh === '') {
+            return null;
+        }
+
+        $orderProductName = $this->getOrderProductName($gdbh);
+        if ($orderProductName === '') {
+            return null;
+        }
+
+        $allRates = $this->fetchWorkshopRatesByMachine($jtbh);
+        if (empty($allRates)) {
+            return null;
+        }
+
+        $orderMatchName = preg_replace('/[()()\s]/u', '', $orderProductName);
+        $candidateList = $this->buildAiCandidateRates($allRates, $orderProductName, $orderMatchName);
+
         $rateJson = json_encode($candidateList, JSON_UNESCAPED_UNICODE);
         $prompt = "角色:计件单价分析助手。
                     背景:单价表由人工维护,覆盖不全。请参考给定单价数据,评估当前工单产品最合理的计件单价(不是简单照搬某一条记录)。
                     【工单】
-                    工单号:{$gdGdbh}
+                    工单号:{$gdbh}
                     产品名称:{$orderProductName}
                     【参考单价数据】
                     {$rateJson}
                     【规则】
                     1. 综合产品名称、系列、款式、工艺等信息,判断该工单产品应对应哪类单价最合理。
-                    2. 参考相近产品的单价水平进行评估,给出最合理的计件单价。
-                    3. 必须返回数字单价,不得为 null 或空。
+                    2. 如果产品名称中包含国家名称,则全部属于外烟产品
+                    3. 参考相近产品的单价水平进行评估,给出最合理的计件单价。
+                    4. 必须返回数字单价,不得为 null 或空。
                     【输出】
                     仅输出 JSON,无其他文字:
                     {\"product_name\":\"{$orderProductName}\",\"piece_price\":数字}";
 
         $apiKey = 'sk-fxlawqVtbbQbNW0wInR3E4wsLo5JHozDC2XOHzMa711su6ss';
         $apiUrl = 'https://chatapi.onechats.top/v1/chat/completions';
-        $modelName = 'gpt-4.1';
-        $messages = [
-            [
-                'role' => 'user',
-                'content' => $prompt,
-            ],
-        ];
         $postData = [
-            'model' => $modelName,
-            'messages' => $messages,
+            'model' => 'gpt-4.1',
+            'messages' => [
+                [
+                    'role' => 'user',
+                    'content' => $prompt,
+                ],
+            ],
             'max_tokens' => 1024,
             'temperature' => 0.2,
         ];
 
-        //CURL请求AI接口,增加超时控制
         $ch = curl_init($apiUrl);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
         curl_setopt($ch, CURLOPT_POST, true);
@@ -107,46 +158,76 @@ class Aicompute extends Api
             'Content-Type: application/json',
             'Authorization: Bearer ' . $apiKey,
         ]);
-        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); // 连接超时10秒
-        curl_setopt($ch, CURLOPT_TIMEOUT, 30);        // 整体请求超时30秒
-        // 测试环境关闭SSL校验,生产环境注释此行开启证书校验
+        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
+        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
         curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
         $response = curl_exec($ch);
-        // CURL异常捕获
         if (curl_errno($ch)) {
-            $errMsg = curl_error($ch);
             curl_close($ch);
-            // 此处可写入AI调用日志
-            $this->error('AI接口请求失败:' . $errMsg);
+            return null;
         }
         curl_close($ch);
 
         $responseData = json_decode($response, true);
         if (!isset($responseData['choices'][0]['message']['content'])) {
-            // 此处可写入AI调用日志
-            $this->error('未能获取AI有效回复', $responseData);
+            return null;
         }
 
-        // 清理markdown代码块标记
         $gptReply = trim($responseData['choices'][0]['message']['content']);
         $gptReply = preg_replace('/^```(?:json)?\s*|\s*```$/u', '', $gptReply);
         $result = json_decode($gptReply, true);
-
-        // 校验AI返回格式与单价合法性
         if (!is_array($result) || !isset($result['piece_price']) || !is_numeric($result['piece_price'])) {
-            // 此处可写入AI调用日志
-            $this->error('AI返回数据格式异常', ['raw_reply' => $gptReply]);
+            return null;
         }
-        $finalPrice = (float)$result['piece_price'];
-//        // 业务价格区间风控,根据实际业务调整上下限
-//        if ($finalPrice <= 0 || $finalPrice > 1.0) {
-//            $this->error('AI估算单价超出业务合理区间', ['price' => $finalPrice]);
-//        }
 
-        $this->success('计算成功', [
-            'product_name' => $orderProductName,
-            'piece_price'  => $finalPrice,
-        ]);
+        return (float)$result['piece_price'];
+    }
+
+    /**
+     * 获取工单产品名称
+     * @param string $gdbh
+     * @return string
+     */
+    protected function getOrderProductName($gdbh)
+    {
+        $order = Db::name('工单_基本资料')
+            ->field('Gd_cpmc')
+            ->where('Gd_gdbh', $gdbh)
+            ->find();
+        if (!$order || empty(trim($order['Gd_cpmc']))) {
+            return '';
+        }
+        return trim($order['Gd_cpmc']);
+    }
+
+    /**
+     * 构建AI候选单价数据
+     * @param array $allRates
+     * @param string $orderProductName
+     * @param string $orderMatchName
+     * @return array
+     */
+    protected function buildAiCandidateRates(array $allRates, $orderProductName, $orderMatchName)
+    {
+        $list = [];
+        foreach ($allRates as $row) {
+            $keywords = $this->extractRateKeywords($row['product_name']);
+            usort($keywords, function ($a, $b) {
+                return mb_strlen($b, 'UTF-8') - mb_strlen($a, 'UTF-8');
+            });
+            foreach ($keywords as $kw) {
+                if ($kw === '') {
+                    continue;
+                }
+                if (mb_strpos($orderProductName, $kw) !== false
+                    || mb_strpos($orderMatchName, $kw) !== false) {
+                    $list[] = $row;
+                    break;
+                }
+            }
+        }
+
+        return !empty($list) ? array_slice($list, 0, 20) : array_slice($allRates, 0, 20);
     }
 
     /**

+ 464 - 5
application/api/controller/GluingReport.php

@@ -341,6 +341,15 @@ class GluingReport extends Api
             $this->error($validate->getError());
         }
 
+        if ($this->isEmptyReportPrice($param['price'] ?? null)) {
+            $resolvedPrice = $this->resolveReportPrice($param);
+            if ($resolvedPrice !== null) {
+                $param['price'] = $resolvedPrice;
+            } else {
+                unset($param['price']);
+            }
+        }
+
         // 3. 事务处理(确保数据一致性)
         $currentTime = date('Y-m-d H:i:s');
         $tableClass = '糊盒报工班组';
@@ -1058,8 +1067,227 @@ class GluingReport extends Api
     }
 
 
+    /**
+     * 判断报工单价是否为空
+     * @param mixed $price
+     * @return bool
+     */
+    protected function isEmptyReportPrice($price)
+    {
+        return $price === null || $price === '';
+    }
+
+    /**
+     * 报工时自动解析单价
+     * @param array $param
+     * @return float|null
+     */
+    protected function resolveReportPrice(array $param)
+    {
+        $machine = trim($param['sczl_jtbh']);
+        $gxmc = trim($param['sczl_gxmc']);
+        $count = $this->extractManualProcessCountSilent($param);
+
+        $machinePrices = $this->collectMachinePriceValues($machine);
+        if (!empty($machinePrices)) {
+            return (float)$machinePrices[0];
+        }
+
+        $manualPrice = $this->resolveManualProcessPriceSilent($gxmc, $count);
+        if ($manualPrice !== null) {
+            return $manualPrice;
+        }
+
+        $aiService = new Aicompute();
+        $rates = $aiService->fetchWorkshopRatesByMachine($machine);
+        if (empty($rates)) {
+            return null;
+        }
+
+        $productName = db('工单_基本资料')
+            ->where('Gd_gdbh', trim($param['sczl_gdbh']))
+            ->value('Gd_cpmc');
+        $productName = $productName ? trim($productName) : '';
+
+        if ($productName !== '') {
+            $matched = $aiService->matchWorkshopRateByProductName($rates, $productName);
+            if (!empty($matched)) {
+                return (float)$matched['piece_price'];
+            }
+        }
+
+        $aiPrice = $aiService->resolvePiecePriceByAi(trim($param['sczl_gdbh']), $machine);
+        if ($aiPrice !== null) {
+            return $aiPrice;
+        }
+
+        return (float)$rates[0]['piece_price'];
+    }
+
+    /**
+     * 收集机台单价列表
+     * @param string $machine
+     * @return array
+     */
+    protected function collectMachinePriceValues($machine)
+    {
+        $list = db('machine_price')
+            ->where('machine_id', $machine)
+            ->field('price1,price2,price3,price4,price5,price6,price7,price8,price9,price10')
+            ->select();
+
+        $result = [];
+        foreach ($list as $item) {
+            foreach ($item as $value) {
+                if ($value !== '' && $value !== null) {
+                    $result[] = $value;
+                }
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * 静默解析手工工序单价(报工场景,不中断请求)
+     * @param string $gxmc
+     * @param int|null $count
+     * @return float|null
+     */
+    protected function resolveManualProcessPriceSilent($gxmc, $count)
+    {
+        if (strpos($gxmc, '割围条') !== false) {
+            $row = db('machine_price')->where('machine_id', '手工割围条')->find();
+            return $row ? (float)$row['price1'] : null;
+        }
+
+        if (strpos($gxmc, '打孔') !== false) {
+            if ($count === null) {
+                return null;
+            }
+            return $this->resolvePunchHolePrice($count);
+        }
+
+        if (strpos($gxmc, '拆片') !== false) {
+            $rows = db('machine_price')->where('machine_id', '手工拆片')->select();
+            if (empty($rows)) {
+                return null;
+            }
+            return $this->resolveManualStripPriceSilent($rows, $gxmc, $count);
+        }
+
+        $row = db('machine_price')
+            ->where('machine_id', $gxmc)
+            ->whereOr('machine_name', 'like', '%' . $gxmc . '%')
+            ->find();
+
+        return $row ? (float)$row['price1'] : null;
+    }
+
+    /**
+     * 静默提取孔数/拼数
+     * @param array $params
+     * @return int|null
+     */
+    protected function extractManualProcessCountSilent(array $params)
+    {
+        if (!isset($params['count']) || $params['count'] === '') {
+            return null;
+        }
+        if (!is_numeric($params['count']) || (int)$params['count'] != $params['count'] || (int)$params['count'] <= 0) {
+            return null;
+        }
+
+        return (int)$params['count'];
+    }
+
+    /**
+     * 静默解析手工拆片单价
+     * @param array $rows
+     * @param string $gxmc
+     * @param int|null $count
+     * @return float|null
+     */
+    protected function resolveManualStripPriceSilent(array $rows, $gxmc, $count)
+    {
+        $gxmc = trim($gxmc);
+
+        if ($gxmc === '手工拆片' || $gxmc === '拆片') {
+            if ($count === null) {
+                return null;
+            }
+            return $this->resolveDefaultStripPriceByCount($count);
+        }
+
+        if ($gxmc !== '') {
+            $row = $this->matchManualPriceRow($rows, $gxmc);
+            if (empty($row)) {
+                return null;
+            }
+            return $this->calculateStripPriceByRowSilent($row, $count);
+        }
+
+        if ($count === null) {
+            return null;
+        }
+
+        return $this->resolveDefaultStripPriceByCount($count);
+    }
+
+    /**
+     * 静默计算拆片规格单价
+     * @param array $row
+     * @param int|null $count
+     * @return float|null
+     */
+    protected function calculateStripPriceByRowSilent(array $row, $count)
+    {
+        $name = $row['machine_name'];
+        $basePrice = (float)$row['price1'];
+
+        if (strpos($name, '1-4拼(特种纸') !== false) {
+            if ($count === null) {
+                return null;
+            }
+            if ($count <= 4) {
+                return $basePrice;
+            }
+            return floatval(number_format($basePrice + ($count - 4) * 0.001, 4, '.', ''));
+        }
+
+        if (strpos($name, '1-4拼(小盒二次拆片') !== false) {
+            if ($count === null) {
+                return null;
+            }
+            if ($count === 8) {
+                return 0.01;
+            }
+            if ($count === 10) {
+                return 0.012;
+            }
+            return $basePrice;
+        }
+
+        if (strpos($name, '5-6拼(小盒二次拆片') !== false) {
+            return $basePrice;
+        }
+
+        if (strpos($name, '6拼及以上') !== false) {
+            return $basePrice;
+        }
+
+        if (preg_match('/^(\d+)拼/u', $name) && $count === null) {
+            return null;
+        }
+
+        return $basePrice;
+    }
+
+
     /**
      * 获取机台报工单价数据
+     * 参数:machine(机台编号)、gxmc(工序名称)、count(孔数/拼数,纯数字)
+     * 优先按机台编号查询;查不到则按手工工序(gxmc + count)匹配单价
      * @return void
      * @throws \think\db\exception\DataNotFoundException
      * @throws \think\db\exception\ModelNotFoundException
@@ -1067,17 +1295,19 @@ class GluingReport extends Api
      */
     public function getMachinePriceData()
     {
-        if ($this->request->isGet() === false){
+        if ($this->request->isGet() === false) {
             $this->error('请求错误');
         }
         $params = $this->request->param();
-        if (!isset($params['machine']) || empty($params['machine'])){
+        if (!isset($params['machine']) || $params['machine'] === '') {
             $this->error('参数错误');
         }
 
-        //查询机台的单价列表(仅返回有值的单价)
+        $machine = trim($params['machine']);
+
+        // 1. 优先按机台编号查询
         $list = db('machine_price')
-            ->where('machine_id',$params['machine'])
+            ->where('machine_id', $machine)
             ->field('price1,price2,price3,price4,price5,price6,price7,price8,price9,price10')
             ->select();
 
@@ -1089,7 +1319,236 @@ class GluingReport extends Api
                 }
             }
         }
-        $this->success('获取成功',$result);
+        if (!empty($result)) {
+            $this->success('获取成功', $result);
+        }
+
+        // 2. 机台编号查不到,按手工工序查询
+        $gxmc = trim((string)($params['gxmc'] ?? ''));
+        if ($gxmc === '') {
+            $this->error('未找到机台单价,请传入工序名称');
+        }
+
+        $price = $this->resolveManualProcessPriceByGxmc($gxmc, $params);
+        if ($price === null) {
+            $this->error('未找到匹配的单价');
+        }
+        $this->success('获取成功', [$price]);
+    }
+
+    /**
+     * 按工序名称解析手工工序单价
+     * @param string $gxmc 工序名称
+     * @param array $params count=孔数/拼数(纯数字)
+     * @return float|null
+     */
+    protected function resolveManualProcessPriceByGxmc($gxmc, array $params)
+    {
+        $count = $this->extractManualProcessCount($params);
+
+        if (strpos($gxmc, '割围条') !== false) {
+            $row = db('machine_price')->where('machine_id', '手工割围条')->find();
+            return $row ? (float)$row['price1'] : null;
+        }
+
+        if (strpos($gxmc, '打孔') !== false) {
+            if ($count === null) {
+                $this->error('请传入孔数(纯数字)');
+            }
+            return $this->resolvePunchHolePrice($count);
+        }
+
+        if (strpos($gxmc, '拆片') !== false) {
+            $rows = db('machine_price')->where('machine_id', '手工拆片')->select();
+            if (empty($rows)) {
+                return null;
+            }
+            return $this->resolveManualStripPrice($rows, $gxmc, $count);
+        }
+
+        // 其他手工工序:按 machine_id 或 machine_name 匹配
+        $row = db('machine_price')
+            ->where('machine_id', $gxmc)
+            ->whereOr('machine_name', 'like', '%' . $gxmc . '%')
+            ->find();
+        return $row ? (float)$row['price1'] : null;
+    }
+
+    /**
+     * 提取孔数/拼数(前端传入纯数字)
+     * @param array $params
+     * @return int|null
+     */
+    protected function extractManualProcessCount(array $params)
+    {
+        if (!isset($params['count']) || $params['count'] === '') {
+            return null;
+        }
+        if (!is_numeric($params['count']) || (int)$params['count'] != $params['count'] || (int)$params['count'] <= 0) {
+            $this->error('孔数/拼数必须为大于0的整数');
+        }
+        return (int)$params['count'];
+    }
+
+    /**
+     * 手工打孔单价(按孔数区间)
+     * @param int $holeCount
+     * @return float
+     */
+    protected function resolvePunchHolePrice($holeCount)
+    {
+        $holeCount = (int)$holeCount;
+        if ($holeCount === 1) {
+            return 0.0055;
+        }
+        if ($holeCount >= 2 && $holeCount <= 4) {
+            return 0.007;
+        }
+        if ($holeCount >= 5 && $holeCount <= 8) {
+            return 0.012;
+        }
+        if ($holeCount >= 9 && $holeCount <= 12) {
+            return 0.016;
+        }
+        if ($holeCount >= 13 && $holeCount <= 18) {
+            return 0.025;
+        }
+        return floatval(number_format(0.025 + ($holeCount - 18) * 0.001, 4, '.', ''));
+    }
+
+    /**
+     * 手工拆片单价(按规格名称 + 拼数)
+     * @param array $rows
+     * @param string $gxmc 工序规格名称(文字)
+     * @param int|null $count 拼数(纯数字)
+     * @return float|null
+     */
+    protected function resolveManualStripPrice(array $rows, $gxmc, $count)
+    {
+        $gxmc = trim($gxmc);
+
+        // 通用拆片工序,仅按拼数数字匹配默认单价
+        if ($gxmc === '手工拆片' || $gxmc === '拆片') {
+            if ($count === null) {
+                $this->error('请传入拼数(纯数字)');
+            }
+            return $this->resolveDefaultStripPriceByCount($count);
+        }
+
+        if ($gxmc !== '') {
+            $row = $this->matchManualPriceRow($rows, $gxmc);
+            if (empty($row)) {
+                return null;
+            }
+            return $this->calculateStripPriceByRow($row, $count);
+        }
+
+        if ($count === null) {
+            $this->error('请传入拼数(纯数字)');
+        }
+
+        return $this->resolveDefaultStripPriceByCount($count);
+    }
+
+    /**
+     * 默认拆片单价(1.0厚以上灰白板,按拼数数字匹配)
+     * @param int $count
+     * @return float
+     */
+    protected function resolveDefaultStripPriceByCount($count)
+    {
+        $prices = [
+            1 => 0.008,
+            2 => 0.01,
+            3 => 0.013,
+            4 => 0.017,
+            5 => 0.022,
+            6 => 0.028,
+        ];
+        $pieceCount = min((int)$count, 6);
+        return $prices[$pieceCount];
+    }
+
+    /**
+     * 按 machine_name 匹配手工单价行
+     * @param array $rows
+     * @param string $gxmc
+     * @return array|null
+     */
+    protected function matchManualPriceRow(array $rows, $gxmc)
+    {
+        $gxmc = trim($gxmc);
+        foreach ($rows as $row) {
+            if ($row['machine_name'] === $gxmc) {
+                return $row;
+            }
+        }
+
+        $best = null;
+        $bestLen = 0;
+        foreach ($rows as $row) {
+            $name = $row['machine_name'];
+            if (strpos($name, $gxmc) !== false || strpos($gxmc, $name) !== false) {
+                $len = mb_strlen($name);
+                if ($len > $bestLen) {
+                    $best = $row;
+                    $bestLen = $len;
+                }
+            }
+        }
+
+        return $best;
+    }
+
+    /**
+     * 根据拆片规格行及拼数计算单价
+     * @param array $row
+     * @param int|null $count 拼数(纯数字)
+     * @return float|null
+     */
+    protected function calculateStripPriceByRow(array $row, $count)
+    {
+        $name = $row['machine_name'];
+        $basePrice = (float)$row['price1'];
+
+        if (strpos($name, '1-4拼(特种纸') !== false) {
+            if ($count === null) {
+                $this->error('请传入拼数(纯数字)');
+            }
+            if ($count <= 4) {
+                return $basePrice;
+            }
+            return floatval(number_format($basePrice + ($count - 4) * 0.001, 4, '.', ''));
+        }
+
+        if (strpos($name, '1-4拼(小盒二次拆片') !== false) {
+            if ($count === null) {
+                $this->error('请传入拼数(纯数字)');
+            }
+            if ($count === 8) {
+                return 0.01;
+            }
+            if ($count === 10) {
+                return 0.012;
+            }
+            return $basePrice;
+        }
+
+        if (strpos($name, '5-6拼(小盒二次拆片') !== false) {
+            return $basePrice;
+        }
+
+        if (strpos($name, '6拼及以上') !== false) {
+            return $basePrice;
+        }
+
+        if (preg_match('/^(\d+)拼/u', $name, $matches)) {
+            if ($count === null) {
+                $this->error('请传入拼数(纯数字)');
+            }
+        }
+
+        return $basePrice;
     }