作者 ZhengBing He

Merge remote-tracking branch 'origin/master' into workorder

... ... @@ -77,14 +77,16 @@ class AiBlogAutoPublish extends Command
$this->output("项目{$project->id}未到执行时间" . $next_auto_date);
continue;
}
//核心关键词+网站关键词
//核心关键词+网站关键词+白帽关键词
$main_keywords = ProjectKeyword::where('project_id', $project->id)->value('main_keyword');
$main_keywords = explode("\r\n", $main_keywords);
$seo_keywords = ProjectKeyword::where('project_id', $project->id)->value('seo_keywords');
$seo_keywords = explode("\r\n", $seo_keywords);
ProjectServer::useProject($project->id);
$site_keywords = WebSetting::where('project_id', $project->id)->value('keyword');
DB::disconnect('custom_mysql');
$site_keywords = explode(",", $site_keywords);
$keywords = array_filter(array_merge($main_keywords, $site_keywords));
$keywords = array_filter(array_merge($main_keywords, $site_keywords, $seo_keywords));
$keywords = array_map('trim', $keywords);
if (empty($keywords)) {
$this->output("项目{$project->id}未获取到关键词");
... ...
... ... @@ -87,6 +87,9 @@ class CountProject extends Command
//剩余服务时常
$arr['service_day'] = $projectInfo['remain_day'];
$arr = $this->inquiry($arr,$domain, $project_id,$projectInfo['is_upgrade'] ?? 0);
if($arr === false){
continue;
}
//查询当天数据是否存在 存在则更新
$info = $count->read(['date'=>$v['updated_date'],'project_id'=>$project_id]);
if($info === false){
... ... @@ -146,7 +149,7 @@ class CountProject extends Command
public function inquiry($arr,$domain,$project_id,$is_upgrade = 0){
$inquiry_list = (new FormGlobalsoApi())->getInquiryAll($domain,$is_upgrade);
if($inquiry_list == false){
return false;
return $arr;
}
// echo date('Y-m-d H:i:s') . '拉取询盘状态:' .json_encode($inquiry_list) . PHP_EOL;
if($inquiry_list['status'] == self::STATUS_ERROR){
... ...
... ... @@ -14,6 +14,8 @@ use App\Models\Devops\ServersIp;
use App\Models\Domain\DomainCreateTask;
use App\Models\Project\CountryCustom;
use App\Models\Project\Project;
use App\Models\ProjectAssociation\ProjectAssociation;
use App\Models\Workchat\MessagePush;
use Illuminate\Console\Command;
use App\Models\Domain\DomainInfo as DomainInfoModel;
use Illuminate\Support\Facades\Log;
... ... @@ -69,6 +71,7 @@ class DomainInfo extends Command
$projectModel = new Project();
$serverIpModel = new ServersIp();
$domainCreateTaskModel = new DomainCreateTask();
$end_day = date('Y-m-d H:i:s', strtotime('+1 month'));//域名1月后到期
$list = $domainModel->where('status', '=', 1)->get();
foreach ($list as $v) {
$project_info = $projectModel->read(['id' => $v['project_id'], 'type' => ['!=', Project::TYPE_CLOSE]], ['serve_id', 'project_type']);
... ... @@ -90,7 +93,7 @@ class DomainInfo extends Command
$v->save();
}
if (empty($v['domain_end_time']) || $v['domain_end_time'] < date('Y-m-d H:i:s')) {
if (empty($v['domain_end_time']) || $v['domain_end_time'] < $end_day) {
//获取主站域名有效期并更新
$valid_time = $this->getDomainValidTime($v['domain']);
if ($valid_time['start'] && $valid_time['end']) {
... ... @@ -99,6 +102,12 @@ class DomainInfo extends Command
$v->save();
}
}
//域名到期提醒
if ($v->domain_end_time && $v->domain_end_time < $end_day) {
$is_end = $v->domain_end_time < date('Y-m-d H:i:s') ? 1 : 0;
$this->domainChatMessage($v['project_id'], $v['id'], $v['domain'], $is_end);
}
} else {
//除自建站项目外,记录已解析到别的ip的域名
if (!check_domain_record($v['domain'], $servers_ip_info)) {
... ... @@ -125,7 +134,7 @@ class DomainInfo extends Command
$v->save();
}
if (empty($v['domain_end_time']) || $v['domain_end_time'] < date('Y-m-d H:i:s')) {
if (empty($v['domain_end_time']) || $v['domain_end_time'] < $end_day) {
//获取主站域名有效期并更新
$valid_time = $this->getDomainValidTime($v['domain']);
if ($valid_time['start'] && $valid_time['end']) {
... ... @@ -135,6 +144,12 @@ class DomainInfo extends Command
}
}
//域名到期提醒
if ($v->domain_end_time && $v->domain_end_time < $end_day) {
$is_end = $v->domain_end_time < date('Y-m-d H:i:s') ? 1 : 0;
$this->domainChatMessage($v['project_id'], $v['id'], $v['domain'], $is_end);
}
if ($v['amp_status'] == 1) {
$domain_array = parse_url($v['domain']);
$host = $domain_array['host'] ?? $domain_array['path'];
... ... @@ -177,7 +192,7 @@ class DomainInfo extends Command
$projectModel = new Project();
$serverIpModel = new ServersIp();
$domainCreateTaskModel = new DomainCreateTask();
$end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期
$end_day = date('Y-m-d H:i:s', strtotime('+3 day'));//3天后到期
$list = $domainModel->where('status', '=', 1)->where('type', '!=', 2)->where('certificate_end_time', '<', $end_day)->get()->toArray();
foreach ($list as $v) {
$project_info = $projectModel->read(['id' => $v['project_id'], 'type' => ['!=', Project::TYPE_CLOSE]], ['serve_id', 'project_type']);
... ... @@ -230,7 +245,7 @@ class DomainInfo extends Command
$projectModel = new Project();
$serverIpModel = new ServersIp();
$domainCreateTaskModel = new DomainCreateTask();
$end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期
$end_day = date('Y-m-d H:i:s', strtotime('+3 day'));//3天后到期
$list = $domainModel->where('status', '=', 1)->where('amp_status', 1)->where('amp_type', '!=', 2)->where('amp_certificate_end_time', '<', $end_day)->get()->toArray();
foreach ($list as $v) {
$domain_array = parse_url($v['domain']);
... ... @@ -287,7 +302,7 @@ class DomainInfo extends Command
$projectModel = new Project();
$serverIpModel = new ServersIp();
$domainCreateTaskModel = new DomainCreateTask();
$end_day = date('Y-m-d H:i:s', time() + 3 * 24 * 3600);//3天后到期
$end_day = date('Y-m-d H:i:s', strtotime('+3 day'));//3天后到期
$list = $customModel->where('status', 1)->where('is_create', 1)->where('type', '=', 1)->where('certificate_end_time', '<', $end_day)->get()->toArray();
foreach ($list as $v) {
$project_info = $projectModel->read(['id' => $v['project_id'], 'type' => ['!=', Project::TYPE_CLOSE]], ['serve_id']);
... ... @@ -379,4 +394,38 @@ class DomainInfo extends Command
}
return ['start' => $start, 'end' => $end];
}
/**
* 推送域名到期微信消息提醒
* @param $project_id
* @param $domain_id
* @param $domain
* @param $is_end
* @author Akun
* @date 2025/08/14 9:56
*/
public function domainChatMessage($project_id, $domain_id, $domain, $is_end)
{
//项目是否有绑定群
$friend_id = ProjectAssociation::where('project_id', $project_id)
->where('status', ProjectAssociation::STATUS_NORMAL)
->where('binding_app', ProjectAssociation::ENTERPRISE_WECHAT)
->value('friend_id');
if ($friend_id) {
$tips = $is_end ? ' 已经到期' : ' 即将到期';
$message = '【域名到期提醒】' . PHP_EOL . '域名 ' . $domain . $tips . ',请及时处理。';
$param = [
'project_id' => $project_id,
'friend_id' => $friend_id,
'type' => MessagePush::TYPE_DOMAIN,
'content' => $message,
'ref_ids' => $domain_id,
'send_time' => date('Y-m-d 14:00:00'),
'status' => 0,
];
//写入一条推送消息 自动消费
$messagePushModel = new MessagePush();
$messagePushModel->add($param);
}
}
}
... ...
... ... @@ -35,7 +35,7 @@ class RemainDay extends Command
* 按照达标天数收费的项目(白帽)
*/
protected $bm_projectId = [
4247,4299,4310,4215,4038,4084,4148
4247,4299,4310,4215,4038,4084,4148,4178
];
... ... @@ -83,7 +83,7 @@ class RemainDay extends Command
* @time :2025/4/2 10:48
*/
public function saveRemainDay(){
$list = $this->project->list(['extend_type'=>Project::TYPE_ZERO,'type'=>['in',[Project::TYPE_TWO,Project::TYPE_THREE,Project::TYPE_FOUR,Project::TYPE_SIX]]],'id',['id','type','uptime','remain_day','is_remain_today','pause_days','finish_remain_day','bm_finish_remain_day']);
$list = $this->project->list(['extend_type'=>Project::TYPE_ZERO,'type'=>['in',[Project::TYPE_TWO,Project::TYPE_THREE,Project::TYPE_FOUR,Project::TYPE_SIX]]],'id',['id','type','level','uptime','remain_day','is_remain_today','pause_days','finish_remain_day','bm_finish_remain_day']);
foreach ($list as $item){
$deploy_build = $this->deployBuild->read(['project_id'=>$item['id']],['service_duration','seo_service_duration','plan','seo_plan']);
echo 'start->项目id:' . $item['id'] . '执行时间:'. date('Y-m-d H:i:s') . PHP_EOL;
... ... @@ -120,7 +120,7 @@ class RemainDay extends Command
//白帽版本的系统
if($deploy_build['seo_plan'] == 1){
if($deploy_build['seo_service_duration'] != 0){
if(in_array($item['id'],$this->bm_projectId)){
if(in_array($item['id'],$this->bm_projectId) || (strpos($item['level'], '19') !== false)){
$compliance_day = (int)$item['bm_finish_remain_day'];
$seo_remain_day = $deploy_build['seo_service_duration'] - (int)$item['bm_finish_remain_day'];
}else{
... ...
... ... @@ -113,6 +113,14 @@ class GeoQuestionRes extends Command
}
// 命中文案
$hit_data[] = $result['text'];
if(!empty($result['annotations'])){
$url = array_column(array_column($result['annotations'], 'url_citation'), 'url');
$title = array_column(array_column($result['annotations'], 'url_citation'), 'title');
$hit_data = array_merge($url, $title, $hit_data);
}
$hit = 0;
//todo::与预期结果是否复合
if(!empty($taskInfo['expect_result'])){
$str = "客户提出的问题:{$question},客户得到的回复:{$result['text']},客户需要预期:{$taskInfo['expect_result']},请分析得到的回复和预期是否一致,仅回复我是或者否";
$strResult = $geo_service->getChatResult($str, 'gpt-4o-mini');
... ... @@ -120,6 +128,7 @@ class GeoQuestionRes extends Command
switch ($strResult['text']){
case '是':
$is_match = 1;
$hit++;
break;
case '否':
$is_match = 2;
... ... @@ -130,12 +139,6 @@ class GeoQuestionRes extends Command
}
}
}
if(!empty($result['annotations'])){
$url = array_column(array_column($result['annotations'], 'url_citation'), 'url');
$title = array_column(array_column($result['annotations'], 'url_citation'), 'title');
$hit_data = array_merge($url, $title, $hit_data);
}
$hit = 0;
$hit_keyword = $this->getKeywords($taskInfo['keywords'],$hit_data);
if (!empty($hit_keyword['keywords'])) {
$hit++;
... ...
... ... @@ -19,6 +19,7 @@ use App\Models\WorkOrder\TicketProject;
use App\Models\WorkOrder\Tickets;
use Illuminate\Console\Command;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
class TicketCount extends Command
... ... @@ -75,6 +76,7 @@ class TicketCount extends Command
$date = Carbon::yesterday()->toDateString(); // 昨日时间
$ticketManageCountModel = new TicketDailyManageCount();
foreach ($manageList as $item){
$average_time = '';
$this->output('按人员统计:执行的人员名称/id:'.$item['name'].'/'.$item['manage_id']);
$ticketLogModel = new TicketLog();
$ticket_num = $ticketLogModel->counts(['engineer_id'=>$item['manage_id'],'is_engineer'=>1]);
... ... @@ -128,6 +130,7 @@ class TicketCount extends Command
$ticketDailyDeptModel = new TicketDailyDeptCount();
$date = Carbon::yesterday()->toDateString(); // "2025-08-07"
foreach ($groupList as $item){
$average_time = '';
$this->output('组统计:执行的组/id:'.$item['name'].'/'.$item['id']);
$manageIdArr = $manageHrModel->selectField(['belong_group'=>$item['id'],'status'=>1,'dept_id'=>1],'manage_id');
$ticket_num = $ticketLogModel->counts(['engineer_id'=>['in',$manageIdArr],'is_engineer'=>1]);
... ... @@ -140,7 +143,7 @@ class TicketCount extends Command
'dept_id'=>$item['id'],
'dept_name'=>$item['name'],
'ticket_num'=>$ticket_num ?? 0,
'average_time'=>$average_time ?? 0
'average_time'=>$average_time ?? ''
];
$deptInfo = $ticketDailyDeptModel->read(['date'=>$date,'dept_id'=>$item['id']],['id']);
if($deptInfo === false){
... ... @@ -173,6 +176,13 @@ class TicketCount extends Command
$processed_num = $ticketModel->counts(['end_at'=>['between',[$date.' 00:00:00',$date.' 23:59:59']]]);
$submit_a_side = $ticketModel->formatQuery(['submit_side'=>1])->sum('submit_side');
$submit_b_side = $ticketModel->formatQuery(['submit_side'=>2])->sum('submit_side');
$dbResult = DB::table('gl_ticket_projects as p')->leftJoin('gl_tickets as t', 'p.id', '=', 't.project_id')
->select(
'p.project_cate',
DB::raw('COUNT(t.id) as ticket_count')
)
->groupBy('p.project_cate')
->pluck('ticket_count', 'project_cate');
$data = [
'date' => $date,
'ticket_num'=>$ticket_num,
... ... @@ -181,6 +191,7 @@ class TicketCount extends Command
'processed_num'=>$processed_num,
'average_time'=>$average_time ?? '',
'source'=>json_encode(['a'=>$submit_a_side,'b'=>$submit_b_side],true),
'source_type'=>json_encode($dbResult,true)
];
$ticketDailyModel = new TicketDailyCount();
$ticketDailyInfo = $ticketDailyModel->read(['date'=>$date],['id']);
... ...
... ... @@ -37,7 +37,7 @@ class BaseController extends Controller
$info = Cache::get(Common::MANAGE_TOKEN . $this->token);
if(!empty($this->token) && !empty($info)){
$this->manage = $info;
Cache::put(Common::MANAGE_TOKEN . $this->token, $info, 3600 * 6);//更新缓存时间
Cache::put(Common::MANAGE_TOKEN . $this->token, $info, 3600 * 12);//更新缓存时间
$this->uid = $info['id'];
}
}
... ...
... ... @@ -779,13 +779,15 @@ class ProjectController extends BaseController
* @author zbj
* @date 2023/9/11
*/
public function getProjectByChannel(){
public function getProjectByChannel(Request $request){
$id = $this->param['id'] ?? '';
$notice_order_id = $this->param['notice_order_id'] ?? '';
$source_id = $this->param['channel_id'] ?? 0; //原系统渠道id
$size = $this->param['page_size'] ?? 20;
$type = $this->param['type'] ?? '';
$company = $this->param['company'] ?? '';
$order_by_field = $request->input('order_by_field', 'id');
$order_by_sort = $request->input('order_by_sort', 'desc');
if(!$source_id && !$id){
$this->response('参数异常',Code::SYSTEM_ERROR);
... ... @@ -828,7 +830,7 @@ class ProjectController extends BaseController
if ($notice_order_id) {
$query->whereIn('notice_order_id', $notice_order_id);
}
})->orderBy('id', 'desc')->paginate($size)->toArray();
})->orderBy($order_by_field, $order_by_sort)->paginate($size)->toArray();
$list = [];
foreach ($data['list'] as $item){
$domain = '';
... ...
... ... @@ -81,7 +81,14 @@ class AsideTicketController extends BaseController
$q->where('project_cate', $projectCate);
});
});
//TODO::用户部门搜索
if(isset($this->param['dept_id']) && !empty($this->param['dept_id'])){
$manageHrModel = new ManageHr();
$manageIdArr = $manageHrModel->selectField(['dept_id'=>$this->param['dept_id'],'status'=>1],'manage_id');
$query->whereHas('logs', function ($q) use ($manageIdArr) {
$q->whereIn('engineer_id', $manageIdArr);
});
}
// 添加排序功能
$query->orderBy('status', 'asc');
// $query->orderBy('id', 'desc');
... ... @@ -192,6 +199,7 @@ class AsideTicketController extends BaseController
$ticket->star = $request->input('star', 3);
$ticket->plan_end_at = $request->input('plan_end_at', null);
$ticket->close_wechat = $request->input('close_wechat', false);
$ticket->num = $request->input('num', 0);
$ticket->save();
// 分配工单参与人
... ... @@ -249,6 +257,8 @@ class AsideTicketController extends BaseController
$ticket->plan_end_at = $request->input('plan_end_at');
if ($request->input('status'))
$ticket->status = $request->input('status');
if ($request->input('num'))
$ticket->num = $request->input('num',0);
if ($ticket->status == Tickets::STATUS_COMPLETED)
{
... ...
... ... @@ -559,7 +559,7 @@ class ProductController extends BaseController
if(!empty($v['og_image'])){
$v['og_image'] = getImageUrl($v['og_image'] ?? '',$this->user['storage_type'],$this->user['project_location']);
}else{
$v['og_image'] = $v['thumb']['url'] ?? '';
$v['og_image'] = '';
}
if(!empty($v['icon'])){
foreach ($v['icon'] as $icon_k => $icon_v){
... ...
... ... @@ -41,13 +41,20 @@ class WebSettingImageController extends BaseController
public function save(WebSettingImage $webSettingImage){
try {
foreach ($this->param['data'] as $v){
if(isset($v['id']) && !empty($v['id'])){
$v['image'] = str_replace_url($v['image']);
$webSettingImage->edit($v,['id'=>$v['id']]);
}else{
$v['project_id'] = $this->user['project_id'];
$v['image'] = str_replace_url($v['image']);
$webSettingImage->add($v);
$info = $webSettingImage->read(['type'=>$v['type']],'id');
if($info === false){
$v['project_id'] = $this->user['project_id'];
$v['image'] = str_replace_url($v['image']);
$webSettingImage->add($v);
}else{
$v['image'] = str_replace_url($v['image']);
$webSettingImage->edit($v,['id'=>$info['id']]);
}
}
}
}catch (\Exception $e){
... ...
... ... @@ -61,9 +61,9 @@ class TicketLogic extends BaseLogic
$dailyModel = new TicketDailyCount();
$dailyList = $dailyModel->list([],'date',['*'],'desc',5);//取最近5条数据
$manageModel = new TicketDailyManageCount();
$manageList = $manageModel->list(['date'=>$date],'average_time',['*'],'asc',5);//取最近5条数据
$manageList = $manageModel->list(['date'=>$date,'ticket_num'=>['!=',0],'average_time'=>['!=','']],'average_time',['*'],'asc',5);//取最近5条数据
$deptModel = new TicketDailyDeptCount();
$deptList = $deptModel->list(['date'=>$date],'average_time',['*'],'asc',5);
$deptList = $deptModel->list(['date'=>$date,'ticket_num'=>['!=',0]],'average_time',['*'],'asc',5);
$data = ['daily'=>$dailyList,'manage'=>$manageList,'dept'=>$deptList];
return $this->success($data);
}
... ...
... ... @@ -3,6 +3,7 @@
namespace App\Http\Logic\Bside\HomeCount;
use App\Helper\FormGlobalsoApi;
use App\Http\Logic\Bside\BaseLogic;
use App\Models\Template\BCustomTemplate;
use App\Models\Visit\Visit;
... ... @@ -14,6 +15,7 @@ use App\Models\Project\Project;
use App\Models\RankData\RankData as RankDataModel;
use App\Models\Service\Service;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
class CountLogic extends BaseLogic
... ... @@ -41,6 +43,17 @@ class CountLogic extends BaseLogic
$info = $this->model->read(['project_id' => $this->user['project_id']],
['pv_num','ip_num','inquiry_num','date','compliance_day','service_day','country']);
}
$inquiry_num = Cache::get('inquiry_num_'.$this->user['project_id']);
if(empty($inquiry_num)){
$domain = parse_url($this->user['domain'], PHP_URL_HOST); // 直接取域名部分
$inquiry_list = (new FormGlobalsoApi())->getInquiryAll($domain,$this->user['is_upgrade']);
if($inquiry_list !== false){
if($inquiry_list['status'] != 400){
$info['inquiry_num'] = $inquiry_list['data']['count'];
Cache::add('inquiry_num_'.$this->user['project_id'],$inquiry_list['data']['count'],3600);
}
}
}
//获取项目的剩余时长
$projectModel = new Project();
$projectInfo = $projectModel->read(['id'=>$this->user['project_id']],['remain_day','finish_remain_day']);
... ...
... ... @@ -111,7 +111,7 @@ class RankDataLogic extends BaseLogic
$lang_data = Arr::setValueToKey($lang_data, 'language');
$data['langs'] = [];
$languageModel = new MinorLanguages();
$languageList = $languageModel->list(['project_id'=>$project['id']]);
$languageList = $languageModel->list(['project_id'=>$project['id'], 'is_delete' => 0]);
if(!empty($languageList) && is_array($languageList)){
foreach($languageList as $lang){
if($lang['lang'] =='ja'){
... ...
... ... @@ -292,12 +292,14 @@ class UserLoginLogic
$info['project_location'] = $project['project_location'];
$info['file_cdn'] = $project['deploy_build']['file_cdn'];
$info['service_duration'] = $project['deploy_build']['service_duration'] ?? 0;
$info['seo_service_duration'] = $project['deploy_build']['seo_service_duration'] ?? 0;
$info['is_comment'] = $project['deploy_build']['is_comment'] ?? 0;
$info['is_ai_blog_send'] = $project['deploy_optimize']['is_ai_blog_send'] ?? 0;
$info['tech_leader'] = $project['deploy_optimize']['tech_leader'] ?? 0;
$manageModel = new ManageHr();
$info['tech_leader_name'] = $manageModel->getName($project['deploy_optimize']['tech_leader'] ?? 0);
$info['remain_day'] = $project['remain_day'] ?? 0;
$info['seo_remain_day'] = $project['seo_remain_day'] ?? 0;
$info['project_created_at'] = $project['created_at'];
$info['type'] = $project['type'] ?? 1;
if($info['is_customized'] == 1){
... ...
... ... @@ -27,4 +27,9 @@ class TicketDailyCount extends Base
{
return Arr::s2a($value);
}
public function getSourceTypeAttribute($value)
{
return Arr::s2a($value);
}
}
... ...
... ... @@ -28,6 +28,7 @@ class MessagePush extends Base
const TYPE_INQUIRY = 'inquiry';
const TYPE_WEEK = 'week';
const TYPE_TICKET = 'Ticket';
const TYPE_DOMAIN = 'domain';
//设置关联表名
/**
* @var mixed
... ...