zory 3 settimane fa
parent
commit
f01a54f8ce

File diff suppressed because it is too large
+ 37 - 0
app/command/OceanStat.php


+ 46 - 0
app/command/PushAuthor.php

@@ -0,0 +1,46 @@
+<?php
+
+namespace app\command;
+
+use app\model\star\StarTaskUser;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use yzh52521\EasyHttp\Http;
+
+class PushAuthor extends Command
+{
+
+
+    protected static string $defaultName = 'push:author';
+    protected static string $defaultDescription = '星川任务';
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        try {
+            $nextPage = 1;
+            $done = 0;
+            while (is_numeric($nextPage)) {
+                $resp = (new StarTaskUser)->page($nextPage,10)->select();
+                if ($resp->isEmpty()) {
+                    $output->writeln("没有任务啦==".getDateFull());
+                    $nextPage = null;
+                    return true;
+                }
+                foreach ($resp as $key=>$val) {
+                    $resp = Http::asJson()->post("https://api.jiandaoyun.com/api/v1/automation/tenant/69dc899f71c9656940c3db33/hooks/69e07cb9d9016a4b9d9e4b140bb32ba471357f09758bdc49",$val->toArray())->array();
+                    print_r($resp);
+                }
+                $nextPage = $nextPage+1;
+                $output->writeln("进入下一页=={$nextPage}==".getDateFull());
+            }
+        } catch (\Throwable $throwable) {
+            echo getDateFull()."==报错啦===".$throwable->getFile()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getLine()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getMessage()."\n";
+        }
+        return true;
+
+    }
+
+}

+ 52 - 0
app/command/PushVideo.php

@@ -0,0 +1,52 @@
+<?php
+
+namespace app\command;
+
+use app\model\star\StarTaskUser;
+use app\model\star\StarTaskVideo;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use yzh52521\EasyHttp\Http;
+
+class PushVideo extends Command
+{
+
+
+
+    protected static string $defaultName = 'push:video';
+    protected static string $defaultDescription = '星川任务';
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        try {
+            $nextPage = 1;
+            $done = 0;
+            while (is_numeric($nextPage)) {
+                $resp = (new StarTaskVideo)->page($nextPage,10)->select();
+                if ($resp->isEmpty()) {
+                    $output->writeln("没有任务啦==".getDateFull());
+                    $nextPage = null;
+                    return true;
+                }
+                foreach ($resp as $key=>$val) {
+                    $resp = Http::asJson()->post("https://api.jiandaoyun.com/api/v1/automation/tenant/69dc899f71c9656940c3db33/hooks/69e07cb9d9016a4ba4737e880bb32ba47135f8c4f8799955",$val->toArray())->array();
+                    if ($resp['code'] <> 0) {
+                        $output->writeln("{$val['video_id']} == 推送数据失败==".getDateFull());
+                    } else {
+                        $output->writeln("{$val['video_id']} == 推送成功==".getDateFull());
+                    }
+                }
+                $nextPage = $nextPage+1;
+                $output->writeln("进入下一页=={$nextPage}==".getDateFull());
+            }
+        } catch (\Throwable $throwable) {
+            echo getDateFull()."==报错啦===".$throwable->getFile()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getLine()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getMessage()."\n";
+        }
+        return true;
+
+    }
+
+}

+ 107 - 0
app/command/StarAuthor.php

@@ -0,0 +1,107 @@
+<?php
+
+namespace app\command;
+
+use app\extra\tools\XcJob;
+use app\model\star\StarTask;
+use app\model\star\StarTaskUser;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class StarAuthor extends Command
+{
+
+    protected static string $defaultName = 'star:author';
+    protected static string $defaultDescription = '星川任务';
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        try {
+            $nextPage = 1;$done = 0;$subPage = 1;
+            while (is_numeric($nextPage))
+            {
+                $output->writeln("开始位置:{$nextPage}==".getDateFull());
+                $resp = (new StarTask)->page($nextPage,10)->select();
+                if ($resp->isEmpty()) {
+                    $output->writeln("没有任务啦==".getDateFull());
+                    $nextPage = null;
+                    return true;
+                }
+                $taskUser = (new StarTaskUser);
+                foreach ($resp as $key=>$val) {
+                    $output->writeln("任务ID:{$val['job_id']}==页码:{$subPage}==开始执行==".getDateFull());
+                    while (is_numeric($subPage))
+                    {
+                        [$state,$taskResp] = (new XcJob)->token()->getTaskAuthor($val['job_id'],$subPage);
+                        if (!$state) {
+                            $output->writeln("任务ID:{$val['job_id']}==没有投稿任务啦==".getDateFull());
+                            $subPage = 1;
+                            break;
+                        }
+                        if (!$taskResp['has_more']) {
+                            $output->writeln("进入下一个任务==".getDateFull());
+                            $subPage = 1;
+                            break;
+                        }
+                        foreach ($taskResp['list'] as $sk=>$sv) {
+                            $userData = $taskUser->where(['job_id' => $val['job_id'],'author_id' => $sv['author_base_info']['author_id']])->findOrEmpty();
+                            if ($userData->isEmpty()) {
+                                $userData->insertGetId([
+                                    "job_id"            => $val['job_id'],
+                                    'nick_name'         => removeEmoji2($sv['author_base_info']['nick_name']),
+                                    'show_nick_name'    => emojiToUnicode($sv['author_base_info']['nick_name']),
+                                    "avatar_uri"        => $sv['author_base_info']['avatar_uri'],
+                                    "author_id"         => $sv['author_base_info']['author_id'],
+                                    "sample_address_str"    => $sv['author_base_info']['sample_address_str']??'',
+                                    "follower"    => $sv['author_base_info']['follower'],
+                                    "gender"    => $sv['author_base_info']['gender'],
+                                    "sec_uid"    => $sv['author_base_info']['sec_uid'],
+                                    "wechat"    => $sv['author_base_info']['wechat']??'',
+                                    "author_level"    => $sv['author_base_info']['ecom_author_level']??'L0',
+                                    "author_order_status"    => $sv['author_order_info']['author_order_status'],
+                                    "invitation_status"    => $sv['author_invitaion_info']['invitation_status'],
+                                    "metric_data_num"    => $sv['author_select_metric_data']['offline_metric_data']['6001']??0,
+                                    "metric_data_rate"    => $sv['author_select_metric_data']['offline_metric_data']['6002']??0,
+                                    "release_item_count"    => $sv['author_order_info']['release_item_count'],
+                                    "visible_item_count"    => $sv['author_order_info']['visible_item_count'],
+                                ]);
+                                echo "任务ID:{$val['job_id']},星图ID:{$sv['author_base_info']['author_id']},昵称:".removeEmoji2($sv['author_base_info']['nick_name'])."===".emojiToUnicode($sv['author_base_info']['nick_name'])."===入库成功!~==>".getDateFull()."\n";
+                            } else {
+                                $userData->save([
+                                    'nick_name'         => removeEmoji2($sv['author_base_info']['nick_name']),
+                                    'show_nick_name'    => emojiToUnicode($sv['author_base_info']['nick_name']),
+                                    "avatar_uri"        => $sv['author_base_info']['avatar_uri'],
+                                    "follower"    => $sv['author_base_info']['follower'],
+                                    "gender"    => $sv['author_base_info']['gender'],
+                                    "wechat"    => $sv['author_base_info']['wechat']??'',
+                                    "author_level"    => $sv['author_base_info']['ecom_author_level']??'L0',
+                                    "author_order_status"    => $sv['author_order_info']['author_order_status'],
+                                    "invitation_status"    => $sv['author_invitaion_info']['invitation_status'],
+                                    "metric_data_num"    => $sv['author_select_metric_data']['offline_metric_data']['6001']??0,
+                                    "metric_data_rate"    => $sv['author_select_metric_data']['offline_metric_data']['6002']??0,
+                                    "release_item_count"    => $sv['author_order_info']['release_item_count'],
+                                    "visible_item_count"    => $sv['author_order_info']['visible_item_count'],
+                                ]);
+                                echo "任务ID:{$val['job_id']},星图ID:{$sv['author_base_info']['author_id']}===更新一下!~==>".getDateFull()."\n";
+                            }
+                        }
+                        $subPage = $subPage+1;
+                        $output->writeln("进入下一页达人=={$nextPage}-{$subPage}==".getDateFull());
+                        $output->writeln("===========================================================================");
+                        sleep(2);
+                    }
+                }
+                $nextPage = $nextPage+1;
+                $subPage = 1;
+                $output->writeln("进入下一页=={$nextPage}==".getDateFull());
+            }
+        } catch (\Throwable $throwable) {
+            echo getDateFull()."==报错啦===".$throwable->getFile()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getLine()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getMessage()."\n";
+        }
+        return true;
+    }
+
+}

