Compare commits

...

335 Commits

Author SHA1 Message Date
奔跑的面条
5f15d2432b Merge branch 'master-fetch-dev' into master-fetch 2023-08-17 10:02:10 +08:00
奔跑的面条
dc10b761d8 build: 初始化依赖 2023-08-17 10:01:50 +08:00
奔跑的面条
800a2f0732 Merge branch 'dev' into master-fetch-dev 2023-08-17 09:57:56 +08:00
奔跑的面条
95b50c7d76 fix: 解决TS打包报错 2023-08-15 09:29:06 +08:00
奔跑的面条
d76ddf1126 !197 新增输入框联动组件
Merge pull request !197 from 阿飞/dev1
2023-08-15 01:11:45 +00:00
luoyp
c5788f79b3 新增输入框组件 2023-08-14 11:01:04 +08:00
奔跑的面条
704a7bd8f8 feat: 新增基础分页表格 2023-08-11 23:56:30 +08:00
奔跑的面条
db73346c71 feat: 处理基础表格图片和文案提示 2023-08-11 23:47:05 +08:00
奔跑的面条
ab5ade9be1 perf: 格式化表格组件代码 2023-08-11 22:35:44 +08:00
奔跑的面条
0d3418259c !192 新增分页表格组件
Merge pull request !192 from 阿飞/dev2
2023-08-11 14:22:14 +00:00
奔跑的面条
541ce8a083 feat: 修改柱状图 & 折线图文件位置和名称,格式化内容 2023-08-11 22:20:32 +08:00
奔跑的面条
6b9e993599 !193 新增组合图
Merge pull request !193 from 阿飞/dev3
2023-08-11 14:08:47 +00:00
奔跑的面条
1ad0658a5f !194 新增分页联动组件
Merge pull request !194 from 阿飞/dev4
2023-08-11 14:03:20 +00:00
奔跑的面条
b89e5d702b !190 feat: 增加全屏按钮组件
Merge pull request !190 from QuietlyChan/feat-fullScreen
2023-08-11 13:55:15 +00:00
奔跑的面条
fed515f844 !191 修复单折线渐变图鼠标移入报错
Merge pull request !191 from 阿飞/dev1
2023-08-11 13:50:54 +00:00
奔跑的面条
9f9df3566f !196 修复naive-ui进度图预览显示bug
Merge pull request !196 from 阿飞/dev6
2023-08-11 13:49:47 +00:00
奔跑的面条
39e735b29c fix: 解决了三维地球不能被截图的bug 2023-08-11 21:43:43 +08:00
奔跑的面条
d2ad32e08e fix: 解决地图point的值展示错误的问题 2023-08-09 09:28:48 +08:00
retire
b75cbea6cc feat: 基础事件增加components参数 2023-08-03 21:05:06 +08:00
luoyp
3c1ea60f21 修复Naive-UI进度图预览显示bug 2023-08-03 15:38:47 +08:00
luoyp
32c5b216f2 修复组合图不显示 2023-08-01 16:44:30 +08:00
luoyp
a08e27da2d 新增分页联动组件 2023-08-01 09:32:55 +08:00
luoyp
4c13dc3184 新增组合图 2023-08-01 09:16:54 +08:00
luoyp
d91c86f01c 新增分页表格组件 2023-08-01 08:48:59 +08:00
luoyp
5479a26832 修复单折线渐变图鼠标移入报错 2023-08-01 08:44:27 +08:00
奔跑的面条
1250829da6 fix: 处理一开始不会请求的问题 2023-07-31 17:09:20 +08:00
奔跑的面条
ac2fd67688 fix: 修复创建分组排序会错误的bug 2023-07-31 15:45:43 +08:00
QuietlyChan
dbc44bf419 fix: 修复初始化不能拖拽 2023-07-28 14:34:40 +08:00
QuietlyChan
1401a091eb feat: 增加全屏按钮组件 2023-07-28 10:11:34 +08:00
奔跑的面条
f528eb29bc fix: 处理加上链接内容就会消失的bug 2023-07-21 16:43:05 +08:00
奔跑的面条
06921ea3f5 !180 修复旋转组件预览错位问题
Merge pull request !180 from 张江胜/dev_fix
2023-07-21 08:29:05 +00:00
奔跑的面条
f2d9f14ea5 !179 修复右下角白点 通过修改样式修改 不需要元素
Merge pull request !179 from cherubic_c/dev
2023-07-21 08:06:37 +00:00
奔跑的面条
97e5d985bd !184 fix: 左侧刻度尺错位问题
Merge pull request !184 from daidai/dev
2023-07-21 06:59:15 +00:00
刘嘉威
bb1828b478 fix: 左侧刻度尺错位问题 2023-07-20 14:28:31 +08:00
Ming
91c4cca62e fix: 粘贴坐标 2023-07-17 18:53:33 +08:00
奔跑的面条
c3140d3746 build: 升级 axios lock错误 2023-07-15 14:13:40 +08:00
张江胜
307cdd9e9a fix: 修复单个组件旋转后,进行分组再次旋转预览错位的问题 2023-07-10 11:06:19 +08:00
IMyself
7bc8c16581 修复右下角白点 2023-07-10 08:21:10 +08:00
奔跑的面条
df01be729d Merge branch 'master-fetch-dev' into master-fetch 2023-07-09 17:09:06 +08:00
奔跑的面条
ec051618e6 Merge branch 'dev' into master-fetch-dev 2023-07-09 17:08:50 +08:00
奔跑的面条
8caa588d3f perf: 优化预览拖拽交互 2023-07-09 17:06:35 +08:00
奔跑的面条
0816f3fcbf Merge branch 'master-fetch-dev' into master-fetch 2023-07-09 15:55:11 +08:00
奔跑的面条
6843f24263 Merge branch 'dev' into master-fetch-dev 2023-07-09 15:54:55 +08:00
奔跑的面条
59bfc78f0a Merge branch 'master-fetch-dev' into master-fetch 2023-07-08 22:03:58 +08:00
奔跑的面条
4064339848 build: 升级到版本 2.2.4 2023-07-08 22:03:27 +08:00
奔跑的面条
d2af67d6ad Merge branch 'dev' into master-fetch-dev 2023-07-08 22:01:54 +08:00
奔跑的面条
3da84b2fa2 Merge branch 'dev' into master-fetch-dev 2023-06-15 19:56:44 +08:00
奔跑的面条
2ad2af97e6 !169 feat:标签选择器增加默认值选项
Merge pull request !169 from h5coder/dev-h5coder
2023-06-15 11:49:54 +00:00
奔跑的面条
291a7bbc61 !171 fix: 修复旧版本没有legend配置导致报settting color错误
Merge pull request !171 from h5coder/h5coder-fix
2023-06-15 11:45:41 +00:00
lyx
27e2e2c68d fix: 修复旧版本没有legend配置导致报settting color错误 2023-06-09 10:56:36 +08:00
lyx
18e0729e54 fix:标签选择器去除多余的代码 2023-06-05 18:06:57 +08:00
lyx
d6afc50ac5 feat:标签选择器增加默认值选项 2023-06-02 17:29:18 +08:00
奔跑的面条
37676176e7 fix: 去除定时存储数据的逻辑 2023-05-30 09:34:54 +08:00
奔跑的面条
895bca92ee Merge branch 'master-fetch-dev' into master-fetch 2023-05-28 18:00:25 +08:00
奔跑的面条
1460ceb07e fix: 处理ts报错 2023-05-28 18:00:07 +08:00
奔跑的面条
30bb48f294 Merge branch 'master-fetch-dev' into master-fetch 2023-05-28 17:56:59 +08:00
奔跑的面条
d5eb3ec4e2 fix: 修改ts 错误 2023-05-28 17:56:38 +08:00
奔跑的面条
7eff3a29c1 Merge branch 'master-fetch-dev' into master-fetch 2023-05-28 17:36:48 +08:00
奔跑的面条
33ca7af62d build: 升级版本到 2.2.3 2023-05-28 17:35:21 +08:00
奔跑的面条
915e4a69e8 Merge branch 'dev' into master-fetch-dev 2023-05-28 17:34:43 +08:00
奔跑的面条
0546b37186 Merge branch 'dev' into master-fetch-dev 2023-05-28 17:18:49 +08:00
奔跑的面条
9e0736c693 !165 更新 axios 到 1.4.0,并在axios响应拦截中处理 401 状态(跳转到登录)
Merge pull request !165 from dodu/fetch-401
2023-05-28 09:09:46 +00:00
tnt group
bd7960b09a chore: 重新 install,更新 pnpm-lock 2023-05-28 17:01:29 +08:00
tnt group
ddc09da8cb Merge branch 'fetch-feat-401' into fetch-401 2023-05-28 17:00:26 +08:00
tnt group
d84e47faa9 chore: 为避免冲突,删除 pnpm-lock 2023-05-28 16:59:11 +08:00
奔跑的面条
23efce86fe !159 地图组件新增卫星地图主题
Merge pull request !159 from tanhao/feat-map-theme
2023-05-28 16:03:10 +08:00
奔跑的面条
6abeef182f Merge branch 'dev' into master-fetch-dev 2023-05-28 15:59:08 +08:00
tnt group
e3d388b5d9 chore: 变更 status 获取方式 2023-05-22 08:15:06 +08:00
tnt group
7cf9c29a34 feat: 更新 axios 到 1.4.0,在响应拦截中处理 401 状态(跳转到登录) 2023-05-22 07:39:33 +08:00
奔跑的面条
e7ab632a92 Merge branch 'master-fetch-dev' into master-fetch 2023-05-08 20:44:30 +08:00
奔跑的面条
1681513d68 build: 升级版本到 2.2.2 2023-05-08 20:43:14 +08:00
奔跑的面条
bd53c68ee2 Merge branch 'master-fetch-dev' into master-fetch 2023-05-08 20:36:15 +08:00
奔跑的面条
40673dddb3 fix: 修改上传的 httpurl 为 fileurl 2023-05-08 20:15:20 +08:00
奔跑的面条
460aa47ee5 feat: 去除多余功能代码 2023-05-01 21:51:18 +08:00
奔跑的面条
1237e16142 feat: 兼容新版本后端 2023-05-01 21:49:08 +08:00
奔跑的面条
1565249e2a Merge branch 'master-fetch-dev' into master-fetch 2023-04-23 21:17:28 +08:00
奔跑的面条
ffd4e165e5 Merge branch 'dev' into master-fetch-dev 2023-04-23 21:14:54 +08:00
奔跑的面条
60c7c36800 Merge branch 'master-fetch-dev' into master-fetch 2023-04-23 21:09:40 +08:00
奔跑的面条
186538afc9 Merge branch 'dev' into master-fetch-dev 2023-04-23 21:07:05 +08:00
奔跑的面条
76f0183acc Merge branch 'dev' into master-fetch-dev 2023-04-23 20:07:03 +08:00
奔跑的面条
2e74522cc3 Merge branch 'master-fetch-dev' into master-fetch 2023-04-05 16:39:50 +08:00
奔跑的面条
2d8e99bed6 Merge branch 'dev' into master-fetch-dev 2023-04-05 16:39:39 +08:00
奔跑的面条
afd42fb1fe Merge branch 'master-fetch-dev' into master-fetch 2023-04-03 20:11:31 +08:00
奔跑的面条
980b91401b Merge branch 'dev' into master-fetch-dev 2023-04-03 20:11:20 +08:00
奔跑的面条
ba1868eb8b Merge branch 'master-fetch-dev' into master-fetch 2023-04-02 18:21:01 +08:00
奔跑的面条
82f026a1b5 build: 升级版本到 2.2.1 2023-04-02 18:20:40 +08:00
奔跑的面条
5213ea0273 Merge branch 'master-fetch-dev' into master-fetch 2023-04-02 18:20:01 +08:00
奔跑的面条
0308004a61 fix: 还原解决冲突不小心删掉的代码 2023-04-02 18:07:38 +08:00
奔跑的面条
d030f89895 Merge branch 'dev' into master-fetch-dev 2023-04-02 17:54:57 +08:00
奔跑的面条
2386687f2e build: 升级版本到 2.2.0 2023-03-16 21:00:13 +08:00
奔跑的面条
f0f9905583 Merge branch 'master-fetch-dev' into master-fetch 2023-03-16 20:59:37 +08:00
奔跑的面条
8d57af2dab fix: 处理联动的合并问题 2023-03-16 20:25:31 +08:00
奔跑的面条
98b1380d0d Merge branch 'dev' into master-fetch-dev 2023-03-16 20:02:18 +08:00
奔跑的面条
a448bb678b Merge branch 'master-fetch-dev' into master-fetch 2023-03-04 17:32:50 +08:00
奔跑的面条
ca580db132 Merge branch 'dev' into master-fetch-dev 2023-03-04 17:32:27 +08:00
奔跑的面条
b248f73a88 Merge branch 'master-fetch-dev' into master-fetch 2023-03-04 17:07:17 +08:00
奔跑的面条
8bff2f9b12 Merge branch 'dev' into master-fetch-dev 2023-03-04 17:06:51 +08:00
奔跑的面条
aa1b11d9f0 Merge branch 'master-fetch-dev' into master-fetch 2023-03-04 16:25:17 +08:00
奔跑的面条
d5fb0b54de build: 升级版本到 2.1.9 2023-03-04 16:24:57 +08:00
奔跑的面条
3d88a39a02 Merge branch 'master-fetch-dev' into master-fetch 2023-03-04 16:22:02 +08:00
奔跑的面条
873c6fef53 !133 解决adcode类型不正确可能导致的问题
Merge pull request !133 from wallellen/master-fetch-dev
2023-03-04 16:10:45 +08:00
奔跑的面条
b2f53a7123 !133 解决adcode类型不正确可能导致的问题
Merge pull request !133 from wallellen/master-fetch-dev
2023-03-04 08:01:54 +00:00
奔跑的面条
2a850e4249 Merge branch 'dev' into master-fetch-dev 2023-03-04 14:42:56 +08:00
wallellen
0b89aeca82 update src/packages/components/Charts/Maps/MapBase/index.vue.
解决https://gitee.com/dromara/go-view/issues/I6E0JS问题

