作者 刘锟

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

正在显示 42 个修改的文件 包含 1357 行增加125 行删除
... ... @@ -43,7 +43,9 @@ class RemainDay extends Command
1893,
2066,
2250,
2193
2193,
2399,
1685
];//需要单独处理的项目
/**
* The console command description.
... ...
<?php
namespace App\Console\Commands\Inquiry;
use App\Models\Domain\DomainInfo;
use App\Models\Inquiry\ReInquiryCount;
use Illuminate\Console\Command;
/**
* Class FBInquiryRemainDay
* @package App\Console\Commands\Inquiry
*/
class FBInquiryRemainDay extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'fb_inquiry_remain_day';
/**
* The console command description.
*
* @var string
*/
protected $description = '执行询盘请求';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
public function handle()
{
$list = ReInquiryCount::all();
foreach ($list as $item){
$this->output('start:' . $item['id']);
$tasks = $item->tasks; //调用访问器
$is_v6 = 0;
foreach ($tasks as $task){
if($task['is_v6']){
$is_v6 = 1;
}
}
if($is_v6){
$project_id = DomainInfo::where('domain', $item['domain'])->value('project_id') ?: 0;
}else{
$project_id = 0;
}
//获取剩余天数
$remaining_days = ReInquiryCount::getRemainingDays($item['domain'], $item['type'], $project_id);
$item->remaining_days = $remaining_days;
$item->save();
}
}
public function output($message)
{
echo date('Y-m-d H:i:s') . ' | ' . $message . PHP_EOL;
}
}
... ...
... ... @@ -28,6 +28,7 @@ use App\Models\RouteMap\RouteMap;
use App\Models\Template\BTemplateMain;
use App\Models\Template\TemplateTypeMain;
use App\Models\Visit\Visit;
use App\Models\WebSetting\TranslateBigProject;
use App\Models\WebSetting\WebLanguage;
use App\Models\WebSetting\WebSetting;
use App\Models\Workchat\MessagePush;
... ... @@ -56,40 +57,26 @@ class lyhDemo extends Command
protected $description = '更新路由';
public function handle(){
$projectModel = new Project();
$lists = $projectModel->list(['delete_status' => 0,'project_type'=>0,'extend_type'=>0,'type'=>['in',[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']);
$authorModel = new AiBlogAuthor();
$author_list = $authorModel->list(['id'=>['>',0]]);
if(empty($author_list)){
echo '跳过的项目id:'.$item['id'].PHP_EOL;
DB::disconnect('custom_mysql');
continue;
}
$projectAiSettingModel = new ProjectAiSetting();
$aiSettingInfo = $projectAiSettingModel->read(['project_id'=>$item['id']]);
if($aiSettingInfo === false){
echo '跳过的项目id:'.$item['id'].PHP_EOL;
DB::disconnect('custom_mysql');
continue;
}
$aiBlogService = new AiBlogService($item['id']);
foreach ($author_list as $val){
$aiBlogService->author_id = $val['author_id'];
$result = $aiBlogService->getAuthorDetail();
if(isset($result['status']) && $result['status'] == 200){
//当前作者的页面
$aiBlogAuthorModel = new AiBlogAuthor();
$authorInfo = $aiBlogAuthorModel->read(['author_id'=>$val['author_id']],['id','route']);
if($authorInfo !== false && !empty($result['data']['section'])){
$aiBlogAuthorModel->edit(['text'=>$result['data']['section']],['author_id'=>$val['author_id']]);
}
}
}
DB::disconnect('custom_mysql');
$str = '3671,955,752,1270,439,2674,3588,2388,1271,1543,738,624,552,1417,1237,651,1143,817,1556,1234,1350,650,538,491,631,2059,1845,866,1194,1699,546,684,905,1805,1728,2811,952,2972,2827,983,812,3081,554,741,1349,980';
$arr = explode(',',$str);
$model = new TranslateBigProject();
foreach ($arr as $val){
$model->addReturnId(['project_id'=>$val]);
}
return true;
// $projectModel = new Project();
// $lists = $projectModel->list(['delete_status' => 0,'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']);
// $webSettingModel = new WebSetting();
// $info = $webSettingModel->read(['project_id'=>$item['id']]);
// if($info === false){
// $webSettingModel->addReturnId(['project_id'=>$item['id']]);
// echo '当前数据为空:'.$item['id'].PHP_EOL;
// }
// DB::disconnect('custom_mysql');
// }
}
public function _actionTemplateMain(){
... ...
<?php
/**
* @remark :
* @name :InitKeywordComment.php
* @author :lyh
* @method :post
* @time :2025/6/3 15:38
*/
namespace App\Console\Commands\Project;
use App\Helper\Common;
use App\Helper\Gpt;
use App\Models\Ai\AiCommand;
use App\Models\Com\NoticeLog;
use App\Models\Project\AggregateKeywordComment;
use App\Models\Project\Project;
use Illuminate\Console\Command;
class InitKeywordComment extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'init_keyword_comment';
/**
* The console command description.
*
* @var string
*/
protected $description = '初始化关键字评论';
public $number = 100;
public function handle(){
return $this->_action(467);
while (true){
$list = NoticeLog::where('type', NoticeLog::TYPE_INIT_KEYWORD_COMMON)->where('status', NoticeLog::STATUS_PENDING)->get();
if(empty($list)){
sleep(200);
continue;
}
foreach ($list as $item){
echo date('Y-m-d H:i:s').'start:' . $item['id'] . PHP_EOL;
$project_id = $item['data']['project_id'];
echo date('Y-m-d H:i:s').'执行的项目id:' . $project_id . PHP_EOL;
try {
$this->_action($project_id);
$count = $keywordCommonModel->counts(['project_id'=>$project_id]);
if($count > 100){
$item->status = NoticeLog::STATUS_SUCCESS;
$item->save();
}
}catch (\Exception $e){
echo date('Y-m-d H:i:s').'错误信息:'.$e->getMessage().PHP_EOL;
continue;
}
echo date('Y-m-d H:i:s').'end:' . $item['id'] . PHP_EOL;
}
}
return true;
}
/**
* @remark :执行的方法
* @name :_action
* @author :lyh
* @method :post
* @time :2025/6/3 15:42
*/
public function _action($project_id){
$aiCommonModel = new AiCommand();
$info = $aiCommonModel->read(['key'=>'tag_comment']);
$text = Gpt::instance()->openai_chat_qqs($info['ai']);
$text = Common::deal_keywords($text);
preg_match_all('/\{[^{}]*\}/', $text, $matches);
if(!empty($text)){
$data = [];
foreach ($matches[0] as $item){
$item = str_replace("'", '"', $item);
// 解码成 PHP 关联数组
$item = json_decode($item, true);
if(!isset($item['name']) || !isset($item['comment'])){
continue;
}
$data[] = [
'nickname'=>$item['name'],
'text'=>$item['comment'],
'project_id'=>$project_id,
'type'=>1,
'uid'=>0,
'created_at'=>date('Y-m-d H:i:s'),
'updated_at'=>date('Y-m-d H:i:s')
];
}
$keywordCommonModel = new AggregateKeywordComment();
$keywordCommonModel->insertAll($data);
}
return true;
}
}
... ...
<?php
namespace App\Console\Commands;
use App\Models\WorkOrder\WorkOrderLog;
use App\Services\DingTalkService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Http;
class WorkOrderDing extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'workorder:ding';
/**
* The console command description.
*
* @var string
*/
protected $description = '售后工单钉钉通知';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
while (true) {
try {
$log = WorkOrderLog::where('ding', 0)->first();
if (!$log) {
sleep(3);
continue;
}
$mobile = $log->manager->mobile;
$response = Http::withBasicAuth(
env('DINGDING_BASIC_USER'),
env('DINGDING_BASIC_PASS')
)->get('https://oa.cmer.com/api/dingding/user/' . $mobile);
if ($response->status() == 200) {
$userid = $response->json()['data']['userid'];
$text = "**您有新的售后工单**<br>";
$text .= "工单ID:{$log->work_order_id}<br>";
$text .= "工单类型:<font color='red'>{$log->workOrder->product}</font><br>";
$text .= "项目:{$log->workOrder->project->title}<br>";
$text .= "时间:{$log->created_at}<br>";
$ding = new DingTalkService();
$resp = $ding->danliao(json_encode([
'text' => $text,
'title' => '售后工单通知',
]), [$userid]);
$log->ding = 1;
}else
$log->ding = 2;
$log->save();
}catch (\Exception $exception){
echo date('Y-m-d H:i:s')." ".$exception->getMessage()."\n";
break;
}
}
}
}
... ...
... ... @@ -39,6 +39,8 @@ class Kernel extends ConsoleKernel
$schedule->command('sync_ad_cost')->everyThirtyMinutes()->withoutOverlapping(1);
// 优化预设关键词 同步 20点会开始TDK生成
$schedule->command('optimize_set_keyword_sync')->dailyAt('20:00')->withoutOverlapping(1);
//FB询盘剩余时间
$schedule->command('fb_inquiry_remain_day')->dailyAt('02:00')->withoutOverlapping(1);
}
/**
... ...
... ... @@ -310,4 +310,25 @@ class QuanqiusouApi
}
}
/**
* 获取代理信息
* @param $domain
* @return array|mixed
* @author zbj
* @date 2024/10/26
*/
public function getV5RemainDay($domain){
$token = md5($domain.'qqs');
try {
$client = new \GuzzleHttp\Client();
$res = $client->request('GET', 'https://quanqiusou.cn/extend_api/api/get_remain_day_by_domain.php?'.http_build_query(['token' => $token, 'domain' => $domain]), [
'proxy' => env('CURL_PROXY'), // 代理服务器地址和端口号
])->getBody()->getContents();
return Arr::s2a($res);
} catch (\Exception | GuzzleException $e) {
errorLog('获取代理失败', [$domain], $e);
return [];
}
}
}
... ...
... ... @@ -879,7 +879,7 @@ function getRouteMap($source,$source_id,$is_upgrade = 0, $returnModel = false){
$route = $info['route'];
}
}
if($returnModel){
if($returnModel && ($info !== false)){
return $info;
}
return $route;
... ...
... ... @@ -35,6 +35,18 @@ class DomainApplicantLogController extends BaseController
}
/**
* @remark :获取详情
* @name :info
* @author :lyh
* @method :post
* @time :2025/5/30 14:35
*/
public function info(){
$lists = $this->logic->info();
$this->response('success',Code::SUCCESS,$lists);
}
/**
* @remark :保存数据
* @name :save
* @author :lyh
... ...
... ... @@ -400,7 +400,6 @@ class AdsController extends BaseController
}else{
$item['project_id'] = 0;
}
}
return $this->response('success', Code::SUCCESS, $result);
... ...
<?php
namespace App\Http\Controllers\Aside\WorkOrder;
use App\Enums\Common\Code;
use App\Http\Controllers\Aside\BaseController;
use App\Http\Requests\Aside\WorkOrder\WorkOrderListRequest;
use App\Http\Requests\Aside\WorkOrder\WorkOrderUpdateRequest;
use App\Models\WorkOrder\WorkOrder;
use App\Models\WorkOrder\WorkOrderLog;
use Illuminate\Support\Facades\DB;
class WorkOrderController extends BaseController
{
/**
* A端工单列表
* 显示有我参与的工单列表
*/
public function index(WorkOrderListRequest $request)
{
/*
* A端工程师工单列表, 查询我的工单
*/
$request->validated();
# manage_id 或 engineer_id 是我
$lists = WorkOrderLog::with([
'workOrder.logs.manager:id,name',
'workOrder.project:id,company,title',
])
->where('manage_id', $this->manage['id'])
->when($request->input('project_id') !== null, function ($query) use ($request) {
// project_id 查 workOrder
return $query->whereHas('workOrder', function ($q) use ($request) {
$q->where('project_id', $request->input('project_id'));
});
})
->when($request->input('status') !== null, function ($query) use ($request) {
// status 查 workOrder
return $query->whereHas('workOrder', function ($q) use ($request) {
$q->where('status', $request->input('status'));
});
})
->when($request->input('search'), function ($query) use ($request) {
// search 查 workOrder
return $query->whereHas('workOrder', function ($q) use ($request) {
$q->where('product', 'like', '%' . $request->input('search') . '%')
->orWhere('content', 'like', '%' . $request->input('search') . '%');
});
})
->orderBy('id', 'desc')
->paginate($this->row, ['*'], 'page', $this->page);
$this->response('success', Code::SUCCESS, $lists);
}
/**
* @param WorkOrderListRequest $request
* @return void
* A端管理员的工单列表
*/
public function manager(WorkOrderListRequest $request)
{
$request->validated();
// 管理员查看所有工单
$lists = WorkOrder::with([
'user:id,name',
'manager:id,name',
'engineer:id,name',
'logs.manager:id,name',
'project:id,company:title',
])
->when($request->input('project_id') !== null, function ($query) use ($request) {
return $query->where('project_id', $request->input('project_id'));
})
->when($request->input('status') !== null, function ($query) use ($request) {
return $query->where('status', $request->input('status'));
})
->when($request->input('search'), function ($query) use ($request) {
return $query->where('product', 'like', '%' . $request->input('search') . '%')
->orWhere('content', 'like', '%' . $request->input('search') . '%');
})
->orderBy('id', 'desc')
->paginate($this->row, ['*'], 'page', $this->page);
$this->response('success', Code::SUCCESS, $lists);
}
/**
* A端工单详情
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$workOrder = WorkOrder::with([
'logs.manager:id,name',
'user:id,name',
'manager:id,name',
'engineer:id,name',
'project:id,company:title',
])->find($id);
if (!$workOrder)
$this->response('工单不存在', Code::USER_MODEL_NOTFOUND_ERROE);
// TODO 判断是否有查看工单详情权限,待添加
$this->response('success', Code::SUCCESS, $workOrder->toArray());
}
/**
* A端操作工单,工程师操作的是工单日志
* - 工程师:回复工单,自动��拆分给自己的子任务改为完成
* - 工单第一对接人:
* - 邀请工程师处理工单
* - 修改工单状态
* 若全部子任务完成,则将工单状态改为完成
*/
public function update(WorkOrderUpdateRequest $request, $id)
{
$request->validated();
$log = WorkOrderLog::find($id); // 拆分的子工单
if (!$log) {
$this->response('工单不存在', Code::USER_MODEL_NOTFOUND_ERROE);
}
if ($log->manage_id != $this->manage['id']) {
// 只能操作自己的工单
$this->response('没有权限操作该工单', Code::USER_PERMISSION_ERROE);
}
$workOrder = $log->workOrder;
$result = DB::transaction(function () use ($request, $workOrder, $log) {
if ($request->input('engineer_ids'))
{
// 有邀请工程师协同处理
foreach ($request->input('engineer_ids') as $engineer_id)
{
try {
// 利用唯一索引去重
$new_log = new WorkOrderLog();
$new_log->manage_id = $engineer_id;
$workOrder->logs()->save($new_log);
$workOrder->engineer_id = $engineer_id;
$workOrder->save();
}catch (\Exception $exception){}
}
}
if ($request->input('content'))
$log->content = $request->input('content');
if ($request->input('files'))
$log->files = $request->input('files');
if ($request->input('status') !== null)
{
$log->status = $request->input('status');
if ($log->status == WorkOrder::STATUS_COMPLETED)
{
// 我的工单标记为已完成
$log->status = WorkOrderLog::STATUS_COMPLETED;
$log->end_at = now();
}
}
$log->save();
// 是否有未完成的子任务
$pending = $workOrder->logs()
->where('status', '<', WorkOrderLog::STATUS_COMPLETED)
->count();
$workOrder->status = $pending == 0 ? WorkOrderLog::STATUS_COMPLETED : WorkOrderLog::STATUS_PROCESSING;
$workOrder->save();
return $log;
});
$this->response('success', Code::SUCCESS, $result->toArray());
}
}
... ...
... ... @@ -143,9 +143,15 @@ class AyrShareController extends BaseController
$data = [
'profileKey'=>$info['profile_key']
];
$res = $ayrShareHelper->post_generate_jwt($data);
if($res['status'] == 'fail'){
$this->response($res['message'],Code::USER_ERROR);
try {
$res = $ayrShareHelper->post_generate_jwt($data);
if($res['status'] == 'fail'){
$ayrShareLogic->ayr_share_edit(['profile_key'=>null,'bind_platforms'=>null,'ref_id'=>null],$info['id']);
$this->response('当前key值已过期,请刷新重新绑定',Code::USER_ERROR);
}
}catch (\Exception $e){
$ayrShareLogic->ayr_share_edit(['profile_key'=>null,'bind_platforms'=>null,'ref_id'=>null],$info['id']);
$this->response('当前key值已过期,请刷新重新绑定',Code::USER_ERROR);
}
$this->response('success',Code::SUCCESS,$res);
}
... ...
... ... @@ -34,6 +34,7 @@ use App\Models\Project\Country as CountryModel;
use App\Models\Project\Project;
use App\Models\RouteMap\RouteMap;
use App\Models\WebSetting\SettingNum;
use App\Models\WebSetting\TranslateBigProject;
use App\Models\WebSetting\WebLanguage;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
... ... @@ -61,7 +62,8 @@ class CNoticeController extends BaseController
],[
'language.required' => 'language不能为空',
]);
$project_id_arr = explode(',',env('PROJECT_ID')) ?? [];
$bigProjectModel = new TranslateBigProject();
$project_id_arr = $bigProjectModel->selectField(['status'=>1],'project_id') ?? [];
if(in_array($this->user['project_id'],$project_id_arr)){
$this->response('success');
}
... ...
... ... @@ -62,8 +62,8 @@ class ProductController extends BaseController
$userModel = new User();
foreach ($lists['list'] as $k=>$v){
$route = getRouteMap(RouteMap::SOURCE_PRODUCT,$v['id'], 0, true);
$v['url'] = $this->user['domain'] . $route['route'];
$v['pv'] = $route['pv'];
$v['url'] = $this->user['domain'] . ($route['route'] ?? '');
$v['pv'] = $route['pv'] ?? '';
$v['category_id_text'] = $this->categoryName($v['id'],$cate_data);
$v['keyword_id_text'] = $this->keywordName($v['keyword_id'],$key_data);
$v['created_uid_text'] = $userModel->getName($v['created_uid']);
... ...
<?php
namespace App\Http\Controllers\Bside\WorkOrder;
use App\Enums\Common\Code;
use App\Http\Controllers\Bside\BaseController;
use App\Http\Requests\Aside\WorkOrder\WorkOrderListRequest;
use App\Http\Requests\Bside\WorkOrder\WorkOrderCreateRequest;
use App\Http\Requests\Bside\WorkOrder\WorkOrderUpdateRequest;
use App\Models\Project\Project;
use App\Models\WorkOrder\WorkOrder;
use App\Models\WorkOrder\WorkOrderLog;
use Illuminate\Support\Facades\DB;
class WorkOrderController extends BaseController
{
/**
* B端售后工单列表
*
* @return \Illuminate\Http\Response
*/
public function index(WorkOrderListRequest $request)
{
$request->validated();
$where = [
'project_id' => $this->user['project_id'],
];
// 分页查询
$lists = WorkOrder::with([
'manager:id,name',
])
->where($where)
->when($request->input('status'), function ($query) use ($request) {
return $query->where('status', $request->input('status'));
})
->when($request->input('search'), function ($query) use ($request) {
return $query->where('product', 'like', '%' . $request->input('search') . '%')
->orWhere('content', 'like', '%' . $request->input('search') . '%');
})
->orderBy('id', 'desc')->paginate($this->row, ['*'], 'page', $this->page);
$this->response('success', Code::SUCCESS, $lists);
}
/**
* B端用户提交工单
*
* @return \Illuminate\Http\Response
*/
public function store(WorkOrderCreateRequest $request)
{
$request->validated();
$result = DB::transaction(function () use ($request) {
$workOrder = new WorkOrder;
$workOrder->product = $request->input('product');
$workOrder->content = $request->input('content');
$workOrder->files = json_encode($request->input('files'));
$workOrder->project_user_id = $this->user['id'];
$workOrder->project_id = $this->user['project_id'];
$workOrder->engineer_id = 0;
if ($this->project['type'] == 3){
// 项目类型是优化推广,项目负责人找优化
$seo = Project::find($this->user['project_id'])->deploy_optimize;
$workOrder->manage_id = $seo->manager_mid ?? $seo->optimist_mid ?? 0;
}else{
// 非优化推广项目,项目负责人找技术组长
$build = Project::find($this->user['project_id'])->deploy_build;
$workOrder->manage_id = $build->leader_mid ?? 0;
}
$workOrder->save();
// 添加工单日志
$log = new WorkOrderLog();
$log->manage_id = $workOrder->manage_id;
$workOrder->logs()->save($log);
return $workOrder;
});
$this->response('success', Code::SUCCESS, $result->toArray());
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
$workOrder = WorkOrder::with([
'logs.manager:id,name',
'user:id,name',
'manager:id,name',
'engineer:id,name',
])->find($id);
if (!$workOrder) {
$this->response('工单未找到', 404);
}
if ($workOrder->project_id != $this->user['project_id'] && $workOrder->engineer_id != $this->user['id']) {
$this->response('无权限查看该工单', 403);
}
$this->response('success', Code::SUCCESS, $workOrder->toArray());
}
/**
* B端用户修改工单,只能是修改工单状态
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(WorkOrderUpdateRequest $request, $id)
{
$request->validated();
$workOrder = WorkOrder::find($id);
if (!$workOrder) {
$this->response('工单未找到', 404);
}
// b端只有自己项目下的账号可以更新工单
if ($workOrder->project_id != $this->user['project_id']) {
$this->response('无权限更新该工单', 403);
}
// 更新工单状态
$workOrder->status = WorkOrder::STATUS_COMPLETED;
$workOrder->save();
// B端完成工单,将所有子任务标记为完成
$workOrder->logs()->update(['status' => WorkOrderLog::STATUS_COMPLETED]);
$this->response('success', Code::SUCCESS);
}
public function destroy($id)
{
$workOrder = WorkOrder::find($id);
if (!$workOrder) {
$this->response('工单未找到', 404);
}
if ($workOrder->status >= WorkOrder::STATUS_COMPLETED)
$this->response('已完结的工单不能删除', 403);
if ($this->user['type'] != 1 && $workOrder->project_user_id != $this->user['id']) {
// 只有项目负责人可以删除工单
$this->response('无权限删除该工单', 403);
}
# 删除工单
$workOrder->delete();
$this->response('工单已删除', Code::SUCCESS);
}
}
... ...
... ... @@ -514,22 +514,22 @@ class ImageController extends Controller
foreach ($files as $file){
if(isset($this->cache['image_max']) && ($this->cache['image_max'] != 0)){
if ($file->getSize() > $this->cache['image_max'] * 1024) {
$this->response('图片最大为'.$this->cache['image_max'],Code::SYSTEM_ERROR);
$this->response('图片最大为'.$this->cache['image_max'].'k',Code::SYSTEM_ERROR);
}
}else{
if ($file->getSize() > $max) {
$this->response('图片最大为1024K',Code::SYSTEM_ERROR);
$this->response('图片最大为2m',Code::SYSTEM_ERROR);
}
}
}
}else{
if(isset($this->cache['image_max']) && ($this->cache['image_max'] != 0)){
if ($files->getSize() > $this->cache['image_max'] * 1024) {
$this->response('图片最大为'.$this->cache['image_max'],Code::SYSTEM_ERROR);
$this->response('图片最大为'.$this->cache['image_max'].'k',Code::SYSTEM_ERROR);
}
}else{
if ($files->getSize() > $max) {
$this->response('图片最大为1024K',Code::SYSTEM_ERROR);
$this->response('图片最大为2m',Code::SYSTEM_ERROR);
}
}
}
... ...
... ... @@ -29,11 +29,32 @@ class DomainApplicantLogLogic extends BaseLogic
* @time :2025/5/29 14:34
*/
public function lists($map,$page,$row){
if(isset($map['domain']) && !empty($map['domain'])){
$map['domain'] = ['like','%'.$map['domain'].'%'];
}
if(isset($map['applicant_name']) && !empty($map['applicant_name'])){
$map['applicant_name'] = ['like','%'.$map['applicant_name'].'%'];
}
if(isset($map['operator_name']) && !empty($map['operator_name'])){
$map['operator_name'] = ['like','%'.$map['operator_name'].'%'];
}
$lists = $this->model->lists($map,$page,$row,'id',['*']);
return $this->success($lists);
}
/**
* @remark :获取详情
* @name :info
* @author :lyh
* @method :post
* @time :2025/5/30 14:35
*/
public function info(){
$lists = $this->model->read($this->param);
return $this->success($lists);
}
/**
* @remark :保存域名申请记录
* @name :saveDomainLog
* @author :lyh
... ...
... ... @@ -553,7 +553,7 @@ class RankDataLogic extends BaseLogic
$without_extension_project_ids = [658]; //是否达标只统计主词的
$extension_project_ids = [354]; //扩展词也到达标的
$compliance_project_ids = [2163,257,823,1750,497]; //直接达标处理的
$ceaseProjectId = [354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250,2193];//暂停的项目
$ceaseProjectId = [354, 378, 649, 1226, 1283, 1703, 1893, 2066, 2250,2193,2399,1685];//暂停的项目
$uptimeProjectId = [1434,1812,276,2414,2974];//按上线时间统计的项目
//一个项目多个api_no
$multiple_api_no_project_ids = [
... ...
... ... @@ -24,7 +24,8 @@ class WebSettingLogic extends BaseLogic
public function setting_read(){
$info = $this->model->read(['project_id'=>$this->user['project_id']]);
if($info === false){
$info = [];
$this->model->addReturnId(['project_id'=>$this->user['project_id']]);
$info =$this->model->read(['project_id'=>$this->user['project_id']]);
}
return $this->success($info);
}
... ...
... ... @@ -7,6 +7,7 @@ use App\Exceptions\AsideGlobalException;
use App\Exceptions\BsideGlobalException;
use App\Helper\Common;
use App\Models\Domain\DomainInfo;
use App\Models\Manage\ManageHr;
use App\Models\Project\Project;
use App\Models\Scoring\ScoringSystem;
use App\Models\Sms\SmsLog;
... ... @@ -292,6 +293,9 @@ class UserLoginLogic
$info['service_duration'] = $project['deploy_build']['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['project_created_at'] = $project['created_at'];
$info['type'] = $project['type'] ?? 1;
... ...
<?php
namespace App\Http\Requests\Aside\WorkOrder;
use Illuminate\Foundation\Http\FormRequest;
class WorkOrderListRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'page' => 'nullable|integer',
'size' => 'nullable|integer',
'project_id' => 'nullable|integer', // 产品ID
'status' => 'nullable|in:0,1,2,3|integer',
'search' => 'nullable|string', // 搜索关键词
];
}
}
... ...
<?php
namespace App\Http\Requests\Aside\WorkOrder;
use Illuminate\Foundation\Http\FormRequest;
class WorkOrderUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
* A端更新售后工单
*/
public function rules()
{
return [
'status' => 'nullable|in:0,1,2,3|integer',
'engineer_ids' => 'nullable|array',
'content' => 'nullable|string',
'files' => 'nullable|array',
];
}
}
... ...
<?php
namespace App\Http\Requests\Bside\WorkOrder;
use Illuminate\Foundation\Http\FormRequest;
class WorkOrderCreateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'product' => 'required|string',
'content' => 'required|string',
'files' => 'nullable|array',
];
}
}
... ...
<?php
namespace App\Http\Requests\Bside\WorkOrder;
use Illuminate\Foundation\Http\FormRequest;
class WorkOrderUpdateRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'status' => 'nullable|in:0,1,2,3|integer',
'engineer_ids' => 'nullable|array',
'content' => 'nullable|string',
'files' => 'nullable|array',
];
}
}
... ...
... ... @@ -13,6 +13,7 @@ class NoticeLog extends Base
const TYPE_PROJECT = 'project';
const TYPE_RANK_DATA = 'rank_data';
const TYPE_INIT_PROJECT = 'init_project';
const TYPE_INIT_KEYWORD_COMMON = 'init_keyword_common';//聚合页关键词评论
const TYPE_COPY_PROJECT = 'copy_project';
const TYPE_INIT_KEYWORD = 'init_keyword';
const DELETE_PRODUCT_CATEGORY = 'delete_product_category';
... ...
... ... @@ -103,4 +103,22 @@ class ReInquiryCount extends Base
}
return $res;
}
public static function getRemainingDays($domain, $type, $project_id)
{
$cache_key = 're_inquiry_count_' . $domain . '_' . date('Ymd');
$data = Cache::get($cache_key);
if($data === null){
if($project_id){
$data = Project::where('id', $project_id)->value('remain_day');
}else if($type == 3){
$data = '-';
}else{
$res = (new QuanqiusouApi())->getV5RemainDay($domain);
$data = $res['data']['remain_day'] ??'-';
}
Cache::put($cache_key, $data, 24 * 3600);
}
return $data;
}
}
... ...
<?php
/**
* @remark :
* @name :AggregateKeywordComment.php
* @author :lyh
* @method :post
* @time :2025/6/3 17:42
*/
namespace App\Models\Project;
use App\Models\Base;
class AggregateKeywordComment extends Base
{
protected $table = 'gl_aggregate_keyword_comment';
}
... ...
... ... @@ -60,6 +60,8 @@ class Project extends Base
5 => 'Q告知书二',
6 => 'KA',
7 => 'CKA',
18 => '白帽V1(AI视频)',
19 => '白帽V2(保证排名)',
];
}
... ...
<?php
/**
* @remark :
* @name :TranslateBigProject.php
* @author :lyh
* @method :post
* @time :2025/6/4 14:40
*/
namespace App\Models\WebSetting;
use App\Models\Base;
/**
* @remark :需要翻译的大网站
* @name :TranslateBigProject
* @author :lyh
* @method :post
* @time :2025/6/4 14:41
*/
class TranslateBigProject extends Base
{
protected $table = 'gl_translate_big_project';
}
... ...
<?php
namespace App\Models\WorkOrder;
use App\Models\Base;
use App\Models\Manage\Manage;
use App\Models\Project\Project;
use App\Models\User\User;
class WorkOrder extends Base
{
protected $table = 'gl_work_orders';
const STATUS_PEDDING = 0; // 待处理
const STATUS_PROCESSING = 1; // 处理中
const STATUS_COMPLETED = 2; // 已完成
const STATUS_CLOSED = 3; // 已关闭
/**
* 工单操作日志
*/
public function logs()
{
return $this->hasMany(WorkOrderLog::class, 'work_order_id', 'id');
}
/**
* 提交工单的用户
*/
public function user()
{
return $this->belongsTo(User::class, 'project_user_id', 'id');
}
/**
* 工单分配的管理员
*/
public function manager()
{
return $this->belongsTo(Manage::class, 'manage_id', 'id');
}
/**
* 工单分配的工程师
*/
public function engineer()
{
return $this->belongsTo(Manage::class, 'engineer_id', 'id');
}
/** 工单所属项目 */
public function project()
{
return $this->belongsTo(Project::class, 'project_id', 'id');
}
}
... ...
<?php
namespace App\Models\WorkOrder;
use App\Models\Base;
use App\Models\Manage\Manage;
class WorkOrderLog extends Base
{
protected $table = 'gl_work_order_logs';
const STATUS_PEDDING = 0; // 待处理
const STATUS_PROCESSING = 1; // 处理中
const STATUS_COMPLETED = 2; // 已完成
const STATUS_CLOSED = 3; // 已关闭
/**
* 所属工单
*/
public function workOrder()
{
return $this->belongsTo(WorkOrder::class, 'work_order_id');
}
/**
* 分配的工单负责人,工程师等
*/
public function manager()
{
return $this->belongsTo(Manage::class, 'manage_id', 'id');
}
}
... ...
<?php
/**
* @remark :
* @name :AiCommandService.php
* @author :lyh
* @method :post
* @time :2025/5/26 17:01
*/
namespace App\Services;
/**
* @remark :AI指令返回数据
* @name :AiCommandService
* @author :lyh
* @method :post
* @time :2025/5/26 17:01
* Class AiCommandService
* @package App\Services
*/
class AiCommandService
{
... ... @@ -22,16 +11,22 @@ class AiCommandService
public $api_key = 'nnLsyr3IhPNsJt5OvTtD9SVCLEixMntg';
/**
* @var string gemini 模型
* https://gemini.google.com/app
* gemini-2.0-flash-lite
* gemini-2.5-pro-preview-05-06
* gemini-2.5-flash-preview-05-20
* gemini-2.5-flash-preview-04-17
*/
public $model = 'gemini-2.0-flash-lite';
public $supplier = 'google';
/**
* @remark :Ai一键排版
* @name :ai_click_layout
* @author :lyh
* @method :post
* @time :2025/5/26 17:03
* AI排版
* @param $content
* @return array
*/
public function send_layout_design($content){
$param = [
... ...
<?php
namespace App\Services;
use App\DingDepartment;
use App\DingUser;
/**
* 文档 https://apihub.cmer.com/docs/cmerdingtalk.html
*/
class DingTalkService
{
protected $appKey;
protected $appSecret;
protected $robotCode;
protected $headers = [];
protected $bashUrl = 'https://api.cmer.com';
public function __construct()
{
$this->appKey = env('DING_TALK_APP_KEY');
$this->appSecret = env('DING_TALK_APP_SECRET');
$this->robotCode = env('DING_TALK_APP_KEY');
$this->headers = [
"Content-Type" => "application/json",
"apikey" => "UkzZljFv83Z2qBi5YR1o3f2otAVWtug6",
"X-CmerApi-Host" => "cmerdingtalk.p.cmer.com",
];
}
/** 发起请求 */
public function send_request(string $method, string $url, array $payload = [], array $params = [])
{
$client = new \GuzzleHttp\Client();
$options = [
'headers' => $this->headers,
'json' => $payload
];
if (!empty($params))
$options['query'] = $params;
$response = $client->request($method, $url, $options);
return $response;
}
/** 批量发送私聊消息 */
public function danliao(string $text, array $user_ids)
{
$endpoint = '/v1/danliao';
$payload = [
"appKey" => $this->appKey,
"appSecret" => $this->appSecret,
"robotCode" => $this->robotCode,
"msg_param" => $text,
"user_ids" => $user_ids
];
return $this->send_request('POST', $this->bashUrl . $endpoint, $payload);
}
/** 批量发送Ding */
public function danliao_ding(string $text, array $user_ids)
{
$endpoint = '/v1/danliao_ding';
$payload = [
"appKey" => $this->appKey,
"appSecret" => $this->appSecret,
"robotCode" => $this->robotCode,
"content" => $text,
"receiver_user_id_list" => $user_ids
];
return $this->send_request('POST', $this->bashUrl . $endpoint, $payload);
}
}
... ...
... ... @@ -12,6 +12,7 @@
"beyondcode/laravel-websockets": "^1.14",
"doctrine/dbal": "^3.6",
"fruitcake/laravel-cors": "^2.0",
"g4t/swagger": "^4.0",
"guzzlehttp/guzzle": "^7.0.1",
"hashids/hashids": "^4.1",
"intervention/image": "^2.7",
... ...
<?php
return [
/*
|--------------------------------------------------------------------------
| API Title
|--------------------------------------------------------------------------
|
| The title of your API documentation.
|
*/
"title" => env("SWAGGER_TITLE", "Globalso V6 Api Documentation"),
/*
|--------------------------------------------------------------------------
| API Description
|--------------------------------------------------------------------------
|
| The description of your API.
|
*/
"description" => env("SWAGGER_DESCRIPTION", "Laravel autogenerate swagger"),
/*
|--------------------------------------------------------------------------
| API Email
|--------------------------------------------------------------------------
|
| The email associated with your API documentation.
|
*/
"email" => env("SWAGGER_EMAIL", "bill@ai.cc"),
/*
|--------------------------------------------------------------------------
| API Version
|--------------------------------------------------------------------------
|
| The version of your API.
|
*/
"version" => env("SWAGGER_VERSION", "3.0.7"),
/*
|--------------------------------------------------------------------------
| Documentation Auth
|--------------------------------------------------------------------------
|
| This options to enable documentation auth
|
*/
"enable_auth" => false,
"username" => "admin",
"password" => "pass",
"sesson_ttl" => 100000,
/*
|--------------------------------------------------------------------------
| Enable Response Schema
|--------------------------------------------------------------------------
|
| Whether to enable response schema or not.
|
*/
"enable_response_schema" => true,
"suggestions_select_input" => false,
"load_from_json" => false,
/*
|--------------------------------------------------------------------------
| Authentication Middlewares
|--------------------------------------------------------------------------
|
| List of middleware names used for authentication.
|
*/
"auth_middlewares" => [
"auth",
"auth:api",
"aloginauth",
"bloginauth",
],
/*
|--------------------------------------------------------------------------
| API URL
|--------------------------------------------------------------------------
|
| The URL path for accessing your API documentation.
|
*/
"url" => env("SWAGGER_URL", "swagger/documentation"),
/*
|--------------------------------------------------------------------------
| Issues URL
|--------------------------------------------------------------------------
|
| The URL path for accessing issues related to your API documentation.
|
*/
"issues_url" => env("SWAGGER_ISSUE_URL", "swagger/issues"),
/*
|--------------------------------------------------------------------------
| Enable Swagger
|--------------------------------------------------------------------------
|
| Whether Swagger is enabled or not.
|
*/
"enable" => env('SWAGGER_ENABLED', true),
/*
|--------------------------------------------------------------------------
| Show Prefix
|--------------------------------------------------------------------------
|
| List of prefixes to show in Swagger.
|
*/
"show_prefix" => [],
/*
|--------------------------------------------------------------------------
| Include Web Routes
|--------------------------------------------------------------------------
|
| If you want to includes web.php routes, then enable this
|
*/
"include_web_routes" => env('SWAGGER_INCLUDE_WEB_ROUTES', true),
/*
|--------------------------------------------------------------------------
| API Versions
|--------------------------------------------------------------------------
|
| List of versions to show in Swagger.
|
*/
"versions" => [
"all",
// "v1"
],
"default" => "all",
/*
|--------------------------------------------------------------------------
| Servers
|--------------------------------------------------------------------------
|
| List of servers associated with your API.
|
*/
"servers" => [
[
"url" => env("APP_URL"),
"description" => "localhost"
]
],
/*
|--------------------------------------------------------------------------
| Security Schemes
|--------------------------------------------------------------------------
|
| Security schemes used in your API.
|
*/
"security_schemes" => [
"APIKeyHeader" => [
"type" => "apiKey",
"name" => "token",
"in" => "header"
],
],
/*
|--------------------------------------------------------------------------
| Spatie Query Builder
|--------------------------------------------------------------------------
|
| Enable it if you using Spatie query builder package to add spatie filters in all GET routes.
|
*/
"spatie_query_builder" => false,
/*
|--------------------------------------------------------------------------
| Status
|--------------------------------------------------------------------------
|
| HTTP response statuses for various methods.
|
*/
"status" => [
"GET" => [
"200" => [
"description" => "Successful Operation",
],
"404" => [
"description" => "Not Found"
]
],
"POST" => [
"200" => [
"description" => "Successful Operation",
],
"422" => [
"description" => "Validation Issues"
]
],
"PUT" => [
"200" => [
"description" => "Successful Operation",
],
"404" => [
"description" => "Not Found"
],
"405" => [
"description" => "Validation exception"
]
],
"PATCH" => [
"200" => [
"description" => "Successful Operation",
],
"404" => [
"description" => "Not Found"
],
"405" => [
"description" => "Validation exception"
]
],
"DELETE" => [
"200" => [
"description" => "successful Operation",
],
"404" => [
"description" => "page Not Found"
]
],
],
];
... ...
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateFailedJobsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('failed_jobs', function (Blueprint $table) {
$table->id();
$table->string('uuid')->unique();
$table->text('connection');
$table->text('queue');
$table->longText('payload');
$table->longText('exception');
$table->timestamp('failed_at')->useCurrent();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('failed_jobs');
}
}
... ... @@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePersonalAccessTokensTable extends Migration
class CreateWorkOrdersTable extends Migration
{
/**
* Run the migrations.
... ... @@ -13,15 +13,21 @@ class CreatePersonalAccessTokensTable extends Migration
*/
public function up()
{
Schema::create('personal_access_tokens', function (Blueprint $table) {
Schema::create('gl_work_orders', function (Blueprint $table) {
$table->id();
$table->morphs('tokenable');
$table->string('name');
$table->string('token', 64)->unique();
$table->text('abilities')->nullable();
$table->timestamp('last_used_at')->nullable();
$table->timestamps();
$table->string('product')->nullable()->comment('相关产品,工单类型');
$table->longText('content')->comment('工单图文描述');
$table->json('files')->nullable()->comment('附件');
$table->integer('status')->index()->default(0)->comment('工单状态,0:待处理, 1:处理中,2:已完成, 3:已关闭');
$table->integer('project_user_id')->index()->comment('客户ID');
$table->integer('project_id')->index()->comment('项目ID');
$table->integer('manage_id')->index()->comment('A端项目负责人ID, gl_manage 表ID');
$table->integer('engineer_id')->index()->comment('处理技术,工程师id, gl_manage 表ID');
$table->timestamp('end_at')->nullable()->comment('完成时间');
});
# 添加表注释
\Illuminate\Support\Facades\DB::statement("ALTER TABLE gl_work_orders comment '工单表'");
}
/**
... ... @@ -31,6 +37,6 @@ class CreatePersonalAccessTokensTable extends Migration
*/
public function down()
{
Schema::dropIfExists('personal_access_tokens');
Schema::dropIfExists('gl_work_orders');
}
}
... ...
... ... @@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateUsersTable extends Migration
class CreateWorkOrderLogsTable extends Migration
{
/**
* Run the migrations.
... ... @@ -13,15 +13,19 @@ class CreateUsersTable extends Migration
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
Schema::create('gl_work_order_logs', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
$table->integer('work_order_id')->index();
$table->integer('manage_id')->comment('gl_manage 表ID,操作人ID');
$table->boolean('ding')->default(false)->comment('是否钉钉通知');
$table->longText('content')->nullable()->comment('处理结果,图文描述');
$table->json('files')->nullable()->comment('附件');
$table->integer('status')->index()->default(0)->comment('工单状态,0:待处理, 1:处理中, 2:已完成');
$table->timestamp('end_at')->nullable()->comment('完成时间');
$table->unique(['work_order_id', 'manage_id'], 'work_order_manage_unique'); # 唯一索引,防止同一工单被同一人多次操作,同一工单,可以多人协作
});
\Illuminate\Support\Facades\DB::statement('ALTER TABLE gl_work_order_logs comment "工单操作日志表,分配工程师时创建,工程师完成时修改状态"');
}
/**
... ... @@ -31,6 +35,6 @@ class CreateUsersTable extends Migration
*/
public function down()
{
Schema::dropIfExists('users');
Schema::dropIfExists('gl_work_order_logs');
}
}
... ...
... ... @@ -4,7 +4,7 @@ use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreatePasswordResetsTable extends Migration
class WorkOrderLogsAddForeignId extends Migration
{
/**
* Run the migrations.
... ... @@ -13,11 +13,12 @@ class CreatePasswordResetsTable extends Migration
*/
public function up()
{
Schema::create('password_resets', function (Blueprint $table) {
$table->string('email')->index();
$table->string('token');
$table->timestamp('created_at')->nullable();
});
Schema::table('gl_work_order_logs', function (Blueprint $table) {
// 字段已存在,给字段添加外键约束
$table->foreign('work_order_id')
->references('id')->on('gl_work_orders')
->onDelete('cascade'); // 设置级联删除
});
}
/**
... ... @@ -27,6 +28,9 @@ class CreatePasswordResetsTable extends Migration
*/
public function down()
{
Schema::dropIfExists('password_resets');
Schema::table('gl_work_order_logs', function (Blueprint $table) {
// 删除外键约束
$table->dropForeign(['work_order_id']);
});
}
}
... ...
不能预览此文件类型
... ... @@ -246,6 +246,13 @@ Route::middleware(['aloginauth'])->group(function () {
Route::post('/save_follow', [Aside\Task\TaskController::class, 'save_follow'])->name('admin.task_save_follow');
Route::any('/getUserTaskList', [Aside\Task\TaskController::class, 'getUserTaskList'])->name('admin.task_getUserTaskList');
});
// 售后工单
Route::prefix('workorder')->group(function () {
Route::get('/', [Aside\WorkOrder\WorkOrderController::class, 'index'])->name('admin.workorder.index')->summary('A端工程师的工单列表');
Route::get('/manager', [Aside\WorkOrder\WorkOrderController::class, 'manager'])->name('admin.workorder.manager')->summary('A端管理员的工单列表');
Route::get('/{id}', [Aside\WorkOrder\WorkOrderController::class, 'show'])->name('admin.workorder.show')->summary('A端工单详情');
Route::post('/{id}', [Aside\WorkOrder\WorkOrderController::class, 'update'])->name('admin.workorder.update')->summary('A端更新工单');
});
//服务器配置
Route::prefix('devops')->group(function () {
Route::any('/', [Aside\Devops\ServerConfigController::class, 'lists'])->name('admin.devops.lists');
... ... @@ -271,6 +278,7 @@ Route::middleware(['aloginauth'])->group(function () {
});
Route::prefix('domain_log')->group(function () {
Route::any('/', [Aside\Domain\DomainApplicantLogController::class, 'lists'])->name('admin.domain_log_lists');
Route::any('/info', [Aside\Domain\DomainApplicantLogController::class, 'info'])->name('admin.domain_log_info');
Route::any('/save', [Aside\Domain\DomainApplicantLogController::class, 'save'])->name('admin.domain_log_save');
Route::any('/del', [Aside\Domain\DomainApplicantLogController::class, 'del'])->name('admin.domain_log_del');
});
... ...
... ... @@ -269,6 +269,16 @@ Route::middleware(['bloginauth'])->group(function () {
Route::any('/save',[\App\Http\Controllers\Bside\Setting\WebSettingAmpController::class, 'save'])->name('amp_save');
});
});
// 售后工单
Route::prefix('workorder')->group(function () {
Route::get('/', [\App\Http\Controllers\Bside\WorkOrder\WorkOrderController::class, 'index'])->name('workorder.index')->summary('B端售后工单列表');
Route::post('/', [\App\Http\Controllers\Bside\WorkOrder\WorkOrderController::class, 'store'])->name('workorder.store')->summary('B端创建工单');
Route::get('/{id}', [\App\Http\Controllers\Bside\WorkOrder\WorkOrderController::class, 'show'])->name('workorder.show')->summary('B端查看工单');
Route::post('/{id}', [\App\Http\Controllers\Bside\WorkOrder\WorkOrderController::class, 'update'])->name('workorder.update')->summary('B端完结工单');
Route::delete('/{id}', [\App\Http\Controllers\Bside\WorkOrder\WorkOrderController::class, 'destroy'])->name('workorder.destroy')->summary('B端删除工单,已完结的工单无法删除');
});
//产品
Route::prefix('product')->group(function () {
//产品
... ...