Files
NewTicket/app/common/service/TicketService.php
2026-05-26 09:44:21 +08:00

244 lines
6.6 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace app\common\service;
use app\common\model\Tickets;
use app\common\model\CompanyOperators;
use app\common\model\Companys;
use app\common\model\User;
use think\facade\Cache;
class TicketService
{
/**
* 获取工单列表业务逻辑
* @param array $params 外部传入的过滤参数
*/
public function getTicketList(array $params)
{
$query = Tickets::with(['ticketStaff', 'ticketCompany', 'ticketOperator']); // 查询构造器
// 状态筛选
if ($params['status'] !== null) {
$query->where('status', $params['status']);
}
// 运营人员筛选
if (!empty($params['operator_id'])) {
$query->where('operator_id', $params['operator_id']);
}
// 负责人筛选
if (!empty($params['user_id'])) {
$query->where('user_id', $params['user_id']);
}
// 关键词搜索
if (!empty($params['searchKeyword'])) {
$query->where(function ($q) use ($params) {
$q->where('website', 'like', '%' . $params['searchKeyword'] . '%')
->whereOr('remark', 'like', '%' . $params['searchKeyword'] . '%');
});
}
$order = strtolower($params['sortOrder']) === 'asc' ? 'asc' : 'desc';
// order -- 排序 paginate -- 分页(查询当前页的数据,还会自动计算总记录数)
$list = $query->order('create_time', $order)->paginate(
$params['limit'],
false,
[
'page' => $params['page'],
'query' => $params // 保持分页链接的查询参数
]
);
$list->each(function ($item) {
$item->hidden(['ticketStaff', 'ticketCompany', 'ticketOperator', 'company_id', 'operator_id', 'user_id']);
$item->append(['username', 'company_name', 'operator_name']);
return $item;
});
return $list;
}
/**
* 新增工单
*
*/
public function createTicket($data)
{
if (empty($data['website'])) {
throw new \Exception('网站不能为空');
}
$website = trim($data['website']);
// 并发锁
$lockKey = 'create_ticket_lock_' . md5($website);
if (Cache::has($lockKey)) {
throw new \Exception('当前该网址正在被创建工单中,请稍后重试');
}
Cache::set($lockKey, 1, 5); // 锁定5秒
try {
// 查找是否有未完成的同网站工单
$unfinishedTicket = Tickets::where('website', $website)
->whereIn('status', [0, 1])
->find();
if ($unfinishedTicket) {
Cache::delete($lockKey);
throw new \Exception('已存在未完成的同网站工单,无法创建');
}
// 当前无相同网站
$ticketResult = Tickets::create($data);
return $ticketResult;
} catch (\Exception $e) {
Cache::delete($lockKey);
throw $e;
}
}
/**
* 更新工单
* @param $id 工单id
* @param $data 外部传入的更新数据
* @param $uid 当前登录用户id
* @param $role 当前登录用户角色
* @return array
*/
public function updateTicket($id, $data, $allowFields, $uid, $isSuper = false)
{
$ticket = Tickets::where('id', $id)->find();
if (!$ticket) {
throw new \Exception('工单不存在');
}
// 当不是管理员,进入判断
if (!$isSuper) {
if (!is_null($ticket->user_id) && $ticket->user_id != $uid) {
throw new \Exception('没有权限修改该工单');
}
}
// 提取 $allowFields 允许修改的字段
$updateData = [];
foreach ($allowFields as $field) {
if (array_key_exists($field, $data)) {
$updateData[$field] = $data[$field];
}
}
// 如果没有有效数据需要更新
if (empty($updateData)) {
throw new \Exception('没有合法的更新字段');
}
return $ticket->save($updateData);
}
/**
* 获取所有运营人员名称 (下拉筛选用)-仅限后台使用
*
*/
public function getAllOperators()
{
$operators = CompanyOperators::with('company')->select();
$operators->each(function ($item) {
$item->hidden(['company_id', 'company', 'create_time', 'status']);
$item->append(['company_name']);
return $item;
});
return $operators;
}
public function TestgetAllOperators()
{
$operators = Companys::with('companyoperators')->select();
return $operators;
}
/**
* 统计各状态工单数量
*/
public function getTicketDashboardStats()
{
return [
'total' => Tickets::count(),
'status_counts' => Tickets::field('status, COUNT(*) as count')
->group('status')
->select()
];
}
/**
* 批量更新工单(事务内执行)
*/
public function batchUpdateTickets(array $ids, array $data, array $allowFields, $uid, $isSuper = false)
{
if (empty($ids)) {
throw new \Exception('请选择要更新的工单');
}
$updateData = [];
foreach ($allowFields as $field) {
if (array_key_exists($field, $data)) {
$updateData[$field] = $data[$field];
}
}
if (empty($updateData)) {
throw new \Exception('没有合法的更新字段');
}
$tickets = Tickets::whereIn('id', $ids)->select();
if ($tickets->isEmpty()) {
throw new \Exception('未找到任何工单');
}
\think\facade\Db::transaction(function () use ($tickets, $updateData, $uid, $isSuper) {
foreach ($tickets as $ticket) {
if (!$isSuper) {
if (!is_null($ticket->user_id) && $ticket->user_id != $uid) {
throw new \Exception("工单 #{$ticket->id} 没有权限修改");
}
}
$ticket->save($updateData);
}
});
return ['updated_count' => count($tickets)];
}
public function getStaffList()
{
$map = [
'role' => ['user', 'admin'],
'status' => 1
];
$staffs = User::where($map)->field('id, username', 'real_name')->select();
return $staffs;
}
}