feat: 🚀 用户修改头像
This commit is contained in:
parent
e9112177d4
commit
6e7bf90315
|
@ -6,11 +6,6 @@ export const getRouterAsync = () => {
|
|||
return http.request<BaseResult<any>>('get', 'router/getRouterAsync');
|
||||
};
|
||||
|
||||
/** 图标管理-获取系统图标 */
|
||||
export const getMenuIconList = (data: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `menuIcon/getMenuIconList/${data.page}/${data.limit}`, { data });
|
||||
};
|
||||
|
||||
/** 菜单管理-列表 */
|
||||
export const getMenusList = (data?: any) => {
|
||||
return http.request<BaseResult<ResultTable>>('get', `router/getMenusList`, { params: data });
|
||||
|
@ -32,67 +27,6 @@ export const deletedMenuByIds = (data?: any) => {
|
|||
};
|
||||
|
||||
/** 上传文件 */
|
||||
export const fetchUploadFIle = (data: any) => {
|
||||
export const fetchUploadFile = (data: any) => {
|
||||
return http.post<BaseResult<any>>('/files/upload', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
||||
};
|
||||
|
||||
// ------------未确认------------
|
||||
/** 获取系统管理-用户管理列表 */
|
||||
export const getUserList = (data?: object) => {
|
||||
return http.request<BaseResult<ResultTable>>('post', '/user', { data });
|
||||
};
|
||||
|
||||
/** 系统管理-用户管理-获取所有角色列表 */
|
||||
export const getAllRoleList = () => {
|
||||
return http.request<any>('get', '/list-all-role');
|
||||
};
|
||||
|
||||
/** 系统管理-用户管理-根据userId,获取对应角色id列表(userId:用户id) */
|
||||
export const getRoleIds = (data?: object) => {
|
||||
return http.request<any>('post', '/list-role-ids', { data });
|
||||
};
|
||||
|
||||
/** 获取系统管理-角色管理列表 */
|
||||
export const getRoleList = (data?: object) => {
|
||||
return http.request<ResultTable>('post', '/role', { data });
|
||||
};
|
||||
|
||||
/** 获取系统管理-部门管理列表 */
|
||||
export const getDeptList = (data?: object) => {
|
||||
return http.request<any>('post', '/dept', { data });
|
||||
};
|
||||
|
||||
/** 获取系统监控-在线用户列表 */
|
||||
export const getOnlineLogsList = (data?: object) => {
|
||||
return http.request<ResultTable>('post', '/online-logs', { data });
|
||||
};
|
||||
|
||||
/** 获取系统监控-登录日志列表 */
|
||||
export const getLoginLogsList = (data?: object) => {
|
||||
return http.request<ResultTable>('post', '/login-logs', { data });
|
||||
};
|
||||
|
||||
/** 获取系统监控-操作日志列表 */
|
||||
export const getOperationLogsList = (data?: object) => {
|
||||
return http.request<ResultTable>('post', '/operation-logs', { data });
|
||||
};
|
||||
|
||||
/** 获取系统监控-系统日志列表 */
|
||||
export const getSystemLogsList = (data?: object) => {
|
||||
return http.request<ResultTable>('post', '/system-logs', { data });
|
||||
};
|
||||
|
||||
/** 获取系统监控-系统日志-根据 id 查日志详情 */
|
||||
export const getSystemLogsDetail = (data?: object) => {
|
||||
return http.request<any>('post', '/system-logs-detail', { data });
|
||||
};
|
||||
|
||||
/** 获取角色管理-权限-菜单权限 */
|
||||
export const getRoleMenu = (data?: object) => {
|
||||
return http.request<any>('post', '/role-menu', { data });
|
||||
};
|
||||
|
||||
/** 获取角色管理-权限-菜单权限-根据角色 id 查对应菜单 */
|
||||
export const getRoleMenuIds = (data?: object) => {
|
||||
return http.request<any>('post', '/role-menu-ids', { data });
|
||||
};
|
||||
|
|
|
@ -71,3 +71,11 @@ export const fetchGetUserinfoById = (data?: object) => {
|
|||
export const fetchUpdateUserPasswordByAdmin = (data: any) => {
|
||||
return http.request<BaseResult<UserResult>>('put', 'user/updateUserPasswordByAdmin', { data });
|
||||
};
|
||||
|
||||
/**
|
||||
* 管理员修改管理员用户头像
|
||||
* @param data
|
||||
*/
|
||||
export const fetchUploadAvatarByAdmin = (data: any) => {
|
||||
return http.request<BaseResult<UserResult>>('put', 'user/uploadAvatarByAdmin', { data }, { headers: { 'Content-Type': 'multipart/form-data' } });
|
||||
};
|
||||
|
|
|
@ -2,12 +2,12 @@ import './circled.css';
|
|||
import Cropper from 'cropperjs';
|
||||
import { ElUpload } from 'element-plus';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import { computed, defineComponent, onMounted, onUnmounted, type PropType, ref, unref } from 'vue';
|
||||
import { useEventListener } from '@vueuse/core';
|
||||
import { longpress } from '@/directives/longpress';
|
||||
import { useTippy, directive as tippy } from 'vue-tippy';
|
||||
import { type PropType, ref, unref, computed, onMounted, onUnmounted, defineComponent } from 'vue';
|
||||
import { delay, debounce, isArray, downloadByBase64, useResizeObserver } from '@pureadmin/utils';
|
||||
import { Reload, Upload, ArrowH, ArrowV, ArrowUp, ArrowDown, ArrowLeft, ChangeIcon, ArrowRight, RotateLeft, SearchPlus, RotateRight, SearchMinus, DownloadIcon } from './svg';
|
||||
import { directive as tippy, useTippy } from 'vue-tippy';
|
||||
import { debounce, delay, downloadByBase64, isArray, useResizeObserver } from '@pureadmin/utils';
|
||||
import { ArrowDown, ArrowH, ArrowLeft, ArrowRight, ArrowUp, ArrowV, ChangeIcon, DownloadIcon, Reload, RotateLeft, RotateRight, SearchMinus, SearchPlus, Upload } from './svg';
|
||||
|
||||
type Options = Cropper.Options;
|
||||
|
||||
|
@ -206,57 +206,20 @@ export default defineComponent({
|
|||
return () => (
|
||||
<div class='flex flex-wrap w-[60px] justify-between'>
|
||||
<ElUpload accept='image/*' show-file-list={false} before-upload={beforeUpload}>
|
||||
<Upload
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '上传',
|
||||
placement: 'left-start',
|
||||
}}
|
||||
/>
|
||||
<Upload class={iconClass.value} v-tippy={{ content: '上传', placement: 'left-start' }} />
|
||||
</ElUpload>
|
||||
<DownloadIcon
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '下载',
|
||||
placement: 'right-start',
|
||||
}}
|
||||
onClick={() => downloadByBase64(imgBase64.value, 'cropping.png')}
|
||||
/>
|
||||
<DownloadIcon class={iconClass.value} v-tippy={{ content: '下载', placement: 'right-start' }} onClick={() => downloadByBase64(imgBase64.value, 'cropping.png')} />
|
||||
<ChangeIcon
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '圆形、矩形裁剪',
|
||||
placement: 'left-start',
|
||||
}}
|
||||
v-tippy={{ content: '圆形、矩形裁剪', placement: 'left-start' }}
|
||||
onClick={() => {
|
||||
inCircled.value = !inCircled.value;
|
||||
realTimeCroppered();
|
||||
}}
|
||||
/>
|
||||
<Reload
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '重置',
|
||||
placement: 'right-start',
|
||||
}}
|
||||
onClick={() => handCropper('reset')}
|
||||
/>
|
||||
<ArrowUp
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '上移(可长按)',
|
||||
placement: 'left-start',
|
||||
}}
|
||||
v-longpress={[() => handCropper('move', [0, -10]), '0:100']}
|
||||
/>
|
||||
<ArrowDown
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '下移(可长按)',
|
||||
placement: 'right-start',
|
||||
}}
|
||||
v-longpress={[() => handCropper('move', [0, 10]), '0:100']}
|
||||
/>
|
||||
<Reload class={iconClass.value} v-tippy={{ content: '重置', placement: 'right-start' }} onClick={() => handCropper('reset')} />
|
||||
<ArrowUp class={iconClass.value} v-tippy={{ content: '上移(可长按)', placement: 'left-start' }} v-longpress={[() => handCropper('move', [0, -10]), '0:100']} />
|
||||
<ArrowDown class={iconClass.value} v-tippy={{ content: '下移(可长按)', placement: 'right-start' }} v-longpress={[() => handCropper('move', [0, 10]), '0:100']} />
|
||||
<ArrowLeft
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
|
@ -265,62 +228,13 @@ export default defineComponent({
|
|||
}}
|
||||
v-longpress={[() => handCropper('move', [-10, 0]), '0:100']}
|
||||
/>
|
||||
<ArrowRight
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '右移(可长按)',
|
||||
placement: 'right-start',
|
||||
}}
|
||||
v-longpress={[() => handCropper('move', [10, 0]), '0:100']}
|
||||
/>
|
||||
<ArrowH
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '水平翻转',
|
||||
placement: 'left-start',
|
||||
}}
|
||||
onClick={() => handCropper('scaleX', -1)}
|
||||
/>
|
||||
<ArrowV
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '垂直翻转',
|
||||
placement: 'right-start',
|
||||
}}
|
||||
onClick={() => handCropper('scaleY', -1)}
|
||||
/>
|
||||
<RotateLeft
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '逆时针旋转',
|
||||
placement: 'left-start',
|
||||
}}
|
||||
onClick={() => handCropper('rotate', -45)}
|
||||
/>
|
||||
<RotateRight
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '顺时针旋转',
|
||||
placement: 'right-start',
|
||||
}}
|
||||
onClick={() => handCropper('rotate', 45)}
|
||||
/>
|
||||
<SearchPlus
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '放大(可长按)',
|
||||
placement: 'left-start',
|
||||
}}
|
||||
v-longpress={[() => handCropper('zoom', 0.1), '0:100']}
|
||||
/>
|
||||
<SearchMinus
|
||||
class={iconClass.value}
|
||||
v-tippy={{
|
||||
content: '缩小(可长按)',
|
||||
placement: 'right-start',
|
||||
}}
|
||||
v-longpress={[() => handCropper('zoom', -0.1), '0:100']}
|
||||
/>
|
||||
<ArrowRight class={iconClass.value} v-tippy={{ content: '右移(可长按)', placement: 'right-start' }} v-longpress={[() => handCropper('move', [10, 0]), '0:100']} />
|
||||
<ArrowH class={iconClass.value} v-tippy={{ content: '水平翻转', placement: 'left-start' }} onClick={() => handCropper('scaleX', -1)} />
|
||||
<ArrowV class={iconClass.value} v-tippy={{ content: '垂直翻转', placement: 'right-start' }} onClick={() => handCropper('scaleY', -1)} />
|
||||
<RotateLeft class={iconClass.value} v-tippy={{ content: '逆时针旋转', placement: 'left-start' }} onClick={() => handCropper('rotate', -45)} />
|
||||
<RotateRight class={iconClass.value} v-tippy={{ content: '顺时针旋转', placement: 'right-start' }} onClick={() => handCropper('rotate', 45)} />
|
||||
<SearchPlus class={iconClass.value} v-tippy={{ content: '放大(可长按)', placement: 'left-start' }} v-longpress={[() => handCropper('zoom', 0.1), '0:100']} />
|
||||
<SearchMinus class={iconClass.value} v-tippy={{ content: '缩小(可长按)', placement: 'right-start' }} v-longpress={[() => handCropper('zoom', -0.1), '0:100']} />
|
||||
</div>
|
||||
);
|
||||
},
|
||||
|
|
|
@ -17,7 +17,7 @@ import { Plus } from '@element-plus/icons-vue';
|
|||
import { ElMessage, UploadRawFile, UploadRequestOptions } from 'element-plus';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { SystemEnum } from '@/enums/upload';
|
||||
import { fetchUploadFIle } from '@/api/v1/system';
|
||||
import { fetchUploadFile } from '@/api/v1/system';
|
||||
|
||||
const props = defineProps({
|
||||
imageUrl: String,
|
||||
|
@ -38,7 +38,7 @@ const onUpload = async (options: UploadRequestOptions) => {
|
|||
const data = { file, type };
|
||||
|
||||
// 上传文件并返回文件地址
|
||||
const result: any = await fetchUploadFIle(data);
|
||||
const result: any = await fetchUploadFile(data);
|
||||
imageSrc.value = result.data.url;
|
||||
emits('uploadCallback', result);
|
||||
};
|
||||
|
@ -85,16 +85,16 @@ onMounted(() => {
|
|||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.el-upload {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
|
||||
.el-upload-dragger {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
}
|
||||
<style lang="scss" scoped>
|
||||
//.el-upload {
|
||||
// width: 128px;
|
||||
// height: 128px;
|
||||
//}
|
||||
//
|
||||
//.el-upload-dragger {
|
||||
// display: flex;
|
||||
// align-items: center;
|
||||
// justify-content: center;
|
||||
// height: 100%;
|
||||
//}
|
||||
</style>
|
||||
|
|
|
@ -6,7 +6,6 @@ import { FormProps } from '@/views/system/adminUser/utils/types';
|
|||
import { $t } from '@/plugins/i18n';
|
||||
import ReCol from '@/components/MyCol';
|
||||
import { sexConstant } from '@/enums/baseConstant';
|
||||
import UploadDialogImage from '@/components/Upload/UploadDialogImage.vue';
|
||||
|
||||
const props = withDefaults(defineProps<FormProps>(), {
|
||||
formInline: () => ({
|
||||
|
@ -93,13 +92,6 @@ defineExpose({ formRef });
|
|||
</el-form-item>
|
||||
</re-col>
|
||||
|
||||
<!-- 头像 -->
|
||||
<re-col :sm="24" :value="24" :xs="24">
|
||||
<el-form-item :label="$t('adminUser_avatar')" prop="avatar">
|
||||
<UploadDialogImage :image-url="form.avatar" type="avatar" @uploadCallback="onUploadCallback" />
|
||||
</el-form-item>
|
||||
</re-col>
|
||||
|
||||
<!-- 用户简介 -->
|
||||
<re-col :sm="24" :value="24" :xs="24">
|
||||
<el-form-item :label="$t('adminUser_summary')" prop="summary">
|
||||
|
|
|
@ -106,7 +106,7 @@ onMounted(() => {
|
|||
|
||||
<PureTableBar :columns="columns" title="用户信息" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||
<template #buttons>
|
||||
<el-button :icon="useRenderIcon(AddFill)" type="primary" @click="onAdd"> 添加用户信息</el-button>
|
||||
<el-button :icon="useRenderIcon(AddFill)" type="primary" @click="onAdd"> {{ $t('add_new') + $t('adminUser') }} </el-button>
|
||||
</template>
|
||||
|
||||
<template v-slot="{ size, dynamicColumns }">
|
||||
|
|
|
@ -2,7 +2,7 @@ import { addDialog } from '@/components/BaseDialog/index';
|
|||
import AdminUserDialog from '@/views/system/adminUser/admin-user-dialog.vue';
|
||||
import { useAdminUserStore } from '@/store/system/adminUser.ts';
|
||||
import { h, reactive, ref } from 'vue';
|
||||
import { messageBox } from '@/utils/message';
|
||||
import { message, messageBox } from '@/utils/message';
|
||||
import type { FormItemProps } from '@/views/system/adminUser/utils/types';
|
||||
import { $t } from '@/plugins/i18n';
|
||||
import { isAddUserinfo } from '@/views/system/adminUser/utils/columns';
|
||||
|
@ -11,6 +11,9 @@ import ResetPasswordDialog from '@/views/system/adminUser/reset-passwords.vue';
|
|||
import { deviceDetection } from '@pureadmin/utils';
|
||||
import CropperPreview from '@/components/CropperPreview';
|
||||
import AssignUserToRole from '@/views/system/adminUser/assign-user-to-role.vue';
|
||||
import { fetchUploadFile } from '@/api/v1/system';
|
||||
import userAvatar from '@/assets/user.jpg';
|
||||
import { fetchUploadAvatarByAdmin } from '@/api/v1/user';
|
||||
|
||||
export const formRef = ref();
|
||||
const cropRef = ref();
|
||||
|
@ -156,7 +159,10 @@ export const updateUserStatus = async (row: any) => {
|
|||
await onSearch();
|
||||
};
|
||||
|
||||
/* 上传头像 */
|
||||
/**
|
||||
* * 上传头像
|
||||
* @param row
|
||||
*/
|
||||
export const onUploadAvatar = (row: any) => {
|
||||
addDialog({
|
||||
title: '裁剪、上传头像',
|
||||
|
@ -170,8 +176,18 @@ export const onUploadAvatar = (row: any) => {
|
|||
onCropper: info => (avatarInfo.value = info),
|
||||
}),
|
||||
beforeSure: async done => {
|
||||
console.log('裁剪后的图片信息:', avatarInfo.value);
|
||||
// 根据实际业务使用avatarInfo.value和row里的某些字段去调用上传头像接口即可
|
||||
// 上传头像
|
||||
const blob = avatarInfo.value.blob;
|
||||
const uploadData = { file: blob, type: 'avatar' };
|
||||
let result = await fetchUploadFile(uploadData);
|
||||
if (result.code !== 200) return;
|
||||
|
||||
// 修改头像
|
||||
const data = { userId: row.id, avatar: result.data.filepath };
|
||||
result = await fetchUploadAvatarByAdmin(data);
|
||||
if (result.code !== 200) return;
|
||||
|
||||
message(result.message, { type: 'success' });
|
||||
done();
|
||||
await onSearch();
|
||||
},
|
||||
|
@ -215,7 +231,7 @@ export const onResetPassword = (row: any) => {
|
|||
export const onAssignRolesToUser = (row: any) => {
|
||||
addDialog({
|
||||
title: `为 ${row.username} 分配角色`,
|
||||
width: '30%',
|
||||
width: '45%',
|
||||
draggable: true,
|
||||
closeOnClickModal: false,
|
||||
fullscreenIcon: true,
|
||||
|
|
Loading…
Reference in New Issue