2
0

完善任务管理

This commit is contained in:
lai
2024-12-26 16:07:04 +08:00
parent de19d9f400
commit f65cb5058e
11 changed files with 1381 additions and 123 deletions

View File

@@ -0,0 +1,150 @@
<script setup lang="ts">
import { reactive, watch, onBeforeMount } from 'vue';
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const emit = defineEmits(['update:value']);
const props = defineProps({
value: {
type: String,
default: '*',
},
});
/**指定列表初始数据 */
const optionsSpecific = Array.from({ length: 31 }, (_, i) => {
let idx = i + 1;
return {
label: `${idx}`,
value: `${idx}`,
};
});
/**数据 */
let data = reactive({
type: '1',
/**间隔 */
increment: 2,
incrementStart: 1,
/**周期 */
rangeStart: 1,
rangeEnd: 2,
/**指定 */
specific: ['1'],
});
/**监听数据,将数值格式化 */
watch(data, () => {
let reultValue = '*';
let val = data.type;
// 每一
if (val === '1') {
reultValue = '*';
}
// 间隔
if (val === '2') {
let start = data.incrementStart;
let increment = data.increment;
reultValue = `${start ?? 0}/${increment ?? 0}`;
}
// 周期
if (val === '3') {
let start = data.rangeStart;
let end = data.rangeEnd;
reultValue = `${start ?? 0}-${end ?? 0}`;
}
// 指定
if (val === '4') {
reultValue = data.specific.sort((a, b) => +a - +b).join(',');
}
emit('update:value', reultValue);
});
/**挂载前初始属性 */
onBeforeMount(() => {
const val = props.value;
if (val === '*') {
data.type = '1';
}
if (val.includes('/')) {
const arr = val.split('/');
data.incrementStart = Number(arr[0]);
data.increment = Number(arr[1]);
data.type = '2';
}
if (val.includes('-')) {
const arr = val.split('-');
data.rangeStart = Number(arr[0]);
data.rangeEnd = Number(arr[1]);
data.type = '3';
}
if (val.includes(',')) {
data.specific = val.split(',').sort((a, b) => +a - +b);
data.type = '4';
}
});
</script>
<template>
<a-radio-group size="small" v-model:value="data.type">
<a-space direction="vertical" :size="18">
<a-radio value="1">
{{ t('components.CronModal.day1') }}
</a-radio>
<a-radio value="2">
{{ t('components.CronModal.day21') }}
<a-input-number
size="small"
v-model:value="data.increment"
:min="1"
:max="31"
placeholder="1-31"
></a-input-number>
{{ t('components.CronModal.day22') }}
<a-input-number
size="small"
v-model:value="data.incrementStart"
:min="1"
:max="31"
placeholder="1-31"
></a-input-number>
{{ t('components.CronModal.day23') }}
</a-radio>
<a-radio value="3">
{{ t('components.CronModal.day31') }}
<a-input-number
size="small"
v-model:value="data.rangeStart"
:min="1"
:max="31"
placeholder="1-31"
></a-input-number>
{{ t('components.CronModal.day32') }}
<a-input-number
size="small"
v-model:value="data.rangeEnd"
:min="1"
:max="31"
placeholder="1-31"
></a-input-number>
{{ t('components.CronModal.day33') }}
</a-radio>
<a-radio value="4">
{{ t('components.CronModal.day4') }}
</a-radio>
<a-select
v-model:value="data.specific"
size="small"
mode="multiple"
style="width: 100%"
:placeholder="t('components.CronModal.day4')"
:options="optionsSpecific"
></a-select>
<a-radio value="5">
{{ t('components.CronModal.day5') }}
</a-radio>
</a-space>
</a-radio-group>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,144 @@
<script setup lang="ts">
import { reactive, watch, onBeforeMount } from 'vue';
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const emit = defineEmits(['update:value']);
const props = defineProps({
value: {
type: String,
default: '*',
},
});
/**指定列表初始数据 */
const optionsSpecific = Array.from({ length: 24 }, (_, i) => ({
label: `${i}`.padStart(2, '0'),
value: `${i}`,
}));
/**数据 */
let data = reactive({
type: '1',
/**间隔 */
increment: 2,
incrementStart: 0,
/**周期 */
rangeStart: 0,
rangeEnd: 2,
/**指定 */
specific: ['0'],
});
/**监听数据,将数值格式化 */
watch(data, () => {
let reultValue = '*';
let val = data.type;
// 每一
if (val === '1') {
reultValue = '*';
}
// 间隔
if (val === '2') {
let start = data.incrementStart;
let increment = data.increment;
reultValue = `${start ?? 0}/${increment ?? 0}`;
}
// 周期
if (val === '3') {
let start = data.rangeStart;
let end = data.rangeEnd;
reultValue = `${start ?? 0}-${end ?? 0}`;
}
// 指定
if (val === '4') {
reultValue = data.specific.sort((a, b) => +a - +b).join(',');
}
emit('update:value', reultValue);
});
/**挂载前初始属性 */
onBeforeMount(() => {
const val = props.value;
if (val === '*') {
data.type = '1';
}
if (val.includes('/')) {
const arr = val.split('/');
data.incrementStart = Number(arr[0]);
data.increment = Number(arr[1]);
data.type = '2';
}
if (val.includes('-')) {
const arr = val.split('-');
data.rangeStart = Number(arr[0]);
data.rangeEnd = Number(arr[1]);
data.type = '3';
}
if (val.includes(',')) {
data.specific = val.split(',').sort((a, b) => +a - +b);
data.type = '4';
}
});
</script>
<template>
<a-radio-group size="small" v-model:value="data.type">
<a-space direction="vertical" :size="18">
<a-radio value="1">
{{ t('components.CronModal.hour1') }}
</a-radio>
<a-radio value="2">
{{ t('components.CronModal.hour21') }}
<a-input-number
size="small"
v-model:value="data.increment"
:min="0"
:max="23"
placeholder="0-23"
></a-input-number>
{{ t('components.CronModal.hour22') }}
<a-input-number
size="small"
v-model:value="data.incrementStart"
:min="0"
:max="23"
placeholder="0-23"
></a-input-number>
{{ t('components.CronModal.hour23') }}
</a-radio>
<a-radio value="3">
{{ t('components.CronModal.hour31') }}
<a-input-number
size="small"
v-model:value="data.rangeStart"
:min="0"
:max="23"
placeholder="1-23"
></a-input-number>
{{ t('components.CronModal.hour32') }}
<a-input-number
size="small"
v-model:value="data.rangeEnd"
:min="0"
:max="23"
placeholder="0-23"
></a-input-number>
{{ t('components.CronModal.hour33') }}
</a-radio>
<a-radio value="4">
{{ t('components.CronModal.hour4') }}
</a-radio>
<a-select
v-model:value="data.specific"
size="small"
mode="multiple"
style="width: 100%"
:placeholder="t('components.CronModal.hour4')"
:options="optionsSpecific"
></a-select>
</a-space>
</a-radio-group>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,146 @@
<script setup lang="ts">
import { reactive, watch, onBeforeMount } from 'vue';
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const emit = defineEmits(['update:value']);
const props = defineProps({
value: {
type: String,
default: '*',
},
});
/**指定列表初始数据 */
const optionsSpecific = Array.from({ length: 60 }, (_, i) => {
return {
label: `${i}`.padStart(2, '0'),
value: `${i}`,
};
});
/**数据 */
let data = reactive({
type: '1',
/**间隔 */
increment: 1,
incrementStart: 0,
/**周期 */
rangeStart: 1,
rangeEnd: 2,
/**指定 */
specific: ['0'],
});
/**监听数据,将数值格式化 */
watch(data, () => {
let reultValue = '*';
let val = data.type;
// 每一
if (val === '1') {
reultValue = '*';
}
// 间隔
if (val === '2') {
let start = data.incrementStart;
let increment = data.increment;
reultValue = `${start ?? 0}/${increment ?? 0}`;
}
// 周期
if (val === '3') {
let start = data.rangeStart;
let end = data.rangeEnd;
reultValue = `${start ?? 0}-${end ?? 0}`;
}
// 指定
if (val === '4') {
reultValue = data.specific.sort((a, b) => +a - +b).join(',');
}
emit('update:value', reultValue);
});
/**挂载前初始属性 */
onBeforeMount(() => {
const val = props.value;
if (val === '*') {
data.type = '1';
}
if (val.includes('/')) {
const arr = val.split('/');
data.incrementStart = Number(arr[0]);
data.increment = Number(arr[1]);
data.type = '2';
}
if (val.includes('-')) {
const arr = val.split('-');
data.rangeStart = Number(arr[0]);
data.rangeEnd = Number(arr[1]);
data.type = '3';
}
if (val.includes(',')) {
data.specific = val.split(',').sort((a, b) => +a - +b);
data.type = '4';
}
});
</script>
<template>
<a-radio-group size="small" v-model:value="data.type">
<a-space direction="vertical" :size="18">
<a-radio value="1">
{{ t('components.CronModal.minute1') }}
</a-radio>
<a-radio value="2">
{{ t('components.CronModal.minute21') }}
<a-input-number
size="small"
v-model:value="data.increment"
:min="0"
:max="59"
placeholder="0-59"
></a-input-number>
{{ t('components.CronModal.minute22') }}
<a-input-number
size="small"
v-model:value="data.incrementStart"
:min="0"
:max="59"
placeholder="0-59"
></a-input-number>
{{ t('components.CronModal.minute23') }}
</a-radio>
<a-radio value="3">
{{ t('components.CronModal.minute31') }}
<a-input-number
size="small"
v-model:value="data.rangeStart"
:min="0"
:max="59"
placeholder="0-59"
></a-input-number>
{{ t('components.CronModal.minute32') }}
<a-input-number
size="small"
v-model:value="data.rangeEnd"
:min="0"
:max="59"
placeholder="0-59"
></a-input-number>
{{ t('components.CronModal.minute33') }}
</a-radio>
<a-radio value="4">
{{ t('components.CronModal.minute4') }}
</a-radio>
<a-select
v-model:value="data.specific"
size="small"
mode="multiple"
style="width: 100%"
:placeholder="t('components.CronModal.minute4')"
:options="optionsSpecific"
></a-select>
</a-space>
</a-radio-group>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,148 @@
<script setup lang="ts">
import { reactive, watch, onBeforeMount } from 'vue';
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const emit = defineEmits(['update:value']);
const props = defineProps({
value: {
type: String,
default: '*',
},
});
/**指定列表初始数据 */
const optionsSpecific = Array.from({ length: 12 }, (_, i) => {
let idx = i + 1;
return {
label: `${idx}`,
value: `${idx}`,
};
});
/**构建数据 */
let data = reactive({
/**类型 */
type: '1',
/**间隔 */
increment: 1,
incrementStart: 1,
/**周期 */
rangeStart: 1,
rangeEnd: 2,
/**指定秒 */
specific: ['1'],
});
/**监听数据,将数值格式化 */
watch(data, () => {
let reultValue = '*';
let val = data.type;
// 每一
if (val === '1') {
reultValue = '*';
}
// 间隔
if (val === '2') {
let start = data.incrementStart;
let increment = data.increment;
reultValue = `${start ?? 0}/${increment ?? 0}`;
}
// 周期
if (val === '3') {
let start = data.rangeStart;
let end = data.rangeEnd;
reultValue = `${start ?? 0}-${end ?? 0}`;
}
// 指定
if (val === '4') {
reultValue = data.specific.sort((a, b) => +a - +b).join(',');
}
emit('update:value', reultValue);
});
/**挂载前初始属性 */
onBeforeMount(() => {
const val = props.value;
if (val === '*') {
data.type = '1';
}
if (val.includes('/')) {
const arr = val.split('/');
data.incrementStart = Number(arr[0]);
data.increment = Number(arr[1]);
data.type = '2';
}
if (val.includes('-')) {
const arr = val.split('-');
data.rangeStart = Number(arr[0]);
data.rangeEnd = Number(arr[1]);
data.type = '3';
}
if (val.includes(',')) {
data.specific = val.split(',').sort((a, b) => +a - +b);
data.type = '4';
}
});
</script>
<template>
<a-radio-group size="small" v-model:value="data.type">
<a-space direction="vertical" :size="18">
<a-radio value="1">
{{ t('components.CronModal.month1') }}
</a-radio>
<a-radio value="2">
{{ t('components.CronModal.month21') }}
<a-input-number
size="small"
v-model:value="data.increment"
:min="1"
:max="12"
placeholder="1-12"
></a-input-number>
{{ t('components.CronModal.month22') }}
<a-input-number
size="small"
v-model:value="data.incrementStart"
:min="1"
:max="12"
placeholder="1-12"
></a-input-number>
{{ t('components.CronModal.month23') }}
</a-radio>
<a-radio value="3">
{{ t('components.CronModal.month31') }}
<a-input-number
size="small"
v-model:value="data.rangeStart"
:min="1"
:max="12"
placeholder="1-12"
></a-input-number>
{{ t('components.CronModal.month32') }}
<a-input-number
size="small"
v-model:value="data.rangeEnd"
:min="1"
:max="12"
placeholder="1-12"
></a-input-number>
{{ t('components.CronModal.month33') }}
</a-radio>
<a-radio value="4">
{{ t('components.CronModal.month4') }}
</a-radio>
<a-select
v-model:value="data.specific"
size="small"
mode="multiple"
style="width: 100%"
:placeholder="t('components.CronModal.month4')"
:options="optionsSpecific"
></a-select>
</a-space>
</a-radio-group>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,145 @@
<script setup lang="ts">
import { reactive, watch, onBeforeMount } from 'vue';
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const emit = defineEmits(['update:value']);
const props = defineProps({
value: {
type: String,
default: '*',
},
});
/**指定列表初始数据 */
const optionsSpecific = Array.from({ length: 60 }, (_, i) => ({
label: `${i}`.padStart(2, '0'),
value: `${i}`,
}));
/**构建数据 */
let data = reactive({
/**类型 */
type: '1',
/**间隔 */
increment: 2,
incrementStart: 0,
/**周期 */
rangeStart: 1,
rangeEnd: 2,
/**指定秒 */
specific: ['0'],
});
/**监听数据,将数值格式化 */
watch(data, () => {
let reultValue = '*';
let val = data.type;
// 每一
if (val === '1') {
reultValue = '*';
}
// 间隔
if (val === '2') {
let start = data.incrementStart;
let increment = data.increment;
reultValue = `${start ?? 0}/${increment ?? 0}`;
}
// 周期
if (val === '3') {
let start = data.rangeStart;
let end = data.rangeEnd;
reultValue = `${start ?? 0}-${end ?? 0}`;
}
// 指定
if (val === '4') {
reultValue = data.specific.sort((a, b) => +a - +b).join(',');
}
emit('update:value', reultValue);
});
/**挂载前初始属性 */
onBeforeMount(() => {
const val = props.value;
if (val === '*') {
data.type = '1';
}
if (val.includes('/')) {
const arr = val.split('/');
data.incrementStart = Number(arr[0]);
data.increment = Number(arr[1]);
data.type = '2';
}
if (val.includes('-')) {
const arr = val.split('-');
data.rangeStart = Number(arr[0]);
data.rangeEnd = Number(arr[1]);
data.type = '3';
}
if (val.includes(',')) {
data.specific = val.split(',').sort((a, b) => +a - +b);
data.type = '4';
}
});
</script>
<template>
<a-radio-group size="small" v-model:value="data.type">
<a-space direction="vertical" :size="18">
<a-radio value="1">
{{ t('components.CronModal.second1') }}
</a-radio>
<a-radio value="2">
{{ t('components.CronModal.second21') }}
<a-input-number
size="small"
v-model:value="data.increment"
:min="0"
:max="59"
placeholder="0-59"
></a-input-number>
{{ t('components.CronModal.second22') }}
<a-input-number
size="small"
v-model:value="data.incrementStart"
:min="0"
:max="59"
placeholder="0-59"
></a-input-number>
{{ t('components.CronModal.second23') }}
</a-radio>
<a-radio value="3">
{{ t('components.CronModal.second31') }}
<a-input-number
size="small"
v-model:value="data.rangeStart"
:min="0"
:max="59"
placeholder="0-59"
></a-input-number>
{{ t('components.CronModal.second32') }}
<a-input-number
size="small"
v-model:value="data.rangeEnd"
:min="0"
:max="59"
placeholder="0-59"
></a-input-number>
{{ t('components.CronModal.second33') }}
</a-radio>
<a-radio value="4">
{{ t('components.CronModal.second4') }}
</a-radio>
<a-select
v-model:value="data.specific"
size="small"
mode="multiple"
style="width: 100%"
:placeholder="t('components.CronModal.second4')"
:options="optionsSpecific"
></a-select>
</a-space>
</a-radio-group>
</template>
<style lang="scss" scoped></style>

