Commit 662125225a6a2c8f592a832948ba061eddb9ae2c

Authored by ww
1 parent eca2a637

feat: 新增运行任务调用模态框

@@ -67,7 +67,7 @@ @@ -67,7 +67,7 @@
67 // margin-top 24 height 24 67 // margin-top 24 height 24
68 const paginationHeight = 24 + 24 + 8; 68 const paginationHeight = 24 + 24 + 8;
69 // list pading top 8 maring-top 8 extra slot 56 69 // list pading top 8 maring-top 8 extra slot 56
70 - const listContainerMarginBottom = 8 + 8 + 56; 70 + const listContainerMarginBottom = 8 + 8 + 72;
71 const listContainerHeight = 71 const listContainerHeight =
72 clientHeight - rect.top - paginationHeight - listContainerMarginBottom; 72 clientHeight - rect.top - paginationHeight - listContainerMarginBottom;
73 const listContainerEl = (unref(listElRef)!.$el as HTMLElement).querySelector( 73 const listContainerEl = (unref(listElRef)!.$el as HTMLElement).querySelector(
@@ -86,7 +86,7 @@ @@ -86,7 +86,7 @@
86 </script> 86 </script>
87 87
88 <template> 88 <template>
89 - <PageWrapper class="bg-gray-100"> 89 + <PageWrapper class="bg-gray-100 device-task-list-container">
90 <section 90 <section
91 class="form-container bg-light-50 px-4 pt-4 mt-4 x dark:text-gray-300 dark:bg-dark-900" 91 class="form-container bg-light-50 px-4 pt-4 mt-4 x dark:text-gray-300 dark:bg-dark-900"
92 > 92 >
@@ -101,7 +101,10 @@ @@ -101,7 +101,10 @@
101 :loading="loading" 101 :loading="loading"
102 > 102 >
103 <template #header> 103 <template #header>
104 - <section class="flex justify-end gap-4"> 104 + <section class="flex justify-between gap-4 min-h-12 items-center">
  105 + <div class="text-lg font-semibold">
  106 + <span>任务列表</span>
  107 + </div>
105 <Tooltip title="刷新"> 108 <Tooltip title="刷新">
106 <Button type="primary" @click="getDataSource"> 109 <Button type="primary" @click="getDataSource">
107 <ReloadOutlined :spin="loading" /> 110 <ReloadOutlined :spin="loading" />
@@ -123,3 +126,15 @@ @@ -123,3 +126,15 @@
123 </section> 126 </section>
124 </PageWrapper> 127 </PageWrapper>
125 </template> 128 </template>
  129 +
  130 +<style lang="less" scoped>
  131 + .device-task-list-container {
  132 + :deep(.ant-list-header) {
  133 + border: none;
  134 + }
  135 +
  136 + :deep(.ant-card-body) {
  137 + padding: 16px 24px;
  138 + }
  139 + }
  140 +</style>
  1 +import { TaskTargetEnum } from '../../config';
  2 +import { FormSchema } from '/@/components/Form';
  3 +
  4 +export enum FormFieldsEnum {
  5 + RUN_TARGET_TYPE = 'runTargetType',
  6 + TASK_TYPE = 'taskType',
  7 + ASSIGN_TARGET = 'assignTarget',
  8 + TASK_TARGET_TYPE = 'taskTargetType',
  9 + TASK_TARGET_VALUE = 'taskTargetValue',
  10 +}
  11 +
  12 +export enum TargetType {
  13 + ALL = 'ALL',
  14 + ASSIGN = 'ASSIGN',
  15 +}
  16 +
  17 +export enum TargetNameType {
  18 + ALL = '所有目标设备',
  19 + ASSIGN = '指定目标设备',
  20 +}
  21 +
  22 +export const formSchemas: FormSchema[] = [
  23 + {
  24 + field: 'taskName',
  25 + component: 'Input',
  26 + label: '任务名称',
  27 + slot: 'taskName',
  28 + },
  29 + {
  30 + field: FormFieldsEnum.TASK_TYPE,
  31 + component: 'Input',
  32 + label: '任务类型',
  33 + slot: 'taskType',
  34 + },
  35 + {
  36 + field: FormFieldsEnum.TASK_TARGET_TYPE,
  37 + component: 'Input',
  38 + label: '目标类型',
  39 + show: false,
  40 + },
  41 + {
  42 + field: FormFieldsEnum.TASK_TARGET_VALUE,
  43 + component: 'Input',
  44 + label: '目标值',
  45 + show: false,
  46 + },
  47 + {
  48 + field: FormFieldsEnum.TASK_TYPE,
  49 + component: 'Input',
  50 + label: '任务类型',
  51 + renderComponentContent: 'taskType',
  52 + show: false,
  53 + },
  54 + {
  55 + field: FormFieldsEnum.RUN_TARGET_TYPE,
  56 + component: 'RadioGroup',
  57 + label: '选择目标类型',
  58 + helpMessage: [
  59 + '您可以对该任务关联的所有设备批量执行任务,也可以指定其中的一个或多个关联的设备来执行任务。',
  60 + ],
  61 + defaultValue: TargetType.ALL,
  62 + componentProps: {
  63 + options: [
  64 + { label: TargetNameType.ALL, value: TargetType.ALL },
  65 + { label: TargetNameType.ASSIGN, value: TargetType.ASSIGN },
  66 + ],
  67 + },
  68 + },
  69 + {
  70 + field: FormFieldsEnum.ASSIGN_TARGET,
  71 + component: 'ApiSelect',
  72 + label: '制定目标设备',
  73 + ifShow: ({ model }) => model[FormFieldsEnum.RUN_TARGET_TYPE] === TargetType.ASSIGN,
  74 + componentProps: ({ formModel }) => {
  75 + const taskTargetType = formModel[FormFieldsEnum.TASK_TARGET_TYPE];
  76 + const isDevices = taskTargetType === TaskTargetEnum.DEVICES;
  77 + return {
  78 + api: async () => {
  79 + try {
  80 + if (isDevices) {
  81 + } else {
  82 + }
  83 + } catch (error) {
  84 + return [];
  85 + }
  86 + },
  87 + getPopupContainer: () => document.body,
  88 + };
  89 + },
  90 + },
  91 +];
  1 +export { default as RunTaskModal } from './index.vue';
  1 +<script lang="ts" setup>
  2 + import { ref } from 'vue';
  3 + import { TaskRecordType } from '/@/api/task/model';
  4 + import { BasicForm, useForm } from '/@/components/Form';
  5 + import { BasicModal, useModalInner } from '/@/components/Modal';
  6 + import { TaskTypeNameEnum } from '../../config';
  7 + import { formSchemas } from './config';
  8 +
  9 + defineEmits(['register']);
  10 +
  11 + const dataSource = ref<TaskRecordType>();
  12 +
  13 + const [registerModal] = useModalInner((record: TaskRecordType) => {
  14 + dataSource.value = record;
  15 + if (record) {
  16 + setFieldsValue(record);
  17 + }
  18 + });
  19 +
  20 + const [registerForm, { setFieldsValue }] = useForm({
  21 + schemas: formSchemas,
  22 + showActionButtonGroup: false,
  23 + });
  24 +</script>
  25 +
  26 +<template>
  27 + <BasicModal @register="registerModal" title="运行任务">
  28 + <BasicForm @register="registerForm">
  29 + <template #taskName>
  30 + <div class="font-semibold">
  31 + {{ dataSource?.name }}
  32 + </div>
  33 + </template>
  34 + <template #taskType>
  35 + <div class="font-semibold">
  36 + {{
  37 + dataSource ? TaskTypeNameEnum[dataSource.executeContent.type] : TaskTypeNameEnum.CUSTOM
  38 + }}
  39 + </div>
  40 + </template>
  41 + </BasicForm>
  42 + </BasicModal>
  43 +</template>
@@ -35,7 +35,7 @@ @@ -35,7 +35,7 @@
35 } 35 }
36 ); 36 );
37 37
38 - const emit = defineEmits(['edit']); 38 + const emit = defineEmits(['edit', 'runTask']);
39 39
40 const loading = ref(false); 40 const loading = ref(false);
41 41
@@ -117,6 +117,10 @@ @@ -117,6 +117,10 @@
117 if (!unref(getRecord).lastExecuteTime) return; 117 if (!unref(getRecord).lastExecuteTime) return;
118 return getTwoDateDiff(unref(getRecord).lastExecuteTime!); 118 return getTwoDateDiff(unref(getRecord).lastExecuteTime!);
119 }); 119 });
  120 +
  121 + const handleRunTask = () => {
  122 + emit('runTask', unref(getRecord));
  123 + };
