| @@ -0,0 +1,27 @@ | |||||
| import request from "@/utils/request.js"; | |||||
| const baseURL = import.meta.env.VITE_APP_BASE_API | |||||
| /** | |||||
| * @description 获取我的视频作品 | |||||
| * @params pageSize,pageNum | |||||
| * @returns data | |||||
| */ | |||||
| export function userPhotoVideoList(pageSize, pageNum, title) { | |||||
| return request({ | |||||
| url: `/api/userPhotoVideo/list?pageSize=${pageSize}&pageNum=${pageNum}&title=${title}`, | |||||
| method: 'get' | |||||
| }) | |||||
| } | |||||
| /** | |||||
| * @description 删除视频作品 | |||||
| * @params videoID | |||||
| * @returns data | |||||
| */ | |||||
| export function delUserPhotoVideoByID(videoID) { | |||||
| return request({ | |||||
| url: `/api/userPhotoVideo/del?id=${videoID}`, | |||||
| method: 'get' | |||||
| }) | |||||
| } | |||||
| @@ -48,12 +48,20 @@ export default { | |||||
| // 我的视频 | // 我的视频 | ||||
| myCreating: { | myCreating: { | ||||
| title: "My Creating", | title: "My Creating", | ||||
| typeTitle: "Type a title", | |||||
| search: "Search...", | |||||
| name: "Name", | name: "Name", | ||||
| date: "Date", | date: "Date", | ||||
| videoTitle: "Video Title:", | |||||
| download: "Download", | download: "Download", | ||||
| delete: "Delete", | delete: "Delete", | ||||
| more: "More", | more: "More", | ||||
| draft: "Draft", | |||||
| generating: "Generating", | |||||
| generationFailed: "Failed", | |||||
| generationSucceed: "Succeed", | |||||
| draftText: "Draft", | |||||
| generatingText: "The video is generating, please wait a moment", | |||||
| generationFailedText: "The video generate is failed, Reason:", | |||||
| }, | }, | ||||
| // 个人账户 | // 个人账户 | ||||
| @@ -48,12 +48,20 @@ export default { | |||||
| // 我的视频 | // 我的视频 | ||||
| myCreating: { | myCreating: { | ||||
| title: "我的视频", | title: "我的视频", | ||||
| typeTitle: "输入标题", | |||||
| search: "搜索:我的视频", | |||||
| name: "名称", | name: "名称", | ||||
| date: "时间", | date: "时间", | ||||
| videoTitle: "视频标题:", | |||||
| download: "下载", | download: "下载", | ||||
| delete: "删除", | delete: "删除", | ||||
| more: "更多", | more: "更多", | ||||
| draft: "草稿", | |||||
| generating: "生成中", | |||||
| generationFailed: "生成失败", | |||||
| generationSucceed: "生成成功", | |||||
| draftText: "草稿", | |||||
| generatingText: "视频正在生成中,请稍等哦", | |||||
| generationFailedText: "视频生成失败。原因:", | |||||
| }, | }, | ||||
| // 个人账户 | // 个人账户 | ||||
| @@ -1,5 +1,4 @@ | |||||
| import router from "@/router"; | import router from "@/router"; | ||||
| import { useUserStoreHook } from "@/store/modules/user"; | |||||
| import { usePermissionStoreHook } from "@/store/modules/permission"; | import { usePermissionStoreHook } from "@/store/modules/permission"; | ||||
| import NProgress from "nprogress"; | import NProgress from "nprogress"; | ||||
| @@ -11,51 +10,28 @@ const permissionStore = usePermissionStoreHook(); | |||||
| // 白名单路由 | // 白名单路由 | ||||
| const whiteList = ["/login", "/signSucceed"]; | const whiteList = ["/login", "/signSucceed"]; | ||||
| // router.beforeEach(async (to, from, next) => { | |||||
| // NProgress.start(); | |||||
| // // const hasToken = localStorage.getItem("accessToken"); | |||||
| // // if (hasToken) { | |||||
| // // if (to.path === "/login") { | |||||
| // // // 如果已登录,跳转首页 | |||||
| // // next({ path: "/" }); | |||||
| // // NProgress.done(); | |||||
| // // } else { | |||||
| // // const userStore = useUserStoreHook(); | |||||
| // // const hasRoles = userStore.roles && userStore.roles.length > 0; | |||||
| // // if (hasRoles) { | |||||
| // // // 未匹配到任何路由,跳转404 | |||||
| // // if (to.matched.length === 0) { | |||||
| // // from.name ? next({ name: from.name }) : next("/404"); | |||||
| // // } else { | |||||
| // // next(); | |||||
| // // } | |||||
| // // } else { | |||||
| // // try { | |||||
| // // const { roles } = await userStore.getInfo(); | |||||
| // // const accessRoutes = await permissionStore.generateRoutes(roles); | |||||
| // // accessRoutes.forEach((route) => { | |||||
| // // router.addRoute(route); | |||||
| // // }); | |||||
| // // next({ ...to, replace: true }); | |||||
| // // } catch (error) { | |||||
| // // // 移除 token 并跳转登录页 | |||||
| // // await userStore.resetToken(); | |||||
| // // next(`/login?redirect=${to.path}`); | |||||
| // // NProgress.done(); | |||||
| // // } | |||||
| // // } | |||||
| // // } | |||||
| // // } else { | |||||
| // // // 未登录可以访问白名单页面 | |||||
| // // if (whiteList.indexOf(to.path) !== -1) { | |||||
| // // next(); | |||||
| // // } else { | |||||
| // // next(`/login?redirect=${to.path}`); | |||||
| // // NProgress.done(); | |||||
| // // } | |||||
| // // } | |||||
| // }); | |||||
| router.beforeEach(async (to, from, next) => { | |||||
| NProgress.start(); | |||||
| const AccessToken = localStorage.getItem("AccessToken"); | |||||
| // 已登录 | |||||
| if (AccessToken) { | |||||
| if (to.path === "/login") { | |||||
| next({ path: "/createVideo" }); | |||||
| } else { | |||||
| next(); | |||||
| } | |||||
| // 未登录 | |||||
| } else { | |||||
| // 未登录可以访问白名单页面 | |||||
| if (whiteList.indexOf(to.path) !== -1) { | |||||
| next(); | |||||
| } else { | |||||
| // 不在白名单内,跳转登录页 | |||||
| next({ path: "/login" }); | |||||
| } | |||||
| } | |||||
| }); | |||||
| // router.afterEach(() => { | |||||
| // NProgress.done(); | |||||
| // }); | |||||
| router.afterEach(() => { | |||||
| NProgress.done(); | |||||
| }); | |||||
| @@ -45,7 +45,7 @@ const defaultSettings: DefaultSettings = { | |||||
| title: "Metavatar-PC", | title: "Metavatar-PC", | ||||
| showSettings: false, | showSettings: false, | ||||
| tagsView: false, | tagsView: false, | ||||
| fixedHeader: false, | |||||
| fixedHeader: true, | |||||
| sidebarLogo: true, | sidebarLogo: true, | ||||
| layout: "left", | layout: "left", | ||||
| /** | /** | ||||
| @@ -1,5 +1,5 @@ | |||||
| import axios from 'axios' | import axios from 'axios' | ||||
| import router from '@/router' | |||||
| import router from '@/router/index' | |||||
| import { ElMessage } from 'element-plus' | import { ElMessage } from 'element-plus' | ||||
| ElMessage | ElMessage | ||||
| @@ -35,25 +35,19 @@ request.interceptors.request.use( | |||||
| request.interceptors.response.use( | request.interceptors.response.use( | ||||
| function (response) { | function (response) { | ||||
| let code = response.data.code | let code = response.data.code | ||||
| // 当token过期或损坏时 | |||||
| // 当token无效(过期或损坏)时 | |||||
| if (code == 1052) { | if (code == 1052) { | ||||
| localStorage.removeItem("AccessToken"); | |||||
| router.push("/login"); | router.push("/login"); | ||||
| ElMessage.error("登录过期,请重新登录!"); | ElMessage.error("登录过期,请重新登录!"); | ||||
| return | return | ||||
| // 弹出错误 | // 弹出错误 | ||||
| } else if (code != 200) { | } else if (code != 200) { | ||||
| if (code == 1053) { | |||||
| router.push("/login"); | |||||
| // Toast.fail("请您先登录!"); | |||||
| return | |||||
| } else if (code == 500) { | |||||
| if (code == 500) { | |||||
| ElMessage.error("系统异常,请稍后再试"); | ElMessage.error("系统异常,请稍后再试"); | ||||
| // 其他错误 | // 其他错误 | ||||
| } else { | } else { | ||||
| return Promise.reject(response.data) | return Promise.reject(response.data) | ||||
| } | } | ||||
| } else { | } else { | ||||
| @@ -0,0 +1,168 @@ | |||||
| /** | |||||
| * @description:使用JSON进行深度拷贝 | |||||
| */ | |||||
| export function deepCopy(data) { | |||||
| const copyData = JSON.stringify(data) | |||||
| return JSON.parse(copyData) | |||||
| } | |||||
| /** | |||||
| * @description 将bytes转化 | |||||
| * @param {number} bytes | |||||
| * @return string | |||||
| */ | |||||
| export function bytesToSize(bytes) { | |||||
| if (bytes === 0) return '0 B'; | |||||
| var k = 1000, // or 1024 | |||||
| sizes = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], | |||||
| i = Math.floor(Math.log(bytes) / Math.log(k)); | |||||
| return (bytes / Math.pow(k, i)).toPrecision(3) + ' ' + sizes[i]; | |||||
| } | |||||
| /** | |||||
| * @description 秒转化时分秒 | |||||
| * @param {number} seconds | |||||
| * @return string | |||||
| */ | |||||
| export function formatSeconds(value) { | |||||
| var theTime = parseInt(value);// 秒 | |||||
| var theTime1 = 0;// 分 | |||||
| var theTime2 = 0;// 小时 | |||||
| if (theTime > 60) { | |||||
| theTime1 = parseInt(theTime / 60); | |||||
| theTime = parseInt(theTime % 60); | |||||
| if (theTime1 > 60) { | |||||
| theTime2 = parseInt(theTime1 / 60); | |||||
| theTime1 = parseInt(theTime1 % 60); | |||||
| } | |||||
| } | |||||
| var result = "" + parseInt(theTime) + " 秒"; | |||||
| if (theTime1 > 0) { | |||||
| result = "" + parseInt(theTime1) + " 分" + result; | |||||
| } | |||||
| if (theTime2 > 0) { | |||||
| result = "" + parseInt(theTime2) + " 小时" + result; | |||||
| } | |||||
| return result; | |||||
| } | |||||
| /** | |||||
| * @description:滚动到对应id的位置 | |||||
| * @param {type} id | |||||
| */ | |||||
| export function scrollToID(id) { | |||||
| document.querySelector("#" + id).scrollIntoView({ | |||||
| behavior: "smooth", | |||||
| block: "start", | |||||
| inline: "nearest", | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * @description 根据时间戳获取时间 | |||||
| * @param {*} timestamp 必传,number类型,时间戳数据(10位及以下,10位至13位) | |||||
| * @param {*} format 选传,string类型,提供以下时间格式:YYYY-MM-DD hh:mm:ss、YYYY/MM/DD hh:mm:ss、YYYY.MM.DD hh:mm:ss、YYYY MM DD hh:mm:ss、YYYY年MM月DD日 hh:mm:ss、YYYY-MM-DD、YYYY/MM/DD、YYYY.MM.DD、YYYY MM DD、YYYY年MM月DD日;若不传,则默认为:YYYY-MM-DD | |||||
| * @returns 根据要求的时间格式 | |||||
| * @version V 1.0, Created by YWQ, 2022.10.20 | |||||
| */ | |||||
| export function timestampToTime(timestamp, format) { | |||||
| //时间戳为10位需*1000,时间戳为13位不需乘1000 | |||||
| const length = timestamp && timestamp.length ? timestamp.length : '' | |||||
| if (!length) return "" | |||||
| let date | |||||
| if (length <= 10) { | |||||
| date = new Date(timestamp * 1000) | |||||
| } else { | |||||
| date = new Date(timestamp) | |||||
| } | |||||
| let Y = String(date.getFullYear()) | |||||
| let M = String(date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1) | |||||
| let D = String(date.getDate() + 1 < 10 ? '0' + (date.getDate()) : date.getDate()) | |||||
| let h = String(date.getHours() + 1 < 10 ? '0' + (date.getHours()) : date.getHours()) | |||||
| let m = String(date.getMinutes() + 1 < 10 ? '0' + (date.getMinutes()) : date.getMinutes()) | |||||
| let s = String(date.getSeconds() + 1 < 10 ? '0' + (date.getSeconds()) : date.getSeconds()) | |||||
| // return Y + M + D + h + m + s | |||||
| if (format == "YYYY-MM-DD hh:mm:ss") { | |||||
| return Y + "-" + M + "-" + D + " " + h + ":" + m + ":" + s | |||||
| } else if (format == "YYYY/MM/DD hh:mm:ss") { | |||||
| return Y + "/" + M + "/" + D + " " + h + ":" + m + ":" + s | |||||
| } else if (format == "YYYY.MM.DD hh:mm:ss") { | |||||
| return Y + "." + M + "." + D + " " + h + ":" + m + ":" + s | |||||
| } else if (format == "YYYY MM DD hh:mm:ss") { | |||||
| return Y + " " + M + " " + D + " " + h + ":" + m + ":" + s | |||||
| } else if (format == "YYYY年MM月DD日 hh:mm:ss") { | |||||
| return Y + "年" + M + "月" + D + "日" + " " + h + ":" + m + ":" + s | |||||
| } else if (format == "YYYY-MM-DD") { | |||||
| return Y + "-" + M + "-" + D | |||||
| } else if (format == "YYYY/MM/DD") { | |||||
| return Y + "/" + M + "/" + D | |||||
| } else if (format == "YYYY.MM.DD") { | |||||
| return Y + "." + M + "." + D | |||||
| } else if (format == "YYYY MM DD") { | |||||
| return Y + " " + M + " " + D | |||||
| } else if (format == "YYYY年MM月DD日") { | |||||
| return Y + "年" + M + "月" + D + "日" | |||||
| } else { | |||||
| return Y + "-" + M + "-" + D | |||||
| } | |||||
| } | |||||
| // /** | |||||
| // * @description:获取设备类型 | |||||
| // * @returns PC端为null,移动端为设备类型(Array) | |||||
| // */ | |||||
| // export function getDeviceType() { | |||||
| // return navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i) | |||||
| // } | |||||
| /** | |||||
| * @description:根据经纬度计算距离 | |||||
| * @param {*} locationInfo (lat1, lng1, lat2, lng2) | |||||
| * @return: distanceObj: { distance , distance_str } | |||||
| */ | |||||
| export function getDistances(lat1, lng1, lat2, lng2) { | |||||
| function rad(d) { | |||||
| return d * Math.PI / 180.0; | |||||
| } | |||||
| var radLat1 = rad(lat1); | |||||
| var radLat2 = rad(lat2); | |||||
| var a = radLat1 - radLat2; | |||||
| var b = rad(lng1) - rad(lng2); | |||||
| var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + | |||||
| Math.cos(radLat1) * Math.cos(radLat2) * Math.pow(Math.sin(b / 2), 2))); | |||||
| s = s * 6378.137; | |||||
| s = Math.round(s * 10000) / 10000; | |||||
| var distance = s; | |||||
| var distance_str = ""; | |||||
| if (parseInt(distance) >= 1) { | |||||
| distance_str = distance.toFixed(2) + "km"; | |||||
| } else { | |||||
| distance_str = (distance * 1000).toFixed(2) + "m"; | |||||
| } | |||||
| let objData = { | |||||
| distance: distance, | |||||
| distance_str: distance_str | |||||
| } | |||||
| return objData | |||||
| } | |||||
| /** | |||||
| * @description:文本打字机 | |||||
| * @param {*} data (text,target,duration) | |||||
| */ | |||||
| export function typeWriter(text, target, duration) { | |||||
| let i = 0; | |||||
| let timer = setInterval(() => { | |||||
| target += text[i]; | |||||
| if (i + 1 == text.length) { | |||||
| clearInterval(timer); | |||||
| } else { | |||||
| i++; | |||||
| } | |||||
| }, duration || 100); | |||||
| } | |||||
| @@ -1,6 +1,6 @@ | |||||
| <template> | <template> | ||||
| <div class="login-container"> | <div class="login-container"> | ||||
| <div class="Version">Version 1.0.4 test</div> | |||||
| <div class="Version">Version 1.0.5 test</div> | |||||
| <div class="videoBox"> | <div class="videoBox"> | ||||
| <video | <video | ||||
| src="https://video.metavatar.cc/sv/4aaaaa5e-18832dbb5e6/4aaaaa5e-18832dbb5e6.mp4" | src="https://video.metavatar.cc/sv/4aaaaa5e-18832dbb5e6/4aaaaa5e-18832dbb5e6.mp4" | ||||
| @@ -3,19 +3,41 @@ | |||||
| <!-- 搜索框 --> | <!-- 搜索框 --> | ||||
| <div class="top"> | <div class="top"> | ||||
| <div class="flex justify-between" style="width: 300px"> | <div class="flex justify-between" style="width: 300px"> | ||||
| <el-input v-model="title" :placeholder="$t('myCreating.typeTitle')" /> | |||||
| <el-icon class="icon-edit"><i-ep-edit /></el-icon> | |||||
| <el-input | |||||
| v-model="title" | |||||
| :placeholder="$t('myCreating.search')" | |||||
| @keyup.enter="searchVideoList" | |||||
| /> | |||||
| <el-icon class="icon-edit" @click="searchVideoList" | |||||
| ><i-ep-search | |||||
| /></el-icon> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <!-- 作品列表 --> | <!-- 作品列表 --> | ||||
| <div class="workList flex"> | <div class="workList flex"> | ||||
| <div class="workItem" v-for="item in 12" :key="item"> | |||||
| <div class="workItem" v-for="item in videoList" :key="item.id"> | |||||
| <div class="workImg"> | <div class="workImg"> | ||||
| <img class="inmiddle" src="" alt="" /> | |||||
| <img | |||||
| v-if="item.coverImg" | |||||
| class="coverImg inmiddle" | |||||
| :src="item.coverImg" | |||||
| alt="" | |||||
| /> | |||||
| <img | |||||
| v-else | |||||
| class="takePlace inmiddle" | |||||
| src="@/assets/img/left-top-logo.png" | |||||
| alt="" | |||||
| /> | |||||
| </div> | </div> | ||||
| <div :class="'statusName ' + item.statusName"> | |||||
| {{ $t("myCreating." + item.statusName) }} | |||||
| </div> | |||||
| <div class="workInfo flex"> | <div class="workInfo flex"> | ||||
| <span>{{ $t("myCreating.name") }}</span> | |||||
| <span>{{ $t("myCreating.date") }}</span> | |||||
| <span>{{ item.title }}</span> | |||||
| <span>{{ item.createDate }}</span> | |||||
| </div> | </div> | ||||
| <!-- 更多遮罩层 --> | <!-- 更多遮罩层 --> | ||||
| <div | <div | ||||
| @@ -26,13 +48,16 @@ | |||||
| <el-icon class="icon-videoPlay"><i-ep-videoPlay /></el-icon> | <el-icon class="icon-videoPlay"><i-ep-videoPlay /></el-icon> | ||||
| <div class="showBtn" @click.stop="mouseenter(item)">...</div> | <div class="showBtn" @click.stop="mouseenter(item)">...</div> | ||||
| <div class="btns" v-show="showPopup"> | <div class="btns" v-show="showPopup"> | ||||
| <div class="btns-item"> | |||||
| <div class="btns-item" @click.stop="handleDownload(item.id)"> | |||||
| <div class="btns-item-icon"> | <div class="btns-item-icon"> | ||||
| <el-icon class="icon-delete"><i-ep-download /></el-icon> | <el-icon class="icon-delete"><i-ep-download /></el-icon> | ||||
| </div> | </div> | ||||
| <div class="text">{{ $t("myCreating.download") }}</div> | <div class="text">{{ $t("myCreating.download") }}</div> | ||||
| </div> | </div> | ||||
| <div class="btns-item"> | |||||
| <div | |||||
| class="btns-item" | |||||
| @click.stop="handelDelete(item.id, item.title)" | |||||
| > | |||||
| <div class="btns-item-icon"> | <div class="btns-item-icon"> | ||||
| <el-icon class="icon-delete"><i-ep-delete /></el-icon> | <el-icon class="icon-delete"><i-ep-delete /></el-icon> | ||||
| </div> | </div> | ||||
| @@ -47,24 +72,38 @@ | |||||
| destroy-on-close | destroy-on-close | ||||
| class="elDialog" | class="elDialog" | ||||
| v-model="showDialog" | v-model="showDialog" | ||||
| :title="presentVideo" | |||||
| :title="presentItem.title" | |||||
| width="40%" | width="40%" | ||||
| center | center | ||||
| > | > | ||||
| <div class="videoBox"> | <div class="videoBox"> | ||||
| <video | <video | ||||
| v-if="presentItem.videoPlayUrl" | |||||
| controls="true" | controls="true" | ||||
| class="" | class="" | ||||
| src="https://wenlian.wenzhou.gov.cn:8001/upload/video/%E3%80%8A%E7%93%AF%E8%B6%8A%E4%B9%8B%E5%8D%8E%E3%80%8B%E7%89%87%E8%8A%B11.mp4" | |||||
| :src="presentItem.videoPlayUrl" | |||||
| ></video> | ></video> | ||||
| <div v-else class="insteadVideo"> | |||||
| {{ $t("myCreating." + presentItem.statusName + "Text") }} | |||||
| <span v-if="presentItem.videoStatus == 3">{{ | |||||
| presentItem.videoMsg | |||||
| }}</span> | |||||
| </div> | |||||
| </div> | </div> | ||||
| <template #footer> | |||||
| <template #footer v-if="presentItem.videoPlayUrl"> | |||||
| <span class="dialog-footer"> | <span class="dialog-footer"> | ||||
| <button class="elBtn" type="primary" @click="showDialog = false"> | |||||
| <button | |||||
| class="elBtn" | |||||
| type="primary" | |||||
| @click.stop="handleDownload(presentItem.id)" | |||||
| > | |||||
| <el-icon class="icon-delete"><i-ep-download /></el-icon | <el-icon class="icon-delete"><i-ep-download /></el-icon | ||||
| >{{ $t("myCreating.download") }} | >{{ $t("myCreating.download") }} | ||||
| </button> | </button> | ||||
| <button class="elBtn" @click="showDialog = false"> | |||||
| <button | |||||
| class="elBtn" | |||||
| @click.stop="handelDelete(presentItem.id, presentItem.title)" | |||||
| > | |||||
| <el-icon class="icon-delete"><i-ep-delete /></el-icon | <el-icon class="icon-delete"><i-ep-delete /></el-icon | ||||
| >{{ $t("myCreating.delete") }} | >{{ $t("myCreating.delete") }} | ||||
| </button> | </button> | ||||
| @@ -74,32 +113,121 @@ | |||||
| </div> | </div> | ||||
| </template> | </template> | ||||
| <script setup> | <script setup> | ||||
| import { userPhotoVideoList, delUserPhotoVideoByID } from "@/apis/myCreating"; | |||||
| import { timestampToTime } from "@/utils/tools"; | |||||
| import { useI18n } from "vue-i18n"; | |||||
| import { getStatus } from "./videoStatus"; | |||||
| // 当前语言状态与国际化组件 | |||||
| const { locale } = useI18n(); | |||||
| const lanChange = ref(locale); | |||||
| let title = ref(""); | let title = ref(""); | ||||
| let pageSize = ref(100); | |||||
| let pageNum = ref(1); | |||||
| // 弹窗显示隐藏 | // 弹窗显示隐藏 | ||||
| let showDialog = ref(false); | let showDialog = ref(false); | ||||
| // 当前作品 | // 当前作品 | ||||
| let presentVideo = ref(""); | |||||
| // 点击作品事件 | |||||
| let presentItem = ref(""); | |||||
| // 作品列表 | |||||
| const videoList = ref([]); | |||||
| // 点击作品 | |||||
| function clickVideoItem(item) { | function clickVideoItem(item) { | ||||
| showDialog.value = true; | showDialog.value = true; | ||||
| presentVideo.value = item; | |||||
| presentItem.value = item; | |||||
| } | } | ||||
| // 删除框是否显示 | // 删除框是否显示 | ||||
| let showPopup = ref(false); | let showPopup = ref(false); | ||||
| function mouseleave() { | function mouseleave() { | ||||
| showPopup.value = false; | showPopup.value = false; | ||||
| } | } | ||||
| function mouseenter(item) { | function mouseenter(item) { | ||||
| presentVideo.value = item; | |||||
| presentItem.value = item; | |||||
| showPopup.value = !showPopup.value; | showPopup.value = !showPopup.value; | ||||
| } | } | ||||
| function handleDownload() {} | |||||
| function searchVideoList() { | |||||
| getPhotoVideoList(pageSize.value, pageNum.value, title.value, true); | |||||
| } | |||||
| function handelDelete(id, title) { | |||||
| const msg = | |||||
| lanChange.value == "zh-cn" | |||||
| ? `确定要删除这个作品吗? 作品标题:${title}` | |||||
| : `Are you sure to delete this video ? Title:${title};`; | |||||
| const notice = lanChange.value == "zh-cn" ? "提示" : "Notice"; | |||||
| const confirm = lanChange.value == "zh-cn" ? "确定" : "Confirm"; | |||||
| const cancel = lanChange.value == "zh-cn" ? "取消" : "Cancel"; | |||||
| ElMessageBox.confirm(msg, notice, { | |||||
| confirmButtonText: confirm, | |||||
| cancelButtonText: cancel, | |||||
| }).then(() => { | |||||
| delPhotoVideo(id); | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * @description:获取我的视频作品 | |||||
| * @return: data | |||||
| */ | |||||
| function getPhotoVideoList(pageSize, pageNum, title, searchFlag) { | |||||
| userPhotoVideoList(pageSize, pageNum, title) | |||||
| .then((res) => { | |||||
| console.log(res, "res"); | |||||
| res.data.list.forEach((item) => { | |||||
| item.createDate = timestampToTime(item.createDate) || ""; | |||||
| item.updateDate = timestampToTime(item.updateDate) || ""; | |||||
| item.createVideoDate = timestampToTime(item.createVideoDate) || ""; | |||||
| item.statusName = getStatus(item.videoStatus); | |||||
| }); | |||||
| videoList.value = res.data.list; | |||||
| if (searchFlag) { | |||||
| const total = res.data.total; | |||||
| const msg1 = | |||||
| lanChange.value == "zh-cn" | |||||
| ? `查询成功!找到${total}条符合条件的视频` | |||||
| : `Found! Match ${total} videos`; | |||||
| const msg2 = | |||||
| lanChange.value == "zh-cn" | |||||
| ? `查询成功!没有符合条件的视频` | |||||
| : `Found! No match videos`; | |||||
| ElMessage.success(total > 0 ? msg1 : msg2); | |||||
| } | |||||
| }) | |||||
| .catch((err) => { | |||||
| console.log(err, "err"); | |||||
| }); | |||||
| } | |||||
| /** | |||||
| * @description:删除视频作品 | |||||
| * @param: videoID | |||||
| * @return: data | |||||
| */ | |||||
| function delPhotoVideo(videoID) { | |||||
| delUserPhotoVideoByID(videoID) | |||||
| .then((res) => { | |||||
| console.log(res, "res"); | |||||
| }) | |||||
| .catch((err) => { | |||||
| console.log(err, "err"); | |||||
| }); | |||||
| } | |||||
| onMounted(() => { | |||||
| getPhotoVideoList(pageSize.value, pageNum.value, title.value); | |||||
| }); | |||||
| </script> | </script> | ||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||
| .page { | .page { | ||||
| // height: calc(100vh - 84px); | // height: calc(100vh - 84px); | ||||
| height: 887px; | height: 887px; | ||||
| padding: 20px 0 0 20px; | |||||
| padding: 50px; | |||||
| background-color: #fff; | background-color: #fff; | ||||
| border-radius: 25px 0 0; | border-radius: 25px 0 0; | ||||
| } | } | ||||
| @@ -112,11 +240,16 @@ function mouseenter(item) { | |||||
| } | } | ||||
| .el-icon.icon-edit { | .el-icon.icon-edit { | ||||
| width: 32px; | |||||
| height: 32px; | |||||
| font-size: 32px; | |||||
| width: 30px; | |||||
| height: 30px; | |||||
| font-size: 30px; | |||||
| color: #8c939d; | color: #8c939d; | ||||
| text-align: center; | text-align: center; | ||||
| cursor: pointer; | |||||
| transition: all 0.3s; | |||||
| &:hover { | |||||
| color: #292929; | |||||
| } | |||||
| } | } | ||||
| .workList { | .workList { | ||||
| @@ -125,23 +258,31 @@ function mouseenter(item) { | |||||
| width: 100%; | width: 100%; | ||||
| height: 200px; | height: 200px; | ||||
| margin-top: 20px; | margin-top: 20px; | ||||
| cursor: pointer; | |||||
| .workItem { | .workItem { | ||||
| position: relative; | position: relative; | ||||
| width: 300px; | width: 300px; | ||||
| height: 200px; | height: 200px; | ||||
| margin: 0 10px 10px 0; | margin: 0 10px 10px 0; | ||||
| border: 1px solid #000; | |||||
| border: 2px solid #c2c2c2; | |||||
| border-radius: 5px; | border-radius: 5px; | ||||
| cursor: pointer; | |||||
| overflow: hidden; | |||||
| .workImg { | .workImg { | ||||
| position: relative; | |||||
| width: 100%; | width: 100%; | ||||
| height: 170px; | height: 170px; | ||||
| background-color: red; | |||||
| img { | |||||
| max-width: 100%; | |||||
| cursor: pointer; | |||||
| padding: 10px; | |||||
| .coverImg { | |||||
| max-width: 90%; | |||||
| max-height: 170px; | max-height: 170px; | ||||
| cursor: pointer; | |||||
| } | |||||
| .takePlace { | |||||
| position: absolute; | |||||
| top: 40%; | |||||
| width: 80%; | |||||
| } | } | ||||
| } | } | ||||
| @@ -153,7 +294,7 @@ function mouseenter(item) { | |||||
| width: 100%; | width: 100%; | ||||
| height: 170px; | height: 170px; | ||||
| background-color: rgb(0 0 0 / 30%); | background-color: rgb(0 0 0 / 30%); | ||||
| cursor: pointer; | |||||
| .icon-videoPlay { | .icon-videoPlay { | ||||
| position: absolute; | position: absolute; | ||||
| top: 50%; | top: 50%; | ||||
| @@ -164,24 +305,25 @@ function mouseenter(item) { | |||||
| color: #fff; | color: #fff; | ||||
| text-align: center; | text-align: center; | ||||
| transform: translate(-50%, -50%); | transform: translate(-50%, -50%); | ||||
| cursor: pointer; | |||||
| } | } | ||||
| .showBtn { | .showBtn { | ||||
| position: absolute; | position: absolute; | ||||
| top: 10px; | top: 10px; | ||||
| right: 10px; | right: 10px; | ||||
| width: 30px; | |||||
| height: 30px; | |||||
| width: 20px; | |||||
| height: 20px; | |||||
| font-size: 20px; | font-size: 20px; | ||||
| line-height: 15px; | |||||
| line-height: 10px; | |||||
| color: #fff; | color: #fff; | ||||
| text-align: center; | text-align: center; | ||||
| transition: all 0.3s; | |||||
| cursor: pointer; | cursor: pointer; | ||||
| // &:hover { | |||||
| // width: 80px; | |||||
| // height: 80px; | |||||
| // background-color: aqua; | |||||
| // } | |||||
| border-radius: 2px; | |||||
| &:hover { | |||||
| background-color: #00000056; | |||||
| } | |||||
| } | } | ||||
| .btns { | .btns { | ||||
| @@ -192,6 +334,7 @@ function mouseenter(item) { | |||||
| // height: 60px; | // height: 60px; | ||||
| overflow: hidden; | overflow: hidden; | ||||
| border-radius: 10px; | border-radius: 10px; | ||||
| cursor: pointer; | |||||
| &-item { | &-item { | ||||
| // width: 70px; | // width: 70px; | ||||
| @@ -199,12 +342,14 @@ function mouseenter(item) { | |||||
| text-align: center; | text-align: center; | ||||
| background-color: #fff; | background-color: #fff; | ||||
| padding: 0 10px; | padding: 0 10px; | ||||
| transition: all 0.3s; | |||||
| cursor: pointer; | |||||
| &-icon { | &-icon { | ||||
| position: relative; | position: relative; | ||||
| display: inline-block; | display: inline-block; | ||||
| width: 20px; | width: 20px; | ||||
| height: 20px; | height: 20px; | ||||
| cursor: pointer; | |||||
| .icon-delete { | .icon-delete { | ||||
| position: absolute; | position: absolute; | ||||
| top: 4px; | top: 4px; | ||||
| @@ -214,6 +359,7 @@ function mouseenter(item) { | |||||
| font-size: 16px; | font-size: 16px; | ||||
| color: #000; | color: #000; | ||||
| text-align: center; | text-align: center; | ||||
| cursor: pointer; | |||||
| } | } | ||||
| } | } | ||||
| @@ -223,6 +369,11 @@ function mouseenter(item) { | |||||
| padding-left: 5px; | padding-left: 5px; | ||||
| margin-top: -5px; | margin-top: -5px; | ||||
| line-height: 20px; | line-height: 20px; | ||||
| cursor: pointer; | |||||
| } | |||||
| &:hover { | |||||
| color: #ffffff; | |||||
| background-color: #0000001a; | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| @@ -233,7 +384,34 @@ function mouseenter(item) { | |||||
| height: 30px; | height: 30px; | ||||
| padding: 0 10px; | padding: 0 10px; | ||||
| line-height: 30px; | line-height: 30px; | ||||
| border-top: 1px solid #000; | |||||
| 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%); | |||||
| } | |||||
| &.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%); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| @@ -247,21 +425,22 @@ function mouseenter(item) { | |||||
| display: flex; | display: flex; | ||||
| justify-content: space-between; | justify-content: space-between; | ||||
| width: 100%; | width: 100%; | ||||
| height: 400px; | |||||
| padding: 0 20px; | |||||
| padding: 10px 40px 30px 40px; | |||||
| video { | video { | ||||
| width: 90%; | |||||
| height: 400px; | |||||
| margin-top: -10px; | |||||
| margin-left: 5%; | |||||
| width: 100%; | |||||
| margin: auto; | |||||
| } | |||||
| .insteadVideo { | |||||
| font-size: 20px; | |||||
| font-weight: 600; | |||||
| margin: 20px auto; | |||||
| } | } | ||||
| } | } | ||||
| .dialog-footer { | .dialog-footer { | ||||
| display: flex; | display: flex; | ||||
| justify-content: space-between; | justify-content: space-between; | ||||
| .elBtn { | .elBtn { | ||||
| color: #fff; | color: #fff; | ||||
| border-radius: 10px; | border-radius: 10px; | ||||
| @@ -288,7 +467,19 @@ function mouseenter(item) { | |||||
| // :deep(.el-dialog__header) { | // :deep(.el-dialog__header) { | ||||
| // } | // } | ||||
| :deep(.el-dialog__title) { | :deep(.el-dialog__title) { | ||||
| color: red; | |||||
| 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; | |||||
| } | } | ||||
| :deep(.el-dialog__body) { | :deep(.el-dialog__body) { | ||||
| @@ -0,0 +1,16 @@ | |||||
| /** | |||||
| * @description:根据状态返回状态名 | |||||
| * @param {number} status | |||||
| * @return: statusName | |||||
| */ | |||||
| export const getStatus = status => { | |||||
| if (status == 0) { | |||||
| return "draft" | |||||
| } else if (status == 1 || status == 2 || status == 4 || status == 6) { | |||||
| return "generating" | |||||
| } else if (status == 3) { | |||||
| return "generationFailed" | |||||
| } else if (status == 5) { | |||||
| return "generationSucceed" | |||||
| } | |||||
| } | |||||
| @@ -10,11 +10,12 @@ | |||||
| style="color: #ffffff; transform: scale(2)" | style="color: #ffffff; transform: scale(2)" | ||||
| /> | /> | ||||
| </div> | </div> | ||||
| <div v-if="isSuccess == 1"> | <div v-if="isSuccess == 1"> | ||||
| <div class="welcome">{{ $t("signSucceed.welcome") }}</div> | <div class="welcome">{{ $t("signSucceed.welcome") }}</div> | ||||
| <div class="success">{{ $t("signSucceed.createSuccess") }}</div> | <div class="success">{{ $t("signSucceed.createSuccess") }}</div> | ||||
| <div class="login pointer" @click="goLogin"> | <div class="login pointer" @click="goLogin"> | ||||
| {{ $t("signSucceed.goLogin") }} | |||||
| {{ $t("signSucceed.goLogin") + " " + count }} | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| @@ -48,6 +49,7 @@ const route = useRoute(); | |||||
| const router = useRouter(); | const router = useRouter(); | ||||
| const { params, query } = route; | const { params, query } = route; | ||||
| const isSuccess = ref(0); | const isSuccess = ref(0); | ||||
| const count = ref(5); | |||||
| function doActivateByTicket() { | function doActivateByTicket() { | ||||
| const ticket = query.ticket; | const ticket = query.ticket; | ||||
| @@ -56,6 +58,14 @@ function doActivateByTicket() { | |||||
| console.log(res, "res"); | console.log(res, "res"); | ||||
| localStorage.setItem("AccessToken", res.data.token); | localStorage.setItem("AccessToken", res.data.token); | ||||
| isSuccess.value = 1; | isSuccess.value = 1; | ||||
| const timer = setInterval(() => { | |||||
| if (count.value != 0) { | |||||
| count.value -= 1; | |||||
| } else { | |||||
| clearInterval(timer); | |||||
| router.push("/createVideo"); | |||||
| } | |||||
| }, 1000); | |||||
| }) | }) | ||||
| .catch((err) => { | .catch((err) => { | ||||
| console.log(err, "err"); | console.log(err, "err"); | ||||
| @@ -118,7 +128,7 @@ onMounted(() => { | |||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||
| .content { | .content { | ||||
| position: relative; | position: relative; | ||||
| height: 1000px; | |||||
| height: 100%; | |||||
| padding: 100px 0 0 40px; | padding: 100px 0 0 40px; | ||||
| background-color: #000000; | background-color: #000000; | ||||
| color: #ffffff; | color: #ffffff; | ||||
| @@ -1,8 +1,15 @@ | |||||
| Arguments: | Arguments: | ||||
| <<<<<<< HEAD | |||||
| B:\nodejs\node.exe B:\nodejs\node_modules\yarn\bin\yarn.js add mic-recorder-to-mp3 | B:\nodejs\node.exe B:\nodejs\node_modules\yarn\bin\yarn.js add mic-recorder-to-mp3 | ||||
| PATH: | PATH: | ||||
| C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;B:\nvm;B:\nodejs;B:\Git\Git\cmd;C:\Users\12574\AppData\Local\Microsoft\WindowsApps;B:\Microsoft VS Code\bin;B:\nvm;B:\nodejs | C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Program Files\NVIDIA Corporation\NVIDIA NvDLISR;B:\nvm;B:\nodejs;B:\Git\Git\cmd;C:\Users\12574\AppData\Local\Microsoft\WindowsApps;B:\Microsoft VS Code\bin;B:\nvm;B:\nodejs | ||||
| ======= | |||||
| C:\Program Files\nodejs\node.exe C:\Users\Holy-Knight-IX\AppData\Roaming\npm\node_modules\yarn\bin\yarn.js add -D --prefer-offline @iconify-json/ph | |||||
| PATH: | |||||
| C:\Users\HOLY-K~1\AppData\Local\Temp\yarn--1685070845077-0.20825812772556618;C:\Users\Holy-Knight-IX\Desktop\Working Space\7.SuiMang\web_pc\node_modules\.bin;C:\Users\Holy-Knight-IX\AppData\Local\Yarn\Data\link\node_modules\.bin;C:\Users\Holy-Knight-IX\AppData\Local\Yarn\bin;C:\Program Files\libexec\lib\node_modules\npm\bin\node-gyp-bin;C:\Program Files\lib\node_modules\npm\bin\node-gyp-bin;C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\nodejs\nodejs-10.24.1;C:\Program Files\Git\cmd;C:\Program Files\dotnet\;E:\微信web开发者工具\dll;C:\Program Files\nodejs\nodejs-10.24.1\;C:\Program Files (x86)\Tencent\微信web开发者工具\dll;C:\Users\Holy-Knight-IX\AppData\Roaming\nvm;C:\Program Files\nodejs;C:\Users\Holy-Knight-IX\AppData\Local\Microsoft\WindowsApps;C:\Users\Holy-Knight-IX\AppData\Local\Programs\Microsoft VS Code\bin;C:\Users\Holy-Knight-IX\AppData\Roaming\npm;C:\Users\Holy-Knight-IX\AppData\Roaming\nvm;C:\Program Files\nodejs | |||||
| >>>>>>> 1130ab9f8d017215cbc06fc6125aa3933cb4eb82 | |||||
| Yarn version: | Yarn version: | ||||
| 1.22.19 | 1.22.19 | ||||
| @@ -14,7 +21,11 @@ Platform: | |||||
| win32 x64 | win32 x64 | ||||
| Trace: | Trace: | ||||
| <<<<<<< HEAD | |||||
| Error: EPERM: operation not permitted, unlink 'B:\0work\0fm\Web-pc\node_modules\@esbuild\win32-x64\esbuild.exe' | Error: EPERM: operation not permitted, unlink 'B:\0work\0fm\Web-pc\node_modules\@esbuild\win32-x64\esbuild.exe' | ||||
| ======= | |||||
| Error: EPERM: operation not permitted, unlink 'C:\Users\Holy-Knight-IX\Desktop\Working Space\7.SuiMang\web_pc\node_modules\@esbuild\win32-x64\esbuild.exe' | |||||
| >>>>>>> 1130ab9f8d017215cbc06fc6125aa3933cb4eb82 | |||||
| npm manifest: | npm manifest: | ||||
| { | { | ||||