优化缓存条件设置,支持不缓存条件设置,支持条件排序等

This commit is contained in:
刘祥超
2021-06-08 22:46:08 +08:00
parent 9de66f080d
commit a8030fa045
17 changed files with 319 additions and 115 deletions

View File

@@ -1,5 +1,6 @@
// 单个缓存条件设置
Vue.component("http-cache-ref-box", {
props: ["v-cache-ref"],
props: ["v-cache-ref", "v-is-reverse"],
data: function () {
let ref = this.vCacheRef
if (ref == null) {
@@ -14,7 +15,8 @@ Vue.component("http-cache-ref-box", {
skipSetCookie: true,
enableRequestCachePragma: false,
conds: null,
allowChunkedEncoding: true
allowChunkedEncoding: true,
isReverse: this.vIsReverse
}
}
if (ref.life == null) {
@@ -51,50 +53,50 @@ Vue.component("http-cache-ref-box", {
<input type="hidden" name="cacheRefJSON" :value="JSON.stringify(ref)"/>
</td>
</tr>
<tr>
<tr v-show="!vIsReverse">
<td>缓存有效期 *</td>
<td>
<time-duration-box :v-value="ref.life" @change="changeLife"></time-duration-box>
</td>
</tr>
<tr>
<tr v-show="!vIsReverse">
<td>缓存Key *</td>
<td>
<input type="text" v-model="ref.key"/>
<p class="comment">用来区分不同缓存内容的唯一Key。</p>
</td>
</tr>
<tr>
<tr v-show="!vIsReverse">
<td colspan="2"><more-options-indicator @change="changeOptionsVisible"></more-options-indicator></td>
</tr>
<tr v-show="moreOptionsVisible">
<tr v-show="moreOptionsVisible && !vIsReverse">
<td>可缓存的最大文件</td>
<td>
<size-capacity-box :v-value="ref.maxSize" @change="changeMaxSize"></size-capacity-box>
</td>
</tr>
<tr v-show="moreOptionsVisible">
<tr v-show="moreOptionsVisible && !vIsReverse">
<td>支持分片内容</td>
<td>
<checkbox name="allowChunkedEncoding" value="1" v-model="ref.allowChunkedEncoding"></checkbox>
<p class="comment">选中后Gzip和Chunked内容可以直接缓存无需检查内容长度。</p>
</td>
</tr>
<tr v-show="moreOptionsVisible">
<tr v-show="moreOptionsVisible && !vIsReverse">
<td>状态码列表</td>
<td>
<values-box name="statusList" size="3" maxlength="3" :values="ref.status"></values-box>
<p class="comment">允许缓存的HTTP状态码列表。</p>
</td>
</tr>
<tr v-show="moreOptionsVisible">
<tr v-show="moreOptionsVisible && !vIsReverse">
<td>跳过的Cache-Control值</td>
<td>
<values-box name="skipResponseCacheControlValues" size="10" maxlength="100" :values="ref.skipCacheControlValues"></values-box>
<p class="comment">当响应的Cache-Control为这些值时不缓存响应内容而且不区分大小写。</p>
</td>
</tr>
<tr v-show="moreOptionsVisible">
<tr v-show="moreOptionsVisible && !vIsReverse">
<td>跳过Set-Cookie</td>
<td>
<div class="ui checkbox">
@@ -104,7 +106,7 @@ Vue.component("http-cache-ref-box", {
<p class="comment">选中后当响应的Header中有Set-Cookie时不缓存响应内容。</p>
</td>
</tr>
<tr v-show="moreOptionsVisible">
<tr v-show="moreOptionsVisible && !vIsReverse">
<td>支持请求no-cache刷新</td>
<td>
<div class="ui checkbox">

View File

@@ -1,3 +1,4 @@
// 缓存条件列表
Vue.component("http-cache-refs-box", {
props: ["v-cache-refs"],
data: function () {
@@ -36,15 +37,23 @@ Vue.component("http-cache-refs-box", {
<table class="ui table selectable celled">
<thead>
<tr>
<th>缓存条件</th>
<th>条件</th>
<th class="two">分组关系</th>
<th class="width10">缓存时间</th>
<th class="two op">操作</th>
</tr>
<tr v-for="(cacheRef, index) in refs">
<td>
<td :class="{'color-border': cacheRef.conds.connector == 'and'}" :style="{'border-left':cacheRef.isReverse ? '1px #db2828 solid' : ''}">
<http-request-conds-view :v-conds="cacheRef.conds"></http-request-conds-view>
</td>
<td>{{cacheRef.life.count}} {{timeUnitName(cacheRef.life.unit)}}</td>
<td>
<span v-if="cacheRef.conds.connector == 'and'">和</span>
<span v-if="cacheRef.conds.connector == 'or'">或</span>
</td>
<td>
<span v-if="!cacheRef.isReverse">{{cacheRef.life.count}} {{timeUnitName(cacheRef.life.unit)}}</span>
<span v-else class="red">不缓存</span>
</td>
<td>
<a href="" @click.prevent="updateRef(index, cacheRef)">修改</a> &nbsp;
<a href="" @click.prevent="removeRef(index)">删除</a>

View File

@@ -1,16 +1,37 @@
Vue.component("http-cache-refs-config-box", {
props: ["v-cache-refs"],
mounted: function () {
let that = this
sortTable(function (ids) {
let newRefs = []
ids.forEach(function (id) {
that.refs.forEach(function (ref) {
if (ref.id == id) {
newRefs.push(ref)
}
})
})
that.refs = newRefs
})
},
data: function () {
let refs = this.vCacheRefs
if (refs == null) {
refs = []
}
let id = 0
refs.forEach(function (ref) {
id++
ref.id = id
})
return {
refs: refs
refs: refs,
id: id // 用来对条件进行排序
}
},
methods: {
addRef: function () {
addRef: function (isReverse) {
window.UPDATING_CACHE_REF = null
let width = window.innerWidth
@@ -22,10 +43,12 @@ Vue.component("http-cache-refs-config-box", {
height = 500
}
let that = this
teaweb.popup("/servers/server/settings/cache/createPopup", {
teaweb.popup("/servers/server/settings/cache/createPopup?isReverse=" + (isReverse ? 1 : 0), {
width: width + "px",
height: height + "px",
callback: function (resp) {
that.id++
resp.data.cacheRef.id = that.id
that.refs.push(resp.data.cacheRef)
}
})
@@ -46,7 +69,11 @@ Vue.component("http-cache-refs-config-box", {
width: width + "px",
height: height + "px",
callback: function (resp) {
resp.data.cacheRef.id = that.refs[index].id
Vue.set(that.refs, index, resp.data.cacheRef)
// 通知子组件更新
that.$refs.cacheRef[index].notifyChange()
}
})
},
@@ -78,27 +105,40 @@ Vue.component("http-cache-refs-config-box", {
<input type="hidden" name="refsJSON" :value="JSON.stringify(refs)"/>
<div>
<table class="ui table selectable celled" v-show="refs.length > 0">
<table class="ui table selectable celled" v-show="refs.length > 0" id="sortable-table">
<thead>
<tr>
<th>缓存条件</th>
<th style="width:1em"></th>
<th>条件</th>
<th class="two wide">分组关系</th>
<th class="width10">缓存时间</th>
<th class="two op">操作</th>
</tr>
<tr v-for="(cacheRef, index) in refs">
<td>
<http-request-conds-view :v-conds="cacheRef.conds"></http-request-conds-view>
</thead>
<tbody v-for="(cacheRef, index) in refs" :key="cacheRef.id" :v-id="cacheRef.id">
<tr>
<td style="text-align: center;"><i class="icon bars handle grey"></i> </td>
<td :class="{'color-border': cacheRef.conds.connector == 'and'}" :style="{'border-left':cacheRef.isReverse ? '1px #db2828 solid' : ''}">
<http-request-conds-view :v-conds="cacheRef.conds" ref="cacheRef"></http-request-conds-view>
</td>
<td>
<span v-if="cacheRef.conds.connector == 'and'">和</span>
<span v-if="cacheRef.conds.connector == 'or'">或</span>
</td>
<td>
<span v-if="!cacheRef.isReverse">{{cacheRef.life.count}} {{timeUnitName(cacheRef.life.unit)}}</span>
<span v-else class="red">不缓存</span>
</td>
<td>{{cacheRef.life.count}} {{timeUnitName(cacheRef.life.unit)}}</td>
<td>
<a href="" @click.prevent="updateRef(index, cacheRef)">修改</a> &nbsp;
<a href="" @click.prevent="removeRef(index)">删除</a>
</td>
</tr>
</thead>
</tbody>
</table>
<p class="comment" v-if="refs.length > 1">所有条件匹配顺序为从上到下,可以拖动左侧的<i class="icon bars"></i>排序。</p>
<button class="ui button tiny" @click.prevent="addRef">+添加缓存设置</button>
<button class="ui button tiny" @click.prevent="addRef(false)">+添加缓存设置</button> &nbsp; &nbsp; <a href="" @click.prevent="addRef(true)">+添加不缓存设置</a>
</div>
<div class="margin"></div>
</div>`

View File

@@ -2,18 +2,26 @@
Vue.component("http-cond-url-extension", {
props: ["v-cond"],
data: function () {
let cond = this.vCond
if (cond == null) {
cond = {
isRequest: true,
param: "${requestPathExtension}",
operator: "in",
value: "[]"
}
let cond = {
isRequest: true,
param: "${requestPathExtension}",
operator: "in",
value: "[]"
}
if (this.vCond != null && this.vCond.param == cond.param) {
cond.value = this.vCond.value
}
let extensions = []
try {
extensions = JSON.parse(cond.value)
} catch (e) {
}
return {
cond: cond,
extensions: JSON.parse(cond.value), // TODO 可以拖动排序
extensions: extensions, // TODO 可以拖动排序
isAdding: false,
addingExt: ""
@@ -49,7 +57,7 @@ Vue.component("http-cond-url-extension", {
if (this.addingExt[0] != ".") {
this.addingExt = "." + this.addingExt
}
this.addingExt = this.addingExt.replace(/\s+/g, "")
this.addingExt = this.addingExt.replace(/\s+/g, "").toLowerCase()
this.extensions.push(this.addingExt)
// 清除状态
@@ -74,7 +82,9 @@ Vue.component("http-cond-url-extension", {
<a href="" title="取消" @click.prevent="cancelAdding"><i class="icon remove"></i></a>
</div>
</div>
<button class="ui button tiny" type="button" @click.prevent="addExt()">+添加扩展名</button>
<div style="margin-top: 1em">
<button class="ui button tiny" type="button" @click.prevent="addExt()">+添加扩展名</button>
</div>
<p class="comment">扩展名需要包含点(.)符号,例如<span class="ui label tiny">.jpg</span>、<span class="ui label tiny">.png</span>之类。</p>
</div>`
})
@@ -83,14 +93,14 @@ Vue.component("http-cond-url-extension", {
Vue.component("http-cond-url-prefix", {
props: ["v-cond"],
data: function () {
let cond = this.vCond
if (cond == null) {
cond = {
isRequest: true,
param: "${requestPath}",
operator: "prefix",
value: ""
}
let cond = {
isRequest: true,
param: "${requestPath}",
operator: "prefix",
value: ""
}
if (this.vCond != null && typeof (this.vCond.value) == "string") {
cond.value = this.vCond.value
}
return {
cond: cond
@@ -99,6 +109,31 @@ Vue.component("http-cond-url-prefix", {
template: `<div>
<input type="hidden" name="condJSON" :value="JSON.stringify(cond)"/>
<input type="text" v-model="cond.value"/>
<p class="comment">URL前缀通常以<code-label>/</code-label>开头,比如<code-label>/static</code-label>。</p>
</div>`
})
Vue.component("http-cond-url-not-prefix", {
props: ["v-cond"],
data: function () {
let cond = {
isRequest: true,
param: "${requestPath}",
operator: "prefix",
value: "",
isReverse: true
}
if (this.vCond != null && typeof this.vCond.value == "string") {
cond.value = this.vCond.value
}
return {
cond: cond
}
},
template: `<div>
<input type="hidden" name="condJSON" :value="JSON.stringify(cond)"/>
<input type="text" v-model="cond.value"/>
<p class="comment">要排除的URL前缀通常以<code-label>/</code-label>开头,比如<code-label>/static</code-label>。</p>
</div>`
})
@@ -106,22 +141,47 @@ Vue.component("http-cond-url-prefix", {
Vue.component("http-cond-url-eq", {
props: ["v-cond"],
data: function () {
let cond = this.vCond
if (cond == null) {
cond = {
isRequest: true,
param: "${requestPath}",
operator: "eq",
value: ""
}
let cond = {
isRequest: true,
param: "${requestPath}",
operator: "eq",
value: ""
}
if (this.vCond != null && typeof this.vCond.value == "string") {
cond.value = this.vCond.value
}
return {
cond: cond
}
},
template: `<div>
<input type="hidden" name="condJSON" :value="JSON.stringify(cond)"/>
<input type="hidden" name="condJSON" :value="JSON.stringify(cond)"/>
<input type="text" v-model="cond.value"/>
<p class="comment">完整的URL路径通常以<code-label>/</code-label>开头,比如<code-label>/static/ui.js</code-label>。</p>
</div>`
})
Vue.component("http-cond-url-not-eq", {
props: ["v-cond"],
data: function () {
let cond = {
isRequest: true,
param: "${requestPath}",
operator: "eq",
value: "",
isReverse: true
}
if (this.vCond != null && typeof this.vCond.value == "string") {
cond.value = this.vCond.value
}
return {
cond: cond
}
},
template: `<div>
<input type="hidden" name="condJSON" :value="JSON.stringify(cond)"/>
<input type="text" v-model="cond.value"/>
<p class="comment">要排除的完整的URL路径通常以<code-label>/</code-label>开头,比如<code-label>/static/ui.js</code-label>。</p>
</div>`
})
@@ -129,22 +189,23 @@ Vue.component("http-cond-url-eq", {
Vue.component("http-cond-url-regexp", {
props: ["v-cond"],
data: function () {
let cond = this.vCond
if (cond == null) {
cond = {
isRequest: true,
param: "${requestPath}",
operator: "regexp",
value: ""
}
let cond = {
isRequest: true,
param: "${requestPath}",
operator: "regexp",
value: ""
}
if (this.vCond != null && typeof this.vCond.value == "string") {
cond.value = this.vCond.value
}
return {
cond: cond
}
},
template: `<div>
<input type="hidden" name="condJSON" :value="JSON.stringify(cond)"/>
<input type="hidden" name="condJSON" :value="JSON.stringify(cond)"/>
<input type="text" v-model="cond.value"/>
<p class="comment">匹配URL的正则表达式比如<code-label>^/static/(.*).js$</code-label>。</p>
</div>`
})
@@ -152,22 +213,23 @@ Vue.component("http-cond-url-regexp", {
Vue.component("http-cond-url-not-regexp", {
props: ["v-cond"],
data: function () {
let cond = this.vCond
if (cond == null) {
cond = {
isRequest: true,
param: "${requestPath}",
operator: "not regexp",
value: ""
}
let cond = {
isRequest: true,
param: "${requestPath}",
operator: "not regexp",
value: ""
}
if (this.vCond != null && typeof this.vCond.value == "string") {
cond.value = this.vCond.value
}
return {
cond: cond
}
},
template: `<div>
<input type="hidden" name="condJSON" :value="JSON.stringify(cond)"/>
<input type="hidden" name="condJSON" :value="JSON.stringify(cond)"/>
<input type="text" v-model="cond.value"/>
<p class="comment"><strong>不要</strong>匹配URL的正则表达式意即只要匹配成功则排除此条件比如<code-label>^/static/(.*).js$</code-label>。</p>
</div>`
})
@@ -175,14 +237,14 @@ Vue.component("http-cond-url-not-regexp", {
Vue.component("http-cond-mime-type", {
props: ["v-cond"],
data: function () {
let cond = this.vCond
if (cond == null) {
cond = {
isRequest: false,
param: "${response.contentType}",
operator: "mime type",
value: "[]"
}
let cond = {
isRequest: false,
param: "${response.contentType}",
operator: "mime type",
value: "[]"
}
if (this.vCond != null && this.vCond.param == cond.param) {
cond.value = this.vCond.value
}
return {
cond: cond,
@@ -244,7 +306,9 @@ Vue.component("http-cond-mime-type", {
<a href="" title="取消" @click.prevent="cancelAdding"><i class="icon remove"></i></a>
</div>
</div>
<button class="ui button tiny" type="button" @click.prevent="addMimeType()">+添加MimeType</button>
<div style="margin-top: 1em">
<button class="ui button tiny" type="button" @click.prevent="addMimeType()">+添加MimeType</button>
</div>
<p class="comment">服务器返回的内容的MimeType比如<span class="ui label tiny">text/html</span>、<span class="ui label tiny">image/*</span>等。</p>
</div>`
})

View File

@@ -63,7 +63,7 @@ Vue.component("http-request-conds-box", {
<div v-if="conds.groups.length > 0">
<table class="ui table">
<tr v-for="(group, groupIndex) in conds.groups">
<td class="title" :style="{'border-bottom':(groupIndex < conds.groups.length-1) ? '1px solid rgba(34,36,38,.15)':''}">分组{{groupIndex+1}}</td>
<td class="title" :class="{'color-border':conds.connector == 'and'}" :style="{'border-bottom':(groupIndex < conds.groups.length-1) ? '1px solid rgba(34,36,38,.15)':''}">分组{{groupIndex+1}}</td>
<td style="background: white;" :style="{'border-bottom':(groupIndex < conds.groups.length-1) ? '1px solid rgba(34,36,38,.15)':''}">
<var v-for="(cond, index) in group.conds" style="font-style: normal;display: inline-block; margin-bottom:0.5em">
<span class="ui label tiny">
@@ -76,20 +76,33 @@ Vue.component("http-request-conds-box", {
</var>
</td>
<td style="width: 5em; background: white" :style="{'border-bottom':(groupIndex < conds.groups.length-1) ? '1px solid rgba(34,36,38,.15)':''}">
<a href="" title="修改" @click.prevent="updateGroup(groupIndex, group)"><i class="icon pencil small"></i></a> <a href="" title="删除" @click.prevent="removeGroup(groupIndex)"><i class="icon remove"></i></a>
<a href="" title="修改分组" @click.prevent="updateGroup(groupIndex, group)"><i class="icon pencil small"></i></a> <a href="" title="删除分组" @click.prevent="removeGroup(groupIndex)"><i class="icon remove"></i></a>
</td>
</tr>
</table>
<div class="ui divider"></div>
</div>
<!-- 分组之间关系 -->
<table class="ui table" v-if="conds.groups.length > 1">
<tr>
<td class="title">分组之间关系</td>
<td>
<select class="ui dropdown auto-width" v-model="conds.connector">
<option value="and">和</option>
<option value="or">或</option>
</select>
<p class="comment">
<span v-if="conds.connector == 'or'">只要满足其中一个条件分组即可。</span>
<span v-if="conds.connector == 'and'">需要满足所有条件分组。</span>
</p>
</td>
</tr>
</table>
<div>
<button class="ui button tiny" type="button" @click.prevent="addGroup()">+</button>
<button class="ui button tiny" type="button" @click.prevent="addGroup()">+添加分组</button>
</div>
<p class="comment">
<span v-if="conds.connector == 'or'">只要满足其中一个条件分组即可。</span>
<span v-if="conds.connector == 'and'">需要满足所有条件分组。</span>
</p>
</div>
</div>`
})

View File

@@ -9,35 +9,53 @@ Vue.component("http-request-conds-view", {
groups: []
}
}
let that = this
conds.groups.forEach(function (group) {
group.conds.forEach(function (cond) {
cond.typeName = that.typeName(cond)
})
})
return {
initConds: conds,
components: window.REQUEST_COND_COMPONENTS
version: 0 // 为了让组件能及时更新加入此变量
}
},
computed: {
// 之所以使用computed是因为需要动态更新
conds: function () {
return this.initConds
},
}
},
methods: {
typeName: function (cond) {
let c = this.components.$find(function (k, v) {
let c = window.REQUEST_COND_COMPONENTS.$find(function (k, v) {
return v.type == cond.type
})
if (c != null) {
return c.name;
}
return cond.param + " " + cond.operator
},
notifyChange: function () {
this.version++
let that = this
this.initConds.groups.forEach(function (group) {
group.conds.forEach(function (cond) {
cond.typeName = that.typeName(cond)
})
})
}
},
template: `<div>
<span v-if="version < 0">{{version}}</span>
<div v-if="conds.groups.length > 0">
<div v-for="(group, groupIndex) in conds.groups">
<var v-for="(cond, index) in group.conds" style="font-style: normal;display: inline-block; margin-bottom:0.5em">
<span class="ui label tiny">
<var v-if="cond.type.length == 0" style="font-style: normal">{{cond.param}} <var>{{cond.operator}}</var></var>
<var v-if="cond.type.length > 0" style="font-style: normal">{{typeName(cond)}}: </var>
<var v-if="cond.type.length > 0" style="font-style: normal">{{cond.typeName}}: </var>
{{cond.value}}
</span>