feat: 添加支持 modelscope 安装的说明

This commit is contained in:
Wenjie Zhang 2026-06-03 22:35:32 +08:00
parent fafbc5c9ee
commit e94d293737
2 changed files with 207 additions and 120 deletions

View File

@ -294,11 +294,26 @@
<a href="https://skills.sh/" target="_blank" rel="noopener noreferrer" <a href="https://skills.sh/" target="_blank" rel="noopener noreferrer"
>skills.sh</a >skills.sh</a
> >
查询开源 skills 查询开源 skills 也支持 ModelScope 单个 Skill
地址每次仅限安装一个`https://modelscope.cn/skills/&lt;skill-id&gt;` Skill
ID 可在
<a href="https://modelscope.cn/skills" target="_blank" rel="noopener noreferrer"
>ModelScope Skill 市场</a
>
进入详情后从地址栏获取
</div> </div>
<!-- 仓库技能分页多选列表 --> <!-- 仓库技能分页多选列表 -->
<div v-if="remoteSkillOptions.length" class="skills-list-section"> <div v-if="remoteSkillOptions.length" class="skills-list-section">
<template v-if="hasSingleRepoSkill">
<div class="single-remote-skill-card">
<div class="single-remote-skill-name">{{ singleRepoSkill.name }}</div>
<div class="single-remote-skill-meta">
{{ singleRepoSkill.description || '暂无描述' }}
</div>
</div>
</template>
<template v-else>
<div class="list-operations-bar"> <div class="list-operations-bar">
<div class="op-buttons"> <div class="op-buttons">
<a-button size="small" type="link" @click="handleRepoSelectAll" <a-button size="small" type="link" @click="handleRepoSelectAll"
@ -359,6 +374,7 @@
已选 {{ selectedRepoSkills.length }} / 共发现 已选 {{ selectedRepoSkills.length }} / 共发现
{{ remoteSkillOptions.length }} skills {{ remoteSkillOptions.length }} skills
</div> </div>
</template>
</div> </div>
</a-form> </a-form>
</div> </div>
@ -392,6 +408,26 @@
<!-- 搜索结果列表 --> <!-- 搜索结果列表 -->
<div v-if="searchedSkills.length" class="skills-list-section"> <div v-if="searchedSkills.length" class="skills-list-section">
<template v-if="hasSingleSearchedSkill">
<div class="single-remote-skill-card">
<div class="single-remote-skill-header">
<div class="single-remote-skill-name">
{{ singleSearchedSkill.name }}
</div>
<a-tag
v-if="singleSearchedSkill.installs"
color="blue"
class="skill-item-installs"
>
{{ singleSearchedSkill.installs }}
</a-tag>
</div>
<div class="single-remote-skill-meta">
{{ singleSearchedSkill.source }}
</div>
</div>
</template>
<template v-else>
<div class="list-operations-bar"> <div class="list-operations-bar">
<div class="op-buttons"> <div class="op-buttons">
<a-button size="small" type="link" @click="handleSearchSelectAll" <a-button size="small" type="link" @click="handleSearchSelectAll"
@ -451,6 +487,7 @@
已选择 {{ selectedSearchSkills.length }} / 共找到 已选择 {{ selectedSearchSkills.length }} / 共找到
{{ searchedSkills.length }} skills {{ searchedSkills.length }} skills
</div> </div>
</template>
</div> </div>
</a-form> </a-form>
</div> </div>
@ -587,11 +624,15 @@ const remoteInstallForm = reactive({
const remoteSkillOptions = ref([]) const remoteSkillOptions = ref([])
const repoFilterKeyword = ref('') const repoFilterKeyword = ref('')
const selectedRepoSkills = ref([]) const selectedRepoSkills = ref([])
const hasSingleRepoSkill = computed(() => remoteSkillOptions.value.length === 1)
const singleRepoSkill = computed(() => remoteSkillOptions.value[0] || null)
const searchKeyword = ref('') const searchKeyword = ref('')
const searchingRemoteSkills = ref(false) const searchingRemoteSkills = ref(false)
const searchedSkills = ref([]) const searchedSkills = ref([])
const selectedSearchSkills = ref([]) const selectedSearchSkills = ref([])
const hasSingleSearchedSkill = computed(() => searchedSkills.value.length === 1)
const singleSearchedSkill = computed(() => searchedSkills.value[0] || null)
const repoHistory = ref([]) const repoHistory = ref([])
const allowedSkillAccessLevels = ref(['user']) const allowedSkillAccessLevels = ref(['user'])
@ -1049,12 +1090,17 @@ const handleListRemoteSkills = async () => {
try { try {
const result = await skillApi.listRemoteSkills(source) const result = await skillApi.listRemoteSkills(source)
remoteSkillOptions.value = result?.data || [] remoteSkillOptions.value = result?.data || []
selectedRepoSkills.value = [] selectedRepoSkills.value =
remoteSkillOptions.value.length === 1 ? [remoteSkillOptions.value[0].name] : []
if (!remoteSkillOptions.value.length) { if (!remoteSkillOptions.value.length) {
message.warning('未发现可安装的 Skills') message.warning('未发现可安装的 Skills')
return return
} }
if (remoteSkillOptions.value.length === 1) {
message.success('已发现 1 个 Skill已自动选中')
} else {
message.success(`已发现 ${remoteSkillOptions.value.length} 个 Skills`) message.success(`已发现 ${remoteSkillOptions.value.length} 个 Skills`)
}
// //
let history = [...repoHistory.value] let history = [...repoHistory.value]
@ -1112,9 +1158,11 @@ const handleSearchRemoteSkills = async () => {
try { try {
const result = await skillApi.searchRemoteSkills(query) const result = await skillApi.searchRemoteSkills(query)
searchedSkills.value = result?.data || [] searchedSkills.value = result?.data || []
selectedSearchSkills.value = [] selectedSearchSkills.value = searchedSkills.value.length === 1 ? [...searchedSkills.value] : []
if (!searchedSkills.value.length) { if (!searchedSkills.value.length) {
message.warning('未搜索到相关的 Skills') message.warning('未搜索到相关的 Skills')
} else if (searchedSkills.value.length === 1) {
message.success('搜索到 1 个 Skill已自动选中')
} else { } else {
message.success(`搜索到 ${searchedSkills.value.length} 个 Skills`) message.success(`搜索到 ${searchedSkills.value.length} 个 Skills`)
} }
@ -1627,6 +1675,45 @@ defineExpose({
} }
} }
.single-remote-skill-card {
border: 1px solid var(--gray-150);
border-radius: 6px;
background: var(--gray-0);
padding: 12px;
}
.single-remote-skill-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
min-width: 0;
.ant-tag {
flex-shrink: 0;
margin-inline-end: 0;
}
}
.single-remote-skill-name {
line-height: 20px;
font-weight: 600;
color: var(--gray-900);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.single-remote-skill-meta {
margin-top: 2px;
font-size: 12px;
line-height: 18px;
color: var(--gray-500);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.skill-list-item-content { .skill-list-item-content {
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -283,7 +283,7 @@ const normalizedTags = computed(() => {
} }
&-mini { &-mini {
padding: 12px 14px; padding: 16px 14px;
gap: 0; gap: 0;
} }