merge: manually check translations

This commit is contained in:
Sheng Fan 2025-03-19 12:54:13 +08:00
commit e190e1484e
9 changed files with 253 additions and 47 deletions

View File

@ -5,10 +5,12 @@ import utils from '@/assets/js/utils'
function cache(fileObj, $event) { function cache(fileObj, $event) {
console.log('Caching fileObj start:', fileObj, $event.target, $event.dataTransfer) console.log('Caching fileObj start:', fileObj, $event.target, $event.dataTransfer)
console.log('typeof fileObj:', Array.isArray(fileObj)) console.log('typeof fileObj:', Array.isArray(fileObj))
// If fileObj is an array, create new element and append to array // If fileObj is an array, create a new element and append to the array
// event.target.files and event.dataTransfer.files are properties related to file upload and drag-drop events // event.target.files and event.dataTransfer.files are event properties in JavaScript related to file upload and drag-and-drop.
// event.target.files: Used with <input type="file"> elements, contains list of files selected via change event // event.target.files: This property is used with HTML file input elements (<input type="file">),
// event.dataTransfer.files: Contains list of files dropped onto an element via drag-drop event // When the user selects a file and triggers the change event, event.target.files can be used to get the list of files selected by the user.
// event.dataTransfer.files: This property is used when the user drags and drops files onto an element,
// event.dataTransfer.files can be used to get the list of dropped files.
console.log('$event:', $event, $event.type) console.log('$event:', $event, $event.type)
let files let files
if ($event.type == 'change') { if ($event.type == 'change') {
@ -33,11 +35,11 @@ function cache(fileObj, $event) {
fileInfo.fileName = file.name fileInfo.fileName = file.name
console.log('Caching fileObj completed:', fileInfo) console.log('Caching fileObj completed:', fileInfo)
if (Array.isArray(fileObj)) { if (Array.isArray(fileObj)) {
// Append to array after successful operation // Append to the end of the array after successful operation
fileObj.push(fileInfo) fileObj.push(fileInfo)
} }
if ($event.type == 'change') { if ($event.type == 'change') {
// Clear input to allow reselecting same file // Solve the problem of selecting the same file not triggering the change event, clean up at the end
$event.target.value = null $event.target.value = null
} }
} }
@ -93,7 +95,7 @@ async function uploads(fileObjs) {
for (let index in fileObjs) { for (let index in fileObjs) {
console.log('Processing file object:', fileObjs, index, fileObjs.length, fileObjs[index]) console.log('Processing file object:', fileObjs, index, fileObjs.length, fileObjs[index])
await upload(fileObjs[index]) await upload(fileObjs[index])
console.log("Upload completed for index:", index, fileObjs[index]) console.log("uploads index:", index, "File upload completed", fileObjs[index])
} }
} }
@ -185,21 +187,23 @@ function readAll(filePath) {
} }
export default { export default {
// Cache on change event // Cache on onChange
cache, cache,
// Single file upload // Upload file
upload, upload,
// Batch file upload // Upload files
uploads, uploads,
// Immediate upload on change // Upload file
upOnChg, upOnChg,
// Add component // Upload on onChange
upOnChg,
// Add to component list
add, add,
// Remove component // Delete component from component list
del, del,
// Object conversion // Convert between Java object and js object
trans, trans,
// Collect file IDs // Collect fileId from Comps
fileIds, fileIds,
// Read file // Read file
readAll readAll

View File

@ -41,10 +41,12 @@ $axios.interceptors.response.use(
console.log("error:" + JSON.stringify(error)) console.log("error:" + JSON.stringify(error))
if (error.response == undefined || error.response == null) { if (error.response == undefined || error.response == null) {
pop("Unknown request error!") pop("Unknown request error!")
pop("Unknown request error!")
} else if (error.response.status == 500) { } else if (error.response.status == 500) {
pop("Unable to communicate with backend, please retry later!") pop("Unable to communicate with backend, please retry later!")
} else { } else {
pop("Request error:" + error) pop("Request error:" + error)
pop("Request error:" + error)
} }
return Promise.reject(error) return Promise.reject(error)
} }
@ -85,21 +87,21 @@ function greet(name) {
} }
/** /**
* Identify whether the object is null * Check if object is null
*/ */
function isNull(obj) { function isNull(obj) {
return obj == undefined || obj == null return obj == undefined || obj == null
} }
/** /**
* Identify whether the object is not null * Check if object is not null
*/ */
function notNull(obj) { function notNull(obj) {
return obj != undefined && obj != null return obj != undefined && obj != null
} }
/** /**
* Identify an empty string * Check if string is blank
*/ */
function isBlank(str) { function isBlank(str) {
return str == undefined || str == null || /^s*$/.test(str) return str == undefined || str == null || /^s*$/.test(str)
@ -113,28 +115,28 @@ function notBlank(str) {
} }
/** /**
* Identify an empty array * Check if array is empty
*/ */
function isEmpty(arr) { function isEmpty(arr) {
return arr == undefined || arr == null || (arr instanceof Array && arr.length == 0) return arr == undefined || arr == null || (arr instanceof Array && arr.length == 0)
} }
/** /**
* Identify a non-empty array * Check if array is not empty
*/ */
function notEmpty(arr) { function notEmpty(arr) {
return arr != undefined && arr != null && arr instanceof Array && arr.length > 0 return arr != undefined && arr != null && arr instanceof Array && arr.length > 0
} }
/** /**
* Identify true * Check if object is true
*/ */
function isTrue(obj) { function isTrue(obj) {
return obj == true || obj == 'true' return obj == true || obj == 'true'
} }
/** /**
* Identify false * Check if object is false
*/ */
function isFalse(obj) { function isFalse(obj) {
return !isTrue(obj) return !isTrue(obj)
@ -157,7 +159,7 @@ function getCharCount(str, char) {
/** /**
* Format date with specified pattern * Format date with specified pattern
* @param {Date|string} date - Date object or date string * @param {Date|string} date - Date object or date string
* @param {string} format - Target format pattern * @param {string} format - Target format pattern; by default, `yyyy-MM-dd HH:mm:ss`
* @returns {string} - Formatted date string * @returns {string} - Formatted date string
*/ */
function dateFormat(date, format) { function dateFormat(date, format) {
@ -451,13 +453,13 @@ function colorByLabel(label) {
function descByLabel(label) { function descByLabel(label) {
if ('ADD' == label) { if ('ADD' == label) {
return '新增' return 'Add'
} }
if ('UPD' == label) { if ('UPD' == label) {
return '更新' return 'Update'
} }
if ('DEL' == label) { if ('DEL' == label) {
return '删除' return 'Delete'
} }
return label return label
} }
@ -534,6 +536,9 @@ function debounce(func, delay) {
} }
} }
/**
* Convert string to lines
*/
function stringToLines(str) { function stringToLines(str) {
if (str == undefined || str == null) { if (str == undefined || str == null) {
return [] return []

View File

@ -73,6 +73,7 @@ const codeValidator = (rule, value, callback) => {
callback() callback()
} else if (!codeReg.test(value)) { } else if (!codeReg.test(value)) {
callback(new Error('Invalid code format')) callback(new Error('Invalid code format'))
callback(new Error('Invalid code format'))
} else { } else {
callback() callback()
} }
@ -92,7 +93,7 @@ function validator() {
console.log("arguments:", arguments) console.log("arguments:", arguments)
if (arguments.length <= 1) { if (arguments.length <= 1) {
const type = arguments[0] const type = arguments[0]
// Generic validators // Default validation logic, no special characters
if (utils.isBlank(type)) { if (utils.isBlank(type)) {
return commonValidator return commonValidator
} else if (type == 'notBlank') { } else if (type == 'notBlank') {
@ -124,7 +125,7 @@ function validator() {
callback(new Error('Invalid code format')) callback(new Error('Invalid code format'))
break break
} else if (typeStr == 'int' && Number.isInteger(value)) { } else if (typeStr == 'int' && Number.isInteger(value)) {
callback(new Error('In')) callback(new Error('Please enter an integer'))
break break
} }
} }

View File

@ -37,18 +37,18 @@ export default defineConfig({
}, },
build: { build: {
chunkSizeWarningLimit: 1500, chunkSizeWarningLimit: 1500,
// Split into chunks // Split chunks, break large chunks into smaller ones
rollupOptions: { rollupOptions: {
output: { output: {
manualChunks(id) { manualChunks(id) {
if (id.includes('node_modules')) { if (id.includes('node_modules')) {
// Pack each package into a separate chunk // Let each plugin be packaged into an independent file
return id.toString().split('node_modules/')[1].split('/')[0].toString() return id.toString().split('node_modules/')[1].split('/')[0].toString()
} }
}, // Unit b, merge smaller modules
// In bytes, merge small modules experimentalMinChunkSize: 10 * 1024
experimentalMinChunkSize: 10 * 1024, }
} }
}, }
} },
}) })

View File

@ -35,6 +35,7 @@ export default {
promptInputPlaceHolder: "Please Input Task Prompt", promptInputPlaceHolder: "Please Input Task Prompt",
promptInput: "Prompt Input", promptInput: "Prompt Input",
promptInputKw: "Prompt Input", promptInputKw: "Prompt Input",
clearCache: "Clear Cache",
clearCacheSuccess: "Clear cache success", clearCacheSuccess: "Clear cache success",
openManusAgiTips: "The above content is generated by OpenManus for reference only", openManusAgiTips: "The above content is generated by OpenManus for reference only",
taskStatus: { taskStatus: {
@ -45,5 +46,8 @@ export default {
terminated: "Terminated", terminated: "Terminated",
}, },
newTask: "New Task", newTask: "New Task",
readConfigSuccess: "Read config success",
readConfigFailed: "Read config failed",
baseConfig: "Base Settings",
serverConfig: "Server Config",
} }

View File

@ -34,6 +34,7 @@ export default {
promptInputPlaceHolder: "请输入任务提示词", promptInputPlaceHolder: "请输入任务提示词",
promptInput: "提示词输入", promptInput: "提示词输入",
promptInputKw: "提示词关键字", promptInputKw: "提示词关键字",
clearCache: "清理缓存",
clearCacheSuccess: "清理缓存成功", clearCacheSuccess: "清理缓存成功",
openManusAgiTips: "以上内容由OpenManus生成, 仅供参考和借鉴", openManusAgiTips: "以上内容由OpenManus生成, 仅供参考和借鉴",
taskStatus: { taskStatus: {
@ -44,4 +45,8 @@ export default {
terminated: "终止", terminated: "终止",
}, },
newTask: "新任务", newTask: "新任务",
readConfigSuccess: "读取配置成功",
readConfigFailed: "读取配置失败",
baseConfig: "基础设置",
serverConfig: "服务器配置",
} }

View File

@ -3,33 +3,211 @@
<el-card> <el-card>
<template #header> <template #header>
<div class="title fxsb"> <div class="title fxsb">
<div>基本信息</div> <div>{{ t('baseConfig') }}</div>
</div>
</template>
<!-- Show Data -->
<div class="card-row-wrap" v-show="baseShow">
<div class="card-row-aline fxsb">
<el-text>{{ t('clearCache') }}:</el-text>
<el-button type="danger" class="mlr-10" @click="clearCache">{{ t('clearCache') }}</el-button>
</div>
</div>
</el-card>
<el-card>
<template #header>
<div class="title fxsb">
<div> {{ t('serverConfig') }}</div>
<div> <div>
<el-link type="primary" class="no-select plr-6" @click="clearCache()">清理缓存</el-link> <el-link type="primary" class="no-select plr-6" @click="toEdit('server')" v-show="serverShow">
{{ t('edit') }}
</el-link>
<el-link type="primary" class="no-select plr-6" @click="toShow('server')" v-show="serverEdit">
{{ t('cancel') }}
</el-link>
</div> </div>
</div> </div>
</template> </template>
<!-- No Data -->
<div class="no-data" v-show="serverNoData">{{ t('noData') }}</div>
<!-- Show Data -->
<div class="card-row-wrap" v-show="serverShow">
<div class="card-row-item">
<el-text>host:</el-text>
<el-text>{{ serverConfig.host }}</el-text>
</div>
<div class="card-row-item">
<el-text>port:</el-text>
<el-text tag="p">{{ serverConfig.port }}</el-text>
</div>
</div>
<!-- Edit Module -->
<el-form ref="ruleFormRef" :model="serverConfigUpd" status-icon :rules="rules" v-show="serverEdit">
<div class="card-row-wrap">
<div class="card-row-item">
<el-text>host:</el-text>
<el-form-item prop="host">
<el-input v-model="serverConfigUpd.host" />
</el-form-item>
</div>
<div class="card-row-item">
<el-text>port:</el-text>
<el-form-item prop="port">
<el-input v-model="serverConfigUpd.port" />
</el-form-item>
</div>
<div class="card-row-aline fxc" v-show="serverEdit">
<el-button class="mlr-10" @click="toShow('server')">{{ t('cancel') }}</el-button>
<el-button type="primary" class="mlr-10" @click="submitForm">{{ t('submit') }}</el-button>
</div>
</div>
</el-form>
</el-card> </el-card>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref, reactive, inject, onMounted } from 'vue' import { ref, reactive, inject, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { useConfig } from '@/store/config' import { useConfig } from '@/store/config'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
const utils = inject('utils') const utils = inject('utils')
const files = inject('files')
const verify = inject('verify')
const router = useRouter() const router = useRouter()
const config = useConfig() const config = useConfig()
const { t } = useI18n() const { t } = useI18n()
//
const viewModel = reactive({
base: 'show',
server: 'show',
})
function toShow(model) {
console.log("toShow:" + model)
viewModel[model] = 'show'
}
function toEdit(model) {
console.log("toEdit:" + model)
viewModel[model] = 'edit'
}
const baseShow = computed(() => {
return viewModel.base == 'show'
})
const baseEdit = computed(() => {
return viewModel.base == 'edit'
})
const baseNoData = computed(() => {
return baseShow && serverConfig.model == null
})
const serverShow = computed(() => {
return viewModel.server == 'show'
})
const serverEdit = computed(() => {
return viewModel.server == 'edit'
})
const readConfigSuccess = ref(false)
const serverNoData = computed(() => {
return serverShow && !readConfigSuccess.value
})
const serverConfig = reactive({
host: null,
port: null,
})
const serverConfigUpd = reactive({
host: null,
port: null,
})
function clearCache() { function clearCache() {
config.$reset() config.$reset()
utils.pop(t('clearCacheSuccess')) utils.pop(t('clearCacheSuccess'))
} }
onMounted(() => {
// config/config.toml
files.readAll("@/../../config/config.toml").then((fileContent) => {
console.log("config/config.toml: ", fileContent)
if (utils.notBlank(fileContent)) {
readConfigSuccess.value = true
} else {
utils.pop(t('readConfigFailed'))
return
}
const lines = utils.stringToLines(fileContent)
// [server]
const serverStart = lines.findIndex((line) => {
return line.includes("[server]")
})
for (let i = serverStart + 1; i < lines.length; i++) {
console.log("line: ", lines[i])
//
if (lines[i].startsWith("[")) {
break
}
//
const line = lines[i]
const lineArr = line.split("=")
if (lineArr.length != 2) {
continue
}
const key = lineArr[0].trim()
const value = lineArr[1].trim()
serverConfig[key] = value
}
console.log("serverConfig read from file: ", serverConfig)
utils.copyProps(serverConfig, serverConfigUpd)
})
})
const submitForm = async () => {
try {
await ruleFormRef.value.validate();
if (!utils.hasDfProps(serverConfig, serverConfigUpd)) {
ElMessage.success('未发生更改!');
toShow('server')
return
}
ElMessage.success('验证通过,提交表单');
// update()
} catch (error) {
ElMessage.error('参数验证失败');
}
}
const rules = reactive({
host: [{ validator: verify.validator('notBlank'), trigger: 'blur' }],
port: [{ validator: verify.validator('notBlank'), trigger: 'blur' }],
api_key: [{ validator: verify.validator('notBlank'), trigger: 'blur' }],
max_tokens: [{ validator: verify.validator('notBlank'), trigger: 'blur' }],
temperature: [{ validator: verify.validator('notBlank'), trigger: 'blur' }],
})
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -15,10 +15,10 @@
</div> </div>
</template> </template>
<!-- 展示模块-无数据 --> <!-- No Data -->
<div class="no-data" v-show="baseNoData">{{ t('noData') }}</div> <div class="no-data" v-show="baseNoData">{{ t('noData') }}</div>
<!-- 展示模块-有数据 --> <!-- Show Data -->
<div class="card-row-wrap" v-show="baseShow"> <div class="card-row-wrap" v-show="baseShow">
<div class="card-row-item"> <div class="card-row-item">
<el-text>model:</el-text> <el-text>model:</el-text>
@ -46,7 +46,7 @@
</div> </div>
</div> </div>
<!-- 编辑模块 --> <!-- Edit Module -->
<el-form ref="ruleFormRef" :model="llmConfigUpd" status-icon :rules="rules" v-show="baseEdit"> <el-form ref="ruleFormRef" :model="llmConfigUpd" status-icon :rules="rules" v-show="baseEdit">
<div class="card-row-wrap"> <div class="card-row-wrap">
<div class="card-row-item"> <div class="card-row-item">
@ -124,15 +124,17 @@ function toEdit(model) {
} }
const baseShow = computed(() => { const baseShow = computed(() => {
return viewModel.base == 'show' || viewModel.base == 'showMore' return viewModel.base == 'show'
}) })
const baseEdit = computed(() => { const baseEdit = computed(() => {
return viewModel.base == 'edit' return viewModel.base == 'edit'
}) })
const readConfigSuccess = ref(false)
const baseNoData = computed(() => { const baseNoData = computed(() => {
return baseShow && llmConfig.model == null return baseShow && !readConfigSuccess.value
}) })
const llmConfig = reactive({ const llmConfig = reactive({
@ -153,12 +155,19 @@ const llmConfigUpd = reactive({
function clearCache() { function clearCache() {
config.$reset() config.$reset()
utils.pop(t('clearCacheSuccess'))
} }
onMounted(() => { onMounted(() => {
// config/config.toml // config/config.toml
files.readAll("@/../../config/config.toml").then((fileContent) => { files.readAll("@/../../config/config.toml").then((fileContent) => {
console.log("config/config.toml: ", fileContent) console.log("config/config.toml: ", fileContent)
if (utils.notBlank(fileContent)) {
readConfigSuccess.value = true
} else {
utils.pop(t('readConfigFailed'))
return
}
const lines = utils.stringToLines(fileContent) const lines = utils.stringToLines(fileContent)
// [llm] // [llm]
@ -190,7 +199,7 @@ onMounted(() => {
const submitForm = async () => { const submitForm = async () => {
try { try {
await ruleFormRef.value.validate(); await ruleFormRef.value.validate();
if (!utils.hasDfProps(designSchemeDtl, designSchemeUpd)) { if (!utils.hasDfProps(llmConfig, llmConfigUpd)) {
ElMessage.success('未发生更改!'); ElMessage.success('未发生更改!');
toShow('base') toShow('base')
return return

View File

@ -81,7 +81,7 @@ const viewModel = reactive({
}) })
const baseShow = computed(() => { const baseShow = computed(() => {
return viewModel.base == 'show' || viewModel.base == 'showMore' return viewModel.base == 'show'
}) })
const baseNoData = computed(() => { const baseNoData = computed(() => {