Initial commit (code only without large binaries)

This commit is contained in:
robin
2026-02-15 18:58:44 +08:00
commit 35df75498f
9442 changed files with 1495866 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
<second-menu>
<menu-item href="/servers/components/cache">策略列表</menu-item>
<span class="item">|</span>
<menu-item :href="'/servers/components/cache/policy?cachePolicyId=' + cachePolicyId" code="index">{{cachePolicyName}}</menu-item>
<menu-item :href="'/servers/components/cache/test?cachePolicyId=' + cachePolicyId" code="test">测试</menu-item>
<menu-item :href="'/servers/components/cache/stat?cachePolicyId=' + cachePolicyId" code="stat">统计</menu-item>
<menu-item :href="'/servers/components/cache/clean?cachePolicyId=' + cachePolicyId" code="clean">清理</menu-item>
<menu-item :href="'/servers/components/cache/purge?cachePolicyId=' + cachePolicyId" code="purge">刷新</menu-item>
<menu-item :href="'/servers/components/cache/fetch?cachePolicyId=' + cachePolicyId" code="fetch">预热</menu-item>
<menu-item :href="'/servers/components/cache/update?cachePolicyId=' + cachePolicyId" code="update">修改</menu-item>
</second-menu>

View File

@@ -0,0 +1,6 @@
<first-menu>
<menu-item href="." code="purge">刷新缓存</menu-item>
<menu-item href=".fetch" code="fetch">预热缓存</menu-item>
<span class="item disabled">|</span>
<menu-item href=".tasks" code="task">所有任务<span v-if="countDoingTasks > 0" class="grey">({{countDoingTasks}})</span></menu-item>
</first-menu>

View File

@@ -0,0 +1,31 @@
{$layout}
{$template "menu"}
<div class="margin"></div>
<div><span class="grey">预热缓存指的是预先从源站读取最新内容当用户访问预热后的URL时直接从缓存中返回内容不需要再次回源。</span></div>
<form method="post" class="ui form" data-tea-action="$" data-tea-before="before" data-tea-success="success" data-tea-fail="fail" data-tea-done="done" data-tea-timeout="3600">
<csrf-token></csrf-token>
<table class="ui table definition selectable">
<tr>
<td>要预热的URL列表</td>
<td>
<textarea name="keys" rows="20" ref="focus"></textarea>
<p class="comment">每行一个URL。</p>
</td>
</tr>
<tr>
<td class="title">操作结果</td>
<td>
<div v-if="isRequesting">数据发送中...</div>
<span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
<div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
<div v-for="failKey in failKeys">
<span class="red">{{failKey.key}}: {{failKey.reason}}</span>
</div>
</div>
</td>
</tr>
</table>
<submit-btn v-if="!isRequesting">提交</submit-btn>
</form>

View File

@@ -0,0 +1,32 @@
Tea.context(function () {
this.isRequesting = false
this.isOk = false
this.message = ""
this.failKeys = []
this.before = function () {
this.isRequesting = true
this.isOk = false
this.message = ""
this.failKeys = []
}
this.success = function (resp) {
this.isOk = true
let f = NotifyReloadSuccess("任务提交成功")
f()
}
this.fail = function (resp) {
this.message = resp.message
if (resp.data.failKeys != null) {
this.failKeys = resp.data.failKeys
}
}
this.done = function () {
this.isRequesting = false
}
});

View File

@@ -0,0 +1,8 @@
.fail-keys-box {
max-height: 10em;
overflow-y: auto;
}
.fail-keys-box::-webkit-scrollbar {
width: 6px;
}
/*# sourceMappingURL=index.css.map */

View File

@@ -0,0 +1 @@
{"version":3,"sources":["index.less"],"names":[],"mappings":"AAAA;EACC,gBAAA;EACA,gBAAA;;AAGD,cAAc;EACb,UAAA","file":"index.css"}

View File

@@ -0,0 +1,43 @@
{$layout}
{$template "menu"}
<div class="margin"></div>
<div><span class="grey">刷新缓存指的是标记URL列表或目录为失效状态当有新的用户请求这些URL时会再次从源站读取最新的内容。</span></div>
<form method="post" class="ui form" data-tea-action="$" data-tea-before="before" data-tea-success="success" data-tea-fail="fail" data-tea-done="done" data-tea-timeout="300">
<csrf-token></csrf-token>
<table class="ui table definition selectable">
<tr>
<td class="title">URL类型</td>
<td>
<radio name="keyType" :v-value="'key'" v-model="keyType">URL</radio> &nbsp;
<radio name="keyType" :v-value="'prefix'" v-model="keyType">目录</radio>
</td>
</tr>
<tr>
<td>
<span v-if="keyType == 'key'">要刷新的URL列表</span>
<span v-if="keyType == 'prefix'">要刷新的URL目录列表</span>
</td>
<td>
<textarea name="keys" rows="20" ref="keysBox"></textarea>
<p class="comment" v-if="keyType == 'key'">每行一个URL比如<code-label>https://example.com/hello/world.html</code-label></p>
<p class="comment" v-if="keyType == 'prefix'">每行一个URL目录比如<code-label>https://example.com/hello/</code-label>;如果只填写域名部分,表示清理全站,比如<code-label>https://example.com/</code-label></p>
</td>
</tr>
<tr>
<td>操作结果</td>
<td>
<div v-if="isRequesting">数据发送中...</div>
<span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
<div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
<div v-for="failKey in failKeys">
<span class="red">{{failKey.key}}: {{failKey.reason}}</span>
</div>
</div>
</td>
</tr>
</table>
<submit-btn v-if="!isRequesting">提交</submit-btn>
</form>

View File

@@ -0,0 +1,47 @@
Tea.context(function () {
this.isRequesting = false
this.isOk = false
this.message = ""
this.failKeys = []
this.$delay(function () {
this.$refs.keysBox.focus()
this.$watch("keyType", function () {
this.$refs.keysBox.focus()
})
})
this.before = function () {
this.isRequesting = true
this.isOk = false
this.message = ""
this.failKeys = []
}
this.success = function () {
this.isOk = true
let that = this
teaweb.success("任务提交成功", function () {
window.location = window.location.pathname + "?keyType=" + that.keyType
})
}
this.fail = function (resp) {
this.message = resp.message
if (resp.data.failKeys != null) {
this.failKeys = resp.data.failKeys
}
}
this.done = function () {
this.isRequesting = false
}
/**
* 操作类型
*/
if (this.keyType == null || this.keyType.length == 0) {
this.keyType = "key" // key | prefix
}
})

