Kaynağa Gözat

我的视频页面优化,新增分页

dev_YWQ
HolyKnightIX 2 yıl önce
ebeveyn
işleme
6b033a0094
9 değiştirilmiş dosya ile 330 ekleme ve 663 silme
  1. +22
    -5
      src/apis/createVideo.js
  2. +3
    -4
      src/apis/myCreating.js
  3. +3
    -0
      src/lang/package/en.ts
  4. +3
    -0
      src/lang/package/zh-cn.ts
  5. +1
    -2
      src/layout/index.vue
  6. +6
    -0
      src/types/components.d.ts
  7. +22
    -30
      src/views/createVideo/index.vue
  8. +270
    -169
      src/views/myCreating/index.vue
  9. +0
    -453
      yarn.lock

+ 22
- 5
src/apis/createVideo.js Dosyayı Görüntüle

@@ -1,22 +1,39 @@
import request from "@/utils/request.js";

/**
* @description 获取人脸列表
* @params pageNum, pageSize
* @returns data
*/
export function personPhotoList(pageNum, pageSize) {
return request({
url: `api/personPhoto/list?pageNum=${pageNum}&pageSize=${pageSize}`,
method: 'get'
})
}

/**
* @description 上传图片
* @params ticket
* @params data
* @returns data
*/
export function awsImgUpload(formData) {
export function awsImgUpload(data) {
return request({
url: `/api/upload/awsImgUpload`,
method: 'post',
data: formData
data
})
}

export function awsMp3Upload(formData) {
/**
* @description 上传视频
* @params data
* @returns data
*/
export function videoUpload(data) {
return request({
url: `api/video/upload`,
method: 'post',
data: formData
data
})
}

+ 3
- 4
src/apis/myCreating.js Dosyayı Görüntüle

@@ -1,15 +1,14 @@
import request from "@/utils/request.js";

const baseURL = import.meta.env.VITE_APP_BASE_API

/**
* @description 获取我的视频作品
* @params pageSize,pageNum
* @params pageNum, pageSize
* @returns data
*/
export function userPhotoVideoList(pageSize, pageNum, title) {
export function userPhotoVideoList(pageNum, pageSize, title) {
return request({
url: `/api/userPhotoVideo/list?pageSize=${pageSize}&pageNum=${pageNum}&title=${title}`,
url: `/api/userPhotoVideo/list?pageNum=${pageNum}&pageSize=${pageSize}&title=${title}`,
method: 'get'
})
}


+ 3
- 0
src/lang/package/en.ts Dosyayı Görüntüle

@@ -31,6 +31,7 @@ export default {
// 创作视频
createVideo: {
title: "CreateVideo",
availableMould:"Available Moulds",
typeScript: "Type your Script",
uploadAudio: "Upload Audio",
aiScript: "Ai Script",
@@ -55,6 +56,8 @@ export default {
download: "Download",
delete: "Delete",
more: "More",
noList:"Nothing here. How about making one ?",
goCreate:"Go Create !",
draft: "Draft",
generating: "Generating",
generationFailed: "Failed",


+ 3
- 0
src/lang/package/zh-cn.ts Dosyayı Görüntüle

@@ -31,6 +31,7 @@ export default {
// 创作视频
createVideo: {
title: "创作视频",
availableMould:"可用模板",
typeScript: "输入文案",
uploadAudio: "上传音频",
aiScript: "AI生成文本",
@@ -55,6 +56,8 @@ export default {
download: "下载",
delete: "删除",
more: "更多",
noList:"暂无没有作品哦,快去尝试制作你的第一个视频吧!",
goCreate:"去创作",
draft: "草稿",
generating: "生成中",
generationFailed: "生成失败",


+ 1
- 2
src/layout/index.vue Dosyayı Görüntüle

@@ -98,8 +98,7 @@ onMounted(() => {});
position: relative;
width: 100%;
height: 100%;

&.mobile.openSidebar {
e &.mobile.openSidebar {
position: fixed;
top: 0;
}


+ 6
- 0
src/types/components.d.ts Dosyayı Görüntüle

@@ -11,6 +11,7 @@ declare module '@vue/runtime-core' {
ElBreadcrumb: typeof import('element-plus/es')['ElBreadcrumb']
ElBreadcrumbItem: typeof import('element-plus/es')['ElBreadcrumbItem']
ElButton: typeof import('element-plus/es')['ElButton']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDivider: typeof import('element-plus/es')['ElDivider']
ElDropdown: typeof import('element-plus/es')['ElDropdown']
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem']
@@ -20,6 +21,7 @@ declare module '@vue/runtime-core' {
ElIcon: typeof import('element-plus/es')['ElIcon']
ElInput: typeof import('element-plus/es')['ElInput']
ElOption: typeof import('element-plus/es')['ElOption']
ElPagination: typeof import('element-plus/es')['ElPagination']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElSelect: typeof import('element-plus/es')['ElSelect']
@@ -32,10 +34,14 @@ declare module '@vue/runtime-core' {
IconSelect: typeof import('./../components/IconSelect/index.vue')['default']
IEpCaretBottom: typeof import('~icons/ep/caret-bottom')['default']
IEpClose: typeof import('~icons/ep/close')['default']
IEpDelete: typeof import('~icons/ep/delete')['default']
IEpDownload: typeof import('~icons/ep/download')['default']
IEpEdit: typeof import('~icons/ep/edit')['default']
IEpGoods: typeof import('~icons/ep/goods')['default']
IEpMenu: typeof import('~icons/ep/menu')['default']
IEpSearch: typeof import('~icons/ep/search')['default']
IEpSetting: typeof import('~icons/ep/setting')['default']
IEpVideoPlay: typeof import('~icons/ep/video-play')['default']
LangSelect: typeof import('./../components/LangSelect/index.vue')['default']
MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default']
Pagination: typeof import('./../components/Pagination/index.vue')['default']


+ 22
- 30
src/views/createVideo/index.vue Dosyayı Görüntüle

@@ -61,15 +61,12 @@

<!-- 底部 -->
<div class="left-bottom">
<div class="ai">
<div class="aiAvatar"></div>
<div style="margin-left: 20px">Generate By Ai</div>
</div>
<div class="faceList scrolly">
<div>{{ $t("createVideo.availableMould") }}:</div>
<div class="faceList">
<div
class="faceItem pointer"
@click="setImgUrl(item.material)"
v-for="item in AiFace"
v-for="item in AiFaceList"
:key="item.id"
>
<!-- <div class="img"></div> -->
@@ -263,24 +260,23 @@
</div>
</template>
<script setup>
import { ref } from "vue";
import { getCurrentInstance } from "vue";
import Recorder from "js-audio-recorder";
import axios from "axios";
import { awsImgUpload, awsMp3Upload } from "@/apis/createVideo";
import { personPhotoList, awsImgUpload, videoUpload } from "@/apis/createVideo";

// 获取AI头像
const AiFace = ref([]);
function getAiFace() {
axios({
url: "https://photo.metavatar.cc/C/api/personPhoto/list?pageNum=1&pageSize=100",
method: "get",
}).then((res) => {
AiFace.value = res.data.data.list;
console.log(res.data.data.list);
});
const AiFaceList = ref([]);

function getAiFaceList(pageNum, pageSize) {
personPhotoList(pageNum, pageSize)
.then((res) => {
console.log(res, "res");
AiFaceList.value = res.data.list;
})
.catch((err) => {
console.log(err, "err");
});
}
getAiFace();

// 标题
let title = ref("");
@@ -354,7 +350,7 @@ async function uploadAudio(params) {
const timestamp = Date.now();
formData.append("file", audioData.value, timestamp + ".mp3");
try {
const res = await awsMp3Upload(formData);
const res = await videoUpload(formData);
ElMessage.success("上传成功!");
} catch (error) {
ElMessage.error(error);
@@ -395,6 +391,10 @@ const {

const string = "createVideo.typeScript";
const t = globalProperties.$t(string);

onMounted(() => {
getAiFaceList(1, 100);
});
</script>

<style lang="scss" scoped>
@@ -537,14 +537,6 @@ const t = globalProperties.$t(string);

.ai {
width: 100%;

.aiAvatar {
width: 100px;
height: 100px;
margin-left: 25px;
background-color: pink;
border-radius: 50%;
}
}

.faceList {
@@ -552,8 +544,8 @@ const t = globalProperties.$t(string);
flex-wrap: wrap;
justify-content: flex-start;
width: 100%;
height: 130px;
height: 160px;
overflow-y: scroll;
.faceItem {
width: 150px;
height: 150px;


+ 270
- 169
src/views/myCreating/index.vue Dosyayı Görüntüle

@@ -14,7 +14,7 @@
</div>
</div>
<!-- 作品列表 -->
<div class="workList flex">
<div v-if="videoList.length > 0" class="workList flex">
<div class="workItem" v-for="item in videoList" :key="item.id">
<div class="workImg">
<img
@@ -67,6 +67,14 @@
</div>
</div>
</div>
<div v-if="videoList.length == 0" class="noList">
<div class="title">
{{ $t("myCreating.noList") }}
</div>
<div class="goCreate" @click="goCreate">
{{ $t("myCreating.goCreate") }}
</div>
</div>
<!-- 预览作品 -->
<el-dialog
destroy-on-close
@@ -110,6 +118,21 @@
</span>
</template>
</el-dialog>

<div class="pagination">
<el-pagination
v-model:current-page="pageNum"
v-model:page-size="pageSize"
:page-sizes="[10, 20, 50, 100, 200]"
:small="false"
:disabled="false"
:background="true"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</template>
<script setup>
@@ -117,20 +140,34 @@ import { userPhotoVideoList, delUserPhotoVideoByID } from "@/apis/myCreating";
import { timestampToTime } from "@/utils/tools";
import { useI18n } from "vue-i18n";
import { getStatus } from "./videoStatus";
import { useRouter } from "vue-router";

const router = useRouter();
// 当前语言状态与国际化组件
const { locale } = useI18n();
const lanChange = ref(locale);

let title = ref("");
let pageSize = ref(100);
let pageNum = ref(1);
const title = ref("");
const pageNum = ref(1);
const pageSize = ref(10);
const total = ref(0);
// 弹窗显示隐藏
let showDialog = ref(false);
const showDialog = ref(false);
// 当前作品
let presentItem = ref("");
const presentItem = ref("");
// 作品列表
const videoList = ref([]);

const handleSizeChange = (val) => {
pageSize.value = val;
getPhotoVideoList(pageNum.value, pageSize.value, title.value);
};

const handleCurrentChange = (val) => {
pageNum.value = val;
getPhotoVideoList(pageNum.value, pageSize.value, title.value);
};

// 点击作品
function clickVideoItem(item) {
showDialog.value = true;
@@ -150,8 +187,12 @@ function mouseenter(item) {

function handleDownload() {}

function goCreate() {
router.push("/createVideo");
}

function searchVideoList() {
getPhotoVideoList(pageSize.value, pageNum.value, title.value, true);
getPhotoVideoList(pageNum.value, pageSize.value, title.value, true);
}

function handelDelete(id, title) {
@@ -174,8 +215,8 @@ function handelDelete(id, title) {
* @description:获取我的视频作品
* @return: data
*/
function getPhotoVideoList(pageSize, pageNum, title, searchFlag) {
userPhotoVideoList(pageSize, pageNum, title)
function getPhotoVideoList(pageNum, pageSize, title, searchFlag) {
userPhotoVideoList(pageNum, pageSize, title)
.then((res) => {
console.log(res, "res");
res.data.list.forEach((item) => {
@@ -185,6 +226,7 @@ function getPhotoVideoList(pageSize, pageNum, title, searchFlag) {
item.statusName = getStatus(item.videoStatus);
});
videoList.value = res.data.list;
total.value = res.data.total * 1;
if (searchFlag) {
const total = res.data.total;
const msg1 =
@@ -195,7 +237,13 @@ function getPhotoVideoList(pageSize, pageNum, title, searchFlag) {
lanChange.value == "zh-cn"
? `查询成功!没有符合条件的视频`
: `Found! No match videos`;
ElMessage.success(total > 0 ? msg1 : msg2);
const msg3 =
lanChange.value == "zh-cn"
? `查询成功!已加载全部视频`
: `Found! Present all videos`;
return title
? ElMessage.success(total > 0 ? msg1 : msg2)
: ElMessage.success(msg3);
}
})
.catch((err) => {
@@ -219,204 +267,257 @@ function delPhotoVideo(videoID) {
}

onMounted(() => {
getPhotoVideoList(pageSize.value, pageNum.value, title.value);
getPhotoVideoList(pageNum.value, pageSize.value, title.value);
});
</script>

<style lang="scss" scoped>
.page {
// height: calc(100vh - 84px);
height: 887px;
padding: 50px;
height: 1200px;
padding: 50px 130px;
background-color: #fff;
border-radius: 25px 0 0;
}

:deep(.el-input__wrapper) {
border: none;
border-bottom: 2px solid #000;
border-radius: 0;
box-shadow: none;
}

.el-icon.icon-edit {
width: 30px;
height: 30px;
font-size: 30px;
color: #8c939d;
text-align: center;
cursor: pointer;
transition: all 0.3s;
&:hover {
color: #292929;
.top {
margin-bottom: 35px;
}
}

.workList {
flex-wrap: wrap;
justify-content: flex-start;
width: 100%;
height: 200px;
margin-top: 20px;
cursor: pointer;
.workItem {
position: relative;
width: 300px;
.workList {
flex-wrap: wrap;
justify-content: flex-start;
width: 100%;
height: 200px;
margin: 0 10px 10px 0;
border: 2px solid #c2c2c2;
border-radius: 5px;
margin-top: 20px;
cursor: pointer;
overflow: hidden;
.workImg {
.workItem {
position: relative;
width: 100%;
height: 170px;
width: 300px;
height: 200px;
margin: 0 20px 30px 0;
border: 2px solid #c2c2c2;
border-radius: 5px;
cursor: pointer;
padding: 10px;
.coverImg {
max-width: 90%;
max-height: 170px;
overflow: hidden;
.workImg {
position: relative;
width: 100%;
height: 170px;
cursor: pointer;
}
.takePlace {
position: absolute;
top: 40%;
width: 80%;
}
}

.more {
position: absolute;
top: 0;
left: 0;
display: none;
width: 100%;
height: 170px;
background-color: rgb(0 0 0 / 30%);
cursor: pointer;
.icon-videoPlay {
position: absolute;
top: 50%;
left: 50%;
width: 50px;
height: 50px;
font-size: 50px;
color: #fff;
text-align: center;
transform: translate(-50%, -50%);
cursor: pointer;
}

.showBtn {
position: absolute;
top: 10px;
right: 10px;
width: 20px;
height: 20px;
font-size: 20px;
line-height: 10px;
color: #fff;
text-align: center;
transition: all 0.3s;
cursor: pointer;
border-radius: 2px;
&:hover {
background-color: #00000056;
padding: 10px;
.coverImg {
max-width: 90%;
max-height: 170px;
cursor: pointer;
}
.takePlace {
position: absolute;
top: 40%;
width: 80%;
}
}

.btns {
.more {
position: absolute;
top: 45px;
right: 10px;
// width: 70px;
// height: 60px;
overflow: hidden;
border-radius: 10px;
top: 0;
left: 0;
width: 100%;
height: 170px;
background-color: rgb(0 0 0 / 30%);
cursor: pointer;
opacity: 0;
transition: all 0.2s;
.icon-videoPlay {
position: absolute;
top: 50%;
left: 50%;
width: 50px;
height: 50px;
font-size: 50px;
color: #fff;
text-align: center;
transform: translate(-50%, -50%);
cursor: pointer;
}

&-item {
// width: 70px;
// height: 30px;
.showBtn {
position: absolute;
top: 10px;
right: 10px;
width: 20px;
height: 20px;
font-size: 20px;
line-height: 10px;
color: #fff;
text-align: center;
background-color: #fff;
padding: 0 10px;
transition: all 0.3s;
cursor: pointer;
&-icon {
position: relative;
display: inline-block;
width: 20px;
height: 20px;
border-radius: 2px;
&:hover {
background-color: #00000056;
}
}

.btns {
position: absolute;
top: 45px;
right: 10px;
// width: 70px;
// height: 60px;
overflow: hidden;
border-radius: 10px;
cursor: pointer;

&-item {
// width: 70px;
// height: 30px;
text-align: center;
background-color: #fff;
padding: 0 10px;
transition: all 0.3s;
cursor: pointer;
.icon-delete {
position: absolute;
top: 4px;
left: 0;
&-icon {
position: relative;
display: inline-block;
width: 20px;
height: 20px;
font-size: 16px;
color: #000;
text-align: center;
cursor: pointer;
.icon-delete {
position: absolute;
top: 4px;
left: 0;
width: 20px;
height: 20px;
font-size: 16px;
color: #000;
text-align: center;
cursor: pointer;
}
}
}

.text {
display: inline-block;
height: 30px;
padding-left: 5px;
margin-top: -5px;
line-height: 20px;
cursor: pointer;
}
&:hover {
color: #ffffff;
background-color: #0000001a;
.text {
display: inline-block;
height: 30px;
padding-left: 5px;
margin-top: -5px;
line-height: 20px;
cursor: pointer;
}
&:hover {
color: #ffffff;
background-color: #0000001a;
}
}
}
}
}

.workInfo {
justify-content: space-between;
height: 30px;
padding: 0 10px;
line-height: 30px;
border-top: 1px solid #afafaf;
}
.statusName {
position: absolute;
top: 10%;
left: -10%;
width: 120px;
text-align: center;
color: #ffffff;
font-size: 14px;
transform: rotate(-45deg);

&.draft {
/* 草稿 */
background: linear-gradient(to right, #d7d2cc 0%, #304352 100%);
.workInfo {
justify-content: space-between;
height: 30px;
padding: 0 10px;
line-height: 30px;
border-top: 1px solid #afafaf;
}
&.generating {
/* 生成中 */
background: linear-gradient(270deg, #4b61dc, #15d1b8);
.statusName {
position: absolute;
top: 10%;
left: -10%;
width: 120px;
text-align: center;
color: #ffffff;
font-size: 14px;
transform: rotate(-45deg);

&.draft {
/* 草稿 */
background: linear-gradient(to right, #d7d2cc 0%, #304352 100%);
}
&.generating {
/* 生成中 */
background: linear-gradient(270deg, #4b61dc, #15d1b8);
}
&.generationFailed {
/* 生成失败 */
background: linear-gradient(120deg, #f093fb 0%, #f5576c 100%);
}
&.generationSucceed {
/* 生成成功 */
background: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%);
}
}
&.generationFailed {
/* 生成失败 */
background: linear-gradient(120deg, #f093fb 0%, #f5576c 100%);
&:hover {
.more {
opacity: 1;
}
}
&.generationSucceed {
/* 生成成功 */
background: linear-gradient(120deg, #84fab0 0%, #8fd3f4 100%);
}
}
.noList {
.title {
font-size: 30px;
text-align: center;
margin-top: 100px;
background-image: -webkit-linear-gradient(
left,
#4b61dc,
#15d1b8 25%,
#4b61dc 50%,
#15d1b8 75%,
#4b61dc
) !important;
-webkit-text-fill-color: transparent !important;
-webkit-background-clip: text !important;
background-clip: text !important;
-webkit-background-size: 200% 100% !important;
background-size: 200% 100% !important;
}

.goCreate {
width: 200px;
height: 40px;
line-height: 40px;
text-align: center;
color: #ffffff;
border-radius: 6px;
background: linear-gradient(270deg, #4b61dc, #15d1b8);
margin: 30px auto;
cursor: pointer;
transition: all 0.3s;
&:hover {
transform: scale(1.1);
}
}
}
.pagination {
position: fixed;
bottom: 50px;
left: 50%;
transform: translateX(-50%);
background-color: #ffffff;
padding: 10px 20px;
border-radius: 8px;
transition: all 0.3s;
cursor: pointer;
&:hover {
background-color: #b8b8b873;
}
}
}

:deep(.el-input__wrapper) {
border: none;
border-bottom: 2px solid #000;
border-radius: 0;
box-shadow: none;
}

.workItem:hover .more {
display: block;
.el-icon.icon-edit {
width: 30px;
height: 30px;
font-size: 30px;
color: #8c939d;
text-align: center;
cursor: pointer;
transition: all 0.3s;
&:hover {
color: #292929;
}
}



+ 0
- 453
yarn.lock
Dosya farkı çok büyük olduğundan ihmal edildi
Dosyayı Görüntüle


Yükleniyor…
İptal
Kaydet