Skip to content

Commit 614184e

Browse files
committed
refactor: rulesets
1 parent fbfbcb4 commit 614184e

File tree

4 files changed

+123
-55
lines changed

4 files changed

+123
-55
lines changed

frontend/src/stores/rulesets.ts

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import { ref } from 'vue'
22
import { defineStore } from 'pinia'
33
import { stringify, parse } from 'yaml'
44

5-
import { Readfile, Writefile, Copyfile, Download, FileExists } from '@/bridge'
5+
import { debounce, ignoredError, isValidRulesJson, omitArray } from '@/utils'
66
import { RulesetsFilePath, RulesetFormat, EmptyRuleSet } from '@/constant'
7-
import { deepClone, debounce, ignoredError, omitArray } from '@/utils'
7+
import { Readfile, Writefile, Copyfile, Download, FileExists, HttpGet } from '@/bridge'
88

99
export type RuleSetType = {
1010
id: string
@@ -15,6 +15,7 @@ export type RuleSetType = {
1515
format: RulesetFormat
1616
path: string
1717
url: string
18+
count: number
1819
// Not Config
1920
updating?: boolean
2021
}
@@ -67,29 +68,53 @@ export const useRulesetsStore = defineStore('rulesets', () => {
6768
}
6869

6970
const _doUpdateRuleset = async (r: RuleSetType) => {
70-
if (r.type === 'Manual') {
71-
if (r.path.length == 0) {
72-
throw 'Ruleset file path is empty'
71+
if (r.format === RulesetFormat.Source) {
72+
let body = ''
73+
let ruleset: any
74+
let isExist = true
75+
76+
if (r.type === 'File') {
77+
body = await Readfile(r.url)
78+
} else if (r.type === 'Http') {
79+
const { body: b } = await HttpGet(r.url)
80+
body = b
81+
} else if (r.type === 'Manual') {
82+
isExist = await FileExists(r.path)
83+
if (isExist) {
84+
body = await Readfile(r.path)
85+
} else {
86+
body = JSON.stringify(EmptyRuleSet)
87+
}
7388
}
74-
if (!(await FileExists(r.path))) {
75-
await Writefile(r.path, JSON.stringify(EmptyRuleSet, null, 2))
89+
90+
if (!isValidRulesJson(body)) {
91+
throw 'Not a valid ruleset data'
7692
}
77-
} else if (r.type === 'File') {
78-
const exists = r.url.length > 0 && (await FileExists(r.url))
79-
if (exists) {
80-
if (r.path != r.url) {
81-
await Copyfile(r.url, r.path)
82-
}
83-
} else if (r.path === r.url) {
84-
// create a default ruleset file
85-
await Writefile(r.path, JSON.stringify(EmptyRuleSet, null, 2))
86-
} else {
87-
throw 'Source ruleset file not exists ' + r.url
93+
94+
ruleset = JSON.parse(body)
95+
96+
r.count = ruleset.rules.reduce(
97+
(p: number, c: string[]) =>
98+
Object.values(c).reduce(
99+
(p, c: string[] | string) => (Array.isArray(c) ? p + c.length : p + 1),
100+
0
101+
) + p,
102+
0
103+
)
104+
105+
if (
106+
(['Http', 'File'].includes(r.type) && r.url !== r.path) ||
107+
(r.type === 'Manual' && !isExist)
108+
) {
109+
await Writefile(r.path, JSON.stringify(ruleset, null, 2))
88110
}
89-
} else if (r.type === 'Http') {
90-
await Download(r.url, r.path)
91-
if (!(await FileExists(r.path))) {
92-
throw 'Ruleset file not downloaded ' + r.url
111+
}
112+
113+
if (r.format === RulesetFormat.Binary) {
114+
if (r.type === 'File' && r.url !== r.path) {
115+
await Copyfile(r.url, r.path)
116+
} else if (r.type === 'Http') {
117+
await Download(r.url, r.path)
93118
}
94119
}
95120

frontend/src/utils/is.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ export const isValidPaylodYAML = (str: string) => {
4141
}
4242
}
4343

44+
export const isValidRulesJson = (str: string) => {
45+
try {
46+
const { rules } = JSON.parse(str)
47+
return !!rules
48+
} catch (error) {
49+
return false
50+
}
51+
}
52+
4453
export const isValidIPv4 = (ip: string) =>
4554
/^((25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(25[0-5]|2[0-4]\d|[01]?\d\d?)$/.test(ip)
4655

frontend/src/views/RulesetsView/components/RulesetForm.vue

Lines changed: 39 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { ref, inject } from 'vue'
2+
import { ref, inject, watch, computed } from 'vue'
33
import { useI18n } from 'vue-i18n'
44
55
import { useMessage } from '@/hooks'
@@ -26,6 +26,7 @@ const ruleset = ref<RuleSetType>({
2626
format: RulesetFormat.Binary,
2727
type: 'Http',
2828
url: '',
29+
count: 0,
2930
path: `data/rulesets/${sampleID()}.srs`,
3031
disabled: false
3132
})
@@ -35,21 +36,6 @@ const { message } = useMessage()
3536
const rulesetsStore = useRulesetsStore()
3637
3738
const handleCancel = inject('cancel') as any
38-
const isManual = () => {
39-
if (ruleset.value.type === 'Manual' && ruleset.value.format === RulesetFormat.Binary) {
40-
ruleset.value.format = RulesetFormat.Source
41-
}
42-
updatePostfix()
43-
return ruleset.value.type === 'Manual'
44-
}
45-
46-
const updatePostfix = async () => {
47-
const source = ruleset.value.format === RulesetFormat.Source ? '.srs' : '.json'
48-
const target = ruleset.value.format === RulesetFormat.Source ? '.json' : '.srs'
49-
if (ruleset.value.path.endsWith(source)) {
50-
ruleset.value.path = ruleset.value.path.replace(source, target)
51-
}
52-
}
5339
5440
const handleSubmit = async () => {
5541
loading.value = true
@@ -79,6 +65,38 @@ const handleSubmit = async () => {
7965
loading.value = true
8066
}
8167
68+
const disabled = computed(
69+
() =>
70+
!ruleset.value.tag ||
71+
(ruleset.value.type === 'Manual' && !ruleset.value.path) ||
72+
(['Http', 'File'].includes(ruleset.value.type) && (!ruleset.value.url || !ruleset.value.path))
73+
)
74+
75+
watch(
76+
() => ruleset.value.type,
77+
(v) => {
78+
if (v === 'Manual') {
79+
ruleset.value.format = RulesetFormat.Source
80+
}
81+
}
82+
)
83+
84+
watch(
85+
() => ruleset.value.format,
86+
(v, old) => {
87+
const isJson = v === RulesetFormat.Source
88+
if (!isJson && ruleset.value.type === 'Manual') {
89+
ruleset.value.format = old
90+
message.error('Not support')
91+
return
92+
}
93+
ruleset.value.path = ruleset.value.path.replace(
94+
isJson ? '.srs' : '.json',
95+
isJson ? '.json' : '.srs'
96+
)
97+
}
98+
)
99+
82100
if (props.isUpdate) {
83101
const r = rulesetsStore.getRulesetById(props.id)
84102
if (r) {
@@ -102,7 +120,7 @@ if (props.isUpdate) {
102120
]"
103121
/>
104122
</div>
105-
<div v-show="!isManual()" class="form-item">
123+
<div v-show="ruleset.type !== 'Manual'" class="form-item">
106124
<div class="name">
107125
{{ t('ruleset.format.name') }}
108126
</div>
@@ -112,14 +130,14 @@ if (props.isUpdate) {
112130
<div class="name">{{ t('ruleset.name') }} *</div>
113131
<Input v-model="ruleset.tag" auto-size autofocus class="input" />
114132
</div>
115-
<div v-show="!isManual()" class="form-item">
133+
<div v-show="ruleset.type !== 'Manual'" class="form-item">
116134
<div class="name">{{ t('ruleset.url') }} *</div>
117135
<Input
118136
v-model="ruleset.url"
119137
:placeholder="
120138
ruleset.type === 'Http'
121139
? 'http(s)://'
122-
: 'data/local/{filename}.' + (ruleset.format === 'binary' ? 'srs' : 'json')
140+
: 'data/local/{filename}.' + (ruleset.format === RulesetFormat.Binary ? 'srs' : 'json')
123141
"
124142
auto-size
125143
class="input"
@@ -129,7 +147,7 @@ if (props.isUpdate) {
129147
<div class="name">{{ t('ruleset.path') }} *</div>
130148
<Input
131149
v-model="ruleset.path"
132-
placeholder="data/rulesets/{filename}.srs"
150+
:placeholder="`data/rulesets/{filename}.${ruleset.format === RulesetFormat.Binary ? 'srs' : 'json'}`"
133151
auto-size
134152
class="input"
135153
/>
@@ -138,12 +156,7 @@ if (props.isUpdate) {
138156

139157
<div class="form-action">
140158
<Button @click="handleCancel">{{ t('common.cancel') }}</Button>
141-
<Button
142-
@click="handleSubmit"
143-
:loading="loading"
144-
:disabled="!ruleset.tag || !ruleset.path || (ruleset.type === 'Http' && !ruleset.url)"
145-
type="primary"
146-
>
159+
<Button @click="handleSubmit" :loading="loading" :disabled="disabled" type="primary">
147160
{{ t('common.save') }}
148161
</Button>
149162
</div>

frontend/src/views/RulesetsView/index.vue

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const rulesetFormID = ref()
2525
const rulesetFormIsUpdate = ref(false)
2626
const subFormTitle = computed(() => (rulesetFormIsUpdate.value ? 'common.edit' : 'common.add'))
2727
28-
const menuList: Menu[] = [
28+
const sourceMenuList: Menu[] = [
2929
{
3030
label: 'rulesets.editRuleset',
3131
handler: (id: string) => handleEditRulesetList(id)
@@ -43,6 +43,15 @@ const menuList: Menu[] = [
4343
}
4444
]
4545
46+
const binaryMenuList: Menu[] = [
47+
{
48+
label: 'common.none',
49+
handler: (id: string) => {
50+
message.info('common.none')
51+
}
52+
}
53+
]
54+
4655
const { t } = useI18n()
4756
const { message } = useMessage()
4857
const envStore = useEnvStore()
@@ -74,7 +83,6 @@ const handleEditRuleset = (r: RuleSetType) => {
7483
const handleEditRulesetList = (id: string) => {
7584
const r = rulesetsStore.getRulesetById(id)
7685
if (r) {
77-
// r.path
7886
rulesetFormID.value = r.id
7987
rulesetTitle.value = r.tag
8088
showRulesetList.value = true
@@ -149,6 +157,13 @@ const _updateAllProvidersRules = async () => {
149157
}
150158
}
151159
160+
const generateMenus = (r: RuleSetType) => {
161+
return {
162+
[RulesetFormat.Source]: sourceMenuList,
163+
[RulesetFormat.Binary]: binaryMenuList
164+
}[r.format].map((v) => ({ ...v, handler: () => v.handler?.(r.id) }))
165+
}
166+
152167
const noUpdateNeeded = computed(() => rulesetsStore.rulesets.every((v) => v.disabled))
153168
154169
const onSortUpdate = debounce(rulesetsStore.saveRulesets, 1000)
@@ -197,11 +212,7 @@ const onSortUpdate = debounce(rulesetsStore.saveRulesets, 1000)
197212
:key="r.id"
198213
:title="r.tag"
199214
:disabled="r.disabled"
200-
v-menu="
201-
r.format == RulesetFormat.Source
202-
? menuList.map((v) => ({ ...v, handler: () => v.handler?.(r.id) }))
203-
: []
204-
"
215+
v-menu="generateMenus(r)"
205216
class="item"
206217
>
207218
<template #title-prefix>
@@ -264,13 +275,23 @@ const onSortUpdate = debounce(rulesetsStore.saveRulesets, 1000)
264275
</div>
265276

266277
<template v-if="appSettingsStore.app.rulesetsView === View.Grid">
278+
<div v-if="r.format === RulesetFormat.Source">
279+
{{ t('rulesets.rulesetCount') }}
280+
:
281+
{{ r.count }}
282+
</div>
267283
<div>
268284
{{ t('common.updateTime') }}
269285
:
270286
{{ r.updateTime ? formatRelativeTime(r.updateTime) : '--' }}
271287
</div>
272288
</template>
273289
<template v-else>
290+
<div v-if="r.format === RulesetFormat.Source">
291+
{{ t('rulesets.rulesetCount') }}
292+
:
293+
{{ r.count }}
294+
</div>
274295
<div>
275296
{{ t('common.updateTime') }}
276297
:

0 commit comments

Comments
 (0)