add 原因管理界面
This commit is contained in:
parent
ff112d066d
commit
eb3307594a
@ -8429,3 +8429,121 @@ export interface ResultOutputBagDtoGetOutput {
|
||||
message?: string | null
|
||||
data?: BagDto
|
||||
}
|
||||
|
||||
/** 撤销原因分页查询输入 */
|
||||
export interface PageInputRevokeReasonGetPageInput {
|
||||
dynamicFilter?: DynamicFilterInfo
|
||||
/** 排序列表 */
|
||||
sortList?: SortInput[] | null
|
||||
/**
|
||||
* 当前页标
|
||||
* @format int32
|
||||
*/
|
||||
currentPage?: number
|
||||
/**
|
||||
* 每页大小
|
||||
* @format int32
|
||||
*/
|
||||
pageSize?: number
|
||||
/** 分页请求 */
|
||||
filter?: RevokeReasonGetPageInput
|
||||
}
|
||||
|
||||
/** 撤销原因分页查询过滤条件 */
|
||||
export interface RevokeReasonGetPageInput {
|
||||
/** 原因描述 */
|
||||
revokeReason?: string | null
|
||||
/** 类型 */
|
||||
revokeType?: string | null
|
||||
/** 是否下发 */
|
||||
isDown?: boolean
|
||||
}
|
||||
|
||||
/** 撤销原因分页查询输出 */
|
||||
export interface RevokeReasonGetPageOutput {
|
||||
/**
|
||||
* 编号
|
||||
* @format int64
|
||||
*/
|
||||
id?: number
|
||||
/** 原因描述 */
|
||||
revokeReason?: string | null
|
||||
/** 类型 */
|
||||
revokeType?: string | null
|
||||
/** 是否下发 */
|
||||
isDown?: boolean
|
||||
/** 创建者 */
|
||||
createdUserName?: string | null
|
||||
/**
|
||||
* 创建时间
|
||||
* @format date-time
|
||||
*/
|
||||
createdTime?: string | null
|
||||
/**
|
||||
* 修改时间
|
||||
* @format date-time
|
||||
*/
|
||||
modifiedTime?: string | null
|
||||
}
|
||||
|
||||
export interface ResultOutputPageOutputRevokeReasonGetPageOutput {
|
||||
success?: boolean
|
||||
code?: string | null
|
||||
message?: string | null
|
||||
data?: PageOutputBagDtoGetPageOutput
|
||||
}
|
||||
|
||||
export interface PageOutputRevokeReasonGetPageOutput {
|
||||
list?: RevokeReasonGetPageOutput[] | null
|
||||
total?: number
|
||||
}
|
||||
|
||||
/** 撤销原因详情输出 */
|
||||
export interface RevokeReasonGetOutput {
|
||||
/** 原因描述 */
|
||||
revokeReason?: string | null
|
||||
/** 类型 */
|
||||
revokeType?: string | null
|
||||
/** 是否下发 */
|
||||
isDown?: boolean
|
||||
/**
|
||||
* 主键Id
|
||||
* @format int64
|
||||
*/
|
||||
id: number
|
||||
}
|
||||
|
||||
/** 撤销原因新增/更新输入 */
|
||||
export interface RevokeReasonDto {
|
||||
/** 原因描述 */
|
||||
keyWord?: string | null
|
||||
|
||||
revokeReason?: string | null
|
||||
/** 类型 */
|
||||
revokeType?: string | null
|
||||
/** 是否下发 */
|
||||
isDown?: boolean
|
||||
/**
|
||||
* 主键Id
|
||||
* @format int64
|
||||
*/
|
||||
id?: number
|
||||
}
|
||||
|
||||
/** 撤回类型枚举项 */
|
||||
export interface RevokeTypeEnumItem {
|
||||
/** 枚举值 */
|
||||
value: number
|
||||
/** 枚举名称 */
|
||||
name: string
|
||||
/** 显示名称/描述 */
|
||||
label: string
|
||||
}
|
||||
|
||||
/** 撤回类型枚举列表输出 */
|
||||
export interface RevokeTypeEnumListOutput {
|
||||
success?: boolean
|
||||
code?: string | null
|
||||
message?: string | null
|
||||
data?: RevokeTypeEnumItem[]
|
||||
}
|
||||
|
84
src/api/admin/revoke-reason.ts
Normal file
84
src/api/admin/revoke-reason.ts
Normal file
@ -0,0 +1,84 @@
|
||||
/* eslint-disable */
|
||||
/* tslint:disable */
|
||||
/*
|
||||
* ---------------------------------------------------------------
|
||||
* ## THIS FILE WAS GENERATED VIA SWAGGER-TYPESCRIPT-API ##
|
||||
* ## ##
|
||||
* ## AUTHOR: adademo / https://github.com/adademo/swagger-typescript-api ##
|
||||
* ## SOURCE: https://github.com/adademo/swagger-typescript-api ##
|
||||
* ---------------------------------------------------------------
|
||||
*/
|
||||
|
||||
import { PageInputRevokeReasonGetPageInput, RevokeReasonDto, RevokeReasonGetOutput,ResultOutputPageOutputRevokeReasonGetPageOutput, RevokeTypeEnumListOutput } from './data-contracts'
|
||||
import { RequestParams } from './http-client'
|
||||
import { ContentType, HttpClient } from './http-client'
|
||||
|
||||
export class RevokeReasonApi extends HttpClient {
|
||||
/**
|
||||
* 获取分页列表
|
||||
*/
|
||||
getPage = (data: PageInputRevokeReasonGetPageInput, params: RequestParams = {}) =>
|
||||
this.request<ResultOutputPageOutputRevokeReasonGetPageOutput>({
|
||||
path: `/api/admin/revoke-reason/get-page`,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
type: ContentType.Json,
|
||||
...params,
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取单条数据
|
||||
*/
|
||||
get = (params: { id: number }, requestParams: RequestParams = {}) =>
|
||||
this.request<RevokeReasonGetOutput>({
|
||||
path: `/api/admin/revoke-reason/get`,
|
||||
method: 'GET',
|
||||
query: params,
|
||||
...requestParams,
|
||||
})
|
||||
|
||||
/**
|
||||
* 新增
|
||||
*/
|
||||
add = (data: RevokeReasonDto, params: RequestParams = {}) =>
|
||||
this.request<any>({
|
||||
path: `/api/admin/revoke-reason/add`,
|
||||
method: 'POST',
|
||||
body: data,
|
||||
type: ContentType.Json,
|
||||
...params,
|
||||
})
|
||||
|
||||
/**
|
||||
* 更新
|
||||
*/
|
||||
update = (data: RevokeReasonDto, params: RequestParams = {}) =>
|
||||
this.request<any>({
|
||||
path: `/api/admin/revoke-reason/update`,
|
||||
method: 'PUT',
|
||||
body: data,
|
||||
type: ContentType.Json,
|
||||
...params,
|
||||
})
|
||||
|
||||
/**
|
||||
* 软删除
|
||||
*/
|
||||
softDelete = (params: { id: number }, requestParams: RequestParams = {}) =>
|
||||
this.request<any>({
|
||||
path: `/api/admin/revoke-reason/soft-delete`,
|
||||
method: 'DELETE',
|
||||
query: params,
|
||||
...requestParams,
|
||||
})
|
||||
|
||||
/**
|
||||
* 获取撤回类型枚举列表
|
||||
*/
|
||||
getRevokeTypeEnumList = (params: RequestParams = {}) =>
|
||||
this.request<RevokeTypeEnumListOutput>({
|
||||
path: `/api/admin/revoke-reason/get-revoke-type-enum-list`,
|
||||
method: 'GET',
|
||||
...params,
|
||||
})
|
||||
}
|
149
src/views/admin/uspreason/components/uspreason-form.vue
Normal file
149
src/views/admin/uspreason/components/uspreason-form.vue
Normal file
@ -0,0 +1,149 @@
|
||||
<template>
|
||||
<div class="uspreason-form">
|
||||
<el-dialog
|
||||
v-model="state.visible"
|
||||
destroy-on-close
|
||||
:title="title"
|
||||
draggable
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
width="600px"
|
||||
>
|
||||
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px" size="default">
|
||||
<div class="form-section">
|
||||
<el-row :gutter="25">
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
||||
<el-form-item label="原因类型" prop="revokeType">
|
||||
<el-select v-model="form.revokeType" placeholder="请选择原因类型" style="width: 100%">
|
||||
<el-option
|
||||
v-for="item in state.revokeTypeOptions"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
|
||||
<el-form-item label="原因描述" prop="revokeReason">
|
||||
<el-input
|
||||
v-model="form.revokeReason"
|
||||
type="textarea"
|
||||
:rows="3"
|
||||
placeholder="请输入原因描述"
|
||||
style="width: 100%"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<span class="dialog-footer">
|
||||
<el-button @click="onCancel" size="default">取 消</el-button>
|
||||
<el-button type="primary" @click="onSubmit" size="default" :loading="state.loading">确 定</el-button>
|
||||
</span>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, defineProps, defineExpose, onMounted } from 'vue'
|
||||
import { RevokeReasonApi } from '/@/api/admin/revoke-reason'
|
||||
import type { RevokeReasonDto, RevokeTypeEnumItem } from '/@/api/admin/data-contracts'
|
||||
import eventBus from '/@/utils/mitt'
|
||||
|
||||
const props = defineProps<{ title: string }>()
|
||||
const emit = defineEmits(['ok'])
|
||||
const formRef = ref()
|
||||
const state = reactive({
|
||||
visible: false,
|
||||
loading: false,
|
||||
revokeTypeOptions: [] as RevokeTypeEnumItem[]
|
||||
})
|
||||
|
||||
const form = reactive<RevokeReasonDto>({
|
||||
revokeReason: '',
|
||||
revokeType: '',
|
||||
isDown: false,
|
||||
id: 0
|
||||
})
|
||||
|
||||
const rules = {
|
||||
revokeReason: [{ required: true, message: '请输入原因描述', trigger: 'blur' }],
|
||||
revokeType: [{ required: true, message: '请选择类型', trigger: 'change' }]
|
||||
}
|
||||
|
||||
// 获取撤回类型枚举列表
|
||||
const getRevokeTypeOptions = async () => {
|
||||
try {
|
||||
const res = await new RevokeReasonApi().getRevokeTypeEnumList()
|
||||
if (res?.success && res.data) {
|
||||
state.revokeTypeOptions = res.data
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取撤回类型枚举列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
function open(row?: Partial<RevokeReasonDto>) {
|
||||
if (row) {
|
||||
Object.assign(form, row)
|
||||
} else {
|
||||
Object.assign(form, { revokeReason: '', revokeType: '', isDown: false, id: 0 })
|
||||
}
|
||||
state.visible = true
|
||||
}
|
||||
|
||||
function onCancel() {
|
||||
state.visible = false
|
||||
}
|
||||
|
||||
function onSubmit() {
|
||||
formRef.value.validate(async (valid: boolean) => {
|
||||
if (!valid) return
|
||||
state.loading = true
|
||||
try {
|
||||
if (form.id) {
|
||||
await new RevokeReasonApi().update(form)
|
||||
} else {
|
||||
await new RevokeReasonApi().add(form)
|
||||
}
|
||||
state.visible = false
|
||||
eventBus.emit('refreshUspReason')
|
||||
} finally {
|
||||
state.loading = false
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getRevokeTypeOptions()
|
||||
})
|
||||
|
||||
defineExpose({ open })
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.form-section {
|
||||
margin-bottom: 24px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 18px;
|
||||
}
|
||||
|
||||
:deep(.el-switch__label) {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
:deep(.el-textarea__inner) {
|
||||
resize: none;
|
||||
}
|
||||
</style>
|
257
src/views/admin/uspreason/index.vue
Normal file
257
src/views/admin/uspreason/index.vue
Normal file
@ -0,0 +1,257 @@
|
||||
<template>
|
||||
<my-layout>
|
||||
<el-card class="my-query-box mt8" shadow="never" :body-style="{ paddingBottom: '0' }">
|
||||
<el-form ref="queryForm" :model="queryParams" :inline="true" label-width="auto" :label-position="'left'" @submit.stop.prevent>
|
||||
<el-form-item label="原因描述" prop="revokeReason">
|
||||
<el-input v-model="queryParams.filter.keyWord" placeholder="请输入原因描述" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
<el-form-item label="原因类型" prop="revokeType">
|
||||
<el-select v-model="queryParams.filter.revokeType" placeholder="请选择原因类型" clearable style="width: 200px">
|
||||
<el-option v-for="item in revokeTypeOptions" :key="item.value" :label="item.label" :value="item.value" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间">
|
||||
<el-date-picker
|
||||
v-model="queryParams.filter.startTime"
|
||||
type="datetime"
|
||||
placeholder="选择开始时间"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 180px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间">
|
||||
<el-date-picker
|
||||
v-model="queryParams.filter.endTime"
|
||||
type="datetime"
|
||||
placeholder="选择结束时间"
|
||||
format="YYYY-MM-DD HH:mm:ss"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
style="width: 180px"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" icon="ele-Search" @click="handleQuery">查询</el-button>
|
||||
<el-button v-auth="'api:admin:revoke-reason:add'" type="primary" icon="ele-Plus" @click="handleAdd">新增</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<el-card class="my-fill mt8" shadow="never">
|
||||
<el-table v-loading="loading" :data="revokeReasonList" row-key="id" style="width: 100%" border>
|
||||
<el-table-column label="原因类型" min-width="120" show-overflow-tooltip>
|
||||
<template #default="{ row }">
|
||||
{{ getRevokeTypeName(row.revokeType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="revokeReason" label="原因描述" min-width="150" show-overflow-tooltip />
|
||||
<el-table-column label="操作" width="180" fixed="right" header-align="center" align="center">
|
||||
<template #default="{ row }">
|
||||
<el-button v-auth="'api:admin:revoke-reason:update'" icon="ele-EditPen" size="small" text type="primary" @click="handleEdit(row)">编辑</el-button>
|
||||
<el-button v-auth="'api:admin:revoke-reason:soft-delete'" icon="ele-Delete" size="small" text type="danger" @click="handleDelete(row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<div class="my-flex my-flex-end" style="margin-top: 10px">
|
||||
<el-pagination
|
||||
v-model:currentPage="queryParams.currentPage"
|
||||
v-model:page-size="queryParams.pageSize"
|
||||
:total="total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
size="small"
|
||||
background
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<uspreason-form ref="formRef" :title="state.formTitle" @ok="getList" />
|
||||
</my-layout>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted, onBeforeMount } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { RevokeReasonApi } from '/@/api/admin/revoke-reason'
|
||||
import eventBus from '/@/utils/mitt'
|
||||
import type {
|
||||
RevokeReasonGetPageOutput,
|
||||
RevokeTypeEnumItem,
|
||||
RevokeTypeEnumListOutput,
|
||||
PageOutputRevokeReasonGetPageOutput
|
||||
} from '/@/api/admin/data-contracts'
|
||||
import UspreasonForm from './components/uspreason-form.vue'
|
||||
import { number } from 'echarts'
|
||||
|
||||
const loading = ref(false)
|
||||
const showSearch = ref(true)
|
||||
const total = ref(0)
|
||||
const revokeReasonList = ref<RevokeReasonGetPageOutput[]>([])
|
||||
const revokeTypeOptions = ref<RevokeTypeEnumItem[]>([])
|
||||
const formRef = ref()
|
||||
const dateRange = ref<[string, string] | null>(null)
|
||||
|
||||
|
||||
const state = reactive({
|
||||
loading: false,
|
||||
formTitle: ''
|
||||
})
|
||||
|
||||
const queryParams = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
filter: {
|
||||
keyWord: '',
|
||||
revokeType: '',
|
||||
isDown: false,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
}
|
||||
})
|
||||
|
||||
/** 查询列表 */
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await new RevokeReasonApi().getPage(queryParams)
|
||||
console.log(res)
|
||||
revokeReasonList.value = res.data?.list || []
|
||||
total.value = res.data?.total || 0
|
||||
} catch (error) {
|
||||
console.error('获取列表失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 获取撤销类型枚举列表 */
|
||||
const getRevokeTypeOptions = async () => {
|
||||
try {
|
||||
const res = await new RevokeReasonApi().getRevokeTypeEnumList()
|
||||
revokeTypeOptions.value = res.data ?? []
|
||||
} catch (error) {
|
||||
console.error('获取撤销类型枚举列表失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const getRevokeTypeName = (revokeType: string) => {
|
||||
const item = revokeTypeOptions.value.find(item => item.value === Number(revokeType))
|
||||
return item?.label || ''
|
||||
}
|
||||
|
||||
/** 处理日期范围变化 */
|
||||
const handleDateRangeChange = (val: [string, string] | null) => {
|
||||
if (val) {
|
||||
queryParams.filter.startTime = val[0]
|
||||
queryParams.filter.endTime = val[1]
|
||||
} else {
|
||||
queryParams.filter.startTime = ''
|
||||
queryParams.filter.endTime = ''
|
||||
}
|
||||
}
|
||||
|
||||
/** 搜索按钮操作 */
|
||||
const handleQuery = () => {
|
||||
queryParams.currentPage = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 重置按钮操作 */
|
||||
const resetQuery = () => {
|
||||
queryParams.filter = {
|
||||
keyWord: '',
|
||||
revokeType: '',
|
||||
isDown: false,
|
||||
startTime: '',
|
||||
endTime: ''
|
||||
}
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
/** 新增按钮操作 */
|
||||
const handleAdd = () => {
|
||||
state.formTitle = '新增原因'
|
||||
formRef.value?.open()
|
||||
}
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleEdit = (row: RevokeReasonGetPageOutput) => {
|
||||
state.formTitle = '编辑原因'
|
||||
formRef.value?.open(row)
|
||||
}
|
||||
|
||||
/** 删除按钮操作 */
|
||||
const handleDelete = (row: RevokeReasonGetPageOutput) => {
|
||||
ElMessageBox.confirm('确认要删除该记录吗?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
const res = await new RevokeReasonApi().softDelete({ id: row.id! })
|
||||
if (res.success) {
|
||||
ElMessage.success('删除成功')
|
||||
getList()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('删除失败:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/** 每页条数改变 */
|
||||
const handleSizeChange = (val: number) => {
|
||||
queryParams.pageSize = val
|
||||
getList()
|
||||
}
|
||||
|
||||
/** 当前页改变 */
|
||||
const handleCurrentChange = (val: number) => {
|
||||
queryParams.currentPage = val
|
||||
getList()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getRevokeTypeOptions()
|
||||
getList()
|
||||
eventBus.on('refreshUspReason', getList)
|
||||
})
|
||||
|
||||
onBeforeMount(() => {
|
||||
eventBus.off('refreshUspReason')
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.my-query-box {
|
||||
:deep(.el-form-item) {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.my-fill {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.my-flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.my-flex-end {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.mt8 {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
142
页面开发指南.md
142
页面开发指南.md
@ -1,142 +0,0 @@
|
||||
# 页面开发指南
|
||||
|
||||
## 页面结构
|
||||
1. 列表页面
|
||||
- 搜索区域:关键词搜索
|
||||
- 操作按钮:新增、查询
|
||||
- 表格区域:基础字段展示
|
||||
- 分页区域:标准分页组件
|
||||
|
||||
2. 编辑页面
|
||||
- 基本信息模块
|
||||
- 网络配置模块
|
||||
- 设备配置模块
|
||||
|
||||
## 样式规范
|
||||
1. 对话框配置
|
||||
```html
|
||||
<el-dialog
|
||||
v-model="state.showDialog"
|
||||
destroy-on-close
|
||||
:title="title"
|
||||
draggable
|
||||
:close-on-click-modal="false"
|
||||
:close-on-press-escape="false"
|
||||
width="900px"
|
||||
>
|
||||
```
|
||||
|
||||
2. 表单布局
|
||||
```html
|
||||
<el-form :model="form" ref="formRef" size="default" label-width="120px">
|
||||
<div class="form-section">
|
||||
<div class="section-title">模块标题</div>
|
||||
<el-row :gutter="25">
|
||||
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
|
||||
<el-form-item label="字段名称" prop="fieldName">
|
||||
<el-input v-model="form.fieldName" clearable placeholder="请输入" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-form>
|
||||
```
|
||||
|
||||
3. 样式定义
|
||||
```scss
|
||||
.form-section {
|
||||
margin-bottom: 24px;
|
||||
&:last-child { margin-bottom: 0; }
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
color: #303133;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 2px solid #f0f0f0;
|
||||
position: relative;
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: -2px;
|
||||
width: 40px;
|
||||
height: 2px;
|
||||
background: #409eff;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 开发规范
|
||||
1. 组件命名
|
||||
- 目录:小写字母,用横线分隔
|
||||
- 组件:PascalCase
|
||||
- 组合函数:camelCase
|
||||
|
||||
2. 代码组织
|
||||
```typescript
|
||||
// 1. 导入声明
|
||||
import { reactive, ref } from 'vue'
|
||||
|
||||
// 2. 类型定义
|
||||
interface State {
|
||||
showDialog: boolean
|
||||
form: FormData
|
||||
}
|
||||
|
||||
// 3. 组件定义
|
||||
const props = defineProps({
|
||||
title: String
|
||||
})
|
||||
|
||||
// 4. 状态定义
|
||||
const state = reactive<State>({
|
||||
showDialog: false,
|
||||
form: {}
|
||||
})
|
||||
|
||||
// 5. 方法定义
|
||||
const handleSubmit = async () => {
|
||||
// 处理逻辑
|
||||
}
|
||||
```
|
||||
|
||||
3. 表单验证
|
||||
```typescript
|
||||
const rules = {
|
||||
fieldName: [
|
||||
{ required: true, message: '请输入', trigger: ['blur', 'change'] }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
4. API 调用
|
||||
```typescript
|
||||
const handleSave = async () => {
|
||||
try {
|
||||
const res = await api.save(state.form)
|
||||
if (res.success) {
|
||||
ElMessage.success('保存成功')
|
||||
emit('refresh')
|
||||
state.showDialog = false
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
1. 保持与 uspscale 页面风格一致
|
||||
2. 使用响应式布局适配不同屏幕
|
||||
3. 统一表单验证规则和错误提示
|
||||
4. 优化用户交互体验
|
||||
5. 保持代码风格统一
|
||||
6. 注意性能优化
|
||||
7. 遵循 TypeScript 类型规范
|
||||
|
||||
---
|
||||
|
||||
**注意**:此模板基于 Vue 3 + TypeScript + Element Plus + Pinia 技术栈,使用时请根据实际项目技术栈进行调整。
|
Loading…
x
Reference in New Issue
Block a user