diff --git a/index.html b/index.html
index 143a2b6..d714576 100644
--- a/index.html
+++ b/index.html
@@ -4,7 +4,7 @@
-
Genshin Copilot Scripts
+ Genshin Copilot Scripts | BetterGI 更好的原神
diff --git a/src/App.vue b/src/App.vue
index 65226bc..c60211b 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -8,38 +8,36 @@
style="width: 320px"
@change="fetchRepoData"
>
- BetterGI 中央仓库
+ BetterGI 中央仓库
-
+
handleTreeSelect(selectedKeys, category.type)"
- :selectedKeys="searchConditions[category.type].tags"
- multiple
+ @select="(selectedKeys, event) => handleTreeSelect(selectedKeys, event, category.name)"
/>
-
+
-
- {{ author }}
+
+ {{ author }}
-
- {{ tag }}
+
+ {{ tag }}
-
+
{{ record.name }}
@@ -102,30 +100,22 @@ const columns = [
{ title: '操作', slotName: 'operations' },
];
-const getTabTitle = (type) => {
- const titles = {
- js: 'JS脚本',
- pathing: '地图追踪',
- macro: '键鼠脚本',
- combat: '战斗策略',
- tcg: '七圣召唤策略',
- onekey: '一键宏',
- };
- return titles[type] || type;
-};
-
const fetchRepoData = async () => {
if (!selectedRepo.value) return;
try {
const response = await fetch(selectedRepo.value);
const data = await response.json();
+
+ // 为所有节点生成 path
+ data.forEach(category => generatePaths(category));
+
repoData.value = data;
initializeSearchConditions();
// 初始化 tagColorMap
data.forEach(category => {
- category.list.forEach(item => {
+ traverseCategory(category, (item) => {
if (Array.isArray(item.tags)) {
item.tags.forEach(tag => {
if (tag && typeof tag === 'string' && !tagColorMap[tag]) {
@@ -141,32 +131,82 @@ const fetchRepoData = async () => {
}
};
-const getUniqueAuthors = (list) => {
- return [...new Set(list.map(item => item.author))];
+// 新增函数:为所有节点生成 path
+const generatePaths = (node, parentPath = '') => {
+ const currentPath = parentPath ? `${parentPath}/${node.name}` : node.name;
+ node.path = currentPath;
+
+ if (node.type === 'directory' && Array.isArray(node.children)) {
+ node.children.forEach(child => generatePaths(child, currentPath));
+ }
};
-const getUniqueTags = (list) => {
- return [...new Set(list.flatMap(item => item.tags))];
+const traverseCategory = (category, callback) => {
+ if (category.type === 'file') {
+ callback(category);
+ } else if (category.type === 'directory' && Array.isArray(category.children)) {
+ if (category.name === 'js') {
+ category.children.forEach(child => {
+ if (child.type === 'directory') {
+ callback(child);
+ } else {
+ traverseCategory(child, callback);
+ }
+ });
+ } else {
+ category.children.forEach(child => traverseCategory(child, callback));
+ }
+ }
};
-const filterData = (type) => {
- const condition = searchConditions[type];
- filteredData[type] = repoData.value.find(category => category.type === type).list.filter(item => {
+const getUniqueAuthors = (category) => {
+ const authors = new Set();
+ traverseCategory(category, (item) => {
+ if (item.author) authors.add(item.author);
+ });
+ return [...authors];
+};
+
+const getUniqueTags = (category) => {
+ const tags = new Set();
+ traverseCategory(category, (item) => {
+ if (Array.isArray(item.tags)) {
+ item.tags.forEach(tag => tags.add(tag));
+ }
+ });
+ return [...tags];
+};
+
+const filterData = (categoryName) => {
+ const category = repoData.value.find(cat => cat.name === categoryName);
+ const condition = searchConditions[categoryName];
+
+ const filtered = [];
+ traverseCategory(category, (item) => {
const nameMatch = !condition.name || item.name.toLowerCase().includes(condition.name.toLowerCase());
const authorMatch = !condition.author || item.author === condition.author;
- const tagMatch = condition.tags.length === 0 || condition.tags.some(tag => item.tags.includes(tag));
- return nameMatch && authorMatch && tagMatch;
+ const tagMatch = condition.tags.length === 0 || (Array.isArray(item.tags) && condition.tags.some(tag => item.tags.includes(tag)));
+ const pathMatch = !condition.path || (item.path && item.path.startsWith(condition.path) && item.path !== condition.path);
+ if (nameMatch && authorMatch && tagMatch && pathMatch && (item.type === 'file' || (category.name === 'js' && item.type === 'directory'))) {
+ filtered.push(item);
+ }
});
+
+ filteredData[categoryName] = filtered;
};
const initializeSearchConditions = () => {
repoData.value.forEach(category => {
- searchConditions[category.type] = {
+ searchConditions[category.name] = {
name: '',
author: '',
- tags: []
+ tags: [],
+ path: ''
};
- filteredData[category.type] = category.list;
+ filteredData[category.name] = [];
+ traverseCategory(category, (item) => {
+ filteredData[category.name].push(item);
+ });
});
};
@@ -190,10 +230,8 @@ const getTagColor = (tag) => {
onMounted(() => {
// 默认选中第一个仓库
- selectedRepo.value = 'https://raw.githubusercontent.com/babalae/bettergi-scripts-list/refs/heads/main/repo/items.json';
- fetchRepoData().then(() => {
- initializeSearchConditions();
- });
+ selectedRepo.value = 'https://raw.githubusercontent.com/babalae/bettergi-scripts-list/refs/heads/main/build/tree.json';
+ fetchRepoData();
});
const downloadScript = (script) => {
@@ -208,7 +246,6 @@ const showDetails = (script) => {
{ label: '作者', value: script.author },
{ label: '版本', value: script.version },
{ label: '描述', value: script.description || '无描述' },
- { label: '路径', value: script.path },
{ label: '标签', value: script.tags },
{ label: 'Hash', value: script.hash },
];
@@ -220,47 +257,50 @@ const closeDrawer = () => {
};
const getCategoryTree = (category) => {
- const tags = getUniqueTags(category.list);
- if (tags.length === 0) {
- return [];
- }
- if (category.type === 'tcg') {
- return [
- {
- title: getTabTitle(category.type),
- key: category.type,
- children: [{ title: '惊喜牌组', key: '惊喜牌组' }],
- selectable: false
+ const buildTree = (node) => {
+ if (node.type === 'file') {
+ return null;
}
- ];
- } else if (category.type === 'pathing') {
- return [
- {
- title: getTabTitle(category.type),
- key: category.type,
- children: tags.map(tag => ({ title: tag, key: tag })),
- selectable: false
- }
- ];
- }
- return [];
+ return {
+ title: node.name,
+ key: node.path,
+ children: Array.isArray(node.children)
+ ? node.children
+ .map(buildTree)
+ .filter(Boolean)
+ : undefined,
+ selectable: true
+ };
+ };
+ return [buildTree(category)].filter(Boolean);
};
const showTree = (category) => {
- if (getCategoryTree(category).length === 0) {
- return false;
- }
-
- return getUniqueTags(category.list).length > 1;
+ return category.name === 'pathing';
};
-const handleTreeSelect = (selectedKeys, categoryType) => {
- searchConditions[categoryType].tags = selectedKeys.filter(key => key !== categoryType);
- filterData(categoryType);
+const handleTreeSelect = (selectedKeys, event, categoryName) => {
+ const selectedNode = event.node;
+ searchConditions[categoryName].path = selectedNode.key;
+ filterData(categoryName);
};
-const handleTagSelect = (categoryType) => {
- filterData(categoryType);
+const handleTagSelect = (categoryName) => {
+ filterData(categoryName);
+};
+
+// 添加类别名称映射
+const categoryNameMap = {
+ 'pathing': '地图追踪',
+ 'js': 'JS脚本',
+ 'combat': '战斗策略',
+ 'tcg': '七圣召唤',
+ 'onekey': '一键宏'
+};
+
+// 添加获取显示名称的函数
+const getCategoryDisplayName = (name) => {
+ return categoryNameMap[name] || name;
};
@@ -268,6 +308,5 @@ const handleTagSelect = (categoryType) => {
.arco-tree {
background-color: var(--color-fill-2);
padding: 16px;
- /* border-radius: 4px; */
}
\ No newline at end of file