Merge branch 'main' of ssh://18.167.251.121:10002/aidlab/lanecarford_front
All checks were successful
git提交控制 AiDA WEB-Node.js main 分支构建部署 / build (20.19.0) (push) Has been skipped

This commit is contained in:
X1627315083
2025-12-23 14:20:11 +08:00
15 changed files with 279 additions and 58 deletions

View File

@@ -192,4 +192,39 @@ export function addTryOnEffectComment(data: Object) {
method: 'post',
data,
})
}
}
/**
* like outfit接口
* @param styleId 设置like的styleid
*/
export function setStyleFavorite(styleId: Object) {
return request({
url: `/api/style/set-favorite/${styleId}`,
method: 'post',
})
}
/**
* 取消like outfit接口
* @param styleId 取消like的styleid
*/
export function cancelStyleFavorite(styleId: Object) {
return request({
url: `/api/style/cancel-favorite/${styleId}`,
method: 'post',
})
}
/**
* try on 返推outfitId
* @param tryOnEffectsId tryOnId
*/
export function retrieveAndRegenerate(data: Object) {
return request({
url: `/api/style/retrieveAndRegenerate`,
method: 'get',
params: data,
})
}

View File

@@ -0,0 +1,9 @@
<svg width="44" height="44" viewBox="0 0 44 44" fill="none" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<rect width="44" height="44" fill="url(#pattern0_27_31213)"/>
<defs>
<pattern id="pattern0_27_31213" patternContentUnits="objectBoundingBox" width="1" height="1">
<use xlink:href="#image0_27_31213" transform="scale(0.0078125)"/>
</pattern>
<image id="image0_27_31213" width="128" height="128" preserveAspectRatio="none" xlink:href="data:image/png;base64,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"/>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -25,13 +25,13 @@
})
.then(() => {
MyEvent.emit('clear-generate-state')
MyEvent.emit('clearAllCache')
// MyEvent.emit('clearAllCache')
nav.path && router.push(nav.path)
})
.catch(() => {})
}
const navs = [
{ label: 'Home', icon: 'home', size: 73, path: '/workshop/home' },
{ label: 'Home', icon: 'home', size: 73, path: '/workshop/home', on: onHome },
{ label: 'Library', icon: 'library', size: 53, path: '/workshop/library' },
// { label: 'Profile', icon: 'profile', size: 55, path: '/workshop/profile' }
]

View File

