mirror of
https://git.mirrors.martin98.com/https://github.com/sub-store-org/Sub-Store.git
synced 2025-09-12 19:53:14 +08:00
Sub-Store 1.2 支持生成远程配置
现在允许用户生成配置并上传到Gist。
This commit is contained in:
parent
29abac4619
commit
bb8bac760e
@ -581,14 +581,18 @@ function service() {
|
|||||||
|
|
||||||
async function deleteArtifact(req, res) {
|
async function deleteArtifact(req, res) {
|
||||||
const name = req.params.name;
|
const name = req.params.name;
|
||||||
|
$.info(`正在删除Artifact:${name}`);
|
||||||
try {
|
try {
|
||||||
const allArtifacts = $.read(ARTIFACTS_KEY);
|
const allArtifacts = $.read(ARTIFACTS_KEY);
|
||||||
if (!allArtifacts[name]) throw new Error(`远程配置:${name}不存在!`);
|
const artifact = allArtifacts[name];
|
||||||
// delete gist
|
if (!artifact) throw new Error(`远程配置:${name}不存在!`);
|
||||||
await syncArtifact({
|
if (artifact.updated) {
|
||||||
filename: name,
|
// delete gist
|
||||||
content: ""
|
await syncArtifact({
|
||||||
});
|
filename: name,
|
||||||
|
content: ""
|
||||||
|
});
|
||||||
|
}
|
||||||
// delete local cache
|
// delete local cache
|
||||||
delete allArtifacts[name];
|
delete allArtifacts[name];
|
||||||
$.write(allArtifacts, ARTIFACTS_KEY);
|
$.write(allArtifacts, ARTIFACTS_KEY);
|
||||||
|
4
backend/sub-store.min.js
vendored
4
backend/sub-store.min.js
vendored
File diff suppressed because one or more lines are too long
5
web/package-lock.json
generated
5
web/package-lock.json
generated
@ -10734,6 +10734,11 @@
|
|||||||
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
"integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"timeago.js": {
|
||||||
|
"version": "4.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/timeago.js/-/timeago.js-4.0.2.tgz",
|
||||||
|
"integrity": "sha512-a7wPxPdVlQL7lqvitHGGRsofhdwtkoSXPGATFuSOA2i1ZNQEPLrGnj68vOp2sOJTCFAQVXPeNMX/GctBaO9L2w=="
|
||||||
|
},
|
||||||
"timers-browserify": {
|
"timers-browserify": {
|
||||||
"version": "2.0.11",
|
"version": "2.0.11",
|
||||||
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz",
|
"resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz",
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
"chartist": "^0.11.4",
|
"chartist": "^0.11.4",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
"material-design-icons-iconfont": "^5.0.1",
|
"material-design-icons-iconfont": "^5.0.1",
|
||||||
|
"timeago.js": "^4.0.2",
|
||||||
"v-clipboard": "^2.2.3",
|
"v-clipboard": "^2.2.3",
|
||||||
"vee-validate": "^3.4.5",
|
"vee-validate": "^3.4.5",
|
||||||
"vue": "^2.6.12",
|
"vue": "^2.6.12",
|
||||||
|
@ -41,6 +41,9 @@ function initStore(store) {
|
|||||||
store.dispatch("FETCH_COLLECTIONS").catch(() => {
|
store.dispatch("FETCH_COLLECTIONS").catch(() => {
|
||||||
showError(`无法拉取组合订阅列表!`);
|
showError(`无法拉取组合订阅列表!`);
|
||||||
});
|
});
|
||||||
|
store.dispatch("FETCH_ARTIFACTS").catch(() => {
|
||||||
|
showError(`无法拉取配置列表!`);
|
||||||
|
});
|
||||||
store.dispatch("FETCH_ENV").catch(() => {
|
store.dispatch("FETCH_ENV").catch(() => {
|
||||||
showError(`无法获取当前运行环境!`);
|
showError(`无法获取当前运行环境!`);
|
||||||
});
|
});
|
||||||
|
@ -8,6 +8,11 @@
|
|||||||
>
|
>
|
||||||
<v-btn :to="{path: '/'}" value="subscription">
|
<v-btn :to="{path: '/'}" value="subscription">
|
||||||
<span>订阅</span>
|
<span>订阅</span>
|
||||||
|
<v-icon>flight_takeoff</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
|
||||||
|
<v-btn :to="{path: '/cloud'}" value="artifacts">
|
||||||
|
<span>同步</span>
|
||||||
<v-icon>mdi-cloud</v-icon>
|
<v-icon>mdi-cloud</v-icon>
|
||||||
</v-btn>
|
</v-btn>
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import Subscription from "@/views/Subscription";
|
|||||||
import Dashboard from "@/views/Dashboard";
|
import Dashboard from "@/views/Dashboard";
|
||||||
import User from "@/views/User";
|
import User from "@/views/User";
|
||||||
import SubEditor from "@/views/SubEditor";
|
import SubEditor from "@/views/SubEditor";
|
||||||
|
import Cloud from "@/views/Cloud";
|
||||||
|
|
||||||
Vue.use(Router);
|
Vue.use(Router);
|
||||||
|
|
||||||
@ -24,6 +25,12 @@ const router = new Router({
|
|||||||
component: Dashboard,
|
component: Dashboard,
|
||||||
meta: {title: "首页"}
|
meta: {title: "首页"}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/cloud",
|
||||||
|
name: "artifact",
|
||||||
|
component: Cloud,
|
||||||
|
meta: {title: "同步"}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/user",
|
path: "/user",
|
||||||
name: "user",
|
name: "user",
|
||||||
|
@ -15,6 +15,7 @@ const store = new Vuex.Store({
|
|||||||
|
|
||||||
subscriptions: {},
|
subscriptions: {},
|
||||||
collections: {},
|
collections: {},
|
||||||
|
artifacts: {},
|
||||||
env: {},
|
env: {},
|
||||||
|
|
||||||
settings: {}
|
settings: {}
|
||||||
@ -57,6 +58,12 @@ const store = new Vuex.Store({
|
|||||||
state.collections = data;
|
state.collections = data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
async FETCH_ARTIFACTS({state}) {
|
||||||
|
return axios.get("/artifacts").then(resp => {
|
||||||
|
const {data} = resp.data;
|
||||||
|
state.artifacts = data;
|
||||||
|
});
|
||||||
|
},
|
||||||
// fetch env
|
// fetch env
|
||||||
async FETCH_ENV({state}) {
|
async FETCH_ENV({state}) {
|
||||||
return axios.get("/utils/env").then(resp => {
|
return axios.get("/utils/env").then(resp => {
|
||||||
|
299
web/src/views/Cloud.vue
Normal file
299
web/src/views/Cloud.vue
Normal file
@ -0,0 +1,299 @@
|
|||||||
|
<template>
|
||||||
|
<v-container>
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
配置
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<!-- <v-btn icon>-->
|
||||||
|
<!-- <v-icon>mdi-cloud-circle</v-icon>-->
|
||||||
|
<!-- </v-btn>-->
|
||||||
|
<!-- <v-btn icon>-->
|
||||||
|
<!-- <v-icon>mdi-refresh-circle</v-icon>-->
|
||||||
|
<!-- </v-btn>-->
|
||||||
|
<v-dialog max-width="400px" v-model="addArtifactDialog">
|
||||||
|
<template #activator="{on}">
|
||||||
|
<v-btn icon v-on="on">
|
||||||
|
<v-icon color="primary">mdi-plus-circle</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
<v-card class="pl-4 pr-4 pb-4 pt-4">
|
||||||
|
<v-subheader>
|
||||||
|
<v-icon left>mdi-plus-circle</v-icon>
|
||||||
|
<h3>添加同步配置</h3>
|
||||||
|
</v-subheader>
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<v-form class="pt-4 pl-4 pr-4 pb-0" v-model="formValid">
|
||||||
|
<v-text-field
|
||||||
|
v-model="newArtifact.name"
|
||||||
|
label="配置名称"
|
||||||
|
placeholder="填入生成配置名称,名称需唯一,如Clash.yaml。"
|
||||||
|
:rules="validations.nameRules"
|
||||||
|
clearable
|
||||||
|
clear-icon="clear"
|
||||||
|
/>
|
||||||
|
<v-menu offset-y>
|
||||||
|
<template v-slot:activator="{on}">
|
||||||
|
<v-text-field
|
||||||
|
label="类型"
|
||||||
|
v-on="on"
|
||||||
|
:rules="validations.required"
|
||||||
|
:value="getType(newArtifact.type)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<v-list dense>
|
||||||
|
<v-list-item @click="setArtifactType('subscription')">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>mdi-link</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>订阅</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item @click="setArtifactType('collection')">
|
||||||
|
<v-list-item-icon>
|
||||||
|
<v-icon>list</v-icon>
|
||||||
|
</v-list-item-icon>
|
||||||
|
<v-list-item-title>组合订阅</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
<v-menu offset-y>
|
||||||
|
<template v-slot:activator="{on}">
|
||||||
|
<v-text-field
|
||||||
|
v-model="newArtifact.source"
|
||||||
|
label="来源"
|
||||||
|
:rules="validations.required"
|
||||||
|
:placeholder="`填入${getType(newArtifact.type) || '来源'}的名称。`"
|
||||||
|
v-on="on"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<v-list dense>
|
||||||
|
<v-list-item
|
||||||
|
v-for="(name, idx) in getSources(newArtifact.type)"
|
||||||
|
@click="newArtifact.source = name"
|
||||||
|
:key="idx"
|
||||||
|
>
|
||||||
|
<v-list-item-title>{{ name }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
|
||||||
|
<v-menu offset-y>
|
||||||
|
<template v-slot:activator="{on}">
|
||||||
|
<v-text-field
|
||||||
|
label="目标"
|
||||||
|
v-on="on"
|
||||||
|
:rules="validations.required"
|
||||||
|
:value="newArtifact.platform"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<v-list dense>
|
||||||
|
<v-list-item
|
||||||
|
v-for="platform in ['Surge', 'Loon', 'QX', 'Clash']"
|
||||||
|
:key="platform"
|
||||||
|
@click="newArtifact.platform = platform"
|
||||||
|
>
|
||||||
|
<v-list-item-avatar>
|
||||||
|
<v-img :src="getIcon(platform)"></v-img>
|
||||||
|
</v-list-item-avatar>
|
||||||
|
<v-list-item-title>{{ platform }}</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</v-form>
|
||||||
|
<v-divider></v-divider>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn color="primary" text small :disabled="!formValid" @click="createArtifact()">
|
||||||
|
确认
|
||||||
|
</v-btn>
|
||||||
|
<v-btn text small @click="clear()">
|
||||||
|
取消
|
||||||
|
</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-dialog>
|
||||||
|
</v-card-title>
|
||||||
|
|
||||||
|
<template v-for="(artifact, idx) in artifacts">
|
||||||
|
<v-list-item three-line dense :key="artifact.name">
|
||||||
|
<v-list-item-avatar>
|
||||||
|
<v-img :src="getIcon(artifact.platform)"/>
|
||||||
|
</v-list-item-avatar>
|
||||||
|
<v-list-item-content>
|
||||||
|
<v-list-item-title>
|
||||||
|
{{ artifact.name }}
|
||||||
|
</v-list-item-title>
|
||||||
|
<v-chip-group>
|
||||||
|
<v-chip label>
|
||||||
|
<v-icon left>info</v-icon>
|
||||||
|
{{ getType(artifact.type) }}
|
||||||
|
</v-chip>
|
||||||
|
<v-chip label>
|
||||||
|
<v-icon left>mdi-link</v-icon>
|
||||||
|
{{ artifact.source }}
|
||||||
|
</v-chip>
|
||||||
|
</v-chip-group>
|
||||||
|
<v-list-item-subtitle>更新于:{{ getUpdatedTime(artifact.updated) }}</v-list-item-subtitle>
|
||||||
|
</v-list-item-content>
|
||||||
|
<v-list-item-action>
|
||||||
|
<v-menu bottom left>
|
||||||
|
<template #activator="{ on }">
|
||||||
|
<v-btn icon v-on="on">
|
||||||
|
<v-icon>mdi-dots-vertical</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
<v-list dense>
|
||||||
|
<v-list-item @click="copy(artifact.url)">
|
||||||
|
<v-list-item-title>复制</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item @click="preview(artifact.name)">
|
||||||
|
<v-list-item-title>预览</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item @click="sync(artifact.name)">
|
||||||
|
<v-list-item-title>同步</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
<v-list-item @click="deleteArtifact(idx, artifact.name)">
|
||||||
|
<v-list-item-title>删除</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
|
</v-list>
|
||||||
|
</v-menu>
|
||||||
|
</v-list-item-action>
|
||||||
|
</v-list-item>
|
||||||
|
</template>
|
||||||
|
</v-card>
|
||||||
|
</v-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {axios} from '@/utils';
|
||||||
|
import {BACKEND_BASE} from "@/config";
|
||||||
|
import {format} from 'timeago.js';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "Cloud",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
addArtifactDialog: false,
|
||||||
|
newArtifact: {
|
||||||
|
name: "",
|
||||||
|
type: "subscription",
|
||||||
|
source: "",
|
||||||
|
platform: "",
|
||||||
|
},
|
||||||
|
formValid: false,
|
||||||
|
validations: {
|
||||||
|
nameRules: [
|
||||||
|
v => !!v || "订阅名称不能为空!",
|
||||||
|
v => /^[\w-_.]*$/.test(v) || "订阅名称只能包含英文字符、横杠、点和下划线!"
|
||||||
|
],
|
||||||
|
required: [
|
||||||
|
v => !!v || "不能为空!"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
axios.get("/artifacts").then(resp => {
|
||||||
|
const {data} = resp.data;
|
||||||
|
this.artifacts = Object.keys(data).map(k => data[k]);
|
||||||
|
})
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
artifacts() {
|
||||||
|
const items = this.$store.state.artifacts;
|
||||||
|
return Object.keys(items).map(k => items[k]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getIcon(platform) {
|
||||||
|
const ICONS = {
|
||||||
|
"Clash": "https://github.com/Dreamacro/clash/raw/master/docs/logo.png",
|
||||||
|
"QX": "https://raw.githubusercontent.com/Orz-3/task/master/quantumultx.png",
|
||||||
|
"Surge": "https://raw.githubusercontent.com/Orz-3/task/master/surge.png",
|
||||||
|
"Loon": "https://raw.githubusercontent.com/Orz-3/task/master/loon.png"
|
||||||
|
}
|
||||||
|
return ICONS[platform];
|
||||||
|
},
|
||||||
|
|
||||||
|
getType(type) {
|
||||||
|
const DESCRIPTIONS = {
|
||||||
|
"subscription": "订阅",
|
||||||
|
"collection": "组合订阅"
|
||||||
|
}
|
||||||
|
return DESCRIPTIONS[type];
|
||||||
|
},
|
||||||
|
|
||||||
|
getUpdatedTime(time) {
|
||||||
|
if (!time) {
|
||||||
|
return "从未更新";
|
||||||
|
} else {
|
||||||
|
return format(time, "zh_CN");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async createArtifact() {
|
||||||
|
try {
|
||||||
|
await axios.post("/artifacts", this.newArtifact);
|
||||||
|
await this.$store.dispatch("FETCH_ARTIFACTS");
|
||||||
|
this.clear();
|
||||||
|
} catch (err) {
|
||||||
|
this.$store.commit("SET_ERROR_MESSAGE", `创建配置失败!${err}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async deleteArtifact(idx, name) {
|
||||||
|
try {
|
||||||
|
await axios.delete(`/artifact/${name}`);
|
||||||
|
await this.$store.dispatch("FETCH_ARTIFACTS");
|
||||||
|
} catch (err) {
|
||||||
|
this.$store.commit("SET_ERROR_MESSAGE", `删除配置失败!${err}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
clear() {
|
||||||
|
this.newArtifact = {
|
||||||
|
name: "",
|
||||||
|
type: "subscription",
|
||||||
|
source: "",
|
||||||
|
platform: ""
|
||||||
|
}
|
||||||
|
this.addArtifactDialog = false;
|
||||||
|
},
|
||||||
|
|
||||||
|
copy(url) {
|
||||||
|
this.$clipboard(url);
|
||||||
|
this.$store.commit("SET_SUCCESS_MESSAGE", "成功复制配置链接");
|
||||||
|
},
|
||||||
|
|
||||||
|
preview(name) {
|
||||||
|
window.open(`${BACKEND_BASE}/api/artifact/${name}?action=preview`);
|
||||||
|
},
|
||||||
|
|
||||||
|
async sync(name) {
|
||||||
|
try {
|
||||||
|
await axios.get(`/artifact/${name}?action=sync`);
|
||||||
|
await this.$store.dispatch("FETCH_ARTIFACTS");
|
||||||
|
this.$store.commit("SET_SUCCESS_MESSAGE", `同步配置成功!`);
|
||||||
|
} catch (err) {
|
||||||
|
this.$store.commit("SET_ERROR_MESSAGE", `同步配置失败!${err}`);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setArtifactType(type) {
|
||||||
|
this.newArtifactType = type;
|
||||||
|
this.newArtifact.source = "";
|
||||||
|
},
|
||||||
|
|
||||||
|
getSources(type) {
|
||||||
|
let data;
|
||||||
|
switch (type) {
|
||||||
|
case "subscription":
|
||||||
|
data = this.$store.state.subscriptions;
|
||||||
|
break;
|
||||||
|
case "collection":
|
||||||
|
data = this.$store.state.collections;
|
||||||
|
}
|
||||||
|
return Object.keys(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,49 +1,77 @@
|
|||||||
<template>
|
<template>
|
||||||
<v-card
|
<v-container>
|
||||||
class="mb-4 ml-4 mr-4 mt-4"
|
<v-card>
|
||||||
>
|
<v-card-title>
|
||||||
<v-card-title>
|
GitHub 配置
|
||||||
云同步
|
<v-spacer></v-spacer>
|
||||||
<v-spacer></v-spacer>
|
<v-icon small>settings</v-icon>
|
||||||
<v-icon small>cloud</v-icon>
|
</v-card-title>
|
||||||
</v-card-title>
|
<v-card-text>
|
||||||
<v-card-text>
|
<v-text-field
|
||||||
<v-text-field
|
label="GitHub 用户名"
|
||||||
label="GitHub Token"
|
hint="填入GitHub用户名"
|
||||||
hint="填入GitHub Token"
|
v-model="settings.githubUser"
|
||||||
v-model="settings.gistToken"
|
clearable clear-icon="clear"
|
||||||
clearable clear-icon="clear"
|
>
|
||||||
/>
|
|
||||||
</v-card-text>
|
</v-text-field>
|
||||||
<v-divider></v-divider>
|
<v-text-field
|
||||||
<v-card-actions>
|
label="GitHub Token"
|
||||||
<v-spacer></v-spacer>
|
hint="填入GitHub Token"
|
||||||
<v-btn label @click="sync('upload')">上传</v-btn>
|
v-model="settings.gistToken"
|
||||||
<v-btn label @click="sync('download')">下载</v-btn>
|
clearable clear-icon="clear"
|
||||||
</v-card-actions>
|
/>
|
||||||
<v-divider/>
|
</v-card-text>
|
||||||
</v-card>
|
<v-divider></v-divider>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn small text @click="save()" color="primary">保存</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
<v-divider/>
|
||||||
|
</v-card>
|
||||||
|
|
||||||
|
<v-card>
|
||||||
|
<v-card-title>
|
||||||
|
Gist 数据同步
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-icon small>mdi-cloud</v-icon>
|
||||||
|
</v-card-title>
|
||||||
|
<v-card-text>
|
||||||
|
最近同步于:{{getSyncTime()}}
|
||||||
|
</v-card-text>
|
||||||
|
<v-card-actions>
|
||||||
|
<v-spacer></v-spacer>
|
||||||
|
<v-btn small text @click="sync('upload')">上传</v-btn>
|
||||||
|
<v-btn small text @click="sync('download')">恢复</v-btn>
|
||||||
|
</v-card-actions>
|
||||||
|
</v-card>
|
||||||
|
</v-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import {axios, showError} from "@/utils";
|
import {axios, showError} from "@/utils";
|
||||||
|
import {format} from "timeago.js";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
settings: {
|
settings: {
|
||||||
gistToken: ""
|
gistToken: "",
|
||||||
|
githubUser: "",
|
||||||
|
syncTime: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
axios.get(`/settings`).then(resp => {
|
axios.get(`/settings`).then(resp => {
|
||||||
this.settings.gistToken = resp.data.gistToken;
|
this.settings.gistToken = resp.data.gistToken;
|
||||||
|
this.settings.githubUser = resp.data.githubUser;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
save() {
|
save() {
|
||||||
axios.patch(`/settings`, this.settings);
|
axios.patch(`/settings`, this.settings);
|
||||||
|
this.$store.commit("SET_SUCCESS_MESSAGE", `保存成功!`);
|
||||||
},
|
},
|
||||||
|
|
||||||
sync(action) {
|
sync(action) {
|
||||||
@ -51,13 +79,13 @@ export default {
|
|||||||
this.$store.commit("SET_ERROR_MESSAGE", "未设置GitHub Token!");
|
this.$store.commit("SET_ERROR_MESSAGE", "未设置GitHub Token!");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.save();
|
|
||||||
axios.get(`/utils/backup?action=${action}`).then(resp => {
|
axios.get(`/utils/backup?action=${action}`).then(resp => {
|
||||||
if (resp.data.status === 'success') {
|
if (resp.data.status === 'success') {
|
||||||
this.$store.commit("SET_SUCCESS_MESSAGE", `${action === 'upload' ? "备份" : "还原"}成功!`);
|
this.$store.commit("SET_SUCCESS_MESSAGE", `${action === 'upload' ? "备份" : "还原"}成功!`);
|
||||||
|
this.settings.syncTime = new Date().getTime();
|
||||||
|
axios.patch(`/settings`, this.settings);
|
||||||
this.updateStore(this.$store);
|
this.updateStore(this.$store);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
this.$store.commit("SET_ERROR_MESSAGE", `备份失败!${resp.data.message}`);
|
this.$store.commit("SET_ERROR_MESSAGE", `备份失败!${resp.data.message}`);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -69,6 +97,14 @@ export default {
|
|||||||
store.dispatch("FETCH_COLLECTIONS").catch(() => {
|
store.dispatch("FETCH_COLLECTIONS").catch(() => {
|
||||||
showError(`无法拉取组合订阅列表!`);
|
showError(`无法拉取组合订阅列表!`);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getSyncTime() {
|
||||||
|
if (this.settings.syncTime) {
|
||||||
|
return format(this.settings.syncTime, "zh_CN");
|
||||||
|
} else {
|
||||||
|
return "从未同步";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user