diff --git a/.env.base b/.env.base deleted file mode 100644 index cf433822..00000000 --- a/.env.base +++ /dev/null @@ -1,19 +0,0 @@ -# 本地开发环境 -NODE_ENV=development - -VITE_DEV=true - -# 请求路径 -VITE_BASE_URL='http://127.0.0.1:48080' - -# 上传路径 -VITE_UPLOAD_URL='http://127.0.0.1:48080/admin-api/infra/file/upload' - -# 接口前缀 -VITE_API_BASEPATH=/dev-api - -# 接口地址 -VITE_API_URL=/admin-api - -# 打包路径 -VITE_BASE_PATH=/ diff --git a/.env.dev b/.env.dev index 9200ece2..21ffa920 100644 --- a/.env.dev +++ b/.env.dev @@ -1,13 +1,13 @@ -# 开发环境 +# 开发环境:本地只启动前端项目,依赖开发环境(后端、APP) NODE_ENV=development -VITE_DEV=false +VITE_DEV=true # 请求路径 -VITE_BASE_URL='http://localhost:48080' +VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn' # 上传路径 -VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload' +VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload' # 接口前缀 VITE_API_BASEPATH=/dev-api @@ -15,17 +15,23 @@ VITE_API_BASEPATH=/dev-api # 接口地址 VITE_API_URL=/admin-api -# 打包路径 -VITE_BASE_PATH=/ - # 是否删除debugger -VITE_DROP_DEBUGGER=true +VITE_DROP_DEBUGGER=false # 是否删除console.log VITE_DROP_CONSOLE=false # 是否sourcemap -VITE_SOURCEMAP=false +VITE_SOURCEMAP=true + +# 打包路径 +VITE_BASE_PATH=/ # 输出路径 VITE_OUT_DIR=dist + +# 商城H5会员端域名 +VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn' + +# 验证码的开关 +VITE_APP_CAPTCHA_ENABLE=false diff --git a/.env.front b/.env.local-dev similarity index 53% rename from .env.front rename to .env.local-dev index 1629ff9f..2eb968c4 100644 --- a/.env.front +++ b/.env.local-dev @@ -1,13 +1,13 @@ -# 本地开发环境 +# 本地开发环境:本地启动所有项目(前端、后端、APP)时使用,不依赖外部环境 NODE_ENV=development VITE_DEV=true # 请求路径 -VITE_BASE_URL='http://api-dashboard.yudao.iocoder.cn' +VITE_BASE_URL='http://localhost:48080' # 上传路径 -VITE_UPLOAD_URL='http://api-dashboard.yudao.iocoder.cn/admin-api/infra/file/upload' +VITE_UPLOAD_URL='http://localhost:48080/admin-api/infra/file/upload' # 接口前缀 VITE_API_BASEPATH=/dev-api @@ -15,12 +15,6 @@ VITE_API_BASEPATH=/dev-api # 接口地址 VITE_API_URL=/admin-api -# 打包路径 -VITE_BASE_PATH=/ - -# 项目本地运行端口号, 与.vscode/launch.json配合 -VITE_PORT=80 - # 是否删除debugger VITE_DROP_DEBUGGER=false @@ -28,7 +22,13 @@ VITE_DROP_DEBUGGER=false VITE_DROP_CONSOLE=false # 是否sourcemap -VITE_SOURCEMAP=true +VITE_SOURCEMAP=false + +# 打包路径 +VITE_BASE_PATH=/ + +# 商城H5会员端域名 +VITE_MALL_H5_DOMAIN='http://localhost:3000' # 验证码的开关 VITE_APP_CAPTCHA_ENABLE=false diff --git a/.env.pro b/.env.prod similarity index 75% rename from .env.pro rename to .env.prod index 8348e02e..070b43a7 100644 --- a/.env.pro +++ b/.env.prod @@ -1,4 +1,4 @@ -# 生产环境 +# 生产环境:只在打包时使用 NODE_ENV=production VITE_DEV=false @@ -28,4 +28,7 @@ VITE_SOURCEMAP=false VITE_BASE_PATH=/ # 输出路径 -VITE_OUT_DIR=dist-pro +VITE_OUT_DIR=dist-prod + +# 商城H5会员端域名 +VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn' diff --git a/.env.stage b/.env.stage index d7157fbb..c0edf340 100644 --- a/.env.stage +++ b/.env.stage @@ -1,4 +1,4 @@ -# 生产环境 +# 预发布环境:只在打包时使用 NODE_ENV=production VITE_DEV=false @@ -29,3 +29,6 @@ VITE_BASE_PATH='http://static-vue3.yudao.iocoder.cn/' # 输出路径 VITE_OUT_DIR=dist-stage + +# 商城H5会员端域名 +VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn' diff --git a/.env.static b/.env.test similarity index 76% rename from .env.static rename to .env.test index 034a7f4d..217ac6e2 100644 --- a/.env.static +++ b/.env.test @@ -1,4 +1,4 @@ -# 开发环境 +# 测试环境:只在打包时使用 NODE_ENV=production VITE_DEV=false @@ -28,4 +28,7 @@ VITE_SOURCEMAP=false VITE_BASE_PATH=/admin-ui-vue3/ # 输出路径 -VITE_OUT_DIR=dist-dev +VITE_OUT_DIR=dist-test + +# 商城H5会员端域名 +VITE_MALL_H5_DOMAIN='http://mall.yudao.iocoder.cn' diff --git a/package.json b/package.json index bc01d35f..2bf975ca 100644 --- a/package.json +++ b/package.json @@ -6,18 +6,17 @@ "private": false, "scripts": { "i": "pnpm install", - "dev": "vite --mode base", - "front": "vite --mode front", + "local-dev": "vite --mode local-dev", + "dev": "vite --mode dev", "ts:check": "vue-tsc --noEmit", - "build:pro": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode pro", + "build:local-dev": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode local-dev", "build:dev": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode dev", - "build:base": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode base", + "build:test": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode test", "build:stage": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode stage", - "build:static": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode static", - "build:front": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode front", - "serve:pro": "vite preview --mode pro", + "build:prod": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build --mode prod", "serve:dev": "vite preview --mode dev", - "preview": "pnpm build:base && vite preview", + "serve:prod": "vite preview --mode prod", + "preview": "pnpm build:local-dev && vite preview", "clean": "npx rimraf node_modules", "clean:cache": "npx rimraf node_modules/.cache", "lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src", diff --git a/src/components/AppLinkInput/AppLinkSelectDialog.vue b/src/components/AppLinkInput/AppLinkSelectDialog.vue index a536ac13..63f19662 100644 --- a/src/components/AppLinkInput/AppLinkSelectDialog.vue +++ b/src/components/AppLinkInput/AppLinkSelectDialog.vue @@ -29,10 +29,11 @@ :key="appLinkIndex" :content="appLink.path" placement="bottom" + :show-after="300" > {{ appLink.name }} @@ -63,7 +64,7 @@ diff --git a/src/components/DiyEditor/components/ComponentLibrary.vue b/src/components/DiyEditor/components/ComponentLibrary.vue index e319a5c2..64b2febc 100644 --- a/src/components/DiyEditor/components/ComponentLibrary.vue +++ b/src/components/DiyEditor/components/ComponentLibrary.vue @@ -82,7 +82,9 @@ watch( // 克隆组件 const handleCloneComponent = (component: DiyComponent) => { - return cloneDeep(component) + const instance = cloneDeep(component) + instance.uid = new Date().getTime() + return instance } diff --git a/src/components/DiyEditor/components/mobile/Carousel/property.vue b/src/components/DiyEditor/components/mobile/Carousel/property.vue index 972ba507..c3a51542 100644 --- a/src/components/DiyEditor/components/mobile/Carousel/property.vue +++ b/src/components/DiyEditor/components/mobile/Carousel/property.vue @@ -39,87 +39,60 @@ - 拖动左上角的小圆点可对其排序 - diff --git a/src/components/DiyEditor/components/mobile/FloatingActionButton/config.ts b/src/components/DiyEditor/components/mobile/FloatingActionButton/config.ts new file mode 100644 index 00000000..fcf129f1 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/FloatingActionButton/config.ts @@ -0,0 +1,36 @@ +import { DiyComponent } from '@/components/DiyEditor/util' + +// 悬浮按钮属性 +export interface FloatingActionButtonProperty { + // 展开方向 + direction: 'horizontal' | 'vertical' + // 是否显示文字 + showText: boolean + // 按钮列表 + list: FloatingActionButtonItemProperty[] +} + +// 悬浮按钮项属性 +export interface FloatingActionButtonItemProperty { + // 图片地址 + imgUrl: string + // 跳转连接 + url: string + // 文字 + text: string + // 文字颜色 + textColor: string +} + +// 定义组件 +export const component = { + id: 'FloatingActionButton', + name: '悬浮按钮', + icon: 'tabler:float-right', + position: 'fixed', + property: { + direction: 'vertical', + showText: true, + list: [{ textColor: '#fff' }] + } +} as DiyComponent diff --git a/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue b/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue new file mode 100644 index 00000000..19e42cb6 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/FloatingActionButton/index.vue @@ -0,0 +1,74 @@ + + + + diff --git a/src/components/DiyEditor/components/mobile/FloatingActionButton/property.vue b/src/components/DiyEditor/components/mobile/FloatingActionButton/property.vue new file mode 100644 index 00000000..5db08d0e --- /dev/null +++ b/src/components/DiyEditor/components/mobile/FloatingActionButton/property.vue @@ -0,0 +1,44 @@ + + + + + diff --git a/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/controller.ts b/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/controller.ts new file mode 100644 index 00000000..a7bd7622 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/controller.ts @@ -0,0 +1,143 @@ +import { HotZoneItemProperty } from '@/components/DiyEditor/components/mobile/HotZone/config' +import { StyleValue } from 'vue' + +// 热区的最小宽高 +export const HOT_ZONE_MIN_SIZE = 100 + +// 控制的类型 +export enum CONTROL_TYPE_ENUM { + LEFT, + TOP, + WIDTH, + HEIGHT +} + +// 定义热区的控制点 +export interface ControlDot { + position: string + types: CONTROL_TYPE_ENUM[] + style: StyleValue +} + +// 热区的8个控制点 +export const CONTROL_DOT_LIST = [ + { + position: '左上角', + types: [ + CONTROL_TYPE_ENUM.LEFT, + CONTROL_TYPE_ENUM.TOP, + CONTROL_TYPE_ENUM.WIDTH, + CONTROL_TYPE_ENUM.HEIGHT + ], + style: { left: '-5px', top: '-5px', cursor: 'nwse-resize' } + }, + { + position: '上方中间', + types: [CONTROL_TYPE_ENUM.TOP, CONTROL_TYPE_ENUM.HEIGHT], + style: { left: '50%', top: '-5px', cursor: 'n-resize', transform: 'translateX(-50%)' } + }, + { + position: '右上角', + types: [CONTROL_TYPE_ENUM.TOP, CONTROL_TYPE_ENUM.WIDTH, CONTROL_TYPE_ENUM.HEIGHT], + style: { right: '-5px', top: '-5px', cursor: 'nesw-resize' } + }, + { + position: '右侧中间', + types: [CONTROL_TYPE_ENUM.WIDTH], + style: { right: '-5px', top: '50%', cursor: 'e-resize', transform: 'translateX(-50%)' } + }, + { + position: '右下角', + types: [CONTROL_TYPE_ENUM.WIDTH, CONTROL_TYPE_ENUM.HEIGHT], + style: { right: '-5px', bottom: '-5px', cursor: 'nwse-resize' } + }, + { + position: '下方中间', + types: [CONTROL_TYPE_ENUM.HEIGHT], + style: { left: '50%', bottom: '-5px', cursor: 's-resize', transform: 'translateX(-50%)' } + }, + { + position: '左下角', + types: [CONTROL_TYPE_ENUM.LEFT, CONTROL_TYPE_ENUM.WIDTH, CONTROL_TYPE_ENUM.HEIGHT], + style: { left: '-5px', bottom: '-5px', cursor: 'nesw-resize' } + }, + { + position: '左侧中间', + types: [CONTROL_TYPE_ENUM.LEFT, CONTROL_TYPE_ENUM.WIDTH], + style: { left: '-5px', top: '50%', cursor: 'w-resize', transform: 'translateX(-50%)' } + } +] as ControlDot[] + +//region 热区的缩放 +// 热区的缩放比例 +export const HOT_ZONE_SCALE_RATE = 2 +// 缩小:缩回适合手机屏幕的大小 +export const zoomOut = (list?: HotZoneItemProperty[]) => { + return ( + list?.map((hotZone) => ({ + ...hotZone, + left: (hotZone.left /= HOT_ZONE_SCALE_RATE), + top: (hotZone.top /= HOT_ZONE_SCALE_RATE), + width: (hotZone.width /= HOT_ZONE_SCALE_RATE), + height: (hotZone.height /= HOT_ZONE_SCALE_RATE) + })) || [] + ) +} +// 放大:作用是为了方便在电脑屏幕上编辑 +export const zoomIn = (list?: HotZoneItemProperty[]) => { + return ( + list?.map((hotZone) => ({ + ...hotZone, + left: (hotZone.left *= HOT_ZONE_SCALE_RATE), + top: (hotZone.top *= HOT_ZONE_SCALE_RATE), + width: (hotZone.width *= HOT_ZONE_SCALE_RATE), + height: (hotZone.height *= HOT_ZONE_SCALE_RATE) + })) || [] + ) +} +//endregion + +/** + * 封装热区拖拽 + * + * 注:为什么不使用vueuse的useDraggable。在本场景下,其使用方式比较复杂 + * @param hotZone 热区 + * @param downEvent 鼠标按下事件 + * @param callback 回调函数 + */ +export const useDraggable = ( + hotZone: HotZoneItemProperty, + downEvent: MouseEvent, + callback: ( + left: number, + top: number, + width: number, + height: number, + moveWidth: number, + moveHeight: number + ) => void +) => { + // 阻止事件冒泡 + downEvent.stopPropagation() + + // 移动前的鼠标坐标 + const { clientX: startX, clientY: startY } = downEvent + // 移动前的热区坐标、大小 + const { left, top, width, height } = hotZone + + // 监听鼠标移动 + document.onmousemove = (e) => { + // 移动宽度 + const moveWidth = e.clientX - startX + // 移动高度 + const moveHeight = e.clientY - startY + // 移动回调 + callback(left, top, width, height, moveWidth, moveHeight) + } + + // 松开鼠标后,结束拖拽 + document.onmouseup = () => { + document.onmousemove = null + document.onmouseup = null + } +} diff --git a/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/index.vue b/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/index.vue new file mode 100644 index 00000000..39250572 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/HotZone/components/HotZoneEditDialog/index.vue @@ -0,0 +1,236 @@ + + + + + diff --git a/src/components/DiyEditor/components/mobile/HotZone/config.ts b/src/components/DiyEditor/components/mobile/HotZone/config.ts new file mode 100644 index 00000000..9dcebcc2 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/HotZone/config.ts @@ -0,0 +1,42 @@ +import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util' + +/** 热区属性 */ +export interface HotZoneProperty { + // 图片地址 + imgUrl: string + // 导航菜单列表 + list: HotZoneItemProperty[] + // 组件样式 + style: ComponentStyle +} +/** 热区项目属性 */ +export interface HotZoneItemProperty { + // 链接的名称 + name: string + // 链接 + url: string + // 宽 + width: number + // 高 + height: number + // 上 + top: number + // 左 + left: number +} + +// 定义组件 +export const component = { + id: 'HotZone', + name: '热区', + icon: 'tabler:hand-click', + property: { + imgUrl: '', + list: [] as HotZoneItemProperty[], + style: { + bgType: 'color', + bgColor: '#fff', + marginBottom: 8 + } as ComponentStyle + } +} as DiyComponent diff --git a/src/components/DiyEditor/components/mobile/HotZone/index.vue b/src/components/DiyEditor/components/mobile/HotZone/index.vue new file mode 100644 index 00000000..3a9b842e --- /dev/null +++ b/src/components/DiyEditor/components/mobile/HotZone/index.vue @@ -0,0 +1,42 @@ + + + + + diff --git a/src/components/DiyEditor/components/mobile/HotZone/property.vue b/src/components/DiyEditor/components/mobile/HotZone/property.vue new file mode 100644 index 00000000..495cbdce --- /dev/null +++ b/src/components/DiyEditor/components/mobile/HotZone/property.vue @@ -0,0 +1,63 @@ + + + + + diff --git a/src/components/DiyEditor/components/mobile/MenuGrid/property.vue b/src/components/DiyEditor/components/mobile/MenuGrid/property.vue index b92e2099..7940fd0f 100644 --- a/src/components/DiyEditor/components/mobile/MenuGrid/property.vue +++ b/src/components/DiyEditor/components/mobile/MenuGrid/property.vue @@ -9,72 +9,50 @@ - 菜单设置 - 拖动左侧的小圆点可以调整顺序 - diff --git a/src/components/DiyEditor/components/mobile/MenuList/property.vue b/src/components/DiyEditor/components/mobile/MenuList/property.vue index 0ed6035c..a5fb4603 100644 --- a/src/components/DiyEditor/components/mobile/MenuList/property.vue +++ b/src/components/DiyEditor/components/mobile/MenuList/property.vue @@ -5,55 +5,34 @@ -
- - - -
- - - 添加菜单 - - + + +
diff --git a/src/components/DiyEditor/components/mobile/MenuSwiper/index.vue b/src/components/DiyEditor/components/mobile/MenuSwiper/index.vue index 6ae6439c..f8e2bbc6 100644 --- a/src/components/DiyEditor/components/mobile/MenuSwiper/index.vue +++ b/src/components/DiyEditor/components/mobile/MenuSwiper/index.vue @@ -28,7 +28,7 @@ 菜单设置 - 拖动左侧的小圆点可以调整顺序 - diff --git a/src/components/DiyEditor/components/mobile/NoticeBar/config.ts b/src/components/DiyEditor/components/mobile/NoticeBar/config.ts index 03e7143a..b6b0860d 100644 --- a/src/components/DiyEditor/components/mobile/NoticeBar/config.ts +++ b/src/components/DiyEditor/components/mobile/NoticeBar/config.ts @@ -1,4 +1,4 @@ -import { DiyComponent } from '@/components/DiyEditor/util' +import { ComponentStyle, DiyComponent } from '@/components/DiyEditor/util' /** 公告栏属性 */ export interface NoticeBarProperty { @@ -10,6 +10,8 @@ export interface NoticeBarProperty { backgroundColor: string // 文字颜色 textColor: string + // 组件样式 + style: ComponentStyle } /** 内容属性 */ @@ -34,6 +36,11 @@ export const component = { } ], backgroundColor: '#fff', - textColor: '#333' + textColor: '#333', + style: { + bgType: 'color', + bgColor: '#fff', + marginBottom: 8 + } as ComponentStyle } } as DiyComponent diff --git a/src/components/DiyEditor/components/mobile/NoticeBar/property.vue b/src/components/DiyEditor/components/mobile/NoticeBar/property.vue index a3eefebe..7129d7cb 100644 --- a/src/components/DiyEditor/components/mobile/NoticeBar/property.vue +++ b/src/components/DiyEditor/components/mobile/NoticeBar/property.vue @@ -1,58 +1,37 @@ diff --git a/src/components/DiyEditor/components/mobile/Popover/config.ts b/src/components/DiyEditor/components/mobile/Popover/config.ts new file mode 100644 index 00000000..e8140900 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/Popover/config.ts @@ -0,0 +1,26 @@ +import { DiyComponent } from '@/components/DiyEditor/util' + +/** 弹窗广告属性 */ +export interface PopoverProperty { + list: PopoverItemProperty[] +} + +export interface PopoverItemProperty { + // 图片地址 + imgUrl: string + // 跳转连接 + url: string + // 显示类型:仅显示一次、每次启动都会显示 + showType: 'once' | 'always' +} + +// 定义组件 +export const component = { + id: 'Popover', + name: '弹窗广告', + icon: 'carbon:popup', + position: 'fixed', + property: { + list: [{ showType: 'once' }] + } +} as DiyComponent diff --git a/src/components/DiyEditor/components/mobile/Popover/index.vue b/src/components/DiyEditor/components/mobile/Popover/index.vue new file mode 100644 index 00000000..347599b3 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/Popover/index.vue @@ -0,0 +1,38 @@ + + + + diff --git a/src/components/DiyEditor/components/mobile/Popover/property.vue b/src/components/DiyEditor/components/mobile/Popover/property.vue new file mode 100644 index 00000000..6535e3b2 --- /dev/null +++ b/src/components/DiyEditor/components/mobile/Popover/property.vue @@ -0,0 +1,38 @@ + + + + + diff --git a/src/components/DiyEditor/components/mobile/SearchBar/property.vue b/src/components/DiyEditor/components/mobile/SearchBar/property.vue index d121a1e3..90027027 100644 --- a/src/components/DiyEditor/components/mobile/SearchBar/property.vue +++ b/src/components/DiyEditor/components/mobile/SearchBar/property.vue @@ -1,81 +1,64 @@