增加自动化脚本
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
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
This commit is contained in:
parent
1dc256452e
commit
abab4f3637
1
.gitignore
vendored
1
.gitignore
vendored
@ -49,3 +49,4 @@ vite.config.ts.*
|
||||
*.sln
|
||||
*.sw?
|
||||
.history
|
||||
node-compile-cache/*
|
||||
|
||||
@ -23,7 +23,12 @@ export interface UserLogOrder {
|
||||
Time: number;
|
||||
Type: number;
|
||||
Diff: number;
|
||||
ChessId: string;
|
||||
ChessId: ChessType[];
|
||||
}
|
||||
|
||||
export interface ChessType {
|
||||
Id: string;
|
||||
Icon: string;
|
||||
}
|
||||
export interface heatType {
|
||||
date: string;
|
||||
|
||||
8
apps/web-antd/src/api/core/scripts.ts
Normal file
8
apps/web-antd/src/api/core/scripts.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { requestClient } from '#/api/request';
|
||||
|
||||
export interface scripts_params{
|
||||
step :number;
|
||||
}
|
||||
export async function copywritingscript(params :scripts_params) {
|
||||
return requestClient.post('/scripts/copywriting', params, {timeout: 180000});
|
||||
}
|
||||
@ -18,8 +18,8 @@ export interface ServerData {
|
||||
AppId : number;
|
||||
ServerId: number;
|
||||
ServerName: string;
|
||||
Status: number;
|
||||
OpenServerTime: number;
|
||||
Status?: number;
|
||||
OpenServerTime?: number;
|
||||
StartTime?: number;
|
||||
PlayerNum?: number;
|
||||
Loading?:boolean;
|
||||
@ -30,6 +30,14 @@ export interface ServerData {
|
||||
Tags?: string[];
|
||||
}
|
||||
|
||||
export interface editServerParam {
|
||||
AppId : number;
|
||||
ServerId: number;
|
||||
ServerName: string;
|
||||
Tags?: string;
|
||||
ClientVersion?: string;
|
||||
}
|
||||
|
||||
export interface NodeData{
|
||||
NodeId?: number;
|
||||
NodeName: string;
|
||||
@ -85,3 +93,7 @@ export async function addServer(AppId:number, ServerId:number, ServerName: strin
|
||||
return requestClient.post(`/server/addServer`, {AppId:AppId, ServerId: ServerId, ServerName: ServerName, Status: Status, OpenServerTime: OpenServerTime});
|
||||
}
|
||||
|
||||
export async function editServer(editParam: editServerParam){
|
||||
return requestClient.post(`/server/editServer`, editParam);
|
||||
}
|
||||
|
||||
|
||||
@ -118,8 +118,8 @@ defineEmits(['click']);
|
||||
<div class="text-foreground/80 mt-4 h-12 ">
|
||||
<div v-if="item.merge && item.merge.length > 0" class="flex flex-wrap gap-1">
|
||||
<img v-for="mergeItem in item.merge" :key="mergeItem.Icon"
|
||||
:src="`../../../merge/${mergeItem.Icon}.png`" class="inline-block h-6 w-6 rounded"
|
||||
:alt="mergeItem.Title" :title="mergeItem.Title" />
|
||||
:src="`${mergeItem.Icon}`" class="inline-block h-6 w-6 rounded"
|
||||
:alt="mergeItem.Icon" :title="mergeItem.Id" />
|
||||
</div>
|
||||
<span v-else>{{ item.content }}</span>
|
||||
</div>
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
"log": "操作日志"
|
||||
},
|
||||
"dashboard": {
|
||||
"title": "服务器管理",
|
||||
"title": "运维管理",
|
||||
"analytics": "分析台",
|
||||
"server-list": "区服列表",
|
||||
"node-list": "节点列表",
|
||||
@ -52,12 +52,18 @@
|
||||
},
|
||||
"operation": {
|
||||
"title": "运营管理",
|
||||
"level": "等级分布",
|
||||
"scripts": "自动化脚本",
|
||||
"mail": "邮件管理",
|
||||
"order": "订单管理",
|
||||
"language": "翻译管理",
|
||||
"copyUser": "用户数据复制"
|
||||
},
|
||||
"server":{
|
||||
"merge_pet_test":"测试服",
|
||||
"merge_pet_sdk":"QA服",
|
||||
"merge_pet_online":"正式服",
|
||||
"merge_pet_audit":"审核服"
|
||||
},
|
||||
"log": {
|
||||
"event": {
|
||||
"order_finish": "完成订单",
|
||||
|
||||
@ -21,12 +21,15 @@ export interface Merge {
|
||||
export interface MergeRecord{
|
||||
[key: string]: Merge;
|
||||
}
|
||||
|
||||
export interface ChessType {
|
||||
Id: string;
|
||||
Icon: string;
|
||||
}
|
||||
export interface Order {
|
||||
id: number;
|
||||
color?: string;
|
||||
icon?:string;
|
||||
merge?: Merge[];
|
||||
merge?: ChessType[];
|
||||
type?: number;
|
||||
typeName?: string;
|
||||
diff: number;
|
||||
@ -72,3 +75,11 @@ export interface copyUserParam{
|
||||
dst_app: number;
|
||||
dst_uid: number;
|
||||
}
|
||||
|
||||
export interface scriptsRecord{
|
||||
step: number;
|
||||
label: string;
|
||||
tips :string[];
|
||||
code: number;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
@ -17,7 +17,7 @@ const routes: RouteRecordRaw[] = [
|
||||
{
|
||||
name: 'Language',
|
||||
path: '/language',
|
||||
component: () => import('#/views/language/language/index.vue'),
|
||||
component: () => import('#/views/language/index.vue'),
|
||||
meta: {
|
||||
affixTab: true,
|
||||
icon: 'lets-icons:order',
|
||||
|
||||
@ -16,13 +16,13 @@ const routes: RouteRecordRaw[] = [
|
||||
path: '/operation',
|
||||
children: [
|
||||
{
|
||||
name: 'Level',
|
||||
path: '/level',
|
||||
component: () => import('#/views/operation/level/index.vue'),
|
||||
name: 'Scripts',
|
||||
path: '/scripts',
|
||||
component: () => import('#/views/operation/scripts/index.vue'),
|
||||
meta: {
|
||||
affixTab: true,
|
||||
icon: 'lucide:chart-no-axes-column-increasing',
|
||||
title: $t('page.operation.level'),
|
||||
title: $t('page.operation.scripts'),
|
||||
authority: ['super', 'admin'],
|
||||
},
|
||||
},
|
||||
|
||||
@ -157,12 +157,7 @@ function confirmUpdate(Server: ServerData) {
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>32ms</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>1.0.0</span>
|
||||
<span>{{ item.ClientVersion }}</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
import { addServer } from '#/api/core/server';
|
||||
import { editServer } from '#/api/core/server';
|
||||
import { useVbenModal } from '@vben/common-ui';
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import dayjs from 'dayjs';
|
||||
@ -79,18 +79,6 @@ const [Form, FormApi] = useVbenForm({
|
||||
label: 'version',
|
||||
formItemClass: 'col-span-2',
|
||||
},
|
||||
{
|
||||
component: 'NumberPicker',
|
||||
defaultValue: '',
|
||||
componentProps: {
|
||||
placeholder: 'node1',
|
||||
},
|
||||
rules: "required",
|
||||
fieldName: 'max_online',
|
||||
label: 'max_online',
|
||||
formItemClass: 'col-span-2',
|
||||
},
|
||||
|
||||
],
|
||||
showDefaultActions: false,
|
||||
// 大屏一行显示3个,中屏一行显示2个,小屏一行显示1个
|
||||
@ -163,12 +151,16 @@ const [Modal, modalApi] = useVbenModal({
|
||||
onConfirm: async () => {
|
||||
// 提交表单
|
||||
const values = await FormApi.getValues();
|
||||
const date = dayjs(values.datePicker).format('YYYY-MM-DD');
|
||||
const time = dayjs(values.timePicker).format('HH:mm:ss');
|
||||
const dateTime = dayjs(`${date} ${time}`).valueOf() / 1000;
|
||||
const modalData = modalApi.getData();
|
||||
const ServerId = parseInt(values.ServerId, 10);
|
||||
await addServer(modalData.AppId, ServerId, values.ServerName, values.Status, dateTime);
|
||||
const editParam = {
|
||||
AppId: modalData.AppId,
|
||||
ServerId: ServerId,
|
||||
ServerName: values.ServerName,
|
||||
Tags: values.Tags,
|
||||
ClientVersion: values.version,
|
||||
}
|
||||
await editServer(editParam);
|
||||
modalApi.close();
|
||||
},
|
||||
});
|
||||
|
||||
@ -9,6 +9,7 @@ import { useVbenModal } from '@vben/common-ui'
|
||||
import { ref,onMounted } from 'vue';
|
||||
import addServerModal from './addServer.vue';
|
||||
import dayjs from 'dayjs';
|
||||
import { $t } from '#/locales'
|
||||
const [BaseForm, BaseFormApi] = useVbenForm({
|
||||
// 所有表单项共用,可单独在表单内覆盖
|
||||
commonConfig: {
|
||||
@ -111,7 +112,7 @@ onMounted(async() => {
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
options: appList.value.map((item) => ({
|
||||
label: item.AppName,
|
||||
label: $t('page.server.' + item.AppName),
|
||||
value: item.AppId,
|
||||
})),
|
||||
},
|
||||
@ -207,11 +208,6 @@ async function update() {
|
||||
<span>MEMORY</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>LATENCY</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>CLIENT VERSION</span>
|
||||
|
||||
@ -100,7 +100,7 @@ const [Modal, modalApi] = useVbenModal({
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<Modal width="100%">
|
||||
<Modal width="80%">
|
||||
<Form />
|
||||
<Grid />
|
||||
</Modal>
|
||||
@ -103,6 +103,9 @@ const formOptions: VbenFormProps = {
|
||||
}
|
||||
const gridOptions: VxeGridProps<languageType> = {
|
||||
border: true,
|
||||
cellConfig:{
|
||||
height:60,
|
||||
},
|
||||
columns: [
|
||||
{ title: 'Id', field: 'Id', width: 100 },
|
||||
{ editRender: { name: 'input' }, field: 'key', title: 'key', filters: [{ data: "" }], filterRender: { name: "input" }, visible: keyVisible },
|
||||
@ -110,7 +113,7 @@ const gridOptions: VxeGridProps<languageType> = {
|
||||
field: 'imageUrl',
|
||||
slots: { default: 'image-url' },
|
||||
title: 'Image',
|
||||
width: 100,
|
||||
width: 60,
|
||||
},
|
||||
{ editRender: { name: 'input' }, field: 'en_US', title: 'en_US', filters: [{ data: "" }], filterRender: { name: "input" }, visible: en_USVisible },
|
||||
{
|
||||
@ -253,7 +256,7 @@ const gridOptions: VxeGridProps<languageType> = {
|
||||
field: 'imageUrl',
|
||||
slots: { default: 'image-url' },
|
||||
title: 'Image',
|
||||
width: 50,
|
||||
width: 60,
|
||||
},
|
||||
{ editRender: { name: 'input' }, field: 'en_US', title: 'en_US', filters: [{ data: "" }], filterRender: { name: "input" }, visible: en_USVisible },
|
||||
{
|
||||
@ -420,7 +423,7 @@ function deleteRow(row: languageType) {
|
||||
<template>
|
||||
<div class="min-h-screen flex flex-col">
|
||||
<Page auto-content-height>
|
||||
<AddLanguageModal width="1200px" height="1200px"></AddLanguageModal />
|
||||
<AddLanguageModal width="800px" height="800px"></AddLanguageModal />
|
||||
<Grid>
|
||||
<template #toolbar-tools>
|
||||
<span class="mr-4 font-bold">{{ $t('page.language.lastUpdate') }}:{{ lastUpdate }}</span>
|
||||
@ -428,11 +431,11 @@ function deleteRow(row: languageType) {
|
||||
{{ $t('page.common.addLine') }}
|
||||
</Button>
|
||||
<Button type="primary" @click="saveAll" class="mr-2"> {{ $t('page.common.save') }} </Button>
|
||||
<Button type="primary" @click="exportLang"> {{ $t('page.common.gitCommit') }} </Button>
|
||||
<!-- <Button type="primary" @click="exportLang"> {{ $t('page.common.gitCommit') }} </Button> -->
|
||||
</template>
|
||||
<template #image-url="{ row }">
|
||||
<!-- <Image src="../../../../public/merge/Launcher_A_LV1.png" height="50" width="50" /> -->
|
||||
<Image v-if="row.url" :src="row.url" height="50" width="50" />
|
||||
<!-- <Image src="./public/merge/Launcher_A_LV1.png" height="50" width="50" /> -->
|
||||
<Image v-if="row.url" :src="row.url" height="40" width="40" />
|
||||
</template>
|
||||
<template #action="{ row }">
|
||||
<AccessControl :codes="['super', 'admin']" type="role">
|
||||
@ -2,6 +2,7 @@
|
||||
import { useVbenForm } from '#/adapter/form';
|
||||
import { message } from 'ant-design-vue'
|
||||
import { copyUser } from '#/api/core/operation';
|
||||
import { VbenPopover, VbenIcon } from '../../../../../../packages/@core/ui-kit/shadcn-ui';
|
||||
import type { copyUserParam } from '#/model/type';
|
||||
const [Form] = useVbenForm({
|
||||
// 所有表单项共用,可单独在表单内覆盖
|
||||
@ -69,16 +70,6 @@ const [Form] = useVbenForm({
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
component: 'Input',
|
||||
fieldName: 'dst_uid',
|
||||
label: '目标用户ID',
|
||||
defaultValue: 100100042,
|
||||
rules: 'required',
|
||||
componentProps: {
|
||||
placeholder: '请输入目标用户ID',
|
||||
},
|
||||
},
|
||||
],
|
||||
handleSubmit: onSubmit,
|
||||
|
||||
@ -102,7 +93,22 @@ async function onSubmit(values: Record<string, any>) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
<Form class="mt-20" />
|
||||
<VbenPopover class="ml-5" :content-props="{ side: 'top' }">
|
||||
<template #trigger>
|
||||
<VbenIcon icon="solar:question-circle-bold" class="ml-5" />
|
||||
</template>
|
||||
<div class="max-w-xs text-sm">
|
||||
<h3 class="font-semibold mt-4 mb-2">账号复制说明</h3>
|
||||
<ul>
|
||||
<li><b>源应用ID:</b>需要复制的账号所在的APP</li>
|
||||
<li><b>源用户ID:</b>需要复制的账号所生成的后端唯一ID</li>
|
||||
<li><b>目标应用ID:</b>需要复制到的APP</li>
|
||||
<li><b>目标应用账号:</b>源用户ID</li>
|
||||
</ul>
|
||||
</div>
|
||||
</VbenPopover>
|
||||
<Form class="mt-20" >
|
||||
|
||||
</Form>
|
||||
|
||||
</template>
|
||||
@ -1,152 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { Page } from '@vben/common-ui';
|
||||
|
||||
import { getStatisticsLevel } from '#/api/core/statistics';
|
||||
import { useVbenVxeGrid } from '#/adapter/vxe-table';
|
||||
|
||||
import type { VxeGridProps } from '#/adapter/vxe-table';
|
||||
import type { VbenFormProps } from '#/adapter/form';
|
||||
import { getServerListApi, getAppListApi } from '#/api/core/server';
|
||||
import type { AppData, ServerData } from '#/api/core/server';
|
||||
import { onMounted, ref } from 'vue';
|
||||
const appList = ref<AppData[]>([]);
|
||||
const ServerList = ref<ServerData[]>([]);
|
||||
interface RowType {
|
||||
Uid: number;
|
||||
change_type: string;
|
||||
change_num: string;
|
||||
change_after: string;
|
||||
item_id: string;
|
||||
timestamp: string;
|
||||
}
|
||||
|
||||
const formOptions: VbenFormProps = {
|
||||
// 默认展开
|
||||
collapsed: false,
|
||||
schema: [
|
||||
{
|
||||
component: 'Select',
|
||||
defaultValue: 1,
|
||||
componentProps: {
|
||||
onChange: async (value: number) => {
|
||||
const serverResponse = await getServerListApi({ AppId: value, Type: 1 });
|
||||
ServerList.value = Array.isArray(serverResponse) ? serverResponse : [];
|
||||
GridApi.formApi.updateSchema([
|
||||
{
|
||||
component: 'CheckboxGroup',
|
||||
componentProps: {
|
||||
options: ServerList.value.map((item) => ({
|
||||
label: item.ServerName,
|
||||
value: item.ServerId,
|
||||
})),
|
||||
},
|
||||
fieldName: 'ServerList',
|
||||
},
|
||||
]);
|
||||
},
|
||||
filterOption: true,
|
||||
options: [
|
||||
|
||||
],
|
||||
placeholder: '请选择',
|
||||
showSearch: true,
|
||||
},
|
||||
fieldName: 'AppId',
|
||||
label: 'APP:',
|
||||
},
|
||||
{
|
||||
component: 'CheckboxGroup',
|
||||
componentProps: {
|
||||
name: 'cname',
|
||||
options: [],
|
||||
},
|
||||
fieldName: 'ServerList',
|
||||
label: '区服',
|
||||
},
|
||||
],
|
||||
// 控制表单是否显示折叠按钮
|
||||
showCollapseButton: true,
|
||||
submitButtonOptions: {
|
||||
content: '查询',
|
||||
},
|
||||
// 是否在字段值改变时提交表单
|
||||
submitOnChange: false,
|
||||
// 按下回车时是否提交表单
|
||||
submitOnEnter: false,
|
||||
}
|
||||
const gridOptions: VxeGridProps<RowType> = {
|
||||
columns: [
|
||||
{ field: 'Level', title: '等级' },
|
||||
{ field: 'Sum', title: '人数' },
|
||||
],
|
||||
height: 'auto',
|
||||
pagerConfig: {},
|
||||
proxyConfig: {
|
||||
response: {
|
||||
total: "total",
|
||||
result: "data"
|
||||
},
|
||||
ajax: {
|
||||
query: async ({ }, formValues) => {
|
||||
if (formValues.ServerList.length == 0) {
|
||||
return []
|
||||
}
|
||||
let AppId = parseInt(formValues.AppId, 10);
|
||||
return await getStatisticsLevel({
|
||||
AppId: AppId,
|
||||
ServerList: formValues.ServerList
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
rowConfig: {
|
||||
isHover: true,
|
||||
},
|
||||
};
|
||||
|
||||
const [Grid, GridApi] = useVbenVxeGrid({ formOptions, gridOptions });
|
||||
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: 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: 'CheckboxGroup',
|
||||
componentProps: {
|
||||
options: ServerList.value.map((item) => ({
|
||||
label: item.ServerName,
|
||||
value: item.ServerId,
|
||||
})),
|
||||
},
|
||||
fieldName: 'ServerList',
|
||||
},
|
||||
]);
|
||||
} catch (e) {
|
||||
appList.value = [];
|
||||
//console.log(e);
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Page auto-content-height class="h-[800px]">
|
||||
<Grid />
|
||||
</Page>
|
||||
</template>
|
||||
112
apps/web-antd/src/views/operation/scripts/drawer.vue
Normal file
112
apps/web-antd/src/views/operation/scripts/drawer.vue
Normal file
@ -0,0 +1,112 @@
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue';
|
||||
import { useVbenDrawer } from '@vben/common-ui';
|
||||
import { VbenIcon } from '../../../../../../packages/@core/ui-kit/shadcn-ui';
|
||||
import { Timeline } from 'ant-design-vue';
|
||||
import { copywritingscript } from '#/api/core/scripts';
|
||||
import type { scriptsRecord } from '#/model/type';
|
||||
const data = ref();
|
||||
const end = ref(false);
|
||||
const pendinglabel = ref('脚本运行中...');
|
||||
const stepList = ref<scriptsRecord[]>([]);
|
||||
const [Drawer, drawerApi] = useVbenDrawer({
|
||||
onCancel() {
|
||||
drawerApi.close();
|
||||
},
|
||||
onConfirm() {
|
||||
console.log('onConfirm');
|
||||
},
|
||||
onOpenChange(open: boolean) {
|
||||
if (open) {
|
||||
data.value = drawerApi.getData<Record<string, any>>();
|
||||
stepList.value = [];
|
||||
end.value = false;
|
||||
pendinglabel.value = '脚本运行中...';
|
||||
// 使用 nextTick 确保状态重置后再执行脚本
|
||||
setTimeout(() => {
|
||||
switch (data.value.scriptInstanceId) {
|
||||
case 1:
|
||||
console.log('running script copywriting');
|
||||
runningStep(copywritingscript, stepList.value.length);
|
||||
break;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
// switch (data.value.scriptInstanceId) {
|
||||
// case 1:
|
||||
// // load data or do something
|
||||
// console.log('running script copywriting');
|
||||
// runningStep(copywritingscript, stepList.value.length);
|
||||
// break;
|
||||
// }
|
||||
},
|
||||
|
||||
});
|
||||
|
||||
function runningStep(func: Function, step: number) {
|
||||
func({ step: step }).then((res: scriptsRecord) => {
|
||||
if (res.step != 1) {
|
||||
stepList.value?.push({
|
||||
step: res.step - 1,
|
||||
label: pendinglabel.value,
|
||||
tips: res.tips || [],
|
||||
code: res.code,
|
||||
});
|
||||
if (res.code !== 0) {
|
||||
// 出错,结束
|
||||
end.value = true;
|
||||
pendinglabel.value = '';
|
||||
stepList.value = stepList.value.map((item, index) => ({
|
||||
...item,
|
||||
color: index === stepList.value.length - 1 ? 'red' : 'blue'
|
||||
}));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (res.step !== -1) {
|
||||
// 合并当前步骤的tips到上一个record
|
||||
stepList.value = stepList.value.map((item, index) => ({
|
||||
...item,
|
||||
color: index === stepList.value.length ? 'gray' : 'blue'
|
||||
}));
|
||||
pendinglabel.value = res.label;
|
||||
runningStep(func, res.step);
|
||||
} else {
|
||||
stepList.value = stepList.value.map((item, index) => ({
|
||||
...item,
|
||||
color: 'blue'
|
||||
}));
|
||||
end.value = true;
|
||||
pendinglabel.value = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<Drawer>
|
||||
<Timeline :pending="pendinglabel">
|
||||
<Timeline.Item v-for="item in stepList" :key="item.step" :pending="false" :color="item.color || 'blue'">
|
||||
<template #dot>
|
||||
<VbenIcon :icon="item.code == 0?'system-uicons:check-circle':'system-uicons:cross-circle'" />
|
||||
</template>
|
||||
<span>{{ item.label }}</span>
|
||||
<div>
|
||||
<ul class="list-disc ml-5">
|
||||
<li v-for="tip in item.tips">{{ tip }}</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Timeline.Item>
|
||||
<Timeline.Item v-if="end" color="blue">
|
||||
<template #dot>
|
||||
<VbenIcon icon="system-uicons:check-circle" />
|
||||
</template>
|
||||
completed
|
||||
</Timeline.Item>
|
||||
<template #pendingDot>
|
||||
<VbenIcon icon="svg-spinners:12-dots-scale-rotate" />
|
||||
</template>
|
||||
</Timeline>
|
||||
</Drawer>
|
||||
</template>
|
||||
@ -1,7 +1,7 @@
|
||||
<script lang="ts" setup>
|
||||
|
||||
|
||||
import AnalyticsVisitsTable from './level-table.vue';
|
||||
import AnalyticsVisitsTable from './scripts.vue';
|
||||
|
||||
|
||||
|
||||
83
apps/web-antd/src/views/operation/scripts/scripts.vue
Normal file
83
apps/web-antd/src/views/operation/scripts/scripts.vue
Normal file
@ -0,0 +1,83 @@
|
||||
<script lang="ts" setup>
|
||||
import { Page } from '@vben/common-ui';
|
||||
import { Button, Card, Space, notification, Tag } from 'ant-design-vue';
|
||||
import { useVbenDrawer, VbenButton } from '@vben/common-ui';
|
||||
import ExtraDrawer from './drawer.vue';
|
||||
const [Drawer, drawerApi] = useVbenDrawer({
|
||||
connectedComponent: ExtraDrawer,
|
||||
});
|
||||
|
||||
|
||||
function startScript(id:number) {
|
||||
notification.success({
|
||||
message: '脚本已启动',
|
||||
description: '文案自动化脚本已成功启动,正在运行中。',
|
||||
});
|
||||
drawerApi.setState({
|
||||
title: '文案自动化脚本',
|
||||
});
|
||||
drawerApi.setData({
|
||||
scriptLaber: '文案自动化脚本',
|
||||
scriptInstanceId: id,
|
||||
});
|
||||
drawerApi.open();
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
<template>
|
||||
<Page>
|
||||
<Drawer />
|
||||
<div class="p-5">
|
||||
<div class="card-box p-4 py-6 flex justify-between h-12">
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>Script Name</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>TAGS</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>Last Running</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>Start</span>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="p-5">
|
||||
<div class="card-box p-4 py-6 flex justify-between h-12">
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>文案自动化脚本</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<Tag>xlsx</Tag>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<span>2026-01-01 12:00:00</span>
|
||||
</h1>
|
||||
</div>
|
||||
<div class="flex flex-col justify-center md:mt-0 lg:w-1/12">
|
||||
<h1 class="text-md font-semibold md:text-ml text-center">
|
||||
<Button type="primary" @click="startScript(1)">Start</Button>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Page>
|
||||
|
||||
|
||||
</template>
|
||||
@ -331,16 +331,6 @@ const [Modal, modalApi] = useVbenModal({
|
||||
}
|
||||
for (const i in r.Order) {
|
||||
var chessArr = r.Order[i]?.ChessId
|
||||
? r.Order[i]?.ChessId.split(' ')
|
||||
: [];
|
||||
var ChessData: Merge[] = [];
|
||||
for (const chessId of chessArr) {
|
||||
const key = String(parseInt(chessId));
|
||||
const chessInfo = (MergeData as Record<string, Merge>)[key];
|
||||
if (chessInfo) {
|
||||
ChessData.push(chessInfo);
|
||||
}
|
||||
}
|
||||
var orderTypeName = Object.entries(orderTypeData).find(
|
||||
([key]) => Number(key) === r.Order[i]?.Type
|
||||
)?.[1];
|
||||
@ -349,9 +339,8 @@ const [Modal, modalApi] = useVbenModal({
|
||||
)?.[1];
|
||||
info.value.Order.push({
|
||||
id: r.Order[i]?.Id || 0,
|
||||
merge: ChessData,
|
||||
merge: chessArr,
|
||||
color: '#3fb27f',
|
||||
content: r.Order[i]?.ChessId || '',
|
||||
typeName: orderTypeName || '未知类型',
|
||||
diff: r.Order[i]?.Diff || 0,
|
||||
diffName: diffName || '未知',
|
||||
|
||||
Loading…
Reference in New Issue
Block a user