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-30 13:10:53 +08:00
9 changed files with 138 additions and 22 deletions

View File

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

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,78 @@
<template>
<div class="loading-container" :style="containerStyle">
<div class="dot"></div>
<div class="dot"></div>
<div class="dot"></div>
</div>
</template>
<script setup>
import { computed } from 'vue'
import { defineProps } from 'vue'
const props = defineProps({
color: {
type: String,
default: '#000' // 默认颜色
},
size: {
type: Number,
default: 10 // 默认圆点大小px
},
spacing: {
type: Number,
default: 3 // 默认间距px调整为合适小尺寸
},
amplitude: {
type: Number,
default: 8 // 默认浮动幅度px调整为合适比例
},
duration: {
type: Number,
default: 1.2 // 默认动画持续时间s
}
})
const containerStyle = computed(() => ({
'--color': props.color,
'--size': `${props.size}px`,
'--spacing': `${props.spacing}px`,
'--amplitude': `${props.amplitude}px`,
'--duration': `${props.duration}s`
}))
</script>
<style scoped>
.loading-container {
display: flex;
justify-content: center;
align-items: center;
/* 可以根据需要调整容器高度或移除 */
}
.dot {
width: var(--size);
height: var(--size);
background-color: var(--color);
border-radius: 50%;
margin: 0 var(--spacing);
animation: wave var(--duration) infinite ease-in-out;
}
.dot:nth-child(2) {
animation-delay: 0.2s;
}
.dot:nth-child(3) {
animation-delay: 0.4s;
}
@keyframes wave {
0%, 100% {
transform: translateY(0);
}
50% {
transform: translateY(calc(-1 * var(--amplitude)));
}
}
</style>

View File

