Tickets.php
8.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
<?php
namespace App\Models\WorkOrder;
use App\Models\Base;
use App\Models\Manage\ManageHr;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Log;
class Tickets extends Base
{
use HasFactory;
protected $table = 'gl_tickets';
const STATUS_PEDDING = 0; // 待处理
const STATUS_PROCESSING = 1; // 处理中
const STATUS_YANSHOU = 2; // 验收中
const STATUS_COMPLETED = 3; // 已完成
const STATUS_CLOSED = 9; // 已关闭,已失效,审核不通过,结束工单设置大一点,方便中途又要加状态
/**
* @return void
* 关联的工单日志
*/
public function logs()
{
return $this->hasMany(TicketLog::class, 'ticket_id', 'id');
}
/**
* 关联项目
*/
public function project()
{
return $this->belongsTo(TicketProject::class, 'project_id', 'id');
}
/**
* 当前工单,保存参与的人员到 gl_ticket_logs 表
* 逻辑说明:
* 1. 如果当前项目是超迹,要把徐莹和第一负责人加进去,为参与人
* 2. 若是域途项目,把黄小玉和第一负责人加进去,为参与人
* 3. 若是V5V6的项目,则把组长和第一负责人加进去,为参与人
*/
public function saveEngineers($engineer_ids = [])
{
$canyu = [
$this->project->engineer_id, // 第一负责人
];
if ($this->project->project_cate == 3)
$canyu[] = 20; // 徐莹
elseif ($this->project->project_cate == 4)
$canyu[] = 85; // 黄小玉
else{
// todo V5V6 的项目, 组长能够给看到组员的工单
$leaders = [];
foreach (array_merge($engineer_ids, $canyu) as $engineer_id)
{
$engineer = ManageHr::where('manage_id', $engineer_id)->first();
if ($engineer)
{
$leader = ManageHr::where('is_leader', 1)
->where('status', ManageHr::STATUS_ONE)
->where('dept_id', $engineer->dept_id)
->where('belong_group', $engineer->belong_group)
->value('manage_id');
if ($leader)
$leaders[] = $leader;
}
}
// 合并组长 id 到 $canyu
$canyu = array_merge($canyu, $leaders);
}
$all_engineer_ids = array_unique(array_merge($canyu, $engineer_ids));
foreach ($all_engineer_ids as $engineer_id)
{
try {
$log = $this->logs()->where('engineer_id', $engineer_id)->first();
if ($log && $log->is_engineer != in_array($engineer_id, $engineer_ids))
{
$log->is_engineer = in_array($engineer_id, $engineer_ids);
$log->plan_end_at = $this->plan_end_at; // 新增时写入 plan_end_at
$log->save();
}else
{
// 利用唯一索引去重
$log = new TicketLog();
$log->engineer_id = $engineer_id;
$log->is_engineer = in_array($engineer_id, $engineer_ids);
$log->plan_end_at = $this->plan_end_at; // 新增时写入 plan_end_at
$this->logs()->save($log);
}
}catch (\Exception $exception){
Log::error(" | ERRPR | Ticket saveEngineers {$exception->getMessage()} \n {$exception->getTraceAsString()}");
}
}
// 删除没有参与当前工单的人员(若之前已有)
$this->logs()->whereNotIn('engineer_id', $all_engineer_ids)->delete();
}
/**
* TODO 这个是一个补充功能
* 那些情况需要推送钉钉内部通知?
* 1. 客户提交了工单
* - 通知第一负责人 (gl_ticket_logs 表做了标记)
* 2. 客户补充了工单
* - 通知最近的聊天技术(gl_ticket_chats 表做了标记)
* 3. 技术完成了工单
* - 通知第一负责人 (暂无,所以这里做补充,如果以后要把上面的逻辑也加进来也可以,只是我为了偷懒,暂时只考虑完成工单请款)
*/
public function pushDing($type = 'finish')
{
try {
$ding = new TicketDing();
$ding->msgKey = 'sampleLink';
$ding->table_name = 'gl_tickets';
$ding->table_id = $this->id;
if ($type == 'finish')
{
// 所有技术完成了工单,通知第一负责人 和 工单的提交人
$userIds = [$this->project->engineer_id];
if ($this->submit_side == 1) {
// A 端提的,还要通知提交人
$userIds[] = $this->submit_user_id;
// 去重
$userIds = array_unique($userIds);
}
$ding->userIds = json_encode($userIds);
$ding->msgParam = json_encode([
'text' => "工单(ID: {$this->id}),已经全部完成,请访问查看详情!",
'title' => 'AI协同工单 - ' . $this->project->title,
'picUrl' => 'https://hub.globalso.com/logocm.png',
'messageUrl' => 'https://oa.quanqiusou.cn/afterorder?project_id=' . $this->project->uuid,
], JSON_UNESCAPED_UNICODE);
$ding->save();
}
}catch (\Exception $exception){
Log::error(" | ERRPR | Ticket {$exception->getMessage()} \n {$exception->getTraceAsString()}");
}
}
/**
* @remark :
* @name :getorderTypeOptions
* @author :lyh
* @method :post
* @time :2025/11/24 14:43
*/
public function getorderTypeOptions()
{
$data = [
'1' => ['资料上传', '美工设计', '网站修改', '优化问题', '优化报告', '网站同步', '页面翻译', '其他问题','关键词相关','上线审核','研发工单(客户不可见)'],
'2' => ['资料上传', '美工设计', '网站修改', '优化问题', '优化报告', '网站同步', '页面翻译', '其他问题','关键词相关','上线审核','GEO项目','研发工单(客户不可见)'],
'3' => ['功能问题', '操作问题', '数据问题', '功能需求', '培训需求', '其他问题','研发工单(客户不可见)'],
'4' => ['账号问题', '报告分析', '效果问题', '发帖问题', '视频问题', '美工设计', '其他问题','研发工单(客户不可见)']
];
$dataSon = [
'研发工单'=>[
'1'=>['工单系统'=>'李宇航','页面及可视化'=>'刘俊杰','翻译'=>'李文涛','v5问题'=>'张关杰','其他问题'=>''],
'2'=>['工单系统'=>'李宇航','oa管理系统'=>'李宇航','v6管理系统'=>'李宇航','社媒分享'=>'李宇航','C端页面生成'=>'李小龙','页面及可视化'=>'刘俊杰','翻译'=>'李文涛','其他问题'=>''],
'3'=>['Whatsapp'=>'赵彬吉','邮件群发'=>'邓超','社媒'=>'何正兵','AI模型'=>'何正兵','其他问题'=>'朱世亮'],
'4'=>['Whatsapp'=>'赵彬吉','邮件群发'=>'邓超','社媒'=>'何正兵','AI模型'=>'何正兵','其他问题'=>'朱世亮'],
]
];
return ['type'=>$data, 'data'=>$dataSon];
}
/**
* @remark :客户提交工单类型
* @name :getApiOrderTypeOptions
* @author :lyh
* @method :post
* @time :2025/11/27 17:01
*/
public function getApiOrderTypeOptions()
{
$data = [
'1' => ['资料上传', '美工设计', '网站修改', '优化问题', '优化报告', '网站同步', '页面翻译', '其他问题','关键词相关','上线审核'],
'2' => ['资料上传', '美工设计', '网站修改', '优化问题', '优化报告', '网站同步', '页面翻译', '其他问题','关键词相关','上线审核','GEO项目'],
'3' => ['功能问题', '操作问题', '数据问题', '功能需求', '培训需求', '其他问题'],
'4' => ['账号问题', '报告分析', '效果问题', '发帖问题', '视频问题', '美工设计', '其他问题',]
];
return ['type'=>$data];
}
}