+ 66 - 0
app/command/StarTask.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace app\command;
+
+use app\extra\tools\XcJob;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class StarTask extends Command
+{
+
+
+    protected static string $defaultName = 'star:task';
+    protected static string $defaultDescription = '星川任务';
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        try {
+            $nextPage = 1;$done = 0;
+            while (is_numeric($nextPage)) {
+                [$state,$resp] = (new XcJob)->token()->getTaskList($nextPage);
+                if (!$state) {
+                    $nextPage = null;
+                    return self::SUCCESS;
+                }
+                if (!$resp['has_more']) {
+                    $nextPage = null;
+                    return self::SUCCESS;
+                }
+                $model = (new \app\model\star\StarTask);
+                foreach ($resp['list'] as $key => $val)
+                {
+                    $task = $model->where("job_id",$val['demand_info']['id'])->findOrEmpty();
+                    if ($task->isEmpty()) { // 新增
+                        $task->insertGetId([
+                            "job_id"        => $val['demand_info']['id'],
+                            "project_id"    => $val['project_info']['project_id'],
+                            "project_name"    => $val['project_info']['project_name'],
+                            "shop_name"    => $val['project_info']['shop_name'],
+                            "product_name"    => $val['project_info']['product_name'],
+                            "cover"    => $val['demand_info']['qc_ecom_product_info']['cover']??'',
+                            "detail_url"    => $val['demand_info']['qc_ecom_product_info']['detail_url']??'',
+                            "product_id"    => $val['demand_info']['qc_ecom_product_info']['product_id']??'',
+                            "expiration_time"    => $val['challenge_info']['expiration_time'],
+                            "expiration_time_end"    => $val['challenge_info']['expiration_time_end'],
+                        ]);
+                        $output->writeln("{$val['demand_info']['id']}===入库成功!~==>".getDateFull());
+                    } else {
+                        // 更新
+                        $output->writeln("{$val['demand_info']['id']}===已存在,不入库!~==>".getDateFull());
+                    }
+                }
+                $nextPage = $nextPage+1;
+                $output->writeln("===当前页码{$nextPage}==>".getDateFull());
+            }
+            return self::SUCCESS;
+        } catch (\Throwable $throwable) {
+            echo getDateFull()."==报错啦===".$throwable->getFile()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getLine()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getMessage()."\n";
+            return self::SUCCESS;
+        }
+    }
+
+}

+ 148 - 0
app/command/StarVideo.php

