mirror of
https://github.com/Buriburizaem0n/ai-dict.git
synced 2025-12-13 03:44:41 +00:00
<edited>added phone adaption. optimized Database record process.
This commit is contained in:
12
main.go
12
main.go
@@ -118,12 +118,17 @@ func main() {
|
||||
}
|
||||
|
||||
func getDefinition(word, sourceLang, targetLang string) ([]byte, error) {
|
||||
wordKey := fmt.Sprintf("%s-%s:%s", sourceLang, targetLang, word)
|
||||
// --- 新增:将接收到的单词统一转换为小写进行处理 ---
|
||||
normalizedWord := strings.ToLower(word)
|
||||
// --- 标准化结束 ---
|
||||
|
||||
// 后续所有操作都使用这个标准化后的单词
|
||||
wordKey := fmt.Sprintf("%s-%s:%s", sourceLang, targetLang, normalizedWord)
|
||||
|
||||
var cachedDefinition string
|
||||
err := db.QueryRow("SELECT definition FROM cache WHERE word_key = ?", wordKey).Scan(&cachedDefinition)
|
||||
if err == nil {
|
||||
log.Printf("Cache hit from SQLite for key: %s", wordKey)
|
||||
log.Printf("Cache hit for key: %s (Original: '%s')", wordKey, word)
|
||||
return []byte(cachedDefinition), nil
|
||||
}
|
||||
|
||||
@@ -134,7 +139,8 @@ func getDefinition(word, sourceLang, targetLang string) ([]byte, error) {
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("unsupported language pair: %s", promptKey)
|
||||
}
|
||||
prompt := strings.Replace(promptTemplate, "${word}", word, -1)
|
||||
// 使用标准化后的单词去填充Prompt
|
||||
prompt := strings.Replace(promptTemplate, "${word}", normalizedWord, -1)
|
||||
|
||||
requestBody, _ := json.Marshal(map[string]interface{}{"model": config.API.Model, "messages": []map[string]string{{"role": "user", "content": prompt}}})
|
||||
req, _ := http.NewRequest("POST", config.API.URL, bytes.NewBuffer(requestBody))
|
||||
|
||||
194
static/goldendict-tutorial.html
Normal file
194
static/goldendict-tutorial.html
Normal file
@@ -0,0 +1,194 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>GoldenDict 集成教程 - AI 词典</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 40px auto;
|
||||
padding: 0 20px;
|
||||
color: #333;
|
||||
line-height: 1.6;
|
||||
}
|
||||
h1, h2, h3 { color: #1a73e8; }
|
||||
h1 { border-bottom: 2px solid #f0f0f0; padding-bottom: 10px; }
|
||||
.step { margin-bottom: 25px; }
|
||||
.step-title { font-size: 1.4em; font-weight: bold; margin-bottom: 10px; }
|
||||
code {
|
||||
background-color: #f1f1f1;
|
||||
padding: 3px 6px;
|
||||
border-radius: 4px;
|
||||
font-family: "Courier New", Courier, monospace;
|
||||
color: #d93025;
|
||||
word-break: break-all;
|
||||
}
|
||||
.container { border: 1px solid #ddd; padding: 20px; border-radius: 8px; }
|
||||
.home-link { display: block; margin-top: 30px; text-align: center; }
|
||||
|
||||
.url-generator {
|
||||
background-color: #f8f9fa;
|
||||
border: 1px solid #e0e0e0;
|
||||
border-radius: 8px;
|
||||
padding: 20px;
|
||||
margin-top: 15px;
|
||||
}
|
||||
.url-generator select {
|
||||
padding: 8px;
|
||||
font-size: 14px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
margin: 0 5px;
|
||||
}
|
||||
.url-output {
|
||||
margin-top: 15px;
|
||||
position: relative;
|
||||
}
|
||||
#generatedUrl {
|
||||
display: block;
|
||||
padding: 10px;
|
||||
padding-right: 80px; /* 为复制按钮留出空间 */
|
||||
}
|
||||
#copyBtn {
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
padding: 5px 10px;
|
||||
cursor: pointer;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 4px;
|
||||
background-color: #fff;
|
||||
}
|
||||
#copyBtn:hover { background-color: #f1f1f1; }
|
||||
.examples-list li { margin-bottom: 10px; }
|
||||
|
||||
@media (max-width: 600px) {
|
||||
body { margin: 20px auto; padding: 0 15px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>如何将 AI 词典添加到 GoldenDict</h1>
|
||||
<div class="container">
|
||||
<p>通过本教程,您可以将这个强大的实时AI词典无缝集成到您本地的 GoldenDict 软件中,获得顶级的桌面端查词体验。</p>
|
||||
|
||||
<div class="step">
|
||||
<div class="step-title">重要说明</div>
|
||||
<p>GoldenDict 无法动态传递您选择的语言对。因此,您需要为您希望使用的**每一个语言对**(例如“英→汉”、“德→英”等)都单独添加一个词典条目。</p>
|
||||
<p>为了简化这个过程,我们提供了下面的 **URL生成器** 和常用示例。</p>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<div class="step-title">URL 生成器</div>
|
||||
<div class="url-generator">
|
||||
<label for="sourceLangGen">源语言:</label>
|
||||
<select id="sourceLangGen"></select>
|
||||
<span>→</span>
|
||||
<label for="targetLangGen">目标语言:</label>
|
||||
<select id="targetLangGen"></select>
|
||||
|
||||
<div class="url-output">
|
||||
<p><strong>生成的URL (请复制):</strong></p>
|
||||
<code id="generatedUrl"></code>
|
||||
<button id="copyBtn">复制</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<div class="step-title">设置步骤</div>
|
||||
<ol>
|
||||
<li>打开 GoldenDict, 进入 <code>编辑</code> → <code>词典</code> (快捷键 <code>F3</code>)。</li>
|
||||
<li>点击 <code>网站</code> 标签页, 然后点击 <code>添加...</code> 按钮。</li>
|
||||
<li>在弹出的窗口中填写信息:
|
||||
<ul>
|
||||
<li><strong>启用</strong>: ✅ (务必勾选)</li>
|
||||
<li><strong>名称</strong>: 建议使用能识别的名称, 例如 <code>AI 词典 (英→汉)</code></li>
|
||||
<li><strong>地址</strong>: 从上方的 **URL生成器** 或下方的常用示例中,复制对应的URL并粘贴到这里。</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>点击 <code>确定</code> 保存。</li>
|
||||
<li>**重复第3、4步**为您需要的其他语言对添加更多词典。</li>
|
||||
<li>全部添加完毕后,点击主设置窗口的 <code>确定</code> 使设置生效。</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="step">
|
||||
<div class="step-title">常用语言对示例</div>
|
||||
<p>为方便起见,这里提供一些常用组合的URL。请根据您的服务器地址(本地或远程)进行修改。</p>
|
||||
<ul class="examples-list">
|
||||
<li><strong>英 → 汉:</strong> <code>http://localhost:8080/golden-dict?source=en&target=zh&word=%GDWORD%</code></li>
|
||||
<li><strong>德 → 汉:</strong> <code>http://localhost:8080/golden-dict?source=de&target=zh&word=%GDWORD%</code></li>
|
||||
<li><strong>日 → 汉:</strong> <code>http://localhost:8080/golden-dict?source=ja&target=zh&word=%GDWORD%</code></li>
|
||||
<li><strong>汉 → 英:</strong> <code>http://localhost:8080/golden-dict?source=zh&target=en&word=%GDWORD%</code></li>
|
||||
<li><strong>英 → 英 (单语):</strong> <code>http://localhost:8080/golden-dict?source=en&target=en&word=%GDWORD%</code></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<h2>完成!</h2>
|
||||
<p>现在,您可以在 GoldenDict 中查词了。您添加的每一个语言对都会作为一个独立的标签页显示结果。</p>
|
||||
</div>
|
||||
|
||||
<a href="/" class="home-link">返回词典主页</a>
|
||||
|
||||
<script>
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
const sourceSelect = document.getElementById('sourceLangGen');
|
||||
const targetSelect = document.getElementById('targetLangGen');
|
||||
const urlOutput = document.getElementById('generatedUrl');
|
||||
const copyBtn = document.getElementById('copyBtn');
|
||||
|
||||
const langNameMap = {
|
||||
"en": "英语 (English)", "zh": "中文 (Chinese)", "es": "西班牙语 (Spanish)",
|
||||
"fr": "法语 (French)", "de": "德语 (German)", "ru": "俄语 (Russian)",
|
||||
"ja": "日语 (Japanese)", "ar": "阿拉伯语 (Arabic)", "pt": "葡萄牙语 (Portuguese)",
|
||||
};
|
||||
|
||||
// 假设可用语言列表(可以从主页的下拉菜单获取或硬编码)
|
||||
const languages = ["en", "zh", "es", "fr", "de", "ru", "ja", "ar", "pt"];
|
||||
|
||||
function populateSelect(selectElement) {
|
||||
languages.forEach(langCode => {
|
||||
const option = document.createElement('option');
|
||||
option.value = langCode;
|
||||
option.textContent = langNameMap[langCode] || langCode;
|
||||
selectElement.appendChild(option);
|
||||
});
|
||||
}
|
||||
|
||||
populateSelect(sourceSelect);
|
||||
populateSelect(targetSelect);
|
||||
|
||||
// 设置默认值
|
||||
sourceSelect.value = 'en';
|
||||
targetSelect.value = 'zh';
|
||||
|
||||
function generateUrl() {
|
||||
const source = sourceSelect.value;
|
||||
const target = targetSelect.value;
|
||||
const baseUrl = window.location.origin; // 自动获取当前域名和端口
|
||||
const generated = `${baseUrl}/golden-dict?source=${source}&target=${target}&word=%GDWORD%`;
|
||||
urlOutput.textContent = generated;
|
||||
}
|
||||
|
||||
sourceSelect.addEventListener('change', generateUrl);
|
||||
targetSelect.addEventListener('change', generateUrl);
|
||||
|
||||
copyBtn.addEventListener('click', () => {
|
||||
navigator.clipboard.writeText(urlOutput.textContent).then(() => {
|
||||
copyBtn.textContent = '已复制!';
|
||||
setTimeout(() => { copyBtn.textContent = '复制'; }, 2000);
|
||||
}, (err) => {
|
||||
console.error('Could not copy text: ', err);
|
||||
});
|
||||
});
|
||||
|
||||
// 初始加载时生成一次URL
|
||||
generateUrl();
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -3,27 +3,118 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>AI Dictionary</title>
|
||||
<title>AI 词典</title>
|
||||
<style>
|
||||
/* CSS样式保持不变 */
|
||||
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; max-width: 800px; margin: 40px auto; padding: 0 20px; color: #333; }
|
||||
/* --- 基础样式 (桌面优先) --- */
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
|
||||
max-width: 800px;
|
||||
margin: 40px auto;
|
||||
padding: 0 20px;
|
||||
color: #333;
|
||||
background-color: #ffffff;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
h1 { color: #1a73e8; }
|
||||
#search-controls { display: flex; gap: 10px; margin-bottom: 20px; align-items: center; }
|
||||
#lang-selectors { display: flex; gap: 5px; }
|
||||
#lang-selectors select { padding: 8px; font-size: 14px; border: 1px solid #ccc; border-radius: 8px; }
|
||||
#search-container { display: flex; flex-grow: 1; gap: 10px; }
|
||||
#wordInput { flex-grow: 1; padding: 10px; font-size: 16px; border: 1px solid #ccc; border-radius: 8px; }
|
||||
#searchButton { padding: 10px 20px; font-size: 16px; background-color: #1a73e8; color: white; border: none; border-radius: 8px; cursor: pointer; }
|
||||
#search-controls {
|
||||
display: flex;
|
||||
gap: 20px; /* 增加桌面端间距 */
|
||||
margin-bottom: 20px;
|
||||
align-items: center;
|
||||
}
|
||||
#lang-selectors {
|
||||
display: flex;
|
||||
gap: 10px; /* 增加桌面端间距 */
|
||||
align-items: center;
|
||||
}
|
||||
#lang-selectors select {
|
||||
padding: 8px;
|
||||
font-size: 14px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
}
|
||||
#search-container {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
gap: 10px;
|
||||
}
|
||||
#wordInput {
|
||||
flex-grow: 1;
|
||||
padding: 10px;
|
||||
font-size: 16px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 8px;
|
||||
}
|
||||
#searchButton {
|
||||
padding: 10px 20px;
|
||||
font-size: 16px;
|
||||
background-color: #1a73e8;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
}
|
||||
#searchButton:hover { background-color: #185abc; }
|
||||
#results { margin-top: 30px; }
|
||||
.entry { border-left: 3px solid #1a73e8; padding: 15px; margin-top: 20px; background-color: #f8f9fa; border-radius: 0 8px 8px 0; }
|
||||
.entry {
|
||||
border-left: 3px solid #1a73e8;
|
||||
padding: 15px;
|
||||
margin-top: 20px;
|
||||
background-color: #f8f9fa;
|
||||
border-radius: 0 8px 8px 0;
|
||||
}
|
||||
.phonetics { font-size: 1.1em; color: #5f6368; }
|
||||
.phonetics span { margin-right: 20px; }
|
||||
.part-of-speech { font-weight: bold; font-size: 1.2em; margin-top: 10px; }
|
||||
.definition-block { margin-top: 15px; }
|
||||
.definition-block small { color: #5f6368; }
|
||||
.example { margin-top: 10px; font-style: italic; color: #3c4043; }
|
||||
.example small { color: #70757a; }
|
||||
|
||||
footer {
|
||||
margin-top: 40px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
text-align: center;
|
||||
font-size: 14px;
|
||||
}
|
||||
footer a {
|
||||
color: #5f6368;
|
||||
text-decoration: none;
|
||||
}
|
||||
footer a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
/* --- 2. 新增:媒体查询 (移动端样式) --- */
|
||||
/* 当屏幕宽度小于等于 600px 时,应用以下样式 */
|
||||
@media (max-width: 600px) {
|
||||
body {
|
||||
/* 减少手机上的边距 */
|
||||
margin: 20px auto;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
#search-controls {
|
||||
/* 关键改动:让搜索控件垂直堆叠 */
|
||||
flex-direction: column;
|
||||
align-items: stretch; /* 让子项宽度撑满 */
|
||||
gap: 15px;
|
||||
}
|
||||
|
||||
#lang-selectors {
|
||||
justify-content: center; /* 让语言选择居中 */
|
||||
}
|
||||
|
||||
#search-container {
|
||||
flex-direction: column; /* 让输入框和按钮也垂直堆叠 */
|
||||
}
|
||||
|
||||
#searchButton {
|
||||
padding: 12px; /* 增大按钮点击区域 */
|
||||
font-size: 18px; /* 增大按钮文字 */
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-size: 2em; /* 调整标题大小 */
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -62,7 +153,10 @@
|
||||
</div>
|
||||
|
||||
<div id="results"></div>
|
||||
<footer>
|
||||
<a href="/goldendict-tutorial.html">如何集成到 GoldenDict?</a>
|
||||
</footer>
|
||||
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
<script src="app.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user