View File

@@ -0,0 +1,8 @@
.fail-keys-box {
max-height: 10em;
overflow-y: auto;
}
.fail-keys-box::-webkit-scrollbar {
width: 6px;
}

View File

@@ -0,0 +1,100 @@
{$layout}
{$template "menu"}
<second-menu>
<menu-item href=".tasks">所有任务</menu-item>
<span class="disabled item" style="padding: 0">&raquo;</span>
<span class="item">任务详情</span>
</second-menu>
<table class="ui table definition selectable">
<tr>
<td class="title">任务编号</td>
<td>{{task.id}}</td>
</tr>
<tr>
<td>任务类型</td>
<td>
<span v-if="task.type == 'purge'">刷新</span>
<span v-if="task.type == 'fetch'">预热</span>
</td>
</tr>
<tr>
<td>缓存URL类型</td>
<td>
<span v-if="task.keyType == 'key'">URL</span>
<span v-if="task.keyType == 'prefix'">目录</span>
</td>
</tr>
<tr>
<td>创建时间</td>
<td>
{{task.createdTime}}
</td>
</tr>
<tr>
<td>完成时间</td>
<td>
<span v-if="task.isDone">{{task.doneTime}}</span>
<span v-else class="disabled">尚未完成</span>
</td>
</tr>
<tr>
<td>所属用户</td>
<td>
<span v-if="task.user != null && task.user.id > 0"><user-link :v-user="task.user"></user-link></span>
<span v-else="" class="disabled">-</span>
</td>
</tr>
<tr>
<td>任务状态</td>
<td>
<span v-if="task.isOk" class="green">已完成</span>
<a :href="'/servers/components/cache/batch/task?taskId=' + task.id" v-else-if="task.isDone" class="red"><span class="red">失败</span></a>
<span v-else-if="!task.isDone" class="grey">等待执行</span>
</td>
</tr>
<tr>
<td>操作</td>
<td>
<a href="" @click.prevent="deleteTask(task.id)">[删除]</a> &nbsp; &nbsp;
<a href="" @click.prevent="resetTask(task.id)">[重置状态]</a>
</td>
</tr>
</table>
<h4>要操作的缓存Key</h4>
<table class="ui table selectable celled">
<thead>
<tr>
<th>
<span v-if="task.keyType == 'key'">URL</span>
<span v-if="task.keyType == 'prefix'">前缀</span>
</th>
<th class="two wide">所属集群</th>
<th class="width6">状态</th>
</tr>
</thead>
<tbody v-for="key in task.keys">
<tr>
<td>
{{key.key}}
<div v-if="key.errors.length > 0" style="margin-top: 0.5em">
<a :href="'/clusters/cluster/node?nodeId=' + err.nodeId" v-for="err in key.errors" class="ui label basic tiny red">
节点{{err.nodeId}}{{err.error}}
</a>
</div>
</td>
<td>
<span v-if="key.cluster != null && key.cluster.id > 0">{{key.cluster.name}}</span>
<span v-else class="disabled">-</span>
</td>
<td>
<span v-if="key.isDone && key.errors.length == 0" class="green">完成</span>
<span v-if="key.isDone && key.errors.length > 0" class="red">失败</span>
<span v-if="!key.isDone && !key.isDoing" class="grey">未执行</span>
<span v-if="!key.isDone && key.isDoing" class="grey">部分完成</span>
</td>
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,42 @@
Tea.context(function () {
this.$delay(function () {
this.reload()
})
this.deleteTask = function (taskId) {
teaweb.confirm("确定要删除此任务吗?", function () {
this.$post(".deleteTask")
.params({
taskId: taskId
})
.success(function () {
window.location = Tea.url(".tasks")
})
})
}
this.resetTask = function (taskId) {
teaweb.confirm("确定要重置任务状态吗?", function () {
this.$post(".resetTask")
.params({
taskId: taskId
})
.refresh()
})
}
this.reload = function () {
this.$post("$")
.params({
taskId: this.task.id
})
.success(function (resp) {
this.task = resp.data.task
})
.done(function () {
this.$delay(function () {
this.reload()
}, 10000)
})
}
})

View File

@@ -0,0 +1,48 @@
{$layout}
{$template "menu"}
<p class="comment" v-if="tasks.length == 0">暂时还没有任务。</p>
<table class="ui table selectable celled" v-if="tasks.length > 0">
<thead>
<tr>
<th style="width: 7em">任务编号</th>
<th>任务类型</th>
<th>URL类型</th>
<th>创建时间</th>
<th class="four wide">所属用户</th>
<th class="two wide">任务状态</th>
<th class="two op">操作</th>
</tr>
</thead>
<tbody v-for="task in tasks">
<tr>
<td><a :href="'/servers/components/cache/batch/task?taskId=' + task.id">{{task.id}}</a></td>
<td>
<span v-if="task.type == 'purge'">刷新</span>
<span v-if="task.type == 'fetch'">预热</span>
</td>
<td>
<span v-if="task.keyType == 'key'">URL</span>
<span v-if="task.keyType == 'prefix'">目录</span>
</td>
<td>{{task.createdTime}}</td>
<td>
<span v-if="task.user != null && task.user.id > 0"><user-link :v-user="task.user"></user-link></span>
<span v-if="task.description.length > 0" class="grey">{{task.description}}</span>
<span v-else="" class="disabled">-</span>
</td>
<td>
<span v-if="task.isOk" class="green">已完成</span>
<a :href="'/servers/components/cache/batch/task?taskId=' + task.id" v-else-if="task.isDone" class="red"><span class="red">失败</span></a>
<span v-else-if="!task.isDone" class="grey">等待执行</span>
</td>
<td>
<a :href="'/servers/components/cache/batch/task?taskId=' + task.id">详情</a> &nbsp;
<a href="" @click.prevent="deleteTask(task.id)">删除</a>
</td>
</tr>
</tbody>
</table>
<page-box></page-box>

View File

@@ -0,0 +1,11 @@
Tea.context(function () {
this.deleteTask = function (taskId) {
teaweb.confirm("确定要删除此任务吗?", function () {
this.$post(".deleteTask")
.params({
taskId: taskId
})
.refresh()
})
}
})

View File

