上传头像 部分卡片加入模型选择
This commit is contained in:
@@ -9,10 +9,11 @@ import request from '@/utils/request'
|
|||||||
export interface getSketchFlowCanvasData {
|
export interface getSketchFlowCanvasData {
|
||||||
id: string
|
id: string
|
||||||
}
|
}
|
||||||
export const getSketchFlowCanvas = (data:getSketchFlowCanvasData) => {
|
export const getSketchFlowCanvas = (data:getSketchFlowCanvasData,loading?:boolean) => {
|
||||||
return request({
|
return request({
|
||||||
url: `/api/canvas/detail/${data.id}`,
|
url: `/api/canvas/detail/${data.id}`,
|
||||||
method: 'get',
|
method: 'get',
|
||||||
|
loading
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,14 +28,15 @@ export interface saveSketchFlowCanvasData {
|
|||||||
id?: string
|
id?: string
|
||||||
canvasData: string
|
canvasData: string
|
||||||
}
|
}
|
||||||
export const putSketchFlowCanvas = (data:saveSketchFlowCanvasData) => {
|
export const putSketchFlowCanvas = (data:saveSketchFlowCanvasData,loading?:boolean) => {
|
||||||
return request({
|
return request({
|
||||||
url: `/api/canvas/detail/${data.id}`,
|
url: `/api/canvas/detail/${data.id}`,
|
||||||
method: 'put',
|
method: 'put',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
data: data.canvasData
|
data: data.canvasData,
|
||||||
|
loading
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,6 +114,7 @@ export const toRealStyleApi = (data:toRealStyleData) => {
|
|||||||
* @param data.imageUrl 进行生成的图片。minio地址和正常地址都可以
|
* @param data.imageUrl 进行生成的图片。minio地址和正常地址都可以
|
||||||
* @param data.variantCount 生成图片的数量
|
* @param data.variantCount 生成图片的数量
|
||||||
* @param data.colors 生成上色的图片颜色列表
|
* @param data.colors 生成上色的图片颜色列表
|
||||||
|
* @param data.mode 选择的模型
|
||||||
* @returns 线稿图上色
|
* @returns 线稿图上色
|
||||||
*/
|
*/
|
||||||
export interface toColorPaletteData {
|
export interface toColorPaletteData {
|
||||||
@@ -119,6 +122,7 @@ export interface toColorPaletteData {
|
|||||||
imageUrl?: string
|
imageUrl?: string
|
||||||
variantCount?: string
|
variantCount?: string
|
||||||
colors?: Array<string>
|
colors?: Array<string>
|
||||||
|
mode?: string
|
||||||
}
|
}
|
||||||
export const toColorPaletteApi = (data:toColorPaletteData) => {
|
export const toColorPaletteApi = (data:toColorPaletteData) => {
|
||||||
return request({
|
return request({
|
||||||
@@ -128,7 +132,8 @@ export const toColorPaletteApi = (data:toColorPaletteData) => {
|
|||||||
sketchId: data.sketchId,
|
sketchId: data.sketchId,
|
||||||
imageUrl: data.imageUrl,
|
imageUrl: data.imageUrl,
|
||||||
variantCount: data.variantCount,
|
variantCount: data.variantCount,
|
||||||
colors: data.colors
|
colors: data.colors,
|
||||||
|
mode: data.mode,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -140,6 +145,7 @@ export const toColorPaletteApi = (data:toColorPaletteData) => {
|
|||||||
* @param data.imageUrl 进行生成的图片。minio地址和正常地址都可以
|
* @param data.imageUrl 进行生成的图片。minio地址和正常地址都可以
|
||||||
* @param data.styles 生成上色的图片颜色列表
|
* @param data.styles 生成上色的图片颜色列表
|
||||||
* @param data.userPrompt 生成上色的图片颜色列表
|
* @param data.userPrompt 生成上色的图片颜色列表
|
||||||
|
* @param data.mode 选择的模型
|
||||||
* @returns 场景构图
|
* @returns 场景构图
|
||||||
*/
|
*/
|
||||||
export interface toSceneCompositionData {
|
export interface toSceneCompositionData {
|
||||||
@@ -147,6 +153,7 @@ export interface toSceneCompositionData {
|
|||||||
imageUrl?: string
|
imageUrl?: string
|
||||||
userPrompt?: string
|
userPrompt?: string
|
||||||
styles?: Array<string>
|
styles?: Array<string>
|
||||||
|
mode?: string
|
||||||
}
|
}
|
||||||
export const toSceneCompositionApi = (data:toSceneCompositionData) => {
|
export const toSceneCompositionApi = (data:toSceneCompositionData) => {
|
||||||
return request({
|
return request({
|
||||||
@@ -156,8 +163,83 @@ export const toSceneCompositionApi = (data:toSceneCompositionData) => {
|
|||||||
sketchId: data.sketchId,
|
sketchId: data.sketchId,
|
||||||
imageUrl: data.imageUrl,
|
imageUrl: data.imageUrl,
|
||||||
userPrompt: data.userPrompt,
|
userPrompt: data.userPrompt,
|
||||||
styles: data.styles
|
styles: data.styles,
|
||||||
|
mode: data.mode,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 线稿贴印花
|
||||||
|
* @param data 线稿贴印花的参数
|
||||||
|
* @param data.sketchId sketch id
|
||||||
|
* @param data.imageUrl 进行生成的图片。minio地址和正常地址都可以
|
||||||
|
* @param data.styles 生成上色的图片颜色列表
|
||||||
|
* @param data.userPrompt 生成上色的图片颜色列表
|
||||||
|
* @param data.mode 选择的模型
|
||||||
|
* @returns 线稿贴印花
|
||||||
|
*/
|
||||||
|
export interface sketchAddPrintData {
|
||||||
|
sketchId?: string
|
||||||
|
imageUrl?: string
|
||||||
|
surFaceUrl?: string
|
||||||
|
userPrompt?: string
|
||||||
|
mode?: string
|
||||||
|
}
|
||||||
|
export const sketchAddPrintApi = (data:sketchAddPrintData) => {
|
||||||
|
return request({
|
||||||
|
url: `/api/image/surface-edit`,
|
||||||
|
method: 'post',
|
||||||
|
data:{
|
||||||
|
sketchId: data.sketchId,
|
||||||
|
imageUrl: data.imageUrl,
|
||||||
|
userPrompt: data.userPrompt,
|
||||||
|
surFaceUrl: data.surFaceUrl,
|
||||||
|
mode: data.mode,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 图片转3d
|
||||||
|
* @param data 图片转3d的参数
|
||||||
|
* @param data.sketchId sketch id
|
||||||
|
* @param data.imageUrls 进行生成的图片。minio地址和正常地址都可以
|
||||||
|
* @returns 图片转3d
|
||||||
|
*/
|
||||||
|
export interface sketchToThreeData {
|
||||||
|
sketchId?: string
|
||||||
|
imageUrls?: Array<string>
|
||||||
|
}
|
||||||
|
export const sketchToThreeApi = (data:sketchToThreeData) => {
|
||||||
|
return request({
|
||||||
|
url: `/api/image/img-to-3d`,
|
||||||
|
method: 'post',
|
||||||
|
data:{
|
||||||
|
sketchId: data.sketchId,
|
||||||
|
imageUrls: data.imageUrls,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 3d模型转3视图
|
||||||
|
* @param data 3d模型转3视图的参数
|
||||||
|
* @param data.sketchId sketch id
|
||||||
|
* @param data.glbUrl 生成的3d模型地址
|
||||||
|
* @returns 3d模型转3视图
|
||||||
|
*/
|
||||||
|
export interface threeToThreeViewsData {
|
||||||
|
sketchId?: string
|
||||||
|
glbUrl?: string
|
||||||
|
}
|
||||||
|
export const threeToThreeViewsApi = (data:threeToThreeViewsData) => {
|
||||||
|
return request({
|
||||||
|
url: `/api/image/glb-to-3views`,
|
||||||
|
method: 'post',
|
||||||
|
data:{
|
||||||
|
sketchId: data.sketchId,
|
||||||
|
glbUrl: data.glbUrl,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
|
||||||
export const uploadImage = (data: FormData) => {
|
export const uploadImage = (data: FormData, loading = false) => {
|
||||||
return request({
|
return request({
|
||||||
url: '/api/file/upload',
|
url: '/api/file/upload',
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
loading,
|
||||||
data
|
data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,3 +109,27 @@ export const UpdateUserProfile = (data, loading = false) => {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传头像
|
||||||
|
* @param data 上传头像的参数
|
||||||
|
* @param data.avatar 头像文件
|
||||||
|
* @returns 上传头像成功的响应
|
||||||
|
*/
|
||||||
|
export const UpdateUserAvatar = (data) => {
|
||||||
|
return request({
|
||||||
|
url: '/api/user/avatar',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取上传头像次数
|
||||||
|
*/
|
||||||
|
export const getAvatarLimit = () => {
|
||||||
|
return request({
|
||||||
|
url: '/api/user/avatar/limit',
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- 颜色调色板 -->
|
<!-- 颜色调色板 -->
|
||||||
<div class="color-palette">
|
<div class="color-palette">
|
||||||
|
<p class="label">Mode</p>
|
||||||
|
<my-select v-model="data.mode" :list="modeList" />
|
||||||
<p class="label">Choose Color</p>
|
<p class="label">Choose Color</p>
|
||||||
<div class="color-list">
|
<div class="color-list">
|
||||||
<div
|
<div
|
||||||
@@ -24,7 +26,8 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted, ref } from 'vue'
|
import { reactive, onMounted, ref } from 'vue'
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
colors: []
|
colors: [],
|
||||||
|
mode: 'Advanced',
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['update-data'])
|
const emit = defineEmits(['update-data'])
|
||||||
const maxColor = 5
|
const maxColor = 5
|
||||||
@@ -41,11 +44,15 @@
|
|||||||
const target = e.target as HTMLInputElement
|
const target = e.target as HTMLInputElement
|
||||||
data.colors.push(target.value)
|
data.colors.push(target.value)
|
||||||
}
|
}
|
||||||
|
const modeList = ref([
|
||||||
|
{ value: 'Advanced', label: 'Advanced' },
|
||||||
|
{ value: 'Normal', label: 'Normal' }
|
||||||
|
])
|
||||||
const getApiData = ()=>{
|
const getApiData = ()=>{
|
||||||
return {
|
return {
|
||||||
variantCount: '2',
|
variantCount: '2',
|
||||||
colors: data.colors
|
colors: data.colors,
|
||||||
|
mode: data.mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
import To3View from './to-3view.vue'
|
import To3View from './to-3view.vue'
|
||||||
import To3DModel from './to-3d-model.vue'
|
import To3DModel from './to-3d-model.vue'
|
||||||
|
|
||||||
import { toRealStyleApi, toColorPaletteApi, toSceneCompositionApi } from '@/api/flow-canvas'
|
import { toRealStyleApi, toColorPaletteApi, toSceneCompositionApi, sketchAddPrintApi, sketchToThreeApi, threeToThreeViewsApi } from '@/api/flow-canvas'
|
||||||
|
|
||||||
// import ToVideo from './to-video.vue'
|
// import ToVideo from './to-video.vue'
|
||||||
// import AddPrint from './add-print.vue'
|
// import AddPrint from './add-print.vue'
|
||||||
@@ -62,6 +62,7 @@
|
|||||||
type: NODE_DATATYPE.SURFACE_EDIT,
|
type: NODE_DATATYPE.SURFACE_EDIT,
|
||||||
title: 'Surface Edit',
|
title: 'Surface Edit',
|
||||||
component: SurfaceEdit,
|
component: SurfaceEdit,
|
||||||
|
api: sketchAddPrintApi
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
tier: NODE_DATATIER.SCENE_COMPOSITION,
|
tier: NODE_DATATIER.SCENE_COMPOSITION,
|
||||||
@@ -81,13 +82,15 @@
|
|||||||
tier: NODE_DATATIER.TO_3D_MODEL,
|
tier: NODE_DATATIER.TO_3D_MODEL,
|
||||||
type: NODE_DATATYPE.TO_3D_MODEL,
|
type: NODE_DATATYPE.TO_3D_MODEL,
|
||||||
title: 'To 3D Model',
|
title: 'To 3D Model',
|
||||||
component: To3DModel
|
component: To3DModel,
|
||||||
|
api:sketchToThreeApi
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
tier: NODE_DATATIER.TO_3VIEW,
|
tier: NODE_DATATIER.TO_3VIEW,
|
||||||
type: NODE_DATATYPE.TO_3VIEW,
|
type: NODE_DATATYPE.TO_3VIEW,
|
||||||
title: 'To 3-View',
|
title: 'To 3-View',
|
||||||
component: To3View
|
component: To3View,
|
||||||
|
api:threeToThreeViewsApi
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
const nodeManager = inject('nodeManager') as any
|
const nodeManager = inject('nodeManager') as any
|
||||||
@@ -133,7 +136,7 @@
|
|||||||
...data,
|
...data,
|
||||||
}
|
}
|
||||||
const taskList = await currentComponent.value.api(apiData).then((rv)=>{
|
const taskList = await currentComponent.value.api(apiData).then((rv)=>{
|
||||||
return rv
|
return [rv]
|
||||||
}) || []
|
}) || []
|
||||||
// const taskList = [{taskId:'123'}]
|
// const taskList = [{taskId:'123'}]
|
||||||
// if (!subordNode) {
|
// if (!subordNode) {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
<div class="scene-composition">
|
<div class="scene-composition">
|
||||||
<p class="label">Prompt</p>
|
<p class="label">Prompt</p>
|
||||||
<my-textarea v-model="data.prompt" />
|
<my-textarea v-model="data.prompt" />
|
||||||
|
<p class="label">Mode</p>
|
||||||
|
<my-select v-model="data.mode" :list="modeList" />
|
||||||
<p class="label">Choose Style</p>
|
<p class="label">Choose Style</p>
|
||||||
<div class="style-list">
|
<div class="style-list">
|
||||||
<div
|
<div
|
||||||
@@ -47,8 +49,13 @@
|
|||||||
])
|
])
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
prompt: '',
|
prompt: '',
|
||||||
styles: ['Colorful', 'Modernist']
|
styles: ['Colorful', 'Modernist'],
|
||||||
|
mode: 'Advanced',
|
||||||
})
|
})
|
||||||
|
const modeList = ref([
|
||||||
|
{ value: 'Advanced', label: 'Advanced' },
|
||||||
|
{ value: 'Normal', label: 'Normal' }
|
||||||
|
])
|
||||||
const onClickStyle = (value: string) => {
|
const onClickStyle = (value: string) => {
|
||||||
if (data.styles.includes(value)) {
|
if (data.styles.includes(value)) {
|
||||||
data.styles = data.styles.filter((v) => v !== value)
|
data.styles = data.styles.filter((v) => v !== value)
|
||||||
@@ -60,6 +67,7 @@
|
|||||||
return {
|
return {
|
||||||
styles: data.styles,
|
styles: data.styles,
|
||||||
userPrompt: data.prompt,
|
userPrompt: data.prompt,
|
||||||
|
mode: data.mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
defineExpose({ data, getApiData })
|
defineExpose({ data, getApiData })
|
||||||
|
|||||||
@@ -3,21 +3,35 @@
|
|||||||
<div class="surface-edit">
|
<div class="surface-edit">
|
||||||
<p class="label">Image</p>
|
<p class="label">Image</p>
|
||||||
<upload-file v-model="data.file" />
|
<upload-file v-model="data.file" />
|
||||||
|
<p class="label">Mode</p>
|
||||||
|
<my-select v-model="data.mode" :list="modeList" />
|
||||||
<p class="label">Prompt</p>
|
<p class="label">Prompt</p>
|
||||||
<my-textarea v-model="data.prompt" />
|
<my-textarea v-model="data.prompt" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted } from 'vue'
|
import { reactive, ref, onMounted } from 'vue'
|
||||||
import myTextarea from '../../tools/my-textarea.vue'
|
import myTextarea from '../../tools/my-textarea.vue'
|
||||||
import uploadFile from '../../tools/upload-file.vue'
|
import uploadFile from '../../tools/upload-file.vue'
|
||||||
|
import mySelect from '../../tools/my-select.vue'
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
prompt: '',
|
prompt: '',
|
||||||
file: null
|
file: null,
|
||||||
|
mode: 'Advanced',
|
||||||
})
|
})
|
||||||
|
const modeList = ref([
|
||||||
defineExpose({ data })
|
{ value: 'Advanced', label: 'Advanced' },
|
||||||
|
{ value: 'Normal', label: 'Normal' }
|
||||||
|
])
|
||||||
|
const getApiData = ()=>{
|
||||||
|
return {
|
||||||
|
mode: data.mode,
|
||||||
|
surFaceUrl: data.file,
|
||||||
|
userPrompt: data.prompt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ data,getApiData })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
|
|||||||
@@ -3,30 +3,38 @@
|
|||||||
<div class="to-3d-model">
|
<div class="to-3d-model">
|
||||||
<p class="label">Image</p>
|
<p class="label">Image</p>
|
||||||
<div class="image">
|
<div class="image">
|
||||||
<img src="https://s3-alpha-sig.figma.com/img/ea2f/590e/9638f62a2fc91e31f33db0022db1642c?Expires=1773014400&Key-Pair-Id=APKAQ4GOSFWCW27IBOMQ&Signature=M0B8oJJOk~dGG0aZAqOIocAp7T0LFdJ9FYmCrEZVTCRzYxM6SJRNtYMTX-rTO3Z~s14QINh~o-S41XiZnBv-0zcKjuWot~VVaNHfd0~1LesfNe2KwvCinT~72btFut1pheLnKE-wWCX5ewtonxU77bnw386YPMTqv7DBZzksf2udsJA7NmOYD6~TUG3Q2dWSt~zPH~lkaidscPqpCnCbqzljCEi4RiHY4U3A45l5XypcX2umqn1UaYUFCTqV9471J4qdB6Dg2pcKocdp-7-3s1De6Q~2SmBOrSgDQ~KEADCB2lhKfhxgWmy0lwMvhTd4l90ygVZDWZRABgjHNrGUvg__" alt="">
|
<img :src="data.url" alt="">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, onMounted } from 'vue'
|
import { reactive, onMounted, useAttrs } from 'vue'
|
||||||
import uploadFile from '../../tools/upload-file.vue'
|
import uploadFile from '../../tools/upload-file.vue'
|
||||||
const data = reactive({
|
const attrs = useAttrs()
|
||||||
file: null
|
|
||||||
})
|
|
||||||
|
|
||||||
defineExpose({ data })
|
const data = reactive({
|
||||||
|
url: attrs.node?.data?.originalImage,
|
||||||
|
})
|
||||||
|
const getApiData = ()=>{
|
||||||
|
return {
|
||||||
|
imageUrls: [data.url],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ data,getApiData })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
.to-3d-model {
|
.to-3d-model {
|
||||||
> .image {
|
> .image {
|
||||||
padding: 18px;
|
padding: 6px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background-color: #f0f0f0;
|
background-color: #f0f0f0;
|
||||||
>img{
|
>img{
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: auto;
|
height: auto;
|
||||||
|
max-height: 87px;
|
||||||
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,13 +48,13 @@
|
|||||||
}
|
}
|
||||||
])
|
])
|
||||||
const modeList = ref([
|
const modeList = ref([
|
||||||
{ value: 'Fast', label: 'Fast' },
|
{ value: 'Advanced', label: 'Advanced' },
|
||||||
{ value: 'Normal', label: 'Normal' }
|
{ value: 'Normal', label: 'Normal' }
|
||||||
])
|
])
|
||||||
const data = reactive({
|
const data = reactive({
|
||||||
prompt: '',
|
prompt: '',
|
||||||
pixelRatio: '1:1',
|
pixelRatio: '1:1',
|
||||||
mode: 'Normal',
|
mode: 'Advanced',
|
||||||
})
|
})
|
||||||
|
|
||||||
const getApiData = ()=>{
|
const getApiData = ()=>{
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, computed } from 'vue'
|
import { reactive, computed } from 'vue'
|
||||||
|
import { uploadImage } from '@/api/upload'
|
||||||
const emit = defineEmits(['update:modelValue', 'change'])
|
const emit = defineEmits(['update:modelValue', 'change'])
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: { type: [File, Object, String, null] },
|
modelValue: { type: [File, Object, String, null] },
|
||||||
@@ -44,7 +45,12 @@
|
|||||||
input.accept = 'image/png, image/jpeg, image/jpg'
|
input.accept = 'image/png, image/jpeg, image/jpg'
|
||||||
input.addEventListener('change', (e) => {
|
input.addEventListener('change', (e) => {
|
||||||
const file = e.target.files[0]
|
const file = e.target.files[0]
|
||||||
if (file) onChange(file)
|
const formData = new FormData()
|
||||||
|
formData.append('file', file)
|
||||||
|
|
||||||
|
uploadImage(formData).then((res) => {
|
||||||
|
if (res) onChange(res)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
input.click()
|
input.click()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
const open = async (options) => {
|
const open = async (options) => {
|
||||||
let json = []
|
let json = []
|
||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
getSketchFlowCanvas({ id: options.imgId }).then((res:any) => {
|
getSketchFlowCanvas({ id: options.imgId },true).then((res:any) => {
|
||||||
if (res) {
|
if (res) {
|
||||||
json = JSON.parse(res)
|
json = JSON.parse(res)
|
||||||
}
|
}
|
||||||
@@ -34,7 +34,7 @@
|
|||||||
await new Promise((resolve) => {
|
await new Promise((resolve) => {
|
||||||
putSketchFlowCanvas({
|
putSketchFlowCanvas({
|
||||||
id: config.value.imgId,
|
id: config.value.imgId,
|
||||||
canvasData: str }).then(() => {
|
canvasData: str },true).then(() => {
|
||||||
resolve(true)
|
resolve(true)
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
resolve(true)
|
resolve(true)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
popper-style="width:auto; min-width: 22rem; padding: 0.8rem; border-radius: 1.4rem;"
|
popper-style="width:auto; min-width: 22rem; padding: 0.8rem; border-radius: 1.4rem;"
|
||||||
>
|
>
|
||||||
<template #reference>
|
<template #reference>
|
||||||
<img class="pic" src="@/assets/images/pic.jpg" />
|
<img class="pic" :src="userInfoStore.state.userInfo?.avatar || '@/assets/images/pic.jpg'" />
|
||||||
</template>
|
</template>
|
||||||
<div class="menu-box">
|
<div class="menu-box">
|
||||||
<div>
|
<div>
|
||||||
@@ -97,6 +97,7 @@
|
|||||||
width: 4.65rem;
|
width: 4.65rem;
|
||||||
height: 4.65rem;
|
height: 4.65rem;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.menu-box {
|
.menu-box {
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ export default {
|
|||||||
userAgreement: 'User Agreement',
|
userAgreement: 'User Agreement',
|
||||||
privacyPolicy: 'Privacy Policy',
|
privacyPolicy: 'Privacy Policy',
|
||||||
view: 'View',
|
view: 'View',
|
||||||
|
remainingNum: 'Remaining number of times to upload profile picture:',
|
||||||
},
|
},
|
||||||
Country:{
|
Country:{
|
||||||
unitedStates: 'United States',
|
unitedStates: 'United States',
|
||||||
|
|||||||
@@ -81,7 +81,8 @@ export default {
|
|||||||
timesPerHour: '{time} 次/小时',
|
timesPerHour: '{time} 次/小时',
|
||||||
userAgreement: '用户协议',
|
userAgreement: '用户协议',
|
||||||
privacyPolicy: '隐私政策',
|
privacyPolicy: '隐私政策',
|
||||||
view: '查看'
|
view: '查看',
|
||||||
|
remainingNum: '剩余上传头像次数:',
|
||||||
},
|
},
|
||||||
Country: {
|
Country: {
|
||||||
unitedStates: '美国',
|
unitedStates: '美国',
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ export const useUserInfoStore = defineStore('userInfo', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateUserInfo = (data: any) => {
|
||||||
|
state.value.userInfo = { ...state.value.userInfo, ...data }
|
||||||
|
}
|
||||||
|
|
||||||
// actions
|
// actions
|
||||||
const setUserInfo = (data: any) => {
|
const setUserInfo = (data: any) => {
|
||||||
state.value.userInfo = data
|
state.value.userInfo = data
|
||||||
@@ -49,6 +53,7 @@ export const useUserInfoStore = defineStore('userInfo', () => {
|
|||||||
getUserInfo,
|
getUserInfo,
|
||||||
setToken,
|
setToken,
|
||||||
setUserInfo,
|
setUserInfo,
|
||||||
logOut
|
logOut,
|
||||||
|
updateUserInfo
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="label">{{ $t('Home.userProfile') }}</div>
|
<div class="label">{{ $t('Home.userProfile') }}</div>
|
||||||
|
<el-tooltip
|
||||||
|
class="box-item"
|
||||||
|
effect="dark"
|
||||||
|
:content="`${$t('Home.remainingNum')} ${remainingNum}`"
|
||||||
|
placement="top"
|
||||||
|
>
|
||||||
<div class="profile">
|
<div class="profile">
|
||||||
<img :src="userInfo?.profile" />
|
<img :src="userInfo?.avatar" />
|
||||||
<span class="edit" @click="onProfileEdit">
|
<span class="edit" @click="onProfileEdit">
|
||||||
<svg-icon name="profile-edit" size="11" />
|
<svg-icon name="profile-edit" size="11" />
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
</el-tooltip>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<div class="label">{{ $t('Home.userName') }}</div>
|
<div class="label">{{ $t('Home.userName') }}</div>
|
||||||
@@ -27,11 +34,13 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, nextTick, inject } from 'vue'
|
import { computed, ref, nextTick, inject, onMounted } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import dropdownMenu from '@/components/dropdown-menu.vue'
|
import dropdownMenu from '@/components/dropdown-menu.vue'
|
||||||
import { useUserInfoStore } from '@/stores'
|
import { useUserInfoStore } from '@/stores'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import { uploadImage } from '@/api/upload'
|
||||||
|
import { UpdateUserAvatar, getAvatarLimit } from '@/api/user'
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const { locale } = useI18n()
|
const { locale } = useI18n()
|
||||||
const userInfoStore = useUserInfoStore()
|
const userInfoStore = useUserInfoStore()
|
||||||
@@ -40,6 +49,7 @@
|
|||||||
{ label: 'English', value: 'ENGLISH' },
|
{ label: 'English', value: 'ENGLISH' },
|
||||||
{ label: '中文', value: 'CHINESE_SIMPLIFIED' }
|
{ label: '中文', value: 'CHINESE_SIMPLIFIED' }
|
||||||
])
|
])
|
||||||
|
const remainingNum = ref(0)
|
||||||
const changeLang = (value: string) => {
|
const changeLang = (value: string) => {
|
||||||
locale.value = value
|
locale.value = value
|
||||||
localStorage.setItem('language', value)
|
localStorage.setItem('language', value)
|
||||||
@@ -50,10 +60,32 @@
|
|||||||
const logout = () => {
|
const logout = () => {
|
||||||
userInfoStore.logOut()
|
userInfoStore.logOut()
|
||||||
}
|
}
|
||||||
|
const getAvatarLimitNum = ()=>{
|
||||||
|
getAvatarLimit().then((res:any) => {
|
||||||
|
if (res) {
|
||||||
|
remainingNum.value = res
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
const onProfileEdit = () => {
|
const onProfileEdit = () => {
|
||||||
// MyEvent.emit('openProfileEditDialog')
|
// MyEvent.emit('openProfileEditDialog')
|
||||||
console.log('openProfileEditDialog')
|
const input = document.createElement('input')
|
||||||
|
input.type = 'file'
|
||||||
|
input.accept = 'image/png, image/jpeg, image/jpg'
|
||||||
|
input.addEventListener('change', (e) => {
|
||||||
|
const file = e.target.files[0]
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('avatar', file)
|
||||||
|
UpdateUserAvatar(formData).then((res) => {
|
||||||
|
userInfoStore.updateUserInfo({avatar: res})
|
||||||
|
getAvatarLimitNum()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
input.click()
|
||||||
}
|
}
|
||||||
|
onMounted(()=>{
|
||||||
|
getAvatarLimitNum()
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less" scoped>
|
<style lang="less" scoped>
|
||||||
@@ -75,6 +107,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
object-fit: cover;
|
||||||
}
|
}
|
||||||
> .edit {
|
> .edit {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|||||||
Reference in New Issue
Block a user