@@ -0,0 +1,148 @@
+<?php
+
+namespace app\command;
+
+use app\extra\tools\XcJob;
+use app\model\star\StarTask;
+use app\model\star\StarTaskVideo;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class StarVideo extends Command
+{
+
+    protected static string $defaultName = 'star:video';
+    protected static string $defaultDescription = '星川任务';
+
+    protected array $status = [
+        3 => "已完成",
+        31 => "平台审核中",
+        32 => "审核未通过",
+        33 => "审核未通过",
+        70 => "服务商审核中",
+        71 => "审核未通过",
+        72 => "预热中",
+        73 => "审核超时",
+        74 => "客户审核中",
+        75 => "审核未通过",
+        76 => "审核超时",
+        80 => "持续计费中",
+        81 => "结果公示中",
+        82 => "计费暂停",
+    ];
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+
+        try {
+            $nextPage = 1;$done = 0;$subPage = 1;
+            while (is_numeric($nextPage)) {
+                $resp = (new StarTask)->page($nextPage,10)->select();
+                if ($resp->isEmpty()) {
+                    $output->writeln("没有任务啦==".getDateFull());
+                    $nextPage = null;
+                    return true;
+                }
+                $taskVideo = (new StarTaskVideo);
+                foreach ($resp as $key=>$val) {
+                    $output->writeln("任务ID:{$val['job_id']}==页码:{$subPage}==开始执行==" . getDateFull());
+                    while (is_numeric($subPage))
+                    {
+                        [$state,$taskResp] = (new XcJob)->token()->getAuthorVideo($val['job_id'],$subPage);
+                        if (!$state) {
+                            $output->writeln("任务ID:{$val['job_id']}==没有视频啦==".getDateFull());
+                            $subPage = 1;
+                            break;
+                        }
+                        if (!$taskResp['has_more']) {
+                            $output->writeln("进入下一个任务==".getDateFull());
+                            $subPage = 1;
+                            break;
+                        }
+                        foreach ($taskResp['list'] as $sk=>$sv) {
+                            $userData = $taskVideo->where(['job_id' => $val['job_id'],'item_id' => $sv['base_info']['item_id']])->findOrEmpty();
+                            [$vState,$videDetail] = (new XcJob)->token()->getVideoDetail($sv['base_info']['video_id']);
+                            if ($userData->isEmpty()) {
+                                $userData->insertGetId([
+                                    "job_id"        => $val['job_id'],
+                                    "author_id"     => $sv['author_info']['author_id'],
+                                    "play_url"      => $vState ? $videDetail['play_url'] : '',
+                                    "cover"         => $vState ? $videDetail['cover'] : '',
+                                    "title"         => removeEmoji2($sv['base_info']['title']),
+                                    "duration"      => $sv['base_info']['duration'],
+                                    "item_id"       => $sv['base_info']['item_id'],
+                                    "lego_mid"      => $sv['ad_info']['lego_mid'],
+                                    "video_id"      => $sv['base_info']['video_id'],
+                                    "item_status"   => $this->status[$sv['extra_info']['item_status']],
+                                    "time_agg_data_10006"   => $sv['item_real_time_agg_data']['10006']??0,
+                                    "time_agg_data_10010"   => $sv['item_real_time_agg_data']['10010']??0,
+                                    "time_agg_data_10014"   => $sv['item_real_time_agg_data']['10014']??0,
+                                    "time_agg_data_10035"   => $sv['item_real_time_agg_data']['10035']??0,
+                                    "time_agg_data_10036"   => $sv['item_real_time_agg_data']['10036']??0,
+                                    "time_agg_data_10057"   => $sv['item_real_time_agg_data']['10057']??0,
+                                    "time_agg_data_10056"   => $sv['item_real_time_agg_data']['10056']??0,
+                                    "time_agg_data_10058"   => $sv['item_real_time_agg_data']['10058']??0,
+                                    "time_agg_data_10059"   => $sv['item_real_time_agg_data']['10059']??0,
+                                    "time_agg_data_10060"   => $sv['item_real_time_agg_data']['10060']??0,
+                                    "time_agg_data_10061"   => $sv['item_real_time_agg_data']['10061']??0,
+                                    "indicator_agg_data_20021"   => $sv['bill_indicator_agg_data']['20021']??0,
+                                    "indicator_agg_data_20022"   => $sv['bill_indicator_agg_data']['20022']??0,
+                                    "indicator_agg_data_20020"   => $sv['bill_indicator_agg_data']['20020']??0,
+                                    "indicator_agg_data_20019"   => $sv['bill_indicator_agg_data']['20019']??0,
+                                    "indicator_agg_data_20016"   => $sv['bill_indicator_agg_data']['20016']??0,
+                                    "indicator_agg_data_20015"   => $sv['bill_indicator_agg_data']['20015']??0,
+                                    "indicator_agg_data_20011"   => $sv['bill_indicator_agg_data']['20011']??0,
+                                ]);
+                                $output->writeln("{$sv['base_info']['video_id']}==【{$sv['base_info']['title']}】==新增一条视频素材==".getDateFull());
+                            } else {
+                                $userData->save([
+                                    "play_url"      => $vState ? $videDetail['play_url'] : '',
+                                    "cover"         => $vState ? $videDetail['cover'] : '',
+                                    "title"         => removeEmoji2($sv['base_info']['title']),
+                                    "duration"      => $sv['base_info']['duration'],
+                                    "item_id"       => $sv['base_info']['item_id'],
+                                    "lego_mid"      => $sv['ad_info']['lego_mid'],
+                                    "video_id"      => $sv['base_info']['video_id'],
+                                    "item_status"   => $this->status[$sv['extra_info']['item_status']],
+                                    "time_agg_data_10006"   => $sv['item_real_time_agg_data']['10006']??0,
+                                    "time_agg_data_10010"   => $sv['item_real_time_agg_data']['10010']??0,
+                                    "time_agg_data_10014"   => $sv['item_real_time_agg_data']['10014']??0,
+                                    "time_agg_data_10035"   => $sv['item_real_time_agg_data']['10035']??0,
+                                    "time_agg_data_10036"   => $sv['item_real_time_agg_data']['10036']??0,
+                                    "time_agg_data_10057"   => $sv['item_real_time_agg_data']['10057']??0,
+                                    "time_agg_data_10056"   => $sv['item_real_time_agg_data']['10056']??0,
+                                    "time_agg_data_10058"   => $sv['item_real_time_agg_data']['10058']??0,
+                                    "time_agg_data_10059"   => $sv['item_real_time_agg_data']['10059']??0,
+                                    "time_agg_data_10060"   => $sv['item_real_time_agg_data']['10060']??0,
+                                    "time_agg_data_10061"   => $sv['item_real_time_agg_data']['10061']??0,
+                                    "indicator_agg_data_20021"   => $sv['bill_indicator_agg_data']['20021']??0,
+                                    "indicator_agg_data_20022"   => $sv['bill_indicator_agg_data']['20022']??0,
+                                    "indicator_agg_data_20020"   => $sv['bill_indicator_agg_data']['20020']??0,
+                                    "indicator_agg_data_20019"   => $sv['bill_indicator_agg_data']['20019']??0,
+                                    "indicator_agg_data_20016"   => $sv['bill_indicator_agg_data']['20016']??0,
+                                    "indicator_agg_data_20015"   => $sv['bill_indicator_agg_data']['20015']??0,
+                                    "indicator_agg_data_20011"   => $sv['bill_indicator_agg_data']['20011']??0,
+                                ]);
+                                $output->writeln("{$sv['base_info']['video_id']}===更新数据==".getDateFull());
+                            }
+                        }
+                        $subPage = $subPage+1;
+                        $output->writeln("进入下一页视频=={$nextPage}-{$subPage}==".getDateFull());
+                        $output->writeln("===========================================================================");
+                        sleep(2);
+                    }
+                }
+                $nextPage = $nextPage+1;
+                $subPage = 1;
+                $output->writeln("进入下一页=={$nextPage}==".getDateFull());
+            }
+        } catch (\Throwable $throwable) {
+            echo getDateFull()."==报错啦===".$throwable->getFile()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getLine()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getMessage()."\n";
+        }
+        return true;
+    }
+
+}

+ 146 - 0
app/controller/jiandao/JDStar.php

