feat: 颜色上传可以从library选择&历史列表参数修改

This commit is contained in:
zhangyh
2025-09-24 11:51:22 +08:00
parent 05e9bada5a
commit 3e3b8b17fe
8 changed files with 184 additions and 57 deletions

8
components.d.ts vendored
View File

@@ -9,32 +9,26 @@ export {}
declare module 'vue' {
export interface GlobalComponents {
ABadge: typeof import('ant-design-vue/es')['Badge']
ABreadcrumb: typeof import('ant-design-vue/es')['Breadcrumb']
ACheckbox: typeof import('ant-design-vue/es')['Checkbox']
AConfigProvider: typeof import('ant-design-vue/es')['ConfigProvider']
ADatePicker: typeof import('ant-design-vue/es')['DatePicker']
ADrawer: typeof import('ant-design-vue/es')['Drawer']
ADropdown: typeof import('ant-design-vue/es')['Dropdown']
AImage: typeof import('ant-design-vue/es')['Image']
AInputNumber: typeof import('ant-design-vue/es')['InputNumber']
AMenu: typeof import('ant-design-vue/es')['Menu']
AMenuItem: typeof import('ant-design-vue/es')['MenuItem']
AModal: typeof import('ant-design-vue/es')['Modal']
APagination: typeof import('ant-design-vue/es')['Pagination']
APopover: typeof import('ant-design-vue/es')['Popover']
ARangePicker: typeof import('ant-design-vue/es')['RangePicker']
ASelect: typeof import('ant-design-vue/es')['Select']
ASelectOption: typeof import('ant-design-vue/es')['SelectOption']
ASlider: typeof import('ant-design-vue/es')['Slider']
ASpace: typeof import('ant-design-vue/es')['Space']
ASpin: typeof import('ant-design-vue/es')['Spin']
ASubMenu: typeof import('ant-design-vue/es')['SubMenu']
ASwitch: typeof import('ant-design-vue/es')['Switch']
ATable: typeof import('ant-design-vue/es')['Table']
ATabPane: typeof import('ant-design-vue/es')['TabPane']
ATabs: typeof import('ant-design-vue/es')['Tabs']
ATimeRangePicker: typeof import('ant-design-vue/es')['TimeRangePicker']
AUpload: typeof import('ant-design-vue/es')['Upload']
ElCascader: typeof import('element-plus/es')['ElCascader']
RouterLink: typeof import('vue-router')['RouterLink']
RouterView: typeof import('vue-router')['RouterView']
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -16,8 +16,16 @@
</div>
</div>
<div class="detailText">{{$t('DesignPrintOperation.Colorfromimage')}}</div>
<div class="uploadImage">
<upload @selectUplpadColor="selectUplpadColor"></upload>
<div class="uploadImage flex flex-align-center flex-justify-around">
<div class="upload-container flex flex-column flex-align-center" :class="{'hide': !showLibrary}">
<upload ref="uploadRef" @selectUplpadColor="selectUplpadColor" @selectFile="showLibrary = false" @deleteColor="showLibrary = true"></upload>
<div class="upload-text" v-show="showLibrary"> {{ $t('LibraryPage.Upload') }} </div>
</div>
<div class="upload-container flex flex-column flex-align-center" v-show="showLibrary">
<!-- <i class="fi fi-rr-followcollection"></i> -->
<SvgIcon name="CLibrary" size="40" @click="handleOpenLibrary" />
<div class="upload-text"> {{ $t('LibraryPage.library') }} </div>
</div>
</div>
<div class="detailText">{{$t('DesignPrintOperation.ColorCode')}}</div>
<div class="colorCode">
@@ -30,7 +38,14 @@
<!-- <div class="getTcxColorBtn" @click="getTcxColor">{{$t('DesignPrintOperation.ExtractColor')}}</div> -->
</div>
</div>
<SelectImages
ref="selectImages"
@select="handleImageSelect"
radio
full-data
:api="Https.httpUrls.queryLibraryPage"
isLibrary
/>
</template>
<script lang="ts">
import { defineComponent,computed,ref,watch,nextTick,toRefs, reactive, onMounted} from 'vue'
@@ -39,14 +54,16 @@ import { ExclamationCircleOutlined } from '@ant-design/icons-vue';
import { useStore } from "vuex";
import { Https } from "@/tool/https";
import { useI18n } from 'vue-i18n'
import { rgbaToHex,rgbToHsv } from "@/tool/util"
import { rgbaToHex,rgbToHsv,UrlToFile } from "@/tool/util"
import { message,Upload} from 'ant-design-vue';
import SelectImages from '@/component/common/SelectImages.vue'
import upload from './upload.vue'
import pallet from './pallet.vue'
export default defineComponent({
components:{
upload,pallet
upload,pallet,SelectImages
},
setup(props,{emit}) {
const store = useStore();
@@ -243,6 +260,33 @@ export default defineComponent({
});
})
}
const uploadRef = ref<any>(null)
const selectImages = ref<any>(null)
const showLibrary = ref(true)
const handleOpenLibrary = ()=>{
selectImages.value.init()
}
const handleImageSelect = (item:any)=>{
console.log('item',item)
UrlToFile(item.url,item.name).then((file:any)=>{
console.log('file',file)
// 构造符合 fileUploadChange 期望的数据结构
const fileData = {
file: {
originFileObj: file, // 将 File 对象放在 originFileObj 属性中
status: 'done'
}
}
uploadRef.value.fileUploadChange(fileData)
})
// uploadRef.value.selectColor(item)
}
const handleShowListChange=(val:boolean)=>{
console.log('val',val)
showLibrary.value = !val
}
const selectUplpadColor = (item:any)=>{
colorData.selectColor = JSON.parse(JSON.stringify(item))
}
@@ -301,6 +345,14 @@ export default defineComponent({
selectUplpadColor,
setSelectColor,
getTcxColor,
handleOpenLibrary,
Https,
showLibrary,
selectImages,
uploadRef,
handleImageSelect,
handleShowListChange,
}
},
@@ -312,6 +364,30 @@ export default defineComponent({
})
</script>
<style lang="less" scoped>
.flex{
display: flex;
}
.flex-column{
flex-direction: column;
}
.flex-align-center{
align-items: center;
}
.flex-justify-center{
justify-content: center;
}
.flex-justify-between{
justify-content: space-between;
}
.flex-justify-around{
justify-content: space-around;
}
.color{
// width: 34rem;
width: 100%;
@@ -374,6 +450,25 @@ export default defineComponent({
height: 10rem;
width: 100%;
border-radius: .5rem;
.upload-container{
background-color: #EDEDED;
padding: 1rem 2rem;
border-radius: 1rem;
width: 8rem;
height: 8rem;
&.hide{
width: initial;
height: initial;
border: none;
padding: 0;
flex: 1;
background-color: transparent;
padding-left: 1rem;
}
:deep(.ant-upload){
background: transparent;
}
}
}
> .colorCode{
margin-bottom: 3rem;

View File

@@ -44,7 +44,7 @@ import { rgbaToHex } from "@/tool/util"
export default defineComponent({
components:{
},
emits:['selectUplpadColor'],
emits:['selectUplpadColor','deleteColor','selectFile'],
setup(props,{emit}) {
const {t} = useI18n();
const store = useStore();
@@ -63,6 +63,8 @@ export default defineComponent({
})
const fileUploadChange = (data:any)=>{
emit('selectFile')
console.log('fileUploadChange',data)
let file:any = data.file
let fileData = file.originFileObj
var reader = new FileReader();
@@ -157,6 +159,7 @@ export default defineComponent({
const colorDeleteFile = ()=>{
colorUpload.uploadList[colorUpload.selectDetail.id] = []
colorUpload.colorList[colorUpload.selectDetail.id] = []
emit('deleteColor')
}
return{
...toRefs(colorUpload),

View File

@@ -40,7 +40,8 @@
</div>
</div>
<a-dropdown>
<i class="fi fi-br-upload" :class="{ Guide_1_2_6:type_.type2 == 'Printboard'}"></i>
<!-- <i class="fi fi-br-upload" :class="{ Guide_1_2_6:type_.type2 == 'Printboard'}"></i> -->
<i class="fi fi-br-upload" :class="{ Guide_1_2_6:type_.type2 == 'Printboard'}" :title="$t('Generate.uploadTitle')" v-show="!isTextarea && upload.level1Type !== 'Moodboard' && scene?.value != 'Slogan' && scene?.value != 'Logo'"></i>
<template #overlay>
<a-menu>
<a-menu-item>
@@ -60,7 +61,7 @@
@change="(file) => fileUploadChange(file)"
>
<div class="drop-container">
<i class="fi fi-br-upload" :class="{ Guide_1_2_6:type_.type2 == 'Printboard'}" :title="$t('Generate.uploadTitle')" v-show="!isTextarea && upload.level1Type !== 'Moodboard' && scene?.value != 'Slogan' && scene?.value != 'Logo'"></i>
<folder-outlined />
<div>{{ $t('PrintboardUpload.Upload') }}</div>
</div>
</a-upload>
@@ -248,6 +249,7 @@ import createSlogan from "@/component/HomePage/createSlogan.vue";
import { useI18n } from "vue-i18n";
import sketchCategory from "@/component/HomePage/sketchCategory.vue";
import SelectImages from '@/component/common/SelectImages.vue'
import { FolderOutlined } from '@ant-design/icons-vue';
export default defineComponent({
components: {
@@ -255,7 +257,8 @@ export default defineComponent({
generalMenu,
createSlogan,
sketchCategory,
SelectImages
SelectImages,
FolderOutlined
},
props: ["msg",'sketchCatecoryList','scene','gender'],
emits:['setLibrary'],

View File

@@ -8,7 +8,7 @@
<div class="modal-content">
<!-- 分类标签 -->
<div class="image-categories">
<div v-if="showCategories" class="image-categories">
<div
v-for="category in categories"
:key="category"
@@ -88,11 +88,6 @@ import { navTypeList } from '@/tool/listData'
const { t } = useI18n()
const libraryTypeList = [
{ label: t('Canvas.all'), value: '' },
...navTypeList(t).library.list
]
// Props
const props = defineProps({
api: {
@@ -110,35 +105,58 @@ const props = defineProps({
fullData: {
type: Boolean,
default: false
},
level1Type: {
type: String,
default: ''
}
})
// Emits
const emits = defineEmits(['select'])
// 响应式数据
const libraryTypeList = ref([
...navTypeList(t).library.list.filter(item => item.value !== 'MyBrand')
])
// 根据传入的level1Type参数确定默认选中的分类
const getDefaultCategory = () => {
if (props.level1Type) {
// 如果传入了level1Type查找匹配的category
const matchedCategory = libraryTypeList.value.find(
item => item.value === props.level1Type
)
return matchedCategory ? matchedCategory.label : libraryTypeList.value[0]?.label || ''
}
// 如果没有传入参数,选择第一个
return libraryTypeList.value[0]?.label || ''
}
const showPanel = ref(false)
const selectedCategory = ref(t('Canvas.all'))
const selectedCategory = ref(getDefaultCategory())
const selectList = ref([])
const list = ref([])
// 新增:分页和加载状态
const currentPage = ref(1)
const hasMore = ref(true)
const loading = ref(false)
// 内部管理的分页大小
const pageSize = ref(10)
const total = ref(0)
// 计算属性:获取所有分类
const categories = computed(() => {
if (props.isLibrary) {
return libraryTypeList.map(item => item.label)
return libraryTypeList.value.map(item => item.label)
} else {
return []
}
})
// 计算属性:是否显示分类选择器
const showCategories = computed(() => {
return !props.level1Type // 如果没有传入level1Type参数则显示分类选择器
})
// 新增API请求函数
const fetchImages = async (
page = 1,
@@ -148,11 +166,10 @@ const fetchImages = async (
if (!props.api) return
loading.value = true
const type = libraryTypeList.find(item => item.label === category).value
console.log('type', type)
const type = libraryTypeList.value.find(item => item.label === category)?.value
const params = {
classificationIdList: [],
level1Type: 'Printboard',
level1Type: props.level1Type || type,
level2Type: '',
page,
ageGroup: '',

View File

@@ -155,6 +155,12 @@ const base64toFile = (dataurl, filename = 'file') => {//转换base64
}
const UrlToFile = async (url, imageName) => {
const response = await fetch(url)
const blob = await response.blob()
return new File([blob], imageName, { type: 'image/png' })
}
function rgbToHsv([R, G, B]) {//根据rgb获取hsv
R /= 255
G /= 255
@@ -613,25 +619,26 @@ function segmentImage(markerImage,fullImage,size){
})
}
export {
isEmail,
getUploadUrl,
getUniversalZoomLevel,
rgbaToHex,
getMinioUrl,
base64ToFile,
dataURLtoFile,
blobToFile,
base64toFile,
rgbToHsv,
formatTime,
dataURLtoBlob,
isMoible,
downloadIamge,
downloadVideoWithFetch,
getBrowserInfo,
setPubDate,
murmur,
setGradual,
calculateGradientCoordinate,
segmentImage,
isEmail,
getUploadUrl,
getUniversalZoomLevel,
rgbaToHex,
getMinioUrl,
base64ToFile,
dataURLtoFile,
blobToFile,
base64toFile,
rgbToHsv,
formatTime,
dataURLtoBlob,
isMoible,
downloadIamge,
downloadVideoWithFetch,
getBrowserInfo,
setPubDate,
murmur,
setGradual,
calculateGradientCoordinate,
segmentImage,
UrlToFile
}

View File

@@ -31,8 +31,8 @@
<div
class="operate_item"
v-if="
record.process !== 'TO_PRODUCT_IMAGE' &&
record.process !== 'POSE_TRANSFER'
record.process ==='SERIES_DESIGN' ||
record.process ==='SINGLE_DESIGN'
"
@click="turnToDetail(record)"
>
@@ -41,8 +41,8 @@
<div
class="operate_item"
v-if="
record.process !== 'TO_PRODUCT_IMAGE' &&
record.process !== 'POSE_TRANSFER'
record.process ==='SERIES_DESIGN' ||
record.process ==='SINGLE_DESIGN'
"
@click="renameCollection(record, index)"
>
@@ -97,6 +97,7 @@ import projectSetting from '@/component/home/newProject/setting.vue'
import { useStore } from 'vuex'
import router from '@/router'
export default defineComponent({
components: {
// HeaderComponent,
@@ -315,8 +316,14 @@ export default defineComponent({
searchHistoryList(value: any) {
// console.log('value', value)
this.currentPage = 1
const process =
value.currentPreset === ''
? []
: value.currentPreset === 'TO_PRODUCT_IMAGE'
? ['TO_PRODUCT_IMAGE', 'RELIGHT']
: [value.currentPreset]
this.getHistoryList({
process: value.currentPreset,
process,
projectName: value.searchText
})
},