远程组件创建提交, 国际化部分代码优化 merge代码
parent
4b66115c88
commit
915df23b2c
11
package.json
11
package.json
|
|
@ -84,7 +84,7 @@
|
|||
"animate.css": "^4.1.1",
|
||||
"axios": "^1.6.4",
|
||||
"color": "^4.2.3",
|
||||
"codemirror": "^5.65.16",
|
||||
"codemirror": "^6.0.1",
|
||||
"cropperjs": "^1.6.1",
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.10",
|
||||
|
|
@ -137,7 +137,14 @@
|
|||
"jszip":"^3.10.1",
|
||||
"shpjs":"^6.1.0",
|
||||
"js-base64":"3.7.7",
|
||||
"monaco-editor": "^0.33.0"
|
||||
"monaco-editor": "^0.33.0",
|
||||
"@codemirror/lang-javascript": "^6.2.2",
|
||||
"@codemirror/language": "^6.10.8",
|
||||
"@codemirror/state": "^6.5.1",
|
||||
"@codemirror/view": "^6.36.2",
|
||||
"@codemirror/basic-setup": "^0.20.0",
|
||||
"vue-codemirror": "^6.1.1",
|
||||
"@codemirror/theme-one-dark": "^6.1.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@amap/amap-jsapi-loader": "^1.0.1",
|
||||
|
|
|
|||
|
|
@ -61,6 +61,16 @@ export enum PageEnum {
|
|||
BASE_HOME_ITEMS = '/project/items',
|
||||
BASE_HOME_ITEMS_NAME = 'Project-Items',
|
||||
|
||||
// 远程组件
|
||||
BASE_HOME_REMOTE = '/project/remote',
|
||||
BASE_HOME_REMOTE_NAME = 'Project-Remote',
|
||||
|
||||
BASE_HOME_LIST_REMOTE = '/project/remote/list',
|
||||
BASE_HOME_LIST_REMOTE_NAME = 'Project-Remote-List',
|
||||
|
||||
BASE_HOME_CREATE_REMOTE = '/project/remote/create/:id(.*)*',
|
||||
BASE_HOME_CREATE_REMOTE_NAME = 'Project-Remote-Create',
|
||||
|
||||
// 我的模板
|
||||
BASE_HOME_TEMPLATE = '/project/my-template',
|
||||
BASE_HOME_TEMPLATE_NAME = 'Project-My-Template',
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
import login from './login'
|
||||
import project from './project'
|
||||
|
||||
const global = {
|
||||
doc_addr: 'Document',
|
||||
code_addr: 'Code',
|
||||
form_account: 'Please enter your account or email',
|
||||
form_password: 'Please enter your password',
|
||||
// header
|
||||
doc: 'Document',
|
||||
help: 'Help',
|
||||
contact: 'About Software',
|
||||
logout: 'Logout',
|
||||
// system setting
|
||||
sys_set: 'System Setting',
|
||||
lang_set: 'Language Setting',
|
||||
// right key
|
||||
r_edit: 'Edit',
|
||||
r_preview: 'Preview',
|
||||
r_copy: 'Clone',
|
||||
r_rename: 'Rename',
|
||||
r_publish: 'Publish',
|
||||
r_unpublish: 'Unpublish',
|
||||
r_download: 'Download',
|
||||
r_delete: 'Delete',
|
||||
r_more: 'More',
|
||||
}
|
||||
|
||||
export default {
|
||||
global,
|
||||
login,
|
||||
project
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
export default {
|
||||
desc: "Login",
|
||||
form_auto: "Sign in automatically",
|
||||
form_button: "Login",
|
||||
login_success: "Login success",
|
||||
login_message: "Please complete the letter",
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
export default {
|
||||
create_btn: 'Create',
|
||||
create_tip: 'Please select a content for development',
|
||||
project: 'Project',
|
||||
my: 'My',
|
||||
new_project: 'New Project',
|
||||
all_project: 'All Project',
|
||||
my_templete: 'My Templete',
|
||||
template_market: 'Template Market',
|
||||
|
||||
// items
|
||||
release: 'Release',
|
||||
unreleased: 'Unrelease',
|
||||
last_edit: 'Last edit time'
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
//语言
|
||||
import { lang } from '@/settings/designSetting';
|
||||
import { createI18n } from 'vue-i18n'; //引入vue-i18n组件
|
||||
import { getLocalStorage } from '@/utils';
|
||||
import { StorageEnum } from '@/enums/storageEnum';
|
||||
import { LangEnum } from '@/enums/styleEnum';
|
||||
import { LangStateType } from '@/store/modules/langStore/langStore.d';
|
||||
import zh from './zh/index';
|
||||
import en from './en/index';
|
||||
|
||||
const langStorage: LangStateType = getLocalStorage(StorageEnum.GO_LANG_STORE);
|
||||
// 语言数组
|
||||
export const langList = [
|
||||
{
|
||||
label: '中文',
|
||||
key: LangEnum.ZH,
|
||||
},
|
||||
{
|
||||
label: 'English',
|
||||
key: LangEnum.EN,
|
||||
},
|
||||
];
|
||||
|
||||
export const i18n = createI18n({
|
||||
legacy: false,
|
||||
globalInjection: true,
|
||||
locale: langStorage?.lang || lang,
|
||||
fallbackLocale: langStorage?.lang || lang,
|
||||
messages: {
|
||||
[LangEnum.ZH]: zh,
|
||||
[LangEnum.EN]: en,
|
||||
},
|
||||
});
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
import login from './login'
|
||||
import project from './project'
|
||||
|
||||
const global = {
|
||||
doc_addr: '文档地址',
|
||||
code_addr: '仓库地址',
|
||||
form_account: '请输入账号或邮箱',
|
||||
form_password: '请输入密码',
|
||||
// 头部
|
||||
doc: '说明文档',
|
||||
help: '帮助中心',
|
||||
contact: '关于软件',
|
||||
logout: '退出登录',
|
||||
// 系统设置
|
||||
sys_set: '系统设置',
|
||||
lang_set: '语言设置',
|
||||
// 功能键
|
||||
r_edit: '编辑',
|
||||
r_preview: '预览',
|
||||
r_copy: '克隆',
|
||||
r_rename: '重命名',
|
||||
r_publish: '发布',
|
||||
r_unpublish: '取消发布',
|
||||
r_download: '下载',
|
||||
r_delete: '删除',
|
||||
r_more: '更多',
|
||||
}
|
||||
|
||||
export default {
|
||||
global,
|
||||
login,
|
||||
project
|
||||
}
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
export default {
|
||||
desc: "登录",
|
||||
form_auto: "自动登录",
|
||||
form_button: "登录",
|
||||
login_success: "登录成功",
|
||||
login_message: "请填写完整信息",
|
||||
}
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
export default {
|
||||
// aside
|
||||
create_btn: '新建',
|
||||
create_tip: '从哪里出发好呢?',
|
||||
project: '项目',
|
||||
my: '我的',
|
||||
new_project: '新项目',
|
||||
all_project: '全部项目',
|
||||
my_templete: '我的模板',
|
||||
template_market: '模板市场',
|
||||
|
||||
// items
|
||||
release: '已发布',
|
||||
unreleased: '未发布',
|
||||
last_edit: '最后编辑'
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"create_btn": "Create",
|
||||
"create_tip": "Please select a content for development",
|
||||
"create_tip": "Please select the content to create",
|
||||
"project": "Project",
|
||||
"my": "My",
|
||||
"new_project": "New Project",
|
||||
|
|
@ -9,5 +9,6 @@
|
|||
"template_market": "Template Market",
|
||||
"release": "Release",
|
||||
"unreleased": "Unrelease",
|
||||
"last_edit": "Last edit time"
|
||||
"last_edit": "Last edit time",
|
||||
"remote_component": "remote"
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"create_btn": "新建",
|
||||
"create_tip": "从哪里出发好呢?",
|
||||
"create_tip": "请选择要创建的内容",
|
||||
"project": "项目",
|
||||
"my": "我的",
|
||||
"new_project": "新项目",
|
||||
|
|
@ -9,5 +9,6 @@
|
|||
"template_market": "模板市场",
|
||||
"release": "已发布",
|
||||
"unreleased": "未发布",
|
||||
"last_edit": "最后编辑"
|
||||
"last_edit": "最后编辑",
|
||||
"remote_component": "远程组件"
|
||||
}
|
||||
|
|
@ -35,7 +35,6 @@ import lineMdIcons from '@iconify/json/json/line-md.json';
|
|||
import wiIcons from '@iconify/json/json/wi.json';
|
||||
import { addCollection } from 'iconify-icon';
|
||||
import { setupNaive, setupDirectives, setupCustomComponents, initFunction } from '@/plugins';
|
||||
import { i18n } from '@/i18n';
|
||||
import { GoAppProvider } from '@/components/GoAppProvider/index';
|
||||
import * as echarts from 'echarts'
|
||||
|
||||
|
|
@ -49,9 +48,7 @@ async function bootstrap() {
|
|||
// 语言注册
|
||||
// app.use(i18n);
|
||||
// 在Vue应用挂载后绑定$t到window对象
|
||||
app.config.globalProperties.$t = i18n.global.t;
|
||||
app.config.globalProperties.$echarts = echarts
|
||||
window['$t'] = i18n.global.t;
|
||||
// 注册全局常用的 naive-ui 组件
|
||||
setupNaive(app);
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ const props = defineProps({
|
|||
})
|
||||
|
||||
let remote = ref()
|
||||
let url = 'http://192.168.10.130:3000/getVue3Str1'
|
||||
let url = 'http://192.168.10.124:3000/getVue3Str2'
|
||||
const data = ref(props.chartConfig.option.dataset)
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import { PageEnum } from '@/enums/pageEnum';
|
|||
const importPath = {
|
||||
'PageEnum.BASE_HOME_NAME': () => import('@/views/project/index.vue'),
|
||||
'PageEnum.BASE_HOME_ITEMS_NAME': () => import('@/views/project/items/index.vue'),
|
||||
'PageEnum.BASE_HOME_REMOTE_NAME': () => import('@/views/project/remote/list/index.vue'),
|
||||
'PageEnum.BASE_HOME_REMOTE_CREATE_NAME': () => import('@/views/project/remote/create/index.vue'),
|
||||
'PageEnum.BASE_HOME_TEMPLATE_NAME': () => import('@/views/project/mtTemplate/index.vue'),
|
||||
'PageEnum.BASE_HOME_TEMPLATE_MARKET_NAME': () =>
|
||||
import('@/views/project/templateMarket/index.vue'),
|
||||
|
|
@ -28,6 +30,34 @@ export const projectRoutes: RouteRecordRaw = {
|
|||
title: '我的项目',
|
||||
},
|
||||
},
|
||||
{
|
||||
path: PageEnum.BASE_HOME_REMOTE,
|
||||
name: PageEnum.BASE_HOME_REMOTE_NAME,
|
||||
redirect: PageEnum.BASE_HOME_LIST_REMOTE,
|
||||
meta: {
|
||||
title: '远程组件',
|
||||
},
|
||||
children: [
|
||||
{
|
||||
path: PageEnum.BASE_HOME_LIST_REMOTE,
|
||||
name: PageEnum.BASE_HOME_LIST_REMOTE_NAME,
|
||||
meta: {
|
||||
title: '远程组件列表',
|
||||
hideMenu: true,
|
||||
},
|
||||
component: importPath['PageEnum.BASE_HOME_REMOTE_NAME'],
|
||||
},
|
||||
{
|
||||
path: PageEnum.BASE_HOME_CREATE_REMOTE,
|
||||
name: PageEnum.BASE_HOME_CREATE_REMOTE_NAME,
|
||||
meta: {
|
||||
title: '创建远程组件',
|
||||
hideMenu: true,
|
||||
},
|
||||
component: importPath['PageEnum.BASE_HOME_REMOTE_CREATE_NAME'],
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
path: PageEnum.BASE_HOME_TEMPLATE,
|
||||
name: PageEnum.BASE_HOME_TEMPLATE_NAME,
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
* * 请求失败统一处理
|
||||
*/
|
||||
export const httpErrorHandle = () => {
|
||||
window['$message'].error(window['$t']('http.error_message'))
|
||||
window['$message'].error('error')
|
||||
}
|
||||
|
|
@ -37,6 +37,6 @@
|
|||
}
|
||||
}
|
||||
.go-project .content-top {
|
||||
top: 10px;
|
||||
top: 0px;
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
:disabled="item.disabled"
|
||||
v-for="item in typeList"
|
||||
:key="item.key"
|
||||
@click="btnHandle"
|
||||
@click="btnHandle(item.key)"
|
||||
>
|
||||
<component :is="item.title"></component>
|
||||
<template #icon>
|
||||
|
|
@ -57,17 +57,23 @@
|
|||
disabled: false,
|
||||
},
|
||||
{
|
||||
title: renderLang('project.my_templete'),
|
||||
key: PageEnum.BASE_HOME_TEMPLATE_NAME,
|
||||
title: renderLang('project.remote_component'),
|
||||
key: PageEnum.BASE_HOME_CREATE_REMOTE_NAME,
|
||||
icon: ObjectStorageIcon,
|
||||
disabled: true,
|
||||
},
|
||||
{
|
||||
title: renderLang('project.template_market'),
|
||||
key: PageEnum.BASE_HOME_TEMPLATE_MARKET_NAME,
|
||||
icon: StoreIcon,
|
||||
disabled: true,
|
||||
disabled: false,
|
||||
},
|
||||
// {
|
||||
// title: renderLang('project.my_templete'),
|
||||
// key: PageEnum.BASE_HOME_TEMPLATE_NAME,
|
||||
// icon: ObjectStorageIcon,
|
||||
// disabled: true,
|
||||
// },
|
||||
// {
|
||||
// title: renderLang('project.template_market'),
|
||||
// key: PageEnum.BASE_HOME_TEMPLATE_MARKET_NAME,
|
||||
// icon: StoreIcon,
|
||||
// disabled: true,
|
||||
// },
|
||||
]);
|
||||
|
||||
watch(props, (newValue) => {
|
||||
|
|
@ -83,8 +89,13 @@
|
|||
const btnHandle = (key: string) => {
|
||||
closeHandle();
|
||||
const id = getUUID();
|
||||
const path = fetchPathByName(ChartEnum.CHART_HOME_NAME, 'href');
|
||||
routerTurnByPath(path, [id], undefined, true);
|
||||
let path = fetchPathByName(key, 'href');
|
||||
if(key == ChartEnum.CHART_HOME_NAME){
|
||||
routerTurnByPath(path, [id], undefined, true);
|
||||
}else{
|
||||
path = path.replace('#','')
|
||||
routerTurnByPath(path, [id], undefined, false);
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
|
|
|
|||
|
|
@ -47,11 +47,11 @@
|
|||
const modalShow = ref<boolean>(false);
|
||||
|
||||
const clickHandle = () => {
|
||||
console.log('clickHandle');
|
||||
const id = getUUID();
|
||||
const path = fetchPathByName(ChartEnum.CHART_HOME_NAME, 'href');
|
||||
routerTurnByPath(path, [id], undefined, true);
|
||||
// modalShow.value = true;
|
||||
// console.log('clickHandle');
|
||||
// const id = getUUID();
|
||||
// const path = fetchPathByName(ChartEnum.CHART_HOME_NAME, 'href');
|
||||
// routerTurnByPath(path, [id], undefined, true);
|
||||
modalShow.value = true;
|
||||
};
|
||||
|
||||
const closeHandle = () => {
|
||||
|
|
|
|||
|
|
@ -45,7 +45,10 @@
|
|||
const { getAsideCollapsedWidth } = toRefs(useSettingStore());
|
||||
|
||||
const route = useRoute();
|
||||
const menuValue = computed(() => route.name);
|
||||
const menuValue = computed(() => {
|
||||
let routeName = route.name.split('-')
|
||||
return `${routeName[0]}-${routeName[1]}`
|
||||
});
|
||||
|
||||
const menuOptions = menuOptionsInit();
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { RouterLink } from 'vue-router';
|
|||
import { PageEnum } from '@/enums/pageEnum';
|
||||
import { MenuOption, MenuGroupOption } from 'naive-ui';
|
||||
import { icon } from '@/plugins';
|
||||
import { useI18n } from '@/hooks/web/useI18n';
|
||||
|
||||
const { GridIcon, TvOutlineIcon } = icon.ionicons5;
|
||||
const { StoreIcon, ObjectStorageIcon, DevicesIcon } = icon.carbon;
|
||||
|
|
@ -14,7 +15,7 @@ export const renderMenuLabel = (option: MenuOption | MenuGroupOption) => {
|
|||
export const expandedKeys = () => ['all-project'];
|
||||
// 我的项目菜单
|
||||
export const menuOptionsInit = () => {
|
||||
const t = window['$t'];
|
||||
const { t } = useI18n();
|
||||
|
||||
return reactive([
|
||||
{
|
||||
|
|
@ -36,6 +37,20 @@ export const menuOptionsInit = () => {
|
|||
key: PageEnum.BASE_HOME_ITEMS_NAME,
|
||||
icon: renderIcon(TvOutlineIcon),
|
||||
},
|
||||
{
|
||||
label: () =>
|
||||
h(
|
||||
RouterLink,
|
||||
{
|
||||
to: {
|
||||
name: PageEnum.BASE_HOME_REMOTE_NAME,
|
||||
},
|
||||
},
|
||||
{ default: () => t('project.remote_component') },
|
||||
),
|
||||
key: PageEnum.BASE_HOME_REMOTE_NAME,
|
||||
icon: renderIcon(TvOutlineIcon),
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,150 @@
|
|||
<template>
|
||||
<div class="out-div">
|
||||
<div class="header">
|
||||
<div class="component-name-div">
|
||||
<n-icon size="20" :depth="3">
|
||||
<fish-icon></fish-icon>
|
||||
</n-icon>
|
||||
<n-text @click="handleFocus" style="white-space: nowrap;">
|
||||
组件名称 -
|
||||
<n-button v-show="!focus" secondary size="tiny">
|
||||
<span class="title">
|
||||
{{ title }}
|
||||
</span>
|
||||
</n-button>
|
||||
</n-text>
|
||||
|
||||
<n-input
|
||||
v-show="focus"
|
||||
ref="inputInstRef"
|
||||
size="small"
|
||||
type="text"
|
||||
maxlength="16"
|
||||
show-count
|
||||
placeholder="请输入项目名称"
|
||||
v-model:value.trim="title"
|
||||
@keyup.enter="handleBlur"
|
||||
@blur="handleBlur"
|
||||
></n-input>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-div">
|
||||
<div class="code-div">
|
||||
<Codemirror
|
||||
v-model="code"
|
||||
:extensions="extensions"
|
||||
placeholder="Code goes here..."
|
||||
:style="{ height: '100%' }"
|
||||
:autofocus="true"
|
||||
:indent-with-tab="true"
|
||||
:tab-size="2"
|
||||
@blur="load"/>
|
||||
</div>
|
||||
<div class="show-div">
|
||||
<component :is="remote" v-if="remote" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { defineComponent, ref, shallowRef, defineAsyncComponent, nextTick } from 'vue'
|
||||
import {Codemirror} from "vue-codemirror";
|
||||
import { javascript } from '@codemirror/lang-javascript'
|
||||
import { oneDark } from '@codemirror/theme-one-dark'
|
||||
import { loadModule } from 'vue3-sfc-loader/dist/vue3-sfc-loader'
|
||||
import * as Vue from 'vue'
|
||||
import { keymap } from "@codemirror/view";
|
||||
import { icon } from '@/plugins';
|
||||
const { FishIcon } = icon.ionicons5;
|
||||
|
||||
const customKeymap = keymap.of([
|
||||
{
|
||||
key: "Ctrl-s", // 监听 Ctrl+S 快捷键
|
||||
run() {
|
||||
load()
|
||||
alert("代码已保存!"); // 这里可以替换为实际的保存逻辑
|
||||
return true; // 返回 true 表示拦截默认行为
|
||||
},
|
||||
},
|
||||
{
|
||||
key: "Mod-s", // Mac 上的 Command+S
|
||||
run() {
|
||||
alert("代码已保存!(Mac)"); // 同样替换为实际保存逻辑
|
||||
return true;
|
||||
},
|
||||
},
|
||||
]);
|
||||
|
||||
const extensions = [javascript(),oneDark, customKeymap ]
|
||||
|
||||
|
||||
const code = ref(`console.log('Hello, world!')`)
|
||||
const remote = ref()
|
||||
const title = ref()
|
||||
const focus = ref(false)
|
||||
const inputInstRef = ref(null);
|
||||
|
||||
const load = () => {
|
||||
const options = {
|
||||
moduleCache: {
|
||||
vue: Vue
|
||||
},
|
||||
getFile() {
|
||||
return code.value
|
||||
},
|
||||
addStyle(textContent) {
|
||||
const style = Object.assign(document.createElement('style'), { textContent })
|
||||
const ref = document.head.getElementsByTagName('style')[0] || null
|
||||
document.head.insertBefore(style, ref)
|
||||
}
|
||||
}
|
||||
remote.value = defineAsyncComponent(() => loadModule('remote.vue', options))
|
||||
}
|
||||
const handleFocus = () => {
|
||||
focus.value = true;
|
||||
nextTick(() => {
|
||||
inputInstRef.value && (inputInstRef.value as any).focus();
|
||||
});
|
||||
};
|
||||
const handleBlur = () => {
|
||||
focus.value = false;
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.out-div{
|
||||
width: 100%;
|
||||
.header{
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
.component-name-div{
|
||||
width: 300px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
.content-div{
|
||||
height: calc(100vh - 61px);
|
||||
display: flex;
|
||||
.code-div{
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
}
|
||||
.show-div{
|
||||
width: 50%;
|
||||
height: 100%;
|
||||
background: #282c34;
|
||||
border-left: 4px solid;
|
||||
}
|
||||
}
|
||||
}
|
||||
:deep(.v-codemirror) {
|
||||
font-size: 16px; /* 设置字体大小 */
|
||||
line-height: 1.5; /* 设置行高,提升可读性 */
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<template>
|
||||
<div class="">远程组件List</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {} from "vue"
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
Loading…
Reference in New Issue