feat(projects): 新增项目、执行、任务等功能

This commit is contained in:
2026-05-09 11:30:34 +08:00
parent f4f43814b3
commit 824392b564
106 changed files with 13060 additions and 1049 deletions

View File

@@ -167,24 +167,25 @@ watch(visible, value => {
<BusinessFormDialog
v-model="visible"
:title="title"
preset="md"
preset="sm"
:loading="detailLoading"
:confirm-loading="submitting"
:scrollbar="false"
@confirm="handleSubmit"
>
<ElForm ref="formRef" :model="model" :rules="rules" label-position="top">
<ElRow :gutter="16">
<ElCol :span="12">
<ElCol :span="24">
<ElFormItem :label="$t('page.system.role.roleName')" prop="name">
<ElInput v-model="model.name" :placeholder="$t('page.system.role.form.roleName')" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElCol :span="24">
<ElFormItem :label="$t('page.system.role.roleCode')" prop="code">
<ElInput v-model="model.code" :placeholder="$t('page.system.role.form.roleCode')" />
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElCol :span="24">
<ElFormItem :label="$t('page.system.role.sort')" prop="sort">
<ElInputNumber
v-model="model.sort"
@@ -194,7 +195,7 @@ watch(visible, value => {
/>
</ElFormItem>
</ElCol>
<ElCol :span="12">
<ElCol :span="24">
<ElFormItem :label="$t('page.system.role.roleStatus')" prop="status">
<ElRadioGroup v-model="model.status" class="business-form-radio-group">
<ElRadio v-for="{ label, value } in commonStatusOptions" :key="value" :value="value">

View File

@@ -1,7 +1,7 @@
<script setup lang="ts">
import { computed } from 'vue';
import { computed, reactive, watch } from 'vue';
import { commonStatusOptions } from '@/constants/business';
import TableSearchPanel from '@/components/custom/table-search-panel.vue';
import TableSearchFields, { type SearchField } from '@/components/custom/table-search-fields.vue';
import { $t } from '@/locales';
defineOptions({ name: 'RoleSearch' });
@@ -15,17 +15,61 @@ const emit = defineEmits<Emits>();
const model = defineModel<Api.SystemManage.RoleSearchParams>('model', { required: true });
const keyword = computed({
get() {
return model.value.name ?? model.value.code ?? '';
},
set(value: string) {
const text = value.trim() || undefined;
model.value.name = text;
model.value.code = text;
}
const searchModel = reactive<{
keyword: string;
status?: Api.SystemManage.CommonStatus;
}>({
keyword: '',
status: undefined
});
let syncingFromSource = false;
watch(
() => [model.value.name, model.value.code, model.value.status] as const,
([name, code, status]) => {
syncingFromSource = true;
searchModel.keyword = name ?? code ?? '';
searchModel.status = status;
syncingFromSource = false;
},
{ immediate: true, flush: 'sync' }
);
watch(
() => [searchModel.keyword, searchModel.status] as const,
([keywordValue, status]) => {
if (syncingFromSource) {
return;
}
const keywordText = keywordValue.trim() || undefined;
model.value.name = keywordText;
model.value.code = keywordText;
model.value.status = status;
},
{ flush: 'sync' }
);
const fields = computed<SearchField[]>(() => [
{
key: 'keyword',
label: $t('page.system.role.searchKeyword'),
type: 'input',
placeholder: $t('page.system.role.searchPlaceholder')
},
{
key: 'status',
label: $t('page.system.role.roleStatus'),
type: 'select',
placeholder: $t('page.system.role.form.roleStatus'),
options: commonStatusOptions.map(item => ({
label: $t(item.label),
value: item.value
}))
}
]);
function reset() {
emit('reset');
}
@@ -36,20 +80,7 @@ function search() {
</script>
<template>
<TableSearchPanel :model="model" :action-col-lg="8" @reset="reset" @search="search">
<ElCol :lg="8" :md="12" :sm="12">
<ElFormItem :label="$t('page.system.role.searchKeyword')" prop="name">
<ElInput v-model="keyword" clearable :placeholder="$t('page.system.role.searchPlaceholder')" />
</ElFormItem>
</ElCol>
<ElCol :lg="8" :md="12" :sm="12">
<ElFormItem :label="$t('page.system.role.roleStatus')" prop="status">
<ElSelect v-model="model.status" clearable :placeholder="$t('page.system.role.form.roleStatus')">
<ElOption v-for="{ label, value } in commonStatusOptions" :key="value" :label="$t(label)" :value="value" />
</ElSelect>
</ElFormItem>
</ElCol>
</TableSearchPanel>
<TableSearchFields v-model="searchModel" :fields="fields" :columns="3" @reset="reset" @search="search" />
</template>
<style scoped></style>