322 lines
8.4 KiB
Vue
322 lines
8.4 KiB
Vue
<script setup lang="ts">
|
|
import type { CodegenOptions } from "@/api/system/codegen";
|
|
|
|
interface Props {
|
|
modelValue: CodegenOptions;
|
|
dataTypeOptions: Array<{ label: string; value: string }>;
|
|
tinyintTransTypeOptions: Array<{ label: string; value: string }>;
|
|
timeTransTypeOptions: Array<{ label: string; value: string }>;
|
|
nameCaseTypeOptions: Array<{ label: string; value: string }>;
|
|
}
|
|
|
|
interface Emits {
|
|
(e: "update:modelValue", value: CodegenOptions): void;
|
|
}
|
|
|
|
const props = defineProps<Props>();
|
|
const emits = defineEmits<Emits>();
|
|
|
|
const updateValue = (key: keyof CodegenOptions, value: any) => {
|
|
emits("update:modelValue", {
|
|
...props.modelValue,
|
|
[key]: value
|
|
});
|
|
};
|
|
|
|
// 配置分组
|
|
const basicConfig = [
|
|
{ key: "dataType", label: "解析引擎", type: "select", options: "dataTypeOptions" },
|
|
{ key: "authorName", label: "作者", type: "input" },
|
|
{ key: "packageName", label: "包名", type: "input" }
|
|
];
|
|
|
|
const returnConfig = [
|
|
{ key: "returnUtilSuccess", label: "成功返回", type: "input" },
|
|
{ key: "returnUtilFailure", label: "失败返回", type: "input" },
|
|
{ key: "ignorePrefix", label: "忽略前缀", type: "input" }
|
|
];
|
|
|
|
const typeConfig = [
|
|
{ key: "tinyintTransType", label: "TinyInt转换", type: "select", options: "tinyintTransTypeOptions" },
|
|
{ key: "timeTransType", label: "时间类型", type: "select", options: "timeTransTypeOptions" },
|
|
{ key: "nameCaseType", label: "命名类型", type: "select", options: "nameCaseTypeOptions" }
|
|
];
|
|
|
|
const switchConfig = [
|
|
{ key: "isPackageType", label: "包装类型" },
|
|
{ key: "isSwagger", label: "Swagger UI" },
|
|
{ key: "isComment", label: "字段注释" },
|
|
{ key: "isAutoImport", label: "自动引包" },
|
|
{ key: "isWithPackage", label: "带包路径" },
|
|
{ key: "isLombok", label: "Lombok" }
|
|
];
|
|
</script>
|
|
|
|
<template>
|
|
<div class="config-form">
|
|
<!-- 基础配置 -->
|
|
<div class="config-section">
|
|
<h4 class="section-title">基础配置</h4>
|
|
<div class="form-grid">
|
|
<el-form-item
|
|
v-for="config in basicConfig"
|
|
:key="config.key"
|
|
:label="config.label"
|
|
>
|
|
<el-select
|
|
v-if="config.type === 'select'"
|
|
:model-value="modelValue[config.key]"
|
|
class="w-full"
|
|
@update:model-value="(val) => updateValue(config.key, val)"
|
|
>
|
|
<el-option
|
|
v-for="option in props[config.options]"
|
|
:key="option.value"
|
|
:label="option.label"
|
|
:value="option.value"
|
|
/>
|
|
</el-select>
|
|
<el-input
|
|
v-else
|
|
:model-value="modelValue[config.key]"
|
|
@update:model-value="(val) => updateValue(config.key, val)"
|
|
/>
|
|
</el-form-item>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 返回值配置 -->
|
|
<div class="config-section">
|
|
<h4 class="section-title">返回值配置</h4>
|
|
<div class="form-grid">
|
|
<el-form-item
|
|
v-for="config in returnConfig"
|
|
:key="config.key"
|
|
:label="config.label"
|
|
>
|
|
<el-input
|
|
:model-value="modelValue[config.key]"
|
|
@update:model-value="(val) => updateValue(config.key, val)"
|
|
/>
|
|
</el-form-item>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 类型转换配置 -->
|
|
<div class="config-section">
|
|
<h4 class="section-title">类型转换</h4>
|
|
<div class="form-grid">
|
|
<el-form-item
|
|
v-for="config in typeConfig"
|
|
:key="config.key"
|
|
:label="config.label"
|
|
>
|
|
<el-select
|
|
:model-value="modelValue[config.key]"
|
|
class="w-full"
|
|
@update:model-value="(val) => updateValue(config.key, val)"
|
|
>
|
|
<el-option
|
|
v-for="option in props[config.options]"
|
|
:key="option.value"
|
|
:label="option.label"
|
|
:value="option.value"
|
|
/>
|
|
</el-select>
|
|
</el-form-item>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 开关配置 -->
|
|
<div class="config-section">
|
|
<h4 class="section-title">功能开关</h4>
|
|
<div class="switch-grid">
|
|
<el-form-item
|
|
v-for="config in switchConfig"
|
|
:key="config.key"
|
|
:label="config.label"
|
|
class="switch-item"
|
|
>
|
|
<el-switch
|
|
:model-value="modelValue[config.key]"
|
|
@update:model-value="(val) => updateValue(config.key, val)"
|
|
/>
|
|
</el-form-item>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped lang="scss">
|
|
.config-form {
|
|
.config-section {
|
|
margin-bottom: 24px;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.section-title {
|
|
position: relative;
|
|
font-size: 15px;
|
|
font-weight: 600;
|
|
color: var(--el-color-primary);
|
|
margin-bottom: 16px;
|
|
padding-left: 12px;
|
|
|
|
&::before {
|
|
content: '';
|
|
position: absolute;
|
|
left: 0;
|
|
top: 50%;
|
|
transform: translateY(-50%);
|
|
width: 4px;
|
|
height: 16px;
|
|
background: linear-gradient(135deg, var(--el-color-primary) 0%, var(--el-color-primary-light-3) 100%);
|
|
border-radius: 2px;
|
|
}
|
|
}
|
|
|
|
.form-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
|
gap: 16px;
|
|
|
|
:deep(.el-form-item) {
|
|
margin-bottom: 0;
|
|
background: var(--el-bg-color);
|
|
padding: 16px;
|
|
border-radius: 8px;
|
|
border: 1px solid var(--el-border-color-lighter);
|
|
transition: all 0.3s ease;
|
|
|
|
&:hover {
|
|
border-color: var(--el-color-primary-light-5);
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
|
transform: translateY(-1px);
|
|
}
|
|
|
|
.el-form-item__label {
|
|
font-weight: 500;
|
|
color: var(--el-text-color-primary);
|
|
margin-bottom: 8px;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.el-input, .el-select {
|
|
.el-input__wrapper {
|
|
border-radius: 8px;
|
|
transition: all 0.2s ease;
|
|
|
|
&:hover {
|
|
box-shadow: 0 0 0 1px var(--el-color-primary-light-7);
|
|
}
|
|
|
|
&.is-focus {
|
|
box-shadow: 0 0 0 1px var(--el-color-primary);
|
|
}
|
|
}
|
|
}
|
|
|
|
.el-select__wrapper {
|
|
border-radius: 8px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.switch-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
gap: 12px;
|
|
|
|
.switch-item {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 12px 16px;
|
|
background: linear-gradient(135deg, var(--el-bg-color) 0%, var(--el-bg-color-page) 100%);
|
|
border-radius: 8px;
|
|
border: 1px solid var(--el-border-color-lighter);
|
|
transition: all 0.3s ease;
|
|
position: relative;
|
|
overflow: hidden;
|
|
|
|
&::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
height: 3px;
|
|
background: linear-gradient(90deg, var(--el-color-primary-light-8) 0%, var(--el-color-primary-light-6) 100%);
|
|
transform: scaleX(0);
|
|
transform-origin: left;
|
|
transition: transform 0.3s ease;
|
|
}
|
|
|
|
&:hover {
|
|
border-color: var(--el-color-primary-light-5);
|
|
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
|
|
transform: translateY(-2px);
|
|
|
|
&::before {
|
|
transform: scaleX(1);
|
|
}
|
|
}
|
|
|
|
:deep(.el-form-item__label) {
|
|
margin-bottom: 0;
|
|
font-weight: 500;
|
|
color: var(--el-text-color-primary);
|
|
font-size: 14px;
|
|
}
|
|
|
|
:deep(.el-form-item__content) {
|
|
margin-left: 0;
|
|
}
|
|
|
|
:deep(.el-switch) {
|
|
.el-switch__core {
|
|
border-radius: 12px;
|
|
transition: all 0.2s ease;
|
|
|
|
&::after {
|
|
border-radius: 10px;
|
|
}
|
|
}
|
|
|
|
&.is-checked .el-switch__core {
|
|
background-color: var(--el-color-primary);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// 响应式设计
|
|
@media (max-width: 768px) {
|
|
.config-form {
|
|
.config-section {
|
|
.form-grid {
|
|
grid-template-columns: 1fr;
|
|
gap: 16px;
|
|
|
|
:deep(.el-form-item) {
|
|
padding: 12px;
|
|
}
|
|
}
|
|
|
|
.switch-grid {
|
|
grid-template-columns: 1fr;
|
|
gap: 10px;
|
|
|
|
.switch-item {
|
|
padding: 10px 14px;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
</style>
|