Browse Source

'0901-c01'

zory 2 tuần trước cách đây
mục cha
commit
1281e765b0

+ 0 - 50
app/command/ShopwwiAuthCommand.php

@@ -1,50 +0,0 @@
-<?php
-
-namespace app\command;
-
-use Shopwwi\WebmanAuth\Facade\Str;
-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;
-
-
-class ShopwwiAuthCommand extends Command
-{
-    protected static $defaultName = 'shopwwi:auth';
-    protected static $defaultDescription = 'shopwwi auth';
-
-    /**
-     * @return void
-     */
-    protected function configure()
-    {
-        $this->addArgument('name', InputArgument::OPTIONAL, 'Name description');
-    }
-
-    /**
-     * @param InputInterface $input
-     * @param OutputInterface $output
-     * @return int
-     */
-    protected function execute(InputInterface $input, OutputInterface $output)
-    {
-        $name = $input->getArgument('name');
-        $output->writeln('生成jwtKey 开始');
-        $key = Str::random(64);
-        file_put_contents(base_path()."/config/plugin/shopwwi/auth/app.php", str_replace(
-            "'access_secret_key' => '".config('plugin.shopwwi.auth.app.jwt.access_secret_key')."'",
-            "'access_secret_key' => '".$key."'",
-            file_get_contents(base_path()."/config/plugin/shopwwi/auth/app.php")
-        ));
-        file_put_contents(base_path()."/config/plugin/shopwwi/auth/app.php", str_replace(
-            "'refresh_secret_key' => '".config('plugin.shopwwi.auth.app.jwt.refresh_secret_key')."'",
-            "'refresh_secret_key' => '".$key."'",
-            file_get_contents(base_path()."/config/plugin/shopwwi/auth/app.php")
-        ));
-        $output->writeln('生成jwtKey 结束'.$key);
-        return self::SUCCESS;
-    }
-
-}

+ 73 - 0
app/controller/admin/Account.php

@@ -0,0 +1,73 @@
+<?php
+
+namespace app\controller\admin;
+
+use app\extra\basic\Base;
+use app\middleware\AuthMiddleware;
+use app\model\cpa\CpaAccountGroup;
+use app\service\cpa\AccountService;
+use app\service\cpa\GroupService;
+use DI\Attribute\Inject;
+use LinFly\Annotation\Attributes\Route\Controller;
+use LinFly\Annotation\Attributes\Route\GetMapping;
+use LinFly\Annotation\Attributes\Route\Middleware;
+use LinFly\Annotation\Attributes\Route\PostMapping;
+use support\Request;
+use support\Response;
+use Webman\RedisQueue\Redis;
+
+
+#[Controller("/api/account"),Middleware(AuthMiddleware::class)]
+class Account extends Base
+{
+
+    #[Inject]
+    protected AccountService $service;
+
+    #[Inject]
+    protected GroupService $serviceGroup;
+
+    #[GetMapping('list')]
+    public function getDataList(Request $request): Response
+    {
+        try {
+            $param = $request->all();
+            $data = $this->service->setModel()->getList($param,['groups']);
+            return successTrans("success.data",pageFormat($data),200);
+        } catch (\Throwable $th) {
+            return error($th->getMessage());
+        }
+    }
+
+    #[GetMapping('group')]
+    public function getGroupList(Request $request): Response
+    {
+        try {
+            $param = $request->all();
+            $data = $this->serviceGroup->setModel()->getList($param);
+            return successTrans("success.data",pageFormat($data),200);
+        } catch (\Throwable $th) {
+            return error($th->getMessage());
+        }
+    }
+
+
+    #[PostMapping('sync')]
+    public function syncAccount(Request $request): Response
+    {
+        try {
+            $param = $this->_valid([
+                "id.require" => "参数错误"
+            ]);
+            if (!is_array($param)) return error($param);
+            $group = (new CpaAccountGroup)->where("account_id",$param['id'])->findOrEmpty();
+            if ($group->isEmpty()) return error("组织信息错误");
+            Redis::send("sync-account",["account_id" => $group['account_id']]);
+            return success("发起同步成功");
+        } catch (\Throwable $th) {
+            return error($th->getMessage());
+        }
+    }
+
+
+}