120 </script> 124 </script>
121 125
122 <template> 126 <template>
@@ -186,7 +190,7 @@ @@ -186,7 +190,7 @@
186 </div> 190 </div>
187 </div> 191 </div>
188 <div class="mt-4 flex justify-between items-center gap-3"> 192 <div class="mt-4 flex justify-between items-center gap-3">
189 - <Button size="small"> 193 + <Button size="small" @click="handleRunTask">
190 <div class="text-xs px-1"> 194 <div class="text-xs px-1">
191 <PlayCircleOutlined class="mr-1" /> 195 <PlayCircleOutlined class="mr-1" />
192 <span>运行任务</span> 196 <span>运行任务</span>
@@ -16,8 +16,10 @@ @@ -16,8 +16,10 @@
16 import { ModalParamsType } from '/#/utils'; 16 import { ModalParamsType } from '/#/utils';
17 import { Authority } from '/@/components/Authority'; 17 import { Authority } from '/@/components/Authority';
18 import { getBoundingClientRect } from '/@/utils/domUtils'; 18 import { getBoundingClientRect } from '/@/utils/domUtils';
  19 + import { RunTaskModal } from './components/RunTaskModal';
19 20
20 const [registerModal, { openModal }] = useModal(); 21 const [registerModal, { openModal }] = useModal();
  22 + const [registerRunTaskModal, { openModal: openRunTaskModal }] = useModal();
