增加callclient功能

main
cysamurai 3 months ago
parent 991ce5dc0f
commit 987f755ae2

@ -0,0 +1,3 @@
# 开发模式Vite 将 /api 代理到此处(见 electron.vite.config.ts
# 修改后需重启 npm run dev
VITE_DEV_PROXY_TARGET=http://192.168.1.10:8845

@ -0,0 +1,11 @@
{
"semi": false,
"singleQuote": true,
"trailingComma": "all",
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "avoid",
"endOfLine": "auto"
}

@ -1,16 +1,34 @@
import vue from '@vitejs/plugin-vue'
import { defineConfig } from 'electron-vite'
import { defineConfig, loadEnv } from 'electron-vite'
import { resolve } from 'path'
export default defineConfig({
main: {},
preload: {},
renderer: {
resolve: {
alias: {
'@renderer': resolve('src/renderer/src'),
/**
* Vite localhost:5173 axios localhost:8845 CORS
* /api service.ts DEV 使 /api/queue/caller
* .env.development VITE_DEV_PROXY_TARGET=http://host:8845
*/
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), '')
const devProxyTarget = env.VITE_DEV_PROXY_TARGET || 'http://127.0.0.1:8845'
return {
main: {},
preload: {},
renderer: {
resolve: {
alias: {
'@renderer': resolve('src/renderer/src'),
},
},
plugins: [vue()],
server: {
proxy: {
'/api': {
target: devProxyTarget,
changeOrigin: true,
},
},
},
},
plugins: [vue()],
},
}
})

