congzc пре 1 година
родитељ
комит
d78226c1c0
13 измењених фајлова са 411 додато и 255 уклоњено
  1. +9
    -1
      .env.test
  2. +1
    -1
      package.json
  3. +20
    -7
      src/apis/createVideo.js
  4. +12
    -0
      src/apis/myCreating.js
  5. +5
    -1
      src/lang/index.ts
  6. +7
    -5
      src/lang/package/en.ts
  7. +2
    -0
      src/lang/package/zh-cn.ts
  8. +2
    -0
      src/types/auto-imports.d.ts
  9. +17
    -6
      src/utils/request.js
  10. +51
    -44
      src/views/createVideo/index.vue
  11. +54
    -3
      src/views/myCreating/index.vue
  12. +10
    -21
      vite.config.ts
  13. +221
    -166
      yarn-error.log

+ 9
- 1
.env.test Прегледај датотеку

@@ -5,5 +5,13 @@ NODE_ENV='test'

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'


# NODE_ENV='development'

# VITE_APP_TITLE = 'Metavatar-PC'
# VITE_APP_PORT = 3000
# VITE_APP_BASE_API = 'https://phototest.metavatar.cc/C'



+ 1
- 1
package.json Прегледај датотеку

@@ -77,4 +77,4 @@
"repository": "https://gitee.com/youlaiorg/vue3-element-admin.git",
"author": "有来开源组织",
"license": "MIT"
}
}

+ 20
- 7
src/apis/createVideo.js Прегледај датотеку

@@ -66,11 +66,18 @@ export function delImgApi(id) {
* @params id
* @returns data
*/
export function checkPhotoApi(material) {
export function baiduPhotoApi(data) {
const formData = new FormData();
formData.append('file', data);
return request({
url: `api/personPhoto/checkPhoto?material=${material}`,
method: 'get',
})
url: 'api/personPhoto/baiduPhoto',
method: 'post',
data: formData,
headers: {
'Content-Type': 'application/form-data'
}
});

}

/**
@@ -79,11 +86,17 @@ export function checkPhotoApi(material) {
* @returns data
*/
export function checkFaceApi(data) {
const formData = new FormData();
formData.append('file', data);
return request({
url: `suimang/image_qualit`,
url: 'api/personPhoto/checkPhoto',
method: 'post',
data: { img: data }
})
data: formData,
headers: {
'Content-Type': 'application/form-data'
}
});

}

/**


+ 12
- 0
src/apis/myCreating.js Прегледај датотеку

@@ -35,4 +35,16 @@ export function videoHyApi(id) {
url: `/api/userPhotoVideo/videoHy?id=${id}`,
method: 'get'
})
}

/**
* @description 查询是否有视频更新
* @params id
* @returns data
*/
export function checkVideoStatusApi(time) {
return request({
url: `/api/userPhotoVideo/checkVideoStatus?time${time}`,
method: 'get'
})
}

+ 5
- 1
src/lang/index.ts Прегледај датотеку

@@ -1,7 +1,11 @@
import { createI18n } from 'vue-i18n';
import { useAppStore } from '@/store/modules/app';

const appStore = useAppStore();
import { store } from '@/store/index'; // 因为不是在setup环境而是js中,必须重新初始化加载store
const appStore = useAppStore(store); //pinia


// const appStore = useAppStore();
// 本地语言包
import enLocale from './package/en';
import zhCnLocale from './package/zh-cn';


+ 7
- 5
src/lang/package/en.ts Прегледај датотеку

