feat: 优化 GiForm(同步 GiDemo 更新)

This commit is contained in:
2025-02-27 22:44:04 +08:00
parent 15ae164eef
commit 47769f9ad8
32 changed files with 589 additions and 586 deletions

View File

@@ -9,7 +9,7 @@
@before-ok="save"
@close="reset"
>
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
<GiForm ref="formRef" v-model="form" :columns="columns" layout="vertical" />
</a-modal>
</template>
@@ -18,7 +18,7 @@ import { Message } from '@arco-design/web-vue'
import { useWindowSize } from '@vueuse/core'
import CryptoJS from 'crypto-js'
import { addClient, getClient, updateClient } from '@/apis/system/client'
import { type Columns, GiForm, type Options } from '@/components/GiForm'
import { type ColumnItem, GiForm } from '@/components/GiForm'
import { DisEnableStatusList } from '@/constant/common'
import { useResetReactive } from '@/hooks'
import { useDict } from '@/hooks/app'
@@ -36,12 +36,6 @@ const title = computed(() => (isUpdate.value ? '修改终端' : '新增终端'))
const formRef = ref<InstanceType<typeof GiForm>>()
const { client_type, auth_type_enum } = useDict('auth_type_enum', 'client_type')
const options: Options = {
form: { size: 'large', layout: 'vertical' },
btns: { hide: true },
grid: { cols: 2 },
}
const [form, resetForm] = useResetReactive({
activeTimeout: 1800,
timeout: 86400,
@@ -54,13 +48,13 @@ const handleGenerate = () => {
form.clientSecret = CryptoJS.MD5(`${timestamp}`).toString(CryptoJS.enc.Hex)
}
const columns: Columns = reactive([
const columns: ColumnItem[] = reactive([
{
label: '终端 Key',
field: 'clientKey',
type: 'input',
rules: [{ required: true, message: '请输入终端 Key' }],
span: 2,
span: 24,
disabled: () => {
return isUpdate.value
},
@@ -70,7 +64,7 @@ const columns: Columns = reactive([
field: 'clientSecret',
type: 'input',
rules: [{ required: true, message: '请输入终端秘钥' }],
span: 2,
span: 24,
disabled: () => {
return isUpdate.value
},
@@ -89,8 +83,8 @@ const columns: Columns = reactive([
label: '认证类型',
field: 'authType',
type: 'select',
options: auth_type_enum,
props: {
options: auth_type_enum,
multiple: true,
maxTagCount: 2,
},
@@ -100,7 +94,9 @@ const columns: Columns = reactive([
label: '终端类型',
field: 'clientType',
type: 'select',
options: client_type,
props: {
options: client_type,
},
rules: [{ required: true, message: '请选择终端类型' }],
},
{

View File

@@ -1,5 +1,5 @@
<template>
<a-drawer v-model:visible="visible" title="终端详情" :width="width >= 600 ? 600 : '100%'" :footer="false">
<a-drawer v-model:visible="visible" title="终端详情" :width="width >= 500 ? 500 : '100%'" :footer="false">
<a-descriptions :column="1" size="large" class="general-description">
<a-descriptions-item label="ID">{{ dataDetail?.id }}</a-descriptions-item>
<a-descriptions-item label="终端ID"><a-typography-paragraph :copyable="!!dataDetail?.clientId">{{ dataDetail?.clientId }}</a-typography-paragraph></a-descriptions-item>

View File

@@ -9,7 +9,7 @@
@before-ok="save"
@close="reset"
>
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
<GiForm ref="formRef" v-model="form" :columns="columns" />
</a-modal>
</template>
@@ -18,7 +18,7 @@ import { Message } from '@arco-design/web-vue'
import { useWindowSize } from '@vueuse/core'
import { mapTree } from 'xe-utils'
import { type DeptResp, addDept, getDept, updateDept } from '@/apis/system/dept'
import { type Columns, GiForm, type Options } from '@/components/GiForm'
import { type ColumnItem, GiForm } from '@/components/GiForm'
import { useResetReactive } from '@/hooks'
interface Props {
@@ -50,26 +50,19 @@ const deptSelectTree = computed(() => {
}))
})
const options: Options = {
form: { size: 'large' },
btns: { hide: true },
}
const [form, resetForm] = useResetReactive({
sort: 999,
status: 1,
})
const columns: Columns = reactive([
const columns: ColumnItem[] = reactive([
{
label: '上级部门',
field: 'parentId',
type: 'tree-select',
data: deptSelectTree,
hide: (form) => {
return form.parentId === 0
},
span: 24,
props: {
data: deptSelectTree,
allowClear: true,
allowSearch: true,
fallbackOption: false,
@@ -81,20 +74,25 @@ const columns: Columns = reactive([
},
},
rules: [{ required: true, message: '请选择上级部门' }],
hide: (form) => {
return form.parentId === 0
},
},
{
label: '名称',
field: 'name',
type: 'input',
rules: [{ required: true, message: '请输入名称' }],
span: 24,
props: {
maxLength: 30,
},
rules: [{ required: true, message: '请输入名称' }],
},
{
label: '排序',
field: 'sort',
type: 'input-number',
span: 24,
props: {
min: 1,
mode: 'button',
@@ -104,6 +102,7 @@ const columns: Columns = reactive([
label: '描述',
field: 'description',
type: 'textarea',
span: 24,
props: {
maxLength: 200,
autoSize: { minRows: 3, maxRows: 5 },
@@ -113,6 +112,7 @@ const columns: Columns = reactive([
label: '状态',
field: 'status',
type: 'switch',
span: 24,
props: {
type: 'round',
checkedValue: 1,

View File

@@ -9,7 +9,7 @@
@before-ok="save"
@close="reset"
>
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns">
<GiForm ref="formRef" v-model="form" :columns="columns">
<template #color>
<a-input v-model="form.color" placeholder="请选择或输入标签颜色" allow-clear>
<template #suffix>
@@ -25,7 +25,7 @@
import { Message } from '@arco-design/web-vue'
import { useWindowSize } from '@vueuse/core'
import { addDictItem, getDictItem, updateDictItem } from '@/apis/system/dict'
import { type Columns, GiForm, type Options } from '@/components/GiForm'
import { type ColumnItem, GiForm } from '@/components/GiForm'
import { useResetReactive } from '@/hooks'
const emit = defineEmits<{
@@ -41,25 +41,38 @@ const isUpdate = computed(() => !!dataId.value)
const title = computed(() => (isUpdate.value ? '修改字典项' : '新增字典项'))
const formRef = ref<InstanceType<typeof GiForm>>()
const options: Options = {
form: { size: 'large' },
btns: { hide: true },
}
const [form, resetForm] = useResetReactive({
color: 'blue',
sort: 999,
status: 1,
})
const columns: Columns = reactive([
{ label: '标签', field: 'label', type: 'input', rules: [{ required: true, message: '请输入标签' }] },
{ label: '值', field: 'value', type: 'input', rules: [{ required: true, message: '请输入值' }] },
{ label: '标签颜色', field: 'color', type: 'input' },
const columns: ColumnItem[] = reactive([
{
label: '标签',
field: 'label',
type: 'input',
span: 24,
rules: [{ required: true, message: '请输入标签' }],
},
{
label: '值',
field: 'value',
type: 'input',
span: 24,
rules: [{ required: true, message: '请输入值' }],
},
{
label: '标签颜色',
field: 'color',
type: 'input',
span: 24,
},
{
label: '排序',
field: 'sort',
type: 'input-number',
span: 24,
props: {
min: 1,
mode: 'button',
@@ -69,6 +82,7 @@ const columns: Columns = reactive([
label: '描述',
field: 'description',
type: 'textarea',
span: 24,
props: {
maxLength: 200,
autoSize: { minRows: 3, maxRows: 5 },
@@ -78,6 +92,7 @@ const columns: Columns = reactive([
label: '状态',
field: 'status',
type: 'switch',
span: 24,
props: {
type: 'round',
checkedValue: 1,

View File

@@ -9,7 +9,7 @@
@before-ok="save"
@close="reset"
>
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
<GiForm ref="formRef" v-model="form" :columns="columns" />
</a-modal>
</template>
@@ -17,7 +17,7 @@
import { Message } from '@arco-design/web-vue'
import { useWindowSize } from '@vueuse/core'
import { addDict, getDict, updateDict } from '@/apis/system/dict'
import { type Columns, GiForm, type Options } from '@/components/GiForm'
import { type ColumnItem, GiForm } from '@/components/GiForm'
import { useResetReactive } from '@/hooks'
const emit = defineEmits<{
@@ -32,20 +32,30 @@ const isUpdate = computed(() => !!dataId.value)
const title = computed(() => (isUpdate.value ? '修改字典' : '新增字典'))
const formRef = ref<InstanceType<typeof GiForm>>()
const options: Options = {
form: { size: 'large' },
btns: { hide: true },
}
const [form, resetForm] = useResetReactive({})
const columns: Columns = reactive([
{ label: '名称', field: 'name', type: 'input', rules: [{ required: true, message: '请输入名称' }] },
{ label: '编码', field: 'code', type: 'input', disabled: () => isUpdate.value, rules: [{ required: true, message: '请输入编码' }] },
const columns: ColumnItem[] = reactive([
{
label: '名称',
field: 'name',
type: 'input',
span: 24,
rules: [{ required: true, message: '请输入名称',
}],
},
{
label: '编码',
field: 'code',
type: 'input',
span: 24,
rules: [{ required: true, message: '请输入编码' }],
disabled: () => isUpdate.value,
},
{
label: '描述',
field: 'description',
type: 'textarea',
span: 24,
props: {
maxLength: 200,
autoSize: { minRows: 3, maxRows: 5 },

View File

@@ -18,7 +18,7 @@
</a-affix>
</div>
<div class="detail_content" style="display: flex; flex-direction: column;">
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns">
<GiForm ref="formRef" v-model="form" :columns="columns">
<template #noticeUsers>
<a-select
v-model="form.noticeUsers"
@@ -61,7 +61,7 @@ import { useWindowSize } from '@vueuse/core'
import AiEditor from './components/index.vue'
import { addNotice, getNotice, updateNotice } from '@/apis/system/notice'
import { listUserDict } from '@/apis'
import { type Columns, GiForm, type Options } from '@/components/GiForm'
import { type ColumnItem, GiForm } from '@/components/GiForm'
import type { LabelValueState } from '@/types/global'
import { useTabsStore } from '@/stores'
import { useResetReactive } from '@/hooks'
@@ -79,12 +79,6 @@ const containerRef = ref<HTMLElement | null>()
const formRef = ref<InstanceType<typeof GiForm>>()
const { notice_type } = useDict('notice_type')
const options: Options = {
form: { size: 'large' },
grid: { cols: 2 },
btns: { hide: true },
}
const [form, resetForm] = useResetReactive({
title: '',
type: '',
@@ -94,7 +88,7 @@ const [form, resetForm] = useResetReactive({
noticeScope: 1,
})
const columns: Columns = reactive([
const columns: ColumnItem[] = reactive([
{
label: '标题',
field: 'title',
@@ -109,7 +103,9 @@ const columns: Columns = reactive([
label: '类型',
field: 'type',
type: 'select',
options: notice_type,
props: {
options: notice_type,
},
rules: [{ required: true, message: '请输入类型' }],
},
{
@@ -132,7 +128,9 @@ const columns: Columns = reactive([
label: '通知范围',
field: 'noticeScope',
type: 'radio-group',
options: [{ label: '所有人', value: 1 }, { label: '指定用户', value: 2 }],
props: {
options: [{ label: '所有人', value: 1 }, { label: '指定用户', value: 2 }],
},
rules: [{ required: true, message: '请选择通知范围' }],
},
{

View File

@@ -4,7 +4,7 @@
:title="title"
:mask-closable="false"
:esc-to-close="false"
:width="width >= 600 ? 600 : '100%'"
:width="width >= 500 ? 500 : '100%'"
@before-ok="save"
@close="reset"
>

View File

@@ -4,7 +4,7 @@
:title="title"
:mask-closable="false"
:esc-to-close="false"
:width="width >= 600 ? 600 : '100%'"
:width="width >= 500 ? 500 : '100%'"
@before-ok="save"
@close="reset"
>

View File

@@ -4,11 +4,11 @@
:title="title"
:mask-closable="false"
:esc-to-close="false"
:width="width >= 600 ? 600 : '100%'"
:width="width >= 500 ? 500 : '100%'"
@before-ok="save"
@close="reset"
>
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
<GiForm ref="formRef" v-model="form" :columns="columns" />
</a-drawer>
</template>
@@ -16,7 +16,7 @@
import { Message, type TreeNodeData } from '@arco-design/web-vue'
import { useWindowSize } from '@vueuse/core'
import { addUser, getUser, updateUser } from '@/apis/system/user'
import { type Columns, GiForm, type Options } from '@/components/GiForm'
import { type ColumnItem, GiForm } from '@/components/GiForm'
import type { Gender, Status } from '@/types/global'
import { GenderList } from '@/constant/common'
import { useResetReactive } from '@/hooks'
@@ -37,21 +37,17 @@ const formRef = ref<InstanceType<typeof GiForm>>()
const { roleList, getRoleList } = useRole()
const { deptList, getDeptList } = useDept()
const options: Options = {
form: { size: 'large' },
btns: { hide: true },
}
const [form, resetForm] = useResetReactive({
gender: 1 as Gender,
status: 1 as Status,
})
const columns: Columns = reactive([
const columns: ColumnItem[] = reactive([
{
label: '用户名',
field: 'username',
type: 'input',
span: 24,
props: {
maxLength: 64,
showWordLimit: true,
@@ -62,6 +58,7 @@ const columns: Columns = reactive([
label: '昵称',
field: 'nickname',
type: 'input',
span: 24,
props: {
maxLength: 30,
showWordLimit: true,
@@ -72,6 +69,7 @@ const columns: Columns = reactive([
label: '密码',
field: 'password',
type: 'input-password',
span: 24,
props: {
maxLength: 32,
showWordLimit: true,
@@ -85,6 +83,7 @@ const columns: Columns = reactive([
label: '手机号码',
field: 'phone',
type: 'input',
span: 24,
props: {
maxLength: 11,
},
@@ -93,6 +92,7 @@ const columns: Columns = reactive([
label: '邮箱',
field: 'email',
type: 'input',
span: 24,
props: {
maxLength: 255,
},
@@ -101,14 +101,18 @@ const columns: Columns = reactive([
label: '性别',
field: 'gender',
type: 'radio-group',
options: GenderList,
span: 24,
props: {
options: GenderList,
},
},
{
label: '所属部门',
field: 'deptId',
type: 'tree-select',
data: deptList,
span: 24,
props: {
data: deptList,
allowClear: true,
allowSearch: true,
fallbackOption: false,
@@ -125,8 +129,9 @@ const columns: Columns = reactive([
label: '角色',
field: 'roleIds',
type: 'select',
options: roleList,
span: 24,
props: {
options: roleList,
multiple: true,
allowClear: true,
allowSearch: true,
@@ -137,6 +142,7 @@ const columns: Columns = reactive([
label: '描述',
field: 'description',
type: 'textarea',
span: 24,
props: {
maxLength: 200,
showWordLimit: true,
@@ -147,6 +153,7 @@ const columns: Columns = reactive([
label: '状态',
field: 'status',
type: 'switch',
span: 24,
props: {
type: 'round',
checkedValue: 1,

View File

@@ -1,5 +1,5 @@
<template>
<a-drawer v-model:visible="visible" title="用户详情" :width="width >= 600 ? 600 : '100%'" :footer="false">
<a-drawer v-model:visible="visible" title="用户详情" :width="width >= 500 ? 500 : '100%'" :footer="false">
<a-descriptions :column="2" size="large" class="general-description">
<a-descriptions-item label="ID" :span="2">
<a-typography-paragraph copyable>{{ dataDetail?.id }}</a-typography-paragraph>

View File

@@ -4,20 +4,20 @@
title="重置密码"
:mask-closable="false"
:esc-to-close="false"
:modal-style="{ maxWidth: '520px' }"
width="90%"
:width="width >= 500 ? 500 : '100%'"
draggable
@before-ok="save"
@close="reset"
>
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
<GiForm ref="formRef" v-model="form" :columns="columns" />
</a-modal>
</template>
<script setup lang="ts">
import { Message } from '@arco-design/web-vue'
import { useWindowSize } from '@vueuse/core'
import { resetUserPwd } from '@/apis/system'
import { type Columns, GiForm } from '@/components/GiForm'
import { type ColumnItem, GiForm } from '@/components/GiForm'
import { useResetReactive } from '@/hooks'
import { encryptByRsa } from '@/utils/encrypt'
@@ -25,19 +25,15 @@ const emit = defineEmits<{
(e: 'save-success'): void
}>()
const { width } = useWindowSize()
const dataId = ref('')
const visible = ref(false)
const formRef = ref<InstanceType<typeof GiForm>>()
const options: Options = {
form: { size: 'large' },
btns: { hide: true },
}
const [form, resetForm] = useResetReactive({})
const columns: Columns = reactive([
{ label: '密码', field: 'newPassword', type: 'input-password', rules: [{ required: true, message: '请输入密码' }] },
const columns: ColumnItem[] = reactive([
{ label: '密码', field: 'newPassword', type: 'input-password', span: 24, rules: [{ required: true, message: '请输入密码' }] },
])
// 重置

View File

@@ -4,12 +4,12 @@
title="分配角色"
:mask-closable="false"
:esc-to-close="false"
:width="width >= 600 ? 600 : '100%'"
:width="width >= 500 ? 500 : '100%'"
draggable
@before-ok="save"
@close="reset"
>
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
<GiForm ref="formRef" v-model="form" :columns="columns" />
</a-modal>
</template>
@@ -17,7 +17,7 @@
import { Message } from '@arco-design/web-vue'
import { useWindowSize } from '@vueuse/core'
import { getUser, updateUserRole } from '@/apis/system'
import { type Columns, GiForm, type Options } from '@/components/GiForm'
import { type ColumnItem, GiForm } from '@/components/GiForm'
import { useResetReactive } from '@/hooks'
import { useRole } from '@/hooks/app'
@@ -31,20 +31,16 @@ const visible = ref(false)
const formRef = ref<InstanceType<typeof GiForm>>()
const { roleList, getRoleList } = useRole()
const options: Options = {
form: { size: 'large' },
btns: { hide: true },
}
const [form, resetForm] = useResetReactive({})
const columns: Columns = reactive([
const columns: ColumnItem[] = reactive([
{
label: '角色',
field: 'roleIds',
type: 'select',
options: roleList,
span: 24,
props: {
options: roleList,
multiple: true,
allowClear: true,
allowSearch: { retainInputValue: true },

View File

@@ -1,10 +1,5 @@
<template>
<div class="gi_page">
<!-- <a-row justify="space-between" align="center" class="header page_header">
<a-space wrap>
<div class="title">用户管理</div>
</a-space>
</a-row> -->
<SplitPanel size="20%">
<template #left>
<DeptTree @node-click="handleSelectDept" />
@@ -22,7 +17,7 @@
@refresh="search"
>
<template #top>
<GiForm v-model="queryForm" :options="options" :columns="queryFormColumns" @search="search" @reset="reset"></GiForm>
<GiForm v-model="queryForm" search :columns="queryFormColumns" size="medium" @search="search" @reset="reset"></GiForm>
</template>
<template #toolbar-left>
<a-button v-permission="['system:user:add']" type="primary" @click="onAdd">
@@ -102,24 +97,19 @@ import UserDetailDrawer from './UserDetailDrawer.vue'
import UserResetPwdModal from './UserResetPwdModal.vue'
import UserUpdateRoleModal from './UserUpdateRoleModal.vue'
import { type UserResp, deleteUser, exportUser, listUser } from '@/apis/system/user'
import type { Columns, Options } from '@/components/GiForm'
import type { TableInstanceColumns } from '@/components/GiTable/type'
import { DisEnableStatusList } from '@/constant/common'
import { useDownload, useResetReactive, useTable } from '@/hooks'
import { isMobile } from '@/utils'
import has from '@/utils/has'
import type { ColumnItem } from '@/components/GiForm'
defineOptions({ name: 'SystemUser' })
const options: Options = reactive({
form: { layout: 'inline' },
grid: { cols: { xs: 1, sm: 1, md: 2, lg: 3, xl: 3, xxl: 3 } },
fold: { enable: true, index: 1, defaultCollapsed: true },
})
const [queryForm, resetForm] = useResetReactive({
sort: ['t1.id,desc'],
})
const queryFormColumns: Columns = reactive([
const queryFormColumns: ColumnItem[] = reactive([
{
type: 'input',
field: 'description',
@@ -133,18 +123,17 @@ const queryFormColumns: Columns = reactive([
{
type: 'select',
field: 'status',
options: DisEnableStatusList,
formItemProps: {
hideLabel: true,
},
props: {
options: DisEnableStatusList,
placeholder: '请选择状态',
},
},
{
type: 'range-picker',
field: 'createTime',
span: { lg: 2, xl: 2, xxl: 1 },
formItemProps: {
hideLabel: true,
},