feat: demo 增加编辑

This commit is contained in:
wangzhengkun 2022-08-12 12:08:59 +08:00
parent 9a0c83aa7e
commit 80fb98e20c
16 changed files with 139 additions and 109 deletions

View file

@ -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

View file

@ -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"`
}

View file

@ -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 {

View file

@ -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)
}

View file

@ -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)
}
}

View file

@ -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;
}
}

View file

@ -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`);
// };

View file

@ -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',
},
};

View file

@ -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: {

View file

@ -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: {

View file

@ -0,0 +1,5 @@
<template>
<div class="form-button">
<slot></slot>
</div>
</template>

View file

@ -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;
}

View file

@ -20,7 +20,7 @@ const demoRouter = {
},
},
{
path: '/demos/table/:op',
path: '/demos/table/:op/:id?',
name: 'DemoCreate',
props: true,
hidden: true,

View file

@ -110,3 +110,7 @@
#nprogress .peg {
box-shadow: 0 0 10px $primary-color, 0 0 5px $primary-color !important;
}
.form-button {
float: right;
}

View file

@ -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) => {

View file

@ -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>