This commit is contained in:
Zengtudor 2025-05-11 01:40:19 +08:00
parent 51c5428a61
commit 37cc168d96
3 changed files with 167 additions and 89 deletions

View File

@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.10) cmake_minimum_required(VERSION 3.10)
project(eew CXX) project(eew CXX)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
find_package(webview REQUIRED) find_package(webview REQUIRED)
find_package(Threads REQUIRED) find_package(Threads REQUIRED)

View File

@ -1,61 +1,81 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="zh-cn"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Environment Variables Table</title> <title>Environment Variables Viewer</title>
<style> <style>
body { body { font-family: system-ui, -apple-system, sans-serif; margin: 0; background: #f5f7fa; }
font-family: Arial, sans-serif; .container { max-width: 1200px; margin: 0 auto; padding: 0 16px; }
margin: 20px; header { background: white; padding: 20px 0; box-shadow: 0 2px 10px rgba(0,0,0,0.05); }
} h1 { color: #165DFF; margin: 0; }
table { main { padding: 24px 0; }
width: 100%; .card { background: white; border-radius: 8px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); padding: 16px; }
border-collapse: collapse; table { width: 100%; border-collapse: collapse; }
margin: 20px 0; th { text-align: left; padding: 12px 16px; background: #f9fafb; color: #6b7280; font-size: 12px; text-transform: uppercase; }
font-size: 18px; td { padding: 12px 16px; border-bottom: 1px solid #e5e7eb; }
text-align: left; tr:last-child td { border-bottom: none; }
} tr:nth-child(even) { background: #f9fafb; }
th, td { tr:hover { background: #f3f4f6; }
padding: 12px; footer { background: #1d2129; color: white; text-align: center; padding: 20px 0; }
border: 1px solid #ddd; .loading { text-align: center; color: #9ca3af; padding: 20px 0; }
} .error { text-align: center; color: #ef4444; padding: 20px 0; }
th { a { color: #165DFF; text-decoration: none; }
background-color: #f4f4f4; a:hover { text-decoration: underline; }
} .btn {
tr:nth-child(even) { background-color: #165DFF;
background-color: #f9f9f9; color: white;
}
tr:hover {
background-color: #f1f1f1;
}
@media (max-width: 600px) {
table, thead, tbody, th, td, tr {
display: block;
}
th, td {
text-align: right;
padding: 10px;
}
th {
background-color: #f4f4f4;
position: sticky;
top: 0;
}
td {
border: none; border: none;
border-bottom: 1px solid #ddd; padding: 8px 16px;
border-radius: 4px;
cursor: pointer;
font-size: 14px;
margin-bottom: 16px;
} }
td::before { .btn:hover {
content: attr(data-label); background-color: #0E42CC;
float: left;
font-weight: bold;
} }
.btn:active {
background-color: #0A3199;
}
.scrollable {
max-height: 80px;
overflow-y: auto;
max-width: 300px;
border: 1px solid #e5e7eb;
padding: 4px;
border-radius: 2px;
background-color: #f9fafb;
}
/* 自定义滚动条样式 */
.scrollable::-webkit-scrollbar {
width: 6px;
}
.scrollable::-webkit-scrollbar-track {
background: #f1f1f1;
}
.scrollable::-webkit-scrollbar-thumb {
background: #c5c5c5;
border-radius: 3px;
}
.scrollable::-webkit-scrollbar-thumb:hover {
background: #a8a8a8;
} }
</style> </style>
</head> </head>
<body> <body>
<h1>Environment Variables</h1> <header>
<div class="container">
<h1>Environment Variables Viewer</h1>
<p>Real-time system environment configuration</p>
</div>
</header>
<main class="container">
<button id="refreshBtn" class="btn">
<i class="fa fa-refresh mr-1"></i> Refresh
</button>
<div class="card">
<table id="envTable"> <table id="envTable">
<thead> <thead>
<tr> <tr>
@ -63,42 +83,77 @@
<th>Value</th> <th>Value</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody id="envTableBody">
<!-- Rows will be dynamically inserted here --> <tr>
<td colspan="2" class="loading">Loading environment variables...</td>
</tr>
</tbody> </tbody>
</table> </table>
</div>
</main>
<script script type="module"> <footer>
// TODO: async getEnvString() will be implemented elsewhere <div class="container">
<p>© 2025 Environment Variables Viewer | Author: Tudor 曾子愚</p>
<p>
<a href="https://blog.zziyu.cn" target="_blank">Blog</a> |
<a href="https://gitcode.com/Zengtudor" target="_blank">GitCode</a> |
<a href="mailto:Zengtudor@outlook.com" target="_blank">Email</a>
</p>
</div>
</footer>
<script>
async function refreshEnvTable() { async function refreshEnvTable() {
const tableBody = document.getElementById('envTableBody');
tableBody.innerHTML = '<tr><td colspan="2" class="loading">Refreshing environment variables...</td></tr>';
try { try {
// 调用 getEnvString 函数并解析返回值
const env = await window.getEnvString(); const env = await window.getEnvString();
console.log("Environment String:", env); tableBody.innerHTML = '';
// 清空表格内容 if (!env || Object.keys(env).length === 0) {
const tableBody = document.querySelector("#envTable tbody"); tableBody.innerHTML = '<tr><td colspan="2" class="loading">No environment variables found</td></tr>';
tableBody.innerHTML = ""; return;
}
// 填充表格 Object.entries(env).forEach(([key, value]) => {
for (const [key, value] of Object.entries(env)) { const row = document.createElement('tr');
const row = document.createElement("tr");
row.innerHTML = ` row.innerHTML = `
<td data-label="Key">${key}</td> <td>${key}</td>
<td data-label="Value">${value}</td> <td><div class="scrollable" title="${value}">${value}</div></td>
`; `;
tableBody.appendChild(row); tableBody.appendChild(row);
}
} catch (error) {
console.error("Failed to refresh environment table:", error);
}
}
document.addEventListener('DOMContentLoaded', async () => {
await refreshEnvTable();
}); });
// 页面加载时刷新表格 } catch (error) {
// document.addEventListener("DOMContentLoaded", refreshEnvTable); tableBody.innerHTML = `
<tr>
<td colspan="2" class="error">Failed to load: ${error.message}</td>
</tr>
`;
}
}
document.addEventListener('DOMContentLoaded', refreshEnvTable);
document.getElementById('refreshBtn').addEventListener('click', refreshEnvTable);
// Mock data for demonstration
if (!window.getEnvString) {
window.getEnvString = async () => {
await new Promise(resolve => setTimeout(resolve, 1000));
return {
NODE_ENV: 'development',
PORT: '3000',
DB_HOST: 'localhost',
DB_USER: 'root',
DB_PASSWORD: '********',
API_KEY: 'sk-********************************',
DEBUG_MODE: 'true',
LONG_TEXT_VARIABLE: 'This is a very long text value that exceeds the normal display area. It should be scrollable within the container so users can view the entire content without truncation. This provides a better user experience when dealing with large environment variable values.'
};
};
}
</script> </script>
</body> </body>
</html> </html>

View File

@ -8,6 +8,8 @@
#include <sstream> #include <sstream>
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include <string_view>
#include <unordered_set>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <webview/backends.hh> #include <webview/backends.hh>
@ -49,20 +51,41 @@ std::ostream&operator<<(std::ostream &os,const std::vector<T> &v){
return os; return os;
} }
std::string envKvToJsonString(const vpss_t &v){
std::stringstream ss;
const auto toJsonString = [](const std::string_view &str)->std::string{
std::stringstream ss;
for(size_t i=0;i<str.size();i++){
const std::unordered_set<char> set={'\\','\"'};
if(set.find(str[i])!=set.end()){
ss<<"\\";
}
ss<<str[i];
}
return ss.str();
};
if(v.size()==0)return "{}";
ss<<"{";
if(v.size()==1){
ss<<"\""<<toJsonString(v[0].first)<<"\":\""<<toJsonString(v[0].second)<<"\"}";
return ss.str();
}
for(size_t i = 0;i<v.size()-1;i++){
ss<<"\""<<toJsonString(v[i].first)<<"\":\""<<toJsonString(v[i].second)<<"\",";
}
ss<<"\""<<toJsonString(v[v.size()-1].first)<<"\":\""<<toJsonString(v[v.size()-1].second)<<"\"}";
return ss.str();
}
int main(const int argc,char *argv[],char *env[]){ int main(const int argc,char *argv[],char *env[]){
try { try {
std::cout<<getEnvKv()<<'\n';
webview::webview wv(true,nullptr); webview::webview wv(true,nullptr);
wv.set_html(html);
wv.bind("getEnvString", wv.bind("getEnvString",
[](const std::string &req)->std::string { [](const std::string &req)->std::string {
std::stringstream oss; std::cout<<envKvToJsonString(getEnvKv())<<'\n';
oss<<getEnvKv(); return envKvToJsonString(getEnvKv());
std::cout<<std::format("{{env:\"{}\"}}",getEnvKv()[0].first)<<'\n';
return std::format("{{\"env\":\"{}\"}}",getEnvKv()[0].first);
}); });
wv.set_html(html);
wv.run(); wv.run();
} catch (const std::exception &e) { } catch (const std::exception &e) {
std::cerr<<e.what()<<'\n'; std::cerr<<e.what()<<'\n';