版本更新
Some checks are pending
CI / Test (ubuntu-latest) (push) Waiting to run
CI / Test (windows-latest) (push) Waiting to run
CI / Lint (ubuntu-latest) (push) Waiting to run
CI / Lint (windows-latest) (push) Waiting to run
CI / Check (ubuntu-latest) (push) Waiting to run
CI / Check (windows-latest) (push) Waiting to run
CI / CI OK (push) Blocked by required conditions
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
Deploy Website on push / Deploy Push Playground Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Docs Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Antd Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Element Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Naive Ftp (push) Waiting to run
Release Drafter / update_release_draft (push) Waiting to run
Some checks are pending
CI / Test (ubuntu-latest) (push) Waiting to run
CI / Test (windows-latest) (push) Waiting to run
CI / Lint (ubuntu-latest) (push) Waiting to run
CI / Lint (windows-latest) (push) Waiting to run
CI / Check (ubuntu-latest) (push) Waiting to run
CI / Check (windows-latest) (push) Waiting to run
CI / CI OK (push) Blocked by required conditions
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Waiting to run
Deploy Website on push / Deploy Push Playground Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Docs Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Antd Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Element Ftp (push) Waiting to run
Deploy Website on push / Deploy Push Naive Ftp (push) Waiting to run
Release Drafter / update_release_draft (push) Waiting to run
This commit is contained in:
parent
d6ab60b5c9
commit
a42ddfc1fa
@ -1,6 +1,6 @@
|
||||
# 应用标题
|
||||
VITE_APP_TITLE=喵喵喵之家
|
||||
VITE_APP_LOGO='../public/favicon.ico' # Adjust the path as necessary
|
||||
VITE_APP_LOGO='https://merge-pet-web.oss-cn-heyuan.aliyuncs.com/favicon.ico' # Adjust the path as necessary
|
||||
|
||||
# 应用命名空间,用于缓存、store等功能的前缀,确保隔离
|
||||
VITE_APP_NAMESPACE=vben-web-antd
|
||||
|
||||
BIN
apps/web-antd/public/public/favicon.ico
Normal file
BIN
apps/web-antd/public/public/favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 33 KiB |
@ -42,6 +42,7 @@ export interface UserLogInfo {
|
||||
Bonus?: number;
|
||||
Code?: string;
|
||||
RegisterTime: number;
|
||||
Ban?: number;
|
||||
Order: UserLogOrder[];
|
||||
Heatmap?: heatType[];
|
||||
}
|
||||
|
||||
@ -32,6 +32,9 @@ export async function userGmApi(data : object) {
|
||||
return requestClient.post('/user/gm', data);
|
||||
}
|
||||
|
||||
export async function userBanApi(data : object) {
|
||||
return requestClient.post('/user/ban', data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ export const overridesPreferences = defineOverridesPreferences({
|
||||
// overrides
|
||||
app: {
|
||||
name: "喵喵喵之家2",
|
||||
defaultAvatar:'../public/favicon.ico', // Adjust the path as necessary
|
||||
defaultAvatar:'https://merge-pet-web.oss-cn-heyuan.aliyuncs.com/favicon.ico', // Adjust the path as necessary
|
||||
},
|
||||
copyright: {
|
||||
companyName: '厦门蹊径科技公司',
|
||||
|
||||
@ -159,7 +159,8 @@ const [Modal, modalApi] = useVbenModal({
|
||||
items: modalData.items,
|
||||
start_time: 0,
|
||||
register_time: modalData.register_time,
|
||||
mail_type: modalData.mail_type === 1 ? '全服邮件' : '个人邮件',
|
||||
mail_type: modalData.mail_type === 1 ? '普通邮件' : '节日邮件',
|
||||
send_type: modalData.send_type === 1 ? '全服邮件' : '个人邮件',
|
||||
ToUids: modalData.to_uids,
|
||||
});
|
||||
FormApi.updateSchema([
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { Button, Card, Space, message } from 'ant-design-vue';
|
||||
import { Button, Card, Space } from 'ant-design-vue';
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
import type { VxeGridListeners, VxeGridProps } from '#/adapter/vxe-table';
|
||||
import type { VbenFormProps } from '#/adapter/form';
|
||||
@ -216,9 +216,7 @@ async function deleteRow(row: MailData) {
|
||||
</Card>
|
||||
<Grid>
|
||||
<template #action="{ row }">
|
||||
<Button type="link" @click="deleteRow(row)" style="color: #cc0000"
|
||||
>删除</Button
|
||||
>
|
||||
<Button type="link" @click="deleteRow(row)" style="color: #cc0000">删除</Button>
|
||||
</template>
|
||||
</Grid>
|
||||
</Page>
|
||||
|
||||
@ -1,8 +1,11 @@
|
||||
<script lang="ts" setup>
|
||||
import { VbenAvatar } from '../../../../../../packages/@core/ui-kit/shadcn-ui/src/components';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { message, Tag } from 'ant-design-vue';
|
||||
import { computed } from 'vue';
|
||||
|
||||
interface Props {
|
||||
avatar?: string;
|
||||
ban?: number;
|
||||
}
|
||||
|
||||
|
||||
@ -26,19 +29,34 @@ defineOptions({
|
||||
name: 'UserHeader',
|
||||
});
|
||||
|
||||
withDefaults(defineProps<Props>(), {
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
avatar: '',
|
||||
ban: 0
|
||||
});
|
||||
const banStatus = computed(() => {
|
||||
if (props.ban === -1) {
|
||||
return { text: '永久封号', color: 'red' };
|
||||
} else if (props.ban > 0) {
|
||||
// 0天=粉红 #ffb6c1, 30天=深红 #b22222
|
||||
const minColor = [255, 182, 193]; // #ffb6c1
|
||||
const maxColor = [178, 34, 34]; // #b22222
|
||||
const days = Math.min(props.ban, 30);
|
||||
const ratio = days / 30;
|
||||
const color = minColor.map((c, i) => Math.round(c + (((maxColor?.[i] ?? c) - c) * ratio)));
|
||||
const colorHex = `#${color.map(x => x.toString(16).padStart(2, '0')).join('')}`;
|
||||
return { text: `封号${props.ban}天`, color: colorHex };
|
||||
} else {
|
||||
return { text: '正常', color: 'green' };
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<div class="card-box p-4 py-6 lg:flex">
|
||||
<VbenAvatar :src="avatar" class="size-20" />
|
||||
<div
|
||||
v-if="$slots.nick_name || $slots.user_name"
|
||||
class="flex flex-col justify-center md:ml-6 md:mt-0"
|
||||
>
|
||||
<div v-if="$slots.nick_name || $slots.user_name" class="flex flex-col justify-center md:ml-6 md:mt-0">
|
||||
<h1 v-if="$slots.nick_name" class="text-md font-semibold md:text-xl">
|
||||
<slot name="nick_name"></slot>
|
||||
<Tag class="ml-2" :color="banStatus.color">{{ banStatus.text }}</Tag>
|
||||
</h1>
|
||||
<span v-if="$slots.user_name" class="text-foreground/80 mt-1 ant-btn" @click='copyUserName' id="user_name">
|
||||
<slot name="user_name"></slot>
|
||||
|
||||
@ -3,7 +3,7 @@ import { ref, watch } from 'vue';
|
||||
import { useVbenModal, useVbenForm } from '@vben/common-ui';
|
||||
import { message } from 'ant-design-vue';
|
||||
import { getUserlogInfoApi } from '#/api/core/log';
|
||||
import { userGmApi } from '#/api/core/user';
|
||||
import { userGmApi, userBanApi } from '#/api/core/user';
|
||||
import { calendar } from '#/component/index';
|
||||
import type { dataType } from '#/component/index';
|
||||
// 引入 cal-heatmap 样式
|
||||
@ -15,6 +15,7 @@ import { WorkbenchProject, WorkbenchDetail } from '@vben/common-ui';
|
||||
import UserHeader from './user-header.vue';
|
||||
import { preferences } from '@vben/preferences';
|
||||
import { useUserStore } from '@vben/stores';
|
||||
import { AccessControl } from '@vben/access';
|
||||
|
||||
const userStore = useUserStore();
|
||||
|
||||
@ -63,6 +64,62 @@ const [BaseForm] = useVbenForm({
|
||||
wrapperClass: 'grid-cols-2 ',
|
||||
});
|
||||
|
||||
const [BanForm] = useVbenForm({
|
||||
// 所有表单项共用,可单独在表单内覆盖
|
||||
commonConfig: {
|
||||
// 所有表单项
|
||||
componentProps: {
|
||||
class: 'w-full',
|
||||
},
|
||||
},
|
||||
|
||||
// 使用 tailwindcss grid布局
|
||||
// 提交函数
|
||||
// 垂直布局,label和input在不同行,值为vertical
|
||||
layout: 'horizontal',
|
||||
// 水平布局,label和input在同一行
|
||||
schema: [
|
||||
{
|
||||
component: 'Select',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
options: [
|
||||
{ label: '封号1天', value: 1 },
|
||||
{ label: '封号7天', value: 7 },
|
||||
{ label: '封号30天', value: 30 },
|
||||
{ label: '封号永久', value: -1 },
|
||||
{ label: '解封', value: 0 },
|
||||
],
|
||||
},
|
||||
label: '封号:',
|
||||
fieldName: 'ban',
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
placeholder: '请输入封号原因',
|
||||
},
|
||||
label: '原因:',
|
||||
fieldName: 'reason',
|
||||
}
|
||||
],
|
||||
handleSubmit: async (values) => {
|
||||
const cv = modalApi.getData<Record<string, any>>();
|
||||
const r = await userBanApi({
|
||||
Uid: cv.uid,
|
||||
AppId: cv.AppId,
|
||||
ServerId: cv.ServerId,
|
||||
Day: values.ban,
|
||||
Reason: values.reason,
|
||||
});
|
||||
message.success(r.Msg);
|
||||
},
|
||||
showDefaultActions: true,
|
||||
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
|
||||
wrapperClass: 'grid-cols-3 ',
|
||||
});
|
||||
|
||||
const data = ref();
|
||||
const info = ref<{
|
||||
Level: number;
|
||||
@ -80,6 +137,7 @@ const info = ref<{
|
||||
Bonus?: number;
|
||||
Code?: string;
|
||||
RegisterTime?: string;
|
||||
Ban?: number;
|
||||
Order: WorkbenchProjectItem[];
|
||||
Heatmap: dataType[];
|
||||
}>({
|
||||
@ -122,6 +180,17 @@ const [Modal, modalApi] = useVbenModal({
|
||||
info.value.Name = r.Name;
|
||||
info.value.Charge = r.Charge;
|
||||
info.value.AreaId = r.AreaId;
|
||||
// 计算封号剩余天数(如果Ban为时间戳且大于当前时间,则计算剩余天数,否则为0或-1)
|
||||
if (r.Ban && r.Ban > 0) {
|
||||
const now = Math.floor(Date.now() / 1000);
|
||||
if (r.Ban > now) {
|
||||
info.value.Ban = Math.ceil((r.Ban - now) / 86400); // 剩余天数
|
||||
} else {
|
||||
info.value.Ban = 0; // 已解封
|
||||
}
|
||||
} else {
|
||||
info.value.Ban = r.Ban; // -1永久封号,0未封号
|
||||
}
|
||||
info.value.LoginTime = dayjs(r.Login * 1000).format(
|
||||
'YYYY-MM-DD HH:mm:ss',
|
||||
); // 转换时间戳
|
||||
@ -172,9 +241,7 @@ watch(
|
||||
<template>
|
||||
<Modal title="玩家详情">
|
||||
<div class="p-5">
|
||||
<UserHeader
|
||||
:avatar="userStore.userInfo?.avatar || preferences.app.defaultAvatar"
|
||||
>
|
||||
<UserHeader :avatar="userStore.userInfo?.avatar || preferences.app.defaultAvatar" :ban="info.Ban">
|
||||
<template #nick_name> nick_name: {{ info.Name || 'N/A' }} </template>
|
||||
<template #user_name> user_name: {{ info.Mac }} </template>
|
||||
<template #uid> uid: {{ info.Uid }} </template>
|
||||
@ -183,20 +250,31 @@ watch(
|
||||
<template #energy>{{ info.Energy }} </template>
|
||||
<template #diamond>{{ info.Diamond }}</template>
|
||||
</UserHeader>
|
||||
<AccessControl :codes="['super']" type="role">
|
||||
<div class="mt-5">
|
||||
<Card class="card-box flex flex-col p-5 ">
|
||||
<BaseForm />
|
||||
</Card>
|
||||
</div>
|
||||
</AccessControl>
|
||||
|
||||
<AccessControl :codes="['super']" type="role">
|
||||
<div class="mt-5">
|
||||
<Card class="card-box flex flex-col p-5 ">
|
||||
<BanForm />
|
||||
</Card>
|
||||
</div>
|
||||
</AccessControl>
|
||||
|
||||
|
||||
|
||||
<div class="mt-5 flex flex-col lg:flex-row">
|
||||
<div class="mr-4 w-full lg:w-3/5">
|
||||
<WorkbenchProject :items="info.Order" title="订单" />
|
||||
<!-- <WorkbenchTrends :items="trendItems" class="mt-5" title="最新动态" /> -->
|
||||
</div>
|
||||
<div class="w-full lg:w-2/5">
|
||||
<WorkbenchDetail
|
||||
:items="projectItems"
|
||||
class="mt-5 lg:mt-0"
|
||||
title="玩家详情"
|
||||
>
|
||||
<WorkbenchDetail :items="projectItems" class="mt-5 lg:mt-0" title="玩家详情">
|
||||
<template #areaid> {{ info.AreaId }}</template>
|
||||
<template #charge> <b>$</b>{{ info.Charge.toFixed(2) }}</template>
|
||||
<template #RegisterTime> {{ info.RegisterTime }}</template>
|
||||
@ -206,22 +284,14 @@ watch(
|
||||
<template #Code>{{ info.Code || 0 }}</template>
|
||||
<template #TodayCumulative>{{ info.TodayCumulative }}</template>
|
||||
</WorkbenchDetail>
|
||||
<calendar
|
||||
v-if="info.Heatmap.length > 0"
|
||||
style="margin-top: 15px"
|
||||
:dataList="info.Heatmap"
|
||||
title="热力图"
|
||||
:key="`heatmap-${info.Uid}`"
|
||||
/>
|
||||
<div
|
||||
v-else
|
||||
style="
|
||||
<calendar v-if="info.Heatmap.length > 0" style="margin-top: 15px" :dataList="info.Heatmap" title="热力图"
|
||||
:key="`heatmap-${info.Uid}`" />
|
||||
<div v-else style="
|
||||
margin-top: 15px;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
"
|
||||
>
|
||||
">
|
||||
暂无热力图数据
|
||||
</div>
|
||||
<!-- <WorkbenchTodo :items="todoItems" class="mt-5" title="待办事项" /> -->
|
||||
|
||||
@ -50,7 +50,7 @@ const defaultPreferences: Preferences = {
|
||||
},
|
||||
logo: {
|
||||
enable: true,
|
||||
source: '../public/favicon.ico',
|
||||
source: 'https://merge-pet-web.oss-cn-heyuan.aliyuncs.com/favicon.ico',
|
||||
},
|
||||
navigation: {
|
||||
accordion: true,
|
||||
|
||||
@ -12,12 +12,15 @@ function defineOverridesPreferences(preferences: DeepPartial<Preferences>) {
|
||||
preferences = {
|
||||
app: {
|
||||
name: '喵喵喵之家',
|
||||
defaultAvatar: '../public/favicon.ico', // Adjust the path as necessary
|
||||
defaultAvatar:
|
||||
'https://merge-pet-web.oss-cn-heyuan.aliyuncs.com/favicon.ico', // Adjust the path as necessary
|
||||
},
|
||||
logo: {
|
||||
source: import.meta.env.VITE_APP_LOGO || '../public/favicon.ico', // Adjust the path as necessary
|
||||
source:
|
||||
import.meta.env.VITE_APP_LOGO ||
|
||||
'https://merge-pet-web.oss-cn-heyuan.aliyuncs.com/favicon.ico', // Adjust the path as necessary
|
||||
},
|
||||
}
|
||||
};
|
||||
return preferences;
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user