Skip to content

Commit 6a13ff2

Browse files
committed
✨ GM储存管理(#15)
1 parent 606ac06 commit 6a13ff2

6 files changed

Lines changed: 309 additions & 62 deletions

File tree

src/apps/script/controller.ts

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -300,31 +300,58 @@ export class ScriptController {
300300

301301
// 第一次获取后在内存中维护
302302
public async getScriptValue(script: Script): Promise<{ [key: string]: Value }> {
303-
if (script.metadata['storagename']) {
304-
return App.Cache.getOrSet("value:storagename:" + script.metadata['storagename'][0], () => {
305-
return new Promise(async resolve => {
306-
let list = <Value[]>await this.valueModel.list((table) => {
307-
return table.where({ storageName: script.metadata['storagename'][0] });
308-
});
309-
let ret: { [key: string]: Value } = {};
310-
list.forEach(val => {
311-
ret[val.key] = val;
312-
});
313-
resolve(ret);
314-
});
315-
});
316-
}
317-
return App.Cache.getOrSet("value:" + script.id, () => {
318-
return new Promise(async resolve => {
303+
return App.Cache.getOrSet("value:storagename:" + script.metadata['storagename'][0], () => {
304+
return this.getValues(script);
305+
});
306+
}
307+
308+
public async getValues(script: Script): Promise<{ [key: string]: Value }> {
309+
return new Promise(async resolve => {
310+
if (script.metadata['storagename']) {
319311
let list = <Value[]>await this.valueModel.list((table) => {
320-
return table.where({ scriptId: script.id });
312+
return table.where({ storageName: script.metadata['storagename'][0] });
321313
});
322314
let ret: { [key: string]: Value } = {};
323315
list.forEach(val => {
324316
ret[val.key] = val;
325317
});
326-
resolve(ret);
318+
return resolve(ret);
319+
}
320+
let list = <Value[]>await this.valueModel.list((table) => {
321+
return table.where({ scriptId: script.id });
322+
});
323+
let ret: { [key: string]: Value } = {};
324+
list.forEach(val => {
325+
ret[val.key] = val;
327326
});
327+
resolve(ret);
328+
});
329+
}
330+
331+
public saveValue(script: Script, key: string, val: any): Promise<Value | undefined> {
332+
return this.updateValue(key, val, script.id, (script.metadata['storagename'] && script.metadata['storagename'][0] || undefined));
333+
}
334+
335+
public deleteValue(script: Script, key: string): Promise<void> {
336+
return new Promise(async resolve => {
337+
let model: Value | undefined;
338+
let storageName = script.metadata['storagename'] && script.metadata['storagename'][0];
339+
if (storageName) {
340+
model = await this.valueModel.findOne({
341+
storageName: storageName,
342+
key: key,
343+
});
344+
} else {
345+
model = await this.valueModel.findOne({
346+
scriptId: script.id,
347+
key: key,
348+
});
349+
}
350+
if (model) {
351+
this.valueModel.delete(model!.id);
352+
MsgCenter.connect(ScriptValueChange, { model: model, tabid: undefined });
353+
}
354+
resolve(undefined);
328355
});
329356
}
330357

src/views/pages/Import/index.vue

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,7 @@ import {
199199
import { SUBSCRIBE_STATUS_ENABLE } from "@App/model/do/subscribe";
200200
import { base64ToStr, waitGroup } from "@App/pkg/utils/utils";
201201
import { Component, Vue } from "vue-property-decorator";
202+
import { parseStorageValue } from "../utils";
202203
203204
@Component({})
204205
export default class Index extends Vue {
@@ -365,7 +366,7 @@ export default class Index extends Vue {
365366
subWait.add(Object.keys(scriptInfo.storage.data).length);
366367
for (const key in scriptInfo.storage.data) {
367368
let importValue = async () => {
368-
let val = this.parseValue(scriptInfo.storage.data[key]);
369+
let val = parseStorageValue(scriptInfo.storage.data[key]);
369370
await this.scriptCtrl.updateValue(
370371
key,
371372
val,
@@ -405,21 +406,6 @@ export default class Index extends Vue {
405406
}
406407
}
407408
408-
parseValue(str: string): any {
409-
let t = str[0];
410-
let s = str.substring(1);
411-
switch (t) {
412-
case "s":
413-
return s;
414-
case "b":
415-
return s == "true";
416-
case "n":
417-
return parseFloat(s);
418-
default:
419-
return JSON.parse(s);
420-
}
421-
}
422-
423409
closeWindow() {
424410
window.close();
425411
}
Lines changed: 208 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,216 @@
11
<template>
2-
<div>GM_setValue GM_getValue</div>
2+
<v-card>
3+
<v-card-title>
4+
<v-text-field
5+
v-model="search"
6+
:append-icon="icons.mdiMagnify"
7+
label="搜索键"
8+
single-line
9+
hide-details
10+
></v-text-field>
11+
<v-spacer></v-spacer>
12+
<v-dialog v-model="dialog" max-width="500px">
13+
<template v-slot:activator="{ on, attrs }">
14+
<v-btn color="primary" dark class="mb-2" v-bind="attrs" v-on="on">
15+
添加新值
16+
</v-btn>
17+
</template>
18+
<v-card>
19+
<v-card-title>
20+
<span class="text-h5">添加新值</span>
21+
</v-card-title>
22+
<v-card-text>
23+
<v-container>
24+
<v-row>
25+
<v-col>
26+
<v-text-field
27+
v-model="editedItem.key"
28+
label="储存键"
29+
></v-text-field>
30+
</v-col>
31+
<v-col>
32+
<v-text-field
33+
v-model="editedItem.value"
34+
label="储存值"
35+
></v-text-field>
36+
</v-col>
37+
</v-row>
38+
</v-container>
39+
</v-card-text>
40+
41+
<v-card-actions>
42+
<v-spacer></v-spacer>
43+
<v-btn color="blue darken-1" text @click="close"> 取消 </v-btn>
44+
<v-btn color="blue darken-1" text @click="save"> 保存 </v-btn>
45+
</v-card-actions>
46+
</v-card>
47+
</v-dialog>
48+
</v-card-title>
49+
<v-data-table
50+
:headers="headers"
51+
:items="values"
52+
:search="search"
53+
:footer-props="{
54+
itemsPerPageAllText: '显示全部',
55+
itemsPerPageText: '每行页数',
56+
}"
57+
>
58+
<template v-slot:top>
59+
<v-toolbar flat>
60+
<p>
61+
储存空间:
62+
{{
63+
(script.metadata["storagename"] &&
64+
script.metadata["storagename"][0]) ||
65+
"匿名空间"
66+
}}
67+
</p>
68+
<v-spacer></v-spacer>
69+
<v-dialog v-model="dialogDelete" max-width="500px">
70+
<v-card>
71+
<v-card-title class="text-h5">请确定是否删除储存项?</v-card-title>
72+
<v-card-actions>
73+
<v-spacer></v-spacer>
74+
<v-btn color="blue darken-1" text @click="closeDelete"
75+
>取消</v-btn
76+
>
77+
<v-btn color="blue darken-1" text @click="deleteItemConfirm"
78+
>确定</v-btn
79+
>
80+
<v-spacer></v-spacer>
81+
</v-card-actions>
82+
</v-card>
83+
</v-dialog>
84+
</v-toolbar>
85+
</template>
86+
<template v-slot:[`item.value`]="{ item }">
87+
{{ toStorageValueStr(item.value) }}
88+
</template>
89+
<template v-slot:[`item.actions`]="{ item }">
90+
<v-icon small class="mr-2" @click="editItem(item)">
91+
{{ icons.mdiPencil }}
92+
</v-icon>
93+
<v-icon small @click="deleteItem(item)">
94+
{{ icons.mdiDelete }}
95+
</v-icon>
96+
</template>
97+
<template v-slot:no-data> 没有储存数据 </template>
98+
</v-data-table>
99+
<v-card-subtitle>
100+
值的第一个字符表示该值的类型,在编辑值时请也按照此规则进行编辑,否则默认识别为文本.
101+
s:文本 n:数字 b:布尔值 o:对象
102+
</v-card-subtitle>
103+
</v-card>
3104
</template>
4105

5106
<script lang="ts">
6-
import { Component, Prop, Vue } from "vue-property-decorator";
107+
import { ScriptController } from "@App/apps/script/controller";
108+
import { Script } from "@App/model/do/script";
109+
import { Value } from "@App/model/do/value";
110+
import { parseStorageValue, toStorageValueStr } from "@App/views/pages/utils";
111+
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
112+
import { mdiMagnify, mdiPencil, mdiDelete } from "@mdi/js";
7113
8114
@Component({})
9-
export default class CloseButton extends Vue {}
115+
export default class CloseButton extends Vue {
116+
icons = {
117+
mdiMagnify: mdiMagnify,
118+
mdiPencil: mdiPencil,
119+
mdiDelete: mdiDelete,
120+
};
121+
scriptCtrl = new ScriptController();
122+
values: Array<Value> = new Array();
123+
dialog = false;
124+
dialogDelete = false;
125+
editedIndex = -1;
126+
editedItem = { key: "", value: "" };
127+
128+
@Prop() script!: Script;
129+
130+
async created() {
131+
let values = await this.scriptCtrl.getValues(this.script);
132+
console.log(this.script, values);
133+
for (const key in values) {
134+
this.values.push(values[key]);
135+
}
136+
}
137+
138+
data() {
139+
return {
140+
search: "",
141+
headers: [
142+
{ text: "储存键", value: "key" },
143+
{ text: "储存值", value: "value" },
144+
{ text: "操作", value: "actions" },
145+
],
146+
};
147+
}
148+
toStorageValueStr = toStorageValueStr;
149+
150+
@Watch("dialog")
151+
watchDialog(val: any) {
152+
val || this.close();
153+
}
154+
155+
@Watch("dialogDelete")
156+
watchDialogDelete(val: any) {
157+
val || this.closeDelete();
158+
}
159+
160+
close() {
161+
this.dialog = false;
162+
this.$nextTick(() => {
163+
this.editedItem = { key: "", value: "" };
164+
this.editedIndex = -1;
165+
});
166+
}
167+
168+
closeDelete() {
169+
this.dialogDelete = false;
170+
this.$nextTick(() => {
171+
this.editedItem = { key: "", value: "" };
172+
this.editedIndex = -1;
173+
});
174+
}
175+
176+
async save() {
177+
let value = await this.scriptCtrl.saveValue(
178+
this.script,
179+
this.editedItem.key,
180+
parseStorageValue(this.editedItem.value)
181+
);
182+
if (!value) {
183+
alert("保存失败");
184+
return;
185+
}
186+
if (this.editedIndex > -1) {
187+
this.values[this.editedIndex].value = value.value;
188+
} else {
189+
this.values.unshift(value);
190+
}
191+
this.close();
192+
}
193+
194+
editItem(item: Value) {
195+
this.editedIndex = this.values.indexOf(item);
196+
this.editedItem = Object.assign({}, item);
197+
this.editedItem.value = toStorageValueStr(item.value);
198+
this.dialog = true;
199+
}
200+
201+
deleteItem(item: Value) {
202+
this.editedIndex = this.values.indexOf(item);
203+
this.editedItem = Object.assign({}, item);
204+
this.editedItem.value = toStorageValueStr(item.value);
205+
this.dialogDelete = true;
206+
}
207+
208+
deleteItemConfirm() {
209+
this.values.splice(this.editedIndex, 1);
210+
this.scriptCtrl.deleteValue(this.script, this.editedItem.key);
211+
this.closeDelete();
212+
}
213+
}
10214
</script>
11215

12-
<style>
13-
</style>
216+
<style></style>

src/views/pages/Option/tabs/ScriptTab/index.vue

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,15 @@
2929
</TabPane>
3030

3131
<TabPane title="设置">
32-
<Config />
32+
<Config :script="script" />
3333
</TabPane>
3434

3535
<TabPane title="存储">
36-
<Storage />
36+
<Storage :script="script" />
3737
</TabPane>
3838

3939
<TabPane title="资源">
40-
<Resource />
40+
<Resource :script="script" />
4141
</TabPane>
4242
</Tab>
4343
</div>
@@ -162,12 +162,14 @@ export default class ScriptTab extends Vue {
162162
163163
async handleSaveScript({ currentCode, debug }: ISaveScript) {
164164
// todo 保存时候错误处理
165-
let [newScript, oldScript] =
166-
await this.scriptController.prepareScriptByCode(
167-
currentCode,
168-
this.script.origin || "",
169-
this.script.uuid ? this.script.uuid : uuidv4()
170-
);
165+
let [
166+
newScript,
167+
oldScript,
168+
] = await this.scriptController.prepareScriptByCode(
169+
currentCode,
170+
this.script.origin || "",
171+
this.script.uuid ? this.script.uuid : uuidv4()
172+
);
171173
172174
if (newScript == undefined) {
173175
alert(oldScript);

0 commit comments

Comments
 (0)