diff --git a/package-lock.json b/package-lock.json index 91c739e..7eb36fe 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,7 +19,7 @@ "core-js": "^3.6.5", "cropperjs": "^1.6.1", "dayjs": "^1.10.7", - "element-plus": "^2.3.7", + "element-plus": "^2.6.3", "fontfaceobserver": "^2.1.0", "html2canvas": "^1.4.1", "mitt": "^3.0.1", @@ -1972,9 +1972,9 @@ "dev": true }, "node_modules/element-plus": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.6.1.tgz", - "integrity": "sha512-6VRpLjwtIVdtUuITJPPKtpOH1NM6nuAkRE3q5O4Lrx0N1bYMhTkiqb2Jy7zfQuDPbOIkkF2OABTzegpNnzgsnQ==", + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.6.3.tgz", + "integrity": "sha512-U4L/mr+1r+EmAUYUHrs0V/8hHMdBGP07rPymSC72LZCN4jK1UwygQYICegTQ5us4mxeqBvW6wfoEfo003fwCqw==", "dependencies": { "@ctrl/tinycolor": "^3.4.1", "@element-plus/icons-vue": "^2.3.1", diff --git a/package.json b/package.json index 65b5f35..a18ed3a 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,7 @@ "core-js": "^3.6.5", "cropperjs": "^1.6.1", "dayjs": "^1.10.7", - "element-plus": "^2.3.7", + "element-plus": "^2.6.3", "fontfaceobserver": "^2.1.0", "html2canvas": "^1.4.1", "mitt": "^3.0.1", diff --git a/src/assets/styles/design.less b/src/assets/styles/design.less index 5f4bd77..55fe310 100644 --- a/src/assets/styles/design.less +++ b/src/assets/styles/design.less @@ -55,6 +55,16 @@ &-item { padding: 1rem; cursor: pointer; + display: inline-flex; + align-items: center; + .icon { + // font-size: 18px; + color: #333333; + } + .text { + font-weight: 600; + margin-left: .4rem; + } } .disable { cursor: not-allowed; @@ -62,37 +72,11 @@ } } } - // .top-title { - // color: @color-black; - // cursor: pointer; - // flex: 1; - // padding-left: 3.2rem; - // // font-weight: bold; - // .input-wrap { - // width: 15rem; - // :deep(input) { - // border: none; - // } - // } - // } - // .top-icon-wrap { - // display: flex; - // align-items: center; - // padding-right: 20px; - // height: @height2; - // .top-icon { - // background-color: rgba(0, 0, 0, 0.4); - // border-radius: 5px; - // color: @color-white; - // cursor: pointer; - // font-weight: bold; - // margin: 8px; - // padding: 5px 8px; - // &:hover { - // background-color: rgba(0, 0, 0, 0.5); - // } - // } - // } + .primary-btn { + font-weight: 600; + transform: scale(0.95); + margin-left: 10px; + } } } .page-design-index-wrap { @@ -109,21 +93,6 @@ // .page-design-index-wrap ::-webkit-scrollbar { // display: none; /* Chrome Safari */ // } - - .extra-operation { - cursor: pointer; - position: relative; - margin-left: 52px; - } - .extra-operation::after { - position: absolute; - content: ''; - left: -50px; - background: #e8eaec; - height: 17px; - width: 1px; - margin: 7px 0 0 18px; - } .shelter, .shelter-bg { position: absolute; diff --git a/src/components/business/aigc/sd.vue b/src/components/business/aigc/sd.vue deleted file mode 100644 index 6999b35..0000000 --- a/src/components/business/aigc/sd.vue +++ /dev/null @@ -1,578 +0,0 @@ - - - - - AIGC(动漫风格大模型) - - - - - 文生图 - 图生图 - 后期处理 - - - 参考图 - - - - - - - - 在此拖入或选择上传图片 - 支持 jpg/png 格式,大小不超过 500kb - - - - - - 均衡 - 偏向提示词 - 偏向原图 - - - - 提示词 (不支持中文) - - - 翻译文本 - - 相关提示词 - - - - - 套用预设 - - - - 取消 - {{ p.name }} - - - - - - 图片比例 - - - {{ item.label }} - {{ item.text }} - - - - - 高级设置 - - - - - - - 免责声明 - - - 在线生成 - - - - - - {{ listLoading ? '刷新中...' : '任务列表' }} - - 空间容量: {{ listData.length }} / {{ limit }} - - - - - {{ i.created_time }} - - {{ i.dp ? '下载进度:' + i.dp + '%' : '' }} - - - - - - - - - - - - - - - - 生成失败 - {{ i.progress ? `生成中 ${i.progress} %` : '排队中...' }} - - - - - - - - - - - - - - diff --git a/src/components/modules/panel/wrap/UserWrap.vue b/src/components/modules/panel/wrap/UserWrap.vue index e84b2e6..cea46e0 100644 --- a/src/components/modules/panel/wrap/UserWrap.vue +++ b/src/components/modules/panel/wrap/UserWrap.vue @@ -3,7 +3,7 @@ * @Date: 2022-02-13 22:18:35 * @Description: 我的 * @LastEditors: ShawnPhang - * @LastEditTime: 2024-03-11 01:42:44 + * @LastEditTime: 2024-04-03 21:00:26 --> @@ -13,9 +13,9 @@ - 上传图片 + 上传图片 - 上传 PSD 模板 + 导入 PSD - * @LastEditTime: 2023-11-30 10:09:55 + * @LastEditTime: 2024-04-04 00:33:01 */ import { useControlStore, useWidgetStore } from '@/store' import { TdWidgetData } from '@/store/design/widget' @@ -13,19 +13,19 @@ const controlStore = useControlStore() const widgetStore = useWidgetStore() export default function keyCodeOptions(e: any, params: any) { - const { f } = params + const { range } = params switch (e.keyCode) { case 38: - udlr('top', -1 * f, e) + udlr('top', -1 * range, e) break case 40: - udlr('top', Number(f), e) + udlr('top', Number(range), e) break case 37: - udlr('left', -1 * f, e) + udlr('left', -1 * range, e) break case 39: - udlr('left', Number(f), e) + udlr('left', Number(range), e) break case 46: case 8: diff --git a/src/mixins/scKeyCodes.ts b/src/mixins/scKeyCodes.ts new file mode 100644 index 0000000..be2fe37 --- /dev/null +++ b/src/mixins/scKeyCodes.ts @@ -0,0 +1,70 @@ +/* + * @Author: ShawnPhang + * @Date: 2024-04-04 00:36:13 + * @Description: 快捷键支持列表 + * @LastEditors: ShawnPhang + * @LastEditTime: 2024-04-05 05:56:27 + */ +const ctrlKey = isMacOS() ? `⌘` : `Ctrl` +function isMacOS() { + return navigator.userAgent.includes(`Macintosh`) || navigator.userAgent.includes(`Mac OS X`) +} + +export default [ + { + feat: `拖拽画布`, + info: `空格 + 鼠标拖拽`, + }, + { + feat: `画布缩小`, + info: `${ctrlKey} - / ${ctrlKey} + 滚轮`, + }, + { + feat: `画布放大`, + info: `${ctrlKey} + / ${ctrlKey} + 滚轮`, + }, + { + feat: `保存`, + info: `${ctrlKey} + S`, + }, + { + feat: `撤销`, + info: `${ctrlKey} + Z`, + }, + { + feat: `重做`, + info: `${ctrlKey} + Shift + Z`, + }, + { + feat: `元素移动`, + info: `← ↑ → ↓`, + }, + { + feat: `快速移动`, + info: `Shift + ← ↑ → ↓`, + }, + { + feat: `复制`, + info: `${ctrlKey} + C`, + }, + { + feat: `粘贴`, + info: `${ctrlKey} + V`, + }, + { + feat: `删除`, + info: `Delete / Backspace`, + }, + { + feat: `多选`, + info: `${ctrlKey} / Shift + 点选`, + }, + { + feat: `成组`, + info: `${ctrlKey} + G`, + }, + { + feat: `取消选中`, + info: `ESC`, + }, +] diff --git a/src/mixins/shortcuts.ts b/src/mixins/shortcuts.ts index 34d00f3..19ccf92 100644 --- a/src/mixins/shortcuts.ts +++ b/src/mixins/shortcuts.ts @@ -3,12 +3,8 @@ * @Date: 2021-08-01 14:12:08 * @Description: 快捷键,目前是mixin形式放入views/index.vue中 * @LastEditors: ShawnPhang - * @LastEditTime: 2023-09-19 17:29:06 + * @LastEditTime: 2024-04-04 00:36:19 */ -// import store from '@/store' -// const _this: any = {} -// _this.dHistoryParams = store.getters.dHistoryParams - import keyCodeOptions from './methods/keyCodeOptions' import dealWithCtrl from './methods/dealWithCtrl' import { TControlStore } from '@/store/design/control' @@ -16,21 +12,6 @@ import { useControlStore, useWidgetStore } from '@/store' const ignoreNode = ['INPUT', 'TEXTAREA'] -// 系统组合键 -const systemKeyCode = [ - { - // ctrl+r刷新 - key: ['ctrlKey', 'metaKey'], - code: 82, - }, - { - // ctrl+alt+i打开开发者 - key: ['ctrlKey', 'metaKey'], - key2: ['altKey'], - code: 73, - }, -] - let hadDown = false const appContainer: any = document.querySelector('#app') const controlStore = useControlStore() @@ -53,11 +34,7 @@ const shortcuts = { const ctrl = e.key === 'Control' || e.key === 'Meta' const alt = e.key === 'Alt' const shift = e.key === 'Shift' - // const dir = e.keyCode === 37 || e.keyCode === 38 || e.keyCode === 39 || e.keyCode === 40 - // const specialKey = ctrl || alt || shift || dir - // if (specialKey || e.metaKey) { - // hadDown = false - // } + if (shift || ctrl) { store.updateAltDown(true) // store.dispatch('updateAltDown', true) @@ -72,28 +49,6 @@ const shortcuts = { } }, 500) } - // const systemKey = systemKeyCode.find((item) => { - // let f = false - // let f2 = false - // for (let i = 0; i < item.key.length; ++i) { - // f = e[item.key[i]] - // if (f) { - // break - // } - // } - // if (item.key2) { - // for (let i = 0; i < item.key2.length; ++i) { - // f2 = e[item.key2[i]] - // if (f2) { - // break - // } - // } - // } - // return f && f2 && e.keyCode === item.code - // }) - // if (systemKey) { - // return - // } const withCtrl = e.ctrlKey || e.metaKey if (withCtrl && !(ctrl || alt || shift)) { dealCtrl(e, instance) @@ -104,20 +59,9 @@ const shortcuts = { // return // } const withShift = e.shiftKey - // if (withShift && !specialKey) { - // return - // } - // // TODO - // if (!this.dActiveElement) { - // return - // } - // if (this.dActiveElement.uuid === '-1') { - // return - // } - // e.stopPropagation() - // e.preventDefault() - const f = withShift ? 10 : 1 - keyCodeOptions(e, { f }) + + const range = withShift ? 10 : 1 + keyCodeOptions(e, { range }) } }, handleKeyup(store: TControlStore, checkCtrl: number | undefined) { diff --git a/src/utils/axios.ts b/src/utils/axios.ts index 90491e6..975912e 100644 --- a/src/utils/axios.ts +++ b/src/utils/axios.ts @@ -1,29 +1,25 @@ /* * @Author: ShawnPhang * @Date: 2021-07-13 02:48:38 - * @Description: 本地测试项目请勿修改此文件 - * @LastEditors: ShawnPhang , Jeremy Yu - * @LastEditTime: 2024-02-26 17:54:00 + * @Description: 本地测试用户身份写死 + * @LastEditors: ShawnPhang + * @LastEditTime: 2024-04-03 20:56:23 */ import axios, { AxiosRequestConfig, AxiosResponse, AxiosStatic } from 'axios' -// import store from '@/store' import app_config, { LocalStorageKey } from '@/config' import { useBaseStore, useUserStore } from '@/store/index'; axios.defaults.timeout = 30000 -axios.defaults.headers.authorization = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTAwMDEsImV4cCI6MTc4ODU3NDc1MDU4NX0.L_t6DFD48Dm6rUPfgIgOWJkz18En1m_-hhMHcpbxliY'; +// axios.defaults.headers.authorization = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTAwMDEsImV4cCI6MTc4ODU3NDc1MDU4NX0.L_t6DFD48Dm6rUPfgIgOWJkz18En1m_-hhMHcpbxliY'; +const defaultToken = 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6MTAwMDEsImV4cCI6MTc4ODU3NDc1MDU4NX0.L_t6DFD48Dm6rUPfgIgOWJkz18En1m_-hhMHcpbxliY'; // const version = app_config.VERSION; const baseUrl = app_config.API_URL // 请求拦截器 axios.interceptors.request.use( (config: AxiosRequestConfig) => { - // const access_token = store.state.currentUser.access_token; const url = config.url ?? "" const values = {} - // values.access_token = access_token; - // values.version = version; - if (!url.startsWith('http://') && !url.startsWith('https://')) { config.url = url.startsWith('/') ? baseUrl + url : config.url = baseUrl + '/' + url } @@ -48,7 +44,6 @@ axios.interceptors.request.use( axios.interceptors.response.use((res: AxiosResponse) => { // store.dispatch('hideLoading'); // 接口规则:只有正确code为200时返回result结果对象,错误返回整个结果对象 - if (!res.data) { return Promise.reject(res) } @@ -95,9 +90,9 @@ const fetch = ( // store.commit('loading', '加载中..'); } - const token = localStorage.getItem(LocalStorageKey.tokenKey) + const token = defaultToken//localStorage.getItem(LocalStorageKey.tokenKey) const headerObject: Record = {} - token && (headerObject.authorization = token) + token && (headerObject.Authorization = token) if (type === 'get') { return axios.get(url, { diff --git a/src/views/Index.vue b/src/views/Index.vue index d2c8a31..30fceb2 100644 --- a/src/views/Index.vue +++ b/src/views/Index.vue @@ -4,7 +4,7 @@ * @Description: * @LastEditors: ShawnPhang * @LastUpdateContent: Support typescript - * @LastEditTime: 2024-04-03 10:58:42 + * @LastEditTime: 2024-04-05 05:34:43 --> @@ -16,22 +16,29 @@ - - - + + 文件 + 帮助 + + - + + 保存 + 下载作品 + - + - + @@ -50,6 +57,8 @@ @cancel="downloadCancel" @done="state.downloadPercent = 0" /> + + @@ -67,12 +76,21 @@ import lineGuides from '@/components/modules/layout/lineGuides.vue' import shortcuts from '@/mixins/shortcuts' // import wGroup from '@/components/modules/widgets/wGroup/wGroup.vue' import HeaderOptions from './components/HeaderOptions.vue' +import Folder from './components/Folder.vue' +import Helper from './components/Helper.vue' import ProgressLoading from '@/components/common/ProgressLoading/download.vue' // import { useSetupMapGetters } from '@/common/hooks/mapGetters' import { useRoute } from 'vue-router' import { wGroupSetting } from '@/components/modules/widgets/wGroup/groupSetting' import { storeToRefs } from 'pinia' import { useCanvasStore, useControlStore, useHistoryStore, useWidgetStore, useGroupStore } from '@/store' +import type { ButtonInstance } from 'element-plus' +import Tour from './components/Tour.vue' + +const ref1 = ref() +const ref2 = ref() +const ref3 = ref() +const ref4 = ref() type TState = { style: CSSProperties @@ -93,8 +111,7 @@ const groupStore = useGroupStore() const { dPage } = storeToRefs(useCanvasStore()) const { dZoom } = storeToRefs(useCanvasStore()) const { dHistoryParams } = storeToRefs(useHistoryStore()) -const { dActiveElement, dCopyElement } = storeToRefs(widgetStore) - +// const { dActiveElement, dCopyElement } = storeToRefs(widgetStore) const state = reactive({ style: { @@ -129,10 +146,6 @@ function jump2home() { window.open('https://xp.palxp.cn/') } -defineExpose({ - jump2home, -}) - const undoable = computed(() => { return !( dHistoryParams.value.index === -1 || @@ -216,15 +229,32 @@ function fixTopBarScroll() { state.style.left = `-${scrollLeft}px` } -// function clickListener(e: Event) { -// console.log('click listener', e) -// } - function optionsChange({ downloadPercent, downloadText, downloadMsg }: { downloadPercent: number, downloadText: string, downloadMsg?: string }) { state.downloadPercent = downloadPercent state.downloadText = downloadText state.downloadMsg = downloadMsg } + +const tourRef = ref() +const fns: any = { + openTour: () => { + tourRef.value.open() + }, + save: () => { + optionsRef.value?.save(false) + }, + download: () => { + optionsRef.value?.download() + }, + changeLineGuides +} +const dealWith = (fnName: string, params?: any) => { + fns[fnName](params) +} + +defineExpose({ + jump2home, +}) diff --git a/src/views/components/HeaderOptions.vue b/src/views/components/HeaderOptions.vue index 6eac4a3..7d2ce94 100644 --- a/src/views/components/HeaderOptions.vue +++ b/src/views/components/HeaderOptions.vue @@ -3,7 +3,7 @@ * @Date: 2022-01-12 11:26:53 * @Description: 顶部操作按钮组 * @LastEditors: ShawnPhang - * @LastEditTime: 2024-04-03 12:21:25 + * @LastEditTime: 2024-04-05 05:37:53 --> @@ -17,10 +17,10 @@ | - 保存 - - 下载作品 - + + + + @@ -34,7 +34,7 @@ import _dl from '@/common/methods/download' import useNotification from '@/common/methods/notification' import SaveImage from '@/components/business/save-download/CreateCover.vue' import { useFontStore } from '@/common/methods/fonts' -import copyRight from './CopyRight.vue' +// import copyRight from './CopyRight.vue' import _config from '@/config' import useConfirm from '@/common/methods/confirm' import { useControlStore, useHistoryStore, useCanvasStore, useUserStore, useWidgetStore } from '@/store/index' @@ -136,6 +136,7 @@ async function saveTemp() { } async function download() { if (state.loading === true) { + useNotification('作品导出中', '当前有作品正在导出,请稍候再试') return } // 临时提示 @@ -173,7 +174,11 @@ async function saveTemp() { state.loading = false } }) - emit('change', { downloadPercent: 100, downloadText: '作品下载成功', downloadMsg: '仅供学习、研究或欣赏等用途,暂不提供商业授权。' }) + emit('change', { downloadPercent: 100, downloadText: '作品下载成功', downloadMsg: '该作品仅供学习、研究或欣赏等用途,暂不提供商业授权。' }) + state.loading = false + } else { + emit('change', { downloadPercent: 0, downloadText: '请稍候..' }) + useNotification('作品为空', '无法下载,请先创建设计', { type: 'error' }) state.loading = false } }, 100) @@ -257,9 +262,10 @@ defineExpose({ .top-title { color: @color-black; flex: 1; - padding-left: 88px; + padding-left: 20px; // font-weight: bold; .input-wrap { + // box-shadow: none; width: 15rem; :deep(input) { border-color: #ffffff; @@ -268,7 +274,7 @@ defineExpose({ } .input-wrap:hover { :deep(input) { - border-color: #e8eaec; + // border-color: #e8eaec; } } } @@ -277,7 +283,6 @@ defineExpose({ transform: scale(0.95); margin-left: 10px; } - .divide__line { margin: 0 1rem; color: #e8eaec; diff --git a/src/views/components/Helper.vue b/src/views/components/Helper.vue new file mode 100644 index 0000000..b6ca4e1 --- /dev/null +++ b/src/views/components/Helper.vue @@ -0,0 +1,94 @@ + + + + + + + + + + 快捷键 + + + + {{ sc.feat }}{{ sc.info }} + + + + 快捷键 + 新手引导 + 反馈或建议 + + + + + + + + diff --git a/src/views/components/Tour.vue b/src/views/components/Tour.vue new file mode 100644 index 0000000..0a528e4 --- /dev/null +++ b/src/views/components/Tour.vue @@ -0,0 +1,40 @@ + + + + + 点击文件菜单,管理你的设计,设置页面视图等操作。 + + + + + + + + diff --git a/src/views/components/UploadTemplate.vue b/src/views/components/UploadTemplate.vue index 81b7e93..9a67685 100644 --- a/src/views/components/UploadTemplate.vue +++ b/src/views/components/UploadTemplate.vue @@ -2,8 +2,8 @@ * @Author: ShawnPhang * @Date: 2022-07-12 11:26:53 * @Description: 上传用户模板 - * @LastEditors: ShawnPhang - * @LastEditTime: 2023-07-14 09:17:56 + * @LastEditors: ShawnPhang + * @LastEditTime: 2024-04-03 20:57:29 --> 上传模板 @@ -136,7 +136,7 @@ async function uploadImgs() { const { id, stat, msg } = await api.home.saveWorks({ cover, title: '自设计模板', data: JSON.stringify({ page, widgets }), width: page.width, height: page.height }) stat !== 0 ? useNotification('保存成功', '可在"我的模板"中查看') : useNotification('保存失败', msg, { type: 'error' }) router.push({ path: '/psd', query: { id }, replace: true }) - emit('change', { downloadPercent: 99.99, downloadText: '上传完成', cancelText: '查看我的作品' }) // 关闭弹窗 + emit('change', { downloadPercent: 99.99, downloadText: '上传完成', cancelText: '点击查看作品' }) // 关闭弹窗 } defineExpose({