Signed-off-by: wallellen <wallellen@hotmail.com>
2023-03-04 05:59:26 +00:00
奔跑的面条
126c7ce5d2 !132 fix: 动态请求中,body的json参数使用javasctipt
Merge pull request !132 from guo_ddt/master-fetch
2023-03-04 13:47:02 +08:00
奔跑的面条
e2ba151794 !132 fix: 动态请求中,body的json参数使用javasctipt
Merge pull request !132 from guo_ddt/master-fetch
2023-03-04 05:46:01 +00:00
郭孔泉
92dcd7fecd fix: 动态请求中,body的json参数使用javasctipt拼接 2023-03-03 11:03:05 +08:00
奔跑的面条
e841d3db17 Merge branch 'master-fetch-dev' into master-fetch 2023-02-27 19:04:38 +08:00
奔跑的面条
800a0141a5 build: 升级版本到2.1.8 2023-02-27 19:04:05 +08:00
奔跑的面条
c92d7cab97 Merge branch 'dev' into master-fetch-dev 2023-02-27 13:07:05 +08:00
奔跑的面条
86de4e105e Merge branch 'dev' into master-fetch-dev 2023-02-27 12:53:44 +08:00
奔跑的面条
62a2ed2b4a feat: 新增颜色自定义功能 2023-02-27 00:29:47 +08:00
奔跑的面条
e8e05033cd Merge branch 'master-fetch-dev' into master-fetch 2023-02-17 18:15:50 +08:00
奔跑的面条
3790bc0207 Merge branch 'dev' into master-fetch-dev 2023-02-17 18:15:35 +08:00
奔跑的面条
8c4e3e8965 Merge branch 'master-fetch-dev' into master-fetch 2023-02-17 14:34:28 +08:00
奔跑的面条
b03107d8cb build: 升级带后端版本到2.1.7 2023-02-17 14:33:53 +08:00
奔跑的面条
e9a4ebe38f Merge branch 'master-fetch-dev' into master-fetch 2023-02-17 14:33:18 +08:00
奔跑的面条
a702decfd4 Merge branch 'dev' into master-fetch-dev 2023-02-15 14:26:56 +08:00
奔跑的面条
0eecc1e19d Merge branch 'dev' into master-fetch-dev 2023-02-15 09:45:37 +08:00
奔跑的面条
182b2c508a Merge branch 'dev' into master-fetch-dev 2023-02-09 16:24:19 +08:00
奔跑的面条
2907d1b514 Merge branch 'master-fetch-dev' into master-fetch 2023-01-17 15:35:40 +08:00
奔跑的面条
7bda46021a feat: 合并修复序列化代码,解决冲突 2023-01-17 15:34:10 +08:00
奔跑的面条
6d91262faa feat: 合并dev 2023-01-17 14:49:49 +08:00
奔跑的面条
1672978730 Merge branch 'master-fetch-dev' into master-fetch 2023-01-16 17:59:40 +08:00
奔跑的面条
36a6bb4214 Merge branch 'dev' into master-fetch-dev 2023-01-16 17:58:29 +08:00
奔跑的面条
14b37d82d0 Merge branch 'dev' into master-fetch-dev 2023-01-16 13:51:54 +08:00
奔跑的面条
4300b1f617 Merge remote-tracking branch 'origin/dev' into master-fetch-dev 2023-01-16 10:22:13 +08:00
奔跑的面条
de4bd655ed build: 升级版本到 2.1.6 2023-01-13 16:53:12 +08:00
奔跑的面条
0434c779cd Merge branch 'master-fetch-dev' into master-fetch 2023-01-13 16:52:43 +08:00
奔跑的面条
aa0578776c Merge remote-tracking branch 'origin/dev' into master-fetch-dev 2023-01-13 16:52:28 +08:00
奔跑的面条
3bd8cbe535 Merge branch 'dev' into master-fetch-dev 2023-01-13 16:15:09 +08:00
奔跑的面条
c81aff2c57 fix: 处理 ts 报错 2023-01-09 20:20:19 +08:00
奔跑的面条
59eaed5b09 feat: 合并标题名称功能, 解决冲突 2023-01-09 20:18:27 +08:00
奔跑的面条
5d0c6f4487 Merge branch 'dev' into master-fetch-dev 2023-01-09 19:32:54 +08:00
奔跑的面条
c903b607df fix: 优化 JSON 序列化无法处理函数的问题 2023-01-09 11:37:57 +08:00
奔跑的面条
ec5bed5b13 feat: 合并dev 2023-01-09 11:31:54 +08:00
奔跑的面条
ec97340c25 build: 升级版本 2.1.5 2023-01-08 20:08:37 +08:00
奔跑的面条
7bbf285e8e build: 升级版本到 2.1.5 2023-01-08 20:06:11 +08:00
奔跑的面条
d652b06137 feat: 合并 dev 分支功能 2023-01-08 20:01:49 +08:00
奔跑的面条
e55e63bca1 Merge remote-tracking branch 'origin/master-fetch-dev' into master-fetch 2022-12-31 21:26:42 +08:00
奔跑的面条
9b47d353c0 build: 新增提醒 2022-12-31 21:26:18 +08:00
奔跑的面条
c3f9a470fc feat: 合并 2.1.4 2022-12-31 21:07:51 +08:00
奔跑的面条
bd2557f3e4 build: 修改版本号到2.1.3 2022-12-31 20:56:55 +08:00
奔跑的面条
730099efb9 build: 升级2.1.2 2022-12-31 20:55:12 +08:00
奔跑的面条
c5706f839e Merge branch 'dev' into master-fetch-dev 2022-12-20 17:05:32 +08:00
奔跑的面条
faa0d6538f Merge branch 'dev' into master-fetch-dev 2022-12-20 16:59:55 +08:00
奔跑的面条
f15e0cd15f build: 升级版本到2.1.3 2022-12-16 14:02:09 +08:00
奔跑的面条
aa17e93966 Merge branch 'master-fetch-dev' into master-fetch 2022-12-16 13:55:55 +08:00
奔跑的面条
feb9796449 feat: 全局接口保存之后调接口存储 2022-12-16 13:01:15 +08:00
奔跑的面条
e4b641a9c9 Merge branch 'dev' into master-fetch-dev 2022-12-16 12:56:28 +08:00
奔跑的面条
352a1742cf !104 fix:图片hash会出现404问题
Merge pull request !104 from lastbee1204/master-fetch
2022-12-16 04:03:40 +00:00
奔跑的面条
1af7ae865d !108 饼状图新增功能 显示标签,标签显示内容,引导线显示,饼状图圆角设置
Merge pull request !108 from 李少白/master-fetch
2022-12-16 02:44:00 +00:00
slxb
7bc6ff7619 饼状图新增功能 显示标签,标签显示内容,引导线显示,饼状图圆角设置 2022-12-13 19:07:47 +08:00
刘彪
67f6dcd1fe fix:图片hash会出现404问题 2022-11-29 11:56:37 +08:00
刘彪
de60c7cde5 fix:图片hash会出现404问题 2022-11-29 11:47:54 +08:00
奔跑的面条
889e5075ba style: 去除全局多余代码 2022-11-28 11:02:52 +08:00
奔跑的面条
2bba1dcae0 style: 修改代码格式,修改错误单词 2022-11-28 10:54:54 +08:00
奔跑的面条
9d81159141 !103 优化Axios相关类型推断和语法
Merge pull request !103 from 石头web/master-fetch-dev
2022-11-28 01:46:22 +00:00
a876691666
f8ebaa60b1 feat: 接口增加泛型支持 2022-11-27 12:16:32 +08:00
a876691666
02ec3c78d6 feat: 更新Type类型 2022-11-27 11:40:00 +08:00
奔跑的面条
8230757bd1 !102 fix:修复状态变更时(如切换语言等),useSync.hook.ts 中 dataSyncFetch 反复执行导致 chartEditStore.componentList 重复
Merge pull request !102 from fankeke007/N/A
2022-11-22 11:18:28 +00:00
奔跑的面条
c1de1f9db6 Merge remote-tracking branch 'origin/master-fetch-dev' into master-fetch 2022-11-22 12:44:37 +08:00
奔跑的面条
1b0591ee62 Merge remote-tracking branch 'origin/dev' into master-fetch-dev 2022-11-22 12:43:27 +08:00
奔跑的面条
3ee5faa248 Merge branch 'master-fetch-dev' into master-fetch 2022-11-21 10:50:33 +08:00
奔跑的面条
ab9b79e8a8 Merge branch 'dev' into master-fetch-dev 2022-11-21 10:50:10 +08:00
奔跑的面条
b6a78c64ed build: 升级版本到 2.1.2 2022-11-19 21:05:32 +08:00
奔跑的面条
9855d28e33 Merge branch 'master-fetch-dev' into master-fetch 2022-11-19 21:05:15 +08:00
奔跑的面条
16fb258908 Merge branch 'dev' into master-fetch-dev 2022-11-19 20:37:29 +08:00
奔跑的面条
52ed72e502 Merge branch 'dev' into master-fetch-dev 2022-11-19 20:27:10 +08:00
奔跑的面条
6f9993e9e8 perf: 解决登录按钮 loading 不会关闭的问题 2022-11-19 20:23:20 +08:00
奔跑的面条
3347e3b12a !94 使右上方正确显示登录账号名
Merge pull request !94 from 吴医生/master0fetch-dev-my
2022-11-19 09:47:01 +00:00
奔跑的面条
b4a5ff7935 fix: 预览页接口错误不处理,默认正确 2022-11-19 15:07:54 +08:00
fankeke007
e75e2ccfe6 fix:修复状态变更时(如切换语言等),useSync.hook.ts 中 dataSyncFetch 反复执行导致 chartEditStore.componentList 重复
Signed-off-by: fankeke007 <610047449@qq.com>
2022-11-18 08:03:35 +00:00
奔跑的面条
3d568f08de !95 feat: JSON编辑优化以及兼容后端接口保存
Merge pull request !95 from 潘潘/master-fetch-dev
2022-11-15 13:39:49 +00:00
潘潘
5cc20e9b19 perf: 编辑JSON兼容后端优化 2022-11-15 16:26:52 +08:00
潘潘
dec1130ace perf: 编辑JSON优化 2022-11-15 16:21:35 +08:00
潘潘
e3a294eb00 perf: 注释定时同步 2022-11-14 21:07:12 +08:00
吴医生
104551b600 fix: 使正确显示右上方登录账号名
Signed-off-by: 吴医生 <draculakkk@hotmail.com>
2022-11-14 09:26:21 +00:00
奔跑的面条
5c6bf57de1 docs: 优化说明文档 2022-11-14 10:00:30 +08:00
奔跑的面条
b0cb3addbd Merge branch 'dev' into master-fetch-dev 2022-11-13 21:45:16 +08:00
奔跑的面条
77ff4cdffd Merge branch 'dev' into master-fetch-dev 2022-11-13 02:39:13 +08:00
奔跑的面条
dde92bfe60 Merge branch 'dev' into master-fetch-dev 2022-11-12 17:42:39 +08:00
奔跑的面条
a8bcc93aed fix: 修改500展示文案 2022-11-05 21:45:48 +08:00
奔跑的面条
b6903a777a Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch-dev 2022-11-05 21:34:39 +08:00
奔跑的面条
f7cbc75e22 fix: 修改地址 2022-11-02 21:33:20 +08:00
奔跑的面条
0e1ae71b78 fix: 修改类型错误的问题 2022-11-02 19:30:47 +08:00
奔跑的面条
7fcfb953bd build: 修改版本到2.1.1 2022-11-02 19:07:18 +08:00
奔跑的面条
a76ad93600 Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch-dev 2022-11-02 19:06:49 +08:00
奔跑的面条
f9ed391c81 chore: 修改上传地址的接口和图片的展示地址拼接 2022-11-01 21:17:24 +08:00
奔跑的面条
8ab64846d4 fix: 处理更换背景图内容不会更新的问题 2022-10-31 10:40:58 +08:00
奔跑的面条
a82cc840b5 fix: 修改发布API错误调用 2022-10-26 10:51:10 +08:00
奔跑的面条
2171843c61 build: 修改版本号为2.1.0 2022-10-15 17:28:23 +08:00
奔跑的面条
934bac7201 fix: 修改版本号到2.0.10 2022-10-15 17:22:06 +08:00
奔跑的面条
ed2a46a3ef Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch-dev 2022-10-15 17:20:05 +08:00
奔跑的面条
766a3a8ede fix: 修复导入组件数据会错乱的问题 2022-10-09 16:39:10 +08:00
奔跑的面条
f3ec85050e Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch-dev 2022-10-09 09:29:40 +08:00
奔跑的面条
ba54d934a2 build: 修改正确版本到 2.0.8 2022-10-08 21:27:21 +08:00
奔跑的面条
d6ecad6467 build: 升级版本到 2.0.9 2022-10-08 21:09:47 +08:00
奔跑的面条
74cab1e9af Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch-dev 2022-10-08 21:06:06 +08:00
奔跑的面条
a823851541 feat: 合并1.1.1 2022-10-08 21:04:41 +08:00
奔跑的面条
618d1d77cb feat: 合并1.1.1,升级版本到2.0.8 2022-09-27 20:28:47 +08:00
奔跑的面条
17c48608ec style: 去除无用代码,设置默认值 2022-09-27 19:53:55 +08:00
奔跑的面条
6d5dfbced0 perf: 优化用户体验,完成接口配置后调用保存接口 2022-09-27 10:33:30 +08:00
奔跑的面条
c773bd8010 Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch-dev 2022-09-22 14:15:18 +08:00
奔跑的面条
5746da73dd Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch-dev 2022-09-21 19:56:56 +08:00
奔跑的面条
60bbfd9c92 Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch-dev 2022-09-19 20:46:53 +08:00
奔跑的面条
12d92f3aa4 Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch-dev 2022-09-19 20:14:40 +08:00
奔跑的面条
2edb1caf18 perf: 优化滤镜模糊问题,默认不开启 2022-09-19 17:51:12 +08:00
奔跑的面条
75067221da fix: 修改请求接口 token 名称 2022-09-18 17:45:59 +08:00
奔跑的面条
3358e164a1 build: 升级版本到2.0.7 2022-09-18 17:23:16 +08:00
奔跑的面条
94cde3f517 !47 修复在编辑项目之前加载数据异常,自动保存导致项目数据清空问题。
Merge pull request !47 from 秋名山路霸/master-fetch
2022-09-18 07:53:47 +00:00
秋名山路霸
a2c8827a35 fix: 修复在编辑项目之前加载数据异常,自动保存导致项目数据清空问题。 2022-09-18 11:56:26 +08:00
奔跑的面条
172a3163aa build: 升级依赖,锁定TS 版本 2022-09-12 01:20:27 +08:00
奔跑的面条
4d189e954c feat: 升级版本到 2.0.6 2022-09-12 00:49:22 +08:00
奔跑的面条
8a1f3ac2ef fix: 合并1.0.9 2022-09-12 00:31:52 +08:00
奔跑的面条
68dbf3e9ef feat: 新增移动撤回 2022-08-30 19:14:52 +08:00
奔跑的面条
0aece46d91 build: 升级版本到 2.0.5 2022-08-30 15:04:29 +08:00
奔跑的面条
094c7ed392 perf: 完善首页预览功能 2022-08-30 15:03:25 +08:00
奔跑的面条
c48517a89b Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch 2022-08-30 12:19:57 +08:00
奔跑的面条
68c68e96b1 fix: 尝试解决背景图片无法截图的问题 2022-08-29 21:35:51 +08:00
奔跑的面条
36b1f37f3f update LICENSE.
Signed-off-by: 奔跑的面条 <1262327911@qq.com>
2022-08-29 10:13:37 +00:00
奔跑的面条
51e5c756a7 perf: 优化参考线的展示方式 2022-08-21 14:52:30 +08:00
奔跑的面条
8df951992e Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch 2022-08-21 14:49:32 +08:00
奔跑的面条
1a00993ee8 Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch 2022-08-19 14:46:49 +08:00
奔跑的面条
cb7e887c36 fix: 补充代码合并丢失的枚举 2022-08-19 11:43:23 +08:00
奔跑的面条
255b14a597 perf: 优化500错误页重定向 2022-08-19 11:34:38 +08:00
奔跑的面条
3f462c1bee feat: 合并多选功能,解决冲突,升级版本到2.0.4 2022-08-19 10:44:44 +08:00
奔跑的面条
cacc99683d Merge branch 'dev' into master-fetch 2022-08-05 08:42:22 +08:00
奔跑的面条
d3a9f7d60f Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch 2022-07-26 16:12:31 +08:00
奔跑的面条
8d4dd3160d Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch 2022-07-21 11:46:54 +08:00
奔跑的面条
6847f7d966 feat: 合并 1.0.6 版本代码 2022-07-21 11:03:04 +08:00
奔跑的面条
35204898fc Merge branch 'dev' into master-fetch 2022-07-08 18:12:33 +08:00
奔跑的面条
7fe743d624 fix: 合并编辑功能的修改 2022-07-07 19:54:53 +08:00
奔跑的面条
6a285f610c Merge branch 'dev' into master-fetch 2022-07-07 13:14:53 +08:00
奔跑的面条
a4c0450f7a fix: 补充合并代码丢失的icon图标 2022-07-06 22:12:24 +08:00
奔跑的面条
a81f016e3f build: 合并dev 1.0.5 版本, 修改fetch分支为2.0.2 2022-07-06 21:58:28 +08:00
奔跑的面条
ee5fed4cd0 Merge branch 'dev' into master-fetch 2022-06-27 21:42:24 +08:00
奔跑的面条
3fb0fe43bb Merge branch 'dev' into master-fetch 2022-06-27 21:38:27 +08:00
奔跑的面条
f1f5f9cca9 fix: 修改合并冲突错误的代码 2022-06-27 20:42:17 +08:00
奔跑的面条
2ce17c3974 perf: 合并dev分支,解决组件无法更新数据的问题 2022-06-27 20:37:26 +08:00
奔跑的面条
1d7e40950f style: 去除多余代码 2022-06-24 11:44:26 +08:00
奔跑的面条
91bda457e7 docs: 修改文档 2022-06-23 09:53:01 +08:00
奔跑的面条
68aeea70cf feat: 新增保存按钮 2022-06-22 18:50:15 +08:00
奔跑的面条
7a19346700 build: 升级依赖 2022-06-20 15:13:50 +08:00
奔跑的面条
8d2269df78 build: 合并dev分支 2022-06-20 15:11:13 +08:00
奔跑的面条
b133cbdfea feat: 新增排名列表字体大小控制功能 2022-06-17 14:13:14 +08:00
奔跑的面条
f45d4ca5af build: 修改版本到 2.0.1 2022-06-16 10:48:42 +08:00
奔跑的面条
d96e7f71d7 fix: 解决打包之后无法加载页面的问题 2022-06-15 17:54:49 +08:00
奔跑的面条
24fee76237 feat: 新增 preview 模式,修改打包后路径指向 2022-06-15 17:48:16 +08:00
奔跑的面条
d59193bc33 feat: 新增commitlint 2022-06-15 17:18:39 +08:00
奔跑的面条
6928a70d9f docs: 更新文档 2022-06-15 17:15:29 +08:00
奔跑的面条
e0796280f5 doc: 文档更新 2022-06-15 17:14:27 +08:00
奔跑的面条
5d803e3fa6 feat: 新增渐变文本组件 2022-06-15 16:20:25 +08:00
奔跑的面条
749c0a2f39 build:升级依赖 2022-06-15 16:11:58 +08:00
奔跑的面条
737504cef5 fix: 解决npm,yarn 安装依赖报错的问题 2022-06-15 16:08:59 +08:00
奔跑的面条
8115950893 fix: 补充丢失的图片 2022-06-14 12:46:07 +08:00
奔跑的面条
f458a21a2f feat:新增数字滚动组件动态获取数据功能 2022-06-14 12:31:46 +08:00
奔跑的面条
13a9675894 feat: 新增表格滚动组件 2022-06-14 12:31:20 +08:00
奔跑的面条
77b5a41af9 fix:解决边框04展示不全的bug 2022-06-14 12:30:29 +08:00
奔跑的面条
2bf895ad3d feat:新增水球图设置项 2022-06-13 17:29:39 +08:00
奔跑的面条
6a5abd6762 fix: 修改列表页展示问题 2022-06-13 14:28:58 +08:00
奔跑的面条
5cb458c45b feat: 新增环形图,新增NaiveUI-进度组件 2022-06-13 13:18:30 +08:00
奔跑的面条
f828c48ab6 feat: 新增进度条组件 2022-06-12 18:47:47 +08:00
奔跑的面条
2626bc794f fix: 解决缩放比例展示不全的问题 2022-06-12 18:45:31 +08:00
奔跑的面条
734dd68607 chore: 优化拖拽锚点 2022-06-11 15:15:38 +08:00
奔跑的面条
19f53f705c fix:修改请求地址为null时引起的异常bug 2022-06-11 14:37:22 +08:00
奔跑的面条
b93caf1386 chore: 优化发布弹窗 2022-06-11 14:23:16 +08:00
奔跑的面条
aa613e2805 build: 依赖基本升级 2022-06-11 14:15:28 +08:00
奔跑的面条
616584fc19 fix: 修改双折线图X轴无法变更的问题 2022-06-11 14:13:32 +08:00
奔跑的面条
a5e83bfe9f fix: 解决项目列表信息栏会换行的问题 2022-06-09 08:49:07 +08:00
奔跑的面条
1252d266dd fix:解决截图有白边的问题 2022-06-09 08:48:28 +08:00
奔跑的面条
3c820d53a6 fix: 修改复制失败的提示类型错误的问题 2022-06-06 10:43:14 +08:00
奔跑的面条
f0525c7522 chore: 新增路由白名单 2022-06-06 10:42:55 +08:00
奔跑的面条
600f1b2dd2 chore:优化搜索结果列表UI 2022-06-05 11:41:57 +08:00
奔跑的面条
757b79514a chore:优化 dialog 的全局封装代码 2022-06-04 16:25:37 +08:00
奔跑的面条
cf8121eb00 build:修改 fetch 版本号 2022-06-04 15:44:26 +08:00
奔跑的面条
faf2d44fbb chore: 优化页面 UI 2022-06-03 20:21:35 +08:00
奔跑的面条
88516d9491 fix: 修改自动复制粘贴的问题 2022-06-03 18:53:37 +08:00
奔跑的面条
88dbbe03ea fix: 新增发布页面处理 2022-06-03 14:48:58 +08:00
奔跑的面条
ae1fd2e7cf chore: 优化了标题展示和大小样式 2022-06-03 11:19:29 +08:00
奔跑的面条
d3931f47bc type: 修改类型错误 2022-06-01 23:00:28 +08:00
奔跑的面条
bf9bd59b63 fix:处理列表页标题过长的展示问题 2022-06-01 22:58:22 +08:00
奔跑的面条
fb0ff50837 type: 定义全局返回值类型 2022-06-01 22:41:11 +08:00
奔跑的面条
93727a0ac7 build: 修改版本号 0.0.9 2022-06-01 22:28:46 +08:00
奔跑的面条
2641e70c78 chore:优化了路由写法,修改了错误页面的展示,新增未发布提示页面 2022-06-01 22:20:05 +08:00
奔跑的面条
bc44584698 feat: 新增动态预览功能 2022-06-01 22:19:03 +08:00
奔跑的面条
82394dd7a3 fix: 修改组件注册会报错的问题 2022-06-01 22:14:33 +08:00
奔跑的面条
2e688ad686 build:升级依赖包 2022-06-01 22:13:49 +08:00
奔跑的面条
9b998e0c6d fix: 解决列表图片展示缓存问题 2022-06-01 20:16:38 +08:00
奔跑的面条
1045588301 fix: 解决获取数据,但是配置模块不完整的问题 2022-06-01 19:01:05 +08:00
奔跑的面条
ba86399fd3 build: 修改请求地址 2022-05-31 11:19:17 +08:00
奔跑的面条
a89164f885 fix: 修改oss接口不会动态更改的问题 2022-05-31 11:18:34 +08:00
奔跑的面条
7f2344c82c chore:修改请求地址 2022-05-29 16:04:07 +08:00
奔跑的面条
3c8e430533 docs: 修改文档说明 2022-05-29 15:23:04 +08:00
奔跑的面条
f7209fba53 feat: 新增背景图文件上传保存 2022-05-29 14:54:35 +08:00
奔跑的面条
9fae683d8b chore: 去除生成预览图时的标尺 2022-05-28 17:58:07 +08:00
奔跑的面条
79a2b98a1a feat: 新增首页预览图展示 2022-05-28 16:39:27 +08:00
奔跑的面条
98b28a631a Merge branch 'dev' into master-fetch 2022-05-28 15:58:06 +08:00
奔跑的面条
6fec64f515 fix: 修改自动保存预览图无法存储的问题 2022-05-28 15:46:07 +08:00
奔跑的面条
01d5890b35 branch: 合并锚点样式修改 2022-05-28 12:46:32 +08:00
奔跑的面条
fea583eb5b feat: 保存预览图 2022-05-28 11:50:17 +08:00
奔跑的面条
bfe5039a1c fix: 解决打包后无法发送请求的bug 2022-05-28 00:32:32 +08:00
奔跑的面条
7a57d944c8 feat: 新增上传文件接口 2022-05-27 20:09:48 +08:00
奔跑的面条
ca27e87241 chore: 修改项目信息结构 2022-05-27 11:49:25 +08:00
奔跑的面条
e674a1ece4 feat: 新增项目信息修改功能 2022-05-26 01:01:59 +08:00
奔跑的面条
dfb63346d3 fix: 修改导入组件id会重复的问题 2022-05-25 23:00:36 +08:00
奔跑的面条
4d899d48dc feat: 新增快捷键展示 2022-05-24 18:17:41 +08:00
奔跑的面条
fa3a3dfcb0 faet: 新增保存快捷键 2022-05-24 18:16:33 +08:00
奔跑的面条
e36210aa27 feat: 新增自动同步功能 2022-05-24 17:42:49 +08:00
奔跑的面条
20a599594c feat: 新增数据保存接口 2022-05-24 15:05:51 +08:00
奔跑的面条
70f8dbae53 Merge branch 'dev' into master-fetch 2022-05-24 12:28:14 +08:00
奔跑的面条
d8022b2682 feat: 新增获取项目数据功能,新增同步数据功能 2022-05-23 23:50:35 +08:00
奔跑的面条
0d7c5b8ace Merge branch 'dev' into master-fetch 2022-05-23 16:06:13 +08:00
奔跑的面条
88c9850c44 Merge branch 'dev' into master-fetch 2022-05-22 23:27:39 +08:00
奔跑的面条
f1ed62cdca feat: 新增获取项目数据接口 2022-05-22 22:11:56 +08:00
奔跑的面条
bfac86d5dd feat:新增发布和取消发布接口 2022-05-22 16:38:22 +08:00
奔跑的面条
341015c584 style: 调整代码格式,去除多余代码 2022-05-22 15:39:30 +08:00
奔跑的面条
7c5a66978e feat: 新增删除接口 2022-05-22 15:25:07 +08:00
奔跑的面条
b21fc3f5e7 feat: 新增首页列表接口 2022-05-22 15:06:45 +08:00
奔跑的面条
0e52628842 Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch 2022-05-22 14:09:38 +08:00
奔跑的面条
f7922cafa5 feat: 新增项目列表接口 2022-05-22 14:05:57 +08:00
奔跑的面条
8c5496829e Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch 2022-05-22 13:36:30 +08:00
奔跑的面条
8514f051a7 fix: 修改新建项目id错误问题 2022-05-21 21:04:10 +08:00
奔跑的面条
61feb29fe2 fix: 修改i18n错误提示 2022-05-21 19:46:44 +08:00
奔跑的面条
fa29881f04 chore: 修改提示内容 2022-05-21 18:04:52 +08:00
奔跑的面条
46cb8e7d0b feat: 新增创建接口,修改i8n部分内容 2022-05-21 18:03:15 +08:00
奔跑的面条
b6143bc75e feat: 新增退出登录接口,新增全局接口封装,修改登录接口内容 2022-05-21 17:31:01 +08:00
奔跑的面条
92e1ec05d2 Merge branch 'master' of https://gitee.com/MTrun/go-view into master-fetch 2022-05-21 14:01:53 +08:00
奔跑的面条
75f23bb1bf Merge branch 'dev' into master-fetch 2022-05-21 13:44:25 +08:00
奔跑的面条
5f5731f813 feat: 新增登录接口请求 2022-05-20 16:12:27 +08:00
奔跑的面条
55159be0dc fix: 修改plop的问题 2022-05-20 16:12:09 +08:00
奔跑的面条
0c4e1dc7ae Merge branch 'dev' of https://gitee.com/MTrun/go-view into master-fetch 2022-05-20 10:25:46 +08:00
奔跑的面条
b4abdeb246 update README.md. 2022-05-19 01:56:30 +00:00
奔跑的面条
7e61dda4aa update README.md. 2022-05-16 10:38:39 +00:00
奔跑的面条
283aafb27d update README.md. 2022-05-16 04:23:10 +00:00
131 changed files with 3235 additions and 769 deletions