@@ -0,0 +1,58 @@
<script setup lang="ts">
import { ref, onMounted, onUnmounted, reactive, toRefs } from "vue";
//const props = defineProps({
//})
//const emit = defineEmits([
//])
let data = reactive({
})
onMounted(()=>{
})
onUnmounted(()=>{
})
defineExpose({})
const {} = toRefs(data);
</script>
<template>
<div class="gradientButton">
<div class="bg">
<slot name="content">
</slot>
</div>
</div>
</template>
<style lang="less" scoped>
.gradientButton{
position: relative;
width: 100%;
height: 100%;
--gradientButtonBorderRadius: var(--borderRadius,1rem);
--gradientButtonBorderWidth: var(--borderWidth,2px);
> .bg{
position: absolute;
inset: var(--gradientButtonBorderWidth);
display: flex;
background-color: #fff;
align-items: center;
justify-content: center;
border-radius: var(--gradientButtonBorderRadius);
overflow: hidden;
}
&::before{
content: '';
position: absolute;
width: calc(100% + 0.2rem);
height: calc(100% + 0.2rem);
top: 50%;
left: 50%;
border-radius: var(--gradientButtonBorderRadius);
transform: translate(-50%, -50%);
background: linear-gradient(125deg,
#f1f1f1 0%,
#000 40%,
#000 65%,
#fff 100%);
}
}
</style>

View File

@@ -121,7 +121,7 @@ const router = createRouter({
},
{
path: '/workshop/selectStyle',
name: 'SelectStyle',
name: 'selectStyle',
component: () => import('../views/Workshop/selectStyle.vue'),
meta: { verify: ()=> VerifyIDs(2) }
},
@@ -133,7 +133,7 @@ const router = createRouter({
},
{
path: '/workshop/product',
name: 'Product',
name: 'product',
component: () => import('../views/Workshop/product.vue'),
meta: { verify: ()=> VerifyIDs(4) }
},

View File

@@ -9,7 +9,10 @@ export const useGenerateStore = defineStore({
return {
style: {
id: '',
oldId: '' //表示从生成页面返回回来需要调整的样式id
path: '',
taskId:'',
isLike: false, //是否喜欢
status: ''
},
styleList: [{}, {}, {}, {}],
model: {
@@ -68,7 +71,7 @@ export const useGenerateStore = defineStore({
/** 进店记录id */
visitRecordId: (state) => state.customerInfo.visitRecordId,
/** 服装id */
styleId: (state) => state.style.id || state.style.oldId,
styleId: (state) => state.style.id,
/** 模特照片id */
modelPhotoId: (state) => state.model.id,
/** 原始试穿id不包含魔改id */
@@ -82,23 +85,19 @@ export const useGenerateStore = defineStore({
},
actions: {
selectStyle(data: any) {
this.style.id = data.id
},
//生成后去掉id 设置oldId来修改样式
useStyleGenerate() {
if (!this.style.id) return
this.style.oldId = this.style.id
// this.style.id = ''
},
updateStyle(data) {
if (data.id == this.style.oldId) {
this.style.oldId = ''
}
if(data.id == this.style.id) {
this.style.id = ''
this.style = {
...data,
}
console.log(this.style)
},
clearStyle() {
this.style = {
id: '',
path: '',
isLike: false,
taskId:'',
status: ''
}
},
//模特相关
selectModel(data: any) {
this.model.id = data.id
@@ -110,7 +109,10 @@ export const useGenerateStore = defineStore({
this.styleList = [{}, {}, {}, {}]
this.style = {
id: '',
oldId: ''
path: '',
isLike: false,
taskId:'',
status: ''
}
this.model = {
id: ''

View File

@@ -60,7 +60,6 @@ export const useHGenerateStore = defineStore({
},
//设置默认数据
clearGenerateData() {
this.clearProductData()
this.clearCustomizeInfo()
},
}

View File

@@ -156,4 +156,31 @@ export async function DownloadImages(list: Array<{ url: string, name?: string }>
*/
export function encryptPassword(password: string): string {
return CryptoJS.MD5(password).toString()
}
/**
* 图片分享到WhatsApp
* @param url 图片URL
* @returns 无
*/
export async function shareImageToWhatsapp (url: string){
// 把图片 URL 转为 Blob
const blob = await fetch(url).then((res) => res.blob())
// 创建文件对象
const file = new File([blob], 'image.jpg', { type: 'image/jpeg' })
// 判断浏览器是否支持文件分享
if (navigator.canShare && navigator.canShare({ files: [file] })) {
await navigator.share({
files: [file]
})
} else {
// 你可以附加一些自定义文本
const message = 'share image ' + url
// 构造WhatsApp链接
const whatsappLink = `https://api.whatsapp.com/send/?text=${encodeURIComponent(message)}`
window.open(whatsappLink, '_blank')
}
}

View File

@@ -40,6 +40,10 @@
navLst.forEach((v) => {
if (v.flowType === query.value.flowType) navActive.value = v.value
})
navLst.forEach((v) => {
if (v.flowType === query.value.active) navActive.value = v.value
})
const clickNav = (v) => {
if (v.value === navActive.value || loading.value) return
navActive.value = v.value

View File

@@ -3,21 +3,21 @@
import { ref, onMounted, computed } from 'vue'
import {
generateTryOnEffect,
generateTryOnEffectDemo,
setTryOnEffectFavorite,
cancelTryOnEffectFavorite
} from '@/api/workshop'
const emit = defineEmits(['viewType'])
import { useRouter, useRoute } from 'vue-router'
import { useGenerateStore } from '@/stores'
import { useGenerateStore, useHGenerateStore } from '@/stores'
import { FlowType, IsHistoryFlow } from '@/types/enum'
const generateStore = useGenerateStore()
const hGenerateStore = useHGenerateStore()
const router = useRouter()
const route = useRoute()
const query = computed(() => route.query)
const isHistoryFlow = computed(() => IsHistoryFlow(query.value.flowType))
const customizeInfo = isHistoryFlow.value
? generateStore.customizeInfoDemo
? hGenerateStore.customizeInfo
: generateStore.customizeInfo
const loading = ref(false)
const onSend = () => {
@@ -53,7 +53,7 @@
}
if (isHistoryFlow.value) {
data['originalTryOnId'] =
type === 'reload' ? customizeInfo.oldTryOnId : generateStore.customizeInfoDemo.tryOnId
type === 'reload' ? customizeInfo.oldTryOnId : hGenerateStore.originalTryOnId
} else {
data['styleId'] = generateStore.styleId
data['originalTryOnId'] =
@@ -62,7 +62,7 @@
generateTryOnEffect(data)
.then((res: any) => {
customizeInfo.count++
customizeInfo.tryOnId = res.tryOnId
customizeInfo.tryOnId = res.id
customizeInfo.tryOnUrl = res.tryOnUrl
customizeInfo.styleUrl = res.styleUrl
customizeInfo.isRegenerated = res.isRegenerated
@@ -102,7 +102,11 @@
}
const onFinish = () => {
// router.push({ name: 'creation', query: query.value })
router.push({ name: 'creation', query: { flowType: FlowType.H_AI } })
const query_ = {
...query.value,
active: FlowType.H_AI
}
router.push({ name: 'creation', query: query_ })
// if (isHistoryFlow.value) {
// router.push({ name: 'end' })
// } else {
@@ -280,7 +284,7 @@
}
> .btns {
margin-top: 4rem;
width: 68%;
min-width: 68%;
display: flex;
// justify-content: center;
justify-content: space-between;

View File

@@ -6,8 +6,8 @@ const route = useRoute()
import { showConfirmDialog } from 'vant'
import MyEvent from '@/utils/myEvent'
import { FlowType, IsHistoryFlow } from '@/types/enum'
import { useGenerateStore } from '@/stores'
const generateStore = useGenerateStore()
import { useHGenerateStore } from '@/stores'
const hGenerateStore = useHGenerateStore()
//const props = defineProps({
@@ -66,13 +66,22 @@ onMounted(()=>{
path: 'uploadFace',
imgPath: new URL('@/assets/images/nav3.png',import.meta.url).href,
flowTypeList: [FlowType.H_TRYON,FlowType.H_AI],
click(){
hGenerateStore.clearCustomizeInfo()
},
},
{
path: 'customize',
imgPath: new URL('@/assets/images/nav4.png',import.meta.url).href,
flowTypeList: [FlowType.H_TRYON,FlowType.H_AI],
click(){
generateStore.updatePhotoInfo({})
hGenerateStore.clearCustomizeInfo()
hGenerateStore.uploadCustomizeInfo({
tryOnId: hGenerateStore.originalTryOn.id,
tryOnUrl: hGenerateStore.originalTryOn.tryOnUrl,
isFavorite: hGenerateStore.originalTryOn.isLike,
styleUrl: hGenerateStore.style.url,
})
},
},
]

View File

@@ -61,7 +61,7 @@ const startGenerate = ()=>{
generateTryOnEffect(value).then((res:any)=>{
data.isLoading = false;
generateStore.originalTryOn.isLike = false
generateStore.originalTryOn.id = res.tryOnId
generateStore.originalTryOn.id = res.id
generateStore.originalTryOn.tryOnUrl = res.tryOnUrl
// generateStore.useStyleGenerate()//生成后需要对选择衣服页面设置不可选中样式
generateStore.setIsGenerate(false)

View File

@@ -2,9 +2,10 @@
import { ref, reactive, onMounted, computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { uploadCustomerPhoto } from '@/api/workshop'
import { useGenerateStore } from '@/stores'
import { useGenerateStore, useHGenerateStore } from '@/stores'
import { IsHistoryFlow } from '@/types/enum'
const generateStore = useGenerateStore()
const hGenerateStore = useHGenerateStore()
const emit = defineEmits(['view-type'])
onMounted(() => {
@@ -47,7 +48,7 @@
formData.append('file', fileData.file)
uploadCustomerPhoto(formData).then((res) => {
generateStore.updatePhotoInfo({ ...res, file: fileData.file })
isHistoryFlow.value ? generateStore.clearCustomizeInfoDemo() : generateStore.clearCustomizeInfo()
isHistoryFlow.value ? hGenerateStore.clearCustomizeInfo() : generateStore.clearCustomizeInfo()
router.push({ name: 'customize', query: query.value })
})
}

View File

@@ -4,12 +4,19 @@
<img src="@/assets/images/chat_loading.png" alt="Loading" class="loading-image" />
<!-- 阴影效果 -->
<div class="loading-shadow"></div>
<div class="loading-text">{{ title }}</div>
<div class="loading-text" ref="textBox">
<span>{{ text }}</span>
<div class="loading-dot" ref="dotBox"></div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { onMounted, watch, reactive, toRefs, nextTick, ref } from "vue";
import { gsap, TweenMax } from "gsap";
// 这个组件只负责显示loading动画
// 定义组件props类型
@@ -20,6 +27,76 @@ const props = defineProps({
}
})
const dotBox = ref(null)
const textBox = ref(null)
let tl1 = null;
const text = ref('')
watch(() => props.title, (newVal, oldVal) => {
if (newVal !== oldVal) {
destroyAnimation()
fadeOut(newVal)
}
})
function fadeOut(newVal) {
gsap.to(textBox.value,.5, {
opacity: 0,
duration: 1,
ease: "power2.in",
onComplete: () => {
// 消失后更换文字
text.value = newVal
// 然后出现
fadeIn();
}
});
}
// 出现动画
function fadeIn() {
gsap.to(textBox.value,.5, {
opacity: 1,
duration: 1,
onComplete:()=>{
setTl1();
}
});
}
const setTl1 = ()=>{
nextTick(()=>{
let el = dotBox.value
let width = el.offsetWidth + el.parentElement.offsetWidth
let time = el.parentElement.offsetWidth / 35
console.log(time,width)
tl1 = gsap.timeline();
tl1.to(el,time,
{
ease: "power1.in",
left:width,
onComplete:()=>{
setTimeout(() => {
tl1.restart()
}, 1000)
}
},
)
tl1.progress(0);
})
}
function destroyAnimation() {
if (tl1) {
tl1.progress(0);
tl1.kill();
tl1 = null;
}
}
onMounted(() => {
text.value = props.title
setTl1()
})
</script>
@@ -54,6 +131,18 @@ const props = defineProps({
font-size: 4.8rem;
letter-spacing: 0.02em;
line-height: 124%;
position: relative;
}
.loading-dot{
height: 100%;
aspect-ratio: 1/1;
background: radial-gradient(ellipse 150% 150% at center, #ffffff,rgba(255,255,255,.4), transparent);
border-radius: 50%;
position: absolute;
top: 50%;
left: 0;
transform: translate(-100%, -50%);
}
@keyframes rotate {

View File

@@ -3,11 +3,8 @@
<div class="header">
<HeaderTitle hasSetting styleType="3" />
</div>
<div class="loading-container" v-if="isLoading">
<GenerateLoading />
</div>
<template v-else>
<div class="content flex-1" v-if="!isLoading">
<template>
<div class="content flex-1">
<NoticeList
ref="noticeListRef"
:list="messageList"
@@ -15,7 +12,7 @@
:streaming-message="currentStreamingMessage"
/>
</div>
<div class="footer" v-if="!isLoading">
<div class="footer">
<InputArea @send-message="handleSendMessage" />
<div class="continue flex">
<div class="btn flex flex-center" @click="handleContinue">Continue</div>
@@ -28,7 +25,6 @@
import HeaderTitle from '@/components/HeaderTitle.vue'
import NoticeList from './components/NoticeList.vue'
import InputArea from './components/InputArea.vue'
import GenerateLoading from './components/GenerateLoading.vue'
import { ref, onMounted, onUnmounted, onActivated } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useUserInfoStore, useGenerateStore } from '@/stores'
@@ -60,7 +56,6 @@ interface ChatMessage {
self?: boolean
}
const isLoading = ref<boolean>(false)
const noticeListRef = ref<NoticeListRef | null>(null)
const messageList = ref<ChatMessage[]>([])
@@ -273,12 +268,8 @@ const handleFetchMessage = (message: string) => {
const handleContinue = () => {
// router.push('/workshop/selectStyle')
// 模拟接口之后再跳转
isLoading.value = true
generateStore.clearProductData()
setTimeout(() => {
router.push('/workshop/selectStyle')
isLoading.value = false
}, 1000)
router.push('/workshop/selectStyle')
}
</script>
<style lang="less" scoped>
@@ -316,11 +307,4 @@ const handleContinue = () => {
}
}
.loading-container {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
}
</style>