Commit 662125225a6a2c8f592a832948ba061eddb9ae2c

Authored by ww
1 parent eca2a637

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

... ... @@ -67,7 +67,7 @@
67 67 // margin-top 24 height 24
68 68 const paginationHeight = 24 + 24 + 8;
69 69 // list pading top 8 maring-top 8 extra slot 56
70   - const listContainerMarginBottom = 8 + 8 + 56;
  70 + const listContainerMarginBottom = 8 + 8 + 72;
71 71 const listContainerHeight =
72 72 clientHeight - rect.top - paginationHeight - listContainerMarginBottom;
73 73 const listContainerEl = (unref(listElRef)!.$el as HTMLElement).querySelector(
... ... @@ -86,7 +86,7 @@
86 86 </script>
87 87
88 88 <template>
89   - <PageWrapper class="bg-gray-100">
  89 + <PageWrapper class="bg-gray-100 device-task-list-container">
90 90 <section
91 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 101 :loading="loading"
102 102 >
103 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 108 <Tooltip title="刷新">
106 109 <Button type="primary" @click="getDataSource">
107 110 <ReloadOutlined :spin="loading" />
... ... @@ -123,3 +126,15 @@
123 126 </section>
124 127 </PageWrapper>
125 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 35 }
36 36 );
37 37
38   - const emit = defineEmits(['edit']);
  38 + const emit = defineEmits(['edit', 'runTask']);
39 39
40 40 const loading = ref(false);
41 41
... ... @@ -117,6 +117,10 @@
117 117 if (!unref(getRecord).lastExecuteTime) return;
118 118 return getTwoDateDiff(unref(getRecord).lastExecuteTime!);
119 119 });
  120 +
  121 + const handleRunTask = () => {
  122 + emit('runTask', unref(getRecord));
  123 + };
120 124 </script>
121 125
122 126 <template>
... ... @@ -186,7 +190,7 @@
186 190 </div>
187 191 </div>
188 192 <div class="mt-4 flex justify-between items-center gap-3">
189   - <Button size="small">
  193 + <Button size="small" @click="handleRunTask">
190 194 <div class="text-xs px-1">
191 195 <PlayCircleOutlined class="mr-1" />
192 196 <span>运行任务</span>
... ...
... ... @@ -16,8 +16,10 @@
16 16 import { ModalParamsType } from '/#/utils';
17 17 import { Authority } from '/@/components/Authority';
18 18 import { getBoundingClientRect } from '/@/utils/domUtils';
  19 + import { RunTaskModal } from './components/RunTaskModal';
19 20
20 21 const [registerModal, { openModal }] = useModal();
  22 + const [registerRunTaskModal, { openModal: openRunTaskModal }] = useModal();
21 23
22 24 const [registerForm, { getFieldsValue }] = useForm({
23 25 schemas: formSchemas,
... ... @@ -61,6 +63,10 @@
61 63 } as ModalParamsType);
62 64 };
63 65
  66 + const handleRunTask = (record: TaskRecordType) => {
  67 + openRunTaskModal(true, record);
  68 + };
  69 +
64 70 const reload = () => getDataSource();
65 71
66 72 const listElRef = ref<Nullable<ComponentElRef>>(null);
... ... @@ -71,7 +77,7 @@
71 77 // margin-top 24 height 24
72 78 const paginationHeight = 24 + 24 + 8;
73 79 // list pading top 8 maring-top 8 extra slot 56
74   - const listContainerMarginBottom = 8 + 8 + 56;
  80 + const listContainerMarginBottom = 8 + 8 + 72;
75 81 const listContainerHeight =
76 82 clientHeight - rect.top - paginationHeight - listContainerMarginBottom;
77 83 const listContainerEl = (unref(listElRef)!.$el as HTMLElement).querySelector(
... ... @@ -90,7 +96,7 @@
90 96 </script>
91 97
92 98 <template>
93   - <PageWrapper class="container">
  99 + <PageWrapper class="task-center-container">
94 100 <section
95 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 115 >
110 116 <BasicForm @register="registerForm" />
111 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 119 <List
114 120 ref="listElRef"
115 121 :dataSource="dataSource"
... ... @@ -118,8 +124,11 @@
118 124 :loading="loading"
119 125 >
120 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 132 <Button type="primary" @click="getDataSource">
124 133 <ReloadOutlined :spin="loading" />
125 134 </Button>
... ... @@ -128,13 +137,24 @@
128 137 </template>
129 138 <template #renderItem="{ item }">
130 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 141 </List.Item>
133 142 </template>
134 143 </List>
135 144 </section>
136 145 <DetailModal @register="registerModal" :reload="reload" />
  146 + <RunTaskModal @register="registerRunTaskModal" />
137 147 </PageWrapper>
138 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>
... ...