Browse Source

批量缩略主图功能

gorden 8 tháng trước cách đây
mục cha
commit
3f807994d4

+ 11 - 6
app/admin/controller/finance/GoodsSalesController.php

@@ -9,9 +9,14 @@ class GoodsSalesController{
 
     public function list(Request $request)
     {
-        // $rows = OrderSheet::leftJoin('goods','goods.goods_id','=','order_sheet.join_sheet_goods_id')
-        //     ->leftJoin('goods_sku','goods_sku.join_sku_goods_id','=','order_sheet.join_sheet_goods_id')
-        //     ->
+        $rows = OrderSheet::leftJoin('goods','goods.goods_id','=','order_sheet.join_sheet_goods_id')
+            ->leftJoin('goods_sku','goods_sku.join_sku_goods_id','=','order_sheet.join_sheet_goods_id')
+            ->selectRaw('SUM(app_order_sheet.order_sheet_num) as num,SUM(app_order_sheet_pay) as amount,CONCAT(app_goods.goods_id,"-",app_goods_sku.goods_sku_id) as goods_flag')
+            ->orderBy('order_sheet_addtimes','DESC')
+            ->groupBy('goods_flag')
+            ->get();
+
+        dump($rows);
 
         return json_success('');
     }
@@ -24,19 +29,19 @@ class GoodsSalesController{
             ->first();
 
         $data['entity'] = OrderSheet::leftJoin('goods','goods.goods_id','=','order_sheet.join_sheet_goods_id')
-            ->where('goods_classify','GOODS')
+            ->where('goods.goods_classify','GOODS')
             ->whereIn('order_sheet_status',['PENDING','NOSTOCK','WAITING','ENDING','RECVING','SIGNED','CONFIRM','DONE'])
             ->selectRaw("SUM(order_sheet_pay) as pay_amount ,SUM(order_sheet_num) as goods_amount")
             ->first();
 
         $data['service'] = OrderSheet::leftJoin('goods','goods.goods_id','=','order_sheet.join_sheet_goods_id')
-            ->where('goods_classify','SERVICE')
+            ->where('goods.goods_classify','SERVICE')
             ->whereIn('order_sheet_status',['PENDING','NOSTOCK','WAITING','ENDING','RECVING','SIGNED','CONFIRM','DONE'])
             ->selectRaw("SUM(order_sheet_pay) as pay_amount ,SUM(order_sheet_num) as goods_amount")
             ->first();
 
         $data['package'] = OrderSheet::leftJoin('goods','goods.goods_id','=','order_sheet.join_sheet_goods_id')
-            ->where('goods_classify','PACKAGE')
+            ->where('goods.goods_classify','PACKAGE')
             ->whereIn('order_sheet_status',['PENDING','NOSTOCK','WAITING','ENDING','RECVING','SIGNED','CONFIRM','DONE'])
             ->selectRaw("SUM(order_sheet_pay) as pay_amount ,SUM(order_sheet_num) as goods_amount")
             ->first();

+ 12 - 7
app/admin/service/order/AppointmentService.php

@@ -137,7 +137,7 @@ class AppointmentService
                 $extendJson = json_decode($goods->goods_attribute_json, true);
                 foreach ($extendJson['times'] as $key => $time) {
                     if ($time['duration'] == $params['appointment_times']) {
-                        if (!empty($appointments)){
+                        if (!empty($appointments)) {
                             foreach ($appointments as $appointment) {
                                 $applyJson = json_decode($appointment['appointment_apply_json'], true);
                                 $applyJsonTimes = $applyJson['times'] ?? '';
@@ -149,7 +149,7 @@ class AppointmentService
                                     }
                                 }
                             }
-                        }else{
+                        } else {
                             if ($extendJson['times'][$key]['person'] < $params['person']) {
                                 return json_fail('当前时段名额不足,请选择其他时段');
                             }
@@ -287,10 +287,10 @@ class AppointmentService
                     'pay_amount' => $sheet['order_sheet_pay'],
                     'pay_remark' => '预约单',
                     'pay_addtimes' => time(),
-                    'pay_prepayid' => $params['join_appointment_member_id'].'-'.$params['settlement_mode'],
+                    'pay_prepayid' => $params['join_appointment_member_id'] . '-' . $params['settlement_mode'],
                     'pay_paytimes' => date('Y-m-d H:i:s'),
-                    'join_pay_object_json'=>json_encode(['appointment_id' => $appointmentId]),
-                    'pay_category'=>"APPOINTMENT"
+                    'join_pay_object_json' => json_encode(['appointment_id' => $appointmentId]),
+                    'pay_category' => "APPOINTMENT"
                 ];
                 // 现金余额结算
                 if ($params['settlement_mode'] == 'CASH') {
@@ -304,7 +304,8 @@ class AppointmentService
                     }
 
                     if ($account->member_account_surplus < $sheet['order_sheet_pay']) {
-                        $pay['pay_status'] = 'PENDING';
+                        throw new BusinessException("账户余额不足");
+//                        $pay['pay_status'] = 'PENDING';
                     } else {
                         MemberAccount::where('member_account_id', $account->member_account_id)->update([
                             'member_account_expend' => $account->member_account_expend + $sheet['order_sheet_pay'],
@@ -327,6 +328,10 @@ class AppointmentService
 
             Db::commit();
             return json_success("添加预约成功");
+        }catch (BusinessException $e){
+            Db::rollBack();
+
+            return json_fail($e->getMessage());
         } catch (\Exception $e) {
             Db::rollBack();
             dump($e->getMessage());
@@ -479,7 +484,7 @@ class AppointmentService
                     }
 
                     if ($account->member_account_surplus < $sheet['order_sheet_pay']) {
-                        $pay['pay_status'] = 'PENDING';
+                        throw new BusinessException("账户余额不足");
                     } else {
                         MemberAccount::where('member_account_id', $account->member_account_id)->update([
                             'member_account_expend' => $account->member_account_expend + $sheet['order_sheet_pay'],

+ 4 - 3
app/admin/service/sys_manage/UploadService.php

@@ -18,17 +18,18 @@ class UploadService
     {
         try {
             $res = Storage::uploadFile($config);
+
+            dump($res);
             $data = [
                 'fileName'=>$res[0]['origin_name'],
-                'url' => getenv("STORAGE_DOMAIN").$config['uri'] . date('Ymd') . '/' . $res[0]['save_name'],
+                'url' => getenv("STORAGE_DOMAIN").$config['uri'] . date('Ymd') . '/thumb/' . $res[0]['save_name'],
                 'path' => $config['uri'] . date('Ymd') . '/' . $res[0]['save_name'],
                 'size' => $res[0]['size'],
                 'mime_type' => $res[0]['mime_type'],
-                'src' => getenv("STORAGE_DOMAIN").$config['uri'] . date('Ymd') . '/' . $res[0]['save_name'],
+                'src' => getenv("STORAGE_DOMAIN").$config['uri'] . date('Ymd') . '/thumb/' . $res[0]['save_name'],
             ];
 
             $insertData = [
-//                'upload_category' => '',
                 'upload_status' => 'ACTIVED',
                 'upload_name' => $res[0]['origin_name'],
                 'upload_ext_name' => $res[0]['extension'],

+ 84 - 0
app/command/GoodsThumbCommand.php

@@ -0,0 +1,84 @@
+<?php
+
+namespace app\command;
+
+use app\model\Goods;
+use Intervention\Image\Gd\Driver;
+use Intervention\Image\ImageManager;
+use Intervention\Image\ImageManagerStatic;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Output\OutputInterface;
+use Tinywan\Storage\Exception\StorageException;
+
+
+class GoodsThumbCommand extends Command
+{
+    protected static $defaultName = 'GoodsThumbCommand';
+    protected static $defaultDescription = 'GoodsThumbCommand';
+
+    /**
+     * @return void
+     */
+    protected function configure()
+    {
+        $this->addArgument('name', InputArgument::OPTIONAL, '商品主图片批量缩略');
+    }
+
+    /**
+     * @param InputInterface $input
+     * @param OutputInterface $output
+     * @return int
+     */
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $goods = Goods::select('goods_id','goods_cover')->limit(1)->get()->toArray();
+
+        foreach ($goods as $good){
+            if (!file_exists(public_path($good['goods_cover']))){
+                echo "【".$good['goods_id']."】源文件不存在,跳过 \n";
+                continue;
+            }
+            $fileNameArray = explode(DIRECTORY_SEPARATOR,$good['goods_cover']);
+            $two = $fileNameArray[count($fileNameArray)-2];
+            if ($two == 'thumb'){
+                echo "【".$good['goods_id']."】已存在,跳过 \n";
+                continue;
+            }
+            array_splice($fileNameArray,-1,0,'thumb');
+
+            $thumbPath = public_path(ltrim(implode(DIRECTORY_SEPARATOR,$fileNameArray),DIRECTORY_SEPARATOR));
+            if (file_exists($thumbPath)){
+                echo "【".$good['goods_id']."】缩略图已存在,跳过 \n";
+                continue;
+            }
+            $path = array_slice($fileNameArray,0,-1);
+            $pathStr = public_path(ltrim(implode(DIRECTORY_SEPARATOR,$path),DIRECTORY_SEPARATOR));
+
+            if (!is_dir($pathStr) && !mkdir($pathStr, 0755, true)){
+                throw new StorageException('文件夹创建失败,请核查是否有对应权限。');
+            }
+
+            $image = ImageManagerStatic::make(public_path($good['goods_cover']));
+
+            $imgWidth = $image->width();
+            $imgHeight = $image->height();
+            $rate = round($imgWidth / 200, 2);
+            $height = intval($imgHeight / $rate);
+            $image = $image->resize(200, $height);
+            $encoded = $image->encode('jpg');
+            $encoded->save($thumbPath);
+
+            Goods::where('goods_id',$good['goods_id'])->update(['goods_cover'=>implode(DIRECTORY_SEPARATOR,$fileNameArray)]);
+
+            echo "【".$good['goods_id']."】已完成 \n";
+        }
+
+
+
+        return self::SUCCESS;
+    }
+
+}

+ 90 - 0
app/common/storage/LocalAdapter.php

@@ -0,0 +1,90 @@
+<?php
+/**
+ * @desc 本地适配器
+ *
+ * @author Tinywan(ShaoBo Wan)
+ * @date 2022/3/7 19:54
+ */
+declare(strict_types=1);
+
+namespace app\common\storage;
+
+use Intervention\Image\ImageManagerStatic as Image;
+use Tinywan\Storage\Adapter\AdapterAbstract;
+use Tinywan\Storage\Exception\StorageException;
+
+class LocalAdapter extends AdapterAbstract
+{
+    /**
+     * @desc: 方法描述
+     *
+     * @author Tinywan(ShaoBo Wan)
+     */
+    public function uploadFile(array $options = []): array
+    {
+        $result = [];
+        $basePath = $this->config['root'] . $this->config['dirname'] . DIRECTORY_SEPARATOR;
+        if (!$this->createDir($basePath)) {
+            throw new StorageException('文件夹创建失败,请核查是否有对应权限。');
+        }
+        if (!$this->createDir($basePath . '/thumb')) {
+            throw new StorageException('文件夹创建失败,请核查是否有对应权限。');
+        }
+
+        $baseUrl = $this->config['domain'] . $this->config['uri'] . str_replace(DIRECTORY_SEPARATOR, '/', $this->config['dirname']) . DIRECTORY_SEPARATOR;
+        foreach ($this->files as $key => $file) {
+            // 缩略
+            $image = Image::make($file);
+
+            $uniqueId = hash_file($this->algo, $file->getPathname());
+            $saveFilename = $uniqueId . '.' . $file->getUploadExtension();
+            $originSavePath = $basePath . $saveFilename;
+            $thumbSavePath = $basePath . 'thumb' . DIRECTORY_SEPARATOR . $saveFilename;
+            $temp = [
+                'key' => $key,
+                'origin_name' => $file->getUploadName(),
+                'save_name' => $saveFilename,
+                'save_path' => $thumbSavePath,
+                'url' => $baseUrl . 'thumb' . DIRECTORY_SEPARATOR . $saveFilename,
+                'unique_id' => $uniqueId,
+                'size' => $file->getSize(),
+                'mime_type' => $file->getUploadMineType(),
+                'extension' => $file->getUploadExtension(),
+            ];
+            // 保存原图
+            $file->move($originSavePath);
+            // 保存缩略图
+            $imgWidth = $image->width();
+            $imgHeight = $image->height();
+            $rate = round($imgWidth / 200, 2);
+            $height = intval($imgHeight / $rate);
+            $image = $image->resize(200, $height);
+            $encoded = $image->encode('jpg');
+            $encoded->save($thumbSavePath);
+
+//            $file->move($savePath);
+            array_push($result, $temp);
+        }
+
+        return $result;
+    }
+
+    /**
+     * @desc: createDir 描述
+     */
+    protected function createDir(string $path): bool
+    {
+        if (is_dir($path)) {
+            return true;
+        }
+
+        $parent = dirname($path);
+        if (!is_dir($parent)) {
+            if (!$this->createDir($parent)) {
+                return false;
+            }
+        }
+
+        return mkdir($path);
+    }
+}

+ 3 - 1
composer.json

@@ -40,7 +40,9 @@
     "workerman/crontab": "^1.0",
     "overtrue/easy-sms": "^2.6",
     "hhink/webman-sms": "^1.0",
-    "ldy/payment": "^3.6"
+    "ldy/payment": "^3.6",
+    "intervention/image": "^2.7",
+    "webman/console": "^1.3"
   },
   "suggest": {
     "ext-event": "For better performance. "

+ 1 - 1
config/plugin/tinywan/storage/app.php

@@ -17,7 +17,7 @@ return [
         'exclude' => [], // 不被允许的文件类型列表
         // 本地对象存储
         'local' => [
-            'adapter' => \Tinywan\Storage\Adapter\LocalAdapter::class,
+            'adapter' => app\common\storage\LocalAdapter::class,
             'root' => public_path() . '/storage/',
             'dirname' => function () {
                 return date('Ymd');

+ 24 - 0
config/plugin/webman/console/app.php

@@ -0,0 +1,24 @@
+<?php
+return [
+    'enable' => true,
+
+    'build_dir'  => BASE_PATH . DIRECTORY_SEPARATOR . 'build',
+
+    'phar_filename' => 'webman.phar',
+
+    'bin_filename' => 'webman.bin',
+
+    'signature_algorithm'=> Phar::SHA256, //set the signature algorithm for a phar and apply it. The signature algorithm must be one of Phar::MD5, Phar::SHA1, Phar::SHA256, Phar::SHA512, or Phar::OPENSSL.
+
+    'private_key_file'  => '', // The file path for certificate or OpenSSL private key file.
+
+    'exclude_pattern'   => '#^(?!.*(composer.json|/.github/|/.idea/|/.git/|/.setting/|/runtime/|/vendor-bin/|/build/|/vendor/webman/admin/))(.*)$#',
+
+    'exclude_files'     => [
+        '.env', 'LICENSE', 'composer.json', 'composer.lock', 'start.php', 'webman.phar', 'webman.bin'
+    ],
+
+    'custom_ini' => '
+memory_limit = 256M
+    ',
+];

+ 1 - 1
route/admin.php

@@ -99,7 +99,7 @@ Route::group('/admin', function () {
         });
         Route::group('/goodsSales',function (){
             Route::get('/statistics',[\app\admin\controller\finance\GoodsSalesController::class,'statistics']);
-            Route::get('/list',[\app\admin\controller\finance\GoodsSalesController::class,'statistics']);
+            Route::get('/list',[\app\admin\controller\finance\GoodsSalesController::class,'list']);
         });
     });
     /* 系统管理中心 */

+ 57 - 0
webman

@@ -0,0 +1,57 @@
+#!/usr/bin/env php
+<?php
+
+use Webman\Config;
+use Webman\Console\Command;
+use Webman\Console\Util;
+use support\Container;
+
+require_once __DIR__ . '/vendor/autoload.php';
+
+if (!in_array($argv[1] ?? '', ['start', 'restart', 'stop', 'status', 'reload', 'connections'])) {
+    require_once __DIR__ . '/support/bootstrap.php';
+} else {
+    if (class_exists('Support\App')) {
+        Support\App::loadAllConfig(['route']);
+    } else {
+        Config::reload(config_path(), ['route', 'container']);
+    }
+}
+
+$cli = new Command();
+$cli->setName('webman cli');
+$cli->installInternalCommands();
+if (is_dir($command_path = Util::guessPath(app_path(), '/command', true))) {
+    $cli->installCommands($command_path);
+}
+
+foreach (config('plugin', []) as $firm => $projects) {
+    if (isset($projects['app'])) {
+        if ($command_str = Util::guessPath(base_path() . "/plugin/$firm", 'command')) {
+            $command_path = base_path() . "/plugin/$firm/$command_str";
+            $cli->installCommands($command_path, "plugin\\$firm\\$command_str");
+        }
+    }
+    foreach ($projects as $name => $project) {
+        if (!is_array($project)) {
+            continue;
+        }
+        foreach ($project['command'] ?? [] as $class_name) {
+            $reflection = new \ReflectionClass($class_name);
+            if ($reflection->isAbstract()) {
+                continue;
+            }
+            $properties = $reflection->getStaticProperties();
+            $name = $properties['defaultName'];
+            if (!$name) {
+                throw new RuntimeException("Command {$class_name} has no defaultName");
+            }
+            $description = $properties['defaultDescription'] ?? '';
+            $command = Container::get($class_name);
+            $command->setName($name)->setDescription($description);
+            $cli->add($command);
+        }
+    }
+}
+
+$cli->run();