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
288 lines
8.8 KiB
Vue
288 lines
8.8 KiB
Vue
<script setup lang="ts">
|
||
import { Page, VbenIcon } from '@vben/common-ui';
|
||
import { Button, Card, Space, Tag } from 'ant-design-vue';
|
||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||
import type { VxeGridListeners, VxeGridProps } from '#/adapter/vxe-table';
|
||
import type { VbenFormProps } from '#/adapter/form';
|
||
import type { ActivityData } from '#/api/core/activity';
|
||
import { getServerListApi, getAppListApi } from '#/api/core/server';
|
||
import { getActivityListApi } from '#/api/core/activity';
|
||
import type { AppData, ServerData } from '#/api/core/server';
|
||
import { useVbenModal } from '@vben/common-ui';
|
||
import { onMounted, ref } from 'vue';
|
||
import AddActivityModal from './activity-add.vue';
|
||
import DetailActivityModal from './activity-detail.vue';
|
||
import SyncActivityModal from './activity-sync.vue';
|
||
import { formatUTC8Time } from '#/store/util';
|
||
import { activityTypeData } from '#/store/order';
|
||
import { parseNumber } from '#/store/util';
|
||
import { $t } from '#/locales'
|
||
const activityList = ref<string[]>([]);
|
||
const appList = ref<AppData[]>([]);
|
||
const ServerList = ref<ServerData[]>([]);
|
||
const formOptions: VbenFormProps = {
|
||
// 默认展开
|
||
collapsed: false,
|
||
schema: [
|
||
{
|
||
component: 'Select',
|
||
defaultValue: 1,
|
||
componentProps: {
|
||
filterOption: true,
|
||
options: [],
|
||
placeholder: '请选择',
|
||
showSearch: true,
|
||
},
|
||
fieldName: 'AppId',
|
||
label: 'APP:',
|
||
},
|
||
{
|
||
component: 'Select',
|
||
defaultValue: "不限",
|
||
componentProps: {
|
||
filterOption: true,
|
||
options: activityTypeData ? Object.entries(activityTypeData).map(([key, value]) => ({
|
||
label: value,
|
||
value: key,
|
||
})) : [],
|
||
placeholder: '请选择',
|
||
showSearch: true,
|
||
},
|
||
fieldName: 'activityType',
|
||
label: '活动类型:',
|
||
},
|
||
],
|
||
// 控制表单是否显示折叠按钮
|
||
showCollapseButton: true,
|
||
submitButtonOptions: {
|
||
content: '查询',
|
||
},
|
||
// 是否在字段值改变时提交表单
|
||
submitOnChange: false,
|
||
// 按下回车时是否提交表单
|
||
submitOnEnter: false,
|
||
};
|
||
const gridOptions: VxeGridProps<ActivityData> = {
|
||
columns: [
|
||
{ field: 'id', title: 'id' },
|
||
{ field: 'type', title: '活动类型', formatter: ({ cellValue }) => activityTypeData[cellValue] || cellValue },
|
||
{ field: 'level', title: '开启等级', },
|
||
{ field: 'now_start_time', title: '开启时间', formatter: ({ cellValue }) => formatUTC8Time(cellValue), slots: { header: 'start_time_header' } },
|
||
{ field: 'now_end_time', title: '结束时间', formatter: ({ cellValue }) => formatUTC8Time(cellValue), slots: { header: 'end_time_header' } },
|
||
{ field: 'interval', title: '活动循环间隔(秒)从上次开始时间开始计算,0表示不循环', },
|
||
{ field: 'tag', title: '状态', slots: { default: 'tag' } },
|
||
],
|
||
minHeight: '650px',
|
||
pagerConfig: {},
|
||
proxyConfig: {
|
||
response: {
|
||
total: 'total',
|
||
result: 'data',
|
||
},
|
||
ajax: {
|
||
query: async ({ page }, formValues) => {
|
||
let AppId = parseNumber(formValues.AppId);
|
||
let activityType = parseNumber(formValues.activityType);
|
||
const response = await getActivityListApi({
|
||
AppId: AppId,
|
||
ServerId: formValues.ServerId,
|
||
PageSize: page.pageSize,
|
||
CurrentPage: page.currentPage,
|
||
activityType: activityType,
|
||
});
|
||
if (!response || !response.data) {
|
||
activityList.value = [];
|
||
return response;
|
||
}
|
||
const now = Math.floor(Date.now() / 1000);
|
||
activityList.value = [];
|
||
for (let item of response.data) {
|
||
const interval = item.interval || 0;
|
||
if (interval == 0) {
|
||
item.now_start_time = item.start_time;
|
||
item.now_end_time = item.end_time;
|
||
} else {
|
||
if (now < item.start_time) {
|
||
item.now_start_time = item.start_time;
|
||
item.now_end_time = item.end_time;
|
||
} else {
|
||
const cycle = Math.floor((now - item.start_time) / interval);
|
||
item.now_start_time = item.start_time + cycle * interval;
|
||
item.now_end_time = item.end_time + cycle * interval;
|
||
if (item.now_end_time < now) {
|
||
item.now_start_time += interval;
|
||
item.now_end_time += interval;
|
||
}
|
||
}
|
||
}
|
||
if (item.now_end_time < now) {
|
||
item.tag = '已结束';
|
||
} else if (item.now_start_time > now) {
|
||
item.tag = '未开始';
|
||
} else {
|
||
activityList.value = Array.from(new Set([...activityList.value, activityTypeData[item.type]])).filter((v): v is string => v !== undefined);
|
||
item.tag = '生效中';
|
||
}
|
||
}
|
||
console.log(response);
|
||
|
||
return response;
|
||
},
|
||
},
|
||
},
|
||
showOverflow: false,
|
||
rowConfig: {
|
||
isHover: true,
|
||
},
|
||
};
|
||
const gridEvents: VxeGridListeners<ActivityData> = {
|
||
cellClick: async ({ row }) => {
|
||
const Value = await GridApi.formApi.getValues();
|
||
DetailActivityApi.setData({ AppId: Value.AppId, cfg: row });
|
||
DetailActivityApi.open();
|
||
// message.info(`cell-click: ${row.title}`);
|
||
},
|
||
};
|
||
const [Grid, GridApi] = useVbenVxeGrid({
|
||
gridEvents,
|
||
formOptions,
|
||
gridOptions,
|
||
});
|
||
const [AddActivityM, AddActivityApi] = useVbenModal({
|
||
connectedComponent: AddActivityModal,
|
||
onClosed: async () => {
|
||
AddActivityApi.close();
|
||
GridApi.query();
|
||
//console.log("close")
|
||
},
|
||
});
|
||
|
||
const [DetailActivityM, DetailActivityApi] = useVbenModal({
|
||
connectedComponent: DetailActivityModal,
|
||
onClosed: async () => {
|
||
DetailActivityApi.close();
|
||
GridApi.query();
|
||
//console.log("close")
|
||
}
|
||
});
|
||
|
||
const [SyncActivityM, SyncActivityApi] = useVbenModal({
|
||
connectedComponent: SyncActivityModal,
|
||
onClosed: async () => {
|
||
SyncActivityApi.close();
|
||
GridApi.query();
|
||
//console.log("close")
|
||
}
|
||
});
|
||
onMounted(async () => {
|
||
try {
|
||
const response = await getAppListApi();
|
||
appList.value = Array.isArray(response) ? response : [];
|
||
const app = appList.value[0];
|
||
if (!app) return;
|
||
GridApi.formApi.updateSchema([
|
||
{
|
||
component: 'Select',
|
||
componentProps: {
|
||
options: appList.value.map((item) => ({
|
||
label: $t('page.server.' + item.AppName),
|
||
value: item.AppId,
|
||
})),
|
||
},
|
||
fieldName: 'AppId',
|
||
},
|
||
]);
|
||
const serverResponse = await getServerListApi({
|
||
AppId: app.AppId,
|
||
Type: 1,
|
||
});
|
||
ServerList.value = Array.isArray(serverResponse) ? serverResponse : [];
|
||
GridApi.formApi.updateSchema([
|
||
{
|
||
component: 'Select',
|
||
componentProps: {
|
||
options: ServerList.value.map((item) => ({
|
||
label: item.ServerName,
|
||
value: item.ServerId,
|
||
})),
|
||
},
|
||
fieldName: 'ServerId',
|
||
},
|
||
]);
|
||
} catch (e) {
|
||
appList.value = [];
|
||
//console.log(e);
|
||
}
|
||
});
|
||
|
||
function getTagColor(tag: string) {
|
||
switch (tag) {
|
||
case '未开始':
|
||
return 'blue';
|
||
case '生效中':
|
||
return 'green';
|
||
case '已结束':
|
||
return 'red';
|
||
default:
|
||
return 'brown';
|
||
}
|
||
}
|
||
|
||
async function addActivity() {
|
||
//console.log('addActivity');
|
||
const Value = await GridApi.formApi.getValues();
|
||
AddActivityApi.setData({ AppId: Value.AppId, ServerId: Value.ServerId });
|
||
AddActivityApi.open();
|
||
}
|
||
|
||
async function syncCfg(){
|
||
const Value = await GridApi.formApi.getValues();
|
||
SyncActivityApi.setData({ AppList: appList.value, AppId: Value.AppId, ServerId: Value.ServerId });
|
||
SyncActivityApi.open();
|
||
}
|
||
|
||
</script>
|
||
|
||
<template>
|
||
<Page auto-content-height>
|
||
<AddActivityM class="w-[50%]" />
|
||
<DetailActivityM class="w-[50%]" />
|
||
<SyncActivityM class="w-[50%]" />
|
||
<Card class="mb-5" title="活动操作">
|
||
<div class="mb-5">
|
||
<Space>
|
||
<template v-for="value in activityList" :key="value">
|
||
<Tag color="green" class="asset-log-change-tag"> <VbenIcon icon="material-symbols:av-timer" class="mr-1" />{{ value }}</Tag>
|
||
</template>
|
||
</Space>
|
||
</div>
|
||
|
||
<Space>
|
||
<Button type="primary" @click="addActivity">新增活动</Button>
|
||
</Space>
|
||
<Space class="ml-5">
|
||
<Button type="primary" @click="syncCfg">同步活动</Button>
|
||
</Space>
|
||
</Card>
|
||
<Grid>
|
||
<template #start_time_header>
|
||
开启时间 <span style="color: red">(UTC+8)</span>
|
||
</template>
|
||
<template #end_time_header>
|
||
结束时间 <span style="color: red">(UTC+8)</span>
|
||
</template>
|
||
<template #tag="{ row }">
|
||
<Tag :color=getTagColor(row.tag) class="asset-log-change-tag"> <VbenIcon icon="solar:user-id-bold" class="mr-1" />{{ row.tag }}</Tag>
|
||
</template>
|
||
</Grid>
|
||
</Page>
|
||
</template>
|
||
|
||
<style lang="css">
|
||
.asset-log-change-tag {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
border-radius: 999px;
|
||
font-weight: 700;
|
||
}
|
||
</style> |