mirror of
https://github.com/rubickCenter/rubick
synced 2025-12-17 16:24:16 +08:00
✨ 支持插件开发者模式
This commit is contained in:
@@ -3,7 +3,7 @@
|
||||
"pluginName": "rubick 系统菜单",
|
||||
"description": "rubick 系统菜单",
|
||||
"main": "index.html",
|
||||
"logo": "httpss://static.91jkys.com/upload/202112/08/8a1abbb051bf4b05bbc9bbf66ade63f2.png",
|
||||
"logo": "https://static.91jkys.com/upload/202112/08/8a1abbb051bf4b05bbc9bbf66ade63f2.png",
|
||||
"version": "0.0.0",
|
||||
"preload":"preload.js",
|
||||
"pluginType": "ui",
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
</template>
|
||||
账户
|
||||
</a-menu-item>
|
||||
<a-menu-item key="dev">
|
||||
<template #icon>
|
||||
<BugOutlined />
|
||||
</template>
|
||||
开发者
|
||||
</a-menu-item>
|
||||
</a-menu>
|
||||
</div>
|
||||
<router-view />
|
||||
@@ -40,6 +46,7 @@ import {
|
||||
UserOutlined,
|
||||
AppstoreOutlined,
|
||||
SettingOutlined,
|
||||
BugOutlined,
|
||||
} from "@ant-design/icons-vue";
|
||||
import { useStore } from "vuex";
|
||||
const router = useRouter();
|
||||
|
||||
@@ -14,4 +14,11 @@ export default {
|
||||
);
|
||||
return res.data;
|
||||
},
|
||||
|
||||
async getSystemDetail() {
|
||||
const res = await axios.get(
|
||||
"https://gitee.com/monkeyWang/rubick-database/raw/master/plugins/system.json"
|
||||
);
|
||||
return res.data;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -3,6 +3,7 @@ import Market from "../views/market/index.vue";
|
||||
import Installed from "../views/installed/index.vue";
|
||||
import Account from "../views/account/index.vue";
|
||||
import Settings from "../views/settings/index.vue";
|
||||
import Dev from "../views/dev/index.vue";
|
||||
|
||||
const routes: Array<RouteRecordRaw> = [
|
||||
{
|
||||
@@ -25,6 +26,11 @@ const routes: Array<RouteRecordRaw> = [
|
||||
name: "settings",
|
||||
component: Settings,
|
||||
},
|
||||
{
|
||||
path: "/dev",
|
||||
name: "dev",
|
||||
component: Dev,
|
||||
},
|
||||
{
|
||||
path: "/:catchAll(.*)",
|
||||
name: "market",
|
||||
|
||||
64
feature/src/views/dev/index.vue
Normal file
64
feature/src/views/dev/index.vue
Normal file
@@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div class="dev">
|
||||
<a-alert style="margin-bottom: 40px;" message="rubick 插件系统依托于 npm 管理,本地调试需要先在本地插件当前目录执行 npm link" type="warning" />
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="formState"
|
||||
:rules="rules"
|
||||
:label-col="labelCol"
|
||||
:wrapper-col="wrapperCol"
|
||||
>
|
||||
<a-form-item label="插件名称" name="name">
|
||||
<a-input v-model:value="formState.name" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
|
||||
<a-button :loading="loading" type="primary" @click="onSubmit">安装</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { reactive, ref } from "vue";
|
||||
|
||||
const formRef = ref();
|
||||
const formState = reactive({
|
||||
name: undefined,
|
||||
});
|
||||
const rules = {
|
||||
name: {
|
||||
required: true,
|
||||
message: "Please input name",
|
||||
},
|
||||
};
|
||||
const onSubmit = () => {
|
||||
formRef.value.validate().then(() => {
|
||||
downloadPlugin(formState.name);
|
||||
});
|
||||
};
|
||||
|
||||
const loading = ref(false);
|
||||
const downloadPlugin = async (pluginName) => {
|
||||
loading.value = true;
|
||||
await window.market.downloadPlugin({
|
||||
name: pluginName,
|
||||
isDev: true,
|
||||
});
|
||||
loading.value = false;
|
||||
};
|
||||
|
||||
const labelCol = { span: 4 };
|
||||
const wrapperCol = { span: 14 };
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.dev {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
background: #fff;
|
||||
height: calc(~"100vh - 46px");
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,57 +1,61 @@
|
||||
<template>
|
||||
<div class="installed">
|
||||
<div class="installed-list">
|
||||
<div
|
||||
:class="currentSelect === index ? 'item active' : 'item'"
|
||||
:key="index"
|
||||
v-for="(plugin, index) in localPlugins"
|
||||
>
|
||||
<img :src="plugin.logo" />
|
||||
<div class="info">
|
||||
<div class="title">
|
||||
{{ plugin.pluginName }}
|
||||
<span class="desc">v{{ plugin.version }}</span>
|
||||
</div>
|
||||
<div class="desc">{{ plugin.description }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="!localPlugins.length">
|
||||
<a-result status="404" title="暂无任何插件" sub-title="去插件市场选择安装合适的插件吧!" />
|
||||
</div>
|
||||
<div class="plugin-detail">
|
||||
<div class="plugin-top">
|
||||
<div class="left">
|
||||
<div class="title">
|
||||
{{ pluginDetail.pluginName }}
|
||||
<a-tag>{{ pluginDetail.version }}</a-tag>
|
||||
<div class="container" v-else>
|
||||
<div class="installed-list">
|
||||
<div
|
||||
:class="currentSelect === index ? 'item active' : 'item'"
|
||||
:key="index"
|
||||
v-for="(plugin, index) in localPlugins"
|
||||
>
|
||||
<img :src="plugin.logo" />
|
||||
<div class="info">
|
||||
<div class="title">
|
||||
{{ plugin.pluginName }}
|
||||
<span class="desc">v{{ plugin.version }}</span>
|
||||
</div>
|
||||
<div class="desc">{{ plugin.description }}</div>
|
||||
</div>
|
||||
<div class="desc">
|
||||
开发者:{{ `${pluginDetail.author || "未知"}` }}
|
||||
</div>
|
||||
<div class="desc">
|
||||
{{ pluginDetail.description }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<a-button
|
||||
type="danger"
|
||||
size="small"
|
||||
shape="round"
|
||||
@click="deletePlugin(pluginDetail)"
|
||||
>移除</a-button
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<a-tabs default-active-key="1">
|
||||
<a-tab-pane key="1" tab="功能关键字">
|
||||
<div class="feature-container">
|
||||
<div
|
||||
class="desc-item"
|
||||
:key="index"
|
||||
v-for="(item, index) in pluginDetail.features"
|
||||
<div class="plugin-detail">
|
||||
<div class="plugin-top">
|
||||
<div class="left">
|
||||
<div class="title">
|
||||
{{ pluginDetail.pluginName }}
|
||||
<a-tag>{{ pluginDetail.version }}</a-tag>
|
||||
</div>
|
||||
<div class="desc">
|
||||
开发者:{{ `${pluginDetail.author || "未知"}` }}
|
||||
</div>
|
||||
<div class="desc">
|
||||
{{ pluginDetail.description }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="right">
|
||||
<a-button
|
||||
type="danger"
|
||||
size="small"
|
||||
shape="round"
|
||||
@click="deletePlugin(pluginDetail)"
|
||||
>移除</a-button
|
||||
>
|
||||
<div>{{ item.explain }}</div>
|
||||
<a-tag
|
||||
:key="cmd"
|
||||
@click="
|
||||
</div>
|
||||
</div>
|
||||
<a-tabs default-active-key="1">
|
||||
<a-tab-pane key="1" tab="功能关键字">
|
||||
<div class="feature-container">
|
||||
<div
|
||||
class="desc-item"
|
||||
:key="index"
|
||||
v-for="(item, index) in pluginDetail.features"
|
||||
>
|
||||
<div>{{ item.explain }}</div>
|
||||
<a-tag
|
||||
:key="cmd"
|
||||
@click="
|
||||
openPlugin({
|
||||
cmd,
|
||||
plugin: pluginDetail,
|
||||
@@ -59,18 +63,20 @@
|
||||
router: $router,
|
||||
})
|
||||
"
|
||||
v-for="cmd in item.cmds"
|
||||
>
|
||||
{{ cmd }}
|
||||
</a-tag>
|
||||
v-for="cmd in item.cmds"
|
||||
>
|
||||
{{ cmd }}
|
||||
</a-tag>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" tab="详情介绍">
|
||||
<div class="detail-container" v-html="readme"></div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane key="2" tab="详情介绍">
|
||||
<div class="detail-container" v-html="readme"></div>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -88,7 +94,11 @@ const appPath = remote.app.getPath("cache");
|
||||
const baseDir = path.join(appPath, "./rubick-plugins");
|
||||
|
||||
const store = useStore();
|
||||
const localPlugins = computed(() => store.state.localPlugins);
|
||||
const localPlugins = computed(() =>
|
||||
store.state.localPlugins.filter(
|
||||
(plugin) => plugin.name !== "rubick-system-feature"
|
||||
)
|
||||
);
|
||||
const updateLocalPlugin = () => store.dispatch("updateLocalPlugin");
|
||||
|
||||
const currentSelect = ref(0);
|
||||
@@ -125,7 +135,14 @@ const deletePlugin = async (plugin) => {
|
||||
overflow: hidden;
|
||||
background: #f3efef;
|
||||
height: calc(~"100vh - 46px");
|
||||
display: flex;
|
||||
.container {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
background: #f3efef;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
}
|
||||
.installed-list {
|
||||
width: 40%;
|
||||
background: #fff;
|
||||
|
||||
@@ -45,7 +45,6 @@ const totalPlugins = computed(() => store.state.totalPlugins);
|
||||
const data = ref([]);
|
||||
|
||||
onBeforeMount(async () => {
|
||||
console.log(12312);
|
||||
data.value = await request.getFinderDetail();
|
||||
});
|
||||
|
||||
|
||||
49
feature/src/views/market/components/system.vue
Normal file
49
feature/src/views/market/components/system.vue
Normal file
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<div class="system">
|
||||
<PluginList
|
||||
v-if="system && !!system.length"
|
||||
@downloadSuccess="downloadSuccess"
|
||||
title="系统插件"
|
||||
:list="system"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onBeforeMount } from "vue";
|
||||
import request from "../../../assets/request/index";
|
||||
import PluginList from "./plugin-list.vue";
|
||||
|
||||
import { useStore } from "vuex";
|
||||
const store = useStore();
|
||||
const totalPlugins = computed(() => store.state.totalPlugins);
|
||||
|
||||
const data = ref([]);
|
||||
|
||||
onBeforeMount(async () => {
|
||||
data.value = await request.getSystemDetail();
|
||||
});
|
||||
|
||||
const system = computed(() => {
|
||||
const defaultData = data.value || [];
|
||||
if (!defaultData.length) return [];
|
||||
return defaultData.map((plugin) => {
|
||||
let searchInfo = null;
|
||||
totalPlugins.value.forEach((t) => {
|
||||
if (t.name === plugin) {
|
||||
searchInfo = t;
|
||||
}
|
||||
});
|
||||
return searchInfo;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.system {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
overflow-x: hidden;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
@@ -67,9 +67,11 @@ import {
|
||||
import { reactive, toRefs, computed } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import Finder from "./components/finder.vue";
|
||||
import System from "./components/system.vue";
|
||||
|
||||
const Components = {
|
||||
finder: Finder,
|
||||
system: System,
|
||||
};
|
||||
|
||||
const state = reactive({
|
||||
|
||||
Reference in New Issue
Block a user