@ -80,7 +80,7 @@ app.whenReady().then(() => {
})
// TicketList -> Main.vue 触发:用于“在票号列表窗口点呼叫/评价后,把主界面对应按钮逻辑执行起来”
ipcMain.on('ticket:main-action', (_event, action: unknown) => {
ipcMain.on('ticket:main-action', (_event, action: unknown, payload: unknown) => {
if (!mainWindow) return
if (action !== 'call' && action !== 'evaluate') return
@ -88,7 +88,7 @@ app.whenReady().then(() => {
try {
mainWindow.show()
mainWindow.focus()
mainWindow.webContents.send('main:ticket-action', action)
mainWindow.webContents.send('main:ticket-action', action, payload)
} catch {
// ignore
}

@ -63,26 +63,37 @@ contextBridge.exposeInMainWorld('nativeDialog', {
ipcRenderer.invoke('dialog:confirm', options),
})
type MainTicketAction = 'call' | 'evaluate'
type MainTicketActionPayload = {
ticketUid?: number
tktNum?: string
}
// TicketList -> Main.vue 触发call/evaluate
contextBridge.exposeInMainWorld('ticketToMain', {
triggerCall: () => ipcRenderer.send('ticket:main-action', 'call'),
triggerEvaluate: () => ipcRenderer.send('ticket:main-action', 'evaluate'),
triggerCall: (payload?: MainTicketActionPayload) => ipcRenderer.send('ticket:main-action', 'call', payload),
triggerEvaluate: (payload?: MainTicketActionPayload) =>
ipcRenderer.send('ticket:main-action', 'evaluate', payload),
})
let currentMainTicketListener:
| ((event: Electron.IpcRendererEvent, action: 'call' | 'evaluate') => void)
| ((
event: Electron.IpcRendererEvent,
action: MainTicketAction,
payload?: MainTicketActionPayload,
) => void)
| null = null
contextBridge.exposeInMainWorld('mainTicketEvents', {
onAction: (callback: (action: 'call' | 'evaluate') => void) => {
onAction: (callback: (action: MainTicketAction, payload?: MainTicketActionPayload) => void) => {
if (currentMainTicketListener) {
ipcRenderer.removeListener('main:ticket-action', currentMainTicketListener)
}
currentMainTicketListener = (event, action) => {
currentMainTicketListener = (event, action, payload) => {
void event
if (action !== 'call' && action !== 'evaluate') return
callback(action)
callback(action, payload)
}
ipcRenderer.on('main:ticket-action', currentMainTicketListener)

@ -4,9 +4,10 @@
<meta charset="UTF-8" />
<title>Electron</title>
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<!-- connect-src 使用 http:/https: 方案源,允许用户配置的 server_ip任意 IP/域名与端口),避免固定白名单导致本机 127.0.0.1 等被拦截 -->
<meta
http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' http://padapi.queuingsystem.cn http://192.168.1.10:8845;"
content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self' http: https: ws: wss:;"
/>
</head>

@ -1,4 +1,10 @@
import type { CallRequest, CallResponse, PauseRequest, ReCallRequest } from '@renderer/types/action'
import type {
IsRankData,
IsRankRequest,
QueueCountData,
QueueCountRequest,
} from '@renderer/types/rank'
import type { TicketPoolRequest, TicketPoolResponse } from '@renderer/types/ticket'
import type { UserRequest, UserResponse } from '@renderer/types/user'
import type { WindowResponse } from '@renderer/types/window'
@ -17,6 +23,7 @@ export const api = {
action: {
call: (data: CallRequest) => http.post<CallResponse>('/call-terminal/call', data),
init: (data: CallRequest) => http.post<CallResponse>('/call-terminal/init', data),
recall: (data: ReCallRequest) => http.post<CallResponse>('/call-terminal/recall', data),
abandon: (data: ReCallRequest) => http.post<CallResponse>('/call-terminal/abandon', data),
pause: (data: PauseRequest) => http.post<CallResponse>('/call-terminal/pause', data),
@ -26,5 +33,12 @@ export const api = {
evaluate: (data: ReCallRequest) => http.post<CallResponse>('/call-terminal/evaluate', data),
pool: (params: TicketPoolRequest) =>
http.get<TicketPoolResponse>('/call-terminal/pool', params),
// evaluating 状态下轮询:判断当前票是否已完成评价/可进入 idle
isRank: (params: IsRankRequest) => http.get<IsRankData>('/call-terminal/is-rank', params),
// idle 状态下轮询:查询当前窗口等候人数
getQueueCount: (params: QueueCountRequest) =>
http.get<QueueCountData>('/call-terminal/queue-count', params),
},
}

@ -55,12 +55,14 @@ interface INativeDialog {
}
interface ITicketToMain {
triggerCall: () => void
triggerEvaluate: () => void
triggerCall: (payload?: { ticketUid?: number; tktNum?: string }) => void
triggerEvaluate: (payload?: { ticketUid?: number; tktNum?: string }) => void
}
interface IMainTicketEvents {
onAction: (callback: (action: 'call' | 'evaluate') => void) => void
onAction: (
callback: (action: 'call' | 'evaluate', payload?: { ticketUid?: number; tktNum?: string }) => void,
) => void
}
declare global {

@ -10,6 +10,7 @@ export interface ActionButton {
export interface CallRequest {
windowUid: number
empUid: number
ticketUid?: number | null
}
export interface CallResponse {

@ -0,0 +1,48 @@
export interface IsRankData {
/**
* hasRank === true idle
*/
hasRank: boolean
/**
* UID
*/
ticketUid?: number
/**
* 使
*/
isEvaluated?: boolean
}
export interface IsRankRequest {
/**
* ticketUid Main.vue callingTkt
*/
ticketUid: number
}
export interface QueueCountData {
/**
*
*/
queueCount: number
/**
* windowUid
*/
windowUid?: number
/**
* count
*/
count?: number
}
export interface QueueCountRequest {
/**
* UID Login.vue windowUid
*/
windowUid: number
}

@ -36,6 +36,11 @@ const instance = axios.create({
})
export function applyServerIpToHttp(serverIp: string): void {
// DEV走当前页面源下的 /api/...,由 Vite 代理到后端,浏览器不跨域,不依赖后端 CORS
if (import.meta.env.DEV) {
instance.defaults.baseURL = API_QUEUE_CALLER_PATH
return
}
const url = buildBaseUrlFromServerIp(serverIp)
instance.defaults.baseURL = url
}

@ -93,13 +93,25 @@ const handleLogin = async (): Promise<void> => {
value: win.windowUid.toString(),
}
})
if (
cachedWinKey.value &&
options.value.some(item => item.value === cachedWinKey.value)
) {
if (cachedWinKey.value && options.value.some(item => item.value === cachedWinKey.value)) {
selectedWin.value = cachedWinKey.value
}
const initWindowUid =
selectedWin.value.trim() !== ''
? parseInt(selectedWin.value)
: Number(sessionState.winUid ?? 0)
const initRes = await api.action.init({
empUid: Number(sessionState.empUid ?? -1),
windowUid: Number.isFinite(initWindowUid) ? initWindowUid : 0,
})
const initSuccess =
((initRes as { data?: { success?: boolean } })?.data?.success ??
(initRes as { success?: boolean })?.success) === true
if (!initSuccess) {
await window.appLogger.log('warn', '初始化接口调用完成,但返回 success=false')
}
//
isLoginSuccessed.value = true
isLoading.value = false
@ -351,7 +363,7 @@ onUnmounted(() => {
flex-direction: column;
align-items: center;
// justify-content: center;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
background: linear-gradient(135deg, #004d99 0%, #003b7a 100%);
overflow: hidden;
position: relative;
padding: 0px;
@ -484,14 +496,14 @@ onUnmounted(() => {
border: 1px solid #dcdfe6;
&:hover {
color: #667eea;
color: #004d99;
}
}
&.is-active {
.el-radio-button__inner {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
border-color: #667eea;
background: linear-gradient(135deg, #004d99 0%, #003b7a 100%);
border-color: #004d99;
box-shadow: none;
}
}
@ -517,11 +529,11 @@ onUnmounted(() => {
transition: all 0.3s ease;
&:hover {
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.15);
box-shadow: 0 4px 12px rgba(0, 77, 153, 0.15);
}
&.is-focus {
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.25);
box-shadow: 0 4px 12px rgba(0, 77, 153, 0.25);
}
}
}
@ -534,14 +546,14 @@ onUnmounted(() => {
font-size: 16px;
font-weight: 500;
border-radius: 8px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
background: linear-gradient(135deg, #004d99 0%, #003b7a 100%);
border: none;
transition: all 0.3s ease;
margin-top: 10px;
&:hover:not(.is-disabled) {
transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(102, 126, 234, 0.3);
box-shadow: 0 8px 20px rgba(0, 77, 153, 0.3);
}
&:active:not(.is-disabled) {
@ -569,10 +581,6 @@ onUnmounted(() => {
//
@media (max-width: 480px) {
.login-container {
// padding: 15px;
}
.form-wrapper {
padding: 25px 20px !important;
}

@ -1,6 +1,7 @@
<script setup lang="ts">
import {
CircleCheck,
Delete,
Menu,
Phone,
Star,
@ -9,7 +10,7 @@ import {
VideoPlay,
} from '@element-plus/icons-vue'
import { SessionState } from 'src/shared/types/session'
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { computed, onMounted, onUnmounted, ref, watch } from 'vue'
import { api } from '../api'
import type { ActionButton } from '../types/action'
@ -18,6 +19,41 @@ const logErr = async (ctx: string, error: unknown): Promise<void> => {
await window.appLogger.log('error', `${ctx}: ${msg}`)
}
type ActionResultLike = {
success?: boolean
message?: string
ticketNo?: string
ticketUid?: number
data?: {
success?: boolean
message?: string
ticketNo?: string
ticketUid?: number
}
}
const getActionData = (res: unknown): NonNullable<ActionResultLike['data']> | ActionResultLike => {
const r = (res ?? {}) as ActionResultLike
return r.data && typeof r.data === 'object' ? r.data : r
}
const isActionSuccess = (res: unknown): boolean => {
return getActionData(res).success === true
}
const getActionMessage = (res: unknown): string => {
return String(getActionData(res).message ?? '')
}
const getActionTicketNo = (res: unknown): string => {
return String(getActionData(res).ticketNo ?? '')
}
const getActionTicketUid = (res: unknown): number => {
const v = getActionData(res).ticketUid
return typeof v === 'number' ? v : -1
}
const sessionState = ref<SessionState>({
empUid: -1,
winUid: -1,
@ -32,9 +68,31 @@ const callStatus = ref('idle')
const callBtnText = ref('呼叫')
const pauseBtnText = ref('暂停')
const callingTkt = ref(-1)
// Login.vue UID /getQueueCount
const cachedWindowUid = ref(-1)
const EVALUATING_COUNTDOWN_SEC = 15
let evaluatingCountdownTimer: ReturnType<typeof setInterval> | null = null
const evaluatingPrefixText = ref('评价中')
let isRankPollingTimer: ReturnType<typeof setInterval> | null = null
let isRankPollingBusy = false
let queueCountPollingTimer: ReturnType<typeof setInterval> | null = null
function clearIsRankPolling(): void {
if (isRankPollingTimer !== null) {
clearInterval(isRankPollingTimer)
isRankPollingTimer = null
}
}
function clearQueueCountPolling(): void {
if (queueCountPollingTimer !== null) {
clearInterval(queueCountPollingTimer)
queueCountPollingTimer = null
}
}
function clearEvaluatingCountdown(): void {
if (evaluatingCountdownTimer !== null) {
@ -49,6 +107,7 @@ function clearEvaluatingCountdown(): void {
*/
function startEvaluatingCountdown(prefixText: string): void {
clearEvaluatingCountdown()
evaluatingPrefixText.value = prefixText
let left = EVALUATING_COUNTDOWN_SEC
const applyMessage = (): void => {
message.value = `${prefixText}(剩余 ${left} 秒)`
@ -58,18 +117,102 @@ function startEvaluatingCountdown(prefixText: string): void {
evaluatingCountdownTimer = setInterval(() => {
left -= 1
if (left <= 0) {
clearEvaluatingCountdown()
// idle /isRank
message.value = evaluatingPrefixText.value
return
}
applyMessage()
}, 1000)
}
async function pollIsRankOnce(): Promise<void> {
if (isRankPollingBusy) return
isRankPollingBusy = true
try {
const ticketUid = callingTkt.value
if (typeof ticketUid !== 'number' || ticketUid <= 0) return
const res = await api.action.isRank({ ticketUid })
const ranked = res.hasRank === true || res.isEvaluated === true
if (ranked) {
clearIsRankPolling()
clearEvaluatingCountdown()
callStatus.value = 'idle'
callBtnText.value = '呼叫'
callingTkt.value = -1
message.value = '欢迎使用紫云呼叫终端'
void window.appLogger.log('info', '评价倒计时结束,进入待机')
await window.appLogger.log('info', 'isRank: 评价完成,进入待机')
return
}
applyMessage()
// message
if (evaluatingCountdownTimer === null) {
message.value = `${evaluatingPrefixText.value}(等待评价完成...`
}
} catch (error) {
await logErr('查询 isRank 失败', error)
} finally {
isRankPollingBusy = false
}
}
function startIsRankPolling(): void {
clearIsRankPolling()
void pollIsRankOnce()
isRankPollingTimer = setInterval(() => {
void pollIsRankOnce()
}, 1000)
}
async function pollQueueCountOnce(): Promise<void> {
try {
const winUidFromCache = cachedWindowUid.value
const winUidFromSession = sessionState.value.winUid ?? -1
const windowUid = winUidFromCache > 0 ? winUidFromCache : winUidFromSession
if (typeof windowUid !== 'number' || windowUid <= 0) return
const res = await api.action.getQueueCount({ windowUid })
const count =
typeof res.queueCount === 'number'
? res.queueCount
: typeof res.count === 'number'
? res.count
: 0
message.value = `欢迎使用紫云呼叫终端,当前窗口等候人数:${count}`
} catch (error) {
await logErr('查询 getQueueCount 失败', error)
}
}
function startQueueCountPolling(): void {
clearQueueCountPolling()
void pollQueueCountOnce()
queueCountPollingTimer = setInterval(() => {
void pollQueueCountOnce()
}, 15000)
}
// callStatus
// evaluating /isRankidle 15 /getQueueCount
watch(
callStatus,
status => {
if (status === 'evaluating') {
startIsRankPolling()
} else {
clearIsRankPolling()
}
if (status === 'idle') {
startQueueCountPolling()
} else {
clearQueueCountPolling()
}
},
{ immediate: true },
)
// buttons computedworking
const buttons = computed(() => {
const startOrComplete =
@ -99,6 +242,12 @@ const buttons = computed(() => {
),
},
startOrComplete,
{
icon: Delete,
label: '弃号',
action: 'abandon',
enabled: callStatus.value === 'calling',
},
{
icon: Switch,
label: '转移',
@ -144,8 +293,14 @@ const callAction = async (): Promise<void> => {
empUid: e,
ticketUid: t,
})
updateLog(`已重呼:${res.ticketNo},请勿重复点击!`)
await window.appLogger.log('info', `重呼成功: ticketNo=${res.ticketNo}`)
if (isActionSuccess(res)) {
updateLog(`已重呼:${getActionTicketNo(res)},请勿重复点击!`)
await window.appLogger.log('info', `重呼成功: ticketNo=${getActionTicketNo(res)}`)
} else {
const m = getActionMessage(res)
updateLog(m)
await window.appLogger.log('warn', `重呼未成功: ${m}`)
}
return
} catch (error) {
console.log('error', error)
@ -156,27 +311,30 @@ const callAction = async (): Promise<void> => {
try {
const w = sessionState.value.winUid || -1
const e = sessionState.value.empUid || -1
await window.appLogger.log('info', `请求呼叫: windowUid=${w}, empUid=${e}`)
const t = callingTkt.value > 0 ? callingTkt.value : null
await window.appLogger.log('info', `请求呼叫: windowUid=${w}, empUid=${e}, ticketUid=${t}`)
const res = await api.action.call({
windowUid: w,
empUid: e,
ticketUid: t,
})
//
if (res.success === true) {
if (isActionSuccess(res)) {
console.log('call success')
callStatus.value = 'calling'
callBtnText.value = '重呼'
callingTkt.value = res.ticketUid
updateLog(`正在呼叫:${res.ticketNo}`)
callingTkt.value = getActionTicketUid(res)
updateLog(`正在呼叫:${getActionTicketNo(res)}`)
await window.appLogger.log(
'info',
`呼叫成功: ticketNo=${res.ticketNo}, ticketUid=${res.ticketUid}`,
`呼叫成功: ticketNo=${getActionTicketNo(res)}, ticketUid=${getActionTicketUid(res)}`,
)
} else {
//
updateLog(res.message)
await window.appLogger.log('warn', `呼叫未成功: ${res.message}`)
const m = getActionMessage(res)
updateLog(m)
await window.appLogger.log('warn', `呼叫未成功: ${m}`)
}
} catch (error) {
console.log('error', error)
@ -184,6 +342,36 @@ const callAction = async (): Promise<void> => {
}
}
// action
const abandonAction = async (): Promise<void> => {
try {
const w = sessionState.value.winUid || -1
const e = sessionState.value.empUid || -1
const t = callingTkt.value
await window.appLogger.log('info', `请求弃号: windowUid=${w}, empUid=${e}`)
const res = await api.action.abandon({
windowUid: w,
empUid: e,
ticketUid: t,
})
if (isActionSuccess(res)) {
callStatus.value = 'idle'
callBtnText.value = '呼叫'
callingTkt.value = -1
updateLog(`弃号成功: ${getActionTicketNo(res)}`)
await window.appLogger.log('info', `弃号成功: ticketNo=${getActionTicketNo(res)}`)
} else {
const m = getActionMessage(res) || 'unknown'
updateLog(`弃号未成功: ${m}`)
await window.appLogger.log('warn', `弃号未成功: ${m}`)
}
} catch (error) {
console.log('error', error)
await logErr('弃号失败', error)
}
}
// action
const startAction = async (): Promise<void> => {
try {
@ -196,12 +384,13 @@ const startAction = async (): Promise<void> => {
empUid: e,
ticketUid: t,
})
if (res.success) {
if (isActionSuccess(res)) {
callStatus.value = 'working'
updateLog(`正在办理:${res.ticketNo}`)
await window.appLogger.log('info', `开始办理成功: ticketNo=${res.ticketNo}`)
updateLog(`正在办理:${getActionTicketNo(res)}`)
await window.appLogger.log('info', `开始办理成功: ticketNo=${getActionTicketNo(res)}`)
} else {
await window.appLogger.log('warn', `开始办理未成功: ${res.message ?? 'unknown'}`)
const m = getActionMessage(res) || 'unknown'
await window.appLogger.log('warn', `开始办理未成功: ${m}`)
}
} catch (error) {
console.log('error', error)
@ -221,15 +410,16 @@ const completeAction = async (): Promise<void> => {
empUid: e,
ticketUid: t,
})
if (!res.success) {
await window.appLogger.log('warn', `完成办理未成功: ${res.message ?? 'unknown'}`)
if (!isActionSuccess(res)) {
const m = getActionMessage(res) || 'unknown'
await window.appLogger.log('warn', `完成办理未成功: ${m}`)
return
}
await window.appLogger.log('info', `完成办理成功: ticketNo=${res.ticketNo}`)
await window.appLogger.log('info', `完成办理成功: ticketNo=${getActionTicketNo(res)}`)
callStatus.value = 'evaluating'
callBtnText.value = '呼叫'
startEvaluatingCountdown(`办理完成:${res.ticketNo},评价中`)
startEvaluatingCountdown(`办理完成:${getActionTicketNo(res)},评价中`)
await window.appLogger.log('info', '完成办理成功,进入评价中状态')
} catch (error) {
console.log('error', error)
@ -302,13 +492,14 @@ const pauseAction = async (): Promise<void> => {
empUid: e,
pauseReason: reason,
})
if (res.success) {
if (isActionSuccess(res)) {
callStatus.value = 'paused'
pauseBtnText.value = '恢复'
updateLog(`暂停中,原因:${reason}`)
await window.appLogger.log('info', `暂停成功: reason=${reason}`)
} else {
await window.appLogger.log('warn', `暂停未成功: ${res.message ?? 'unknown'}`)
const m = getActionMessage(res) || 'unknown'
await window.appLogger.log('warn', `暂停未成功: ${m}`)
}
} catch (err) {
await logErr('暂停失败', err)
@ -323,12 +514,13 @@ const pauseAction = async (): Promise<void> => {
windowUid: w,
empUid: e,
})
if (res.success) {
if (isActionSuccess(res)) {
callStatus.value = 'idle'
pauseBtnText.value = '暂停'
await window.appLogger.log('info', '恢复成功')
} else {
await window.appLogger.log('warn', `恢复未成功: ${res.message ?? 'unknown'}`)
const m = getActionMessage(res) || 'unknown'
await window.appLogger.log('warn', `恢复未成功: ${m}`)
}
} catch (err) {
await logErr('恢复失败', err)
@ -345,6 +537,9 @@ const handleButtonClick = (button: ActionButton): void => {
case 'call':
callAction()
break
case 'abandon':
abandonAction()
break
case 'pause':
pauseAction()
break
@ -374,8 +569,24 @@ const updateLog = (log: string): void => {
onMounted(async () => {
sessionState.value = await window.session.get()
// Login.vue appConfig selected_win_uid /getQueueCount
try {
const cfg = await window.appConfig.getAll()
const v = (cfg as Record<string, unknown>)?.selected_win_uid
const n = typeof v === 'number' ? v : Number(v)
if (Number.isFinite(n)) {
cachedWindowUid.value = n
}
} catch (error) {
// 退使 sessionState.winUid
await logErr('读取 selected_win_uid 失败', error)
}
// TicketList -> Main.vue
window.mainTicketEvents.onAction(action => {
window.mainTicketEvents.onAction((action, payload) => {
if (typeof payload?.ticketUid === 'number' && payload.ticketUid > 0) {
callingTkt.value = payload.ticketUid
}
if (action === 'call') {
void callAction()
return
@ -389,6 +600,8 @@ onMounted(async () => {
onUnmounted(() => {
clearEvaluatingCountdown()
clearIsRankPolling()
clearQueueCountPolling()
})
</script>

@ -294,7 +294,10 @@ function normalizeRows(raw: unknown[]): Tkt[] {
const handleCall = async (row: Tkt): Promise<void> => {
window.winControl.windowMinimize()
window.ticketToMain.triggerCall()
window.ticketToMain.triggerCall({
ticketUid: row.ticketUid,
tktNum: row.tktNum,
})
await window.appLogger.log(
'info',
`票池呼叫按钮点击: ticketUid=${row.ticketUid}, tktNum=${row.tktNum}`,
@ -303,7 +306,10 @@ const handleCall = async (row: Tkt): Promise<void> => {
const handleReEvaluate = async (row: Tkt): Promise<void> => {
window.winControl.windowMinimize()
window.ticketToMain.triggerEvaluate()
window.ticketToMain.triggerEvaluate({
ticketUid: row.ticketUid,
tktNum: row.tktNum,
})
await window.appLogger.log(
'info',
`票池评价按钮点击: ticketUid=${row.ticketUid}, tktNum=${row.tktNum}`,

Loading…
Cancel
Save