diff --git a/CHANGELOG.md b/CHANGELOG.md index 068a5bb..487a437 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,3 @@ -# 1.0.0 (2022-04-13) - -前端架构搭建完毕,目前使用vue这块最新,最前沿的技术栈 - -基于vbenAdmin2.8.0重构 - -非常感谢所有通过代码(下面列出的作者)或GitHub上的评论和分类对这个版本做出贡献的人: - -[Vben Admin](https://vvbin.cn/doc-next/) - -[长沙康来生物有限公司-王翔](https://github.com/wangxiang4/wangxiang4) +# 1.0.0 (2023-01-16) +海豚生态计划-打造一个web端,安卓端,ios端的一个海豚开发平台生态圈,不接收任何商业化,并且完全免费开源(包含高级功能)。 diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..ce469c9 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023-PRESENT Dolphin Ecology + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index b733138..2246ff0 100644 --- a/README.md +++ b/README.md @@ -1,66 +1,166 @@ -# 🐇`kicc-ui`(康来智慧冷链-UI) 基于Vue3的中后台系统 © 长沙康来生物有限公司版权所有 - -## 🔥 当前版本 -`1.0.0` 基础功能已完善,后续功能正在加紧迭代开发中。 - -## 💡 简介 - -kicc-ui 是基于vben Admin的模板开发,使用了最新的`vue3`,`vite2`,`TypeScript`等主流技术,支持标本箱配送,监控,地图路线规划, -努力做成中国最好的智慧冷链平台。 - -## 💥 技术特性 - +

+ +
+
+

+ +

一个快速开发软件的平台

+ +

+ Website • + Documentation +