@@ -7,7 +7,9 @@
import {
getGenerateHistoricals,
setTryOnEffectFavorite,
cancelTryOnEffectFavorite
cancelTryOnEffectFavorite,
cancelStyleFavorite,
setStyleFavorite
} from '@/api/workshop'
import { useRouter } from 'vue-router'
import MyEvent from '@/utils/myEvent'
@@ -106,17 +108,22 @@
}
// 详情页
const onDetailsItem = (v) => {
if (v.isRegenerated) return
if (v.isRegenerated || !v.styleUrl) return
router.push({ query: { ...query.value, styleUrl: v.styleUrl } })
}
// 喜欢
const isLoveLoading = ref(false)
const onLoveItem = (v) => {
if (isLoveLoading.value) return
const http = v.isFavorite ? cancelTryOnEffectFavorite : setTryOnEffectFavorite
var http
if (navActive.value === 'Outfit') {
http = v.isFavorite ? cancelStyleFavorite : setStyleFavorite
} else {
http = v.isFavorite ? cancelTryOnEffectFavorite : setTryOnEffectFavorite
}
isLoveLoading.value = true
v.isFavorite = !v.isFavorite
http(v.tryOnId)
http(v.id)
.then(() => {
isLoveLoading.value = false
})
@@ -154,7 +161,10 @@
alert(`现在${isShare.value ? '可以' : '不可以'}分享`)
}
const onShareItem = (v) => {
const url = v.tryOnUrl || v.url
if (url) shareImageToWhatsapp(url)
}
const onDownloadItem = async (v) => {
if (isShare.value) {
await shareImageToWhatsapp(v.tryOnUrl)
@@ -287,9 +297,12 @@
<div @click.stop="onLoveItem(v)">
<SvgIcon :name="`love_${v.isFavorite ? '1' : '0'}`" size="27" />
</div>
<div @click.stop="onDownloadItem(v)">
<!-- <div @click.stop="onDownloadItem(v)">
<SvgIcon name="download" size="27" v-show="!v.loading" />
<van-loading color="#000" size="3rem" v-show="v.loading" />
</div> -->
<div @click.stop="onShareItem(v)">
<SvgIcon name="share" size="27" />
</div>
</div>
<div class="icon-selected" v-show="(isChooseSave || isChooseOne) && v.selected">

View File

@@ -38,7 +38,7 @@ const onContinue = ()=>{
if(!isHistoryFlow.value){
router.push({ path: 'uploadFace', query: {...query.value} })
}else{
router.push({ path: 'creation', query: {...query.value} })
router.push({ path: 'creation', query: {...query.value, active: FlowType.H_TRYON } })
}
}

View File

@@ -2,7 +2,7 @@
import { ref, reactive, onMounted, inject } from 'vue'
import router from '@/router'
import { showConfirmDialog, showToast } from 'vant'
import { useUserInfoStore, useOverallStore } from '@/stores'
import { useUserInfoStore, useOverallStore,useGenerateStore } from '@/stores'
import { LogOut } from '@/api/login'
import { getCustomerList, type CustomerListParams, customerCheckin } from '@/api/workshop'
import MyEvent from '@/utils/myEvent'
@@ -15,6 +15,8 @@
const userInfoStore = useUserInfoStore()
const overallStore = useOverallStore()
const generateStore = useGenerateStore()
const emit = defineEmits(['selected-customer'])
const show = ref(false)
const isEdit = ref(false)
@@ -187,7 +189,8 @@
customerCheckin({ nickname: selectedCustomer.name }).then((res) => {
useUserInfoStore().resetGenerateParams()
MyEvent.emit('clear-generate-state')
useUserInfoStore().setCustomerInfo(res)
useGenerateStore().setCustomerInfo(res)
router.push({ path: '/workshop/home' })
})
}
showSwitchCustomerPopup.value = false

View File

@@ -9,7 +9,8 @@
<div class="message-content">
<div class="message-text" :class="{ streaming: isStreaming }">
<div v-html="content"></div>
<span v-if="isStreaming" class="streaming-cursor">|</span>
<!-- <span v-if="isStreaming" class="streaming-cursor">|</span> -->
<WaveLoading v-if="isStreaming" />
</div>
<!-- <div v-if="!isMyself" class="message-actions flex">
<SvgIcon
@@ -27,6 +28,7 @@
<script setup lang="ts">
import { computed } from 'vue'
import MarkdownIt from 'markdown-it'
import WaveLoading from '@/components/WaveLoading.vue'
import { useUserInfoStore } from '@/stores'
const md = new MarkdownIt()

View File

@@ -1,7 +1,7 @@
<template>
<div class="asistant-container flex flex-column">
<div class="header">
<HeaderTitle hasSetting styleType="3" />
<HeaderTitle hasSetting styleType="3" @clickProfile="handleClickProfile" />
</div>
<div class="content flex-1">
<NoticeList
@@ -17,12 +17,14 @@
<div class="btn flex flex-center" @click="handleContinue">Generate</div>
</div>
</div>
<Profile ref="profileRef" />
</div>
</template>
<script setup lang="ts">
import HeaderTitle from '@/components/HeaderTitle.vue'
import NoticeList from './components/NoticeList.vue'
import InputArea from './components/InputArea.vue'
import Profile from '../Workshop/profile.vue'
import { ref, onMounted, onUnmounted, onActivated } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { useUserInfoStore, useGenerateStore } from '@/stores'
@@ -54,6 +56,11 @@ interface ChatMessage {
self?: boolean
}
const profileRef = ref<InstanceType<typeof Profile> | null>(null)
const handleClickProfile = () => {
profileRef.value.open()
}
const noticeListRef = ref<NoticeListRef | null>(null)
const messageList = ref<ChatMessage[]>([])

View File

@@ -88,7 +88,7 @@ const router = useRouter()
const generateStore = useGenerateStore()
const loading = ref(false)
type PageMode = 'form' | 'entry' | 'create'
type PageMode = 'entry' | 'form' | 'create'
const pageMode = ref<PageMode>('entry')
const formTitle = computed(() => {
return pageMode.value === 'entry' || pageMode.value === 'form' ? 'Customer ID' : 'Create Profile'
@@ -147,7 +147,7 @@ const handleShowPopup = (flag: Boolean) => {
}
const handleSelectCustomer = (value) => {
if (value) {
if (value && pageMode.value === 'form') {
customerData.value.nickname = value.name
}
}
@@ -189,7 +189,7 @@ const handleBack = (e?: Event) => {
.setting {
z-index: 1;
padding: 3.17rem 4.9rem 0 8.4rem;
padding: 3.67rem 4.9rem 0 8.4rem;
font-size: 7rem;
.c-svg {
width: initial;

View File

@@ -5,7 +5,7 @@
<!-- 标题 -->
<div class="header">
<div class="title">Choose Stylist.</div>
<div class="sub-title">What style are you looking for? </div>
<div class="sub-title">What style are you looking for?</div>
</div>
<div class="carousel-container" v-show="!showVideo">
@@ -35,7 +35,13 @@
</div>
<!-- Continue按钮 -->
<div class="continue-button" @click="handleContinue" v-if="!$route.query?.demo">Continue</div>
<button
class="sandblasted-blurred continue-button flex flex-center"
@click="handleContinue"
v-if="!$route.query?.demo"
>
<span>Continue</span>
</button>
<!-- <van-dialog
class="video-dialog"
:show-confirm-button="false"
@@ -181,7 +187,7 @@ const handleContinue = () => {
letter-spacing: -0.04rem;
margin-bottom: 3.2rem;
}
.sub-title{
.sub-title {
font-family: 'satoshiRegular';
font-size: 4rem;
}
@@ -294,9 +300,9 @@ const handleContinue = () => {
}
}
.continue-button {
button.sandblasted-blurred.continue-button {
height: 6.7rem;
box-sizing: border-box;
width: 24.6rem;
position: absolute;
bottom: 6.4rem;
right: 7.6rem;
@@ -306,11 +312,9 @@ const handleContinue = () => {
color: white;
font-size: 4rem;
font-weight: 500;
cursor: pointer;
z-index: 3;
font-family: 'satoshiRegular';
display: flex;
align-items: center;
box-sizing: border-box;
}
:deep(.van-overlay) {