chore: format code style and update linting configuration

This commit is contained in:
Megghy
2025-10-02 10:38:23 +08:00
parent 6fd046adcd
commit 758549d29d
253 changed files with 16258 additions and 15833 deletions

View File

@@ -1,3 +1,425 @@
<script lang="ts" setup>
import type { DataTableColumns } from 'naive-ui'
import type { CheckInRankingInfo, CheckInResult } from '@/api/api-models'
import { Info24Filled } from '@vicons/fluent'
import { NAlert, NButton, NCard, NDataTable, NDivider, NForm, NFormItem, NIcon, NInput, NInputGroup, NInputNumber, NPopconfirm, NSelect, NSpace, NSpin, NSwitch, NTabPane, NTabs, NText, NTime, NTooltip } from 'naive-ui'
import { computed, h, onMounted, ref } from 'vue'
import { SaveEnableFunctions, SaveSetting, useAccount } from '@/api/account'
import { FunctionTypes } from '@/api/api-models'
import { QueryGetAPI } from '@/api/query'
import { useAutoAction } from '@/client/store/useAutoAction'
import { CHECKIN_API_URL } from '@/data/constants'
import AutoActionEditor from '../AutoActionEditor.vue'
import TemplateHelper from '../TemplateHelper.vue'
interface LiveInfo {
roomId?: number
}
const autoActionStore = useAutoAction()
const config = autoActionStore.checkInModule.checkInConfig
const accountInfo = useAccount()
const isLoading = ref(false)
const customTestContext = ref({
checkin: {
points: 0,
consecutiveDays: 0,
todayRank: 0,
time: new Date(),
},
})
// 签到模板的特定占位符
const checkInPlaceholders = [
{ name: '{{checkin.points}}', description: '获得的总积分' },
{ name: '{{checkin.consecutiveDays}}', description: '连续签到天数' },
{ name: '{{checkin.todayRank}}', description: '今日签到排名' },
{ name: '{{checkin.time}}', description: '签到时间对象' },
]
// 服务端签到设置
const serverSetting = computed(() => {
return accountInfo.value?.settings?.point || {}
})
// 是否可以编辑设置
const canEdit = computed(() => {
return accountInfo.value && accountInfo.value.settings && accountInfo.value.settings.point
})
// 更新所有设置
async function updateSettings() {
// 先保存服务端设置
const serverSaved = await updateServerSettings()
if (serverSaved) {
window.$notification.success({
title: '设置已保存',
duration: 3000,
})
}
return serverSaved
}
// 更新服务端签到设置
async function updateServerSettings() {
if (!canEdit.value) {
return false
}
isLoading.value = true
try {
const msg = await SaveSetting('Point', accountInfo.value.settings.point)
if (msg) {
return true
} else {
window.$notification.error({
title: '保存失败',
content: msg,
duration: 5000,
})
}
} catch (err) {
window.$notification.error({
title: '保存失败',
content: String(err),
duration: 5000,
})
console.error('保存签到设置失败:', err)
} finally {
isLoading.value = false
}
return false
}
// 排行榜数据
const rankingData = ref<CheckInRankingInfo[]>([])
const isLoadingRanking = ref(false)
const timeRange = ref<string>('all')
const userFilter = ref<string>('')
const pagination = ref({
page: 1,
pageSize: 10,
})
// 时间段选项
const timeRangeOptions = [
{ label: '全部时间', value: 'all' },
{ label: '今日', value: 'today' },
{ label: '本周', value: 'week' },
{ label: '本月', value: 'month' },
{ label: '上个月', value: 'lastMonth' },
]
// 过滤后的排行榜数据
const filteredRankingData = computed(() => {
let filtered = rankingData.value
// 按时间范围筛选
if (timeRange.value !== 'all') {
const now = new Date()
let startTime: Date
if (timeRange.value === 'today') {
// 今天凌晨
startTime = new Date(now)
startTime.setHours(0, 0, 0, 0)
} else if (timeRange.value === 'week') {
// 本周一
const dayOfWeek = now.getDay() || 7 // 把周日作为7处理
startTime = new Date(now)
startTime.setDate(now.getDate() - (dayOfWeek - 1))
startTime.setHours(0, 0, 0, 0)
} else if (timeRange.value === 'month') {
// 本月1号
startTime = new Date(now.getFullYear(), now.getMonth(), 1)
} else if (timeRange.value === 'lastMonth') {
// 上月1号
startTime = new Date(now.getFullYear(), now.getMonth() - 1, 1)
// 本月1号作为结束时间
const endTime = new Date(now.getFullYear(), now.getMonth(), 1)
filtered = filtered.filter((user) => {
const checkInTime = new Date(user.lastCheckInTime)
return checkInTime >= startTime && checkInTime < endTime
})
// 已经筛选完成,不需要再次筛选
startTime = new Date(0)
}
// 如果不是上个月,用通用筛选逻辑
if (timeRange.value !== 'lastMonth') {
filtered = filtered.filter((user) => {
const checkInTime = new Date(user.lastCheckInTime)
return checkInTime >= startTime
})
}
}
// 按用户名筛选
if (userFilter.value) {
const keyword = userFilter.value.toLowerCase()
filtered = filtered.filter(user =>
user.name.toLowerCase().includes(keyword),
)
}
return filtered
})
// 排行榜列定义
const rankingColumns: DataTableColumns<CheckInRankingInfo> = [
{
title: '排名',
key: 'rank',
render: (row: CheckInRankingInfo, index: number) => h('span', {}, index + 1),
},
{
title: '用户名',
key: 'name',
},
{
title: '连续签到天数',
key: 'consecutiveDays',
sorter: 'default',
},
{
title: '积分',
key: 'points',
sorter: 'default',
},
{
title: '最近签到时间',
key: 'lastCheckInTime',
render(row: CheckInRankingInfo) {
return h(NTooltip, {
}, {
trigger: () => h(NTime, {
time: row.lastCheckInTime,
type: 'relative',
}),
default: () => new Date(row.lastCheckInTime).toLocaleString(),
})
},
sorter: 'default',
},
{
title: '已认证',
key: 'isAuthed',
render(row: CheckInRankingInfo) {
return h('span', {}, row.isAuthed ? '是' : '否')
},
},
{
title: '操作',
key: 'actions',
render(row: CheckInRankingInfo) {
return h(
NPopconfirm,
{
onPositiveClick: () => resetUserCheckInByGuid(row.ouId),
},
{
trigger: () => h(
NButton,
{
size: 'small',
type: 'warning',
disabled: isResetting.value,
loading: isResetting.value && resetTargetId.value === row.ouId,
onClick: e => e.stopPropagation(),
},
{ default: () => '重置签到' },
),
default: () => '确定要重置该用户的所有签到数据吗?此操作不可撤销。',
},
)
},
},
]
// 加载签到排行榜数据
async function loadCheckInRanking() {
if (isLoadingRanking.value) return
isLoadingRanking.value = true
try {
// 获取所有用户数据,不再根据时间范围过滤
const response = await QueryGetAPI<CheckInRankingInfo[]>(`${CHECKIN_API_URL}admin/users`)
if (response.code == 200) {
rankingData.value = response.data
pagination.value.page = 1 // 重置为第一页
} else {
rankingData.value = []
window.$message.error(`获取签到排行榜失败: ${response.message}`)
}
} catch (error) {
console.error('加载签到排行榜失败:', error)
window.$notification.error({
title: '加载失败',
content: '无法加载签到排行榜数据',
duration: 5000,
})
rankingData.value = []
} finally {
isLoadingRanking.value = false
}
}
// 重置签到数据相关
const isResetting = ref(false)
const resetTargetId = ref<string>()
// 重置单个用户签到数据
async function resetUserCheckInByGuid(ouId: string) {
if (!ouId || isResetting.value) return
isResetting.value = true
resetTargetId.value = ouId
try {
const response = await QueryGetAPI(`${CHECKIN_API_URL}admin/reset`, {
ouId,
})
if (response && response.code === 200) {
window.$notification.success({
title: '重置成功',
content: '用户签到数据已重置',
duration: 3000,
})
// 重置成功后重新加载排行榜
await loadCheckInRanking()
} else {
window.$notification.error({
title: '重置失败',
content: response?.message || '无法重置用户签到数据',
duration: 5000,
})
}
} catch (error) {
console.error('重置用户签到数据失败:', error)
window.$notification.error({
title: '重置失败',
content: '重置用户签到数据时发生错误',
duration: 5000,
})
} finally {
isResetting.value = false
resetTargetId.value = undefined
}
}
// 重置所有用户签到数据
async function resetAllCheckIn() {
if (isResetting.value) return
isResetting.value = true
try {
const response = await QueryGetAPI(`${CHECKIN_API_URL}admin/reset`, {})
if (response && response.code === 200) {
window.$notification.success({
title: '重置成功',
content: '所有用户的签到数据已重置',
duration: 3000,
})
// 重置成功后重新加载排行榜
await loadCheckInRanking()
} else {
window.$notification.error({
title: '重置失败',
content: response?.message || '无法重置所有用户签到数据',
duration: 5000,
})
}
} catch (error) {
console.error('重置所有用户签到数据失败:', error)
window.$notification.error({
title: '重置失败',
content: '重置所有用户签到数据时发生错误',
duration: 5000,
})
} finally {
isResetting.value = false
}
}
// 测试签到功能
const testUid = ref<number>()
const testUsername = ref<string>('测试用户')
const testResult = ref<{ success: boolean, message: string }>()
// 处理测试签到
async function handleTestCheckIn() {
if (!testUid.value || !serverSetting.value.enableCheckIn) {
testResult.value = {
success: false,
message: '请输入有效的UID或确保签到功能已启用',
}
return
}
try {
// 直接调用服务端签到API
const response = await QueryGetAPI<CheckInResult>(`${CHECKIN_API_URL}check-in-for`, {
uId: testUid.value,
name: testUsername.value || '测试用户',
})
if (response.code === 200 && response.data) {
const result = response.data
testResult.value = {
success: result.success,
message: result.success
? `签到成功!用户 ${testUsername.value || '测试用户'} 获得 ${result.points} 积分,连续签到 ${result.consecutiveDays}`
: result.message || '签到失败,可能今天已经签到过了',
}
// 显示通知
window.$notification[result.success ? 'success' : 'info']({
title: result.success ? '测试签到成功' : '测试签到失败',
content: testResult.value.message,
duration: 3000,
})
} else {
testResult.value = {
success: false,
message: `API返回错误: ${response.message || '未知错误'}`,
}
}
} catch (error) {
testResult.value = {
success: false,
message: `签到操作失败: ${error instanceof Error ? error.message : String(error)}`,
}
// 显示错误通知
window.$notification.error({
title: '测试签到失败',
content: testResult.value.message,
duration: 5000,
})
}
}
function updateCheckInRanking(value: boolean) {
accountInfo.value.settings.enableFunctions = value ? [...accountInfo.value.settings.enableFunctions, FunctionTypes.CheckInRanking] : accountInfo.value.settings.enableFunctions.filter(f => f !== FunctionTypes.CheckInRanking)
SaveEnableFunctions(accountInfo.value.settings.enableFunctions)
}
// 组件挂载时加载排行榜
onMounted(() => {
loadCheckInRanking()
})
</script>
<template>
<NCard
v-if="config"
@@ -24,7 +446,7 @@
label-placement="left"
:label-width="120"
:style="{
maxWidth: '650px'
maxWidth: '650px',
}"
>
<!-- 服务端签到设置 -->
@@ -272,7 +694,7 @@
showSizePicker: true,
pageSizes: [10, 20, 50, 100],
onChange: (page: number) => pagination.page = page,
onUpdatePageSize: (pageSize: number) => pagination.pageSize = pageSize
onUpdatePageSize: (pageSize: number) => pagination.pageSize = pageSize,
}"
:bordered="false"
:loading="isLoadingRanking"
@@ -380,428 +802,6 @@
</NCard>
</template>
<script lang="ts" setup>
import { SaveEnableFunctions, SaveSetting, useAccount } from '@/api/account';
import { CheckInRankingInfo, CheckInResult, FunctionTypes } from '@/api/api-models';
import { QueryGetAPI } from '@/api/query';
import { useAutoAction } from '@/client/store/useAutoAction';
import { CHECKIN_API_URL } from '@/data/constants';
import { GuidUtils } from '@/Utils';
import { Info24Filled } from '@vicons/fluent';
import type { DataTableColumns } from 'naive-ui';
import { NAlert, NButton, NCard, NDataTable, NDivider, NEmpty, NForm, NFormItem, NIcon, NInput, NInputGroup, NInputNumber, NPopconfirm, NSelect, NSpace, NSpin, NSwitch, NTabPane, NTabs, NText, NTime, NTooltip } from 'naive-ui';
import { computed, h, onMounted, ref, watch } from 'vue';
import AutoActionEditor from '../AutoActionEditor.vue';
import TemplateHelper from '../TemplateHelper.vue';
interface LiveInfo {
roomId?: number;
}
const autoActionStore = useAutoAction();
const config = autoActionStore.checkInModule.checkInConfig;
const accountInfo = useAccount();
const isLoading = ref(false);
const customTestContext = ref({
checkin: {
points: 0,
consecutiveDays: 0,
todayRank: 0,
time: new Date()
}
});
// 签到模板的特定占位符
const checkInPlaceholders = [
{ name: '{{checkin.points}}', description: '获得的总积分' },
{ name: '{{checkin.consecutiveDays}}', description: '连续签到天数' },
{ name: '{{checkin.todayRank}}', description: '今日签到排名' },
{ name: '{{checkin.time}}', description: '签到时间对象' }
];
// 服务端签到设置
const serverSetting = computed(() => {
return accountInfo.value?.settings?.point || {};
});
// 是否可以编辑设置
const canEdit = computed(() => {
return accountInfo.value && accountInfo.value.settings && accountInfo.value.settings.point;
});
// 更新所有设置
async function updateSettings() {
// 先保存服务端设置
const serverSaved = await updateServerSettings();
if (serverSaved) {
window.$notification.success({
title: '设置已保存',
duration: 3000
});
}
return serverSaved;
}
// 更新服务端签到设置
async function updateServerSettings() {
if (!canEdit.value) {
return false;
}
isLoading.value = true;
try {
const msg = await SaveSetting('Point', accountInfo.value.settings.point);
if (msg) {
return true;
} else {
window.$notification.error({
title: '保存失败',
content: msg,
duration: 5000
});
}
} catch (err) {
window.$notification.error({
title: '保存失败',
content: String(err),
duration: 5000
});
console.error('保存签到设置失败:', err);
} finally {
isLoading.value = false;
}
return false;
}
// 排行榜数据
const rankingData = ref<CheckInRankingInfo[]>([]);
const isLoadingRanking = ref(false);
const timeRange = ref<string>('all');
const userFilter = ref<string>('');
const pagination = ref({
page: 1,
pageSize: 10
});
// 时间段选项
const timeRangeOptions = [
{ label: '全部时间', value: 'all' },
{ label: '今日', value: 'today' },
{ label: '本周', value: 'week' },
{ label: '本月', value: 'month' },
{ label: '上个月', value: 'lastMonth' },
];
// 过滤后的排行榜数据
const filteredRankingData = computed(() => {
let filtered = rankingData.value;
// 按时间范围筛选
if (timeRange.value !== 'all') {
const now = new Date();
let startTime: Date;
if (timeRange.value === 'today') {
// 今天凌晨
startTime = new Date(now);
startTime.setHours(0, 0, 0, 0);
} else if (timeRange.value === 'week') {
// 本周一
const dayOfWeek = now.getDay() || 7; // 把周日作为7处理
startTime = new Date(now);
startTime.setDate(now.getDate() - (dayOfWeek - 1));
startTime.setHours(0, 0, 0, 0);
} else if (timeRange.value === 'month') {
// 本月1号
startTime = new Date(now.getFullYear(), now.getMonth(), 1);
} else if (timeRange.value === 'lastMonth') {
// 上月1号
startTime = new Date(now.getFullYear(), now.getMonth() - 1, 1);
// 本月1号作为结束时间
const endTime = new Date(now.getFullYear(), now.getMonth(), 1);
filtered = filtered.filter(user => {
const checkInTime = new Date(user.lastCheckInTime);
return checkInTime >= startTime && checkInTime < endTime;
});
// 已经筛选完成,不需要再次筛选
startTime = new Date(0);
}
// 如果不是上个月,用通用筛选逻辑
if (timeRange.value !== 'lastMonth') {
filtered = filtered.filter(user => {
const checkInTime = new Date(user.lastCheckInTime);
return checkInTime >= startTime;
});
}
}
// 按用户名筛选
if (userFilter.value) {
const keyword = userFilter.value.toLowerCase();
filtered = filtered.filter(user =>
user.name.toLowerCase().includes(keyword)
);
}
return filtered;
});
// 排行榜列定义
const rankingColumns: DataTableColumns<CheckInRankingInfo> = [
{
title: '排名',
key: 'rank',
render: (row: CheckInRankingInfo, index: number) => h('span', {}, index + 1)
},
{
title: '用户名',
key: 'name'
},
{
title: '连续签到天数',
key: 'consecutiveDays',
sorter: 'default'
},
{
title: '积分',
key: 'points',
sorter: 'default'
},
{
title: '最近签到时间',
key: 'lastCheckInTime',
render(row: CheckInRankingInfo) {
return h(NTooltip, {
}, {
trigger: () => h(NTime, {
time: row.lastCheckInTime,
type: 'relative'
}),
default: () => new Date(row.lastCheckInTime).toLocaleString()
});
},
sorter: 'default'
},
{
title: '已认证',
key: 'isAuthed',
render(row: CheckInRankingInfo) {
return h('span', {}, row.isAuthed ? '是' : '否');
}
},
{
title: '操作',
key: 'actions',
render(row: CheckInRankingInfo) {
return h(
NPopconfirm,
{
onPositiveClick: () => resetUserCheckInByGuid(row.ouId)
},
{
trigger: () => h(
NButton,
{
size: 'small',
type: 'warning',
disabled: isResetting.value,
loading: isResetting.value && resetTargetId.value === row.ouId,
onClick: (e) => e.stopPropagation()
},
{ default: () => '重置签到' }
),
default: () => '确定要重置该用户的所有签到数据吗?此操作不可撤销。'
}
);
}
}
];
// 加载签到排行榜数据
async function loadCheckInRanking() {
if (isLoadingRanking.value) return;
isLoadingRanking.value = true;
try {
// 获取所有用户数据,不再根据时间范围过滤
const response = await QueryGetAPI<CheckInRankingInfo[]>(`${CHECKIN_API_URL}admin/users`);
if (response.code == 200) {
rankingData.value = response.data;
pagination.value.page = 1; // 重置为第一页
} else {
rankingData.value = [];
window.$message.error(`获取签到排行榜失败: ${response.message}`);
}
} catch (error) {
console.error('加载签到排行榜失败:', error);
window.$notification.error({
title: '加载失败',
content: '无法加载签到排行榜数据',
duration: 5000
});
rankingData.value = [];
} finally {
isLoadingRanking.value = false;
}
}
// 重置签到数据相关
const isResetting = ref(false);
const resetTargetId = ref<string>();
// 重置单个用户签到数据
async function resetUserCheckInByGuid(ouId: string) {
if (!ouId || isResetting.value) return;
isResetting.value = true;
resetTargetId.value = ouId;
try {
const response = await QueryGetAPI(`${CHECKIN_API_URL}admin/reset`, {
ouId: ouId
});
if (response && response.code === 200) {
window.$notification.success({
title: '重置成功',
content: '用户签到数据已重置',
duration: 3000
});
// 重置成功后重新加载排行榜
await loadCheckInRanking();
} else {
window.$notification.error({
title: '重置失败',
content: response?.message || '无法重置用户签到数据',
duration: 5000
});
}
} catch (error) {
console.error('重置用户签到数据失败:', error);
window.$notification.error({
title: '重置失败',
content: '重置用户签到数据时发生错误',
duration: 5000
});
} finally {
isResetting.value = false;
resetTargetId.value = undefined;
}
}
// 重置所有用户签到数据
async function resetAllCheckIn() {
if (isResetting.value) return;
isResetting.value = true;
try {
const response = await QueryGetAPI(`${CHECKIN_API_URL}admin/reset`, {});
if (response && response.code === 200) {
window.$notification.success({
title: '重置成功',
content: '所有用户的签到数据已重置',
duration: 3000
});
// 重置成功后重新加载排行榜
await loadCheckInRanking();
} else {
window.$notification.error({
title: '重置失败',
content: response?.message || '无法重置所有用户签到数据',
duration: 5000
});
}
} catch (error) {
console.error('重置所有用户签到数据失败:', error);
window.$notification.error({
title: '重置失败',
content: '重置所有用户签到数据时发生错误',
duration: 5000
});
} finally {
isResetting.value = false;
}
}
// 测试签到功能
const testUid = ref<number>();
const testUsername = ref<string>('测试用户');
const testResult = ref<{ success: boolean; message: string }>();
// 处理测试签到
async function handleTestCheckIn() {
if (!testUid.value || !serverSetting.value.enableCheckIn) {
testResult.value = {
success: false,
message: '请输入有效的UID或确保签到功能已启用'
};
return;
}
try {
// 直接调用服务端签到API
const response = await QueryGetAPI<CheckInResult>(`${CHECKIN_API_URL}check-in-for`, {
uId: testUid.value,
name: testUsername.value || '测试用户'
});
if (response.code === 200 && response.data) {
const result = response.data;
testResult.value = {
success: result.success,
message: result.success
? `签到成功!用户 ${testUsername.value || '测试用户'} 获得 ${result.points} 积分,连续签到 ${result.consecutiveDays}`
: result.message || '签到失败,可能今天已经签到过了'
};
// 显示通知
window.$notification[result.success ? 'success' : 'info']({
title: result.success ? '测试签到成功' : '测试签到失败',
content: testResult.value.message,
duration: 3000
});
} else {
testResult.value = {
success: false,
message: `API返回错误: ${response.message || '未知错误'}`
};
}
} catch (error) {
testResult.value = {
success: false,
message: `签到操作失败: ${error instanceof Error ? error.message : String(error)}`
};
// 显示错误通知
window.$notification.error({
title: '测试签到失败',
content: testResult.value.message,
duration: 5000
});
}
}
function updateCheckInRanking(value: boolean) {
accountInfo.value.settings.enableFunctions = value ? [...accountInfo.value.settings.enableFunctions, FunctionTypes.CheckInRanking] : accountInfo.value.settings.enableFunctions.filter(f => f !== FunctionTypes.CheckInRanking);
SaveEnableFunctions(accountInfo.value.settings.enableFunctions);
}
// 组件挂载时加载排行榜
onMounted(() => {
loadCheckInRanking();
});
</script>
<style scoped>
.settings-section {
margin: 8px 0;
@@ -810,4 +810,4 @@ onMounted(() => {
.ranking-filter {
margin: 10px 0;
}
</style>
</style>