| @@ -5,6 +5,6 @@ NODE_ENV='development' | |||||
| VITE_APP_TITLE = 'Metavatar-PC' | VITE_APP_TITLE = 'Metavatar-PC' | ||||
| VITE_APP_PORT = 3000 | VITE_APP_PORT = 3000 | ||||
| # VITE_APP_BASE_API = 'https://photo.metavatar.cc/C' | |||||
| VITE_APP_BASE_API = 'https://phototest.metavatar.cc/C' | VITE_APP_BASE_API = 'https://phototest.metavatar.cc/C' | ||||
| # VITE_APP_BASE_API = 'https://phototest.metavatar.cc/C/api' | |||||
| @@ -5,5 +5,5 @@ NODE_ENV='production' | |||||
| VITE_APP_TITLE = 'Metavatar-PC' | VITE_APP_TITLE = 'Metavatar-PC' | ||||
| VITE_APP_PORT = 3000 | VITE_APP_PORT = 3000 | ||||
| # VITE_APP_BASE_API = 'https://photo.metavatar.cc/C' | |||||
| VITE_APP_BASE_API = 'https://photo.metavatar.cc/C' | VITE_APP_BASE_API = 'https://photo.metavatar.cc/C' | ||||
| # VITE_APP_BASE_API = 'https://photo.metavatar.cc/C/C' | |||||
| @@ -1,7 +1,7 @@ | |||||
| import request from "@/utils/request.js"; | import request from "@/utils/request.js"; | ||||
| /** | /** | ||||
| * @description 获取人脸列表 | |||||
| * @description 获取系统人脸列表 | |||||
| * @params pageNum, pageSize | * @params pageNum, pageSize | ||||
| * @returns data | * @returns data | ||||
| */ | */ | ||||
| @@ -13,7 +13,7 @@ export function personPhotoList(pageNum, pageSize, sendType) { | |||||
| } | } | ||||
| /** | /** | ||||
| * @description 获取人脸列表 | |||||
| * @description 获取个人人脸列表 | |||||
| * @params pageNum, pageSize | * @params pageNum, pageSize | ||||
| * @returns data | * @returns data | ||||
| */ | */ | ||||
| @@ -25,7 +25,7 @@ export function personPhotoUserListList(pageNum, pageSize, sendType) { | |||||
| } | } | ||||
| /** | /** | ||||
| * @description 上传图片 | |||||
| * @description 保存图片 | |||||
| * @params data | * @params data | ||||
| * @returns data | * @returns data | ||||
| */ | */ | ||||
| @@ -61,6 +61,31 @@ export function delImgApi(id) { | |||||
| }) | }) | ||||
| } | } | ||||
| /** | |||||
| * @description 检测图片是否敏感(百度) | |||||
| * @params id | |||||
| * @returns data | |||||
| */ | |||||
| export function checkPhotoApi(material) { | |||||
| return request({ | |||||
| url: `api/personPhoto/checkPhoto?material=${material}`, | |||||
| method: 'get', | |||||
| }) | |||||
| } | |||||
| /** | |||||
| * @description 检测人脸(邃芒) | |||||
| * @params id | |||||
| * @returns data | |||||
| */ | |||||
| export function checkFaceApi(data) { | |||||
| return request({ | |||||
| url: `suimang/image_qualit`, | |||||
| method: 'post', | |||||
| data: { img: data } | |||||
| }) | |||||
| } | |||||
| /** | /** | ||||
| * @description 上传音频 | * @description 上传音频 | ||||
| * @params data | * @params data | ||||
| @@ -13,7 +13,10 @@ | |||||
| ></path> | ></path> | ||||
| </svg> | </svg> | ||||
| </el-icon> | </el-icon> | ||||
| <span class="loadingText">{{ $t("myCreating.loading") }}</span> | |||||
| <span class="loadingText" | |||||
| ><span v-if="tips">{{ $t(`myCreating.${tips}`) }},</span | |||||
| >{{ $t("myCreating.loading1") }}</span | |||||
| > | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| @@ -27,6 +30,9 @@ const props = defineProps({ | |||||
| isLoading: { | isLoading: { | ||||
| required: true, //是否必传 | required: true, //是否必传 | ||||
| }, | }, | ||||
| tips: { | |||||
| required: false, //是否必传 | |||||
| }, | |||||
| }); | }); | ||||
| </script> | </script> | ||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||
| @@ -96,6 +96,10 @@ export default { | |||||
| delete: "Delete", | delete: "Delete", | ||||
| more: "More", | more: "More", | ||||
| loading: "Loading , just a moment", | loading: "Loading , just a moment", | ||||
| loading1: "just a moment", | |||||
| sensitiveness: "Sensitive information is being tested", | |||||
| chackFace: "Face detection in progress", | |||||
| upLoadPictures: "Uploading pictures", | |||||
| noList: "Nothing here. How about making one ?", | noList: "Nothing here. How about making one ?", | ||||
| goCreate: "Go Create !", | goCreate: "Go Create !", | ||||
| manuscript: "Manuscript", | manuscript: "Manuscript", | ||||
| @@ -108,6 +112,7 @@ export default { | |||||
| edit:'Edit', | edit:'Edit', | ||||
| upSharpness:'Upgrade image quality', | upSharpness:'Upgrade image quality', | ||||
| upSharpnessTips:'If you are satisfied with the preview, you can click here to improve the video sharpness ~', | upSharpnessTips:'If you are satisfied with the preview, you can click here to improve the video sharpness ~', | ||||
| freeUserTip:'Free user-generated videos are limited to 1 minute', | |||||
| }, | }, | ||||
| // 个人账户 | // 个人账户 | ||||
| @@ -95,7 +95,11 @@ export default { | |||||
| download: "下载", | download: "下载", | ||||
| delete: "删除", | delete: "删除", | ||||
| more: "更多", | more: "更多", | ||||
| loading: "加载中,请稍等哦", | |||||
| loading: "加载中,请稍等", | |||||
| loading1: "请稍等", | |||||
| sensitiveness: "正在进行敏感信息检测", | |||||
| chackFace: "正在进行人脸检测", | |||||
| upLoadPictures: "正在上传图片", | |||||
| noList: "暂无没有作品哦,快去尝试制作你的第一个视频吧!", | noList: "暂无没有作品哦,快去尝试制作你的第一个视频吧!", | ||||
| goCreate: "去创作", | goCreate: "去创作", | ||||
| manuscript: "草稿", | manuscript: "草稿", | ||||
| @@ -108,6 +112,7 @@ export default { | |||||
| edit:'编辑', | edit:'编辑', | ||||
| upSharpness:'升级画质', | upSharpness:'升级画质', | ||||
| upSharpnessTips:'如果对预览效果满意,您可以点击此处来提升视频清晰度~', | upSharpnessTips:'如果对预览效果满意,您可以点击此处来提升视频清晰度~', | ||||
| freeUserTip:'免费用户生成视频时长限制为1分钟', | |||||
| }, | }, | ||||
| // 个人账户 | // 个人账户 | ||||
| @@ -2,7 +2,6 @@ | |||||
| export {} | export {} | ||||
| declare global { | declare global { | ||||
| const EffectScope: typeof import('vue')['EffectScope'] | const EffectScope: typeof import('vue')['EffectScope'] | ||||
| const ElForm: typeof import('element-plus/es')['ElForm'] | |||||
| const ElMessage: typeof import('element-plus/es')['ElMessage'] | const ElMessage: typeof import('element-plus/es')['ElMessage'] | ||||
| const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] | const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] | ||||
| const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | ||||
| @@ -271,7 +270,6 @@ import { UnwrapRef } from 'vue' | |||||
| declare module 'vue' { | declare module 'vue' { | ||||
| interface ComponentCustomProperties { | interface ComponentCustomProperties { | ||||
| readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']> | readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']> | ||||
| readonly ElForm: UnwrapRef<typeof import('element-plus/es')['ElForm']> | |||||
| readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']> | readonly ElMessage: UnwrapRef<typeof import('element-plus/es')['ElMessage']> | ||||
| readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']> | readonly ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']> | ||||
| readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | ||||
| @@ -8,7 +8,9 @@ import { store } from '@/store/index'; // 因为不是在setup环境而是js | |||||
| const userInfoPinia = userInfoModules(store); //pinia | const userInfoPinia = userInfoModules(store); //pinia | ||||
| // 开发环境需以 "/api" 拼接,其他环境需以 "/C" 拼接 | // 开发环境需以 "/api" 拼接,其他环境需以 "/C" 拼接 | ||||
| const env = process.env.NODE_ENV == 'development' ? "/api" : "/C" | const env = process.env.NODE_ENV == 'development' ? "/api" : "/C" | ||||
| // const env = process.env.NODE_ENV == 'development' ? "" : "" | |||||
| // console.log(process.env.NODE_ENV, 'env') | // console.log(process.env.NODE_ENV, 'env') | ||||
| console.log(env) | |||||
| /** | /** | ||||
| @@ -77,6 +77,7 @@ | |||||
| <my-loading | <my-loading | ||||
| style="margin-top: 150px" | style="margin-top: 150px" | ||||
| :isLoading="compressionImgLoad" | :isLoading="compressionImgLoad" | ||||
| :tips="imgUploadTips" | |||||
| ></my-loading> | ></my-loading> | ||||
| <div v-if="!compressionImgLoad" class="trueImg inmiddle"> | <div v-if="!compressionImgLoad" class="trueImg inmiddle"> | ||||
| <div class="imgBox"> | <div class="imgBox"> | ||||
| @@ -693,6 +694,8 @@ import { | |||||
| personPhotoUserListList, | personPhotoUserListList, | ||||
| awsImgUpload, | awsImgUpload, | ||||
| delImgApi, | delImgApi, | ||||
| checkPhotoApi, | |||||
| checkFaceApi, | |||||
| videoUpload, | videoUpload, | ||||
| saveImgApi, | saveImgApi, | ||||
| uploadProgressApi, | uploadProgressApi, | ||||
| @@ -712,7 +715,8 @@ import { useI18n } from "vue-i18n"; | |||||
| import Recorder from "js-audio-recorder"; //mp3插件 | import Recorder from "js-audio-recorder"; //mp3插件 | ||||
| import imageCompression from "browser-image-compression"; //压缩图片插件 | import imageCompression from "browser-image-compression"; //压缩图片插件 | ||||
| import { useRoute, useRouter } from "vue-router"; | import { useRoute, useRouter } from "vue-router"; | ||||
| import axios from "axios"; | |||||
| import { loginApi } from "@/api/auth"; | |||||
| //#endregion --------------------------------- | //#endregion --------------------------------- | ||||
| const route = useRoute(); | const route = useRoute(); | ||||
| @@ -831,6 +835,7 @@ async function deleteFaceImg(id) { | |||||
| //#endregion ------------------------------ | //#endregion ------------------------------ | ||||
| //#region 预览图片 | //#region 预览图片 | ||||
| const imgUploadTips = ref(null); // 图片检测loading的文字提示 | |||||
| const compressionImgLoad = ref(false); | const compressionImgLoad = ref(false); | ||||
| async function lookImg(e) { | async function lookImg(e) { | ||||
| if (e.target.files[0]) { | if (e.target.files[0]) { | ||||
| @@ -842,20 +847,63 @@ async function lookImg(e) { | |||||
| compressionImgLoad.value = true; | compressionImgLoad.value = true; | ||||
| // 压缩配置 | // 压缩配置 | ||||
| const options = { | const options = { | ||||
| maxSizeMB: 2, // 最大压缩大小为 1MB | |||||
| maxSizeMB: 4, // 最大压缩大小为 4MB | |||||
| useWebWorker: true, // 使用 Web Worker 进行压缩,提高性能 | useWebWorker: true, // 使用 Web Worker 进行压缩,提高性能 | ||||
| }; | }; | ||||
| const compressedFile = await imageCompression(e.target.files[0], options); | const compressedFile = await imageCompression(e.target.files[0], options); | ||||
| imgUrl.value = URL.createObjectURL(compressedFile); | |||||
| imgData.value = compressedFile; | |||||
| showUploadBtn.value = 4; | |||||
| submitImgBtn.value = true; | |||||
| compressionImgLoad.value = false; | |||||
| await changeFile(); | |||||
| imgUploadTips.value = "sensitiveness"; | |||||
| try { | |||||
| await getImageBase64(compressedFile).then(async (base64) => { | |||||
| const res = await checkFaceApi(base64); | |||||
| console.log(res); | |||||
| // axios({ | |||||
| // method: "post", | |||||
| // url: "https://phototest.metavatar.cc/suimang/image_qualit", | |||||
| // // headers: { | |||||
| // // "content-type": "multipart/form-data", | |||||
| // // token: AccessToken, | |||||
| // // "Access-Control-Allow-Credentials": true, | |||||
| // // }, | |||||
| // data: { img: base64 }, | |||||
| // }).then(async (res) => { | |||||
| // // const res2 = await checkPhotoApi(compressedFile); | |||||
| // // // const res = await checkFaceApi(compressedFile); | |||||
| // // imgUrl.value = URL.createObjectURL(compressedFile); | |||||
| // // imgData.value = compressedFile; | |||||
| // // showUploadBtn.value = 4; | |||||
| // // submitImgBtn.value = true; | |||||
| // // compressionImgLoad.value = false; | |||||
| // // await changeFile(); | |||||
| // }); | |||||
| }); | |||||
| } catch (error) { | |||||
| ElMessage.error( | |||||
| lanChange.value == "zh-cn" | |||||
| ? `图片涉及敏感内容,上传失败` | |||||
| : `Image related to sensitive content, upload failed` | |||||
| ); | |||||
| showFace.value = 1; | |||||
| showUploadBtn.value = 2; | |||||
| compressionImgLoad.value = false; | |||||
| imgUploadTips.value = null; | |||||
| } | |||||
| } else { | } else { | ||||
| return; | return; | ||||
| } | } | ||||
| } | } | ||||
| // blob转base64 | |||||
| function getImageBase64(blob) { | |||||
| return new Promise((resolve, reject) => { | |||||
| const reader = new FileReader(); | |||||
| reader.readAsDataURL(blob); | |||||
| reader.onload = () => { | |||||
| const base64 = reader.result; | |||||
| resolve(base64); | |||||
| }; | |||||
| reader.onerror = (error) => reject(error); | |||||
| }); | |||||
| } | |||||
| //#endregion ------------------ | //#endregion ------------------ | ||||
| // 标题 | // 标题 | ||||
| @@ -874,6 +922,7 @@ function chooSystemImg(params) { | |||||
| } | } | ||||
| // 上传图片 | // 上传图片 | ||||
| async function changeFile() { | async function changeFile() { | ||||
| imgUploadTips.value = "upLoadPictures"; | |||||
| compressionImgLoad.value = true; | compressionImgLoad.value = true; | ||||
| showUploadBtn.value = 3; | showUploadBtn.value = 3; | ||||
| imgUrl.value = URL.createObjectURL(imgData.value); | imgUrl.value = URL.createObjectURL(imgData.value); | ||||
| @@ -906,8 +955,10 @@ async function changeFile() { | |||||
| submitImgBtn.value = false; | submitImgBtn.value = false; | ||||
| console.log(123654); | console.log(123654); | ||||
| showUploadBtn.value = 1; | showUploadBtn.value = 1; | ||||
| imgUploadTips.value = null; | |||||
| } catch (error) { | } catch (error) { | ||||
| ElMessage.error(error); | |||||
| ElMessage.error(lanChange.value == "zh-cn" ? `上传失败` : `Upload failure`); | |||||
| imgUploadTips.value = null; | |||||
| } | } | ||||
| } | } | ||||
| // 点击个人仓库tab | // 点击个人仓库tab | ||||
| @@ -1157,8 +1208,8 @@ const handleFileChange = async () => { | |||||
| if (uploadAudioTime.value > 60) { | if (uploadAudioTime.value > 60) { | ||||
| ElMessage.error( | ElMessage.error( | ||||
| lanChange.value == "zh-cn" | lanChange.value == "zh-cn" | ||||
| ? `上传失败,上传音频时长最多为60秒` | |||||
| : `Description Failed to upload audio files. The maximum duration of uploading audio files is 60 seconds` | |||||
| ? `上传失败,免费用户上传音频时长最多为60秒` | |||||
| : `Upload failed, free users can upload audio for up to 60 seconds` | |||||
| ); | ); | ||||
| audioUrl.value = null; | audioUrl.value = null; | ||||
| audioData.value = null; | audioData.value = null; | ||||
| @@ -1168,8 +1219,8 @@ const handleFileChange = async () => { | |||||
| if (file.size / 1048576 > 3) { | if (file.size / 1048576 > 3) { | ||||
| ElMessage.error( | ElMessage.error( | ||||
| lanChange.value == "zh-cn" | lanChange.value == "zh-cn" | ||||
| ? `上传失败,上传音频大小最大为3MB` | |||||
| : `Description Upload failed. The maximum size of uploaded audio is 3MB` | |||||
| ? `上传失败,免费用户上传音频大小最大为3MB` | |||||
| : `Failed to upload. The maximum size of audio uploaded by free users is 3MB` | |||||
| ); | ); | ||||
| audioUrl.value = null; | audioUrl.value = null; | ||||
| audioData.value = null; | audioData.value = null; | ||||
| @@ -1509,8 +1560,8 @@ async function uploadMusic() { | |||||
| if (uploadAudioTime.value > 60) { | if (uploadAudioTime.value > 60) { | ||||
| ElMessage.error( | ElMessage.error( | ||||
| lanChange.value == "zh-cn" | lanChange.value == "zh-cn" | ||||
| ? `上传失败,上传音频时长最多为60秒` | |||||
| : `Description Failed to upload audio files. The maximum duration of uploading audio files is 60 seconds` | |||||
| ? `上传失败,免费用户上传音频时长最多为60秒` | |||||
| : `Upload failed, free users can upload audio for up to 60 seconds` | |||||
| ); | ); | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -1518,8 +1569,8 @@ async function uploadMusic() { | |||||
| if (file.size / 1048576 > 3) { | if (file.size / 1048576 > 3) { | ||||
| ElMessage.error( | ElMessage.error( | ||||
| lanChange.value == "zh-cn" | lanChange.value == "zh-cn" | ||||
| ? `上传失败,上传音频大小最大为3MB` | |||||
| : `Description Upload failed. The maximum size of uploaded audio is 3MB` | |||||
| ? `上传失败,免费用户上传音频大小最大为3MB` | |||||
| : `Failed to upload. The maximum size of audio uploaded by free users is 3MB` | |||||
| ); | ); | ||||
| return; | return; | ||||
| } | } | ||||
| @@ -126,6 +126,11 @@ | |||||
| center | center | ||||
| > | > | ||||
| <div class="videoBox"> | <div class="videoBox"> | ||||
| <!-- 免费用户1分钟 --> | |||||
| <div v-if="false" class="overtimeTips"> | |||||
| <img src="../../assets/img/tips.png" alt="" /> | |||||
| {{ $t("myCreating.freeUserTip") }} | |||||
| </div> | |||||
| <video | <video | ||||
| v-if="presentItem.videoPlayUrl" | v-if="presentItem.videoPlayUrl" | ||||
| controls="true" | controls="true" | ||||
| @@ -706,6 +711,23 @@ onMounted(() => { | |||||
| // justify-content: space-between; | // justify-content: space-between; | ||||
| width: 100%; | width: 100%; | ||||
| padding: 20px; | padding: 20px; | ||||
| .overtimeTips { | |||||
| // width: 60%; | |||||
| // display: inline-block; | |||||
| padding: 5px; | |||||
| margin-bottom: 10px; | |||||
| background-color: #ccc; | |||||
| border-radius: 5px; | |||||
| line-height: 20px; | |||||
| color: #000; | |||||
| text-align: center; | |||||
| img { | |||||
| width: 20px; | |||||
| height: 20px; | |||||
| vertical-align: middle; | |||||
| margin-right: 5px; | |||||
| } | |||||
| } | |||||
| video { | video { | ||||
| width: 100%; | width: 100%; | ||||
| max-height: 600px; | max-height: 600px; | ||||
| @@ -53,10 +53,32 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { | |||||
| proxy: { | proxy: { | ||||
| // 反向代理解决跨域 | // 反向代理解决跨域 | ||||
| "/api": { | "/api": { | ||||
| // target: https://phototest.metavatar.cc/C, // 线上接口地址 | |||||
| target: env.VITE_APP_BASE_API, // 线上接口地址 | target: env.VITE_APP_BASE_API, // 线上接口地址 | ||||
| changeOrigin: true, | changeOrigin: true, | ||||
| rewrite: (path) => path.replace(/^\/api/, ""), | rewrite: (path) => path.replace(/^\/api/, ""), | ||||
| }, | }, | ||||
| "/api/suimang": { | |||||
| // target: https://phototest.metavatar.cc/C, // 线上接口地址 | |||||
| target:'https://phototest.metavatar.cc/', // 线上接口地址 | |||||
| changeOrigin: true, | |||||
| rewrite: (path) => path.replace(/^\/api\/suimang/, "/suimang"), | |||||
| // pathRewrite: { | |||||
| // "^/api/suimang": "/suimang", | |||||
| // } | |||||
| }, | |||||
| "/suimang": { | |||||
| // target: https://phototest.metavatar.cc/C, // 线上接口地址 | |||||
| target:'https://phototest.metavatar.cc/', // 线上接口地址 | |||||
| changeOrigin: true, | |||||
| rewrite: (path) => path.replace(/^\/suimang/, '/suimang/image_qualit') | |||||
| // pathRewrite: { | |||||
| // "^/api/suimang": "/suimang", | |||||
| // } | |||||
| }, | |||||
| }, | }, | ||||
| }, | }, | ||||
| plugins: [ | plugins: [ | ||||