@@ -0,0 +1,146 @@
+<?php
+
+namespace app\controller\jiandao;
+
+use app\extra\basic\Base;
+use app\extra\tools\XcJob;
+use app\model\bluev\BluevOceanAccount;
+use HuaweiCloud\SDK\Apig\V2\Model\Signature;
+use LinFly\Annotation\Route\Controller;
+use LinFly\Annotation\Route\Route;
+use support\Request;
+use support\Response;
+use support\think\Db;
+use yzh52521\EasyHttp\Http;
+
+
+#[Controller(prefix: "/jd/star")]
+class JDStar extends Base
+{
+
+
+    #[Route(path: "push",methods: "post")]
+    public function getJDYPush(Request $request): Response
+    {
+        try {
+            // 密钥: g8Fbj7NHwS5OhhVEVfP1nTN7
+            $param = $request->all();
+            print_r($param);
+            return success("ok");
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+    #[Route(path: "info",methods: "get")]
+    public function getStarInfo(Request $request): Response
+    {
+        try {
+            $param = $this->_valid([
+                "uid.require"   => trans("empty.require"),
+                "name.require"  => trans("empty.require")
+            ],$request->method());
+            if (!is_array($param)) return error($param);
+            [$state,$xcData] = (new XcJob)->token()->getStarData($param['uid']);
+            if (!$state) return error($xcData);
+            if (empty($xcData['list'])) return error("获取数据失败");
+            $return = [];
+            foreach ($xcData['list'] as $key=>$val) {
+                if (md5($val['attribute_datas']['nick_name']) == md5($param['name'])) {
+                    $return['level'] = $val['attribute_datas']['author_ecom_level']; // 带货等级
+                    $return['avatar_uri'] = $val['attribute_datas']['avatar_uri']; // 用户头像
+                    $return['nick_name'] = $val['attribute_datas']['nick_name']; // 用户昵称
+                    $return['gender'] = $val['attribute_datas']['gender']; // 性别 1 男 2女
+                    $return['follower'] = (int)$val['attribute_datas']['follower']; // 粉丝数
+                    $return['star_id'] = (string)$val['star_id']; // 星图ID
+                    $return['city'] = $val['attribute_datas']['city']; // 所在城市
+                }
+            }
+            if (empty($return)) return error("获取数据失败");
+            [$state,$starDetail] = (new XcJob)->token()->getStarDetail($return['star_id']);
+            if (!$state) return error($xcData);
+            $return['link'] = "https://www.douyin.com/user/{$starDetail['sec_uid']}";
+            return success("ok",$return);
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+    #[Route(path: "express",methods: "get")]
+    public function getExpress(Request $request)
+    {
+        try {
+            $param = $this->_valid([
+                "number.require"   => trans("empty.require"),
+            ],$request->method());
+            if (!is_array($param)) return error($param);
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+    /**
+     * 方舟消耗统计
+     * @param Request $request
+     * @return Response
+     */
+    #[Route(path: "stat",methods: "get")]
+    public function getAdStatData(Request $request): Response
+    {
+        try {
+            $param = $this->_valid([
+                "day.default"   => date("Y-m-d",strtotime("-1 day")),
+                "type.default"  => 'day',
+                "page.default"  => 1,
+                "size.default"  => 10,
+            ],$request->method());
+            if (!is_array($param)) return error($param);
+            switch ($param['type'])
+            {
+                case "year":
+                    $data = (new BluevOceanAccount)
+                        ->where("day", "like","%{$param['day']}%")
+                        ->field("YEAR(day) as year, advertiser_id, ROUND(SUM(noGrantCost)/100000,2) AS total_cost")
+                        ->group("YEAR(day), advertiser_id")
+                        ->order('year', 'desc')
+                        ->paginate([
+                            "list_rows" => $param['size'],
+                            "page" => $param['page']
+                        ]);
+                    break;
+                case "mon":
+                    $data = (new BluevOceanAccount)
+                        ->where("day", "like","%{$param['day']}%")
+                        ->field("DATE_FORMAT(day, '%Y-%m') AS month, advertiser_id, ROUND(SUM(noGrantCost)/100000,2) AS total_cost")
+                        ->group("DATE_FORMAT(day, '%Y-%m'), advertiser_id")
+                        ->order('month', 'desc')
+                        ->paginate([
+                            "list_rows" => $param['size'],
+                            "page" => $param['page']
+                        ]);
+                    break;
+                case "day":
+                default:
+                    $data = (new BluevOceanAccount)->where("day", $param['day'])->paginate([
+                                "list_rows" => $param['size'],
+                                "page" => $param['page']
+                            ]);
+                    break;
+            }
+            return success("ok",pageFormat($data));
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+    #[Route(path: "cost",methods: "get")]
+    public function getJobCostData(Request $request)
+    {
+        try {
+
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+}

+ 127 - 0
app/controller/jiandao/JDXingtu.php

@@ -0,0 +1,127 @@
+<?php
+
+namespace app\controller\jiandao;
+
+use app\extra\basic\Base;
+use app\extra\service\star\TaskVideoService;
+use app\extra\tools\XcJob;
+use DI\Attribute\Inject;
+use LinFly\Annotation\Route\Controller;
+use LinFly\Annotation\Route\Route;
+use support\Request;
+use support\Response;
+
+
+#[Controller(prefix: "/jd/xt")]
+class JDXingtu extends Base
+{
+
+    #[Inject]
+    protected TaskVideoService $service;
+
+    protected array $status = [
+        3 => "已完成",
+        31 => "平台审核中",
+        32 => "审核未通过",
+        33 => "审核未通过",
+        70 => "服务商审核中",
+        71 => "审核未通过",
+        72 => "预热中",
+        73 => "审核超时",
+        74 => "客户审核中",
+        75 => "审核未通过",
+        76 => "审核超时",
+        80 => "持续计费中",
+        81 => "结果公示中",
+        82 => "计费暂停",
+    ];
+
+    /**
+     * 星川任务素材信息
+     * @param Request $request
+     * @return Response
+     */
+    #[Route(path: "video",methods: "get")]
+    public function getXtVideo(Request $request): Response
+    {
+        try {
+            $param = $this->_valid([
+                "job.require"   => trans("empty.require"),
+                "page.default"  => 1,
+                "size.default"  => 10,
+            ],$request->method());
+            if (!is_array($param)) return error($param);
+            $param['pageSize'] = $param['size'];
+            $list = $this->service->getList($param);
+            return successTrans("success.data",pageFormat($list),200);
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+
+    /**
+     * 获取单个任务中指定达人的投稿视频-试试
+     * @param Request $request
+     * @return Response
+     */
+    #[Route(path: "user",methods: "get")]
+    public function getXtUserVideo(Request $request): Response
+    {
+        try {
+            $param = $this->_valid([
+                "job.require"   => trans("empty.require"),
+                "star.require"   => trans("empty.require"),
+                "page.default"  => 1,
+                "size.default"  => 10,
+            ],$request->method());
+            if (!is_array($param)) return error($param);
+            [$state,$videoData] = (new XcJob)->token()->getAuthorVide2Task($param['job'],$param['star'],$param['page'],$param['size']);
+            if (!$state) return error("获取数据失败");
+            $data = [];
+            foreach ($videoData['list'] as $key=>$sv)
+            {
+                [$vState,$videDetail] = (new XcJob)->token()->getVideoDetail($sv['base_info']['video_id']);
+                $data[$key] = [
+                    "job_id"        => $param['job'],
+                    "author_id"     => (string) $sv['author_info']['author_id'],
+                    "play_url"      => $vState ? $videDetail['play_url'] : '',
+                    "cover"         => $vState ? $videDetail['cover'] : '',
+                    "title"         => removeEmoji2($sv['base_info']['title']),
+                    "duration"      => $sv['base_info']['duration'],
+                    "item_id"       => (string) $sv['base_info']['item_id'],
+                    "lego_mid"      => (string) $sv['ad_info']['lego_mid'],
+                    "video_id"      => (string) $sv['base_info']['video_id'],
+                    "item_status"   => $this->status[$sv['extra_info']['item_status']],
+                    "time_agg_data_10006"   => $sv['item_real_time_agg_data']['10006']??0,
+                    "time_agg_data_10010"   => $sv['item_real_time_agg_data']['10010']??0,
+                    "time_agg_data_10014"   => $sv['item_real_time_agg_data']['10014']??0,
+                    "time_agg_data_10035"   => $sv['item_real_time_agg_data']['10035']??0,
+                    "time_agg_data_10036"   => $sv['item_real_time_agg_data']['10036']??0,
+                    "time_agg_data_10057"   => $sv['item_real_time_agg_data']['10057']??0,
+                    "time_agg_data_10056"   => $sv['item_real_time_agg_data']['10056']??0,
+                    "time_agg_data_10058"   => $sv['item_real_time_agg_data']['10058']??0,
+                    "time_agg_data_10059"   => $sv['item_real_time_agg_data']['10059']??0,
+                    "time_agg_data_10060"   => $sv['item_real_time_agg_data']['10060']??0,
+                    "time_agg_data_10061"   => $sv['item_real_time_agg_data']['10061']??0,
+                    "indicator_agg_data_20021"   => $sv['bill_indicator_agg_data']['20021']??0,
+                    "indicator_agg_data_20022"   => $sv['bill_indicator_agg_data']['20022']??0,
+                    "indicator_agg_data_20020"   => $sv['bill_indicator_agg_data']['20020']??0,
+                    "indicator_agg_data_20019"   => $sv['bill_indicator_agg_data']['20019']??0,
+                    "indicator_agg_data_20016"   => $sv['bill_indicator_agg_data']['20016']??0,
+                    "indicator_agg_data_20015"   => $sv['bill_indicator_agg_data']['20015']??0,
+                    "indicator_agg_data_20011"   => $sv['bill_indicator_agg_data']['20011']??0,
+                ];
+            }
+            return successTrans("success.data",[
+                "total"     => $videoData['total'],
+                "page"      => $videoData['page'],
+                "pageSize"  => intval($param['size']),
+                "rows"      => $data
+            ],200);
+        } catch (\Throwable $throwable) {
+            return error($throwable->getMessage());
+        }
+    }
+
+}

+ 45 - 0
app/extra/service/star/TaskVideoService.php

@@ -0,0 +1,45 @@
+<?php
+
+namespace app\extra\service\star;
+
+use app\extra\basic\Service;
+use app\model\star\StarTaskVideo;
+
+class TaskVideoService extends Service
+{
+
+
+    /**
+     * 列表
+     * @param array $param
+     */
+    public function getList(array $param = [])
+    {
+        $this->mode = new StarTaskVideo();
+        return $this->searchVal($param,$this->searchFilter($param))->with(['star' => function($query){
+            $query->field("author_id,avatar_uri,show_nick_name,follower,wechat,author_level")->append(['level','nick_name'])->withAttr(['level' => function($data,$resp){
+                return str_replace('"', '', $resp['author_level']);
+            },'nick_name' => function($data,$resp) {
+                return unicodeToEmoji($resp['show_nick_name']);
+            }]);
+        }])->paginate([
+            "list_rows" => $param['pageSize'],
+            "page"      => $param['page']
+        ]);
+    }
+
+    /**
+     *
+     * @param array $param
+     * @return array
+     */
+    public function searchFilter(array $param = []): array
+    {
+        $filter = [];
+        !empty($param['type']) && $filter[] = ["type", '=', $param['type']];
+        !empty($param['status']) && $filter[] = ["status", '=', $param['status']];
+        !empty($param['job']) && $filter[] = ["job_id", 'like', $param['job']];
+        return $filter;
+    }
+
+}

+ 160 - 4
app/extra/tools/XcJob.php

@@ -25,11 +25,125 @@ class XcJob
         return $this;
     }
 
+    /**
+     * 获取达人详情信息
+     * @param string $uid
+     * @return array
+     */
+    public function getStarDetail(string $uid = ""): array
+    {
+        $param = [
+            "o_author_id"   => $uid,
+            "platform_source"   => 1,
+            "platform_channel"  => 1,
+            "recommend" => true,
+            "need_sec_uid"  => true,
+            "need_linkage_info" => true
+        ];
+        $resp = Http::withHeaders($this->header)->asJson()->get("https://www.xingtu.cn/gw/api/author/get_author_base_info",$param)->array();
+        if (empty($resp['sec_uid'])) return [0,'获取数据失败'];
+        return [1,$resp];
+    }
+
+    /**
+     * 获取达人信息
+     * {"scene_param":{"platform_source":1,"search_scene":1,"display_scene":1,"marketing_target":1,"task_category":1,"first_industry_id":0,"task_status":3},"search_param":{"keyword":"11_0306","seach_type":2,"is_new_nickname_query":true},"sort_param":{"sort_type":2,"sort_field":{"field_name":"score"}},"page_param":{"page":1,"limit":20},"attribute_filter":[{"field":{"field_name":"price_by_video_type__ge","rel_id":"2"},"field_value":"0"}]}
+     * @param string $uid
+     * @return array
+     */
+    public function getStarData(string $uid = ""): array
+    {
+        $param = [
+            "scene_param"   => [
+                "platform_source" => 1,
+                "search_scene" => 1,
+                "display_scene" => 1,
+                "marketing_target" => 1,
+                "task_category" => 1,
+                "first_industry_id" => 0,
+                "task_status" => 3
+            ],
+            "search_param"  => [
+                "keyword"   => $uid,
+                "seach_type" => 2,
+                "is_new_nickname_query" => true
+            ],
+            "sort_param"    => [
+                "sort_type" => 2,
+                "sort_field" => [
+                    "field_name" => "score"
+                ]
+            ],
+            "page_param"    => [
+                "page" => 1,
+                "limit" => 20
+            ]
+        ];
+        $resp = Http::withHeaders($this->header)->asJson()->post("https://www.xingtu.cn/gw/api/gsearch/search_for_author_square",$param)->array();
+        if ($resp['base_resp']['status_code'] <> 0) return [0,'获取数据失败'];
+        return [1,['total' => $resp['pagination']['total_count'],'has_more' => $resp['pagination']['has_more'],'list' => $resp['authors']]];
+    }
+
+    /**
+     * 获取星川任务列表
+     * @param int $page
+     * @param int $size
+     * @return array
+     */
+    public function getTaskList(int $page = 1,int $size = 10): array
+    {
+        // {"query":{"task_category_list":[137],"order_status":[],"qc_metrics_time_range_param":{"start_time":"1767628800000","end_time":"1783353599000"}},"page":1,"limit":10}
+        $param = [
+            "query" => [
+                "task_category_list" => [137],
+                "order_status"       => [],
+                "qc_metrics_time_range_param"   => [
+                    "start_time"    => strtotime(date("Y-m-d 00:00:00",strtotime("-180 day"))) * 1000,
+                    "end_time"      => strtotime(date("Y-m-d 23:59:59")) * 1000,
+                ]
+            ],
+            "page"  => $page,
+            "limit" => $size
+        ];
+        $resp = Http::withHeaders($this->header)->asJson()->post("https://www.xingtu.cn/gw/api/task/provider_get_task_order_list",$param)->array();
+        if ($resp['base_resp']['status_code'] <> 0) return [0,'获取数据失败'];
+        return [1,['total' => $resp['pagination']['total_count'],'has_more' => $resp['pagination']['has_more'],'page' => $resp['pagination']['page'],'list' => $resp['provider_task_order_list']]];
+    }
+
+    /**
+     * 投稿达人
+     * @param string $jobId
+     * @param int $page
+     * @param int $size
+     * @return array
+     */
+    public function getTaskAuthor(string $jobId = "",int $page = 1,int $size = 10): array
+    {
+        // {"task_id":"7650432488166899755","qc_metrics_time_range_param":{"start_time":"1767628800000","end_time":"1783353599000"},"page":2,"limit":10,"scene":1}
+        $param = [
+            "task_id"       => $jobId,
+            "qc_metrics_time_range_param"   => [
+                "start_time"    => strtotime(date("Y-m-d 00:00:00",strtotime("-180 day"))) * 1000,
+                "end_time"      => strtotime(date("Y-m-d 23:59:59")) * 1000,
+            ],
+            "page"  => $page,
+            "limit" => $size,
+            "scene" => 1
+        ];
+        $resp = Http::withHeaders($this->header)->post("https://www.xingtu.cn/gw/api/task/provider_get_task_author_performance_list",$param)->array();
+        if ($resp['base_resp']['status_code'] <> 0) return [0,'获取数据失败'];
+        if ($resp['pagination']['total_count'] == 0) return [0,'没有数据'];
+        return [1,['total' => $resp['pagination']['total_count'],'has_more' => $resp['pagination']['has_more'],'page' => $resp['pagination']['page'],'list' => $resp['author_list']]];
+    }
+
     /**
      * 获取达人投稿视频消耗数据
      * https://www.xingtu.cn/gw/api/task/provider_get_star_task_item_list
      * POST
      * {"page":1,"limit":10,"query":{"provider_confirmed":false,"task_search_key":"7628487095040311348","qc_metrics_time_range_param":{"start_time":"1762963200000","end_time":"1778687999000"}}}
+     * @param string $jobId
+     * @param int $page
+     * @param int $size
      * @return array
      */
     public function getAuthorVideo(string $jobId = "",int $page = 1,int $size = 10): array
@@ -46,9 +160,51 @@ class XcJob
                 ]
             ]
         ];
-        $resp = Http::withHeaders($this->header)->post("https://www.xingtu.cn/gw/api/task/provider_get_star_task_item_list",$param)->array();
+        $resp = Http::withHeaders($this->header)->asJson()->post("https://www.xingtu.cn/gw/api/task/provider_get_star_task_item_list",$param)->array();
+        if ($resp['base_resp']['status_code'] <> 0) return [0,'获取数据失败'];
+        return [1,['total' => $resp['pagination']['total_count'],'has_more' => $resp['pagination']['has_more'],'page' => $resp['pagination']['page'],'list' => $resp['item_list']]];
+    }
+
+    /**
+     * 获取单个任务中指定达人的投稿视频
+     * @param string $jobId
+     * @param int $page
+     * @param int $size
+     * @return array
+     */
+    public function getAuthorVide2Task(string $jobId = "",string $starId = "",int $page = 1,int $size = 10): array
+    {
+        $param = [
+            "page"  => $page,
+            "limit" => $size,
+            "query" => [
+                "provider_confirmed"    => false,
+                "task_search_key"       => $jobId,
+                "author_search_key"     => $starId,
+                "qc_metrics_time_range_param"   => [
+                    "start_time"    => strtotime(date("Y-m-d 00:00:00",strtotime("-180 day"))) * 1000,
+                    "end_time"      => strtotime(date("Y-m-d 23:59:59")) * 1000,
+                ]
+            ]
+        ];
+        $resp = Http::withHeaders($this->header)->asJson()->post("https://www.xingtu.cn/gw/api/task/provider_get_star_task_item_list",$param)->array();
+        if ($resp['base_resp']['status_code'] <> 0) return [0,'获取数据失败'];
+        return [1,['total' => $resp['pagination']['total_count'],'has_more' => $resp['pagination']['has_more'],'page' => $resp['pagination']['page'],'list' => $resp['item_list']]];
+    }
+
+    /**
+     * 获取视频播放链接
+     * @param string $videoId
+     * @return array
+     */
+    public function getVideoDetail(string $videoId = ""): array
+    {
+        $param = [
+            "video_id" => $videoId
+        ];
+        $resp = Http::withHeaders($this->header)->get("https://www.xingtu.cn/gw/api/ggeneric/get_video_info",$param)->array();
         if ($resp['base_resp']['status_code'] <> 0) return [0,'获取数据失败'];
-        return [1,['total' => $resp['pagination']['total_count'],'has_more' => $resp['pagination']['has_more'],'list' => $resp['item_list']]];
+        return [1,['cover' => $resp['cover'],'duration' => $resp['duration'],'play_url' => $resp['play_url'],'width' => $resp['width'],'height' => $resp['width']]];
     }
 
     /**
@@ -69,7 +225,7 @@ class XcJob
             "event_id"      => $jobId,
             "share_type"    => 4
         ];
-        $resp = Http::withHeaders($this->header)->post("https://www.xingtu.cn/gw/api/fe_common_service/share/info",$param)->array();
+        $resp = Http::withHeaders($this->header)->asJson()->post("https://www.xingtu.cn/gw/api/fe_common_service/share/info",$param)->array();
         if ($resp['base_resp']['status_code'] <> 0) return [0,'生成失败'];
         return [1,"https://www.xingtu.cn/share/{$resp['share_id']}?hide_nav_bar=1&hide_status_bar=1&should_full_screen=1&utm_source=share_4&session_track_id={$resp['share_id']}"];
     }
@@ -87,6 +243,6 @@ class XcJob
 
     protected function getCookie(): string
     {
-        return "passport_csrf_token=dc2c5075e29c15785b2433afb8d9dd10; passport_csrf_token_default=dc2c5075e29c15785b2433afb8d9dd10; is_staff_user=false; has_biz_token=false; x-web-secsdk-uid=f676fb7e-81a3-42e2-b9e1-73c0ea919aea; csrf_session_id=5499e75e3f1f76a628c1efa81b7c89b3; tt_webid=7637860647254296090; Hm_lvt_5d77c979053345c4bd8db63329f818ec=1778328034; HMACCOUNT=DE9169EBCCD81810; passport_auth_status=93b289d15b8bb4866b32877a48a3b4b6%2C3a1cc997a270fa7b4f4fb3c3a79939fd; passport_auth_status_ss=93b289d15b8bb4866b32877a48a3b4b6%2C3a1cc997a270fa7b4f4fb3c3a79939fd; uid_tt=b918d45f40210fd4799129be8d1e7ae1; uid_tt_ss=b918d45f40210fd4799129be8d1e7ae1; sid_tt=2cf53e24db19ce7e1d9094d82a7e0a15; sessionid=2cf53e24db19ce7e1d9094d82a7e0a15; sessionid_ss=2cf53e24db19ce7e1d9094d82a7e0a15; Hm_lpvt_5d77c979053345c4bd8db63329f818ec=1778501158; sid_guard=2cf53e24db19ce7e1d9094d82a7e0a15%7C1778501177%7C5184000%7CFri%2C+10-Jul-2026+12%3A06%3A17+GMT; session_tlb_tag=sttt%7C14%7CLPU-JNsZzn4dkJTYKn4KFf_________UDv5aLsuhDiFj6DTslfpmqljmlqIjrEWo6QWJ6REal5U%3D; sid_ucp_v1=1.0.0-KDMyOTUxMzAzNDFkZjFjMzBmYzYyNWJjNGU3YTFiYTcwODYyOGJjZjAKFwiUv5Cvv8yyBxC5jIfQBhj6EzgCQPEHGgJscSIgMmNmNTNlMjRkYjE5Y2U3ZTFkOTA5NGQ4MmE3ZTBhMTU; ssid_ucp_v1=1.0.0-KDMyOTUxMzAzNDFkZjFjMzBmYzYyNWJjNGU3YTFiYTcwODYyOGJjZjAKFwiUv5Cvv8yyBxC5jIfQBhj6EzgCQPEHGgJscSIgMmNmNTNlMjRkYjE5Y2U3ZTFkOTA5NGQ4MmE3ZTBhMTU; star_sessionid=485fed1891a1b504a23ee3ce76ccd568";
+        return "csrftoken=DiDhfVo0pz9HnEsJ3zGKA39ixm9AxA8t; tt_webid=7637854168573183526; passport_csrf_token=9510b4581fea0015ec5e3293fefb6194; passport_csrf_token_default=9510b4581fea0015ec5e3293fefb6194; is_staff_user=false; has_biz_token=false; s_v_web_id=verify_mqhwxxgj_rimh5qRs_m3VS_4oAv_8yXX_EMfuKVBYkpVW; passport_auth_status=39cd9f76ea3c8ac5c9beab7dfee4825f%2C56147e39ce55d737468b0c00fe003bc2; passport_auth_status_ss=39cd9f76ea3c8ac5c9beab7dfee4825f%2C56147e39ce55d737468b0c00fe003bc2; uid_tt=32a10b0de605d5e5e09080d5531eb77e; uid_tt_ss=32a10b0de605d5e5e09080d5531eb77e; sid_tt=528106ce020f1db0e4ca4ff7895135ef; sessionid=528106ce020f1db0e4ca4ff7895135ef; sessionid_ss=528106ce020f1db0e4ca4ff7895135ef; Hm_lvt_5d77c979053345c4bd8db63329f818ec=1781690725,1782806402; HMACCOUNT=7B24288D273CC431; csrf_session_id=7b04abc1fd6e463b4e7e191681f733da; Hm_lpvt_5d77c979053345c4bd8db63329f818ec=1783489162; sid_guard=528106ce020f1db0e4ca4ff7895135ef%7C1783489186%7C5184000%7CSun%2C+06-Sep-2026+05%3A39%3A46+GMT; session_tlb_tag=sttt%7C16%7CUoEGzgIPHbDkyk_3iVE17_________-2m7Gf0ljknGiOP6NwunArIr0uRP8Cc8jMGlCcp1XhGac%3D; sid_ucp_v1=1.0.0-KDFkMTdlODNhYTQ5NTZkMTg4YWYzZWE0OTA2OTQzOTFiMzc0MjNjNGMKFwiUv5Cvv8yyBxCixbfSBhimDDgCQPEHGgJsZiIgNTI4MTA2Y2UwMjBmMWRiMGU0Y2E0ZmY3ODk1MTM1ZWY; ssid_ucp_v1=1.0.0-KDFkMTdlODNhYTQ5NTZkMTg4YWYzZWE0OTA2OTQzOTFiMzc0MjNjNGMKFwiUv5Cvv8yyBxCixbfSBhimDDgCQPEHGgJsZiIgNTI4MTA2Y2UwMjBmMWRiMGU0Y2E0ZmY3ODk1MTM1ZWY; star_sessionid=85b9f01f4fb6e21eaaeadeb62d7b4b6c";
     }
 }

+ 49 - 0
app/functions.php

@@ -681,4 +681,53 @@ if (!function_exists("strip_img_attributes"))
         // 一次性替换掉所有 img 里的目标属性
         return preg_replace($pattern, '', $html);
     }
+}
+
+
+if(! function_exists('emojiToUnicode'))
+{
+    /**
+     * @param string $str
+     * @return string
+     */
+    function emojiToUnicode(string $str): string
+    {
+        return trim(json_encode($str, JSON_UNESCAPED_SLASHES), '"');
+    }
+}
+
+if(! function_exists('unicodeToEmoji'))
+{
+    function unicodeToEmoji(string $str): string
+    {
+        return json_decode("\"{$str}\"");
+    }
+}
+
+if(! function_exists('removeEmoji2'))
+{
+    /**
+     * 清除字符串中所有emoji表情
+     * @param string $str
+     * @return string
+     */
+    function removeEmoji2(string $str): string
+    {
+        // 1. 匹配所有emoji Unicode区间
+        $emoji = '/[\x{1F600}-\x{1F64F}\x{1F300}-\x{1F5FF}\x{1F680}-\x{1F6FF}\x{1F1E0}-\x{1F1FF}\x{2600}-\x{26FF}\x{2700}-\x{27BF}\x{FE00}-\x{FE0F}\x{1F900}-\x{1F9FF}\x{1F018}-\x{1F0FF}\x{2300}-\x{23FF}]/u';
+        $str = preg_replace($emoji, '', $str);
+
+        // 2. 过滤颜文字、日文符号、装饰特殊符号、全角特殊符号
+        $face_sym = '/[\x{3000}-\x{303F}\x{3040}-\x{30FF}\x{31F0}-\x{31FF}\x{2460}-\x{24FF}\x{2100}-\x{214F}\x{2190}-\x{21FF}\x{2500}-\x{257F}\x{25A0}-\x{25FF}\x{2900}-\x{297F}\x{2B00}-\x{2BFF}\x{4DC0}-\x{4DFF}\x{1F000}-\x{1F02F}\x{00A0}-\x{00AF}\x{02B0}-\x{02FF}]/u';
+        $str = preg_replace($face_sym, '', $str);
+
+        // 3. 只允许保留:中文、大小写字母、数字、逗号句号顿号冒号分号问号感叹号空格
+        // 不想保留空格就删掉 \s
+        $allow = '/[^\x{4E00}-\x{9FA5}a-zA-Z0-9\s\,\.、\:;\?\!]/u';
+        $str = preg_replace($allow, '', $str);
+
+        // 去除多余连续空格
+        $str = preg_replace('/\s+/', ' ', $str);
+        return trim($str);
+    }
 }

+ 70 - 0
app/model/blue/BlueTaskRevenue.php

@@ -0,0 +1,70 @@
+<?php
+
+namespace app\model\blue;
+
+use app\extra\basic\Model;
+
+
+/**
+ * @property integer $id (主键)
+ * @property mixed $openid 
+ * @property string $avatar_uri 
+ * @property string $nick_name 
+ * @property mixed $job_id 
+ * @property mixed $author_id 
+ * @property string $duration 视频秒数
+ * @property integer $item_id 视频ID
+ * @property string $title 视频标题
+ * @property integer $time_agg_data_10006 整体消耗
+ * @property integer $time_agg_data_10010 视频播放数
+ * @property integer $time_agg_data_10014 视频完播率
+ * @property integer $time_agg_data_10035 整体消耗-推商品
+ * @property integer $time_agg_data_10036 整体消费-推直播
+ * @property integer $time_agg_data_10057 服务商预估总收益-推商品
+ * @property integer $time_agg_data_10056 服务商预估总收益-推商品
+ * @property integer $time_agg_data_10058 服务商预估总收益
+ * @property integer $time_agg_data_10059 达人预估投放分成收益-推直播
+ * @property integer $time_agg_data_10060 达人预估投放分成收益
+ * @property integer $time_agg_data_10061 达人预估投放分成收益-推商品
+ * @property integer $indicator_agg_data_20021 达人预估收益
+ * @property integer $indicator_agg_data_20022 达人已结算收益
+ * @property integer $indicator_agg_data_20020 达人已结算投放分成收益-推直播
+ * @property integer $indicator_agg_data_20019 达人已结算投放分成收益-推商品
+ * @property integer $indicator_agg_data_20016 服务商已结算收益-推直播
+ * @property integer $indicator_agg_data_20015 服务商已结算收益-推商品
+ * @property integer $indicator_agg_data_20011 服务商已结算收益
+ * @property mixed $day 
+ * @property mixed $month
+ */
+class BlueTaskRevenue 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 = "blue_task_revenue";
+    
+    /**
+     * 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;
+
+
+}

+ 55 - 0
app/model/bluev/BluevOceanAccount.php

@@ -0,0 +1,55 @@
+<?php
+
+namespace app\model\bluev;
+
+use app\extra\basic\Model;
+
+
+/**
+ * @property integer $id (主键)
+ * @property mixed $day 
+ * @property integer $advertiser_id 
+ * @property string $advertiser_name 
+ * @property integer $company_id 
+ * @property string $company_name 
+ * @property string $registerTime 
+ * @property string $platform 
+ * @property integer $noGrantCost 累计消耗
+ * @property mixed $create_at 创建时间
+ */
+class BluevOceanAccount 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 = "bluev_ocean_account";
+    
+    /**
+     * 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;
+
+    public function getNoGrantCostAttr($data): string
+    {
+        return format_money($data/100000);
+    }
+
+}

+ 53 - 0
app/model/star/StarTask.php

@@ -0,0 +1,53 @@
+<?php
+
+namespace app\model\star;
+
+use app\extra\basic\Model;
+
+
+/**
+ * @property integer $id (主键)
+ * @property mixed $job_id 
+ * @property mixed $project_id 
+ * @property string $project_name 
+ * @property string $shop_name 
+ * @property string $product_name 
+ * @property string $cover 
+ * @property string $detail_url 
+ * @property mixed $product_id 
+ * @property integer $expiration_time 发布时间
+ * @property integer $expiration_time_end 投稿截止时间
+ * @property mixed $create_at 创建时间
+ */
+class StarTask 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 = "star_task";
+    
+    /**
+     * 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;
+
+
+}

+ 43 - 0
app/model/star/StarTaskUser.php

@@ -0,0 +1,43 @@
+<?php
+
+namespace app\model\star;
+
+use app\extra\basic\Model;
+
+
+/**
+ * @property integer $id (主键)
+ * @property mixed $job_id
+ */
+class StarTaskUser 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 = "star_task_user";
+    
+    /**
+     * 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;
+
+
+}

+ 48 - 0
app/model/star/StarTaskVideo.php

@@ -0,0 +1,48 @@
+<?php
+
+namespace app\model\star;
+
+use app\extra\basic\Model;
+use think\model\relation\HasOne;
+
+
+/**
+ * @property integer $id (主键)
+ * @property mixed $job_id
+ */
+class StarTaskVideo 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 = "star_task_video";
+    
+    /**
+     * 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;
+
+    public function star(): HasOne
+    {
+        return $this->hasOne(StarTaskUser::class,"author_id","author_id");
+    }
+
+}

+ 99 - 0
app/queue/redis/StarAuthor.php

@@ -0,0 +1,99 @@
+<?php
+
+namespace app\queue\redis;
+
+use app\extra\tools\XcJob;
+use app\model\star\StarTask;
+use app\model\star\StarTaskUser;
+use Webman\RedisQueue\Consumer;
+
+/**
+ * 同步星川任务达人投稿视频
+ */
+class StarAuthor implements Consumer
+{
+
+
+    public string $queue = "star-author";
+
+    public string $connection = "default";
+
+    public function consume($data): bool
+    {
+        try {
+            $nextPage = 1;$done = 0;$subPage = 1;
+            while (is_numeric($nextPage)) {
+                $starPage = ($nextPage-1) * 10;
+                $resp = (new StarTask)->limit($starPage,10)->select()->toArray();
+                if (empty($resp)) {
+                    echo "==没有任务啦==".getDateFull()."\n";
+                    $nextPage = null;
+                    return true;
+                }
+                while (is_numeric($subPage))
+                {
+                    $taskUser = (new StarTaskUser);
+                    foreach ($resp as $key=>$val) {
+                        [$state,$taskResp] = (new XcJob)->token()->getTaskAuthor($val['job_id'],$subPage);
+                        if (!$state) {
+                            echo "任务ID:{$val['job_id']}==没有投稿任务啦==".getDateFull()."\n";
+                            $subPage = null;
+                            continue;
+                        }
+                        foreach ($taskResp as $sk=>$sv) {
+                            $userData = $taskUser->where(['job_id' => $val['job_id']])->findOrEmpty();
+                            if ($userData->isEmpty()) {
+                                $userData->insertGetId([
+                                    "job_id"            => $val['job_id'],
+                                    'nick_name'         => removeEmoji2($sv['author_base_info']['nick_name']),
+                                    'show_nick_name'    => emojiToUnicode($sv['author_base_info']['nick_name']),
+                                    "avatar_uri"        => $sv['author_base_info']['avatar_uri'],
+                                    "author_id"         => $sv['author_base_info']['author_id'],
+                                    "sample_address_str"    => $sv['author_base_info']['sample_address_str'],
+                                    "follower"    => $sv['author_base_info']['follower'],
+                                    "gender"    => $sv['author_base_info']['gender'],
+                                    "sec_uid"    => $sv['author_base_info']['sec_uid'],
+                                    "wechat"    => $sv['author_base_info']['wechat']??'',
+                                    "author_level"    => $sv['author_base_info']['ecom_author_level']??'L0',
+                                    "author_order_status"    => $sv['author_order_info']['author_order_status'],
+                                    "invitation_status"    => $sv['author_invitaion_info']['invitation_status'],
+                                    "metric_data_num"    => $sv['author_select_metric_data']['offline_metric_data']['6001']??0,
+                                    "metric_data_rate"    => $sv['author_select_metric_data']['offline_metric_data']['6002']??0,
+                                    "release_item_count"    => $sv['author_order_info']['release_item_count'],
+                                    "visible_item_count"    => $sv['author_order_info']['visible_item_count'],
+                                ]);
+                                echo "任务ID{$val['job_id']},星图ID{$sv['author_base_info']['author_id']}===入库成功!~==>".getDateFull()."\n";
+                            } else {
+                                $userData->save([
+                                    'nick_name'         => removeEmoji2($sv['author_base_info']['nick_name']),
+                                    'show_nick_name'    => emojiToUnicode($sv['author_base_info']['nick_name']),
+                                    "avatar_uri"        => $sv['author_base_info']['avatar_uri'],
+                                    "follower"    => $sv['author_base_info']['follower'],
+                                    "gender"    => $sv['author_base_info']['gender'],
+                                    "wechat"    => $sv['author_base_info']['wechat']??'',
+                                    "author_level"    => $sv['author_base_info']['ecom_author_level']??'L0',
+                                    "author_order_status"    => $sv['author_order_info']['author_order_status'],
+                                    "invitation_status"    => $sv['author_invitaion_info']['invitation_status'],
+                                    "metric_data_num"    => $sv['author_select_metric_data']['offline_metric_data']['6001']??0,
+                                    "metric_data_rate"    => $sv['author_select_metric_data']['offline_metric_data']['6002']??0,
+                                    "release_item_count"    => $sv['author_order_info']['release_item_count'],
+                                    "visible_item_count"    => $sv['author_order_info']['visible_item_count'],
+                                ]);
+                                echo "任务ID{$val['job_id']},星图ID{$sv['author_base_info']['author_id']}===更新一下!~==>".getDateFull()."\n";
+                            }
+                        }
+                    }
+                    $subPage = $subPage+1;
+                    echo "===当前页码{$nextPage}--{$subPage}==>".getDateFull()."\n";
+                }
+                $nextPage = $nextPage+1;
+            }
+        } catch (\Throwable $throwable) {
+            echo getDateFull()."==报错啦===".$throwable->getFile()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getLine()."\n";
+            echo getDateFull()."==报错啦===".$throwable->getMessage()."\n";
+        }
+        return true;
+    }
+
+}

+ 23 - 0
app/queue/redis/StarVideo.php

@@ -0,0 +1,23 @@
+<?php
+
+namespace app\queue\redis;
+
+use Webman\RedisQueue\Consumer;
+
+
+/**
+ * 同步星川任务达人投稿视频
+ */
+class StarVideo implements Consumer
+{
+
+    public string $queue = "star-video";
+
+    public string $connection = "default";
+
+    public function consume($data): bool
+    {
+
+        return true;
+    }
+}

+ 2 - 1
composer.json

@@ -55,7 +55,8 @@
     "hzdad/codecheck": "^1.0",
     "php-di/php-di": "7.0",
     "zoujingli/wechat-developer": "^1.2",
-    "webman/push": "^1.1"
+    "webman/push": "^1.1",
+    "huaweicloud/huaweicloud-sdk-php": "3.1.191"
   },
   "suggest": {
     "ext-event": "For better performance. "

BIN
xg-api.zip


Some files were not shown because too many files changed in this diff