diff --git a/.gitignore b/.gitignore index 230a187..d66bd99 100644 --- a/.gitignore +++ b/.gitignore @@ -26,4 +26,3 @@ pnpm-debug.log* /__MACOSX /node_modules /设计图 -/src/assets/images diff --git a/package.json b/package.json index 69ca720..255abec 100644 --- a/package.json +++ b/package.json @@ -25,4 +25,4 @@ "@vitejs/plugin-vue-jsx": "^3.0.0", "vite": "^7.1.3" } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 788315e..bf86dcb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -422,67 +422,56 @@ packages: resolution: {integrity: sha512-u72Mzc6jyJwKjJbZZcIYmd9bumJu7KNmHYdue43vT1rXPm2rITwmPWF0mmPzLm9/vJWxIRbao/jrQmxTO0Sm9w==} cpu: [arm] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm-musleabihf@4.50.0': resolution: {integrity: sha512-S4UefYdV0tnynDJV1mdkNawp0E5Qm2MtSs330IyHgaccOFrwqsvgigUD29uT+B/70PDY1eQ3t40+xf6wIvXJyg==} cpu: [arm] os: [linux] - libc: [musl] '@rollup/rollup-linux-arm64-gnu@4.50.0': resolution: {integrity: sha512-1EhkSvUQXJsIhk4msxP5nNAUWoB4MFDHhtc4gAYvnqoHlaL9V3F37pNHabndawsfy/Tp7BPiy/aSa6XBYbaD1g==} cpu: [arm64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-arm64-musl@4.50.0': resolution: {integrity: sha512-EtBDIZuDtVg75xIPIK1l5vCXNNCIRM0OBPUG+tbApDuJAy9mKago6QxX+tfMzbCI6tXEhMuZuN1+CU8iDW+0UQ==} cpu: [arm64] os: [linux] - libc: [musl] '@rollup/rollup-linux-loongarch64-gnu@4.50.0': resolution: {integrity: sha512-BGYSwJdMP0hT5CCmljuSNx7+k+0upweM2M4YGfFBjnFSZMHOLYR0gEEj/dxyYJ6Zc6AiSeaBY8dWOa11GF/ppQ==} cpu: [loong64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-ppc64-gnu@4.50.0': resolution: {integrity: sha512-I1gSMzkVe1KzAxKAroCJL30hA4DqSi+wGc5gviD0y3IL/VkvcnAqwBf4RHXHyvH66YVHxpKO8ojrgc4SrWAnLg==} cpu: [ppc64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-gnu@4.50.0': resolution: {integrity: sha512-bSbWlY3jZo7molh4tc5dKfeSxkqnf48UsLqYbUhnkdnfgZjgufLS/NTA8PcP/dnvct5CCdNkABJ56CbclMRYCA==} cpu: [riscv64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-riscv64-musl@4.50.0': resolution: {integrity: sha512-LSXSGumSURzEQLT2e4sFqFOv3LWZsEF8FK7AAv9zHZNDdMnUPYH3t8ZlaeYYZyTXnsob3htwTKeWtBIkPV27iQ==} cpu: [riscv64] os: [linux] - libc: [musl] '@rollup/rollup-linux-s390x-gnu@4.50.0': resolution: {integrity: sha512-CxRKyakfDrsLXiCyucVfVWVoaPA4oFSpPpDwlMcDFQvrv3XY6KEzMtMZrA+e/goC8xxp2WSOxHQubP8fPmmjOQ==} cpu: [s390x] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-gnu@4.50.0': resolution: {integrity: sha512-8PrJJA7/VU8ToHVEPu14FzuSAqVKyo5gg/J8xUerMbyNkWkO9j2ExBho/68RnJsMGNJq4zH114iAttgm7BZVkA==} cpu: [x64] os: [linux] - libc: [glibc] '@rollup/rollup-linux-x64-musl@4.50.0': resolution: {integrity: sha512-SkE6YQp+CzpyOrbw7Oc4MgXFvTw2UIBElvAvLCo230pyxOLmYwRPwZ/L5lBe/VW/qT1ZgND9wJfOsdy0XptRvw==} cpu: [x64] os: [linux] - libc: [musl] '@rollup/rollup-openharmony-arm64@4.50.0': resolution: {integrity: sha512-PZkNLPfvXeIOgJWA804zjSFH7fARBBCpCXxgkGDRjjAhRLOR8o0IGS01ykh5GYfod4c2yiiREuDM8iZ+pVsT+Q==} diff --git a/src/App.vue b/src/App.vue index d58263c..801557b 100644 --- a/src/App.vue +++ b/src/App.vue @@ -89,6 +89,8 @@ const initUserGameInfos = async (refresh_official, refresh_cap_scan) => { const result = await Request('game/info', { refresh_official: refresh_official, refresh_cap_scan: refresh_cap_scan }, "GET") if (result.res.status === 200) { + globalStore.draw_chances = result.json.draw_chances + globalStore.game_chances = result.json.game_chances globalStore.invitees = result.json.invitees globalStore.followed_official = result.json.followed_official globalStore.cap_scan = result.json.cap_scan diff --git a/src/components/GenerateImg.vue b/src/components/GenerateImg.vue index 569f8d9..03af555 100644 --- a/src/components/GenerateImg.vue +++ b/src/components/GenerateImg.vue @@ -3,7 +3,11 @@ import { ref, computed, watch, onMounted } from "vue" import { useRouter, useRoute } from 'vue-router' import positionMaps from '../static/positionMaps.js' import imagePositionMaps from '../static/imagePositionMaps.js' -import { RequestImg, Storage } from "../libs/utils" +import { Storage } from "../libs/utils" +import { globalStore } from "../globalstore.js"; +import faceTemplate from "../static/ali_face_template.js"; +import MyPhoto from './MyPhoto.vue' +import PhotoSquare from './PhotoSquare.vue' defineProps({ show: true @@ -14,41 +18,63 @@ onMounted(() => { import { ElMessage } from 'element-plus'; import { Plus } from '@element-plus/icons-vue'; +import { tr } from "element-plus/es/locales.mjs" -const imageUrl1 = ref(''); // 上传前的校验 -// const beforeUpload = (file) => { -// const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; -// if (!isJpgOrPng) { -// ElMessage.error('只能上传JPG或PNG格式的图片!'); -// return false; // 返回false阻止上传 -// } -// const isLt2M = file.size / 1024 / 1024 < 2; -// if (!isLt2M) { -// ElMessage.error('图片大小不能超过2MB!'); -// return false; -// } -// return true; // 返回true继续上传 -// }; +const beforeUpload = (file) => { + const isJpgOrPng = file.type === 'image/jpeg' || file.type === 'image/png'; + if (!isJpgOrPng) { + ElMessage.error('只能上传JPG或PNG格式的图片!'); + return false; + } + const isLt2M = file.size / 1024 / 1024 < 2; + if (!isLt2M) { + ElMessage.error('图片大小不能超过2MB!'); + return false; + } + return true; +}; + +const getTemplateIdsFromUrl = (response, url, index)=> { + const filename = url.split('/').pop(); + const matchedTemplate = faceTemplate.find(template => template.name === filename); + if (!matchedTemplate) { + console.error(`No template found for filename: ${filename}`); + return null; + } + + const dataItem = matchedTemplate.data[index]; + if (!dataItem) { + console.error(`No data found at index ${index} for template: ${filename}`); + return null; + } + + return { + "mergeId": response.id, + "template_id": matchedTemplate.template_id, + "templateFaceID": dataItem.templateFaceID + } + ; +} // 上传成功回调 -// const handleSuccess = (response, index) => { -// console.log(index) -// imageUrl1.value = response.url; -// ElMessage.success('上传成功!'); -// }; +const handleSuccess = (response, index) => { + // 上传成功后,将文件信息添加到数组 + if (response) { + const ids = getTemplateIdsFromUrl(response, window.location.href, index); + uploadedFiles.push({ + templateIds: ids + }); + } + uploadItems.value[index].imageUrl = response.url; + ElMessage.success('上传成功!'); +}; // 上传失败回调 -// const handleError = (error) => { -// // console.error('上传失败:', error); -// // ElMessage.error('上传失败,请重试!'); -// uploadItems.value[0].imageUrl = "src/assets/images/demo.png"; -// uploadItems.value[1].imageUrl = "src/assets/images/demo.png"; -// uploadItems.value[2].imageUrl = "src/assets/images/demo.png"; -// uploadItems.value[3].imageUrl = "src/assets/images/demo.png"; -// uploadItems.value[4].imageUrl = "src/assets/images/demo.png"; -// ElMessage.success('上传成功!'); -// }; +const handleError = (error) => { + console.error('上传失败:', error); + ElMessage.error('上传失败,请重试!'); +}; // 根据imageUrl的结尾编号确定需要多少个上传项 const getUploadItemsCount = () => { @@ -102,11 +128,157 @@ const clearUploadFile = (index) => { if (uploadRefs.value[index]) { uploadRefs.value[index].clearFiles(); uploadItems.value[index].imageUrl = ''; + + uploadedFiles.value.splice(index, 1); } }; -const generateImage = () => { +// 存储上传成功的文件数据 +const uploadedFiles = []; +const currentImageUrl = ref(null) +// const generateImage = (options) => { +// globalStore.generateStatus = true; +// const urlParams = new URLSearchParams(window.location.search); +// currentImageUrl.value = urlParams.get('imageUrl'); +// globalStore.generateImgTemplates.push(currentImageUrl.value); + +// disableClick.value = true; +// displayScanModel.value = true; +// const formData = { +// "template_id": "01a1d6a7-43e3-4a52-bfc3-ab4216cb56ee", +// "faces": [ +// { +// "image_id": 65, +// "template_face_id": "01a1d6a7-43e3-4a52-bfc3-ab4216cb56ee_0" +// }, +// { +// "image_id": 66, +// "template_face_id": "01a1d6a7-43e3-4a52-bfc3-ab4216cb56ee_1" +// } +// ], +// "is_public": false +// } + +// const timeoutPromise = new Promise((resolve, reject) => { +// setTimeout(() => { +// resolve({ timedOut: true }); +// }, 4000); +// }); + +// const apiPromise = fetch('https://huodong2.lzlj.com/api/faceFamily/face/merge', { +// method: 'POST', +// headers: { +// 'Content-Type': 'application/json', +// Accept: "application/json", +// 'Authorization': `Bearer ${Storage.get("userinfos").api_token}` +// }, +// body: JSON.stringify(formData) +// }) +// .then(response => response.json()) +// .then(data => { +// globalStore.mergeId = data.merge_id; +// fetch(`https://api.example.com/face/merge/${data.merge_id}/status`, { +// method: 'GET', +// headers: { +// 'Authorization': `Bearer ${Storage.get("userinfos").api_token}` +// } +// }) +// const res = response.json() +// console.log('get status Success:', res) +// console.log('merge Success:', data); +// return { success: true, data }; +// }) +// .catch((error) => { +// console.error('Error:', error); +// return { success: false, error }; +// }); + +// Promise.race([apiPromise, timeoutPromise]) +// .then(result => { +// if (result.success) { +// navigateToSynthesizedResults(); +// } +// }) +// .catch((error) => { +// console.error('Error:', error); +// }); +// } +const faces = []; +const generateImage = async (options) => { + console.log(uploadedFiles); + globalStore.generateStatus = true; + const urlParams = new URLSearchParams(window.location.search); + currentImageUrl.value = urlParams.get('imageUrl'); + + disableClick.value = true; + displayScanModel.value = true; + + uploadedFiles.forEach(file => { + globalStore.generateImgTemplates.push({ + merge_id: file.templateIds.mergeId, + backgroundImg: currentImageUrl.value + }); + faces.push({ + image_id: file.templateIds.mergeId, + template_face_id: file.templateIds.templateFaceID + }); + }); + + const formData = { + "template_id": uploadedFiles[0].templateIds.template_id, + "faces": faces, + "is_public": false + } + + try { + const mergeResponse = await fetch('https://huodong2.lzlj.com/api/faceFamily/face/merge', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + Accept: "application/json", + 'Authorization': `Bearer ${Storage.get("userinfos").api_token}` + }, + body: JSON.stringify(formData) + }); + + const mergeData = await mergeResponse.json(); + globalStore.mergeId = mergeData.merge_id; + + let statusSuccess = false; + const startTime = Date.now(); + const timeoutDuration = 2000; + + while (Date.now() - startTime < timeoutDuration) { + fetch(`https://huodong2.lzlj.com/api/faceFamily/face/merge/${mergeData.merge_id}/status`, { + method: 'GET', + headers: { + 'Authorization': `Bearer ${Storage.get("userinfos").api_token}` + } + }) + .then(response => response.json()) + .then(data => { + console.log('Success:', data); + if (data.status = 'success') { + globalStore.result_url = data.result_url; + statusSuccess = true; + } + }) + .catch((error) => { + console.error('Error:', error); + }); + } + + if (statusSuccess) { + navigateToSynthesizedResults(); + } else { + navigateToSynthesizedResults(); //TODO 上线删除 + console.log('Status check timed out or failed'); + } + + } catch (error) { + console.error('Merge API error:', error); + } } const router = useRouter(); @@ -223,65 +395,91 @@ const imagePosition = (index) => { }; }; - - // 自定义上传方法 const customUpload = async (options) => { const { file, data, onProgress, onSuccess, onError } = options try { - // FormData对象用于构建表单数据 const formData = new FormData() formData.append('type', 'ali-face') formData.append('image', file) - - const config = { + + fetch('https://huodong2.lzlj.com/api/faceFamily/upload/image', { + method: 'POST', headers: { - 'Content-Type': 'multipart/form-data' + 'Authorization': `Bearer ${Storage.get("userinfos").api_token}` }, - onUploadProgress: (progressEvent) => { - if (progressEvent.lengthComputable) { - const percent = Math.round((progressEvent.loaded / progressEvent.total) * 100) - onProgress({ percent }) // 更新上传进度 - } - } - } - - // 使用你封装的Request方法调用API - const result = await RequestImg('upload/image', formData) - - // API调用成功处理 - if (result.code === 'success') { // code字段需要根据你的API实际返回调整 - onSuccess(result.data) // result.data包含服务器返回的数据 - } else { - onError(new Error(result.message || '上传失败')) - } - - return result - + body: formData + }) + .then(response => response.json()) + .then(data => { + console.log('Success:', data); + onSuccess(data); + }) + .catch((error) => { + console.error('Error:', error); + }); } catch (error) { onError(error) throw error } } + +const displayScanModel = ref(false); +const disableClick = ref(false); + +const isMyPhotoVisible = ref(false); +const isPhotoSquareVisible = ref(false); +const showMyPhoto = () => { + isMyPhotoVisible.value = true; + isPhotoSquareVisible.value = false; +}; + +const showPhotoSquare = () => { + isMyPhotoVisible.value = false; + isPhotoSquareVisible.value = true; +}; + +const navigateToSynthesizedResults = () => { + router.push({ + name: 'synthesizedResults' + }) +} \ No newline at end of file diff --git a/src/components/GenerateImgConfirm.vue b/src/components/GenerateImgConfirm.vue index 878dc30..ed4863d 100644 --- a/src/components/GenerateImgConfirm.vue +++ b/src/components/GenerateImgConfirm.vue @@ -16,11 +16,17 @@ const goToGenerateImgPage = () => { }) } +const closeTodoList = () => { + router.push({ + name: 'selectTemplateV2' + }) +} +