generated from dellevin/template
179 lines
8.3 KiB
HTML
179 lines
8.3 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='font-awesome.css') }}">
|
|
<title>Chmod 计算器</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body {
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
background: #f5f5f5; color: #333;
|
|
height: 100vh; overflow-y: auto;
|
|
}
|
|
.container { max-width: 700px; margin: 0 auto; padding: 24px 28px 40px; }
|
|
|
|
.header { display: flex; align-items: center; margin-bottom: 2px; }
|
|
.header h1 { font-size: 18px; font-weight: 700; color: #1a1a1a; }
|
|
.subtitle { color: #aaa; font-size: 12px; margin-bottom: 16px; }
|
|
|
|
.section-card {
|
|
background: #fafafa; border: 1px solid #f0f0f0;
|
|
border-radius: 10px; padding: 14px 16px; margin-bottom: 12px;
|
|
}
|
|
.section-title {
|
|
font-size: 11px; font-weight: 600; color: #999;
|
|
text-transform: uppercase; letter-spacing: 0.06em;
|
|
margin-bottom: 12px; display: flex; align-items: center; gap: 6px;
|
|
}
|
|
.section-title i { font-size: 11px; }
|
|
|
|
/* 权限网格 */
|
|
.perm-grid {
|
|
display: grid; grid-template-columns: 72px 1fr 1fr 1fr;
|
|
gap: 0; border: 1px solid #e8e8e8; border-radius: 8px; overflow: hidden;
|
|
background: #fff;
|
|
}
|
|
.perm-grid .gh {
|
|
padding: 8px; font-size: 11px; font-weight: 600; color: #999;
|
|
text-transform: uppercase; letter-spacing: 0.04em; text-align: center;
|
|
background: #fafafa; border-bottom: 1px solid #e8e8e8;
|
|
}
|
|
.perm-grid .gh:first-child { text-align: right; }
|
|
.perm-grid .rh {
|
|
padding: 8px 10px; font-size: 12px; font-weight: 600; color: #666;
|
|
text-align: right; background: #fafafa;
|
|
border-right: 1px solid #e8e8e8; border-bottom: 1px solid #f0f0f0;
|
|
display: flex; align-items: center; justify-content: flex-end; gap: 4px;
|
|
}
|
|
.perm-grid .rh:last-of-type { border-bottom: none; }
|
|
.perm-grid .rh .val { font-size: 10px; color: #bbb; font-weight: 400; }
|
|
.perm-grid .cell {
|
|
padding: 8px; text-align: center;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
display: flex; align-items: center; justify-content: center;
|
|
}
|
|
.perm-grid .row-last .cell { border-bottom: none; }
|
|
.perm-grid input[type="checkbox"] { display: none; }
|
|
.perm-grid .cb {
|
|
width: 30px; height: 30px; border: 2px solid #ddd; border-radius: 5px;
|
|
display: flex; align-items: center; justify-content: center;
|
|
cursor: pointer; transition: all 0.15s;
|
|
}
|
|
.perm-grid .cb i { font-size: 13px; color: #fff; opacity: 0; transition: opacity 0.15s; }
|
|
.perm-grid input:checked + .cb { background: #0078d4; border-color: #0078d4; }
|
|
.perm-grid input:checked + .cb i { opacity: 1; }
|
|
|
|
/* 结果区 */
|
|
.result-card {
|
|
background: #fff; border: 1px solid #f0f0f0;
|
|
border-radius: 10px; padding: 24px;
|
|
text-align: center;
|
|
}
|
|
.octal-display {
|
|
font-size: 64px; font-weight: 700; font-family: "SFMono-Regular", Consolas, monospace;
|
|
color: #0078d4; letter-spacing: 0.08em; margin-bottom: 4px;
|
|
}
|
|
.symbolic-display {
|
|
font-size: 22px; font-family: "SFMono-Regular", Consolas, monospace;
|
|
color: #555; letter-spacing: 0.15em; margin-bottom: 20px;
|
|
}
|
|
.cmd-wrap {
|
|
display: inline-flex; align-items: center; gap: 10px;
|
|
background: #fafafa; border: 1px solid #e0e0e0; border-radius: 8px;
|
|
padding: 10px 16px;
|
|
}
|
|
.cmd-wrap code {
|
|
font-family: "SFMono-Regular", Consolas, monospace;
|
|
font-size: 14px; color: #333;
|
|
}
|
|
.btn-cp {
|
|
padding: 5px 12px; background: #0078d4; color: #fff; border: none;
|
|
border-radius: 5px; font-size: 12px; font-weight: 600; cursor: pointer;
|
|
transition: all 0.15s; white-space: nowrap;
|
|
}
|
|
.btn-cp:hover { background: #006cbd; }
|
|
.btn-cp.copied { background: #2e7d32; }
|
|
|
|
@media (max-width: 768px) {
|
|
.container { padding: 14px 16px 28px; }
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="container">
|
|
<div class="header">
|
|
<h1><i class="fas fa-shield-halved" style="color:#0078d4;font-size:16px;margin-right:6px;"></i>Chmod 计算器</h1>
|
|
</div>
|
|
<p class="subtitle">Linux 文件权限速算</p>
|
|
|
|
<div class="section-card">
|
|
<div class="section-title"><i class="fas fa-check-square"></i> 勾选权限</div>
|
|
<div class="perm-grid">
|
|
<div class="gh"></div>
|
|
<div class="gh">Owner</div>
|
|
<div class="gh">Group</div>
|
|
<div class="gh">Public</div>
|
|
|
|
<div class="rh">Read <span class="val">(4)</span></div>
|
|
<div class="cell"><label><input type="checkbox" data-g="owner" data-s="read" onchange="calc()"><span class="cb"><i class="fas fa-check"></i></span></label></div>
|
|
<div class="cell"><label><input type="checkbox" data-g="group" data-s="read" onchange="calc()"><span class="cb"><i class="fas fa-check"></i></span></label></div>
|
|
<div class="cell"><label><input type="checkbox" data-g="public" data-s="read" onchange="calc()"><span class="cb"><i class="fas fa-check"></i></span></label></div>
|
|
|
|
<div class="rh">Write <span class="val">(2)</span></div>
|
|
<div class="cell"><label><input type="checkbox" data-g="owner" data-s="write" onchange="calc()"><span class="cb"><i class="fas fa-check"></i></span></label></div>
|
|
<div class="cell"><label><input type="checkbox" data-g="group" data-s="write" onchange="calc()"><span class="cb"><i class="fas fa-check"></i></span></label></div>
|
|
<div class="cell"><label><input type="checkbox" data-g="public" data-s="write" onchange="calc()"><span class="cb"><i class="fas fa-check"></i></span></label></div>
|
|
|
|
<div class="rh row-last">Exec <span class="val">(1)</span></div>
|
|
<div class="cell"><label><input type="checkbox" data-g="owner" data-s="execute" onchange="calc()"><span class="cb"><i class="fas fa-check"></i></span></label></div>
|
|
<div class="cell"><label><input type="checkbox" data-g="group" data-s="execute" onchange="calc()"><span class="cb"><i class="fas fa-check"></i></span></label></div>
|
|
<div class="cell"><label><input type="checkbox" data-g="public" data-s="execute" onchange="calc()"><span class="cb"><i class="fas fa-check"></i></span></label></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="result-card">
|
|
<div class="octal-display" id="octal">000</div>
|
|
<div class="symbolic-display" id="symbolic">---------</div>
|
|
<div class="cmd-wrap">
|
|
<code id="cmd">chmod 000 path</code>
|
|
<button class="btn-cp" id="copyBtn" onclick="copyCmd()">复制</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
var vals={read:4,write:2,execute:1};
|
|
var chars={read:'r',write:'w',execute:'x'};
|
|
|
|
function calc(){
|
|
var groups=['owner','group','public'];
|
|
var octal='',symbolic='';
|
|
groups.forEach(function(g){
|
|
var sum=0,sym='';
|
|
['read','write','execute'].forEach(function(s){
|
|
var checked=document.querySelector('input[data-g="'+g+'"][data-s="'+s+'"]').checked;
|
|
if(checked){sum+=vals[s];sym+=chars[s];}else{sym+='-';}
|
|
});
|
|
octal+=sum;symbolic+=sym;
|
|
});
|
|
document.getElementById('octal').textContent=octal;
|
|
document.getElementById('symbolic').textContent=symbolic;
|
|
document.getElementById('cmd').textContent='chmod '+octal+' path';
|
|
}
|
|
|
|
function copyCmd(){
|
|
var text=document.getElementById('cmd').textContent;
|
|
var el=document.createElement('textarea');
|
|
el.value=text;el.style.cssText='position:fixed;left:-9999px';
|
|
document.body.appendChild(el);el.select();document.execCommand('copy');document.body.removeChild(el);
|
|
var btn=document.getElementById('copyBtn');
|
|
btn.textContent='已复制';btn.classList.add('copied');
|
|
setTimeout(function(){btn.textContent='复制';btn.classList.remove('copied');},1500);
|
|
}
|
|
calc();
|
|
</script>
|
|
</body>
|
|
</html>
|