新增部分软件源

This commit is contained in:
Super Manito
2025-10-14 15:32:16 +08:00
parent 61868705dd
commit cae539f6b7
18 changed files with 1420 additions and 689 deletions

View File

@@ -0,0 +1 @@
<?xml version="1.0" encoding="UTF-8"?><svg id="_图层_1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 198.425 198.425"><defs><style>.cls-1{fill:#0085d0;}.cls-2{fill:#8fc31f;}</style></defs><path class="cls-1" d="m172.518,84.013c-8.748-9.716-20.756-15.443-33.812-16.128-15.824-.824-31.025,4.553-42.793,15.149l-24.441,21.933c-4.742,4.256-5.017,11.593-.608,16.192l.744.776,32.811-29.437c9.25-8.329,21.189-12.558,33.62-11.905,9.661.506,18.547,4.745,25.021,11.934s9.76,16.47,9.253,26.131c-1.009,19.246-17.14,34.322-36.726,34.322-6.043,0-11.937-1.46-17.196-4.189-1.356-.703-3.001-.517-4.137.503l-7.843,7.042c8.439,6.067,18.646,9.37,29.176,9.37,26.357,0,48.071-20.373,49.434-46.381.684-13.056-3.757-25.597-12.505-35.312Z"/><path class="cls-2" d="m126.601,111.581l-7.507-7.832c-4.035-4.21-10.683-4.459-15.023-.563l-19.26,17.294c-2.062,1.852-5.221,1.733-7.139-.267l-8.681-9.054,2.619,10.777,7.513,7.836c4.036,4.209,10.683,4.458,15.021.562l19.253-17.288c2.062-1.851,5.22-1.734,7.138.266l6.252,6.517-.187-8.246Z"/><path class="cls-1" d="m126.601,111.581l-32.813,29.433c-9.273,8.35-21.215,12.592-33.619,11.94-19.946-1.045-35.321-18.137-34.275-38.1.493-9.414,4.558-18.141,11.445-24.573,6.145-5.739,13.948-9.106,22.239-9.668,1.662-.113,2.972-1.456,2.995-3.122l.133-9.684c-12.946-.198-25.282,4.705-34.638,13.728-8.343,8.046-13.582,18.851-14.713,30.386-2.739,27.931,18.441,52.289,46.147,53.741,1.057.055,2.11.083,3.161.083,14.657,0,28.629-5.36,39.63-15.266l24.444-21.926c4.743-4.255,5.02-11.592.611-16.192l-.748-.78Z"/><path class="cls-1" d="m172.518,84.013c-8.748-9.716-20.756-15.443-33.812-16.128-15.824-.824-31.025,4.553-42.793,15.149l-24.441,21.933c-4.742,4.256-5.017,11.593-.608,16.192l.744.776,32.811-29.437c9.25-8.329,21.189-12.558,33.62-11.905,9.661.506,18.547,4.745,25.021,11.934s9.76,16.47,9.253,26.131c-1.009,19.246-17.14,34.322-36.726,34.322-6.166,0-12.176-1.52-17.515-4.356-1.165-.619-2.595-.427-3.577.454l-8.083,7.258c8.439,6.067,18.646,9.37,29.176,9.37,26.357,0,48.071-20.373,49.434-46.381.684-13.056-3.757-25.597-12.505-35.312Z"/><path class="cls-1" d="m99.804,32.258c-26.989,0-48.946,21.957-48.946,48.946l4.227-.003c1.847-.364,3.732-.585,5.637-.655,1.603-.059,2.883-1.33,3.04-2.926,1.805-18.296,17.279-32.637,36.042-32.637,19.269,0,35.157,15.057,36.169,34.278l12.708-.67c-1.368-25.982-22.838-46.334-48.877-46.334Z"/><path class="cls-1" d="m71.61,121.935l3.81,3.973c-2.037-3.374-1.436-6.103,2.464-9.602,3.9-3.499-4.063-2.137-4.063-2.137l-2.21,7.765Z"/><path class="cls-1" d="m126.602,111.582l-3.81-3.973c2.037,3.374,1.436,6.103-2.464,9.602-3.9,3.499,4.063,2.137,4.063,2.137l2.21-7.765Z"/></svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -1,3 +1,7 @@
const __p = typeof window !== 'undefined' && window.location && window.location.pathname ? window.location.pathname : ''
const __isZhHant = __p.includes('/zh-Hant')
const __isEn = __p.includes('/en')
// 防抖
function debounce(func, wait) {
let timeout
@@ -24,6 +28,7 @@ const ComponentSystem = {
lastInitTime: 0,
def: componentDef,
debouncedInit: null,
app: null,
}
// 创建组件初始化函数
const initFunc = function () {
@@ -49,6 +54,14 @@ const ComponentSystem = {
component.isInitializing = true
component.lastInitTime = now
try {
if (component.app && typeof component.app.unmount === 'function') {
try {
component.app.unmount()
} catch (err) {
console.error('ComponentSystem: unmount previous app error', err)
}
component.app = null
}
// 清空容器内容,防止重复初始化
while (component.instance.firstChild) {
component.instance.removeChild(component.instance.firstChild)
@@ -65,17 +78,19 @@ const ComponentSystem = {
App.use(TDesign.default)
// 挂载应用
App.mount(component.instance)
// 保存 app 引用以便后续卸载
component.app = App
// console.log(`组件 ${componentId} 初始化成功`)
// 标记组件已初始化
component.instance.setAttribute('data-initialized', 'true')
// 立即更新主题
updateTDesignGlobalTheme()
} else if (typeof Vue !== 'undefined') {
} else if (typeof Vue !== 'undefined') {
console.error('Vue 未找到')
const errorDiv = document.createElement('div')
errorDiv.innerHTML = `<div class="admonition failure"><p class="admonition-title">组件 ${componentId} 加载失败,请检查 Vue 是否存在!</p></div>`
component.instance.appendChild(errorDiv)
} else if (typeof TDesign !== 'undefined') {
} else if (typeof TDesign !== 'undefined') {
console.error('TDesign UI 未找到')
const errorDiv = document.createElement('div')
errorDiv.innerHTML = `<div class="admonition failure"><p class="admonition-title">组件 ${componentId} 加载失败,请检查 TDesign UI 是否存在!</p></div>`
@@ -107,6 +122,14 @@ const ComponentSystem = {
if (component) {
component.instance = document.getElementById(componentId)
if (component.instance) {
if (component.app && typeof component.app.unmount === 'function') {
try {
component.app.unmount()
} catch (err) {
console.error('ComponentSystem: unmount on reinitialize error', err)
}
component.app = null
}
component.instance.removeAttribute('data-initialized')
setTimeout(component.debouncedInit, 300)
}

View File

@@ -1,381 +1,531 @@
// 表格数据
const mirrorsTableData = [
{
name: window.location.pathname.includes('/zh-Hant') ? '阿里雲' : window.location.pathname.includes('/en') ? 'Alibaba Cloud' : '阿里云',
officialName: window.location.pathname.includes('/zh-Hant') ? '阿里巴巴開源鏡像站' : window.location.pathname.includes('/en') ? 'Alibaba Cloud Open Source Mirror' : '阿里巴巴开源镜像站',
name: __isZhHant ? '阿里雲' : __isEn ? 'Alibaba Cloud' : '阿里云',
officialName: __isZhHant ? '阿里巴巴開源鏡像站' : __isEn ? 'Alibaba Cloud Open Source Mirror' : '阿里巴巴开源镜像站',
icon: 'alibabacloud.svg',
iconStyle: { verticalAlign: '-0.2em' },
url: 'https://mirrors.aliyun.com',
domain: 'mirrors.aliyun.com',
ipv6: false,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: 'incompatible',
rocky: 'incompatible',
almalinux: true,
epel: true,
fedora: true,
opencloudos: false,
openeuler: true,
anolis: true,
openkylin: true,
alpinelinux: true,
alpine: true,
armbian: true,
proxmox: false,
linuxmint: true,
gentoo: true,
nix: false,
raspberry: true,
nix_channels: false,
raspberrypi: true,
manjaro: true,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '騰訊雲' : window.location.pathname.includes('/en') ? 'Tencent Cloud' : '腾讯云',
officialName: window.location.pathname.includes('/zh-Hant') ? '騰訊軟體源' : window.location.pathname.includes('/en') ? 'Tencent Software Repository' : '腾讯软件源',
name: __isZhHant ? '騰訊雲' : __isEn ? 'Tencent Cloud' : '腾讯云',
officialName: __isZhHant ? '騰訊軟體源' : __isEn ? 'Tencent Software Repository' : '腾讯软件源',
icon: 'tencentcloud.ico',
iconStyle: { verticalAlign: '-0.25em' },
url: 'https://mirrors.tencent.com',
domain: 'mirrors.tencent.com',
ipv6: false,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: false,
rockylinux: true,
rocky: true,
almalinux: true,
epel: true,
fedora: true,
opencloudos: true,
openeuler: true,
anolis: false,
openkylin: false,
alpinelinux: true,
alpine: true,
armbian: false,
proxmox: false,
linuxmint: true,
gentoo: true,
nix: false,
raspberry: false,
nix_channels: false,
raspberrypi: false,
manjaro: false,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '華為雲' : window.location.pathname.includes('/en') ? 'Huawei Cloud' : '华为云',
officialName: window.location.pathname.includes('/zh-Hant') ? '華為開源鏡像站' : window.location.pathname.includes('/en') ? 'Huawei Open Source Mirror' : '华为开源镜像站',
name: __isZhHant ? '華為雲' : __isEn ? 'Huawei Cloud' : '华为云',
officialName: __isZhHant ? '華為開源鏡像站' : __isEn ? 'Huawei Open Source Mirror' : '华为开源镜像站',
icon: 'huaweicloud.ico',
iconStyle: { verticalAlign: '-0.15em' },
url: 'https://mirrors.huaweicloud.com',
domain: 'mirrors.huaweicloud.com',
ipv6: false,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: 'incompatible',
rocky: 'incompatible',
almalinux: true,
epel: true,
fedora: true,
opencloudos: false,
openeuler: true,
anolis: false,
openkylin: false,
alpinelinux: true,
alpine: true,
armbian: false,
proxmox: false,
linuxmint: true,
gentoo: true,
nix: false,
raspberry: false,
nix_channels: false,
raspberrypi: false,
manjaro: true,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '網易' : window.location.pathname.includes('/en') ? 'NetEase' : '网易',
officialName: window.location.pathname.includes('/zh-Hant') ? '網易開源鏡像站' : window.location.pathname.includes('/en') ? 'NetEase Open Source Mirror' : '网易开源镜像站',
name: __isZhHant ? '移動雲' : __isEn ? 'China Mobile Cloud' : '移动云 ',
officialName: __isZhHant ? '移動雲開源鏡像站' : __isEn ? 'China Mobile Cloud Open Source Mirror' : '移动云开源镜像站',
icon: 'cmecloud.svg',
iconStyle: { verticalAlign: '-0.2em' },
url: 'https://mirrors.cmecloud.cn',
domain: 'mirrors.cmecloud.cn',
ipv6: true,
debian: true,
ubuntu: true,
centos: true,
centos_stream: false,
opensuse: true,
archlinux: false,
kali: false,
deepin: false,
rocky: true,
almalinux: false,
epel: true,
fedora: true,
opencloudos: false,
openeuler: true,
anolis: true,
openkylin: false,
alpine: false,
armbian: false,
proxmox: false,
linuxmint: false,
gentoo: false,
nix_channels: false,
raspberrypi: false,
manjaro: false,
},
{
name: __isZhHant ? '天翼雲' : __isEn ? 'China Telecom Cloud' : '天翼云',
officialName: __isZhHant ? '天翼雲開源鏡像站' : __isEn ? 'China Telecom Cloud Open Source Mirror' : '天翼云开源镜像站',
icon: 'ctyun.ico',
iconStyle: { verticalAlign: '-0.2em' },
url: 'https://mirrors.ctyun.cn',
domain: 'mirrors.ctyun.cn',
ipv6: false,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: false,
archlinux: false,
kali: false,
deepin: false,
rocky: true,
almalinux: false,
epel: true,
fedora: false,
opencloudos: false,
openeuler: true,
anolis: false,
openkylin: false,
alpine: false,
armbian: false,
proxmox: false,
linuxmint: false,
gentoo: false,
nix_channels: false,
raspberrypi: false,
manjaro: false,
},
{
name: __isZhHant ? '網易' : __isEn ? 'NetEase' : '网易',
officialName: __isZhHant ? '網易開源鏡像站' : __isEn ? 'NetEase Open Source Mirror' : '网易开源镜像站',
icon: '163.ico',
iconStyle: { verticalAlign: '-0.15em' },
url: 'https://mirrors.163.com',
domain: 'mirrors.163.com',
ipv6: false,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: false,
kali: false,
deepin: true,
rockylinux: true,
rocky: true,
almalinux: false,
epel: false,
fedora: true,
opencloudos: false,
openeuler: true,
anolis: false,
openkylin: true,
alpinelinux: false,
alpine: false,
armbian: false,
proxmox: false,
linuxmint: true,
gentoo: true,
nix: false,
raspberry: false,
nix_channels: false,
raspberrypi: false,
manjaro: false,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '火山引擎' : window.location.pathname.includes('/en') ? 'Volcengine' : '火山引擎',
officialName: window.location.pathname.includes('/zh-Hant') ? '火山引擎開源軟體鏡像站' : window.location.pathname.includes('/en') ? 'Volcengine Open Source Software Mirror' : '火山引擎开源软件镜像站',
name: __isZhHant ? '火山引擎' : __isEn ? 'Volcengine' : '火山引擎',
officialName: __isZhHant ? '火山引擎開源軟體鏡像站' : __isEn ? 'Volcengine Open Source Software Mirror' : '火山引擎开源软件镜像站',
icon: 'volcengine.svg',
iconStyle: { verticalAlign: '-0.25em' },
url: 'https://developer.volcengine.com/mirror',
domain: 'mirrors.volces.com',
ipv6: false,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: false,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: 'incompatible',
rocky: 'incompatible',
almalinux: true,
epel: true,
fedora: true,
opencloudos: false,
openeuler: true,
anolis: false,
openkylin: false,
alpinelinux: true,
alpine: true,
armbian: false,
proxmox: false,
linuxmint: false,
gentoo: false,
nix: false,
raspberry: false,
nix_channels: false,
raspberrypi: false,
manjaro: false,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '清華大學' : window.location.pathname.includes('/en') ? 'Tsinghua University' : '清华大学',
officialName: window.location.pathname.includes('/zh-Hant') ? '清華大學開源軟體鏡像站' : window.location.pathname.includes('/en') ? 'Tsinghua University Open Source Mirror' : '清华大学开源软件镜像站',
name: __isZhHant ? '清華大學' : __isEn ? 'Tsinghua University' : '清华大学',
officialName: __isZhHant ? '清華大學開源軟體鏡像站' : __isEn ? 'Tsinghua University Open Source Mirror' : '清华大学开源软件镜像站',
icon: 'tsinghua.png',
iconStyle: { verticalAlign: '-0.3em' },
url: 'https://mirrors.tuna.tsinghua.edu.cn',
domain: 'mirrors.tuna.tsinghua.edu.cn',
ipv6: true,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: false,
rocky: false,
almalinux: false,
epel: true,
fedora: true,
opencloudos: false,
openeuler: true,
anolis: false,
openkylin: false,
alpinelinux: true,
alpine: true,
armbian: true,
proxmox: true,
linuxmint: true,
gentoo: true,
nix: true,
raspberry: true,
nix_channels: true,
raspberrypi: true,
manjaro: true,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '北京大學' : window.location.pathname.includes('/en') ? 'Peking University' : '北京大学',
officialName: window.location.pathname.includes('/zh-Hant') ? '北京大學開源鏡像站' : window.location.pathname.includes('/en') ? 'Peking University Open Source Mirror' : '北京大学开源镜像站',
name: __isZhHant ? '北京大學' : __isEn ? 'Peking University' : '北京大学',
officialName: __isZhHant ? '北京大學開源鏡像站' : __isEn ? 'Peking University Open Source Mirror' : '北京大学开源镜像站',
icon: 'pku.ico',
iconStyle: { verticalAlign: '-0.2em' },
url: 'https://mirrors.pku.edu.cn/Mirrors',
domain: 'mirrors.pku.edu.cn',
ipv6: true,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: false,
kali: false,
deepin: false,
rockylinux: true,
rocky: true,
almalinux: true,
epel: true,
fedora: false,
opencloudos: false,
openeuler: true,
anolis: false,
openkylin: false,
alpinelinux: false,
alpine: false,
armbian: false,
proxmox: false,
linuxmint: false,
gentoo: false,
nix: false,
raspberry: false,
nix_channels: false,
raspberrypi: false,
manjaro: true,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '浙江大學' : window.location.pathname.includes('/en') ? 'Zhejiang University' : '浙江大学',
officialName: window.location.pathname.includes('/zh-Hant') ? '浙江大學鏡像站' : window.location.pathname.includes('/en') ? 'Zhejiang University Mirror Site' : '浙江大学镜像站',
name: __isZhHant ? '浙江大學' : __isEn ? 'Zhejiang University' : '浙江大学',
officialName: __isZhHant ? '浙江大學鏡像站' : __isEn ? 'Zhejiang University Mirror Site' : '浙江大学镜像站',
icon: 'zju.ico',
iconStyle: { verticalAlign: '-0.15em' },
url: 'https://mirrors.zju.edu.cn',
domain: 'mirrors.zju.edu.cn',
ipv6: true,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: true,
rocky: true,
almalinux: true,
epel: true,
fedora: true,
opencloudos: false,
openeuler: true,
anolis: true,
openkylin: false,
alpinelinux: true,
alpine: true,
armbian: false,
proxmox: false,
linuxmint: true,
gentoo: true,
nix: false,
raspberry: false,
nix_channels: false,
raspberrypi: false,
manjaro: true,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '南京大學' : window.location.pathname.includes('/en') ? 'Nanjing University' : '南京大学',
officialName: window.location.pathname.includes('/zh-Hant') ? '南京大學開源鏡像站' : window.location.pathname.includes('/en') ? 'Nanjing University Open Source Mirror' : '南京大学开源镜像站',
name: __isZhHant ? '南京大學' : __isEn ? 'Nanjing University' : '南京大学',
officialName: __isZhHant ? '南京大學開源鏡像站' : __isEn ? 'Nanjing University Open Source Mirror' : '南京大学开源镜像站',
icon: 'nju.ico',
iconStyle: { verticalAlign: '-0.3em' },
url: 'https://mirrors.nju.edu.cn',
domain: 'mirrors.nju.edu.cn',
ipv6: true,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: true,
rocky: true,
almalinux: true,
epel: true,
fedora: true,
opencloudos: true,
openeuler: true,
anolis: true,
openkylin: true,
alpinelinux: true,
alpine: true,
armbian: true,
proxmox: true,
linuxmint: true,
gentoo: true,
nix: true,
raspberry: true,
nix_channels: true,
raspberrypi: true,
manjaro: true,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '蘭州大學' : window.location.pathname.includes('/en') ? 'Lanzhou University' : '兰州大学',
officialName: window.location.pathname.includes('/zh-Hant') ? '蘭州大學開源軟體鏡像站' : window.location.pathname.includes('/en') ? 'Lanzhou University Open Source Software Mirror' : '兰州大学开源软件镜像站',
name: __isZhHant ? '蘭州大學' : __isEn ? 'Lanzhou University' : '兰州大学',
officialName: __isZhHant ? '蘭州大學開源軟體鏡像站' : __isEn ? 'Lanzhou University Open Source Software Mirror' : '兰州大学开源软件镜像站',
icon: 'lzu.png',
iconStyle: { verticalAlign: '-0.25em' },
url: 'https://mirror.lzu.edu.cn',
domain: 'mirror.lzu.edu.cn',
ipv6: true,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: true,
rocky: true,
almalinux: true,
epel: true,
fedora: true,
opencloudos: false,
openeuler: true,
anolis: false,
openkylin: true,
alpinelinux: true,
alpine: true,
armbian: false,
proxmox: false,
linuxmint: true,
gentoo: true,
nix: false,
raspberry: false,
nix_channels: false,
raspberrypi: false,
manjaro: true,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '上海交通大學' : window.location.pathname.includes('/en') ? 'Shanghai Jiao Tong University' : '上海交通大学',
officialName: window.location.pathname.includes('/zh-Hant') ? '上海交通大學思源鏡像站' : window.location.pathname.includes('/en') ? 'Shanghai Jiao Tong University Siyuan Mirror' : '上海交通大学思源镜像站',
name: __isZhHant ? '上海交通大學' : __isEn ? 'Shanghai Jiao Tong University' : '上海交通大学',
officialName: __isZhHant ? '上海交通大學思源鏡像站' : __isEn ? 'Shanghai Jiao Tong University Siyuan Mirror' : '上海交通大学思源镜像站',
icon: 'sjtu.ico',
iconStyle: { verticalAlign: '-0.15em' },
url: 'https://mirror.sjtu.edu.cn',
domain: 'mirror.sjtu.edu.cn',
ipv6: true,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: true,
rocky: true,
almalinux: true,
epel: true,
fedora: 'incompatible',
opencloudos: true,
openeuler: true,
anolis: false,
openkylin: true,
alpinelinux: true,
alpine: true,
armbian: true,
proxmox: false,
linuxmint: true,
gentoo: true,
nix: false,
raspberry: true,
nix_channels: false,
raspberrypi: true,
manjaro: true,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '重慶郵電大學' : window.location.pathname.includes('/en') ? 'Chongqing University of Posts and Telecommunications' : '重庆邮电大学',
officialName: window.location.pathname.includes('/zh-Hant') ? '重慶郵電大學開源鏡像站' : window.location.pathname.includes('/en') ? 'Chongqing University of Posts and Telecommunications Open Source Mirror' : '重庆邮电大学开源镜像站',
name: __isZhHant ? '重慶郵電大學' : __isEn ? 'Chongqing University of Posts and Telecommunications' : '重庆邮电大学',
officialName: __isZhHant ? '重慶郵電大學開源鏡像站' : __isEn ? 'Chongqing University of Posts and Telecommunications Open Source Mirror' : '重庆邮电大学开源镜像站',
icon: 'cqupt.ico',
iconStyle: {},
url: 'https://mirrors.cqupt.edu.cn',
domain: 'mirrors.cqupt.edu.cn',
ipv6: true,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: false,
rocky: false,
almalinux: true,
epel: true,
fedora: true,
opencloudos: false,
openeuler: true,
anolis: false,
openkylin: false,
alpinelinux: true,
alpine: true,
armbian: true,
proxmox: true,
linuxmint: false,
gentoo: false,
nix: true,
raspberry: true,
nix_channels: true,
raspberrypi: true,
manjaro: true,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '中國科學技術大學' : window.location.pathname.includes('/en') ? 'University of Science and Technology of China' : '中国科学技术大学',
officialName: window.location.pathname.includes('/zh-Hant') ? '中國科學技術大學開源軟體鏡像站' : window.location.pathname.includes('/en') ? 'USTC Open Source Software Mirror' : '中国科学技术大学开源软件镜像站',
name: __isZhHant ? '中國科學技術大學' : __isEn ? 'University of Science and Technology of China' : '中国科学技术大学',
officialName: __isZhHant ? '中國科學技術大學開源軟體鏡像站' : __isEn ? 'University of Science and Technology of China Open Source Software Mirror' : '中国科学技术大学开源软件镜像站',
icon: 'ustc.png',
iconStyle: { verticalAlign: '-0.2em' },
url: 'https://mirrors.ustc.edu.cn',
domain: 'mirrors.ustc.edu.cn',
ipv6: true,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: true,
rocky: true,
almalinux: false,
epel: true,
fedora: true,
opencloudos: false,
openeuler: true,
anolis: false,
openkylin: false,
alpinelinux: true,
alpine: true,
armbian: true,
proxmox: true,
linuxmint: true,
gentoo: true,
nix: true,
raspberry: true,
nix_channels: true,
raspberrypi: true,
manjaro: true,
},
{
name: window.location.pathname.includes('/zh-Hant') ? '中國科學院軟體研究所' : window.location.pathname.includes('/en') ? 'Institute of Software, Chinese Academy of Sciences (ISCAS)' : '中国科学院软件研究所',
officialName: window.location.pathname.includes('/zh-Hant') ? 'ISCAS 開源鏡像站' : window.location.pathname.includes('/en') ? 'ISCAS Open Source Mirror' : 'ISCAS 开源镜像站',
name: __isZhHant ? '中國科學院軟體研究所' : __isEn ? 'Institute of Software, Chinese Academy of Sciences (ISCAS)' : '中国科学院软件研究所',
officialName: __isZhHant ? 'ISCAS 開源鏡像站' : __isEn ? 'ISCAS Open Source Mirror' : 'ISCAS 开源镜像站',
icon: 'iscas.png',
iconStyle: { verticalAlign: '-0.25em' },
url: 'https://mirror.iscas.ac.cn',
domain: 'mirror.iscas.ac.cn',
ipv6: false,
debian: true,
ubuntu: true,
centos: true,
centos_stream: true,
opensuse: true,
archlinux: true,
kalilinux: true,
kali: true,
deepin: true,
rockylinux: true,
rocky: true,
almalinux: true,
epel: true,
fedora: true,
opencloudos: true,
openeuler: true,
anolis: false,
openkylin: true,
alpinelinux: true,
alpine: true,
armbian: true,
proxmox: true,
linuxmint: true,
gentoo: true,
nix: true,
raspberry: true,
nix_channels: true,
raspberrypi: true,
manjaro: true,
},
]
@@ -384,7 +534,7 @@ const mirrorsTableData = [
const mirrorsTableColumns = [
{
colKey: 'name',
title: window.location.pathname.includes('/zh-Hant') ? '鏡像站' : window.location.pathname.includes('/en') ? 'Mirror Site' : '镜像站',
title: __isZhHant ? '鏡像站' : __isEn ? 'Mirror Site' : '镜像站',
align: 'left',
width: '180',
fixed: 'left',
@@ -400,7 +550,37 @@ const mirrorsTableColumns = [
title: 'EPEL',
align: 'center',
width: '90',
tooltip: 'EPEL (Extra Packages for Enterprise Linux) ' + (window.location.pathname.includes('/zh-Hant') ? '是由 Fedora 組織維護的一個附加軟體包倉庫,它主要適用於除 Fedora 作業系統以外的紅帽系 Linux 發行版' : window.location.pathname.includes('/en') ? 'is an additional package repository maintained by the Fedora organization. It is mainly applicable to Red Hat Linux distributions other than the Fedora operating system.' : '是由 Fedora 组织维护的一个附加软件包仓库,它主要适用于除 Fedora 操作系统以外的红帽系 Linux 发行版'),
tooltip: 'EPEL (Extra Packages for Enterprise Linux) ' + (__isZhHant ? '是由 Fedora 組織維護的一個附加軟體包倉庫,它主要適用於除 Fedora 作業系統以外的紅帽系 Linux 發行版' : __isEn ? 'is an additional package repository maintained by the Fedora organization. It is mainly applicable to Red Hat Linux distributions other than the Fedora operating system.' : '是由 Fedora 组织维护的一个附加软件包仓库,它主要适用于除 Fedora 操作系统以外的红帽系 Linux 发行版'),
},
// {
// colKey: 'debian',
// title: 'Debian',
// align: 'center',
// width: '80',
// },
// {
// colKey: 'ubuntu',
// title: 'Ubuntu',
// align: 'center',
// width: '80',
// },
// {
// colKey: 'centos',
// title: 'CentOS',
// align: 'center',
// width: '80',
// },
{
colKey: 'centos_stream',
title: 'CentOS Stream',
align: 'center',
width: '150',
},
{
colKey: 'opensuse',
title: 'openSUSE',
align: 'center',
width: '110',
},
{
colKey: 'archlinux',
@@ -415,7 +595,7 @@ const mirrorsTableColumns = [
width: '100',
},
{
colKey: 'kalilinux',
colKey: 'kali',
title: 'Kali Linux',
align: 'center',
width: '110',
@@ -433,7 +613,7 @@ const mirrorsTableColumns = [
width: '90',
},
{
colKey: 'raspberry',
colKey: 'raspberrypi',
title: 'Raspberry Pi OS',
align: 'center',
width: '150',
@@ -457,7 +637,7 @@ const mirrorsTableColumns = [
width: '90',
},
{
colKey: 'rockylinux',
colKey: 'rocky',
title: 'Rocky Linux',
align: 'center',
width: '120',
@@ -474,6 +654,12 @@ const mirrorsTableColumns = [
align: 'center',
width: '140',
},
// {
// colKey: 'openeuler',
// title: 'openEuler',
// align: 'center',
// width: '110',
// },
{
colKey: 'anolis',
title: 'Anolis OS',
@@ -487,7 +673,7 @@ const mirrorsTableColumns = [
width: '110',
},
{
colKey: 'alpinelinux',
colKey: 'alpine',
title: 'Alpine Linux',
align: 'center',
width: '130',
@@ -499,31 +685,197 @@ const mirrorsTableColumns = [
width: '90',
},
{
colKey: 'nix',
colKey: 'nix_channels',
title: 'NixOS',
align: 'center',
width: '80',
},
].map((item) => {
if (['ipv6', 'epel', 'archlinux', 'manjaro', 'kalilinux', 'armbian', 'deepin', 'raspberry', 'linuxmint', 'proxmox', 'fedora', 'rockylinux', 'almalinux', 'opencloudos', 'anolis', 'openkylin', 'alpinelinux', 'gentoo', 'nix'].includes(item.colKey)) {
item.sortType = 'all'
item.sorter = (a, b) => {
const getValue = (row) => {
if (typeof row[item.colKey] === 'boolean') {
return row[item.colKey] ? 0 : 1
if (['ipv6', 'debian', 'ubuntu', 'centos', 'centos_stream', 'opensuse', 'epel', 'archlinux', 'manjaro', 'kali', 'armbian', 'deepin', 'raspberrypi', 'linuxmint', 'proxmox', 'fedora', 'rocky', 'almalinux', 'opencloudos', 'openeuler', 'anolis', 'openkylin', 'alpine', 'gentoo', 'nix_channels'].includes(item.colKey)) {
const labelSupported = __isZhHant ? '支持' : __isEn ? 'Supported' : '支持'
const labelUnsupported = __isZhHant ? '不支持' : __isEn ? 'Unsupported' : '不支持'
const labelIncompatible = __isZhHant ? '不兼容' : __isEn ? 'Incompatible' : '不兼容'
item.filter = {
label: item.title || item.colKey,
type: 'single',
list: [
{ label: labelSupported, value: 'supported' },
{ label: labelUnsupported, value: 'unsupported' },
{ label: labelIncompatible, value: 'incompatible' },
],
confirmEvents: ['onChange'],
filterMethod(value, row) {
try {
const key = item.colKey
const cell = row && Object.prototype.hasOwnProperty.call(row, key) ? row[key] : undefined
if (value === 'supported') return cell === true
if (value === 'unsupported') return cell === false
if (value === 'incompatible') return cell === 'incompatible'
return false
} catch (e) {
return false
}
return 2
},
}
item.filterMethod = function (value, row) {
try {
const key = item.colKey
const cell = row && Object.prototype.hasOwnProperty.call(row, key) ? row[key] : undefined
if (value === 'supported') return cell === true
if (value === 'unsupported') return cell === false
if (value === 'incompatible') return cell === 'incompatible'
return false
} catch (e) {
return false
}
const aValue = getValue(a)
const bValue = getValue(b)
return aValue - bValue
}
}
return item
})
const mirrorsTableConfig = {
sortAscendingOperationText: window.location.pathname.includes('/zh-Hant') ? '点击升序' : window.location.pathname.includes('/en') ? 'click to sort ascending' : '点击升序',
sortCancelOperationText: window.location.pathname.includes('/zh-Hant') ? '点击取消排序' : window.location.pathname.includes('/en') ? 'click to cancel sorting' : '点击取消排序',
sortDescendingOperationText: window.location.pathname.includes('/zh-Hant') ? '点击降序' : window.location.pathname.includes('/en') ? 'click to sort descending' : '点击降序',
}
const mirrorsTableFilterSelectOptions = [
{ label: __isZhHant ? '全選' : __isEn ? 'Select All' : '全选', checkAll: true },
{
value: 'ipv6',
label: 'IPv6',
},
{
group: 'Debian',
children: [
// {
// value: 'debian',
// label: 'Debian',
// iconName: 'debian.svg',
// },
// {
// value: 'ubuntu',
// label: 'Ubuntu',
// iconName: 'ubuntu.svg',
// },
{
value: 'kali',
label: 'Kali Linux',
iconName: 'kali-linux.svg',
},
{
value: 'armbian',
label: 'Armbian',
iconName: 'armbian.png',
},
{
value: 'raspberrypi',
label: 'Raspberry Pi OS',
iconName: 'raspberry-pi.png',
},
{
value: 'openkylin',
label: 'openKylin',
iconName: 'openkylin.ico',
},
{
value: 'linuxmint',
label: 'Linux Mint',
iconName: 'linux-mint.ico',
},
{
value: 'deepin',
label: 'Deepin',
iconName: 'deepin.png',
},
{
value: 'proxmox',
label: 'Proxmox VE',
iconName: 'proxmox.svg',
},
],
},
{
group: 'RedHat',
children: [
{
value: 'fedora',
label: 'Fedora',
iconName: 'fedora.ico',
},
// {
// value: 'centos',
// label: 'CentOS',
// iconName: 'centos.svg',
// },
{
value: 'centos_stream',
label: 'CentOS Stream',
iconName: 'centos.svg',
},
{
value: 'rocky',
label: 'Rocky Linux',
iconName: 'rocky-linux.svg',
},
{
value: 'almalinux',
label: 'AlmaLinux',
iconName: 'almalinux.svg',
},
// {
// value: 'openeuler',
// label: 'openEuler',
// iconName: 'openeuler.ico',
// },
{
value: 'opencloudos',
label: 'OpenCloudOS',
iconName: 'opencloudos.png',
},
{
value: 'anolis',
label: 'Anolis OS',
iconName: 'anolis.png',
},
{
value: 'epel',
label: 'EPEL',
},
],
},
{
group: 'Arch Linux',
children: [
{
value: 'archlinux',
label: 'Arch Linux',
iconName: 'arch-linux.ico',
},
{
value: 'manjaro',
label: 'Manjaro',
iconName: 'manjaro.svg',
},
],
},
{
group: 'Other',
children: [
{
value: 'opensuse',
label: 'openSUSE',
iconName: 'opensuse.svg',
},
{
value: 'alpine',
label: 'Alpine Linux',
iconName: 'alpine.png',
},
{
value: 'gentoo',
label: 'Gentoo',
iconName: 'gentoo.svg',
},
{
value: 'nix_channels',
label: 'NixOS',
iconName: 'nixos.svg',
},
],
},
]

View File

@@ -1,71 +1,385 @@
ComponentSystem.register('mirrors-table', {
template: `
<div>
<t-config-provider :global-config="{ table: tableConfig }">
<t-table
:columns="columns"
:data="data"
row-key="name"
size="small"
verticalAlign="bottom"
@data-change="dataChange"
>
<template v-for="col in columns" :key="col.colKey" #[col.title]>
<div v-if="col.tooltip" class="t-table__th-cell-inner">
<t-space style="gap: 4px">
<span>{{ col.title }}</span>
<t-tooltip :content="col.tooltip" placement="bottom" :show-arrow="false">
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24"><path fill="currentColor" d="M11.95 18q.525 0 .888-.363t.362-.887t-.362-.888t-.888-.362t-.887.363t-.363.887t.363.888t.887.362m.05 4q-2.075 0-3.9-.788t-3.175-2.137T2.788 15.9T2 12t.788-3.9t2.137-3.175T8.1 2.788T12 2t3.9.788t3.175 2.137T21.213 8.1T22 12t-.788 3.9t-2.137 3.175t-3.175 2.138T12 22m0-2q3.35 0 5.675-2.325T20 12t-2.325-5.675T12 4T6.325 6.325T4 12t2.325 5.675T12 20m.1-12.3q.625 0 1.088.4t.462 1q0 .55-.337.975t-.763.8q-.575.5-1.012 1.1t-.438 1.35q0 .35.263.588t.612.237q.375 0 .638-.25t.337-.625q.1-.525.45-.937t.75-.788q.575-.55.988-1.2t.412-1.45q0-1.275-1.037-2.087T12.1 6q-.95 0-1.812.4T8.975 7.625q-.175.3-.112.638t.337.512q.35.2.725.125t.625-.425q.275-.375.688-.575t.862-.2"/></svg>
</t-tooltip>
<div>
<t-config-provider :global-config="globalConfig">
<t-space v-if="!isMobile" align="center" style="margin-bottom: 8px; display: flex; flex-flow: wrap; justify-content: flex-end">
<t-popup placement="bottom" :show-arrow="false">
<template #content>
<t-checkbox-group v-model="selectedCellStatuses" style="padding: 6px" @change="onCellStatusChange">
<t-space align="start" direction="vertical" style="gap: 4px">
<t-checkbox value="supported">
<t-space align="center" style="gap: 2px">
<t-tag theme="success" variant="light" style="background-color: transparent; vertical-align: -0.35em">
<template #icon>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><path fill="currentColor" d="M21 7L9 19l-5.5-5.5l1.41-1.41L9 16.17L19.59 5.59L21 7Z"></svg>
</template>
</t-tag>
<span>{{ statusLabels.supported }}</span>
</t-space>
</t-checkbox>
<t-checkbox value="unsupported">
<t-space align="center" style="gap: 0">
<t-tag theme="danger" variant="light" style="background-color: transparent; vertical-align: -0.35em">
<template #icon>
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" style="vertical-align: -0.2em"><path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z"></svg>
</template>
</t-tag>
<span>{{ statusLabels.unsupported }}</span>
</t-space>
</t-checkbox>
<t-checkbox value="incompatible">
<t-space align="center" style="gap: 2px">
<t-tag theme="warning" variant="light" style="background-color: transparent; vertical-align: -0.35em">
<svg xmlns="http://www.w3.org/2000/svg" style="margin-left: 2px" width="16" height="16" viewBox="0 0 24 24" style="vertical-align: -0.15em"><path fill="#F6B604" d="M22.11 21.46L2.39 1.73L1.11 3l2.95 2.95A9.95 9.95 0 0 0 2 12c0 5.5 4.5 10 10 10c2.28 0 4.37-.77 6.05-2.06l2.79 2.79l1.27-1.27M12 20c-4.42 0-8-3.58-8-8c0-1.73.56-3.32 1.5-4.62L16.62 18.5A7.78 7.78 0 0 1 12 20M8.17 4.97L6.72 3.5C8.25 2.56 10.06 2 12 2c5.5 0 10 4.5 10 10c0 1.94-.56 3.75-1.5 5.28l-1.47-1.45c.62-1.14.97-2.44.97-3.83c0-4.42-3.58-8-8-8c-1.39 0-2.69.35-3.83.97Z"></svg>
</t-tag>
<span>{{ statusLabels.incompatible }}</span>
</t-space>
</t-checkbox>
</t-space>
</t-checkbox-group>
</template>
<t-button variant="text" shape="circle"><svg fill="none" viewBox="0 0 24 24" width="1em" height="1em" class="t-icon t-icon-filter" style="fill: none;"><g id="filter"><path id="fill1" fill="transparent" d="M19.5 4H4.5L10.5 12.5V20H13.5V12.5L19.5 4Z" fill-rule="evenodd" clip-rule="evenodd"></path><path id="stroke1" stroke="currentColor" d="M19.5 4H4.5L10.5 12.5V20H13.5V12.5L19.5 4Z" fill-rule="evenodd" stroke-linecap="square" stroke-width="2" clip-rule="evenodd"></path></g></svg></t-button>
</t-popup>
<t-select
v-model="selectedRowFilters"
:options="rowFilterOptionsRendered"
:min-collapsed-num="1"
multiple
clearable
:placeholder="rowSelectPlaceholder"
style="width: 250px"
@change="onRowFilterChange"
/>
<t-select
v-model="selectedColumnFilters"
:options="filterOptions"
:min-collapsed-num="1"
multiple
clearable
:placeholder="selectPlaceholder"
style="width: 230px"
@change="onFilterChange"
/>
</t-space>
<t-table
:columns="columns"
:data="data"
row-key="name"
size="small"
verticalAlign="bottom"
@data-change="dataChange"
@filter-change="onTableFilterChange"
>
<template v-for="col in columns" :key="col.colKey" #[col.colKey]="{ row }">
<div v-if="col.colKey === 'name'">
<t-popup placement="bottom" :show-arrow="false" v-if="cellStatusEnabled">
<template #content>
<t-space direction="vertical" algin="center" style="gap: 2px">
<span>{{ row.officialName }}</span>
<a :href="row.url" target="_blank" style="color: var(--md-typeset-a-color)">{{ row.domain }}</a>
</t-space>
</div>
<div v-else class="t-table__th-cell-inner">{{ col.title }}</div>
</template>
<template v-for="col in columns" :key="col.colKey" #[col.colKey]="{ row }">
<template v-if="col.colKey === 'name'">
<t-popup placement="bottom" :show-arrow="false">
<template #content>
<t-space direction="vertical" algin="center" style="gap: 2px">
<span>{{ row.officialName }}</span>
<a :href="row.url" target="_blank" style="color: var(--md-typeset-a-color)">{{ row.domain }}</a>
</t-space>
</template>
<a :href="row.url" target="_blank">
<t-space align="center" style="gap: 6px">
<span style="display: flex; height: 16px; width: 16px; align-items: center; justify-content: center">
<img v-if="row.icon" :src="\`/assets/images/icon/mirrors/\${row.icon}\`" width="16" height="16">
</span>
<span>{{ row.name }}</span>
</t-space>
</template>
<a :href="row.url" target="_blank">
<t-space align="center" style="gap: 6px">
<span style="display: flex; height: 16px; width: 16px; align-items: center; justify-content: center">
<img v-if="row.icon" :src="'/assets/images/icon/mirrors/' + row.icon" width="16" height="16">
</span>
<span style="display: flex; align-items: center; justify-content: center">{{ row.name }}</span>
</t-space>
</a>
</t-popup>
</div>
<div v-else>
<t-tag v-if="typeof row[col.colKey] === 'boolean'" :theme="row[col.colKey] ? 'success' : 'danger'" variant="light" size="small" style="background-color: transparent; height: 26px">
<template #icon>
<div v-if="row[col.colKey] === true && !['ipv6'].includes(col.colKey) && showSupported">
<a :href="'https://' + row.domain + '/' + col.colKey.replace(/_/, '-')" target="_blank" style="color: var(--td-success-color)">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><path fill="currentColor" d="M21 7L9 19l-5.5-5.5l1.41-1.41L9 16.17L19.59 5.59L21 7Z"></svg>
</a>
</t-popup>
</div>
<svg v-else-if="row[col.colKey] === true && showSupported" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><path fill="currentColor" d="M21 7L9 19l-5.5-5.5l1.41-1.41L9 16.17L19.59 5.59L21 7Z"></svg>
<svg v-else-if="row[col.colKey] === false && showUnsupported" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z"></svg>
</template>
<template v-else>
<t-tag v-if="typeof row[col.colKey] === 'boolean'" :theme="row[col.colKey] ? 'success' : 'danger'" variant="light" size="small" style="background-color: transparent; height: 100%; vertical-align: -0.35em">
<template #icon>
<svg v-if="row[col.colKey]" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><path fill="currentColor" d="M21 7L9 19l-5.5-5.5l1.41-1.41L9 16.17L19.59 5.59L21 7Z"></svg>
<svg v-else xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" style="vertical-align: -0.2em"><path fill="currentColor" d="M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12L19 6.41Z"></svg>
</template>
</t-tag>
<t-tag v-else theme="warning" variant="light" size="small" style="background-color: transparent; vertical-align: -0.35em">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" style="vertical-align: -0.1em"><path fill="#F6B604" d="M22.11 21.46L2.39 1.73L1.11 3l2.95 2.95A9.95 9.95 0 0 0 2 12c0 5.5 4.5 10 10 10c2.28 0 4.37-.77 6.05-2.06l2.79 2.79l1.27-1.27M12 20c-4.42 0-8-3.58-8-8c0-1.73.56-3.32 1.5-4.62L16.62 18.5A7.78 7.78 0 0 1 12 20M8.17 4.97L6.72 3.5C8.25 2.56 10.06 2 12 2c5.5 0 10 4.5 10 10c0 1.94-.56 3.75-1.5 5.28l-1.47-1.45c.62-1.14.97-2.44.97-3.83c0-4.42-3.58-8-8-8c-1.39 0-2.69.35-3.83.97Z"></svg>
</t-tag>
</t-tag>
<t-tag v-else theme="warning" variant="light" size="small" style="background-color: transparent; height: 26px">
<template #icon>
<svg v-if="showIncompatible" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24"><path fill="#F6B604" d="M22.11 21.46L2.39 1.73L1.11 3l2.95 2.95A9.95 9.95 0 0 0 2 12c0 5.5 4.5 10 10 10c2.28 0 4.37-.77 6.05-2.06l2.79 2.79l1.27-1.27M12 20c-4.42 0-8-3.58-8-8c0-1.73.56-3.32 1.5-4.62L16.62 18.5A7.78 7.78 0 0 1 12 20M8.17 4.97L6.72 3.5C8.25 2.56 10.06 2 12 2c5.5 0 10 4.5 10 10c0 1.94-.56 3.75-1.5 5.28l-1.47-1.45c.62-1.14.97-2.44.97-3.83c0-4.42-3.58-8-8-8c-1.39 0-2.69.35-3.83.97Z"></svg>
</template>
</template>
</t-table>
</t-config-provider>
</div>
`,
</t-tag>
</template>
</template>
</t-table>
</t-config-provider>
</div>
`,
data() {
return {
allColumns: mirrorsTableColumns,
columns: mirrorsTableColumns,
data: mirrorsTableData,
tableConfig: mirrorsTableConfig,
originalData: mirrorsTableData,
data: mirrorsTableData.slice(),
rawFilterOptions: mirrorsTableFilterSelectOptions,
selectedColumnFilters: [],
selectedRowFilters: [],
selectedCellStatuses: ['supported', 'unsupported', 'incompatible'],
cellStatusEnabled: true,
activeTableFilters: {},
}
},
created() {
const allKeys = this._flattenFilterKeys(this.filterOptions)
this.selectedColumnFilters = allKeys.slice()
this.selectedRowFilters = Array.isArray(this.originalData) ? this.originalData.map((r) => r.name) : []
this._debouncedUpdateColumns = debounce(this._updateColumns.bind(this), 120)
this._debouncedUpdateRows = debounce(this._updateRows.bind(this), 120)
this._updateColumns()
this._updateRows()
},
computed: {
isMobile() {
return window.matchMedia('(max-width: 768px)').matches
},
localeFlags() {
const p = (window && window.location && window.location.pathname) || ''
return {
isZhHant: p.includes('/zh-Hant'),
isEn: p.includes('/en'),
}
},
globalConfig() {
const f = this.localeFlags
return {
animation: { include: ['expand', 'fade'], exclude: [] },
table: f.isZhHant
? {
empty: '\u66AB\u7121\u6578\u64DA',
loadingText: '\u6B63\u5728\u8F09\u5165\u4E2D\uFF0C\u8ACB\u7A0D\u5F8C',
loadingMoreText: '\u9EDE\u64CA\u8F09\u5165\u66F4\u591A',
filterInputPlaceholder: '\u8ACB\u8F38\u5165\u5185\u5BB9\uFF08\u7121\u9ED8\u8A8D\u503C\uFF09',
sortAscendingOperationText: '\u9EDE\u64CA\u5347\u5E8F',
sortCancelOperationText: '\u9EDE\u64CA\u53D6\u6D88\u6392\u5E8F',
sortDescendingOperationText: '\u9EDE\u64CA\u964D\u5E8F',
clearFilterResultButtonText: '\u6E05\u7A7A\u7BE9\u9078',
columnConfigButtonText: '\u884C\u914D\u7F6E',
columnConfigTitleText: '\u8868\u683C\u884C\u914D\u7F6E',
columnConfigDescriptionText: '\u8ACB\u9078\u64C7\u9700\u8981\u5728\u8868\u683C\u4E2D\u986F\u793A\u7684\u6578\u64DA\u884C',
confirmText: '\u78BA\u8A8D',
cancelText: '\u53D6\u6D88',
resetText: '\u91CD\u7F6E',
selectAllText: '\u5168\u9078',
searchResultText: '\u641C\u5C0B"{result}"\uFF0C\u627E\u5230{count}\u9805\u7D50\u679C',
}
: f.isEn
? {
empty: 'Empty Data',
loadingText: 'loading...',
loadingMoreText: 'loading more',
filterInputPlaceholder: '',
sortAscendingOperationText: 'click to sort ascending',
sortCancelOperationText: 'click to cancel sorting',
sortDescendingOperationText: 'click to sort descending',
clearFilterResultButtonText: 'Clear',
columnConfigButtonText: 'Column Config',
columnConfigTitleText: 'Table Column Config',
columnConfigDescriptionText: 'Please select columns to show them in the table',
confirmText: 'Confirm',
cancelText: 'Cancel',
resetText: 'Reset',
selectAllText: 'Select All',
searchResultText: 'Search "{result}". Found no items. | Search "{result}". Found 1 item. | Search "{result}". Found {count} items.',
}
: undefined,
select: f.isZhHant
? {
empty: '\u66AB\u7121\u6578\u64DA',
loadingText: '\u8F09\u5165\u4E2D',
placeholder: '\u8ACB\u9078\u64C7',
}
: f.isEn
? {
empty: 'Empty Data',
loadingText: 'loading...',
placeholder: 'please select',
}
: undefined,
}
},
selectPlaceholder() {
const f = this.localeFlags
return f.isZhHant ? '选择要显示的列' : f.isEn ? 'Select columns to show' : '选择要显示的列'
},
rowSelectPlaceholder() {
const f = this.localeFlags
return f.isZhHant ? '筛选显示的镜像' : f.isEn ? 'Filter mirrors to show' : '筛选显示的镜像'
},
rowFilterOptions() {
const f = this.localeFlags
const arr = Array.isArray(this.originalData) ? this.originalData.map((r) => ({ value: r.name, label: r.name, iconName: r.icon })) : []
const head = { value: '__all__', label: f.isZhHant ? '全選' : f.isEn ? 'Select All' : '全选', checkAll: true }
return [head].concat(arr)
},
rowFilterOptionsRendered() {
return Array.isArray(this.rowFilterOptions) ? this.rowFilterOptions.map((o) => this._mapOptionForRow(o)) : []
},
statusLabels() {
const f = this.localeFlags
return {
supported: f.isZhHant ? '支援' : f.isEn ? 'Supported' : '支持',
unsupported: f.isZhHant ? '不支援' : f.isEn ? 'Unsupported' : '不支持',
incompatible: f.isZhHant ? '不相容' : f.isEn ? 'Incompatible' : '不兼容',
}
},
showSupported() {
return Array.isArray(this.selectedCellStatuses) && this.selectedCellStatuses.includes('supported')
},
showUnsupported() {
return Array.isArray(this.selectedCellStatuses) && this.selectedCellStatuses.includes('unsupported')
},
showIncompatible() {
return Array.isArray(this.selectedCellStatuses) && this.selectedCellStatuses.includes('incompatible')
},
filterOptions() {
return Array.isArray(this.rawFilterOptions) ? this.rawFilterOptions.map((o) => this._mapOptionForFilter(o)) : []
},
},
methods: {
_mapOptionForRow(opt) {
const prefix = '/assets/images/icon/mirrors/'
const copy = Object.assign({}, opt)
if (copy.iconName) copy.prefixIcon = prefix + copy.iconName
copy.content = function (h, ctx) {
const option = (ctx && ctx.option) || copy
const children = []
if (option.iconName) {
children.push(h('img', { src: prefix + option.iconName, width: 16, height: 16, style: 'vertical-align: middle' }))
}
children.push(h('span', { style: option.iconName ? 'margin-left: 8px' : '' }, option.label || option.value || ''))
return h('div', { style: 'display: flex; align-items: center' }, children)
}
return copy
},
_mapOptionForFilter(opt) {
const prefix = '/assets/images/icon/'
const copy = Object.assign({}, opt)
if (copy.iconName) copy.prefixIcon = prefix + copy.iconName
copy.content = function (h, ctx) {
const option = (ctx && ctx.option) || copy
const children = []
if (option.iconName) {
children.push(h('img', { src: prefix + option.iconName, width: 16, height: 16, style: 'vertical-align: middle' }))
}
children.push(h('span', { style: option.iconName ? 'margin-left: 8px' : '' }, option.label || option.value || ''))
return h('div', { style: 'display: flex; align-items: center' }, children)
}
if (Array.isArray(copy.children)) {
copy.children = copy.children.map((c) => this._mapOptionForFilter(c))
}
return copy
},
dataChange(data) {
this.data = data
try {
const hasColumnFilters = this.activeTableFilters && Object.keys(this.activeTableFilters).length > 0
const hasRowFilters = Array.isArray(this.selectedRowFilters) && this.selectedRowFilters.length > 0
if (hasColumnFilters || hasRowFilters) {
return
}
this.data = data
} catch (e) { console.error('mirrors-table dataChange error', e) }
},
onFilterChange() {
if (this._debouncedUpdateColumns) this._debouncedUpdateColumns()
else this._updateColumns()
},
onRowFilterChange() {
try {
if (Array.isArray(this.selectedRowFilters) && this.selectedRowFilters.includes('__all__')) {
this.selectedRowFilters = Array.isArray(this.originalData) ? this.originalData.map((r) => r.name) : []
}
} catch (e) { console.error('mirrors-table onRowFilterChange error', e) }
if (this._debouncedUpdateRows) this._debouncedUpdateRows()
else this._updateRows()
},
onCellStatusChange() {
if (this._debouncedUpdateRows) this._debouncedUpdateRows()
else this._updateRows()
},
onTableFilterChange(filters) {
try {
this.activeTableFilters = filters || {}
if (this._debouncedUpdateRows) this._debouncedUpdateRows()
else this._updateRows()
} catch (e) { console.error('mirrors-table onTableFilterChange error', e) }
},
_updateColumns() {
try {
const keys = new Set(this.selectedColumnFilters || [])
this.columns = this.allColumns.filter((col) => col.colKey === 'name' || keys.has(col.colKey))
} catch (e) {
this.columns = this.allColumns
}
},
_updateRows() {
try {
this._computeFilteredData()
} catch (e) {
console.error('mirrors-table _updateRows error', e)
this.data = this.originalData.slice()
}
},
_computeFilteredData() {
try {
let rows = Array.isArray(this.originalData) ? this.originalData.slice() : []
if (Array.isArray(this.selectedRowFilters) && this.selectedRowFilters.length) {
const names = new Set(this.selectedRowFilters || [])
rows = rows.filter((r) => names.has(r.name))
}
const filters = this.activeTableFilters || {}
const filterKeys = Object.keys(filters)
if (filterKeys.length) {
rows = rows.filter((row) => {
for (let i = 0; i < filterKeys.length; i++) {
const key = filterKeys[i]
let value = filters[key]
if (Array.isArray(value)) value = value.length ? value[0] : undefined
if (!value) continue
const cell = Object.prototype.hasOwnProperty.call(row, key) ? row[key] : undefined
if (value === 'supported') {
if (cell !== true) return false
} else if (value === 'unsupported') {
if (cell !== false) return false
} else if (value === 'incompatible') {
if (cell !== 'incompatible') return false
} else {
continue
}
}
return true
})
}
this.data = rows
} catch (e) {
console.error('mirrors-table _computeFilteredData error', e)
this.data = this.originalData.slice()
}
},
_flattenFilterKeys(options) {
const set = new Set()
options.forEach((opt) => {
if (opt.group && Array.isArray(opt.children)) {
opt.children.forEach((child) => {
if (child && child.value) set.add(child.value)
})
} else if (Array.isArray(opt.children)) {
opt.children.forEach((child) => {
if (child && child.value) set.add(child.value)
})
} else if (opt.value) {
set.add(opt.value)
}
})
return Array.from(set)
},
},
})

View File

@@ -78,7 +78,7 @@ const OramaI18nData = {
// get search box config
function getOramaSearchBoxConfig() {
const currentLang = window.location.pathname.includes('/zh-Hant') ? 'zh-Hant' : window.location.pathname.includes('/en') ? 'en' : 'zh-Hans'
const currentLang = __isZhHant ? 'zh-Hant' : __isEn ? 'en' : 'zh-Hans'
return {
themeConfig: {
// colors: {
@@ -139,7 +139,7 @@ function getOramaSearchBoxConfig() {
// localization search box component
function localizationOramaSearchBox(searchBox) {
if (!searchBox) return
const currentLang = window.location.pathname.includes('/zh-Hant') ? 'zh-Hant' : window.location.pathname.includes('/en') ? 'en' : 'zh-Hans'
const currentLang = __isZhHant ? 'zh-Hant' : __isEn ? 'en' : 'zh-Hans'
const askAiText = OramaI18nData[currentLang].askAiText
const searchText = OramaI18nData[currentLang].searchText
const observer = new MutationObserver((mutations, obs) => {