12
.env
View File

@@ -1,14 +1,8 @@
# port
VITE_DEV_PORT = '8001'
VITE_DEV_PORT = '8080'
# development path
VITE_DEV_PATH = '/'
VITE_DEV_PATH = 'https://demo.mtruning.club'
# production path
VITE_PRO_PATH = '/'
# spa-title
VITE_GLOB_APP_TITLE = GoView
# spa shortname
VITE_GLOB_APP_SHORT_NAME = GoView
VITE_PRO_PATH = 'https://demo.mtruning.club'

202
README.md
View File

@@ -1,146 +1,114 @@
## 总览
![logo](readme/logo-t-y.png)
**`master-fetch` 分支是带有后端接口请求的分支**
GoView 是一个高效的拖拽式低代码数据可视化开发平台,将图表或页面元素封装为基础组件,无需编写代码即可制作数据大屏,减少心智负担。
**后端项目地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)**
### 😶 纯 **前端** 分支: **`master`**
**接口说明地址:[https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb)**
### 👻 携带 **后端** 请求分支: **`master-fetch`**
## 使用
### 📚 GoView **文档** 地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
所有的接口地址位置:`src\api\path\*`
项目纯前端-Demo 地址:[https://www.mtruning.club](https://www.mtruning.club)
项目带后端-Demo 地址:[后端 Demo 地址](http://1.117.240.165:8080/goview/#/login)
文档-在线地址:[http://www.mtruning.club:81/](http://www.mtruning.club:81/)
文档-源码地址:[https://gitee.com/MTrun/go-view-doc](https://gitee.com/MTrun/go-view-doc)
### 🤯 后端项目
后端项目 gitee 地址:[https://gitee.com/MTrun/go-view-serve](https://gitee.com/MTrun/go-view-serve)
接口说明地址:[https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb](https://docs.apipost.cn/preview/5aa85d10a59d66ce/ddb813732007ad2b?target_id=84dbc5b0-158f-4bcb-8f74-793ac604ada3#3e053622-1e76-43f9-a039-756aee822dbb)
技术点:
- 框架:基于 `Vue3` 框架编写,使用 `hooks` 写法抽离部分逻辑,使代码结构更加清晰;
- 类型:使用 `TypeScript` 进行类型约束,减少未知错误发生概率,可以大胆修改逻辑内容;
- 性能:多处性能优化,使用页面懒加载、组件动态注册、数据滚动加载等方式,提升页面渲染速度;
- 存储:拥有本地记忆,部分配置项采用 `storage` 存储本地,提升使用体验;
- 封装:项目进行了详细的工具类封装如:路由、存储、加/解密、文件处理、主题、NaiveUI 全局方法、组件等
工作台:
![项目截图](readme/go-view-canvas.png)
请求配置:
![项目截图](readme/go-view-fetch.png)
数据过滤:
![项目截图](readme/go-view-filter.png)
主题色:
![项目截图](readme/go-view-color.png)
主要技术栈为:
| 名称 | 版本 | 名称 | 版本 |
| ------------------- | ----- | ----------- | ------ |
| Vue | 3.2.x | TypeScript4 | 4.6.x |
| Vite | 4.2.x | NaiveUI | 2.34.x |
| ECharts | 5.3.x | Pinia | 2.0.x |
| 详见 `package.json` | 😁 | 🥰 | 🤗 |
开发环境:
| 名称 | 版本 | 名称 | 版本 |
| ---- | ------- | ------- | ----- |
| node | 16.16.x | npm | 8.5.x |
| pnpm | 7.1.x | windows | 11 |
已完成图表:
| 分类 | 名称 | 名称 | 名称 |
| ------ | ---------------- | ---------------- | -------- |
| 图表 | 柱状图 | 横向柱状图 | 折线图 |
| \* | 单/多 折线面积图 | 饼图 | 水球图 |
| \* | 环形图 | NaiveUI 多种进度 | 🤠 |
| 信息 | 文字 | 图片 | 😶 |
| 列表 | 滚动排名列表 | 滚动表格 | 🤓 |
| 小组件 | 边框-01~13 | 装饰-01~05 | 数字翻牌 |
## 浏览器支持
开发和测试平台均在 `Google` 和最新版 `EDGE` 上完成,暂未测试 `IE11` 等其它浏览器,如有需求请自行测试与兼容。
## 安装
本项目采用` pnpm` 进行包管理
接口地址修改:`.env`
```shell
#建议使用 nrm 切换到淘宝源 https://registry.npmmirror.com/
#pnpm
pnpm install
# port
VITE_DEV_PORT = '8080'
#yarn
yarn install
# development path
VITE_DEV_PATH = 'http://127.0.0.1:8080'
#npm
npm install
# production path
VITE_PRO_PATH = 'http://127.0.0.1:8080'
```
## 启动
公共前缀修改:`src\settings\httpSetting.ts`
```shell
#pnpm
pnpm dev
# npm
npm run dev
#yarn
yarn dev
#Makefile
make dev
// 请求前缀
export const axiosPre = '/api/goview'
```
## 编译
接口封装:`src\api\http.ts`
```shell
#pnpm
pnpm run build
```ts
import axiosInstance from './axios'
import { RequestHttpEnum, ContentTypeEnum } from '@/enums/httpEnum'
# npm
npm run build
export const get = (url: string, params?: object) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.GET,
params: params,
})
}
#yarn
yarn run build
export const post = (url: string, data?: object, headersType?: string) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.POST,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
#Makefile
make dist
export const put = (url: string, data?: object, headersType?: string) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.PUT,
data: data,
headers: {
'Content-Type': headersType || ContentTypeEnum.JSON
}
})
}
export const del = (url: string, params?: object) => {
return axiosInstance({
url: url,
method: RequestHttpEnum.DELETE,
params
})
}
// 获取请求函数默认get
export const http = (type?: RequestHttpEnum) => {
switch (type) {
case RequestHttpEnum.GET:
return get
case RequestHttpEnum.POST:
return post
case RequestHttpEnum.PUT:
return put
case RequestHttpEnum.DELETE:
return del
default:
return get
}
}
```
## 代码提交
- feat: 新功能
- fix: 修复 Bug
- docs: 文档修改
- perf: 性能优化
- revert: 版本回退
- ci: CICD 集成相关
- test: 添加测试代码
- refactor: 代码重构
- build: 影响项目构建或依赖修改
- style: 不影响程序逻辑的代码修改
- chore: 不属于以上类型的其他类型(日常事务)
* feat: 新功能
* fix: 修复 Bug
* docs: 文档修改
* perf: 性能优化
* revert: 版本回退
* ci: CICD集成相关
* test: 添加测试代码
* refactor: 代码重构
* build: 影响项目构建或依赖修改
* style: 不影响程序逻辑的代码修改
* chore: 不属于以上类型的其他类型(日常事务)
## 交流

View File

@@ -1,9 +0,0 @@
/**
* Get the configuration file variable name
* @param env
*/
export const getConfigFileName = (env: Record<string, any>) => {
return `__PRODUCTION__${env.VITE_GLOB_APP_SHORT_NAME || '__APP'}__CONF__`
.toUpperCase()
.replace(/\s/g, '');
};

View File

@@ -1,8 +1,8 @@
{
"name": "go-view",
"version": "1.1.11",
"version": "2.2.4",
"engines": {
"node": ">=16.14 <18.0.0"
"node": ">=12.0"
},
"scripts": {
"dev": "vite --host",
@@ -21,7 +21,7 @@
"@types/keymaster": "^1.6.30",
"@types/lodash": "^4.14.184",
"animate.css": "^4.1.1",
"axios": "^0.27.2",
"axios": "^1.4.0",
"color": "^4.2.3",
"crypto-js": "^4.1.1",
"dayjs": "^1.11.7",

96
pnpm-lock.yaml generated
View File

@@ -1,5 +1,9 @@
lockfileVersion: '6.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
dependencies:
'@amap/amap-jsapi-loader':
specifier: ^1.0.1
@@ -23,8 +27,8 @@ dependencies:
specifier: ^4.1.1
version: 4.1.1
axios:
specifier: ^0.27.2
version: 0.27.2
specifier: ^1.4.0
version: 1.4.0
color:
specifier: ^4.2.3
version: 4.2.3
@@ -185,7 +189,7 @@ devDependencies:
version: 1.52.3
sass-loader:
specifier: ^12.6.0
version: 12.6.0(sass@1.52.3)(webpack@5.82.1)
version: 12.6.0(sass@1.52.3)(webpack@5.88.2)
typescript:
specifier: 4.6.3
version: 4.6.3
@@ -1196,8 +1200,8 @@ packages:
engines: {node: '>=6.0.0'}
dev: true
/@jridgewell/source-map@0.3.3:
resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==}
/@jridgewell/source-map@0.3.5:
resolution: {integrity: sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ==}
dependencies:
'@jridgewell/gen-mapping': 0.3.3
'@jridgewell/trace-mapping': 0.3.18
@@ -1316,12 +1320,12 @@ packages:
/@types/eslint-scope@3.7.4:
resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==}
dependencies:
'@types/eslint': 8.37.0
'@types/eslint': 8.44.2
'@types/estree': 1.0.1
dev: true
/@types/eslint@8.37.0:
resolution: {integrity: sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==}
/@types/eslint@8.44.2:
resolution: {integrity: sha512-sdPRb9K6iL5XZOmBubg8yiFp5yS/JdUDQsq5e6h95km91MCYMuvp7mh1fjPEYUhvHepKpZOjnEaMBR4PxjWDzg==}
dependencies:
'@types/estree': 1.0.1
'@types/json-schema': 7.0.11
@@ -1392,7 +1396,7 @@ packages:
dev: true
/@types/node@17.0.43:
resolution: {integrity: sha512-jnUpgw8fL9kP2iszfIDyBQtw5Mf4/XSqy0Loc1J9pI14ejL83XcCEvSf50Gs/4ET0I9VCCDoOfufQysj0S66xA==, tarball: https://registry.npm.taobao.org/@types/node/-/node-17.0.43.tgz}
resolution: {integrity: sha512-jnUpgw8fL9kP2iszfIDyBQtw5Mf4/XSqy0Loc1J9pI14ejL83XcCEvSf50Gs/4ET0I9VCCDoOfufQysj0S66xA==}
/@types/normalize-package-data@2.4.1:
resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==}
@@ -1888,12 +1892,12 @@ packages:
through: 2.3.8
dev: true
/acorn-import-assertions@1.9.0(acorn@8.8.2):
/acorn-import-assertions@1.9.0(acorn@8.7.1):
resolution: {integrity: sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==}
peerDependencies:
acorn: ^8
dependencies:
acorn: 8.8.2
acorn: 8.7.1
dev: true
/acorn-jsx@5.3.2(acorn@8.7.1):
@@ -1915,14 +1919,14 @@ packages:
hasBin: true
dev: true
/acorn@8.7.1:
resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==}
/acorn@8.10.0:
resolution: {integrity: sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
/acorn@8.8.2:
resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==}
/acorn@8.7.1:
resolution: {integrity: sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==}
engines: {node: '>=0.4.0'}
hasBin: true
dev: true
@@ -2064,11 +2068,12 @@ packages:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
dev: false
/axios@0.27.2:
resolution: {integrity: sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==}
/axios@1.4.0:
resolution: {integrity: sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==}
dependencies:
follow-redirects: 1.15.1
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
dev: false
@@ -2752,7 +2757,7 @@ packages:
dev: false
/echarts-wordcloud@2.0.0(echarts@5.3.3):
resolution: {integrity: sha512-K7l6pTklqdW7ZWzT/1CS0KhBSINr/cd7c5N1fVMzZMwLQHEwT7x+nivK7g5hkVh7WNcAv4Dn6/ZS5zMKRozC1g==, tarball: https://registry.npm.taobao.org/echarts-wordcloud/-/echarts-wordcloud-2.0.0.tgz}
resolution: {integrity: sha512-K7l6pTklqdW7ZWzT/1CS0KhBSINr/cd7c5N1fVMzZMwLQHEwT7x+nivK7g5hkVh7WNcAv4Dn6/ZS5zMKRozC1g==}
peerDependencies:
echarts: ^5.0.1
dependencies:
@@ -2789,8 +2794,8 @@ packages:
engines: {node: '>= 0.8'}
dev: true
/enhanced-resolve@5.14.0:
resolution: {integrity: sha512-+DCows0XNwLDcUhbFJPdlQEVnT2zXlCv7hPxemTz86/O+B/hCQ+mb7ydkPKiflpVraqLPCAfu7lDy+hBXueojw==}
/enhanced-resolve@5.15.0:
resolution: {integrity: sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==}
engines: {node: '>=10.13.0'}
dependencies:
graceful-fs: 4.2.11
@@ -2841,8 +2846,8 @@ packages:
unbox-primitive: 1.0.2
dev: true
/es-module-lexer@1.2.1:
resolution: {integrity: sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==}
/es-module-lexer@1.3.0:
resolution: {integrity: sha512-vZK7T0N2CBmBOixhmjdqx2gWVbFZ4DXZ/NyRMZVlJXPa7CyFS+/a4QQsDGDQy9ZfEzxFuNEsMLeQJnKP2p5/JA==}
dev: true
/es-shim-unscopables@1.0.0:
@@ -3537,6 +3542,7 @@ packages:
/graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
requiresBuild: true
dev: true
/gsap@3.11.3:
@@ -4826,6 +4832,10 @@ packages:
asap: 2.0.6
dev: true
/proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
dev: false
/pug-attrs@3.0.0:
resolution: {integrity: sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA==}
dependencies:
@@ -5139,7 +5149,7 @@ packages:
resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==}
dev: true
/sass-loader@12.6.0(sass@1.52.3)(webpack@5.82.1):
/sass-loader@12.6.0(sass@1.52.3)(webpack@5.88.2):
resolution: {integrity: sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==}
engines: {node: '>= 12.13.0'}
peerDependencies:
@@ -5161,7 +5171,7 @@ packages:
klona: 2.0.5
neo-async: 2.6.2
sass: 1.52.3
webpack: 5.82.1
webpack: 5.88.2
dev: true
/sass@1.52.3:
@@ -5174,8 +5184,8 @@ packages:
source-map-js: 1.0.2
dev: true
/schema-utils@3.1.2:
resolution: {integrity: sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==}
/schema-utils@3.3.0:
resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==}
engines: {node: '>= 10.13.0'}
dependencies:
'@types/json-schema': 7.0.11
@@ -5428,8 +5438,8 @@ packages:
engines: {node: '>=6'}
dev: true
/terser-webpack-plugin@5.3.8(webpack@5.82.1):
resolution: {integrity: sha512-WiHL3ElchZMsK27P8uIUh4604IgJyAW47LVXGbEoB21DbQcZ+OuMpGjVYnEUaqcWM6dO8uS2qUbA7LSCWqvsbg==}
/terser-webpack-plugin@5.3.9(webpack@5.88.2):
resolution: {integrity: sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==}
engines: {node: '>= 10.13.0'}
peerDependencies:
'@swc/core': '*'
@@ -5446,19 +5456,19 @@ packages:
dependencies:
'@jridgewell/trace-mapping': 0.3.18
jest-worker: 27.5.1
schema-utils: 3.1.2
schema-utils: 3.3.0
serialize-javascript: 6.0.1
terser: 5.17.3
webpack: 5.82.1
terser: 5.19.2
webpack: 5.88.2
dev: true
/terser@5.17.3:
resolution: {integrity: sha512-AudpAZKmZHkG9jueayypz4duuCFJMMNGRMwaPvQKWfxKedh8Z2x3OCoDqIIi1xx5+iwx1u6Au8XQcc9Lke65Yg==}
/terser@5.19.2:
resolution: {integrity: sha512-qC5+dmecKJA4cpYxRa5aVkKehYsQKc+AHeKl0Oe62aYjBL8ZA33tTljktDHJSaxxMnbI5ZYw+o/S2DxxLu8OfA==}
engines: {node: '>=10'}
hasBin: true
dependencies:
'@jridgewell/source-map': 0.3.3
acorn: 8.8.2
'@jridgewell/source-map': 0.3.5
acorn: 8.10.0
commander: 2.20.3
source-map-support: 0.5.21
dev: true
@@ -6135,8 +6145,8 @@ packages:
engines: {node: '>=10.13.0'}
dev: true
/webpack@5.82.1:
resolution: {integrity: sha512-C6uiGQJ+Gt4RyHXXYt+v9f+SN1v83x68URwgxNQ98cvH8kxiuywWGP4XeNZ1paOzZ63aY3cTciCEQJNFUljlLw==}
/webpack@5.88.2:
resolution: {integrity: sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ==}
engines: {node: '>=10.13.0'}
hasBin: true
peerDependencies:
@@ -6150,12 +6160,12 @@ packages:
'@webassemblyjs/ast': 1.11.6
'@webassemblyjs/wasm-edit': 1.11.6
'@webassemblyjs/wasm-parser': 1.11.6
acorn: 8.8.2
acorn-import-assertions: 1.9.0(acorn@8.8.2)
acorn: 8.7.1
acorn-import-assertions: 1.9.0(acorn@8.7.1)
browserslist: 4.21.5
chrome-trace-event: 1.0.3
enhanced-resolve: 5.14.0
es-module-lexer: 1.2.1
enhanced-resolve: 5.15.0
es-module-lexer: 1.3.0
eslint-scope: 5.1.1
events: 3.3.0
glob-to-regexp: 0.4.1
@@ -6164,9 +6174,9 @@ packages:
loader-runner: 4.3.0
mime-types: 2.1.35
neo-async: 2.6.2
schema-utils: 3.1.2
schema-utils: 3.3.0
tapable: 2.2.1
terser-webpack-plugin: 5.3.8(webpack@5.82.1)
terser-webpack-plugin: 5.3.9(webpack@5.88.2)
watchpack: 2.4.0
webpack-sources: 3.2.3
transitivePeerDependencies:

View File

@@ -17,7 +17,7 @@
import { NConfigProvider } from 'naive-ui'
import { GoAppProvider } from '@/components/GoAppProvider'
import { I18n } from '@/components/I18n'
import { useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
import { useSystemInit, useDarkThemeHook, useThemeOverridesHook, useCode, useLang } from '@/hooks'
// 暗黑主题
const darkTheme = useDarkThemeHook()
@@ -28,6 +28,9 @@ const overridesTheme = useThemeOverridesHook()
// 代码主题
const hljsTheme = useCode()
// 系统全局数据初始化
useSystemInit()
// 全局语言
const { locale, dateLocale } = useLang()

14
src/api/axios.config.ts Normal file
View File

@@ -0,0 +1,14 @@
import { ModuleTypeEnum } from '@/enums/httpEnum'
// 接口白名单(免登录)
export const fetchAllowList = [
// 登录
`${ModuleTypeEnum.SYSTEM}/login`,
// 获取 OSS 接口
`${ModuleTypeEnum.SYSTEM}/getOssInfo`,
// 预览获取数据
`${ModuleTypeEnum.PROJECT}/getData`,
]
// 接口黑名单
export const fetchBlockList = []

View File

@@ -1,34 +1,93 @@
import axios, { AxiosResponse, InternalAxiosRequestConfig, AxiosError } from 'axios'
import { ResultEnum } from "@/enums/httpEnum"
import { ErrorPageNameMap } from "@/enums/pageEnum"
import { redirectErrorPage } from '@/utils'
import axios, { AxiosResponse, AxiosRequestConfig, Axios, AxiosError, InternalAxiosRequestConfig } from 'axios'
import { RequestHttpHeaderEnum, ResultEnum, ModuleTypeEnum } from '@/enums/httpEnum'
import { PageEnum, ErrorPageNameMap } from '@/enums/pageEnum'
import { StorageEnum } from '@/enums/storageEnum'
import { axiosPre } from '@/settings/httpSetting'
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
import { redirectErrorPage, getLocalStorage, routerTurnByName, isPreview } from '@/utils'
import { fetchAllowList } from './axios.config'
import includes from 'lodash/includes'
export interface MyResponseType<T> {
code: ResultEnum
data: T
message: string
}
export interface MyRequestInstance extends Axios {
<T = any>(config: AxiosRequestConfig): Promise<MyResponseType<T>>
}
const axiosInstance = axios.create({
baseURL: import.meta.env.DEV ? import.meta.env.VITE_DEV_PATH : import.meta.env.VITE_PRO_PATH,
timeout: ResultEnum.TIMEOUT,
})
baseURL: `${import.meta.env.PROD ? import.meta.env.VITE_PRO_PATH : ''}${axiosPre}`,
timeout: ResultEnum.TIMEOUT
}) as unknown as MyRequestInstance
axiosInstance.interceptors.request.use(
(config: InternalAxiosRequestConfig) => {
// 白名单校验
if (includes(fetchAllowList, config.url)) return config
// 获取 token
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
// 重新登录
if (!info) {
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
return config
}
const userInfo = info[SystemStoreEnum.USER_INFO]
config.headers[userInfo[SystemStoreUserInfoEnum.TOKEN_NAME] || 'token'] = userInfo[SystemStoreUserInfoEnum.USER_TOKEN] || ''
return config
},
(error: AxiosError) => {
Promise.reject(error)
(err: AxiosError) => {
Promise.reject(err)
}
)
// 响应拦截器
axiosInstance.interceptors.response.use(
(res: AxiosResponse) => {
// 预览页面错误不进行处理
if (isPreview()) {
return Promise.resolve(res.data)
}
const { code } = res.data as { code: number }
if (code === undefined || code === null) return Promise.resolve(res.data)
if (code === ResultEnum.DATA_SUCCESS) return Promise.resolve(res.data)
// 重定向
if (ErrorPageNameMap.get(code)) redirectErrorPage(code)
// 成功
if (code === ResultEnum.SUCCESS) {
return Promise.resolve(res.data)
}
// 登录过期
if (code === ResultEnum.TOKEN_OVERDUE) {
window['$message'].error(window['$t']('http.token_overdue_message'))
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
return Promise.resolve(res.data)
}
// 固定错误码重定向
if (ErrorPageNameMap.get(code)) {
redirectErrorPage(code)
return Promise.resolve(res.data)
}
// 提示错误
window['$message'].error(window['$t']((res.data as any).msg))
return Promise.resolve(res.data)
},
(err: AxiosResponse) => {
Promise.reject(err)
(err: AxiosError) => {
const status = err.response?.status
switch (status) {
case 401:
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
Promise.reject(err)
break
default:
Promise.reject(err)
break
}
}
)

View File

@@ -9,16 +9,16 @@ import {
} from '@/enums/httpEnum'
import type { RequestGlobalConfigType, RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
export const get = (url: string, params?: object) => {
return axiosInstance({
export const get = <T = any>(url: string, params?: object) => {
return axiosInstance<T>({
url: url,
method: RequestHttpEnum.GET,
params: params
params: params,
})
}
export const post = (url: string, data?: object, headersType?: string) => {
return axiosInstance({
export const post = <T = any>(url: string, data?: object, headersType?: string) => {
return axiosInstance<T>({
url: url,
method: RequestHttpEnum.POST,
data: data,
@@ -28,8 +28,8 @@ export const post = (url: string, data?: object, headersType?: string) => {
})
}
export const patch = (url: string, data?: object, headersType?: string) => {
return axiosInstance({
export const patch = <T = any>(url: string, data?: object, headersType?: string) => {
return axiosInstance<T>({
url: url,
method: RequestHttpEnum.PATCH,
data: data,
@@ -39,8 +39,8 @@ export const patch = (url: string, data?: object, headersType?: string) => {
})
}
export const put = (url: string, data?: object, headersType?: ContentTypeEnum) => {
return axiosInstance({
export const put = <T = any>(url: string, data?: object, headersType?: ContentTypeEnum) => {
return axiosInstance<T>({
url: url,
method: RequestHttpEnum.PUT,
data: data,
@@ -50,8 +50,8 @@ export const put = (url: string, data?: object, headersType?: ContentTypeEnum) =
})
}
export const del = (url: string, params?: object) => {
return axiosInstance({
export const del = <T = any>(url: string, params?: object) => {
return axiosInstance<T>({
url: url,
method: RequestHttpEnum.DELETE,
params
@@ -82,11 +82,11 @@ export const http = (type?: RequestHttpEnum) => {
}
const prefix = 'javascript:'
// 对输入字符进行转义处理
export const translateStr = (target: string | object) => {
export const translateStr = (target: string | Record<any, any>) => {
if (typeof target === 'string') {
if (target.startsWith(prefix)) {
const funcStr = target.split(prefix)[1]
let result;
let result
try {
result = new Function(`${funcStr}`)()
} catch (error) {
@@ -100,8 +100,8 @@ export const translateStr = (target: string | object) => {
}
for (const key in target) {
if (Object.prototype.hasOwnProperty.call(target, key)) {
const subTarget = (target as any)[key];
(target as any)[key] = translateStr(subTarget)
const subTarget = target[key]
target[key] = translateStr(subTarget)
}
}
return target

2
src/api/path/index.ts Normal file
View File

@@ -0,0 +1,2 @@
export * from '@/api/path/project.api'
export * from '@/api/path/system.api'

View File

@@ -0,0 +1,99 @@
import { http } from '@/api/http'
import { httpErrorHandle } from '@/utils'
import { ContentTypeEnum, RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum'
import { ProjectItem, ProjectDetail } from './project'
// * 项目列表
export const projectListApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.GET)<ProjectItem[]>(`${ModuleTypeEnum.PROJECT}/list`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 新增项目
export const createProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)<{
/**
* 项目id
*/
id: number
}>(`${ModuleTypeEnum.PROJECT}/create`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 获取项目
export const fetchProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.GET)<ProjectDetail>(`${ModuleTypeEnum.PROJECT}/getData`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 保存项目
export const saveProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)(
`${ModuleTypeEnum.PROJECT}/save/data`,
data,
ContentTypeEnum.FORM_URLENCODED
)
return res
} catch {
httpErrorHandle()
}
}
// * 修改项目基础信息
export const updateProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)(`${ModuleTypeEnum.PROJECT}/edit`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 删除项目
export const deleteProjectApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.DELETE)(`${ModuleTypeEnum.PROJECT}/delete`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 修改发布状态 [-1未发布,1发布]
export const changeProjectReleaseApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.PUT)(`${ModuleTypeEnum.PROJECT}/publish`, data)
return res
} catch {
httpErrorHandle()
}
}
// * 上传文件
export const uploadFile = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)<{
/**
* 文件地址
*/
fileName: string,
fileurl: string,
}>(`${ModuleTypeEnum.PROJECT}/upload`, data, ContentTypeEnum.FORM_DATA)
return res
} catch {
httpErrorHandle()
}
}

39
src/api/path/project.d.ts vendored Normal file
View File

@@ -0,0 +1,39 @@
export type ProjectItem = {
/**
* 项目 id
*/
id: string
/**
* 项目名称
*/
projectName: string
/**
* 项目状态:\
* -1: 未发布\
* 1: 已发布
*/
state: number
/**
* 创建时间
*/
createTime: string
/**
* 预览图片url
*/
indexImage: string
/**
* 创建者 id
*/
createUserId: string
/**
* 项目备注
*/
remarks: string
}
export interface ProjectDetail extends ProjectItem {
/**
* 项目参数
*/
content: string
}

View File

@@ -0,0 +1,39 @@
import { http } from '@/api/http'
import { httpErrorHandle } from '@/utils'
import { RequestHttpEnum, ModuleTypeEnum } from '@/enums/httpEnum'
import { LoginResult } from './system'
// * 登录
export const loginApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.POST)<LoginResult>(`${ModuleTypeEnum.SYSTEM}/login`, data)
return res
} catch (err) {
httpErrorHandle()
}
}
// * 登出
export const logoutApi = async () => {
try {
const res = await http(RequestHttpEnum.GET)(`${ModuleTypeEnum.SYSTEM}/logout`)
return res
} catch (err) {
httpErrorHandle()
}
}
// * 获取 oss 上传接口
export const ossUrlApi = async (data: object) => {
try {
const res = await http(RequestHttpEnum.GET)<{
/**
* bucket 地址
*/
bucketURL?: string
}>(`${ModuleTypeEnum.SYSTEM}/getOssInfo`, data)
return res
} catch (err) {
httpErrorHandle()
}
}

26
src/api/path/system.d.ts vendored Normal file
View File

@@ -0,0 +1,26 @@
export interface LoginResult {
token: {
/**
* token 值
*/
tokenValue: string
/**
* token key
*/
tokenName: string
}
userinfo: {
/**
* 昵称
*/
nickname: string
/**
* 用户名
*/
username: string
/**
* 用户 id
*/
id: string
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -27,7 +27,9 @@
<script lang="ts" setup>
import { h, ref } from 'vue'
import { NAvatar, NText } from 'naive-ui'
import { renderIcon } from '@/utils'
import { renderIcon, getLocalStorage } from '@/utils'
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
import { StorageEnum } from '@/enums/storageEnum'
import { logout, renderLang } from '@/utils'
import { GoSystemSet } from '@/components/GoSystemSet/index'
import { GoSystemInfo } from '@/components/GoSystemInfo/index'
@@ -64,7 +66,17 @@ const renderUserInfo = () => {
}),
h('div', null, [
h('div', null, [
h(NText, { depth: 2 }, { default: () => '奔跑的面条' })
h(NText, { depth: 2 }, {
default: () => {
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
if (info) {
return info[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_NAME];
}
else {
return 'admin';
}
}
})
])
])
]
@@ -137,4 +149,4 @@ const handleSelect = (key: string) => {
cursor: pointer;
transform: scale(0.7);
}
</style>
</style>

View File

@@ -48,7 +48,6 @@ export enum MenuEnum {
UN_GROUP = 'unGroup',
// 后退
BACK = 'back',
// 前进
FORWORD = 'forward',
// 保存
SAVE = 'save',
@@ -84,3 +83,15 @@ export enum MacKeyboard {
ALT_SOURCE_KEY = '⌥',
SPACE = 'Space'
}
// 同步状态枚举
export enum SyncEnum {
// 等待
PENDING,
// 开始
START,
// 成功
SUCCESS,
// 失败
FAILURE
}

View File

@@ -1,13 +1,18 @@
/**
* @description: 请求结果集
*/
// 模块 Path 前缀分类
export enum ModuleTypeEnum {
SYSTEM = 'sys',
PROJECT = 'project',
}
// 请求结果集
export enum ResultEnum {
DATA_SUCCESS = 0,
SUCCESS = 200,
SERVER_ERROR = 500,
SERVER_FORBIDDEN = 403,
NOT_FOUND = 404,
TIMEOUT = 60000
TOKEN_OVERDUE = 886,
TIMEOUT = 60000,
}
// 数据相关
@@ -28,9 +33,13 @@ export enum RequestContentTypeEnum {
SQL = 1
}
/**
* @description: 请求方法
*/
// 头部
export enum RequestHttpHeaderEnum {
TOKEN = 'Token',
COOKIE = 'Cookie'
}
// 请求方法
export enum RequestHttpEnum {
GET = 'get',
POST = 'post',
@@ -111,9 +120,7 @@ export type RequestParams = {
}
}
/**
* @description: 常用的contentTyp类型
*/
// 常用的contentTyp类型
export enum ContentTypeEnum {
// json
JSON = 'application/json;charset=UTF-8',

View File

@@ -26,10 +26,15 @@ export enum PageEnum {
//重定向
REDIRECT = '/redirect',
REDIRECT_NAME = 'Redirect',
// 未发布
REDIRECT_UN_PUBLISH = '/redirect/unPublish',
REDIRECT_UN_PUBLISH_NAME = 'redirect-un-publish',
// 重载
RELOAD = '/reload',
RELOAD_NAME = 'Reload',
// 首页
BASE_HOME = '/project',
BASE_HOME_NAME = 'Project',

View File

@@ -1,10 +1,8 @@
export enum StorageEnum {
// 全局设置
GO_SYSTEM_SETTING_STORE = 'GO_SYSTEM_SETTING',
// token 等信息
GO_ACCESS_TOKEN_STORE = 'GO_ACCESS_TOKEN',
GO_SETTING_STORE = 'GO_SETTING',
// 登录信息
GO_LOGIN_INFO_STORE = 'GO_LOGIN_INFO',
GO_SYSTEM_STORE = 'GO_SYSTEM',
// 语言
GO_LANG_STORE = 'GO_LANG',
// 当前选择的主题

View File

@@ -2,6 +2,7 @@ export * from '@/hooks/useTheme.hook'
export * from '@/hooks/usePreviewScale.hook'
export * from '@/hooks/useCode.hook'
export * from '@/hooks/useChartDataFetch.hook'
export * from '@/hooks/useSystemInit.hook'
export * from '@/hooks/useChartDataPondFetch.hook'
export * from '@/hooks/useLifeHandler.hook'
export * from '@/hooks/useLang.hook'

View File

@@ -95,7 +95,7 @@ export const useChartDataFetch = (
fetchFn()
},
{
immediate: false,
immediate: true,
deep: true
}
)

View File

@@ -48,10 +48,10 @@ export const useLifeHandler = (chartConfig: CreateComponentType | CreateComponen
try {
return new Function(`
return (
async function(mouseEvent){
async function(components,mouseEvent){
${fnStr}
}
)`)()
)`)().bind(undefined,components)
} catch (error) {
console.error(error)
}

