版本更新
Some checks failed
CI / Test (ubuntu-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Lint (ubuntu-latest) (push) Has been cancelled
CI / Lint (windows-latest) (push) Has been cancelled
CI / Check (ubuntu-latest) (push) Has been cancelled
CI / Check (windows-latest) (push) Has been cancelled
CodeQL / Analyze (${{ matrix.language }}) (none, javascript-typescript) (push) Has been cancelled
Deploy Website on push / Deploy Push Playground Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Docs Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Antd Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Element Ftp (push) Has been cancelled
Deploy Website on push / Deploy Push Naive Ftp (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
CI / CI OK (push) Has been cancelled
@ -50,6 +50,7 @@
|
|||||||
"vue": "catalog:",
|
"vue": "catalog:",
|
||||||
"vue-router": "catalog:",
|
"vue-router": "catalog:",
|
||||||
"vue3-pixi": "1.0.0-beta.3",
|
"vue3-pixi": "1.0.0-beta.3",
|
||||||
"vxe-table": "^4.6.25"
|
"vxe-pc-ui": "4.10.18",
|
||||||
|
"vxe-table": "^4.17.11"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
apps/web-antd/public/cat_bg.png
Normal file
|
After Width: | Height: | Size: 280 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 41 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 37 KiB |
BIN
apps/web-antd/public/merge/Production_R2_lv1.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
apps/web-antd/public/merge/Production_R2_lv2.png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
apps/web-antd/public/merge/Production_R2_lv3.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
apps/web-antd/public/merge/Production_R2_lv4.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
apps/web-antd/public/merge/Production_R2_lv5.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
BIN
apps/web-antd/public/merge/Production_R2_lv6.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
apps/web-antd/public/merge/Production_S2_lv1.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
apps/web-antd/public/merge/Production_S2_lv2.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
apps/web-antd/public/merge/Production_S2_lv3.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
apps/web-antd/public/merge/Production_S2_lv4.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
apps/web-antd/public/merge/Production_S2_lv5.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
apps/web-antd/public/merge/Production_S2_lv6.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
BIN
apps/web-antd/public/merge/Production_S2_lv7.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
BIN
apps/web-antd/public/merge/Production_S2_lv8.png
Normal file
|
After Width: | Height: | Size: 38 KiB |
BIN
apps/web-antd/public/merge/Production_S2_lv9.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 31 KiB |
@ -4,7 +4,6 @@ import { registerAccessDirective } from '@vben/access';
|
|||||||
import { preferences } from '@vben/preferences';
|
import { preferences } from '@vben/preferences';
|
||||||
import { initStores } from '@vben/stores';
|
import { initStores } from '@vben/stores';
|
||||||
import '@vben/styles';
|
import '@vben/styles';
|
||||||
import '@vben/styles/antd';
|
|
||||||
|
|
||||||
import { useTitle } from '@vueuse/core';
|
import { useTitle } from '@vueuse/core';
|
||||||
import { $t, setupI18n } from '#/locales';
|
import { $t, setupI18n } from '#/locales';
|
||||||
|
|||||||
@ -6,8 +6,10 @@ import {
|
|||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
VbenIcon,
|
VbenIcon,
|
||||||
|
VbenPopover
|
||||||
} from '../../../../../packages/@core/ui-kit/shadcn-ui';
|
} from '../../../../../packages/@core/ui-kit/shadcn-ui';
|
||||||
import type { Order } from '#/model/type';
|
import type { Order } from '#/model/type';
|
||||||
|
import { computed, toRefs } from 'vue';
|
||||||
interface Props {
|
interface Props {
|
||||||
items: Order[];
|
items: Order[];
|
||||||
title: string;
|
title: string;
|
||||||
@ -17,9 +19,10 @@ defineOptions({
|
|||||||
name: 'WorkbenchProject',
|
name: 'WorkbenchProject',
|
||||||
});
|
});
|
||||||
|
|
||||||
withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
items: () => [],
|
items: () => [],
|
||||||
});
|
});
|
||||||
|
const { items, title } = toRefs(props);
|
||||||
function getTagColor(diff: number): string {
|
function getTagColor(diff: number): string {
|
||||||
if (diff === 1) {
|
if (diff === 1) {
|
||||||
return 'green';
|
return 'green';
|
||||||
@ -32,13 +35,69 @@ function getTagColor(diff: number): string {
|
|||||||
}
|
}
|
||||||
return 'red';
|
return 'red';
|
||||||
}
|
}
|
||||||
|
const orderTypeMeta: Record<number, { name: string; desc: string }> = {
|
||||||
|
1: { name: '普通订单', desc: '自动生成的基础订单。' },
|
||||||
|
2: { name: '额外订单(弃用)', desc: '历史类型,当前已弃用。' },
|
||||||
|
3: { name: '超级订单', desc: '奖励更高,难度更大的订单类型。' },
|
||||||
|
4: { name: '预热订单', desc: '用于活动或阶段开始前的预热内容。' },
|
||||||
|
5: { name: '触发订单', desc: '由特定事件或条件触发生成。' },
|
||||||
|
6: { name: '退役发射器清理订单', desc: '用于清理退役发射器相关棋子。' },
|
||||||
|
7: { name: '清理无法生成订单的棋子', desc: '处理异常或失效的棋子。' },
|
||||||
|
8: { name: '棋盘空格不足清理订单', desc: '当空间不足时清理低优先级棋子。' },
|
||||||
|
9: { name: '安慰订单', desc: '与安慰或情绪相关的特殊订单。' },
|
||||||
|
10: { name: '引导订单', desc: '用于新手或阶段引导流程。' },
|
||||||
|
11: { name: '消耗品订单', desc: '与宠物系统相关的订单。' },
|
||||||
|
12: { name: '预览订单', desc: '提前展示后续内容的预览类订单。' },
|
||||||
|
13: { name: '预设订单', desc: '新手过程从配置中生成的订单!' },
|
||||||
|
14: { name: 'Playroom装饰物订单', desc: '生成与Playroom装饰物相关的订单。' },
|
||||||
|
15: { name: '零件订单', desc: '用于收集或合成零件的订单。' },
|
||||||
|
};
|
||||||
|
const popoverTypes = computed(() => {
|
||||||
|
const types = new Set<number>();
|
||||||
|
(items.value || []).forEach(it => {
|
||||||
|
const t = Number((it as any).group);
|
||||||
|
if (!isNaN(t)) types.add(t);
|
||||||
|
});
|
||||||
|
return Array.from(types.values()).sort((a, b) => a - b).map(id => ({
|
||||||
|
id,
|
||||||
|
...orderTypeMeta[id],
|
||||||
|
}));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
defineEmits(['click']);
|
defineEmits(['click']);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader class="py-4">
|
<CardHeader class="py-4">
|
||||||
<CardTitle class="text-lg">{{ title }}</CardTitle>
|
<CardTitle class="text-lg">
|
||||||
|
<div class="flex">
|
||||||
|
<span class="text-center">{{ title }}</span>
|
||||||
|
|
||||||
|
<VbenPopover class="ml-2" :content-props="{ side: 'left' }">
|
||||||
|
|
||||||
|
<template #trigger>
|
||||||
|
<VbenIcon icon="solar:question-circle-bold" class="ml-2" />
|
||||||
|
</template>
|
||||||
|
<div class="max-w-xs text-sm">
|
||||||
|
<h3 class="font-semibold mb-2">订单类型说明</h3>
|
||||||
|
<ul v-if="popoverTypes.length" class="list-disc pl-5 space-y-1">
|
||||||
|
<li v-for="t in popoverTypes" :key="t.id">
|
||||||
|
<b>{{ t.name }}</b>:{{ t.desc }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<div v-else class="text-xs text-gray-500">暂无订单类型数据</div>
|
||||||
|
<h3 class="font-semibold mt-4 mb-2">订单难度说明</h3>
|
||||||
|
<ul>
|
||||||
|
<li><b>简单:</b>订单总消耗体力在15-150之间</li>
|
||||||
|
<li><b>中等:</b>订单总消耗体力在100-600之间</li>
|
||||||
|
<li><b>困难:</b>订单总消耗体力在500-1200之间</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</VbenPopover>
|
||||||
|
</div>
|
||||||
|
</CardTitle>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
<CardContent class="flex flex-wrap p-0">
|
<CardContent class="flex flex-wrap p-0">
|
||||||
<template v-for="(item, index) in items" :key="item.title">
|
<template v-for="(item, index) in items" :key="item.title">
|
||||||
@ -50,8 +109,7 @@ defineEmits(['click']);
|
|||||||
class="border-border group w-full cursor-pointer border-b border-r border-t p-4 transition-all hover:shadow-xl md:w-1/2 lg:w-1/3">
|
class="border-border group w-full cursor-pointer border-b border-r border-t p-4 transition-all hover:shadow-xl md:w-1/2 lg:w-1/3">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<VbenIcon :color="item.color" :icon="item.icon"
|
<VbenIcon :color="item.color" :icon="item.icon"
|
||||||
class="size-8 transition-all duration-300 group-hover:scale-110"
|
class="size-8 transition-all duration-300 group-hover:scale-110" />
|
||||||
@click="$emit('click', item)" />
|
|
||||||
<span class="ml-2 text-lg font-medium">{{ item.id }}</span>
|
<span class="ml-2 text-lg font-medium">{{ item.id }}</span>
|
||||||
<tag class="ml-2 text-sm" :color="getTagColor(item.diff)">{{ item.diffName }}</tag>
|
<tag class="ml-2 text-sm" :color="getTagColor(item.diff)">{{ item.diffName }}</tag>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,14 +1,94 @@
|
|||||||
{
|
{
|
||||||
|
"common":{
|
||||||
|
"save": "Save",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"edit": "Edit",
|
||||||
|
"delete": "Delete",
|
||||||
|
"search": "Search",
|
||||||
|
"gitCommit":"GitCommit",
|
||||||
|
"addLine": "AddLine",
|
||||||
|
"searchField": "Search Field",
|
||||||
|
"value": "Value",
|
||||||
|
"startTime": "Start Time",
|
||||||
|
"endTime": "End Time"
|
||||||
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"login": "Login",
|
"login": "Login",
|
||||||
"register": "Register",
|
"register": "Register",
|
||||||
"codeLogin": "Code Login",
|
"codeLogin": "Code Login",
|
||||||
"qrcodeLogin": "Qr Code Login",
|
"qrcodeLogin": "QR Code Login",
|
||||||
"forgetPassword": "Forget Password"
|
"forgetPassword": "Forget Password"
|
||||||
},
|
},
|
||||||
|
"admin": {
|
||||||
|
"title": "Admin",
|
||||||
|
"user": "User",
|
||||||
|
"setting": "Setting",
|
||||||
|
"log": "Log"
|
||||||
|
},
|
||||||
"dashboard": {
|
"dashboard": {
|
||||||
"title": "Dashboard",
|
"title": "Dashboard",
|
||||||
"analytics": "Analytics",
|
"analytics": "Analytics",
|
||||||
"workspace": "Workspace"
|
"server-list": "Server List",
|
||||||
|
"node-list": "Node List",
|
||||||
|
"mysql-list": "MySQL List",
|
||||||
|
"app-list": "App List"
|
||||||
|
},
|
||||||
|
"userlog": {
|
||||||
|
"title": "User Log",
|
||||||
|
"userlist": "User List",
|
||||||
|
"assetlog": "Asset Log",
|
||||||
|
"eventlog": "Event Log",
|
||||||
|
"orderlog": "Order Log"
|
||||||
|
},
|
||||||
|
"language": {
|
||||||
|
"title": "Language",
|
||||||
|
"languageList": "Language List",
|
||||||
|
"translationList": "Translation List",
|
||||||
|
"lastUpdate": "Last update",
|
||||||
|
"newLineContent": "New Translation"
|
||||||
|
},
|
||||||
|
"operation": {
|
||||||
|
"title": "Operation",
|
||||||
|
"level": "Level",
|
||||||
|
"mail": "Mail",
|
||||||
|
"order": "Order",
|
||||||
|
"language": "Language"
|
||||||
|
},
|
||||||
|
"log": {
|
||||||
|
"event": {
|
||||||
|
"order_finish": "Finish Order",
|
||||||
|
"time_limited_event_enable": "Open Time-limited Event",
|
||||||
|
"collection_add": "Add Collection",
|
||||||
|
"mutil_merge_change": "Change Merge Multiplier",
|
||||||
|
"sell_item": "Sell Item",
|
||||||
|
"buy_product_diamond": "Purchase Item",
|
||||||
|
"store_buy": "Purchase in Store",
|
||||||
|
"refresh_store_diamond": "Refresh Store",
|
||||||
|
"one_click_decoration": "Build All",
|
||||||
|
"championship_reward": "Tournament Reward",
|
||||||
|
"piggy_bank_open": "Open Piggy Bank",
|
||||||
|
"get_chest": "Collect Chest",
|
||||||
|
"weekly_gift": "Weekly Gift",
|
||||||
|
"finish_deco": "Build",
|
||||||
|
"plot_unlock": "Unlock Scene",
|
||||||
|
"scene_reward": "Scene Reward",
|
||||||
|
"piggy_bank_income": "Gain from Piggy Bank",
|
||||||
|
"card_pack_open": "Open Card Pack",
|
||||||
|
"get_new_card": "Collect New Card",
|
||||||
|
"gift_free": "Free Gift from Store",
|
||||||
|
"item_change": "Item Change",
|
||||||
|
"daily_task": "Daily Task",
|
||||||
|
"weekly_task": "Weekly Task",
|
||||||
|
"level_up": "Level Up",
|
||||||
|
"property_level_up": "Property Level Up",
|
||||||
|
"time_limited_slot": "Time Limited Event",
|
||||||
|
"buy_energy_diamond": "Buy Energy",
|
||||||
|
"time_limited_event_action": "Choose Time-limited Event",
|
||||||
|
"petname_set": "Set Pet Name",
|
||||||
|
"emoji_income": "Collect Emote",
|
||||||
|
"avatarIcon_income": "Collect Avatar",
|
||||||
|
"gm": "Use GM Tool",
|
||||||
|
"nickname_set": "Set Nickname"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,17 @@
|
|||||||
{
|
{
|
||||||
|
"common":{
|
||||||
|
"save": "保存",
|
||||||
|
"cancel": "取消",
|
||||||
|
"edit": "编辑",
|
||||||
|
"delete": "删除",
|
||||||
|
"search": "搜索",
|
||||||
|
"gitCommit":"git提交",
|
||||||
|
"addLine": "新增行",
|
||||||
|
"searchField": "搜索列",
|
||||||
|
"value": "值",
|
||||||
|
"startTime": "开始时间",
|
||||||
|
"endTime": "结束时间"
|
||||||
|
},
|
||||||
"auth": {
|
"auth": {
|
||||||
"login": "登录",
|
"login": "登录",
|
||||||
"register": "注册",
|
"register": "注册",
|
||||||
@ -30,7 +43,9 @@
|
|||||||
"language": {
|
"language": {
|
||||||
"title": "翻译管理",
|
"title": "翻译管理",
|
||||||
"languageList": "语言列表",
|
"languageList": "语言列表",
|
||||||
"translationList": "翻译列表"
|
"translationList": "翻译列表",
|
||||||
|
"lastUpdate": "最后修改日期",
|
||||||
|
"newLineContent": "新增翻译"
|
||||||
},
|
},
|
||||||
"operation": {
|
"operation": {
|
||||||
"title": "运营管理",
|
"title": "运营管理",
|
||||||
|
|||||||
@ -51,6 +51,7 @@ export interface languageType {
|
|||||||
key: string;
|
key: string;
|
||||||
English: string;
|
English: string;
|
||||||
ChineseSimplified: string;
|
ChineseSimplified: string;
|
||||||
|
Portuguese: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import type { languageType } from '#/model/type';
|
|||||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { addLanguageList } from '#/api/core/statistics';
|
import { addLanguageList } from '#/api/core/statistics';
|
||||||
|
import { $t } from '#/locales'
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'AddLanguageModal',
|
name: 'AddLanguageModal',
|
||||||
});
|
});
|
||||||
@ -11,15 +12,15 @@ let ld = [] as languageType[];
|
|||||||
const gridOptions: VxeGridProps<languageType> = {
|
const gridOptions: VxeGridProps<languageType> = {
|
||||||
border: true,
|
border: true,
|
||||||
columns: [
|
columns: [
|
||||||
{ title: '序号', field: 'Id', width: 50 },
|
{ title: 'Id', field: 'Id', width: 50 },
|
||||||
{ editRender: { name: 'input' }, field: 'key', title: '键值' },
|
{ editRender: { name: 'input' }, field: 'key', title: 'key' },
|
||||||
{ editRender: { name: 'input' }, field: 'English', title: '英文' },
|
{ editRender: { name: 'input' }, field: 'English', title: 'English' },
|
||||||
{
|
{
|
||||||
editRender: { name: 'input' },
|
editRender: { name: 'input' },
|
||||||
field: 'ChineseSimplified',
|
field: 'ChineseSimplified',
|
||||||
title: '简体中文',
|
title: 'ChineseSimplified',
|
||||||
},
|
},
|
||||||
{ editRender: { name: 'input' }, field: 'Portuguese', title: '葡萄牙语' },
|
{ editRender: { name: 'input' }, field: 'Portuguese', title: 'Portuguese' },
|
||||||
],
|
],
|
||||||
data: ld,
|
data: ld,
|
||||||
pagerConfig: {
|
pagerConfig: {
|
||||||
@ -56,10 +57,10 @@ const [Form] = useVbenForm({
|
|||||||
{
|
{
|
||||||
component: 'Textarea',
|
component: 'Textarea',
|
||||||
fieldName: 'ToUids',
|
fieldName: 'ToUids',
|
||||||
label: '新增翻译',
|
label: $t('page.language.newLineContent'),
|
||||||
componentProps: {
|
componentProps: {
|
||||||
disabled: false,
|
disabled: false,
|
||||||
placeholder: 'key | English | 简体中文| 葡萄牙语,一行一条记录',
|
placeholder: 'key | English | ChineseSimplified| Portuguese,One record per line',
|
||||||
type: 'textarea',
|
type: 'textarea',
|
||||||
rows: 8,
|
rows: 8,
|
||||||
onChange: (e: Event) => {
|
onChange: (e: Event) => {
|
||||||
@ -94,7 +95,7 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<Modal width="100%" title="添加翻译">
|
<Modal width="100%">
|
||||||
<Form />
|
<Form />
|
||||||
<Grid />
|
<Grid />
|
||||||
</Modal>
|
</Modal>
|
||||||
|
|||||||
@ -9,6 +9,7 @@ import type { VbenFormProps } from '#/adapter/form';
|
|||||||
import type { languageType, languageRecord } from '#/model/type';
|
import type { languageType, languageRecord } from '#/model/type';
|
||||||
import type { languageParam } from '#/api/core/statistics';
|
import type { languageParam } from '#/api/core/statistics';
|
||||||
import { useVbenModal } from '@vben/common-ui';
|
import { useVbenModal } from '@vben/common-ui';
|
||||||
|
import { $t } from '#/locales'
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
const [AddLanguageModal, AddLanguageModalApi] = useVbenModal({
|
const [AddLanguageModal, AddLanguageModalApi] = useVbenModal({
|
||||||
connectedComponent: addLanguage,
|
connectedComponent: addLanguage,
|
||||||
@ -18,6 +19,13 @@ let newData: languageType[] = [];
|
|||||||
let op: languageRecord[] = [];
|
let op: languageRecord[] = [];
|
||||||
let lastOp: languageRecord[] = [];
|
let lastOp: languageRecord[] = [];
|
||||||
let lastUpdate: string = '';
|
let lastUpdate: string = '';
|
||||||
|
let total: languageType = {
|
||||||
|
Id: 1,
|
||||||
|
key: '',
|
||||||
|
English: '',
|
||||||
|
ChineseSimplified: '',
|
||||||
|
Portuguese: '',
|
||||||
|
};
|
||||||
const startDate = dayjs().subtract(7, 'day').startOf('day');
|
const startDate = dayjs().subtract(7, 'day').startOf('day');
|
||||||
const endDate = dayjs().endOf('day');
|
const endDate = dayjs().endOf('day');
|
||||||
const formOptions: VbenFormProps = {
|
const formOptions: VbenFormProps = {
|
||||||
@ -29,16 +37,16 @@ const formOptions: VbenFormProps = {
|
|||||||
componentProps: {
|
componentProps: {
|
||||||
filterOption: true,
|
filterOption: true,
|
||||||
options: [
|
options: [
|
||||||
{ label: '键值', value: 'key' },
|
{ label: 'key', value: 'key' },
|
||||||
{ label: '英文', value: 'English' },
|
{ label: 'English', value: 'English' },
|
||||||
{ label: '简体中文', value: 'ChineseSimplified' },
|
{ label: 'ChineseSimplified', value: 'ChineseSimplified' },
|
||||||
{ label: '葡萄牙语', value: 'Portuguese' },
|
{ label: 'Portuguese', value: 'Portuguese' },
|
||||||
],
|
],
|
||||||
placeholder: 'key',
|
placeholder: 'key',
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
},
|
},
|
||||||
fieldName: 'SearchField',
|
fieldName: 'SearchField',
|
||||||
label: '搜索列:',
|
label: $t('page.common.searchField') + ':',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'Input',
|
component: 'Input',
|
||||||
@ -48,50 +56,35 @@ const formOptions: VbenFormProps = {
|
|||||||
showSearch: true,
|
showSearch: true,
|
||||||
},
|
},
|
||||||
fieldName: 'SearchValue',
|
fieldName: 'SearchValue',
|
||||||
label: '值:',
|
label: $t('page.common.value') + ':',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
defaultValue: startDate,
|
defaultValue: startDate,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
format: 'YYYY-MM-DD',
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
},
|
},
|
||||||
fieldName: 'StartTime',
|
fieldName: 'StartTime',
|
||||||
label: '开始时间',
|
label: $t('page.common.startTime'),
|
||||||
formItemClass: 'col-start-1',
|
formItemClass: 'col-start-1',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
component: 'TimePicker',
|
|
||||||
componentProps: {
|
|
||||||
placeholder: '时间',
|
|
||||||
},
|
|
||||||
fieldName: 'StartTime',
|
|
||||||
label: '--',
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
defaultValue: endDate,
|
defaultValue: endDate,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
format: 'YYYY-MM-DD',
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
},
|
},
|
||||||
fieldName: 'EndTime',
|
fieldName: 'EndTime',
|
||||||
label: '结束时间',
|
label: $t('page.common.endTime'),
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
|
||||||
component: 'TimePicker',
|
|
||||||
componentProps: {
|
|
||||||
placeholder: '时间',
|
|
||||||
},
|
|
||||||
fieldName: 'EndTime',
|
|
||||||
label: '--',
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
// 控制表单是否显示折叠按钮
|
// 控制表单是否显示折叠按钮
|
||||||
showCollapseButton: true,
|
showCollapseButton: true,
|
||||||
submitButtonOptions: {
|
submitButtonOptions: {
|
||||||
content: '查询',
|
content: $t('page.common.search'),
|
||||||
},
|
},
|
||||||
wrapperClass: 'grid-cols-1 md:grid-cols-5',
|
wrapperClass: 'grid-cols-1 md:grid-cols-5',
|
||||||
// 是否在字段值改变时提交表单
|
// 是否在字段值改变时提交表单
|
||||||
@ -102,16 +95,20 @@ const formOptions: VbenFormProps = {
|
|||||||
const gridOptions: VxeGridProps<languageType> = {
|
const gridOptions: VxeGridProps<languageType> = {
|
||||||
border: true,
|
border: true,
|
||||||
columns: [
|
columns: [
|
||||||
{ title: '序号', field: 'Id', width: 50 },
|
{ title: 'Id', field: 'Id', width: 100 },
|
||||||
{ editRender: { name: 'input' }, field: 'key', title: '键值' },
|
{ editRender: { name: 'input' }, field: 'key', title: 'key', filters: [{ data: "" }], filterRender: { name: "input" } },
|
||||||
{ editRender: { name: 'input' }, field: 'English', title: '英文' },
|
{ editRender: { name: 'input' }, field: 'English', title: 'English', filters: [{ data: "" }], filterRender: { name: "input" } },
|
||||||
{
|
{
|
||||||
editRender: { name: 'input' },
|
editRender: { name: 'input' },
|
||||||
field: 'ChineseSimplified',
|
field: 'ChineseSimplified',
|
||||||
title: '简体中文',
|
title: 'ChineseSimplified', filters: [{ data: "" }], filterRender: { name: "input" }
|
||||||
},
|
},
|
||||||
{ editRender: { name: 'input' }, field: 'Portuguese', title: '葡萄牙语' },
|
{ editRender: { name: 'input' }, field: 'Portuguese', title: 'Portuguese', filters: [{ data: "" }], filterRender: { name: "input" } }
|
||||||
],
|
],
|
||||||
|
scrollY: {
|
||||||
|
enabled: true,
|
||||||
|
gt: 0
|
||||||
|
},
|
||||||
toolbarConfig: {
|
toolbarConfig: {
|
||||||
custom: true,
|
custom: true,
|
||||||
refresh: true,
|
refresh: true,
|
||||||
@ -178,6 +175,50 @@ const gridOptions: VxeGridProps<languageType> = {
|
|||||||
} else {
|
} else {
|
||||||
lastUpdate = '';
|
lastUpdate = '';
|
||||||
}
|
}
|
||||||
|
// 统计 response.data 中 English 字段包含的单词数量(单词由字母、连字符或撇号组成,如 don't、mother-in-law)
|
||||||
|
const englishCount = (response.data || []).reduce((sum: number, item: languageType) => {
|
||||||
|
const s = item?.English || '';
|
||||||
|
const matches = s.match(/[A-Za-z]+(?:['-][A-Za-z]+)*/g);
|
||||||
|
return sum + (matches ? matches.length : 0);
|
||||||
|
}, 0);
|
||||||
|
// 更新 total 变量和 footerData 显示
|
||||||
|
total.English = String(englishCount);
|
||||||
|
if (gridOptions && Array.isArray(gridOptions.footerData) && gridOptions.footerData.length > 0) {
|
||||||
|
(gridOptions.footerData[0] as any).English = String(englishCount);
|
||||||
|
}
|
||||||
|
// 统计 ChineseSimplified 中中文字符总数(只统计汉字)
|
||||||
|
const countHan = (str: string) => {
|
||||||
|
try {
|
||||||
|
const m = str.match(/\p{Script=Han}/gu);
|
||||||
|
return m ? m.length : 0;
|
||||||
|
} catch (e) {
|
||||||
|
const m = str.match(/[\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFAFF]/g);
|
||||||
|
return m ? m.length : 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const chineseCount = (response.data || []).reduce((sum: number, item: languageType) => {
|
||||||
|
return sum + countHan(item?.ChineseSimplified || '');
|
||||||
|
}, 0);
|
||||||
|
|
||||||
|
total.ChineseSimplified = String(chineseCount);
|
||||||
|
if (gridOptions && Array.isArray(gridOptions.footerData) && gridOptions.footerData.length > 0) {
|
||||||
|
(gridOptions.footerData[0] as any).ChineseSimplified = String(chineseCount);
|
||||||
|
}
|
||||||
|
GridApi.setGridOptions({
|
||||||
|
pagerConfig: {
|
||||||
|
enabled: true,
|
||||||
|
pageSize: page.pageSize,
|
||||||
|
pageSizes: [40, 80, 100, 200, 500, 1000, 3000, 10000],
|
||||||
|
},
|
||||||
|
footerData: [{
|
||||||
|
Id: 'Word',
|
||||||
|
key: '-',
|
||||||
|
English: total.English,
|
||||||
|
ChineseSimplified: total.ChineseSimplified,
|
||||||
|
Portuguese: '',
|
||||||
|
}],
|
||||||
|
});
|
||||||
return {
|
return {
|
||||||
data: response.data || [],
|
data: response.data || [],
|
||||||
total: response.total || 0,
|
total: response.total || 0,
|
||||||
@ -185,13 +226,28 @@ const gridOptions: VxeGridProps<languageType> = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
keepSource: true,
|
||||||
|
keyboardConfig: {
|
||||||
|
isArrow: true,
|
||||||
|
isTab: true,
|
||||||
|
isEnter: true,
|
||||||
|
},
|
||||||
|
footerData: [{
|
||||||
|
Id: '字符数统计',
|
||||||
|
key: '-',
|
||||||
|
English: total.English,
|
||||||
|
ChineseSimplified: '',
|
||||||
|
Portuguese: '',
|
||||||
|
}],
|
||||||
|
showFooter: true,
|
||||||
editConfig: {
|
editConfig: {
|
||||||
mode: 'cell',
|
mode: 'cell',
|
||||||
trigger: 'dblclick',
|
trigger: 'dblclick',
|
||||||
|
showStatus: true,
|
||||||
},
|
},
|
||||||
pagerConfig: {
|
pagerConfig: {
|
||||||
enabled: true,
|
enabled: true,
|
||||||
pageSize: 80,
|
pageSizes: [40, 80, 100, 200, 500, 1000],
|
||||||
},
|
},
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
showOverflow: true,
|
showOverflow: true,
|
||||||
@ -231,6 +287,9 @@ const [Grid, GridApi] = useVbenVxeGrid({ formOptions, gridOptions, gridEvents })
|
|||||||
|
|
||||||
function addRow() {
|
function addRow() {
|
||||||
AddLanguageModalApi.open();
|
AddLanguageModalApi.open();
|
||||||
|
AddLanguageModalApi.setState({
|
||||||
|
title: $t('page.language.newLineContent'),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
function saveAll() {
|
function saveAll() {
|
||||||
saveLanguageList(op).then((response) => {
|
saveLanguageList(op).then((response) => {
|
||||||
@ -273,27 +332,28 @@ function exportLang() {
|
|||||||
|
|
||||||
<style lang="css">
|
<style lang="css">
|
||||||
.row-green {
|
.row-green {
|
||||||
background-color: #1ecf0d;
|
background-color: #0ea800;
|
||||||
}
|
}
|
||||||
|
|
||||||
.row-yellow {
|
.row-yellow {
|
||||||
background-color: #f2ff00;
|
background-color: #c9bc04;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<template>
|
<template>
|
||||||
|
<div class="h-full flex flex-col">
|
||||||
|
<Page auto-content-height class="h-[800px]">
|
||||||
<Page auto-content-height>
|
<AddLanguageModal width="1200px" height="1200px"></AddLanguageModal />
|
||||||
<AddLanguageModal width="1200px" title="添加翻译"></AddLanguageModal />
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
<span class="mr-4 font-bold">最后修改日期:{{ lastUpdate }}</span>
|
<span class="mr-4 font-bold">{{ $t('page.language.lastUpdate') }}:{{ lastUpdate }}</span>
|
||||||
<Button class="mr-2" type="primary" @click="addRow">
|
<Button class="mr-2" type="primary" @click="addRow">
|
||||||
新增行
|
{{ $t('page.common.addLine') }}
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="primary" @click="saveAll" class="mr-2"> 保存 </Button>
|
<Button type="primary" @click="saveAll" class="mr-2"> {{ $t('page.common.save') }} </Button>
|
||||||
<Button type="primary" @click="exportLang"> git提交 </Button>
|
<Button type="primary" @click="exportLang"> {{ $t('page.common.gitCommit') }} </Button>
|
||||||
</template>
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -93,8 +93,8 @@ const gridOptions: VxeGridProps<RowType> = {
|
|||||||
}
|
}
|
||||||
let AppId = parseInt(formValues.AppId, 10);
|
let AppId = parseInt(formValues.AppId, 10);
|
||||||
return await getStatisticsLevel({
|
return await getStatisticsLevel({
|
||||||
AppId :AppId,
|
AppId: AppId,
|
||||||
ServerList:formValues.ServerList
|
ServerList: formValues.ServerList
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -146,7 +146,7 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height class="h-[800px]">
|
||||||
<Grid />
|
<Grid />
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
@ -206,7 +206,7 @@ async function deleteRow(row: MailData) {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height class="h-[800px]">
|
||||||
<AddMailM class="w-[50%]" />
|
<AddMailM class="w-[50%]" />
|
||||||
<AddMailM2 class="w-[50%]" />
|
<AddMailM2 class="w-[50%]" />
|
||||||
<Card class="mb-5" title="邮件操作">
|
<Card class="mb-5" title="邮件操作">
|
||||||
|
|||||||
@ -88,9 +88,14 @@ const formOptions: VbenFormProps = {
|
|||||||
const gridOptions: VxeGridProps<RowType> = {
|
const gridOptions: VxeGridProps<RowType> = {
|
||||||
columns: [
|
columns: [
|
||||||
{ field: 'Type', title: '订单类型' },
|
{ field: 'Type', title: '订单类型' },
|
||||||
{ field: 'Num', title: '该类订单持有数量' },
|
{ field: 'Num', title: '该类订单持有数量', formatter: ({ cellValue }) => cellValue === 0 ? '总数' : cellValue },
|
||||||
{ field: 'Sum', title: '流失玩家数' },
|
{ field: 'Sum', title: '流失玩家数' },
|
||||||
{ field: 'Prop', title: '占比', formatter: ({ cellValue }) => `${cellValue}%` },
|
{ field: 'Prop', title: '占比', formatter: ({ cellValue }) => `${cellValue}%`, cellRender: { name: 'pie' } },
|
||||||
|
],
|
||||||
|
border: true,
|
||||||
|
mergeCells: [
|
||||||
|
{ row: 0, col: 0, rowspan: 5, colspan: 1 },
|
||||||
|
{ row: 5, col: 0, rowspan: 5, colspan: 1 },
|
||||||
],
|
],
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
pagerConfig: {},
|
pagerConfig: {},
|
||||||
@ -110,10 +115,6 @@ const gridOptions: VxeGridProps<RowType> = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
rowConfig: {
|
|
||||||
isHover: true,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const [Grid, GridApi] = useVbenVxeGrid({ formOptions, gridOptions });
|
const [Grid, GridApi] = useVbenVxeGrid({ formOptions, gridOptions });
|
||||||
@ -146,7 +147,7 @@ onMounted(async () => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height class="h-[800px]">
|
||||||
<Grid>
|
<Grid>
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
<span class="mr-5 font-semibold" style="color: red;">该类订单持有数量为0的流失玩家数为该订单难度的总流失玩家数</span>
|
<span class="mr-5 font-semibold" style="color: red;">该类订单持有数量为0的流失玩家数为该订单难度的总流失玩家数</span>
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Page, useVbenModal } from '@vben/common-ui';
|
import { Page, useVbenModal } from '@vben/common-ui';
|
||||||
import type { VxeGridListeners } from 'vxe-table';
|
import type { VxeGridListeners } from '#/adapter/vxe-table';
|
||||||
import { getUserLogAssetApi } from '#/api/core/log';
|
import { getUserLogAssetApi } from '#/api/core/log';
|
||||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||||
import { inject, ref } from 'vue';
|
import { inject, ref } from 'vue';
|
||||||
@ -24,6 +24,7 @@ interface RowType {
|
|||||||
item_id: string;
|
item_id: string;
|
||||||
timestamp: string;
|
timestamp: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const formatType = (cellValue: string) => {
|
const formatType = (cellValue: string) => {
|
||||||
switch (cellValue) {
|
switch (cellValue) {
|
||||||
case "gain":
|
case "gain":
|
||||||
@ -45,6 +46,11 @@ const d = ref({
|
|||||||
});
|
});
|
||||||
const startDate = dayjs().startOf('day');
|
const startDate = dayjs().startOf('day');
|
||||||
const endDate = dayjs().endOf('day');
|
const endDate = dayjs().endOf('day');
|
||||||
|
const itemIdOptions = ref([
|
||||||
|
{ label: '能量', value: 100001 },
|
||||||
|
{ label: '宠物币', value: 100002 },
|
||||||
|
{ label: '钻石', value: 100003 },
|
||||||
|
]);
|
||||||
const formOptions: VbenFormProps = {
|
const formOptions: VbenFormProps = {
|
||||||
// 所有表单项共用,可单独在表单内覆盖
|
// 所有表单项共用,可单独在表单内覆盖
|
||||||
commonConfig: {
|
commonConfig: {
|
||||||
@ -70,19 +76,31 @@ const formOptions: VbenFormProps = {
|
|||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
defaultValue: startDate,
|
defaultValue: startDate,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
format: 'YYYY-MM-DD',
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
},
|
},
|
||||||
fieldName: 'StartTime',
|
fieldName: 'StartTime',
|
||||||
label: '开始时间',
|
label: '开始时间',
|
||||||
},
|
},
|
||||||
|
|
||||||
{
|
{
|
||||||
component: 'TimePicker',
|
component: 'DatePicker',
|
||||||
|
defaultValue: endDate,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: '时间',
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
},
|
},
|
||||||
fieldName: 'StartTime',
|
fieldName: 'EndTime',
|
||||||
label: '--',
|
label: '结束时间',
|
||||||
wrapperClass: 'col-span-3 col-start-2',
|
},
|
||||||
|
{
|
||||||
|
component: 'Select',
|
||||||
|
componentProps: {
|
||||||
|
options: itemIdOptions,
|
||||||
|
allowClear: true,
|
||||||
|
},
|
||||||
|
fieldName: 'ItemId',
|
||||||
|
label: '道具id',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'Select',
|
component: 'Select',
|
||||||
@ -96,37 +114,6 @@ const formOptions: VbenFormProps = {
|
|||||||
fieldName: 'Event',
|
fieldName: 'Event',
|
||||||
label: '变化类型',
|
label: '变化类型',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
component: 'DatePicker',
|
|
||||||
defaultValue: endDate,
|
|
||||||
componentProps: {
|
|
||||||
format: 'YYYY-MM-DD',
|
|
||||||
},
|
|
||||||
fieldName: 'EndTime',
|
|
||||||
label: '结束时间',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'TimePicker',
|
|
||||||
componentProps: {
|
|
||||||
placeholder: '时间',
|
|
||||||
},
|
|
||||||
fieldName: 'EndTime',
|
|
||||||
label: '--',
|
|
||||||
wrapperClass: 'col-span-3 col-start-2',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'Select',
|
|
||||||
componentProps: {
|
|
||||||
options: [
|
|
||||||
{ label: '能量', value: 100001 },
|
|
||||||
{ label: '宠物币', value: '100002' },
|
|
||||||
{ label: '钻石', value: '100003' },
|
|
||||||
],
|
|
||||||
allowClear: true,
|
|
||||||
},
|
|
||||||
fieldName: 'ItemId',
|
|
||||||
label: '道具id',
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
// 控制表单是否显示折叠按钮
|
// 控制表单是否显示折叠按钮
|
||||||
showCollapseButton: true,
|
showCollapseButton: true,
|
||||||
@ -150,16 +137,17 @@ const gridEvents: VxeGridListeners<RowType> = {
|
|||||||
};
|
};
|
||||||
const gridOptions: VxeGridProps<RowType> = {
|
const gridOptions: VxeGridProps<RowType> = {
|
||||||
columns: [
|
columns: [
|
||||||
{ field: 'Uid', title: 'Uid' },
|
{ field: 'Uid', title: 'Uid', align: 'center' },
|
||||||
{ field: 'change_type', title: '变化类型', formatter: ({ cellValue }) => formatType(cellValue) },
|
{ field: 'change_type', title: '变化类型', formatter: ({ cellValue }) => formatType(cellValue), align: 'center' },
|
||||||
{ field: 'change_num', title: '变化数值' },
|
{ field: 'change_num', title: '变化数值', align: 'center' },
|
||||||
{ field: 'change_after', title: '变化后数值' },
|
{ field: 'change_after', title: '变化后数值', align: 'center' },
|
||||||
{ field: 'item_id', title: '道具名称', formatter: ({ cellValue }) => formatItemName(cellValue) },
|
{ field: 'item_id', title: '道具名称', formatter: ({ cellValue }) => formatItemName(cellValue), align: 'center' },
|
||||||
{ field: 'item_id', title: '道具id' },
|
{ field: 'item_id', title: '道具id', align: 'center' },
|
||||||
{ field: 'timestamp', title: '时间', formatter: ({ cellValue }) => new Date(cellValue * 1000).toLocaleString() },
|
{ field: 'timestamp', title: '时间', formatter: ({ cellValue }) => new Date(cellValue * 1000).toLocaleString(), align: 'center' },
|
||||||
],
|
],
|
||||||
|
stripe: true,
|
||||||
|
round: true,
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
keepSource: true,
|
|
||||||
exportConfig: {
|
exportConfig: {
|
||||||
filename: '用户资产日志',
|
filename: '用户资产日志',
|
||||||
type: 'csv',
|
type: 'csv',
|
||||||
@ -198,6 +186,29 @@ const gridOptions: VxeGridProps<RowType> = {
|
|||||||
CurrentPage: page.currentPage,
|
CurrentPage: page.currentPage,
|
||||||
PageSize: page.pageSize,
|
PageSize: page.pageSize,
|
||||||
});
|
});
|
||||||
|
// 动态收集 item_id 与 item_name 生成下拉
|
||||||
|
if (Array.isArray(r.data)) {
|
||||||
|
itemIdOptions.value = [
|
||||||
|
{ label: '能量', value: 100001 },
|
||||||
|
{ label: '宠物币', value: 100002 },
|
||||||
|
{ label: '钻石', value: 100003 },
|
||||||
|
];
|
||||||
|
const exist = new Set(itemIdOptions.value.map(o => String(o.value)));
|
||||||
|
for (const row of r.data as any[]) {
|
||||||
|
const idRaw = (row as any).item_id;
|
||||||
|
const nameRaw = String(formatItemName(idRaw));
|
||||||
|
if (idRaw !== undefined && idRaw !== null) {
|
||||||
|
const idStr = String(idRaw);
|
||||||
|
if (!exist.has(idStr)) {
|
||||||
|
exist.add(idStr);
|
||||||
|
itemIdOptions.value.push({
|
||||||
|
label: nameRaw,
|
||||||
|
value: parseInt(idStr, 10) || idRaw,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
d.value.sum = r.sum;
|
d.value.sum = r.sum;
|
||||||
d.value.psum = r.psum;
|
d.value.psum = r.psum;
|
||||||
d.value.nsum = r.nsum;
|
d.value.nsum = r.nsum;
|
||||||
@ -217,8 +228,15 @@ const [Grid] = useVbenVxeGrid({ formOptions, gridOptions, gridEvents });
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height class="h-[800px]">
|
||||||
<Grid>
|
<Grid>
|
||||||
|
<template #empty>
|
||||||
|
<div style="display:flex;flex-direction:column;align-items:center;justify-content:center;">
|
||||||
|
<img src="https://n.sinaimg.cn/sinacn17/w120h120/20180314/89fc-fyscsmv5911424.gif" alt="no-data"
|
||||||
|
style="max-width:200px;display:block;">
|
||||||
|
<p style="margin:8px 0 0;">没有更多数据了!</p>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
<template #toolbar-tools>
|
<template #toolbar-tools>
|
||||||
总数:<span style="margin-right: 10px;margin-left: 5px;"> {{ d.sum }} </span>
|
总数:<span style="margin-right: 10px;margin-left: 5px;"> {{ d.sum }} </span>
|
||||||
正数和: <span style="margin-right: 10px;margin-left: 5px;color:green">{{ d.psum }} </span>
|
正数和: <span style="margin-right: 10px;margin-left: 5px;color:green">{{ d.psum }} </span>
|
||||||
@ -226,6 +244,6 @@ const [Grid] = useVbenVxeGrid({ formOptions, gridOptions, gridEvents });
|
|||||||
</template>
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
</Page>
|
</Page>
|
||||||
<Modal class="w-[1200px]" "> </Modal>
|
<Modal class="w-[1200px]"> </Modal>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -13,8 +13,8 @@ import { assetModal } from '#/component';
|
|||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
const state = inject('globalState', globalState);
|
const state = inject('globalState', globalState);
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
connectedComponent:assetModal,
|
connectedComponent: assetModal,
|
||||||
class:'width:1800px;',
|
class: 'width:1800px;',
|
||||||
|
|
||||||
});
|
});
|
||||||
const startDate = dayjs().startOf('day');
|
const startDate = dayjs().startOf('day');
|
||||||
@ -51,40 +51,23 @@ const formOptions: VbenFormProps = {
|
|||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
defaultValue: startDate,
|
defaultValue: startDate,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
format: 'YYYY-MM-DD',
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
},
|
},
|
||||||
fieldName: 'StartTime',
|
fieldName: 'StartTime',
|
||||||
label: '开始时间',
|
label: '开始时间',
|
||||||
formItemClass: 'col-start-1',
|
formItemClass: 'col-start-1',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
component: 'TimePicker',
|
|
||||||
componentProps: {
|
|
||||||
placeholder: '时间',
|
|
||||||
},
|
|
||||||
fieldName: 'StartTime',
|
|
||||||
label: '--',
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
defaultValue: endDate,
|
defaultValue: endDate,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
format: 'YYYY-MM-DD',
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
},
|
},
|
||||||
fieldName: 'EndTime',
|
fieldName: 'EndTime',
|
||||||
label: '结束时间',
|
label: '结束时间',
|
||||||
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
component: 'TimePicker',
|
|
||||||
componentProps: {
|
|
||||||
placeholder: '时间',
|
|
||||||
},
|
|
||||||
fieldName: 'EndTime',
|
|
||||||
label: '--',
|
|
||||||
|
|
||||||
},
|
|
||||||
],
|
],
|
||||||
// 控制表单是否显示折叠按钮
|
// 控制表单是否显示折叠按钮
|
||||||
showCollapseButton: true,
|
showCollapseButton: true,
|
||||||
@ -111,9 +94,9 @@ const gridOptions: VxeGridProps<RowType> = {
|
|||||||
columns: [
|
columns: [
|
||||||
{ field: 'Uid', title: 'Uid' },
|
{ field: 'Uid', title: 'Uid' },
|
||||||
{ field: 'Event', title: '事件类型', formatter: ({ cellValue }) => $t('page.log.event.' + `${cellValue}`) || cellValue },
|
{ field: 'Event', title: '事件类型', formatter: ({ cellValue }) => $t('page.log.event.' + `${cellValue}`) || cellValue },
|
||||||
{ field: 'Label', title: 'Label'},
|
{ field: 'Label', title: 'Label' },
|
||||||
{ field: 'Param', title: '参数' },
|
{ field: 'Param', title: '参数' },
|
||||||
{ field: 'Timestamp', title: '时间', formatter: ({ cellValue }) => new Date(cellValue*1000).toLocaleString()},
|
{ field: 'Timestamp', title: '时间', formatter: ({ cellValue }) => new Date(cellValue * 1000).toLocaleString() },
|
||||||
],
|
],
|
||||||
stripe: true,
|
stripe: true,
|
||||||
height: 'auto',
|
height: 'auto',
|
||||||
@ -154,7 +137,7 @@ const [Grid] = useVbenVxeGrid({ formOptions, gridOptions, gridEvents });
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height class="h-[800px]">
|
||||||
<Grid />
|
<Grid />
|
||||||
</Page>
|
</Page>
|
||||||
<Modal class="w-[1200px]"> </Modal>
|
<Modal class="w-[1200px]"> </Modal>
|
||||||
|
|||||||
@ -155,7 +155,7 @@ onMounted(async () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height class="h-[800px]">
|
||||||
<Grid />
|
<Grid />
|
||||||
</Page>
|
</Page>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, watch } from 'vue';
|
import { ref, watch, computed } from 'vue';
|
||||||
import MergeData from '#/store/MergeData.json';
|
import MergeData from '#/store/MergeData.json';
|
||||||
import { orderTypeData, orderDiffData } from '#/store/order';
|
import { orderTypeData, orderDiffData } from '#/store/order';
|
||||||
import { faceTypeData } from '#/store/face';
|
import { faceTypeData } from '#/store/face';
|
||||||
import { useVbenModal, useVbenForm, WorkbenchTrends } from '@vben/common-ui';
|
import { useVbenModal, useVbenForm, WorkbenchTrends } from '@vben/common-ui';
|
||||||
import { message } from 'ant-design-vue';
|
import { message, Card } from 'ant-design-vue';
|
||||||
import { getUserlogInfoApi } from '#/api/core/log';
|
import { getUserlogInfoApi } from '#/api/core/log';
|
||||||
import { userGmApi, userBanApi } from '#/api/core/user';
|
import { userGmApi, userBanApi } from '#/api/core/user';
|
||||||
import { calendar } from '#/component/index';
|
import { calendar } from '#/component/index';
|
||||||
@ -26,6 +26,8 @@ import { AccessControl } from '@vben/access';
|
|||||||
// 例如:url: /dashboard/workspace
|
// 例如:url: /dashboard/workspace
|
||||||
const projectItems: WorkbenchProjectItem[] = [];
|
const projectItems: WorkbenchProjectItem[] = [];
|
||||||
|
|
||||||
|
const chargeDisplay = computed(() => (Number(info.value?.Charge ?? 0)).toFixed(2));
|
||||||
|
|
||||||
const [BaseForm] = useVbenForm({
|
const [BaseForm] = useVbenForm({
|
||||||
// 所有表单项共用,可单独在表单内覆盖
|
// 所有表单项共用,可单独在表单内覆盖
|
||||||
commonConfig: {
|
commonConfig: {
|
||||||
@ -42,10 +44,64 @@ const [BaseForm] = useVbenForm({
|
|||||||
// 水平布局,label和input在同一行
|
// 水平布局,label和input在同一行
|
||||||
schema: [
|
schema: [
|
||||||
{
|
{
|
||||||
component: 'Input',
|
component: 'Mentions',
|
||||||
defaultValue: '',
|
defaultValue: '',
|
||||||
componentProps: {
|
componentProps: {
|
||||||
placeholder: '请输入gm命令',
|
placeholder: '请输入gm命令,输入@可查看命令列表',
|
||||||
|
options: [
|
||||||
|
// 基础
|
||||||
|
{ label: 'additem 100002 100 增加宠物币100', value: 'additem 100002 100' },
|
||||||
|
{ label: 'additem 100001 100 增加能量100', value: 'additem 100001 100' },
|
||||||
|
{ label: 'additem 100003 100 增加钻石100', value: 'additem 100003 100' },
|
||||||
|
{ label: 'subitem 100002 100 减少宠物币100', value: 'subitem 100002 100' },
|
||||||
|
{ label: 'addexp 100 增加100经验', value: 'addexp 100' },
|
||||||
|
{ label: 'setlv 1 设置为1级', value: 'setlv 1' },
|
||||||
|
{ label: 'AllFace 获取所有头像和头像框', value: 'AllFace' },
|
||||||
|
|
||||||
|
// 订单
|
||||||
|
{ label: 'reset_order 重置订单', value: 'reset_order' },
|
||||||
|
{ label: 'orderMerge 获取订单所需棋子', value: 'orderMerge' },
|
||||||
|
|
||||||
|
// 卡牌
|
||||||
|
{ label: 'add_card_star 5 增加5点卡包碎片', value: 'add_card_star 5' },
|
||||||
|
{ label: 'add_card 1 增加id为1的卡牌', value: 'add_card 1' },
|
||||||
|
{ label: 'addAddCard 获取所有卡牌', value: 'addAddCard' },
|
||||||
|
{ label: 'addAddCard 获取当前轮次全部卡牌', value: 'addAddCard' },
|
||||||
|
{ label: 'resetCardSeasonFirst 重置卡牌赛季初始奖励', value: 'resetCardSeasonFirst' },
|
||||||
|
|
||||||
|
// 每日任务
|
||||||
|
{ label: 'setSevenLoginActive 20 设置签到进度为20', value: 'setSevenLoginActive 20' },
|
||||||
|
|
||||||
|
// 限时事件
|
||||||
|
{ label: 'setProgress 4 设置转盘进度为4', value: 'setProgress 4' },
|
||||||
|
{ label: 'setProgressReward 完成限时事件转盘', value: 'setProgressReward' },
|
||||||
|
|
||||||
|
// 锦标赛
|
||||||
|
{ label: 'champshipGroup 锦标赛分组', value: 'champshipGroup' },
|
||||||
|
|
||||||
|
// 游戏模拟
|
||||||
|
{ label: 'zeroUpdate 模拟0点更新', value: 'zeroUpdate' },
|
||||||
|
|
||||||
|
// Playroom
|
||||||
|
{ label: 'playroomTrigger 生成playroom触发式订单', value: 'playroomTrigger' },
|
||||||
|
{ label: 'playroomCollect 获取playroom所有装饰', value: 'playroomCollect' },
|
||||||
|
{ label: 'addChip 增加playroom房间纸屑', value: 'addChip' },
|
||||||
|
{ label: 'addFriendStar 4 在宠物宝藏中增加4个宠物币', value: 'addFriendStar 4' },
|
||||||
|
{ label: 'addPhysiology type num 增加生理类型为type的数值num', value: 'addPhysiology type num' },
|
||||||
|
{ label: 'resetTriggerTime 重置playroom触发订单cd', value: 'resetTriggerTime' },
|
||||||
|
{ label: 'playroomDress 获取playroom所有服装', value: 'playroomDress' },
|
||||||
|
{ label: 'playroomAir 获取playroom所有飞行背包', value: 'playroomAir' },
|
||||||
|
|
||||||
|
// 好友
|
||||||
|
{ label: 'addFriend 对方uid 仅用于调试,对方好友列表不会增加', value: 'addFriend 对方uid' },
|
||||||
|
|
||||||
|
// 场景
|
||||||
|
{ label: 'setDecorateArea 1 设置装饰区域id', value: 'setDecorateArea 1' },
|
||||||
|
{ label: 'setDecorateProgresse 1 设置装饰进度', value: 'setDecorateProgresse 1' },
|
||||||
|
|
||||||
|
// 图鉴
|
||||||
|
{ label: 'handbook 解锁所有图鉴', value: 'handbook' },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
label: 'Gm:',
|
label: 'Gm:',
|
||||||
fieldName: 'gm',
|
fieldName: 'gm',
|
||||||
@ -53,11 +109,13 @@ const [BaseForm] = useVbenForm({
|
|||||||
],
|
],
|
||||||
handleSubmit: async (values) => {
|
handleSubmit: async (values) => {
|
||||||
const cv = modalApi.getData<Record<string, any>>();
|
const cv = modalApi.getData<Record<string, any>>();
|
||||||
|
let gm = values.gm;
|
||||||
|
gm = String(gm || '').replace(/@/g, '');
|
||||||
const r = await userGmApi({
|
const r = await userGmApi({
|
||||||
Uid: cv.uid,
|
Uid: cv.uid,
|
||||||
AppId: cv.AppId,
|
AppId: cv.AppId,
|
||||||
ServerId: cv.ServerId,
|
ServerId: cv.ServerId,
|
||||||
Command: values.gm,
|
Command: gm,
|
||||||
});
|
});
|
||||||
message.success(r.Msg);
|
message.success(r.Msg);
|
||||||
},
|
},
|
||||||
@ -163,12 +221,7 @@ const info = ref<{
|
|||||||
Chess: [],
|
Chess: [],
|
||||||
});
|
});
|
||||||
let trendItems: WorkbenchTrendItem[] = [
|
let trendItems: WorkbenchTrendItem[] = [
|
||||||
{
|
|
||||||
avatar: 'svg:avatar-1',
|
|
||||||
content: `在 <a>开源组</a> 创建了项目 <a>Vue</a>`,
|
|
||||||
date: '刚刚',
|
|
||||||
title: '威廉',
|
|
||||||
}
|
|
||||||
];
|
];
|
||||||
const [Modal, modalApi] = useVbenModal({
|
const [Modal, modalApi] = useVbenModal({
|
||||||
onCancel() {
|
onCancel() {
|
||||||
@ -189,10 +242,12 @@ const [Modal, modalApi] = useVbenModal({
|
|||||||
CurrentPage: 1, // replace 1 with the actual current page
|
CurrentPage: 1, // replace 1 with the actual current page
|
||||||
});
|
});
|
||||||
trendItems = [];
|
trendItems = [];
|
||||||
|
let id = 0;
|
||||||
if (r.ActLog) {
|
if (r.ActLog) {
|
||||||
for (const logEntry of r.ActLog.reverse()) {
|
for (const logEntry of r.ActLog.reverse()) {
|
||||||
let [title, content] = formatActLog(logEntry.Type, logEntry.Param)
|
let [title, content] = formatActLog(logEntry.Type, logEntry.Param)
|
||||||
trendItems.push({
|
trendItems.push({
|
||||||
|
Id: id++,
|
||||||
avatar: 'svg:avatar-1',
|
avatar: 'svg:avatar-1',
|
||||||
content: content || '',
|
content: content || '',
|
||||||
date: dayjs(logEntry.Time * 1000).format('YYYY-MM-DD HH:mm:ss'),
|
date: dayjs(logEntry.Time * 1000).format('YYYY-MM-DD HH:mm:ss'),
|
||||||
@ -406,21 +461,15 @@ watch(
|
|||||||
<template #diamond>{{ info.Diamond }}</template>
|
<template #diamond>{{ info.Diamond }}</template>
|
||||||
</UserHeader>
|
</UserHeader>
|
||||||
<AccessControl :codes="['super', 'admin']" type="role">
|
<AccessControl :codes="['super', 'admin']" type="role">
|
||||||
<div class="mt-5">
|
<div class="mt-5 flex">
|
||||||
<Card class="card-box flex flex-col p-5">
|
<Card class="card-box flex flex-col p-5 w-[50%]">
|
||||||
<BaseForm />
|
<BaseForm />
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
<Card class="card-box flex flex-col p-5 w-[45%] ml-5">
|
||||||
</AccessControl>
|
|
||||||
|
|
||||||
<AccessControl :codes="['super', 'admin']" type="role">
|
|
||||||
<div class="mt-5">
|
|
||||||
<Card class="card-box flex flex-col p-5">
|
|
||||||
<BanForm />
|
<BanForm />
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</AccessControl>
|
</AccessControl>
|
||||||
|
|
||||||
<div class="mt-5 flex flex-col lg:flex-row">
|
<div class="mt-5 flex flex-col lg:flex-row">
|
||||||
<div class="mr-4 w-full lg:w-3/5">
|
<div class="mr-4 w-full lg:w-3/5">
|
||||||
<orderComponent :items="info.Order" title="订单" />
|
<orderComponent :items="info.Order" title="订单" />
|
||||||
@ -429,7 +478,7 @@ watch(
|
|||||||
<div class="w-full lg:w-2/5">
|
<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 #areaid> {{ info.AreaId }}</template>
|
||||||
<template #charge> <b>$</b>{{ info.Charge.toFixed(2) }}</template>
|
<template #charge> <b>$</b>{{ chargeDisplay }}</template>
|
||||||
<template #RegisterTime> {{ info.RegisterTime }}</template>
|
<template #RegisterTime> {{ info.RegisterTime }}</template>
|
||||||
<template #logintime> {{ info.LoginTime }}</template>
|
<template #logintime> {{ info.LoginTime }}</template>
|
||||||
<template #Cumulative>{{ info.Cumulative }}</template>
|
<template #Cumulative>{{ info.Cumulative }}</template>
|
||||||
|
|||||||
@ -99,39 +99,24 @@ const formOptions: VbenFormProps = {
|
|||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
defaultValue: startDate,
|
defaultValue: startDate,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
format: 'YYYY-MM-DD',
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
},
|
},
|
||||||
fieldName: 'StartTime',
|
fieldName: 'StartTime',
|
||||||
label: '开始时间',
|
label: '开始时间',
|
||||||
formItemClass: 'col-start-1',
|
formItemClass: 'col-start-1',
|
||||||
},
|
},
|
||||||
{
|
|
||||||
component: 'TimePicker',
|
|
||||||
componentProps: {
|
|
||||||
placeholder: '时间',
|
|
||||||
},
|
|
||||||
fieldName: 'StartTime',
|
|
||||||
label: '--',
|
|
||||||
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
component: 'DatePicker',
|
component: 'DatePicker',
|
||||||
defaultValue: endDate,
|
defaultValue: endDate,
|
||||||
componentProps: {
|
componentProps: {
|
||||||
format: 'YYYY-MM-DD',
|
showTime: true,
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
},
|
},
|
||||||
fieldName: 'EndTime',
|
fieldName: 'EndTime',
|
||||||
label: '结束时间',
|
label: '结束时间',
|
||||||
|
|
||||||
},
|
},
|
||||||
{
|
|
||||||
component: 'TimePicker',
|
|
||||||
componentProps: {
|
|
||||||
placeholder: '时间',
|
|
||||||
},
|
|
||||||
fieldName: 'EndTime',
|
|
||||||
label: '--',
|
|
||||||
}
|
|
||||||
],
|
],
|
||||||
// 控制表单是否显示折叠按钮
|
// 控制表单是否显示折叠按钮
|
||||||
showCollapseButton: true,
|
showCollapseButton: true,
|
||||||
@ -245,13 +230,13 @@ function getTagColor(online: string): string {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<Page auto-content-height>
|
<Page auto-content-height class="h-[800px]">
|
||||||
<Grid>
|
<Grid>
|
||||||
<template #online="{ row }">
|
<template #online="{ row }">
|
||||||
<Tag :color="getTagColor(row.Online)">{{ row.Online }}</Tag>
|
<Tag :color="getTagColor(row.Online)">{{ row.Online }}</Tag>
|
||||||
</template>
|
</template>
|
||||||
</Grid>
|
</Grid>
|
||||||
<userModal class="w-[100%]" />
|
<userModal class="w-[98%]" />
|
||||||
</Page>
|
</Page>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@ -45,11 +45,7 @@ const forwarded = useForwardPropsEmits(delegatedProps, emits);
|
|||||||
<PopoverTrigger>
|
<PopoverTrigger>
|
||||||
<slot name="trigger"></slot>
|
<slot name="trigger"></slot>
|
||||||
|
|
||||||
<PopoverContent
|
<PopoverContent :class="contentClass" class="side-content z-[1000]" v-bind="contentProps">
|
||||||
:class="contentClass"
|
|
||||||
class="side-content z-[1000]"
|
|
||||||
v-bind="contentProps"
|
|
||||||
>
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</PopoverContent>
|
</PopoverContent>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
|
|||||||
@ -86,26 +86,20 @@ onMounted(() => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="relative">
|
<div class="relative">
|
||||||
<div
|
<div v-if="
|
||||||
v-if="
|
|
||||||
description ||
|
description ||
|
||||||
$slots.description ||
|
$slots.description ||
|
||||||
title ||
|
title ||
|
||||||
$slots.title ||
|
$slots.title ||
|
||||||
$slots.extra
|
$slots.extra
|
||||||
"
|
" ref="headerRef" :class="cn(
|
||||||
ref="headerRef"
|
|
||||||
:class="
|
|
||||||
cn(
|
|
||||||
'bg-card relative px-6 py-4',
|
'bg-card relative px-6 py-4',
|
||||||
headerClass,
|
headerClass,
|
||||||
fixedHeader
|
fixedHeader
|
||||||
? 'border-border border-b transition-all duration-200'
|
? 'border-border border-b transition-all duration-200'
|
||||||
: '',
|
: '',
|
||||||
)
|
)
|
||||||
"
|
" :style="headerStyle">
|
||||||
:style="headerStyle"
|
|
||||||
>
|
|
||||||
<slot name="title">
|
<slot name="title">
|
||||||
<div v-if="title" class="mb-2 flex text-lg font-semibold">
|
<div v-if="title" class="mb-2 flex text-lg font-semibold">
|
||||||
{{ title }}
|
{{ title }}
|
||||||
@ -127,16 +121,11 @@ onMounted(() => {
|
|||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div v-if="$slots.footer" ref="footerRef" :class="cn(
|
||||||
v-if="$slots.footer"
|
|
||||||
ref="footerRef"
|
|
||||||
:class="
|
|
||||||
cn(
|
|
||||||
footerClass,
|
footerClass,
|
||||||
'bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4',
|
'bg-card align-center absolute bottom-0 left-0 right-0 flex px-6 py-4',
|
||||||
)
|
)
|
||||||
"
|
">
|
||||||
>
|
|
||||||
<slot name="footer"></slot>
|
<slot name="footer"></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -20,6 +20,7 @@ interface WorkbenchProjectItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface WorkbenchTrendItem {
|
interface WorkbenchTrendItem {
|
||||||
|
Id: number;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
content: string;
|
content: string;
|
||||||
date: string;
|
date: string;
|
||||||
|
|||||||
@ -2,4 +2,8 @@ export { setupVbenVxeTable } from './init';
|
|||||||
export * from './use-vxe-grid';
|
export * from './use-vxe-grid';
|
||||||
export { default as VbenVxeGrid } from './use-vxe-grid.vue';
|
export { default as VbenVxeGrid } from './use-vxe-grid.vue';
|
||||||
|
|
||||||
export type { VxeGridListeners, VxeGridProps } from 'vxe-table';
|
export type {
|
||||||
|
VxeGridListeners,
|
||||||
|
VxeGridProps,
|
||||||
|
VxeColumnPropTypes,
|
||||||
|
} from 'vxe-table';
|
||||||
|
|||||||
762
pnpm-lock.yaml
@ -176,8 +176,8 @@ catalog:
|
|||||||
vue-i18n: ^10.0.5
|
vue-i18n: ^10.0.5
|
||||||
vue-router: ^4.5.0
|
vue-router: ^4.5.0
|
||||||
vue-tsc: ^2.1.10
|
vue-tsc: ^2.1.10
|
||||||
vxe-pc-ui: ^4.3.14
|
vxe-pc-ui: ^4.10.18
|
||||||
vxe-table: ^4.9.14
|
vxe-table: ^4.17.10
|
||||||
watermark-js-plus: ^1.5.7
|
watermark-js-plus: ^1.5.7
|
||||||
zod: ^3.23.8
|
zod: ^3.23.8
|
||||||
zod-defaults: ^0.1.3
|
zod-defaults: ^0.1.3
|
||||||
|
|||||||