feat: 国际化

This commit is contained in:
ulleo 2024-10-31 16:34:52 +08:00
parent 0bf5f1ee94
commit 63fa79a665
32 changed files with 224 additions and 103 deletions

View File

@ -11,6 +11,7 @@ import io.dataease.api.template.vo.MarketLatestReleaseVO;
import io.dataease.api.template.vo.MarketMetaDataVO; import io.dataease.api.template.vo.MarketMetaDataVO;
import io.dataease.constant.CommonConstants; import io.dataease.constant.CommonConstants;
import io.dataease.exception.DEException; import io.dataease.exception.DEException;
import io.dataease.i18n.Translator;
import io.dataease.operation.manage.CoreOptRecentManage; import io.dataease.operation.manage.CoreOptRecentManage;
import io.dataease.system.manage.SysParameterManage; import io.dataease.system.manage.SysParameterManage;
import io.dataease.template.dao.auto.entity.VisualizationTemplateCategoryMap; import io.dataease.template.dao.auto.entity.VisualizationTemplateCategoryMap;
@ -166,11 +167,11 @@ public class TemplateCenterManage {
public MarketPreviewBaseResponse searchTemplatePreview() { public MarketPreviewBaseResponse searchTemplatePreview() {
try { try {
MarketBaseResponse baseContentRsp = searchTemplate(); MarketBaseResponse baseContentRsp = searchTemplate();
List<MarketMetaDataVO> categories = baseContentRsp.getCategories().stream().filter(category -> !"最近使用".equals(category.getLabel())).collect(Collectors.toList()); List<MarketMetaDataVO> categories = baseContentRsp.getCategories().stream().filter(category -> !Translator.get("i18n_template_recent").equals(category.getLabel())).toList();
List<TemplateMarketDTO> contents = baseContentRsp.getContents(); List<TemplateMarketDTO> contents = baseContentRsp.getContents();
List<TemplateMarketPreviewInfoDTO> previewContents = new ArrayList<>(); List<TemplateMarketPreviewInfoDTO> previewContents = new ArrayList<>();
categories.forEach(category -> { categories.forEach(category -> {
if ("推荐".equals(category.getLabel())) { if (Translator.get("i18n_template_recommend").equals(category.getLabel())) {
previewContents.add(new TemplateMarketPreviewInfoDTO(category, contents.stream().filter(template -> "Y".equals(template.getSuggest())).collect(Collectors.toList()))); previewContents.add(new TemplateMarketPreviewInfoDTO(category, contents.stream().filter(template -> "Y".equals(template.getSuggest())).collect(Collectors.toList())));
} else { } else {
previewContents.add(new TemplateMarketPreviewInfoDTO(category, contents.stream().filter(template -> checkCategoryMatch(template, category.getLabel())).collect(Collectors.toList()))); previewContents.add(new TemplateMarketPreviewInfoDTO(category, contents.stream().filter(template -> checkCategoryMatch(template, category.getLabel())).collect(Collectors.toList())));
@ -235,7 +236,7 @@ public class TemplateCenterManage {
List<MarketMetaDataVO> categoryVO = getCategoriesObject().stream().filter(node -> !"全部".equalsIgnoreCase(node.getLabel())).collect(Collectors.toList()); List<MarketMetaDataVO> categoryVO = getCategoriesObject().stream().filter(node -> !"全部".equalsIgnoreCase(node.getLabel())).collect(Collectors.toList());
Map<String, String> categoriesMap = categoryVO.stream() Map<String, String> categoriesMap = categoryVO.stream()
.collect(Collectors.toMap(MarketMetaDataVO::getValue, MarketMetaDataVO::getLabel)); .collect(Collectors.toMap(MarketMetaDataVO::getValue, MarketMetaDataVO::getLabel));
List<String> activeCategoriesName = new ArrayList<>(Arrays.asList("最近使用", "推荐")); List<String> activeCategoriesName = new ArrayList<>(Arrays.asList(Translator.get("i18n_template_recent"), Translator.get("i18n_template_recommend")));
contents.stream().forEach(templateMarketDTO -> { contents.stream().forEach(templateMarketDTO -> {
Long recentUseTime = useTime.get(templateMarketDTO.getId()); Long recentUseTime = useTime.get(templateMarketDTO.getId());
templateMarketDTO.setRecentUseTime(recentUseTime == null ? 0 : recentUseTime); templateMarketDTO.setRecentUseTime(recentUseTime == null ? 0 : recentUseTime);
@ -264,7 +265,7 @@ public class TemplateCenterManage {
public List<MarketMetaDataVO> getCategoriesObject() { public List<MarketMetaDataVO> getCategoriesObject() {
List<MarketMetaDataVO> result = getCategoriesV2(); List<MarketMetaDataVO> result = getCategoriesV2();
result.add(0, new MarketMetaDataVO("recent", "最近使用", CommonConstants.TEMPLATE_SOURCE.PUBLIC)); result.add(0, new MarketMetaDataVO("recent", Translator.get("i18n_template_recent"), CommonConstants.TEMPLATE_SOURCE.PUBLIC));
return result; return result;
} }
@ -285,7 +286,7 @@ public class TemplateCenterManage {
String resultStr = marketGet(templateParams.get("template.url") + TEMPLATE_META_DATA_URL, null); String resultStr = marketGet(templateParams.get("template.url") + TEMPLATE_META_DATA_URL, null);
MarketMetaDataBaseResponse metaData = JsonUtil.parseObject(resultStr, MarketMetaDataBaseResponse.class); MarketMetaDataBaseResponse metaData = JsonUtil.parseObject(resultStr, MarketMetaDataBaseResponse.class);
allCategories.addAll(metaData.getLabels()); allCategories.addAll(metaData.getLabels());
allCategories.add(0, new MarketMetaDataVO("suggest", "推荐", CommonConstants.TEMPLATE_SOURCE.PUBLIC)); allCategories.add(0, new MarketMetaDataVO("suggest", Translator.get("i18n_template_recommend"), CommonConstants.TEMPLATE_SOURCE.PUBLIC));
} catch (Exception e) { } catch (Exception e) {
LogUtil.error("模板市场分类获取错误", e); LogUtil.error("模板市场分类获取错误", e);
} }

View File

@ -104,3 +104,10 @@ i18n_df_multiple_value_split=use ';' to split multiple value
i18n_df_email_type=email type i18n_df_email_type=email type
i18n_df_phone_type=phone type i18n_df_phone_type=phone type
i18n_copilot_cross_ds_error=This feature is not supported for cross-source datasets.
i18n_template_recommend=Recommend
i18n_template_recent=Recently Used

View File

@ -126,3 +126,6 @@ i18n_df_phone_type=\u624B\u673A\u53F7\u683C\u5F0F
i18n_copilot_cross_ds_error=\u8DE8\u6E90\u6570\u636E\u96C6\u4E0D\u652F\u6301\u8BE5\u529F\u80FD i18n_copilot_cross_ds_error=\u8DE8\u6E90\u6570\u636E\u96C6\u4E0D\u652F\u6301\u8BE5\u529F\u80FD
i18n_template_recommend=\u63A8\u8350
i18n_template_recent=\u6700\u8FD1\u4F7F\u7528

View File

@ -124,3 +124,10 @@ i18n_df_email_type=\u90F5\u7BB1\u683C\u5F0F
i18n_df_phone_type=\u624B\u6A5F\u865F\u683C\u5F0F i18n_df_phone_type=\u624B\u6A5F\u865F\u683C\u5F0F
i18n_copilot_cross_ds_error=\u8DE8\u6E90\u6578\u64DA\u96C6\u4E0D\u652F\u6301\u8A72\u529F\u80FD
i18n_template_recommend=\u63A8\u85A6
i18n_template_recent=\u6700\u8FD1\u4F7F\u7528

View File

@ -395,7 +395,7 @@ const fullScreenPreview = () => {
编辑 编辑
</el-button> </el-button>
<el-button v-else class="preview-button" @click="fullScreenPreview" style="float: right"> <el-button v-else class="preview-button" @click="fullScreenPreview" style="float: right">
预览 {{ t('template_manage.preview') }}
</el-button> </el-button>
<el-button <el-button
@click="saveCanvasWithCheck()" @click="saveCanvasWithCheck()"

View File

@ -47,7 +47,8 @@ const dialogInfo = {
} }
const dialogInit = initInfo => { const dialogInit = initInfo => {
const canvasTypeName = initInfo.canvasType === 'dataV' ? '数据大屏' : '仪表板' const canvasTypeName =
initInfo.canvasType === 'dataV' ? t('work_branch.big_data_screen') : t('work_branch.dashboard')
dialogInfo.resourceId = initInfo.resourceId dialogInfo.resourceId = initInfo.resourceId
dialogInfo.title = '存在未保存的' + canvasTypeName dialogInfo.title = '存在未保存的' + canvasTypeName
dialogInfo.tips = canvasTypeName + '存在未保存的修改,立即恢复?' dialogInfo.tips = canvasTypeName + '存在未保存的修改,立即恢复?'

View File

@ -465,7 +465,9 @@ const { t } = useI18n()
const dialogShow = ref(false) const dialogShow = ref(false)
const snapshotStore = snapshotStoreWithOut() const snapshotStore = snapshotStoreWithOut()
const resourceType = computed(() => (dvInfo.value.type === 'dashboard' ? '仪表板' : '数据大屏')) const resourceType = computed(() =>
dvInfo.value.type === 'dashboard' ? t('work_branch.dashboard') : t('work_branch.big_data_screen')
)
const state = reactive({ const state = reactive({
loading: false, loading: false,

View File

@ -205,7 +205,7 @@
<div class="select-filed"> <div class="select-filed">
<el-select <el-select
v-model="itemLinkage.targetField" v-model="itemLinkage.targetField"
:placeholder="'请选择'" :placeholder="t('common.selectText')"
style="width: 100%" style="width: 100%"
> >
<el-option <el-option

View File

@ -166,7 +166,7 @@
filterable filterable
clearable clearable
style="width: 100%" style="width: 100%"
placeholder="请选择" :placeholder="t('common.selectText')"
> >
<template #header> <template #header>
<el-tabs <el-tabs

View File

@ -22,7 +22,9 @@ const { dvInfo, mobileInPc } = storeToRefs(dvMainStore)
const tips = const tips =
'从顶部工具栏中选择组件,添加到这里创建' + '从顶部工具栏中选择组件,添加到这里创建' +
(dvInfo.value.type === 'dashboard' ? '仪表板' : '数据大屏') (dvInfo.value.type === 'dashboard'
? t('work_branch.dashboard')
: t('work_branch.big_data_screen'))
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -620,7 +620,7 @@ const handleInputEnd = value => {
</template> </template>
</div> </div>
<div v-if="curComponent.defaultValueCheck" class="parameters" :class="dynamicTime && 'setting'"> <div v-if="curComponent.defaultValueCheck" class="parameters" :class="dynamicTime && 'setting'">
<div class="setting-label" v-if="dynamicTime">预览</div> <div class="setting-label" v-if="dynamicTime">{{ t('template_manage.preview') }}</div>
<div :class="dynamicTime ? 'setting-value' : 'w100'"> <div :class="dynamicTime ? 'setting-value' : 'w100'">
<component :config="curComponent" isConfig ref="inputCom" :is="filterTypeCom"></component> <component :config="curComponent" isConfig ref="inputCom" :is="filterTypeCom"></component>
</div> </div>

View File

@ -400,7 +400,7 @@ const relativeToCurrentListRange = computed(() => {
</template> </template>
</div> </div>
<div class="parameters" :class="dynamicTime && 'setting'"> <div class="parameters" :class="dynamicTime && 'setting'">
<div class="setting-label" v-if="dynamicTime">预览</div> <div class="setting-label" v-if="dynamicTime">{{ t('template_manage.preview') }}</div>
<div :class="dynamicTime ? 'setting-value' : 'w100'"> <div :class="dynamicTime ? 'setting-value' : 'w100'">
<component <component
:config="timeRange" :config="timeRange"

View File

@ -11,6 +11,7 @@ export default {
add_component_hint: 'Click or drag the component on the left to add a field' add_component_hint: 'Click or drag the component on the left to add a field'
}, },
inputText: 'Please input', inputText: 'Please input',
selectText: 'Please select',
account: 'Account', account: 'Account',
email: 'Email', email: 'Email',
phone: 'Phone', phone: 'Phone',
@ -99,7 +100,12 @@ export default {
delete_catalog_hint: 'Are You Sure You Want to Delete This Category?', delete_catalog_hint: 'Are You Sure You Want to Delete This Category?',
delete_catalog_tip: 'Deletion Is Irreversible. Do You Want to Continue?', delete_catalog_tip: 'Deletion Is Irreversible. Do You Want to Continue?',
illegal_name_hint: 'Illegal Name. Please Change!', illegal_name_hint: 'Illegal Name. Please Change!',
exists_name_hint: 'This Name Already Exists in Template Management. Please Modify' exists_name_hint: 'This Name Already Exists in Template Management. Please Modify',
get_download_link_hint:
'Please contact the official template marketplace if you have not obtained the template download link.',
search_result_count: 'The search results are {0} items.',
template_center: 'Template Center',
preview: 'Preview'
}, },
commons: { commons: {
date: { date: {
@ -384,6 +390,7 @@ export default {
last_edited_by: 'Last edited by', last_edited_by: 'Last edited by',
last_edit_time: 'last edit time', last_edit_time: 'last edit time',
big_data_screen: 'Big data screen', big_data_screen: 'Big data screen',
big_screen: 'Big screen',
dashboard: 'Dashboard', dashboard: 'Dashboard',
data_set: 'data set', data_set: 'data set',
data_source: 'data source', data_source: 'data source',
@ -411,7 +418,13 @@ export default {
password_null_hint: 'Password cannot be empty. Please re-enter!', password_null_hint: 'Password cannot be empty. Please re-enter!',
password_hint: password_hint:
'Password must be a 4-10 character string containing numbers, letters, and special characters [!@#$%^&*()_+]', 'Password must be a 4-10 character string containing numbers, letters, and special characters [!@#$%^&*()_+]',
max_ticket_count: 'Supports up to 5 Tickets creation' max_ticket_count: 'Supports up to 5 Tickets creation',
last: 'Previous',
next: 'Next',
recommend: 'Recommended',
recent: 'Recently Used',
all_types: 'All Types',
all_source: 'All Sources'
}, },
data_set: { data_set: {
ten_wan: '100000', ten_wan: '100000',

View File

@ -11,6 +11,7 @@ export default {
add_component_hint: '點擊或拖拽左側組件添加字段' add_component_hint: '點擊或拖拽左側組件添加字段'
}, },
inputText: '請輸入', inputText: '請輸入',
selectText: '請選擇',
add: '添加', add: '添加',
account: '賬號', account: '賬號',
email: '郵箱', email: '郵箱',
@ -122,7 +123,11 @@ export default {
delete_catalog_hint: '確定刪除該分類嗎', delete_catalog_hint: '確定刪除該分類嗎',
delete_catalog_tip: '刪除后不可恢復是否繼續', delete_catalog_tip: '刪除后不可恢復是否繼續',
illegal_name_hint: '不合法命名請更換', illegal_name_hint: '不合法命名請更換',
exists_name_hint: '當前名稱已在模版管理中存在請修改' exists_name_hint: '當前名稱已在模版管理中存在請修改',
get_download_link_hint: '未獲取模板下載鏈接請聯系模板市場官方',
search_result_count: '的搜索結果是 {0} ',
template_center: '模版中心',
preview: '預覽'
}, },
work_branch: { work_branch: {
back_to_work_branch: '返回工作台', back_to_work_branch: '返回工作台',
@ -137,6 +142,7 @@ export default {
last_edited_by: '最近編輯人', last_edited_by: '最近編輯人',
last_edit_time: '最近編輯時間', last_edit_time: '最近編輯時間',
big_data_screen: '數據大屏', big_data_screen: '數據大屏',
big_screen: '大屏',
dashboard: '儀表板', dashboard: '儀表板',
data_set: '數據集', data_set: '數據集',
data_source: '數據源', data_source: '數據源',
@ -161,7 +167,13 @@ export default {
error_link_hint: '鏈接格式錯誤請重新填寫', error_link_hint: '鏈接格式錯誤請重新填寫',
password_null_hint: '密碼不能為空請重新輸入', password_null_hint: '密碼不能為空請重新輸入',
password_hint: '密碼必須是包含數字字母特殊字符[!@#$%^&*()_+]的4-10位字符串', password_hint: '密碼必須是包含數字字母特殊字符[!@#$%^&*()_+]的4-10位字符串',
max_ticket_count: '最多支持創建5個Ticket' max_ticket_count: '最多支持創建5個Ticket',
last: '上一個',
next: '下一個',
recommend: '推薦',
recent: '最近使用',
all_types: '全部類型',
all_source: '全部來源'
}, },
data_set: { data_set: {
ten_wan: '10萬', ten_wan: '10萬',
@ -2603,6 +2615,8 @@ export default {
enter_name_tips: '請輸入儀表板名稱', enter_name_tips: '請輸入儀表板名稱',
name: '名稱', name: '名稱',
apply_template: '應用模板', apply_template: '應用模板',
style_template: '樣式模板',
all_type: '全部分類',
enter_template_name_tips: '搜索模板名稱', enter_template_name_tips: '搜索模板名稱',
pic_adaptation: '適應組件', pic_adaptation: '適應組件',
pic_equiratio: '等比適應', pic_equiratio: '等比適應',

View File

@ -11,6 +11,7 @@ export default {
add_component_hint: '点击或拖拽左侧组件添加字段' add_component_hint: '点击或拖拽左侧组件添加字段'
}, },
inputText: '请输入', inputText: '请输入',
selectText: '请选择',
add: '添加', add: '添加',
account: '账号', account: '账号',
email: '邮箱', email: '邮箱',
@ -122,7 +123,11 @@ export default {
delete_catalog_hint: '确定删除该分类吗', delete_catalog_hint: '确定删除该分类吗',
delete_catalog_tip: '删除后不可恢复是否继续', delete_catalog_tip: '删除后不可恢复是否继续',
illegal_name_hint: '不合法命名请更换', illegal_name_hint: '不合法命名请更换',
exists_name_hint: '当前名称已在模版管理中存在请修改' exists_name_hint: '当前名称已在模版管理中存在请修改',
get_download_link_hint: '未获取模板下载链接请联系模板市场官方',
search_result_count: '的搜索结果是 {0} ',
template_center: '模版中心',
preview: '预览'
}, },
work_branch: { work_branch: {
back_to_work_branch: '返回工作台', back_to_work_branch: '返回工作台',
@ -137,6 +142,7 @@ export default {
last_edited_by: '最近编辑人', last_edited_by: '最近编辑人',
last_edit_time: '最近编辑时间', last_edit_time: '最近编辑时间',
big_data_screen: '数据大屏', big_data_screen: '数据大屏',
big_screen: '大屏',
dashboard: '仪表板', dashboard: '仪表板',
data_set: '数据集', data_set: '数据集',
data_source: '数据源', data_source: '数据源',
@ -161,7 +167,13 @@ export default {
error_link_hint: '链接格式错误请重新填写', error_link_hint: '链接格式错误请重新填写',
password_null_hint: '密码不能为空请重新输入', password_null_hint: '密码不能为空请重新输入',
password_hint: '密码必须是包含数字字母特殊字符[!@#$%^&*()_+]的4-10位字符串', password_hint: '密码必须是包含数字字母特殊字符[!@#$%^&*()_+]的4-10位字符串',
max_ticket_count: '最多支持创建5个Ticket' max_ticket_count: '最多支持创建5个Ticket',
last: '上一个',
next: '下一个',
recommend: '推荐',
recent: '最近使用',
all_types: '全部类型',
all_source: '全部来源'
}, },
data_set: { data_set: {
ten_wan: '10万', ten_wan: '10万',
@ -2603,6 +2615,8 @@ export default {
enter_name_tips: '请输入仪表板名称', enter_name_tips: '请输入仪表板名称',
name: '名称', name: '名称',
apply_template: '应用模板', apply_template: '应用模板',
style_template: '样式模板',
all_type: '全部分类',
enter_template_name_tips: '搜索模板名称', enter_template_name_tips: '搜索模板名称',
pic_adaptation: '适应组件', pic_adaptation: '适应组件',
pic_equiratio: '等比适应', pic_equiratio: '等比适应',

View File

@ -274,7 +274,7 @@ onMounted(() => {
class="data-set-dark" class="data-set-dark"
@focus="handleFocus" @focus="handleFocus"
:disabled="disabled" :disabled="disabled"
:placeholder="'请选择' + sourceName" :placeholder="t('common.selectText') + sourceName"
> >
<template #suffix> <template #suffix>
<el-icon class="input-arrow-icon" :class="{ reverse: _popoverShow }"> <el-icon class="input-arrow-icon" :class="{ reverse: _popoverShow }">

View File

@ -228,7 +228,7 @@ defineExpose({
/> />
</div> </div>
</el-form-item> </el-form-item>
<el-form-item label="预览"> <el-form-item :label="t('template_manage.preview')">
<DynamicTime style="width: 100%" :config="curComponent" isConfig></DynamicTime> <DynamicTime style="width: 100%" :config="curComponent" isConfig></DynamicTime>
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -175,7 +175,11 @@ const props = defineProps({
const { componentData, canvasViewInfo, curCanvasType, themes } = toRefs(props) const { componentData, canvasViewInfo, curCanvasType, themes } = toRefs(props)
const dvPreName = computed(() => (curCanvasType.value === 'dashboard' ? '仪表板' : '数据大屏')) const dvPreName = computed(() =>
curCanvasType.value === 'dashboard'
? t('work_branch.dashboard')
: t('work_branch.big_data_screen')
)
const addDsWindow = () => { const addDsWindow = () => {
// do addDsWindow // do addDsWindow
const url = '#/data/datasource?opt=create' const url = '#/data/datasource?opt=create'
@ -243,7 +247,10 @@ const initData = () => {
dfs(resultTree as unknown as BusiTreeNode[]) dfs(resultTree as unknown as BusiTreeNode[])
state.dvTree = (resultTree as unknown as BusiTreeNode[]) || [] state.dvTree = (resultTree as unknown as BusiTreeNode[]) || []
if (state.dvTree.length && state.dvTree[0].name === 'root' && state.dvTree[0].id === '0') { if (state.dvTree.length && state.dvTree[0].name === 'root' && state.dvTree[0].id === '0') {
state.dvTree[0].name = curCanvasType.value === 'dataV' ? '数据大屏' : '仪表板' state.dvTree[0].name =
curCanvasType.value === 'dataV'
? t('work_branch.big_data_screen')
: t('work_branch.dashboard')
} }
}) })

View File

@ -46,7 +46,9 @@ const resourceForm = reactive({
pName: null, pName: null,
name: '新建' name: '新建'
}) })
const sourceLabel = computed(() => (curCanvasType.value === 'dataV' ? '数据大屏' : '仪表板')) const sourceLabel = computed(() =>
curCanvasType.value === 'dataV' ? t('work_branch.big_data_screen') : t('work_branch.dashboard')
)
const methodMap = { const methodMap = {
move: moveResource, move: moveResource,
@ -154,7 +156,10 @@ const optInit = (type, data: BusiTreeNode, exec, parentSelect = false) => {
dfs(resultTree as unknown as BusiTreeNode[]) dfs(resultTree as unknown as BusiTreeNode[])
state.tData = (resultTree as unknown as BusiTreeNode[]) || [] state.tData = (resultTree as unknown as BusiTreeNode[]) || []
if (state.tData.length && state.tData[0].name === 'root' && state.tData[0].id === '0') { if (state.tData.length && state.tData[0].name === 'root' && state.tData[0].id === '0') {
state.tData[0].name = curCanvasType.value === 'dataV' ? '数据大屏' : '仪表板' state.tData[0].name =
curCanvasType.value === 'dataV'
? t('work_branch.big_data_screen')
: t('work_branch.dashboard')
} }
tData = [...state.tData] tData = [...state.tData]
if ('move' === exec) { if ('move' === exec) {

View File

@ -73,7 +73,8 @@ const mounted = ref(false)
const rootManage = ref(false) const rootManage = ref(false)
const anyManage = ref(false) const anyManage = ref(false)
const { curCanvasType, showPosition } = toRefs(props) const { curCanvasType, showPosition } = toRefs(props)
const resourceLabel = curCanvasType.value === 'dataV' ? '数据大屏' : '仪表板' const resourceLabel =
curCanvasType.value === 'dataV' ? t('work_branch.big_data_screen') : t('work_branch.dashboard')
const newResourceLabel = '新建' + resourceLabel const newResourceLabel = '新建' + resourceLabel
const selectedNodeKey = ref(null) const selectedNodeKey = ref(null)
const filterText = ref(null) const filterText = ref(null)
@ -139,7 +140,7 @@ const resourceTypeList = computed(() => {
command: 'newLeaf' command: 'newLeaf'
}, },
{ {
label: '使用模板新建', label: t('work_branch.new_using_template'),
svgName: dvUseTemplate, svgName: dvUseTemplate,
command: 'newFromTemplate' command: 'newFromTemplate'
}, },
@ -569,7 +570,7 @@ defineExpose({
<el-icon class="handle-icon"> <el-icon class="handle-icon">
<Icon name="dv-use-template"><dvUseTemplate class="svg-icon" /></Icon> <Icon name="dv-use-template"><dvUseTemplate class="svg-icon" /></Icon>
</el-icon> </el-icon>
使用模板新建 {{ t('work_branch.new_using_template') }}
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</template> </template>

View File

@ -1,6 +1,14 @@
<template> <template>
<div class="info-card"> <div class="info-card">
<div class="info-title">{{ `${dvInfo.type === 'dashboard' ? '仪表板' : '数据大屏'}ID` }}</div> <div class="info-title">
{{
`${
dvInfo.type === 'dashboard'
? t('work_branch.dashboard')
: t('work_branch.big_data_screen')
}ID`
}}
</div>
<div class="info-content">{{ dvInfo.id }}</div> <div class="info-content">{{ dvInfo.id }}</div>
<div v-if="dvInfo.creatorName" class="info-title">{{ t('visualization.create_by') }}</div> <div v-if="dvInfo.creatorName" class="info-title">{{ t('visualization.create_by') }}</div>
<div v-if="dvInfo.creatorName" class="info-content">{{ dvInfo.creatorName }}</div> <div v-if="dvInfo.creatorName" class="info-content">{{ dvInfo.creatorName }}</div>

View File

@ -157,8 +157,8 @@ const initOpenHandler = newWindow => {
<template #icon> <template #icon>
<icon name="icon_pc_outlined"><icon_pc_outlined class="svg-icon" /></icon> <icon name="icon_pc_outlined"><icon_pc_outlined class="svg-icon" /></icon>
</template> </template>
预览</el-button {{ t('template_manage.preview') }}
> </el-button>
<ShareVisualHead <ShareVisualHead
v-if="!shareDisable" v-if="!shareDisable"
:resource-id="dvInfo.id" :resource-id="dvInfo.id"
@ -194,12 +194,14 @@ const initOpenHandler = newWindow => {
<el-dropdown-item style="width: 118px" @click="download('pdf')" <el-dropdown-item style="width: 118px" @click="download('pdf')"
>PDF</el-dropdown-item >PDF</el-dropdown-item
> >
<el-dropdown-item style="width: 118px" @click="downloadAsAppTemplate('template')" <el-dropdown-item
>样式模板</el-dropdown-item style="width: 118px"
> @click="downloadAsAppTemplate('template')"
<el-dropdown-item style="width: 118px" @click="downloadAsAppTemplate('app')" >{{ t('visualization.style_template') }}</el-dropdown-item
>应用模板</el-dropdown-item
> >
<el-dropdown-item style="width: 118px" @click="downloadAsAppTemplate('app')">{{
t('visualization.apply_template')
}}</el-dropdown-item>
<el-dropdown-item @click="download('img')">{{ <el-dropdown-item @click="download('img')">{{
t('chart.image') t('chart.image')
}}</el-dropdown-item> }}</el-dropdown-item>

View File

@ -304,7 +304,7 @@ onBeforeMount(() => {
<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('commons.create') }}数据大屏 {{ $t('commons.create') }}{{ t('work_branch.big_data_screen') }}
</el-button> </el-button>
</empty-background> </empty-background>
</template> </template>

View File

@ -202,13 +202,13 @@ onMounted(() => {
<van-sticky> <van-sticky>
<van-nav-bar <van-nav-bar
safe-area-inset-top safe-area-inset-top
:title="activeDirectName || '仪表板'" :title="activeDirectName || t('work_branch.dashboard')"
:left-arrow="!!activeDirectName" :left-arrow="!!activeDirectName"
@click-left="onClickLeft" @click-left="onClickLeft"
/> />
<div class="direct-name-arr" v-if="directName.length"> <div class="direct-name-arr" v-if="directName.length">
<div @click="onClickPanel" key="仪表板"> <div @click="onClickPanel" :key="t('work_branch.dashboard')">
<span class="label primary-name">仪表板</span> <span class="label primary-name">{{ t('work_branch.dashboard') }}</span>
<el-icon> <el-icon>
<Icon name="icon_right_outlined"><icon_right_outlined class="svg-icon" /></Icon> <Icon name="icon_right_outlined"><icon_right_outlined class="svg-icon" /></Icon>
</el-icon> </el-icon>

View File

@ -72,7 +72,7 @@ const loadShareTableData = () => {
} }
const tablePaneList = ref([ const tablePaneList = ref([
{ title: '最近使用', name: 'recent', disabled: false }, { title: t('work_branch.recent'), name: 'recent', disabled: false },
{ title: '我的收藏', name: 'store', disabled: false }, { title: '我的收藏', name: 'store', disabled: false },
{ title: t('visualization.share_out'), name: 'share', disabled: false } { title: t('visualization.share_out'), name: 'share', disabled: false }
]) ])

View File

@ -59,8 +59,9 @@ onBeforeMount(() => {
:is="active ? mobileIcon_dashboard_filled : mobileIcon_dashboard_outlined" :is="active ? mobileIcon_dashboard_filled : mobileIcon_dashboard_outlined"
></component ></component
></Icon> ></Icon>
</el-icon> </template </el-icon>
>仪表板</van-tabbar-item </template>
{{ t('work_branch.dashboard') }}</van-tabbar-item
> >
<van-tabbar-item name="user" <van-tabbar-item name="user"
><template #icon="{ active }"> ><template #icon="{ active }">

View File

@ -3,7 +3,9 @@
<div class="custom-split-line"></div> <div class="custom-split-line"></div>
<span v-show="!searchText" class="custom-category">{{ label }}</span> <span v-show="!searchText" class="custom-category">{{ label }}</span>
<span v-show="searchText" class="custom-search">{{ label }}</span> <span v-show="searchText" class="custom-search">{{ label }}</span>
<span v-if="searchText" class="custom-search-result">的搜索结果是{{ searchResult }}</span> <span v-if="searchText" class="custom-search-result">
{{ t('template_manage.search_result_count', [searchResult]) }}
</span>
</el-col> </el-col>
<el-col <el-col
v-for="(templateItem, index) in fullTemplateShowList" v-for="(templateItem, index) in fullTemplateShowList"
@ -28,7 +30,9 @@
<script setup lang="ts"> <script setup lang="ts">
import TemplateMarketV2Item from '@/views/template-market/component/TemplateMarketV2Item.vue' import TemplateMarketV2Item from '@/views/template-market/component/TemplateMarketV2Item.vue'
import { computed } from 'vue' import { computed } from 'vue'
import { useI18n } from '@/hooks/web/useI18n'
const emits = defineEmits(['templateApply', 'templatePreview']) const emits = defineEmits(['templateApply', 'templatePreview'])
const { t } = useI18n()
const templateApply = params => { const templateApply = params => {
emits('templateApply', params) emits('templateApply', params)

View File

@ -2,9 +2,9 @@
<el-row style="width: 100%"> <el-row style="width: 100%">
<el-row style="display: table; width: 100%"> <el-row style="display: table; width: 100%">
<el-col style="float: left" :class="state.asideActive ? 'aside-active' : 'aside-inActive'"> <el-col style="float: left" :class="state.asideActive ? 'aside-active' : 'aside-inActive'">
<el-icon v-show="!state.asideActive" class="insert" @click="asideActiveChange(true)" <el-icon v-show="!state.asideActive" class="insert" @click="asideActiveChange(true)">
><DArrowRight <DArrowRight />
/></el-icon> </el-icon>
<el-row v-show="state.asideActive" style="padding: 12px 12px 0"> <el-row v-show="state.asideActive" style="padding: 12px 12px 0">
<el-row style="align-items: center"> <el-row style="align-items: center">
<el-icon class="insert" @click="closePreview()"><Close /></el-icon> <el-icon class="insert" @click="closePreview()"><Close /></el-icon>
@ -18,21 +18,22 @@
prefix-icon="Search" prefix-icon="Search"
class="title-name-search" class="title-name-search"
:placeholder="t('visualization.enter_template_name_tips')" :placeholder="t('visualization.enter_template_name_tips')"
clearable="true" clearable
/> />
<el-icon <el-icon
class="insert-filter filter-icon-span" class="insert-filter filter-icon-span"
:class="state.extFilterActive ? 'filter-icon-active' : ''" :class="state.extFilterActive ? 'filter-icon-active' : ''"
@click="extFilterActiveChange()" @click="extFilterActiveChange()"
><Filter >
/></el-icon> <Filter />
</el-icon>
</el-row> </el-row>
<el-row v-show="state.extFilterActive"> <el-row v-show="state.extFilterActive">
<el-select <el-select
v-model="state.marketActiveTab" v-model="state.marketActiveTab"
class="margin-top16" class="margin-top16"
size="small" size="small"
placeholder="请选择" :placeholder="t('common.selectText')"
> >
<el-option v-for="item in state.marketTabs" :key="item" :label="item" :value="item" /> <el-option v-for="item in state.marketTabs" :key="item" :label="item" :value="item" />
</el-select> </el-select>
@ -56,9 +57,9 @@
/> />
<el-row v-show="!state.hasResult" class="custom-position"> <el-row v-show="!state.hasResult" class="custom-position">
<div style="text-align: center"> <div style="text-align: center">
<Icon name="no_result" <Icon name="no_result">
><no_result style="margin-bottom: 16px; font-size: 75px" class="svg-icon" <no_result style="margin-bottom: 16px; font-size: 75px" class="svg-icon" />
/></Icon> </Icon>
<br /> <br />
<span>{{ t('commons.no_result') }}</span> <span>{{ t('commons.no_result') }}</span>
</div> </div>
@ -78,8 +79,9 @@
type="primary" type="primary"
size="small" size="small"
@click="templateApply(state.curTemplate)" @click="templateApply(state.curTemplate)"
>{{ t('visualization.apply_this_template') }}</el-button
> >
{{ t('visualization.apply_this_template') }}
</el-button>
</div> </div>
</el-row> </el-row>
<el-row class="img-main"> <el-row class="img-main">

View File

@ -2,17 +2,30 @@
<el-row style="width: 100%"> <el-row style="width: 100%">
<el-row style="display: table; width: 100%"> <el-row style="display: table; width: 100%">
<el-col style="float: left" :class="state.asideActive ? 'aside-active' : 'aside-inActive'"> <el-col style="float: left" :class="state.asideActive ? 'aside-active' : 'aside-inActive'">
<el-tooltip class="box-item" effect="dark" content="展开" placement="right"> <el-tooltip
class="box-item"
effect="dark"
:content="t('relation.expand')"
placement="right"
>
<el-icon v-show="!state.asideActive" class="insert" @click="asideActiveChange(true)"> <el-icon v-show="!state.asideActive" class="insert" @click="asideActiveChange(true)">
<Icon name="market-expand"><marketExpand class="svg-icon" /></Icon> <Icon name="market-expand"><marketExpand class="svg-icon" /></Icon>
</el-icon> </el-icon>
</el-tooltip> </el-tooltip>
<el-row v-show="state.asideActive" style="padding: 24px 12px 0"> <el-row v-show="state.asideActive" style="padding: 24px 12px 0">
<el-row style="align-items: center"> <el-row style="align-items: center">
<span class="custom-breadcrumb-item" @click="closePreview()">模版中心</span> <span class="custom-breadcrumb-item" @click="closePreview()">{{
<el-icon><ArrowRight /></el-icon> <span class="custom-breadcrumb-item-to"></span> t('template_manage.template_center')
}}</span>
<el-icon><ArrowRight /></el-icon>
<span class="custom-breadcrumb-item-to">{{ t('template_manage.preview') }}</span>
<el-tooltip class="box-item" effect="dark" content="收起" placement="right"> <el-tooltip
class="box-item"
effect="dark"
:content="t('relation.retract')"
placement="right"
>
<div @click="asideActiveChange(false)" class="insert-retract"> <div @click="asideActiveChange(false)" class="insert-retract">
<el-icon> <el-icon>
<Icon name="icon_left_outlined"><icon_left_outlined class="svg-icon" /></Icon> <Icon name="icon_left_outlined"><icon_left_outlined class="svg-icon" /></Icon>
@ -26,17 +39,22 @@
prefix-icon="Search" prefix-icon="Search"
class="title-name-search" class="title-name-search"
:placeholder="t('visualization.enter_template_name_tips')" :placeholder="t('visualization.enter_template_name_tips')"
clearable="true" clearable
/> />
<el-icon <el-icon
class="insert-filter filter-icon-span" class="insert-filter filter-icon-span"
:class="state.extFilterActive ? 'filter-icon-active' : ''" :class="state.extFilterActive ? 'filter-icon-active' : ''"
@click="extFilterActiveChange()" @click="extFilterActiveChange()"
><Filter >
/></el-icon> <Filter />
</el-icon>
</el-row> </el-row>
<el-row v-show="state.extFilterActive"> <el-row v-show="state.extFilterActive">
<el-select v-model="state.templateType" style="margin-top: 8px" placeholder="请选择"> <el-select
v-model="state.templateType"
style="margin-top: 8px"
:placeholder="t('common.selectText')"
>
<el-option <el-option
v-for="item in state.templateTypeOptions" v-for="item in state.templateTypeOptions"
:key="item.value" :key="item.value"
@ -49,7 +67,7 @@
<el-select <el-select
v-model="state.templateSourceType" v-model="state.templateSourceType"
style="margin-top: 8px" style="margin-top: 8px"
placeholder="请选择" :placeholder="t('common.selectText')"
> >
<el-option <el-option
v-for="item in state.templateSourceOptions" v-for="item in state.templateSourceOptions"
@ -89,11 +107,11 @@
</el-collapse> </el-collapse>
<el-row v-show="!state.hasResult" class="custom-position"> <el-row v-show="!state.hasResult" class="custom-position">
<div style="text-align: center"> <div style="text-align: center">
<Icon name="no_result" <Icon name="no_result">
><no_result style="margin-bottom: 16px; font-size: 75px" class="svg-icon" <no_result style="margin-bottom: 16px; font-size: 75px" class="svg-icon" />
/></Icon> </Icon>
<br /> <br />
<span>没有找到相关模板</span> <span>{{ t('work_branch.relevant_templates_found') }}</span>
</div> </div>
</el-row> </el-row>
</el-row> </el-row>
@ -111,8 +129,9 @@
type="primary" type="primary"
:disabled="!createAuth[state.curTemplate?.templateType]" :disabled="!createAuth[state.curTemplate?.templateType]"
@click="templateApply(state.curTemplate)" @click="templateApply(state.curTemplate)"
>{{ t('visualization.apply_this_template') }}</el-button
> >
{{ t('visualization.apply_this_template') }}
</el-button>
</div> </div>
</el-row> </el-row>
<el-row class="img-main"> <el-row class="img-main">
@ -180,30 +199,30 @@ const state = reactive({
templateSourceOptions: [ templateSourceOptions: [
{ {
value: 'all', value: 'all',
label: '全部来源' label: t('work_branch.all_source')
}, },
{ {
value: 'market', value: 'market',
label: '模板市场' label: t('work_branch.template_market_official')
}, },
{ {
value: 'manage', value: 'manage',
label: '模板管理' label: t('template_manage.name')
} }
], ],
templateType: 'all', templateType: 'all',
templateTypeOptions: [ templateTypeOptions: [
{ {
value: 'all', value: 'all',
label: '全部类型' label: t('work_branch.all_types')
}, },
{ {
value: 'PANEL', value: 'PANEL',
label: '仪表板' label: t('work_branch.dashboard')
}, },
{ {
value: 'SCREEN', value: 'SCREEN',
label: '大屏' label: t('work_branch.big_screen')
} }
] ]
}) })

View File

@ -24,14 +24,14 @@
:disabled="state.curTemplateIndex === 0" :disabled="state.curTemplateIndex === 0"
style="float: right" style="float: right"
@click="preOne" @click="preOne"
>上一个</el-button >{{ t('work_branch.last') }}</el-button
> >
<el-button <el-button
:disabled="state.curTemplateIndex === state.curTemplateShowFilter.length - 1" :disabled="state.curTemplateIndex === state.curTemplateShowFilter.length - 1"
style="float: right" style="float: right"
secondary secondary
@click="nextOne" @click="nextOne"
>下一个</el-button >{{ t('work_branch.next') }}</el-button
> >
<el-button <el-button
style="float: right" style="float: right"
@ -116,7 +116,7 @@
id="template-show-area" id="template-show-area"
class="template-right" class="template-right"
> >
<el-row v-show="state.marketActiveTab !== '推荐'"> <el-row v-show="state.marketActiveTab !== t('work_branch.recommend')">
<category-template-v2 <category-template-v2
:search-text="state.searchText" :search-text="state.searchText"
:label="state.marketActiveTab" :label="state.marketActiveTab"
@ -128,16 +128,16 @@
:create-auth="createAuth" :create-auth="createAuth"
@templateApply="templateApply" @templateApply="templateApply"
@templatePreview="templatePreview" @templatePreview="templatePreview"
></category-template-v2> />
</el-row> </el-row>
<el-row v-show="state.marketActiveTab === '推荐'"> <el-row v-show="state.marketActiveTab === t('work_branch.recommend')">
<el-row <el-row
style="display: inline; width: 100%; margin-bottom: 16px" style="display: inline; width: 100%; margin-bottom: 16px"
v-for="(categoryItem, index) in categoriesComputed" v-for="(categoryItem, index) in categoriesComputed"
:key="index" :key="index"
> >
<category-template-v2 <category-template-v2
v-if="categoryItem.label !== '最近使用'" v-if="categoryItem.label !== t('work_branch.recent')"
:search-text="state.searchText" :search-text="state.searchText"
:label="categoryItem.label" :label="categoryItem.label"
:full-template-show-list="state.currentMarketTemplateShowList" :full-template-show-list="state.currentMarketTemplateShowList"
@ -148,7 +148,7 @@
:create-auth="createAuth" :create-auth="createAuth"
@templateApply="templateApply" @templateApply="templateApply"
@templatePreview="templatePreview" @templatePreview="templatePreview"
></category-template-v2> />
</el-row> </el-row>
</el-row> </el-row>
</div> </div>
@ -158,7 +158,7 @@
><no_result style="margin-bottom: 16px; font-size: 75px" class="svg-icon" ><no_result style="margin-bottom: 16px; font-size: 75px" class="svg-icon"
/></Icon> /></Icon>
<br /> <br />
<span>没有找到相关模板</span> <span>{{ t('work_branch.relevant_templates_found') }}</span>
</div> </div>
</el-row> </el-row>
<el-row v-show="!state.networkStatus" class="template-empty"> <el-row v-show="!state.networkStatus" class="template-empty">
@ -201,7 +201,11 @@ const close = () => {
emits('close') emits('close')
} }
const title = computed(() => (state.curPosition === 'branch' ? '模板中心' : '使用模板新建')) const title = computed(() =>
state.curPosition === 'branch'
? t('work_branch.template_center')
: t('work_branch.new_using_template')
)
const isEmbedded = computed(() => appStore.getIsDataEaseBi || appStore.getIsIframe) const isEmbedded = computed(() => appStore.getIsDataEaseBi || appStore.getIsIframe)
const state = reactive({ const state = reactive({
initReady: true, initReady: true,
@ -218,43 +222,43 @@ const state = reactive({
templateClassifyOptions: [ templateClassifyOptions: [
{ {
value: 'all', value: 'all',
label: '全部分类' label: t('visualization.all_type')
}, },
{ {
value: 'app', value: 'app',
label: '应用模板' label: t('visualization.apply_template')
}, },
{ {
value: 'template', value: 'template',
label: '样式模板' label: t('visualization.style_template')
} }
], ],
templateSourceOptions: [ templateSourceOptions: [
{ {
value: 'all', value: 'all',
label: '全部来源' label: t('work_branch.all_source')
}, },
{ {
value: 'market', value: 'market',
label: '模板市场' label: t('work_branch.template_market_official')
}, },
{ {
value: 'manage', value: 'manage',
label: '模板管理' label: t('template_manage.name')
} }
], ],
templateTypeOptions: [ templateTypeOptions: [
{ {
value: 'all', value: 'all',
label: '全部类型' label: t('work_branch.all_types')
}, },
{ {
value: 'PANEL', value: 'PANEL',
label: '仪表板' label: t('work_branch.dashboard')
}, },
{ {
value: 'SCREEN', value: 'SCREEN',
label: '数据大屏' label: t('work_branch.big_data_screen')
} }
], ],
loading: false, loading: false,
@ -454,7 +458,7 @@ const templateApply = template => {
const apply = template => { const apply = template => {
if (state.dvCreateForm.newFrom === 'new_market_template' && !state.dvCreateForm.templateUrl) { if (state.dvCreateForm.newFrom === 'new_market_template' && !state.dvCreateForm.templateUrl) {
ElMessage.warning('未获取模板下载链接请联系模板市场官方') ElMessage.warning(t('template_manage.get_download_link_hint'))
return false return false
} }
const templateTemplate = { const templateTemplate = {
@ -464,7 +468,7 @@ const apply = template => {
templateId: state.dvCreateForm.templateId templateId: state.dvCreateForm.templateId
} }
state.curApplyTemplate.recentUseTime = Date.now() state.curApplyTemplate.recentUseTime = Date.now()
state.curApplyTemplate.categoryNames.push('最近使用') state.curApplyTemplate.categoryNames.push(t('work_branch.recent'))
const baseUrl = const baseUrl =
(['dataV', 'SCREEN'].includes(state.dvCreateForm.nodeType) (['dataV', 'SCREEN'].includes(state.dvCreateForm.nodeType)
? '#/dvCanvas?opt=create&createType=template' ? '#/dvCanvas?opt=create&createType=template'
@ -555,7 +559,7 @@ const templatePreview = previewId => {
previewModel.value = 'marketPreview' previewModel.value = 'marketPreview'
} else { } else {
state.curTemplateShowFilter = state.curTemplateShowFilter =
state.marketActiveTab === '推荐' state.marketActiveTab === t('work_branch.recommend')
? state.currentMarketTemplateShowList.filter(ele => ele.showFlag) ? state.currentMarketTemplateShowList.filter(ele => ele.showFlag)
: state.currentMarketTemplateShowList.filter( : state.currentMarketTemplateShowList.filter(
ele => ele.showFlag && ele.categoryNames?.includes(state.marketActiveTab) ele => ele.showFlag && ele.categoryNames?.includes(state.marketActiveTab)

@ -1 +1 @@
Subproject commit 22928ead8f23a94c5dc96fdf35ce4ac2f49fe856 Subproject commit b2b01bc8057344a79f862fd5bf402743e579bb91

View File

@ -2,6 +2,7 @@ package io.dataease.api.template.dto;
import io.dataease.api.template.vo.MarketCategoryVO; import io.dataease.api.template.vo.MarketCategoryVO;
import io.dataease.api.template.vo.MarketMetasVO; import io.dataease.api.template.vo.MarketMetasVO;
import io.dataease.i18n.Translator;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
@ -55,8 +56,9 @@ public class TemplateMarketDTO implements Comparable<TemplateMarketDTO> {
this.classify = manageDTO.getNodeType(); this.classify = manageDTO.getNodeType();
if (manageDTO.getRecentUseTime() != null) { if (manageDTO.getRecentUseTime() != null) {
this.recentUseTime = manageDTO.getRecentUseTime(); this.recentUseTime = manageDTO.getRecentUseTime();
this.categories.add(new MarketCategoryVO("最近使用")); String name = Translator.get("i18n_template_recent");
this.categoryNames.add("最近使用"); this.categories.add(new MarketCategoryVO(name));
this.categoryNames.add(name);
} }
} }
@ -70,13 +72,15 @@ public class TemplateMarketDTO implements Comparable<TemplateMarketDTO> {
this.categoryNames = new ArrayList<>(Arrays.asList(categoryName)) ; this.categoryNames = new ArrayList<>(Arrays.asList(categoryName)) ;
if (recentUseTime != null) { if (recentUseTime != null) {
this.recentUseTime = recentUseTime; this.recentUseTime = recentUseTime;
this.categories.add(new MarketCategoryVO("最近使用")); String name = Translator.get("i18n_template_recent");
this.categoryNames.add("最近使用"); this.categories.add(new MarketCategoryVO(name));
this.categoryNames.add(name);
} }
if ("Y".equalsIgnoreCase(suggest)) { if ("Y".equalsIgnoreCase(suggest)) {
this.suggest = "Y"; this.suggest = "Y";
this.categories.add(new MarketCategoryVO("推荐")); String name = Translator.get("i18n_template_recommend");
this.categoryNames.add("推荐"); this.categories.add(new MarketCategoryVO(name));
this.categoryNames.add(name);
} }
} }