View File

@@ -0,0 +1,23 @@
import { useSystemStore } from '@/store/modules/systemStore/systemStore'
import { SystemStoreEnum } from '@/store/modules/systemStore/systemStore.d'
import { ResultEnum } from '@/enums/httpEnum'
import { ossUrlApi } from '@/api/path'
// * 初始化
export const useSystemInit = async () => {
const systemStore = useSystemStore()
// 获取 OSS 信息的 url 地址,用来拼接展示图片的地址
const getOssUrl = async () => {
const res = await ossUrlApi({})
if (res && res.code === ResultEnum.SUCCESS) {
systemStore.setItem(SystemStoreEnum.FETCH_INFO, {
OSSUrl: res.data?.bucketURL
})
}
}
// 执行
getOssUrl()
}

View File

@@ -11,6 +11,8 @@ const global = {
help: 'Help',
contact: 'About Software',
logout: 'Logout',
logout_success: 'Logout success',
logout_failure: 'Logout Failed',
// system setting
sys_set: 'System Setting',
lang_set: 'Language Setting',
@@ -26,8 +28,14 @@ const global = {
r_more: 'More',
}
const http = {
error_message: 'The interface is abnormal, please check the interface!',
token_overdue_message: 'Login expired, please log in again!'
}
export default {
global,
http,
login,
project
}

View File

@@ -2,6 +2,6 @@ export default {
desc: "Login",
form_auto: "Sign in automatically",
form_button: "Login",
login_success: "Login success",
login_message: "Please complete the letter",
login_success: "Login success!",
login_message: "Please complete the letter!",
}

View File

@@ -1,6 +1,8 @@
export default {
create_btn: 'Create',
create_tip: 'Please select a content for development',
create_btn: 'Creat',
create_success: 'Creat Success!',
create_failure: 'Failed to create, please try again later',
create_tip: 'Please select a content for development!',
project: 'Project',
my: 'My',
new_project: 'New Project',

View File

@@ -11,6 +11,8 @@ const global = {
help: '帮助中心',
contact: '关于软件',
logout: '退出登录',
logout_success: '退出成功!',
logout_failure: '退出失败!',
// 系统设置
sys_set: '系统设置',
lang_set: '语言设置',
@@ -18,16 +20,27 @@ const global = {
r_edit: '编辑',
r_preview: '预览',
r_copy: '克隆',
r_copy_success: '克隆成功!',
r_rename: '重命名',
r_rename_success: '重命名成功!',
r_publish: '发布',
r_publish_success: '成功发布!',
r_unpublish: '取消发布',
r_unpublish_success: '取消成功!',
r_download: '下载',
r_delete: '删除',
r_delete_success: '删除成功!',
r_more: '更多',
}
const http = {
error_message: '获取数据失败,请稍后重试!',
token_overdue_message: '登录过期,请重新登录!'
}
export default {
global,
http,
login,
project
}

View File

@@ -2,6 +2,6 @@ export default {
desc: "登录",
form_auto: "自动登录",
form_button: "登录",
login_success: "登录成功",
login_message: "请填写完整信息",
login_success: "登录成功!",
}

View File

@@ -1,6 +1,8 @@
export default {
// aside
create_btn: '新建',
create_success: '新建成功!',
create_failure: '新建失败,请稍后重试!',
create_tip: '从哪里出发好呢?',
project: '项目',
my: '我的',

View File

@@ -0,0 +1,75 @@
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { BarLineConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = ['legend', 'xAxis', 'yAxis', 'grid']
// 柱状折线组合图 分别定义series
// 写死name可以定义legend显示的名称
export const barSeriesItem = {
type: 'bar',
barWidth: 15,
label: {
show: true,
position: 'top',
color: '#fff',
fontSize: 12
},
itemStyle: {
color: null,
borderRadius: 2
}
}
export const lineSeriesItem = {
type: 'line',
symbol: 'circle',
label: {
show: true,
position: 'top',
color: '#fff',
fontSize: 12
},
symbolSize: 5, //设定实心点的大小
itemStyle: {
color: '#FFE47A',
borderWidth: 1
},
lineStyle: {
type: 'solid',
width: 3,
color: null
}
}
export const option = {
tooltip: {
show: true,
trigger: 'axis',
axisPointer: {
show: true,
type: 'shadow'
}
},
legend: {
data: null
},
xAxis: {
show: true,
type: 'category'
},
yAxis: {
show: true,
type: 'value'
},
dataset: { ...dataJson },
series: [barSeriesItem, lineSeriesItem]
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = BarLineConfig.key
public chartConfig = cloneDeep(BarLineConfig)
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
}

View File

@@ -0,0 +1,93 @@
<template>
<!-- Echarts 全局设置 -->
<global-setting :optionData="optionData"></global-setting>
<CollapseItem
v-for="(item, index) in seriesList"
:key="index"
:name="`${item.type == 'bar' ? '柱状图' : '折线图'}`"
:expanded="true"
>
<SettingItemBox name="图形" v-if="item.type == 'bar'">
<SettingItem name="宽度">
<n-input-number
v-model:value="item.barWidth"
:min="1"
:max="100"
size="small"
placeholder="自动计算"
></n-input-number>
</SettingItem>
<SettingItem name="圆角">
<n-input-number v-model:value="item.itemStyle.borderRadius" :min="0" size="small"></n-input-number>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="线条" v-if="item.type == 'line'">
<SettingItem name="宽度">
<n-input-number
v-model:value="item.lineStyle.width"
:min="1"
:max="100"
size="small"
placeholder="自动计算"
></n-input-number>
</SettingItem>
<SettingItem name="类型">
<n-select v-model:value="item.lineStyle.type" size="small" :options="lineConf.lineStyle.type"></n-select>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="实心点" v-if="item.type == 'line'">
<SettingItem name="大小">
<n-input-number
v-model:value="item.symbolSize"
:min="1"
:max="100"
size="small"
placeholder="自动计算"
></n-input-number>
</SettingItem>
</SettingItemBox>
<setting-item-box name="标签">
<setting-item>
<n-space>
<n-switch v-model:value="item.label.show" size="small" />
<n-text>展示标签</n-text>
</n-space>
</setting-item>
<setting-item name="大小">
<n-input-number v-model:value="item.label.fontSize" size="small" :min="1"></n-input-number>
</setting-item>
<setting-item name="tip颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="item.label.color"></n-color-picker>
</setting-item>
<setting-item name="位置">
<n-select
v-model:value="item.label.position"
:options="[
{ label: 'top', value: 'top' },
{ label: 'left', value: 'left' },
{ label: 'right', value: 'right' },
{ label: 'bottom', value: 'bottom' }
]"
/>
</setting-item>
</setting-item-box>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType, computed } from 'vue'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { lineConf } from '@/packages/chartConfiguration/echarts'
import { GlobalThemeJsonType } from '@/settings/chartThemes'
const props = defineProps({
optionData: {
type: Object as PropType<GlobalThemeJsonType>,
required: true
}
})
const seriesList = computed(() => {
return props.optionData.series
})
</script>

View File

@@ -0,0 +1,40 @@
{
"dimensions": ["product", "data1", "data2"],
"source": [
{
"product": "1月",
"data1": 104,
"data2": 30
},
{
"product": "2月",
"data1": 56,
"data2": 56
},
{
"product": "3月",
"data1": 136,
"data2": 36
},
{
"product": "4月",
"data1": 86,
"data2": 6
},
{
"product": "5月",
"data1": 98,
"data2": 10
},
{
"product": "6月",
"data1": 86,
"data2": 70
},
{
"product": "7月",
"data1": 77,
"data2": 57
}
]
}

View File

@@ -0,0 +1,16 @@
// 公共类型声明
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
// 当前[信息模块]分类声明
import { ChatCategoryEnum,ChatCategoryEnumName } from '../../index.d'
export const BarLineConfig: ConfigType = {
key: 'BarLine',
chartKey: 'VBarLine',
conKey: 'VCBarLine',
title: '柱状图 & 折线图',
category: ChatCategoryEnum.BAR,
categoryName: ChatCategoryEnumName.BAR,
package: PackagesCategoryEnum.CHARTS,
chartFrame: ChartFrameEnum.ECHARTS,
image: 'bar_line.png'
}

View File

@@ -0,0 +1,73 @@
<template>
<v-chart
ref="vChartRef"
:init-options="initOptions"
:theme="themeColor"
:option="option"
:manual-update="isPreview()"
autoresize
></v-chart>
</template>
<script setup lang="ts">
import { ref, computed, watch, PropType, nextTick } from 'vue'
import VChart from 'vue-echarts'
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
//引入柱状图 折线图
import { BarChart, LineChart } from 'echarts/charts'
import config, { includes, barSeriesItem, lineSeriesItem } from './config'
import { mergeTheme } from '@/packages/public/chart'
import { useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { isPreview } from '@/utils'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
const props = defineProps({
themeSetting: {
type: Object,
required: true
},
themeColor: {
type: Object,
required: true
},
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
use([DatasetComponent, CanvasRenderer, BarChart, LineChart, GridComponent, TooltipComponent, LegendComponent])
const replaceMergeArr = ref<string[]>()
const option = computed(() => {
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
})
watch(
() => props.chartConfig.option.dataset,
(newData, oldData) => {
if (newData.dimensions.length !== oldData.dimensions.length) {
const seriesArr = []
for (let i = 0; i < newData.dimensions.length - 1; i++) {
seriesArr.push(barSeriesItem, lineSeriesItem)
}
replaceMergeArr.value = ['series']
props.chartConfig.option.series = seriesArr
nextTick(() => {
replaceMergeArr.value = []
})
}
},
{
deep: false
}
)
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
</script>

View File

@@ -1,5 +1,6 @@
import { BarCommonConfig } from './BarCommon/index'
import { BarCrossrangeConfig } from './BarCrossrange/index'
import { CapsuleChartConfig } from './CapsuleChart/index'
export default [BarCommonConfig, BarCrossrangeConfig, CapsuleChartConfig]
import { BarCommonConfig } from './BarCommon/index'
import { BarCrossrangeConfig } from './BarCrossrange/index'
import { CapsuleChartConfig } from './CapsuleChart/index'
import { BarLineConfig } from './BarLine/index'
export default [BarCommonConfig, BarCrossrangeConfig, BarLineConfig, CapsuleChartConfig]

View File

@@ -33,6 +33,10 @@ export const option = {
width: 3,
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{
offset: 0,

View File

@@ -84,7 +84,10 @@ export const option = {
shadowColor: '#E1FFFF',
shadowBlur: 10
},
data: []
data: [],
encode: {
value: 2
}
},
{
name: '区域',

View File

@@ -3,7 +3,7 @@
:type="type"
:height="h"
:processing="processing"
:percentage="option.dataset"
:percentage="dataset"
:indicator-placement="indicatorPlacement"
:color="color"
:rail-color="railColor"
@@ -15,7 +15,7 @@
fontSize: `${indicatorTextSize}px`
}"
>
{{ option.dataset }} {{ unit }}
{{ dataset }} {{ unit }}
</n-text>
</n-progress>
</template>

View File

@@ -14,5 +14,6 @@ export enum ChatCategoryEnumName {
LINE = '折线图',
SCATTER = '散点图',
MAP = '地图',
COMBINATION = '组合图',
MORE = '更多'
}

View File

@@ -0,0 +1,18 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import { FullScreenConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
export const option = {
border: 6,
bgColor: '#84a5e9',
borderColor: '#84a5e9'
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = FullScreenConfig.key
public attr = { ...chartInitConfig, w: 150, h: 150, zIndex: -1 }
public chartConfig = cloneDeep(FullScreenConfig)
public option = cloneDeep(option)
}

View File

@@ -0,0 +1,28 @@
<template>
<CollapseItem name="全屏按钮" expanded>
<SettingItemBox name="按钮">
<SettingItem name="背景色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.bgColor"></n-color-picker>
</SettingItem>
<SettingItem name="边框色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.borderColor"></n-color-picker>
</SettingItem>
<SettingItem name="边框大小">
<n-input-number v-model:value="optionData.border" size="small" :step="0.5" :min="0"></n-input-number>
</SettingItem>
</SettingItemBox>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { option } from './config'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const FullScreenConfig: ConfigType = {
key: 'FullScreen',
chartKey: 'VFullScreen',
conKey: 'VCFullScreen',
title: '全屏按钮',
category: ChatCategoryEnum.MORE,
categoryName: ChatCategoryEnumName.MORE,
package: PackagesCategoryEnum.DECORATES,
chartFrame: ChartFrameEnum.STATIC,
image: 'fullScreen.png'
}

View File

@@ -0,0 +1,111 @@
<template>
<svg @click="toggleFullscreen" v-if="!isFullscreen" viewBox="0 0 1024 1024">
<path
d="M665.6 1017.6c-19.2 0-38.4-19.2-38.4-38.4s19.2-38.4 38.4-38.4h268.8l6.4-268.8c0-19.2 19.2-38.4 38.4-38.4s38.4 19.2 38.4 38.4v294.4c0 32-25.6 51.2-51.2 51.2h-300.8zM51.2 396.8c-19.2 0-38.4-19.2-38.4-38.4V64C12.8 32 38.4 12.8 64 12.8h294.4c19.2 0 38.4 19.2 38.4 38.4s-19.2 38.4-38.4 38.4H89.6v268.8c0 19.2-19.2 38.4-38.4 38.4zM64 1017.6c-32 0-51.2-25.6-51.2-51.2v-294.4c0-19.2 19.2-38.4 38.4-38.4s38.4 19.2 38.4 38.4v217.6l198.4-198.4c6.4-6.4 19.2-12.8 25.6-12.8s19.2 6.4 25.6 12.8c6.4 6.4 12.8 19.2 12.8 25.6 0 12.8-6.4 19.2-12.8 25.6l-198.4 198.4h217.6c19.2 0 38.4 19.2 38.4 38.4s-19.2 38.4-38.4 38.4H64z m915.2-620.8c-19.2 0-38.4-19.2-38.4-38.4V140.8l-198.4 198.4c-6.4 6.4-19.2 12.8-25.6 12.8-12.8 0-19.2-6.4-25.6-12.8-12.8-12.8-12.8-38.4 0-51.2l198.4-198.4h-217.6c-19.2 0-38.4-19.2-38.4-38.4s19.2-38.4 38.4-38.4h294.4c32 0 51.2 25.6 51.2 51.2v294.4c0 19.2-19.2 38.4-38.4 38.4z"
class="fullScreen-border"
></path>
</svg>
<svg @click="toggleFullscreen" v-else viewBox="0 0 1024 1024">
<path
d="M379.336 697.237L153.362 921.55c-14.11 14.007-36.905 13.922-50.912-0.188-14.007-14.11-13.922-36.905 0.188-50.912l227.6-225.927H138.645c-18.99 0-34.385-15.446-34.385-34.5 0-19.053 15.395-34.5 34.385-34.5H413.72c18.99 0 34.384 15.447 34.384 34.5v276c0 9.15-3.622 17.926-10.07 24.396a34.326 34.326 0 0 1-24.314 10.104 34.326 34.326 0 0 1-24.314-10.104 34.559 34.559 0 0 1-10.071-24.396V697.237z m263.395-366.88l227.813-227.813c14.059-14.059 36.853-14.059 50.912 0 14.059 14.059 14.059 36.853 0 50.912l-225.18 225.18h187.147c18.99 0 34.385 15.445 34.385 34.5 0 19.053-15.395 34.5-34.385 34.5H608.346c-18.99 0-34.384-15.447-34.384-34.5v-276c0-9.15 3.622-17.926 10.07-24.396a34.326 34.326 0 0 1 24.314-10.105c9.12 0 17.865 3.635 24.314 10.105a34.559 34.559 0 0 1 10.07 24.395v193.223zM99.385 410a34.326 34.326 0 0 1-24.314-10.105A34.559 34.559 0 0 1 65 375.5v-276C65 80.446 80.395 65 99.385 65h275.077c18.99 0 34.384 15.446 34.384 34.5 0 19.054-15.394 34.5-34.384 34.5H133.769v241.5c0 9.15-3.622 17.925-10.07 24.395A34.326 34.326 0 0 1 99.384 410z m825.23 552H649.538c-18.99 0-34.384-15.446-34.384-34.5 0-19.054 15.394-34.5 34.384-34.5h240.693V651.5c0-19.054 15.394-34.5 34.384-34.5 18.99 0 34.385 15.446 34.385 34.5v276c0 19.054-15.395 34.5-34.385 34.5z"
class="fullScreen-border"
></path>
</svg>
</template>
<script setup lang="ts">
import { PropType, toRefs, ref, onMounted, onUnmounted } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { option } from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType & typeof option>,
required: true
}
})
let { border, bgColor, borderColor } = toRefs(props.chartConfig.option)
const isFullscreen = ref(false)
const checkFullscreen = () => {
isFullscreen.value = !!(
document.fullscreenElement ||
(document as any).webkitFullscreenElement ||
(document as any).mozFullScreenElement ||
(document as any).msFullscreenElement
)
}
checkFullscreen()
const requestFullscreen = (element: Element) => {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if ((document as any).mozRequestFullScreen) {
/* Firefox */
(document as any).mozRequestFullScreen()
} else if ((document as any).webkitRequestFullscreen) {
/* Chrome, Safari and Opera */
(document as any).webkitRequestFullscreen()
} else if ((document as any).msRequestFullscreen) {
/* IE/Edge */
(document as any).msRequestFullscreen()
}
}
const exitFullscreen = () => {
if (document.fullscreenElement && document.exitFullscreen) {
document.exitFullscreen()
} else if ((document as any).mozFullScreenElement && (document as any).mozCancelFullScreen) {
/* Firefox */
(document as any).mozCancelFullScreen()
} else if ((document as any).webkitFullscreenElement && (document as any).webkitExitFullscreen) {
/* Chrome, Safari and Opera */
(document as any).webkitExitFullscreen()
} else if ((document as any).msFullscreenElement && (document as any).msExitFullscreen) {
/* IE/Edge */
(document as any).msExitFullscreen()
}
}
const toggleFullscreen = () => {
if (!isFullscreen.value) {
requestFullscreen(document.documentElement)
} else {
exitFullscreen()
}
isFullscreen.value = !isFullscreen.value
// 由于全屏状态的改变不会立即生效,所以需要延迟一段时间再去获取全屏状态
setTimeout(() => {
checkFullscreen()
}, 1000)
}
// 监听全屏状态的改变,保证多个全屏组件的状态一致
onMounted(() => {
document.addEventListener('fullscreenchange', checkFullscreen)
document.addEventListener('webkitfullscreenchange', checkFullscreen)
document.addEventListener('mozfullscreenchange', checkFullscreen)
document.addEventListener('MSFullscreenChange', checkFullscreen)
})
onUnmounted(() => {
document.removeEventListener('fullscreenchange', checkFullscreen)
document.removeEventListener('webkitfullscreenchange', checkFullscreen)
document.removeEventListener('mozfullscreenchange', checkFullscreen)
document.removeEventListener('MSFullscreenChange', checkFullscreen)
})
</script>
<style lang="scss" scoped>
svg {
display: block;
width: 100%;
height: 100%;
cursor: pointer;
}
.fullScreen-border {
stroke: v-bind('borderColor');
stroke-width: v-bind('border+"px"');
fill: v-bind('bgColor');
}
</style>

View File

@@ -1,9 +1,19 @@
import { NumberConfig } from './Number/index'
import { TimeCommonConfig } from './TimeCommon/index'
import { ClockConfig } from './Clock/index'
import { FullScreenConfig } from './FullScreen/index'
import { CountDownConfig } from './CountDown/index'
import { FlipperNumberConfig } from './FlipperNumber'
import { PipelineHConfig } from './PipelineH/index'
import { PipelineVConfig } from './PipelineV/index'
export default [NumberConfig, FlipperNumberConfig, TimeCommonConfig, CountDownConfig, ClockConfig, PipelineHConfig, PipelineVConfig]
export default [
NumberConfig,
FlipperNumberConfig,
TimeCommonConfig,
CountDownConfig,
ClockConfig,
FullScreenConfig,
PipelineHConfig,
PipelineVConfig
]

View File

@@ -1,62 +1,63 @@
/**
* 创建 threejs 四大天王
* 场景、相机、渲染器、控制器
*/
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export class Basic {
public scene!: THREE.Scene
public camera!: THREE.PerspectiveCamera
public renderer!: THREE.WebGLRenderer
public controls!: OrbitControls
public dom: HTMLElement
constructor(dom: HTMLElement) {
this.dom = dom
this.initScenes()
this.setControls()
}
/**
* 初始化场景
*/
initScenes() {
this.scene = new THREE.Scene()
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100000)
this.camera.position.set(0, 30, -250)
this.renderer = new THREE.WebGLRenderer({
// canvas: this.dom,
alpha: true, // 透明
antialias: true // 抗锯齿
})
this.renderer.setPixelRatio(window.devicePixelRatio) // 设置屏幕像素比
this.renderer.setSize(window.innerWidth, window.innerHeight) // 设置渲染器宽高
this.dom.appendChild(this.renderer.domElement) // 添加到dom中
}
/**
* 设置控制器
*/
setControls() {
// 鼠标控制 相机渲染dom
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
this.controls.autoRotateSpeed = 3
// 使动画循环使用时阻尼或自转 意思是否有惯性
this.controls.enableDamping = true
// 动态阻尼系数 就是鼠标拖拽旋转灵敏度
this.controls.dampingFactor = 0.05
// 是否可以缩放
this.controls.enableZoom = true
// 设置相机距离原点的最远距离
this.controls.minDistance = 100
// 设置相机距离原点的最远距离
this.controls.maxDistance = 300
// 是否开启右键拖拽
this.controls.enablePan = false
}
}
/**
* 创建 threejs 四大天王
* 场景、相机、渲染器、控制器
*/
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
export class Basic {
public scene!: THREE.Scene
public camera!: THREE.PerspectiveCamera
public renderer!: THREE.WebGLRenderer
public controls!: OrbitControls
public dom: HTMLElement
constructor(dom: HTMLElement) {
this.dom = dom
this.initScenes()
this.setControls()
}
/**
* 初始化场景
*/
initScenes() {
this.scene = new THREE.Scene()
this.camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 1, 100000)
this.camera.position.set(0, 30, -250)
this.renderer = new THREE.WebGLRenderer({
// canvas: this.dom,
alpha: true, // 透明
antialias: true, // 抗锯齿
preserveDrawingBuffer: true
})
this.renderer.setPixelRatio(window.devicePixelRatio) // 设置屏幕像素比
this.renderer.setSize(window.innerWidth, window.innerHeight) // 设置渲染器宽高
this.dom.appendChild(this.renderer.domElement) // 添加到dom中
}
/**
* 设置控制器
*/
setControls() {
// 鼠标控制 相机渲染dom
this.controls = new OrbitControls(this.camera, this.renderer.domElement)
this.controls.autoRotateSpeed = 3
// 使动画循环使用时阻尼或自转 意思是否有惯性
this.controls.enableDamping = true
// 动态阻尼系数 就是鼠标拖拽旋转灵敏度
this.controls.dampingFactor = 0.05
// 是否可以缩放
this.controls.enableZoom = true
// 设置相机距离原点的最远距离
this.controls.minDistance = 100
// 设置相机距离原点的最远距离
this.controls.maxDistance = 300
// 是否开启右键拖拽
this.controls.enablePan = false
}
}

View File

@@ -0,0 +1,24 @@
import cloneDeep from 'lodash/cloneDeep'
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
import { interactActions, ComponentInteractEventEnum } from './interact'
import {InputsInputConfig} from "./index";
export const option = {
// 时间组件展示类型,必须和 interactActions 中定义的数据一致
[COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA,
// 默认值
inputValue: "0",
// 暴露配置内容给用户
dataset: ""
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = InputsInputConfig.key
public attr = { ...chartInitConfig, w: 260, h: 32, zIndex: -1 }
public chartConfig = cloneDeep(InputsInputConfig)
public interactActions = interactActions
public option = cloneDeep(option)
}

View File

@@ -0,0 +1,18 @@
<template>
<collapse-item name="输入框配置" :expanded="true">
<setting-item-box name="默认值" :alone="true">
<n-input v-model:value="optionData.dataset" placeholder="若未输入则默认值为0"/>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { CollapseItem, SettingItemBox } from '@/components/Pages/ChartItemSetting'
import { option } from './config'
defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const InputsInputConfig: ConfigType = {
key: 'InputsInput',
chartKey: 'VInputsInput',
conKey: 'VCInputsInput',
title: '输入框',
category: ChatCategoryEnum.INPUTS,
categoryName: ChatCategoryEnumName.INPUTS,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.STATIC,
image: 'inputs_select.png'
}

View File

@@ -0,0 +1,64 @@
<template>
<div>
<n-input :style="`width:${w}px;`" type="text"
v-model:value="option.value.dataset"
placeholder="请输入"
@change="onChange">
</n-input>
</div>
</template>
<script lang="ts" setup>
import { PropType, toRefs, shallowReactive, watch } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useChartInteract } from '@/hooks'
import { InteractEventOn } from '@/enums/eventEnum'
import { ComponentInteractParamsEnum } from './interact'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const option = shallowReactive({
value: {
inputValue: props.chartConfig.option.inputValue,
dataset: props.chartConfig.option.dataset
}
})
const onChange = (v: string) => {
if(v == undefined) return;
// 存储到联动数据
useChartInteract(
props.chartConfig,
useChartEditStore,
{ [ComponentInteractParamsEnum.DATA]: v },
InteractEventOn.CHANGE
)
}
// 手动更新
watch(
() => props.chartConfig.option,
(newData: any) => {
option.value = newData
onChange(newData.inputValue)
},
{
immediate: true,
deep: true
}
)
</script>

View File

@@ -0,0 +1,27 @@
import { InteractEventOn, InteractActionsType } from '@/enums/eventEnum'
// 时间组件类型
export enum ComponentInteractEventEnum {
DATA = 'data'
}
// 联动参数
export enum ComponentInteractParamsEnum {
DATA = 'data'
}
// 定义组件触发回调事件
export const interactActions: InteractActionsType[] = [
{
interactType: InteractEventOn.CHANGE,
interactName: '选择完成',
componentEmitEvents: {
[ComponentInteractEventEnum.DATA]: [
{
value: ComponentInteractParamsEnum.DATA,
label: '选择项'
}
]
}
}
]

View File

@@ -0,0 +1,26 @@
import cloneDeep from 'lodash/cloneDeep'
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
import { interactActions, ComponentInteractEventEnum } from './interact'
import {InputsPaginationConfig} from "./index";
export const option = {
// 时间组件展示类型,必须和 interactActions 中定义的数据一致
[COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA,
// 默认值
pageValue:1,
sizeValue:[2,4,8,10,20],
pageSize:4,
// 暴露配置内容给用户
dataset: 10
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = InputsPaginationConfig.key
public attr = { ...chartInitConfig, w: 395, h: 32, zIndex: -1 }
public chartConfig = cloneDeep(InputsPaginationConfig)
public interactActions = interactActions
public option = cloneDeep(option)
}

View File

@@ -0,0 +1,35 @@
<template>
<collapse-item name="分页配置" :expanded="true">
<setting-item-box :alone="false" name="分页设置">
<setting-item name="默认页码" :alone="true">
<n-input-number v-model:value="optionData.pageValue" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
<setting-item name="分页" :alone="true">
<n-select v-model:value="optionData.pageSize" size="small"
:options="page" />
</setting-item>
<setting-item name="页数" :alone="true">
<n-input-number v-model:value="optionData.dataset" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import {CollapseItem, SettingItem, SettingItemBox} from '@/components/Pages/ChartItemSetting'
import { option } from './config'
const page = [
{label:'2',value:2},
{label:'4',value:4},
{label:'8',value:8},
{label:'10',value:10},
{label:'20',value:20}
]
defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const InputsPaginationConfig: ConfigType = {
key: 'InputsPagination',
chartKey: 'VInputsPagination',
conKey: 'VCInputsPagination',
title: '分页',
category: ChatCategoryEnum.INPUTS,
categoryName: ChatCategoryEnumName.INPUTS,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.STATIC,
image: 'inputs_pagination.png'
}

View File

@@ -0,0 +1,66 @@
<template>
<div>
<n-pagination
@on-update:page="onChange" :style="`width:${w}px;`"
v-model:page="option.value.pageValue"
:page-count="option.value.dataset"
:page-slot="7"
show-size-picker
:page-sizes="option.value.sizeValue"
v-model:page-size="option.value.pageSize"
/>
</div>
</template>
<script lang="ts" setup>
import { PropType, toRefs, shallowReactive, watch } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useChartInteract } from '@/hooks'
import { InteractEventOn } from '@/enums/eventEnum'
import { ComponentInteractParamsEnum } from './interact'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const option = shallowReactive({
value: {
pageValue: props.chartConfig.option.pageValue,
dataset:props.chartConfig.option.dataset,
sizeValue:props.chartConfig.option.sizeValue,
pageSize:props.chartConfig.option.pageSize
}
})
const onChange = (v: number,v2:number) => {
if(v == undefined) return;
// 存储到联动数据
useChartInteract(
props.chartConfig,
useChartEditStore,
{
[ComponentInteractParamsEnum.DATA]: v ,
[ComponentInteractParamsEnum.DATA2]:v2
},
InteractEventOn.CHANGE
)
}
// 手动更新
watch(
() => props.chartConfig.option,
(newData: any) => {
option.value = newData
onChange(newData.pageValue,newData.pageSize)
},
{
immediate: true,
deep: true
}
)
</script>

View File

@@ -0,0 +1,32 @@
import { InteractEventOn, InteractActionsType } from '@/enums/eventEnum'
// 时间组件类型
export enum ComponentInteractEventEnum {
DATA = 'data'
}
// 联动参数
export enum ComponentInteractParamsEnum {
DATA = 'data',
DATA2 = 'data2'
}
// 定义组件触发回调事件
export const interactActions: InteractActionsType[] = [
{
interactType: InteractEventOn.CHANGE,
interactName: '选择完成',
componentEmitEvents: {
[ComponentInteractEventEnum.DATA]: [
{
value: ComponentInteractParamsEnum.DATA,
label: '页数'
},
{
value: ComponentInteractParamsEnum.DATA2,
label: '每页条数'
}
]
}
}
]

View File

@@ -1,5 +1,7 @@
import { InputsDateConfig } from './InputsDate/index'
import { InputsSelectConfig } from './InputsSelect/index'
import { InputsTabConfig } from './InputsTab/index'
import { InputsPaginationConfig } from "./InputsPagination/index";
import { InputsInputConfig} from "./InputsInput/index";
export default [InputsDateConfig, InputsSelectConfig, InputsTabConfig]
export default [InputsDateConfig, InputsSelectConfig, InputsTabConfig,InputsPaginationConfig,InputsInputConfig]

View File

@@ -1,89 +1,89 @@
<template>
<collapse-item name="信息" :expanded="true">
<setting-item-box name="文字" :alone="true">
<setting-item>
<n-input v-model:value="optionData.dataset" size="small"></n-input>
</setting-item>
</setting-item-box>
</collapse-item>
<collapse-item name="样式" :expanded="true">
<setting-item-box name="文字">
<setting-item name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.fontColor"></n-color-picker>
</setting-item>
<setting-item name="字体大小">
<n-input-number v-model:value="optionData.fontSize" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
<setting-item name="字体粗细">
<n-select v-model:value="optionData.fontWeight" size="small" :options="fontWeightOptions" />
</setting-item>
<setting-item name="字间距">
<n-input-number v-model:value="optionData.letterSpacing" size="small" placeholder="输入字间距"></n-input-number>
</setting-item>
</setting-item-box>
<setting-item-box name="阴影">
<setting-item>
<n-space>
<n-switch v-model:value="optionData.showShadow" size="small" />
<n-text>展示阴影</n-text>
</n-space>
</setting-item>
<setting-item name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.colorShadow"></n-color-picker
></setting-item>
<setting-item name="x">
<n-input-number v-model:value="optionData.hShadow" size="small"></n-input-number
></setting-item>
<setting-item name="y">
<n-input-number v-model:value="optionData.vShadow" size="small"></n-input-number
></setting-item>
<setting-item name="模糊">
<n-input-number v-model:value="optionData.blurShadow" size="small"></n-input-number
></setting-item>
</setting-item-box>
<setting-item-box name="动画">
<setting-item name="动画速度">
<n-input-number
v-model:value="optionData.animationSpeed"
size="small"
placeholder="动画速度"
:min="0"
></n-input-number>
</setting-item>
<setting-item name="动画间隔">
<n-input-number
v-model:value="optionData.animationTime"
size="small"
placeholder="动画间隔"
:min="0"
></n-input-number>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option, FontWeightEnum, FontWeightObject } from './config'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
const fontWeightOptions = [
{
label: FontWeightEnum.NORMAL,
value: FontWeightObject[FontWeightEnum.NORMAL]
},
{
label: FontWeightEnum.BOLD,
value: FontWeightObject[FontWeightEnum.BOLD]
}
]
</script>
<template>
<collapse-item name="信息" :expanded="true">
<setting-item-box name="文字" :alone="true">
<setting-item>
<n-input v-model:value="optionData.dataset" type="textarea" size="small"></n-input>
</setting-item>
</setting-item-box>
</collapse-item>
<collapse-item name="样式" :expanded="true">
<setting-item-box name="文字">
<setting-item name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.fontColor"></n-color-picker>
</setting-item>
<setting-item name="字体大小">
<n-input-number v-model:value="optionData.fontSize" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
<setting-item name="字体粗细">
<n-select v-model:value="optionData.fontWeight" size="small" :options="fontWeightOptions" />
</setting-item>
<setting-item name="字间距">
<n-input-number v-model:value="optionData.letterSpacing" size="small" placeholder="输入字间距"></n-input-number>
</setting-item>
</setting-item-box>
<setting-item-box name="阴影">
<setting-item>
<n-space>
<n-switch v-model:value="optionData.showShadow" size="small" />
<n-text>展示阴影</n-text>
</n-space>
</setting-item>
<setting-item name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.colorShadow"></n-color-picker
></setting-item>
<setting-item name="x">
<n-input-number v-model:value="optionData.hShadow" size="small"></n-input-number
></setting-item>
<setting-item name="y">
<n-input-number v-model:value="optionData.vShadow" size="small"></n-input-number
></setting-item>
<setting-item name="模糊">
<n-input-number v-model:value="optionData.blurShadow" size="small"></n-input-number
></setting-item>
</setting-item-box>
<setting-item-box name="动画">
<setting-item name="动画速度">
<n-input-number
v-model:value="optionData.animationSpeed"
size="small"
placeholder="动画速度"
:min="0"
></n-input-number>
</setting-item>
<setting-item name="动画间隔">
<n-input-number
v-model:value="optionData.animationTime"
size="small"
placeholder="动画间隔"
:min="0"
></n-input-number>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option, FontWeightEnum, FontWeightObject } from './config'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
const fontWeightOptions = [
{
label: FontWeightEnum.NORMAL,
value: FontWeightObject[FontWeightEnum.NORMAL]
},
{
label: FontWeightEnum.BOLD,
value: FontWeightObject[FontWeightEnum.BOLD]
}
]
</script>

View File

@@ -1,7 +1,7 @@
<template>
<div class="go-text-box">
<div class="content">
<span style="cursor: pointer; white-space: pre-wrap" v-if="link" @click="click"></span>
<span style="cursor: pointer; white-space: pre-wrap" v-if="link" @click="click">{{ option.dataset }}</span>
<span style="white-space: pre-wrap" v-else>{{ option.dataset }}</span>
</div>
</div>

View File

@@ -1,45 +1,45 @@
<template>
<collapse-item name="信息" :expanded="true">
<setting-item-box name="文字" :alone="true">
<setting-item>
<n-input v-model:value="optionData.dataset" size="small"></n-input>
</setting-item>
</setting-item-box>
</collapse-item>
<collapse-item name="样式" :expanded="true">
<setting-item-box name="文字">
<setting-item name="字体大小">
<n-input-number v-model:value="optionData.size" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
</setting-item-box>
<setting-item-box name="渐变色参数">
<setting-item name="起始值">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.from"></n-color-picker>
</setting-item>
<setting-item name="结束值">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.to"></n-color-picker>
</setting-item>
<setting-item name="偏移角度">
<n-input-number v-model:value="optionData.gradient.deg" size="small" placeholder="颜色旋转"></n-input-number>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option } from './config'
import {
CollapseItem,
SettingItemBox,
SettingItem
} from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>
<template>
<collapse-item name="信息" :expanded="true">
<setting-item-box name="文字" :alone="true">
<setting-item>
<n-input v-model:value="optionData.dataset" type="textarea" size="small"></n-input>
</setting-item>
</setting-item-box>
</collapse-item>
<collapse-item name="样式" :expanded="true">
<setting-item-box name="文字">
<setting-item name="字体大小">
<n-input-number v-model:value="optionData.size" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
</setting-item-box>
<setting-item-box name="渐变色参数">
<setting-item name="起始值">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.from"></n-color-picker>
</setting-item>
<setting-item name="结束值">
<n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.to"></n-color-picker>
</setting-item>
<setting-item name="偏移角度">
<n-input-number v-model:value="optionData.gradient.deg" size="small" placeholder="颜色旋转"></n-input-number>
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { option } from './config'
import {
CollapseItem,
SettingItemBox,
SettingItem
} from '@/components/Pages/ChartItemSetting'
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
</script>