@@ -72,7 +72,7 @@ export default {
AipictureTip:'Please customize your picture',
chooseMusic:'Choose Music',
searchMusic:'Search Music',
comingSoon:'coming soon',
comingSoon:'COMING SOON',
hotMusic:'Hit song',
inputRequirement:'Please enter your requirements, for example: Please generate a beverage advertisement of 500 words or less',
GeneratedText:'Generated Text',
@@ -81,7 +81,7 @@ export default {
tooltip1:'Click to listen',
tooltip2:'Add Pause',
uploadImgTip1:'Click here to upload pictures',
uploadImgTip2:'Please ensure that the uploaded image is an open face image',
uploadImgTip2:'Please upload unobstructed frontal photo',
entered:'entered'
},

@@ -97,6 +97,7 @@ export default {
more: "More",
loading: "Loading , just a moment",
loading1: "just a moment",
compress:'Compressed picture',
sensitiveness: "Sensitive information is being tested",
chackFace: "Face detection in progress",
upLoadPictures: "Uploading pictures",
@@ -108,11 +109,12 @@ export default {
generationSucceed: "Succeed",
manuscriptText: "Manuscript",
generatingText: "The video is generating, Please wait a moment",
generationFailedText: "Video generation failed, you can click the button below to edit the generation again ",
generationFailedText: "Video generation failed, click Edit button to retry.",
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',
hasNewVideo:'You have a new video generated!!',
},

// 个人账户
@@ -150,7 +152,7 @@ export default {
selectPlan: "SELECT PLAN",
WeChatPay: "WeChatPay",
Alipay: "Alipay",
score:'score',
score:'Credit',
day:'day',
second:'second',
yes:'yes',
@@ -160,7 +162,7 @@ export default {
AIGeneratesPhotoPrices:'AI generates photo unit prices',
UnitChargeDuration:'Unit charge duration',
Language:'Language',
sound:'sound',
sound:'Sound',
IndividualVideoDuration:'Individual video duration',
AIGeneratedPortrait:'AI generated portrait',
PhotoSinging:'Photo singing',


+ 2
- 0
src/lang/package/zh-cn.ts Прегледај датотеку

@@ -97,6 +97,7 @@ export default {
more: "更多",
loading: "加载中,请稍等",
loading1: "请稍等",
compress:'正在压缩图片',
sensitiveness: "正在进行敏感信息检测",
chackFace: "正在进行人脸检测",
upLoadPictures: "正在上传图片",
@@ -113,6 +114,7 @@ export default {
upSharpness:'升级画质',
upSharpnessTips:'如果对预览效果满意,您可以点击此处来提升视频清晰度~',
freeUserTip:'免费用户生成视频时长限制为1分钟',
hasNewVideo:'您有新的视频生成了!',
},

// 个人账户


+ 2
- 0
src/types/auto-imports.d.ts Прегледај датотеку

@@ -2,6 +2,7 @@
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']
@@ -270,6 +271,7 @@ 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']>


+ 17
- 6
src/utils/request.js Прегледај датотеку

@@ -1,18 +1,20 @@
import axios from 'axios'
import router from '@/router/index'
import { ElMessage } from 'element-plus'

// ElMessage
import { useAppStore } from '@/store/modules/app';
import { userInfoModules } from "@/store/modules/userInfo";
// import stores from '@/store/index'
import { store } from '@/store/index'; // 因为不是在setup环境而是js中,必须重新初始化加载store

const appStore = useAppStore(store); //pinia
const userInfoPinia = userInfoModules(store); //pinia
// 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)


/**
* @description:发送Axios请求
*/
@@ -42,7 +44,10 @@ request.interceptors.response.use(
function (response) {

if (!response.data) {
ElMessage.error($t('tips.systemException'));
// ElMessage.error($t('tips.systemException'));
ElMessage.error(
appStore.language == "zh-cn" ? `服务器繁忙,请重试!` : `The server is busy, please try again`
);
}
let code = response.data.code
// 当token无效(过期或损坏)时 1053为未登录
@@ -50,13 +55,19 @@ request.interceptors.response.use(
localStorage.removeItem("AccessToken");
router.push("/login");
// ElMessage.error("登录过期,请重新登录!");
ElMessage.error($t('tips.tokenExpired'));
// ElMessage.error($t('tips.tokenExpired'));
ElMessage.error(
appStore.language == "zh-cn" ? `登录过期,请重新登录!` : `Login expired, please login again`
);
return
// 弹出错误
} else if (code != 200) {
if (code == 500) {
// ElMessage.error("系统异常,请稍后再试");
ElMessage.error($t('tips.systemException'));
// ElMessage.error($t('tips.systemException'));
ElMessage.error(
appStore.language == "zh-cn" ? `服务器繁忙,请重试!` : `The server is busy, please try again`
);
// 其他错误
} else {
return Promise.reject(response.data)


+ 51
- 44
src/views/createVideo/index.vue Прегледај датотеку

@@ -694,7 +694,7 @@ import {
personPhotoUserListList,
awsImgUpload,
delImgApi,
checkPhotoApi,
baiduPhotoApi,
checkFaceApi,
videoUpload,
saveImgApi,
@@ -850,38 +850,33 @@ async function lookImg(e) {
maxSizeMB: 4, // 最大压缩大小为 4MB
useWebWorker: true, // 使用 Web Worker 进行压缩,提高性能
};
imgUploadTips.value = "compress";

const compressedFile = await imageCompression(e.target.files[0], options);

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();
// });
});
const res = await baiduPhotoApi(compressedFile);
if (res.code != 200) {
throw new Error();
}
// 图片人脸信息检测通过时,继续检测敏感信息
imgUploadTips.value = "chackFace";
const res2 = await checkFaceApi(compressedFile);
if (res2.code != 200) {
throw new Error();
}
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`
? `图片不符合规范,上传失败`
: `Image does not meet the specifications, upload failed`
);
showFace.value = 1;
showUploadBtn.value = 2;
@@ -925,15 +920,25 @@ async function changeFile() {
imgUploadTips.value = "upLoadPictures";
compressionImgLoad.value = true;
showUploadBtn.value = 3;
imgUrl.value = URL.createObjectURL(imgData.value);
// imgUrl.value = URL.createObjectURL(imgData.value);
let formData = new FormData();
const timestamp = Date.now();
formData.append("file", imgData.value, timestamp + ".png");
try {
// 上传图片
const res = await awsImgUpload(formData);
if (res.code != 200) {
throw new Error();
}
// 保存图片
const res2 = await saveImgApi({ material: res.data.url });
if (res2.code != 200) {
throw new Error();
} else {
ElMessage.success(
lanChange.value == "zh-cn" ? `上传成功` : `Upload successfully`
);
}
// 重新获取列表
compressionImgLoad.value = false;
showUploadBtn.value = 4;
@@ -941,23 +946,17 @@ async function changeFile() {
getAiFaceUserList(1, 10, 3);
pageNumUser.value = 1;
overLoadUser.value = false;
if (res2.code == 200) {
ElMessage.success(
lanChange.value == "zh-cn" ? `上传成功` : `Upload successfully`
);
} else {
ElMessage.error(
lanChange.value == "zh-cn" ? `上传失败` : `Upload failure`
);
}
faceItemActive.value = res2.data.id;
imgUrl.value = res2.data.material;
submitImgBtn.value = false;
console.log(123654);
showUploadBtn.value = 1;
imgUploadTips.value = null;
} catch (error) {
ElMessage.error(lanChange.value == "zh-cn" ? `上传失败` : `Upload failure`);
imgUrl.value = null;
showFace.value = 1;
showUploadBtn.value = 2;
compressionImgLoad.value = false;
imgUploadTips.value = null;
}
}
@@ -972,8 +971,14 @@ function chooseMyImg() {
}
// 点击AI头像区的+号
function clickAddBtn() {
faceItemActive.value = null;
// if (!imgUploadTips.value) {
// showUploadBtn.value = 3;
// submitImgBtn.value = false;
// compressionImgLoad.value = true;
// return;
// }
showUploadBtn.value = 2;
faceItemActive.value = null;
}
//#endregion ---------------------------

@@ -1084,6 +1089,8 @@ async function getPreviewAudio() {
return;
}
previewAudioUrl.value = res.data.data;
// previewAudioUrl.value =
// "/suimang/static/tts/2023-07-04/16884538755531874.wav";
let audioA = document.getElementById("audio");
audioA.addEventListener("loadedmetadata", async () => {
audioA.muted = false; // 将 muted 属性设置为 false
@@ -1208,19 +1215,19 @@ const handleFileChange = async () => {
if (uploadAudioTime.value > 60) {
ElMessage.error(
lanChange.value == "zh-cn"
? `上传失败,免费用户上传音频时长最多为60秒`
: `Upload failed, free users can upload audio for up to 60 seconds`
? `上传音频大小或者长度超出限制,请重新上传`
: `The size or length of the uploaded audio exceeds the limit. Please upload it again`
);
audioUrl.value = null;
audioData.value = null;
return;
}
// 限制3mb
if (file.size / 1048576 > 3) {
// 限制5mb
if (file.size / 1048576 > 5) {
ElMessage.error(
lanChange.value == "zh-cn"
? `上传失败,免费用户上传音频大小最大为3MB`
: `Failed to upload. The maximum size of audio uploaded by free users is 3MB`
? `上传音频大小或者长度超出限制,请重新上传`
: `The size or length of the uploaded audio exceeds the limit. Please upload it again`
);
audioUrl.value = null;
audioData.value = null;


+ 54
- 3
src/views/myCreating/index.vue Прегледај датотеку

@@ -12,6 +12,10 @@
><i-ep-search
/></el-icon>
</div>
<!-- 更新视频提示 -->
<div class="hasNewVideoTips" :class="hasNewCreate ? '' : 'hasNew'">
{{ $t("myCreating.hasNewVideo") }}
</div>
</div>
<!-- 作品列表 -->
<div v-if="!isLoading">
@@ -127,7 +131,7 @@
>
<div class="videoBox">
<!-- 免费用户1分钟 -->
<div v-if="false" class="overtimeTips">
<div v-if="true" class="overtimeTips">
<img src="../../assets/img/tips.png" alt="" />
{{ $t("myCreating.freeUserTip") }}
</div>
@@ -243,6 +247,7 @@ import {
userPhotoVideoListApi,
delUserPhotoVideoByIDApi,
videoHyApi,
checkVideoStatusApi,
} from "@/apis/myCreating";
import { timestampToTime } from "@/utils/tools";
import { useI18n } from "vue-i18n";
@@ -428,23 +433,70 @@ function delPhotoVideo(videoID) {
ElMessage.error(err.message);
});
}

//#region 定时刷新
const hasNewCreate = ref(false); //提示框显示隐藏
const nowTime = Date.now();
const checkVideoStatus = async () => {
console.log(nowTime);
// const res = await checkVideoStatusApi();
// if (res.code == 2115) {
// hasNewCreate.value = true;
// const changeHasNewCreate = setTimeout(() => {
// hasNewCreate.value = false;
// }, 5000);
// getPhotoVideoList(1, 10, "");
// }
};
const startLogin = () => {
// 每隔 3 秒执行一次登录请求
const intervalId = setInterval(checkVideoStatus, 3000);
// 在组件销毁前清除定时器
onUnmounted(() => {
clearInterval(intervalId);
});
};
//#endregion ---------------------------
//#region 页面初始化
onMounted(() => {
isLoading.value = true;
getPhotoVideoList(pageNum.value, pageSize.value, title.value);
// startLogin();
});
//#endregion ---------------------------
</script>

<style lang="scss" scoped>
.page {
position: relative;
min-height: calc(100vh - 80px);
padding: 15px 130px;
background-color: #fff;
border-radius: 25px 0 0;
width: 100%;
overflow: hidden;

.top {
position: relative;
margin-bottom: 35px;
.hasNewVideoTips {
position: absolute;
top: 0;
left: 50%;
transform: translateX(-50%);
width: 400px;
padding: 5px 30px;
color: #fff;
background-color: #000;
text-align: center;
font-size: 20px;
transition: all 0.5s;
opacity: 1;
border-radius: 15px;
}
.hasNew {
opacity: 0;
transition: all 0.5s;
}
}
.loadingIcon {
height: 100px;
@@ -465,7 +517,6 @@ onMounted(() => {
// height: 200px;
margin-top: 5px;
padding-bottom: 50px;
cursor: pointer;
.workItem {
position: relative;
width: 300px;


+ 10
- 21
vite.config.ts Прегледај датотеку

@@ -58,27 +58,16 @@ export default defineConfig(({ mode }: ConfigEnv): UserConfig => {
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",

// }
},

// "/C/api/suimang": {
// target:'https://phototest.metavatar.cc/', // 线上接口地址
// changeOrigin: true,
// rewrite: (path) => path.replace(/^\/C\/api\/suimang/, '/suimang/image_qualit')
// },
// "/api/suimang": {
// target:'https://phototest.metavatar.cc/', // 线上接口地址
// changeOrigin: true,
// rewrite: (path) => path.replace(/^\/api\/suimang/, '/suimang/image_qualit')
// },
},
},
plugins: [


+ 221
- 166
yarn-error.log
Разлика између датотеке није приказан због своје велике величине
Прегледај датотеку


Loading…
Откажи
Сачувај