View File

@@ -0,0 +1,114 @@
<template>
<a-modal
:destroyOnClose="true"
:title="t('components.CronModal.title')"
:open="props.open"
:body-style="{ padding: '0 24px' }"
@cancel="fnCronModal(false)"
@ok="fnCronModal(true)"
>
<a-tabs tab-position="top" type="line">
<a-tab-pane key="1" :tab="t('common.units.second')">
<CronSecond v-model:value="cronValue.second"></CronSecond>
</a-tab-pane>
<a-tab-pane key="2" :tab="t('common.units.minute')">
<CronMinute v-model:value="cronValue.minute"></CronMinute>
</a-tab-pane>
<a-tab-pane key="3" :tab="t('common.units.hour')">
<CronHour v-model:value="cronValue.hour"></CronHour>
</a-tab-pane>
<a-tab-pane key="4" :tab="t('common.units.day')">
<CronDay v-model:value="cronValue.day"></CronDay>
</a-tab-pane>
<a-tab-pane key="5" :tab="t('common.units.month')">
<CronMonth v-model:value="cronValue.month"></CronMonth>
</a-tab-pane>
</a-tabs>
<a-input
class="reultBox"
:addon-before="t('components.CronModal.addon')"
v-model:value="cronStr"
disabled
/>
</a-modal>
</template>
<script lang="ts" setup>
import CronSecond from './components/Second.vue';
import CronMinute from './components/Minute.vue';
import CronHour from './components/Hour.vue';
import CronDay from './components/Day.vue';
import CronMonth from './components/Month.vue';
import { reactive, computed, watch } from 'vue';
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const emit = defineEmits(['cancel', 'ok', 'update:open']);
const props = defineProps({
open: {
type: Boolean,
required: true,
},
cron: {
type: String,
default: '* * * * * ?',
},
});
/**cron属性值 */
let cronValue = reactive({
second: '*',
minute: '*',
hour: '*',
day: '*',
month: '*',
week: '?',
});
/**组合cron结果 */
const cronStr = computed(() => {
let time = `${cronValue.second} ${cronValue.minute} ${cronValue.hour}`;
let date = `${cronValue.day} ${cronValue.month} ${cronValue.week}`;
return `${time} ${date}`;
});
/**监听是否显示初始cron属性 */
watch(
() => props.open,
val => {
if (!val) return;
const arr = props.cron.split(' ');
// 6 位以上是合法表达式
if (arr.length >= 6) {
Object.assign(cronValue, {
second: arr[0],
minute: arr[1],
hour: arr[2],
day: arr[3],
month: arr[4],
week: arr[5],
});
}
}
);
/**
* 窗口事件
* @param val modal触发事件
*/
function fnCronModal(val: boolean) {
emit('update:open', false);
if (val) {
emit('ok', cronStr.value);
} else {
emit('cancel');
}
}
</script>
<style lang="scss" scoped>
.reultBox {
margin-top: 48px;
margin-bottom: 24px;
}
</style>

View File

@@ -50,7 +50,7 @@ function handleExport() {
<div class="flex flex-wrap justify-end gap-x-12px gap-y-8px lt-sm:(w-200px py-12px)">
<slot name="prefix"></slot>
<slot name="default">
<AButton v-if="isShowBtn(`system:${tableType}:add`)" size="small" ghost type="primary" @click="add">
<AButton v-if="isShowBtn(`system:${tableType}:add`) && !notShowAdd" size="small" ghost type="primary" @click="add">
<div class="flex-y-center gap-8px">
<icon-ic-round-plus class="text-icon" />
<span>{{ $t('common.add') }}</span>