View File

@@ -0,0 +1,35 @@
import cloneDeep from 'lodash/cloneDeep'
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { chartInitConfig } from '@/settings/designSetting'
import { TablesBasicConfig } from './index'
import dataJson from './data.json'
const { dimensions, source } = dataJson
export const option = {
dataset: { dimensions, source },
pagination: {
page: 1,
pageSize: 5
},
align: 'center',
style: {
border: 'on',
singleColumn: 'off',
singleLine: 'off',
bottomBordered: 'on',
striped: 'on',
fontSize: 16,
borderWidth: 0,
borderColor: 'black',
borderStyle: 'solid'
},
inputShow: 'none'
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = TablesBasicConfig.key
public attr = { ...chartInitConfig, w: 600, h: 300, zIndex: -1 }
public chartConfig = cloneDeep(TablesBasicConfig)
public option = cloneDeep(option)
}

View File

@@ -0,0 +1,162 @@
<template>
<collapse-item name="表格设置" :expanded="true">
<n-tag type="primary">若配置无响应请在预览页面查看效果</n-tag>
<setting-item-box :alone="true" name="对齐方式">
<setting-item :alone="true">
<n-select
v-model:value="optionData.align"
size="small"
:options="[
{ label: '靠左', value: 'left' },
{ label: '居中', value: 'center' },
{ label: '靠右', value: 'right' }
]"
/>
</setting-item>
</setting-item-box>
<setting-item-box :alone="false" name="分页设置">
<setting-item name="默认页码" :alone="true">
<n-input-number v-model:value="optionData.pagination.page" size="small" placeholder="字体大小"></n-input-number>
</setting-item>
<setting-item name="分页" :alone="true">
<n-select v-model:value="optionData.pagination.pageSize" size="small" :options="page" />
</setting-item>
</setting-item-box>
<setting-item-box :alone="false" name="表格数据">
<SettingItem name="表头名称" class="form_name">
<div style="width: 260px">
<n-input v-model:value="header" size="small" placeholder="表头数据(英文','分割)"></n-input>
</div>
</SettingItem>
</setting-item-box>
<setting-item-box :alone="false" name="表格样式">
<SettingItem name="显示边框" :alone="true">
<n-select v-model:value="(optionData as any).style.border" size="small" :options="borderFlag" />
</SettingItem>
<SettingItem name="底部边框" :alone="true">
<n-select
v-model:value="(optionData as any).style.bottomBordered"
size="small"
:options="bottom_borderedFlag"
/>
</SettingItem>
<SettingItem name="列分割线" :alone="true">
<n-select v-model:value="(optionData as any).style.singleLine" size="small" :options="columnFlag" />
</SettingItem>
<SettingItem name="行分割线" :alone="true">
<n-select v-model:value="(optionData as any).style.singleColumn" size="small" :options="lineFlag" />
</SettingItem>
<SettingItem name="斑马条纹" :alone="true">
<n-select v-model:value="(optionData as any).style.striped" size="small" :options="stripedFlag" />
</SettingItem>
<setting-item name="字体大小" :alone="true">
<n-input-number
v-model:value="optionData.style.fontSize"
:min="12"
size="small"
placeholder="字体大小"
></n-input-number>
</setting-item>
<setting-item name="边框宽度" :alone="true">
<n-input-number
v-model:value="optionData.style.borderWidth"
:min="0"
size="small"
placeholder="字体大小"
></n-input-number>
</setting-item>
<setting-item name="边框颜色" :alone="true">
<n-color-picker size="small" :modes="['rgb']" v-model:value="optionData.style.borderColor"></n-color-picker>
</setting-item>
<setting-item name="边框样式" :alone="true">
<n-select v-model:value="optionData.style.borderStyle" size="small" :options="borderStyleFlag" />
</setting-item>
<SettingItem name="表格搜索(前端静态搜索)" :alone="true">
<n-select v-model:value="optionData.inputShow" size="small" :options="inputSelect" />
</SettingItem>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType, watch, ref } from 'vue'
import { option } from './config'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
const page = [
{ label: '2', value: 2 },
{ label: '5', value: 5 },
{ label: '10', value: 10 },
{ label: '15', value: 15 },
{ label: '30', value: 30 }
]
const borderFlag = [
{ label: '显示', value: 'on' },
{ label: '不显示', value: 'off' }
]
const columnFlag = [
{ label: '显示', value: 'off' },
{ label: '不显示', value: 'on' }
]
const lineFlag = [
{ label: '显示', value: 'off' },
{ label: '不显示', value: 'on' }
]
const bottom_borderedFlag = [
{ label: '显示', value: 'on' },
{ label: '不显示', value: 'off' }
]
const stripedFlag = [
{ label: '显示', value: 'on' },
{ label: '不显示', value: 'off' }
]
const borderStyleFlag = [
{ label: '实线边框', value: 'solid' },
{ label: '虚线边框', value: 'dashed' },
{ label: '点状边框', value: 'dotted' },
{ label: '双线边框', value: 'double' }
]
const inputSelect = [
{ label: '停用', value: 'none' },
{ label: '启用', value: 'flex' }
]
const props = defineProps({
optionData: {
type: Object as PropType<typeof option>,
required: true
}
})
const header = ref()
const median = ref<string[]>([])
props.optionData.dataset.dimensions.forEach(item => {
median.value.push(item.title)
})
//转string
watch(
() => props.optionData,
() => {
median.value = []
props.optionData.dataset.dimensions.forEach(item => {
median.value.push(item.title)
})
header.value = median.value.toString()
},
{
deep: false,
immediate: true
}
)
//更新columns
watch([header], ([headerNew], [headerOld]) => {
if (headerNew !== headerOld) {
headerNew.split(',').forEach((item: string, index: number) => {
if (index + 1 <= props.optionData.dataset.dimensions.length) {
props.optionData.dataset.dimensions[index].title = headerNew.split(',')[index]
}
})
}
})
</script>

