添加whatshub工单
This commit is contained in:
Regular → Executable
+129
-1
@@ -58,6 +58,7 @@ class Ticket extends Backend
|
||||
$this->assignconfig('ticketTypeList', $this->model->getTicketTypeList());
|
||||
$this->assignconfig('numberTypeList', $this->model->getNumberTypeList());
|
||||
$this->assignconfig('statusList', $this->model->getStatusList());
|
||||
$this->assignconfig('splitLinkFilterList', $this->buildTicketSplitLinkFilterList());
|
||||
$this->assignconfig([
|
||||
'syncConfirmMsg' => __('Sync confirm'),
|
||||
'syncBackgroundStartedMsg' => __('Sync background started'),
|
||||
@@ -142,6 +143,71 @@ class Ticket extends Backend
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 已有工单关联的分流链接(供列表筛选下拉)
|
||||
*
|
||||
* @return array<string, string> id => label
|
||||
*/
|
||||
private function buildTicketSplitLinkFilterList(): array
|
||||
{
|
||||
$ticketTable = $this->model->getTable();
|
||||
$linkTable = (new LinkModel())->getTable();
|
||||
$query = Db::table($ticketTable)
|
||||
->alias('t')
|
||||
->join($linkTable . ' l', 't.split_link_id = l.id')
|
||||
->where('t.split_link_id', '>', 0)
|
||||
->group('t.split_link_id')
|
||||
->field('l.id,l.link_code,l.description')
|
||||
->order('l.id', 'desc');
|
||||
if ($this->dataLimit) {
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds)) {
|
||||
$query->where('t.admin_id', 'in', $adminIds);
|
||||
}
|
||||
}
|
||||
$list = [];
|
||||
foreach ($query->select() as $row) {
|
||||
$code = (string) $row['link_code'];
|
||||
$desc = (string) $row['description'];
|
||||
$label = $desc !== '' ? $code . ' - ' . $desc : $code;
|
||||
$list[(string) $row['id']] = $label;
|
||||
}
|
||||
return $list;
|
||||
}
|
||||
|
||||
/**
|
||||
* 按当前筛选条件汇总列表统计列
|
||||
*
|
||||
* @param callable|array<mixed> $where buildparams() 返回的闭包或条件数组
|
||||
* @return array<string, int|float|string>
|
||||
*/
|
||||
private function buildListSummary($where): array
|
||||
{
|
||||
$stats = $this->model
|
||||
->where($where)
|
||||
->fieldRaw(
|
||||
'COALESCE(SUM(ticket_total), 0) AS sum_ticket_total,'
|
||||
. ' COALESCE(SUM(complete_count), 0) AS sum_complete_count,'
|
||||
. ' COALESCE(SUM(speed_per_hour), 0) AS sum_speed_per_hour,'
|
||||
. ' COALESCE(AVG(CASE WHEN ticket_total > 0 THEN complete_count * 100.0 / ticket_total ELSE 0 END), 0) AS avg_ticket_progress'
|
||||
)
|
||||
->find();
|
||||
if (!$stats) {
|
||||
return [
|
||||
'ticket_total' => 0,
|
||||
'complete_count' => 0,
|
||||
'speed_per_hour' => '0.00',
|
||||
'ticket_progress_text' => '0.00%',
|
||||
];
|
||||
}
|
||||
return [
|
||||
'ticket_total' => (int) ($stats['sum_ticket_total'] ?? 0),
|
||||
'complete_count' => (int) ($stats['sum_complete_count'] ?? 0),
|
||||
'speed_per_hour' => number_format((float) ($stats['sum_speed_per_hour'] ?? 0), 2, '.', ''),
|
||||
'ticket_progress_text' => number_format((float) ($stats['avg_ticket_progress'] ?? 0), 2, '.', '') . '%',
|
||||
];
|
||||
}
|
||||
|
||||
private function fetchPatch(string $template): string
|
||||
{
|
||||
$patchFile = ROOT_PATH . self::PATCH_VIEW_DIR . $template . '.html';
|
||||
@@ -179,7 +245,11 @@ class Ticket extends Backend
|
||||
->where($where)
|
||||
->order($sort, $order)
|
||||
->paginate($limit);
|
||||
$result = ['total' => $list->total(), 'rows' => $list->items()];
|
||||
$result = [
|
||||
'total' => $list->total(),
|
||||
'rows' => $list->items(),
|
||||
'summary' => $this->buildListSummary($where),
|
||||
];
|
||||
return json($result);
|
||||
}
|
||||
|
||||
@@ -331,6 +401,10 @@ class Ticket extends Backend
|
||||
public function add()
|
||||
{
|
||||
if (false === $this->request->isPost()) {
|
||||
$copyRow = $this->buildCopyRowData();
|
||||
if ($copyRow !== null) {
|
||||
$this->view->assign('row', $copyRow);
|
||||
}
|
||||
return $this->fetchPatch('add');
|
||||
}
|
||||
$params = $this->request->post('row/a', []);
|
||||
@@ -367,6 +441,60 @@ class Ticket extends Backend
|
||||
$this->success('', null, ['id' => (int) $this->model->id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从 copy_id 构建添加工单表单的预填数据(仅复制业务字段,不含同步统计)
|
||||
*
|
||||
* @return array<string, mixed>|null
|
||||
*/
|
||||
private function buildCopyRowData(): ?array
|
||||
{
|
||||
$copyId = (int) $this->request->get('copy_id/d', 0);
|
||||
if ($copyId <= 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$row = $this->model->get($copyId);
|
||||
if (!$row) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$adminIds = $this->getDataLimitAdminIds();
|
||||
if (is_array($adminIds) && !in_array((int) $row[$this->dataLimitField], $adminIds, true)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$data = $row->toArray();
|
||||
$copyFields = [
|
||||
'ticket_type',
|
||||
'ticket_name',
|
||||
'ticket_url',
|
||||
'ticket_total',
|
||||
'split_link_id',
|
||||
'number_type',
|
||||
'number_type_custom',
|
||||
'order_limit',
|
||||
'assign_ratio',
|
||||
'account',
|
||||
'password',
|
||||
];
|
||||
$copyRow = [];
|
||||
foreach ($copyFields as $field) {
|
||||
if (array_key_exists($field, $data)) {
|
||||
$copyRow[$field] = $data[$field];
|
||||
}
|
||||
}
|
||||
|
||||
$copyRow['start_time'] = $data['start_time_text'] ?? '';
|
||||
$copyRow['end_time'] = $data['end_time_text'] ?? '';
|
||||
|
||||
$name = trim((string) ($copyRow['ticket_name'] ?? ''));
|
||||
if ($name !== '' && mb_strpos($name, ' (副本)') === false) {
|
||||
$copyRow['ticket_name'] = $name . ' (副本)';
|
||||
}
|
||||
|
||||
return $copyRow;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $ids
|
||||
* @return string
|
||||
|
||||
Reference in New Issue
Block a user