@@ -0,0 +1,74 @@
{$layout}
{$template "policy_menu"}
<h3>选择集群</h3>
<select class="ui dropdown auto-width" v-model="clusterId">
<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
</select>
<div class="ui divider"></div>
<h3>清理</h3>
<p class=""><span class="red">严重警告:该操作将清理集群所有节点上的所有当前策略产生的缓存;如果只是想清理单个缓存,请使用“刷新预热”功能。</span></p>
<form method="post" data-tea-action="$" data-tea-before="before" data-tea-success="success" data-tea-fail="fail" data-tea-done="done" data-tea-timeout="300">
<input type="hidden" name="cachePolicyId" :value="cachePolicyId"/>
<input type="hidden" name="clusterId" :value="clusterId"/>
<table class="ui table definition selectable">
<tr>
<td class="title">操作原因 *</td>
<td>
<p class="comment">为了防止新手滥用此功能、导致节点崩溃,你需要选择操作原因,才能继续操作:</p>
<div>
<radio v-model="reason" :v-value="REASON_NEW_PIE">我是一名新手,我不知道怎么清除缓存</radio>
</div>
<div style="margin-top: 0.6em">
<radio v-model="reason" :v-value="REASON_BATCH_DELETE">要清理的域名太多,我比较懒,我不想用“刷新预热”功能</radio>
</div>
<div style="margin-top: 0.6em">
<radio v-model="reason" :v-value="REASON_MAINTAINS">因节点硬盘空间不足或以往缓存设置错误或其他原因,想清除所有缓存,重新开始</radio>
</div>
<div style="margin-top: 0.6em">
<radio v-model="reason" :v-value="REASON_ISSUE_REPORT">我怀疑“刷新预热”功能不起作用</radio>
</div>
</td>
</tr>
<tr v-show="!isReasonable()">
<td>新手操作建议</td>
<td>
请使用左侧主菜单中的 <a href="/servers/components/cache/batch?keyType=prefix" target="_blank">[刷新预热]</a> 功能来清理你的缓存。
</td>
</tr>
<tr v-show="reason == REASON_ISSUE_REPORT">
<td>操作建议</td>
<td>
当前系统提供的 <a href="/servers/components/cache/batch?keyType=prefix" target="_blank">[刷新预热]</a> 功能运行非常可靠如果你确认发现功能异常且能100%几率重现问题,请及时报告给软件开发者。
</td>
</tr>
<tr v-show="reason == REASON_BATCH_DELETE">
<td>操作建议</td>
<td>
请尽可能使用 <a href="/servers/components/cache/batch?keyType=prefix" target="_blank">[刷新预热]</a> 功能,避免影响当前系统上的别的网站。
</td>
</tr>
<tr v-show="reason == REASON_MAINTAINS">
<td>操作建议</td>
<td>
缓存文件较多时,系统需要消耗更多系统资源和更多时间删除缓存文件,硬盘使用空间会逐渐恢复,操作后,请耐心等待。
</td>
</tr>
<tr v-show="isReasonable()">
<td class="title">操作结果</td>
<td>
<div v-if="isRequesting">数据发送中...</div>
<span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
<div v-if="!isRequesting && isOk">
<span v-if="results.length == 0" class="red">此集群下没有任何可用的节点。</span>
<div class="ui label tiny" v-for="one in results" :class="{green:one.isOk, red:!one.isOk}" style="margin-bottom: 0.5em">{{one.nodeName}}{{one.message}}</div>
</div>
</td>
</tr>
</table>
<submit-btn v-if="!isRequesting && isReasonable()">提交</submit-btn>
<button class="ui button disabled" type="button" v-if="!isReasonable()">提交</button>
</form>

View File

@@ -0,0 +1,45 @@
Tea.context(function () {
this.reason = 0
this.REASON_NEW_PIE = 0
this.REASON_ISSUE_REPORT = 1
this.REASON_BATCH_DELETE = 2
this.REASON_MAINTAINS = 3
this.isReasonable = function () {
return this.reason == this.REASON_ISSUE_REPORT || this.reason == this.REASON_BATCH_DELETE || this.reason == this.REASON_MAINTAINS
}
if (this.clusterId == null) {
if (this.clusters.length > 0) {
this.clusterId = this.clusters[0].id
} else {
this.clusterId = 0
}
}
this.isRequesting = false
this.isOk = false
this.message = ""
this.results = []
this.before = function () {
this.isRequesting = true
this.isOk = false
this.message = ""
this.results = []
}
this.success = function (resp) {
this.isOk = true
this.results = resp.data.results
}
this.fail = function (resp) {
this.message = resp.message
}
this.done = function () {
this.isRequesting = false
}
});

View File