View File

@@ -0,0 +1,60 @@
{
"dimensions": [
{
"title": "产品名称",
"key": "productName"
},
{
"title": "产品销量(万)",
"key": "totalSum"
},
{
"title": "销售额(万)",
"key": "totalAmount"
}
],
"source": [
{
"key": 0,
"productName": "产品A1",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 1,
"productName": "产品B1",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 2,
"productName": "产品C1",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 3,
"productName": "产品D1",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 4,
"productName": "产品A2",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 5,
"productName": "产品D2",
"totalSum": 10,
"totalAmount": 10
},
{
"key": 6,
"productName": "产品A3",
"totalSum": 10,
"totalAmount": 10
}
]
}

View File

@@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const TablesBasicConfig: ConfigType = {
key: 'TablesBasic',
chartKey: 'VTablesBasic',
conKey: 'VCTablesBasic',
title: '基础分页表格',
category: ChatCategoryEnum.TABLE,
categoryName: ChatCategoryEnumName.TABLE,
package: PackagesCategoryEnum.TABLES,
chartFrame: ChartFrameEnum.COMMON,
image: 'tables_basic.png'
}

View File

@@ -0,0 +1,95 @@
<template>
<div class="go-tables-basic">
<n-input
v-model:value="inputData"
placeholder="请输入信息"
:style="`display: ${inputShow}`"
style="margin-bottom: 5px; float: right; width: 240px"
>
<template #prefix>
<n-icon :component="SearchIcon" />
</template>
</n-input>
<n-data-table
:style="`
width: ${w}px;
height: ${h}px;
font-size: ${option.style.fontSize}px;
border-width: ${option.style.border === 'on' ? option.style.borderWidth : 0}px;
border-color: ${option.style.borderColor};
border-style: ${option.style.borderStyle}`"
:bordered="option.style.border === 'on'"
:single-column="option.style.singleColumn === 'on'"
:single-line="option.style.singleLine === 'on'"
:bottom-bordered="option.style.bottomBordered === 'on'"
:striped="option.style.striped === 'on'"
:max-height="h"
size="small"
:columns="option.dataset.dimensions"
:data="filterData"
:pagination="pagination"
/>
</div>
</template>
<script setup lang="ts">
import { computed, PropType, toRefs, watch, reactive, ref } from 'vue'
import { CreateComponentType } from '@/packages/index.d'
import { icon } from '@/plugins'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { SearchIcon } = icon.ionicons5
//查询字段
const inputData = ref('')
//前台过滤
const filterData = computed(() => {
return option?.dataset?.source?.filter((item: any) => {
return Object.values(item).some(val => {
return String(val).toLowerCase().includes(inputData.value.toLowerCase())
})
})
})
const { align, pagination, inputShow } = toRefs(props.chartConfig.option)
pagination.value.onChange = (page: number) => {
pagination.value.page = page
}
const { w, h } = toRefs(props.chartConfig.attr)
const option = reactive({
dataset: props.chartConfig.option.dataset,
style: props.chartConfig.option.style
})
watch(
() => props.chartConfig.option.dataset,
(newData: any) => {
option.dataset = newData
option?.dataset?.dimensions?.forEach((header: any) => {
header.align = align.value
})
},
{
immediate: true,
deep: true
}
)
</script>
<style lang="scss" scoped>
@include go('tables-basic') {
display: flex;
flex-direction: column;
gap: 15px;
align-items: flex-end;
}
</style>

View File

@@ -1,4 +1,5 @@
import { TableListConfig } from './TableList'
import { TableScrollBoardConfig } from './TableScrollBoard'
import { TablesBasicConfig } from "./TablesBasic/index";
export default [TableListConfig, TableScrollBoardConfig]
export default [TableListConfig, TableScrollBoardConfig,TablesBasicConfig]

View File

@@ -8,7 +8,10 @@ import { SketchRule } from 'vue3-sketch-ruler'
* @param app
*/
export function setupCustomComponents(app: App) {
// 骨架屏
app.component('GoSkeleton', GoSkeleton)
// 加载
app.component('GoLoading', GoLoading)
// 标尺
app.component('SketchRule', SketchRule)
}

View File

@@ -56,6 +56,7 @@ import {
ArrowDown as ArrowDownIcon,
Planet as PawIcon,
Search as SearchIcon,
Reload as ReloadIcon,
ChevronUpOutline as ChevronUpOutlineIcon,
ChevronDownOutline as ChevronDownOutlineIcon,
Pulse as PulseIcon,
@@ -97,6 +98,7 @@ import {
FitToScreen as FitToScreenIcon,
FitToHeight as FitToHeightIcon,
FitToWidth as FitToWidthIcon,
Save as SaveIcon,
Carbon3DCursor as Carbon3DCursorIcon,
Carbon3DSoftware as Carbon3DSoftwareIcon,
Filter as FilterIcon,
@@ -218,6 +220,8 @@ const ionicons5 = {
PawIcon,
// 搜索(放大镜)
SearchIcon,
// 加载
ReloadIcon,
// 过滤器
FilterIcon,
// 向上
@@ -289,6 +293,8 @@ const carbon = {
FitToScreenIcon,
FitToHeightIcon,
FitToWidthIcon,
// 保存
SaveIcon,
// 成组
Carbon3DCursorIcon,
// 解组

View File

@@ -1,13 +1,13 @@
import { RouteRecordRaw } from 'vue-router'
import type { AppRouteRecordRaw } from '@/router/types';
import { ErrorPage404, ErrorPage403, ErrorPage500, Layout } from '@/router/constant';
import { ErrorPage404, ErrorPage403, ErrorPage500, Layout, RedirectHome, RedirectUnPublish } from '@/router/constant';
import { PageEnum } from '@/enums/pageEnum'
import { GoReload } from '@/components/GoReload'
export const LoginRoute: RouteRecordRaw = {
path: '/login',
name: 'Login',
path: PageEnum.BASE_LOGIN,
name: PageEnum.BASE_LOGIN_NAME,
component: () => import('@/views/login/index.vue'),
meta: {
title: '登录',
@@ -60,22 +60,21 @@ export const ReloadRoute: AppRouteRecordRaw = {
},
}
export const RedirectRoute: AppRouteRecordRaw = {
path: PageEnum.REDIRECT,
name: PageEnum.REDIRECT_NAME,
component: Layout,
meta: {
title: PageEnum.REDIRECT_NAME,
},
children: [
{
path: '/redirect/:path(.*)',
name: PageEnum.REDIRECT_NAME,
component: () => import('@/views/redirect/index.vue'),
meta: {
title: PageEnum.REDIRECT_NAME,
hideBreadcrumb: true,
},
export const RedirectRoute: RouteRecordRaw[] = [
{
path: PageEnum.REDIRECT,
name: PageEnum.REDIRECT_NAME,
component: RedirectHome,
meta: {
title: PageEnum.REDIRECT_NAME,
},
],
};
},
{
path: PageEnum.REDIRECT_UN_PUBLISH,
name: PageEnum.REDIRECT_UN_PUBLISH_NAME,
component: RedirectUnPublish,
meta: {
title: PageEnum.REDIRECT_UN_PUBLISH_NAME,
},
},
]

View File

@@ -4,6 +4,10 @@ export const ErrorPage403 = () => import('@/views/exception/403.vue');
export const ErrorPage500 = () => import('@/views/exception/500.vue');
export const RedirectHome = () => import('@/views/redirect/index.vue');
export const RedirectUnPublish = () => import('@/views/redirect/UnPublish.vue');
export const Layout = () => import('@/layout/index.vue');
export const ParentLayout = () => import('@/layout/parentLayout.vue');

View File

@@ -1,9 +1,8 @@
import type { App } from 'vue'
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import { RedirectRoute } from '@/router/base'
import { createRouterGuards } from './router-guards'
import { PageEnum } from '@/enums/pageEnum'
import { HttpErrorPage, LoginRoute, ReloadRoute } from '@/router/base'
import { HttpErrorPage, LoginRoute, ReloadRoute, RedirectRoute } from '@/router/base'
import { Layout } from '@/router/constant'
import modules from '@/router/modules'
@@ -19,6 +18,7 @@ const RootRoute: Array<RouteRecordRaw> = [
},
children: [
...HttpErrorPage,
...RedirectRoute,
modules.projectRoutes,
modules.chartRoutes,
modules.previewRoutes,
@@ -28,7 +28,7 @@ const RootRoute: Array<RouteRecordRaw> = [
]
export const constantRouter: any[] = [LoginRoute, ...RootRoute, RedirectRoute, ReloadRoute];
export const constantRouter: any[] = [LoginRoute, ...RootRoute, ReloadRoute];
const router = createRouter({
history: createWebHashHistory(''),

View File

@@ -1,7 +1,15 @@
import { Router } from 'vue-router';
import { PageEnum } from '@/enums/pageEnum'
import { PageEnum, PreviewEnum } from '@/enums/pageEnum'
import { loginCheck } from '@/utils'
// 路由白名单
const routerAllowList = [
// 登录
PageEnum.BASE_LOGIN_NAME,
// 预览
PreviewEnum.CHART_PREVIEW_NAME
]
export function createRouterGuards(router: Router) {
// 前置
router.beforeEach(async (to, from, next) => {
@@ -19,10 +27,8 @@ export function createRouterGuards(router: Router) {
next({ name: PageEnum.ERROR_PAGE_NAME_404 })
}
if (!loginCheck()) {
if (to.name === PageEnum.BASE_LOGIN_NAME) {
next()
}
// @ts-ignore
if (!routerAllowList.includes(to.name) && !loginCheck()) {
next({ name: PageEnum.BASE_LOGIN_NAME })
}
next()

View File

@@ -61,6 +61,9 @@ export const editToJsonInterval = 5000
// 数据请求间隔
export const requestInterval = 30
// 工作台自动保存间隔s
export const saveInterval = 30
// 数据请求间隔单位
export const requestIntervalUnit = RequestHttpIntervalEnum.SECOND

View File

@@ -0,0 +1,2 @@
// 请求前缀
export const axiosPre = '/api/goview'

View File

@@ -1,5 +1,6 @@
import { CreateComponentType, CreateComponentGroupType, FilterEnum } from '@/packages/index.d'
import { HistoryActionTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
import { SyncEnum } from '@/enums/editPageEnum'
import {
RequestHttpEnum,
RequestContentTypeEnum,
@@ -12,6 +13,29 @@ import {
import { PreviewScaleEnum } from '@/enums/styleEnum'
import type { ChartColorsNameType, CustomColorsType, GlobalThemeJsonType } from '@/settings/chartThemes/index'
// 项目数据枚举
export enum ProjectInfoEnum {
// ID
PROJECT_ID = "projectId",
// 名称
PROJECT_NAME = 'projectName',
// 描述
REMARKS = 'remarks',
// 缩略图
THUMBNAIL= 'thumbnail',
// 是否公开发布
RELEASE = 'release'
}
// 项目数据
export type ProjectInfoType = {
[ProjectInfoEnum.PROJECT_ID]: string,
[ProjectInfoEnum.PROJECT_NAME]: string,
[ProjectInfoEnum.REMARKS]: string,
[ProjectInfoEnum.THUMBNAIL]: string,
[ProjectInfoEnum.RELEASE]: boolean
}
// 编辑画布属性
export enum EditCanvasTypeEnum {
EDIT_LAYOUT_DOM = 'editLayoutDom',
@@ -20,13 +44,14 @@ export enum EditCanvasTypeEnum {
SCALE = 'scale',
USER_SCALE = 'userScale',
LOCK_SCALE = 'lockScale',
SAVE_STATUS = 'saveStatus',
IS_CREATE = 'isCreate',
IS_DRAG = 'isDrag',
IS_SELECT = 'isSelect',
IS_CODE_EDIT="isCodeEdit"
}
// 编辑区域
// 编辑区域(临时)
export type EditCanvasType = {
// 编辑区域 DOM
[EditCanvasTypeEnum.EDIT_LAYOUT_DOM]: HTMLElement | null
@@ -43,13 +68,15 @@ export type EditCanvasType = {
[EditCanvasTypeEnum.IS_CREATE]: boolean
// 拖拽中
[EditCanvasTypeEnum.IS_DRAG]: boolean
// 保存状态
[EditCanvasTypeEnum.SAVE_STATUS]: SyncEnum
// 框选中
[EditCanvasTypeEnum.IS_SELECT]: boolean
// 代码编辑中
[EditCanvasTypeEnum.IS_CODE_EDIT]: boolean
}
// 滤镜/背景色/宽高主题等
// 画布数据/滤镜/背景色/宽高主题等
export enum EditCanvasConfigEnum {
PROJECT_NAME = 'projectName',
WIDTH = 'width',
@@ -63,7 +90,14 @@ export enum EditCanvasConfigEnum {
PREVIEW_SCALE_TYPE = 'previewScaleType'
}
export interface EditCanvasConfigType {
// 画布属性(需保存)
export type EditCanvasConfigType = {
// ID
[EditCanvasConfigEnum.PROJECT_ID]: string,
// 项目名称
[EditCanvasConfigEnum.PROJECT_NAME]?: string,
// 项目描述
[EditCanvasConfigEnum.REMARKS]: string,
// 滤镜-启用
[FilterEnum.FILTERS_SHOW]: boolean
// 滤镜-色相
@@ -140,6 +174,7 @@ export type RecordChartType = {
// Store 枚举
export enum ChartEditStoreEnum {
PROJECT_INFO = 'projectInfo',
EDIT_RANGE = 'editRange',
EDIT_CANVAS = 'editCanvas',
RIGHT_MENU_SHOW = 'rightMenuShow',
@@ -201,6 +236,7 @@ export interface RequestConfigType extends RequestPublicConfigType {
// Store 类型
export interface ChartEditStoreType {
[ChartEditStoreEnum.PROJECT_INFO]: ProjectInfoType
[ChartEditStoreEnum.EDIT_CANVAS]: EditCanvasType
[ChartEditStoreEnum.EDIT_CANVAS_CONFIG]: EditCanvasConfigType
[ChartEditStoreEnum.RIGHT_MENU_SHOW]: boolean

View File

@@ -10,14 +10,22 @@ import { requestInterval, previewScaleType, requestIntervalUnit } from '@/settin
import { useChartHistoryStore } from '@/store/modules/chartHistoryStore/chartHistoryStore'
// 全局设置
import { useSettingStore } from '@/store/modules/settingStore/settingStore'
// 历史类型
import { HistoryActionTypeEnum, HistoryItemType, HistoryTargetTypeEnum } from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
// 画布枚举
import { MenuEnum, SyncEnum } from '@/enums/editPageEnum'
import {
HistoryActionTypeEnum,
HistoryItemType,
HistoryTargetTypeEnum
} from '@/store/modules/chartHistoryStore/chartHistoryStore.d'
import { MenuEnum } from '@/enums/editPageEnum'
import { getUUID, loadingStart, loadingFinish, loadingError, isString, isArray } from '@/utils'
getUUID,
loadingStart,
loadingFinish,
loadingError,
isString,
isArray
} from '@/utils'
import {
ProjectInfoType,
ChartEditStoreEnum,
ChartEditStorage,
ChartEditStoreType,
@@ -36,6 +44,14 @@ const settingStore = useSettingStore()
export const useChartEditStore = defineStore({
id: 'useChartEditStore',
state: (): ChartEditStoreType => ({
// 项目数据
projectInfo: {
projectId: '',
projectName: '',
remarks: '',
thumbnail: '',
release: false
},
// 画布属性
editCanvas: {
// 编辑区域 Dom
@@ -55,6 +71,8 @@ export const useChartEditStore = defineStore({
isDrag: false,
// 框选中
isSelect: false,
// 同步中
saveStatus: SyncEnum.PENDING,
// 代码编辑中
isCodeEdit: false
},
@@ -138,6 +156,9 @@ export const useChartEditStore = defineStore({
componentList: []
}),
getters: {
getProjectInfo(): ProjectInfoType {
return this.projectInfo
},
getMousePosition(): MousePositionType {
return this.mousePosition
},
@@ -172,6 +193,10 @@ export const useChartEditStore = defineStore({
}
},
actions: {
// * 设置 peojectInfo 数据项
setProjectInfo<T extends keyof ProjectInfoType, K extends ProjectInfoType[T]>(key: T, value: K) {
this.projectInfo[key] = value
},
// * 设置 editCanvas 数据项
setEditCanvas<T extends keyof EditCanvasType, K extends EditCanvasType[T]>(key: T, value: K) {
this.editCanvas[key] = value
@@ -500,8 +525,8 @@ export const useChartEditStore = defineStore({
}
const parseHandle = (e: CreateComponentType | CreateComponentGroupType) => {
e = cloneDeep(e)
e.attr.x = this.getMousePosition.x + 30
e.attr.y = this.getMousePosition.y + 30
e.attr.x = this.getMousePosition.startX
e.attr.y = this.getMousePosition.startY
// 外层生成新 id
e.id = getUUID()
// 分组列表生成新 id
@@ -510,11 +535,11 @@ export const useChartEditStore = defineStore({
item.id = getUUID()
})
}
return e
}
const isCut = recordCharts.type === HistoryActionTypeEnum.CUT
const targetList = Array.isArray(recordCharts.charts) ? recordCharts.charts : [ recordCharts.charts ]
const targetList = Array.isArray(recordCharts.charts) ? recordCharts.charts : [recordCharts.charts]
// 多项
targetList.forEach((e: CreateComponentType | CreateComponentGroupType) => {
this.addComponentList(parseHandle(e), undefined, true)
@@ -614,7 +639,7 @@ export const useChartEditStore = defineStore({
} else {
const group = historyData[0] as CreateComponentGroupType
group.groupList.forEach(item => {
ids.push(item.id)
ids.unshift(item.id)
})
}
this.setGroup(ids, false)
@@ -763,7 +788,7 @@ export const useChartEditStore = defineStore({
// 高
groupAttr.b = b < y + h ? y + h : b
targetList.push(item)
targetList.unshift(item)
historyList.push(toRaw(item))
})
@@ -809,7 +834,7 @@ export const useChartEditStore = defineStore({
if (isHistory) chartHistoryStore.createUnGroupHistory(cloneDeep([targetGroup]))
// 分离组件并还原位置属性
targetGroup.groupList.forEach(item => {
targetGroup.groupList.reverse().forEach(item => {
item.attr.x = item.attr.x + targetGroup.attr.x
item.attr.y = item.attr.y + targetGroup.attr.y
if (!callBack) {

View File

@@ -4,10 +4,10 @@ import { asideCollapsedWidth } from '@/settings/designSetting'
import { SettingStoreType, ToolsStatusEnum } from './settingStore.d'
import { setLocalStorage, getLocalStorage } from '@/utils'
import { StorageEnum } from '@/enums/storageEnum'
const { GO_SYSTEM_SETTING_STORE } = StorageEnum
const { GO_SETTING_STORE } = StorageEnum
const storageSetting: SettingStoreType = getLocalStorage(
GO_SYSTEM_SETTING_STORE
GO_SETTING_STORE
)
// 全局设置
@@ -48,7 +48,7 @@ export const useSettingStore = defineStore({
this.$patch(state => {
state[key] = value
})
setLocalStorage(GO_SYSTEM_SETTING_STORE, this.$state)
setLocalStorage(GO_SETTING_STORE, this.$state)
}
}
})

View File

@@ -0,0 +1,31 @@
export enum SystemStoreUserInfoEnum {
USER_TOKEN = 'userToken',
TOKEN_NAME = 'tokenName',
USER_ID = 'userId',
USER_NAME = 'userName',
NICK_NAME = 'nickName',
}
export interface UserInfoType {
[SystemStoreUserInfoEnum.USER_TOKEN]?: string,
[SystemStoreUserInfoEnum.TOKEN_NAME]?: string,
[SystemStoreUserInfoEnum.USER_ID]?: string,
[SystemStoreUserInfoEnum.USER_NAME]?: string,
[SystemStoreUserInfoEnum.NICK_NAME]?: string,
}
export interface FetchInfoType {
OSSUrl?: string,
}
export enum SystemStoreEnum {
// 用户
USER_INFO = 'userInfo',
// 请求
FETCH_INFO = 'fetchInfo'
}
export interface SystemStoreType {
[SystemStoreEnum.USER_INFO]: UserInfoType
[SystemStoreEnum.FETCH_INFO]: FetchInfoType
}

View File

@@ -0,0 +1,40 @@
import { defineStore } from 'pinia'
import { SystemStoreType, UserInfoType, FetchInfoType } from './systemStore.d'
import { setLocalStorage, getLocalStorage } from '@/utils'
import { StorageEnum } from '@/enums/storageEnum'
const { GO_SYSTEM_STORE } = StorageEnum
const storageSystem: SystemStoreType = getLocalStorage(GO_SYSTEM_STORE)
// 系统数据记录
export const useSystemStore = defineStore({
id: 'useSystemStore',
state: (): SystemStoreType => storageSystem || {
userInfo: {
userId: undefined,
userName: undefined,
userToken: undefined,
nickName: undefined
},
fetchInfo: {
OSSUrl: undefined
}
},
getters: {
getUserInfo(): UserInfoType {
return this.userInfo
},
getFetchInfo(): FetchInfoType {
return this.fetchInfo
},
},
actions: {
setItem<T extends keyof SystemStoreType, K extends SystemStoreType[T]>(key: T, value: K): void {
this.$patch(state => {
state[key] = value
});
setLocalStorage(GO_SYSTEM_STORE, this.$state)
}
}
})

View File

@@ -1,3 +1,65 @@
/**
* * base64转file
* @param dataurl
* @param fileName
* @returns
*/
export const base64toFile = (dataurl: string, fileName: string) => {
let dataArr = dataurl.split(","),
mime = (dataArr as any[])[0].match(/:(.*?);/)[1],
bstr = atob(dataArr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], fileName, { type: mime });
}
/**
* * file转url
*/
export const fileToUrl = (file: File): string => {
const Url = URL || window.URL || window.webkitURL
const ImageUrl = Url.createObjectURL(file)
return ImageUrl
}
/**
* * url转file
*/
export const urlToFile = (fileUrl: string, fileName = `${new Date().getTime()}`): File => {
const dataArr = fileUrl.split(',')
const mime = (dataArr as any[])[0].match(/:(.*);/)[1]
const originStr = atob(dataArr[1])
return new File([originStr], `${fileName}`, { type: mime })
}
/**
* * file转base64
* @param file 文件数据
* @param callback 回调函数
*/
export const fileTobase64 = (file: File, callback: Function) => {
let reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function (e: ProgressEvent<FileReader>) {
if (e.target) {
let base64 = e.target.result
callback(base64)
}
}
}
/**
* * canvas转file
* @param canvas
*/
export const canvastoFile = (canvas: HTMLCanvasElement, name?: string) => {
const dataurl = canvas.toDataURL('image/png')
return urlToFile(dataurl, name)
}
/**
* *获取上传的文件数据
* @param { File } file 文件对象
@@ -51,4 +113,4 @@ export const downloadTextFile = (
// 字符内容转变成blob地址
const blob = new Blob([content])
downloadByA(URL.createObjectURL(blob), filename, fileSuffix)
}
}

6
src/utils/http.ts Normal file
View File

@@ -0,0 +1,6 @@
/**
* * 请求失败统一处理
*/
export const httpErrorHandle = () => {
window['$message'].error(window['$t']('http.error_message'))
}

View File

@@ -7,3 +7,4 @@ export * from '@/utils/plugin'
export * from '@/utils/components'
export * from '@/utils/type'
export * from '@/utils/file'
export * from '@/utils/http'

View File

@@ -35,7 +35,7 @@ export const loadingError = () => {
* })
* ```
*/
export const goDialog = (
export const goDialog = (
params: {
// 基本
type?: DialogEnum

View File

@@ -1,11 +1,12 @@
import { useRoute } from 'vue-router'
import { ResultEnum } from '@/enums/httpEnum'
import { ErrorPageNameMap, PageEnum } from '@/enums/pageEnum'
import { ResultEnum, RequestHttpHeaderEnum } from '@/enums/httpEnum'
import { ErrorPageNameMap, PageEnum, PreviewEnum } from '@/enums/pageEnum'
import { docPath, giteeSourceCodePath } from '@/settings/pathConst'
import { cryptoDecode } from './crypto'
import { SystemStoreEnum, SystemStoreUserInfoEnum } from '@/store/modules/systemStore/systemStore.d'
import { StorageEnum } from '@/enums/storageEnum'
import { clearLocalStorage, getLocalStorage } from './storage'
import { clearLocalStorage, getLocalStorage, clearCookie } from './storage'
import router from '@/router'
import { logoutApi } from '@/api/path'
/**
* * 根据名字跳转路由
@@ -101,11 +102,20 @@ export const reloadRoutePage = () => {
}
/**
* * 退出
* * 退出登录
*/
export const logout = () => {
clearLocalStorage(StorageEnum.GO_LOGIN_INFO_STORE)
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
export const logout = async () => {
try {
const res = await logoutApi()
if(res && res.code === ResultEnum.SUCCESS) {
window['$message'].success(window['$t']('global.logout_success'))
clearCookie(RequestHttpHeaderEnum.COOKIE)
clearLocalStorage(StorageEnum.GO_SYSTEM_STORE)
routerTurnByName(PageEnum.BASE_LOGIN_NAME)
}
} catch (error) {
window['$message'].success(window['$t']('global.logout_failure'))
}
}
/**
@@ -157,7 +167,7 @@ export const fetchRouteParams = () => {
* * 通过硬解析获取当前路由下的参数
* @returns object
*/
export const fetchRouteParamsLocation = () => {
export const fetchRouteParamsLocation = () => {
try {
// 防止添加query参数的时候解析ID异常
return document.location.hash.split('?')[0].split('/').pop() || ''
@@ -176,19 +186,29 @@ export const goHome = () => {
}
/**
* * 判断是否登录(现阶段是有 login 数据即可)
* * 判断是否登录
* @return boolean
*/
export const loginCheck = () => {
try {
const info = getLocalStorage(StorageEnum.GO_LOGIN_INFO_STORE)
const info = getLocalStorage(StorageEnum.GO_SYSTEM_STORE)
if (!info) return false
const decodeInfo = cryptoDecode(info)
if (decodeInfo) {
if (info[SystemStoreEnum.USER_INFO][SystemStoreUserInfoEnum.USER_TOKEN]) {
return true
}
return false
} catch (error) {
return false
}
}
/**
* * 预览地址
* @returns
*/
export const previewPath = (id?: string | number) => {
const { origin, pathname } = document.location
const path = fetchPathByName(PreviewEnum.CHART_PREVIEW_NAME, 'href')
const previewPath = `${origin}${pathname}${path}/${id || fetchRouteParamsLocation()}`
return previewPath
}

View File

@@ -70,3 +70,41 @@ export const getSessionStorage: (k: string) => any = (k: string) => {
export const clearSessioStorage = (name: string) => {
window.sessionStorage.removeItem(name)
}
/**
* * 设置 cookie
* @param name 键名
* @param cvalue 键值
* @param exdays 过期时间
*/
export const setCookie = (name: string, cvalue: string, exdays: number) => {
const d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
const expires = "expires=" + d.toUTCString();
document.cookie = name + "=" + cvalue + "; " + expires;
}
/**
* * 获取 cookie
* @param cname 键名
* @returns string
*/
export const getCookie = (cname: string) => {
const name = cname + "=";
const ca = document.cookie.split(';');
for (let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') c = c.substring(1);
if (c.indexOf(name) != -1) return c.substring(name.length, c.length);
}
return "";
}
/**
* * 清除 cookie
* @param name 键名
* @returns string
*/
export const clearCookie = (name: string) => {
setCookie(name, "", -1);
}

View File

@@ -114,29 +114,6 @@ export const isMac = () => {
return /macintosh|mac os x/i.test(navigator.userAgent)
}
/**
* * file转url
*/
export const fileToUrl = (file: File): string => {
const Url = URL || window.URL || window.webkitURL
const ImageUrl = Url.createObjectURL(file)
return ImageUrl
}
/**
* * file转base64
*/
export const fileTobase64 = (file: File, callback: Function) => {
let reader = new FileReader()
reader.readAsDataURL(file)
reader.onload = function (e: ProgressEvent<FileReader>) {
if (e.target) {
let base64 = e.target.result
callback(base64)
}
}
}
/**
* * 挂载监听
*/
@@ -353,3 +330,23 @@ export const JSONParse = (data: string) => {
export const setTitle = (title?: string) => {
title && (document.title = title)
}
/**
* 处理网页关闭事件
*/
export const addWindowUnload = () => {
// 关闭网页出现离开提示
window.onbeforeunload = function (e) {
e = e || window.event
// 兼容IE8和Firefox 4之前的版本
if (e) {
e.returnValue = '您确定要离开当前页面吗?请确认是否保存数据!'
}
// Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
return '您确定要离开当前页面吗?请确认是否保存数据!'
}
// 返回销毁事件函数
return () => {
window.onbeforeunload = null
}
}

View File

@@ -132,16 +132,20 @@ import { swatchesColors } from '@/settings/chartThemes/index'
import { FileTypeEnum } from '@/enums/fileTypeEnum'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { useSystemStore } from '@/store/modules/systemStore/systemStore'
import { StylesSetting } from '@/components/Pages/ChartItemSetting'
import { UploadCustomRequestOptions } from 'naive-ui'
import { fileToUrl, loadAsyncComponent } from '@/utils'
import { loadAsyncComponent, fetchRouteParamsLocation } from '@/utils'
import { PreviewScaleEnum } from '@/enums/styleEnum'
import { ResultEnum } from '@/enums/httpEnum'
import { icon } from '@/plugins'
import { uploadFile } from '@/api/path'
const { ColorPaletteIcon } = icon.ionicons5
const { ScaleIcon, FitToScreenIcon, FitToHeightIcon, FitToWidthIcon } = icon.carbon
const chartEditStore = useChartEditStore()
const systemStore = useSystemStore()
const canvasConfig = chartEditStore.getEditCanvasConfig
const editCanvas = chartEditStore.getEditCanvas
@@ -266,11 +270,32 @@ const clearColor = () => {
// 自定义上传操作
const customRequest = (options: UploadCustomRequestOptions) => {
const { file } = options
nextTick(() => {
nextTick(async () => {
if (file.file) {
const ImageUrl = fileToUrl(file.file)
chartEditStore.setEditCanvasConfig(EditCanvasConfigEnum.BACKGROUND_IMAGE, ImageUrl)
chartEditStore.setEditCanvasConfig(EditCanvasConfigEnum.SELECT_COLOR, false)
// 修改名称
const newNameFile = new File([file.file], `${fetchRouteParamsLocation()}_index_background.png`, {
type: file.file.type
})
let uploadParams = new FormData()
uploadParams.append('object', newNameFile)
const uploadRes = await uploadFile(uploadParams)
if (uploadRes && uploadRes.code === ResultEnum.SUCCESS) {
if (uploadRes.data.fileurl) {
chartEditStore.setEditCanvasConfig(
EditCanvasConfigEnum.BACKGROUND_IMAGE,
`${uploadRes.data.fileurl}?time=${new Date().getTime()}`
)
} else {
chartEditStore.setEditCanvasConfig(
EditCanvasConfigEnum.BACKGROUND_IMAGE,
`${systemStore.getFetchInfo.OSSUrl || ''}${uploadRes.data.fileName}?time=${new Date().getTime()}`
)
}
chartEditStore.setEditCanvasConfig(EditCanvasConfigEnum.SELECT_COLOR, false)
return
}
window['$message'].error('添加图片失败,请稍后重试!')
} else {
window['$message'].error('添加图片失败,请稍后重试!')
}

View File

@@ -34,6 +34,7 @@ import { RequestContentTypeEnum } from '@/enums/httpEnum'
import { useTargetData } from '../../../hooks/useTargetData.hook'
import { RequestGlobalConfig } from './components/RequestGlobalConfig'
import { RequestTargetConfig } from './components/RequestTargetConfig'
import { useSync } from '@/views/chart/hooks/useSync.hook'
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
const props = defineProps({
@@ -43,6 +44,9 @@ const props = defineProps({
})
const emit = defineEmits(['update:modelShow', 'sendHandle'])
const { targetData } = useTargetData()
const { dataSyncUpdate } = useSync()
// 解构基础配置
const { chartConfig } = toRefs(props.targetData as CreateComponentType)
const { requestContentType } = toRefs((props.targetData as CreateComponentType).request)
@@ -69,6 +73,7 @@ const closeHandle = () => {
const closeAndSendHandle = () => {
emit('update:modelShow', false)
emit('sendHandle')
dataSyncUpdate()
}
</script>

View File

@@ -48,6 +48,7 @@ import { useTargetData } from '../../../hooks/useTargetData.hook'
import { RequestGlobalConfig } from './components/RequestGlobalConfig'
import { RequestTargetConfig } from './components/RequestTargetConfig'
import { RequestDataPondItemType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { useSync } from '@/views/chart/hooks/useSync.hook'
import { goDialog } from '@/utils'
const props = defineProps({
@@ -56,6 +57,7 @@ const props = defineProps({
})
const emit = defineEmits(['update:modelShow', 'editSaveHandle'])
const { dataSyncUpdate } = useSync()
const pondName = ref()
const inputInstRef = ref()
const modelShowRef = ref(false)
@@ -82,6 +84,7 @@ const closeAndSendHandle = () => {
onPositiveCallback: () => {
emit('update:modelShow', false)
emit('editSaveHandle', props.targetDataRequest)
dataSyncUpdate()
}
})
}

View File

@@ -16,7 +16,7 @@
<p>
<span class="func-annotate">// {{ EventTypeName[eventName] }}</span>
<br />
<span class="func-keyword">async {{ eventName }}</span> (mouseEvent) {
<span class="func-keyword">async {{ eventName }}</span> (mouseEvent,components) {
</p>
<p class="go-ml-4">
<n-code :code="(targetData.events.baseEvent || {})[eventName] || ''" language="typescript"></n-code>
@@ -52,7 +52,7 @@
<!-- 函数名称 -->
<p class="go-pl-3">
<span class="func-keyword">async function &nbsp;&nbsp;</span>
<span class="func-keyNameWord">{{ eventName }}(mouseEvent)&nbsp;&nbsp;{</span>
<span class="func-keyNameWord">{{ eventName }}(mouseEvent,components)&nbsp;&nbsp;{</span>
</p>
<!-- 编辑主体 -->
<monaco-editor v-model:modelValue="baseEvent[eventName]" height="480px" language="javascript" />

View File

@@ -5,6 +5,8 @@
<edit-history></edit-history>
<!-- CTRL按键触发展示 -->
<n-text id="keyboard-dress-show" depth="3"></n-text>
<n-divider vertical />
<edit-data-sync></edit-data-sync>
</n-space>
<n-space class="bottom-ri">
@@ -57,7 +59,8 @@ import { SelectInst } from 'naive-ui'
import { reactive, ref, toRefs, watchEffect } from 'vue'
import { icon } from '@/plugins'
import { EditHistory } from '../EditHistory/index'
import EditShortcutKey from '../EditShortcutKey/index.vue'
import { EditShortcutKey } from '../EditShortcutKey/index'
import { EditDataSync } from '../EditDataSync/index'
import { useDesignStore } from '@/store/modules/designStore/designStore'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasTypeEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
@@ -151,6 +154,10 @@ $max-width: 670px;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
width: 100%;
min-width: $min-width;
height: 40px;
.bottom-ri {
position: relative;
top: 15px;

View File

@@ -0,0 +1,3 @@
import EditDataSync from './index.vue'
export { EditDataSync }

View File

@@ -0,0 +1,97 @@
<template>
<div class="go-edit-data-sync go-flex-items-center">
<n-tooltip trigger="hover">
<template #trigger>
<n-text class="status-desc go-ml-2" :type="descType" depth="3">
{{ statusDesc }}
</n-text>
</template>
<span>{{saveInterval}}s 更新一次</span>
</n-tooltip>
<n-spin
v-show="statusDesc === statusDescObj[1]['text']"
class="go-ml-2"
size="small"
>
<template #icon>
<n-icon size="13">
<reload-icon />
</n-icon>
</template>
</n-spin>
</div>
</template>
<script lang="ts" setup>
import { ref, toRefs, watch } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useDesignStore } from '@/store/modules/designStore/designStore'
import { SyncEnum } from '@/enums/editPageEnum'
import { icon } from '@/plugins'
import { saveInterval } from '@/settings/designSetting'
const { ReloadIcon } = icon.ionicons5
const chartEditStore = useChartEditStore()
const designStore = useDesignStore()
const { saveStatus } = toRefs(chartEditStore.getEditCanvas)
const themeColor = ref(designStore.getAppTheme)
const statusDesc = ref('')
const descType = ref('')
let setTimeoutIns: NodeJS.Timeout = setTimeout(() => {})
const statusDescObj = {
[SyncEnum.PENDING]: {
text: '等待自动同步',
type: '',
},
[SyncEnum.START]: {
text: '正在同步中',
type: 'success',
},
[SyncEnum.SUCCESS]: {
text: '同步成功!',
type: 'success',
},
[SyncEnum.FAILURE]: {
text: '同步失败!',
type: 'error',
},
}
watch(
() => saveStatus.value,
newData => {
clearTimeout(setTimeoutIns)
statusDesc.value = statusDescObj[newData]['text']
descType.value = statusDescObj[newData]['type']
// 3秒重置展示
setTimeoutIns = setTimeout(() => {
statusDesc.value = statusDescObj[SyncEnum.PENDING]['text']
descType.value = statusDescObj[SyncEnum.PENDING]['type']
}, 3000)
},
{
immediate: true,
}
)
</script>
<style lang="scss" scoped>
@include go('edit-data-sync') {
@include deep() {
.n-spin {
width: 13px;
height: 13px;
}
}
.status-desc {
cursor: default;
color: v-bind('themeColor');
font-size: 12px;
opacity: 0.8;
}
}
</style>

View File

@@ -133,9 +133,6 @@ const options = computed(() => {
</script>
<style lang="scss" scoped>
.mr-10 {
margin-right: 10px;
}
.edit-history-popover {
.btn-text {
font-size: 12px;

View File

@@ -27,7 +27,7 @@
</div>
</div>
<!-- 修复右下角白点用的 -->
<div v-if="designStore.getDarkTheme" class="fix-edit-screens-block"></div>
<!-- <div v-if="designStore.getDarkTheme" class="fix-edit-screens-block"></div> -->
</div>
</template>
<script setup lang="ts">
@@ -290,7 +290,6 @@ window.onKeySpacePressHold = (isHold: boolean) => {
<style lang="scss" scoped>
@include go('sketch-rule') {
position: relative;
overflow: hidden;
width: 100%;
height: 100%;
@@ -321,6 +320,10 @@ window.onKeySpacePressHold = (isHold: boolean) => {
border-radius: 5px;
background-color: rgba(144, 146, 152, 0.3);
}
// 修复右下角白点用的
&::-webkit-scrollbar-corner {
background-color: transparent;
}
}
.fix-edit-screens-block {
@@ -341,7 +344,7 @@ window.onKeySpacePressHold = (isHold: boolean) => {
.canvas {
position: absolute;
top: 50%;
top:50%;
left: 50%;
transform-origin: 50% 0;
transform: translateY(-50%);

View File

@@ -112,20 +112,25 @@ const shortcutKeyOptions = [
win: `${WinKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + Z `,
mac: `${MacKeyboard.CTRL.toUpperCase()} + ${MacKeyboard.SHIFT.toUpperCase()} + Z `
},
{
label: '保存',
win: `${WinKeyboard.CTRL.toUpperCase()} + S `,
mac: `${MacKeyboard.CTRL.toUpperCase()} + S `,
},
{
label: '多选',
win: `${WinKeyboard.CTRL.toUpperCase()} + 🖱️ `,
mac: `${MacKeyboard.CTRL_SOURCE_KEY.toUpperCase()} + 🖱️ `
mac: `${MacKeyboard.CTRL.toUpperCase()} + 🖱️ `
},
{
label: '创建分组',
win: `${WinKeyboard.CTRL.toUpperCase()} + G / 🖱️ `,
mac: `${MacKeyboard.CTRL_SOURCE_KEY.toUpperCase()} + G / 🖱️`
mac: `${MacKeyboard.CTRL.toUpperCase()} + G / 🖱️`
},
{
label: '解除分组',
win: `${WinKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + G `,
mac: `${MacKeyboard.CTRL_SOURCE_KEY.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + G `
mac: `${MacKeyboard.CTRL.toUpperCase()} + ${WinKeyboard.SHIFT.toUpperCase()} + G `
}
]

View File

@@ -1,2 +1,3 @@
import EditShortcutKey from './index.vue'
export { EditShortcutKey }

Some files were not shown because too many files have changed in this diff Show More