feat: 适配naive
parent
04d2cc2952
commit
d59c137036
|
@ -1,4 +1,6 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import type { UploadFileInfo } from 'naive-ui';
|
||||||
|
|
||||||
import type { CropendResult, CropperModalProps, CropperType } from './typing';
|
import type { CropendResult, CropperModalProps, CropperType } from './typing';
|
||||||
|
|
||||||
import { ref } from 'vue';
|
import { ref } from 'vue';
|
||||||
|
@ -49,13 +51,13 @@ function modalLoading(loading: boolean) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Block upload
|
// Block upload
|
||||||
function handleBeforeUpload(file: File) {
|
function handleBeforeUpload(file: UploadFileInfo) {
|
||||||
if (props.size > 0 && file.size > 1024 * 1024 * props.size) {
|
if (props.size > 0 && file.size > 1024 * 1024 * props.size) {
|
||||||
emit('uploadError', { msg: $t('ui.cropper.imageTooBig') });
|
emit('uploadError', { msg: $t('ui.cropper.imageTooBig') });
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const reader = new FileReader();
|
const reader = new FileReader();
|
||||||
reader.readAsDataURL(file);
|
reader.readAsDataURL(file.file);
|
||||||
src.value = '';
|
src.value = '';
|
||||||
previewSource.value = '';
|
previewSource.value = '';
|
||||||
reader.addEventListener('load', (e) => {
|
reader.addEventListener('load', (e) => {
|
||||||
|
@ -111,7 +113,7 @@ async function handleOk() {
|
||||||
:confirm-text="$t('ui.cropper.okText')"
|
:confirm-text="$t('ui.cropper.okText')"
|
||||||
:fullscreen-button="false"
|
:fullscreen-button="false"
|
||||||
:title="$t('ui.cropper.modalTitle')"
|
:title="$t('ui.cropper.modalTitle')"
|
||||||
class="w-[800px]"
|
class="w-[50%]"
|
||||||
>
|
>
|
||||||
<div :class="prefixCls">
|
<div :class="prefixCls">
|
||||||
<div :class="`${prefixCls}-left`" class="w-full">
|
<div :class="`${prefixCls}-left`" class="w-full">
|
||||||
|
@ -127,130 +129,148 @@ async function handleOk() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div :class="`${prefixCls}-toolbar`">
|
<div :class="`${prefixCls}-toolbar`">
|
||||||
<NUpload
|
|
||||||
:before-upload="handleBeforeUpload"
|
|
||||||
:file-list="[]"
|
|
||||||
accept="image/*"
|
|
||||||
>
|
|
||||||
<NTooltip :title="$t('ui.cropper.selectImage')" placement="bottom">
|
|
||||||
<NButton size="small" type="primary">
|
|
||||||
<template #icon>
|
|
||||||
<div class="flex items-center justify-center">
|
|
||||||
<span class="icon-[ant-design--upload-outlined]"></span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</NButton>
|
|
||||||
</NTooltip>
|
|
||||||
</NUpload>
|
|
||||||
<NSpace>
|
<NSpace>
|
||||||
<NTooltip :title="$t('ui.cropper.btn_reset')" placement="bottom">
|
<NUpload
|
||||||
<NButton
|
@before-upload="handleBeforeUpload"
|
||||||
:disabled="!src"
|
:file-list="[]"
|
||||||
size="small"
|
accept="image/*"
|
||||||
type="primary"
|
|
||||||
@click="handlerToolbar('reset')"
|
|
||||||
>
|
|
||||||
<template #icon>
|
|
||||||
<div class="flex items-center justify-center">
|
|
||||||
<span class="icon-[ant-design--reload-outlined]"></span>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</NButton>
|
|
||||||
</NTooltip>
|
|
||||||
<NTooltip
|
|
||||||
:title="$t('ui.cropper.btn_rotate_left')"
|
|
||||||
placement="bottom"
|
|
||||||
>
|
>
|
||||||
<NButton
|
<NTooltip placement="bottom">
|
||||||
:disabled="!src"
|
<template #trigger>
|
||||||
size="small"
|
<NButton size="small" type="primary">
|
||||||
type="primary"
|
<template #icon>
|
||||||
@click="handlerToolbar('rotate', -45)"
|
<div class="flex items-center justify-center">
|
||||||
>
|
<span class="icon-[ant-design--upload-outlined]"></span>
|
||||||
<template #icon>
|
</div>
|
||||||
<div class="flex items-center justify-center">
|
</template>
|
||||||
<span
|
</NButton>
|
||||||
class="icon-[ant-design--rotate-left-outlined]"
|
|
||||||
></span>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
</NButton>
|
{{ $t('ui.cropper.selectImage') }}
|
||||||
|
</NTooltip>
|
||||||
|
</NUpload>
|
||||||
|
<NTooltip placement="bottom">
|
||||||
|
<template #trigger>
|
||||||
|
<NButton
|
||||||
|
:disabled="!src"
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="handlerToolbar('reset')"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<div class="flex items-center justify-center">
|
||||||
|
<span class="icon-[ant-design--reload-outlined]"></span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
{{ $t('ui.cropper.btn_reset') }}
|
||||||
</NTooltip>
|
</NTooltip>
|
||||||
<NTooltip
|
<NTooltip placement="bottom">
|
||||||
:title="$t('ui.cropper.btn_rotate_right')"
|
<template #trigger>
|
||||||
placement="bottom"
|
<NButton
|
||||||
>
|
:disabled="!src"
|
||||||
<NButton
|
size="small"
|
||||||
:disabled="!src"
|
type="primary"
|
||||||
pre-icon="ant-design:rotate-right-outlined"
|
@click="handlerToolbar('rotate', -45)"
|
||||||
size="small"
|
>
|
||||||
type="primary"
|
<template #icon>
|
||||||
@click="handlerToolbar('rotate', 45)"
|
<div class="flex items-center justify-center">
|
||||||
>
|
<span
|
||||||
<template #icon>
|
class="icon-[ant-design--rotate-left-outlined]"
|
||||||
<div class="flex items-center justify-center">
|
></span>
|
||||||
<span
|
</div>
|
||||||
class="icon-[ant-design--rotate-right-outlined]"
|
</template>
|
||||||
></span>
|
</NButton>
|
||||||
</div>
|
</template>
|
||||||
</template>
|
{{ $t('ui.cropper.btn_rotate_left') }}
|
||||||
</NButton>
|
|
||||||
</NTooltip>
|
</NTooltip>
|
||||||
<NTooltip :title="$t('ui.cropper.btn_scale_x')" placement="bottom">
|
<NTooltip placement="bottom">
|
||||||
<NButton
|
<template #trigger>
|
||||||
:disabled="!src"
|
<NButton
|
||||||
size="small"
|
:disabled="!src"
|
||||||
type="primary"
|
pre-icon="ant-design:rotate-right-outlined"
|
||||||
@click="handlerToolbar('scaleX')"
|
size="small"
|
||||||
>
|
type="primary"
|
||||||
<template #icon>
|
@click="handlerToolbar('rotate', 45)"
|
||||||
<div class="flex items-center justify-center">
|
>
|
||||||
<span class="icon-[vaadin--arrows-long-h]"></span>
|
<template #icon>
|
||||||
</div>
|
<div class="flex items-center justify-center">
|
||||||
</template>
|
<span
|
||||||
</NButton>
|
class="icon-[ant-design--rotate-right-outlined]"
|
||||||
|
></span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
{{ $t('ui.cropper.btn_rotate_right') }}
|
||||||
</NTooltip>
|
</NTooltip>
|
||||||
<NTooltip :title="$t('ui.cropper.btn_scale_y')" placement="bottom">
|
<NTooltip placement="bottom">
|
||||||
<NButton
|
<template #trigger>
|
||||||
:disabled="!src"
|
<NButton
|
||||||
size="small"
|
:disabled="!src"
|
||||||
type="primary"
|
size="small"
|
||||||
@click="handlerToolbar('scaleY')"
|
type="primary"
|
||||||
>
|
@click="handlerToolbar('scaleX')"
|
||||||
<template #icon>
|
>
|
||||||
<div class="flex items-center justify-center">
|
<template #icon>
|
||||||
<span class="icon-[vaadin--arrows-long-v]"></span>
|
<div class="flex items-center justify-center">
|
||||||
</div>
|
<span class="icon-[vaadin--arrows-long-h]"></span>
|
||||||
</template>
|
</div>
|
||||||
</NButton>
|
</template>
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
{{ $t('ui.cropper.btn_scale_x') }}
|
||||||
</NTooltip>
|
</NTooltip>
|
||||||
<NTooltip :title="$t('ui.cropper.btn_zoom_in')" placement="bottom">
|
<NTooltip placement="bottom">
|
||||||
<NButton
|
<template #trigger>
|
||||||
:disabled="!src"
|
<NButton
|
||||||
size="small"
|
:disabled="!src"
|
||||||
type="primary"
|
size="small"
|
||||||
@click="handlerToolbar('zoom', 0.1)"
|
type="primary"
|
||||||
>
|
@click="handlerToolbar('scaleY')"
|
||||||
<template #icon>
|
>
|
||||||
<div class="flex items-center justify-center">
|
<template #icon>
|
||||||
<span class="icon-[ant-design--zoom-in-outlined]"></span>
|
<div class="flex items-center justify-center">
|
||||||
</div>
|
<span class="icon-[vaadin--arrows-long-v]"></span>
|
||||||
</template>
|
</div>
|
||||||
</NButton>
|
</template>
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
{{ $t('ui.cropper.btn_scale_y') }}
|
||||||
</NTooltip>
|
</NTooltip>
|
||||||
<NTooltip :title="$t('ui.cropper.btn_zoom_out')" placement="bottom">
|
<NTooltip placement="bottom">
|
||||||
<NButton
|
<template #trigger>
|
||||||
:disabled="!src"
|
<NButton
|
||||||
size="small"
|
:disabled="!src"
|
||||||
type="primary"
|
size="small"
|
||||||
@click="handlerToolbar('zoom', -0.1)"
|
type="primary"
|
||||||
>
|
@click="handlerToolbar('zoom', 0.1)"
|
||||||
<template #icon>
|
>
|
||||||
<div class="flex items-center justify-center">
|
<template #icon>
|
||||||
<span class="icon-[ant-design--zoom-out-outlined]"></span>
|
<div class="flex items-center justify-center">
|
||||||
</div>
|
<span class="icon-[ant-design--zoom-in-outlined]"></span>
|
||||||
</template>
|
</div>
|
||||||
</NButton>
|
</template>
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
{{ $t('ui.cropper.btn_zoom_in') }}
|
||||||
|
</NTooltip>
|
||||||
|
<NTooltip placement="bottom">
|
||||||
|
<template #trigger>
|
||||||
|
<NButton
|
||||||
|
:disabled="!src"
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
@click="handlerToolbar('zoom', -0.1)"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<div class="flex items-center justify-center">
|
||||||
|
<span class="icon-[ant-design--zoom-out-outlined]"></span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</NButton>
|
||||||
|
</template>
|
||||||
|
{{ $t('ui.cropper.btn_zoom_out') }}
|
||||||
</NTooltip>
|
</NTooltip>
|
||||||
</NSpace>
|
</NSpace>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@ import { onMounted, ref } from 'vue';
|
||||||
|
|
||||||
import { Page } from '@vben/common-ui';
|
import { Page } from '@vben/common-ui';
|
||||||
|
|
||||||
import { NCard, NTabs } from 'naive-ui';
|
import { NCard, NTabPane, NTabs } from 'naive-ui';
|
||||||
|
|
||||||
import { getUserProfile } from '#/api/system/user/profile';
|
import { getUserProfile } from '#/api/system/user/profile';
|
||||||
import { useAuthStore } from '#/store';
|
import { useAuthStore } from '#/store';
|
||||||
|
@ -47,16 +47,16 @@ onMounted(loadProfile);
|
||||||
|
|
||||||
<!-- 右侧 标签页 -->
|
<!-- 右侧 标签页 -->
|
||||||
<NCard class="ml-3 w-3/5">
|
<NCard class="ml-3 w-3/5">
|
||||||
<NTabs v-model:active-key="activeName" class="-mt-4">
|
<NTabs v-model:value="activeName" class="-mt-4">
|
||||||
<NTabs.TabPane key="basicInfo" tab="基本设置">
|
<NTabPane name="basicInfo" tab="基本设置">
|
||||||
<BaseInfo :profile="profile" @success="refreshProfile" />
|
<BaseInfo :profile="profile" @success="refreshProfile" />
|
||||||
</NTabs.TabPane>
|
</NTabPane>
|
||||||
<NTabs.TabPane key="resetPwd" tab="密码设置">
|
<NTabPane name="resetPwd" tab="密码设置">
|
||||||
<ResetPwd />
|
<ResetPwd />
|
||||||
</NTabs.TabPane>
|
</NTabPane>
|
||||||
<NTabs.TabPane key="userSocial" tab="社交绑定" force-render>
|
<NTabPane name="userSocial" tab="社交绑定" force-render>
|
||||||
<UserSocial @update:active-name="activeName = $event" />
|
<UserSocial @update:active-name="activeName = $event" />
|
||||||
</NTabs.TabPane>
|
</NTabPane>
|
||||||
<!-- TODO @芋艿:在线设备 -->
|
<!-- TODO @芋艿:在线设备 -->
|
||||||
</NTabs>
|
</NTabs>
|
||||||
</NCard>
|
</NCard>
|
||||||
|
|
|
@ -45,14 +45,17 @@ async function handelUpload({
|
||||||
<template>
|
<template>
|
||||||
<div v-if="profile">
|
<div v-if="profile">
|
||||||
<div class="flex flex-col items-center">
|
<div class="flex flex-col items-center">
|
||||||
<NTooltip title="点击上传头像">
|
<NTooltip>
|
||||||
<CropperAvatar
|
<template #trigger>
|
||||||
:show-btn="false"
|
<CropperAvatar
|
||||||
:upload-api="handelUpload"
|
:show-btn="false"
|
||||||
:value="avatar"
|
:upload-api="handelUpload"
|
||||||
:width="120"
|
:value="avatar"
|
||||||
@change="emit('success')"
|
:width="120"
|
||||||
/>
|
@change="emit('success')"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
点击上传头像
|
||||||
</NTooltip>
|
</NTooltip>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
|
|
|
@ -13,7 +13,10 @@ const [Form, formApi] = useVbenForm({
|
||||||
},
|
},
|
||||||
schema: [
|
schema: [
|
||||||
{
|
{
|
||||||
component: 'InputPassword',
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
type: 'password',
|
||||||
|
},
|
||||||
fieldName: 'oldPassword',
|
fieldName: 'oldPassword',
|
||||||
label: '旧密码',
|
label: '旧密码',
|
||||||
rules: z
|
rules: z
|
||||||
|
@ -22,7 +25,10 @@ const [Form, formApi] = useVbenForm({
|
||||||
.max(20, '密码长度不能超过 20 个字符'),
|
.max(20, '密码长度不能超过 20 个字符'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'InputPassword',
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
type: 'password',
|
||||||
|
},
|
||||||
dependencies: {
|
dependencies: {
|
||||||
rules(values) {
|
rules(values) {
|
||||||
return z
|
return z
|
||||||
|
@ -41,7 +47,10 @@ const [Form, formApi] = useVbenForm({
|
||||||
rules: 'required',
|
rules: 'required',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
component: 'InputPassword',
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
type: 'password',
|
||||||
|
},
|
||||||
dependencies: {
|
dependencies: {
|
||||||
rules(values) {
|
rules(values) {
|
||||||
return z
|
return z
|
||||||
|
|
|
@ -192,9 +192,9 @@ onMounted(() => {
|
||||||
{{ item.socialUser?.nickname || item.socialUser?.openid }}
|
{{ item.socialUser?.nickname || item.socialUser?.openid }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
绑定{{
|
绑定
|
||||||
getDictLabel(DICT_TYPE.SYSTEM_SOCIAL_TYPE, item.type)
|
{{ getDictLabel(DICT_TYPE.SYSTEM_SOCIAL_TYPE, item.type) }}
|
||||||
}}账号
|
账号
|
||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue