commit
This commit is contained in:
@@ -81,4 +81,20 @@ const addUrls = async (gameId, urls) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export { schedule, games, urls, go,addUrls };
|
// 在nba.js中添加删除函数
|
||||||
|
const deleteUrlById = async (id) => {
|
||||||
|
return await nbaapi({
|
||||||
|
url: `/delete/${id}`,
|
||||||
|
method: 'get',
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
return response.data;
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error('删除直播URL失败:', error);
|
||||||
|
throw error;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
export { schedule, games, urls, go,addUrls,deleteUrlById };
|
||||||
@@ -10,41 +10,31 @@
|
|||||||
|
|
||||||
<div class="teams">
|
<div class="teams">
|
||||||
<div class="team">
|
<div class="team">
|
||||||
<img
|
<img :src="game.homeTeamLogoDark" :alt="game.homeTeamName" class="team-logo" />
|
||||||
:src="game.homeTeamLogoDark"
|
|
||||||
:alt="game.homeTeamName"
|
|
||||||
class="team-logo"
|
|
||||||
/>
|
|
||||||
<span class="team-name">{{ game.homeTeamName }}</span>
|
<span class="team-name">{{ game.homeTeamName }}</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="vs">VS</span>
|
<span class="vs">VS</span>
|
||||||
<div class="team">
|
<div class="team">
|
||||||
<img
|
<img :src="game.awayTeamLogoDark" :alt="game.awayTeamName" class="team-logo" />
|
||||||
:src="game.awayTeamLogoDark"
|
|
||||||
:alt="game.awayTeamName"
|
|
||||||
class="team-logo"
|
|
||||||
/>
|
|
||||||
<span class="team-name">{{ game.awayTeamName }}</span>
|
<span class="team-name">{{ game.awayTeamName }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span class="start-time">{{ formatTime(game.startTime) }}</span>
|
<span class="start-time">{{ formatTime(game.startTime) }}</span>
|
||||||
|
|
||||||
<!-- 显示直播URL -->
|
<!-- 直播链接区域 -->
|
||||||
<div
|
<div v-if="getGameUrls(game.gameId).length > 0" class="urls-container">
|
||||||
v-if="getGameUrls(game.gameId).length > 0"
|
<div v-for="(url, index) in getGameUrls(game.gameId)" :key="index" class="url-item">
|
||||||
class="urls-container"
|
|
||||||
>
|
|
||||||
<h4>直播链接:</h4>
|
|
||||||
<div
|
|
||||||
v-for="(url, index) in getGameUrls(game.gameId)"
|
|
||||||
:key="index"
|
|
||||||
class="url-item"
|
|
||||||
>
|
|
||||||
<span class="url-type">{{ formatUrlType(url.type) }}:</span>
|
<span class="url-type">{{ formatUrlType(url.type) }}:</span>
|
||||||
<a :href="url.url" target="_blank" class="url-link">{{
|
<span class="truncated-url" @click="showFullUrl(url.url)">
|
||||||
url.url
|
{{ truncateUrl(url.url) }}
|
||||||
}}</a>
|
</span>
|
||||||
|
<button class="check-btn" @click.stop="showFullUrl(url.url)">
|
||||||
|
<i class="el-icon-view"></i> 查看
|
||||||
|
</button>
|
||||||
|
<button class="delete-btn" @click.stop="deleteUrl(url.id)">
|
||||||
|
<i class="el-icon-delete"></i> 删除
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="no-urls">暂无直播链接</div>
|
<div v-else class="no-urls">暂无直播链接</div>
|
||||||
@@ -56,17 +46,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 添加直播URL的对话框 -->
|
<!-- URL详情弹窗 -->
|
||||||
<!-- 添加直播URL的对话框 -->
|
<el-dialog v-model="urlDialogVisible" title="直播链接详情" width="50%" center>
|
||||||
|
<div class="url-dialog-content">
|
||||||
|
<div class="full-url">{{ currentUrl }}</div>
|
||||||
|
<el-button type="primary" @click="copyUrl(currentUrl)">复制链接</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
|
||||||
|
<!-- 添加直播URL对话框 -->
|
||||||
<div v-if="showDialog" class="dialog-overlay">
|
<div v-if="showDialog" class="dialog-overlay">
|
||||||
<div class="dialog-content">
|
<div class="dialog-content">
|
||||||
<h3>
|
<h3>为 {{ selectedGame.homeTeamName }} VS {{ selectedGame.awayTeamName }} 添加直播URL</h3>
|
||||||
为 {{ selectedGame.homeTeamName }} VS
|
|
||||||
{{ selectedGame.awayTeamName }} 添加直播URL
|
|
||||||
</h3>
|
|
||||||
|
|
||||||
<div class="url-inputs">
|
<div class="url-inputs">
|
||||||
<div v-for="(url, index) in newUrls" :key="index" class="url-item">
|
<div v-for="(url, index) in newUrls" :key="index" class="url-input-item">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>直播类型 {{ index + 1 }}:</label>
|
<label>直播类型 {{ index + 1 }}:</label>
|
||||||
<select v-model="url.type" class="url-type-select">
|
<select v-model="url.type" class="url-type-select">
|
||||||
@@ -88,11 +82,7 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button
|
<button v-if="newUrls.length > 1" class="remove-btn" @click="removeUrl(index)">
|
||||||
v-if="newUrls.length > 1"
|
|
||||||
class="remove-btn"
|
|
||||||
@click="removeUrl(index)"
|
|
||||||
>
|
|
||||||
<i class="el-icon-remove"></i> 删除
|
<i class="el-icon-remove"></i> 删除
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -104,11 +94,7 @@
|
|||||||
|
|
||||||
<div class="dialog-footer">
|
<div class="dialog-footer">
|
||||||
<button class="cancel-btn" @click="closeDialog">取消</button>
|
<button class="cancel-btn" @click="closeDialog">取消</button>
|
||||||
<button
|
<button class="confirm-btn" @click="submitUrls" :disabled="isSubmitting">
|
||||||
class="confirm-btn"
|
|
||||||
@click="submitUrls"
|
|
||||||
:disabled="isSubmitting"
|
|
||||||
>
|
|
||||||
<span v-if="!isSubmitting">确认添加</span>
|
<span v-if="!isSubmitting">确认添加</span>
|
||||||
<span v-else>正在提交...</span>
|
<span v-else>正在提交...</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -119,20 +105,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, onBeforeMount } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import { ElMessage, ElLoading } from "element-plus";
|
import { ElMessage, ElLoading } from "element-plus";
|
||||||
import { games, urls, addUrls as apiAddUrls,go } from "@/api/nba";
|
import { games, urls, addUrls as apiAddUrls, go, deleteUrlById } from "@/api/nba";
|
||||||
|
|
||||||
// 组件状态
|
// 响应式状态
|
||||||
const gamesData = ref([]);
|
const gamesData = ref([]);
|
||||||
const urlData = ref([]);
|
const urlData = ref([]);
|
||||||
const showDialog = ref(false);
|
const showDialog = ref(false);
|
||||||
const selectedGame = ref(null);
|
const selectedGame = ref(null);
|
||||||
const newUrls = ref([{ type: "tx", url: "" }]);
|
const newUrls = ref([{ type: "tx", url: "" }]);
|
||||||
const isSubmitting = ref(false);
|
const isSubmitting = ref(false);
|
||||||
|
const urlDialogVisible = ref(false);
|
||||||
|
const currentUrl = ref('');
|
||||||
|
|
||||||
// 获取比赛和URL数据
|
// 初始化数据
|
||||||
onMounted(async () => {
|
const initData = async () => {
|
||||||
try {
|
try {
|
||||||
const [urlsRes, gamesRes] = await Promise.all([urls(), games()]);
|
const [urlsRes, gamesRes] = await Promise.all([urls(), games()]);
|
||||||
urlData.value = urlsRes || [];
|
urlData.value = urlsRes || [];
|
||||||
@@ -141,143 +129,65 @@ onMounted(async () => {
|
|||||||
console.error("获取数据失败:", err);
|
console.error("获取数据失败:", err);
|
||||||
ElMessage.error("获取比赛数据失败,请刷新重试");
|
ElMessage.error("获取比赛数据失败,请刷新重试");
|
||||||
}
|
}
|
||||||
});
|
};
|
||||||
|
|
||||||
// 提交直播链接
|
// URL处理函数
|
||||||
const submitUrls = async () => {
|
const truncateUrl = (url) => {
|
||||||
// 验证URL格式
|
try {
|
||||||
const validUrls = newUrls.value
|
const urlObj = new URL(url);
|
||||||
.filter((item) => item.url.trim() !== "")
|
return `${urlObj.hostname}${urlObj.pathname.substring(0, 20)}...`;
|
||||||
.map((item) => ({
|
} catch {
|
||||||
type: item.type,
|
return url.length > 30 ? `${url.substring(0, 30)}...` : url;
|
||||||
url: item.url.trim(),
|
|
||||||
}));
|
|
||||||
|
|
||||||
if (validUrls.length === 0) {
|
|
||||||
ElMessage.warning("请至少输入一个有效的直播URL");
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// 验证URL格式是否正确
|
const showFullUrl = (url) => {
|
||||||
for (const url of validUrls) {
|
currentUrl.value = url;
|
||||||
if (!isValidUrl(url.url)) {
|
urlDialogVisible.value = true;
|
||||||
ElMessage.warning(`直播地址格式不正确: ${url.url}`);
|
};
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
isSubmitting.value = true;
|
const copyUrl = (url) => {
|
||||||
const loading = ElLoading.service({
|
navigator.clipboard.writeText(url)
|
||||||
|
.then(() => {
|
||||||
|
ElMessage.success('链接已复制');
|
||||||
|
urlDialogVisible.value = false;
|
||||||
|
})
|
||||||
|
.catch(() => ElMessage.error('复制失败'));
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除URL
|
||||||
|
const deleteUrl = async (id) => {
|
||||||
|
let loading = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const confirm = window.confirm('确定要删除这个直播链接吗?');
|
||||||
|
if (!confirm) return;
|
||||||
|
|
||||||
|
loading = ElLoading.service({
|
||||||
lock: true,
|
lock: true,
|
||||||
text: "正在提交直播链接...",
|
text: "正在删除直播链接...",
|
||||||
background: "rgba(0, 0, 0, 0.7)",
|
background: "rgba(0, 0, 0, 0.7)",
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
await deleteUrlById(id);
|
||||||
// 调用API添加URL
|
|
||||||
await apiAddUrls(selectedGame.value.gameId, validUrls);
|
|
||||||
|
|
||||||
// 更新本地数据
|
urlData.value = urlData.value.map(gameUrl => {
|
||||||
updateLocalUrls(selectedGame.value.gameId, validUrls);
|
const gameId = Object.keys(gameUrl)[0];
|
||||||
|
return {
|
||||||
|
[gameId]: gameUrl[gameId].filter(url => url.id !== id)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
ElMessage.success("直播链接添加成功!");
|
ElMessage.success('直播链接删除成功');
|
||||||
closeDialog();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("添加直播URL失败:", error);
|
console.error('删除直播链接失败:', error);
|
||||||
ElMessage.error(`添加失败: ${error.message || "服务器错误"}`);
|
ElMessage.error(`删除失败: ${error.message || "服务器错误"}`);
|
||||||
} finally {
|
} finally {
|
||||||
loading.close();
|
loading?.close();
|
||||||
isSubmitting.value = false;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 更新本地URL数据
|
// 添加URL相关函数
|
||||||
const updateLocalUrls = (gameId, urlsToAdd) => {
|
|
||||||
const existingIndex = urlData.value.findIndex(
|
|
||||||
(item) => item.gameId === gameId
|
|
||||||
);
|
|
||||||
|
|
||||||
if (existingIndex >= 0) {
|
|
||||||
// 合并现有URL
|
|
||||||
urlData.value[existingIndex].urls = [
|
|
||||||
...urlData.value[existingIndex].urls,
|
|
||||||
...urlsToAdd,
|
|
||||||
];
|
|
||||||
} else {
|
|
||||||
// 添加新比赛URL
|
|
||||||
urlData.value.push({
|
|
||||||
gameId,
|
|
||||||
urls: urlsToAdd,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// URL验证函数
|
|
||||||
const isValidUrl = (url) => {
|
|
||||||
try {
|
|
||||||
new URL(url);
|
|
||||||
return true;
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
onBeforeMount(async () => {
|
|
||||||
const storedPassword = localStorage.getItem("password");
|
|
||||||
if (storedPassword && storedPassword == "inspur123") {
|
|
||||||
console.log("=======进入后台======");
|
|
||||||
// return;
|
|
||||||
} else {
|
|
||||||
const password = prompt("请输入密码:");
|
|
||||||
try {
|
|
||||||
const response = await go(password);
|
|
||||||
if (response == true) {
|
|
||||||
// console.log("=======进入后台======");
|
|
||||||
localStorage.setItem("password", password);
|
|
||||||
} else {
|
|
||||||
// console.log("==========密码错误=========");
|
|
||||||
window.location.href = "/";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
// console.error("验证密码失败:", err);
|
|
||||||
window.location.href = "/";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
onMounted(async () => {
|
|
||||||
try {
|
|
||||||
const [res_urls, response] = await Promise.all([urls(), games()]);
|
|
||||||
urlData.value = res_urls || [];
|
|
||||||
gamesData.value = response || [];
|
|
||||||
} catch (err) {
|
|
||||||
console.error("获取数据失败:", err);
|
|
||||||
gamesData.value = [];
|
|
||||||
urlData.value = [];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// 根据gameId获取对应的URLs
|
|
||||||
const getGameUrls = (gameId) => {
|
|
||||||
const gameUrls = urlData.value.find((item) => item[gameId]);
|
|
||||||
return gameUrls ? gameUrls[gameId] : [];
|
|
||||||
};
|
|
||||||
|
|
||||||
// 格式化URL类型显示
|
|
||||||
const formatUrlType = (type) => {
|
|
||||||
const typeMap = {
|
|
||||||
tx: "腾讯",
|
|
||||||
wl: "纬来",
|
|
||||||
mg: "咪咕",
|
|
||||||
nba: "原声",
|
|
||||||
zb: "其他",
|
|
||||||
qq: "腾讯",
|
|
||||||
wx: "微信",
|
|
||||||
};
|
|
||||||
return typeMap[type] || type;
|
|
||||||
};
|
|
||||||
|
|
||||||
const openAddUrlDialog = (game) => {
|
const openAddUrlDialog = (game) => {
|
||||||
selectedGame.value = game;
|
selectedGame.value = game;
|
||||||
newUrls.value = [{ type: "tx", url: "" }];
|
newUrls.value = [{ type: "tx", url: "" }];
|
||||||
@@ -296,29 +206,85 @@ const removeUrl = (index) => {
|
|||||||
newUrls.value.splice(index, 1);
|
newUrls.value.splice(index, 1);
|
||||||
};
|
};
|
||||||
|
|
||||||
const addUrls = async () => {
|
const isValidUrl = (url) => {
|
||||||
const validUrls = newUrls.value.filter((item) => item.url.trim() !== "");
|
try {
|
||||||
|
new URL(url);
|
||||||
|
return true;
|
||||||
|
} catch {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const submitUrls = async () => {
|
||||||
|
const validUrls = newUrls.value
|
||||||
|
.filter(item => item.url.trim() !== "")
|
||||||
|
.map(item => ({
|
||||||
|
type: item.type,
|
||||||
|
url: item.url.trim(),
|
||||||
|
}));
|
||||||
|
|
||||||
if (validUrls.length === 0) {
|
if (validUrls.length === 0) {
|
||||||
alert("请至少输入一个有效的直播URL");
|
ElMessage.warning("请至少输入一个有效的直播URL");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const payload = {
|
for (const url of validUrls) {
|
||||||
gameId: selectedGame.value.gameId,
|
if (!isValidUrl(url.url)) {
|
||||||
urls: validUrls,
|
ElMessage.warning(`直播地址格式不正确: ${url.url}`);
|
||||||
};
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
isSubmitting.value = true;
|
||||||
|
const loading = ElLoading.service({
|
||||||
|
lock: true,
|
||||||
|
text: "正在提交直播链接...",
|
||||||
|
background: "rgba(0, 0, 0, 0.7)",
|
||||||
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// console.log("提交的数据:", payload);
|
const response = await apiAddUrls(selectedGame.value.gameId, validUrls);
|
||||||
alert("直播URL添加成功!");
|
updateLocalUrls(selectedGame.value.gameId, response.data || validUrls);
|
||||||
|
ElMessage.success("直播链接添加成功!");
|
||||||
closeDialog();
|
closeDialog();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("添加直播URL失败:", error);
|
console.error("添加直播URL失败:", error);
|
||||||
alert("添加失败,请重试");
|
ElMessage.error(`添加失败: ${error.message || "服务器错误"}`);
|
||||||
|
} finally {
|
||||||
|
loading.close();
|
||||||
|
isSubmitting.value = false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const updateLocalUrls = (gameId, urlsToAdd) => {
|
||||||
|
const newUrlData = [...urlData.value];
|
||||||
|
const existingIndex = newUrlData.findIndex(item => Object.keys(item)[0] === gameId.toString());
|
||||||
|
|
||||||
|
if (existingIndex >= 0) {
|
||||||
|
const existingItem = { ...newUrlData[existingIndex] };
|
||||||
|
existingItem[gameId] = [...existingItem[gameId], ...urlsToAdd];
|
||||||
|
newUrlData[existingIndex] = existingItem;
|
||||||
|
} else {
|
||||||
|
newUrlData.push({ [gameId]: urlsToAdd });
|
||||||
|
}
|
||||||
|
|
||||||
|
urlData.value = newUrlData;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 工具函数
|
||||||
|
const getGameUrls = (gameId) => {
|
||||||
|
const gameUrls = urlData.value.find(item => item[gameId]);
|
||||||
|
return gameUrls ? gameUrls[gameId] : [];
|
||||||
|
};
|
||||||
|
|
||||||
|
const formatUrlType = (type) => {
|
||||||
|
const typeMap = {
|
||||||
|
tx: "腾讯", wl: "纬来", mg: "咪咕",
|
||||||
|
nba: "原声", zb: "其他", qq: "腾讯", wx: "微信"
|
||||||
|
};
|
||||||
|
return typeMap[type] || type;
|
||||||
|
};
|
||||||
|
|
||||||
const formatDate = (dateString) => {
|
const formatDate = (dateString) => {
|
||||||
const date = new Date(dateString);
|
const date = new Date(dateString);
|
||||||
return `${date.getMonth() + 1}月${date.getDate()}日`;
|
return `${date.getMonth() + 1}月${date.getDate()}日`;
|
||||||
@@ -328,55 +294,39 @@ const formatTime = (timeString) => {
|
|||||||
const time = new Date(timeString);
|
const time = new Date(timeString);
|
||||||
return `${time.getHours()}:${time.getMinutes().toString().padStart(2, "0")}`;
|
return `${time.getHours()}:${time.getMinutes().toString().padStart(2, "0")}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 生命周期钩子
|
||||||
|
onMounted(() => {
|
||||||
|
initData();
|
||||||
|
|
||||||
|
const storedPassword = localStorage.getItem("password");
|
||||||
|
if (storedPassword && storedPassword === "inspur123") return;
|
||||||
|
|
||||||
|
const password = prompt("请输入密码:");
|
||||||
|
go(password)
|
||||||
|
.then(response => {
|
||||||
|
if (response) {
|
||||||
|
localStorage.setItem("password", password);
|
||||||
|
} else {
|
||||||
|
window.location.href = "/";
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(() => window.location.href = "/");
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
/* 添加一些样式使URL显示更美观 */
|
|
||||||
.urls-container {
|
|
||||||
margin-top: 10px;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.url-item {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.url-type {
|
|
||||||
font-weight: bold;
|
|
||||||
margin-right: 8px;
|
|
||||||
min-width: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.url-link {
|
|
||||||
color: #0066cc;
|
|
||||||
text-decoration: none;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.url-link:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.no-urls {
|
|
||||||
margin-top: 10px;
|
|
||||||
color: #999;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
.games-container {
|
.games-container {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
max-width: 1000px;
|
max-width: 1000px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.game-list {
|
.game-list {
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -396,21 +346,27 @@ h2 {
|
|||||||
|
|
||||||
.game-info {
|
.game-info {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
flex-direction: column;
|
||||||
gap: 20px;
|
gap: 10px;
|
||||||
}
|
flex-grow: 1;
|
||||||
|
|
||||||
.game-date,
|
.game-date, .game-id, .start-time {
|
||||||
.game-id,
|
|
||||||
.start-time {
|
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
color: #666;
|
color: #666;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.teams {
|
.teams {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 10px;
|
justify-content: center;
|
||||||
|
gap: 15px;
|
||||||
|
margin: 10px 0;
|
||||||
|
|
||||||
|
.vs {
|
||||||
|
font-weight: bold;
|
||||||
|
color: #e63946;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.team {
|
.team {
|
||||||
@@ -418,7 +374,6 @@ h2 {
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 5px;
|
gap: 5px;
|
||||||
}
|
|
||||||
|
|
||||||
.team-logo {
|
.team-logo {
|
||||||
width: 40px;
|
width: 40px;
|
||||||
@@ -430,10 +385,81 @@ h2 {
|
|||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.vs {
|
.urls-container {
|
||||||
|
margin-top: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
.url-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #f0f0f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.url-type {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #e63946;
|
min-width: 50px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.truncated-url {
|
||||||
|
flex: 1;
|
||||||
|
color: #409eff;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: underline;
|
||||||
|
margin: 0 10px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: #66b1ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.check-btn {
|
||||||
|
padding: 4px 8px;
|
||||||
|
background-color: #987eff;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #7d5fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete-btn {
|
||||||
|
margin-left: 8px;
|
||||||
|
padding: 4px 8px;
|
||||||
|
background-color: #ff4444;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #cc0000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.no-urls {
|
||||||
|
margin-top: 10px;
|
||||||
|
color: #999;
|
||||||
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
.add-url-btn {
|
.add-url-btn {
|
||||||
@@ -443,7 +469,7 @@ h2 {
|
|||||||
border: none;
|
border: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.3s;
|
align-self: flex-start;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #45a049;
|
background-color: #45a049;
|
||||||
@@ -471,14 +497,14 @@ h2 {
|
|||||||
width: 90%;
|
width: 90%;
|
||||||
max-width: 500px;
|
max-width: 500px;
|
||||||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-content h3 {
|
h3 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
color: #333;
|
color: #333;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.url-inputs {
|
.url-inputs {
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
@@ -486,7 +512,7 @@ h2 {
|
|||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.url-item {
|
.url-input-item {
|
||||||
background-color: #f9f9f9;
|
background-color: #f9f9f9;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
@@ -496,22 +522,21 @@ h2 {
|
|||||||
|
|
||||||
.form-group {
|
.form-group {
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
|
||||||
|
|
||||||
.form-group label {
|
label {
|
||||||
display: block;
|
display: block;
|
||||||
margin-bottom: 5px;
|
margin-bottom: 5px;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-group input,
|
input, select {
|
||||||
.form-group select {
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
border: 1px solid #ddd;
|
border: 1px solid #ddd;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.remove-btn {
|
.remove-btn {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -544,24 +569,18 @@ h2 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-buttons {
|
.dialog-footer {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
|
||||||
|
|
||||||
.cancel-btn,
|
.cancel-btn {
|
||||||
.confirm-btn {
|
|
||||||
padding: 8px 15px;
|
padding: 8px 15px;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
color: #333;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: background-color 0.3s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cancel-btn {
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
color: #333;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #e0e0e0;
|
background-color: #e0e0e0;
|
||||||
@@ -569,11 +588,38 @@ h2 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.confirm-btn {
|
.confirm-btn {
|
||||||
|
padding: 8px 15px;
|
||||||
background-color: #2196f3;
|
background-color: #2196f3;
|
||||||
color: white;
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background-color: #0b7dda;
|
background-color: #0b7dda;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:disabled {
|
||||||
|
background-color: #cccccc;
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* URL详情弹窗样式 */
|
||||||
|
.url-dialog-content {
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.full-url {
|
||||||
|
padding: 10px;
|
||||||
|
margin: 15px 0;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
border-radius: 4px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-button {
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Reference in New Issue
Block a user