+ 34 - 0
app/controller/admin/Order.php

@@ -0,0 +1,34 @@
+<?php
+
+namespace app\controller\admin;
+
+use app\extra\basic\Base;
+use app\middleware\AuthMiddleware;
+use app\service\cpa\OrderService;
+use DI\Attribute\Inject;
+use LinFly\Annotation\Attributes\Route\Controller;
+use LinFly\Annotation\Attributes\Route\GetMapping;
+use LinFly\Annotation\Attributes\Route\Middleware;
+use support\Request;
+use support\Response;
+
+#[Controller("/api/order"),Middleware(AuthMiddleware::class)]
+class Order extends Base
+{
+
+    #[Inject]
+    protected OrderService $service;
+
+    #[GetMapping('list')]
+    public function getDataList(Request $request): Response
+    {
+        try {
+            $param = $request->all();
+            $data = $this->service->setModel()->getList($param,['product','pages','account']);
+            return successTrans("success.data",pageFormat($data),200);
+        } catch (\Throwable $th) {
+            return error($th->getMessage());
+        }
+    }
+
+}

+ 1 - 1
app/controller/admin/Pages.php

@@ -29,7 +29,7 @@ class Pages extends Base
     {
         try {
             $param = $request->all();
-            $data = $this->service->setModel()->getList($param);
+            $data = $this->service->setModel()->getList($param,['product','account']);
             return successTrans("success.data",pageFormat($data),200);
         } catch (\Throwable $th) {
             return error($th->getMessage());

+ 20 - 0
app/controller/admin/Product.php

@@ -52,4 +52,24 @@ class Product extends Base
         }
     }
 
