mirror of
https://gitee.com/JavaLionLi/plus-ui.git
synced 2026-09-15 00:25:07 +08:00
Pre Merge pull request !208 from 张硕/ts
This commit is contained in:
commit
a7f0eb0140
44
src/api/doc/data/index.ts
Normal file
44
src/api/doc/data/index.ts
Normal file
@ -0,0 +1,44 @@
|
||||
import request from '@/utils/request';
|
||||
import type { AxiosPromise } from 'axios';
|
||||
import type { ExcelGenerateParams, ExcelGenerateResponse } from './types';
|
||||
|
||||
/**
|
||||
* 生成Excel数据
|
||||
* @param data 生成参数
|
||||
*/
|
||||
export const generateData = (data: ExcelGenerateParams): AxiosPromise<ExcelGenerateResponse> => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', data.file as Blob);
|
||||
formData.append('count', data.count.toString());
|
||||
|
||||
return request({
|
||||
url: '/system/caiqr/uploadExcelFile',
|
||||
method: 'post',
|
||||
data: formData,
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 下载Excel文件
|
||||
* @param fileName 文件名
|
||||
*/
|
||||
export const downloadFile = (fileName: string): AxiosPromise => {
|
||||
return request({
|
||||
url: '/system/caiqr/downloadExcel',
|
||||
method: 'get',
|
||||
params: { fileName },
|
||||
responseType: 'blob'
|
||||
});
|
||||
};
|
||||
|
||||
export const exportExcel = (data: ExportParams): Promise<AxiosResponse<Blob>> => {
|
||||
return request({
|
||||
url: '/system/caiqr/downloadExcel',
|
||||
method: 'post',
|
||||
data,
|
||||
responseType: 'blob'
|
||||
});
|
||||
};
|
||||
23
src/api/doc/data/types.ts
Normal file
23
src/api/doc/data/types.ts
Normal file
@ -0,0 +1,23 @@
|
||||
export interface ExcelFileItem {
|
||||
/** 文件名 */
|
||||
name: string;
|
||||
/** 下载地址 */
|
||||
url: string;
|
||||
}
|
||||
|
||||
export interface ExcelGenerateParams {
|
||||
/** 上传文件 */
|
||||
file: File | null;
|
||||
/** 生成组数 */
|
||||
count: number;
|
||||
}
|
||||
|
||||
export interface ExcelGenerateResponse {
|
||||
/** 返回码 */
|
||||
code: number;
|
||||
/** 返回信息 */
|
||||
msg: string;
|
||||
/** 生成文件名 */
|
||||
data: string;
|
||||
}
|
||||
|
||||
33
src/api/doc/filter/index.ts
Normal file
33
src/api/doc/filter/index.ts
Normal file
@ -0,0 +1,33 @@
|
||||
// api/index.ts
|
||||
import request from '@/utils/request';
|
||||
import type { AxiosResponse } from 'axios';
|
||||
import type { MatchCountResponse, ExportParams } from './types';
|
||||
|
||||
export const getMatchCount = (date: string, playCode: PlayType): Promise<AxiosResponse<MatchCountResponse>> => {
|
||||
return request({
|
||||
url: '/system/caiqr/getDateMatchCount',
|
||||
method: 'get',
|
||||
params: { date, playCode }
|
||||
});
|
||||
};
|
||||
|
||||
export const exportExcel = (data: ExportParams): Promise<AxiosResponse<Blob>> => {
|
||||
return request({
|
||||
url: '/system/caiqr/filter',
|
||||
method: 'post',
|
||||
data,
|
||||
responseType: 'blob'
|
||||
});
|
||||
};
|
||||
|
||||
// 新增日期格式化工具函数
|
||||
export const formatLocalDate = (dateString: string): string => {
|
||||
const dateObj = new Date(dateString);
|
||||
if (isNaN(dateObj.getTime())) return ''; // 无效日期处理
|
||||
|
||||
const year = dateObj.getFullYear();
|
||||
const month = String(dateObj.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(dateObj.getDate()).padStart(2, '0');
|
||||
|
||||
return `${year}-${month}-${day}`;
|
||||
};
|
||||
18
src/api/doc/filter/types.ts
Normal file
18
src/api/doc/filter/types.ts
Normal file
@ -0,0 +1,18 @@
|
||||
// types.ts
|
||||
export type PlayType = 'spf_handicap' | 'total_goals' | 'half_full' | '';
|
||||
|
||||
export interface DateFilter {
|
||||
date: string;
|
||||
filterCount: number;
|
||||
}
|
||||
|
||||
export interface MatchCountResponse {
|
||||
code: number;
|
||||
message: string;
|
||||
data: number;
|
||||
}
|
||||
|
||||
export interface ExportParams {
|
||||
playType: PlayType;
|
||||
dateFilters: DateFilter[];
|
||||
}
|
||||
63
src/api/operation/logs/index.ts
Normal file
63
src/api/operation/logs/index.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { LogsVO, LogsForm, LogsQuery } from '@/api/operation/logs/types';
|
||||
|
||||
/**
|
||||
* 查询nginx日志列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const listLogs = (query?: LogsQuery): AxiosPromise<LogsVO[]> => {
|
||||
return request({
|
||||
url: '/jshdconsole/logs/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询nginx日志详细
|
||||
* @param id
|
||||
*/
|
||||
export const getLogs = (id: string | number): AxiosPromise<LogsVO> => {
|
||||
return request({
|
||||
url: '/jshdconsole/logs/' + id,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增nginx日志
|
||||
* @param data
|
||||
*/
|
||||
export const addLogs = (data: LogsForm) => {
|
||||
return request({
|
||||
url: '/jshdconsole/logs',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改nginx日志
|
||||
* @param data
|
||||
*/
|
||||
export const updateLogs = (data: LogsForm) => {
|
||||
return request({
|
||||
url: '/jshdconsole/logs',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除nginx日志
|
||||
* @param id
|
||||
*/
|
||||
export const delLogs = (id: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/jshdconsole/logs/' + id,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
242
src/api/operation/logs/types.ts
Normal file
242
src/api/operation/logs/types.ts
Normal file
@ -0,0 +1,242 @@
|
||||
export interface LogsVO {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
id: string | number;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
realIp: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
timeLocal: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
requestMethod: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
requestUri: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
userAgent: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
requestParams: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
userToken: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
createdAt: string;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
mobile: string;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
userId: string | number;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
deviceId: string | number;
|
||||
|
||||
/**
|
||||
* 更新用户信息表, 是否已更新
|
||||
*/
|
||||
isUpdateUser: number;
|
||||
|
||||
/**
|
||||
* 比赛id
|
||||
*/
|
||||
matchId: string | number;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
apiNames: string;
|
||||
|
||||
}
|
||||
|
||||
export interface LogsForm extends BaseEntity {
|
||||
/**
|
||||
*
|
||||
*/
|
||||
id?: string | number;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
realIp?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
timeLocal?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
requestMethod?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
requestUri?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
userAgent?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
requestParams?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
userToken?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
createdAt?: string;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
mobile?: string;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
userId?: string | number;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
deviceId?: string | number;
|
||||
|
||||
/**
|
||||
* 更新用户信息表, 是否已更新
|
||||
*/
|
||||
isUpdateUser?: number;
|
||||
|
||||
/**
|
||||
* 比赛id
|
||||
*/
|
||||
matchId?: string | number;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
apiNames?: string;
|
||||
|
||||
}
|
||||
|
||||
export interface LogsQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
realIp?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
timeLocal?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
requestMethod?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
requestUri?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
userAgent?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
requestParams?: string;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
userToken?: string;
|
||||
|
||||
/**
|
||||
* 起始时间
|
||||
*/
|
||||
beginTime?: string;
|
||||
|
||||
/**
|
||||
* 终止时间
|
||||
*/
|
||||
endTime?: string;
|
||||
|
||||
/**
|
||||
* 手机号
|
||||
*/
|
||||
mobile?: string;
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
userId?: string | number;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
deviceId?: string | number;
|
||||
|
||||
/**
|
||||
* 更新用户信息表, 是否已更新
|
||||
*/
|
||||
isUpdateUser?: number;
|
||||
|
||||
/**
|
||||
* 比赛id
|
||||
*/
|
||||
matchId?: string | number;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
apiNames?: string;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
* @deprecated 请使用 beginTime 和 endTime
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
63
src/api/prediction/program/index.ts
Normal file
63
src/api/prediction/program/index.ts
Normal file
@ -0,0 +1,63 @@
|
||||
import request from '@/utils/request';
|
||||
import { AxiosPromise } from 'axios';
|
||||
import { ProgramVO, ProgramForm, ProgramQuery } from '@/api/prediction/program/types';
|
||||
|
||||
/**
|
||||
* 查询赛事方案列表
|
||||
* @param query
|
||||
* @returns {*}
|
||||
*/
|
||||
|
||||
export const listProgram = (query?: ProgramQuery): AxiosPromise<ProgramVO[]> => {
|
||||
return request({
|
||||
url: '/jshdconsole/program/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查询赛事方案详细
|
||||
* @param programId
|
||||
*/
|
||||
export const getProgram = (programId: string | number): AxiosPromise<ProgramVO> => {
|
||||
return request({
|
||||
url: '/jshdconsole/program/' + programId,
|
||||
method: 'get'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 新增赛事方案
|
||||
* @param data
|
||||
*/
|
||||
export const addProgram = (data: ProgramForm) => {
|
||||
return request({
|
||||
url: '/jshdconsole/program',
|
||||
method: 'post',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 修改赛事方案
|
||||
* @param data
|
||||
*/
|
||||
export const updateProgram = (data: ProgramForm) => {
|
||||
return request({
|
||||
url: '/jshdconsole/program',
|
||||
method: 'put',
|
||||
data: data
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 删除赛事方案
|
||||
* @param programId
|
||||
*/
|
||||
export const delProgram = (programId: string | number | Array<string | number>) => {
|
||||
return request({
|
||||
url: '/jshdconsole/program/' + programId,
|
||||
method: 'delete'
|
||||
});
|
||||
};
|
||||
204
src/api/prediction/program/types.ts
Normal file
204
src/api/prediction/program/types.ts
Normal file
@ -0,0 +1,204 @@
|
||||
export interface ProgramVO {
|
||||
/**
|
||||
* 方案号
|
||||
*/
|
||||
programId: string | number;
|
||||
|
||||
/**
|
||||
* 一段JSON文本,返回给客户端
|
||||
*/
|
||||
tickets: string;
|
||||
|
||||
/**
|
||||
* 收益倍数
|
||||
*/
|
||||
earnings: number;
|
||||
|
||||
/**
|
||||
* 9 -- 未开奖
|
||||
0 -- 未中奖
|
||||
1 -- 已中奖
|
||||
*/
|
||||
status: number;
|
||||
|
||||
/**
|
||||
* 相关比赛
|
||||
*/
|
||||
reference: string;
|
||||
|
||||
/**
|
||||
* 预测概率
|
||||
*/
|
||||
mojieIndex: number;
|
||||
|
||||
/**
|
||||
* 方案类型
|
||||
0 -- 精选方案
|
||||
1 -- 高赔方案
|
||||
2 -- 自定义方案
|
||||
*/
|
||||
type: number;
|
||||
|
||||
/**
|
||||
* 0 -- 无效
|
||||
1 -- 有效
|
||||
*/
|
||||
isValid: string | number;
|
||||
|
||||
/**
|
||||
* 串关个数
|
||||
*/
|
||||
passNum: number;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
beginTime: string;
|
||||
|
||||
/**
|
||||
* 截止时间
|
||||
*/
|
||||
closingTime: string;
|
||||
|
||||
/**
|
||||
* 当天的第几个方案
|
||||
*/
|
||||
programNum: number;
|
||||
|
||||
}
|
||||
|
||||
export interface ProgramForm extends BaseEntity {
|
||||
/**
|
||||
* 方案号
|
||||
*/
|
||||
programId?: string | number;
|
||||
|
||||
/**
|
||||
* 一段JSON文本,返回给客户端
|
||||
*/
|
||||
tickets?: string;
|
||||
|
||||
/**
|
||||
* 收益倍数
|
||||
*/
|
||||
earnings?: number;
|
||||
|
||||
/**
|
||||
* 9 -- 未开奖
|
||||
0 -- 未中奖
|
||||
1 -- 已中奖
|
||||
*/
|
||||
status?: number;
|
||||
|
||||
/**
|
||||
* 相关比赛
|
||||
*/
|
||||
reference?: string;
|
||||
|
||||
/**
|
||||
* 预测概率
|
||||
*/
|
||||
mojieIndex?: number;
|
||||
|
||||
/**
|
||||
* 方案类型
|
||||
0 -- 精选方案
|
||||
1 -- 高赔方案
|
||||
2 -- 自定义方案
|
||||
*/
|
||||
type?: number;
|
||||
|
||||
/**
|
||||
* 0 -- 无效
|
||||
1 -- 有效
|
||||
*/
|
||||
isValid?: string | number;
|
||||
|
||||
/**
|
||||
* 串关个数
|
||||
*/
|
||||
passNum?: number;
|
||||
|
||||
/**
|
||||
* 截止时间
|
||||
*/
|
||||
closingTime?: string;
|
||||
|
||||
/**
|
||||
* 当天的第几个方案
|
||||
*/
|
||||
programNum?: number;
|
||||
|
||||
}
|
||||
|
||||
export interface ProgramQuery extends PageQuery {
|
||||
|
||||
/**
|
||||
* 一段JSON文本,返回给客户端
|
||||
*/
|
||||
tickets?: string;
|
||||
|
||||
/**
|
||||
* 收益倍数
|
||||
*/
|
||||
earnings?: number;
|
||||
|
||||
/**
|
||||
* 9 -- 未开奖
|
||||
0 -- 未中奖
|
||||
1 -- 已中奖
|
||||
*/
|
||||
status?: number;
|
||||
|
||||
/**
|
||||
* 相关比赛
|
||||
*/
|
||||
reference?: string;
|
||||
|
||||
/**
|
||||
* 预测概率
|
||||
*/
|
||||
mojieIndex?: number;
|
||||
|
||||
/**
|
||||
* 方案类型
|
||||
0 -- 精选方案
|
||||
1 -- 高赔方案
|
||||
2 -- 自定义方案
|
||||
*/
|
||||
type?: number;
|
||||
|
||||
/**
|
||||
* 0 -- 无效
|
||||
1 -- 有效
|
||||
*/
|
||||
isValid?: string | number;
|
||||
|
||||
/**
|
||||
* 串关个数
|
||||
*/
|
||||
passNum?: number;
|
||||
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
beginTime?: string;
|
||||
|
||||
/**
|
||||
* 截止时间
|
||||
*/
|
||||
closingTime?: string;
|
||||
|
||||
/**
|
||||
* 当天的第几个方案
|
||||
*/
|
||||
programNum?: number;
|
||||
|
||||
/**
|
||||
* 日期范围参数
|
||||
*/
|
||||
params?: any;
|
||||
}
|
||||
|
||||
|
||||
|
||||
204
src/views/doc/data/index.vue
Normal file
204
src/views/doc/data/index.vue
Normal file
@ -0,0 +1,204 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<el-card shadow="hover" class="mb-[10px]">
|
||||
<el-form :inline="true">
|
||||
<!-- 上传区域 -->
|
||||
<el-form-item label="上传Excel" prop="excelFile" class="mr-4">
|
||||
<el-upload
|
||||
v-model:file-list="fileList"
|
||||
:auto-upload="false"
|
||||
:on-change="handleFileChange"
|
||||
accept=".xlsx,.xls"
|
||||
:show-file-list="false"
|
||||
>
|
||||
<el-button type="primary">选择文件</el-button>
|
||||
<span class="ml-2" v-if="formData.file">{{ formData.file.name }}</span>
|
||||
</el-upload>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 组数输入 -->
|
||||
<el-form-item label="组数" prop="count" class="mb-[30px]">
|
||||
<div class="flex items-center">
|
||||
<el-button @click="decrease" icon="Minus" circle />
|
||||
<el-input-number
|
||||
v-model="formData.count"
|
||||
:min="1"
|
||||
:max="1000"
|
||||
class="mx-2 w-24"
|
||||
/>
|
||||
<el-button @click="increase" icon="Plus" circle />
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 生成按钮 -->
|
||||
<el-form-item>
|
||||
<el-button
|
||||
type="primary"
|
||||
:loading="loading"
|
||||
@click="handleGenerate"
|
||||
>
|
||||
生成数据
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 下载区域 -->
|
||||
<el-card shadow="hover" class="mb-[10px]">
|
||||
<div class="flex items-center">
|
||||
<el-input
|
||||
v-model="downloadFileName"
|
||||
placeholder="请输入要下载的文件名"
|
||||
class="mr-2 w-64"
|
||||
/>
|
||||
<el-button type="success" @click="handleDownload">
|
||||
下载文件
|
||||
</el-button>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<el-card shadow="hover">
|
||||
<el-table :data="generatedFiles" style="width: 40%">
|
||||
<el-table-column prop="name" label="文件名" />
|
||||
<el-table-column label="操作" width="120">
|
||||
<template #default="scope">
|
||||
<el-button
|
||||
type="success"
|
||||
size="small"
|
||||
@click="handleDownloadItem(scope.row)"
|
||||
>
|
||||
下载
|
||||
</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</el-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { generateData, downloadFile } from '@/api/doc/data';
|
||||
import type { ExcelGenerateParams, ExcelFileItem } from '@/api/doc/data/types';
|
||||
|
||||
import { globalHeaders } from '@/utils/request';
|
||||
import { to } from 'await-to-js';
|
||||
|
||||
//服务器地址
|
||||
const baseURL = import.meta.env.VITE_APP_BASE_API;
|
||||
// 响应式数据
|
||||
const loading = ref(false);
|
||||
const downloadFileName = ref('');
|
||||
const generatedFiles = ref<ExcelFileItem[]>([]);
|
||||
|
||||
const formData = reactive<ExcelGenerateParams>({
|
||||
file: null,
|
||||
count: 4
|
||||
});
|
||||
|
||||
// 文件选择处理
|
||||
const handleFileChange = (file: File) => {
|
||||
formData.file = file.raw;
|
||||
};
|
||||
|
||||
// 组数增减
|
||||
const increase = () => {
|
||||
if (formData.count < 100) formData.count++;
|
||||
};
|
||||
const decrease = () => {
|
||||
if (formData.count > 1) formData.count--;
|
||||
};
|
||||
|
||||
// 生成数据
|
||||
const handleGenerate = async () => {
|
||||
if (!formData.file) {
|
||||
ElMessage.warning('请选择Excel文件');
|
||||
return;
|
||||
}
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await generateData(formData);
|
||||
generatedFiles.value.unshift({
|
||||
name: res.data,
|
||||
url: `${baseURL}/system/caiqr/upload/downloadExcel?fileName=${res.data}`
|
||||
});
|
||||
ElMessage.success('文件生成成功');
|
||||
} catch (error) {
|
||||
ElMessage.error('文件生成失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 下载处理
|
||||
const handleDownload = async () => {
|
||||
if (!downloadFileName.value.trim()) {
|
||||
ElMessage.warning('请输入文件名');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
ElMessage.success('文件下载开始');
|
||||
const res = await downloadFile(downloadFileName.value);
|
||||
if (res) {
|
||||
const blob = new Blob([res], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
});
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.style.display = 'none';
|
||||
link.href = url;
|
||||
link.setAttribute('download', `match_data_${new Date().getTime()}.xlsx`);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
ElMessage.success('导出成功');
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('文件下载失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 下载列表项
|
||||
// ... existing code ...
|
||||
const handleDownloadItem = async (item: ExcelFileItem) => {
|
||||
downloadFileName.value = item.name;
|
||||
try {
|
||||
const res = await downloadFile(item.name);
|
||||
ElMessage.success('文件下载开始');
|
||||
if (res) {
|
||||
const blob = new Blob([res], {
|
||||
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
|
||||
});
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.style.display = 'none';
|
||||
link.href = url;
|
||||
link.setAttribute('download', `match_data_${new Date().getTime()}.xlsx`);
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
ElMessage.success('导出成功');
|
||||
}
|
||||
} catch (error) {
|
||||
ElMessage.error('文件下载失败');
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 可以保留原有样式或使用Element Plus样式 */
|
||||
.mr-4 {
|
||||
margin-right: 1rem;
|
||||
}
|
||||
.w-24 {
|
||||
width: 6rem;
|
||||
}
|
||||
.w-64 {
|
||||
width: 16rem;
|
||||
}
|
||||
</style>
|
||||
268
src/views/doc/filter/index.vue
Normal file
268
src/views/doc/filter/index.vue
Normal file
@ -0,0 +1,268 @@
|
||||
<!-- index.vue -->
|
||||
<template>
|
||||
<div class="form-container">
|
||||
<el-form :model="formData" class="el-form">
|
||||
<!-- 玩法类型选择 -->
|
||||
<el-form-item label="玩法类型">
|
||||
<el-select v-model="formData.playType" placeholder="请选择玩法">
|
||||
<el-option label="胜平负/让球胜平负" value="spf_handicap" />
|
||||
<el-option label="总进球" value="total_goals" />
|
||||
<el-option label="半全场" value="half_full" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 动态日期项 -->
|
||||
<el-form-item label="选择日期">
|
||||
<div id="datesContainer">
|
||||
<div v-for="(dateItem, index) in dateFilters" :key="index" class="date-item">
|
||||
<el-date-picker
|
||||
v-model="dateItem.date"
|
||||
type="date"
|
||||
placeholder="请选择日期"
|
||||
@change="handleDateChange(dateItem)" clearable>
|
||||
</el-date-picker>
|
||||
<span class="match-count">{{ dateItem.countTip }}</span>
|
||||
<div class="date-actions">
|
||||
<span class="date-filter-label">筛选场次数</span>
|
||||
<el-input-number
|
||||
v-model="dateItem.filterCount"
|
||||
:min="0"
|
||||
class="session-count-input"
|
||||
/>
|
||||
<el-button
|
||||
type="danger"
|
||||
@click="removeDate(index)"
|
||||
style="
|
||||
background: #f56c6c;
|
||||
border-color: #f56c6c;
|
||||
color: white;
|
||||
padding: 8px 12px;
|
||||
border-radius: 4px;
|
||||
"
|
||||
>
|
||||
<i class="el-icon-delete"></i>
|
||||
<span style="margin-left: 6px">删除</span>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="add-date-wrapper">
|
||||
<el-button type="primary" @click="addDate" class="add-date-btn">
|
||||
<i class="el-icon-plus"></i> 添加日期
|
||||
</el-button>
|
||||
</div>
|
||||
</el-form-item>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<el-form-item>
|
||||
<el-button type="primary" :loading="loading" @click="handleExport">
|
||||
<i class="el-icon-download"></i> 导出Excel
|
||||
</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<!-- 加载遮罩 -->
|
||||
<el-dialog :visible.sync="loading" title="处理中" width="30%" :show-close="false">
|
||||
<div class="loading-content">
|
||||
<i class="el-icon-loading"></i> 正在导出数据,请稍候...
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { getMatchCount, exportExcel ,formatLocalDate} from '@/api/doc/filter';
|
||||
import type { PlayType, DateFilter, MatchCountResponse } from '@/api/doc/filter/types';
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
playType: 'spf_handicap' as PlayType
|
||||
});
|
||||
|
||||
// 日期过滤器数组
|
||||
const dateFilters = ref<Array<DateFilter & { countTip: string }>>([
|
||||
{ date: '2025-04-01', filterCount: 0, countTip: '' }
|
||||
]);
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(false);
|
||||
|
||||
// 添加日期项
|
||||
const addDate = () => {
|
||||
dateFilters.value.push({
|
||||
date: '',
|
||||
filterCount: 0,
|
||||
countTip: ''
|
||||
});
|
||||
};
|
||||
|
||||
// 删除日期项
|
||||
const removeDate = (index: number) => {
|
||||
if (dateFilters.value.length > 1) {
|
||||
dateFilters.value.splice(index, 1);
|
||||
} else {
|
||||
ElMessage.warning('至少需要保留一个日期');
|
||||
}
|
||||
};
|
||||
|
||||
// 日期变更处理
|
||||
const handleDateChange = async (dateItem: typeof dateFilters.value[number]) => {
|
||||
if (!dateItem.date || !formData.playType) return;
|
||||
|
||||
try {
|
||||
// 确保日期格式为yyyy-MM-dd
|
||||
const dateObj = new Date(dateItem.date);
|
||||
if (isNaN(dateObj.getTime())) {
|
||||
throw new Error('Invalid date');
|
||||
}
|
||||
|
||||
// 获取本地时间的年、月、日(自动处理时区偏移)
|
||||
const year = dateObj.getFullYear();
|
||||
const month = String(dateObj.getMonth() + 1).padStart(2, '0'); // 月份从0开始需要+1
|
||||
const day = String(dateObj.getDate()).padStart(2, '0');
|
||||
|
||||
// 手动构造 yyyy-MM-dd 格式字符串
|
||||
const formattedDate = `${year}-${month}-${day}`;
|
||||
|
||||
const res = await getMatchCount(formattedDate, formData.playType);
|
||||
dateItem.countTip = `赛事数: ${res.data}`;
|
||||
dateItem.filterCount = res.data;
|
||||
} catch {
|
||||
dateItem.countTip = '获取失败';
|
||||
}
|
||||
};
|
||||
|
||||
// 导出处理
|
||||
const handleExport = async () => {
|
||||
if (!validateForm()) return;
|
||||
|
||||
loading.value = true;
|
||||
try {
|
||||
const params = {
|
||||
playType: formData.playType,
|
||||
dateFilters: dateFilters.value.map(item => ({
|
||||
date: formatLocalDate(item.date),
|
||||
filterCount: item.filterCount
|
||||
}))
|
||||
};
|
||||
|
||||
const res = await exportExcel(params);
|
||||
handleFileDownload(res);
|
||||
} catch (error) {
|
||||
ElMessage.error('导出失败');
|
||||
} finally {
|
||||
loading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 文件下载处理
|
||||
const handleFileDownload = (blob: Blob) => {
|
||||
const url = window.URL.createObjectURL(blob);
|
||||
const link = document.createElement('a');
|
||||
link.href = url;
|
||||
link.download = 'match_data.xlsx';
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
window.URL.revokeObjectURL(url);
|
||||
};
|
||||
|
||||
// 表单验证
|
||||
const validateForm = (): boolean => {
|
||||
if (!formData.playType) {
|
||||
ElMessage.warning('请选择玩法类型');
|
||||
return false;
|
||||
}
|
||||
|
||||
const hasValidDate = dateFilters.value.some(item => !!item.date);
|
||||
if (!hasValidDate) {
|
||||
ElMessage.warning('请至少选择一个有效日期');
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
// 重置表单
|
||||
const handleReset = () => {
|
||||
formData.playType = 'spf_handicap';
|
||||
dateFilters.value = [{ date: '2025-04-01', filterCount: 0, countTip: '' }];
|
||||
};
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.form-container {
|
||||
max-width: 800px;
|
||||
margin: 20px auto;
|
||||
padding: 20px;
|
||||
border: 1px solid #ebeef5;
|
||||
border-radius: 4px;
|
||||
box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.date-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 10px;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.match-count {
|
||||
color: #67C23A;
|
||||
font-weight: bold;
|
||||
min-width: 100px;
|
||||
}
|
||||
|
||||
.session-count-input {
|
||||
width: 120px;
|
||||
}
|
||||
|
||||
.date-filter-label {
|
||||
width: 100px;
|
||||
text-align: right;
|
||||
padding-right: 12px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.loading-content {
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 新增样式 */
|
||||
.add-date-wrapper {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
justify-content: flex-start; /* 左对齐 */
|
||||
}
|
||||
|
||||
.add-date-btn {
|
||||
padding: 10px 20px;
|
||||
border-radius: 4px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
/* 响应式调整 */
|
||||
@media (max-width: 768px) {
|
||||
.add-date-wrapper {
|
||||
justify-content: center; /* 小屏幕居中 */
|
||||
}
|
||||
.add-date-btn {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 保持原有日期项样式 */
|
||||
.date-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12px;
|
||||
gap: 12px;
|
||||
}
|
||||
</style>
|
||||
344
src/views/operation/logs/index.vue
Normal file
344
src/views/operation/logs/index.vue
Normal file
@ -0,0 +1,344 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="IP" prop="realIp">
|
||||
<el-input v-model="queryParams.realIp" placeholder="请输入IP" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="url" prop="requestUri">
|
||||
<el-input v-model="queryParams.requestUri" placeholder="请输入url" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="user_token" prop="userToken">
|
||||
<el-input v-model="queryParams.userToken" placeholder="请输入token" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="接口名" prop="apiNames">
|
||||
<el-input v-model="queryParams.apiNames" placeholder="请输入" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="beginTime">
|
||||
<el-date-picker clearable
|
||||
v-model="queryParams.beginTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择起始日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="终止时间" prop="endTime">
|
||||
<el-date-picker clearable
|
||||
v-model="queryParams.endTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择终止日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号" prop="mobile">
|
||||
<el-input v-model="queryParams.mobile" placeholder="请输入手机号" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="用户ID" prop="userId">
|
||||
<el-input v-model="queryParams.userId" placeholder="请输入用户ID" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="设备ID" prop="deviceId">
|
||||
<el-input v-model="queryParams.deviceId" placeholder="请输入" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<!-- <el-form-item label="更新用户信息表, 是否已更新" prop="isUpdateUser">
|
||||
<el-input v-model="queryParams.isUpdateUser" placeholder="请输入更新用户信息表, 是否已更新" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item> -->
|
||||
<el-form-item label="比赛ID" prop="matchId">
|
||||
<el-input v-model="queryParams.matchId" placeholder="请输入比赛id" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<!-- <template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['console:logs:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['console:logs:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['console:logs:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['console:logs:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template> -->
|
||||
|
||||
<el-table v-loading="loading" :data="logsList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<!-- <el-table-column label="" align="center" prop="id" v-if="true" /> -->
|
||||
<el-table-column label="IP" align="center" prop="realIp" />
|
||||
<!-- <el-table-column label="" align="center" prop="timeLocal" /> -->
|
||||
<!-- <el-table-column label="" align="center" prop="requestMethod" /> -->
|
||||
<el-table-column label="url" align="center" prop="requestUri" />
|
||||
<!-- <el-table-column label="" align="center" prop="userAgent" /> -->
|
||||
<!-- <el-table-column label="" align="center" prop="requestParams" /> -->
|
||||
<el-table-column label="用户token" align="center" prop="userToken" />
|
||||
<el-table-column label="访问时间" align="center" prop="createdAt" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.createdAt, '{y}-{m}-{d} {h}:{i}:{s}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="手机号" align="center" prop="mobile" />
|
||||
<el-table-column label="用户ID" align="center" prop="userId" />
|
||||
<el-table-column label="设备ID" align="center" prop="deviceId" />
|
||||
<!-- <el-table-column label="更新用户信息表, 是否已更新" align="center" prop="isUpdateUser" /> -->
|
||||
<el-table-column label="比赛id" align="center" prop="matchId" />
|
||||
<el-table-column label="接口名" align="center" prop="apiNames" />
|
||||
<!-- <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['console:logs:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['console:logs:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column> -->
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改nginx日志对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="logsFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="" prop="realIp">
|
||||
<el-input v-model="form.realIp" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="timeLocal">
|
||||
<el-input v-model="form.timeLocal" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="requestMethod">
|
||||
<el-input v-model="form.requestMethod" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="requestUri">
|
||||
<el-input v-model="form.requestUri" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="userAgent">
|
||||
<el-input v-model="form.userAgent" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="requestParams">
|
||||
<el-input v-model="form.requestParams" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="userToken">
|
||||
<el-input v-model="form.userToken" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="createdAt">
|
||||
<el-date-picker clearable
|
||||
v-model="form.createdAt"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号" prop="mobile">
|
||||
<el-input v-model="form.mobile" placeholder="请输入手机号" />
|
||||
</el-form-item>
|
||||
<el-form-item label="用户ID" prop="userId">
|
||||
<el-input v-model="form.userId" placeholder="请输入用户ID" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="deviceId">
|
||||
<el-input v-model="form.deviceId" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
<el-form-item label="更新用户信息表, 是否已更新" prop="isUpdateUser">
|
||||
<el-input v-model="form.isUpdateUser" placeholder="请输入更新用户信息表, 是否已更新" />
|
||||
</el-form-item>
|
||||
<el-form-item label="比赛id" prop="matchId">
|
||||
<el-input v-model="form.matchId" placeholder="请输入比赛id" />
|
||||
</el-form-item>
|
||||
<el-form-item label="" prop="apiNames">
|
||||
<el-input v-model="form.apiNames" placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Logs" lang="ts">
|
||||
import { listLogs, getLogs, delLogs, addLogs, updateLogs } from '@/api/operation/logs';
|
||||
import { LogsVO, LogsQuery, LogsForm } from '@/api/operation/logs/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const logsList = ref<LogsVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const logsFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: LogsForm = {
|
||||
id: undefined,
|
||||
realIp: undefined,
|
||||
timeLocal: undefined,
|
||||
requestMethod: undefined,
|
||||
requestUri: undefined,
|
||||
userAgent: undefined,
|
||||
requestParams: undefined,
|
||||
userToken: undefined,
|
||||
createdAt: undefined,
|
||||
mobile: undefined,
|
||||
userId: undefined,
|
||||
deviceId: undefined,
|
||||
isUpdateUser: undefined,
|
||||
matchId: undefined,
|
||||
apiNames: undefined
|
||||
}
|
||||
const data = reactive<PageData<LogsForm, LogsQuery>>({
|
||||
form: {...initFormData},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
realIp: undefined,
|
||||
timeLocal: undefined,
|
||||
requestMethod: undefined,
|
||||
requestUri: undefined,
|
||||
userAgent: undefined,
|
||||
requestParams: undefined,
|
||||
userToken: undefined,
|
||||
// createdAt: undefined, // 移除此行
|
||||
beginTime: undefined, // 添加起始时间
|
||||
endTime: undefined, // 添加终止时间
|
||||
mobile: undefined,
|
||||
userId: undefined,
|
||||
deviceId: undefined,
|
||||
isUpdateUser: undefined,
|
||||
matchId: undefined,
|
||||
apiNames: undefined,
|
||||
params: {
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
id: [
|
||||
{ required: true, message: "不能为空", trigger: "blur" }
|
||||
],
|
||||
createdAt: [
|
||||
{ required: true, message: "不能为空", trigger: "blur" }
|
||||
],
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询nginx日志列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listLogs(queryParams.value);
|
||||
logsList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
}
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = {...initFormData};
|
||||
logsFormRef.value?.resetFields();
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: LogsVO[]) => {
|
||||
ids.value = selection.map(item => item.id);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
// /** 新增按钮操作 */
|
||||
// const handleAdd = () => {
|
||||
// reset();
|
||||
// dialog.visible = true;
|
||||
// dialog.title = "添加nginx日志";
|
||||
// }
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: LogsVO) => {
|
||||
reset();
|
||||
const _id = row?.id || ids.value[0]
|
||||
const res = await getLogs(_id);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = "修改nginx日志";
|
||||
}
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
logsFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.id) {
|
||||
await updateLogs(form.value).finally(() => buttonLoading.value = false);
|
||||
} else {
|
||||
await addLogs(form.value).finally(() => buttonLoading.value = false);
|
||||
}
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: LogsVO) => {
|
||||
const _ids = row?.id || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除nginx日志编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
|
||||
await delLogs(_ids);
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
await getList();
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download('console/logs/export', {
|
||||
...queryParams.value
|
||||
}, `logs_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
315
src/views/prediction/program/index.vue
Normal file
315
src/views/prediction/program/index.vue
Normal file
@ -0,0 +1,315 @@
|
||||
<template>
|
||||
<div class="p-2">
|
||||
<transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
|
||||
<div v-show="showSearch" class="mb-[10px]">
|
||||
<el-card shadow="hover">
|
||||
<el-form ref="queryFormRef" :model="queryParams" :inline="true">
|
||||
<el-form-item label="开始日期" prop="beginTime">
|
||||
<el-date-picker clearable
|
||||
v-model="queryParams.beginTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择开始日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束日期" prop="endTime">
|
||||
<el-date-picker clearable
|
||||
v-model="queryParams.endTime"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择结束日期"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<el-card shadow="never">
|
||||
<template #header>
|
||||
<el-row :gutter="10" class="mb8">
|
||||
<el-col :span="1.5">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['console:program:add']">新增</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['console:program:edit']">修改</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['console:program:remove']">删除</el-button>
|
||||
</el-col>
|
||||
<el-col :span="1.5">
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['console:program:export']">导出</el-button>
|
||||
</el-col>
|
||||
<right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<el-table v-loading="loading" :data="programList" @selection-change="handleSelectionChange">
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="方案号" align="center" prop="programId" v-if="true" />
|
||||
<el-table-column label="一段JSON文本,返回给客户端" align="center" prop="tickets" />
|
||||
<el-table-column label="收益倍数" align="center" prop="earnings" />
|
||||
<el-table-column label="开奖状态" align="center" prop="status" />
|
||||
<el-table-column label="相关比赛" align="center" prop="reference" />
|
||||
<el-table-column label="预测概率" align="center" prop="mojieIndex" />
|
||||
<el-table-column label="方案类型" align="center" prop="type" />
|
||||
<el-table-column label="方案状态" align="center" prop="isValid" />
|
||||
<el-table-column label="串关个数" align="center" prop="passNum" />
|
||||
<el-table-column label="截止时间" align="center" prop="closingTime" width="180">
|
||||
<template #default="scope">
|
||||
<span>{{ parseTime(scope.row.closingTime, '{y}-{m}-{d}') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="当天的第几个方案" align="center" prop="programNum" />
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
<el-tooltip content="修改" placement="top">
|
||||
<el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['console:program:edit']"></el-button>
|
||||
</el-tooltip>
|
||||
<el-tooltip content="删除" placement="top">
|
||||
<el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['console:program:remove']"></el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
|
||||
</el-card>
|
||||
<!-- 添加或修改赛事方案对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="programFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="一段JSON文本,返回给客户端" prop="tickets">
|
||||
<el-input v-model="form.tickets" type="textarea" placeholder="请输入内容" />
|
||||
</el-form-item>
|
||||
<el-form-item label="收益倍数" prop="earnings">
|
||||
<el-input v-model="form.earnings" placeholder="请输入收益倍数" />
|
||||
</el-form-item>
|
||||
<el-form-item label="相关比赛" prop="reference">
|
||||
<el-input v-model="form.reference" placeholder="请输入相关比赛" />
|
||||
</el-form-item>
|
||||
<el-form-item label="预测概率" prop="mojieIndex">
|
||||
<el-input v-model="form.mojieIndex" placeholder="请输入预测概率" />
|
||||
</el-form-item>
|
||||
<el-form-item label="方案状态" prop="isValid">
|
||||
<el-input v-model="form.isValid" placeholder="请输入0 -- 无效 1 -- 有效" />
|
||||
</el-form-item>
|
||||
<el-form-item label="串关个数" prop="passNum">
|
||||
<el-input v-model="form.passNum" placeholder="请输入串关个数" />
|
||||
</el-form-item>
|
||||
<el-form-item label="截止时间" prop="closingTime">
|
||||
<el-date-picker clearable
|
||||
v-model="form.closingTime"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="请选择截止时间">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
<el-form-item label="当天的第几个方案" prop="programNum">
|
||||
<el-input v-model="form.programNum" placeholder="请输入当天的第几个方案" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup name="Program" lang="ts">
|
||||
import { listProgram, getProgram, delProgram, addProgram, updateProgram } from '@/api/prediction/program';
|
||||
import { ProgramVO, ProgramQuery, ProgramForm } from '@/api/prediction/program/types';
|
||||
|
||||
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
||||
|
||||
const programList = ref<ProgramVO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const loading = ref(true);
|
||||
const showSearch = ref(true);
|
||||
const ids = ref<Array<string | number>>([]);
|
||||
const single = ref(true);
|
||||
const multiple = ref(true);
|
||||
const total = ref(0);
|
||||
|
||||
const queryFormRef = ref<ElFormInstance>();
|
||||
const programFormRef = ref<ElFormInstance>();
|
||||
|
||||
const dialog = reactive<DialogOption>({
|
||||
visible: false,
|
||||
title: ''
|
||||
});
|
||||
|
||||
const initFormData: ProgramForm = {
|
||||
programId: undefined,
|
||||
tickets: undefined,
|
||||
earnings: undefined,
|
||||
status: undefined,
|
||||
reference: undefined,
|
||||
mojieIndex: undefined,
|
||||
type: undefined,
|
||||
isValid: undefined,
|
||||
passNum: undefined,
|
||||
closingTime: undefined,
|
||||
beginTime: undefined,
|
||||
endTime: undefined,
|
||||
programNum: undefined
|
||||
}
|
||||
const data = reactive<PageData<ProgramForm, ProgramQuery>>({
|
||||
form: {...initFormData},
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
tickets: undefined,
|
||||
earnings: undefined,
|
||||
status: undefined,
|
||||
reference: undefined,
|
||||
mojieIndex: undefined,
|
||||
type: undefined,
|
||||
isValid: undefined,
|
||||
passNum: undefined,
|
||||
closingTime: undefined,
|
||||
beginTime: undefined,
|
||||
endTime: undefined,
|
||||
programNum: undefined,
|
||||
params: {
|
||||
}
|
||||
},
|
||||
rules: {
|
||||
programId: [
|
||||
{ required: true, message: "方案号不能为空", trigger: "blur" }
|
||||
],
|
||||
tickets: [
|
||||
{ required: true, message: "一段JSON文本,返回给客户端不能为空", trigger: "blur" }
|
||||
],
|
||||
earnings: [
|
||||
{ required: true, message: "收益倍数不能为空", trigger: "blur" }
|
||||
],
|
||||
status: [
|
||||
{ required: true, message: "9 -- 未开奖 0 -- 未中奖 1 -- 已中奖不能为空", trigger: "change" }
|
||||
],
|
||||
reference: [
|
||||
{ required: true, message: "相关比赛不能为空", trigger: "blur" }
|
||||
],
|
||||
mojieIndex: [
|
||||
{ required: true, message: "预测概率不能为空", trigger: "blur" }
|
||||
],
|
||||
type: [
|
||||
{ required: true, message: "方案类型 0 -- 精选方案 1 -- 高赔方案 2 -- 自定义方案不能为空", trigger: "change" }
|
||||
],
|
||||
isValid: [
|
||||
{ required: true, message: "0 -- 无效 1 -- 有效不能为空", trigger: "blur" }
|
||||
],
|
||||
passNum: [
|
||||
{ required: true, message: "串关个数不能为空", trigger: "blur" }
|
||||
],
|
||||
closingTime: [
|
||||
{ required: true, message: "截止时间不能为空", trigger: "blur" }
|
||||
],
|
||||
programNum: [
|
||||
{ required: true, message: "当天的第几个方案不能为空", trigger: "blur" }
|
||||
]
|
||||
}
|
||||
});
|
||||
|
||||
const { queryParams, form, rules } = toRefs(data);
|
||||
|
||||
/** 查询赛事方案列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true;
|
||||
const res = await listProgram(queryParams.value);
|
||||
programList.value = res.rows;
|
||||
total.value = res.total;
|
||||
loading.value = false;
|
||||
}
|
||||
|
||||
/** 取消按钮 */
|
||||
const cancel = () => {
|
||||
reset();
|
||||
dialog.visible = false;
|
||||
}
|
||||
|
||||
/** 表单重置 */
|
||||
const reset = () => {
|
||||
form.value = {...initFormData};
|
||||
programFormRef.value?.resetFields();
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.value.pageNum = 1;
|
||||
getList();
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryFormRef.value?.resetFields();
|
||||
handleQuery();
|
||||
}
|
||||
|
||||
/** 多选框选中数据 */
|
||||
const handleSelectionChange = (selection: ProgramVO[]) => {
|
||||
ids.value = selection.map(item => item.programId);
|
||||
single.value = selection.length != 1;
|
||||
multiple.value = !selection.length;
|
||||
}
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
reset();
|
||||
dialog.visible = true;
|
||||
dialog.title = "添加赛事方案";
|
||||
}
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row?: ProgramVO) => {
|
||||
reset();
|
||||
const _programId = row?.programId || ids.value[0]
|
||||
const res = await getProgram(_programId);
|
||||
Object.assign(form.value, res.data);
|
||||
dialog.visible = true;
|
||||
dialog.title = "修改赛事方案";
|
||||
}
|
||||
|
||||
/** 提交按钮 */
|
||||
const submitForm = () => {
|
||||
programFormRef.value?.validate(async (valid: boolean) => {
|
||||
if (valid) {
|
||||
buttonLoading.value = true;
|
||||
if (form.value.programId) {
|
||||
await updateProgram(form.value).finally(() => buttonLoading.value = false);
|
||||
} else {
|
||||
await addProgram(form.value).finally(() => buttonLoading.value = false);
|
||||
}
|
||||
proxy?.$modal.msgSuccess("操作成功");
|
||||
dialog.visible = false;
|
||||
await getList();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = async (row?: ProgramVO) => {
|
||||
const _programIds = row?.programId || ids.value;
|
||||
await proxy?.$modal.confirm('是否确认删除赛事方案编号为"' + _programIds + '"的数据项?').finally(() => loading.value = false);
|
||||
await delProgram(_programIds);
|
||||
proxy?.$modal.msgSuccess("删除成功");
|
||||
await getList();
|
||||
}
|
||||
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
proxy?.download('prediction/program/export', {
|
||||
...queryParams.value
|
||||
}, `program_${new Date().getTime()}.xlsx`)
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in New Issue
Block a user