Merge branches 'main' and 'main' of ssh://18.167.251.121:10002/aidlab/lanecarford_front

This commit is contained in:
X1627315083
2025-10-31 11:16:10 +08:00
15 changed files with 85 additions and 52 deletions

View File

@@ -20,6 +20,10 @@ button.sandblasted-blurred::after {
}
button.sandblasted-blurred::before {
backdrop-filter: blur(9.5rem);
-webkit-backdrop-filter: blur(9.5rem);
-moz-backdrop-filter: blur(9.5rem);
-ms-backdrop-filter: blur(9.5rem);
-o-backdrop-filter: blur(9.5rem);
}
button.sandblasted-blurred::after {
opacity: 0.1;

View File

@@ -22,6 +22,10 @@ button.sandblasted-blurred {
&::before {
backdrop-filter: blur(9.5rem);
-webkit-backdrop-filter: blur(9.5rem);
-moz-backdrop-filter: blur(9.5rem);
-ms-backdrop-filter: blur(9.5rem);
-o-backdrop-filter: blur(9.5rem);
}
&::after {

View File

@@ -1,6 +1,7 @@
// 每一个存储的模块命名规则use开头store结尾
import { defineStore } from 'pinia'
import MyEvent from '@/utils/myEvent'
import { uploadCustomerPhoto } from '@/api/workshop'
MyEvent.add('clear-generate-state', () => useGenerateStore().clearGenerateData())
export const useGenerateStore = defineStore({
@@ -32,6 +33,9 @@ export const useGenerateStore = defineStore({
/** AI魔改信息 */
customizeInfo: {
inputText: '',
count: 0,
oldInputText: '',
oldTryOnId: '',
tryOnId: '',
tryOnUrl: '',
@@ -108,12 +112,18 @@ export const useGenerateStore = defineStore({
/** 清空 AI魔改信息 */
clearCustomizeInfo() {
this.customizeInfo.inputText = ''
this.customizeInfo.count = 0
this.customizeInfo.tryOnId = ''
this.customizeInfo.tryOnUrl = ''
this.customizeInfo.styleUrl = ''
this.customizeInfo.isRegenerated = ''
this.customizeInfo.isFavorite = false
},
uploadCustomizeInfo(data: object){
for (const key in data) {
this.customizeInfo[key] = data[key]
}
},
clearCustomerInfo(){
this.customerInfo = {
customerId: '',

View File

@@ -89,8 +89,7 @@ service.interceptors.response.use(
position: 'top',
icon: 'none'
})
return Promise.reject(new Error('error'))
return Promise.reject(new Error(res.errMsg || res.message || 'error'))
} else {
// 默认只返回data不返回状态码和message
// 通过 meta 中的 responseAll 配置来取决后台是否返回所有数据(包括状态码message和data)

View File

@@ -108,7 +108,7 @@ export function FormatDate(value: Date | number | string, format: string = 'yyyy
* @param onError 下载错误回调
* @param onSuccess 下载成功回调
*/
export async function DownloadImages(list: Array<{ url: string, name: string }>, onProgress?: (count: number, total: number, item: any) => void, onError?: (count: number, total: number, item: any) => void, onSuccess?: (successCount: number, errCount: number) => void) {
export async function DownloadImages(list: Array<{ url: string, name?: string }>, onProgress?: (count: number, total: number, item: any) => void, onError?: (count: number, total: number, item: any) => void, onSuccess?: (successCount: number, errCount: number) => void) {
const total = list.length;
let count = 0;
let successCount = 0;
@@ -124,7 +124,7 @@ export async function DownloadImages(list: Array<{ url: string, name: string }>,
const blob = this.response;
const a = document.createElement('a');
a.href = URL.createObjectURL(blob);
a.download = list[i].name || list[i].url;
a.download = list[i].name || list[i].url.split('/').pop().split('?').shift();
a.click();
successCount++;
typeof onProgress === "function" && onProgress(count, total, list[i]);

View File

@@ -4,15 +4,12 @@
import { DownloadImages } from '@/utils/tools'
const router = useRouter()
const query = computed(() => router.currentRoute.value.query)
const styleUrl = computed(() => query.value.styleUrl)
const styleUrl = computed(() => query.value.styleUrl as string)
onMounted(() => {})
const loading = ref(false)
const onDownload = () => {
DownloadImages([{
url: styleUrl.value,
name: 'lane-crawford.png'
}])
DownloadImages([{ url: styleUrl.value }])
}
const onEdit = () => {
console.log('edit')

View File

@@ -13,7 +13,7 @@
const router = useRouter()
const emit = defineEmits(['view-type'])
const query = computed(() => router.currentRoute.value.query)
const visitRecordId = computed(() => query.value.visitRecordId)
const visitRecordId = computed(() => query.value.visitRecordId)// 访问记录ID
import { useGenerateStore } from '@/stores'
const generateStore = useGenerateStore()
@@ -85,11 +85,7 @@
if (v.loading) return
v.loading = true
v.selected = false
const obj = {
url: v.tryOnUrl,
name: v.tryOnUrl.split('/').pop()
}
DownloadImages([obj], null, null, () => {
DownloadImages([{ url: v.tryOnUrl }], null, null, () => {
v.loading = false
v.downloaded = true
})
@@ -114,8 +110,7 @@
v.loading = true
downloadList.push({
index: i,
url: v.tryOnUrl,
name: v.tryOnUrl.split('/').pop()
url: v.tryOnUrl
})
}
})
@@ -223,7 +218,7 @@
// justify-content: space-around;
.item {
width: 47%;
height: 52.9rem;
height: 62.2rem;
// overflow: hidden;
border-radius: var(--border-radius);
background-color: #fff;
@@ -233,7 +228,7 @@
> img {
width: 100%;
height: 100%;
object-fit: contain;
object-fit: cover;
border-radius: var(--border-radius);
}
> .corner {

View File

@@ -25,25 +25,29 @@
// console.log('发送消息:', text)
}
const onReload = () => {
customizeInfo.inputText = customizeInfo.oldInputText
generate("reload")
customizeInfo.inputText = ''
generate()
}
// 生成结果
const generate = () => {
const generate = (type?: "reload") => {
customizeInfo.oldInputText = customizeInfo.inputText
customizeInfo.oldTryOnId = customizeInfo.tryOnId
const data = {
customerId: generateStore.customerId,
visitRecordId: generateStore.visitRecordId,
styleId: generateStore.styleId,
// modelPhotoId: generateStore.modelPhotoId,
originalTryOnId: generateStore.originalTryOnId,
originalTryOnId: type === "reload" ? customizeInfo.oldTryOnId : generateStore.originalTryOnId,
isRegenerated: 1,
prompt: customizeInfo.inputText
}
if (generateStore.customerPhotoId) data["customerPhotoId"] = generateStore.customerPhotoId
if (generateStore.customerPhotoId && customizeInfo.count === 0) data["customerPhotoId"] = generateStore.customerPhotoId
loading.value = true
generateTryOnEffect(data)
.then((res:any) => {
customizeInfo.count++
customizeInfo.tryOnId = res.tryOnId
customizeInfo.tryOnUrl = res.tryOnUrl
customizeInfo.styleUrl = res.styleUrl
@@ -113,7 +117,7 @@
<div @click="onLove">
<SvgIcon :name="`love_${customizeInfo.isFavorite ? 1 : 0}`" size="35" />
</div>
<div @click="onReload"><SvgIcon name="reload" size="35" /></div>
<div @click="onReload" v-show="customizeInfo.oldInputText"><SvgIcon name="reload" size="35" /></div>
<!-- <div @click="onDownload"><SvgIcon name="download" size="35" /></div> -->
</div>
</div>
@@ -145,7 +149,7 @@
font-size: 8.4rem;
text-align: center;
line-height: 124%;
margin-top: 3.6rem;
margin-top: 3.2rem;
}
> .tip {
margin-top: 0.56rem;
@@ -155,7 +159,7 @@
color: rgba(0, 0, 0, 0.6);
}
> .input-box {
margin-top: 6rem;
margin-top: 4.5rem;
width: 87.5rem;
height: 8.3rem;
border-radius: 0.5rem;
@@ -192,9 +196,9 @@
}
}
> .card {
margin-top: 6.4rem;
width: 72.9rem;
height: 102.3rem;
margin-top: 5rem;
width: 73rem;
height: 109.5rem;
border-radius: 2rem;
// box-shadow: 1.3rem 1.4rem 2rem 0.2rem #0000004d;
border: 0.2rem solid #d9d9d9;
@@ -246,7 +250,7 @@
}
}
> .btns {
margin-top: 5.6rem;
margin-top: 5rem;
width: 100%;
display: flex;
justify-content: center;

View File

@@ -26,7 +26,7 @@
const obj = {
visitRecordId: v.visitRecordId,
defaultImageUrl: v.defaultImageUrl,
datetime: FormatDate(v.visitTime, 'dd-MM-yyyy HH:mm'),
datetime: FormatDate(v.visitTime, 'dd/MM/yyyy HH:mm'),
lastopened: FormatDate(v.visitTime, 'HH:mm')
}
list.push(obj)
@@ -146,7 +146,7 @@
margin-top: 0;
}
> .image {
width: 21.4rem;
width: 22.9rem;
height: 100%;
overflow: hidden;
border-radius: 2rem;
@@ -154,7 +154,7 @@
> img {
width: 100%;
height: 100%;
object-fit: contain;
object-fit: cover;
display: block;
}
}

View File

@@ -20,6 +20,11 @@
const handleFinish = () => {
generateStore.updatePhotoInfo({})
generateStore.clearCustomizeInfo()
generateStore.uploadCustomizeInfo({
tryOnId: generateStore.originalTryOn.id,
tryOnUrl: generateStore.originalTryOn.tryOnUrl,
isFavorite: generateStore.originalTryOn.isLike,
})
router.push({ name: 'customize' })
}
</script>

View File

@@ -119,6 +119,10 @@
height: 86.5rem;
border-radius: 1rem;
backdrop-filter: blur(5.27rem);
-webkit-backdrop-filter: blur(5.27rem);
-moz-backdrop-filter: blur(5.27rem);
-ms-backdrop-filter: blur(5.27rem);
-o-backdrop-filter: blur(5.27rem);
box-shadow: 1.9rem 2.3rem 1.66rem 0.23rem -0.3rem 0.23rem #36180c40;
border: 0.439rem solid #fff;
// border-image: linear-gradient(90deg,#BF926E94, #ffffff) 1;

View File

@@ -181,6 +181,10 @@ const handleSuccess = (data: any) => {
rgba(0, 0, 0, 0) 100%
);
backdrop-filter: blur(35px);
-webkit-backdrop-filter: blur(35px);
-moz-backdrop-filter: blur(35px);
-ms-backdrop-filter: blur(35px);
-o-backdrop-filter: blur(35px);
border: 2px solid rgba(255, 255, 255, 0.15);
border-radius: 4.79rem;
padding: 6.8rem 5.9rem 6.2rem 7.18rem;

View File

@@ -88,38 +88,31 @@ const validatePassword = (password: string) => {
// 验证表单
const validateForm = () => {
let isValid = true
// 重置错误信息
formErrors.name = ''
formErrors.email = ''
formErrors.password = ''
// 验证邮箱
if (!formData.name) {
formErrors.name = '请输入姓名'
isValid = false
showToast('Please input your name')
return false
}
// 验证邮箱
if (!formData.email) {
formErrors.email = '请输入邮箱地址'
isValid = false
showToast('Please input your email')
return false
} else if (!validateEmail(formData.email)) {
formErrors.email = '请输入有效的邮箱地址'
isValid = false
showToast('Please input valid email')
return false
}
// 验证密码
if (!formData.password) {
formErrors.password = '请输入密码'
isValid = false
showToast('Please input password')
return false
} else if (!validatePassword(formData.password)) {
formErrors.password = '密码至少需要6位字符'
isValid = false
showToast('Password must be at least 6 characters')
return false
}
return isValid
return true
}
// 返回上一页
@@ -130,7 +123,6 @@ const goBack = () => {
// 处理注册
const handleConfirm = async () => {
if (!validateForm()) {
showToast('请检查输入信息')
return
}
@@ -247,6 +239,10 @@ const handleSignupByGoogle = async () => {
rgba(0, 0, 0, 0) 100%
);
backdrop-filter: blur(35px);
-webkit-backdrop-filter: blur(35px);
-moz-backdrop-filter: blur(35px);
-ms-backdrop-filter: blur(35px);
-o-backdrop-filter: blur(35px);
border: 2px solid rgba(255, 255, 255, 0.15);
border-radius: 4.79rem;
padding: 11.2rem 8.62rem 14.28rem 7.18rem;

View File

@@ -150,6 +150,9 @@ const handleConfirm = async () => {
background: rgba(0, 0, 0, 0.2);
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
-moz-backdrop-filter: blur(20px);
-ms-backdrop-filter: blur(20px);
-o-backdrop-filter: blur(20px);
margin-left: 7rem;
position: relative;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1), inset 0 1px 0 #000000;

View File

@@ -224,6 +224,10 @@ watch(showVideo, (newValue) => {
rgba(0, 0, 0, 0) 100%
);
backdrop-filter: blur(35px);
-webkit-backdrop-filter: blur(35px);
-moz-backdrop-filter: blur(35px);
-ms-backdrop-filter: blur(35px);
-o-backdrop-filter: blur(35px);
overflow: hidden;
position: relative;
img {
@@ -305,6 +309,10 @@ watch(showVideo, (newValue) => {
border-radius: 50%;
cursor: pointer;
backdrop-filter: blur(1rem);
-webkit-backdrop-filter: blur(1rem);
-moz-backdrop-filter: blur(1rem);
-ms-backdrop-filter: blur(1rem);
-o-backdrop-filter: blur(1rem);
border: 1px solid rgba(255, 255, 255, 0.3);
box-shadow: 0 0.8rem 1.6rem rgba(0, 0, 0, 0.4), inset 0 0.2rem 0.4rem rgba(255, 255, 255, 0.1),
inset 0 -0.2rem 0.4rem rgba(0, 0, 0, 0.3);