|
|
@@ -7,6 +7,14 @@
|
|
|
*
|
|
|
-->
|
|
|
<script setup lang="ts">
|
|
|
+import Dialog from '@/components/common/CustomDialog.vue'
|
|
|
+import Table from '@/components/table/CustomTable.vue'
|
|
|
+import { useRequest } from '@/hooks/useRequest.ts'
|
|
|
+import type { ReqConfig } from '@/types/dataAnalysis.ts'
|
|
|
+import type { DialogConfig } from '@/types/dialog.ts'
|
|
|
+import type { FormField } from '@/types/form.ts'
|
|
|
+import { FormFieldType } from '@/types/form.ts'
|
|
|
+import type { ResponseInfo } from '@/types/res.ts'
|
|
|
import type {
|
|
|
QueryInfo,
|
|
|
TableFieldInfo,
|
|
|
@@ -14,20 +22,11 @@ import type {
|
|
|
TableToolsConfig
|
|
|
} from '@/types/table.ts'
|
|
|
import { FilterType } from '@/types/table.ts'
|
|
|
-import AxiosInstance from '@/utils/axios/axiosInstance.ts'
|
|
|
-import type { FormRules } from 'element-plus'
|
|
|
-import type { DialogConfig } from '@/types/dialog.ts'
|
|
|
-import type { FormField } from '@/types/form.ts'
|
|
|
-import { FormFieldType } from '@/types/form.ts'
|
|
|
-import type { ResponseInfo } from '@/types/res.ts'
|
|
|
|
|
|
import { FieldSpecialEffectType } from '@/types/tableText.ts'
|
|
|
-import { computed, onMounted, reactive, ref } from 'vue'
|
|
|
-import { useRequest } from '@/hooks/useRequest.ts'
|
|
|
-
|
|
|
-import Dialog from '@/components/common/CustomDialog.vue'
|
|
|
-import Table from '@/components/table/CustomTable.vue'
|
|
|
import axiosInstance from '@/utils/axios/axiosInstance.ts'
|
|
|
+import type { FormRules } from 'element-plus'
|
|
|
+import { computed, onMounted, reactive, ref } from 'vue'
|
|
|
|
|
|
interface GameInfo {
|
|
|
gameName: string
|
|
|
@@ -52,11 +51,11 @@ const gameTableRef = ref<InstanceType<typeof Table>>()
|
|
|
const gameDialogRef = ref()
|
|
|
|
|
|
// 配置请求参数
|
|
|
-const requestConfig = reactive({
|
|
|
+const requestConfig = reactive<ReqConfig>({
|
|
|
url: AllApi.getGameTable,
|
|
|
// url: 'http://192.168.1.139:8000/user/getGidConfig',
|
|
|
otherOptions: {
|
|
|
- appSecret: '6YJSuc50uJ18zj45'
|
|
|
+ search: ''
|
|
|
}
|
|
|
})
|
|
|
|
|
|
@@ -158,16 +157,10 @@ const fieldsInfo = reactive<Array<TableFieldInfo>>([
|
|
|
// 查询字段设置
|
|
|
const queryInfo: Array<QueryInfo> = [
|
|
|
{
|
|
|
- name: 'gameName',
|
|
|
+ name: 'search',
|
|
|
label: '游戏名',
|
|
|
type: FilterType.INPUT,
|
|
|
- placeholder: '请输入游戏名进行搜索'
|
|
|
- },
|
|
|
- {
|
|
|
- name: 'pid',
|
|
|
- label: '项目ID',
|
|
|
- type: FilterType.INPUT,
|
|
|
- placeholder: '请输入Pid进行搜索'
|
|
|
+ placeholder: '请输入游戏名 / GID / PID 进行搜索'
|
|
|
}
|
|
|
]
|
|
|
|
|
|
@@ -188,58 +181,30 @@ const isAddDialog = ref(false)
|
|
|
|
|
|
const projectList = ref<ProjectInfo[]>([])
|
|
|
|
|
|
-/**
|
|
|
- * 校验GID有没有重复
|
|
|
- *
|
|
|
- * @param _rule 规则,可忽略
|
|
|
- * @param value 值
|
|
|
- * @param callback 回调函数
|
|
|
- */
|
|
|
-const checkGid = (_rule: any, value: any, callback: any) => {
|
|
|
- if (!value) {
|
|
|
- return callback(new Error('请输入游戏ID'))
|
|
|
- }
|
|
|
- if (!isAddDialog.value) {
|
|
|
- callback()
|
|
|
- return
|
|
|
- }
|
|
|
- setTimeout(() => {
|
|
|
- for (let i = 0; i < tableData.length; i++) {
|
|
|
- if (tableData[i].gid === value) {
|
|
|
- callback(new Error('游戏ID已存在'))
|
|
|
- break
|
|
|
- }
|
|
|
+const checkGid = (_rule: unknown, value: string, callback: (err?: Error) => void) => {
|
|
|
+ if (!value) return callback(new Error('请输入游戏ID'))
|
|
|
+ // 编辑时不检查重复
|
|
|
+ if (!isAddDialog.value) return callback()
|
|
|
+
|
|
|
+ for (let i = 0; i < tableData.length; i++) {
|
|
|
+ if (tableData[i].gid === value) {
|
|
|
+ return callback(new Error('游戏ID已存在'))
|
|
|
}
|
|
|
- callback()
|
|
|
- }, 10)
|
|
|
+ }
|
|
|
+ return callback()
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * 校验游戏名
|
|
|
- *
|
|
|
- * 主要对已经存在的游戏名进行校验
|
|
|
- *
|
|
|
- * @param _rule 规则,可忽略
|
|
|
- * @param value 值
|
|
|
- * @param callback 回调函数
|
|
|
- */
|
|
|
-const checkGameName = (_rule: any, value: any, callback: any) => {
|
|
|
- if (!value) {
|
|
|
- return callback(new Error('请输入游戏名'))
|
|
|
- }
|
|
|
- if (!isAddDialog.value) {
|
|
|
- callback()
|
|
|
- return
|
|
|
- }
|
|
|
- setTimeout(() => {
|
|
|
- for (let i = 0; i < tableData.length; i++) {
|
|
|
- if (tableData[i].gameName === value) {
|
|
|
- callback(new Error('游戏名已存在'))
|
|
|
- break
|
|
|
- }
|
|
|
+const checkGameName = (_rule: unknown, value: string, callback: (err?: Error) => void) => {
|
|
|
+ if (!value) return callback(new Error('请输入游戏名'))
|
|
|
+ // 编辑时不检查重复
|
|
|
+ if (!isAddDialog.value) return callback()
|
|
|
+
|
|
|
+ for (let i = 0; i < tableData.length; i++) {
|
|
|
+ if (tableData[i].gameName === value) {
|
|
|
+ return callback(new Error('游戏名已存在'))
|
|
|
}
|
|
|
- callback()
|
|
|
- }, 10)
|
|
|
+ }
|
|
|
+ return callback()
|
|
|
}
|
|
|
|
|
|
// 表单规则
|
|
|
@@ -417,76 +382,72 @@ const handleEdit = (row: any) => {
|
|
|
gameDialogRef.value.editForm(row)
|
|
|
}
|
|
|
|
|
|
-const formSub = (formData: any, type: number) => {
|
|
|
- // if (type === 0) {
|
|
|
- // allGameInfo.push({
|
|
|
- // gid: formData.gid,
|
|
|
- // gameName: formData.gameName
|
|
|
- // })
|
|
|
- // } else {
|
|
|
- // let game = allGameInfo.find((item) => item.gid === formData.gid)
|
|
|
- // if (game) {
|
|
|
- // game.gameName = formData.gameName
|
|
|
- // }
|
|
|
- // }
|
|
|
- getTableData()
|
|
|
- updateProjectList()
|
|
|
+const formSub = () => {
|
|
|
+ gameTableRef.value?.updateTableData()
|
|
|
}
|
|
|
|
|
|
-const getTableData = async () => {
|
|
|
- const res = (await axiosInstance.post(
|
|
|
- requestConfig.url,
|
|
|
- requestConfig.otherOptions
|
|
|
- )) as ResponseInfo
|
|
|
- const dataList = res.data as Array<any>
|
|
|
- tableData.splice(0, tableData.length, ...dataList)
|
|
|
+async function postWithRetry<T>(fn: () => Promise<T>, maxRetries = 2) {
|
|
|
+ let lastErr: unknown
|
|
|
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
|
+ try {
|
|
|
+ return await fn()
|
|
|
+ } catch (e) {
|
|
|
+ lastErr = e
|
|
|
+ if (attempt === maxRetries) throw e
|
|
|
+ }
|
|
|
+ }
|
|
|
+ throw lastErr
|
|
|
}
|
|
|
|
|
|
-const updateProjectList = async () => {
|
|
|
- const allProjects: ProjectInfo[] = []
|
|
|
- const limit = 10000 // 每次请求最大数量,建议与后端保持一致
|
|
|
+async function* fetchProjectsByPage(limit: number) {
|
|
|
let offset = 0
|
|
|
-
|
|
|
let total: number | null = null
|
|
|
+ let fetched = 0
|
|
|
|
|
|
- while (true) {
|
|
|
- try {
|
|
|
- const res = (await AxiosInstance.post(AllApi.getProjectList, {
|
|
|
+ while (total === null || fetched < total) {
|
|
|
+ const res = await postWithRetry(async () => {
|
|
|
+ return (await axiosInstance.post(AllApi.getProjectList, {
|
|
|
offset,
|
|
|
limit
|
|
|
})) as ResponseInfo
|
|
|
+ }, 2)
|
|
|
|
|
|
- let { count, data } = res
|
|
|
- if (count === undefined) {
|
|
|
- ElMessage.error('获取Pid列表错误')
|
|
|
- count = 10000
|
|
|
- }
|
|
|
+ if (typeof res.count !== 'number') {
|
|
|
+ throw new Error('后端未返回count')
|
|
|
+ }
|
|
|
|
|
|
- // 第一次请求时获取总数
|
|
|
- if (total === null) {
|
|
|
- total = count
|
|
|
- }
|
|
|
+ total ??= res.count
|
|
|
+ const page = (res.data ?? []) as ProjectInfo[]
|
|
|
|
|
|
- // 将当前页数据追加到总列表
|
|
|
- allProjects.push(...data)
|
|
|
+ yield page
|
|
|
|
|
|
- // 判断是否已全部获取:已获取数量 >= 总数
|
|
|
- if (allProjects.length >= total) {
|
|
|
- break
|
|
|
- }
|
|
|
+ fetched += page.length
|
|
|
+ offset += limit
|
|
|
|
|
|
- // 继续下一页
|
|
|
- offset += limit
|
|
|
- } catch (error) {
|
|
|
- ElMessage.error('获取Pid列表错误失败')
|
|
|
- console.error(`分页请求失败,偏移量: ${offset}`)
|
|
|
+ // 保险:如果后端返回空数组但 total 还没到,避免死循环
|
|
|
+ if (page.length === 0) break
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+const updateProjectList = async () => {
|
|
|
+ try {
|
|
|
+ const limit = 10000
|
|
|
+ const all: ProjectInfo[] = []
|
|
|
+
|
|
|
+ for await (const page of fetchProjectsByPage(limit)) {
|
|
|
+ all.push(...page)
|
|
|
}
|
|
|
+
|
|
|
+ projectList.value = all
|
|
|
+ } catch (e) {
|
|
|
+ ElMessage.error('获取Pid列表失败')
|
|
|
+ console.error(e)
|
|
|
+ projectList.value = []
|
|
|
}
|
|
|
- projectList.value = [...allProjects]
|
|
|
}
|
|
|
|
|
|
onMounted(() => {
|
|
|
- getTableData()
|
|
|
+ // getTableData()
|
|
|
updateProjectList()
|
|
|
})
|
|
|
</script>
|
|
|
@@ -495,13 +456,13 @@ onMounted(() => {
|
|
|
<div class="gameTableContainer">
|
|
|
<Table
|
|
|
ref="gameTableRef"
|
|
|
+ :request-config="requestConfig"
|
|
|
:tools="tableToolsConfig"
|
|
|
:open-filter-query="true"
|
|
|
:open-page-query="true"
|
|
|
- :open-remote-req-data="false"
|
|
|
- :open-remote-query="false"
|
|
|
+ :open-remote-req-data="true"
|
|
|
+ :open-remote-query="true"
|
|
|
:query-info="queryInfo"
|
|
|
- :data-list="tableData"
|
|
|
:table-fields-info="fieldsInfo"
|
|
|
:pagination-config="paginationConfig"
|
|
|
@addNewItem="addNewItem"
|