+ +
+ + + + + + + + + +
+ +## 🐬 介绍 +海豚生态计划-打造一个web端,安卓端,ios端的一个海豚开发平台生态圈,不接收任何商业化,并且完全免费开源(包含高级功能)。 + +## 💪 愿景 +让人人都可以快速高效的开发软件 + +## ✨ 特性 - **最新技术栈**:使用 Vue3/vite2 等前端前沿技术开发 -- **TypeScript**: 应用程序级 JavaScript 的语言 +- **TypeScript**: 集成TypeScript管控项目,具有可预测的静态类型,提高了代码的可读性、可维护性和可靠性 - **主题**:可配置的主题 - **国际化**:内置完善的国际化方案 -- **Mock 数据** 内置 Mock 数据方案 -- **权限** 内置完善的动态路由权限生成方案 -- **组件** 二次封装了多个常用的组件 - -## 🧬 开发准备前,你必须所需要具备的技术 +- **权限**:内置完善的动态嵌套路由权限生成实现 +- **组件**:二次封装了多个常用的组件 +- **地图**:高德地图在线规划路线导航 +- **多租户**:使用SASS提供独立的、隔离的数据管理,在线无缝切换多个租户数据 +- **动画**:内部默认实现大量的动画过渡、让组件切换更加丝滑 +- **UI组件库**:集成ant-design-vue,提供了一系列高质量、易于使用的组件,可快速迭代项目开发 +- **图表组件**:集成echarts让图表组件开箱即用,提供了各种类型的图表和强大的可定制性 +- **工具**:集成lodash,@vueuse/core,降低相关API的学习成本,提高工作效率,封装了诸多常用的函数和操作,让写vue3也可以甜甜的 +- **状态管理**:集成pinia采用了基于函数式编程的方式来处理状态的更新和变化,更加直观的 API 和高性能的响应式状态管理方案 +- **可拖拽**:集成SortableJS提供了用于创建可排序列表和网格的功能,可以用于实现拖放排序等交互式用户界面 +- **富文本编辑器**:一个基于 JavaScript 的所见即所得的富文本编辑器,TinyMCE的功能非常灵活和高度可定制,开源版功能也比较齐全 +- **高级表格组件**:集成vxe-table提供了丰富的表格功能和灵活的配置选项,可以用于展示和编辑各种类型的数据,同时也支持异步数据和虚拟滚动等优化性能的特性 +- **渐进式网络应用程序**:集成vite-plugin-pwa,用于将Vue.js或其他前端应用程序转换为具有离线缓存和本地存储能力的PWA + +## 黑客节 +加入[Github HackToberFest](https://hacktoberfest.com/) 开始为此项目做出贡献. + +## 🔨 开发目录 -- [node](http://nodejs.org/) 和 [git](https://git-scm.com/) -项目开发环境 -- [Vite](https://vitejs.dev/) - 熟悉 vite 特性 -- [Vue3](https://v3.vuejs.org/) - 熟悉 Vue 基础语法 -- [TypeScript](https://www.typescriptlang.org/) - 熟悉`TypeScript`基本语法 -- [Es6+](http://es6.ruanyifeng.com/) - 熟悉 es6 基本语法 -- [Vue-Router-Next](https://next.router.vuejs.org/) - 熟悉 vue-router 基本使用 -- [Ant-Design-Vue](https://2x.antdv.com/docs/vue/introduce-cn/) - ui 基本使用 -- [Mock.js](https://github.com/nuysoft/Mock) - mockjs 基本语法 +``` +├─ dolphin-admin -- 海豚vue3-管理系统 +│ ├─build -- 构建打包配置 +│ │ ├─config -- 通用配置 +│ │ ├─generate -- 资源生成配置(less变量,icon) +│ │ ├─script -- 附加构建脚本 +│ │ ├─vite -- vite配置 +│ ├─docker -- docker容器配置 +│ ├─public -- 公共资源目录 +│ ├─src -- 开发的目录 +│ │ ├─api -- 请求接口 +│ │ │ ├─common -- 通用请求数据类型(根据后端通用实体类定义) +│ │ │ │ ├─base -- 基础类型 +│ │ │ │ ├─data -- 数据类型 +│ │ │ ├─platform -- 微服务框架平台业务api +│ │ │ │ ├─common -- 通用业务模块api +│ │ │ │ ├─core -- 系统核心业务api +│ │ │ │ ├─monitor -- 运维监控业务模块api +│ │ │ │ ├─system -- 系统业务模块api +│ │ ├─assets -- 开发资源目录(会被打包编译) +│ │ ├─components -- 全局组件 +│ │ │ ├─AMap -- 高德地图设计器 +│ │ │ ├─Application -- 应用核心组件 +│ │ │ ├─Authority -- 角色权限控制 +│ │ │ ├─Basic -- 系统基础组件 +│ │ │ ├─Button -- 按钮 +│ │ │ ├─ClickOutSide -- 元素点击监听包装 +│ │ │ ├─Container -- 组件包装容器 +│ │ │ ├─ContextMenu -- 右击菜单上下文 +│ │ │ ├─CountDown -- 验证码倒计时 +│ │ │ ├─CountTo -- 计数器 +│ │ │ ├─Cropper -- 图片裁剪 +│ │ │ ├─Description -- 详细页面 +│ │ │ ├─Drawer -- 弹出抽屉 +│ │ │ ├─Dropdown -- 下拉列表 +│ │ │ ├─Excel -- Excel导入导出 +│ │ │ ├─Form -- 动态表单 +│ │ │ ├─Icon -- icon图标 +│ │ │ ├─Loading -- 加载遮罩层 +│ │ │ ├─Markdown -- Markdown编辑器 +│ │ │ ├─Menu -- 顶部菜单模式菜单 +│ │ │ ├─Modal -- 弹出模态框 +│ │ │ ├─Page -- 页面包装 +│ │ │ ├─Qrcode -- 二维码生成 +│ │ │ ├─Scrollbar -- 滚动条 +│ │ │ ├─SimpleMenu -- 侧边栏菜单 +│ │ │ ├─StrengthMeter -- 密码强度检查 +│ │ │ ├─Table -- 动态表格 +│ │ │ ├─Time -- 当前时间显示 +│ │ │ ├─Tinymce -- 功能齐全的富文本编辑器 +│ │ │ ├─Transition -- 过度动画 +│ │ │ ├─Tree -- 树形控件 +│ │ │ ├─Upload -- 文件上传 +│ │ ├─directives -- 自定义指令 +│ │ ├─enums -- 全局枚举 +│ │ ├─hooks -- vue组合API钩子工具 +│ │ │ ├─component -- 组件相关钩子 +│ │ │ ├─core -- 系统核心相关钩子 +│ │ │ ├─event -- 事件相关钩子 +│ │ │ ├─setting -- 全局设置相关钩子 +│ │ │ ├─web -- 网页相关钩子 +│ │ ├─layouts -- 系统总布局 +│ │ │ ├─default -- 默认总系统布局框架组件 +│ │ │ ├─iframe -- 内嵌页面 +│ │ │ ├─page -- 路由模块页面 +│ │ ├─locales -- 国际化 +│ │ ├─logics -- 系统全局控制逻辑 +│ │ ├─router -- 路由 +│ │ ├─settings -- 默认全局设置配置 +│ │ ├─store -- 全局状态管理 +│ │ ├─utils -- 工具类 +│ │ │ ├─auth -- 存储授权信息缓存 +│ │ │ ├─cache -- 缓存实例工具 +│ │ │ ├─event -- 事件工具 +│ │ │ ├─factory -- 组件工厂 +│ │ │ ├─file -- 文件工具 +│ │ │ ├─helper -- 路由转换帮助工具 +│ │ │ ├─http -- api请求工具 +│ │ │ ├─lib -- 图表组件库 +│ │ ├─views -- 页面模块组件 +│ │ │ ├─common -- 通用业务页面 +│ │ │ ├─core -- 系统核心业务页面 +│ │ │ ├─dashboard -- 仪表板分析页面 +│ │ │ ├─level -- 多级菜单页面 +│ │ │ ├─monitor -- 运维监控业务页面 +│ │ │ ├─system -- 系统业务页面 +│ ├─types -- 全局类型定义 +``` ## 🍀 需要注意的地方 -##1.钩子工具跟项目基础工具区别 -- **hooks目录: 基于Vue3-Composition-API二次封装的使用实用程序的组合api,目的为了扩展@vueuse/core组合api** -- **utils目录: 二次封装,或原生写的工具类,不会去使用一些框架的钩子** - -```bash -两者的区别: - 可以理解为两者都是工具,但是区别在于utils目录没有使用Vue3-Composition-API封装, - hooks目录使用了Vue3-Composition-API,hooks目录说的在明白一点就是在扩展自己的Vue3-Composition-API -``` -**Vue3-Composition-API官方介绍: https://staging-cn.vuejs.org/guide/extras/composition-api-faq.html** - -#2.打包前应该如何执行typescript类型检查 +### 1.打包前应该如何执行typescript类型检查 - **vite是不支持typescript类型检查,因为没必要,现在的开发工具都是支持eslint的,让开发工具接管类型检查就行啦** - **vite官网TypeScript介绍:https://vitejs.bootcss.com/guide/features.html#typescript** -- **注意:既然vite不支持typescript类型检查,那我们就应该要在发布编译阶段手动执行 vue-tsc 命令检查类型,要不然完全体现不出typescript在项目中的作用,使用了typescript就应该要检查代码是否符合类型规范** +- **注意:既然vite不支持typescript类型检查,那我们就应该要在发布编译阶段手动执行 vue-tsc 命令检查类型是否符合typescript类型规范** -## 🗽 启动项目 -```bash +## 🤔 一起讨论 +加入我们的 [Discord](https://discord.gg/DREuQWrRYQ) 开始与大家交流。 -# 进入项目目录 -cd kicc-ui +## 🤗 我想成为开发团队的一员! +欢迎😀!我们正在寻找有才华的开发者加入我们,让海豚开发平台变得更好!如果您想加入开发团队,请联系我们,非常欢迎您加入我们!💖 -# 安装依赖 -yarn install +## 在线一键设置 +您可以使用 Gitpod,一个在线 IDE(开源免费)来在线贡献或运行示例。 -# 运行 -yarn serve +[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/wangxiang4/dolphin-admin) -# 打包 -yarn build +## 📄 执照 +[Dolphin Development Platform 是获得MIT许可](https://github.com/wangxiang4/dolphin-admin/blob/master/LICENSE) 的开源软件 。 -``` diff --git a/src/api/platform/core/entity/upload.ts b/src/api/platform/core/entity/upload.ts index ed8b941..b8069c0 100644 --- a/src/api/platform/core/entity/upload.ts +++ b/src/api/platform/core/entity/upload.ts @@ -6,9 +6,7 @@ * @create: 2022/4/8 */ +import type { File as OssFile } from '/@/api/platform/system/entity/file'; + /** oss上传返回结果对象 */ -export interface UploadResult { - bucketName: string; - fileName: string; - url: string; -} +export type UploadResult = OssFile diff --git a/src/api/platform/system/controller/region.ts b/src/api/platform/system/controller/region.ts index 0736a59..d77c627 100644 --- a/src/api/platform/system/controller/region.ts +++ b/src/api/platform/system/controller/region.ts @@ -16,22 +16,13 @@ enum Api { del = '/system_proxy/system/region/remove' } -export const listRegion = (params?: Partial) => { - let url = Api.lazyList; - if (params?.name || params?.code || params?.beginTime || params?.endTime) url = Api.list; - return defHttp.get({ url: url, params }); -}; - -export const listRegionCascade = (params?: Partial) => defHttp.get({ url: Api.lazyList, params }).then(res => { - return res.map(item => { - const { children, ...result } = item; - return { ...result, isLeaf: !!!children }; - }); -}); - -export const addRegion = (params:Partial) => defHttp.post({ url: Api.add,data:params }); - -export const editRegion = (params:Partial) => defHttp.put({ url: Api.edit,data:params }); +export const listRegion = (params?: Partial) => defHttp.get({ url: Api.list, params }); + +export const lazyListRegion = (params?: Partial) => defHttp.get({ url: Api.lazyList, params }); + +export const addRegion = (params:Partial) => defHttp.post({ url: Api.add, data: params }); + +export const editRegion = (params:Partial) => defHttp.put({ url: Api.edit, data: params }); export const getRegion = (id: string) => defHttp.get>({ url: `${Api.get}/${id}` }); diff --git a/src/api/platform/system/controller/user.ts b/src/api/platform/system/controller/user.ts index 4b7215b..dd03857 100644 --- a/src/api/platform/system/controller/user.ts +++ b/src/api/platform/system/controller/user.ts @@ -14,7 +14,6 @@ enum Api { add = '/system_proxy/system/user/save', get = '/system_proxy/system/user', edit = '/system_proxy/system/user/update', - editUser = '/system_proxy/system/user/updateUser', del = '/system_proxy/system/user/remove', updatePwd = '/system_proxy/system/user/updatePwd', resetPwd='/system_proxy/system/user/resetPwd', @@ -31,11 +30,8 @@ export const listUser = (params?: Partial) => defHttp.get) => defHttp.post({ url: Api.add, data: params }); -/** 修改用户关联用户角色表 */ -export const editUserRole = (params: Partial) => defHttp.put({ url: Api.edit, data: params }); - /** 修改用户 */ -export const editUser = (params: Partial) => defHttp.put({ url: Api.editUser, data: params }); +export const editUser = (params: Partial) => defHttp.put({ url: Api.edit, data: params }); /** 查询用户详细 */ export const getUser = (id: string) => defHttp.get({ url: `${Api.get}/${id}` }); diff --git a/src/api/platform/system/entity/file.ts b/src/api/platform/system/entity/file.ts index 48ebd98..c578a17 100644 --- a/src/api/platform/system/entity/file.ts +++ b/src/api/platform/system/entity/file.ts @@ -19,6 +19,9 @@ export interface File extends CommonEntity { original: string; type: string; fileSize: number; + availablePath: string; + duration: number; + mimeType: string; [key: string]: any; } diff --git a/src/components/AMap/src/AMapDesigner/index.vue b/src/components/AMap/src/AMapDesigner/index.vue index c737ebf..60ed5f8 100644 --- a/src/components/AMap/src/AMapDesigner/index.vue +++ b/src/components/AMap/src/AMapDesigner/index.vue @@ -112,11 +112,11 @@ import { useDebounceFn } from '@vueuse/core'; import { EventSourcePolyfill } from 'event-source-polyfill/src/eventsource'; import { getAccessToken } from '/@/utils/auth'; + import { useTimeoutFn } from '@vueuse/core' /** 类型规范统一声明定义区域 */ interface MapState { first: boolean; - loading: boolean; defaultZoom: number; toggleOperatePanelClass: Recordable; toggleStatus: boolean; @@ -168,8 +168,6 @@ const mapState = reactive({ /** 首次初始化 */ first: false, - /** 遮罩层状态 */ - loading: false, /** 默认缩放大小 */ defaultZoom: 7, /** 面板类样式属性 */ @@ -242,53 +240,75 @@ onBeforeMount(() => { if (!instance) return; - mapState.loading = true; // 初始化高德地图组件 AMapLoader.load({ key: mapState.mapConfig.amapKey, version: '2.0', plugins: ['AMap.MarkerCluster', 'AMap.Driving'] }).then(async AMap => { - // 创建地图实例 - map = new AMap.Map(instance.refs.mapview, mapState.mapConfig.options); - map.plugin(['AMap.ToolBar', 'AMap.MapType', 'AMap.ControlBar', 'AMap.Scale'], () => { - if (mapProps.mapControl?.includes('toolBar')) { - // 地图操作工具条插件 - map.addControl(new AMap.ToolBar()); - } - if (mapProps.mapControl?.includes('controlBar')) { - // 组合了旋转,倾斜,复位,缩放插件 - map.addControl(new AMap.ControlBar()); - } - if (mapProps.mapControl?.includes('scale')) { - // 比例尺插件 - const scale = new AMap.Scale(); - scale.show(); - map.addControl(scale); - } - if (mapProps.mapControl?.includes('mapType')) { - // 地图类型切换插件 - map.addControl( - new AMap.MapType({ - defaultType: 0, - showRoad: true - }) - ); - } - }); - map.on('zoomchange', ctx => { - mapState.defaultZoom = subtract(divide(map.getZoom(),2), 1); - }); + useTimeoutFn(() => { + // 创建地图实例 + map = new AMap.Map(instance.refs.mapview, mapState.mapConfig.options); + map.plugin(['AMap.ToolBar', 'AMap.MapType', 'AMap.ControlBar', 'AMap.Scale'], () => { + if (mapProps.mapControl?.includes('toolBar')) { + // 地图操作工具条插件 + map.addControl(new AMap.ToolBar()); + } + if (mapProps.mapControl?.includes('controlBar')) { + // 组合了旋转,倾斜,复位,缩放插件 + map.addControl(new AMap.ControlBar()); + } + if (mapProps.mapControl?.includes('scale')) { + // 比例尺插件 + const scale = new AMap.Scale(); + scale.show(); + map.addControl(scale); + } + if (mapProps.mapControl?.includes('mapType')) { + // 地图类型切换插件 + map.addControl( + new AMap.MapType({ + defaultType: 0, + showRoad: true + }) + ); + } + }); + map.on('zoomchange', ctx => { + mapState.defaultZoom = subtract(divide(map.getZoom(),2), 1); + }); - // 医院集群标记点 - hospitalMarkerCluster = new AMap.MarkerCluster(map, [], { - gridSize: 80, - maxZoom: 14, - renderMarker(ctx) { - const { marker, data } = ctx; - if (Array.isArray(data) && data[0]) { - const { label, mapOrientation, mapNotify } = data[0]; - let content = ``; + // 医院集群标记点 + hospitalMarkerCluster = new AMap.MarkerCluster(map, [], { + gridSize: 80, + maxZoom: 14, + renderMarker(ctx) { + const { marker, data } = ctx; + if (Array.isArray(data) && data[0]) { + const { label, mapOrientation, mapNotify } = data[0]; + let content = ``; + marker.setLabel({ + direction: 'bottom', + // 设置文本标注偏移量 + offset: new AMap.Pixel(-4, 0), + // 设置文本标注内容 + content: `
${label}
` + }); + marker.setOffset(new AMap.Pixel(-18, -10)); + if (mapNotify) { + content = ``; + } + marker.setContent(content); + } + }, + renderClusterMarker(ctx) { + const { clusterData, marker, count } = ctx; + let content = ``; + if(clusterData.some(item => item.mapNotify)){ + content = ``; + } + marker.setContent(content); + const label = count == 1 ? clusterData[0].label : `医院数量:${count}`; marker.setLabel({ direction: 'bottom', // 设置文本标注偏移量 @@ -297,45 +317,38 @@ content: `
${label}
` }); marker.setOffset(new AMap.Pixel(-18, -10)); - if (mapNotify) { - content = ``; - } - marker.setContent(content); - } - }, - renderClusterMarker(ctx) { - const { clusterData, marker, count } = ctx; - let content = ``; - if(clusterData.some(item => item.mapNotify)){ - content = ``; } - marker.setContent(content); - const label = count == 1 ? clusterData[0].label : `医院数量:${count}`; - marker.setLabel({ - direction: 'bottom', - // 设置文本标注偏移量 - offset: new AMap.Pixel(-4, 0), - // 设置文本标注内容 - content: `
${label}
` - }); - marker.setOffset(new AMap.Pixel(-18, -10)); - } - }); - hospitalMarkerCluster.on('click', ctx => { - const { lnglat } = ctx; - map.setZoomAndCenter(18, lnglat); - }); + }); + hospitalMarkerCluster.on('click', ctx => { + const { lnglat } = ctx; + map.setZoomAndCenter(18, lnglat); + }); - // 医检机构集群标记点 - orgMarkerCluster = new AMap.MarkerCluster(map, [], { - gridSize: 80, - maxZoom: 14, - renderMarker(ctx) { - const { marker, data } = ctx; - if (Array.isArray(data) && data[0]) { - const { label, mapOrientation } = data[0]; - const content = ``; + // 医检机构集群标记点 + orgMarkerCluster = new AMap.MarkerCluster(map, [], { + gridSize: 80, + maxZoom: 14, + renderMarker(ctx) { + const { marker, data } = ctx; + if (Array.isArray(data) && data[0]) { + const { label, mapOrientation } = data[0]; + const content = ``; + marker.setContent(content); + marker.setLabel({ + direction: 'bottom', + // 设置文本标注偏移量 + offset: new AMap.Pixel(-4, 0), + // 设置文本标注内容 + content: `
${label}
` + }); + marker.setOffset(new AMap.Pixel(-18, -10)); + } + }, + renderClusterMarker(ctx) { + const { clusterData, marker, count } = ctx; + const content = ``; marker.setContent(content); + const label = count == 1 ? clusterData[0].label : `医检机构数量:${count}`; marker.setLabel({ direction: 'bottom', // 设置文本标注偏移量 @@ -345,37 +358,37 @@ }); marker.setOffset(new AMap.Pixel(-18, -10)); } - }, - renderClusterMarker(ctx) { - const { clusterData, marker, count } = ctx; - const content = ``; - marker.setContent(content); - const label = count == 1 ? clusterData[0].label : `医检机构数量:${count}`; - marker.setLabel({ - direction: 'bottom', - // 设置文本标注偏移量 - offset: new AMap.Pixel(-4, 0), - // 设置文本标注内容 - content: `
${label}
` - }); - marker.setOffset(new AMap.Pixel(-18, -10)); - } - }); - orgMarkerCluster.on('click', ctx => { - const { lnglat } = ctx; - map.setZoomAndCenter(18, lnglat); - }); + }); + orgMarkerCluster.on('click', ctx => { + const { lnglat } = ctx; + map.setZoomAndCenter(18, lnglat); + }); - // 收样员集群标记点 - courierUserMarkerCluster = new AMap.MarkerCluster(map, [], { - gridSize: 80, - maxZoom: 14, - renderMarker(ctx) { - const { marker, data } = ctx; - if (Array.isArray(data) && data[0]) { - const { label, mapOrientation } = data[0]; - const content = ``; + // 收样员集群标记点 + courierUserMarkerCluster = new AMap.MarkerCluster(map, [], { + gridSize: 80, + maxZoom: 14, + renderMarker(ctx) { + const { marker, data } = ctx; + if (Array.isArray(data) && data[0]) { + const { label, mapOrientation } = data[0]; + const content = ``; + marker.setContent(content); + marker.setLabel({ + direction: 'bottom', + // 设置文本标注偏移量 + offset: new AMap.Pixel(-4, 0), + // 设置文本标注内容 + content: `
${label}
` + }); + marker.setOffset(new AMap.Pixel(-18, -10)); + } + }, + renderClusterMarker(ctx) { + const { clusterData, marker, count } = ctx; + const content = ``; marker.setContent(content); + const label = count == 1 ? clusterData[0].label : `收样员数量:${count}`; marker.setLabel({ direction: 'bottom', // 设置文本标注偏移量 @@ -385,102 +398,87 @@ }); marker.setOffset(new AMap.Pixel(-18, -10)); } - }, - renderClusterMarker(ctx) { - const { clusterData, marker, count } = ctx; - const content = ``; - marker.setContent(content); - const label = count == 1 ? clusterData[0].label : `收样员数量:${count}`; - marker.setLabel({ - direction: 'bottom', - // 设置文本标注偏移量 - offset: new AMap.Pixel(-4, 0), - // 设置文本标注内容 - content: `
${label}
` - }); - marker.setOffset(new AMap.Pixel(-18, -10)); - } - }); - courierUserMarkerCluster.on('click', ctx => { - const { lnglat } = ctx; - map.setZoomAndCenter(18, lnglat); - }); + }); + courierUserMarkerCluster.on('click', ctx => { + const { lnglat } = ctx; + map.setZoomAndCenter(18, lnglat); + }); - // 扫描收样员园形范围 - scanCourierUserCircleRange = new AMap.Circle({ - radius: 14000, - borderWeight: 3, - strokeColor: '#3600ff', - strokeOpacity: 0, - strokeWeight: 6, - fillOpacity: 0, - strokeStyle: 'dashed', - strokeDasharray: [8, 8], - fillColor: '#1791fc', - zIndex: 50 - }); + // 扫描收样员园形范围 + scanCourierUserCircleRange = new AMap.Circle({ + radius: 14000, + borderWeight: 3, + strokeColor: '#3600ff', + strokeOpacity: 0, + strokeWeight: 6, + fillOpacity: 0, + strokeStyle: 'dashed', + strokeDasharray: [8, 8], + fillColor: '#1791fc', + zIndex: 50 + }); - // 构造路线导航类 - driving = new AMap.Driving({ - map: map, - panel: instance.refs.mapPanel - }); + // 构造路线导航类 + driving = new AMap.Driving({ + map: map, + panel: instance.refs.mapPanel + }); - // 初始化地图组件所需数据 - const hospitalList = await listHospital({ size: 40, mapNotify: '1' }); - mapState.hospitalList = hospitalList.data?.map(item => ({ - value: item.id, - label: item.name, - mapLat: item.mapLat, - mapLng: item.mapLng, - mapNotify: !!~~item.mapNotify, - mapOrientation: item.mapOrientation - })); - const hospitalPoints = mapState.hospitalList.map(hospital => ({ - lnglat: [hospital.mapLng, hospital.mapLat], ...hospital - })); - hospitalMarkerCluster?.setData(hospitalPoints); - const orgList = await listOrg({ size: 40 }); - mapState.orgList = orgList.data?.map(item => ({ - value: item.id, - label: item.name, - mapOrientation: item.mapOrientation, - mapLat: item.mapLat, - mapLng: item.mapLng - })); - const orgPoints = mapState.orgList.map(org => ({ - lnglat: [org.mapLng, org.mapLat], ...org - })); - orgMarkerCluster?.setData(orgPoints); + // 初始化地图组件所需数据 + const hospitalList = await listHospital({ size: 40, mapNotify: '1' }); + mapState.hospitalList = hospitalList.data?.map(item => ({ + value: item.id, + label: item.name, + mapLat: item.mapLat, + mapLng: item.mapLng, + mapNotify: !!~~item.mapNotify, + mapOrientation: item.mapOrientation + })); + const hospitalPoints = mapState.hospitalList.map(hospital => ({ + lnglat: [hospital.mapLng, hospital.mapLat], ...hospital + })); + hospitalMarkerCluster?.setData(hospitalPoints); + const orgList = await listOrg({ size: 40 }); + mapState.orgList = orgList.data?.map(item => ({ + value: item.id, + label: item.name, + mapOrientation: item.mapOrientation, + mapLat: item.mapLat, + mapLng: item.mapLng + })); + const orgPoints = mapState.orgList.map(org => ({ + lnglat: [org.mapLng, org.mapLat], ...org + })); + orgMarkerCluster?.setData(orgPoints); - // sse长轮询连接获取收样员gps位置 - eventSource = new EventSourcePolyfill(mapDesigner.sseUrl, { - headers: { Authorization: `Bearer ${getAccessToken()}` } - }); + // sse长轮询连接获取收样员gps位置 + eventSource = new EventSourcePolyfill(mapDesigner.sseUrl, { + headers: { Authorization: `Bearer ${getAccessToken()}` } + }); - eventSource.onopen = function (ev) { - console.info(ev,'建立连接。。。'); - }; - - eventSource.onmessage = function (ev) { - try { - let { data } = ev; - let mapLogistic = JSON.parse(data); - let courierUser = mapState.courierUserList.find(item => item.value == mapLogistic?.courierUserId); - courierUser && (courierUser.mapLat = mapLogistic.courierLat); - courierUser && (courierUser.mapLng = mapLogistic.courierLng); - } catch (e) {} - console.info(ev); - }; - - eventSource.onerror = function (ev) { - console.info(ev); - }; - - // 加载完毕 - complete(); + eventSource.onopen = function (ev) { + console.info(ev,'建立连接。。。'); + }; + + eventSource.onmessage = function (ev) { + try { + let { data } = ev; + let mapLogistic = JSON.parse(data); + let courierUser = mapState.courierUserList.find(item => item.value == mapLogistic?.courierUserId); + courierUser && (courierUser.mapLat = mapLogistic.courierLat); + courierUser && (courierUser.mapLng = mapLogistic.courierLng); + } catch (e) {} + console.info(ev); + }; + + eventSource.onerror = function (ev) { + console.info(ev); + }; + + // 加载完毕 + complete(); + },350, { immediate: true }); }).catch(error => { - mapState.loading = false; throw error; }); }); @@ -497,7 +495,6 @@ if (map) { setMapDataJson(mapProps.options); handleSetCourierUserList(); - mapState.loading = false; mapState.first = true; } } diff --git a/src/components/Cropper/src/CropperAvatar.vue b/src/components/Cropper/src/CropperAvatar.vue index c0bf5b2..92fd16e 100644 --- a/src/components/Cropper/src/CropperAvatar.vue +++ b/src/components/Cropper/src/CropperAvatar.vue @@ -53,7 +53,7 @@ showBtn: { type: Boolean, default: true }, btnProps: { type: Object as PropType }, btnText: { type: String, default: '' }, - uploadApi: { type: Function as PropType<({ file: Blob, name: string }) => Promise> }, + uploadApi: { type: Function as PropType<(file: Blob, name: string) => Promise> }, }; export default defineComponent({ diff --git a/src/components/Dropdown/src/Dropdown.vue b/src/components/Dropdown/src/Dropdown.vue index 58a5f5e..bfc7ab2 100644 --- a/src/components/Dropdown/src/Dropdown.vue +++ b/src/components/Dropdown/src/Dropdown.vue @@ -41,10 +41,10 @@ import { defineComponent } from 'vue'; import { Dropdown, Menu, Popconfirm } from 'ant-design-vue'; - import { Icon } from '/@/components/Icon'; import { omit } from 'lodash-es'; import { isFunction } from '/@/utils/is'; import { useDesign } from '/@/hooks/web/useDesign'; + import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent'; export default defineComponent({ name: 'BasicDropdown', @@ -53,7 +53,7 @@ Menu, MenuItem: Menu.Item, MenuDivider: Menu.Divider, - Icon, + Icon: createAsyncComponent(() => import('/@/components/Icon')), Popconfirm, }, props: { diff --git a/src/components/Upload/src/BasicUpload.vue b/src/components/Upload/src/BasicUpload.vue index bb082f9..4031f39 100644 --- a/src/components/Upload/src/BasicUpload.vue +++ b/src/components/Upload/src/BasicUpload.vue @@ -54,7 +54,7 @@ setup(props, { emit, attrs }) { const { t } = useI18n(); // 上传modal - const [registerUploadModal, { openModal: openUploadModal, closeModal: closeUploadModal }] = useModal(); + const [registerUploadModal, { openModal: openUploadModal}] = useModal(); // 预览modal const [registerPreviewModal, { openModal: openPreviewModal }] = useModal(); @@ -103,7 +103,6 @@ } return { - closeUploadModal, registerUploadModal, openUploadModal, handleChange, diff --git a/src/components/Upload/src/UploadModal.vue b/src/components/Upload/src/UploadModal.vue index 3023064..037b37f 100644 --- a/src/components/Upload/src/UploadModal.vue +++ b/src/components/Upload/src/UploadModal.vue @@ -26,10 +26,11 @@
-