21 23
22 const [registerForm, { getFieldsValue }] = useForm({ 24 const [registerForm, { getFieldsValue }] = useForm({
23 schemas: formSchemas, 25 schemas: formSchemas,
@@ -61,6 +63,10 @@ @@ -61,6 +63,10 @@
61 } as ModalParamsType); 63 } as ModalParamsType);
62 }; 64 };
63 65
  66 + const handleRunTask = (record: TaskRecordType) => {
  67 + openRunTaskModal(true, record);
  68 + };
  69 +
64 const reload = () => getDataSource(); 70 const reload = () => getDataSource();
65 71
66 const listElRef = ref<Nullable<ComponentElRef>>(null); 72 const listElRef = ref<Nullable<ComponentElRef>>(null);
@@ -71,7 +77,7 @@ @@ -71,7 +77,7 @@
71 // margin-top 24 height 24 77 // margin-top 24 height 24
72 const paginationHeight = 24 + 24 + 8; 78 const paginationHeight = 24 + 24 + 8;
73 // list pading top 8 maring-top 8 extra slot 56 79 // list pading top 8 maring-top 8 extra slot 56
74 - const listContainerMarginBottom = 8 + 8 + 56; 80 + const listContainerMarginBottom = 8 + 8 + 72;
75 const listContainerHeight = 81 const listContainerHeight =
76 clientHeight - rect.top - paginationHeight - listContainerMarginBottom; 82 clientHeight - rect.top - paginationHeight - listContainerMarginBottom;
77 const listContainerEl = (unref(listElRef)!.$el as HTMLElement).querySelector( 83 const listContainerEl = (unref(listElRef)!.$el as HTMLElement).querySelector(
@@ -90,7 +96,7 @@ @@ -90,7 +96,7 @@
90 </script> 96 </script>
91 97
92 <template> 98 <template>
93 - <PageWrapper class="container"> 99 + <PageWrapper class="task-center-container">
94 <section 100 <section
95 class="bg-light-50 flex p-4 justify-between items-center x dark:text-gray-300 dark:bg-dark-900" 101 class="bg-light-50 flex p-4 justify-between items-center x dark:text-gray-300 dark:bg-dark-900"
96 > 102 >
@@ -109,7 +115,7 @@ @@ -109,7 +115,7 @@
109 > 115 >
110 <BasicForm @register="registerForm" /> 116 <BasicForm @register="registerForm" />
111 </section> 117 </section>
112 - <section class="bg-light-50 mt-4 p-4 x dark:text-gray-300 dark:bg-dark-900"> 118 + <section class="bg-light-50 mt-4 p-4 dark:text-gray-300 dark:bg-dark-900">
113 <List 119 <List
114 ref="listElRef" 120 ref="listElRef"
115 :dataSource="dataSource" 121 :dataSource="dataSource"
@@ -118,8 +124,11 @@ @@ -118,8 +124,11 @@
118 :loading="loading" 124 :loading="loading"
119 > 125 >
120 <template #header> 126 <template #header>
121 - <section class="flex justify-end gap-4">  
122 - <Tooltip title="刷新"> 127 + <section class="flex justify-between gap-4 min-h-12 items-center">
  128 + <div>
  129 + <span class="text-lg font-medium">任务列表</span>
  130 + </div>
  131 + <Tooltip v-if="dataSource.length" title="刷新">
123 <Button type="primary" @click="getDataSource"> 132 <Button type="primary" @click="getDataSource">
124 <ReloadOutlined :spin="loading" /> 133 <ReloadOutlined :spin="loading" />
125 </Button> 134 </Button>
@@ -128,13 +137,24 @@ @@ -128,13 +137,24 @@
128 </template> 137 </template>
129 <template #renderItem="{ item }"> 138 <template #renderItem="{ item }">
130 <List.Item :key="item.id"> 139 <List.Item :key="item.id">
131 - <TaskCard :record="item" :reload="reload" @edit="handleEdit" /> 140 + <TaskCard :record="item" :reload="reload" @runTask="handleRunTask" @edit="handleEdit" />
132 </List.Item> 141 </List.Item>
133 </template> 142 </template>
134 </List> 143 </List>
135 </section> 144 </section>
136 <DetailModal @register="registerModal" :reload="reload" /> 145 <DetailModal @register="registerModal" :reload="reload" />
  146 + <RunTaskModal @register="registerRunTaskModal" />
137 </PageWrapper> 147 </PageWrapper>
138 </template> 148 </template>
139 149
140 -<style lang="less" scoped></style> 150 +<style lang="less" scoped>
  151 + .task-center-container {
  152 + :deep(.ant-list-header) {
  153 + border: none;
  154 + }
  155 +
  156 + :deep(.ant-card-body) {
  157 + padding: 16px 24px;
  158 + }
  159 + }
  160 +</style>