@@ -0,0 +1,135 @@
{$layout "layout_popup"}
<h3>创建缓存策略</h3>
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
<table class="ui table definition selectable">
<tr>
<td class="title">策略名称 *</td>
<td><input type="text" name="name" maxlength="100" ref="focus"/> </td>
</tr>
<tr>
<td class="color-border">缓存类型 *</td>
<td>
<select class="ui dropdown auto-width" name="type" v-model="policyType">
<option v-for="type in types" :value="type.type">{{type.name}}</option>
</select>
</td>
</tr>
<!-- 文件缓存选项 -->
<tbody v-if="policyType == 'file'">
<tr>
<td class="color-border">缓存目录 *</td>
<td>
<input type="text" name="fileDir" maxlength="500" value="/opt/cache"/>
<p class="comment">存放文件缓存的目录,通常填写绝对路径。</p>
</td>
</tr>
<tr>
<td class="color-border">缓存硬盘最大用量 *</td>
<td>
<size-capacity-box :v-name="'capacityJSON'" :v-count="128" :v-unit="'gb'" :key="'capacityJSON1'"></size-capacity-box>
<p class="comment">单个节点上缓存所在硬盘的最大用量超出此用量或硬盘接近用尽时将会自动尝试清理旧数据如果为0表示没有限制。</p>
</td>
</tr>
<tr>
<td class="color-border">内存最大容量</td>
<td>
<size-capacity-box :v-name="'fileMemoryCapacityJSON'" :v-count="1" :v-unit="'gb'" :key="'fileMemoryCapacityJSON'"></size-capacity-box>
<p class="comment">单个节点上作为一级缓存的内存最大容量可以作为硬盘缓冲区和存储热点缓存内容如果为0表示不使用内存作为一级缓存。</p>
</td>
</tr>
</tbody>
<tbody v-if="policyType == 'memory'">
<tr>
<td>内存最大容量</td>
<td>
<size-capacity-box :key="'a'" :v-name="'capacityJSON'" :v-count="2" :v-unit="'gb'" :key="'capacityJSON2'"></size-capacity-box>
<p class="comment">单个节点上允许缓存的最大容量如果为0表示没有限制。</p>
</td>
</tr>
</tbody>
<tr>
<td>最大内容尺寸</td>
<td>
<size-capacity-box :v-name="'maxSizeJSON'" :v-count="256" :v-unit="'mb'" :key="'maxSizeJSON'"></size-capacity-box>
<p class="comment">允许缓存的单个内容最大尺寸如果为0表示没有限制。</p>
</td>
</tr>
<tr>
<td colspan="2"><more-options-indicator></more-options-indicator></td>
</tr>
<tbody v-show="moreOptionsVisible && policyType == 'file'">
<tr>
<td class="color-border">缓存硬盘最小空余空间</td>
<td>
<size-capacity-box :v-name="'fileMinFreeSizeJSON'" :v-count="0" :v-unit="'gb'" :key="'minFreeSizeJSON'"></size-capacity-box>
<p class="comment">缓存硬盘保留的最小空余空间如果为0表示自动限制目前默认保留5GiB</p>
</td>
</tr>
<tr>
<td class="color-border">缓存文件句柄缓存</td>
<td>
<input type="text" name="fileOpenFileCacheMax" maxlength="6" value="0" style="width: 10em"/>
<p class="comment"><pro-warning-label></pro-warning-label>保持在内存中的缓存文件句柄的数量提升缓存文件打开速度同时也会占用系统更多的内存建议数量不超过缓存文件数量的百分之一0表示不启用。</p>
</td>
</tr>
<tr v-show="teaIsPlus">
<td class="color-border">开启Sendfile</td>
<td>
<checkbox name="fileEnableSendfile"></checkbox>
<p class="comment"><pro-warning-label></pro-warning-label><plus-label></plus-label>使用sendfile提升发送缓存文件的效率。</p>
</td>
</tr>
<tr>
<td class="color-border">允许读取不完整的Partial Content</td>
<td>
<checkbox name="enableIncompletePartialContent" checked="checked"></checkbox>
<p class="comment">允许在有一部分内容缓存的情况下读取分区内容,剩余的部分将会自动回源读取。</p>
</td>
</tr>
<!-- <tr v-show="moreOptionsVisible && policyType == 'file'">
<td class="color-border">启用MMAP</td>
<td>
<checkbox name="enableMMAP"></checkbox>
<p class="comment">选中后表示允许系统自动利用MMAP提升缓存读取性能。</p>
</td>
</tr>-->
</tbody>
<tbody v-show="moreOptionsVisible">
<tr>
<td>同步写入压缩缓存</td>
<td>
<checkbox name="syncCompressionCache"></checkbox>
<p class="comment">选中后在压缩设置开启的情况下在缓存源站内容的同时也会同步写入压缩缓存不选中表示在源站内容缓存后下一次调用才会缓存压缩内容防止同一时间内硬盘IO负载过高。</p>
</td>
</tr>
<tr>
<td>预热超时时间</td>
<td>
<time-duration-box :v-name="'fetchTimeoutJSON'" :v-unit="'minute'" maxlength="6"></time-duration-box>
<p class="comment">预热读取源站的超时时间默认20分钟。</p>
</td>
</tr>
<tr>
<td>描述</td>
<td>
<textarea maxlength="200" name="description" rows="3"></textarea>
</td>
</tr>
<tr>
<td>启用当前策略</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="isOn" value="1" checked="checked"/>
<label></label>
</div>
</td>
</tr>
</tbody>
</table>
<submit-btn></submit-btn>
</form>

View File

@@ -0,0 +1,5 @@
Tea.context(function () {
this.success = NotifyPopup
this.policyType = this.types[0].type
})

View File

@@ -0,0 +1,28 @@
{$layout}
{$template "policy_menu"}
<form method="post" class="ui form" data-tea-action="$" data-tea-before="before" data-tea-success="success" data-tea-fail="fail" data-tea-done="done" data-tea-timeout="3600">
<input type="hidden" name="cachePolicyId" :value="cachePolicyId"/>
<table class="ui table definition selectable">
<tr>
<td>URL列表</td>
<td>
<textarea name="keys" rows="10" ref="focus"></textarea>
<p class="comment">每行一个URL。</p>
</td>
</tr>
<tr>
<td class="title">操作结果</td>
<td>
<div v-if="isRequesting">数据发送中...</div>
<span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
<div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
<div v-for="failKey in failKeys">
<span class="red">{{failKey.key}}: {{failKey.reason}}</span>
</div>
</div>
</td>
</tr>
</table>
<submit-btn v-if="!isRequesting">提交</submit-btn>
</form>

View File

@@ -0,0 +1,32 @@
Tea.context(function () {
this.isRequesting = false
this.isOk = false
this.message = ""
this.failKeys = []
this.before = function () {
this.isRequesting = true
this.isOk = false
this.message = ""
this.failKeys = []
}
this.success = function (resp) {
this.isOk = true
let f = NotifyReloadSuccess("任务提交成功")
f()
}
this.fail = function (resp) {
this.message = resp.message
if (resp.data.failKeys != null) {
this.failKeys = resp.data.failKeys
}
}
this.done = function () {
this.isRequesting = false
}
});

View File

