mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-12-18 05:19:19 +08:00
feat: demo 增加编辑
This commit is contained in:
parent
9a0c83aa7e
commit
80fb98e20c
16 changed files with 139 additions and 109 deletions
|
|
@ -2,6 +2,7 @@ package v1
|
|||
|
||||
import (
|
||||
"github.com/pkg/errors"
|
||||
"strconv"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/app/api/v1/helper"
|
||||
"github.com/1Panel-dev/1Panel/app/dto"
|
||||
|
|
@ -125,7 +126,8 @@ func (b *BaseApi) UpdateUser(c *gin.Context) {
|
|||
|
||||
upMap := make(map[string]interface{})
|
||||
upMap["email"] = req.Email
|
||||
if err := userService.Update(upMap); err != nil {
|
||||
upMap["name"] = req.Name
|
||||
if err := userService.Update(req.ID, upMap); err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
}
|
||||
|
|
@ -133,13 +135,14 @@ func (b *BaseApi) UpdateUser(c *gin.Context) {
|
|||
}
|
||||
|
||||
func (b *BaseApi) GetUserInfo(c *gin.Context) {
|
||||
name, ok := c.Params.Get("name")
|
||||
idParam, ok := c.Params.Get("id")
|
||||
if !ok {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error name"))
|
||||
return
|
||||
}
|
||||
intNum, _ := strconv.Atoi(idParam)
|
||||
|
||||
user, err := userService.Get(name)
|
||||
user, err := userService.Get(uint(intNum))
|
||||
if err != nil {
|
||||
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ type CaptchaResponse struct {
|
|||
}
|
||||
|
||||
type UserUpdate struct {
|
||||
ID uint `json:"id" validate:"required"`
|
||||
Name string `json:"name" validate:"required"`
|
||||
Email string `json:"email" validate:"required,email"`
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ type IUserRepo interface {
|
|||
GetList(opts ...DBOption) ([]model.User, error)
|
||||
Page(limit, offset int, opts ...DBOption) (int64, []model.User, error)
|
||||
Create(user *model.User) error
|
||||
Update(vars map[string]interface{}) error
|
||||
Update(id uint, vars map[string]interface{}) error
|
||||
Save(user model.User) error
|
||||
Delete(opts ...DBOption) error
|
||||
}
|
||||
|
|
@ -57,8 +57,8 @@ func (u *UserRepo) Create(user *model.User) error {
|
|||
return global.DB.Create(user).Error
|
||||
}
|
||||
|
||||
func (u *UserRepo) Update(vars map[string]interface{}) error {
|
||||
return global.DB.Model(&model.User{}).Updates(vars).Error
|
||||
func (u *UserRepo) Update(id uint, vars map[string]interface{}) error {
|
||||
return global.DB.Model(&model.User{}).Where("id = ?", id).Updates(vars).Error
|
||||
}
|
||||
|
||||
func (u *UserRepo) Save(user model.User) error {
|
||||
|
|
|
|||
|
|
@ -17,22 +17,22 @@ import (
|
|||
type UserService struct{}
|
||||
|
||||
type IUserService interface {
|
||||
Get(name string) (*dto.UserBack, error)
|
||||
Get(name uint) (*dto.UserBack, error)
|
||||
Page(search dto.UserPage) (int64, interface{}, error)
|
||||
Register(userDto dto.UserCreate) error
|
||||
Login(c *gin.Context, info dto.Login) (*dto.UserLoginInfo, error)
|
||||
LogOut(c *gin.Context) error
|
||||
Delete(name string) error
|
||||
Save(req model.User) error
|
||||
Update(upMap map[string]interface{}) error
|
||||
Update(id uint, upMap map[string]interface{}) error
|
||||
}
|
||||
|
||||
func NewIUserService() IUserService {
|
||||
return &UserService{}
|
||||
}
|
||||
|
||||
func (u *UserService) Get(name string) (*dto.UserBack, error) {
|
||||
user, err := userRepo.Get(commonRepo.WithByName(name))
|
||||
func (u *UserService) Get(id uint) (*dto.UserBack, error) {
|
||||
user, err := userRepo.Get(commonRepo.WithByID(id))
|
||||
if err != nil {
|
||||
return nil, constant.ErrRecordNotFound
|
||||
}
|
||||
|
|
@ -136,6 +136,6 @@ func (u *UserService) Save(req model.User) error {
|
|||
return userRepo.Save(req)
|
||||
}
|
||||
|
||||
func (u *UserService) Update(upMap map[string]interface{}) error {
|
||||
return userRepo.Update(upMap)
|
||||
func (u *UserService) Update(id uint, upMap map[string]interface{}) error {
|
||||
return userRepo.Update(id, upMap)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ func (s *UserRouter) InitUserRouter(Router *gin.RouterGroup) {
|
|||
withRecordRouter.POST("", baseApi.Register)
|
||||
withRecordRouter.DELETE("", baseApi.DeleteUser)
|
||||
userRouter.POST("/search", baseApi.PageUsers)
|
||||
userRouter.GET(":name", baseApi.GetUserInfo)
|
||||
userRouter.GET(":id", baseApi.GetUserInfo)
|
||||
userRouter.POST(":id", baseApi.UpdateUser)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,9 @@ import { CommonModel, ReqPage } from '.';
|
|||
|
||||
export namespace User {
|
||||
export interface User extends CommonModel {
|
||||
username: string;
|
||||
name: string;
|
||||
email: string;
|
||||
password: string;
|
||||
}
|
||||
export interface UserCreate {
|
||||
username: string;
|
||||
|
|
@ -11,7 +12,7 @@ export namespace User {
|
|||
}
|
||||
|
||||
export interface ReqGetUserParams extends ReqPage {
|
||||
username?: string;
|
||||
name?: string;
|
||||
email?: string;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,52 +13,19 @@ export const getUserList = (params: User.ReqGetUserParams) => {
|
|||
};
|
||||
|
||||
// * 新增用户
|
||||
export const addUser = (params: User.UserCreate) => {
|
||||
return http.post(`/users/add`, params);
|
||||
export const addUser = (params: User.User) => {
|
||||
return http.post(`/users`, params);
|
||||
};
|
||||
|
||||
export const getUserById = (id: string) => {
|
||||
return http.get(`/users/detail/${id}`);
|
||||
export const getUserById = (id: number) => {
|
||||
return http.get<User.User>(`/users/${id}`);
|
||||
};
|
||||
// // * 批量添加用户
|
||||
// export const BatchAddUser = (params: FormData) => {
|
||||
// return http.post(`/users/import`, params);
|
||||
// };
|
||||
|
||||
// * 编辑用户
|
||||
export const editUser = (params: User.User) => {
|
||||
return http.post(`/users/edit`, params);
|
||||
return http.post(`/users/` + params.id, params);
|
||||
};
|
||||
|
||||
// * 批量删除用户
|
||||
export const deleteUser = (params: { ids: number[] }) => {
|
||||
return http.post(`/users/delete`, params);
|
||||
};
|
||||
|
||||
// * 切换用户状态
|
||||
// export const changeUserStatus = (params: { id: string; status: number }) => {
|
||||
// return http.post(`/users/change`, params);
|
||||
|
||||
// };
|
||||
|
||||
// // * 重置用户密码
|
||||
// export const resetUserPassWord = (params: { id: string }) => {
|
||||
// return http.post(`/users/rest_password`, params);
|
||||
// };
|
||||
|
||||
// // * 导出用户数据
|
||||
// export const exportUserInfo = (params: User.ReqGetUserParams) => {
|
||||
// return http.post<BlobPart>(`/user/export`, params, {
|
||||
// responseType: 'blob',
|
||||
// });
|
||||
// };
|
||||
|
||||
// // * 获取用户状态
|
||||
// export const getUserStatus = () => {
|
||||
// return http.get<User.ResStatus>(`/user/status`);
|
||||
// };
|
||||
|
||||
// // * 获取用户性别字典
|
||||
// export const getUserGender = () => {
|
||||
// return http.get<User.ResGender>(`/user/gender`);
|
||||
// };
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { FormItemRule } from 'element-plus';
|
|||
interface CommonRule {
|
||||
required: FormItemRule;
|
||||
name: FormItemRule;
|
||||
email: FormItemRule;
|
||||
}
|
||||
|
||||
export const Rules: CommonRule = {
|
||||
|
|
@ -20,4 +21,9 @@ export const Rules: CommonRule = {
|
|||
trigger: 'blur',
|
||||
pattern: '/^[a-zA-Z0-9\u4e00-\u9fa5]{1}[a-zA-Z0-9_.\u4e00-\u9fa5-]{0,30}$/',
|
||||
},
|
||||
email: {
|
||||
type: 'email',
|
||||
message: i18n.global.t('commons.rule.email'),
|
||||
trigger: 'blur',
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -22,6 +22,12 @@ export default {
|
|||
deleteSuccess: 'Delete Success',
|
||||
loginSuccess: 'Login Success',
|
||||
requestTimeout: 'The request timed out, please try again later',
|
||||
deleteTitle: 'Delete',
|
||||
operationSuccess: 'Successful operation',
|
||||
infoTitle: 'Hint',
|
||||
sureLogOut: 'Are you sure you want to log out?',
|
||||
createSuccess: 'Create Success',
|
||||
updateSuccess: 'Update Success',
|
||||
},
|
||||
login: {
|
||||
captchaHelper: 'Please enter the verification code',
|
||||
|
|
@ -31,12 +37,14 @@ export default {
|
|||
password: 'Please enter a password',
|
||||
required: 'Please enter the required fields',
|
||||
commonName: 'Support English, Chinese, numbers, .-_, length 1-30',
|
||||
email: 'Email format error',
|
||||
},
|
||||
},
|
||||
business: {
|
||||
user: {
|
||||
username: 'Username',
|
||||
email: 'Email',
|
||||
password: 'Password',
|
||||
},
|
||||
},
|
||||
menu: {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ export default {
|
|||
requestTimeout: '请求超时,请稍后重试',
|
||||
infoTitle: '提示',
|
||||
sureLogOut: '您是否确认退出登录?',
|
||||
createSuccess: '新建成功',
|
||||
updateSuccess: '更新成功',
|
||||
},
|
||||
login: {
|
||||
captchaHelper: '请输入验证码',
|
||||
|
|
@ -35,12 +37,14 @@ export default {
|
|||
password: '请输入密码',
|
||||
required: '请填写必填项',
|
||||
commonName: '支持英文、中文、数字、.-_,长度1-30',
|
||||
email: '邮箱格式错误',
|
||||
},
|
||||
},
|
||||
business: {
|
||||
user: {
|
||||
username: '用户名',
|
||||
email: '邮箱',
|
||||
password: '密码',
|
||||
},
|
||||
},
|
||||
menu: {
|
||||
|
|
|
|||
5
frontend/src/layout/form-button.vue
Normal file
5
frontend/src/layout/form-button.vue
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<template>
|
||||
<div class="form-button">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -16,10 +16,11 @@
|
|||
<slot name="toolbar"></slot>
|
||||
</div>
|
||||
<div class="content-container_form">
|
||||
<slot name="form"> </slot>
|
||||
<div class="form-button">
|
||||
<slot name="button"></slot>
|
||||
</div>
|
||||
<slot name="form">
|
||||
<form-button>
|
||||
<slot name="button"></slot>
|
||||
</form-button>
|
||||
</slot>
|
||||
</div>
|
||||
<slot></slot>
|
||||
</div>
|
||||
|
|
@ -28,6 +29,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, useSlots } from 'vue';
|
||||
import BackButton from '@/components/back-button/index.vue';
|
||||
import FormButton from './form-button.vue';
|
||||
defineOptions({ name: 'LayoutContent' }); // 组件名
|
||||
const slots = useSlots();
|
||||
const prop = defineProps({
|
||||
|
|
@ -59,8 +61,8 @@ const showBack = computed(() => {
|
|||
|
||||
.content-container_form {
|
||||
text-align: -webkit-center;
|
||||
width: 80%;
|
||||
margin-left: 10%;
|
||||
width: 60%;
|
||||
margin-left: 15%;
|
||||
.form-button {
|
||||
float: right;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ const demoRouter = {
|
|||
},
|
||||
},
|
||||
{
|
||||
path: '/demos/table/:op',
|
||||
path: '/demos/table/:op/:id?',
|
||||
name: 'DemoCreate',
|
||||
props: true,
|
||||
hidden: true,
|
||||
|
|
|
|||
|
|
@ -110,3 +110,7 @@
|
|||
#nprogress .peg {
|
||||
box-shadow: 0 0 10px $primary-color, 0 0 5px $primary-color !important;
|
||||
}
|
||||
|
||||
.form-button {
|
||||
float: right;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
<LayoutContent :header="'样例'">
|
||||
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data" @search="search">
|
||||
<template #toolbar>
|
||||
<el-button type="primary" @click="openOperate({})">{{ $t('commons.button.create') }}</el-button>
|
||||
<el-button type="primary" @click="openOperate(null)">{{ $t('commons.button.create') }}</el-button>
|
||||
<el-button type="primary" plain>{{ '其他操作' }}</el-button>
|
||||
<el-button type="danger" plain :disabled="selects.length === 0" @click="batchDelete">{{
|
||||
$t('commons.button.delete')
|
||||
|
|
@ -49,10 +49,22 @@ const userSearch = reactive({
|
|||
page: 1,
|
||||
pageSize: 5,
|
||||
});
|
||||
|
||||
const openOperate = (row: User.User | null) => {
|
||||
let params: { [key: string]: any } = {
|
||||
op: 'create',
|
||||
};
|
||||
if (row !== null) {
|
||||
params.op = 'edit';
|
||||
params.id = row.id;
|
||||
}
|
||||
|
||||
router.push({ name: 'DemoCreate', params });
|
||||
};
|
||||
const buttons = [
|
||||
{
|
||||
label: i18n.global.t('commons.button.edit'),
|
||||
click: edit,
|
||||
click: openOperate,
|
||||
},
|
||||
// {
|
||||
// label: '执行',
|
||||
|
|
@ -72,36 +84,6 @@ const buttons = [
|
|||
// click: buttonClick,
|
||||
// },
|
||||
];
|
||||
|
||||
// function select(row: any) {
|
||||
// console.log(row);
|
||||
// selects.value.push(row.ID);
|
||||
// console.log(selects);
|
||||
// }
|
||||
function edit(row: User.User) {
|
||||
console.log(row);
|
||||
}
|
||||
|
||||
// interface OperateOpen {
|
||||
// acceptParams: (params: any) => void;
|
||||
// }
|
||||
// const operateRef = ref<OperateOpen>();
|
||||
|
||||
const openOperate = (row: User.User) => {
|
||||
console.log(row);
|
||||
// let title = 'commons.button.create';
|
||||
// if (row != null) {
|
||||
// title = 'commons.button.edit';
|
||||
// }
|
||||
// let params = {
|
||||
// titke: title,
|
||||
// row: row,
|
||||
// };
|
||||
// operateRef.value!.acceptParams(params);
|
||||
router.push({ name: 'DemoCreate', params: { op: 'create' } });
|
||||
// router.push({ name: 'operate', params: { operate: 'create' } });
|
||||
};
|
||||
|
||||
const batchDelete = async () => {
|
||||
let ids: Array<number> = [];
|
||||
selects.value.forEach((item: User.User) => {
|
||||
|
|
|
|||
|
|
@ -2,43 +2,88 @@
|
|||
<LayoutContent :header="$t('commons.button.' + op)" :back-name="'Table'">
|
||||
<template #form>
|
||||
<el-form ref="ruleFormRef" label-position="left" :model="demoForm" :rules="rules" label-width="140px">
|
||||
<el-form-item :label="$t('business.user.username')" prop="username">
|
||||
<el-input v-model="demoForm.username" />
|
||||
<el-form-item :label="$t('business.user.username')" prop="name">
|
||||
<el-input v-model="demoForm.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('business.user.email')" prop="email">
|
||||
<el-input v-model="demoForm.email" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('business.user.password')" prop="password">
|
||||
<el-input type="password" v-model="demoForm.password" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div style="float: right">
|
||||
<el-button>{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary">{{ $t('commons.button.create') }}</el-button>
|
||||
<div class="form-button">
|
||||
<el-button @click="router.back()">{{ $t('commons.button.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="submitForm(ruleFormRef)">{{
|
||||
$t('commons.button.confirm')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</LayoutContent>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { User } from '@/api/interface/user';
|
||||
import LayoutContent from '@/layout/layout-content.vue';
|
||||
import { FormInstance, FormRules } from 'element-plus';
|
||||
import { reactive, ref } from 'vue';
|
||||
import { ElMessage, FormInstance, FormRules } from 'element-plus';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { Rules } from '@/global/form-rues';
|
||||
import { addUser, editUser, getUserById } from '@/api/modules/user';
|
||||
import i18n from '@/lang';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { User } from '@/api/interface/user';
|
||||
const router = useRouter();
|
||||
const ruleFormRef = ref<FormInstance>();
|
||||
let demoForm = ref<User.User>({
|
||||
id: 0,
|
||||
name: '',
|
||||
email: '',
|
||||
password: '',
|
||||
});
|
||||
|
||||
interface OperateProps {
|
||||
op: string;
|
||||
id?: number;
|
||||
id: number;
|
||||
}
|
||||
|
||||
withDefaults(defineProps<OperateProps>(), {
|
||||
const props = withDefaults(defineProps<OperateProps>(), {
|
||||
op: 'create',
|
||||
});
|
||||
|
||||
const demoForm = reactive<User.User>({
|
||||
id: 0,
|
||||
username: '',
|
||||
email: '',
|
||||
});
|
||||
const rules = reactive<FormRules>({
|
||||
username: [Rules.required, Rules.name],
|
||||
email: [Rules.required],
|
||||
name: [Rules.required, Rules.name],
|
||||
email: [Rules.required, Rules.email],
|
||||
password: [Rules.required],
|
||||
});
|
||||
|
||||
const submitForm = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return;
|
||||
await formEl.validate((valid) => {
|
||||
if (!valid) {
|
||||
return;
|
||||
}
|
||||
if (props.op === 'create') {
|
||||
addUser(demoForm.value).then(() => {
|
||||
ElMessage.success(i18n.global.t('commons.msg.createSuccess'));
|
||||
router.back();
|
||||
});
|
||||
} else {
|
||||
editUser(demoForm.value).then(() => {
|
||||
ElMessage.success(i18n.global.t('commons.msg.updateSuccess'));
|
||||
router.back();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const getUser = async (id: number) => {
|
||||
const res = await getUserById(id);
|
||||
demoForm.value = res.data;
|
||||
console.log(demoForm);
|
||||
};
|
||||
onMounted(() => {
|
||||
if (props.op == 'edit') {
|
||||
getUser(props.id).catch(() => {
|
||||
router.back();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue