修复编译时components.js可能没有更新的Bug

This commit is contained in:
GoEdgeLab
2021-12-08 10:03:27 +08:00
parent 5db25e3d3c
commit d943de2b3b
2 changed files with 151 additions and 40 deletions

View File

@@ -50,6 +50,10 @@ function build() {
echo "=============================="
cd -
# generate files
echo "generating files ..."
go run -tags $TAG $ROOT/../cmd/edge-admin/main.go generate
# create dir & copy files
echo "copying ..."
if [ ! -d $DIST ]; then
@@ -83,10 +87,6 @@ function build() {
rm -f $(basename $EDGE_API_ZIP_FILE)
cd -
# generate files
echo "generating files ..."
go run -tags $TAG $ROOT/../cmd/edge-admin/main.go generate
# build
echo "building "${NAME}" ..."
env GOOS=$OS GOARCH=$ARCH go build -tags $TAG -ldflags="-s -w" -o $DIST/bin/${NAME} $ROOT/../cmd/edge-admin/main.go

View File

@@ -57,10 +57,24 @@ Vue.component("traffic-map-box", {
areaColor: "#E9F0F9",
borderColor: "#DDD"
},
label: {
show: false,
fontSize: "10px",
color: "#fff",
backgroundColor: "#8B9BD3",
padding: [2, 2, 2, 2]
},
emphasis: {
itemStyle: {
areaColor: "#8B9BD3",
opacity: 1.0
},
label: {
show: true,
fontSize: "10px",
color: "#fff",
backgroundColor: "#8B9BD3",
padding: [2, 2, 2, 2]
}
},
//select: {itemStyle:{ areaColor: "#8B9BD3", opacity: 0.8 }},
@@ -107,6 +121,12 @@ Vue.component("traffic-map-box", {
itemStyle: {
areaColor: bgColor,
opacity: fullOpacity
},
label: {
show: true,
formatter: function (args) {
return args.name
}
}
},
label: {
@@ -2254,6 +2274,7 @@ Vue.component("http-cache-refs-box", {
<span v-if="cacheRef.maxSize != null && cacheRef.maxSize.count > 0">- {{cacheRef.maxSize.count}}{{cacheRef.maxSize.unit}}</span>
</grey-label>
<grey-label v-else-if="cacheRef.maxSize != null && cacheRef.maxSize.count > 0">0 - {{cacheRef.maxSize.count}}{{cacheRef.maxSize.unit}}</grey-label>
<grey-label v-if="cacheRef.methods != null && cacheRef.methods.length > 0">{{cacheRef.methods.join(", ")}}</grey-label>
<grey-label v-if="cacheRef.status != null && cacheRef.status.length > 0 && (cacheRef.status.length > 1 || cacheRef.status[0] != 200)">状态码:{{cacheRef.status.map(function(v) {return v.toString()}).join(", ")}}</grey-label>
</td>
<td>
@@ -2515,13 +2536,16 @@ Vue.component("http-host-redirect-box", {
// 单个缓存条件设置
Vue.component("http-cache-ref-box", {
props: ["v-cache-ref", "v-is-reverse"],
mounted: function () {
this.$refs.variablesDescriber.update(this.ref.key)
},
data: function () {
let ref = this.vCacheRef
if (ref == null) {
ref = {
isOn: true,
cachePolicyId: 0,
key: "${scheme}://${host}${requestURI}",
key: "${scheme}://${host}${requestPath}${isArgs}${args}",
life: {count: 2, unit: "hour"},
status: [200],
maxSize: {count: 32, unit: "mb"},
@@ -2531,9 +2555,17 @@ Vue.component("http-cache-ref-box", {
enableRequestCachePragma: false,
conds: null,
allowChunkedEncoding: true,
isReverse: this.vIsReverse
isReverse: this.vIsReverse,
methods: []
}
}
if (ref.key == null) {
ref.key = ""
}
if (ref.methods == null) {
ref.methods = []
}
if (ref.life == null) {
ref.life = {count: 2, unit: "hour"}
}
@@ -2574,6 +2606,14 @@ Vue.component("http-cache-ref-box", {
result.push(statusNumber)
})
this.ref.status = result
},
changeMethods: function (methods) {
this.ref.methods = methods.map(function (v) {
return v.toUpperCase()
})
},
changeKey: function (key) {
this.$refs.variablesDescriber.update(key)
}
},
template: `<tbody>
@@ -2594,13 +2634,20 @@ Vue.component("http-cache-ref-box", {
<tr v-show="!vIsReverse">
<td>缓存Key *</td>
<td>
<input type="text" v-model="ref.key"/>
<p class="comment">用来区分不同缓存内容的唯一Key。</p>
<input type="text" v-model="ref.key" @input="changeKey(ref.key)"/>
<p class="comment">用来区分不同缓存内容的唯一Key。<request-variables-describer ref="variablesDescriber"></request-variables-describer>。</p>
</td>
</tr>
<tr v-show="!vIsReverse">
<td colspan="2"><more-options-indicator @change="changeOptionsVisible"></more-options-indicator></td>
</tr>
<tr v-show="moreOptionsVisible && !vIsReverse">
<td>请求方法</td>
<td>
<values-box size="5" maxlength="10" :values="ref.methods" @change="changeMethods"></values-box>
<p class="comment">允许请求的缓存方法,默认支持所有的请求方法。</p>
</td>
</tr>
<tr v-show="moreOptionsVisible && !vIsReverse">
<td>可缓存的最大内容尺寸</td>
<td>
@@ -3791,6 +3838,7 @@ Vue.component("http-cache-refs-config-box", {
<span v-if="cacheRef.maxSize != null && cacheRef.maxSize.count > 0">- {{cacheRef.maxSize.count}}{{cacheRef.maxSize.unit}}</span>
</grey-label>
<grey-label v-else-if="cacheRef.maxSize != null && cacheRef.maxSize.count > 0">0 - {{cacheRef.maxSize.count}}{{cacheRef.maxSize.unit}}</grey-label>
<grey-label v-if="cacheRef.methods != null && cacheRef.methods.length > 0">{{cacheRef.methods.join(", ")}}</grey-label>
<grey-label v-if="cacheRef.status != null && cacheRef.status.length > 0 && (cacheRef.status.length > 1 || cacheRef.status[0] != 200)">状态码:{{cacheRef.status.map(function(v) {return v.toString()}).join(", ")}}</grey-label>
</td>
<td>
@@ -3808,7 +3856,7 @@ Vue.component("http-cache-refs-config-box", {
</tr>
</tbody>
</table>
<p class="comment" v-if="refs.length > 1">所有条件匹配顺序为从上到下,可以拖动左侧的<i class="icon bars"></i>排序。</p>
<p class="comment" v-if="refs.length > 1">所有条件匹配顺序为从上到下,可以拖动左侧的<i class="icon bars"></i>排序。服务设置的优先级比全局缓存策略设置的优先级要高。</p>
<button class="ui button tiny" @click.prevent="addRef(false)">+添加缓存设置</button> &nbsp; &nbsp; <a href="" @click.prevent="addRef(true)">+添加不缓存设置</a>
</div>
@@ -5501,7 +5549,7 @@ Vue.component("http-header-policy-box", {
responseDeletingHeaders = responsePolicy.deleteHeaders
}
}
return {
type: type,
typeName: (type == "request") ? "请求" : "响应",
@@ -5522,21 +5570,21 @@ Vue.component("http-header-policy-box", {
addSettingHeader: function (policyId) {
teaweb.popup("/servers/server/settings/headers/createSetPopup?" + this.vParams + "&headerPolicyId=" + policyId, {
callback: function () {
window.location.reload()
teaweb.successRefresh("保存成功")
}
})
},
addDeletingHeader: function (policyId, type) {
teaweb.popup("/servers/server/settings/headers/createDeletePopup?" + this.vParams + "&headerPolicyId=" + policyId + "&type=" + type, {
callback: function () {
window.location.reload()
teaweb.successRefresh("保存成功")
}
})
},
updateSettingPopup: function (policyId, headerId) {
teaweb.popup("/servers/server/settings/headers/updateSetPopup?" + this.vParams + "&headerPolicyId=" + policyId + "&headerId=" + headerId, {
callback: function () {
window.location.reload()
teaweb.successRefresh("保存成功")
}
})
},
@@ -6393,7 +6441,8 @@ Vue.component("http-access-log-config-box", {
})
return {
accessLog: accessLog
accessLog: accessLog,
hasRequestBodyField: this.vFields.$contains(8)
}
},
methods: {
@@ -6403,6 +6452,7 @@ Vue.component("http-access-log-config-box", {
}).map(function (v) {
return v.code
})
this.hasRequestBodyField = this.accessLog.fields.$contains(8)
}
},
template: `<div>
@@ -6423,12 +6473,19 @@ Vue.component("http-access-log-config-box", {
</tbody>
<tbody v-show="((!vIsLocation && !vIsGroup) || accessLog.isPrior) && accessLog.isOn">
<tr>
<td>要存储的访问日志字段</td>
<td>基础信息</td>
<td><p class="comment" style="padding-top: 0">默认记录客户端IP、请求URL等基础信息。</p></td>
</tr>
<tr>
<td>高级信息</td>
<td>
<div class="ui checkbox" v-for="field in vFields" style="width:10em;margin-bottom:0.8em">
<input type="checkbox" v-model="field.isChecked" @change="changeFields"/>
<label>{{field.name}}</label>
<div class="ui checkbox" v-for="(field, index) in vFields" style="width:10em;margin-bottom:0.8em">
<input type="checkbox" v-model="field.isChecked" @change="changeFields" :id="'access-log-field-' + index"/>
<label :for="'access-log-field-' + index">{{field.name}}</label>
</div>
<p class="comment">在基础信息之外要存储的信息。
<span class="red" v-if="hasRequestBodyField">记录"请求Body"将会显著消耗更多的系统资源建议仅在调试时启用最大记录尺寸为2MB。</span>
</p>
</td>
</tr>
<tr>
@@ -10422,6 +10479,41 @@ Vue.component("health-check-config-box", {
</div>`
})
// 将变量转换为中文
Vue.component("request-variables-describer", {
data: function () {
return {
vars:[]
}
},
methods: {
update: function (variablesString) {
this.vars = []
let that = this
variablesString.replace(/\${.+?}/g, function (v) {
let def = that.findVar(v)
if (def == null) {
return v
}
that.vars.push(def)
})
},
findVar: function (name) {
let def = null
window.REQUEST_VARIABLES.forEach(function (v) {
if (v.code == name) {
def = v
}
})
return def
}
},
template: `<span>
<span v-for="(v, index) in vars"><code-label :title="v.description">{{v.code}}</code-label> - {{v.name}}<span v-if="index < vars.length-1"></span></span>
</span>`
})
Vue.component("time-duration-box", {
props: ["v-name", "v-value", "v-count", "v-unit"],
mounted: function () {
@@ -10817,7 +10909,7 @@ Vue.component("node-role-name", {
let sourceCodeBoxIndex = 0
Vue.component("source-code-box", {
props: ["name", "type", "id", "read-only"],
props: ["name", "type", "id", "read-only", "width", "height"],
mounted: function () {
let readOnly = this.readOnly
if (typeof readOnly != "boolean") {
@@ -10831,27 +10923,46 @@ Vue.component("source-code-box", {
} else if (valueBox.innerText != null) {
value = valueBox.innerText
}
let boxEditor = CodeMirror.fromTextArea(box, {
theme: "idea",
lineNumbers: true,
value: "",
readOnly: readOnly,
showCursorWhenSelecting: true,
height: "auto",
//scrollbarStyle: null,
viewportMargin: Infinity,
lineWrapping: true,
highlightFormatting: false,
indentUnit: 4,
indentWithTabs: true
})
boxEditor.setValue(value)
let info = CodeMirror.findModeByMIME(this.type)
if (info != null) {
boxEditor.setOption("mode", info.mode)
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js"
CodeMirror.autoLoadMode(boxEditor, info.mode)
this.createEditor(box, value, readOnly)
},
methods: {
createEditor: function (box, value, readOnly) {
let boxEditor = CodeMirror.fromTextArea(box, {
theme: "idea",
lineNumbers: true,
value: "",
readOnly: readOnly,
showCursorWhenSelecting: true,
height: "auto",
//scrollbarStyle: null,
viewportMargin: Infinity,
lineWrapping: true,
highlightFormatting: false,
indentUnit: 4,
indentWithTabs: true
})
boxEditor.setValue(value)
let width = this.width
let height = this.height
if (width != null && height != null) {
width = parseInt(width)
height = parseInt(height)
if (!isNaN(width) && !isNaN(height)) {
if (width <= 0) {
width = box.parentNode.offsetWidth
}
boxEditor.setSize(width, height)
}
}
let info = CodeMirror.findModeByMIME(this.type)
if (info != null) {
boxEditor.setOption("mode", info.mode)
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js"
CodeMirror.autoLoadMode(boxEditor, info.mode)
}
}
},
data: function () {
@@ -12357,7 +12468,7 @@ window.REQUEST_COND_COMPONENTS = [{"type":"url-extension","name":"URL扩展名",
window.REQUEST_COND_OPERATORS = [{"description":"判断是否正则表达式匹配","name":"正则表达式匹配","op":"regexp"},{"description":"判断是否正则表达式不匹配","name":"正则表达式不匹配","op":"not regexp"},{"description":"使用字符串对比参数值是否相等于某个值","name":"字符串等于","op":"eq"},{"description":"参数值包含某个前缀","name":"字符串前缀","op":"prefix"},{"description":"参数值包含某个后缀","name":"字符串后缀","op":"suffix"},{"description":"参数值包含另外一个字符串","name":"字符串包含","op":"contains"},{"description":"参数值不包含另外一个字符串","name":"字符串不包含","op":"not contains"},{"description":"使用字符串对比参数值是否不相等于某个值","name":"字符串不等于","op":"not"},{"description":"判断参数值在某个列表中","name":"在列表中","op":"in"},{"description":"判断参数值不在某个列表中","name":"不在列表中","op":"not in"},{"description":"判断小写的扩展名(不带点)在某个列表中","name":"扩展名","op":"file ext"},{"description":"判断MimeType在某个列表中支持类似于image/*的语法","name":"MimeType","op":"mime type"},{"description":"判断版本号在某个范围内格式为version1,version2","name":"版本号范围","op":"version range"},{"description":"将参数转换为整数数字后进行对比","name":"整数等于","op":"eq int"},{"description":"将参数转换为可以有小数的浮点数字进行对比","name":"浮点数等于","op":"eq float"},{"description":"将参数转换为数字进行对比","name":"数字大于","op":"gt"},{"description":"将参数转换为数字进行对比","name":"数字大于等于","op":"gte"},{"description":"将参数转换为数字进行对比","name":"数字小于","op":"lt"},{"description":"将参数转换为数字进行对比","name":"数字小于等于","op":"lte"},{"description":"对整数参数值取模除数为10对比值为余数","name":"整数取模10","op":"mod 10"},{"description":"对整数参数值取模除数为100对比值为余数","name":"整数取模100","op":"mod 100"},{"description":"对整数参数值取模,对比值格式为:除数,余数比如10,1","name":"整数取模","op":"mod"},{"description":"将参数转换为IP进行对比","name":"IP等于","op":"eq ip"},{"description":"将参数转换为IP进行对比","name":"IP大于","op":"gt ip"},{"description":"将参数转换为IP进行对比","name":"IP大于等于","op":"gte ip"},{"description":"将参数转换为IP进行对比","name":"IP小于","op":"lt ip"},{"description":"将参数转换为IP进行对比","name":"IP小于等于","op":"lte ip"},{"description":"IP在某个范围之内范围格式可以是英文逗号分隔的ip1,ip2或者CIDR格式的ip/bits","name":"IP范围","op":"ip range"},{"description":"对IP参数值取模除数为10对比值为余数","name":"IP取模10","op":"ip mod 10"},{"description":"对IP参数值取模除数为100对比值为余数","name":"IP取模100","op":"ip mod 100"},{"description":"对IP参数值取模对比值格式为除数,余数比如10,1","name":"IP取模","op":"ip mod"},{"description":"判断参数值解析后的文件是否存在","name":"文件存在","op":"file exist"},{"description":"判断参数值解析后的文件是否不存在","name":"文件不存在","op":"file not exist"}]
window.REQUEST_VARIABLES = [{"code":"${edgeVersion}","description":"","name":"边缘节点版本"},{"code":"${remoteAddr}","description":"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取适合前端有别的反向代理服务时使用存在伪造的风险","name":"客户端地址IP"},{"code":"${rawRemoteAddr}","description":"返回直接连接服务的客户端原始IP地址","name":"客户端地址IP"},{"code":"${remotePort}","description":"","name":"客户端端口"},{"code":"${remoteUser}","description":"","name":"客户端用户名"},{"code":"${requestURI}","description":"比如/hello?name=lily","name":"请求URI"},{"code":"${requestPath}","description":"比如/hello","name":"请求路径(不包括参数)"},{"code":"${requestURL}","description":"比如https://example.com/hello?name=lily","name":"完整的请求URL"},{"code":"${requestLength}","description":"","name":"请求内容长度"},{"code":"${requestMethod}","description":"比如GET、POST","name":"请求方法"},{"code":"${requestFilename}","description":"","name":"请求文件路径"},{"code":"${scheme}","description":"","name":"请求协议http或https"},{"code":"${proto}","description:":"类似于HTTP/1.0","name":"包含版本的HTTP请求协议"},{"code":"${timeISO8601}","description":"比如2018-07-16T23:52:24.839+08:00","name":"ISO 8601格式的时间"},{"code":"${timeLocal}","description":"比如17/Jul/2018:09:52:24 +0800","name":"本地时间"},{"code":"${msec}","description":"比如1531756823.054","name":"带有毫秒的时间"},{"code":"${timestamp}","description":"","name":"unix时间戳单位为秒"},{"code":"${host}","description":"","name":"主机名"},{"code":"${serverName}","description":"","name":"接收请求的服务器名"},{"code":"${serverPort}","description":"","name":"接收请求的服务器端口"},{"code":"${referer}","description":"","name":"请求来源URL"},{"code":"${referer.host}","description":"","name":"请求来源URL域名"},{"code":"${userAgent}","description":"","name":"客户端信息"},{"code":"${contentType}","description":"","name":"请求头部的Content-Type"},{"code":"${cookies}","description":"","name":"所有cookie组合字符串"},{"code":"${cookie.NAME}","description":"","name":"单个cookie值"},{"code":"${args}","description":"","name":"所有参数组合字符串"},{"code":"${arg.NAME}","description":"","name":"单个参数值"},{"code":"${headers}","description":"","name":"所有Header信息组合字符串"},{"code":"${header.NAME}","description":"","name":"单个Header值"}]
window.REQUEST_VARIABLES = [{"code":"${edgeVersion}","description":"","name":"边缘节点版本"},{"code":"${remoteAddr}","description":"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取适合前端有别的反向代理服务时使用存在伪造的风险","name":"客户端地址IP"},{"code":"${rawRemoteAddr}","description":"返回直接连接服务的客户端原始IP地址","name":"客户端地址IP"},{"code":"${remotePort}","description":"","name":"客户端端口"},{"code":"${remoteUser}","description":"","name":"客户端用户名"},{"code":"${requestURI}","description":"比如/hello?name=lily","name":"请求URI"},{"code":"${requestPath}","description":"比如/hello","name":"请求路径(不包括参数)"},{"code":"${requestURL}","description":"比如https://example.com/hello?name=lily","name":"完整的请求URL"},{"code":"${requestLength}","description":"","name":"请求内容长度"},{"code":"${requestMethod}","description":"比如GET、POST","name":"请求方法"},{"code":"${requestFilename}","description":"","name":"请求文件路径"},{"code":"${scheme}","description":"","name":"请求协议http或https"},{"code":"${proto}","description:":"类似于HTTP/1.0","name":"包含版本的HTTP请求协议"},{"code":"${timeISO8601}","description":"比如2018-07-16T23:52:24.839+08:00","name":"ISO 8601格式的时间"},{"code":"${timeLocal}","description":"比如17/Jul/2018:09:52:24 +0800","name":"本地时间"},{"code":"${msec}","description":"比如1531756823.054","name":"带有毫秒的时间"},{"code":"${timestamp}","description":"","name":"unix时间戳单位为秒"},{"code":"${host}","description":"","name":"主机名"},{"code":"${serverName}","description":"","name":"接收请求的服务器名"},{"code":"${serverPort}","description":"","name":"接收请求的服务器端口"},{"code":"${referer}","description":"","name":"请求来源URL"},{"code":"${referer.host}","description":"","name":"请求来源URL域名"},{"code":"${userAgent}","description":"","name":"客户端信息"},{"code":"${contentType}","description":"","name":"请求头部的Content-Type"},{"code":"${cookies}","description":"","name":"所有cookie组合字符串"},{"code":"${cookie.NAME}","description":"","name":"单个cookie值"},{"code":"${isArgs}","description":"如果URL有参数则值为`?`;否则,则值为空","name":"问号(?)标记"},{"code":"${args}","description":"","name":"所有参数组合字符串"},{"code":"${arg.NAME}","description":"","name":"单个参数值"},{"code":"${headers}","description":"","name":"所有Header信息组合字符串"},{"code":"${header.NAME}","description":"","name":"单个Header值"}]
window.METRIC_HTTP_KEYS = [{"name":"客户端地址IP","code":"${remoteAddr}","description":"会依次根据X-Forwarded-For、X-Real-IP、RemoteAddr获取适用于前端可能有别的反向代理的情形存在被伪造的可能","icon":""},{"name":"直接客户端地址IP","code":"${rawRemoteAddr}","description":"返回直接连接服务的客户端原始IP地址","icon":""},{"name":"客户端用户名","code":"${remoteUser}","description":"通过基本认证填入的用户名","icon":""},{"name":"请求URI","code":"${requestURI}","description":"包含参数,比如/hello?name=lily","icon":""},{"name":"请求路径","code":"${requestPath}","description":"不包含参数,比如/hello","icon":""},{"name":"完整URL","code":"${requestURL}","description":"比如https://example.com/hello?name=lily","icon":""},{"name":"请求方法","code":"${requestMethod}","description":"比如GET、POST等","icon":""},{"name":"请求协议Scheme","code":"${scheme}","description":"http或https","icon":""},{"name":"文件扩展名","code":"${requestPathExtension}","description":"请求路径中的文件扩展名,包括点符号,比如.html、.png","icon":""},{"name":"主机名","code":"${host}","description":"通常是请求的域名","icon":""},{"name":"请求协议Proto","code":"${proto}","description":"包含版本的HTTP请求协议类似于HTTP/1.0","icon":""},{"name":"HTTP协议","code":"${proto}","description":"包含版本的HTTP请求协议类似于HTTP/1.0","icon":""},{"name":"URL参数值","code":"${arg.NAME}","description":"单个URL参数值","icon":""},{"name":"请求来源URL","code":"${referer}","description":"请求来源Referer URL","icon":""},{"name":"请求来源URL域名","code":"${referer.host}","description":"请求来源Referer URL域名","icon":""},{"name":"Header值","code":"${header.NAME}","description":"单个Header值比如${header.User-Agent}","icon":""},{"name":"Cookie值","code":"${cookie.NAME}","description":"单个cookie值比如${cookie.sid}","icon":""},{"name":"状态码","code":"${status}","description":"","icon":""},{"name":"响应的Content-Type值","code":"${response.contentType}","description":"","icon":""}]