@@ -0,0 +1,39 @@ | |||
import request from "@/utils/request.js"; | |||
/** | |||
* @description 获取密钥列表 | |||
* @param {*} (pageNum,pageSize) | |||
* @returns data | |||
*/ | |||
export function keyListApi(pageNum, pageSize) { | |||
return request({ | |||
url: `/thirdPartyApi/page?pageNum=${pageNum}&pageSize=${pageSize}`, | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description 根据id获取密钥详情 | |||
* @param {*} (id) | |||
* @returns data | |||
*/ | |||
export function getKeyByIdApi(id) { | |||
return request({ | |||
url: `/thirdPartyApi/get?id=${id}`, | |||
method: 'get' | |||
}) | |||
} | |||
/** | |||
* @description 更改密钥状态 | |||
* @param {*} (id,status) | |||
* @returns data | |||
*/ | |||
export function updateKeyStatusApi(id, status) { | |||
return request({ | |||
url: `/thirdPartyApi/updateStatus`, | |||
method: 'post', | |||
data: { id, status } | |||
}) | |||
} |
@@ -226,6 +226,11 @@ export default { | |||
keyMangage: { | |||
title: "Key", | |||
list: "Key List", | |||
name: "Owner", | |||
status: "Status", | |||
operations: "Operations", | |||
check: "Check", | |||
}, | |||
priceMangage: { | |||
@@ -225,6 +225,11 @@ export default { | |||
keyMangage: { | |||
title: "密钥管理", | |||
list: "密钥列表", | |||
name: "所属人", | |||
status: "密钥状态", | |||
operations: "操作", | |||
check: "查看", | |||
}, | |||
priceMangage: { | |||
@@ -47,7 +47,7 @@ | |||
</div> | |||
</div> | |||
<div class="myRouter-item" @click="router.push('/keyCheck')"> | |||
<div class="myRouter-item" @click="router.push('/keyList')"> | |||
<div class="icon"> | |||
<el-icon><i-ep-edit /></el-icon> | |||
{{ $t("keyMangage.title") }} | |||
@@ -38,6 +38,24 @@ export const constantRoutes: RouteRecordRaw[] = [ | |||
], | |||
}, | |||
{ | |||
path: "/", | |||
component: Layout, | |||
redirect: "/keyList", | |||
children: [ | |||
{ | |||
path: "keyList", | |||
component: () => import("@/views/mangage/keyList.vue"), | |||
name: "keyList", | |||
meta: { | |||
title: "keyList", | |||
icon: "homepage", | |||
affix: true, | |||
name: "keyMangage.list", | |||
}, | |||
}, | |||
], | |||
}, | |||
{ | |||
path: "/", | |||
component: Layout, | |||
@@ -14,37 +14,26 @@ declare module '@vue/runtime-core' { | |||
EditPosition: typeof import('./../components/EditPosition.vue')['default'] | |||
'EditPosition copy': typeof import('./../components/EditPosition copy.vue')['default'] | |||
ElButton: typeof import('element-plus/es')['ElButton'] | |||
ElCard: typeof import('element-plus/es')['ElCard'] | |||
ElDialog: typeof import('element-plus/es')['ElDialog'] | |||
ElDropdown: typeof import('element-plus/es')['ElDropdown'] | |||
ElDropdownItem: typeof import('element-plus/es')['ElDropdownItem'] | |||
ElDropdownMenu: typeof import('element-plus/es')['ElDropdownMenu'] | |||
ElForm: typeof import('element-plus/es')['ElForm'] | |||
ElFormItem: typeof import('element-plus/es')['ElFormItem'] | |||
ElIcon: typeof import('element-plus/es')['ElIcon'] | |||
ElInput: typeof import('element-plus/es')['ElInput'] | |||
ElInputNumber: typeof import('element-plus/es')['ElInputNumber'] | |||
ElOption: typeof import('element-plus/es')['ElOption'] | |||
ElPagination: typeof import('element-plus/es')['ElPagination'] | |||
ElRadio: typeof import('element-plus/es')['ElRadio'] | |||
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup'] | |||
ElSelect: typeof import('element-plus/es')['ElSelect'] | |||
ElSwitch: typeof import('element-plus/es')['ElSwitch'] | |||
ElTable: typeof import('element-plus/es')['ElTable'] | |||
ElTableColumn: typeof import('element-plus/es')['ElTableColumn'] | |||
ElTag: typeof import('element-plus/es')['ElTag'] | |||
ElTooltip: typeof import('element-plus/es')['ElTooltip'] | |||
ElUpload: typeof import('element-plus/es')['ElUpload'] | |||
GithubCorner: typeof import('./../components/GithubCorner/index.vue')['default'] | |||
Hamburger: typeof import('./../components/Hamburger/index.vue')['default'] | |||
IconSelect: typeof import('./../components/IconSelect/index.vue')['default'] | |||
IEpCollection: typeof import('~icons/ep/collection')['default'] | |||
IEpDelete: typeof import('~icons/ep/delete')['default'] | |||
IEpDocumentAdd: typeof import('~icons/ep/document-add')['default'] | |||
IEpEdit: typeof import('~icons/ep/edit')['default'] | |||
IEpPlus: typeof import('~icons/ep/plus')['default'] | |||
IEpRefresh: typeof import('~icons/ep/refresh')['default'] | |||
IEpSearch: typeof import('~icons/ep/search')['default'] | |||
LangSelect: typeof import('./../components/LangSelect/index.vue')['default'] | |||
MultiUpload: typeof import('./../components/Upload/MultiUpload.vue')['default'] | |||
MyLoading: typeof import('./../components/myLoading.vue')['default'] | |||
@@ -60,6 +49,5 @@ declare module '@vue/runtime-core' { | |||
} | |||
export interface ComponentCustomProperties { | |||
vInfiniteScroll: typeof import('element-plus/es')['ElInfiniteScroll'] | |||
vLoading: typeof import('element-plus/es')['ElLoadingDirective'] | |||
} | |||
} |
@@ -1,22 +1,47 @@ | |||
<template> | |||
<div class="page flex justify-around"> | |||
<div class="card"> | |||
<div class="title">密钥管理</div> | |||
<div class="title">密钥详情</div> | |||
<div class="key"> | |||
<span class="text">密钥:{{ showCode }}</span> | |||
<span class="text">{{ $t("keyMangage.name") }}:{{ name }}</span> | |||
</div> | |||
<!-- appId --> | |||
<div class="key"> | |||
<span class="text">appId:{{ showCode }}</span> | |||
<span class="showOrHide" @click="showHideCode">{{ showText }}</span> | |||
<span v-if="showText == '隐藏'" class="copy" @click="copyKey" | |||
<span v-if="showText == '隐藏'" class="copy" @click="copyKey(showCode)" | |||
>复制</span | |||
> | |||
</div> | |||
<div class="keyStatus"> | |||
<span class="text" | |||
>密钥状态:{{ keyStatus == 1 ? "正常" : "作废" }}</span | |||
<!-- appKey --> | |||
<div class="key"> | |||
<span class="text">appKey:{{ showCodeII }}</span> | |||
<span class="showOrHide" @click="showHideCodeII">{{ showTextII }}</span> | |||
<span | |||
v-if="showTextII == '隐藏'" | |||
class="copy" | |||
@click="copyKey(showCodeII)" | |||
>复制</span | |||
> | |||
<span v-if="keyStatus == 1" class="success" @click="changeStatus(2)" | |||
>恢复</span | |||
</div> | |||
<!-- signKey --> | |||
<div class="key"> | |||
<span class="text">signKey:{{ showCodeIII }}</span> | |||
<span class="showOrHide" @click="showHideCodeIII(showCodeIII)">{{ | |||
showTextIII | |||
}}</span> | |||
<span v-if="showTextIII == '隐藏'" class="copy" @click="copyKey" | |||
>复制</span | |||
> | |||
<span v-if="keyStatus == 2" class="fail" @click="changeStatus(1)" | |||
</div> | |||
<div class="keyStatus"> | |||
<span class="text" | |||
>密钥状态: | |||
<span v-if="!keyStatus" style="color: #36db43">正常</span> | |||
<span v-else style="color: #ff0000">失效</span> | |||
</span> | |||
<span v-if="keyStatus" class="fail" @click="changeStatus(0)">恢复</span> | |||
<span v-if="!keyStatus" class="success" @click="changeStatus(1)" | |||
>作废</span | |||
> | |||
</div> | |||
@@ -34,40 +59,107 @@ import { useI18n } from "vue-i18n"; | |||
import { useRoute, useRouter } from "vue-router"; | |||
import { getKeyByIdApi, updateKeyStatusApi } from "@/api_mangage/key"; | |||
const route = useRoute(); | |||
const router = useRouter(); | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
const AccessToken = localStorage.getItem("AccessToken"); // 判断有没有登录 | |||
const key = ref("AE0DVHDWMDOURSBCAP"); | |||
const keyId = ref(""); | |||
const name = ref(""); | |||
const appId = ref(""); | |||
const hideCode = ref(""); | |||
const showCode = ref(""); | |||
const showText = ref("查看"); | |||
const getKey = () => { | |||
const len = key.value.length; | |||
let code = ""; | |||
for (let index = 0; index < len; index++) { | |||
code += "*"; | |||
} | |||
hideCode.value = code; | |||
showCode.value = code; | |||
}; | |||
const showHideCode = () => { | |||
if (showText.value == "查看") { | |||
showText.value = "隐藏"; | |||
showCode.value = key.value; | |||
showCode.value = appId.value; | |||
} else { | |||
showText.value = "查看"; | |||
showCode.value = hideCode.value; | |||
} | |||
}; | |||
const copyKey = () => { | |||
const appKey = ref(""); | |||
const hideCodeII = ref(""); | |||
const showCodeII = ref(""); | |||
const showTextII = ref("查看"); | |||
const showHideCodeII = () => { | |||
if (showTextII.value == "查看") { | |||
showTextII.value = "隐藏"; | |||
showCodeII.value = appKey.value; | |||
} else { | |||
showTextII.value = "查看"; | |||
showCodeII.value = hideCodeII.value; | |||
} | |||
}; | |||
const signKey = ref(""); | |||
const hideCodeIII = ref(""); | |||
const showCodeIII = ref(""); | |||
const showTextIII = ref("查看"); | |||
const showHideCodeIII = () => { | |||
if (showTextIII.value == "查看") { | |||
showTextIII.value = "隐藏"; | |||
showCodeIII.value = signKey.value; | |||
} else { | |||
showTextIII.value = "查看"; | |||
showCodeIII.value = hideCodeIII.value; | |||
} | |||
}; | |||
const getKeyFunc = async () => { | |||
const id = keyId.value; | |||
try { | |||
const res = await getKeyByIdApi(id); | |||
console.log(res, "res"); | |||
appId.value = res.data.appId; | |||
appKey.value = res.data.appKey; | |||
signKey.value = res.data.signKey; | |||
keyStatus.value = res.data.status; | |||
name.value = res.data.name; | |||
const len = signKey.value.length; | |||
const lenII = signKey.value.length; | |||
const lenIII = signKey.value.length; | |||
let code = ""; | |||
let codeII = ""; | |||
let codeIII = ""; | |||
for (let index = 0; index < len; index++) { | |||
code += "*"; | |||
} | |||
for (let index = 0; index < lenII; index++) { | |||
codeII += "*"; | |||
} | |||
for (let index = 0; index < lenIII; index++) { | |||
codeIII += "*"; | |||
} | |||
hideCode.value = code; | |||
showCode.value = code; | |||
hideCodeII.value = codeII; | |||
showCodeII.value = codeII; | |||
hideCodeIII.value = codeIII; | |||
showCodeIII.value = codeIII; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
const copyKey = (text) => { | |||
navigator.clipboard | |||
.writeText(key.value) | |||
.writeText(text) | |||
.then(() => { | |||
ElMessage.success("复制成功!"); | |||
}) | |||
@@ -78,19 +170,48 @@ const copyKey = () => { | |||
const keyStatus = ref(""); | |||
const getStatus = () => { | |||
// 1:正常;2:作废 | |||
const status = 1; | |||
keyStatus.value = status; | |||
}; | |||
const changeStatus = (num) => { | |||
keyStatus.value = num; | |||
const changeStatus = async (status) => { | |||
const id = keyId.value; | |||
if (status) { | |||
ElMessageBox.confirm("此操作将作废密钥,确定?", "Warning", { | |||
confirmButtonText: "确定", | |||
cancelButtonText: "取消", | |||
type: "warning", | |||
}) | |||
.then(async () => { | |||
try { | |||
const res = await updateKeyStatusApi(id, status); | |||
if (res.code == 200) { | |||
ElMessage({ | |||
type: "success", | |||
message: "作废成功!", | |||
}); | |||
getKeyFunc(); | |||
} | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}) | |||
.catch(() => {}); | |||
} else { | |||
try { | |||
const res = await updateKeyStatusApi(id, status); | |||
if (res.code == 200) { | |||
ElMessage({ | |||
type: "success", | |||
message: "恢复成功!", | |||
}); | |||
getKeyFunc(); | |||
} | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
} | |||
}; | |||
onMounted(() => { | |||
getKey(); | |||
getStatus(); | |||
keyId.value = route.query.id; | |||
getKeyFunc(); | |||
}); | |||
</script> | |||
@@ -102,23 +223,25 @@ onMounted(() => { | |||
border-radius: 30px 0 0 0; | |||
overflow: hidden; | |||
.card { | |||
width: 70%; | |||
width: 80%; | |||
height: 70%; | |||
background-color: #f8f8f8; | |||
background-color: #fafafa; | |||
margin-top: 10vh; | |||
border-radius: 5vh; | |||
box-shadow: #0000002e 1px 1px 1px 1px; | |||
.title { | |||
text-align: center; | |||
font-size: 4vh; | |||
padding: 5vh; | |||
font-size: 3vh; | |||
padding: 4vh; | |||
} | |||
.key { | |||
text-align: center; | |||
font-size: 4vh; | |||
font-size: 2.5vh; | |||
padding: 5vh; | |||
padding-bottom: 0.5vh; | |||
text-align: left; | |||
.copy { | |||
color: #ffffff; | |||
@@ -144,25 +267,32 @@ onMounted(() => { | |||
} | |||
.keyStatus { | |||
text-align: center; | |||
font-size: 4vh; | |||
padding: 5vh; | |||
font-size: 2.9vh; | |||
padding: 4vh; | |||
margin-top: 1vh; | |||
.success { | |||
color: #ff0000; | |||
color: #ffffff; | |||
background-color: #ff0000; | |||
margin-left: 2vh; | |||
padding: 0.7vh; | |||
border-radius: 15px; | |||
cursor: pointer; | |||
transition: all 0.3s; | |||
&:hover { | |||
color: #36db43; | |||
background-color: #36db43; | |||
} | |||
} | |||
.fail { | |||
color: #36db43; | |||
color: #ffffff; | |||
background-color: #36db43; | |||
margin-left: 2vh; | |||
padding: 0.7vh; | |||
border-radius: 15px; | |||
cursor: pointer; | |||
transition: all 0.3s; | |||
&:hover { | |||
color: #ff0000; | |||
background-color: #ff0000; | |||
} | |||
} | |||
} | |||
@@ -0,0 +1,148 @@ | |||
<template> | |||
<div class="page flex justify-around"> | |||
<el-table | |||
:data="tableData" | |||
style="width: 100%; height: 90%" | |||
size="large" | |||
align="center" | |||
> | |||
<el-table-column | |||
prop="name" | |||
:label="$t('keyMangage.name')" | |||
width="220" | |||
align="center" | |||
/> | |||
<el-table-column | |||
prop="status" | |||
:label="$t('keyMangage.status')" | |||
width="220" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
<span | |||
:style="1 * scope.row.status ? 'color: #ff0000' : 'color: #36db43'" | |||
>{{ getStatus(scope.row.status) }}</span | |||
> | |||
</template> | |||
</el-table-column> | |||
<el-table-column | |||
fixed="right" | |||
:label="$t('keyMangage.operations')" | |||
width="220" | |||
align="center" | |||
> | |||
<template #default="scope"> | |||
<el-button | |||
link | |||
type="primary" | |||
size="small" | |||
@click="showDetail(scope.row.id)" | |||
>{{ $t("keyMangage.check") }}</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> | |||
</div> | |||
</template> | |||
<!-- videoType==1为竖,==2为横 --> | |||
<script setup> | |||
//#region 导入 | |||
import { linkEmits } from "element-plus"; | |||
import { getCurrentInstance } from "vue"; | |||
import { keyListApi } from "@/api_mangage/key"; | |||
import { useI18n } from "vue-i18n"; | |||
import { useRoute, useRouter } from "vue-router"; | |||
const route = useRoute(); | |||
const router = useRouter(); | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
const tableData = ref([]); | |||
const showDetail = (id) => { | |||
router.push({ | |||
path: "/keyCheck", | |||
query: { | |||
id, | |||
}, | |||
}); | |||
}; | |||
const pageNum = ref(1); | |||
const pageSize = ref(10); | |||
const total = ref(0); | |||
const getStatus = (val) => { | |||
return val * 1 ? "失效" : "正常"; | |||
}; | |||
const handleSizeChange = (val) => { | |||
pageSize.value = val; | |||
getKeyListFunc(pageNum.value, pageSize.value); | |||
}; | |||
const handleCurrentChange = (val) => { | |||
pageNum.value = val; | |||
getKeyListFunc(pageNum.value, pageSize.value); | |||
}; | |||
const getKeyListFunc = async (PageNum, PageSize) => { | |||
try { | |||
const res = await keyListApi(PageNum, PageSize); | |||
console.log(res, "res"); | |||
tableData.value = res.data.list; | |||
} catch (error) { | |||
console.log(error, "err"); | |||
} | |||
}; | |||
onMounted(() => { | |||
getKeyListFunc(1, 10); | |||
}); | |||
</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; | |||
.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,698 +0,0 @@ | |||
<template> | |||
<div class="page"> | |||
<!-- 搜索框 --> | |||
<div class="top"> | |||
<div class="flex justify-between" style="width: 300px"> | |||
<el-input | |||
v-model="title" | |||
:placeholder="$t('myCreating.search')" | |||
@keyup.enter="searchVideoList" | |||
/> | |||
<el-icon class="icon-edit" @click="searchVideoList" | |||
><i-ep-search | |||
/></el-icon> | |||
</div> | |||
</div> | |||
<!-- 作品列表 --> | |||
<div 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].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)" | |||
> | |||
<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"> | |||
<video | |||
v-if="presentItem.videoPlayUrl" | |||
controls="true" | |||
class="" | |||
:src="presentItem.videoPlayUrl" | |||
></video> | |||
<div v-else class="insteadVideo"> | |||
{{ $t("myCreating." + presentItem.statusName + "Text") }} | |||
<span v-if="presentItem.videoStatus == 3">{{ | |||
presentItem.videoMsg | |||
}}</span> | |||
</div> | |||
<!-- 有视频路径的页脚 --> | |||
<div class="footer" v-if="presentItem.videoPlayUrl"> | |||
<span class="dialog-footer"> | |||
<!-- dialog下载按钮 --> | |||
<button | |||
class="elBtn" | |||
type="primary" | |||
@click.stop="handleDownload(presentItem.videoPlayUrl)" | |||
> | |||
<el-icon class="icon-delete"><i-ep-download /></el-icon | |||
>{{ $t("myCreating.download") }} | |||
</button> | |||
<!-- 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="[10, 20, 50, 100, 200]" | |||
:small="false" | |||
:disabled="false" | |||
:background="true" | |||
layout="total, sizes, prev, pager, next, jumper" | |||
:total="total" | |||
@size-change="handleSizeChange" | |||
@current-change="handleCurrentChange" | |||
/> | |||
</div> | |||
</div> | |||
</template> | |||
<script setup> | |||
import { | |||
userPhotoVideoListApi, | |||
delUserPhotoVideoByIDApi, | |||
} 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"; | |||
const router = useRouter(); | |||
// 当前语言状态与国际化组件 | |||
const { locale } = useI18n(); | |||
const lanChange = ref(locale); | |||
const title = ref(""); | |||
const pageNum = ref(1); | |||
const pageSize = ref(10); | |||
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) { | |||
if (itemVideoPlayUrl) { | |||
const link = document.createElement("a"); | |||
link.href = itemVideoPlayUrl; | |||
document.body.appendChild(link); | |||
link.click(); | |||
document.body.removeChild(link); | |||
} else { | |||
ElMessage.error( | |||
lanChange.value == "zh-cn" ? `无法下载` : `Unable to download` | |||
); | |||
} | |||
} | |||
function goCreate() { | |||
router.push("/createVideo"); | |||
} | |||
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); | |||
}); | |||
} | |||
/** | |||
* @description:获取我的视频作品 | |||
* @return: data | |||
*/ | |||
function getPhotoVideoList(pageNum, pageSize, title, searchFlag) { | |||
userPhotoVideoList(pageNum, pageSize, title) | |||
.then((res) => { | |||
console.log(res, "res"); | |||
res.data.list.forEach((item) => { | |||
// item.createDate = timestampToTime(item.createDate) || ""; | |||
// item.updateDate = timestampToTime(item.updateDate) || ""; | |||
// item.createVideoDate = timestampToTime(item.createVideoDate) || ""; | |||
item.statusName = getStatus(item.videoStatus); | |||
}); | |||
videoList.value = res.data.list; | |||
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) { | |||
delUserPhotoVideoByID(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); | |||
}); | |||
} | |||
onMounted(() => { | |||
isLoading.value = true; | |||
getPhotoVideoList(pageNum.value, pageSize.value, title.value); | |||
}); | |||
</script> | |||
<style lang="scss" scoped> | |||
.page { | |||
min-height: calc(100vh - 80px); | |||
padding: 15px 130px; | |||
background-color: #fff; | |||
border-radius: 25px 0 0; | |||
.top { | |||
margin-bottom: 35px; | |||
} | |||
.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; | |||
cursor: pointer; | |||
.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; | |||
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%); | |||
} | |||
} | |||
&: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; | |||
video { | |||
width: 100%; | |||
max-height: 600px; | |||
margin: auto; | |||
} | |||
.insteadVideo { | |||
font-size: 20px; | |||
font-weight: 600; | |||
margin: 20px auto; | |||
text-align: center; | |||
} | |||
} | |||
.dialog-footer { | |||
display: flex; | |||
justify-content: space-between; | |||
.elBtn { | |||
color: #fff; | |||
border-radius: 10px; | |||
padding: 5px 10px; | |||
cursor: pointer; | |||
background-color: #000; | |||
transition: all 0.3s; | |||
&:hover { | |||
background-color: #15d1b8; | |||
} | |||
} | |||
: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> |