+    #[PostMapping("status")]
+    public function setProductData(Request $request): Response
+    {
+        try {
+            $param = $this->_valid([
+                "id.require" => "参数错误",
+                "status.require" => "参数错误"
+            ],$request->method());
+            if (!is_array($param)) return error($param);
+            $product = $this->model->where("id",$param['id'])->findOrEmpty();
+            if ($product->isEmpty()) return error("数据错误");
+            $product->status = $param['status'] - 1;
+            $state = $product->save();
+            if (!$state) return errorTrans("error.data");
+            return successTrans("success.data");
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
 }

+ 148 - 0
app/controller/common/Ocean.php

@@ -0,0 +1,148 @@
+<?php
+
+namespace app\controller\common;
+
+use app\extra\basic\Base;
+use app\extra\ocean\AccessToken;
+use app\model\cpa\CpaAccountGroup;
+use LinFly\Annotation\Attributes\Route\Controller;
+use LinFly\Annotation\Attributes\Route\GetMapping;
+use support\Request;
+use support\Response;
+use support\think\Cache;
+use Webman\RedisQueue\Redis;
+
+
+#[Controller(prefix: "/ocean")]
+class Ocean extends Base
+{
+
+
+    /**
+     * AccessToken前缀
+     * @var string
+     */
+    protected string $tokenPrefix = "ocean_[appid]_access_token";
+
+    /**
+     * RefreshToken前缀
+     * @var string
+     */
+    protected string $refreshPrefix = "ocean_[appid]_refresh_token";
+
+    /**
+     * 应用授权Token
+     * @param Request $request
+     * @return Response
+     */
+    #[GetMapping("oauth")]
+    public function getAdTokenOauth(Request $request): Response
+    {
+        try {
+            $param = $this->_valid([
+                "auth_code.require" => "参数错误",
+                "app_id.require"    => "参数错误",
+                "state.require"     => "参数错误"
+            ]);
+            if (!is_array($param)) return error($param);
+            $config = $this->getConfig($param['app_id']);
+            $accessToken = (new AccessToken)->config($config)->getAccessTokenCode($param['auth_code'],$param['state']);
+            if (isset($accessToken['access_token'])) {
+                Cache::set($this->getTokenPrefix($param['app_id']),$accessToken['access_token'],$accessToken['expires_in']);
+                Cache::set($this->getRefreshPrefix($param['app_id']),$accessToken['refresh_token'],$accessToken['refresh_token_expires_in']);
+                $group = (new AccessToken)->config($config)->getOauthAccount();
+                if (!empty($group['list'])) {
+                    foreach ($group['list'] as $val) {
+                        $groupModel = (new CpaAccountGroup)->where("advertiser_id",$val['advertiser_id'])->findOrEmpty();
+                        if ($groupModel->isEmpty()) {
+                            $groupModel->strict(false)->insertGetId($val);
+                        }
+                    }
+                }
+                return success("换取成功");
+            }
+            return error("换取Token失败");
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+
+    #[GetMapping("account")]
+    public function getAccount(): Response
+    {
+        try {
+            $config = $this->getConfig();
+            $accessToken = (new AccessToken)->config($config)->getOauthAccount();
+            return success("换取成功",$accessToken);
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+
+    #[GetMapping("token")]
+    public function getAccountToken(): Response
+    {
+        try {
+            $config = $this->getConfig();
+            $accessToken = (new AccessToken)->config($config)->getAccessToken();
+            return success("换取成功",['data'=> $accessToken]);
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+
+    #[GetMapping("sync")]
+    public function syncAccount(Request $request): Response
+    {
+        try {
+            $param = $this->_valid([
+                "account.require" => "参数错误"
+            ]);
+            if (!is_array($param)) return error($param);
+            Redis::send("sync-account",["account_id" => $param['account']]);
+            return success("发起同步成功");
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+
+    /**
+     * 配置信息
+     * @param string $type
+     * @return array
+     */
+    protected function getConfig(string $type = ""): array
+    {
+        return [
+            "appid"     => "1874672050081403",
+            "secret"    => "584e48eab19f6ec69118686b40998e2082eb77ee",
+            "prefix"    => "ocean",
+        ];
+    }
+
+
+    /**
+     * @param string $type
+     * @return string
+     */
+    protected function getTokenPrefix(string $type = ""): string
+    {
+        $config = $this->getConfig($type);
+        return str_replace("[appid]",$config['appid'],$this->tokenPrefix);
+    }
+
+    /**
+     * @param string $type
+     * @return string
+     */
+    protected function getRefreshPrefix(string $type = ""): string
+    {
+        $config = $this->getConfig($type);
+        return str_replace("[appid]",$config['appid'],$this->refreshPrefix);
+    }
+
+}

+ 76 - 0
app/extra/ocean/AccessToken.php

@@ -0,0 +1,76 @@
+<?php
+
+namespace app\extra\ocean;
+
+class AccessToken extends Base
+{
+
+
+    /**
+     * 获取AccessToken
+     * https://open.oceanengine.com/labels/37/docs/1696710505596940?origin=left_nav
+     * @param string $type
+     * @param string $authCode
+     * @param string $grantType
+     * @return array
+     */
+    public function getAccessTokenCode(string $authCode,string $type = "ad",string $grantType = 'auth_code'): array
+    {
+        $data = [
+            "app_id"        => $this->config['appid'],
+            "secret"        => $this->config['secret'],
+            "grant_type"    => $grantType,
+            "auth_code"     => $authCode
+        ];
+        $url = "oauth2/access_token/";
+        return $this->curlPostApi($url,$data);
+    }
+
+
+    /**
+     * 刷新AccessToken
+     * https://open.oceanengine.com/labels/37/docs/1696710506097679?origin=left_nav
+     * @param string $token
+     * @param string $grantType
+     * @return array
+     */
+    public function refreshAccessToken(string $token,string $type = "ad",string $grantType = 'refresh_token'): array
+    {
+        $data = [
+            "app_id"        => $this->config['appid'],
+            "secret"        => $this->config['secret'],
+            "grant_type"    => $grantType,
+            "refresh_token" => $token
+        ];
+        $url = "oauth2/refresh_token/";
+        return $this->curlPostApi($url,$data);
+    }
+
+    /**
+     * 获取已授权账户
+     * https://open.oceanengine.com/labels/37/docs/1696710506574848?origin=left_nav
+     * @return array
+     */
+    public function getOauthAccount(): array
+    {
+        $data = [
+            "access_token" => $this->getAccessToken()
+        ];
+        $url = "oauth2/advertiser/get/";
+        return $this->curlGetApi($url,$data);
+    }
+
+
+    /**
+     * 获取授权User信息
+     * https://open.oceanengine.com/labels/7/docs/1696710507039756?origin=left_nav
+     * @param string $access_token
+     * @return array
+     */
+    public function getOauthAccountInfo(string $access_token = ""): array
+    {
+        $url = "2/user/info/";
+        return $this->curlGetApi($url);
+    }
+
+}

+ 28 - 0
app/extra/ocean/Account.php

@@ -0,0 +1,28 @@
+<?php
+
+namespace app\extra\ocean;
+
+class Account extends Base
+{
+
+    /**
+     * 获取升级版巨量引擎工作台下账户列表
+     * https://open.oceanengine.com/labels/7/docs/1829550825614739?origin=left_nav
+     * @param string $orgId
+     * @param string $type
+     * @param int $page
+     * @param int $size
+     * @return array
+     */
+    public function getAccountList(string $orgId = "",string $type = "AD",int $page = 1,int $size = 100): array
+    {
+        $param = [
+            "enterprise_organization_id" => $orgId,
+            "account_source"            => $type,
+            "page"              => $page,
+            "page_size"         => $size
+        ];
+        return $this->curlGetApi("2/ebp/advertiser/list/",$param);
+    }
+
+}

+ 141 - 0
app/extra/ocean/Base.php

@@ -0,0 +1,141 @@
+<?php
+
+namespace app\extra\ocean;
+
+use support\think\Cache;
+use yzh52521\EasyHttp\Http;
+
+class Base
+{
+
+
+    /**
+     * 新版API地址
+     * @var string
+     */
+    protected string $gateway = "https://api.oceanengine.com/open_api/";
+
+    /**
+     * API地址
+     * @var string
+     */
+    protected string $gatewayOld = "https://ad.oceanengine.com/open_api/";
+
+    /**
+     * 配置信息
+     * @var array
+     */
+    protected array $config = [];
+
+    /**
+     * @var string
+     */
+    private string $access_token;
+
+    /**
+     * 默认header
+     * @var string[]
+     */
+    protected array $header = ['Content-Type: application/json'];
+
+    /**
+     * AccessToken前缀
+     * @var string
+     */
+    protected string $tokenPrefix = "ocean_[appid]_access_token";
+
+    /**
+     * RefreshToken前缀
+     * @var string
+     */
+    protected string $refreshPrefix = "ocean_[appid]_refresh_token";
+
+
+
+    public function token(): static
+    {
+        $this->header = [
+            "Access-Token" => $this->getAccessToken()
+        ];
+        return $this;
+    }
+
+    /**
+     * 设置配置信息
+     * @param array $config
+     * @return $this
+     */
+    public function config(array $config = []): static
+    {
+        $this->config = $config;
+        return $this;
+    }
+
+
+    public function getAccessToken()
+    {
+        $accessToken = Cache::get($this->getTokenPrefix());
+        if (!empty($accessToken)) return $accessToken;
+        $refreshToken = Cache::get($this->getRefreshPrefix());
+        $result = (new AccessToken)->config($this->config)->refreshAccessToken($refreshToken,$this->config['prefix']);
+        if (!is_array($result)) return "获取Token失败\n";
+        Cache::set($this->getTokenPrefix(),$result['access_token'],$result['expires_in']);
+        Cache::set($this->getRefreshPrefix(),$result['refresh_token'],$result['refresh_token_expires_in']);
+        return $result['access_token'];
+    }
+
+
+    /**
+     * @param string $url
+     * @param array $data
+     * @param string $field
+     * @return array
+     */
+    public function curlPostApi(string $url = "", array $data = [], string $field = "data"): array
+    {
+        $result = Http::asJson()->withHeaders($this->header)->post($this->gateway.$url,$data)->array();
+        if (isset($result['code']) && $result['code'] <> 0) return ['msg' => $result['message']];
+        if(!empty($result[$field]))
+        {
+            return $result[$field];
+        }
+        return [];
+    }
+
+    /**
+     * @param string $url
+     * @param array $data
+     * @param string $field
+     * @return array
+     */
+    public function curlGetApi(string $url = "", array $data = [], string $field = "data"): array
+    {
+        $result = Http::asJson()->withHeaders($this->header)->get($this->gateway.$url,$data)->array();
+        if (isset($result['code']) && $result['code'] <> 0) return ['msg' => $result['message']];
+        if(!empty($result[$field]))
+        {
+            return $result[$field];
+        }
+        return [];
+    }
+
+
+    /**
+     * @return string
+     */
+    protected function getTokenPrefix(): string
+    {
+        return str_replace("[appid]",$this->config['appid'],$this->tokenPrefix);
+    }
+
+    /**
+     * @return string
+     */
+    protected function getRefreshPrefix(): string
+    {
+        return str_replace("[appid]",$this->config['appid'],$this->refreshPrefix);
+    }
+
+
+
+}

+ 10 - 4
app/model/cpa/CpaAccount.php

@@ -3,13 +3,14 @@
 namespace app\model\cpa;
 
 use app\extra\basic\Model;
+use think\model\relation\HasOne;
 
 
 /**
- * @property integer $id (主键)
- * @property mixed $advertiser_id 
- * @property string $advertiser_name 
- * @property integer $status 
+ * @property integer $id (主键)
+ * @property mixed $advertiser_id 
+ * @property string $advertiser_name 
+ * @property integer $status 
  * @property mixed $create_at
  */
 class CpaAccount extends Model
@@ -43,4 +44,9 @@ class CpaAccount extends Model
     public bool $timestamps = false;
 
 
+    public function groups(): HasOne
+    {
+        return $this->hasOne(CpaAccountGroup::class,"account_id","group_id");
+    }
+
 }

+ 50 - 0
app/model/cpa/CpaAccountGroup.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace app\model\cpa;
+
+use app\extra\basic\Model;
+
+
+/**
+ * @property integer $id (主键)
+ * @property mixed $account_id 
+ * @property string $account_name 
+ * @property string $account_role 
+ * @property string $account_type 
+ * @property mixed $advertiser_id 
+ * @property string $advertiser_name 
+ * @property string $advertiser_role 
+ * @property mixed $is_valid
+ */
+class CpaAccountGroup extends Model
+{
+    /**
+     * The connection name for the model.
+     *
+     * @var string|null
+     */
+    protected $connection = 'mysql';
+    
+    /**
+     * The table associated with the model.
+     *
+     * @var string
+     */
+    protected string $table = "cpa_account_group";
+    
+    /**
+     * The primary key associated with the table.
+     *
+     * @var string
+     */
+    protected string $primaryKey = "id";
+    
+    /**
+     * Indicates if the model should be timestamped.
+     *
+     * @var bool
+     */
+    public bool $timestamps = false;
+
+
+}

+ 25 - 10
app/model/cpa/CpaOrder.php

@@ -3,19 +3,20 @@
 namespace app\model\cpa;
 
 use app\extra\basic\Model;
+use think\model\relation\HasOne;
 
 
 /**
- * @property integer $id (主键)
- * @property mixed $order_no 
- * @property mixed $product_id 商品ID
- * @property mixed $link_code 链接
- * @property mixed $content 
- * @property string $ip_addr 
- * @property mixed $ip_province 
- * @property mixed $ip_city 
- * @property integer $is_callback 1已回传
- * @property mixed $callback_at 回传时间
+ * @property integer $id (主键)
+ * @property mixed $order_no 
+ * @property mixed $product_id 商品ID
+ * @property mixed $link_code 链接
+ * @property mixed $content 
+ * @property string $ip_addr 
+ * @property mixed $ip_province 
+ * @property mixed $ip_city 
+ * @property integer $is_callback 1已回传
+ * @property mixed $callback_at 回传时间
  * @property mixed $create_at
  */
 class CpaOrder extends Model
@@ -48,5 +49,19 @@ class CpaOrder extends Model
      */
     public bool $timestamps = false;
 
+    public function product(): HasOne
+    {
+        return $this->hasOne(CpaProduct::class,"code","product_id");
+    }
+
+    public function pages(): HasOne
+    {
+        return $this->hasOne(CpaPage::class,"link_code","link_code");
+    }
+
+    public function account(): HasOne
+    {
+        return $this->hasOne(CpaAccount::class,"advertiser_id","advertiser_id");
+    }
 
 }

+ 16 - 5
app/model/cpa/CpaPage.php

@@ -3,14 +3,15 @@
 namespace app\model\cpa;
 
 use app\extra\basic\Model;
+use think\model\relation\HasOne;
 
 
 /**
- * @property integer $id (主键)
- * @property mixed $product_id 
- * @property mixed $link_code 
- * @property mixed $content 
- * @property integer $status 
+ * @property integer $id (主键)
+ * @property mixed $product_id 
+ * @property mixed $link_code 
+ * @property mixed $content 
+ * @property integer $status 
  * @property mixed $create_at
  */
 class CpaPage extends Model
@@ -44,4 +45,14 @@ class CpaPage extends Model
     public bool $timestamps = false;
 
 
+    public function account(): HasOne
+    {
+        return $this->hasOne(CpaAccount::class,"advertiser_id","advertiser_id");
+    }
+
+    public function product(): HasOne
+    {
+        return $this->hasOne(CpaProduct::class,"code","product_id");
+    }
+
 }

+ 84 - 0
app/queue/redis/fast/SyncAccount.php

@@ -0,0 +1,84 @@
+<?php
+
+namespace app\queue\redis\fast;
+
+use app\extra\ocean\Account;
+use app\model\cpa\CpaAccount;
+use Webman\RedisQueue\Consumer;
+
+class SyncAccount implements Consumer
+{
+
+    /**
+     * 消费队列名
+     * 核销队列
+     * @var string
+     */
+    public string $queue = "sync-account";
+
+    /**
+     * 连接配置
+     * @var string
+     */
+    public string $connection = "default";
+
+    public function consume($data): bool
+    {
+        try {
+            if (empty($data['account_id'])) return true;
+            echo("开始同步====>" . getDateFull());
+            $nextPage = 1;
+            while (is_numeric($nextPage)) {
+                $resp = (new Account)->config($this->getConfig())->token()->getAccountList($data['account_id'],"AD",$nextPage);
+                if (empty($resp['account_list'])) {
+                    echo getDateFull()."==没有数据了==\n";
+                    $nextPage = null;
+                    return true;
+                }
+                foreach ($resp['account_list'] as $item) {
+                    $account = (new CpaAccount)->where("advertiser_id",$item['account_id'])->findOrEmpty();
+                    if ($account->isEmpty()) {
+                        $account->strict(false)->insertGetId([
+                            "advertiser_id" => $item['account_id'],
+                            "group_id"      => $data['account_id'],
+                            "advertiser_name"   => $item['account_name']
+                        ]);
+                        echo getDateFull()."==新账户入库=={$item['account_id']}====\n";
+                    } else {
+                        $account->save([
+                            "advertiser_id" => $item['account_id'],
+                            "advertiser_name"   => $item['account_name']
+                        ]);
+                        echo getDateFull()."==更新账户=={$item['account_id']}====\n";
+                    }
+                }
+                $nextPage = $nextPage+1;
+                echo("进入下一页=={$nextPage}==".getDateFull());
+            }
+        } catch (\Throwable $throwable) {
+            echo getDateFull()."===同步账户列表报错\n";
+            echo $throwable->getFile()."\n";
+            echo $throwable->getLine()."\n";
+            echo $throwable->getMessage()."\n";
+            return true;
+        }
+        return true;
+    }
+
+
+
+    /**
+     * 配置信息
+     * @param string $type
+     * @return array
+     */
+    protected function getConfig(string $type = ""): array
+    {
+        return [
+            "appid"     => "1874672050081403",
+            "secret"    => "584e48eab19f6ec69118686b40998e2082eb77ee",
+            "prefix"    => "ocean",
+        ];
+    }
+
+}

+ 36 - 0
app/service/cpa/AccountService.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace app\service\cpa;
+
+use app\extra\basic\Service;
+use app\model\cpa\CpaAccount;
+
+class AccountService extends Service
+{
+
+
+    /**
+     *
+     * @return $this
+     */
+    public function setModel(): static
+    {
+        $this->mode = (new CpaAccount);
+        return $this;
+    }
+
+    /**
+     *
+     * @param array $param
+     * @return array
+     */
+    public function searchFilter(array $param = []): array
+    {
+        $filter = [];
+        !empty($param['status']) && $filter[] = ["status", '=', $param['status']];
+        !empty($param['code']) && $filter[] = ["link_code", 'like', "%{$param['code']}%"];
+        !empty($param['name']) && $filter[] = ["title", 'like', "%{$param['name']}%"];
+        return $filter;
+    }
+
+}

+ 36 - 0
app/service/cpa/GroupService.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace app\service\cpa;
+
+use app\extra\basic\Service;
+use app\model\cpa\CpaAccountGroup;
+
+class GroupService extends Service
+{
+
+
+    /**
+     *
+     * @return $this
+     */
+    public function setModel(): static
+    {
+        $this->mode = (new CpaAccountGroup);
+        return $this;
+    }
+
+    /**
+     *
+     * @param array $param
+     * @return array
+     */
+    public function searchFilter(array $param = []): array
+    {
+        $filter = [];
+        !empty($param['status']) && $filter[] = ["status", '=', $param['status']];
+        !empty($param['code']) && $filter[] = ["link_code", 'like', "%{$param['code']}%"];
+        !empty($param['name']) && $filter[] = ["title", 'like', "%{$param['name']}%"];
+        return $filter;
+    }
+
+}

+ 36 - 0
app/service/cpa/OrderService.php

@@ -0,0 +1,36 @@
+<?php
+
+namespace app\service\cpa;
+
+use app\extra\basic\Service;
+use app\model\cpa\CpaOrder;
+
+class OrderService extends Service
+{
+
+
+    /**
+     *
+     * @return $this
+     */
+    public function setModel(): static
+    {
+        $this->mode = (new CpaOrder);
+        return $this;
+    }
+
+    /**
+     *
+     * @param array $param
+     * @return array
+     */
+    public function searchFilter(array $param = []): array
+    {
+        $filter = [];
+        !empty($param['status']) && $filter[] = ["status", '=', $param['status']];
+        !empty($param['order_no']) && $filter[] = ["order_no", 'like', "%{$param['order_no']}%"];
+        !empty($param['name']) && $filter[] = ["title", 'like', "%{$param['name']}%"];
+        return $filter;
+    }
+
+}