@@ -0,0 +1,71 @@
{$layout}
<first-menu>
<menu-item href="/servers/components/cache" code="index">列表</menu-item>
<span class="item">|</span>
<a href="" class="item" @click.prevent="createPolicy()">[创建]</a>
</first-menu>
<!-- 搜索 -->
<div class="margin"></div>
<form class="ui form" method="get" action="/servers/components/cache">
<div class="ui fields inline">
<div class="ui field">
<node-cluster-combo-box :v-cluster-id="clusterId"></node-cluster-combo-box>
</div>
<div class="ui field">
<input type="text" name="keyword" v-model="keyword" placeholder="策略名称..."/>
</div>
<div class="ui field">
<select class="ui dropdown" name="storageType" v-model="storageType">
<option value="">[存储类型]</option>
<option v-for="storageType in storageTypes" :value="storageType.type">{{storageType.name}}</option>
</select>
</div>
<div class="ui field">
<button type="submit" class="ui button">搜索</button>
&nbsp;
<a :href="Tea.url('.')" v-if="keyword.length > 0 || clusterId > 0 || storageType.length > 0">[清除条件]</a>
</div>
</div>
</form>
<!-- 列表 -->
<p class="comment" v-if="cachePolicies == null || cachePolicies.length == 0">暂时还没有缓存策略。</p>
<table class="ui table selectable celled" v-if="cachePolicies != null && cachePolicies.length > 0">
<thead>
<tr>
<th>策略名称</th>
<th>策略类型</th>
<th>容量</th>
<th class="center">集群数</th>
<th class="center">状态</th>
<th class="two op">操作</th>
</tr>
</thead>
<tr v-for="(policy, index) in cachePolicies">
<td>
<a :href="'/servers/components/cache/policy?cachePolicyId=' + policy.id"><keyword :v-word="keyword">{{policy.name}}</keyword>
&nbsp;
<i class="icon disk small blue" v-if="policy.type == 'file'" title="硬盘"></i>
</a>
</td>
<td>{{infos[index].typeName}} <span class="small">{{policy.type}}</span></td>
<td>
<span v-if="policy.capacity != null && policy.capacity.count > 0">
{{policy.capacity.count}}{{policy.capacity.unit.toUpperCase().replace(/(.)B/, "$1iB")}}
<span v-if="policy.type == 'file' && policy.options.memoryPolicy != null && policy.options.memoryPolicy.capacity != null && policy.options.memoryPolicy.capacity.count > 0" class="small grey" title="内存容量">
(内存:{{policy.options.memoryPolicy.capacity.count}}{{policy.options.memoryPolicy.capacity.unit.toUpperCase().replace(/(.)B/, "$1iB")}}
</span>
</span>
<span v-else class="disabled">不限</span>
</td>
<td class="center">{{infos[index].countClusters}}</td>
<td class="center"><label-on :v-is-on="policy.isOn"></label-on></td>
<td>
<a :href="'/servers/components/cache/policy?cachePolicyId=' + policy.id">详情</a> &nbsp; <a href="" @click.prevent="deletePolicy(policy.id)">删除</a>
</td>
</tr>
</table>
<div class="page" v-html="page"></div>

View File

@@ -0,0 +1,25 @@
Tea.context(function () {
// 创建策略
this.createPolicy = function () {
teaweb.popup("/servers/components/cache/createPopup", {
height: "27em",
callback: function () {
teaweb.success("保存成功", function () {
window.location.reload()
})
}
})
}
// 删除策略
this.deletePolicy = function (policyId) {
let that = this
teaweb.confirm("确定要删除此缓存策略吗?", function () {
that.$post("/servers/components/cache/delete")
.params({
cachePolicyId: policyId
})
.refresh()
})
}
})

View File

@@ -0,0 +1,128 @@
{$layout}
{$template "policy_menu"}
<table class="ui table definition selectable">
<tr>
<td class="title">策略名称</td>
<td>{{cachePolicy.name}}</td>
</tr>
<tr>
<td>状态</td>
<td><label-on :v-is-on="cachePolicy.isOn"></label-on></td>
</tr>
<tr>
<td class="color-border">缓存类型</td>
<td>
{{typeName}}<span class="small">{{cachePolicy.type}}</span>
</td>
</tr>
<!-- 文件缓存选项 -->
<tbody v-if="cachePolicy.type == 'file'">
<tr>
<td class="color-border">缓存目录</td>
<td>
{{cachePolicy.options.dir}}
<p class="comment">存放文件缓存的目录,通常填写绝对路径。</p>
</td>
</tr>
<tr>
<td class="color-border">缓存硬盘最大用量</td>
<td>
<size-capacity-view :v-value="cachePolicy.capacity" :v-default-text="'不限'"></size-capacity-view>
<p class="comment">单个节点上缓存所在硬盘的最大用量如果为0表示没有限制。</p>
</td>
</tr>
<tr v-if="cachePolicy.options.memoryPolicy != null && cachePolicy.options.memoryPolicy.capacity != null && cachePolicy.options.memoryPolicy.capacity.count > 0">
<td class="color-border">内存最大容量</td>
<td>
<size-capacity-view :v-value="cachePolicy.options.memoryPolicy.capacity"></size-capacity-view>
<p class="comment">作为一级缓存的内存最大容量可以作为硬盘缓冲区和存储热点缓存内容如果为0表示不使用内存作为一级缓存。</p>
</td>
</tr>
<tr v-else>
<td class="color-border">内存最大容量</td>
<td>
<a :href="Tea.url('.update', {cachePolicyId:cachePolicy.id})"><span class="red">请设置一个内存容量作为缓冲区,以提升缓存写入性能。</span></a>
</td>
</tr>
<tr v-if="cachePolicy.options.openFileCache != null && cachePolicy.options.openFileCache.isOn && cachePolicy.options.openFileCache.max > 0">
<td class="color-border">缓存文件句柄缓存</td>
<td>{{cachePolicy.options.openFileCache.max}}</td>
</tr>
<tr v-if="cachePolicy.options.enableSendfile">
<td class="color-border">开启Sendfile</td>
<td><span v-if="cachePolicy.options.enableSendfile" class="green">Y</span><span v-else class="disabled">N</span></td>
</tr>
<tr v-if="cachePolicy.options.minFreeSize != null && cachePolicy.options.minFreeSize.count > 0">
<td class="color-border">缓存硬盘最小空余空间</td>
<td><size-capacity-view :v-value="cachePolicy.options.minFreeSize"></size-capacity-view></td>
</tr>
<tr v-if="cachePolicy.options.enableIncompletePartialContent">
<td class="color-border">允许读取不完整的Partial Content</td>
<td>
<span class="green">Y</span>
</td>
</tr>
<!--<tr v-if="cachePolicy.options.enableMMAP">
<td class="color-border">启用MMAP</td>
<td>
<span>Y</span>
</td>
</tr>-->
</tbody>
<tbody v-if="cachePolicy.type != 'file'">
<tr>
<td>缓存最大容量</td>
<td>
<size-capacity-view :v-value="cachePolicy.capacity" :v-default-text="'不限'"></size-capacity-view>
<p class="comment">允许缓存的最大容量如果为0表示没有限制。</p>
</td>
</tr>
</tbody>
<tr>
<td colspan="2"><more-options-indicator></more-options-indicator></td>
</tr>
<tbody v-show="moreOptionsVisible">
<tr>
<td>最大内容长度</td>
<td>
<size-capacity-view :v-value="cachePolicy.maxSize" :v-default-text="'不限'"></size-capacity-view>
<p class="comment">允许缓存的单个内容最大尺寸如果为0表示没有限制。</p>
</td>
</tr>
<tr>
<td>同步写入压缩缓存</td>
<td>
<span v-if="cachePolicy.syncCompressionCache" class="green">Y</span>
<span v-else class="disabled">N</span>
</td>
</tr>
<tr>
<td>预热超时时间</td>
<td><span v-if="fetchTimeoutString.length > 0">{{fetchTimeoutString}}</span><span v-else class="disabled">使用默认</span></td>
</tr>
<tr>
<td>描述</td>
<td>
<span v-if="cachePolicy.description.length > 0">{{cachePolicy.description}}</span>
<span v-else class="disabled">暂时还没有描述。</span>
</td>
</tr>
</tbody>
</table>
<!-- 默认缓存条件 -->
<h4>默认缓存条件</h4>
<http-cache-refs-box :v-cache-refs="cachePolicy.cacheRefs"></http-cache-refs-box>
<!-- 使用此策略的集群 -->
<h4>使用此策略的集群</h4>
<p class="comment" v-if="clusters.length == 0">暂时还没有集群使用此策略。</p>
<table class="ui table selectable" v-if="clusters.length > 0">
<tr v-for="cluster in clusters">
<td>{{cluster.name}}<link-icon :href="'/clusters/cluster?clusterId=' + cluster.id"></link-icon></td>
</tr>
</table>

View File

@@ -0,0 +1,40 @@
{$layout}
{$template "policy_menu"}
<p class="comment">可以在这里批量刷新一组URL。</p>
<form method="post" class="ui form" data-tea-action="$" data-tea-before="before" data-tea-success="success" data-tea-fail="fail" data-tea-done="done" data-tea-timeout="300">
<input type="hidden" name="cachePolicyId" :value="cachePolicyId"/>
<table class="ui table definition selectable">
<tr>
<td class="title">URL类型</td>
<td>
<radio name="keyType" :v-value="'key'" v-model="keyType">URL</radio> &nbsp;
<radio name="keyType" :v-value="'prefix'" v-model="keyType">目录</radio>
</td>
</tr>
<tr>
<td>
<span v-if="keyType == 'key'">URL</span>
<span v-if="keyType == 'prefix'">目录</span>
</td>
<td>
<textarea name="keys" rows="10" ref="keysBox"></textarea>
<p class="comment" v-if="keyType == 'key'">每行一个URL比如<code-label>https://example.com/hello/world.html</code-label></p>
<p class="comment" v-if="keyType == 'prefix'">每行一个URL目录比如<code-label>https://example.com/hello/</code-label>;如果只填写域名部分,表示清理全站,比如<code-label>https://example.com/</code-label></p>
</td>
</tr>
<tr>
<td>操作结果</td>
<td>
<div v-if="isRequesting">数据发送中...</div>
<span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
<div v-if="!isRequesting && !isOk && failKeys.length > 0" class="fail-keys-box">
<div v-for="failKey in failKeys">
<span class="red">{{failKey.key}}: {{failKey.reason}}</span>
</div>
</div>
</td>
</tr>
</table>
<submit-btn v-if="!isRequesting">提交</submit-btn>
</form>

View File

@@ -0,0 +1,43 @@
Tea.context(function () {
this.isRequesting = false
this.isOk = false
this.message = ""
this.failKeys = []
this.$delay(function () {
this.$refs.keysBox.focus()
this.$watch("keyType", function () {
this.$refs.keysBox.focus()
})
})
this.before = function () {
this.isRequesting = true
this.isOk = false
this.message = ""
this.failKeys = []
}
this.success = function () {
this.isOk = true
let f = NotifyReloadSuccess("任务提交成功")
f()
}
this.fail = function (resp) {
this.message = resp.message
if (resp.data.failKeys != null) {
this.failKeys = resp.data.failKeys
}
}
this.done = function () {
this.isRequesting = false
}
/**
* 操作类型
*/
this.keyType = "key" // key | prefix
})

View File

@@ -0,0 +1,24 @@
{$layout "layout_popup"}
<h3>选择缓存策略</h3>
<table class="ui table selectable">
<thead>
<tr>
<th>策略名称</th>
<th style="width: 7em">状态</th>
<th class="two op">操作</th>
</tr>
</thead>
<tr v-for="cachePolicy in cachePolicies">
<td>{{cachePolicy.name}}</td>
<td>
<label-on :v-is-on="cachePolicy.isOn"></label-on>
</td>
<td>
<span v-if="cachePolicy.isOn">
<a href="" @click.prevent="selectPolicy(cachePolicy)">选择</a>
</span>
</td>
</tr>
</table>
<div class="page" v-html="page"></div>

View File

@@ -0,0 +1,11 @@
Tea.context(function () {
this.selectPolicy = function (cachePolicy) {
NotifyPopup({
code: 200,
data: {
cachePolicy: cachePolicy
},
message: ""
})
}
})

View File

@@ -0,0 +1,31 @@
{$layout}
{$template "policy_menu"}
<h3>选择集群</h3>
<select class="ui dropdown auto-width" v-model="clusterId">
<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
</select>
<div class="ui divider"></div>
<h3>统计</h3>
<form method="post" data-tea-action="$" data-tea-before="before" data-tea-success="success" data-tea-fail="fail" data-tea-done="done">
<input type="hidden" name="cachePolicyId" :value="cachePolicyId"/>
<input type="hidden" name="clusterId" :value="clusterId"/>
<table class="ui table definition selectable">
<tr>
<td class="title">操作结果</td>
<td>
<div v-if="isRequesting">数据发送中...</div>
<span class="red" v-if="!isRequesting && !isOk && message.length > 0">失败:{{message}}</span>
<div v-if="!isRequesting && isOk">
<span v-if="results.length == 0" class="red">此集群下没有任何可用的节点。</span>
<div class="ui label tiny" v-for="one in results" :class="{green:one.isOk, red:!one.isOk}" style="margin-bottom: 0.5em">{{one.nodeName}}{{one.message}}</div>
</div>
</td>
</tr>
</table>
<submit-btn v-if="!isRequesting">提交</submit-btn>
</form>

View File

@@ -0,0 +1,34 @@
Tea.context(function () {
if (this.clusterId == null) {
if (this.clusters.length > 0) {
this.clusterId = this.clusters[0].id
} else {
this.clusterId = 0
}
}
this.isRequesting = false
this.isOk = false
this.message = ""
this.results = []
this.before = function () {
this.isRequesting = true
this.isOk = false
this.message = ""
this.results = []
}
this.success = function (resp) {
this.isOk = true
this.results = resp.data.results
}
this.fail = function (resp) {
this.message = resp.message
}
this.done = function () {
this.isRequesting = false
}
});

View File

@@ -0,0 +1,70 @@
{$layout}
{$template "policy_menu"}
<h3>选择集群</h3>
<select class="ui dropdown auto-width" v-model="clusterId">
<option v-for="cluster in clusters" :value="cluster.id">{{cluster.name}}</option>
</select>
<div class="ui divider"></div>
<h3>测试写入</h3>
<form method="post" class="ui form" data-tea-action=".testWrite" data-tea-before="beforeWrite" data-tea-done="doneWrite" data-tea-success="successWrite" data-tea-fail="failWrite">
<input type="hidden" name="clusterId" :value="clusterId"/>
<input type="hidden" name="cachePolicyId" :value="cachePolicyId"/>
<table class="ui table selectable definition">
<tr>
<td class="title">Key</td>
<td>
<input type="text" name="key" value="my-key"/>
</td>
</tr>
<tr>
<td>Value</td>
<td>
<textarea name="value" rows="3">my-value</textarea>
</td>
</tr>
<tr>
<td>操作结果</td>
<td>
<div v-if="isRequestingWrite">数据发送中...</div>
<span class="red" v-if="!isRequestingWrite && !writeOk && writeMessage.length > 0">失败:{{writeMessage}}</span>
<div v-if="!isRequestingWrite && writeOk">
<span v-if="writeResults.length == 0" class="red">此集群下没有任何可用的节点。</span>
<div class="ui label tiny" v-for="result in writeResults" :class="{green:result.isOk, red:!result.isOk}" style="margin-bottom:0.5em">节点{{result.nodeName}}{{result.message}}</div>
</div>
</td>
</tr>
</table>
<submit-btn v-if="!isRequestingWrite">提交</submit-btn>
</form>
<div class="ui divider"></div>
<h3>测试读取</h3>
<form method="post" class="ui form" data-tea-action=".testRead" data-tea-before="beforeRead" data-tea-done="doneRead" data-tea-success="successRead" data-tea-fail="failRead">
<input type="hidden" name="clusterId" :value="clusterId"/>
<input type="hidden" name="cachePolicyId" :value="cachePolicyId"/>
<table class="ui table selectable definition">
<tr>
<td class="title">Key</td>
<td>
<input type="text" name="key" value="my-key"/>
</td>
</tr>
<tr>
<td>操作结果</td>
<td>
<div v-if="isRequestingRead">数据发送中...</div>
<span class="red" v-if="!isRequestingRead && !readOk && readMessage.length > 0">失败:{{readMessage}}</span>
<div v-if="!isRequestingRead && readOk">
<span v-if="readResults.length == 0" class="red">此集群下没有任何可用的节点。</span>
<div class="ui label tiny" v-for="result in readResults" :class="{green:result.isOk, red:!result.isOk}" style="margin-bottom: 0.5em">节点{{result.nodeName}}{{result.message}}</div>
</div>
</td>
</tr>
</table>
<submit-btn v-if="!isRequestingRead">提交</submit-btn>
</form>

View File

@@ -0,0 +1,65 @@
Tea.context(function () {
if (this.clusterId == null) {
if (this.clusters.length > 0) {
this.clusterId = this.clusters[0].id
} else {
this.clusterId = 0
}
}
this.isRequestingWrite = false
this.writeOk = false
this.writeMessage = ""
this.writeIsAllOk = false
this.writeResults = []
this.beforeWrite = function () {
this.isRequestingWrite = true
this.writeOk = false
this.writeMessage = ""
this.writeResult = {}
}
this.failWrite = function (resp) {
this.writeOk = false
this.writeMessage = resp.message
}
this.successWrite = function (resp) {
this.writeOk = true
this.writeIsAllOk = resp.data.isAllOk
this.writeResults = resp.data.results
}
this.doneWrite = function () {
this.isRequestingWrite = false
}
this.isRequestingRead = false
this.readOk = false
this.readMessage = ""
this.readIsAllOk = false
this.readResults = []
this.beforeRead = function () {
this.isRequestingRead = true
this.readOk = false
this.readMessage = ""
this.readResult = {}
}
this.failRead = function (resp) {
this.readOk = false
this.readMessage = resp.message
};
this.successRead = function (resp) {
this.readOk = true;
this.readIsAllOk = resp.data.isAllOk
this.readResults = resp.data.results
}
this.doneRead = function () {
this.isRequestingRead = false
}
});

View File

@@ -0,0 +1,146 @@
{$layout}
{$template "policy_menu"}
<form method="post" class="ui form" data-tea-action="$" data-tea-success="success">
<input type="hidden" name="cachePolicyId" :value="cachePolicy.id"/>
<table class="ui table definition selectable">
<tr>
<td class="title">策略名称 *</td>
<td><input type="text" name="name" maxlength="100" ref="focus" v-model="cachePolicy.name"/> </td>
</tr>
<tr>
<td class="color-border">缓存类型 *</td>
<td>
<select class="ui dropdown auto-width" name="type" v-model="policyType" @change="changePolicyType">
<option v-for="type in types" :value="type.type">{{type.name}}</option>
</select>
</td>
</tr>
<!-- 文件缓存选项 -->
<tbody v-if="policyType == 'file'">
<tr>
<td class="color-border">缓存目录 *</td>
<td>
<input type="text" name="fileDir" maxlength="500" v-model="cachePolicy.options.dir"/>
<p class="comment">存放文件缓存的目录,通常填写绝对路径。</p>
</td>
</tr>
<tr>
<td class="color-border">缓存硬盘最大用量</td>
<td>
<size-capacity-box :v-name="'capacityJSON'" :v-value="cachePolicy.capacity" :v-count="0" :v-unit="'gb'"></size-capacity-box>
<p class="comment">单个节点上缓存所在硬盘的最大用量超出此用量或硬盘接近用尽时将会自动尝试清理旧数据如果为0表示没有限制。</p>
</td>
</tr>
<tr v-if="cachePolicy.options.memoryPolicy != null && cachePolicy.options.memoryPolicy.capacity != null">
<td class="color-border">内存最大容量</td>
<td>
<size-capacity-box :v-name="'fileMemoryCapacityJSON'" :v-value="cachePolicy.options.memoryPolicy.capacity" :v-count="1" :v-unit="'gb'"></size-capacity-box>
<p class="comment">单个节点上作为一级缓存的内存最大容量可以作为硬盘缓冲区和存储热点缓存内容如果为0表示不使用内存作为一级缓存。</p>
</td>
</tr>
<tr v-if="cachePolicy.options.memoryPolicy == null || cachePolicy.options.memoryPolicy.capacity == null">
<td class="color-border">内存最大容量</td>
<td>
<size-capacity-box :v-name="'fileMemoryCapacityJSON'" :v-count="0" :v-unit="'gb'"></size-capacity-box>
<p class="comment">作为一级缓存的内存最大容量可以作为硬盘缓冲区和存储热点缓存内容如果为0表示不使用内存作为一级缓存。</p>
</td>
</tr>
</tbody>
<tbody v-if="policyType != 'file'">
<tr>
<td>缓存最大容量</td>
<td>
<size-capacity-box :v-name="'capacityJSON'" :v-value="cachePolicy.capacity" :v-count="0" :v-unit="'gb'"></size-capacity-box>
<p class="comment">单个节点上允许缓存的最大容量如果为0表示没有限制。</p>
</td>
</tr>
</tbody>
<tr>
<td>最大内容长度</td>
<td>
<size-capacity-box :v-value="cachePolicy.maxSize" :v-name="'maxSizeJSON'" :v-count="32" :v-unit="'mb'"></size-capacity-box>
<p class="comment">允许缓存的单个内容最大尺寸如果为0表示没有限制。</p>
</td>
</tr>
<tr>
<td colspan="2"><more-options-indicator></more-options-indicator></td>
</tr>
<tbody v-show="moreOptionsVisible && policyType == 'file'">
<tr>
<td class="color-border">缓存硬盘最小空余空间</td>
<td>
<size-capacity-box :v-name="'fileMinFreeSizeJSON'" :v-value="cachePolicy.options.minFreeSize" :key="'minFreeSizeJSON'"></size-capacity-box>
<p class="comment">缓存硬盘保留的最小空余空间如果为0表示使用默认目前默认保留5GiB</p>
</td>
</tr>
<tr>
<td class="color-border">缓存文件句柄缓存</td>
<td>
<input type="text" name="fileOpenFileCacheMax" v-model="fileOpenFileCacheMax" maxlength="6" value="0" style="width: 10em"/>
<p class="comment"><pro-warning-label></pro-warning-label>保持在内存中的缓存文件句柄的数量提升缓存文件打开速度同时也会占用系统更多的内存建议数量不超过缓存文件数量的百分之一0表示不启用。</p>
</td>
</tr>
<tr v-show="teaIsPlus">
<td class="color-border">开启Sendfile</td>
<td>
<checkbox name="fileEnableSendfile" v-model="cachePolicy.options.enableSendfile"></checkbox>
<p class="comment"><pro-warning-label></pro-warning-label><plus-label></plus-label>使用sendfile提升发送缓存文件的效率。</p>
</td>
</tr>
<tr>
<td class="color-border">允许读取不完整的Partial Content</td>
<td>
<checkbox name="enableIncompletePartialContent" v-model="cachePolicy.options.enableIncompletePartialContent"></checkbox>
<p class="comment">允许在有一部分内容缓存的情况下读取分区内容,剩余的部分将会自动回源读取。</p>
</td>
</tr>
<tr v-show="false">
<td class="color-border">启用MMAP</td>
<td>
<checkbox name="enableMMAP" v-model="cachePolicy.options.enableMMAP"></checkbox>
<p class="comment">选中后表示允许系统自动利用MMAP提升缓存读取性能。</p>
</td>
</tr>
</tbody>
<tbody v-show="moreOptionsVisible">
<tr>
<td>同步写入压缩缓存</td>
<td>
<checkbox name="syncCompressionCache" v-model="cachePolicy.syncCompressionCache"></checkbox>
<p class="comment">选中后在压缩设置开启的情况下在缓存源站内容的同时也会同步写入压缩缓存不选中表示在源站内容缓存后下一次调用才会缓存压缩内容防止同一时间内硬盘IO负载过高。</p>
</td>
</tr>
<tr>
<td>预热超时时间</td>
<td>
<time-duration-box :v-name="'fetchTimeoutJSON'" :v-value="cachePolicy.fetchTimeout" maxlength="6"></time-duration-box>
<p class="comment">预热读取源站的超时时间默认20分钟。</p>
</td>
</tr>
<tr>
<td>描述</td>
<td>
<textarea maxlength="200" name="description" rows="3" v-model="cachePolicy.description"></textarea>
</td>
</tr>
<tr>
<td>启用当前策略</td>
<td>
<div class="ui checkbox">
<input type="checkbox" name="isOn" value="1" v-model="cachePolicy.isOn"/>
<label></label>
</div>
</td>
</tr>
</tbody>
</table>
<h4>默认缓存条件</h4>
<http-cache-refs-config-box :v-cache-refs="cachePolicy.cacheRefs" :v-cache-policy-id="cachePolicy.id" :v-max-bytes="cachePolicy.maxSize"></http-cache-refs-config-box>
<submit-btn></submit-btn>
</form>

View File

@@ -0,0 +1,27 @@
Tea.context(function () {
this.success = NotifyReloadSuccess("保存成功 ")
this.policyType = this.cachePolicy.type
this.fileOpenFileCacheMax = 0
if (this.cachePolicy.type == "file" && this.cachePolicy.options.openFileCache != null && this.cachePolicy.options.openFileCache.isOn && this.cachePolicy.options.openFileCache.max > 0) {
this.fileOpenFileCacheMax = this.cachePolicy.options.openFileCache.max
}
this.changePolicyType = function () {
if (this.policyType == "file") {
let options = this.cachePolicy.options
if (options != null && typeof options == "object" && typeof options["dir"] === "undefined") {
options["enableMMAP"] = false
options["enableIncompletePartialContent"] = true
options["dir"] = "/opt/cache"
options["memoryPolicy"] = {
capacity: {
unit: "gb",
count: 2
}
}
}
}
}
})