Merge pull request #12968 from dataease/pr@dev-v2_st

feat: 国家化
This commit is contained in:
dataeaseShu 2024-10-29 14:48:04 +08:00 committed by GitHub
commit 3e5845c2b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
14 changed files with 265 additions and 105 deletions

View File

@ -36,6 +36,77 @@ export default {
delete_success: 'Delete success', delete_success: 'Delete success',
no_auth_tips: 'Missing menu permissions, please contact the administrator' no_auth_tips: 'Missing menu permissions, please contact the administrator'
}, },
date: {
permanent: 'Permanent',
one_year: 'One year',
six_months: 'Six months',
three_months: 'Three months',
of_range_1_59: 'Minutes out of range [1-59]',
of_range_1_23: 'Hours out of range [1-23]'
},
system: {
click_to_show: 'Click to show',
click_to_hide: 'Click to hide',
basic_settings: 'Basic settings',
and_0_seconds: '0 minutes and 0 seconds',
time_0_seconds: 'Minutes (execution time: 0 seconds)',
and_0_seconds_de: 'Hours (execution time: 0 minutes and 0 seconds)',
fonts_before_deleting: 'Please set other fonts as default fonts before deleting.',
sure_to_delete:
'After the current font is deleted, the components using the font will use the default font. Are you sure to delete?',
setting_successful: 'Setting successful',
font_management: 'Font management',
search_font_name: 'Search font name',
a_new_font: 'Create a new font',
add_font: 'Add font',
default_font: 'Default font',
system_built_in: 'System built-in',
update_time: 'Update time:',
font_file: 'Font file:',
upload_font_file: 'Upload font file',
replace_font_file: 'Replace font file',
as_default_font: 'Set as default font',
the_font_name: 'Please enter the font name',
in_ttf_format: 'Only supports uploading font files in ttf format!',
character_length_1_50: 'Character length 1-50',
upload_font_file_de: 'Please upload font file',
font_name: 'Font name',
font_file_de: 'Font file',
be_the_same: 'New and old passwords cannot be the same',
twice_are_inconsistent: 'The passwords entered twice are inconsistent',
log_in_again: 'Change successfully, please log in again',
original_password: 'Original password',
the_original_password: 'Please enter the original password',
new_password: 'New password',
the_new_password: 'Please enter the new password',
confirm_password: 'Confirm password',
the_confirmation_password: 'Please enter the confirmation password',
map_settings: 'Map settings',
engine_settings: 'Engine settings',
normal_login: 'Normal login',
to_take_effect:
'Request timeout (unit: seconds, note: save and refresh the browser to take effect)',
and_platform_docking: 'Scope includes authentication settings and platform docking',
not_enabled: 'Not enabled',
default_organization: 'Default organization',
normal_role: 'Normal role',
engine_type: 'Engine type',
on_the_left: 'Please select a region on the left',
region_code: 'Region code',
superior_region: 'Superior region',
coordinate_file: 'Coordinate file',
delete_this_node: 'Are you sure you want to delete this node?',
at_the_end:
'Country code consists of three digits, province, city, district, county, and township codes consist of two digits; non-national regions need to add 0 at the end',
non_zero_three_digit_number: 'Please enter a non-zero three-digit number',
or_11_digits: 'Please enter 9 or 11 digits',
contact_the_administrator: 'If execution fails, please contact the administrator',
upload_json_files: 'Can only upload json files',
maximum_upload_200m: 'Maximum upload 200M',
geographic_information: 'Geographic information',
superior_region_first: 'Please select the superior region first',
region_name: 'Region name'
},
components: { components: {
dashboard_style: 'Dashboard style', dashboard_style: 'Dashboard style',
overall_configuration: 'Overall configuration', overall_configuration: 'Overall configuration',

View File

@ -391,7 +391,66 @@ export default {
system: { system: {
user: '用户', user: '用户',
role: '角色', role: '角色',
addUser: '@:common.add@:system.user' addUser: '@:common.add@:system.user',
click_to_show: '点击显示',
click_to_hide: '点击隐藏',
basic_settings: '基础设置',
and_0_seconds: '0分0秒',
time_0_seconds: '分钟执行时间0秒',
and_0_seconds_de: '小时执行时间0分0秒',
fonts_before_deleting: '请先将其他字体设置为默认字体再进行删除',
sure_to_delete: '当前字体被删除后使用该字体的组件将会使用默认字体确定删除?',
setting_successful: '设置成功',
font_management: '字体管理',
search_font_name: '搜索字体名称',
a_new_font: '新建字体',
add_font: '添加字体',
default_font: '默认字体',
system_built_in: '系统内置',
update_time: '更新时间',
font_file: '字库文件',
upload_font_file: '上传字库文件',
replace_font_file: '替换字库文件',
as_default_font: '设为默认字体',
the_font_name: '请输入字体名称',
in_ttf_format: '只支持上传ttf格式的字体文件!',
character_length_1_50: '字符长度1-50',
upload_font_file_de: '请上传字库文件',
font_name: '字体名称',
font_file_de: '字库文件',
be_the_same: '新旧密码不能相同',
twice_are_inconsistent: '两次输入的密码不一致',
log_in_again: '修改成功请重新登录',
original_password: '原始密码',
the_original_password: '请输入原始密码',
new_password: '新密码',
the_new_password: '请输入新密码',
confirm_password: '确认密码',
the_confirmation_password: '请输入确认密码',
map_settings: '地图设置',
engine_settings: '引擎设置',
normal_login: '普通登录',
to_take_effect: '请求超时时间(单位注意保存后刷新浏览器生效)',
and_platform_docking: '作用域包括认证设置和平台对接',
not_enabled: '未开启',
default_organization: '默认组织',
normal_role: '普通角色',
engine_type: '引擎类型',
on_the_left: '请在左侧选择区域',
region_code: '区域代码',
superior_region: '上级区域',
coordinate_file: '坐标文件',
delete_this_node: '确定删除此节点吗',
at_the_end:
'国家代码由三位数字组成区县乡镇代码由两位数字组成非国家区域需要再后面补0',
non_zero_three_digit_number: '请输入非0的三位数字',
or_11_digits: '请输入9或11位数字',
contact_the_administrator: '执行失败请联系管理员',
upload_json_files: '只能上传json文件',
maximum_upload_200m: '最大上传200M',
geographic_information: '地理信息',
superior_region_first: '请先选择上级区域',
region_name: '区域名称'
}, },
components: { components: {
dashboard_style: '仪表板风格', dashboard_style: '仪表板风格',
@ -2184,7 +2243,13 @@ export default {
data_time_error: '开始日期不能大于结束日期', data_time_error: '开始日期不能大于结束日期',
one_day: '一天', one_day: '一天',
one_week: '一周', one_week: '一周',
one_month: '一个月' one_month: '一个月',
permanent: '永久',
one_year: '一年',
six_months: '半年',
three_months: '三个月',
of_range_1_59: '分钟超出范围1-59',
of_range_1_23: '小时超出范围1-23'
}, },
adv_search: { adv_search: {
title: '高级搜索', title: '高级搜索',

View File

@ -48,7 +48,9 @@
<el-tooltip <el-tooltip
effect="dark" effect="dark"
:content="pwdItem[item.pkey]['hidden'] ? '点击显示' : '点击隐藏'" :content="
pwdItem[item.pkey]['hidden'] ? t('system.click_to_show') : t('system.click_to_hide')
"
placement="top" placement="top"
> >
<el-button text @click="switchPwd(item.pkey)" class="setting-tip-btn"> <el-button text @click="switchPwd(item.pkey)" class="setting-tip-btn">
@ -64,7 +66,7 @@
</el-tooltip> </el-tooltip>
</div> </div>
<span v-else-if="item.pkey.includes('basic.dsIntervalTime')"> <span v-else-if="item.pkey.includes('basic.dsIntervalTime')">
<span>{{ item.pval + ' ' + executeTime + '执行一次' }}</span> <span>{{ item.pval + ' ' + executeTime + t('common.every_exec') }}</span>
</span> </span>
<span v-else> <span v-else>
<span>{{ item.pval }}</span> <span>{{ item.pval }}</span>
@ -113,7 +115,7 @@ const props = defineProps({
}, },
settingTitle: { settingTitle: {
type: String, type: String,
default: '基础设置' default: t('system.basic_settings')
}, },
hideHead: { hideHead: {
type: Boolean, type: Boolean,
@ -132,7 +134,7 @@ const props = defineProps({
default: () => [] default: () => []
} }
}) })
const executeTime = ref('0分0秒') const executeTime = ref(t('system.and_0_seconds'))
const curTitle = computed(() => { const curTitle = computed(() => {
return props.settingTitle return props.settingTitle
}) })
@ -159,8 +161,8 @@ const loadList = () => {
const getExecuteTime = val => { const getExecuteTime = val => {
const options = [ const options = [
{ value: 'minute', label: '分钟执行时间0秒' }, { value: 'minute', label: t('system.time_0_seconds') },
{ value: 'hour', label: '小时执行时间0分0秒' } { value: 'hour', label: t('system.and_0_seconds_de') }
] ]
return options.filter(item => item.value === val)[0].label return options.filter(item => item.value === val)[0].label
} }

View File

@ -2,15 +2,18 @@
import icon_upload_outlined from '@/assets/svg/icon_upload_outlined.svg' import icon_upload_outlined from '@/assets/svg/icon_upload_outlined.svg'
import { ref, reactive } from 'vue' import { ref, reactive } from 'vue'
import { uploadFontFile } from '@/api/font' import { uploadFontFile } from '@/api/font'
import { useI18n } from '@/hooks/web/useI18n'
import FontInfo from './FontInfo.vue' import FontInfo from './FontInfo.vue'
import { ElMessage } from 'element-plus-secondary' import { ElMessage } from 'element-plus-secondary'
import { edit } from '@/api/font' import { edit } from '@/api/font'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
const state = reactive({ const state = reactive({
fileList: null fileList: null
}) })
const loading = ref(false) const loading = ref(false)
const upload = ref() const upload = ref()
const { t } = useI18n()
const uploadExcel = () => { const uploadExcel = () => {
const formData = new FormData() const formData = new FormData()
formData.append('file', state.fileList.raw) formData.append('file', state.fileList.raw)
@ -53,7 +56,7 @@ const defaultForm = {
const ruleForm = reactive(cloneDeep(defaultForm)) const ruleForm = reactive(cloneDeep(defaultForm))
const init = (val, type, item) => { const init = (val, type, item) => {
dialogTitle.value = val || '添加字体' dialogTitle.value = val || t('system.add_font')
action.value = type action.value = type
dialogVisible.value = true dialogVisible.value = true
Object.assign(ruleForm, cloneDeep(defaultForm)) Object.assign(ruleForm, cloneDeep(defaultForm))
@ -67,8 +70,8 @@ const fontDel = () => {
const ruleFormRef = ref() const ruleFormRef = ref()
const rules = { const rules = {
name: [ name: [
{ required: true, message: '请输入字体名称', trigger: 'blur' }, { required: true, message: t('system.the_font_name'), trigger: 'blur' },
{ min: 1, max: 50, message: '字符长度1-50', trigger: 'blur' } { min: 1, max: 50, message: t('system.character_length_1_50'), trigger: 'blur' }
] ]
} }
defineExpose({ defineExpose({
@ -77,7 +80,7 @@ defineExpose({
const beforeAvatarUpload = rawFile => { const beforeAvatarUpload = rawFile => {
if (!rawFile.name.endsWith('.ttf')) { if (!rawFile.name.endsWith('.ttf')) {
ElMessage.error('只支持上传ttf格式的字体文件!') ElMessage.error(t('system.in_ttf_format'))
return false return false
} }
return true return true
@ -105,12 +108,12 @@ const confirm = () => {
if (val) { if (val) {
if (action.value === 'uploadFile') { if (action.value === 'uploadFile') {
if (ruleForm.fileTransName === '') { if (ruleForm.fileTransName === '') {
ElMessage.error('请上传字库文件') ElMessage.error(t('system.upload_font_file_de'))
return return
} }
} }
edit(ruleForm).then(() => { edit(ruleForm).then(() => {
ElMessage.success(dialogTitle.value + '成功') ElMessage.success(dialogTitle.value + t('data_set.success'))
cancel() cancel()
emits('finish') emits('finish')
}) })
@ -136,10 +139,14 @@ const confirm = () => {
label-width="auto" label-width="auto"
class="demo-ruleForm" class="demo-ruleForm"
> >
<el-form-item v-if="action !== 'uploadFile'" label="字体名称" prop="name"> <el-form-item v-if="action !== 'uploadFile'" :label="t('system.font_name')" prop="name">
<el-input placeholder="请输入字体名称" v-model.trim="ruleForm.name" /> <el-input :placeholder="t('system.the_font_name')" v-model.trim="ruleForm.name" />
</el-form-item> </el-form-item>
<el-form-item v-loading="loading" v-if="action !== 'rename'" label="字库文件"> <el-form-item
v-loading="loading"
v-if="action !== 'rename'"
:label="t('system.font_file_de')"
>
<el-upload <el-upload
action="" action=""
:multiple="false" :multiple="false"
@ -158,7 +165,7 @@ const confirm = () => {
<template #icon> <template #icon>
<Icon name="icon_upload_outlined"><icon_upload_outlined class="svg-icon" /></Icon> <Icon name="icon_upload_outlined"><icon_upload_outlined class="svg-icon" /></Icon>
</template> </template>
上传字库文件 {{ t('system.upload_font_file') }}
</el-button> </el-button>
</template> </template>
</el-upload> </el-upload>
@ -182,15 +189,17 @@ const confirm = () => {
v-show="state.fileList" v-show="state.fileList"
> >
<template #trigger> <template #trigger>
<el-button text> 重新上传 </el-button> <el-button text> {{ t('data_source.reupload') }} </el-button>
</template> </template>
</el-upload> </el-upload>
</el-form-item> </el-form-item>
</el-form> </el-form>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">
<el-button @click="cancel">取消</el-button> <el-button @click="cancel">{{ t('userimport.cancel') }}</el-button>
<el-button v-loading="loading" type="primary" @click="confirm"> 确定 </el-button> <el-button v-loading="loading" type="primary" @click="confirm">
{{ t('userimport.sure') }}
</el-button>
</div> </div>
</template> </template>
</el-dialog> </el-dialog>

View File

@ -4,12 +4,13 @@ import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg'
import { onMounted, ref, computed } from 'vue' import { onMounted, ref, computed } from 'vue'
import UploadDetail from './UploadDetail.vue' import UploadDetail from './UploadDetail.vue'
import { useAppearanceStoreWithOut } from '@/store/modules/appearance' import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
import { useI18n } from '@/hooks/web/useI18n'
import { deleteById, edit, defaultFont } from '@/api/font' import { deleteById, edit, defaultFont } from '@/api/font'
import { ElMessage, ElMessageBox } from 'element-plus-secondary' import { ElMessage, ElMessageBox } from 'element-plus-secondary'
import { cloneDeep } from 'lodash-es' import { cloneDeep } from 'lodash-es'
const appearanceStore = useAppearanceStoreWithOut() const appearanceStore = useAppearanceStoreWithOut()
const { t } = useI18n()
const fontKeyword = ref('') const fontKeyword = ref('')
const fontList = ref([]) const fontList = ref([])
const basePath = import.meta.env.VITE_API_BASEPATH const basePath = import.meta.env.VITE_API_BASEPATH
@ -35,10 +36,10 @@ const fontListComputed = computed(() => {
const deleteFont = item => { const deleteFont = item => {
if (item.isDefault) { if (item.isDefault) {
ElMessage.warning('请先将其他字体设置为默认字体,再进行删除。') ElMessage.warning(t('system.fonts_before_deleting'))
return return
} }
ElMessageBox.confirm('当前字体被删除后,使用该字体的组件将会使用默认字体,确定删除?', { ElMessageBox.confirm(t('system.sure_to_delete'), {
confirmButtonType: 'danger', confirmButtonType: 'danger',
type: 'warning', type: 'warning',
autofocus: false, autofocus: false,
@ -47,7 +48,7 @@ const deleteFont = item => {
loading.value = true loading.value = true
deleteById(item.id) deleteById(item.id)
.then(() => { .then(() => {
ElMessage.success('删除成功') ElMessage.success(t('common.delete_success'))
listFont() listFont()
getDefaultFont() getDefaultFont()
}) })
@ -62,7 +63,7 @@ const setToDefault = item => {
loading.value = true loading.value = true
edit(item) edit(item)
.then(() => { .then(() => {
ElMessage.success('设置成功') ElMessage.success(t('system.setting_successful'))
getDefaultFont() getDefaultFont()
listFont() listFont()
}) })
@ -115,9 +116,14 @@ onMounted(() => {
<template> <template>
<div class="font-management_system" v-loading="loading"> <div class="font-management_system" v-loading="loading">
<div class="route-title"> <div class="route-title">
字体管理 {{ t('system.font_management') }}
<div class="search-font"> <div class="search-font">
<el-input v-model="fontKeyword" clearable style="width: 240px" placeholder="搜索字体名称"> <el-input
v-model="fontKeyword"
clearable
style="width: 240px"
:placeholder="t('system.search_font_name')"
>
<template #prefix> <template #prefix>
<el-icon> <el-icon>
<Icon name="icon_search-outline_outlined" <Icon name="icon_search-outline_outlined"
@ -127,42 +133,45 @@ onMounted(() => {
</template> </template>
</el-input> </el-input>
<el-button type="primary" @click="uploadFont('新建字体', 'create', {})"> <el-button type="primary" @click="uploadFont(t('system.a_new_font'), 'create', {})">
<template #icon> <template #icon>
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon> <Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
</template> </template>
添加字体 {{ t('system.add_font') }}
</el-button> </el-button>
</div> </div>
</div> </div>
<div class="font-content_overflow"> <div class="font-content_overflow">
<div class="font-content_list"> <div class="font-content_list">
<div class="font-content_item" v-for="ele in fontListComputed" :key="ele"> <div class="font-content_item" v-for="ele in fontListComputed" :key="ele">
<span v-if="ele.isDefault" class="font-default">默认字体</span> <span v-if="ele.isDefault" class="font-default">{{ t('system.default_font') }}</span>
<div class="font-name"> <div class="font-name">
{{ ele.name }} <span v-if="ele.isBuiltin" class="font-type"> 系统内置 </span> {{ ele.name }}
<span v-if="ele.isBuiltin" class="font-type"> {{ t('system.system_built_in') }} </span>
</div> </div>
<div :title="ele.fileName" class="font-update_time"> <div :title="ele.fileName" class="font-update_time">
更新时间 {{ new Date(ele.updateTime).toLocaleString() }} {{ t('system.update_time') }} {{ new Date(ele.updateTime).toLocaleString() }}
<span class="line"></span> 字库文件 {{ ele.fileName }} <span class="line"></span> {{ t('system.font_file') }} {{ ele.fileName }}
</div> </div>
<div class="font-upload_btn"> <div class="font-upload_btn">
<el-button <el-button
v-if="!ele.fileTransName" v-if="!ele.fileTransName"
@click="uploadFont('上传字库文件', 'uploadFile', ele)" @click="uploadFont(t('system.upload_font_file'), 'uploadFile', ele)"
secondary secondary
>上传字库文件</el-button >{{ t('system.upload_font_file') }}</el-button
> >
<el-button <el-button
v-if="ele.fileTransName" v-if="ele.fileTransName"
@click="uploadFont('替换字库文件', 'uploadFile', ele)" @click="uploadFont(t('system.replace_font_file'), 'uploadFile', ele)"
secondary secondary
>替换字库文件</el-button >{{ t('system.replace_font_file') }}</el-button
> >
<el-button v-if="!ele.isDefault" @click="setToDefault(ele)" secondary <el-button v-if="!ele.isDefault" @click="setToDefault(ele)" secondary>{{
>设为默认字体</el-button t('system.as_default_font')
> }}</el-button>
<el-button v-if="ele.id !== '1'" @click="deleteFont(ele)" secondary>删除</el-button> <el-button v-if="ele.id !== '1'" @click="deleteFont(ele)" secondary>{{
t('common.delete')
}}</el-button>
</div> </div>
</div> </div>
</div> </div>

View File

@ -19,7 +19,7 @@ const pwdForm = reactive(cloneDeep(defaultForm))
const validatePwd = (_: any, value: any, callback: any) => { const validatePwd = (_: any, value: any, callback: any) => {
if (value === pwdForm.pwd) { if (value === pwdForm.pwd) {
callback(new Error('新旧密码不能相同')) callback(new Error(t('system.be_the_same')))
} }
const pattern = const pattern =
/^.*(?=.{6,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/])[a-zA-Z0-9~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/]*$/ /^.*(?=.{6,20})(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/])[a-zA-Z0-9~!@#$%^&*()_+\-\={}|":<>?`[\];',.\/]*$/
@ -34,7 +34,7 @@ const validatePwd = (_: any, value: any, callback: any) => {
const validateConfirmPwd = (_: any, value: any, callback: any) => { const validateConfirmPwd = (_: any, value: any, callback: any) => {
if (value !== pwdForm.newPwd) { if (value !== pwdForm.newPwd) {
callback(new Error('两次输入的密码不一致')) callback(new Error(t('system.twice_are_inconsistent')))
} else { } else {
callback() callback()
} }
@ -85,7 +85,7 @@ const save = () => {
const pwd = rsaEncryp(pwdForm.pwd) const pwd = rsaEncryp(pwdForm.pwd)
const newPwd = rsaEncryp(pwdForm.newPwd) const newPwd = rsaEncryp(pwdForm.newPwd)
request.post({ url: '/user/modifyPwd', data: { pwd, newPwd } }).then(() => { request.post({ url: '/user/modifyPwd', data: { pwd, newPwd } }).then(() => {
ElMessage.success('修改成功,请重新登录') ElMessage.success(t('system.log_in_again'))
logoutHandler() logoutHandler()
}) })
} }
@ -103,28 +103,28 @@ const save = () => {
label-width="80px" label-width="80px"
label-position="top" label-position="top"
> >
<el-form-item label="原始密码" prop="pwd"> <el-form-item :label="t('system.original_password')" prop="pwd">
<CustomPassword <CustomPassword
v-model="pwdForm.pwd" v-model="pwdForm.pwd"
show-password show-password
type="password" type="password"
placeholder="请输入原始密码" :placeholder="t('system.the_original_password')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="新密码" prop="newPwd"> <el-form-item :label="t('system.new_password')" prop="newPwd">
<CustomPassword <CustomPassword
v-model="pwdForm.newPwd" v-model="pwdForm.newPwd"
show-password show-password
type="password" type="password"
placeholder="请输入新密码" :placeholder="t('system.the_new_password')"
/> />
</el-form-item> </el-form-item>
<el-form-item label="确认密码" prop="confirm"> <el-form-item :label="t('system.confirm_password')" prop="confirm">
<CustomPassword <CustomPassword
v-model="pwdForm.confirm" v-model="pwdForm.confirm"
show-password show-password
type="password" type="password"
placeholder="请输入确认密码" :placeholder="t('system.the_confirmation_password')"
/> />
</el-form-item> </el-form-item>
<el-button @click="save" type="primary"> <el-button @click="save" type="primary">

View File

@ -2,7 +2,7 @@
<div class="user-center flex-align-center"> <div class="user-center flex-align-center">
<div class="user-center-container"> <div class="user-center-container">
<div class="user-tabs"> <div class="user-tabs">
<div class="tabs-title flex-align-center">用户中心</div> <div class="tabs-title flex-align-center">{{ t('commons.user_center') }}</div>
<el-divider /> <el-divider />
<div class="list-item_primary active"> <div class="list-item_primary active">
{{ t('user.change_password') }} {{ t('user.change_password') }}

View File

@ -9,15 +9,15 @@ const dialogVisible = ref(false)
const loadingInstance = ref(null) const loadingInstance = ref(null)
const basicForm = ref<FormInstance>() const basicForm = ref<FormInstance>()
const options = [ const options = [
{ value: 'minute', label: '分钟执行时间0秒' }, { value: 'minute', label: t('system.time_0_seconds') },
{ value: 'hour', label: '小时执行时间0分0秒' } { value: 'hour', label: t('system.and_0_seconds_de') }
] ]
const pvpOptions = [ const pvpOptions = [
{ value: '0', label: '永久' }, { value: '0', label: t('date.permanent') },
{ value: '1', label: '一年' }, { value: '1', label: t('date.one_year') },
{ value: '2', label: '半年' }, { value: '2', label: t('date.six_months') },
{ value: '3', label: '三个月' }, { value: '3', label: t('date.three_months') },
{ value: '4', label: '一个月' } { value: '4', label: t('date.one_month') }
] ]
const state = reactive({ const state = reactive({
@ -30,7 +30,7 @@ const state = reactive({
orgOptions: [], orgOptions: [],
roleOptions: [], roleOptions: [],
loginOptions: [ loginOptions: [
{ value: '0', label: '普通登录' }, { value: '0', label: t('system.normal_login') },
{ value: '1', label: 'LDAP' }, { value: '1', label: 'LDAP' },
{ value: '2', label: 'OIDC' }, { value: '2', label: 'OIDC' },
{ value: '3', label: 'CAS' }, { value: '3', label: 'CAS' },
@ -69,14 +69,14 @@ const submitForm = async (formEl: FormInstance | undefined) => {
state.form.dsExecuteTime === 'minute' && state.form.dsExecuteTime === 'minute' &&
(Number(state.form.dsIntervalTime) < 1 || Number(state.form.dsIntervalTime) > 59) (Number(state.form.dsIntervalTime) < 1 || Number(state.form.dsIntervalTime) > 59)
) { ) {
ElMessage.error('分钟超出范围【1-59】') ElMessage.error(t('date.of_range_1_59'))
return return
} }
if ( if (
state.form.dsExecuteTime === 'hour' && state.form.dsExecuteTime === 'hour' &&
(Number(state.form.dsIntervalTime) < 1 || Number(state.form.dsIntervalTime) > 23) (Number(state.form.dsIntervalTime) < 1 || Number(state.form.dsIntervalTime) > 23)
) { ) {
ElMessage.error('小时超出范围【1-23】') ElMessage.error(t('date.of_range_1_23'))
return return
} }
const param = buildSettingList() const param = buildSettingList()
@ -210,7 +210,7 @@ defineExpose({
<template> <template>
<el-drawer <el-drawer
title="基础设置" :title="t('system.basic_settings')"
v-model="dialogVisible" v-model="dialogVisible"
custom-class="basic-param-drawer" custom-class="basic-param-drawer"
size="600px" size="600px"
@ -241,7 +241,7 @@ defineExpose({
v-model="state.form[item.pkey]" v-model="state.form[item.pkey]"
/> />
<div v-else-if="item.pkey === 'dsIntervalTime'" class="ds-task-form-inline"> <div v-else-if="item.pkey === 'dsIntervalTime'" class="ds-task-form-inline">
<span></span> <span>{{ t('cron.every') }}</span>
<el-input-number <el-input-number
v-model="state.form.dsIntervalTime" v-model="state.form.dsIntervalTime"
autocomplete="off" autocomplete="off"
@ -260,7 +260,7 @@ defineExpose({
:value="item.value" :value="item.value"
/> />
</el-select> </el-select>
<span class="ds-span">执行一次</span> <span class="ds-span">{{ t('cron.every_exec') }}</span>
</div> </div>
<div v-else-if="item.pkey === 'frontTimeOut'"> <div v-else-if="item.pkey === 'frontTimeOut'">
<el-input-number <el-input-number

View File

@ -3,7 +3,7 @@
ref="infoTemplate" ref="infoTemplate"
:label-tooltips="tooltips" :label-tooltips="tooltips"
setting-key="basic" setting-key="basic"
setting-title="基础设置" :setting-title="t('system.basic_settings')"
:setting-data="state.templateList" :setting-data="state.templateList"
@edit="edit" @edit="edit"
/> />
@ -24,24 +24,24 @@ const editor = ref()
const infoTemplate = ref() const infoTemplate = ref()
const showDefaultLogin = ref(false) const showDefaultLogin = ref(false)
const pvpOptions = [ const pvpOptions = [
{ value: '0', label: '永久' }, { value: '0', label: t('date.permanent') },
{ value: '1', label: '一年' }, { value: '1', label: t('date.one_year') },
{ value: '2', label: '半年' }, { value: '2', label: t('date.six_months') },
{ value: '3', label: '三个月' }, { value: '3', label: t('date.three_months') },
{ value: '4', label: '一个月' } { value: '4', label: t('date.one_month') }
] ]
const tooltips = [ const tooltips = [
{ {
key: 'setting_basic.frontTimeOut', key: 'setting_basic.frontTimeOut',
val: '请求超时时间(单位:秒,注意:保存后刷新浏览器生效)' val: t('system.to_take_effect')
}, },
{ {
key: 'setting_basic.platformOid', key: 'setting_basic.platformOid',
val: '作用域包括认证设置和平台对接' val: t('system.and_platform_docking')
}, },
{ {
key: 'setting_basic.platformRid', key: 'setting_basic.platformRid',
val: '作用域包括认证设置和平台对接' val: t('system.and_platform_docking')
} }
] ]
const state = reactive({ const state = reactive({
@ -62,7 +62,7 @@ const state = reactive({
} }
], ],
loginOptions: [ loginOptions: [
{ value: '0', label: '普通登录' }, { value: '0', label: t('system.normal_login') },
{ value: '1', label: 'LDAP' }, { value: '1', label: 'LDAP' },
{ value: '2', label: 'OIDC' }, { value: '2', label: 'OIDC' },
{ value: '3', label: 'CAS' }, { value: '3', label: 'CAS' },
@ -89,11 +89,11 @@ const search = cb => {
item.pkey === 'basic.dip' || item.pkey === 'basic.dip' ||
item.pkey === 'basic.pwdStrategy' item.pkey === 'basic.pwdStrategy'
) { ) {
item.pval = item.pval === 'true' ? '开启' : '未开启' item.pval = item.pval === 'true' ? t('.chart.open') : t('system.not_enabled')
} else if (item.pkey === 'basic.platformOid') { } else if (item.pkey === 'basic.platformOid') {
selectedOid.value = item.pval selectedOid.value = item.pval
await loadOrgOptions() await loadOrgOptions()
item.pval = selectedOName.value || '默认组织' item.pval = selectedOName.value || t('system.default_organization')
} else if (item.pkey === 'basic.platformRid') { } else if (item.pkey === 'basic.platformRid') {
const pval = item.pval const pval = item.pval
if (pval?.length) { if (pval?.length) {
@ -103,11 +103,11 @@ const search = cb => {
if (selectedRName.value.length) { if (selectedRName.value.length) {
item.pval = selectedRName.value.join(',') item.pval = selectedRName.value.join(',')
} else { } else {
item.pval = '普通角色' item.pval = t('system.normal_role')
} }
} else { } else {
selectedRid.value = [] selectedRid.value = []
item.pval = '普通角色' item.pval = t('system.normal_role')
} }
} else if (item.pkey === 'basic.pvp') { } else if (item.pkey === 'basic.pvp') {
selectedPvp.value = item.pval || '0' selectedPvp.value = item.pval || '0'

View File

@ -254,7 +254,7 @@ defineExpose({
<template> <template>
<el-drawer <el-drawer
title="引擎设置" :title="t('system.engine_settings')"
v-model="dialogVisible" v-model="dialogVisible"
custom-class="basic-param-drawer" custom-class="basic-param-drawer"
size="600px" size="600px"

View File

@ -4,7 +4,7 @@
setting-key="basic" setting-key="basic"
showValidate showValidate
style="padding-bottom: 0" style="padding-bottom: 0"
setting-title="引擎设置" :setting-title="t('system.engine_settings')"
:setting-data="templateList" :setting-data="templateList"
@edit="edit" @edit="edit"
@check="validateById" @check="validateById"
@ -91,7 +91,7 @@ const getEngine = () => {
templateList.value = [ templateList.value = [
{ {
pkey: '引擎类型', pkey: t('system.engine_type'),
pval: typeMap[type], pval: typeMap[type],
type: '', type: '',
sort: 0 sort: 0

View File

@ -28,9 +28,9 @@ import { XpackComponent } from '@/components/plugin'
const { t } = useI18n() const { t } = useI18n()
const tabArray = ref([ const tabArray = ref([
{ label: '基础设置', name: 'basic' }, { label: t('system.basic_settings'), name: 'basic' },
{ label: '地图设置', name: 'map' }, { label: t('system.map_settings'), name: 'map' },
{ label: '引擎设置', name: 'engine' } { label: t('system.engine_settings'), name: 'engine' }
]) ])
const activeName = ref('basic') const activeName = ref('basic')

View File

@ -69,7 +69,7 @@
</el-aside> </el-aside>
<el-main class="geometry-main"> <el-main class="geometry-main">
<div class="geo-content-container" v-if="!selectedData"> <div class="geo-content-container" v-if="!selectedData">
<EmptyBackground img-type="noneWhite" description="请在左侧选择区域" /> <EmptyBackground img-type="noneWhite" :description="t('system.on_the_left')" />
</div> </div>
<div v-else class="geo-content-container"> <div v-else class="geo-content-container">
<div class="geo-content-top"> <div class="geo-content-top">
@ -77,13 +77,17 @@
</div> </div>
<div class="geo-content-middle"> <div class="geo-content-middle">
<div class="geo-area"> <div class="geo-area">
<div class="area-label"><span>区域代码</span></div> <div class="area-label">
<span>{{ t('system.region_code') }}</span>
</div>
<div class="area-content"> <div class="area-content">
<span>{{ selectedData.id }}</span> <span>{{ selectedData.id }}</span>
</div> </div>
</div> </div>
<div class="geo-area"> <div class="geo-area">
<div class="area-label"><span>上级区域</span></div> <div class="area-label">
<span>{{ t('system.superior_region') }}</span>
</div>
<div class="area-content"> <div class="area-content">
<span>{{ selectedData.parentName || '-' }}</span> <span>{{ selectedData.parentName || '-' }}</span>
<span v-if="selectedData.pid" class="area-secondary">{{ <span v-if="selectedData.pid" class="area-secondary">{{
@ -93,7 +97,9 @@
</div> </div>
</div> </div>
<div class="geo-content-bottom"> <div class="geo-content-bottom">
<div class="area-label"><span>坐标文件</span></div> <div class="area-label">
<span>{{ t('system.coordinate_file') }}</span>
</div>
<el-scrollbar class="area-content-geo"> <el-scrollbar class="area-content-geo">
<span>{{ selectedData.geoJson }}</span> <span>{{ selectedData.geoJson }}</span>
</el-scrollbar> </el-scrollbar>
@ -145,7 +151,7 @@ const handleNodeClick = async (data: Tree) => {
} }
} }
const delHandler = data => { const delHandler = data => {
ElMessageBox.confirm('确定删除此节点吗', { ElMessageBox.confirm(t('system.delete_this_node'), {
confirmButtonType: 'danger', confirmButtonType: 'danger',
type: 'warning', type: 'warning',
confirmButtonText: t('common.delete'), confirmButtonText: t('common.delete'),

View File

@ -39,9 +39,7 @@ const formatPid = computed(() => {
const pid = state.form.pid const pid = state.form.pid
return pid.replace(/(0+)$/g, '').replace(/\D/g, '') return pid.replace(/(0+)$/g, '').replace(/\D/g, '')
}) })
const codeTips = ref( const codeTips = ref(t('system.at_the_end'))
'国家代码由三位数字组成省、市、区县、乡镇代码由两位数字组成非国家区域需要再后面补0'
)
const pidChange = () => { const pidChange = () => {
state.form.code = null state.form.code = null
} }
@ -50,7 +48,7 @@ const validateCode = (_: any, value: any, callback: any) => {
if (isCountry) { if (isCountry) {
const reg = /^[0-9]\d{2}$/ const reg = /^[0-9]\d{2}$/
if (!reg.test(value) || value === '000') { if (!reg.test(value) || value === '000') {
const msg = '请输入非0的三位数字' const msg = t('system.non_zero_three_digit_number')
callback(new Error(msg)) callback(new Error(msg))
} else { } else {
callback() callback()
@ -59,7 +57,7 @@ const validateCode = (_: any, value: any, callback: any) => {
const fullValue = formatPid.value + value const fullValue = formatPid.value + value
const reg = /^[1-9](\d{8}|\d{10})$/ const reg = /^[1-9](\d{8}|\d{10})$/
if (!reg.test(fullValue)) { if (!reg.test(fullValue)) {
const msg = '请输入9或11位数字' const msg = t('system.or_11_digits')
callback(new Error(msg)) callback(new Error(msg))
} else { } else {
callback() callback()
@ -157,7 +155,7 @@ const handleExceed: UploadProps['onExceed'] = () => {
ElMessage.warning(t('userimport.exceedMsg')) ElMessage.warning(t('userimport.exceedMsg'))
} }
const handleError = () => { const handleError = () => {
ElMessage.warning('执行失败请联系管理员') ElMessage.warning(t('system.contact_the_administrator'))
} }
const setFile = (options: UploadRequestOptions) => { const setFile = (options: UploadRequestOptions) => {
geoFile.value = options.file geoFile.value = options.file
@ -166,12 +164,12 @@ const setFile = (options: UploadRequestOptions) => {
const uploadValidate = file => { const uploadValidate = file => {
const suffix = file.name.substring(file.name.lastIndexOf('.') + 1) const suffix = file.name.substring(file.name.lastIndexOf('.') + 1)
if (suffix !== 'json') { if (suffix !== 'json') {
ElMessage.warning('只能上传json文件') ElMessage.warning(t('system.upload_json_files'))
return false return false
} }
if (file.size / 1024 / 1024 > 200) { if (file.size / 1024 / 1024 > 200) {
ElMessage.warning('最大上传200M') ElMessage.warning(t('system.maximum_upload_200m'))
return false return false
} }
return true return true
@ -191,7 +189,7 @@ defineExpose({
<template> <template>
<el-drawer <el-drawer
title="地理信息" :title="t('system.geographic_information')"
v-model="dialogVisible" v-model="dialogVisible"
custom-class="basic-info-drawer" custom-class="basic-info-drawer"
size="600px" size="600px"
@ -205,7 +203,7 @@ defineExpose({
label-width="80px" label-width="80px"
label-position="top" label-position="top"
> >
<el-form-item label="上级区域" prop="pid"> <el-form-item :label="t('system.superior_region')" prop="pid">
<el-tree-select <el-tree-select
class="map-tree-selector" class="map-tree-selector"
node-key="id" node-key="id"
@ -219,10 +217,10 @@ defineExpose({
/> />
</el-form-item> </el-form-item>
<el-form-item label="区域代码" prop="code"> <el-form-item :label="t('system.region_code')" prop="code">
<template v-slot:label> <template v-slot:label>
<span class="area-code-label"> <span class="area-code-label">
<span>区域代码</span> <span>{{ t('system.region_code') }}</span>
<el-tooltip effect="dark" :content="codeTips" placement="top"> <el-tooltip effect="dark" :content="codeTips" placement="top">
<el-icon class="info-tips" <el-icon class="info-tips"
><Icon name="dv-info"><dvInfo class="svg-icon" /></Icon ><Icon name="dv-info"><dvInfo class="svg-icon" /></Icon
@ -240,19 +238,19 @@ defineExpose({
v-else v-else
class="box-item" class="box-item"
effect="dark" effect="dark"
content="请先选择上级区域" :content="t('system.superior_region_first')"
placement="top" placement="top"
> >
<el-input v-model="state.form.code" disabled /> <el-input v-model="state.form.code" disabled />
</el-tooltip> </el-tooltip>
</el-form-item> </el-form-item>
<el-form-item label="区域名称" prop="name"> <el-form-item :label="t('system.region_name')" prop="name">
<el-input v-model="state.form.name" /> <el-input v-model="state.form.name" />
</el-form-item> </el-form-item>
<div class="geo-label-mask" /> <div class="geo-label-mask" />
<el-form-item label="坐标文件" prop="fileName"> <el-form-item :label="t('system.coordinate_file')" prop="fileName">
<el-upload <el-upload
class="upload-geo" class="upload-geo"
action="" action=""