mirror of
https://github.com/continew-org/continew-admin-ui.git
synced 2025-09-10 18:58:37 +08:00
feat: 新增上传个人头像
This commit is contained in:
@@ -3,6 +3,11 @@ import type * as System from '@/apis/system/type'
|
|||||||
|
|
||||||
const BASE_URL = '/system/user'
|
const BASE_URL = '/system/user'
|
||||||
|
|
||||||
|
/** @desc 上传头像 */
|
||||||
|
export function uploadAvatar(data: FormData) {
|
||||||
|
return http.post(`${BASE_URL}/avatar`, data)
|
||||||
|
}
|
||||||
|
|
||||||
/** @desc 修改用户基本信息 */
|
/** @desc 修改用户基本信息 */
|
||||||
export function updateUserBaseInfo(data: { nickname: string; gender: number }) {
|
export function updateUserBaseInfo(data: { nickname: string; gender: number }) {
|
||||||
return http.patch(`${BASE_URL}/basic/info`, data)
|
return http.patch(`${BASE_URL}/basic/info`, data)
|
||||||
|
@@ -3,14 +3,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import Dayjs from 'dayjs'
|
|
||||||
import { useAppStore } from '@/stores'
|
import { useAppStore } from '@/stores'
|
||||||
|
|
||||||
const appStore = useAppStore()
|
const appStore = useAppStore()
|
||||||
|
|
||||||
defineOptions({ name: 'GiFooter' })
|
defineOptions({ name: 'GiFooter' })
|
||||||
|
|
||||||
const year = Dayjs(new Date()).format('YYYY')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { useUserStore, useRouteStore, useAppStore } from '@/stores'
|
import { useUserStore, useRouteStore } from '@/stores'
|
||||||
import { getToken } from '@/utils/auth'
|
import { getToken } from '@/utils/auth'
|
||||||
import { isHttp } from '@/utils/validate'
|
import { isHttp } from '@/utils/validate'
|
||||||
|
|
||||||
|
@@ -26,7 +26,7 @@ export function downloadByUrl({
|
|||||||
}): Promise<boolean> {
|
}): Promise<boolean> {
|
||||||
// 是否同源
|
// 是否同源
|
||||||
const isSameHost = new URL(url).host == location.host
|
const isSameHost = new URL(url).host == location.host
|
||||||
return new Promise<boolean>((resolve, reject) => {
|
return new Promise<boolean>((resolve) => {
|
||||||
if (isSameHost) {
|
if (isSameHost) {
|
||||||
const link = document.createElement('a')
|
const link = document.createElement('a')
|
||||||
link.href = url
|
link.href = url
|
||||||
|
@@ -177,7 +177,7 @@ const del = <T = any>(url: string, params?: object, config?: AxiosRequestConfig)
|
|||||||
...config
|
...config
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const download = <T = any>(url: string, params?: object, config?: AxiosRequestConfig): Promise<AxiosResponse> => {
|
const download = (url: string, params?: object, config?: AxiosRequestConfig): Promise<AxiosResponse> => {
|
||||||
return requestNative({
|
return requestNative({
|
||||||
method: 'get',
|
method: 'get',
|
||||||
url,
|
url,
|
||||||
|
@@ -37,7 +37,6 @@ import { getImageCaptcha } from '@/apis'
|
|||||||
import { Message, type FormInstance } from '@arco-design/web-vue'
|
import { Message, type FormInstance } from '@arco-design/web-vue'
|
||||||
import { useUserStore } from '@/stores'
|
import { useUserStore } from '@/stores'
|
||||||
import { useStorage } from '@vueuse/core'
|
import { useStorage } from '@vueuse/core'
|
||||||
import { useLoading } from '@/hooks'
|
|
||||||
import { encryptByRsa } from '@/utils/encrypt'
|
import { encryptByRsa } from '@/utils/encrypt'
|
||||||
|
|
||||||
const loginConfig = useStorage('login-config', {
|
const loginConfig = useStorage('login-config', {
|
||||||
|
@@ -1,54 +0,0 @@
|
|||||||
<template>
|
|
||||||
<a-model v-model:visible="visible">
|
|
||||||
<div class="cropper">
|
|
||||||
// 裁剪左侧内容
|
|
||||||
<div class="cropper_left">
|
|
||||||
<vueCropper
|
|
||||||
:tyle="{ width: '400px' }"
|
|
||||||
ref="cropperRef"
|
|
||||||
:img="options.img"
|
|
||||||
:info="true"
|
|
||||||
:info-true="options.infoTrue"
|
|
||||||
:auto-crop="options.autoCrop"
|
|
||||||
:fixed-box="options.fixedBox"
|
|
||||||
:can-move="options.canMoveBox"
|
|
||||||
:can-scale="options.canScale"
|
|
||||||
:fixed-number="fixedNumber"
|
|
||||||
:fixed="options.fixed"
|
|
||||||
:full="options.full"
|
|
||||||
:center-box="options.centerBox"
|
|
||||||
@real-time="previewHandle"
|
|
||||||
/>
|
|
||||||
<div class="reupload_box">
|
|
||||||
<div class="reupload_text" @click="uploadFile('reload')">重新上传</div>
|
|
||||||
<div>
|
|
||||||
<el-icon class="rotate_right" @click="changeScale(1)">
|
|
||||||
<CirclePlus />
|
|
||||||
</el-icon>
|
|
||||||
<el-icon class="rotate_right" @click="changeScale(-1)">
|
|
||||||
<Remove />
|
|
||||||
</el-icon>
|
|
||||||
<el-icon class="rotate_right" @click="rotateRight">
|
|
||||||
<RefreshRight />
|
|
||||||
</el-icon>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="cropper_right">
|
|
||||||
<div class="preview_text">预览</div>
|
|
||||||
<div :style="getStyle" class="previewImg">
|
|
||||||
<div :style="previewFileStyle">
|
|
||||||
<img :style="previews.img" :src="previews.url" alt="" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</a-model>
|
|
||||||
</template>
|
|
||||||
<script setup lang="ts">
|
|
||||||
import 'vue-cropper/dist/index.css'
|
|
||||||
import VueCropper from 'vue-cropper'
|
|
||||||
import { ref } from 'vue'
|
|
||||||
|
|
||||||
const visible = ref(true)
|
|
||||||
</script>
|
|
77
src/views/setting/profile/BasicInfoUpdateModal.vue
Normal file
77
src/views/setting/profile/BasicInfoUpdateModal.vue
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<a-modal v-model:visible="visible" title="修改基本信息" @before-ok="save" @close="reset">
|
||||||
|
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
|
||||||
|
</a-modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { updateUserBaseInfo } from '@/apis'
|
||||||
|
import { Message } from '@arco-design/web-vue'
|
||||||
|
import { GiForm, type Columns } from '@/components/GiForm'
|
||||||
|
import { useForm } from '@/hooks'
|
||||||
|
import { useUserStore } from '@/stores'
|
||||||
|
|
||||||
|
const options: Options = {
|
||||||
|
form: {},
|
||||||
|
col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 },
|
||||||
|
btns: { hide: true }
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns: Columns = [
|
||||||
|
{
|
||||||
|
label: '昵称',
|
||||||
|
field: 'nickname',
|
||||||
|
type: 'input',
|
||||||
|
rules: [{ required: true, message: '请输入昵称' }]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '性别',
|
||||||
|
field: 'gender',
|
||||||
|
type: 'radio-group',
|
||||||
|
options: [
|
||||||
|
{ label: '男', value: 1 },
|
||||||
|
{ label: '女', value: 2 },
|
||||||
|
{ label: '未知', value: 0, disabled: true }
|
||||||
|
],
|
||||||
|
rules: [{ required: true, message: '请选择性别' }]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const userStore = useUserStore()
|
||||||
|
const userInfo = computed(() => userStore.userInfo)
|
||||||
|
const { form, resetForm } = useForm({
|
||||||
|
nickname: userInfo.value.nickname,
|
||||||
|
gender: userInfo.value.gender
|
||||||
|
})
|
||||||
|
|
||||||
|
const formRef = ref<InstanceType<typeof GiForm>>()
|
||||||
|
// 重置
|
||||||
|
const reset = () => {
|
||||||
|
formRef.value?.formRef?.resetFields()
|
||||||
|
resetForm()
|
||||||
|
}
|
||||||
|
|
||||||
|
const visible = ref(false)
|
||||||
|
// 修改
|
||||||
|
const onUpdate = async () => {
|
||||||
|
reset()
|
||||||
|
visible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// 保存
|
||||||
|
const save = async () => {
|
||||||
|
const isInvalid = await formRef.value?.formRef?.validate()
|
||||||
|
if (isInvalid) return false
|
||||||
|
try {
|
||||||
|
await updateUserBaseInfo(form)
|
||||||
|
Message.success('修改成功')
|
||||||
|
// 修改成功后,重新获取用户信息
|
||||||
|
await userStore.getInfo()
|
||||||
|
return true
|
||||||
|
} catch (error) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defineExpose({ onUpdate })
|
||||||
|
</script>
|
@@ -2,9 +2,21 @@
|
|||||||
<a-card title="基本信息" bordered class="gradient-card">
|
<a-card title="基本信息" bordered class="gradient-card">
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<section>
|
<section>
|
||||||
<div class="avatar">
|
<a-upload
|
||||||
<img :src="userStore.avatar" alt="avatar" />
|
:file-list="avatarList"
|
||||||
</div>
|
accept="image/*"
|
||||||
|
:show-file-list="false"
|
||||||
|
list-type="picture-card"
|
||||||
|
:show-upload-button="true"
|
||||||
|
:on-before-upload="onBeforeUpload"
|
||||||
|
>
|
||||||
|
<template #upload-button>
|
||||||
|
<a-avatar :size="100">
|
||||||
|
<template #trigger-icon><icon-camera /></template>
|
||||||
|
<img v-if="avatarList.length" :src="avatarList[0].url" alt="avatar" />
|
||||||
|
</a-avatar>
|
||||||
|
</template>
|
||||||
|
</a-upload>
|
||||||
<div class="name">
|
<div class="name">
|
||||||
<span style="margin-right: 10px">{{ userInfo.nickname }}</span>
|
<span style="margin-right: 10px">{{ userInfo.nickname }}</span>
|
||||||
<icon-edit :size="16" class="btn" @click="onUpdate" />
|
<icon-edit :size="16" class="btn" @click="onUpdate" />
|
||||||
@@ -44,84 +56,146 @@
|
|||||||
<div class="footer">注册于 {{ userInfo.registrationDate }}</div>
|
<div class="footer">注册于 {{ userInfo.registrationDate }}</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
|
||||||
<a-modal v-model:visible="visible" title="修改基本信息" @before-ok="save" @close="reset">
|
<a-modal v-model:visible="visible" title="上传头像" :width="400" :footer="false" @close="reset">
|
||||||
<GiForm ref="formRef" v-model="form" :options="options" :columns="columns" />
|
<a-row>
|
||||||
|
<a-col :span="14" style="width: 200px; height: 200px">
|
||||||
|
<vue-cropper
|
||||||
|
ref="cropperRef"
|
||||||
|
:img="options.img"
|
||||||
|
:info="true"
|
||||||
|
:auto-crop="options.autoCrop"
|
||||||
|
:auto-crop-width="options.autoCropWidth"
|
||||||
|
:auto-crop-height="options.autoCropHeight"
|
||||||
|
:fixed-box="options.fixedBox"
|
||||||
|
:fixed="options.fixed"
|
||||||
|
:full="options.full"
|
||||||
|
:center-box="options.centerBox"
|
||||||
|
:can-move="options.canMove"
|
||||||
|
:output-type="options.outputType"
|
||||||
|
:output-size="options.outputSize"
|
||||||
|
@real-time="handleRealTime"
|
||||||
|
/>
|
||||||
|
</a-col>
|
||||||
|
<a-col :span="10" style="display: flex; justify-content: center">
|
||||||
|
<div :style="previewStyle">
|
||||||
|
<div :style="previews.div">
|
||||||
|
<img :src="previews.url" :style="previews.img" alt="" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</a-col>
|
||||||
|
</a-row>
|
||||||
|
<div style="text-align: center; padding-top: 30px">
|
||||||
|
<a-space>
|
||||||
|
<a-button type="primary" @click="handleUpload">确定</a-button>
|
||||||
|
<a-button @click="reset">取消</a-button>
|
||||||
|
</a-space>
|
||||||
|
</div>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
<BasicInfoUpdateModal ref="BasicInfoUpdateModalRef" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { updateUserBaseInfo, updateUserPassword } from '@/apis'
|
import { uploadAvatar } from '@/apis'
|
||||||
import { Message } from '@arco-design/web-vue'
|
import BasicInfoUpdateModal from './BasicInfoUpdateModal.vue'
|
||||||
import { type Columns, GiForm } from '@/components/GiForm'
|
import { Message, type FileItem } from '@arco-design/web-vue'
|
||||||
import { useForm } from '@/hooks'
|
import { VueCropper } from 'vue-cropper'
|
||||||
|
import 'vue-cropper/dist/index.css'
|
||||||
import { useUserStore } from '@/stores'
|
import { useUserStore } from '@/stores'
|
||||||
import { encryptByRsa } from '@/utils/encrypt'
|
import getAvatar from '@/utils/avatar'
|
||||||
|
|
||||||
const userStore = useUserStore()
|
const userStore = useUserStore()
|
||||||
const userInfo = computed(() => userStore.userInfo)
|
const userInfo = computed(() => userStore.userInfo)
|
||||||
const formRef = ref<InstanceType<typeof GiForm>>()
|
|
||||||
|
|
||||||
const options: Options = {
|
const avatar = {
|
||||||
form: {},
|
uid: '-2',
|
||||||
col: { xs: 24, sm: 24, md: 24, lg: 24, xl: 24, xxl: 24 },
|
name: 'avatar.png',
|
||||||
btns: { hide: true }
|
url: userInfo.value.avatar
|
||||||
}
|
}
|
||||||
|
const avatarList = ref<FileItem[]>([avatar])
|
||||||
const columns: Columns = [
|
const fileRef = ref(reactive({ name: 'avatar.png' }))
|
||||||
{
|
const options: cropperOptions = reactive({
|
||||||
label: '昵称',
|
img: '',
|
||||||
field: 'nickname',
|
autoCrop: true,
|
||||||
type: 'input',
|
autoCropWidth: 160,
|
||||||
rules: [{ required: true, message: '请输入昵称' }]
|
autoCropHeight: 160,
|
||||||
},
|
fixedBox: true,
|
||||||
{
|
fixed: true,
|
||||||
label: '性别',
|
full: false,
|
||||||
field: 'gender',
|
centerBox: true,
|
||||||
type: 'radio-group',
|
canMove: true,
|
||||||
options: [
|
outputSize: 1,
|
||||||
{ label: '男', value: 1 },
|
outputType: 'png'
|
||||||
{ label: '女', value: 2 },
|
|
||||||
{ label: '未知', value: 0, disabled: true }
|
|
||||||
],
|
|
||||||
rules: [{ required: true, message: '请选择性别' }]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
const { form, resetForm } = useForm({
|
|
||||||
nickname: userInfo.value.nickname,
|
|
||||||
gender: userInfo.value.gender
|
|
||||||
})
|
})
|
||||||
|
const visible = ref(false)
|
||||||
|
// 打开裁剪框
|
||||||
|
const onBeforeUpload = (file: File): boolean => {
|
||||||
|
fileRef.value = file
|
||||||
|
const reader = new FileReader()
|
||||||
|
reader.readAsDataURL(file)
|
||||||
|
reader.onload = () => {
|
||||||
|
options.img = reader.result
|
||||||
|
}
|
||||||
|
visible.value = true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
formRef.value?.formRef?.resetFields()
|
fileRef.value = { name: '' }
|
||||||
resetForm()
|
options.img = ''
|
||||||
|
visible.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const visible = ref(false)
|
const previews: any = ref({})
|
||||||
// 修改
|
const previewStyle: any = ref({})
|
||||||
const onUpdate = async () => {
|
// 实时预览
|
||||||
reset()
|
const handleRealTime = (data: any) => {
|
||||||
visible.value = true
|
previewStyle.value = {
|
||||||
}
|
width: `${data.w}px`,
|
||||||
|
height: `${data.h}px`,
|
||||||
// 保存
|
overflow: 'hidden',
|
||||||
const save = async () => {
|
margin: '0',
|
||||||
const isInvalid = await formRef.value?.formRef?.validate()
|
zoom: 100 / data.h,
|
||||||
if (isInvalid) return false
|
borderRadius: '50%'
|
||||||
try {
|
|
||||||
await updateUserBaseInfo(form)
|
|
||||||
Message.success('修改成功')
|
|
||||||
// 修改成功后,重新获取用户信息
|
|
||||||
await userStore.getInfo()
|
|
||||||
return true
|
|
||||||
} catch (error) {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
previews.value = data
|
||||||
|
}
|
||||||
|
|
||||||
|
const cropperRef = ref()
|
||||||
|
// 上传头像
|
||||||
|
const handleUpload = async () => {
|
||||||
|
cropperRef.value.getCropBlob((data: any) => {
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('avatarFile', data, fileRef.value?.name)
|
||||||
|
uploadAvatar(formData).then((res) => {
|
||||||
|
userInfo.value.avatar = res.data.avatar
|
||||||
|
avatarList.value[0].url = getAvatar(res.data.avatar, undefined)
|
||||||
|
reset()
|
||||||
|
Message.success('更新成功')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const BasicInfoUpdateModalRef = ref<InstanceType<typeof BasicInfoUpdateModal>>()
|
||||||
|
// 修改基本信息
|
||||||
|
const onUpdate = async () => {
|
||||||
|
BasicInfoUpdateModalRef.value?.onUpdate()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
:deep(.arco-avatar-trigger-icon-button) {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
line-height: 32px;
|
||||||
|
background-color: #e8f3ff;
|
||||||
|
.arco-icon-camera {
|
||||||
|
margin-top: 8px;
|
||||||
|
color: rgb(var(--arcoblue-6));
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.body {
|
.body {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -137,11 +211,6 @@ const save = async () => {
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 32px 0 50px;
|
padding: 32px 0 50px;
|
||||||
.avatar > img {
|
|
||||||
width: 80px;
|
|
||||||
height: 80px;
|
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
.name {
|
.name {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
<div class="sub-text-wrapper">
|
<div class="sub-text-wrapper">
|
||||||
<div class="sub-text">无操作登录会话保持<span class="sub-text-value">30</span>分钟,超时登录会话将失效</div>
|
<div class="sub-text">无操作登录会话保持<span class="sub-text-value">30</span>分钟,超时登录会话将失效</div>
|
||||||
<div class="sub-text">登录会话最大保持<span class="sub-text-value">0</span>天,超时登录会话将失效</div>
|
<div class="sub-text">登录会话最大保持<span class="sub-text-value">0</span>天,超时登录会话将失效</div>
|
||||||
<a-link class="link">修改规则(未开放)</a-link class="link">
|
<a-link class="link">修改规则(未开放)</a-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</a-card>
|
</a-card>
|
||||||
|
@@ -20,16 +20,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { Message } from '@arco-design/web-vue'
|
|
||||||
import BasicsSetting from './BasicsSetting.vue'
|
import BasicsSetting from './BasicsSetting.vue'
|
||||||
import SessionSetting from './SessionSetting.vue'
|
import SessionSetting from './SessionSetting.vue'
|
||||||
import PasswordPolicy from './PasswordPolicy.vue'
|
import PasswordPolicy from './PasswordPolicy.vue'
|
||||||
import AccountProtection from './AccountProtection.vue'
|
import AccountProtection from './AccountProtection.vue'
|
||||||
|
|
||||||
defineOptions({ name: 'SettingSecurity' })
|
defineOptions({ name: 'SettingSecurity' })
|
||||||
|
|
||||||
const route = useRoute()
|
|
||||||
const form = reactive({ name: '' })
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@@ -179,6 +179,7 @@ const getMenuAllCheckedKeys = () => {
|
|||||||
// 获取半选中的菜单
|
// 获取半选中的菜单
|
||||||
const halfCheckedNodes = menuTreeRef.value?.getHalfCheckedNodes()
|
const halfCheckedNodes = menuTreeRef.value?.getHalfCheckedNodes()
|
||||||
const halfCheckedKeys = halfCheckedNodes.map((item: TreeNodeData) => item.key)
|
const halfCheckedKeys = halfCheckedNodes.map((item: TreeNodeData) => item.key)
|
||||||
|
// eslint-disable-next-line prefer-spread
|
||||||
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
|
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
|
||||||
return checkedKeys
|
return checkedKeys
|
||||||
}
|
}
|
||||||
@@ -194,6 +195,7 @@ const getDeptAllCheckedKeys = () => {
|
|||||||
// 获取半选中的部门
|
// 获取半选中的部门
|
||||||
const halfCheckedNodes = deptTreeRef.value?.getHalfCheckedNodes()
|
const halfCheckedNodes = deptTreeRef.value?.getHalfCheckedNodes()
|
||||||
const halfCheckedKeys = halfCheckedNodes.map((item: TreeNodeData) => item.key)
|
const halfCheckedKeys = halfCheckedNodes.map((item: TreeNodeData) => item.key)
|
||||||
|
// eslint-disable-next-line prefer-spread
|
||||||
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
|
checkedKeys.unshift.apply(checkedKeys, halfCheckedKeys)
|
||||||
return checkedKeys
|
return checkedKeys
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user