Files
NewTicket/app/common/service/TicketService.php
2026-07-21 16:40:38 +08:00

223 lines
6.1 KiB
PHP

<?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)
{
$page = max(intval($params['page'] ?? 1), 1);
$limit = min(max(intval($params['limit'] ?? 20), 1), 100);
$order = strtolower($params['sortOrder']) === 'asc' ? 'asc' : 'desc';
// 查询构造器
$query = Tickets::with(['ticketStaff', 'ticketCompany', 'ticketOperator']);
$equalFilters = ['operator_id', 'user_id', 'status'];
foreach ($equalFilters as $field) {
if (!empty($params[$field])) {
$query->where($field, $params[$field]);
}
}
// 关键词(模糊搜索)
if (!empty($params['searchKeyword'])) {
$query->where(function ($q) use ($params) {
$q->where('website', 'like', '%' . $params['searchKeyword'] . '%')
->whereOr('remark', 'like', '%' . $params['searchKeyword'] . '%');
});
}
$list = $query->order('create_time', $order)
->hidden(['ticketStaff', 'ticketCompany', 'ticketOperator', 'company_id', 'operator_id', 'user_id'])
->append(['username', 'company_name', 'operator_name'])
->paginate(
$limit,
false,
[
'page' => $page,
'query' => $params
]
);
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, $isRole, $isSuper = false)
{
$ticket = Tickets::where('id', $id)->find();
if (!$ticket) {
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;
}
}