@@ -6,5 +6,7 @@ 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://photo.metavatar.cc/C' | ||||
VITE_APP_BASE_API = 'https://test.metavatar.cc/C' | |||||
# VITE_APP_BASE_API = 'https://test.metavatar.cc/C' | |||||
# VITE_APP_BASE_API = 'https://phototest.metavatar.cc/C' | |||||
VITE_APP_BASE_API = 'https://m.metavatar.cc/C' | |||||
@@ -6,4 +6,4 @@ NODE_ENV='test' | |||||
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://test.metavatar.cc/C' | |||||
VITE_APP_BASE_API = 'https://mtest.metavatar.cc/C' |
@@ -5,7 +5,7 @@ | |||||
<meta charset="UTF-8" /> | <meta charset="UTF-8" /> | ||||
<link rel="icon" href="/favicon.ico" /> | <link rel="icon" href="/favicon.ico" /> | ||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||||
<title>Metavatar-慧影</title> | |||||
<title>Metavatar</title> | |||||
</head> | </head> | ||||
<body> | <body> | ||||
@@ -34,6 +34,7 @@ | |||||
"vue": "^3.2.45", | "vue": "^3.2.45", | ||||
"vue-cropper": "^1.0.9", | "vue-cropper": "^1.0.9", | ||||
"vue-i18n": "9", | "vue-i18n": "9", | ||||
"vue-qr": "^4.0.9", | |||||
"vue-router": "^4.0.13" | "vue-router": "^4.0.13" | ||||
}, | }, | ||||
"devDependencies": { | "devDependencies": { | ||||
@@ -0,0 +1,39 @@ | |||||
import request from "@/utils/request.js"; | |||||
/** | |||||
* @description 服务端api签名指南 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function getAvailableApiGuideApi() { | |||||
return request({ | |||||
url: `/api/apiGuide/getAvailableApiGuide`, | |||||
method: 'get' | |||||
}) | |||||
} | |||||
/** | |||||
* @description 开放接口列表 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function apiMenuApi() { | |||||
return request({ | |||||
url: `/api/apiMenu/list`, | |||||
method: 'get' | |||||
}) | |||||
} | |||||
/** | |||||
* @description 获取接口详情 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function getContentApi(id) { | |||||
return request({ | |||||
url: `/api/apiMenu/get?id=${id}`, | |||||
method: 'get' | |||||
}) | |||||
} |
@@ -7,8 +7,9 @@ import request from "@/utils/request.js"; | |||||
* @returns data | * @returns data | ||||
*/ | */ | ||||
export function modeListApi(sex, pageNum, pageSize, videoType) { | export function modeListApi(sex, pageNum, pageSize, videoType) { | ||||
let api = localStorage.getItem("AccessToken") ? '/api/personPatch/loginList' : '/api/personPatch/list' | |||||
return request({ | return request({ | ||||
url: `/api/personPatch/list?sex=${sex}&pageNum=${pageNum}&pageSize=${pageSize}&videoType=${videoType}`, | |||||
url: `${api}?sex=${sex}&pageNum=${pageNum}&pageSize=${pageSize}&videoType=${videoType}`, | |||||
method: 'get' | method: 'get' | ||||
}) | }) | ||||
} | } | ||||
@@ -19,8 +20,9 @@ export function modeListApi(sex, pageNum, pageSize, videoType) { | |||||
* @returns data | * @returns data | ||||
*/ | */ | ||||
export function voiceTotalApi() { | export function voiceTotalApi() { | ||||
let api = localStorage.getItem("AccessToken") ? '/api/voiceMould/loginVoiceTotal' : '/api/voiceMould/voiceTotal' | |||||
return request({ | return request({ | ||||
url: `api/voiceMould/voiceTotal`, | |||||
url: api, | |||||
method: 'GET', | method: 'GET', | ||||
}) | }) | ||||
} | } | ||||
@@ -88,12 +90,32 @@ export function personSCIListApi(pageNum, pageSize) { | |||||
* @returns data | * @returns data | ||||
*/ | */ | ||||
export function previewAudioApi(gen_txt, voice_id, voice_style) { | export function previewAudioApi(gen_txt, voice_id, voice_style) { | ||||
let api = localStorage.getItem("AccessToken") ? '/api/voiceMould/loginPreview' : '/api/voiceMould/hypreview' | |||||
return request({ | return request({ | ||||
url: `api/voiceMould/preview`, | |||||
url: api, | |||||
method: 'POST', | method: 'POST', | ||||
data: { gen_txt, voice_id, voice_style } | data: { gen_txt, voice_id, voice_style } | ||||
}) | }) | ||||
} | } | ||||
/** | |||||
* @description 图片检测接口 | |||||
* @params id | |||||
* @returns data | |||||
*/ | |||||
export function checkPhotoApi(data) { | |||||
const timestamp = Date.now(); | |||||
const formData = new FormData(); | |||||
formData.append('file', data, timestamp + ".png"); | |||||
return request({ | |||||
url: '/api/baidu/checkPhoto', | |||||
method: 'post', | |||||
data: formData, | |||||
headers: { | |||||
'Content-Type': 'application/form-data', | |||||
"Access-Control-Allow-Credentials": true, | |||||
} | |||||
}); | |||||
} | |||||
/** | /** | ||||
* @description 上传阿里云--裁剪后的个人背景图 | * @description 上传阿里云--裁剪后的个人背景图 | ||||
@@ -173,7 +195,10 @@ export function createVideoApi(id) { | |||||
return request({ | return request({ | ||||
url: `/api/userVideo/createVideo`, | url: `/api/userVideo/createVideo`, | ||||
method: 'post', | method: 'post', | ||||
data: { id } | |||||
data: { | |||||
id, | |||||
projectType: '2' | |||||
} | |||||
}) | }) | ||||
} | } | ||||
@@ -188,3 +213,39 @@ export function getModelDetailByIdApi(id) { | |||||
method: 'get' | method: 'get' | ||||
}) | }) | ||||
} | } | ||||
/** | |||||
* @description:文字判断语种 | |||||
* @param {number} id | |||||
* @return data | |||||
*/ | |||||
export function getLanguageApi(data) { | |||||
return request({ | |||||
url: `/api/VoiceLanguage/getLanguage`, | |||||
method: 'POST', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* @description:视频校验 | |||||
* @param {number} id | |||||
* @return data | |||||
*/ | |||||
export function checkVideoApi(id) { | |||||
return request({ | |||||
url: `/api/userVideo/checkVideo?id=${id}`, | |||||
method: 'get' | |||||
}) | |||||
} | |||||
/** | |||||
* @description:扣币 | |||||
* @return data | |||||
*/ | |||||
export function reduceUserPoinsApi() { | |||||
return request({ | |||||
url: `/api/user/reduceUserPoins`, | |||||
method: 'get' | |||||
}) | |||||
} |
@@ -0,0 +1,81 @@ | |||||
/* | |||||
* @Autor: Chutingting | |||||
* @Date: 2023-11-13 14:29:58 | |||||
* @LastEditors: Chutingting | |||||
* @LastEditTime: 2023-11-14 10:48:23 | |||||
* @Description: | |||||
*/ | |||||
import request from "@/utils/request.js"; | |||||
/** | |||||
* @description 充值订单 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function rechargeListApi(data) { | |||||
return request({ | |||||
url: `/api/productOrder/myPaiedOrders?projectType=${data.projectType}&pageNum=${data.pageNum}&pageSize=${data.pageSize}`, | |||||
method: 'get' | |||||
}) | |||||
} | |||||
/** | |||||
* @description 获取详情 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function getDetailApi(id) { | |||||
return request({ | |||||
url: `/api/userVideo/findById?id=${id}`, | |||||
method: 'get' | |||||
}) | |||||
} | |||||
/** | |||||
* @description 扣币详情 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function coindedApi(data) { | |||||
return request({ | |||||
url: `/api/userVideo/list?videoStatus=5&pageNum=${data.pageNum}&pageSize=${data.pageSize}`, | |||||
method: 'get' | |||||
}) | |||||
} | |||||
/** | |||||
* @description 当前币值 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function getUserPoinsApi() { | |||||
return request({ | |||||
url: `/api/user/getUserPoins`, | |||||
method: 'get' | |||||
}) | |||||
} | |||||
/** | |||||
* @description 充值订单详情 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function findByNumberApi(orderNumber) { | |||||
return request({ | |||||
url: `/api/productOrder/findByNumber?orderNumber=${orderNumber}`, | |||||
method: 'get' | |||||
}) | |||||
} | |||||
/** | |||||
* @description 扣币订单详情 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function findByIdApi(id) { | |||||
return request({ | |||||
url: `/api/userVideo/findById?id=${id}`, | |||||
method: 'get' | |||||
}) | |||||
} |
@@ -1,3 +1,4 @@ | |||||
import request from "@/utils/request.js"; | import request from "@/utils/request.js"; | ||||
@@ -52,7 +53,7 @@ export function videoHyApi(id) { | |||||
*/ | */ | ||||
export function checkVideoStatusApi(list) { | export function checkVideoStatusApi(list) { | ||||
return request({ | return request({ | ||||
url: `/api/userPhotoVideo/checkVideoStatus?list=${list}`, | |||||
url: `/api/userVideo/checkVideoStatus?list=${list}`, | |||||
method: 'get' | method: 'get' | ||||
}) | }) | ||||
} | } |
@@ -8,9 +8,48 @@ import request from "@/utils/request.js"; | |||||
*/ | */ | ||||
export function packageInfoApi() { | export function packageInfoApi() { | ||||
return request({ | return request({ | ||||
url: `/api/user/getPackageInfo`, | |||||
url: `/api/product/list_v1?type=2&projectType=2`, // /api/user/getPackageInfo | |||||
method: 'get' | method: 'get' | ||||
}) | }) | ||||
} | } | ||||
/** | |||||
* @description 订单详情 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function orderDetailApi(id) { | |||||
return request({ | |||||
url: `/api/productOrder/findByNumber?orderNumber=${id}`, | |||||
method: 'get' | |||||
}) | |||||
} | |||||
/** | |||||
* @description 创建支付 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function createPayApi(data) { | |||||
return request({ | |||||
url: `/api/productOrder/createPay`, | |||||
method: 'post', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* @description 创建支付 | |||||
* @params | |||||
* @returns | |||||
*/ | |||||
export function findStatusApi(data) { | |||||
return request({ | |||||
url: `/api/productOrder/findStatus?orderNumber=${data.orderNumber}&payVendor=${data.payVendor}`, | |||||
method: 'get' | |||||
}) | |||||
} | |||||
@@ -0,0 +1,39 @@ | |||||
import request from "@/utils/request.js"; | |||||
/** | |||||
* @description:购买金币下单 | |||||
* @param productId | |||||
* @return: data | |||||
*/ | |||||
export function createOrderApi(data) { | |||||
return request({ | |||||
url: `api/productOrder/createOrder`, | |||||
method: 'post', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* @description:获取订单数据 | |||||
* @param data | |||||
* @return: data | |||||
*/ | |||||
export function createPayApi(data) { | |||||
return request({ | |||||
url: `api/productOrder/createPay`, | |||||
method: 'post', | |||||
data | |||||
}) | |||||
} | |||||
/** | |||||
* @description:获取订单支付状态 | |||||
* @param orderNumber | |||||
* @return: data payStatus 查询支付状态 0:待支付,2:支付中,3:已支付 | |||||
*/ | |||||
export function getOrderStatusApi(orderNumber, payVendor) { | |||||
return request({ | |||||
url: `api/productOrder/findStatus?orderNumber=${orderNumber}&payVendor=${payVendor}`, | |||||
method: 'get' | |||||
}) | |||||
} |
@@ -51,7 +51,7 @@ | |||||
v-for="(item, index) in materialList.scList" | v-for="(item, index) in materialList.scList" | ||||
:key="item.id" | :key="item.id" | ||||
class="scListItem" | class="scListItem" | ||||
:class="showBorderActive == item.id ? 'border' : ''" | |||||
:class="scBorderActive == index ? 'border' : ''" | |||||
@mousedown.stop="handleDragSc(item, index, $event)" | @mousedown.stop="handleDragSc(item, index, $event)" | ||||
:style="{ | :style="{ | ||||
top: item.y / props.proportion + 'px', | top: item.y / props.proportion + 'px', | ||||
@@ -64,7 +64,7 @@ | |||||
<img id="scListItemImg" draggable="false" :src="item.material" alt="" /> | <img id="scListItemImg" draggable="false" :src="item.material" alt="" /> | ||||
<div ref="box1" class="stretchBox box1"></div> | <div ref="box1" class="stretchBox box1"></div> | ||||
<div | <div | ||||
v-show="showBorderActive == item.id" | |||||
v-show="scBorderActive == index" | |||||
class="stretchBox box2" | class="stretchBox box2" | ||||
@click="delScListItem(index)" | @click="delScListItem(index)" | ||||
> | > | ||||
@@ -77,7 +77,7 @@ | |||||
</div> | </div> | ||||
<div class="stretchBox box3"></div> | <div class="stretchBox box3"></div> | ||||
<div | <div | ||||
v-show="showBorderActive == item.id" | |||||
v-show="scBorderActive == index" | |||||
ref="box4" | ref="box4" | ||||
@mousedown.stop="changeScaleSc(index, $event)" | @mousedown.stop="changeScaleSc(index, $event)" | ||||
class="stretchBox box4" | class="stretchBox box4" | ||||
@@ -161,6 +161,7 @@ const virtualStyle = computed(() => { | |||||
}); | }); | ||||
// 拖动盒子 | // 拖动盒子 | ||||
const showBorderActive = ref(-1); //判断显示边框 | const showBorderActive = ref(-1); //判断显示边框 | ||||
const scBorderActive = ref('') | |||||
watch( | watch( | ||||
() => props.materialList.virtual.id, | () => props.materialList.virtual.id, | ||||
(newValue, oldValue) => { | (newValue, oldValue) => { | ||||
@@ -223,14 +224,14 @@ function changeScale(event) { | |||||
let deltaY = touchStart.pageY - y; | let deltaY = touchStart.pageY - y; | ||||
let boxDistance2 = Math.sqrt(deltaX ** 2 + deltaY ** 2); | let boxDistance2 = Math.sqrt(deltaX ** 2 + deltaY ** 2); | ||||
if (deltaX < 0) { | if (deltaX < 0) { | ||||
if (props.materialList.virtual.w < 0.4) { | |||||
props.materialList.virtual.w = 0.4; | |||||
if (props.materialList.virtual.w < 0.2) { | |||||
props.materialList.virtual.w = 0.2; | |||||
return; | return; | ||||
} | } | ||||
props.materialList.virtual.w = (baseLineScale + boxDistance2) / baseLine; | props.materialList.virtual.w = (baseLineScale + boxDistance2) / baseLine; | ||||
} else { | } else { | ||||
if (props.materialList.virtual.w > 1.3) { | |||||
props.materialList.virtual.w = 1.3; | |||||
if (props.materialList.virtual.w > 2.0) { | |||||
props.materialList.virtual.w = 2.0; | |||||
return; | return; | ||||
} | } | ||||
props.materialList.virtual.w = (baseLineScale - boxDistance2) / baseLine; | props.materialList.virtual.w = (baseLineScale - boxDistance2) / baseLine; | ||||
@@ -253,8 +254,12 @@ function changeScale(event) { | |||||
//#region 素材图逻辑 | //#region 素材图逻辑 | ||||
const handleDragSc = (item, index, event) => { | const handleDragSc = (item, index, event) => { | ||||
realImgUrl.value = item.material; | realImgUrl.value = item.material; | ||||
scBorderActive.value= index | |||||
showBorderActive.value = item.id; | showBorderActive.value = item.id; | ||||
props.materialList.scList.forEach(res => { | |||||
res.activeIndex ='' | |||||
}) | |||||
item.activeIndex = item.id | |||||
event.preventDefault(); | event.preventDefault(); | ||||
const imageElement = fatherBox.value; | const imageElement = fatherBox.value; | ||||
const startX = event.clientX; //保存初始值,避免闪烁 | const startX = event.clientX; //保存初始值,避免闪烁 | ||||
@@ -293,15 +298,15 @@ function changeScaleSc(index, event) { | |||||
let deltaY = touchStart.pageY - y; | let deltaY = touchStart.pageY - y; | ||||
let boxDistance2 = Math.sqrt(deltaX ** 2 + deltaY ** 2); | let boxDistance2 = Math.sqrt(deltaX ** 2 + deltaY ** 2); | ||||
if (deltaX < 0) { | if (deltaX < 0) { | ||||
if (props.materialList.scList[index].w < 0.4) { | |||||
props.materialList.scList[index].w = 0.4; | |||||
if (props.materialList.scList[index].w < 0.2) { | |||||
props.materialList.scList[index].w = 0.2; | |||||
return; | return; | ||||
} | } | ||||
props.materialList.scList[index].w = | props.materialList.scList[index].w = | ||||
(baseLineScale + boxDistance2) / baseLine; | (baseLineScale + boxDistance2) / baseLine; | ||||
} else { | } else { | ||||
if (props.materialList.scList[index].w > 1.3) { | |||||
props.materialList.scList[index].w = 1.3; | |||||
if (props.materialList.scList[index].w > 2.0) { | |||||
props.materialList.scList[index].w = 2.0; | |||||
return; | return; | ||||
} | } | ||||
props.materialList.scList[index].w = | props.materialList.scList[index].w = | ||||
@@ -63,7 +63,7 @@ | |||||
// import { VueCropper } from "vue-cropper"; | // import { VueCropper } from "vue-cropper"; | ||||
import { ElMessage } from "element-plus/es"; | import { ElMessage } from "element-plus/es"; | ||||
import { ref, reactive, watch } from "vue"; | import { ref, reactive, watch } from "vue"; | ||||
import { awsImgUpload, saveImgApi } from "../apis/createVideo"; | |||||
import { awsImgUpload, saveImgApi, checkPhotoApi } from "../apis/createVideo"; | |||||
import { useI18n } from "vue-i18n"; | import { useI18n } from "vue-i18n"; | ||||
const { locale } = useI18n(); | const { locale } = useI18n(); | ||||
@@ -92,30 +92,58 @@ function myUpload(params) {} | |||||
const cropper = ref(null); | const cropper = ref(null); | ||||
const option = reactive({ | const option = reactive({ | ||||
img: "", | img: "", | ||||
canMove: true, | |||||
outputSize: 0.5, //图片质量 | outputSize: 0.5, //图片质量 | ||||
info: false, // 裁剪框的大小信息 | |||||
// outputType: 'jpeg', // 裁剪生成图片的格式 | |||||
outputType: "png", // 裁剪生成图片的格式 | |||||
outputType: "png", | |||||
canScale: true, // 图片是否允许滚轮缩放 | canScale: true, // 图片是否允许滚轮缩放 | ||||
autoCrop: true, // 是否默认生成截图框 | |||||
fixedBox: false, | |||||
original: false, | |||||
canMoveBox: true, | |||||
autoCrop: true, | |||||
// 只有自动截图开启 宽度高度才生效 | |||||
autoCropWidth: window.innerWidth - 100 + "px", // 默认生成截图框宽度 | autoCropWidth: window.innerWidth - 100 + "px", // 默认生成截图框宽度 | ||||
autoCropHeight: window.innerWidth - 100 + "px", // 默认生成截图框高度 | autoCropHeight: window.innerWidth - 100 + "px", // 默认生成截图框高度 | ||||
high: true, // 是否按照设备的dpr 输出等比例图片 | |||||
fixedBox: false, // 固定截图框大小 不允许改变 | |||||
fixed: false, // 是否开启截图框宽高固定比例 | |||||
// fixedNumber: [1, 1], // 截图框的宽高比例 | |||||
full: true, // 是否输出原图比例的截图 | |||||
canMoveBox: true, // 截图框能否拖动 | |||||
original: false, // 上传图片按照原始比例渲染 | |||||
centerBox: true, // 截图框是否被限制在图片里面 | |||||
centerBox: true, | |||||
high: true, | |||||
cropData: {}, | |||||
enlarge: 1, | |||||
mode: 'contain', | |||||
maxImgSize: 3000, | |||||
// limitMinSize: [50, 50], | |||||
fixed: false, | |||||
// fixedNumber: [2, 1], | |||||
fillColor: '', | |||||
full: true, | |||||
infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 | infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 | ||||
mode: "100% auto", // 图片默认渲染方式 | |||||
// outputSize: 0.5, //图片质量 | |||||
// info: false, // 裁剪框的大小信息 | |||||
// // outputType: 'jpeg', // 裁剪生成图片的格式 | |||||
// outputType: "png", // 裁剪生成图片的格式 | |||||
// canScale: true, // 图片是否允许滚轮缩放 | |||||
// autoCrop: true, // 是否默认生成截图框 | |||||
// autoCropWidth: window.innerWidth - 100 + "px", // 默认生成截图框宽度 | |||||
// autoCropHeight: window.innerWidth - 100 + "px", // 默认生成截图框高度 | |||||
// high: true, // 是否按照设备的dpr 输出等比例图片 | |||||
// fixedBox: false, // 固定截图框大小 不允许改变 | |||||
// fixed: false, // 是否开启截图框宽高固定比例 | |||||
// // fixedNumber: [1, 1], // 截图框的宽高比例 | |||||
// full: true, // 是否输出原图比例的截图 | |||||
// canMoveBox: true, // 截图框能否拖动 | |||||
// original: false, // 上传图片按照原始比例渲染 | |||||
// centerBox: true, // 截图框是否被限制在图片里面 | |||||
// infoTrue: false, // true 为展示真实输出图片宽高 false 展示看到的截图框宽高 | |||||
// mode: "100% auto", // 图片默认渲染方式 | |||||
}); | }); | ||||
//#region 裁剪图片 | //#region 裁剪图片 | ||||
const cropperOverData = ref(null); | const cropperOverData = ref(null); | ||||
function sendImgData() { | function sendImgData() { | ||||
cropper.value.getCropBlob(async (data) => { | cropper.value.getCropBlob(async (data) => { | ||||
try { | try { | ||||
const checkPhotoRes = await checkPhotoApi(data) | |||||
if (checkPhotoRes.code !== 200) { | |||||
ElMessage.error(checkPhotoRes.message); | |||||
return | |||||
} | |||||
const res = await awsImgUpload(data); | const res = await awsImgUpload(data); | ||||
const res2 = await saveImgApi({ | const res2 = await saveImgApi({ | ||||
type: props.type, | type: props.type, | ||||
@@ -0,0 +1,51 @@ | |||||
<template> | |||||
<div class="loadingIcon"> | |||||
<div> | |||||
<el-icon class="is-loading"> | |||||
<svg | |||||
viewBox="0 0 1024 1024" | |||||
xmlns="http://www.w3.org/2000/svg" | |||||
data-v-ea893728="" | |||||
> | |||||
<path | |||||
fill="currentColor" | |||||
d="M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32zM195.2 195.2a32 32 0 0 1 45.248 0L376.32 331.008a32 32 0 0 1-45.248 45.248L195.2 240.448a32 32 0 0 1 0-45.248zm452.544 452.544a32 32 0 0 1 45.248 0L828.8 783.552a32 32 0 0 1-45.248 45.248L647.744 692.992a32 32 0 0 1 0-45.248zM828.8 195.264a32 32 0 0 1 0 45.184L692.992 376.32a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0zm-452.544 452.48a32 32 0 0 1 0 45.248L240.448 828.8a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0z" | |||||
></path> | |||||
</svg> | |||||
</el-icon> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script setup> | |||||
import { useI18n } from "vue-i18n"; | |||||
const { locale } = useI18n(); | |||||
const lanChange = ref(locale); | |||||
const props = defineProps({ | |||||
isLoading: { | |||||
required: false, //是否必传 | |||||
}, | |||||
}); | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.loadingIcon { | |||||
position: relative; | |||||
width: 100%; | |||||
height: 60px; | |||||
line-height: 60px; | |||||
text-align: center; | |||||
transform: scale(2); | |||||
> div { | |||||
position: absolute; | |||||
top: 0; | |||||
left: 50%; | |||||
transform: translateX(-50%); | |||||
} | |||||
.loadingText { | |||||
position: relative; | |||||
top: -2px; | |||||
left: 4px; | |||||
} | |||||
} | |||||
</style> |
@@ -51,6 +51,7 @@ export default { | |||||
logout: "Logout", | logout: "Logout", | ||||
goLogin: "Go and log in", | goLogin: "Go and log in", | ||||
LanguageChange: "Language switching", | LanguageChange: "Language switching", | ||||
currencyValue: 'Current currency value' | |||||
}, | }, | ||||
// 创作视频 | // 创作视频 | ||||
@@ -85,6 +86,7 @@ export default { | |||||
comingSoon: "COMING SOON", | comingSoon: "COMING SOON", | ||||
material: "Material", | material: "Material", | ||||
subtitles: "Subtitles", | subtitles: "Subtitles", | ||||
AItext:"AI Script", | |||||
sex: "Sex", | sex: "Sex", | ||||
videoRatio: "Video Ratio", | videoRatio: "Video Ratio", | ||||
all: "All", | all: "All", | ||||
@@ -104,6 +106,11 @@ export default { | |||||
tooltip2: "Add Pause", | tooltip2: "Add Pause", | ||||
SubtitlesTip: "Subtitles will be shown here", | SubtitlesTip: "Subtitles will be shown here", | ||||
subtitlesSwitch: "Subtitles Switch", | subtitlesSwitch: "Subtitles Switch", | ||||
inputRequirement:'Please enter your requirements, for example: Please generate a beverage advertisement of 500 words or less', | |||||
GeneratedText:'Generated Text', | |||||
SmartText:'Smart Text', | |||||
copy:'Copy to text', | |||||
custom: 'VIP' | |||||
}, | }, | ||||
// 我的视频 | // 我的视频 | ||||
@@ -202,6 +209,18 @@ export default { | |||||
title: "API Access", | title: "API Access", | ||||
comingSoon: "Coming Soon", | comingSoon: "Coming Soon", | ||||
}, | }, | ||||
cooperate: { | |||||
title: 'Partner Access', | |||||
api: { | |||||
title: 'API Access' | |||||
}, | |||||
privatization: { | |||||
title: 'Privatization deployment' | |||||
} | |||||
}, | |||||
my: { | |||||
title: 'My', | |||||
}, | |||||
signSucceed: { | signSucceed: { | ||||
title: "Confirm your email", | title: "Confirm your email", | ||||
@@ -215,4 +234,44 @@ export default { | |||||
goLogin: "Login now", | goLogin: "Login now", | ||||
reSend: "Resend", | reSend: "Resend", | ||||
}, | }, | ||||
recharge: { | |||||
title: 'Recharge order', | |||||
currencyValue: 'Current currency value', | |||||
productTitle: 'name', | |||||
orderNumber: 'Order No', | |||||
payment: 'amount of money', | |||||
createTime: 'Creation time', | |||||
operate: 'operate', | |||||
view: 'view', | |||||
detailTitle: 'Recharge Details', | |||||
payVendor: 'Payment method', | |||||
weChat: 'WeChat', | |||||
alipay: 'Alipay', | |||||
paymentStr: 'Payment amount', | |||||
orderStatus: 'Payment status', | |||||
paymentTime: 'Pay time', | |||||
close: 'close' | |||||
}, | |||||
coindeduc: { | |||||
title: 'Creation Record', | |||||
currencyValue: 'Current currency value', | |||||
titleList: 'name', | |||||
videoPlayUrl: 'Video address', | |||||
videoTime: 'Video duration(S)', | |||||
costPoints: 'Deduction quantity', | |||||
createTime: 'Creation time', | |||||
operate: 'operate', | |||||
view: 'view', | |||||
detailTitle: 'Deduction Details', | |||||
second: 'S' | |||||
}, | |||||
store: { | |||||
priceRmb: 'original price', | |||||
glod: 'currency value', | |||||
createOrder: 'BUY NOW', | |||||
payType:'Choose payment method', | |||||
cancel: 'Cancel', | |||||
confirm: 'Confirm', | |||||
pay: 'Payment in progress...', | |||||
} | |||||
}; | }; |
@@ -52,6 +52,7 @@ export default { | |||||
logout: "注销", | logout: "注销", | ||||
goLogin: "登录", | goLogin: "登录", | ||||
LanguageChange: "语言切换", | LanguageChange: "语言切换", | ||||
currencyValue: '当前币值' | |||||
}, | }, | ||||
// 创作视频 | // 创作视频 | ||||
@@ -86,6 +87,7 @@ export default { | |||||
BackgroundImage: "背景", | BackgroundImage: "背景", | ||||
material: "素材", | material: "素材", | ||||
subtitles: "字幕", | subtitles: "字幕", | ||||
AItext:"AI生成文本", | |||||
sex: "性别", | sex: "性别", | ||||
videoRatio: "视频比例", | videoRatio: "视频比例", | ||||
all: "全部", | all: "全部", | ||||
@@ -105,6 +107,11 @@ export default { | |||||
tooltip2: "添加停顿", | tooltip2: "添加停顿", | ||||
SubtitlesTip: "字幕将在此处展示", | SubtitlesTip: "字幕将在此处展示", | ||||
subtitlesSwitch: "字幕开关", | subtitlesSwitch: "字幕开关", | ||||
inputRequirement:'请输入您的需求,例如:请生成一个500字以内的饮料广告', | |||||
GeneratedText:'生成文本', | |||||
SmartText:'智能文本', | |||||
copy:'复制到文案', | |||||
custom: '私人订制' | |||||
}, | }, | ||||
// 我的视频 | // 我的视频 | ||||
@@ -202,6 +209,18 @@ export default { | |||||
title: "API 接口", | title: "API 接口", | ||||
comingSoon: "敬请期待", | comingSoon: "敬请期待", | ||||
}, | }, | ||||
cooperate: { | |||||
title: '合作商接入', | |||||
api: { | |||||
title: 'API 接口' | |||||
}, | |||||
privatization: { | |||||
title: '私有化部署' | |||||
} | |||||
}, | |||||
my: { | |||||
title: '我的', | |||||
}, | |||||
signSucceed: { | signSucceed: { | ||||
title: "确认邮箱", | title: "确认邮箱", | ||||
@@ -214,4 +233,44 @@ export default { | |||||
goLogin: "即将登录", | goLogin: "即将登录", | ||||
reSend: "重新发送", | reSend: "重新发送", | ||||
}, | }, | ||||
recharge: { | |||||
title: '充值订单', | |||||
currencyValue: '当前币值', | |||||
productTitle: '名称', | |||||
orderNumber: '订单号', | |||||
payment: '金额', | |||||
createTime: '创建时间', | |||||
operate: '操作', | |||||
view: '查看', | |||||
detailTitle: '充值详情', | |||||
payVendor: '支付方式', | |||||
weChat: '微信', | |||||
alipay: '支付宝', | |||||
paymentStr: '支付金额', | |||||
orderStatus: '支付状态', | |||||
paymentTime: '支付时间', | |||||
close: '关闭' | |||||
}, | |||||
coindeduc: { | |||||
title: '创作记录', | |||||
currencyValue: '当前币值', | |||||
titleList: '名称', | |||||
videoPlayUrl: '视频地址', | |||||
videoTime: '视频时长(秒)', | |||||
costPoints: '扣币数量', | |||||
createTime: '创建时间', | |||||
operate: '操作', | |||||
view: '查看', | |||||
detailTitle: '扣币详情', | |||||
second: '秒' | |||||
}, | |||||
store: { | |||||
priceRmb: '原价', | |||||
glod: '币值', | |||||
createOrder: '立即购买', | |||||
payType:'选择支付方式', | |||||
cancel: '取消', | |||||
confirm: '确定', | |||||
pay: '支付中...', | |||||
} | |||||
}; | }; |
@@ -23,39 +23,58 @@ | |||||
</div> | </div> | ||||
{{ $t("myCreating.title") }} | {{ $t("myCreating.title") }} | ||||
</div> | </div> | ||||
<div class="myRouter-item" @click="showTalkUsDialog = true"> | |||||
<div class="myRouter-item" @click="router.push('/separation')"> | |||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-user /></el-icon> | <el-icon><i-ep-user /></el-icon> | ||||
</div> | </div> | ||||
{{ $t("userModel.title") }} | {{ $t("userModel.title") }} | ||||
</div> | </div> | ||||
<div class="myRouter-item" @click="showTalkUsDialog = true"> | |||||
<div class="myRouter-item" @click="router.push('/voiceprint')"> | |||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-phone /></el-icon> | <el-icon><i-ep-phone /></el-icon> | ||||
</div> | </div> | ||||
{{ $t("voiceModel.title") }} | {{ $t("voiceModel.title") }} | ||||
</div> | </div> | ||||
<div class="bottomBtx"> | |||||
<!-- <div class="bottomBtx"> --> | |||||
<div class="myRouter-item" @click="router.push('/myStore')"> | <div class="myRouter-item" @click="router.push('/myStore')"> | ||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-Goods /></el-icon> | <el-icon><i-ep-Goods /></el-icon> | ||||
</div> | </div> | ||||
{{ $t("shop.title") }} | {{ $t("shop.title") }} | ||||
</div> | </div> | ||||
<div class="myRouter-item" @click="router.push('/myAPI')"> | |||||
<!-- <div class="myRouter-item" @click="router.push('/myAPI')"> | |||||
<div class="icon"> | <div class="icon"> | ||||
<el-icon><i-ep-DocumentAdd /></el-icon> | <el-icon><i-ep-DocumentAdd /></el-icon> | ||||
</div> | </div> | ||||
{{ $t("API.title") }} | {{ $t("API.title") }} | ||||
</div> | |||||
</div> | |||||
</div> --> | |||||
<el-menu | |||||
default-active="" | |||||
class="el-menu-vertical-demo" | |||||
active-text-color="#ffd04b" | |||||
background-color="#000" | |||||
text-color="#fff" | |||||
> | |||||
<el-sub-menu index="1"> | |||||
<template #title> | |||||
<el-icon><location /></el-icon> | |||||
<span>{{ $t("my.title") }}</span> | |||||
</template> | |||||
<el-menu-item-group> | |||||
<el-menu-item index="2-1" @click="router.push('/myRecharge')">{{ $t("recharge.title") }} </el-menu-item> | |||||
<el-menu-item index="2-2" @click="router.push('/coindeduc')">{{ $t("coindeduc.title") }} </el-menu-item> | |||||
</el-menu-item-group> | |||||
</el-sub-menu> | |||||
</el-menu> | |||||
<!-- </div> --> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
<!-- 右边显示部分 --> | <!-- 右边显示部分 --> | ||||
<div class="rightBox"> | <div class="rightBox"> | ||||
<!-- nav栏 --> | <!-- nav栏 --> | ||||
<div class="nav"> | <div class="nav"> | ||||
<div class="navItem">{{ $t("navbar.currencyValue") }}:{{ currentValue }}</div> | |||||
<!-- 语言 --> | <!-- 语言 --> | ||||
<el-tooltip | <el-tooltip | ||||
style="cursor: pointer; z-index: 999" | style="cursor: pointer; z-index: 999" | ||||
@@ -66,6 +85,7 @@ | |||||
> | > | ||||
<lang-select class="navItem" /> | <lang-select class="navItem" /> | ||||
</el-tooltip> | </el-tooltip> | ||||
<div class="navItem" v-if="currentPhone">{{ currentPhone }}</div> | |||||
<!-- 登录 --> | <!-- 登录 --> | ||||
<div class="navItem" v-if="!AccessToken" @click="router.push('login')"> | <div class="navItem" v-if="!AccessToken" @click="router.push('login')"> | ||||
{{ $t("navbar.goLogin") }} | {{ $t("navbar.goLogin") }} | ||||
@@ -103,6 +123,14 @@ import { useRoute, useRouter } from "vue-router"; | |||||
import { useI18n } from "vue-i18n"; | import { useI18n } from "vue-i18n"; | ||||
import { userInfoModules } from "@/store/modules/userInfo"; | import { userInfoModules } from "@/store/modules/userInfo"; | ||||
import { getUserPoinsApi } from '@/apis/my.js' | |||||
import { | |||||
Document, | |||||
Menu as IconMenu, | |||||
Location, | |||||
Setting, | |||||
} from '@element-plus/icons-vue' | |||||
const userInfoPinia = userInfoModules(); | const userInfoPinia = userInfoModules(); | ||||
const route = useRoute(); | const route = useRoute(); | ||||
@@ -162,20 +190,41 @@ function handleOutsideClick() { | |||||
appStore.closeSideBar(false); | appStore.closeSideBar(false); | ||||
} | } | ||||
onMounted(() => {}); | |||||
// 当前币值 | |||||
const currentValue = ref('') | |||||
const currentPhone = localStorage.getItem('phone') | |||||
function currentValFn() { | |||||
getUserPoinsApi().then(res => { | |||||
currentValue.value = res.data | |||||
localStorage.setItem('userPoinsVal', res.data) | |||||
}) | |||||
} | |||||
onMounted(() => { | |||||
currentValFn() | |||||
}); | |||||
//#region 联系我们弹窗 | //#region 联系我们弹窗 | ||||
const showTalkUsDialog = ref(false); | const showTalkUsDialog = ref(false); | ||||
const updateShowTalkUsDialog = (newValue: any) => { | const updateShowTalkUsDialog = (newValue: any) => { | ||||
showTalkUsDialog.value = newValue; | showTalkUsDialog.value = newValue; | ||||
}; | }; | ||||
//#endregion ----------------------------------- | |||||
//#region 页面跳转 | |||||
function toUserModel() { | |||||
// router.push("/userModel"); | |||||
window.location.href = '/priMakeHtml/dingzhifenshen/index.shtml' | |||||
showTalkUsDialog.value = true; | |||||
} | |||||
//#endregion ------------------------------------ | //#endregion ------------------------------------ | ||||
</script> | </script> | ||||
<!-- 新样式 --> | <!-- 新样式 --> | ||||
<style lang="scss" scoped> | <style lang="scss" scoped> | ||||
.app-wrapper { | .app-wrapper { | ||||
width: 1920px; | |||||
width: 100%; | |||||
display: flex; | display: flex; | ||||
overflow: hidden; | |||||
} | } | ||||
.Sidebar { | .Sidebar { | ||||
width: 230px; | width: 230px; | ||||
@@ -194,9 +243,12 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||||
.myRouter { | .myRouter { | ||||
position: relative; | position: relative; | ||||
height: calc(100% - 80px); | height: calc(100% - 80px); | ||||
padding: 130px 20px 0; | |||||
padding: 40px 20px 0; | |||||
color: #fff; | color: #fff; | ||||
user-select: none; | |||||
// color: #868593; | // color: #868593; | ||||
overflow: auto; | |||||
overflow-x: hidden; | |||||
.bottomBtx { | .bottomBtx { | ||||
position: absolute; | position: absolute; | ||||
@@ -207,8 +259,7 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||||
width: 100%; | width: 100%; | ||||
height: 50px; | height: 50px; | ||||
padding-left: 10px; | padding-left: 10px; | ||||
font-size: 20px; | |||||
font-weight: 500; | |||||
font-size: 18px; | |||||
line-height: 50px; | line-height: 50px; | ||||
text-align: center; | text-align: center; | ||||
cursor: pointer; | cursor: pointer; | ||||
@@ -234,7 +285,6 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||||
vertical-align: sub; | vertical-align: sub; | ||||
} | } | ||||
} | } | ||||
&:hover { | &:hover { | ||||
// background: rgba(255, 255, 255, 0.2); | // background: rgba(255, 255, 255, 0.2); | ||||
color: #000; | color: #000; | ||||
@@ -261,7 +311,7 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||||
} | } | ||||
} | } | ||||
.rightBox { | .rightBox { | ||||
width: 1690px; | |||||
width: calc(100% - 230px); | |||||
// background-color: #000; | // background-color: #000; | ||||
.nav { | .nav { | ||||
display: flex; | display: flex; | ||||
@@ -280,4 +330,11 @@ const updateShowTalkUsDialog = (newValue: any) => { | |||||
} | } | ||||
} | } | ||||
} | } | ||||
.el-menu{ | |||||
border: none; | |||||
:deep .el-sub-menu__title, :deep .el-menu-item{ | |||||
font-size: 18px; | |||||
} | |||||
} | |||||
</style> | </style> |
@@ -1,4 +1,4 @@ | |||||
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router"; | |||||
import { createRouter, createWebHashHistory, RouteRecordRaw, useRoute } from "vue-router"; | |||||
import { getCurrentInstance } from "vue"; | import { getCurrentInstance } from "vue"; | ||||
export const Layout = () => import("@/layout/index.vue"); | export const Layout = () => import("@/layout/index.vue"); | ||||
@@ -55,6 +55,42 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||||
}, | }, | ||||
}, | }, | ||||
], | ], | ||||
}, // 定制分身 | |||||
{ | |||||
path: "/", | |||||
component: Layout, | |||||
redirect: "/userModel", | |||||
children: [ | |||||
{ | |||||
path: "userModel", | |||||
component: () => import("@/views/userModel/index.vue"), | |||||
name: "userModel", | |||||
meta: { | |||||
title: "userModel", | |||||
icon: "homepage", | |||||
affix: true, | |||||
name: "userModel.title", | |||||
}, | |||||
}, | |||||
], | |||||
}, // 定制声纹 | |||||
{ | |||||
path: "/", | |||||
component: Layout, | |||||
redirect: "/voiceModel", | |||||
children: [ | |||||
{ | |||||
path: "voiceModel", | |||||
component: () => import("@/views/voiceModel/index.vue"), | |||||
name: "voiceModel", | |||||
meta: { | |||||
title: "voiceModel", | |||||
icon: "homepage", | |||||
affix: true, | |||||
name: "voiceModel.title", | |||||
}, | |||||
}, | |||||
], | |||||
}, { | }, { | ||||
path: "/", | path: "/", | ||||
component: Layout, | component: Layout, | ||||
@@ -75,17 +111,28 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||||
}, { | }, { | ||||
path: "/", | path: "/", | ||||
component: Layout, | component: Layout, | ||||
redirect: "/myAPI", | |||||
redirect: "/myRecharge", | |||||
children: [ | children: [ | ||||
{ | { | ||||
path: "myAPI", | |||||
component: () => import("@/views/myAPI/index.vue"), | |||||
name: "myAPI", | |||||
path: "/myRecharge", | |||||
component: () => import("@/views/my/recharge.vue"), | |||||
name: "myRecharge", | |||||
meta: { | meta: { | ||||
title: "myAPI", | |||||
title: "myRecharge", | |||||
icon: "homepage", | icon: "homepage", | ||||
affix: true, | affix: true, | ||||
name: "API.title", | |||||
name: "my.title", | |||||
}, | |||||
}, | |||||
{ | |||||
path: "/coindeduc", | |||||
component: () => import("@/views/my/coindeduc.vue"), | |||||
name: "coindeduc", | |||||
meta: { | |||||
title: "coindeduc", | |||||
icon: "homepage", | |||||
affix: true, | |||||
name: "my.title", | |||||
}, | }, | ||||
}, | }, | ||||
], | ], | ||||
@@ -108,6 +155,57 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||||
}, | }, | ||||
], | ], | ||||
}, | }, | ||||
{ | |||||
path: "/", | |||||
component: Layout, | |||||
redirect: "/separation", | |||||
children: [ | |||||
{ | |||||
path: "/separation", | |||||
component: () => import("@/views/separation/index.vue"), | |||||
name: "separation", | |||||
meta: { | |||||
title: "separation", | |||||
icon: "homepage", | |||||
affix: true, | |||||
name: "separation.title", | |||||
}, | |||||
}, | |||||
{ | |||||
path: "/voiceprint", | |||||
component: () => import("@/views/voiceprint/index.vue"), | |||||
name: "voiceprint", | |||||
meta: { | |||||
title: "voiceprint", | |||||
icon: "homepage", | |||||
affix: true, | |||||
name: "separation.title", | |||||
}, | |||||
}, | |||||
{ | |||||
path: "/privatization", | |||||
component: () => import("@/views/privatization/index.vue"), | |||||
name: "privatization", | |||||
meta: { | |||||
title: "privatization", | |||||
icon: "homepage", | |||||
affix: true, | |||||
name: "separation.title", | |||||
}, | |||||
}, | |||||
{ | |||||
path: "/api", | |||||
component: () => import("@/views/api/index.vue"), | |||||
name: "api", | |||||
meta: { | |||||
title: "api", | |||||
icon: "homepage", | |||||
affix: true, | |||||
name: "separation.title", | |||||
}, | |||||
}, | |||||
], | |||||
}, | |||||
]; | ]; | ||||
@@ -121,7 +219,9 @@ const router = createRouter({ | |||||
// 2023-5-23 添加平滑滚动 YWQ | // 2023-5-23 添加平滑滚动 YWQ | ||||
scrollBehavior: () => ({ behavior: "smooth", left: 0, top: 0 }), | scrollBehavior: () => ({ behavior: "smooth", left: 0, top: 0 }), | ||||
}); | }); | ||||
router.beforeEach((to, from) => { | |||||
document.title = '元气智驾-' + (to.query.p || from.query.p || localStorage.getItem("title") || '悟空') | |||||
}) | |||||
/** | /** | ||||
* 重置路由 | * 重置路由 | ||||
*/ | */ | ||||
@@ -13,6 +13,7 @@ export const userInfoModules = defineStore("userInfo", () => { | |||||
async function getUserInfo() { | async function getUserInfo() { | ||||
const res = await getUserInfoApi() | const res = await getUserInfoApi() | ||||
userInfo.value = res.data | userInfo.value = res.data | ||||
localStorage.setItem('phone', res.data.phone) | |||||
} | } | ||||
// 退出清除用户信息 | // 退出清除用户信息 | ||||
function loginOut(params) { | function loginOut(params) { | ||||
@@ -2,6 +2,8 @@ | |||||
export {} | export {} | ||||
declare global { | declare global { | ||||
const EffectScope: typeof import('vue')['EffectScope'] | const EffectScope: typeof import('vue')['EffectScope'] | ||||
const ElMessage: typeof import('element-plus/es')['ElMessage'] | |||||
const ElMessageBox: typeof import('element-plus/es')['ElMessageBox'] | |||||
const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | const asyncComputed: typeof import('@vueuse/core')['asyncComputed'] | ||||
const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] | const autoResetRef: typeof import('@vueuse/core')['autoResetRef'] | ||||
const computed: typeof import('vue')['computed'] | const computed: typeof import('vue')['computed'] | ||||
@@ -268,6 +270,8 @@ 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 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']> | readonly asyncComputed: UnwrapRef<typeof import('@vueuse/core')['asyncComputed']> | ||||
readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']> | readonly autoResetRef: UnwrapRef<typeof import('@vueuse/core')['autoResetRef']> | ||||
readonly computed: UnwrapRef<typeof import('vue')['computed']> | readonly computed: UnwrapRef<typeof import('vue')['computed']> | ||||
@@ -13,6 +13,7 @@ declare module '@vue/runtime-core' { | |||||
CutImg1: typeof import('./../components/cutImg1.vue')['default'] | CutImg1: typeof import('./../components/cutImg1.vue')['default'] | ||||
EditPosition: typeof import('./../components/EditPosition.vue')['default'] | EditPosition: typeof import('./../components/EditPosition.vue')['default'] | ||||
'EditPosition copy': typeof import('./../components/EditPosition copy.vue')['default'] | 'EditPosition copy': typeof import('./../components/EditPosition copy.vue')['default'] | ||||
ElAlert: typeof import('element-plus/es')['ElAlert'] | |||||
ElButton: typeof import('element-plus/es')['ElButton'] | ElButton: typeof import('element-plus/es')['ElButton'] | ||||
ElDialog: typeof import('element-plus/es')['ElDialog'] | ElDialog: typeof import('element-plus/es')['ElDialog'] | ||||
ElDropdown: typeof import('element-plus/es')['ElDropdown'] | ElDropdown: typeof import('element-plus/es')['ElDropdown'] | ||||
@@ -23,10 +24,19 @@ declare module '@vue/runtime-core' { | |||||
ElIcon: typeof import('element-plus/es')['ElIcon'] | ElIcon: typeof import('element-plus/es')['ElIcon'] | ||||
ElInput: typeof import('element-plus/es')['ElInput'] | ElInput: typeof import('element-plus/es')['ElInput'] | ||||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] | ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] | ||||
ElMenu: typeof import('element-plus/es')['ElMenu'] | |||||
ElMenuItem: typeof import('element-plus/es')['ElMenuItem'] | |||||
ElMenuItemGroup: typeof import('element-plus/es')['ElMenuItemGroup'] | |||||
ElOption: typeof import('element-plus/es')['ElOption'] | ElOption: typeof import('element-plus/es')['ElOption'] | ||||
ElPagination: typeof import('element-plus/es')['ElPagination'] | ElPagination: typeof import('element-plus/es')['ElPagination'] | ||||
ElRadio: typeof import('element-plus/es')['ElRadio'] | |||||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] | |||||
ElScrollbar: typeof import('element-plus/es')['ElScrollbar'] | |||||
ElSelect: typeof import('element-plus/es')['ElSelect'] | ElSelect: typeof import('element-plus/es')['ElSelect'] | ||||
ElSubMenu: typeof import('element-plus/es')['ElSubMenu'] | |||||
ElSwitch: typeof import('element-plus/es')['ElSwitch'] | ElSwitch: typeof import('element-plus/es')['ElSwitch'] | ||||
ElTable: typeof import('element-plus/es')['ElTable'] | |||||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] | |||||
ElTooltip: typeof import('element-plus/es')['ElTooltip'] | ElTooltip: typeof import('element-plus/es')['ElTooltip'] | ||||
ElUpload: typeof import('element-plus/es')['ElUpload'] | ElUpload: typeof import('element-plus/es')['ElUpload'] | ||||
GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default'] | GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default'] | ||||
@@ -49,6 +59,7 @@ declare module '@vue/runtime-core' { | |||||
MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default'] | MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default'] | ||||
MyLoading: typeof import('./../components/myLoading.vue')['default'] | MyLoading: typeof import('./../components/myLoading.vue')['default'] | ||||
MyLoadingIcon: typeof import('./../components/myLoadingIcon.vue')['default'] | MyLoadingIcon: typeof import('./../components/myLoadingIcon.vue')['default'] | ||||
MyLoadingIcon2: typeof import('./../components/myLoadingIcon2.vue')['default'] | |||||
Pagination: typeof import('./../components/Pagination/index.vue')['default'] | Pagination: typeof import('./../components/Pagination/index.vue')['default'] | ||||
RouterLink: typeof import('vue-router')['RouterLink'] | RouterLink: typeof import('vue-router')['RouterLink'] | ||||
RouterView: typeof import('vue-router')['RouterView'] | RouterView: typeof import('vue-router')['RouterView'] | ||||
@@ -69,12 +69,12 @@ request.interceptors.response.use( | |||||
); | ); | ||||
return | return | ||||
// 弹出错误 | // 弹出错误 | ||||
} else if (code != 200) { | |||||
} else if (code != 200 && code !== 64001) { | |||||
if (code == 500) { | if (code == 500) { | ||||
// ElMessage.error("系统异常,请稍后再试"); | // ElMessage.error("系统异常,请稍后再试"); | ||||
// ElMessage.error($t('tips.systemException')); | // ElMessage.error($t('tips.systemException')); | ||||
ElMessage.error( | ElMessage.error( | ||||
appStore.language == "zh-cn" ? `服务器繁忙,请重试!` : `The server is busy, please try again` | |||||
appStore.language == "zh-cn" ? (response.data.languageMessage && response.data.languageMessage['zh-cn']) || `服务器繁忙,请重试!` : (response.data.languageMessage && response.data.languageMessage[appStore.language]) || `The server is busy, please try again` | |||||
); | ); | ||||
// 其他错误 | // 其他错误 | ||||
} else { | } else { | ||||
@@ -0,0 +1,141 @@ | |||||
<!DOCTYPE html> | |||||
<html lang="en"> | |||||
<head> | |||||
<meta charset="UTF-8"> | |||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |||||
<title>Document</title> | |||||
<style> | |||||
* { | |||||
padding: 0; | |||||
margin: 0; | |||||
} | |||||
.page { | |||||
padding: 50px | |||||
} | |||||
h1 { | |||||
font-size: 20px; | |||||
font-weight: 600; | |||||
margin-bottom: 0.8em; | |||||
} | |||||
p { | |||||
margin-bottom: 0.5em; | |||||
font-size: 14px; | |||||
line-height: 1.6; | |||||
} | |||||
.table { | |||||
margin-top: 50px; | |||||
} | |||||
.table .table-wrp { | |||||
margin: 1em 0 3em; | |||||
overflow-x: auto; | |||||
max-width: 100%; | |||||
} | |||||
.table table { | |||||
display: table; | |||||
width: 100%; | |||||
border-collapse: collapse; | |||||
border-spacing: 0; | |||||
overflow: auto; | |||||
font-size: 14px; | |||||
} | |||||
.table table th { | |||||
font-weight: 600; | |||||
text-align: left; | |||||
border-bottom: 1px solid #888; | |||||
padding: 10px 20px; | |||||
white-space: nowrap; | |||||
color: #888; | |||||
} | |||||
.table table td { | |||||
color: #353535; | |||||
text-align: left; | |||||
border-bottom: 1px solid #e5e5e5; | |||||
padding: 20px 20px; | |||||
height: 62px; | |||||
box-sizing: border-box; | |||||
word-break: normal; | |||||
} | |||||
.style .code{ | |||||
background-color: #f9f9fa; | |||||
margin: 1em 0; | |||||
border-radius: 4px | |||||
} | |||||
</style> | |||||
</head> | |||||
<body> | |||||
<div class="page"> | |||||
<!-- 文字 --> | |||||
<div class="text"> | |||||
<h1>概述</h1> | |||||
<p>在小程序管理后台开启api加密后,开发者需要对原APl的请求内容 加密 与签名,同时AP的回包内容需要开发者验签 与 解密 。支持的api可参考接口调用。</p> | |||||
<p>目前支持以下几种算法,可在MP管理页配置。</p> | |||||
</div> | |||||
<!-- 表格 --> | |||||
<div class="table"> | |||||
<h1>API请求处理</h1> | |||||
<div class="table-wrp"> | |||||
<table> | |||||
<thead> | |||||
<tr> | |||||
<th>参数</th> | |||||
<th>类型</th> | |||||
<th>默认值</th> | |||||
<th>必填</th> | |||||
<th>备注</th> | |||||
</tr> | |||||
</thead> | |||||
<tbody> | |||||
<tr> | |||||
<td>iv</td> | |||||
<td>string</td> | |||||
<td></td> | |||||
<td>是</td> | |||||
<td>初始向量,为16字节base64字符串(解码后为12字节随机字符串)</td> | |||||
</tr> | |||||
<tr> | |||||
<td>data</td> | |||||
<td>string</td> | |||||
<td></td> | |||||
<td>是</td> | |||||
<td>加密后的密文,使用base64编码</td> | |||||
</tr> | |||||
<tr> | |||||
<td>authtag</td> | |||||
<td>string</td> | |||||
<td></td> | |||||
<td>是</td> | |||||
<td>GCM模式输出的认证信息,使用base64编码</td> | |||||
</tr> | |||||
</tbody> | |||||
</table> | |||||
</div> | |||||
</div> | |||||
<!-- 样式 --> | |||||
<div class="style"> | |||||
<h1>样式</h1> | |||||
<div class="code"> | |||||
<pre class="language-json"> | |||||
<code> | |||||
<span>{</span> | |||||
<span>"Sn"</span><span>:</span> <span>"fa05fe1e5bcc79b81ad5ad4b58acf787"</span><span>,</span> | |||||
<span>"Key"</span><span>:</span> <span>"otUpngOjU+nVQaWJIC3D/yMLV17RKaP6t4Ot9tbnzLY="</span> | |||||
<span>}</span> | |||||
</code> | |||||
</pre> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</body> | |||||
</html> |
@@ -0,0 +1,125 @@ | |||||
<template> | |||||
<div class="page"> | |||||
<div class=""> | |||||
<el-menu | |||||
default-active="1-1" | |||||
class="sidebar" | |||||
@open="handleOpen" | |||||
@close="handleClose" | |||||
> | |||||
<el-sub-menu index="1"> | |||||
<template #title> | |||||
<span>开发前必读</span> | |||||
</template> | |||||
<el-menu-item index="1-1" @click="guide">服务端API签名指南</el-menu-item> | |||||
</el-sub-menu> | |||||
<el-sub-menu index="2"> | |||||
<template #title> | |||||
<span>开发接口</span> | |||||
</template> | |||||
<el-menu-item v-for="item in apiMenuList" :key="item.id" :index="item.id" @click="getContent(item.id)">{{ item.name }}</el-menu-item> | |||||
</el-sub-menu> | |||||
</el-menu> | |||||
</div> | |||||
<div class="content"> | |||||
<div v-html="content"></div> | |||||
</div> | |||||
</div> | |||||
</template> | |||||
<script setup> | |||||
import { getAvailableApiGuideApi, apiMenuApi, getContentApi } from '@/apis/api.js' | |||||
const handleOpen = (key, keyPath) => { | |||||
console.log(key, keyPath) | |||||
if (key === '2') { | |||||
getMenu() | |||||
} | |||||
} | |||||
const handleClose = (key, keyPath) => { | |||||
console.log(key, keyPath) | |||||
} | |||||
const content = ref(''); | |||||
// 签名指南 | |||||
const guide = () => { | |||||
getAvailableApiGuideApi().then(res => { | |||||
if(res.code === 200) { | |||||
content.value = res.data.content | |||||
} | |||||
}) | |||||
} | |||||
// 开发接口 | |||||
const apiMenuList = ref([]) | |||||
const getMenu = () => { | |||||
apiMenuApi().then(res => { | |||||
if (res.code === 200) { | |||||
apiMenuList.value = res.data | |||||
} | |||||
}) | |||||
} | |||||
// 详情 | |||||
const getContent = (id) => { | |||||
getContentApi(id).then(res => { | |||||
if (res.code === 200) { | |||||
content.value = res.data.content || '' | |||||
} | |||||
}) | |||||
} | |||||
onMounted(() => { | |||||
guide() | |||||
}); | |||||
</script> | |||||
<style> | |||||
.sidebar.el-menu--vertical .el-sub-menu__title:hover { | |||||
background-color: #fff !important; | |||||
} | |||||
.sidebar.el-menu--vertical .el-menu-item:hover { | |||||
background-color: #fff !important; | |||||
} | |||||
</style> | |||||
<style lang="scss" scoped> | |||||
.page { | |||||
display: flex; | |||||
width: 100%; | |||||
overflow: hidden; | |||||
overflow-y: scroll; | |||||
background-color: #f5f5f5; | |||||
border-radius: 25px 0 0 0; | |||||
min-height: calc(100vh - 80px); | |||||
// text-align: center; | |||||
.title { | |||||
font-size: 50px; | |||||
} | |||||
.sidebar { | |||||
position: absolute; | |||||
width: 340px; | |||||
top: 0; | |||||
bottom: 0; | |||||
overflow: auto; | |||||
padding: 40px 30px; | |||||
box-sizing: border-box; | |||||
z-index: 1; | |||||
} | |||||
.content{ | |||||
position: absolute; | |||||
left: 340px; | |||||
right: 0; | |||||
top: 0; | |||||
bottom:0; | |||||
background: #fff; | |||||
padding: 40px 30px; | |||||
overflow: auto; | |||||
} | |||||
} | |||||
:deep(.el-submenu .el-menu:hover) { | |||||
background: transparent; | |||||
color: #d75b5f; | |||||
} | |||||
</style> |
@@ -19,7 +19,7 @@ | |||||
> | > | ||||
<div class="flex text-white items-center"> | <div class="flex text-white items-center"> | ||||
<span class="flex-1 text-center">{{ | <span class="flex-1 text-center">{{ | ||||
$t("login.title") + " " + $t("login.login") | |||||
title + " " + $t("login.login") | |||||
}}</span> | }}</span> | ||||
<el-tooltip | <el-tooltip | ||||
class="box-item" | class="box-item" | ||||
@@ -136,7 +136,7 @@ | |||||
> | > | ||||
<div class="flex text-white items-center"> | <div class="flex text-white items-center"> | ||||
<span class="flex-1 text-center">{{ | <span class="flex-1 text-center">{{ | ||||
$t("login.title") + " " + $t("login.register") | |||||
title + " " + $t("login.register") | |||||
}}</span> | }}</span> | ||||
<el-tooltip | <el-tooltip | ||||
class="box-item" | class="box-item" | ||||
@@ -250,7 +250,7 @@ | |||||
> | > | ||||
<div class="flex text-white items-center"> | <div class="flex text-white items-center"> | ||||
<span class="flex-1 text-center">{{ | <span class="flex-1 text-center">{{ | ||||
$t("login.title") + " " + $t("login.register") | |||||
title + " " + $t("login.register") | |||||
}}</span> | }}</span> | ||||
<el-tooltip | <el-tooltip | ||||
class="box-item" | class="box-item" | ||||
@@ -318,7 +318,7 @@ | |||||
> | > | ||||
<div class="flex text-white items-center"> | <div class="flex text-white items-center"> | ||||
<span class="flex-1 text-center">{{ | <span class="flex-1 text-center">{{ | ||||
$t("login.title") + " " + $t("login.forgetPwdTitle") | |||||
title + " " + $t("login.forgetPwdTitle") | |||||
}}</span> | }}</span> | ||||
<el-tooltip | <el-tooltip | ||||
class="box-item" | class="box-item" | ||||
@@ -403,7 +403,7 @@ | |||||
> | > | ||||
<div class="flex text-white items-center"> | <div class="flex text-white items-center"> | ||||
<span class="flex-1 text-center">{{ | <span class="flex-1 text-center">{{ | ||||
$t("login.title") + " " + $t("login.resetPassword") | |||||
title + " " + $t("login.resetPassword") | |||||
}}</span> | }}</span> | ||||
<el-tooltip | <el-tooltip | ||||
class="box-item" | class="box-item" | ||||
@@ -524,7 +524,7 @@ | |||||
> | > | ||||
<div class="flex text-white items-center"> | <div class="flex text-white items-center"> | ||||
<span class="flex-1 text-center">{{ | <span class="flex-1 text-center">{{ | ||||
$t("login.title") + " " + $t("login.setNewPwd") | |||||
title + " " + $t("login.setNewPwd") | |||||
}}</span> | }}</span> | ||||
<el-tooltip | <el-tooltip | ||||
class="box-item" | class="box-item" | ||||
@@ -619,7 +619,7 @@ | |||||
> | > | ||||
<div class="flex text-white items-center"> | <div class="flex text-white items-center"> | ||||
<span class="flex-1 text-center">{{ | <span class="flex-1 text-center">{{ | ||||
$t("login.title") + " " + $t("login.login") | |||||
title + " " + $t("login.login") | |||||
}}</span> | }}</span> | ||||
<el-tooltip | <el-tooltip | ||||
class="box-item" | class="box-item" | ||||
@@ -716,7 +716,7 @@ | |||||
> | > | ||||
<div class="flex text-white items-center"> | <div class="flex text-white items-center"> | ||||
<span class="flex-1 text-center">{{ | <span class="flex-1 text-center">{{ | ||||
$t("login.title") + " " + $t("login.setInvitatioCode") | |||||
title + " " + $t("login.setInvitatioCode") | |||||
}}</span> | }}</span> | ||||
<el-tooltip | <el-tooltip | ||||
class="box-item" | class="box-item" | ||||
@@ -818,6 +818,15 @@ const currentLan = ref(locale); | |||||
const userInfoPinia = userInfoModules(); | const userInfoPinia = userInfoModules(); | ||||
const route = useRoute(); | const route = useRoute(); | ||||
const router = useRouter(); | const router = useRouter(); | ||||
/** | |||||
* 获取页面标题 | |||||
*/ | |||||
const title = ref(<string>route.query.p || '慧影') | |||||
if (title) { | |||||
localStorage.setItem("title", title.value) | |||||
document.title = 'Metavatar-' + title.value | |||||
} | |||||
/** | /** | ||||
* 按钮loading | * 按钮loading | ||||
*/ | */ | ||||
@@ -0,0 +1,207 @@ | |||||
<template> | |||||
<div class="page justify-around"> | |||||
<el-alert :title="`${$t('coindeduc.currencyValue')}:${currentValue}`" type="success" :closable="false" /> | |||||
<el-table :data="tableData" style="width: 100%; height: 90%" size="large" align="center" border> | |||||
<el-table-column | |||||
prop="title" | |||||
:label="$t('coindeduc.titleList')" | |||||
align="center" | |||||
/> | |||||
<el-table-column | |||||
prop="videoPlayUrl" | |||||
:label="$t('coindeduc.videoPlayUrl')" | |||||
align="center" | |||||
/> | |||||
<el-table-column | |||||
prop="videoTime" | |||||
:label="$t('coindeduc.videoTime')" | |||||
align="center" | |||||
/> | |||||
<el-table-column | |||||
prop="costPoints" | |||||
:label="$t('coindeduc.costPoints')" | |||||
align="center" | |||||
/> | |||||
<el-table-column | |||||
prop="createTime" | |||||
:label="$t('coindeduc.createTime')" | |||||
align="center" | |||||
> | |||||
<template #default="scope"> | |||||
{{ getDate(scope.row.createDate) }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column | |||||
fixed="right" | |||||
:label="$t('coindeduc.operate')" | |||||
align="center" | |||||
> | |||||
<template #default="scope"> | |||||
<el-button link type="primary" size="small" @click="detailView(scope.row)">{{ $t('coindeduc.view') }}</el-button> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<div class="pagination"> | |||||
<el-pagination | |||||
v-model:current-page="pageNum" | |||||
v-model:page-size="pageSize" | |||||
:page-sizes="[10, 50, 100]" | |||||
:small="false" | |||||
:disabled="false" | |||||
:background="true" | |||||
layout="total, sizes, prev, pager, next, jumper" | |||||
:total="total" | |||||
@size-change="handleSizeChange" | |||||
@current-change="handleCurrentChange" | |||||
/> | |||||
</div> | |||||
<el-dialog v-model="dialogVisible" :title="`${$t('coindeduc.detailTitle')}:`" width="40%" :before-close="handleClose" > | |||||
<el-form :model="form" label-width="120px"> | |||||
<el-form-item label="名称"> | |||||
<el-input v-model="form.title" /> | |||||
</el-form-item> | |||||
<el-form-item label="视频类型"> | |||||
<el-radio-group v-model="form.videoType"> | |||||
<el-radio :label="1">竖版</el-radio> | |||||
<el-radio :label="2">横版</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item label="文案"> | |||||
<el-input v-model="form.paperwork" type="textarea" /> | |||||
</el-form-item> | |||||
<el-form-item label="封面图"> | |||||
<img :src="form.coverImg" alt="" :style="{ width: form.videoType === 1 ? '50%' : '100%'}"> | |||||
</el-form-item> | |||||
<el-form-item label="视频地址"> | |||||
<el-input v-model="form.videoPlayUrl" /> | |||||
<!-- <video :src="form.videoPlayUrl" style="width:100%;max-height: 300px;"></video> --> | |||||
</el-form-item> | |||||
<el-form-item label="视频时长"> | |||||
<el-input v-model="form.videoTime" /> | |||||
</el-form-item> | |||||
<el-form-item label="创建时间"> | |||||
<el-input v-model="form.createDate" /> | |||||
</el-form-item> | |||||
<el-form-item label="消耗金币"> | |||||
<el-input v-model="form.costPoints" /> | |||||
</el-form-item> | |||||
<el-form-item label="消耗金币明细"> | |||||
<el-input v-model="form.costPointsDetail" /> | |||||
</el-form-item> | |||||
<el-form-item> | |||||
<el-button @click="dialogVisible = false">关闭</el-button> | |||||
</el-form-item> | |||||
</el-form> | |||||
</el-dialog> | |||||
</div> | |||||
</template> | |||||
<!-- videoType==1为竖,==2为横 --> | |||||
<script setup> | |||||
//#region 导入 | |||||
import { coindedApi, getDetailApi, getUserPoinsApi, findByIdApi } from '@/apis/my.js' | |||||
import dayjs from "dayjs"; | |||||
import { useI18n } from "vue-i18n"; | |||||
const { locale } = useI18n(); | |||||
const lanChange = ref(locale); | |||||
const tableData = ref([]); | |||||
const pageNum = ref(1); | |||||
const pageSize = ref(10); | |||||
const total = ref(0); | |||||
const getDate = (val) => { | |||||
return dayjs(val).format("YYYY-MM-DD HH:mm:ss"); | |||||
}; | |||||
const handleSizeChange = (val) => { | |||||
pageSize.value = val; | |||||
getListData(pageNum.value, pageSize.value); | |||||
}; | |||||
const handleCurrentChange = (val) => { | |||||
pageNum.value = val; | |||||
getListData(pageNum.value, pageSize.value); | |||||
}; | |||||
const getListData = async (PageNum, PageSize) => { | |||||
try { | |||||
let data = { | |||||
projectType: 2, | |||||
pageNum: 1, | |||||
pageSize: 10 | |||||
} | |||||
const res = await coindedApi(data); | |||||
tableData.value = res.data.list; | |||||
total.value = res.data.total * 1; | |||||
} catch (error) { | |||||
console.log(error, "err"); | |||||
} | |||||
}; | |||||
// 当前币值 | |||||
const currentValue = ref('') | |||||
function currentValFn() { | |||||
getUserPoinsApi().then(res => { | |||||
currentValue.value = res.data | |||||
}) | |||||
} | |||||
// 查看详情 | |||||
const dialogVisible = ref(false) | |||||
const form = ref({ | |||||
title: '', | |||||
videoPlayUrl: '' | |||||
}) | |||||
function detailView(item) { | |||||
findByIdApi(item.id).then(res => { | |||||
res.data.createDate = getDate(res.data.createDate) | |||||
res.data.videoTime = res.data.videoTime + (lanChange.value == "zh-cn" ? '(秒)' : '(S)') | |||||
form.value = res.data | |||||
dialogVisible.value = true | |||||
}) | |||||
} | |||||
onMounted(() => { | |||||
getListData(1, 10); | |||||
currentValFn() | |||||
}); | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.page { | |||||
height: calc(100vh - 80px); | |||||
// height: calc(100vh - 80px); | |||||
background-color: #ffffff; | |||||
border-radius: 30px 0 0 0; | |||||
overflow: hidden; | |||||
padding: 10vh; | |||||
.addbtn { | |||||
margin-bottom: 2vh; | |||||
} | |||||
.formData { | |||||
padding: 5vh 3vh; | |||||
} | |||||
.pagination { | |||||
position: fixed; | |||||
left: 55%; | |||||
bottom: 8vh; | |||||
transform: translateX(-50%); | |||||
border-radius: 5px; | |||||
padding: 10px 20px; | |||||
z-index: 99; | |||||
transition: all 0.3s; | |||||
cursor: pointer; | |||||
&:hover { | |||||
background-color: #b8b8b873; | |||||
} | |||||
} | |||||
} | |||||
</style> |
@@ -0,0 +1,193 @@ | |||||
<template> | |||||
<div class="page justify-around"> | |||||
<el-alert :title="`${$t('recharge.currencyValue')}:${currentValue}`" type="success" :closable="false" /> | |||||
<el-table :data="tableData" style="width: 100%; height: 90%" size="large" align="center" border> | |||||
<el-table-column | |||||
prop="productTitle" | |||||
:label="$t('recharge.productTitle')" | |||||
align="center" | |||||
/> | |||||
<el-table-column | |||||
prop="orderNumber" | |||||
:label="$t('recharge.orderNumber')" | |||||
align="center" | |||||
/> | |||||
<el-table-column | |||||
prop="paymentStr" | |||||
:label="$t('recharge.payment')" | |||||
align="center" | |||||
/> | |||||
<el-table-column | |||||
prop="createTime" | |||||
:label="$t('recharge.createTime')" | |||||
align="center" | |||||
> | |||||
<template #default="scope"> | |||||
{{ getDate(scope.row.createTime) }} | |||||
</template> | |||||
</el-table-column> | |||||
<el-table-column | |||||
fixed="right" | |||||
:label="$t('recharge.operate')" | |||||
align="center" | |||||
> | |||||
<template #default="scope"> | |||||
<el-button link type="primary" size="small" @click="detailView(scope.row)">{{ $t('recharge.view') }}</el-button> | |||||
</template> | |||||
</el-table-column> | |||||
</el-table> | |||||
<div class="pagination"> | |||||
<el-pagination | |||||
v-model:current-page="pageNum" | |||||
v-model:page-size="pageSize" | |||||
:page-sizes="[10, 50, 100]" | |||||
:small="false" | |||||
:disabled="false" | |||||
:background="true" | |||||
layout="total, sizes, prev, pager, next, jumper" | |||||
:total="total" | |||||
@size-change="handleSizeChange" | |||||
@current-change="handleCurrentChange" | |||||
/> | |||||
</div> | |||||
<el-dialog v-model="dialogVisible" :title="`${ $t('recharge.detailTitle')}:`" width="40%" > | |||||
<el-form :model="form" label-width="120px"> | |||||
<el-form-item :label="$t('recharge.productTitle')"> | |||||
<el-input v-model="form.productTitle" /> | |||||
</el-form-item> | |||||
<el-form-item :label="$t('recharge.orderNumber')"> | |||||
<el-input v-model="form.orderNumber" /> | |||||
</el-form-item> | |||||
<el-form-item :label="$t('recharge.payVendor')"> | |||||
<el-radio-group v-model="form.payVendor"> | |||||
<el-radio :label="2">{{ $t('recharge.weChat') }}</el-radio> | |||||
<el-radio :label="4">{{$t('recharge.alipay')}}</el-radio> | |||||
</el-radio-group> | |||||
</el-form-item> | |||||
<el-form-item :label="$t('recharge.paymentStr')"> | |||||
<el-input v-model="form.paymentStr" /> | |||||
</el-form-item> | |||||
<el-form-item :label="$t('recharge.orderStatus')"> | |||||
<el-input v-model="form.orderStatus" /> | |||||
</el-form-item> | |||||
<el-form-item :label="$t('recharge.paymentTime')"> | |||||
<el-input v-model="form.paymentTime" /> | |||||
</el-form-item> | |||||
<el-form-item> | |||||
<el-button @click="dialogVisible = false">{{ $t('recharge.close') }}</el-button> | |||||
</el-form-item> | |||||
</el-form> | |||||
</el-dialog> | |||||
</div> | |||||
</template> | |||||
<!-- videoType==1为竖,==2为横 --> | |||||
<script setup> | |||||
//#region 导入 | |||||
import { rechargeListApi, getDetailApi, getUserPoinsApi, findByNumberApi } from '@/apis/my.js' | |||||
import dayjs from "dayjs"; | |||||
import { useI18n } from "vue-i18n"; | |||||
const { locale } = useI18n(); | |||||
const lanChange = ref(locale); | |||||
const tableData = ref([]); | |||||
const pageNum = ref(1); | |||||
const pageSize = ref(10); | |||||
const total = ref(0); | |||||
const getDate = (val) => { | |||||
return dayjs(val).format("YYYY-MM-DD HH:mm:ss"); | |||||
}; | |||||
const handleSizeChange = (val) => { | |||||
pageSize.value = val; | |||||
getListData(pageNum.value, pageSize.value); | |||||
}; | |||||
const handleCurrentChange = (val) => { | |||||
pageNum.value = val; | |||||
getListData(pageNum.value, pageSize.value); | |||||
}; | |||||
const getListData = async (PageNum, PageSize) => { | |||||
try { | |||||
let data = { | |||||
projectType: 2, | |||||
pageNum: 1, | |||||
pageSize: 10 | |||||
} | |||||
const res = await rechargeListApi(data); | |||||
tableData.value = res.data.list; | |||||
total.value = res.data.total * 1; | |||||
} catch (error) { | |||||
console.log(error, "err"); | |||||
} | |||||
}; | |||||
// 当前币值 | |||||
const currentValue = ref('') | |||||
function currentValFn() { | |||||
getUserPoinsApi().then(res => { | |||||
currentValue.value = res.data | |||||
}) | |||||
} | |||||
// 查看详情 | |||||
const dialogVisible = ref(false) | |||||
const form = ref({ | |||||
productTitle: '', | |||||
orderStatus:'', | |||||
paymentTime: '', | |||||
}) | |||||
function detailView(item) { | |||||
findByNumberApi(item.id).then(res => { | |||||
res.data.paymentTime = getDate(res.data.paymentTime) | |||||
res.data.orderStatus = res.data.orderStatus === 3 ? lanChange.value == "zh-cn" ? '支付成功' : 'Payment successful': lanChange.value == "zh-cn" ? '支付失败' : 'Payment failed' | |||||
form.value = res.data | |||||
dialogVisible.value = true | |||||
}) | |||||
} | |||||
onMounted(() => { | |||||
getListData(1, 10); | |||||
currentValFn() | |||||
}); | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.page { | |||||
height: calc(100vh - 80px); | |||||
// height: calc(100vh - 80px); | |||||
background-color: #ffffff; | |||||
border-radius: 30px 0 0 0; | |||||
overflow: hidden; | |||||
padding: 10vh; | |||||
.addbtn { | |||||
margin-bottom: 2vh; | |||||
} | |||||
.formData { | |||||
padding: 5vh 3vh; | |||||
} | |||||
.pagination { | |||||
position: fixed; | |||||
left: 55%; | |||||
bottom: 8vh; | |||||
transform: translateX(-50%); | |||||
border-radius: 5px; | |||||
padding: 10px 20px; | |||||
z-index: 99; | |||||
transition: all 0.3s; | |||||
cursor: pointer; | |||||
&:hover { | |||||
background-color: #b8b8b873; | |||||
} | |||||
} | |||||
} | |||||
</style> |
@@ -1,22 +0,0 @@ | |||||
<template> | |||||
<div class="page"> | |||||
<div class="title">{{ $t("API.comingSoon") }}</div> | |||||
</div> | |||||
</template> | |||||
<script setup> | |||||
// import { ref } from 'vue' | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.page { | |||||
padding: 30px; | |||||
width: 100%; | |||||
overflow: hidden; | |||||
overflow-y: scroll; | |||||
background-color: #fff; | |||||
min-height: calc(100vh - 80px); | |||||
text-align: center; | |||||
.title { | |||||
font-size: 50px; | |||||
} | |||||
} | |||||
</style> |
@@ -481,6 +481,7 @@ const checkVideoStatus = async () => { | |||||
// 如果列表中没有生成中的视频,不发送请求 | // 如果列表中没有生成中的视频,不发送请求 | ||||
const intervalId = setInterval(async () => { | const intervalId = setInterval(async () => { | ||||
// && notGenerateList2.value.length == 0; | // && notGenerateList2.value.length == 0; | ||||
console.log(""); | |||||
if (notGenerateList.value.length == 0) { | if (notGenerateList.value.length == 0) { | ||||
return; | return; | ||||
} | } | ||||
@@ -509,7 +510,7 @@ onMounted(() => { | |||||
isLoading.value = true; | isLoading.value = true; | ||||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | getPhotoVideoList(pageNum.value, pageSize.value, title.value); | ||||
// checkVideoStatus(); | |||||
checkVideoStatus(); | |||||
}); | }); | ||||
//#endregion --------------------------- | //#endregion --------------------------- | ||||
</script> | </script> | ||||
@@ -1,141 +1,48 @@ | |||||
<template> | <template> | ||||
<div class="page"> | <div class="page"> | ||||
<div class="commoditylIst" ref="scrollContainerRef" @wheel="handleWheel"> | |||||
<div class="item" v-for="item in packageList" :key="item.typeDesc"> | |||||
<!-- 遮罩层 --> | |||||
<div class="mask" v-if="item.type != 1"> | |||||
<el-icon><i-ep-Lock /></el-icon> | |||||
</div> | |||||
<div @click="clickPayDialog(item)" v-if="item.typeDesc"> | |||||
<div class="line" :style="`background-color:${item.color} ;`"></div> | |||||
<div class="info"> | |||||
<!-- 商品信息 --> | |||||
<div class="content"> | |||||
<div class="titleBox"> | |||||
<div class="title"> | |||||
{{ lanChange == "zh-cn" ? item.typeDesc : item.englishName }} | |||||
<div class="commoditylIst"> | |||||
<el-scrollbar :always="true"> | |||||
<div class="scrollbar-flex-content"> | |||||
<div class="item" v-for="item in packageList" :key="item.typeDesc" :class="item.sellPriceRmb <= 0 ? 'dashed' : ''"> | |||||
<!-- @click="clickPayDialog(item)" --> | |||||
<div> | |||||
<div class="line" :style="`background-color:${ item.sellPriceRmb > 0 ? item.color : '#eee'} ;`"></div> | |||||
<div class="info"> | |||||
<!-- 商品信息 --> | |||||
<div class="content"> | |||||
<div class="titleBox"> | |||||
<!-- <p class="iconText" v-if="item.sellPriceRmb <= 0" >会员权益</p> --> | |||||
<div class="title"> | |||||
{{ item.title }} | |||||
</div> | |||||
</div> | </div> | ||||
<template v-if="item.sellPriceRmb > 0"> | |||||
<div class="money"> | |||||
<span class="price">{{ | |||||
item.sellPriceRmb / 100 | |||||
}} ¥</span | |||||
>/ <span style="text-decoration:line-through;"> {{ $t("store.priceRmb") }}{{ item.priceRmb / 100 }}</span> | |||||
</div> | |||||
<div class="time"> | |||||
{{ $t("store.glod") }}<span> {{ item.glod }}</span | |||||
> | |||||
</div> | |||||
<div v-if="item.sellPriceRmb > 0" class="button" @click="clickPayDialog(item)" :style="`background-color: #f3af00 ;`"> | |||||
{{ $t("store.createOrder") }} | |||||
</div> | |||||
</template> | |||||
</div> | </div> | ||||
<div class="money"> | |||||
<span class="price">{{ | |||||
lanChange == "zh-cn" ? item.rmb + "¥" : item.dollar + "$" | |||||
}}</span | |||||
>/{{ item.validityDuration }}{{ $t("shop.day") }} | |||||
</div> | |||||
<div class="time"> | |||||
<span>{{ item.credit }}</span | |||||
>{{ $t("shop.score") }} | |||||
</div> | |||||
<div | |||||
v-if="item.type != 1" | |||||
class="button" | |||||
:style="`background-color:${item.color} ;`" | |||||
> | |||||
{{ $t("createVideo.comingSoon") }} | |||||
</div> | |||||
<div | |||||
v-else | |||||
class="button" | |||||
:style="`background-color:${item.color} ;`" | |||||
> | |||||
{{ $t("shop.selectPlan") }} | |||||
</div> | |||||
</div> | |||||
<!-- 商品权益 --> | |||||
<div class="authority"> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.InviteGetscore") }}: | |||||
<span> | |||||
<i>{{ item.inviteUserCredit }}</i | |||||
>{{ $t("shop.score") }}</span | |||||
> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.createVideoPrice") }}:<span | |||||
><i>{{ item.videoPrice }}</i | |||||
>{{ $t("shop.score") }}</span | |||||
> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.AIGeneratesPhotoPrices") }}:<span | |||||
><i>{{ item.photoPrice }}</i | |||||
>{{ $t("shop.score") }}</span | |||||
> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.UnitChargeDuration") }}:<span | |||||
><i>{{ item.chargeTime }}</i | |||||
>{{ $t("shop.second") }}</span | |||||
> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.Language") }}:<span | |||||
><i>{{ item.userPackageDetails[0].languageDesc }}</i></span | |||||
> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.sound") }}:<span | |||||
><i>{{ item.userPackageDetails[0].soundDesc }}</i></span | |||||
> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.IndividualVideoDuration") }}:<span | |||||
><i>{{ item.userPackageDetails[0].videoTime }}</i | |||||
>{{ $t("shop.second") }}</span | |||||
> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.Watermark") }}:<span>{{ | |||||
item.userPackageDetails[0].aiPortrait == 0 | |||||
? $t("shop.yes") | |||||
: $t("shop.no") | |||||
}}</span> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.AIGeneratedPortrait") }}:<span>{{ | |||||
item.userPackageDetails[0].aiPortrait == 0 | |||||
? $t("shop.no") | |||||
: $t("shop.yes") | |||||
}}</span> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.PhotoSinging") }}:<span>{{ | |||||
item.userPackageDetails[0].photoSing == 0 | |||||
? $t("shop.no") | |||||
: $t("shop.yes") | |||||
}}</span> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.AIGeneratedText") }}:<span | |||||
><i>{{ item.userPackageDetails[0].aiCreateTime }}</i></span | |||||
> | |||||
</div> | |||||
<div class="authority-item"> | |||||
{{ $t("shop.VideoResolution") }}:<span>{{ | |||||
item.userPackageDetails[0].resolutionRatioDesc | |||||
}}</span> | |||||
<!-- 商品权益 --> | |||||
<div class="authority"> | |||||
<div v-html="item.detail"></div> | |||||
</div> | </div> | ||||
<!-- <div class="authority-item"> | |||||
{{ $t("shop.DigitalPersonTemplate") }}:{{ | |||||
item.userPackageDetails[0].humanTemplateDesc | |||||
}} | |||||
</div> --> | |||||
<!-- <div | |||||
class="authority-item" | |||||
v-for="items in item.authority" | |||||
:key="items" | |||||
> | |||||
<span>✔</span>{{ items }} | |||||
</div> --> | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</el-scrollbar> | |||||
<!-- 企业版 --> | <!-- 企业版 --> | ||||
<div class="item" @click="showTalkUsDialog = true"> | |||||
<!-- 遮罩层 --> | |||||
<!-- <div class="item" @click="showTalkUsDialog = true"> | |||||
<div class="mask" v-if="false"> | <div class="mask" v-if="false"> | ||||
<el-icon><i-ep-Lock /></el-icon> | <el-icon><i-ep-Lock /></el-icon> | ||||
</div> | </div> | ||||
@@ -147,7 +54,6 @@ | |||||
{{ $t("shop.Ent") }} | {{ $t("shop.Ent") }} | ||||
</div> | </div> | ||||
</div> | </div> | ||||
<!-- 描述 --> | |||||
<div class="description"> | <div class="description"> | ||||
<div> | <div> | ||||
{{ lanChange == "zh-cn" ? "所有权限" : "All Pro Benefits" }} | {{ lanChange == "zh-cn" ? "所有权限" : "All Pro Benefits" }} | ||||
@@ -178,64 +84,68 @@ | |||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | </div> | ||||
</div> | |||||
</div> --> | |||||
</div> | </div> | ||||
<!-- 对话框 --> | |||||
<el-dialog v-if="false" v-model="showPayDialog" width="60%" center> | |||||
<!-- 对话框 v-if="false"--> | |||||
<el-dialog v-model="showPayDialog" v-if="showPayDialog" | |||||
:title="$t('store.payType')" width="300px"> | |||||
<div class="payDialog"> | <div class="payDialog"> | ||||
<div class="left"> | |||||
<div class="title">{{ $t(presentItme.value.title) }}</div> | |||||
<div class="price"> | |||||
<span>{{ presentItme.value.price }}</span> | |||||
元/{{ presentItme.value.priceTime }} | |||||
</div> | |||||
<div | |||||
class="authority" | |||||
v-for="item in presentItme.value.authority" | |||||
:key="item" | |||||
> | |||||
{{ item }} | |||||
</div> | |||||
</div> | |||||
<div class="right"> | |||||
<div | |||||
style="background-color: #07c160; cursor: pointer" | |||||
@click="showOrderCode(1)" | |||||
> | |||||
{{ $t("shop.WeChatPay") }} | |||||
</div> | |||||
<div | |||||
style="background-color: #1378fe; cursor: pointer" | |||||
@click="showOrderCode(2)" | |||||
> | |||||
{{ $t("shop.Alipay") }} | |||||
</div> | |||||
<div | |||||
style="background-color: #0070ba; cursor: pointer" | |||||
@click="showOrderCode(3)" | |||||
> | |||||
Paypal | |||||
</div> | |||||
</div> | |||||
<el-radio-group v-model="payVendor"> | |||||
<el-radio label="4" border> | |||||
<img src="../../assets/img/alipay.png" alt="" />{{ $t("recharge.alipay") }} | |||||
</el-radio> | |||||
<el-radio label="2" border> | |||||
<img src="../../assets/img/weChat.png" alt="" />{{ $t("recharge.weChat") }} | |||||
</el-radio> | |||||
</el-radio-group> | |||||
</div> | </div> | ||||
<!-- 二维码弹出框 --> | <!-- 二维码弹出框 --> | ||||
<el-dialog | <el-dialog | ||||
v-model="orderCodeDialogShow" | v-model="orderCodeDialogShow" | ||||
width="30%" | |||||
width="500px" | |||||
append-to-body | append-to-body | ||||
destroy-on-close | destroy-on-close | ||||
@closed="clearCode" | |||||
:close-on-click-modal="false" | |||||
> | > | ||||
<div class="orderCodeDialog"> | |||||
<div class="orderCodeDialog" v-loading="loading" | |||||
:element-loading-text="`${$t('store.pay')}`"> | |||||
<div class="codeImg"> | <div class="codeImg"> | ||||
<my-Loading-Icon v-if="!orderCodeUrl"></my-Loading-Icon> | |||||
<img v-if="orderCodeUrl" src="../../assets/img/false1.png" alt="" /> | |||||
<my-Loading-Icon2 | |||||
v-if="!payCodeUrl && !iframeBody" | |||||
></my-Loading-Icon2> | |||||
<!-- :callback="qrcode" --> | |||||
<vue-qr v-if="payCodeUrl" :text="payCodeUrl" :size="280"></vue-qr> | |||||
<iframe | |||||
v-show="iframeBody" | |||||
id="myIframe" | |||||
width="210PX" | |||||
height="205PX" | |||||
frameborder="0" | |||||
></iframe> | |||||
</div> | </div> | ||||
<div class="tips">扫描二维码进行付款</div> | |||||
<div class="btnBox"> | |||||
<div>刷新二维码</div> | |||||
<div class="tips"> | |||||
{{ | |||||
lanChange == "zh-cn" | |||||
? `扫描二维码进行付款` | |||||
: `Scan the QR code for payment` | |||||
}} | |||||
</div> | </div> | ||||
<!-- <div class="btnBox"> | |||||
<div @click="RefreshQR"> | |||||
{{ lanChange == "zh-cn" ? `刷新二维码` : `Refresh QR code` }} | |||||
</div> | |||||
</div> --> | |||||
</div> | </div> | ||||
</el-dialog> | </el-dialog> | ||||
<template #footer> | |||||
<span class="dialog-footer"> | |||||
<el-button size="small" @click="showPayDialog = false">{{ $t("store.cancel") }}</el-button> | |||||
<el-button size="small" type="primary" @click="payConfirm"> | |||||
{{$t("store.confirm")}} | |||||
</el-button> | |||||
</span> | |||||
</template> | |||||
</el-dialog> | </el-dialog> | ||||
<!-- 联系我们对话框 --> | <!-- 联系我们对话框 --> | ||||
@@ -249,10 +159,14 @@ | |||||
<script setup> | <script setup> | ||||
//#region 导入 | //#region 导入 | ||||
import { getCurrentInstance, ref, onMounted } from "vue"; | import { getCurrentInstance, ref, onMounted } from "vue"; | ||||
// import { packageInfoApi } from "@/apis/myStore"; | |||||
import { packageInfoApi } from "@/apis/myStore"; | |||||
import { useI18n } from "vue-i18n"; | import { useI18n } from "vue-i18n"; | ||||
import talkUs from "@/components/talkUs.vue"; | import talkUs from "@/components/talkUs.vue"; | ||||
import { useRoute, useRouter } from "vue-router"; | import { useRoute, useRouter } from "vue-router"; | ||||
import { createOrderApi, createPayApi, getOrderStatusApi } from "@/apis/pay"; | |||||
import { orderDetailApi, findStatusApi } from '@/apis/myStore.js' | |||||
import vueQr from 'vue-qr/src/packages/vue-qr.vue'; | |||||
const route = useRoute(); | const route = useRoute(); | ||||
const router = useRouter(); | const router = useRouter(); | ||||
const { locale } = useI18n(); | const { locale } = useI18n(); | ||||
@@ -261,236 +175,33 @@ const lanChange = ref(locale); | |||||
const AccessToken = localStorage.getItem("AccessToken"); // 判断有没有登录 | const AccessToken = localStorage.getItem("AccessToken"); // 判断有没有登录 | ||||
//#endregion ------------------------------------ | //#endregion ------------------------------------ | ||||
//#region 各个套餐的逻辑 | |||||
const packageList = ref([ | |||||
{ | |||||
id: 1, | |||||
type: 1, | |||||
typeDesc: "基础版", | |||||
englishName: "Trial", | |||||
dollar: "0.00", | |||||
rmb: "0.00", | |||||
credit: 100, | |||||
validityDuration: 30, | |||||
inviteUserCredit: 10, | |||||
videoPrice: 10, | |||||
photoPrice: 10, | |||||
talkPrice: 20, | |||||
chargeTime: 60, | |||||
createDate: 1686814258000, | |||||
updateDate: 1686814258000, | |||||
isDel: 0, | |||||
color: "#f3af00", | |||||
userPackageDetails: [ | |||||
{ | |||||
id: 1, | |||||
detailType: 1, | |||||
detailTypeDesc: "照片说话", | |||||
packageId: 1, | |||||
watermark: 1, | |||||
watermarkDesc: "是", | |||||
language: 1, | |||||
languageDesc: "50+", | |||||
sound: 1, | |||||
soundDesc: "400+", | |||||
videoTime: 60, | |||||
aiPortrait: 0, | |||||
aiPortraitDesc: "否", | |||||
photoSing: 0, | |||||
photoSingDesc: "否", | |||||
aiCreateTime: 0, | |||||
resolutionRatio: 1, | |||||
resolutionRatioDesc: "720p", | |||||
createDate: 1686882177000, | |||||
updateDate: 1686882177000, | |||||
isDel: 0, | |||||
}, | |||||
{ | |||||
id: 4, | |||||
detailType: 2, | |||||
detailTypeDesc: "口播", | |||||
packageId: 1, | |||||
watermark: 1, | |||||
watermarkDesc: "是", | |||||
language: 1, | |||||
languageDesc: "50+", | |||||
sound: 1, | |||||
soundDesc: "400+", | |||||
videoTime: 60, | |||||
aiCreateTime: 0, | |||||
resolutionRatio: 1, | |||||
resolutionRatioDesc: "720p", | |||||
humanTemplate: 1, | |||||
humanTemplateDesc: "免费", | |||||
createDate: 1686882177000, | |||||
updateDate: 1686882177000, | |||||
isDel: 0, | |||||
}, | |||||
], | |||||
}, | |||||
{ | |||||
id: 2, | |||||
type: 2, | |||||
typeDesc: "专业版", | |||||
englishName: "Pro", | |||||
dollar: "7.99", | |||||
rmb: "49.99", | |||||
credit: 200, | |||||
validityDuration: 30, | |||||
inviteUserCredit: 10, | |||||
videoPrice: 6, | |||||
photoPrice: 6, | |||||
talkPrice: 16, | |||||
chargeTime: 60, | |||||
createDate: 1686814258000, | |||||
updateDate: 1686814258000, | |||||
isDel: 0, | |||||
color: "#c971ff", | |||||
userPackageDetails: [ | |||||
{ | |||||
id: 2, | |||||
detailType: 1, | |||||
detailTypeDesc: "照片说话", | |||||
packageId: 2, | |||||
watermark: 0, | |||||
watermarkDesc: "否", | |||||
language: 1, | |||||
languageDesc: "50+", | |||||
sound: 1, | |||||
soundDesc: "400+", | |||||
videoTime: 300, | |||||
aiPortrait: 1, | |||||
aiPortraitDesc: "是", | |||||
photoSing: 1, | |||||
photoSingDesc: "是", | |||||
aiCreateTime: 30, | |||||
resolutionRatio: 2, | |||||
resolutionRatioDesc: "1080p", | |||||
createDate: 1686882177000, | |||||
updateDate: 1686882177000, | |||||
isDel: 0, | |||||
}, | |||||
{ | |||||
id: 5, | |||||
detailType: 2, | |||||
detailTypeDesc: "口播", | |||||
packageId: 2, | |||||
watermark: 0, | |||||
watermarkDesc: "否", | |||||
language: 1, | |||||
languageDesc: "50+", | |||||
sound: 1, | |||||
soundDesc: "400+", | |||||
videoTime: 300, | |||||
aiCreateTime: 100, | |||||
resolutionRatio: 2, | |||||
resolutionRatioDesc: "1080p", | |||||
humanTemplate: 2, | |||||
humanTemplateDesc: "VIP", | |||||
createDate: 1686882177000, | |||||
updateDate: 1686882177000, | |||||
isDel: 0, | |||||
}, | |||||
], | |||||
}, | |||||
{ | |||||
id: 3, | |||||
type: 3, | |||||
typeDesc: "加强版", | |||||
englishName: "Advanced", | |||||
dollar: "39.99", | |||||
rmb: "279.99", | |||||
credit: 1200, | |||||
validityDuration: 30, | |||||
inviteUserCredit: 10, | |||||
videoPrice: 5, | |||||
photoPrice: 5, | |||||
talkPrice: 15, | |||||
chargeTime: 60, | |||||
createDate: 1686814258000, | |||||
updateDate: 1686814258000, | |||||
isDel: 0, | |||||
color: "#7b61ff", | |||||
userPackageDetails: [ | |||||
{ | |||||
id: 3, | |||||
detailType: 1, | |||||
detailTypeDesc: "照片说话", | |||||
packageId: 3, | |||||
watermark: 0, | |||||
watermarkDesc: "否", | |||||
language: 1, | |||||
languageDesc: "50+", | |||||
sound: 1, | |||||
soundDesc: "400+", | |||||
videoTime: 300, | |||||
aiPortrait: 1, | |||||
aiPortraitDesc: "是", | |||||
photoSing: 1, | |||||
photoSingDesc: "是", | |||||
aiCreateTime: 200, | |||||
resolutionRatio: 2, | |||||
resolutionRatioDesc: "1080p", | |||||
createDate: 1686882177000, | |||||
updateDate: 1686882177000, | |||||
isDel: 0, | |||||
}, | |||||
{ | |||||
id: 6, | |||||
detailType: 2, | |||||
detailTypeDesc: "口播", | |||||
packageId: 3, | |||||
watermark: 0, | |||||
watermarkDesc: "否", | |||||
language: 1, | |||||
languageDesc: "50+", | |||||
sound: 1, | |||||
soundDesc: "400+", | |||||
videoTime: 300, | |||||
aiCreateTime: 200, | |||||
resolutionRatio: 2, | |||||
resolutionRatioDesc: "1080p", | |||||
humanTemplate: 2, | |||||
humanTemplateDesc: "VIP", | |||||
createDate: 1686882177000, | |||||
updateDate: 1686882177000, | |||||
isDel: 0, | |||||
}, | |||||
], | |||||
}, | |||||
]); | |||||
const packageList = ref([]); | |||||
async function getPackageList() { | async function getPackageList() { | ||||
const res = await packageInfoApi(); | const res = await packageInfoApi(); | ||||
packageList.value = res.data; | packageList.value = res.data; | ||||
} | } | ||||
const showPayDialog = ref(false); //套餐信息dialog显示隐藏 | const showPayDialog = ref(false); //套餐信息dialog显示隐藏 | ||||
const presentItme = reactive({}); //点击的套餐项 | const presentItme = reactive({}); //点击的套餐项 | ||||
// const presentItme = ref({}); //点击的套餐项 | |||||
function clickPayDialog(item) { | function clickPayDialog(item) { | ||||
presentItme.value = item; | presentItme.value = item; | ||||
createOrder(item) | |||||
showPayDialog.value = true; | showPayDialog.value = true; | ||||
} | } | ||||
function showOrderCode(type) { | |||||
orderCodeDialogShow.value = true; | |||||
} | |||||
//#endregion ------------------------------------ | //#endregion ------------------------------------ | ||||
//#region 点击套餐内的支付 | //#region 点击套餐内的支付 | ||||
function showOrderCode(type) { | |||||
orderCodeDialogShow.value = true; | |||||
myPayVendor.value = type; | |||||
createOrderFunc(); | |||||
} | |||||
const orderCodeDialogShow = ref(false); | const orderCodeDialogShow = ref(false); | ||||
const orderCodeUrl = ref(null); | const orderCodeUrl = ref(null); | ||||
//#endregion ------------------------------------ | //#endregion ------------------------------------ | ||||
//#region $t在script中的使用 | |||||
// const { | |||||
// appContext: { | |||||
// config: { globalProperties }, | |||||
// }, | |||||
// } = getCurrentInstance(); | |||||
// const string = "createVideo.typeScript"; | |||||
// const t = globalProperties.$t(string); | |||||
//#endregion ------------------------------------ | |||||
//#region 页面滚动 | //#region 页面滚动 | ||||
const scrollContainerRef = ref(null); | const scrollContainerRef = ref(null); | ||||
function handleWheel(event) { | function handleWheel(event) { | ||||
@@ -517,20 +228,191 @@ const updateShowTalkUsDialog = (newValue) => { | |||||
//#region 页面初始化 | //#region 页面初始化 | ||||
onMounted(async () => { | onMounted(async () => { | ||||
// getPackageList(); | |||||
getPackageList(); | |||||
// createOrderFunc(); | |||||
}); | }); | ||||
//#endregion ------------------------------------ | //#endregion ------------------------------------ | ||||
//#region | |||||
//#region 支付 | |||||
const myPayVendor = ref(null); // 2微信 4支付宝 | |||||
const payCodeUrl = ref(null); //付款二维码地址 | |||||
const payCodeImg = ref(null); //付款二维码图片 | |||||
// 支付失败处理 | |||||
function payErrorHandle() { | |||||
orderCodeDialogShow.value = false; | |||||
ElMessage.error( | |||||
lanChange.value == "zh-cn" | |||||
? `获取订单失败,请重试` | |||||
: `Failed to get the order, please try again` | |||||
); | |||||
} | |||||
// 获取订单 | |||||
const myOrderNumber = ref(null); //订单号 | |||||
async function createOrderFunc() { | |||||
const data = { | |||||
productId: 30, | |||||
}; | |||||
try { | |||||
const res = await createOrderApi(data); | |||||
if (res.code == 200) { | |||||
myOrderNumber.value = res.data; | |||||
createPayFunc(res.data); | |||||
} else { | |||||
payErrorHandle(); | |||||
} | |||||
} catch (error) { | |||||
payErrorHandle(); | |||||
} | |||||
} | |||||
// 获取订单详情 | |||||
let iframeBody = ref(null); | |||||
const iframeDom = ref(null); | |||||
const loading = ref(false) | |||||
async function createPayFunc(orderNumber) { | |||||
const data = { | |||||
orderNumber, | |||||
payVendor: payVendor.value, | |||||
}; | |||||
try { | |||||
const res = await createPayApi(data); | |||||
if (res.code == 200) { | |||||
// 支付宝获取iframe内容 | |||||
if (res.data.body) { | |||||
orderCodeDialogShow.value = true; | |||||
setTimeout(() => { | |||||
iframeBody.value = res.data.body; | |||||
iframeDom.value = document.getElementById("myIframe"); | |||||
iframeDom.value.srcdoc = iframeBody.value; | |||||
}, 1000) | |||||
} | |||||
// 直接获取二维码 | |||||
if (res.data.codeUrl) { | |||||
payCodeUrl.value = res.data.codeUrl; | |||||
// showOrderCode(payVendor.value) | |||||
orderCodeDialogShow.value = true; | |||||
} | |||||
// findStatus() | |||||
await getStatusOfOrderFunc(orderNumber); | |||||
} else { | |||||
payErrorHandle(); | |||||
} | |||||
} catch (error) { | |||||
payErrorHandle(); | |||||
} | |||||
} | |||||
// 获取订单支付状态 payStatus 查询支付状态 0:待支付,2:支付中,3:已支付 | |||||
async function getStatusOfOrderFunc(orderNumber) { | |||||
// if ( | |||||
// route.path != "/myStore" || | |||||
// orderCodeDialogShow.value == false || | |||||
// orderNumber != payVendor.value | |||||
// ) { | |||||
// return; | |||||
// } | |||||
try { | |||||
// let payVendor = payVendor.value; | |||||
let data = { | |||||
orderNumber, | |||||
payVendor: payVendor.value | |||||
} | |||||
const res = await findStatusApi(data); | |||||
if (res.code == 200) { | |||||
if (res.data.orderStatus == 1) { // 页面就不动,继续定时请求 | |||||
setTimeout(() => { | |||||
getStatusOfOrderFunc(orderNumber); | |||||
}, 3000); | |||||
} else if (res.data.orderStatus == 2) { // 页面就不动, loading....的效果盖在二维码之前,继续定时请求 | |||||
loading.value = true | |||||
setTimeout(() => { | |||||
getStatusOfOrderFunc(orderNumber); | |||||
}, 3000); | |||||
} else if (res.data.orderStatus == 3) { // 提示支付成功,关闭当前页 | |||||
orderCodeDialogShow.value = false; | |||||
showPayDialog.value = false | |||||
ElMessage.success( | |||||
lanChange.value == "zh-cn" ? `支付成功!` : `Payment is successful!` | |||||
); | |||||
} else { // 提示支付失败,关闭当前页 | |||||
ElMessage.success('支付失败'); | |||||
} | |||||
} else { | |||||
setTimeout(() => { | |||||
getStatusOfOrderFunc(orderNumber); | |||||
}, 3000); | |||||
} | |||||
} catch (error) { | |||||
console.log(error, "error"); | |||||
ElMessage.error( | |||||
lanChange.value == "zh-cn" | |||||
? `获取订单失败,请重试` | |||||
: `Failed to get the order, please try again` | |||||
); | |||||
} | |||||
} | |||||
// 生成二维码 | |||||
// function qrcode() { | |||||
// return; | |||||
// } | |||||
// 关闭二维码弹窗 | |||||
function clearCode() { | |||||
myPayVendor.value = null; // 2微信 4支付宝 | |||||
payCodeUrl.value = null; | |||||
iframeBody.value = null; | |||||
showPayDialog.value = false; | |||||
} | |||||
// 刷新二维码 | |||||
function RefreshQR() { | |||||
payCodeUrl.value = null; | |||||
iframeBody.value = null; | |||||
// createOrderFunc(); | |||||
createPayFunc(myOrderNumber.value); | |||||
} | |||||
//#endregion ------------------------------------ | //#endregion ------------------------------------ | ||||
//#region | //#region | ||||
//#endregion ------------------------------------ | //#endregion ------------------------------------ | ||||
</script> | |||||
const payVendor = ref('4') | |||||
const orderNumber = ref('') | |||||
// 创建订单 | |||||
function createOrder(item) { | |||||
createOrderApi({productId: item.id}).then(res => { | |||||
orderNumber.value = res.data | |||||
}) | |||||
} | |||||
// 创建支付 | |||||
function payConfirm() { | |||||
createPayFunc(orderNumber.value); | |||||
} | |||||
// 获取订单详情 | |||||
function getOrderDetail(item) { | |||||
orderDetailApi(item.id).then(res => { | |||||
}) | |||||
} | |||||
//每隔一分钟运行一次保存方法 | |||||
// const timer = setInterval(()=>{ | |||||
// findStatus() | |||||
// },1000) | |||||
function findStatus() { | |||||
let data = { | |||||
orderNumber: '', | |||||
payVendor: '' | |||||
} | |||||
findStatusApi(data).then(res => { | |||||
if (res.data !== 2) { // 如果是2就不停的调,直到返回1、3、4 | |||||
clearInterval(timer); | |||||
} | |||||
}) | |||||
} | |||||
</script> | |||||
<style> | |||||
.el-dialog { | |||||
border-radius: 5px !important; | |||||
}</style> | |||||
<style lang="scss" scoped> | <style lang="scss" scoped> | ||||
.page { | .page { | ||||
// min-width: calc(100vw - 210px); | // min-width: calc(100vw - 210px); | ||||
height: calc(100vh - 80px); | height: calc(100vh - 80px); | ||||
@@ -552,18 +434,14 @@ onMounted(async () => { | |||||
overflow-x: scroll; | overflow-x: scroll; | ||||
padding: 30px 20px 20px 10px; | padding: 30px 20px 20px 10px; | ||||
max-width: 100%; | max-width: 100%; | ||||
// height: 75%; | |||||
// overflow: hidden; | |||||
// overflow-x: scroll; | |||||
// scrollbar-width: none; /* 隐藏滚动条(Chrome、Firefox) */ | |||||
// -ms-overflow-style: none; /* 隐藏滚动条(IE、Edge) */ | |||||
// &::-webkit-scrollbar { | |||||
// display: none; /* 隐藏滚动条(Safari、Chrome) */ | |||||
// } | |||||
.scrollbar-flex-content{ | |||||
display: flex; | |||||
padding-bottom: 30px; | |||||
} | |||||
.item { | .item { | ||||
position: relative; | position: relative; | ||||
width: 480px; | |||||
width: 450px; | |||||
// height: 680px; | // height: 680px; | ||||
margin-left: 45px; | margin-left: 45px; | ||||
background-color: #fffefd; | background-color: #fffefd; | ||||
@@ -573,6 +451,9 @@ onMounted(async () => { | |||||
overflow: hidden; | overflow: hidden; | ||||
transition: all 0.2s; | transition: all 0.2s; | ||||
cursor: pointer; | cursor: pointer; | ||||
&.dashed { | |||||
border: 1px dashed #c0bfbd; | |||||
} | |||||
&:hover { | &:hover { | ||||
.mask { | .mask { | ||||
display: block; | display: block; | ||||
@@ -606,10 +487,21 @@ onMounted(async () => { | |||||
padding: 20px; | padding: 20px; | ||||
border-bottom: 1px solid #c0bfbd; | border-bottom: 1px solid #c0bfbd; | ||||
cursor: pointer; | cursor: pointer; | ||||
position: relative; | |||||
.titleBox { | .titleBox { | ||||
display: flex; | display: flex; | ||||
justify-content: space-between; | justify-content: space-between; | ||||
} | } | ||||
.iconText{ | |||||
font-size: 14px; | |||||
position: absolute; | |||||
left:-20px; | |||||
top:0; | |||||
transform: rotate(-45deg); | |||||
background: rgb(243, 175, 0); | |||||
padding: 3px 10px; | |||||
color: #fff; | |||||
} | |||||
.title { | .title { | ||||
font-size: 30px; | font-size: 30px; | ||||
font-weight: 700; | font-weight: 700; | ||||
@@ -636,7 +528,6 @@ onMounted(async () => { | |||||
text-align: end; | text-align: end; | ||||
.price { | .price { | ||||
font-size: 30px; | font-size: 30px; | ||||
font-weight: 700; | |||||
color: #242625; | color: #242625; | ||||
cursor: pointer; | cursor: pointer; | ||||
} | } | ||||
@@ -649,10 +540,10 @@ onMounted(async () => { | |||||
cursor: pointer; | cursor: pointer; | ||||
margin-bottom: 20px; | margin-bottom: 20px; | ||||
span { | span { | ||||
font-weight: 700; | |||||
color: #242625; | color: #242625; | ||||
cursor: pointer; | cursor: pointer; | ||||
margin-right: 5px; | margin-right: 5px; | ||||
padding-left: 10px; | |||||
} | } | ||||
} | } | ||||
@@ -729,62 +620,29 @@ onMounted(async () => { | |||||
} | } | ||||
} | } | ||||
// 支付弹窗 | // 支付弹窗 | ||||
.payDialog { | |||||
display: flex; | |||||
position: relative; | |||||
min-height: 500px; | |||||
.left { | |||||
width: 35%; | |||||
border-right: 1px solid #7c7c7a; | |||||
.title { | |||||
color: #242625; | |||||
font-weight: 700; | |||||
font-size: 30px; | |||||
text-align: center; | |||||
} | |||||
.price { | |||||
span { | |||||
font-size: 30px; | |||||
font-weight: 700; | |||||
color: #242625; | |||||
} | |||||
} | |||||
.authority { | |||||
padding: 10px 20px; | |||||
} | |||||
} | |||||
.right { | |||||
width: 65%; | |||||
position: absolute; | |||||
top: 20%; | |||||
right: 0%; | |||||
padding-left: 20%; | |||||
> div { | |||||
width: 200px; | |||||
height: 40px; | |||||
// border: 1px solid #242625; | |||||
border-radius: 10px; | |||||
text-align: center; | |||||
line-height: 40px; | |||||
margin: 30px; | |||||
color: #fff; | |||||
} | |||||
.el-radio{ | |||||
width: 100px; | |||||
img { | |||||
vertical-align: middle; | |||||
margin-right: 5px; | |||||
width: 16px; | |||||
} | } | ||||
} | } | ||||
// 二维码弹窗 | // 二维码弹窗 | ||||
.orderCodeDialog { | .orderCodeDialog { | ||||
width: 100%; | width: 100%; | ||||
.codeImg { | .codeImg { | ||||
display: flex; | display: flex; | ||||
margin: auto; | margin: auto; | ||||
justify-content: space-evenly; | |||||
// justify-content: space-evenly; | |||||
align-items: center; | align-items: center; | ||||
width: 300px; | |||||
height: 300px; | |||||
width: 220PX; | |||||
height: 220PX; | |||||
border: 1px solid #ccc; | border: 1px solid #ccc; | ||||
border-radius: 15px; | border-radius: 15px; | ||||
overflow: hidden; | overflow: hidden; | ||||
padding: 10px; | |||||
padding: 13px; | |||||
img { | img { | ||||
width: 100%; | width: 100%; | ||||
height: 100%; | height: 100%; | ||||
@@ -0,0 +1,7 @@ | |||||
<!-- | |||||
* @Description: 定制分身 | |||||
--> | |||||
<template> | |||||
<iframe src="/priMakeHtml/siyouhuabushu/index.shtml" style="width: 100%;height:86vh"></iframe> | |||||
</template> |
@@ -0,0 +1,6 @@ | |||||
<!-- | |||||
* @Description: 定制声纹 | |||||
--> | |||||
<template> | |||||
<iframe src="/priMakeHtml/dingzhifenshen/index.shtml" style="width: 100%;height:86vh"></iframe> | |||||
</template> |
@@ -0,0 +1,944 @@ | |||||
<template> | |||||
<div class="page"> | |||||
<!-- 搜索框 --> | |||||
<div class="top"> | |||||
<div class="search"> | |||||
<el-input | |||||
style="width: 300px" | |||||
v-model="title" | |||||
:placeholder="$t('myCreating.search')" | |||||
@keyup.enter="searchVideoList" | |||||
/> | |||||
<el-icon class="icon-edit" @click="searchVideoList" | |||||
><i-ep-search | |||||
/></el-icon> | |||||
<!-- 重置按钮 --> | |||||
<div v-show="title" class="resetSearch" @click="resetSearch"> | |||||
{{ $t("myCreating.reset") }} | |||||
</div> | |||||
</div> | |||||
<!-- 更新视频提示 --> | |||||
<div class="hasNewVideoTips" :class="hasNewCreate ? '' : 'hasNew'"> | |||||
{{ $t("myCreating.hasNewVideo") }} | |||||
</div> | |||||
</div> | |||||
<!-- 作品列表 --> | |||||
<div v-if="!isLoading"> | |||||
<div v-if="videoList.length > 0" class="workList flex"> | |||||
<div class="workItem" v-for="item in videoList" :key="item.id"> | |||||
<div class="workImg"> | |||||
<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 :class="'statusName ' + item.statusName"> | |||||
{{ $t("myCreating." + item.statusName) }} | |||||
</div> | |||||
<div class="workInfo flex"> | |||||
<span>{{ item.title }}</span> | |||||
<span>{{ dayjs(item.createDate).format("YYYY-MM-DD") }}</span> | |||||
</div> | |||||
<!-- 更多遮罩层 --> | |||||
<div | |||||
class="more" | |||||
@mouseleave="mouseleave" | |||||
@click="clickVideoItem(item)" | |||||
> | |||||
<el-icon | |||||
v-if="[0].includes(item.videoStatus)" | |||||
class="icon-videoPlay" | |||||
><i-ep-edit | |||||
/></el-icon> | |||||
<el-icon | |||||
v-if="[1, 2, 4, 6].includes(item.videoStatus)" | |||||
class="icon-videoPlay" | |||||
><i-ep-loading | |||||
/></el-icon> | |||||
<el-icon | |||||
v-if="[3].includes(item.videoStatus)" | |||||
class="icon-videoPlay" | |||||
><i-ep-closeBold | |||||
/></el-icon> | |||||
<el-icon | |||||
v-if="[5, 7, 8, 9, 10, 11, 12].includes(item.videoStatus)" | |||||
class="icon-videoPlay" | |||||
><i-ep-videoPlay | |||||
/></el-icon> | |||||
<div class="showBtn" @click.stop="mouseenter(item)">...</div> | |||||
<div class="btns" v-show="showPopup"> | |||||
<!-- 下载按钮 --> | |||||
<div | |||||
class="btns-item" | |||||
@click.stop="handleDownload(item.videoPlayUrl, item.title)" | |||||
> | |||||
<div class="btns-item-icon"> | |||||
<el-icon class="icon-delete"><i-ep-download /></el-icon> | |||||
</div> | |||||
<div class="text">{{ $t("myCreating.download") }}</div> | |||||
</div> | |||||
<!-- 删除按钮 --> | |||||
<div | |||||
class="btns-item" | |||||
@click.stop="handelDelete(item.id, item.title)" | |||||
> | |||||
<div class="btns-item-icon"> | |||||
<el-icon class="icon-delete"><i-ep-delete /></el-icon> | |||||
</div> | |||||
<div class="text">{{ $t("myCreating.delete") }}</div> | |||||
</div> | |||||
</div> | |||||
</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> | |||||
</div> | |||||
<div v-if="isLoading" class="loadingIcon"> | |||||
<el-icon class="is-loading"> | |||||
<svg | |||||
viewBox="0 0 1024 1024" | |||||
xmlns="http://www.w3.org/2000/svg" | |||||
data-v-ea893728="" | |||||
> | |||||
<path | |||||
fill="currentColor" | |||||
d="M512 64a32 32 0 0 1 32 32v192a32 32 0 0 1-64 0V96a32 32 0 0 1 32-32zm0 640a32 32 0 0 1 32 32v192a32 32 0 1 1-64 0V736a32 32 0 0 1 32-32zm448-192a32 32 0 0 1-32 32H736a32 32 0 1 1 0-64h192a32 32 0 0 1 32 32zm-640 0a32 32 0 0 1-32 32H96a32 32 0 0 1 0-64h192a32 32 0 0 1 32 32zM195.2 195.2a32 32 0 0 1 45.248 0L376.32 331.008a32 32 0 0 1-45.248 45.248L195.2 240.448a32 32 0 0 1 0-45.248zm452.544 452.544a32 32 0 0 1 45.248 0L828.8 783.552a32 32 0 0 1-45.248 45.248L647.744 692.992a32 32 0 0 1 0-45.248zM828.8 195.264a32 32 0 0 1 0 45.184L692.992 376.32a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0zm-452.544 452.48a32 32 0 0 1 0 45.248L240.448 828.8a32 32 0 0 1-45.248-45.248l135.808-135.808a32 32 0 0 1 45.248 0z" | |||||
></path> | |||||
</svg> | |||||
</el-icon> | |||||
<span class="loadingText">{{ $t("myCreating.loading") }}</span> | |||||
</div> | |||||
<!-- 弹出框预览作品 --> | |||||
<el-dialog | |||||
destroy-on-close | |||||
class="elDialog" | |||||
v-model="showDialog" | |||||
:title="presentItem.title" | |||||
width="40%" | |||||
center | |||||
> | |||||
<div class="videoBox"> | |||||
<!-- 免费用户1分钟 [5].includes(presentItem.videoStatus)--> | |||||
<div | |||||
v-if="presentItem.videoPlayUrl && presentItem.videoTime > 300" | |||||
class="overtimeTips" | |||||
> | |||||
<img src="../../assets/img/tips.png" alt="" /> | |||||
{{ $t("myCreating.freeUserTip") }} | |||||
</div> | |||||
<video | |||||
v-if="presentItem.videoPlayUrl" | |||||
controls="true" | |||||
class="" | |||||
:src="presentItem.videoPlayUrl" | |||||
></video> | |||||
<div v-else class="insteadVideo"> | |||||
{{ $t("myCreating." + presentItem.statusName + "Text") }} | |||||
<p v-if="lanChange == 'zh-cn' && presentItem.videoStatus == 3"> | |||||
错误原因: {{ presentItem.videoMsg }} | |||||
</p> | |||||
<p v-if="lanChange == 'en' && presentItem.videoStatus == 3"> | |||||
Error cause: {{ presentItem.videoMsg }} | |||||
</p> | |||||
<!-- <span v-if="presentItem.videoStatus == 3">{{ | |||||
presentItem.videoMsg | |||||
}}</span> --> | |||||
</div> | |||||
<!-- 有视频路径的页脚 --> | |||||
<div class="footer" v-if="presentItem.videoPlayUrl"> | |||||
<span class="dialog-footer"> | |||||
<!-- dialog下载按钮 upGrades--> | |||||
<button | |||||
class="elBtn" | |||||
type="primary" | |||||
@click.stop=" | |||||
handleDownload(presentItem.videoPlayUrl, presentItem.title) | |||||
" | |||||
> | |||||
<!-- <el-icon class="icon-delete"><i-ep-download /></el-icon> --> | |||||
{{ $t("myCreating.download") }} | |||||
</button> | |||||
<!-- 提升画质 v-if="presentItem.isHy == 0"--> | |||||
<el-tooltip | |||||
style="cursor: pointer" | |||||
v-if="false" | |||||
class="box-item" | |||||
effect="light" | |||||
:content="$t('myCreating.upSharpnessTips')" | |||||
placement="top" | |||||
> | |||||
<button | |||||
style="cursor: pointer" | |||||
v-if="presentItem.isHy == 0" | |||||
class="elBtn upSharpness" | |||||
@click.stop="upGrades(presentItem.id)" | |||||
> | |||||
<div v-if="!upGradesLoading" style="cursor: pointer"> | |||||
<img src="../../assets/img/Upgrades.png" alt="" /> | |||||
{{ $t("myCreating.upSharpness") }} | |||||
</div> | |||||
<div v-if="upGradesLoading"> | |||||
<!-- <my-Loading-Icon | |||||
class="previewAudioLoadingBox" | |||||
v-if="!upGradesLoading" | |||||
></my-Loading-Icon> --> | |||||
<el-icon class="is-loading" style="font-size: 16px" | |||||
><i-ep-Loading | |||||
/></el-icon> | |||||
</div> | |||||
</button> | |||||
</el-tooltip> | |||||
<!-- dialog删除按钮 --> | |||||
<button | |||||
class="elBtn" | |||||
@click.stop="handelDelete(presentItem.id, presentItem.title)" | |||||
> | |||||
<!-- <el-icon class="icon-delete"><i-ep-delete /></el-icon> --> | |||||
{{ $t("myCreating.delete") }} | |||||
</button> | |||||
</span> | |||||
</div> | |||||
<!-- 无视频路径的页脚 --> | |||||
<div class="footer" v-if="!presentItem.videoPlayUrl"> | |||||
<span class="dialog-footer"> | |||||
<!-- dialog编辑按钮 --> | |||||
<button | |||||
class="elBtn" | |||||
type="primary" | |||||
@click.stop=" | |||||
router.push({ | |||||
path: '/createVideo', | |||||
query: { id: presentItem.id }, | |||||
}) | |||||
" | |||||
v-if="[0, 3].includes(presentItem.videoStatus)" | |||||
> | |||||
{{ $t("myCreating.edit") }} | |||||
</button> | |||||
</span> | |||||
</div> | |||||
</div> | |||||
</el-dialog> | |||||
<!-- 分页 --> | |||||
<div v-if="!isLoading" class="pagination"> | |||||
<el-pagination | |||||
v-model:current-page="pageNum" | |||||
v-model:page-size="pageSize" | |||||
:page-sizes="[12, 24, 36]" | |||||
: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> | |||||
//#region 导入 | |||||
import { | |||||
userPhotoVideoListApi, | |||||
delUserPhotoVideoByIDApi, | |||||
videoHyApi, | |||||
checkVideoStatusApi, | |||||
} from "@/apis/myCreating"; | |||||
import { timestampToTime } from "@/utils/tools"; | |||||
import { useI18n } from "vue-i18n"; | |||||
import { getStatus } from "./videoStatus"; | |||||
import { useRouter } from "vue-router"; | |||||
import dayjs from "dayjs"; | |||||
//#endregion ---------------------- | |||||
const router = useRouter(); | |||||
// 当前语言状态与国际化组件 | |||||
const { locale } = useI18n(); | |||||
const lanChange = ref(locale); | |||||
//#region 老页面逻辑 | |||||
const title = ref(""); | |||||
const pageNum = ref(1); | |||||
const pageSize = ref(12); | |||||
const total = ref(0); | |||||
// 弹窗显示隐藏 | |||||
const showDialog = ref(false); | |||||
const isLoading = ref(true); | |||||
// 当前作品 | |||||
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; | |||||
presentItem.value = item; | |||||
} | |||||
// 删除框是否显示 | |||||
let showPopup = ref(false); | |||||
function mouseleave() { | |||||
showPopup.value = false; | |||||
} | |||||
function mouseenter(item) { | |||||
presentItem.value = item; | |||||
showPopup.value = !showPopup.value; | |||||
} | |||||
// 下载 | |||||
function handleDownload(itemVideoPlayUrl, name) { | |||||
if (itemVideoPlayUrl) { | |||||
console.log(1); | |||||
let a = document.createElement("a"); | |||||
a.download = `${name}.mp4`; | |||||
a.href = itemVideoPlayUrl; | |||||
// 设置下载文件名 | |||||
a.style.display = "none"; | |||||
document.body.appendChild(a); | |||||
a.click(); | |||||
a.remove(); | |||||
ElMessage.success( | |||||
lanChange.value == "zh-cn" ? `下载成功` : `Download Successfully` | |||||
); | |||||
} else { | |||||
ElMessage.error( | |||||
lanChange.value == "zh-cn" ? `无法下载` : `Unable to download` | |||||
); | |||||
} | |||||
} | |||||
function goCreate() { | |||||
router.push("/createVideo"); | |||||
} | |||||
function resetSearch(params) { | |||||
title.value = ""; | |||||
searchVideoList(); | |||||
} | |||||
// 搜索 | |||||
function searchVideoList() { | |||||
getPhotoVideoList(pageNum.value, pageSize.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); | |||||
}); | |||||
} | |||||
// 升级画质 | |||||
const upGradesLoading = ref(false); | |||||
function upGrades(id) { | |||||
if (upGradesLoading.value == true) { | |||||
ElMessage.error( | |||||
lanChange.value == "zh-cn" | |||||
? `正在升级,请稍后~` | |||||
: `Upgrading, please wait ~` | |||||
); | |||||
return; | |||||
} | |||||
const msg = | |||||
lanChange.value == "zh-cn" | |||||
? `确定要升级该作品吗?` | |||||
: `Are you sure you want to upgrade this work?`; | |||||
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(async () => { | |||||
upGradesLoading.value = true; | |||||
try { | |||||
const res = await videoHyApi(id); | |||||
ElMessage.success( | |||||
lanChange.value == "zh-cn" | |||||
? `升级中!请稍等~` | |||||
: `Upgrading! Please wait a moment` | |||||
); | |||||
showDialog.value = false; | |||||
upGradesLoading.value = false; | |||||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||||
} catch (error) { | |||||
ElMessage.error( | |||||
lanChange.value == "zh-cn" | |||||
? `升级失败,请稍后重试` | |||||
: `Upgrade failed, please try again later` | |||||
); | |||||
upGradesLoading.value = false; | |||||
} | |||||
}); | |||||
} | |||||
/** | |||||
* @description:获取我的视频作品 | |||||
* @return: data | |||||
*/ | |||||
function getPhotoVideoList(pageNum, pageSize, title, searchFlag) { | |||||
userPhotoVideoListApi(pageNum, pageSize, title) | |||||
.then((res) => { | |||||
console.log(res, "res"); | |||||
notGenerateList.value = []; | |||||
// 找到数组中未生成的,放入列表,为了刷新 | |||||
res.data.list.forEach((item) => { | |||||
if ([1, 2, 4, 6, 7, 8, 10, 12].includes(item.videoStatus)) { | |||||
notGenerateList.value.push(item.id); | |||||
} | |||||
}); | |||||
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; | |||||
total.value = res.data.total * 1; | |||||
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`; | |||||
const msg3 = | |||||
lanChange.value == "zh-cn" | |||||
? `查询成功!已加载全部视频` | |||||
: `Found! Present all videos`; | |||||
return title | |||||
? ElMessage.success(total > 0 ? msg1 : msg2) | |||||
: ElMessage.success(msg3); | |||||
} | |||||
isLoading.value = false; | |||||
}) | |||||
.catch((err) => { | |||||
console.log(err, "err"); | |||||
}); | |||||
} | |||||
/** | |||||
* @description:删除视频作品 | |||||
* @param: videoID | |||||
* @return: data | |||||
*/ | |||||
function delPhotoVideo(videoID) { | |||||
delUserPhotoVideoByIDApi(videoID) | |||||
.then((res) => { | |||||
console.log(res, "res"); | |||||
const msg = lanChange.value == "zh-cn" ? `删除成功!` : `Success !`; | |||||
ElMessage.success(msg); | |||||
showDialog.value = false; | |||||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||||
}) | |||||
.catch((err) => { | |||||
console.log(err, "err"); | |||||
ElMessage.error(err.message); | |||||
}); | |||||
} | |||||
//#endregion ---------------------- | |||||
//#region 定时刷新 | |||||
const hasNewCreate = ref(false); //提示框显示隐藏 | |||||
const notGenerateList = ref([]); //页面上未生成的视频的id 普通视频 | |||||
const notGenerateList2 = ref([]); //页面上未生成的视频的id 升级视频 | |||||
const checkVideoStatus = async () => { | |||||
// 如果列表中没有生成中的视频,不发送请求 | |||||
const intervalId = setInterval(async () => { | |||||
// && notGenerateList2.value.length == 0; | |||||
console.log(""); | |||||
if (notGenerateList.value.length == 0) { | |||||
return; | |||||
} | |||||
try { | |||||
const res = await checkVideoStatusApi(notGenerateList.value); | |||||
// 如果有新的,则提示且更新列表 | |||||
if (res.code != 2115) { | |||||
hasNewCreate.value = true; | |||||
const changeHasNewCreate = setTimeout(() => { | |||||
hasNewCreate.value = false; | |||||
}, 5000); | |||||
notGenerateList.value = []; | |||||
// notGenerateList2.value = []; | |||||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||||
} | |||||
} catch (error) {} | |||||
}, 3000); | |||||
onUnmounted(() => { | |||||
clearInterval(intervalId); | |||||
}); | |||||
}; | |||||
//#endregion --------------------------- | |||||
//#region 页面初始化 | |||||
onMounted(() => { | |||||
isLoading.value = true; | |||||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||||
// checkVideoStatus(); | |||||
}); | |||||
//#endregion --------------------------- | |||||
</script> | |||||
<style lang="scss" scoped> | |||||
.page { | |||||
position: relative; | |||||
height: calc(100vh - 80px); | |||||
padding: 15px 130px; | |||||
background-color: #fff; | |||||
border-radius: 25px 0 0; | |||||
width: 100%; | |||||
overflow: hidden; | |||||
overflow-y: auto; | |||||
.top { | |||||
position: relative; | |||||
margin-bottom: 35px; | |||||
.search { | |||||
display: flex; | |||||
justify-content: flex-start; | |||||
.resetSearch { | |||||
margin-left: 10px; | |||||
padding: 0 10px; | |||||
height: 30px; | |||||
width: 100px; | |||||
text-align: center; | |||||
line-height: 30px; | |||||
background-color: #000; | |||||
border: 1px solid #000; | |||||
border-radius: 15px; | |||||
cursor: pointer; | |||||
transition: all 0.3s; | |||||
color: #fff; | |||||
&:hover { | |||||
background-color: #fff; | |||||
color: #000; | |||||
} | |||||
} | |||||
} | |||||
.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; | |||||
line-height: 100px; | |||||
text-align: center; | |||||
transform: scale(2); | |||||
.loadingText { | |||||
position: relative; | |||||
top: -2px; | |||||
left: 4px; | |||||
} | |||||
} | |||||
.workList { | |||||
flex-wrap: wrap; | |||||
justify-content: flex-start; | |||||
width: 100%; | |||||
// height: 200px; | |||||
margin-top: 5px; | |||||
padding-bottom: 50px; | |||||
.workItem { | |||||
position: relative; | |||||
width: 300px; | |||||
// height: 200px; | |||||
margin: 0 20px 20px 0; | |||||
border: 2px solid #c2c2c2; | |||||
border-radius: 15px; | |||||
cursor: pointer; | |||||
overflow: hidden; | |||||
.workImg { | |||||
position: relative; | |||||
width: 100%; | |||||
height: 170px; | |||||
cursor: pointer; | |||||
padding: 10px; | |||||
overflow: hidden; | |||||
.coverImg { | |||||
max-width: 90%; | |||||
max-height: 170px; | |||||
cursor: pointer; | |||||
} | |||||
.takePlace { | |||||
position: absolute; | |||||
top: 40%; | |||||
width: 80%; | |||||
} | |||||
} | |||||
.more { | |||||
position: absolute; | |||||
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; | |||||
} | |||||
.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; | |||||
} | |||||
} | |||||
.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 { | |||||
position: relative; | |||||
display: inline-block; | |||||
width: 20px; | |||||
height: 20px; | |||||
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; | |||||
font-size: 13px; | |||||
cursor: pointer; | |||||
} | |||||
&:hover { | |||||
color: #ffffff; | |||||
background-color: #0000001a; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.workInfo { | |||||
justify-content: space-between; | |||||
height: 40px; | |||||
padding: 0 10px; | |||||
line-height: 40px; | |||||
border-top: 1px solid #afafaf; | |||||
white-space: nowrap; | |||||
overflow: hidden; | |||||
text-overflow: ellipsis; | |||||
font-size: 13px; | |||||
} | |||||
.statusName { | |||||
position: absolute; | |||||
top: 10%; | |||||
left: -10%; | |||||
width: 120px; | |||||
text-align: center; | |||||
color: #ffffff; | |||||
font-size: 14px; | |||||
transform: rotate(-45deg); | |||||
&.manuscript { | |||||
/* 草稿 */ | |||||
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%); | |||||
} | |||||
&.videoUping { | |||||
/* 升级中 */ | |||||
background: linear-gradient(120deg, #4512c7 0%, #4fd334 100%); | |||||
} | |||||
&.videoUpFailed { | |||||
/* HD */ | |||||
background: linear-gradient(120deg, #ff0019 0%, #ff00c3 100%); | |||||
} | |||||
&.videoUpSucceed { | |||||
/* HD */ | |||||
background: linear-gradient(120deg, #fdeb71 0%, #d37e1a 100%); | |||||
} | |||||
} | |||||
&:hover { | |||||
.more { | |||||
opacity: 1; | |||||
} | |||||
} | |||||
} | |||||
} | |||||
.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: 20px; | |||||
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; | |||||
} | |||||
.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; | |||||
} | |||||
} | |||||
.elDialog { | |||||
.videoBox { | |||||
// display: flex; | |||||
// 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; | |||||
margin: auto; | |||||
} | |||||
.insteadVideo { | |||||
font-size: 20px; | |||||
font-weight: 400; | |||||
margin: 20px auto; | |||||
text-align: center; | |||||
} | |||||
p { | |||||
font-weight: 700; | |||||
} | |||||
} | |||||
.dialog-footer { | |||||
display: flex; | |||||
justify-content: space-between; | |||||
.elBtn { | |||||
color: #fff; | |||||
border-radius: 10px; | |||||
padding: 10px 15px; | |||||
cursor: pointer; | |||||
background-color: #000; | |||||
transition: all 0.3s; | |||||
&:hover { | |||||
background-color: #15d1b8; | |||||
} | |||||
} | |||||
.upSharpness { | |||||
img { | |||||
width: 14px; | |||||
height: 14px; | |||||
} | |||||
} | |||||
:deep(.el-icon) { | |||||
margin-right: 5px; | |||||
font-weight: 700; | |||||
} | |||||
} | |||||
} | |||||
:deep(.el-dialog) { | |||||
overflow: hidden; | |||||
border-radius: 25px; | |||||
} | |||||
// :deep(.el-dialog__header) { | |||||
// } | |||||
:deep(.el-dialog__title) { | |||||
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) { | |||||
padding: 0; | |||||
} | |||||
:deep(.dialog__footer) { | |||||
padding: 0; | |||||
} | |||||
</style> |
@@ -0,0 +1,16 @@ | |||||
/** | |||||
* @description:根据状态返回状态名 | |||||
* @param {number} status | |||||
* @return: statusName | |||||
*/ | |||||
export const getStatus = status => { | |||||
if (status == 0) { | |||||
return "manuscript" | |||||
} else if (status == 1 || status == 2 || status == 4 || status == 6) { | |||||
return "generating" | |||||
} else if (status == 3) { | |||||
return "generationFailed" | |||||
} else if (status == 5) { | |||||
return "generationSucceed" | |||||
} | |||||
} |
@@ -0,0 +1,7 @@ | |||||
<template> | |||||
<div></div> | |||||
</template> | |||||
<script setup> | |||||
// import { ref } from 'vue' | |||||
</script> | |||||
<style lang="scss" scoped></style> |
@@ -0,0 +1,6 @@ | |||||
<!-- | |||||
* @Description: 定制分身 | |||||
--> | |||||
<template> | |||||
<iframe src="/priMakeHtml/dingzhishengwen/index.shtml" style="width: 100%;height:86vh"></iframe> | |||||
</template> |