fix(ticket): complete stale request guards
This commit is contained in:
@@ -43,7 +43,8 @@ func (c *TicketController) AnyList() *web.JsonResult {
|
|||||||
if unassigned, _ := params.Get(c.Ctx, "unassigned"); unassigned == "1" || strings.EqualFold(unassigned, "true") {
|
if unassigned, _ := params.Get(c.Ctx, "unassigned"); unassigned == "1" || strings.EqualFold(unassigned, "true") {
|
||||||
cnd.Eq("current_assignee_id", 0)
|
cnd.Eq("current_assignee_id", 0)
|
||||||
}
|
}
|
||||||
if staleHours, _ := params.GetInt(c.Ctx, "staleHours"); staleHours > 0 {
|
if staleHoursValue, _ := params.Get(c.Ctx, "staleHours"); strings.TrimSpace(staleHoursValue) != "" {
|
||||||
|
staleHours, _ := params.GetInt(c.Ctx, "staleHours")
|
||||||
services.TicketService.ApplyStaleFilter(cnd, staleHours)
|
services.TicketService.ApplyStaleFilter(cnd, staleHours)
|
||||||
}
|
}
|
||||||
aggregate, err := services.TicketService.FindPageAggregateByCnd(cnd, operator.UserID)
|
aggregate, err := services.TicketService.FindPageAggregateByCnd(cnd, operator.UserID)
|
||||||
|
|||||||
@@ -76,24 +76,29 @@ export function TicketDetailDialog({
|
|||||||
const [editOpen, setEditOpen] = useState(false)
|
const [editOpen, setEditOpen] = useState(false)
|
||||||
const [editSaving, setEditSaving] = useState(false)
|
const [editSaving, setEditSaving] = useState(false)
|
||||||
const loadSeqRef = useRef(0)
|
const loadSeqRef = useRef(0)
|
||||||
|
const currentTicketIdRef = useRef<number | null>(null)
|
||||||
|
currentTicketIdRef.current = open ? ticketId : null
|
||||||
|
|
||||||
const loadDetail = useCallback(async () => {
|
const loadDetail = useCallback(async (targetTicketId = ticketId) => {
|
||||||
|
if (currentTicketIdRef.current !== targetTicketId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
const seq = loadSeqRef.current + 1
|
const seq = loadSeqRef.current + 1
|
||||||
loadSeqRef.current = seq
|
loadSeqRef.current = seq
|
||||||
if (!open || !ticketId) {
|
if (!open || !targetTicketId) {
|
||||||
setDetail(null)
|
setDetail(null)
|
||||||
setLoading(false)
|
setLoading(false)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
try {
|
try {
|
||||||
const data = await fetchTicketDetail(ticketId)
|
const data = await fetchTicketDetail(targetTicketId)
|
||||||
if (loadSeqRef.current !== seq) {
|
if (loadSeqRef.current !== seq || currentTicketIdRef.current !== targetTicketId) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setDetail(data)
|
setDetail(data)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
if (loadSeqRef.current !== seq) {
|
if (loadSeqRef.current !== seq || currentTicketIdRef.current !== targetTicketId) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
toast.error(error instanceof Error ? error.message : "加载工单详情失败")
|
toast.error(error instanceof Error ? error.message : "加载工单详情失败")
|
||||||
@@ -112,11 +117,12 @@ export function TicketDetailDialog({
|
|||||||
if (!detail || detail.ticket.status === status) {
|
if (!detail || detail.ticket.status === status) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const activeTicketId = detail.ticket.id
|
||||||
setStatusSaving(status)
|
setStatusSaving(status)
|
||||||
try {
|
try {
|
||||||
await changeTicketStatus({ ticketId: detail.ticket.id, status })
|
await changeTicketStatus({ ticketId: activeTicketId, status })
|
||||||
toast.success("工单状态已更新")
|
toast.success("工单状态已更新")
|
||||||
await loadDetail()
|
await loadDetail(activeTicketId)
|
||||||
onChanged()
|
onChanged()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(error instanceof Error ? error.message : "更新工单状态失败")
|
toast.error(error instanceof Error ? error.message : "更新工单状态失败")
|
||||||
@@ -129,6 +135,7 @@ export function TicketDetailDialog({
|
|||||||
if (!detail) {
|
if (!detail) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
const activeTicketId = detail.ticket.id
|
||||||
const content = progressContent.trim()
|
const content = progressContent.trim()
|
||||||
if (!content) {
|
if (!content) {
|
||||||
toast.error("请填写处理进展")
|
toast.error("请填写处理进展")
|
||||||
@@ -137,12 +144,12 @@ export function TicketDetailDialog({
|
|||||||
setProgressSaving(true)
|
setProgressSaving(true)
|
||||||
try {
|
try {
|
||||||
await createTicketProgress({
|
await createTicketProgress({
|
||||||
ticketId: detail.ticket.id,
|
ticketId: activeTicketId,
|
||||||
content,
|
content,
|
||||||
})
|
})
|
||||||
toast.success("处理进展已记录")
|
toast.success("处理进展已记录")
|
||||||
setProgressContent("")
|
setProgressContent("")
|
||||||
await loadDetail()
|
await loadDetail(activeTicketId)
|
||||||
onChanged()
|
onChanged()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(error instanceof Error ? error.message : "记录处理进展失败")
|
toast.error(error instanceof Error ? error.message : "记录处理进展失败")
|
||||||
@@ -152,7 +159,10 @@ export function TicketDetailDialog({
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function handleAssigned() {
|
async function handleAssigned() {
|
||||||
await loadDetail()
|
if (!ticket?.id) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await loadDetail(ticket.id)
|
||||||
onChanged()
|
onChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,7 +176,7 @@ export function TicketDetailDialog({
|
|||||||
await updateTicket(payload)
|
await updateTicket(payload)
|
||||||
toast.success("工单已更新")
|
toast.success("工单已更新")
|
||||||
setEditOpen(false)
|
setEditOpen(false)
|
||||||
await loadDetail()
|
await loadDetail(payload.ticketId)
|
||||||
onChanged()
|
onChanged()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(error instanceof Error ? error.message : "更新工单失败")
|
toast.error(error instanceof Error ? error.message : "更新工单失败")
|
||||||
|
|||||||
Reference in New Issue
Block a user