|
|
@@ -19,12 +19,25 @@
|
|
|
hide-required-asterisk
|
|
|
>
|
|
|
<el-form-item :label="$t('projectName')" prop="name">
|
|
|
- <el-input v-model="formData.name" :placeholder="$t('pleaseEnter')"></el-input>
|
|
|
+ <el-input
|
|
|
+ v-model="formData.name"
|
|
|
+ :placeholder="$t('pleaseEnter')"
|
|
|
+ spellcheck="false"
|
|
|
+ ></el-input>
|
|
|
</el-form-item>
|
|
|
<el-form-item :label="$t('projectPath')" prop="path" required>
|
|
|
<el-input v-model="formData.path" readonly>
|
|
|
<template #append>
|
|
|
- <el-button @click="selectPath"
|
|
|
+ <el-button @click="selectPath('path')"
|
|
|
+ ><LuFolder :size="16" :disabled="mode === 'edit'"
|
|
|
+ /></el-button>
|
|
|
+ </template>
|
|
|
+ </el-input>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item :label="$t('codePath')" prop="codePath" required>
|
|
|
+ <el-input v-model="formData.codePath" readonly>
|
|
|
+ <template #append>
|
|
|
+ <el-button @click="selectPath('codePath')"
|
|
|
><LuFolder :size="16" :disabled="mode === 'edit'"
|
|
|
/></el-button>
|
|
|
</template>
|
|
|
@@ -163,42 +176,74 @@
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="PCLK">
|
|
|
- <el-input v-model="item.params.PCLK" />
|
|
|
+ <el-input-number
|
|
|
+ controls-position="right"
|
|
|
+ style="width: 100%"
|
|
|
+ v-model="item.params.PCLK"
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="VBP">
|
|
|
- <el-input v-model="item.params.VBP" />
|
|
|
+ <el-input-number
|
|
|
+ controls-position="right"
|
|
|
+ style="width: 100%"
|
|
|
+ v-model="item.params.VBP"
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="VFP">
|
|
|
- <el-input v-model="item.params.VFP" />
|
|
|
+ <el-input-number
|
|
|
+ controls-position="right"
|
|
|
+ style="width: 100%"
|
|
|
+ v-model="item.params.VFP"
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="HFP">
|
|
|
- <el-input v-model="item.params.HFP" />
|
|
|
+ <el-input-number
|
|
|
+ controls-position="right"
|
|
|
+ style="width: 100%"
|
|
|
+ v-model="item.params.HFP"
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="HSYNC">
|
|
|
- <el-input v-model="item.params.HSYNC" />
|
|
|
+ <el-input-number
|
|
|
+ controls-position="right"
|
|
|
+ style="width: 100%"
|
|
|
+ v-model="item.params.HSYNC"
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="VSYNC">
|
|
|
- <el-input v-model="item.params.VSYNC" />
|
|
|
+ <el-input-number
|
|
|
+ controls-position="right"
|
|
|
+ style="width: 100%"
|
|
|
+ v-model="item.params.VSYNC"
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="HsyncWidth">
|
|
|
- <el-input v-model="item.params.HsyncWidth" />
|
|
|
+ <el-input-number
|
|
|
+ controls-position="right"
|
|
|
+ style="width: 100%"
|
|
|
+ v-model="item.params.HsyncWidth"
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
<el-col :span="8">
|
|
|
<el-form-item label="VsyncWidth">
|
|
|
- <el-input v-model="item.params.VsyncWidth" />
|
|
|
+ <el-input-number
|
|
|
+ controls-position="right"
|
|
|
+ style="width: 100%"
|
|
|
+ v-model="item.params.VsyncWidth"
|
|
|
+ />
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
@@ -349,11 +394,13 @@
|
|
|
</el-row>
|
|
|
</el-form>
|
|
|
</el-scrollbar>
|
|
|
- <div class="w-200px shrink-0">最近项目</div>
|
|
|
+ <div class="w-200px shrink-0 flex flex-col">
|
|
|
+ <Recent @opened="close" />
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
<template #footer>
|
|
|
- <el-button @click="showModal = false">{{ $t('cancel') }}</el-button>
|
|
|
+ <el-button @click="close">{{ $t('cancel') }}</el-button>
|
|
|
<el-button type="primary" @click="mode === 'add' ? handleSubmit() : handleEdit()">{{
|
|
|
$t('create')
|
|
|
}}</el-button>
|
|
|
@@ -384,11 +431,13 @@
|
|
|
<script setup lang="ts">
|
|
|
import type { AppMeta } from '@/types/appMeta'
|
|
|
import { ElMessage, type FormInstance } from 'element-plus'
|
|
|
-import { computed, reactive, ref, defineExpose, nextTick } from 'vue'
|
|
|
+import { computed, reactive, ref, nextTick, watch } from 'vue'
|
|
|
import { LuFolder } from 'vue-icons-plus/lu'
|
|
|
import { useProjectStore } from '@/store/modules/project'
|
|
|
+import { useRecentProject } from '@/store/modules/recentProject'
|
|
|
import { useAppStore } from '@/store/modules/app'
|
|
|
import { useI18n } from 'vue-i18n'
|
|
|
+import Recent from './Recent.vue'
|
|
|
|
|
|
import chipConfig from '@/config/multi_chip_config.json'
|
|
|
import boardConfig from '@/config/board_card_config.json'
|
|
|
@@ -397,6 +446,10 @@ import { klona } from 'klona'
|
|
|
|
|
|
const { t } = useI18n()
|
|
|
const mode = ref<'add' | 'edit'>('add')
|
|
|
+const projectStore = useProjectStore()
|
|
|
+const appStore = useAppStore()
|
|
|
+const recentProject = useRecentProject()
|
|
|
+
|
|
|
const formData = reactive<
|
|
|
AppMeta & {
|
|
|
path: string
|
|
|
@@ -404,8 +457,9 @@ const formData = reactive<
|
|
|
>({
|
|
|
version: '1.0.0',
|
|
|
description: '',
|
|
|
- name: 'ProjectName',
|
|
|
+ name: '',
|
|
|
path: 'D:\\sunmicroDesignerProjects',
|
|
|
+ codePath: 'D:\\sunmicroDesignerProjects',
|
|
|
type: 'chip',
|
|
|
chip: {
|
|
|
model: '',
|
|
|
@@ -452,8 +506,12 @@ const formData = reactive<
|
|
|
imageCompress: []
|
|
|
})
|
|
|
|
|
|
-const projectStore = useProjectStore()
|
|
|
-const appStore = useAppStore()
|
|
|
+watch(
|
|
|
+ () => recentProject.recentProjects,
|
|
|
+ () => {
|
|
|
+ formData.name = `projectName${(recentProject.recentProjects?.length || 0) + 1}`
|
|
|
+ }
|
|
|
+)
|
|
|
|
|
|
const form = ref<FormInstance>()
|
|
|
// 显示模态框
|
|
|
@@ -468,17 +526,32 @@ const customScreen = ref({
|
|
|
})
|
|
|
// 项目类型选项
|
|
|
const typeOptions = computed(() => {
|
|
|
- console.log(appStore.lang)
|
|
|
- return [
|
|
|
- { label: t('chip'), value: 'chip' },
|
|
|
- { label: t('board'), value: 'board' },
|
|
|
- { label: t('analogDisplay'), value: 'analog_display' }
|
|
|
- ]
|
|
|
+ return (
|
|
|
+ appStore.lang && [
|
|
|
+ { label: t('chip'), value: 'chip' },
|
|
|
+ { label: t('board'), value: 'board' },
|
|
|
+ { label: t('analogDisplay'), value: 'analog_display' }
|
|
|
+ ]
|
|
|
+ )
|
|
|
})
|
|
|
|
|
|
const rules = computed(() => {
|
|
|
return {
|
|
|
- name: [{ required: true, message: t('nameRequired'), trigger: 'blur' }],
|
|
|
+ name: [
|
|
|
+ { required: true, message: t('nameRequired'), trigger: 'blur' },
|
|
|
+ {
|
|
|
+ trigger: 'blur',
|
|
|
+ validator: (_rule, val, callback) => {
|
|
|
+ const names = recentProject.recentProjects?.map((item) => item.projectName) || []
|
|
|
+ if (names.includes(val)) {
|
|
|
+ callback(new Error(t('nameRepeat')))
|
|
|
+ } else {
|
|
|
+ callback()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ codePath: [{ required: true, message: t('codePathRequired'), trigger: 'blur' }],
|
|
|
'chip.model': [{ required: true, message: t('chipIsRequired'), trigger: 'blur' }],
|
|
|
'chip.flash_size.capacity': [
|
|
|
{ required: true, message: t('flashIsRequired'), trigger: 'blur' }
|
|
|
@@ -498,12 +571,12 @@ const handlChangeType = (type: string) => {
|
|
|
handleChangeScreenTypeByAnalog(formData.screenType)
|
|
|
}
|
|
|
|
|
|
-// 选择项目路径
|
|
|
-const selectPath = async () => {
|
|
|
+// 选择文件夹路径
|
|
|
+const selectPath = async (key: string) => {
|
|
|
const path = await window.electron.ipcRenderer.invoke('get-directory')
|
|
|
|
|
|
if (path) {
|
|
|
- formData.path = path
|
|
|
+ formData[key] = path
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -757,9 +830,10 @@ const handleChangeScreenTypeByAnalog = (type: any) => {
|
|
|
const handleSubmit = async () => {
|
|
|
await form.value?.validate()
|
|
|
if (formData.type === 'board' && !formData.board.model) {
|
|
|
- ElMessage.warning('请选择板卡')
|
|
|
+ ElMessage.warning(t('selectBoard'))
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
projectStore.createApp(formData)
|
|
|
form.value?.resetFields()
|
|
|
showModal.value = false
|
|
|
@@ -770,6 +844,13 @@ const handleEdit = async () => {
|
|
|
await form.value?.validate()
|
|
|
}
|
|
|
|
|
|
+// 关闭弹窗
|
|
|
+const close = () => {
|
|
|
+ console.log('close')
|
|
|
+ form.value?.resetFields()
|
|
|
+ showModal.value = false
|
|
|
+}
|
|
|
+
|
|
|
// expose
|
|
|
defineExpose({
|
|
|
create: async () => {
|