作者 赵彬吉
... ... @@ -350,16 +350,26 @@ class GeoQuestionRes extends Command
$lock_key = 'geo_task_generation_lock';
$lock_ttl = 60; // 锁时间大于当前 锁功能执行时间
// 尝试获取锁,非阻塞方式
$lock = Redis::set($lock_key, 1, 'EX', $lock_ttl, 'NX');
if (empty($lock)){
// $lock = Redis::set($lock_key, 1, 'EX', $lock_ttl, 'NX');
$lock = Redis::get($lock_key);
if ($lock)
return $task_id;
}
$project_ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)->where('next_time', '<=', date('Y-m-d'))->pluck('project_id')->unique()->values()->toArray();
Redis::setex($lock_key, $lock_ttl, 1);
$project_ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)
->where(function ($query){
$query->where('next_time', '<=', date('Y-m-d'))
->orWhereNull('next_time');
})
->pluck('project_id')
->unique()
->values()
->toArray();
if(FALSE == empty($project_ids)){
$ids = GeoQuestion::where('status', GeoQuestion::STATUS_OPEN)
->whereIn('project_id', $project_ids)
->where(function ($query){
$query->where('next_time', '<=', date('Y-m-d'))
$query->where('current_time', '<>', date('Y-m-d'))
->orWhereNull('next_time');
})
->orderBy('next_time', 'asc')
... ...
... ... @@ -58,9 +58,31 @@ class lyhDemo extends Command
protected $description = '更新路由';
public function handle(){
return $this->_actionRoute();
return $this->_actionAiBolog();
}
/**
* @remark :修改ai_blog
* @name :_actionAiBolog
* @author :lyh
* @method :post
* @time :2025/11/21 13:52
*/
public function _actionAiBolog()
{
$projectModel = new Project();
$lists = $projectModel->list(['delete_status' => 0,'id'=>1,'project_type'=>0,'extend_type'=>0,'type'=>['in',[1,2,3,4,6]]], 'id', ['id']);
foreach ($lists as $item) {
echo date('Y-m-d H:i:s') . '开始--项目的id:' . $item['id'] . PHP_EOL;
ProjectServer::useProject($item['id']);
$aiblog = new AiBlog();
$task_ids = $aiblog->selectField(['image'=>''],'id');
dd($task_ids);
DB::disconnect('custom_mysql');
}
}
public function _actionDa()
{
$geoLinkModel = new GeoLink();
... ...
... ... @@ -1642,5 +1642,16 @@ if (!function_exists('httpGetSsl')) {
return $truncated;
}
/**
* @remark :写入日志
* @name :outMessage
* @author :lyh
* @method :post
* @time :2025/11/20 16:04
*/
function outMessage($filename = 'lyh_info',$message = '')
{
@file_put_contents(storage_path('logs/'.$filename.'.log'), "错误信息: " . $message . PHP_EOL, FILE_APPEND);
return true;
}
}
... ...
<?php
/**
* @remark :
* @name :ComController.php
* @author :lyh
* @method :post
* @time :2025/11/19 15:50
*/
namespace App\Http\Controllers\Api;
use App\Enums\Common\Code;
use App\Models\Geo\GeoLink;
class ComController extends BaseController
{
/**
* @remark :获取geo链接
* @name :getGeoLink
* @author :lyh
* @method :post
* @time :2025/11/19 15:51
*/
public function getGeoLink()
{
$this->request->validate([
'project_id' => 'required',
], [
'project_id.required' => 'project_id不能为空',
]);
$geoLinkModel = new GeoLink();
$filed = ['id','project_id','url','da','type','created_at','updated_at'];
$lists = $geoLinkModel->lists($this->map,$this->page,$this->row,$filed);
$this->response('success',Code::SUCCESS,$lists);
}
}
... ...
... ... @@ -8,9 +8,12 @@
namespace App\Http\Controllers\Api;
use App\Enums\Common\Code;
use App\Models\Geo\GeoConf;
use App\Models\Geo\GeoConfirm;
use App\Models\Geo\GeoWritings;
use App\Models\Manage\ManageHr;
use App\Models\Project\Project;
use App\Services\DingService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
... ... @@ -89,11 +92,28 @@ class GeoController extends BaseController
if ($info['status'] == GeoWritings::STATUS_FINISH){
return $this->response('当前文章已确认,不可再次确认',Code::SYSTEM_ERROR);
}
try {
$this->param['confirm_ip'] = $this->request->ip();
$this->param['confirm_at'] = date('Y-m-d H:i:s');
$this->param['content_length'] = strlen($this->param['content']);
$this->param['status'] = GeoWritings::STATUS_FINISH;
$geoWritingsModel->edit($this->param,['uniqid' => $token]);
$geoConfModel = new GeoConf();
$confInfo = $geoConfModel->read(['project_id'=>$info['project_id']]);
$hrModel = new ManageHr();
$manage_name = $hrModel->getName($confInfo['manager_id'] ??'');
$dingService = new DingService();
$dingService->handle([
'keyword' => '项目数据确认',
'msg' =>
'cm:文章确认完成' . PHP_EOL .
'项目名称:'.($confInfo['company'] ?? '') . PHP_EOL .
'负责人:'.$manage_name . PHP_EOL,
'isAtAll' => false, // 是否@所有人
], 'https://oapi.dingtalk.com/robot/send?access_token=4effe85882009a8a1617dbeadc38c350f832deef7431ce10f5fda751b4c82fb9');
}catch (\Exception $e){
$this->response('非法请求',Code::SYSTEM_ERROR);
}
$this->response('success',Code::SUCCESS);
}
... ... @@ -138,10 +158,31 @@ class GeoController extends BaseController
'confirm_num.max' => '客户确认数量不能为空',
]);
$geoConfirmModel = new GeoConfirm();
$info = $geoConfirmModel->read(['uniqid'=>$this->param['uniqid']]);
if ($info === false){
$this->response('当前数据不存在已被删除',Code::SYSTEM_ERROR);
}
try {
$this->param['status'] = $geoConfirmModel::STATUS_FINISH;
$this->param['confirm_ip'] = $this->request->ip();
$this->param['confirm_at'] = date('Y-m-d H:i:s');
$result = $geoConfirmModel->edit($this->param,['uniqid'=>$this->param['uniqid']]);
$result = $geoConfirmModel->edit($this->param,['id'=>$info['$info']]);
$geoConfModel = new GeoConf();
$confInfo = $geoConfModel->read(['project_id'=>$info['project_id']]);
$hrModel = new ManageHr();
$manage_name = $hrModel->getName($confInfo['manager_id'] ??'');
$dingService = new DingService();
$dingService->handle([
'keyword' => '项目数据确认',
'msg' =>
'cm:'.(($info['type'] == 1) ? '标题确认' : '关键词确认'). PHP_EOL .
'项目名称:'.($confInfo['company'] ?? '') . PHP_EOL .
'负责人:'.$manage_name . PHP_EOL,
'isAtAll' => false, // 是否@所有人
], 'https://oapi.dingtalk.com/robot/send?access_token=4effe85882009a8a1617dbeadc38c350f832deef7431ce10f5fda751b4c82fb9');
}catch (\Exception $e){
$this->response('非法请求',Code::SYSTEM_ERROR);
}
$this->response('success',Code::SUCCESS,$result);
}
}
... ...
... ... @@ -48,7 +48,7 @@ class PrivateController extends BaseController
public function optimizeProjectList(Request $request)
{
$page_size = $request->input('page_size', 20);
$field = ['gl_project.id', 'gl_project.company', 'gl_project.is_upgrade', 'b.start_date', 'd.domain', 'b.special', 'gl_project.from_order_id'];// 'f.industry_name',
$field = ['gl_project.id', 'gl_project.company', 'gl_project.post_id' ,'gl_project.is_upgrade', 'b.start_date', 'd.domain', 'b.special', 'gl_project.from_order_id'];// 'f.industry_name',
$result = Project::select($field)->leftJoin('gl_project_deploy_optimize as b', 'gl_project.id', '=', 'b.project_id')
->leftJoin('gl_project_online_check as c', 'gl_project.id', '=', 'c.project_id')
->leftJoin('gl_domain_info as d', 'gl_project.id', '=', 'd.project_id')
... ...
<?php
namespace App\Http\Controllers\Aside\AiRemove;
use App\Enums\Common\Code;
use App\Http\Controllers\Aside\BaseController;
use App\Jobs\WordAi;
use App\Models\AiRemove\AiRemove;
use App\Models\Manage\Manage;
class AiRemoveController extends BaseController
{
/**
* 获取去AI痕迹任务列表
* @author Akun
* @date 2025/11/20 11:35
*/
public function getTaskLists()
{
$model = new AiRemove();
$lists = $model->lists($this->map, $this->page, $this->row, 'id', ['id', 'user_id', 'status', 'created_at', 'updated_at']);
if (!empty($lists)) {
$manage_model = new Manage();
foreach ($lists['list'] as $k => $v) {
$lists['list'][$k]['operator_name'] = $manage_model->getName($v['user_id']);
}
}
$this->response('success', Code::SUCCESS, $lists);
}
/**
* 获取去AI任务详情
* @author Akun
* @date 2025/11/20 11:47
*/
public function taskInfo()
{
$this->request->validate([
'id' => 'required'
], [
'id.required' => 'ID不能为空'
]);
$model = new AiRemove();
$info = $model->read(['id' => $this->param['id']]);
$this->response('success', Code::SUCCESS, $info);
}
/**
* 提交去AI痕迹任务
* @throws \App\Exceptions\AsideGlobalException
* @author Akun
* @date 2025/11/20 11:41
*/
public function saveTask()
{
$this->request->validate([
'origin_text' => 'required',
], [
'origin_text.required' => '需要去痕迹的内容不能为空'
]);
$data = [
'user_id' => $this->uid,
'origin_text' => $this->param['origin_text'],
'status' => ['<', AiRemove::STATUS_FAL]
];
$model = new AiRemove();
$task_info = $model->read($data);
if ($task_info) {
$this->fail('已提交过相同任务,请勿重复提交');
}
$data['status'] = AiRemove::STATUS_UN;
$id = $model->addReturnId($data);
WordAi::dispatch(['id' => $id]);
$this->response('success');
}
}
... ...
... ... @@ -13,8 +13,10 @@ use App\Models\Manage\Manage;
use App\Models\User\User;
use App\Models\WebSetting\WebLanguage;
use App\Services\HumanizeAiTextService;
use App\Services\WordAiService;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Http;
/**
* Class IndexController
... ... @@ -190,6 +192,25 @@ class IndexController extends BaseController
}
/**
* @remark :去Ai痕迹
* @name :notWordAi
* @author :lyh
* @method :post
* @time :2025/11/19 17:57
*/
public function notWordAiHumanizer()
{
$this->request->validate([
'text'=>'required',
],[
'text.required' => '文本text不能为空',
]);
$wordAiService = new WordAiService();
$data = $wordAiService->setApiAvoid($this->param['text']);
$this->response('success', Code::SUCCESS, $data);
}
/**
* @remark :翻译
* @name :stringTranslation
* @author :lyh
... ... @@ -210,7 +231,23 @@ class IndexController extends BaseController
*/
public function prInfoDownload()
{
$url = 'http://crawl.scraper.waimaoq.com/export/issuewire?token=MT0CM7y4tdFTFTm';
$this->response('success', Code::SUCCESS, ['url'=>$url]);
$url = 'http://crawl.scraper.waimaoq.com/export/issuewire';
$param = [
'page' => $this->page,
'page_size' => $this->row,
'token' => 'MT0CM7y4tdFTFTm',
'pr_id' => $this->param['pr_id'] ?? '',
'release_time_start'=>$this->param['release_time_start'] ?? '',
'release_time_end'=>$this->param['release_time_end'] ?? '',
'headline'=>$this->param['headline'] ?? '',
];
$param = array_filter($param);
$response = Http::withHeaders(['Accept' => 'application/json',])->get($url, $param);
if ($response->successful()) {
$result = $response->json();
$this->response('success', Code::SUCCESS, ['url' => $url, 'list' => $result, 'page' => $this->page, 'page_size' => $this->row]);
} else {
$this->response('请求失败', Code::SYSTEM_ERROR, ['status_code' => $response->status(), 'error' => $response->body()]);
}
}
}
... ...
... ... @@ -10,6 +10,7 @@ use App\Http\Requests\Aside\WorkOrder\AsideTicketUpdateRequest;
use App\Http\Requests\Aside\WorkOrder\TicketProjectListRequest;
use App\Models\Manage\Manage;
use App\Models\Manage\ManageHr;
use App\Models\Ticket\TicketUploadData;
use App\Models\WorkOrder\TicketLog;
use App\Models\WorkOrder\TicketProject;
use App\Models\WorkOrder\Tickets;
... ... @@ -214,6 +215,24 @@ class AsideTicketController extends BaseController
return $query->where('id', 0); // 返回空结果
}
})
//待审核项目列表
->when(!empty($this->param['pending_review']), function ($query) use ($validated) {
// 查找项目名称或公司名称
$ticketUploadModel = new TicketUploadData();
if(!isset($this->param['project_type']) || empty($this->param['project_type'])){
$projectIds = $ticketUploadModel->where('status', 0)->where('project_type',1)->distinct('project_id')->pluck('project_id')->toArray();
$projectV6Ids = $ticketUploadModel->where('status', 0)->where('project_type',2)->distinct('project_id')->pluck('project_id')->toArray();
return $query->whereIn('post_id', $projectIds)->orWhereIn('table_id', $projectV6Ids);
}else{
if($this->param['project_type'] == 2){
$projectV6Ids = $ticketUploadModel->where('status', 0)->where('project_type',2)->distinct('project_id')->pluck('project_id')->toArray();
return $query->whereIn('table_id', $projectV6Ids);
}elseif ($this->param['project_type'] == 1){
$projectIds = $ticketUploadModel->where('status', 0)->where('project_type',1)->distinct('project_id')->pluck('project_id')->toArray();
return $query->whereIn('post_id', $projectIds);
}
}
})
->when(!empty($validated['search']), function ($query) use ($validated) {
// 查找项目名称或公司名称
$search = $validated['search'];
... ... @@ -375,6 +394,8 @@ class AsideTicketController extends BaseController
}
if ($project->wechat_switch)
$project->pushWechatGroupMsg();
else
$this->response('请先点击开关,打开微信推送', Code::USER_MODEL_NOTFOUND_ERROE);
$this->response('success', Code::SUCCESS);
}
}
... ...
<?php
/**
* @remark :
* @name :Extension3915ModuleController.php
* @author :lyh
* @method :post
* @time :2025/11/20 11:42
*/
namespace App\Http\Controllers\Bside\ExtensionModule;
use App\Enums\Common\Code;
use App\Http\Controllers\Bside\BaseController;
use App\Models\ExtentModule\ExtensionModuleField;
use App\Models\ExtentModule\ExtensionModuleValue;
use Illuminate\Support\Facades\Cache;
class Extension3915ModuleController extends BaseController
{
/**
* @remark :获取列表数据
* @name :lists
* @author :lyh
* @method :post
* @time :2025/11/20 14:38
*/
public function lists(){
$this->request->validate([
'module_id'=>'required',
],[
'module_id.required' => '模块id不能为空',
]);
$searchParam = [
'module_id'=>$this->param['module_id'],
];
$resultData = Cache::get('extension_module_list_3915_'.$this->param['module_id']);
if(empty($resultData)){
$data = [];
$moduleValueModel = new ExtensionModuleValue();
if(isset($this->param['field_id']) && ($this->param['field_id'] != 0) && isset($this->param['value'])){
$uuidArr = $moduleValueModel->formatQuery(['field_id'=>$this->param['field_id'],'value'=>$this->param['value'],'module_id'=>$this->param['module_id']])->distinct()->pluck('uuid')->toArray();
if(!empty($uuidArr)){
$searchParam['uuid'] = ['in',$uuidArr];
}
}
if(isset($this->param['start_time']) && !empty($this->param['start_time']) && isset($this->param['end_time']) && !empty($this->param['end_time'])){
$searchParam['created_at'] = ['between',[$this->param['start_time'],$this->param['end_time']]];
}
$lists = $moduleValueModel->list($searchParam);
if(!empty($lists)){
foreach ($lists as $k => $v){
$data[$v['uuid']][$v['field_id']] = $v['value'];
$data[$v['uuid']]['created_at'] = $v['created_at'];
}
}
$resultData = [];
foreach ($data as $k => $v){
$v['uuid'] = $k;
$resultData[] = $v;
}
Cache::add('extension_module_list_3915_'.$this->param['module_id'],$resultData);
}
$resultData = $this->formatPaginate($resultData,$this->row,$this->page);
//执行分页
$this->response('success',Code::SUCCESS,$resultData);
}
/**
* @remark :分页
* @name :simplePaginate
* @author :lyh
* @method :post
* @time :2025/11/20 14:50
*/
public function formatPaginate($data, $size = 20, $page = 1)
{
$collection = collect($data);
$total = $collection->count();
$totalPage = max(1, ceil($total / $size));
// 确保页码在有效范围内
$page = max(1, min($page, $totalPage));
$list = $collection->forPage($page, $size)->values()->toArray();
return [
'list' => $list,
'page' => (int)$page,
'size' => (string)$size,
'total' => $total,
'total_page' => $totalPage
];
}
/**
* @remark :导入数据
* @name :importData
* @author :lyh
* @method :post
* @time :2025/11/20 14:40
*/
public function importData()
{
$this->request->validate([
'module_id'=>'required',
],[
'module_id.required' => '模块id不能为空',
]);
if($this->user['project_id'] != 3915){
$this->fail('当前项目不能调用当前方法');
}
$moduleFieldModel = new ExtensionModuleField();
$filedList = $moduleFieldModel->where(['module_id' => $this->param['module_id']])->pluck('field_name', 'id')->toArray();
if(empty($filedList)){
$this->response('请先设置字段,再添加数据',Code::SUCCESS);
}
$data = $this->param['data'];
$moduleValueModel = new ExtensionModuleValue();
$key_filedId = [];
$resultData = [];
foreach ($data as $k => $v){
foreach ($v as $k1 => $v1){
if($k == 0){
if(isset($filedList[$v1])){
$key_filedId[$k1] = $filedList[$v1];
}
continue;
}
$resultData[] = [
'uuid'=>$k + 1,
'module_id'=>$this->param['module_id'],
'field_id'=>$key_filedId[$k1],
'value'=>$v1 ?? '',
];
}
}
if(!empty($resultData)){
//todo::优先截断表
$moduleValueModel->truncate();
$moduleValueModel->insertAll($resultData);
}
$this->response('success',Code::SUCCESS,$resultData);
}
}
... ...
... ... @@ -207,11 +207,14 @@ class ImageController extends Controller
if($this->upload_location == 0){
$watermarkOptions = $this->getProjectConfig($this->cache['project_id'] ?? 0);
$cosService = new CosService();
$cosService->uploadFile($files,$this->path,$fileName,false,$watermarkOptions);
$res = $cosService->uploadFile($files,$this->path,$fileName,false,$watermarkOptions);
}else{
//TODO::上传亚马逊
$amazonS3Service = new AmazonS3Service();
$amazonS3Service->uploadFiles($files,$this->path,$fileName);
$res = $amazonS3Service->uploadFiles($files,$this->path,$fileName);
}
if($res === false){
$this->response('上传失败,请重新上传',Code::SYSTEM_ERROR);
}
$this->saveMysql($imageModel,$files->getSize(),$image_type,$fileName,$hash,$this->upload_location,$files->getMimeType(), $name);
$this->synchronizationImage($fileName,$this->upload_location);
... ... @@ -354,11 +357,15 @@ class ImageController extends Controller
if($this->upload_location == 0){
$watermarkOptions = $this->getProjectConfig($this->cache['project_id'] ?? 0);
$cosService = new CosService();
$cosService->uploadFile($file,$this->path,$fileName,false,$watermarkOptions);
$res = $cosService->uploadFile($file,$this->path,$fileName,false,$watermarkOptions);
}else{
//TODO::上传亚马逊
$amazonS3Service = new AmazonS3Service();
$amazonS3Service->uploadFiles($file,$this->path,$fileName);
$res = $amazonS3Service->uploadFiles($file,$this->path,$fileName);
}
if($res === false){
outMessage('upload_images','图片上传失败'.$name);
continue;
}
$this->synchronizationImage($fileName,$this->upload_location);
$data[] = $this->responseData($this->path.'/'.$fileName,$name);
... ... @@ -700,6 +707,9 @@ class ImageController extends Controller
$info = $imageSetting->read(['project_id'=>$this->cache['project_id']]);
$domain = 'http://globalso-v6-1309677403.cos.ap-hongkong.myqcloud.com';//cos域名
if($is_image){
if(empty($data['image'])){
$this->response('开启图片水印需要先关闭水印功能,重新上传水印图片'.Code::SYSTEM_ERROR);
}
$param = [
'image/'.$domain.($data['image'] ?? ''),//图片
'gravity/'.($data['gravity'] ?? 'SouthEast'),
... ... @@ -755,11 +765,11 @@ class ImageController extends Controller
if($info === false){
$this->response('请先设置水印',Code::SYSTEM_ERROR);
}
if($info['status'] == 1 && empty($info['image_data'])){
if($this->param['status'] == 1 && empty($info['image_data'])){
$this->response('请先设置水印',Code::SYSTEM_ERROR);
}
if($info['status'] == 2 && empty($info['str_data'])){
$this->response('请先设置水印',Code::SYSTEM_ERROR);
if($this->param['status'] == 2 && empty($info['str_data'])){
$this->response('请先设置文字水印',Code::SYSTEM_ERROR);
}
$imageSetting->edit(['status'=>$this->param['status']],['project_id'=>$this->cache['project_id']]);
$this->response('success');
... ...
... ... @@ -92,12 +92,15 @@ class GeoArticleLogic extends BaseLogic
if(!empty($this->param['data'])){
$data = [];
foreach ($this->param['data'] as $item){
$info = $this->model->read(['url'=>$item['url'],'filename'=>$item['filename']],['id','url']);
if($info === false){
$data[] = [
'filename' => $item['filename'],
'url'=> $item['url'],
'project_id'=>$this->param['project_id']
];
}
}
$this->model->insertAll($data);
}
}catch (\Exception $e){
... ...
... ... @@ -9,10 +9,12 @@
namespace App\Http\Logic\Aside\Geo;
use App\Enums\Common\Code;
use App\Http\Logic\Aside\BaseLogic;
use App\Models\Geo\GeoConf;
use App\Models\Geo\GeoConfirm;
use App\Models\Manage\ManageHr;
use App\Models\ProjectAssociation\ProjectAssociation;
use App\Services\DingService;
/**
* @remark :用户确认信息
... ... @@ -40,7 +42,7 @@ class GeoConfirmLogic extends BaseLogic
public function saveConfirmContent($param)
{
try {
$wechat = $param['wechat'] ?? true;
$wechat = $param['wechat'] ?? 1;
unset($param['wechat']);
$info = $this->model->read(['project_id' => $param['project_id'],'type' => $param['type']]);
if($info === false){
... ... @@ -92,6 +94,19 @@ class GeoConfirmLogic extends BaseLogic
}else{
$id = $info['id'];
$this->model->edit($this->param,['id'=>$info['id']]);
$geoConfModel = new GeoConf();
$confInfo = $geoConfModel->read(['project_id'=>$info['project_id']]);
$hrModel = new ManageHr();
$manage_name = $hrModel->getName($confInfo['manager_id'] ??'');
$dingService = new DingService();
$dingService->handle([
'keyword' => '项目数据确认',
'msg' =>
'cm:'.(($info['type'] == 1) ? '标题确认' : '关键词确认'). PHP_EOL .
'项目名称:'.($confInfo['company'] ?? '') . PHP_EOL .
'负责人:'.$manage_name . PHP_EOL,
'isAtAll' => false, // 是否@所有人
], 'https://oapi.dingtalk.com/robot/send?access_token=4effe85882009a8a1617dbeadc38c350f832deef7431ce10f5fda751b4c82fb9');
}
return $this->success(['id'=>$id]);
}
... ...
... ... @@ -85,10 +85,15 @@ class GeoQuestionLogic extends BaseLogic
public function saveGeoQuestion(){
//处理数据
$count = count($this->param['question']);
$sum = $this->model->where('project_id',$this->param['project_id'])->sum('question_num') ?? 0;
if($sum >= 200 || $count >= 200){
$this->fail('当前问题数量大于最大数量200个问题,不允许保存');
}
$question = $this->param['question'];
$this->param['url'] = json_encode($this->param['url'] ?? [],true);
$this->param['keywords'] = json_encode($this->param['keywords'] ?? [],true);
if($count <= 20){
$this->param['question_num'] = $count;
if(isset($this->param['id']) && !empty($this->param['id'])){
$id = $this->param['id'];
$this->model->edit($this->param,['id'=>$id]);
... ... @@ -101,6 +106,7 @@ class GeoQuestionLogic extends BaseLogic
$chunks = array_chunk($question, 20);
if(isset($this->param['id']) && !empty($this->param['id'])){
foreach ($chunks as $index => $chunk) {
$this->param['question_num'] = count($chunk);
$this->param['question'] = json_encode($chunk ?? [],true);
if($index == 0){
$id = $this->param['id'];
... ...
... ... @@ -65,9 +65,11 @@ class GeoWritingsLogic extends BaseLogic
$this->param['status'] = GeoWritings::STATUS_INIT;
if(isset($this->param['id']) &&!empty($this->param['id'])){
$id = $this->param['id'];
$this->param['content_length'] = strlen($this->param['content'] ?? '');
$this->model->edit($this->param,['id'=>$id]);
}else{
$this->param['type'] = GeoWritings::TYPE_SUBMIT;
$this->param['content_length'] = strlen($this->param['content'] ?? '');
$this->param['uniqid'] = uniqid().$this->param['project_id'];
$id = $this->model->addReturnId($this->param);
}
... ... @@ -102,7 +104,7 @@ class GeoWritingsLogic extends BaseLogic
*/
public function sendWechatMessage()
{
$wechat = $this->param['wechat'] ?? true;
$wechat = $this->param['wechat'] ?? 1;
$this->model->edit(['status'=>2],['status'=>1,'project_id'=>$this->param['project_id']]);
$data = GeoWritings::sendConfirmMessage($this->param['project_id'],$wechat);
if($data === false){
... ...
... ... @@ -551,8 +551,11 @@ class InquiryForwardLogic extends BaseLogic
$last_year_month = date('Y-m', strtotime($last_year_month . ' +1 month'));
}
$data_month['total'] = $data_month_total;
$data_month['合计'] = $data_month_total;
foreach ($data_month as $km => $vm) {
$data_month[$km]['月/年合计'] = array_sum($vm);
}
//周统计
$last_week_day = date('Y-m-d', strtotime('-1 week'));
... ... @@ -576,7 +579,11 @@ class InquiryForwardLogic extends BaseLogic
$last_week_day = date('Y-m-d', strtotime($last_week_day . ' +1 day'));
}
$data_week['total'] = $data_week_total;
$data_week['合计'] = $data_week_total;
foreach ($data_week as $kw => $vw) {
$data_week[$kw]['日/周合计'] = array_sum($vw);
}
$data = ['data_month' => $data_month, 'data_week' => $data_week];
... ...
... ... @@ -870,7 +870,12 @@ class ProductLogic extends BaseLogic
$img_arr = explode('^v6sp$',$data[7]);
foreach ($img_arr as $v_img){
if($v_img){
if($project_id == 4847){
//4847项目特殊处理
$one_img = 'https://ecdn6.globalso.com/upload/p/4847/image_other/2025-11/'.$v_img;
}else{
$one_img = check_remote_url_down($v_img,$project_id,$domain);
}
if($one_img){
$one_gallery = [
'alt' => '',
... ...
... ... @@ -113,6 +113,8 @@ class RankDataLogic extends BaseLogic
'remain_day' => $project['remain_day'],
'seo_remain_day' => $project['seo_remain_day'],
'g_top_plan' => $g_top_plan ?? [],
'is_remain_today'=>$project['is_remain_today'] ?? 0,
'bm_is_remain_today'=>$project['bm_is_remain_today'] ?? 0
];
//小语种列表
$quanqiusou_api = new QuanqiusouApi();
... ...
... ... @@ -38,7 +38,7 @@ class GeoWritingsTaskRequest extends FormRequest
// 'prefix' => 'required|string',
// 'suffix' => 'required|string',
'event_title' => 'required|string',
'event_content' => 'required|string',
// 'event_content' => 'required|string',
'title' => 'required|string|max:120',
'description' => 'required|string',
];
... ...
<?php
/**
* @remark :
* @name :WordAi.php
* @author :lyh
* @method :post
* @time :2025/11/20 11:22
*/
namespace App\Jobs;
use App\Models\AiRemove\AiRemove;
use App\Services\WordAiService;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class WordAi implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $param;
public function __construct($data)
{
$this->param = $data;
}
/**
* @remark :执行数据
* @name :handle
* @author :lyh
* @method :post
* @time :2025/11/20 11:24
*/
public function handle()
{
$model = new AiRemove();
$info = $model->read(['id'=>$this->param['id']]);
if($info !== false && !empty($info['origin_text'])) {
$model->edit(['status'=>$model::STATUS_ING],['id'=>$info['id']]);
$wordAiService = new WordAiService();
$data = $wordAiService->setApiAvoid($info['origin_text']);
if(isset($data['status']) && $data['status'] == 'Success'){
//todo::更新当前任务状态,并记录返回的值
$model->edit(['target_text'=>$data['text'],'status'=>$model::STATUS_SUC],['id'=>$info['id']]);
}else{
//todo::更改执行次数,及错误结果
$model->edit(['error_msg'=>substr(json_encode($data,JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE),0,255),'status'=>$model::STATUS_FAL],['id'=>$info['id']]);
sleep(10);
}
}
return true;
}
}
... ...
... ... @@ -41,6 +41,7 @@ class APublicModel extends Base
->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();
$newsNumber = DB::connection('custom_mysql')->table('gl_news')
->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();
$aiBlogNumber = DB::connection('custom_mysql')->table('gl_ai_blog')->where('project_id', $project_id)->count();
$keyNumber = DB::connection('custom_mysql')->table('gl_product_keyword')
->where('project_id', $project_id)->where('status', self::STATUS_ON)->count();
//获取项目的询盘数量
... ... @@ -49,7 +50,7 @@ class APublicModel extends Base
if(!empty($countInfo)){
$inquiryNumber = $countInfo->inquiry_num ?? 0;
}
$data = ['product'=>$productNumber,'blog'=>$blogNumber,'news'=>$newsNumber,'key'=>$keyNumber,'inquiry'=>$inquiryNumber];
$data = ['product'=>$productNumber,'blog'=>($blogNumber + $aiBlogNumber),'news'=>$newsNumber,'key'=>$keyNumber,'inquiry'=>$inquiryNumber];
Cache::add('product_blog_news_'.$project_id,$data,30 * 60);
}
}catch (\Exception $e){
... ...
<?php
namespace App\Models\AiRemove;
use App\Models\Base;
class AiRemove extends Base
{
protected $table = 'gl_ai_remove_task';
const STATUS_UN = 0;
const STATUS_ING = 1;
const STATUS_SUC = 2;
const STATUS_FAL = 3;
}
... ...
... ... @@ -106,7 +106,7 @@ class GeoConfirm extends Base
* @param $id
* @return bool
*/
public static function sendConfirmMessage($id, $friend_id,$send = true)
public static function sendConfirmMessage($id, $friend_id,$send = 1)
{
$data = self::where(compact('id'))->first();
$project_id = $data->project_id;
... ... @@ -127,7 +127,7 @@ class GeoConfirm extends Base
'url' => 'https://oa.quanqiusou.cn/public-geo-confirm?token=' . $token
];
$content = json_encode($content_array, JSON_UNESCAPED_UNICODE);
if($send == true){
if($send){
$data->send_at = now();
$data->status = self::STATUS_RUNNING;
MessagePush::insert(compact('project_id', 'friend_id', 'type', 'content_type', 'content', 'send_time', 'updated_at', 'created_at'));
... ...
... ... @@ -77,7 +77,7 @@ class GeoWritings extends Base
* @return bool
* @throws \Exception
*/
public static function sendConfirmMessage($project_id,$wechat = true)
public static function sendConfirmMessage($project_id,$wechat = 1)
{
$friend = ProjectAssociation::where(['project_id' => $project_id])->first();
if (empty($friend)) {
... ...
... ... @@ -24,7 +24,7 @@ class CosService
* @method :post
* @time :2023/7/19 15:28
*/
public function uploadFile(&$files,$path,$filename, $binary = false,$watermarkOptions = '')
public function uploadFile(&$files, $path, $filename, $binary = false, $watermarkOptions = '')
{
$cos = config('filesystems.disks.cos');
$cosClient = new Client([
... ... @@ -34,7 +34,9 @@ class CosService
'secretKey' => $cos['credentials']['secretKey'],
],
]);
$key = $path.'/'.$filename;
$key = $path . '/' . $filename;
// 判断是否为 Base64 编码的图片流文件
if (Str::startsWith($files, 'data:image')) {
// 分离 Base64 头部和数据部分
... ... @@ -42,18 +44,30 @@ class CosService
// 解码 Base64 数据
$Body = base64_decode($base64Data);
if ($Body === false) {
throw new \Exception("Base64 数据解码失败");
outMessage('upload_images',"解码失败");
return false;
}
} else {
// 如果不是 Base64 流文件,处理为普通文件上传
try {
$Body = $binary ? $files : fopen($files->getRealPath(), 'r');
// 检查文件是否有效
if (!$Body) {
outMessage('upload_images',"文件打开失败");
return false;
}
} catch (\Exception $e) {
outMessage('upload_images',"文件处理失败: " . $e->getMessage());
return false;
}
}
try {
$options = [
'Bucket' => $cos['bucket'],
'Key' => $key,
'Body' => $Body,
];
//水印
// 水印处理
if ($watermarkOptions) {
$options['PicOperations'] = json_encode([
'is_pic_info' => 1,
... ... @@ -65,10 +79,21 @@ class CosService
]
], true);
}
$res = $cosClient->putObject($options);
$cosClient->putObject($options);
} catch (\Exception $e) {
// 记录上传失败日志
outMessage('upload_images',$e->getMessage());
return false;
} finally {
// 确保非二进制模式下关闭文件资源
if (!$binary && is_resource($Body)) {
fclose($Body);
}
}
return $key;
}
/**
* @param $image_name
* @remark :获取图片访问链接
... ...
... ... @@ -31,7 +31,7 @@ class DingService
public function handle(array $body, $link = '')
{
$link = $link ?: self::LINK;
$msgKey = mb_substr($body['msg'], 50);
$msgKey = mb_substr($body['msg'], 100);
if (!$this->getData(RedisKey::DING_MSG . $msgKey)) {
$arr = [
'msgtype' => 'text',
... ...
<?php
/**
* @remark :
* @name :WordAiService.php
* @author :lyh
* @method :post
* @time :2025/11/19 17:40
*/
namespace App\Services;
use Illuminate\Support\Facades\Http;
class WordAiService
{
public $email = 'bill@ai.cc';
public $key = '868545714b911ab135327793fcadf46e';
public $url = 'https://wai.wordai.com/';
/**
* @remark :ai检测(WordAi 避免检测到)
* @name :setApiAvoid
* @author :lyh
* @method :post
* @time :2025/11/19 17:43
*/
public function setApiAvoid($input = '',$model = 'change_less')
{
$response = Http::timeout(600)->retry(3, 5000)
->post($this->url.'/api/avoid', [
'email' => $this->email,
'key' => $this->key,
'input' => $input,
'mode' => $model
]);
if ($response->successful()) {
$result = $response->json();
// 处理返回结果
return $result;
} else {
// 处理错误
return false;
}
}
}
... ...
... ... @@ -81,6 +81,7 @@ return [
'cdn' => env('COS_CDN'),
'cdn1' => env('COS_CDN1'),
'cdn2' => env('COS_CDN2'),
'cdn3' => env('COS_CDN3'),
'timeout' => 60,
'connect_timeout' => 60,
],
... ...
... ... @@ -125,5 +125,7 @@ Route::prefix('geo')->group(function () {
Route::any('/getWritingsList', [\App\Http\Controllers\Api\GeoController::class, 'getWritingsList'])->name('geo.getWritingsList');//文章确认列表
Route::any('/confirmWritings', [\App\Http\Controllers\Api\GeoController::class, 'confirmWritings'])->name('geo.confirmWritings');//确认文章信息
});
//获取geo外链数据
Route::any('/getGeoLink', [\App\Http\Controllers\Api\ComController::class, 'getGeoLink'])->name('geo.getGeoLink');
... ...
... ... @@ -18,6 +18,7 @@ Route::middleware(['aloginauth'])->group(function () {
Route::any('/getCountry', [Aside\Com\CNoticeController::class, 'getCountry'])->name('admin.getCountry');
Route::any('/getDynamicPassword', [Aside\Com\IndexController::class, 'getDynamicPassword'])->name('admin.getDynamicPassword');
Route::any('/notAiHumanizer', [Aside\Com\IndexController::class, 'notAiHumanizer'])->name('admin.notAiHumanizer');
Route::any('/notWordAiHumanizer', [Aside\Com\IndexController::class, 'notWordAiHumanizer'])->name('admin.notWordAiHumanizer');
Route::any('/prInfoDownload', [Aside\Com\IndexController::class, 'prInfoDownload'])->name('admin.prInfoDownload');//pr报告下载
//会员相关
Route::prefix('user')->group(function () {
... ... @@ -690,6 +691,12 @@ Route::middleware(['aloginauth'])->group(function () {
Route::any('/del', [Aside\Manage\ManageEntryPositionController::class,'del'])->name('entry_position_del');
});
//去AI痕迹管理
Route::prefix('ai_remove')->group(function () {
Route::any('/', [Aside\AiRemove\AiRemoveController::class, 'getTaskLists'])->name('admin.ai_remove_getTaskLists');
Route::any('/taskInfo', [Aside\AiRemove\AiRemoveController::class, 'taskInfo'])->name('admin.ai_remove_taskInfo');
Route::any('/saveTask', [Aside\AiRemove\AiRemoveController::class, 'saveTask'])->name('admin.ai_remove_saveTask');
});
});
//无需登录验证的路由组
... ...
... ... @@ -656,6 +656,9 @@ Route::middleware(['bloginauth'])->group(function () {
//2205项目单独处理
Route::any('2205/get2205List', [\App\Http\Controllers\Bside\ExtensionModule\Extension2205ModuleController::class, 'get2205List'])->name('extension_module_get2205List');
Route::any('2205/save2205Status', [\App\Http\Controllers\Bside\ExtensionModule\Extension2205ModuleController::class, 'save2205Status'])->name('extension_module_save2205Status');
//3915项目处理
Route::any('3915/lists', [\App\Http\Controllers\Bside\ExtensionModule\Extension3915ModuleController::class, 'lists'])->name('extension_module_3915_lists');
Route::any('3915/importData', [\App\Http\Controllers\Bside\ExtensionModule\Extension3915ModuleController::class, 'importData'])->name('extension_module_3915_importData');
});
//自定义小语种文本信息
... ...