@@ -5,6 +5,6 @@ NODE_ENV='development' | |||
VITE_APP_TITLE = 'Metavatar-PC' | |||
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/api' | |||
@@ -5,5 +5,5 @@ NODE_ENV='production' | |||
VITE_APP_TITLE = 'Metavatar-PC' | |||
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/C' |
@@ -1,7 +1,7 @@ | |||
import request from "@/utils/request.js"; | |||
/** | |||
* @description 获取人脸列表 | |||
* @description 获取系统人脸列表 | |||
* @params pageNum, pageSize | |||
* @returns data | |||
*/ | |||
@@ -13,7 +13,7 @@ export function personPhotoList(pageNum, pageSize, sendType) { | |||
} | |||
/** | |||
* @description 获取人脸列表 | |||
* @description 获取个人人脸列表 | |||
* @params pageNum, pageSize | |||
* @returns data | |||
*/ | |||
@@ -25,7 +25,7 @@ export function personPhotoUserListList(pageNum, pageSize, sendType) { | |||
} | |||
/** | |||
* @description 上传图片 | |||
* @description 保存图片 | |||
* @params 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 上传音频 | |||
* @params data | |||
@@ -13,7 +13,10 @@ | |||
></path> | |||
</svg> | |||
</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> | |||
</template> | |||
@@ -27,6 +30,9 @@ const props = defineProps({ | |||
isLoading: { | |||
required: true, //是否必传 | |||
}, | |||
tips: { | |||
required: false, //是否必传 | |||
}, | |||
}); | |||
</script> | |||
<style lang="scss" scoped> | |||
@@ -96,6 +96,10 @@ export default { | |||
delete: "Delete", | |||
more: "More", | |||
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 ?", | |||
goCreate: "Go Create !", | |||
manuscript: "Manuscript", | |||
@@ -108,6 +112,7 @@ export default { | |||
edit:'Edit', | |||
upSharpness:'Upgrade image quality', | |||
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: "下载", | |||
delete: "删除", | |||
more: "更多", | |||
loading: "加载中,请稍等哦", | |||
loading: "加载中,请稍等", | |||
loading1: "请稍等", | |||
sensitiveness: "正在进行敏感信息检测", | |||
chackFace: "正在进行人脸检测", | |||
upLoadPictures: "正在上传图片", | |||
noList: "暂无没有作品哦,快去尝试制作你的第一个视频吧!", | |||
goCreate: "去创作", | |||
manuscript: "草稿", | |||
@@ -108,6 +112,7 @@ export default { | |||
edit:'编辑', | |||
upSharpness:'升级画质', | |||
upSharpnessTips:'如果对预览效果满意,您可以点击此处来提升视频清晰度~', | |||
freeUserTip:'免费用户生成视频时长限制为1分钟', | |||
}, | |||
// 个人账户 | |||
@@ -2,7 +2,6 @@ | |||
export {} | |||
declare global { | |||
const EffectScope: typeof import('vue')['EffectScope'] | |||
const ElForm: typeof import('element-plus/es')['ElForm'] | |||
const ElMessage: typeof import('element-plus/es')['ElMessage'] | |||
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] | |||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | |||
@@ -271,7 +270,6 @@ import { UnwrapRef } from 'vue' | |||
declare module 'vue' { | |||
interface ComponentCustomProperties { | |||
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 ElMessageBox: UnwrapRef<typeof import('element-plus/es')['ElMessageBox']> | |||
readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | |||
@@ -8,7 +8,9 @@ import { store } from '@/store/index'; // 因为不是在setup环境而是js | |||
const userInfoPinia = userInfoModules(store); //pinia | |||
// 开发环境需以 "/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(env) | |||
/** | |||
@@ -77,6 +77,7 @@ | |||
<my-loading | |||
style="margin-top: 150px" | |||
:isLoading="compressionImgLoad" | |||
:tips="imgUploadTips" | |||
></my-loading> | |||
<div v-if="!compressionImgLoad" class="trueImg inmiddle"> | |||
<div class="imgBox"> | |||
@@ -693,6 +694,8 @@ import { | |||
personPhotoUserListList, | |||
awsImgUpload, | |||
delImgApi, | |||
checkPhotoApi, | |||
checkFaceApi, | |||
videoUpload, | |||
saveImgApi, | |||
uploadProgressApi, | |||
@@ -712,7 +715,8 @@ import { useI18n } from "vue-i18n"; | |||
import Recorder from "js-audio-recorder"; //mp3插件 | |||
import imageCompression from "browser-image-compression"; //压缩图片插件 | |||
import { useRoute, useRouter } from "vue-router"; | |||
import axios from "axios"; | |||
import { loginApi } from "@/api/auth"; | |||
//#endregion --------------------------------- | |||
const route = useRoute(); | |||
@@ -831,6 +835,7 @@ async function deleteFaceImg(id) { | |||
//#endregion ------------------------------ | |||
//#region 预览图片 | |||
const imgUploadTips = ref(null); // 图片检测loading的文字提示 | |||
const compressionImgLoad = ref(false); | |||
async function lookImg(e) { | |||
if (e.target.files[0]) { | |||
@@ -842,20 +847,63 @@ async function lookImg(e) { | |||
compressionImgLoad.value = true; | |||
// 压缩配置 | |||
const options = { | |||
maxSizeMB: 2, // 最大压缩大小为 1MB | |||
maxSizeMB: 4, // 最大压缩大小为 4MB | |||
useWebWorker: true, // 使用 Web Worker 进行压缩,提高性能 | |||
}; | |||
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 { | |||
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 ------------------ | |||
// 标题 | |||
@@ -874,6 +922,7 @@ function chooSystemImg(params) { | |||
} | |||
// 上传图片 | |||
async function changeFile() { | |||
imgUploadTips.value = "upLoadPictures"; | |||
compressionImgLoad.value = true; | |||
showUploadBtn.value = 3; | |||
imgUrl.value = URL.createObjectURL(imgData.value); | |||
@@ -906,8 +955,10 @@ async function changeFile() { | |||
submitImgBtn.value = false; | |||
console.log(123654); | |||
showUploadBtn.value = 1; | |||
imgUploadTips.value = null; | |||
} catch (error) { | |||
ElMessage.error(error); | |||
ElMessage.error(lanChange.value == "zh-cn" ? `上传失败` : `Upload failure`); | |||
imgUploadTips.value = null; | |||
} | |||
} | |||
// 点击个人仓库tab | |||
@@ -1157,8 +1208,8 @@ const handleFileChange = async () => { | |||
if (uploadAudioTime.value > 60) { | |||
ElMessage.error( | |||
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; | |||
audioData.value = null; | |||
@@ -1168,8 +1219,8 @@ const handleFileChange = async () => { | |||
if (file.size / 1048576 > 3) { | |||
ElMessage.error( | |||
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; | |||
audioData.value = null; | |||
@@ -1509,8 +1560,8 @@ async function uploadMusic() { | |||
if (uploadAudioTime.value > 60) { | |||
ElMessage.error( | |||
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; | |||
} | |||
@@ -1518,8 +1569,8 @@ async function uploadMusic() { | |||
if (file.size / 1048576 > 3) { | |||
ElMessage.error( | |||
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; | |||
} | |||
@@ -126,6 +126,11 @@ | |||
center | |||
> | |||
<div class="videoBox"> | |||
<!-- 免费用户1分钟 --> | |||
<div v-if="false" class="overtimeTips"> | |||
<img src="../../assets/img/tips.png" alt="" /> | |||
{{ $t("myCreating.freeUserTip") }} | |||
</div> | |||
<video | |||
v-if="presentItem.videoPlayUrl" | |||
controls="true" | |||
@@ -706,6 +711,23 @@ onMounted(() => { | |||
// justify-content: space-between; | |||
width: 100%; | |||
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 { | |||
width: 100%; | |||
max-height: 600px; | |||
@@ -53,10 +53,32 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => { | |||
proxy: { | |||
// 反向代理解决跨域 | |||
"/api": { | |||
// target: https://phototest.metavatar.cc/C, // 线上接口地址 | |||
target: env.VITE_APP_BASE_API, // 线上接口地址 | |||
changeOrigin: true, | |||
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: [ | |||