111 Commits

Author SHA1 Message Date
TinyAnts
83f57ad01d Merge branch 'release/13.2' 2022-09-30 16:32:37 +08:00
TinyAnts
e05348206e 修复底部导航错误 2022-09-30 16:26:39 +08:00
TinyAnts
f4e4130cab 调整安装SQL 2022-09-30 15:36:20 +08:00
TinyAnts
0817b16615 调整素材 2022-09-30 14:53:46 +08:00
Jason
f3b10f07b1 打包 2022-09-30 14:13:20 +08:00
Jason
e191fc8d26 公众号回复调整 2022-09-30 14:05:38 +08:00
TinyAnts
8052475e40 修复公众号回复管理 2022-09-30 11:49:03 +08:00
Jason
0cc7c8e7b9 修改环境变量配置,app目录-->uniapp 2022-09-30 10:23:58 +08:00
TinyAnts
9b5b625680 调整SQL文件 2022-09-29 17:11:40 +08:00
Jason
5d06003895 修改代码生气器模板 2022-09-29 15:23:46 +08:00
Jason
061543a191 热门搜索排除空值 2022-09-29 15:18:41 +08:00
Jason
c073cc65a7 只展开一个一级菜单开关 2022-09-29 14:55:04 +08:00
Jason
5b9af90590 修复保存图片错误 2022-09-29 14:41:46 +08:00
Jason
61ef48d446 修复登录账号没有任何权限时跳转到403页面错误 2022-09-29 14:39:56 +08:00
Jason
331997e1e9 上传文件优化 2022-09-29 10:41:33 +08:00
Jason
a4b6b2d6c8 修改搜索栏input框宽度 2022-09-29 10:26:49 +08:00
Jason
140249aca8 修复通知提示bug 2022-09-29 10:26:11 +08:00
Jason
6719e1b4f1 素材中心优化 2022-09-29 10:19:03 +08:00
likeshop技术社区
6bf572a01a add LICENSE.
Signed-off-by: likeshop技术社区 <419339937@qq.com>
2022-09-29 02:17:21 +00:00
Jason
b74724084e 富文本优化 2022-09-29 10:16:59 +08:00
likeshop技术社区
580c06686a 删除文件 LICENSE 2022-09-29 02:16:58 +00:00
TinyAnts
235ab92413 优化代码 2022-09-28 09:38:52 +08:00
TinyAnts
4b58de936c init 2022-09-28 09:25:54 +08:00
TinyAnts
611f59941f 优化代码规范 2022-09-27 19:01:50 +08:00
TinyAnts
8db1cff376 优化代码 2022-09-27 18:54:07 +08:00
TinyAnts
6cb4ad95a7 优化代码 2022-09-27 18:25:24 +08:00
TinyAnts
5e9db85f86 优化调整代码规范 2022-09-27 17:47:32 +08:00
TinyAnts
11c06ec81e 代码生成器 2022-09-26 11:14:36 +08:00
TinyAnts
551a042582 修复代码生成器bug 2022-09-26 11:11:58 +08:00
TinyAnts
eb0ab251d5 优化代码生成器注释生成 2022-09-26 10:43:48 +08:00
TinyAnts
19e2d1c03b 优化代码生成器注释生成 2022-09-26 10:42:34 +08:00
TinyAnts
71066b6d83 修复代码生成器主键有下划线错误 2022-09-26 10:22:02 +08:00
TinyAnts
6f11895f70 修复AOP上传文件记录日志错误 2022-09-26 09:29:31 +08:00
Ants
909b4f03a0 !18 处理文件类型上传导致日志收集失败: I5SYLB
Merge pull request !18 from mlzhang/cherry-pick-1664048747
2022-09-26 01:27:07 +00:00
TinyAnts
48e39fa4f9 阿里云存储文案调整 2022-09-26 09:21:23 +08:00
mlzhang
b20738061e fixed 1d998d1 from https://gitee.com/zmldaniu/likeadmin_java/pulls/17
🐛 增加日志类型、判断文件类型记录文件名称 #I5SYLB
2022-09-24 19:45:49 +00:00
Ants
808cda3277 回退 'Pull Request !8 : 处理iss 优化建议' 2022-09-23 07:00:25 +00:00
Ants
42c7936f40 !8 处理iss 优化建议
Merge pull request !8 from mlzhang/master
2022-09-23 06:10:22 +00:00
Ants
dacded0e7a !15 修复代码生成器导入数据表,编辑字段问题,兼容mysql8
Merge pull request !15 from hawk/master
2022-09-23 06:08:37 +00:00
hawk
b2cf624380 取消更新javaType 2022-09-23 09:40:01 +08:00
hawk
5faf6aa301 Revert "不更新配置"
This reverts commit a70c5f6fc3.
2022-09-23 09:36:26 +08:00
hawk
b66eb35abb Merge branch 'javaType修复'
* javaType修复:
  修复代码生成器编辑数据表,不能保存java类型
2022-09-23 08:49:08 +08:00
hawk
ee8636ec54 修复代码生成器编辑数据表,不能保存java类型 2022-09-23 08:31:46 +08:00
hawk
a6d3ffb016 Revert "修复代码生成器编辑数据表,不能保存java类型"
This reverts commit 04a5d121a8.
2022-09-23 08:11:23 +08:00
hawk
04a5d121a8 修复代码生成器编辑数据表,不能保存java类型 2022-09-23 07:56:15 +08:00
hawk
a70c5f6fc3 不更新配置 2022-09-23 07:55:01 +08:00
TinyAnts
6dc8cc78a2 调整SQL文件 2022-09-22 09:39:24 +08:00
hawk
78db1ace6d 修复代码生成器导入数据表,编辑字段问题,兼容mysql8 2022-09-21 23:20:13 +08:00
TinyAnts
158125c3d0 Merge tag '1.3.1' into develop 2022-09-21 17:42:28 +08:00
TinyAnts
abc001b76b Merge branch 'release/1.3.1' 2022-09-21 17:42:27 +08:00
TinyAnts
4574db504a 调整SQL文件 2022-09-21 17:38:49 +08:00
TinyAnts
dfc50e2623 调整版本号 2022-09-21 17:33:24 +08:00
Jason
04290c78de 打包 2022-09-21 17:24:38 +08:00
Jason
a717ee326c code lint 2022-09-21 16:44:00 +08:00
Jason
5e844a1d38 后台页面调整 2022-09-21 16:42:53 +08:00
Jason
cbdb12f5d7 修改搜索页面样式问题 2022-09-21 14:11:23 +08:00
TinyAnts
a8e08053be 修复素材移动bug 2022-09-21 11:59:22 +08:00
TinyAnts
a70ec891d7 增加基类继承 2022-09-21 11:35:51 +08:00
TinyAnts
d12cae1937 调整验证器增加基类 2022-09-21 11:29:36 +08:00
TinyAnts
78726b8373 增加验证器基类 2022-09-21 11:21:15 +08:00
TinyAnts
5dfea2ad46 修复文章分类删除bug 2022-09-21 10:32:17 +08:00
TinyAnts
6e0f1ade38 修复文章分类删除bug 2022-09-21 10:29:58 +08:00
TinyAnts
f89d34915b 忽略文件 2022-09-21 10:26:42 +08:00
TinyAnts
8db154f01d 增加idea注释 2022-09-21 10:24:50 +08:00
TinyAnts
878f740bda 修复系统管理员账号被可被慕改bug 2022-09-21 10:07:24 +08:00
TinyAnts
1df98b147a 优化配置和静态资源 2022-09-21 09:59:51 +08:00
Jason
cadad25176 菜单调整,资讯图标预览调整 2022-09-20 18:50:08 +08:00
Jason
73984d52c0 Merge branch 'develop' of https://gitee.com/likeshop_gitee/likeadmin-java into develop 2022-09-20 18:49:02 +08:00
Jason
c3ea44292f 视频播放 2022-09-20 18:48:47 +08:00
TinyAnts
02317bee8e 调整视频上传大小限制 2022-09-20 18:43:48 +08:00
Jason
61dc2bf16d 调整登录页面样式 2022-09-20 16:23:29 +08:00
Jason
db45652f28 打包 2022-09-20 15:44:27 +08:00
Jason
51b35b664d 调整备注 2022-09-20 12:15:36 +08:00
Jason
29999f4e4a 调整登录,注册 2022-09-20 12:15:08 +08:00
Jason
77fb6acc2d 个人中心账号复制,切换tab页面时报错 2022-09-20 11:36:41 +08:00
Jason
b512eac708 调整工具函数 2022-09-20 11:06:54 +08:00
Jason
654c7b3c11 后台打包 2022-09-20 11:00:40 +08:00
Jason
fe5522dc2d 多标签tabs 调整 2022-09-20 10:58:38 +08:00
Jason
aee93d81b4 修改部门验证 2022-09-19 15:26:00 +08:00
Jason
56da1c18dd 部分多行文本框添加字数限制 2022-09-19 15:20:43 +08:00
Jason
ccd4747203 修复富文本编辑器样式问题 2022-09-19 14:52:45 +08:00
Jason
5240b89b35 后台打包 2022-09-19 14:04:54 +08:00
Jason
db7a0e3161 后台-岗位-文案错误 2022-09-19 12:13:58 +08:00
Jason
8f52978021 后台-热搜-删除搜索的id 2022-09-19 12:13:26 +08:00
Jason
83469090dd 字典数据无法访问bug 2022-09-19 12:12:40 +08:00
Jason
fa4de3214d Merge branch 'develop' of https://gitee.com/likeshop_gitee/likeadmin-java into develop 2022-09-19 12:12:03 +08:00
Jason
65da3d4a3a 素材中心优化 2022-09-19 12:11:54 +08:00
TinyAnts
a7e50bf511 修复后台上传视频获取不到名称bug 2022-09-19 11:57:35 +08:00
TinyAnts
e40689135f 修复前端默认logo与后台不一致bug 2022-09-19 10:10:43 +08:00
TinyAnts
3560cd45c5 Merge branch 'develop' of https://gitee.com/likeadmin/likeadmin_java into develop 2022-09-19 10:07:44 +08:00
TinyAnts
8d75e4c934 修复微信授权登录都是同一个账号bug 2022-09-19 10:07:27 +08:00
lr
9393de9063 Merge branch 'hotfix/lr-20220818-redeme' 2022-09-18 16:29:40 +08:00
lr
e0f11a53e2 Merge branch 'master' into develop 2022-09-18 16:29:40 +08:00
lr
b142dee20f 调整REMDME信息 2022-09-18 16:29:18 +08:00
lr
3d83b85588 Merge branch 'hotfix/lr-20220818' 2022-09-18 16:27:04 +08:00
lr
18cbb4374c Merge branch 'master' into develop 2022-09-18 16:27:04 +08:00
lr
ba7560b9e2 调整README信息 2022-09-18 16:26:42 +08:00
Jason
b7e010b634 Merge tag 'wjx202209160658' into develop
no message
2022-09-16 18:59:59 +08:00
Jason
8167380abe Merge branch 'hotfix/wjx202209160658' 2022-09-16 18:59:59 +08:00
Jason
c69c104cd6 打包 2022-09-16 18:59:46 +08:00
Jason
370cde09c4 Merge tag 'wjx202209160657' into develop
no message
2022-09-16 18:58:25 +08:00
Jason
5ae19337d9 Merge branch 'hotfix/wjx202209160657' 2022-09-16 18:58:25 +08:00
Jason
387b38a009 删除h5打包 2022-09-16 18:58:10 +08:00
Jason
8ee7d03ce2 Merge tag 'wjx202209160652' into develop
no message

# Conflicts:
#	h5/assets/account.304e4c09.js
#	h5/assets/index.5ddae38f.js
#	h5/assets/news-card.cacc1bdf.js
#	h5/assets/pages-bind_mobile-bind_mobile.1e39d2a7.js
#	h5/assets/pages-change_password-change_password.5516de7d.js
#	h5/assets/pages-collection-collection.5d101da7.js
#	h5/assets/pages-customer_service-customer_service.35e5d1d2.js
#	h5/assets/pages-forget_pwd-forget_pwd.0cebded6.js
#	h5/assets/pages-index-index.e7cbfcb8.js
#	h5/assets/pages-login-login.3d278588.js
#	h5/assets/pages-news-news.e71c4738.js
#	h5/assets/pages-news_detail-news_detail.32038bef.js
#	h5/assets/pages-register-register.07ea7f19.js
#	h5/assets/pages-search-search.fb4812e5.js
#	h5/assets/pages-user-user.97ccd207.js
#	h5/assets/pages-user_data-user_data.1a85e802.js
#	h5/assets/pages-user_set-user_set.a86f2f01.js
#	h5/assets/pages-webview-webview.320ac922.js
#	h5/assets/tabbar.3ac4b4ec.js
#	h5/assets/u-avatar.aaafa077.js
#	h5/assets/u-button.f89bd070.js
#	h5/assets/u-checkbox.e15726da.js
#	h5/assets/u-form-item.f2bc17f6.js
#	h5/assets/u-form.e908a5a2.js
#	h5/assets/u-icon.947d1557.js
#	h5/assets/u-image.f03d2bad.js
#	h5/assets/u-parse.466924cc.js
#	h5/assets/u-popup.c389a818.js
#	h5/assets/u-search.939c3f7f.js
#	h5/assets/u-verification-code.8f91217a.js
#	h5/assets/uni.fb5f5659.css
#	h5/assets/uni_modules-vk-uview-ui-components-u-avatar-cropper-u-avatar-cropper.e582869e.js
#	h5/assets/z-paging.34848bf3.js
#	h5/index.html
2022-09-16 18:55:34 +08:00
Jason
9be1caf811 Merge tag 'wjx202209160644' into develop
no message

# Conflicts:
#	h5/assets/account.461df912.js
#	h5/assets/index.4cc19f69.js
#	h5/assets/news-card.f9659a05.js
#	h5/assets/news.7d996083.js
#	h5/assets/pages-as_us-as_us.8bc9b466.js
#	h5/assets/pages-bind_mobile-bind_mobile.34dd4d4a.js
#	h5/assets/pages-change_password-change_password.16c95aef.js
#	h5/assets/pages-collection-collection.7f1501b9.js
#	h5/assets/pages-customer_service-customer_service.bd6a8b1f.js
#	h5/assets/pages-forget_pwd-forget_pwd.ed85d829.js
#	h5/assets/pages-index-index.19c7f55a.js
#	h5/assets/pages-login-login.432b5d68.js
#	h5/assets/pages-news-news.b7c7c850.js
#	h5/assets/pages-register-register.b6b6ae54.js
#	h5/assets/pages-search-search.26e01199.js
#	h5/assets/pages-user-user.3fd280ce.js
#	h5/assets/pages-user_data-user_data.6cd74f38.js
#	h5/assets/pages-user_set-user_set.5b8235ee.js
#	h5/assets/pages-webview-webview.d074f33b.js
#	h5/assets/tabbar.32c15533.js
#	h5/assets/u-avatar.40df6bc2.js
#	h5/assets/u-button.eb2fc020.js
#	h5/assets/u-checkbox.a3de132d.js
#	h5/assets/u-form-item.80dd7f49.js
#	h5/assets/u-form.9f54964a.js
#	h5/assets/u-icon.adf02ff2.js
#	h5/assets/u-image.554b827f.js
#	h5/assets/u-parse.a2aa510a.js
#	h5/assets/u-popup.2aaf05d4.js
#	h5/assets/u-search.18076790.js
#	h5/assets/u-verification-code.a41295d0.js
#	h5/assets/uni_modules-vk-uview-ui-components-u-avatar-cropper-u-avatar-cropper.8be1cad8.js
#	h5/assets/z-paging.ae4248a3.js
#	h5/index.html
2022-09-16 18:48:08 +08:00
Jason
53071be070 Merge tag 'wjx202209160640' into develop
no message

# Conflicts:
#	h5/assets/account.304e4c09.js
#	h5/assets/account.9ecc88ea.js
#	h5/assets/account.e236fd55.js
#	h5/assets/index.24de5888.js
#	h5/assets/index.5ddae38f.js
#	h5/assets/index.9d01590f.js
#	h5/assets/news-card.0f53c999.js
#	h5/assets/news-card.c91540ca.js
#	h5/assets/news-card.cacc1bdf.js
#	h5/assets/news.5c5bd132.js
#	h5/assets/news.7d996083.js
#	h5/assets/news.eb80f754.js
#	h5/assets/pages-as_us-as_us.27714390.js
#	h5/assets/pages-as_us-as_us.8bc9b466.js
#	h5/assets/pages-as_us-as_us.a75e6bf4.js
#	h5/assets/pages-bind_mobile-bind_mobile.1e39d2a7.js
#	h5/assets/pages-bind_mobile-bind_mobile.3d1ff6fd.js
#	h5/assets/pages-bind_mobile-bind_mobile.b0b2132a.js
#	h5/assets/pages-change_password-change_password.3e609524.js
#	h5/assets/pages-change_password-change_password.5516de7d.js
#	h5/assets/pages-change_password-change_password.7fcdae1a.js
#	h5/assets/pages-collection-collection.14907c26.js
#	h5/assets/pages-collection-collection.53abd56e.js
#	h5/assets/pages-collection-collection.5d101da7.js
#	h5/assets/pages-customer_service-customer_service.0e4773a4.js
#	h5/assets/pages-customer_service-customer_service.35e5d1d2.js
#	h5/assets/pages-customer_service-customer_service.c942a0bb.js
#	h5/assets/pages-forget_pwd-forget_pwd.0c22cfa7.js
#	h5/assets/pages-forget_pwd-forget_pwd.0cebded6.js
#	h5/assets/pages-forget_pwd-forget_pwd.41860f0c.js
#	h5/assets/pages-index-index.21b55a1c.js
#	h5/assets/pages-index-index.697592e8.js
#	h5/assets/pages-index-index.e7cbfcb8.js
#	h5/assets/pages-login-login.3d278588.js
#	h5/assets/pages-login-login.583742c3.js
#	h5/assets/pages-login-login.cc17b6ae.js
#	h5/assets/pages-news-news.6e6dfc74.js
#	h5/assets/pages-news-news.e71c4738.js
#	h5/assets/pages-news-news.f27837dc.js
#	h5/assets/pages-register-register.07ea7f19.js
#	h5/assets/pages-register-register.127a8342.js
#	h5/assets/pages-register-register.707197f6.js
#	h5/assets/pages-search-search.5bd1eb0e.js
#	h5/assets/pages-search-search.c9a4fc47.js
#	h5/assets/pages-search-search.fb4812e5.js
#	h5/assets/pages-user-user.29445b03.js
#	h5/assets/pages-user-user.97ccd207.js
#	h5/assets/pages-user-user.e6fd2164.js
#	h5/assets/pages-user_data-user_data.1a85e802.js
#	h5/assets/pages-user_data-user_data.2a0211b5.js
#	h5/assets/pages-user_data-user_data.65619aff.js
#	h5/assets/pages-user_set-user_set.9387105d.js
#	h5/assets/pages-user_set-user_set.a86f2f01.js
#	h5/assets/pages-user_set-user_set.d71e173b.js
#	h5/assets/pages-webview-webview.183e0d8c.js
#	h5/assets/pages-webview-webview.320ac922.js
#	h5/assets/pages-webview-webview.c3fa2ff9.js
#	h5/assets/shop.067e3a04.js
#	h5/assets/tabbar.1370a2f3.js
#	h5/assets/tabbar.3ac4b4ec.js
#	h5/assets/tabbar.5a261344.js
#	h5/assets/u-avatar.0975a40c.js
#	h5/assets/u-avatar.665749d0.js
#	h5/assets/u-avatar.aaafa077.js
#	h5/assets/u-button.4291cf3a.js
#	h5/assets/u-button.6324a944.js
#	h5/assets/u-button.f89bd070.js
#	h5/assets/u-checkbox.4a48075d.js
#	h5/assets/u-checkbox.a9e5c7b5.js
#	h5/assets/u-checkbox.e15726da.js
#	h5/assets/u-form-item.8b18cdc2.js
#	h5/assets/u-form-item.e8316076.js
#	h5/assets/u-form-item.f2bc17f6.js
#	h5/assets/u-form.718bda0a.js
#	h5/assets/u-form.9d11b0a8.js
#	h5/assets/u-form.e908a5a2.js
#	h5/assets/u-icon.947d1557.js
#	h5/assets/u-icon.b22654a8.js
#	h5/assets/u-icon.b511ef4e.js
#	h5/assets/u-image.2abefbca.js
#	h5/assets/u-image.dcffbc78.js
#	h5/assets/u-image.f03d2bad.js
#	h5/assets/u-parse.2b02a1d4.js
#	h5/assets/u-parse.466924cc.js
#	h5/assets/u-parse.cd76eaa8.js
#	h5/assets/u-popup.0657d28e.js
#	h5/assets/u-popup.6fa83f64.js
#	h5/assets/u-popup.c389a818.js
#	h5/assets/u-search.939c3f7f.js
#	h5/assets/u-search.9f49742b.js
#	h5/assets/u-search.dad6632d.js
#	h5/assets/u-verification-code.419886b4.js
#	h5/assets/u-verification-code.8f91217a.js
#	h5/assets/u-verification-code.9a7d2ff4.js
#	h5/assets/uni_modules-vk-uview-ui-components-u-avatar-cropper-u-avatar-cropper.75f62b2e.js
#	h5/assets/uni_modules-vk-uview-ui-components-u-avatar-cropper-u-avatar-cropper.859f9abd.js
#	h5/assets/uni_modules-vk-uview-ui-components-u-avatar-cropper-u-avatar-cropper.e582869e.js
#	h5/assets/util.7b793930.js
#	h5/assets/z-paging.34848bf3.js
#	h5/assets/z-paging.51f9fb6d.js
#	h5/assets/z-paging.9a4d68b6.js
#	h5/index.html
2022-09-16 18:43:18 +08:00
TinyAnts
769c1c0ff6 Merge branch 'master' into develop 2022-09-16 18:39:48 +08:00
TinyAnts
b660028a6c Merge branch 'develop' of https://gitee.com/likeadmin/likeadmin_java into develop 2022-09-16 18:33:51 +08:00
TinyAnts
4ee067a1f7 Merge tag '1.3.0' into develop 2022-09-16 18:25:36 +08:00
Jason
3f699d3c7c 打包 2022-09-16 18:23:03 +08:00
zhangml
2db501d36d 优化部门级联和默认 #I5R3QL 2022-09-16 13:42:11 +08:00
812 changed files with 3431 additions and 1957 deletions

1
.gitignore vendored
View File

@@ -5,5 +5,6 @@
target/
application-dev.yml
application-pro.yml
application-dem.yml
application-prod.yml
application-test.yml

214
LICENSE
View File

@@ -1,201 +1,21 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
MIT License
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
Copyright (c) 2022 likeshop技术社区
1. Definitions.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -1,5 +1,5 @@
<h1 align="center">likeadmin通用管理后台Java</h1>
<h4 align="center">🚀快速开发、🛠️ 一键生成代码、📱手机自适应</h4>
<h4 align="center">🚀快速开发、🛠️ 一键生成代码、✅后台多端自适应、📱手机端uniapp前台</h4>
<p align="center">
<a href="https://www.java.com/zh-CN/download/"><img src="https://img.shields.io/badge/JAVA-8-d74f11"> </a><a href="#"> <img src="https://img.shields.io/badge/Spring Boot-2-5ea931"> </a><a href="https://www.tslang.cn/"><img src="https://img.shields.io/badge/TypeScript-3-294e80"></a> <a href="#"><img src="https://img.shields.io/badge/Vue.js-3-4eb883"> </a><a href="#"><img src="https://img.shields.io/badge/vite-2-ffc018"> </a><a href="#"><img src="https://img.shields.io/badge/Element Plus-2-409eff"> </a><a target="_blank" href="https://www.docker.com/"><img src="https://img.shields.io/badge/Docker--139cff"></a>
<div align="center">
@@ -7,9 +7,14 @@
</div>
<br>
## 👀体验后台
## 👀体验
### 管理后台
地址https://demo-java.likeadmin.cn <br>
账号admin 密码123456
### 手机端uniapp前台
<img width="40%" src="https://md.likeshop.cn/server/index.php?s=/api/attachment/visitFile&sign=260c0869d9ba7e692b2db1e216078241" /><br>
## 👨‍💻‍简介
@@ -20,24 +25,33 @@
1.likeadmin已经搭建好前后端分离的底层包含程序安装、登录、登出、工作台、菜单权限控制、角色、管理员、部门管理、岗位管理、素材管理、网站设置、图库管理等基础功能无需重复造轮子。更有开发者工具功能一生成代码大大节省开发时间。<br>
2.可视化系统程序安装界面,可自定义安装数据,开发者可快速扩展发行自己的软件产品。<br>
3.likeadmin定位为通用的软件系统管理后台方便开发者快速开发软件系统文档清晰、代码易懂、简单易用。<br>
4.未来将持续集成通用的微信/支付宝支付,阿里云/腾讯云短信,阿里云/腾讯云OSS等通用模块
4.手机端uniapp前台含导导航配置、微信登录、个人登录等等基础功能方便根据业务开发含手机前台的项目
### 🐙 后端架构方面
1.服务端使用JAVA8开发性能有突破性的提升。<br>
2.使用Spring Boot2.5框架目前国内流行的JAVA框架高性能、简单易用、文档齐全、支持Mave高级项目管理工具、支持Redis等。
### 🐹 前端架构方面
#### 后台
1.使用最流性的前后端分离方案typescript、vue3、vite开发保持了代码的简洁、一致和规范。<br>
2.后台界面使用element-plus UI框架简单精美的后台界面丰富的组件库方便快速开发满足各种后台交互。
<br>
### 前台
手机端uniapp前台可以编译成手机H5网页、微信小程序、安卓App苹果App等客户端。<br>
### 🛠️ 代码生成器
一键生成前后端业务代码,大大提示开发效率。
### 🖥️界面预览
一键生成前后端业务代码,大大提示开发效率。<br>
## 界面预览
### 🖥️后台页面
![](https://md.likeshop.cn/server/index.php?s=/api/attachment/visitFile&sign=9cf02b831e49d6a411bafbc4d79f51d4)<br>
![](https://md.likeshop.cn/server/index.php?s=/api/attachment/visitFile&sign=eb83547d55b4f41f0d92fd6a3e01d87e)
![](https://md.likeshop.cn/server/index.php?s=/api/attachment/visitFile&sign=818d843fb9cba396226e32dad1a58f3c)<br>
![](https://md.likeshop.cn/server/index.php?s=/api/attachment/visitFile&sign=194ab31919cd4dd619e6c453d7a44304)<br>
![](https://md.likeshop.cn/server/index.php?s=/api/attachment/visitFile&sign=f6770e2a8069d7b6ea3d83b91204b9d6)<br>
<br>
### 📱手机端前台界面
<div class="half">
<img width="30%" src="https://md.likeshop.cn/server/index.php?s=/api/attachment/visitFile&sign=2dbac190afadfb6650a04c8af44980e1" /> <img width="30%" src="https://md.likeshop.cn/server/index.php?s=/api/attachment/visitFile&sign=73adbdb91ff5c43ca3e694a99effae7a" /> <img width="30%" src="https://md.likeshop.cn/server/index.php?s=/api/attachment/visitFile&sign=55b51eaebd7d696f96ccbf60d4694368" />
</div><br>
### 🪐接口文档
[点击这里进入更多更详细文档。](https://www.likeadmin.cn "点击这里进入更多更详细文档。")

View File

@@ -1,4 +0,0 @@
NODE_ENV = 'development'
# 请求域名
VITE_APP_BASE_URL='https://likeadmin-java.yixiangonline.com'

View File

@@ -0,0 +1,4 @@
NODE_ENV = 'development'
# 请求域名
VITE_APP_BASE_URL=''

3
admin/.gitignore vendored
View File

@@ -30,3 +30,6 @@ components.d.ts
*.sln
*.sw?
# .env
.env.development
.env.production

View File

@@ -55,6 +55,7 @@
"vite": "^3.0.0",
"vite-plugin-style-import": "^2.0.0",
"vite-plugin-svg-icons": "^2.0.1",
"vite-plugin-vue-setup-extend": "^0.4.0",
"vue-tsc": "^0.38.1"
}
}

View File

@@ -1,4 +1,5 @@
import request from '@/utils/request'
import { firstToUpperCase } from '@/utils/util'
// 微信公众号配置保存
export function setOaConfig(params: any) {
@@ -47,12 +48,11 @@ export function setOaMenuPublish(params: Menu | any) {
}
/**
* @return { Promise }
* @param { string } type
* @description 获取回复列表
* @description 默认回复列表
*/
export function getOaReplyList(params: { type: string }) {
return request.get({ url: '/channel/oaReply/list', params })
export function getOaReplyList(params: any) {
const type = firstToUpperCase(params.type)
return request.get({ url: `/channel/oaReply${type}/list`, params })
}
/**
@@ -60,8 +60,9 @@ export function getOaReplyList(params: { type: string }) {
* @param { number } id
* @description 回复列表删除
*/
export function oaReplyDel(params: { id: number }) {
return request.post({ url: '/channel/oaReply/del', params })
export function oaReplyDel(params: any) {
const type = firstToUpperCase(params.type)
return request.post({ url: `/channel/oaReply${type}/del`, params })
}
/**
@@ -69,8 +70,9 @@ export function oaReplyDel(params: { id: number }) {
* @param { number } id
* @description 回复状态修改
*/
export function changeOaReplyStatus(params: { id: number }) {
return request.post({ url: '/channel/oaReply/status', params })
export function changeOaReplyStatus(params: any) {
const type = firstToUpperCase(params.type)
return request.post({ url: `/channel/oaReply${type}/status`, params })
}
export interface Reply {
@@ -85,25 +87,26 @@ export interface Reply {
}
/**
* @return { Promise }
* @description 回复添加
* @description 默认回复编辑
*/
export function oaReplyAdd(params: Reply) {
return request.post({ url: '/channel/oaReply/add', params })
const type = firstToUpperCase(params.type)
return request.post({ url: `/channel/oaReply${type}/add`, params })
}
/**
* @return { Promise }
* @description 回复编辑
* @description 默认回复编辑
*/
export function oaReplyEdit(params: Reply) {
return request.post({ url: '/channel/oaReply/edit', params })
const type = firstToUpperCase(params.type)
return request.post({ url: `/channel/oaReply${type}/edit`, params })
}
/**
* @return { Promise }
* @param { string } type
* @description 获取回复详情
* @description 默认回复详情
*/
export function getOaReplyDetail(params: { id: number }) {
return request.get({ url: '/channel/oaReply/detail', params })
export function getOaReplyDetail(params: any) {
const type = firstToUpperCase(params.type)
return request.get({ url: `/channel/oaReply${type}/detail`, params })
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -15,9 +15,10 @@
/>
<material-picker
ref="materialPickerRef"
:type="fileType"
:limit="-1"
hidden-upload
@change="imageSelectChange"
@change="selectChange"
/>
</div>
</template>
@@ -39,12 +40,10 @@ const props = withDefaults(
}>(),
{
modelValue: '',
mode: 'simple',
mode: 'default',
height: '100%',
width: 'auto',
toolbarConfig: () => ({
excludeKeys: ['fullScreen']
})
toolbarConfig: () => ({})
}
)
@@ -55,16 +54,24 @@ const emit = defineEmits<{
// 编辑器实例,必须用 shallowRef
const editorRef = shallowRef()
const materialPickerRef = shallowRef<InstanceType<typeof MaterialPicker>>()
const fileType = ref('')
let insertImageFn: any
let insertFn: any
const editorConfig: Partial<IEditorConfig> = {
MENU_CONF: {
uploadImage: {
customBrowseAndUpload(insertFn: any) {
console.log(insertFn)
customBrowseAndUpload(insert: any) {
fileType.value = 'image'
materialPickerRef.value?.showPopup(-1)
insertImageFn = insertFn
insertFn = insert
}
},
uploadVideo: {
customBrowseAndUpload(insert: any) {
fileType.value = 'video'
materialPickerRef.value?.showPopup(-1)
insertFn = insert
}
}
}
@@ -83,9 +90,9 @@ const valueHtml = computed({
}
})
const imageSelectChange = (image: string[]) => {
image.forEach((url) => {
insertImageFn(url)
const selectChange = (fileUrl: string[]) => {
fileUrl.forEach((url) => {
insertFn(url)
})
}
@@ -100,3 +107,37 @@ const handleCreated = (editor: any) => {
editorRef.value = editor // 记录 editor 实例,重要!
}
</script>
<style lang="scss">
.w-e-full-screen-container {
z-index: 999999;
}
.w-e-text-container [data-slate-editor] ul {
list-style: disc;
}
.w-e-text-container [data-slate-editor] ol {
list-style: decimal;
}
h1 {
font-size: 2em;
}
h2 {
font-size: 1.5em;
}
h3 {
font-size: 1.17em;
}
h4 {
font-size: 1em;
}
h5 {
font-size: 0.83em;
}
h1,
h2,
h3,
h4,
h5 {
font-weight: bold;
}
</style>

View File

@@ -20,7 +20,11 @@ const props = defineProps({
type: [String, Number],
default: 0
},
...imageProps
...imageProps,
hideOnClickModal: {
type: Boolean,
default: true
}
})
const styles = computed<CSSProperties>(() => {

View File

@@ -1,8 +1,14 @@
<template>
<div>
<div class="file-item" :style="{ height: fileSize, width: fileSize }">
<div class="file-item relative" :style="{ height: fileSize, width: fileSize }">
<el-image class="image" v-if="type == 'image'" fit="contain" :src="uri"></el-image>
<video class="video" v-else-if="type == 'video'" :src="uri"></video>
<div
v-if="type == 'video'"
class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] rounded-full w-5 h-5 flex justify-center items-center bg-[rgba(0,0,0,0.3)]"
>
<icon name="el-icon-CaretRight" :size="18" color="#fff" />
</div>
<slot></slot>
</div>
</div>

View File

@@ -45,8 +45,7 @@ export function useCate(type: number) {
}
// 添加分组
const handleAddCate = async () => {
const { value } = await feedback.prompt('', '添加分组')
const handleAddCate = async (value: string) => {
await fileCateAdd({
type,
name: value,
@@ -56,8 +55,7 @@ export function useCate(type: number) {
}
// 编辑分组
const handleEditCate = async (name: string, id: number) => {
const { value } = await feedback.prompt('', '重命分组', { inputValue: name })
const handleEditCate = async (value: string, id: number) => {
await fileCateEdit({
id,
name: value
@@ -180,8 +178,7 @@ export function useFile(
clearSelect()
}
const handleFileRename = async (name: string, id: number) => {
const { value } = await feedback.prompt('', '重命名', { inputValue: name })
const handleFileRename = async (value: string, id: number) => {
await fileRename({
id,
name: value

View File

@@ -34,12 +34,22 @@
<span class="muted m-r-10">···</span>
<template #dropdown>
<el-dropdown-menu>
<div
<popover-input
v-perms="['common:album:cateRename']"
@click="handleEditCate(data.name, data.id)"
@confirm="handleEditCate($event, data.id)"
size="default"
:value="data.name"
width="400px"
:limit="20"
show-limit
teleported
>
<el-dropdown-item>命名分组</el-dropdown-item>
</div>
<div>
<el-dropdown-item>
命名分组
</el-dropdown-item>
</div>
</popover-input>
<div
v-perms="['common:album:cateDel']"
@click="handleDeleteCate(data.id)"
@@ -57,9 +67,17 @@
</div>
<div class="flex justify-center p-2 border-t border-br">
<el-button @click="handleAddCate" v-perms="['common:album:cateAdd']">
添加分组
</el-button>
<popover-input
v-perms="['common:album:cateAdd']"
@confirm="handleAddCate"
size="default"
width="400px"
:limit="20"
show-limit
teleported
>
<el-button> 添加分组 </el-button>
</popover-input>
</div>
</div>
<div class="material__center flex flex-col">
@@ -195,14 +213,18 @@
<overflow-tooltip class="mt-1" :content="item.name" />
<div class="operation-btns flex items-center">
<el-button
<popover-input
v-perms="['common:album:albumRename']"
type="primary"
link
@click="handleFileRename(item.name, item.id)"
@confirm="handleFileRename($event, item.id)"
size="default"
:value="item.name"
width="400px"
:limit="50"
show-limit
teleported
>
重命名
</el-button>
<el-button type="primary" link> 重命名 </el-button>
</popover-input>
<el-button type="primary" link @click="handlePreview(item.uri)">
查看
</el-button>
@@ -226,27 +248,33 @@
<el-checkbox :modelValue="isSelect(row.id)" @change="selectFile(row)" />
</template>
</el-table-column>
<el-table-column label="图片" width="60">
<el-table-column label="图片" width="100">
<template #default="{ row }">
<file-item :uri="row.uri" file-size="40px"></file-item>
<file-item :uri="row.uri" file-size="50px" :type="type"></file-item>
</template>
</el-table-column>
<el-table-column label="名称" min-width="100" show-overflow-tooltip>
<template #default="{ row }">
<el-link @click.stop="handlePreview(row.uri)">{{ row.name }}</el-link>
<el-link @click.stop="handlePreview(row.uri)" :underline="false">
{{ row.name }}
</el-link>
</template>
</el-table-column>
<el-table-column prop="createTime" label="上传时间" min-width="100" />
<el-table-column label="操作" width="150" fixed="right">
<template #default="{ row }">
<div class="inline-block" v-perms="['common:album:albumRename']">
<el-button
type="primary"
link
@click.stop="handleFileRename(row.name, row.id)"
<popover-input
@confirm="handleFileRename($event, row.id)"
size="default"
:value="row.name"
width="400px"
:limit="50"
show-limit
teleported
>
重命名
</el-button>
<el-button type="primary" link> 重命名 </el-button>
</popover-input>
</div>
<div class="inline-block">
<el-button type="primary" link @click.stop="handlePreview(row.uri)">

View File

@@ -214,6 +214,7 @@ export default defineComponent({
const handleClose = () => {
nextTick(() => {
if (props.hiddenUpload) fileList.value = []
materialRef.value?.clearSelect()
})
}

View File

@@ -6,16 +6,18 @@
:width="width"
trigger="contextmenu"
class="popover-input"
:teleported="false"
:teleported="teleported"
:persistent="false"
popper-class="!p-0"
>
<div class="flex">
<div class="flex p-3" @click.stop="">
<div class="popover-input__input mr-[10px] flex-1">
<el-select
class="flex-1"
size="small"
:size="size"
v-if="type == 'select'"
v-model="inputValue"
:teleported="false"
:teleported="teleported"
>
<el-option
v-for="item in options"
@@ -27,14 +29,17 @@
<el-input
v-else
v-model.trim="inputValue"
:maxlength="limit"
:show-word-limit="showLimit"
:type="type"
size="small"
:size="size"
clearable
:placeholder="placeholder"
/>
</div>
<div class="popover-input__btns flex-none">
<el-button link @click="visible = false">取消</el-button>
<el-button type="primary" size="small" @click="handleConfirm">确定</el-button>
<el-button link @click="close">取消</el-button>
<el-button type="primary" :size="size" @click="handleConfirm">确定</el-button>
</div>
</div>
<template #reference>
@@ -60,7 +65,7 @@ const props = defineProps({
},
width: {
type: [Number, String],
default: 250
default: '300px'
},
placeholder: String,
disabled: {
@@ -70,6 +75,22 @@ const props = defineProps({
options: {
type: Array as PropType<any[]>,
default: () => []
},
size: {
type: String as PropType<'default' | 'small' | 'large'>,
default: 'default'
},
limit: {
type: Number,
default: 200
},
showLimit: {
type: Boolean,
default: false
},
teleported: {
type: Boolean,
default: true
}
})
const emit = defineEmits(['confirm'])
@@ -99,7 +120,8 @@ watch(
immediate: true
}
)
useEventListener(document.body, 'click', () => {
useEventListener(document.documentElement, 'click', () => {
if (inPopover.value) return
close()
})

View File

@@ -12,6 +12,7 @@
:on-success="handleSuccess"
:on-exceed="handleExceed"
:on-error="handleError"
:accept="getAccept"
>
<slot></slot>
</el-upload>
@@ -110,18 +111,30 @@ export default defineComponent({
emit('error')
}
const handleExceed = () => {
feedback.msgError('超出上传上限,请重新上传')
feedback.msgError(`超出上传上限${props.limit},请重新上传`)
}
const handleClose = () => {
uploadRefs.value?.clearFiles()
visible.value = false
}
const getAccept = computed(() => {
switch (props.type) {
case 'image':
return '.jpj,.png,.gif,.jpeg,.ico,.bmp'
case 'video':
return '.wmv,.avi,.mov,.mp4,.flv,.rmvb'
default:
return '*'
}
})
return {
uploadRefs,
action,
headers,
visible,
fileList,
getAccept,
handleProgress,
handleSuccess,
handleError,

View File

@@ -37,7 +37,7 @@ const options = reactive({
mirror: false, //镜像画面
ligthOff: false, //关灯模式
volume: 0.3, //默认音量大小
control: false, //是否显示控制器
control: true, //是否显示控制器
title: '', //视频名称
poster: '', //封面
...props

View File

@@ -1,10 +1,10 @@
const config = {
terminal: 1,
title: '后台管理系统',
version: '1.1.6',
baseUrl: `${import.meta.env.VITE_APP_BASE_URL}/`,
urlPrefix: 'api',
timeout: 20 * 1000
terminal: 1, //终端
title: '后台管理系统', //网站默认标题
version: '1.2.0', //版本号
baseUrl: `${import.meta.env.VITE_APP_BASE_URL || ''}/`, //请求接口域名
urlPrefix: 'api', //请求默认前缀
timeout: 10 * 1000 //请求超时时长
}
export default config

View File

@@ -1,13 +1,16 @@
const defaultSetting = {
sideWidth: 200,
sideTheme: 'light',
sideDarkColor: '#1d2124',
theme: '#4A5DFF',
openMultipleTabs: true,
successTheme: '#67c23a',
warningTheme: '#e6a23c',
dangerTheme: '#f56c6c',
errorTheme: '#f56c6c',
infoTheme: '#909399'
isUniqueOpened: false, //只展开一个一级菜单
sideWidth: 200, //侧边栏宽度
sideTheme: 'light', //侧边栏主题
sideDarkColor: '#1d2124', //侧边栏深色主题颜色
openMultipleTabs: true, // 是否开启多标签tab栏
theme: '#4A5DFF', //主题色
successTheme: '#67c23a', //成功主题色
warningTheme: '#e6a23c', //警告主题色
dangerTheme: '#f56c6c', //危险主题色
errorTheme: '#f56c6c', //错误主题色
infoTheme: '#909399' //信息主题色
}
//以上各种主题色分别对应element-plus的几种行为主题
export default defaultSetting

View File

@@ -0,0 +1,47 @@
import useTabsStore from '@/stores/modules/multipleTabs'
import useSettingStore from '@/stores/modules/setting'
export default function useMultipleTabs() {
const router = useRouter()
const route = useRoute()
const tabsStore = useTabsStore()
const settingStore = useSettingStore()
const tabsLists = computed(() => {
return tabsStore.getTabList
})
const currentTab = computed(() => {
return route.fullPath
})
const addTab = () => {
if (!settingStore.openMultipleTabs) return
tabsStore.addTab(router)
}
const removeTab = (fullPath?: any) => {
if (!settingStore.openMultipleTabs) return
fullPath = fullPath ?? route.fullPath
tabsStore.removeTab(fullPath, router)
}
const removeOtherTab = () => {
if (!settingStore.openMultipleTabs) return
tabsStore.removeOtherTab(route)
}
const removeAllTab = () => {
if (!settingStore.openMultipleTabs) return
tabsStore.removeAllTab(router)
}
return {
tabsLists,
currentTab,
addTab,
removeTab,
removeOtherTab,
removeAllTab
}
}

View File

@@ -3,12 +3,12 @@
<div class="flex-1 min-w-0">
<el-tabs
:model-value="currentTab"
:closable="tabsState.length > 1"
:closable="tabsLists.length > 1"
@tab-change="handleChange"
@tab-remove="handleRemove"
@tab-remove="removeTab($event)"
>
<template v-for="item in tabsState" :key="item.path">
<el-tab-pane :label="item.title" :name="item.path"></el-tab-pane>
<template v-for="item in tabsLists" :key="item.fullPath">
<el-tab-pane :label="item.title" :name="item.fullPath"></el-tab-pane>
</template>
</el-tabs>
</div>
@@ -28,40 +28,31 @@
</template>
<script setup lang="ts">
import useMultipleTabs from '@/hooks/useMultipleTabs'
import { useWatchRoute } from '@/hooks/useWatchRoute'
import useTabsStore, { getRouteParams } from '@/stores/modules/multipleTabs'
const router = useRouter()
const tabsStore = useTabsStore()
const { route } = useWatchRoute((route) => {
tabsStore.addTab(route, router)
const { removeOtherTab, addTab, removeAllTab, removeTab, tabsLists, currentTab } = useMultipleTabs()
useWatchRoute(() => {
addTab()
})
const currentTab = computed(() => {
return route.path
})
const tabsState = computed(() => {
return tabsStore.getTabList
})
const handleChange = (path: any) => {
const tabItem = tabsStore.tasMap[path]
const handleChange = (fullPath: any) => {
const tabItem = tabsStore.tasMap[fullPath]
router.push(getRouteParams(tabItem))
}
const handleRemove = (path: any) => {
tabsStore.removeTab(path, router)
}
const handleCommand = (command: any) => {
switch (command) {
case 'closeCurrent':
handleRemove(route.path)
removeTab()
break
case 'closeOther':
tabsStore.removeOtherTab(route.path)
removeOtherTab()
break
case 'closeAll':
tabsStore.removeAllTab(router)
removeAllTab()
break
}
}

View File

@@ -3,7 +3,9 @@
<el-scrollbar>
<div class="p-4">
<router-view v-if="isRouteShow" v-slot="{ Component, route }">
<component :is="Component" :key="route.fullPath" />
<keep-alive :include="includeList" :max="20">
<component :is="Component" :key="route.fullPath" />
</keep-alive>
</router-view>
</div>
</el-scrollbar>
@@ -12,8 +14,13 @@
<script setup lang="ts">
import useAppStore from '@/stores/modules/app'
import useTabsStore from '@/stores/modules/multipleTabs'
import useSettingStore from '@/stores/modules/setting'
const appStore = useAppStore()
const tabsStore = useTabsStore()
const settingStore = useSettingStore()
const isRouteShow = computed(() => appStore.isRouteShow)
const includeList = computed(() => (settingStore.openMultipleTabs ? tabsStore.getCacheTabList : []))
</script>
<style></style>

View File

@@ -47,6 +47,16 @@
/>
</div>
</div>
<div class="setting-item mb-5 flex justify-between items-center">
<span class="text-tx-secondary">只展开一个一级菜单</span>
<div>
<el-switch
v-model="isUniqueOpened"
:active-value="true"
:inactive-value="false"
/>
</div>
</div>
<div class="setting-item mb-5">
<div class="text-tx-secondary mb-4">菜单栏宽度</div>
<div><el-input-number v-model="sideWidth" :min="180" :max="250" /></div>
@@ -65,7 +75,6 @@ import theme_light from '@/assets/images/theme_white.png'
import theme_dark from '@/assets/images/theme_black.png'
const settingStore = useSettingStore()
const predefineColors = ref(['#409EFF', '#28C76F', '#EA5455', '#FF9F43', '#01CFE8', '#4A5DFF'])
const sideThemeList = [
{
@@ -102,6 +111,18 @@ const openMultipleTabs = computed({
}
})
const isUniqueOpened = computed({
get() {
return settingStore.isUniqueOpened
},
set(value) {
settingStore.setSetting({
key: 'isUniqueOpened',
value
})
}
})
const sideWidth = computed({
get() {
return settingStore.sideWidth

View File

@@ -10,7 +10,7 @@
:default-active="activeMenu"
:collapse="isCollapsed"
mode="vertical"
:unique-opened="true"
:unique-opened="uniqueOpened"
@select="$emit('select')"
>
<menu-item
@@ -41,6 +41,10 @@ const props = defineProps({
type: Boolean,
default: false
},
uniqueOpened: {
type: Boolean,
default: false
},
theme: {
type: String
},

View File

@@ -5,6 +5,7 @@
:routes="routes"
:isCollapsed="isCollapsed"
:width="settingStore.sideWidth"
:unique-opened="settingStore.isUniqueOpened"
:config="menuProp"
:theme="sideTheme"
@select="handleSelect"

View File

@@ -11,6 +11,7 @@ import { INDEX_ROUTE, INDEX_ROUTE_NAME } from './router/routes'
import { PageEnum } from './enums/pageEnum'
import useTabsStore from './stores/modules/multipleTabs'
import { clearAuthInfo } from './utils/auth'
import config from './config'
// NProgress配置
NProgress.configure({ showSpinner: false })
@@ -22,6 +23,7 @@ const whiteList: string[] = [PageEnum.LOGIN, PageEnum.ERROR_403]
router.beforeEach(async (to, from, next) => {
// 开始 Progress Bar
NProgress.start()
document.title = to.meta.title ?? config.title
const userStore = useUserStore()
const tabsStore = useTabsStore()
if (userStore.token) {
@@ -42,7 +44,7 @@ router.beforeEach(async (to, from, next) => {
const routeName = findFirstValidRoute(routes)
// 没有有效路由跳转到403页面
if (!routeName) {
await userStore.logout()
clearAuthInfo()
next(PageEnum.ERROR_403)
return
}

View File

@@ -86,8 +86,8 @@ export function findFirstValidRoute(routes: RouteRecordRaw[]): string | undefine
}
//通过权限字符查询路由路径
export function getRoutePath(perms: string) {
const router = useRouter()
return router.getRoutes().find((item) => item.meta?.perms == perms)?.path || ''
const routerObj = useRouter() || router
return routerObj.getRoutes().find((item) => item.meta?.perms == perms)?.path || ''
}
// 重置路由

View File

@@ -11,6 +11,7 @@ import { PageEnum } from '@/enums/pageEnum'
interface TabItem {
name: RouteRecordName
fullPath: string
path: string
title?: string
query?: LocationQuery
@@ -24,8 +25,8 @@ interface TabsSate {
indexRouteName: RouteRecordName
}
const getHasTabIndex = (path: string, tabList: TabItem[]) => {
return tabList.findIndex((item) => item.path == path)
const getHasTabIndex = (fullPath: string, tabList: TabItem[]) => {
return tabList.findIndex((item) => item.fullPath == fullPath)
}
const isCannotAddRoute = (route: RouteLocationNormalized, router: Router) => {
@@ -39,8 +40,12 @@ const isCannotAddRoute = (route: RouteLocationNormalized, router: Router) => {
return false
}
const findTabsIndex = (path: string, tabList: TabItem[]) => {
return tabList.findIndex((item) => item.path === path)
const findTabsIndex = (fullPath: string, tabList: TabItem[]) => {
return tabList.findIndex((item) => item.fullPath === fullPath)
}
const getComponentName = (route: RouteLocationNormalized) => {
return route.matched.at(-1)?.components?.default?.name
}
export const getRouteParams = (tabItem: TabItem) => {
@@ -63,45 +68,67 @@ const useTabsStore = defineStore({
getters: {
getTabList(): TabItem[] {
return this.tabList
},
getCacheTabList(): string[] {
return Array.from(this.cacheTabList)
}
},
actions: {
setRouteName(name: RouteRecordName) {
this.indexRouteName = name
},
addCache(componentName?: string) {
if (componentName) this.cacheTabList.add(componentName)
},
removeCache(componentName?: string) {
if (componentName && this.cacheTabList.has(componentName)) {
this.cacheTabList.delete(componentName)
}
console.log(this.cacheTabList)
},
clearCache() {
this.cacheTabList.clear()
},
resetState() {
this.cacheTabList = new Set()
this.tabList = []
this.tasMap = {}
this.indexRouteName = ''
},
addTab(route: RouteLocationNormalized, router: Router) {
const { name, path, query, meta, params } = route
addTab(router: Router) {
const route = unref(router.currentRoute)
const { name, query, meta, params, fullPath, path } = route
if (isCannotAddRoute(route, router)) return
const hasTabIndex = getHasTabIndex(path!, this.tabList)
const hasTabIndex = getHasTabIndex(fullPath!, this.tabList)
const componentName = getComponentName(route)
const tabItem = {
name: name!,
path,
fullPath,
title: meta?.title,
query,
params
}
this.tasMap[path] = tabItem
this.tasMap[fullPath] = tabItem
if (meta?.keepAlive) {
this.addCache(componentName)
}
if (hasTabIndex != -1) {
this.tabList.splice(hasTabIndex, 1, tabItem)
return
}
this.tabList.push(tabItem)
},
removeTab(path: string, router: Router) {
removeTab(fullPath: string, router: Router) {
const { currentRoute, push } = router
const index = findTabsIndex(path, this.tabList)
const index = findTabsIndex(fullPath, this.tabList)
// 移除tab
if (this.tabList.length > 1) {
index !== -1 && this.tabList.splice(index, 1)
}
if (path !== currentRoute.value.path) {
const componentName = getComponentName(currentRoute.value)
this.removeCache(componentName)
if (fullPath !== currentRoute.value.fullPath) {
return
}
// 删除选中的tab
@@ -116,17 +143,24 @@ const useTabsStore = defineStore({
const toRoute = getRouteParams(toTab)
push(toRoute)
},
removeOtherTab(path: string) {
this.tabList = this.tabList.filter((item) => item.path == path)
removeOtherTab(route: RouteLocationNormalized) {
this.tabList = this.tabList.filter((item) => item.fullPath == route.fullPath)
const componentName = getComponentName(route)
this.cacheTabList.forEach((name) => {
if (componentName !== name) {
this.removeCache(name)
}
})
},
removeAllTab(router: Router) {
const { push, currentRoute } = router
const { path, name } = unref(currentRoute)
const { name } = unref(currentRoute)
if (name == this.indexRouteName) {
this.removeOtherTab(path)
this.removeOtherTab(currentRoute.value)
return
}
this.tabList = []
this.clearCache()
push(PageEnum.INDEX)
}
}

View File

@@ -32,7 +32,6 @@ const useUserStore = defineStore({
this.token = ''
this.userInfo = {}
this.perms = []
this.menu = []
},
login(playload: any) {
const { account, password } = playload
@@ -54,8 +53,9 @@ const useUserStore = defineStore({
logout() {
return new Promise((resolve, reject) => {
logout()
.then((data) => {
router.push(PageEnum.LOGIN)
.then(async (data) => {
this.token = ''
await router.push(PageEnum.LOGIN)
clearAuthInfo()
resolve(data)
})

View File

@@ -91,7 +91,7 @@
--el-messagebox-width: 350px;
}
.el-date-editor {
--el-date-editor-width: 235px;
--el-date-editor-width: 280px;
.el-range-input {
font-size: var(--el-font-size-small);
}
@@ -115,6 +115,9 @@
.el-image__error {
font-size: 12px;
}
.el-tabs__nav-wrap::after {
height: 1px;
}
}
@media (max-width: 768px) {
.el-pagination > .el-pagination__jump {

View File

@@ -12,7 +12,7 @@ export function clearAuthInfo() {
const userStore = useUserStore()
const tabsStore = useTabsStore()
userStore.resetState()
tabsStore.resetState()
tabsStore.$reset()
cache.remove(TOKEN_KEY)
resetRouter()
}

View File

@@ -71,11 +71,10 @@ export class Axios {
this.removeCancelToken(err.config?.url!)
}
if (err.code == AxiosError.ECONNABORTED) {
setTimeout(() => {
console.log(err)
if (err.code == AxiosError.ECONNABORTED || err.code == AxiosError.ERR_NETWORK) {
return new Promise((resolve) => setTimeout(resolve, 500)).then(() =>
this.retryRequest(err)
}, 500)
)
}
return Promise.reject(err)
}
@@ -103,17 +102,17 @@ export class Axios {
retryRequest(error: AxiosError) {
const config = error.config
const { retryCount, isOpenRetry } = config.requestOptions
if (!isOpenRetry && config.method?.toUpperCase() == RequestMethodsEnum.POST) {
return
if (!isOpenRetry || config.method?.toUpperCase() == RequestMethodsEnum.POST) {
return Promise.reject(error)
}
config.retryCount = config.retryCount ?? 0
if (config.retryCount >= retryCount) {
return
return Promise.reject(error)
}
config.retryCount++
this.axiosInstance.request(config)
return this.axiosInstance.request(config)
}
/**
* @description get请求

View File

@@ -160,3 +160,12 @@ export const getNonDuplicateID = (length = 8) => {
idStr += Math.random().toString(36).substring(3, length)
return idStr
}
/**
* @description 单词首字母大写
* @param { String } str
* @return { String } id
*/
export const firstToUpperCase = (str = '') => {
return str.toLowerCase().replace(/( |^)[a-z]/g, ($1) => $1.toUpperCase())
}

View File

@@ -6,7 +6,7 @@
<image-contain :src="config.webBackdrop" :width="400" height="100%" />
</div>
<div
class="login-form bg-body flex flex-col px-10 pt-10 md:w-[400px] w-[375px] flex-none mx-auto"
class="login-form bg-body flex flex-col justify-center px-10 py-10 md:w-[400px] w-[375px] flex-none mx-auto"
>
<div class="text-center text-3xl font-medium mb-8">{{ config.webName }}</div>
<el-form ref="formRef" :model="formData" size="large" :rules="rules">

View File

@@ -65,7 +65,7 @@
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="articleColumn">
import { articleCateDelete, articleCateLists, articleCateStatus } from '@/api/article'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'

View File

@@ -18,6 +18,10 @@
<el-input
v-model="formData.title"
placeholder="请输入文章标题"
type="textarea"
:autosize="{ minRows: 3, maxRows: 3 }"
maxlength="64"
show-word-limit
clearable
/>
</div>
@@ -42,6 +46,10 @@
<el-input
v-model="formData.intro"
placeholder="请输入文章简介"
type="textarea"
:autosize="{ minRows: 3, maxRows: 6 }"
:maxlength="200"
show-word-limit
clearable
/>
</div>
@@ -50,8 +58,10 @@
<div class="w-80">
<el-input
type="textarea"
:rows="6"
:autosize="{ minRows: 6, maxRows: 6 }"
v-model="formData.summary"
maxlength="200"
show-word-limit
clearable
/>
</div>
@@ -101,11 +111,12 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="articleListsEdit">
import type { FormInstance } from 'element-plus'
import feedback from '@/utils/feedback'
import { useDictOptions } from '@/hooks/useDictOptions'
import { articleCateAll, articleDetail, articleEdit, articleAdd } from '@/api/article'
import useMultipleTabs from '@/hooks/useMultipleTabs'
const route = useRoute()
const router = useRouter()
@@ -123,6 +134,7 @@ const formData = reactive({
summary: ''
})
const { removeTab } = useMultipleTabs()
const formRef = shallowRef<FormInstance>()
const rules = reactive({
title: [{ required: true, message: '请输入文章标题', trigger: 'blur' }],
@@ -155,6 +167,7 @@ const handleSave = async () => {
await articleAdd(formData)
}
feedback.msgSuccess('操作成功')
removeTab()
router.back()
}

View File

@@ -4,14 +4,14 @@
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
<el-form-item label="文章标题">
<el-input
class="w-56"
class="w-[280px]"
v-model="queryParams.title"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="栏目名称">
<el-select class="w-56" v-model="queryParams.cid">
<el-select class="w-[280px]" v-model="queryParams.cid">
<el-option label="全部" value />
<el-option
v-for="item in optionsData.articleCate"
@@ -22,7 +22,7 @@
</el-select>
</el-form-item>
<el-form-item label="文章状态">
<el-select class="w-56" v-model="queryParams.isShow">
<el-select class="w-[280px]" v-model="queryParams.isShow">
<el-option label="全部" value />
<el-option label="显示" :value="1" />
<el-option label="隐藏" :value="0" />
@@ -37,9 +37,9 @@
<el-card class="!border-none mt-4" shadow="never">
<div>
<router-link
v-perms="['article:add']"
v-perms="['article:add', 'article:add/edit']"
:to="{
path: getRoutePath('article:edit')
path: getRoutePath('article:add/edit')
}"
>
<el-button type="primary" class="mb-4">
@@ -54,10 +54,11 @@
<el-table-column label="ID" prop="id" min-width="80" />
<el-table-column label="封面" min-width="100">
<template #default="{ row }">
<el-image
<image-contain
v-if="row.image"
:src="row.image"
class="w-[60px] h-[45px]"
:width="60"
:height="45"
:preview-src-list="[row.image]"
preview-teleported
fit="contain"
@@ -88,10 +89,10 @@
<el-table-column label="发布时间" prop="createTime" min-width="120" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button v-perms="['article:edit']" type="primary" link>
<el-button v-perms="['article:edit','article:add/edit']" type="primary" link>
<router-link
:to="{
path: getRoutePath('article:edit'),
path: getRoutePath('article:add/edit'),
query: {
id: row.id
}
@@ -117,7 +118,7 @@
</el-card>
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="articleLists">
import { articleLists, articleDelete, articleStatus, articleCateAll } from '@/api/article'
import { useDictOptions } from '@/hooks/useDictOptions'
import { usePaging } from '@/hooks/usePaging'
@@ -159,5 +160,9 @@ const handleDelete = async (id: number) => {
getLists()
}
onActivated(() => {
getLists()
})
getLists()
</script>

View File

@@ -32,7 +32,7 @@
</footer-btns>
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="h5Config">
import { getH5Config, setH5Config } from '@/api/channel/h5'
import feedback from '@/utils/feedback'

View File

@@ -140,7 +140,7 @@
</footer-btns>
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="weappConfig">
import { getWeappConfig, setWeappConfig } from '@/api/channel/weapp'
import feedback from '@/utils/feedback'

View File

@@ -35,7 +35,7 @@
</footer-btns>
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="wxDevConfig">
import { getWxDevConfig, setWxDevConfig } from '@/api/channel/wx_dev'
import feedback from '@/utils/feedback'

View File

@@ -156,7 +156,7 @@
</footer-btns>
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="wxOaConfig">
import { getOaConfig, setOaConfig } from '@/api/channel/wx_oa'
import feedback from '@/utils/feedback'
import { useClipboard } from '@vueuse/core'

View File

@@ -1,4 +1,4 @@
<script setup lang="ts">
<script setup lang="ts" name="wxOaMenu">
import OaPhone from './menu_com/oa-phone.vue'
import OaAttr from './menu_com/oa-attr.vue'
import { useMenuOa } from './menu_com/useMenuOa'

View File

@@ -10,24 +10,30 @@
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div>
<el-button class="mb-4" type="primary" @click="handleAdd()">
<el-button
v-perms="['channel:oaReplyDefault:add']"
class="mb-4"
type="primary"
@click="handleAdd()"
>
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
</div>
<el-table size="large" :data="lists">
<el-table size="large" :data="pager.lists" v-loading="pager.loading">
<el-table-column label="规则名称" prop="name" min-width="120" />
<el-table-column label="回复类型" min-width="120">
<template #default="{ row }">
{{ getContentType(1) }}
{{ getContentType(row.contentType) }}
</template>
</el-table-column>
<el-table-column label="回复内容" prop="content" min-width="120" />
<el-table-column label="状态" min-width="120">
<template #default="{ row }">
<el-switch
v-perms="['channel:oaReplyDefault:status']"
v-model="row.status"
:active-value="1"
:inactive-value="0"
@@ -38,25 +44,40 @@
<el-table-column label="排序" prop="sort" min-width="120" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)"> 编辑 </el-button>
<el-button type="danger" link @click="handleDelete(row.id)">
<el-button
v-perms="['channel:oaReplyDefault:edit']"
type="primary"
link
@click="handleEdit(row)"
>
编辑
</el-button>
<el-button
v-perms="['channel:oaReplyDefault:del']"
type="danger"
link
@click="handleDelete(row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup>
import { oaReplyDel, getOaReplyList, changeOaReplyStatus } from '@/api/channel/wx_oa'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const showEdit = ref(false)
const lists = ref()
const type = 'default'
const getContentType = computed(() => {
return (val: number) => {
switch (val) {
@@ -66,33 +87,36 @@ const getContentType = computed(() => {
}
})
const getLists = async () => {
lists.value = await getOaReplyList({ type: 'default' })
}
const { pager, getLists } = usePaging({
fetchFun: getOaReplyList,
params: {
type
}
})
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add', 'default')
editRef.value?.open('add', type)
}
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit', 'default')
editRef.value?.open('edit', type)
editRef.value?.getDetail(data)
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await oaReplyDel({ id })
await oaReplyDel({ id, type })
feedback.msgSuccess('删除成功')
getLists()
}
const changeStatus = async (id: number) => {
try {
await changeOaReplyStatus({ id })
await changeOaReplyStatus({ id, type })
feedback.msgSuccess('修改成功')
getLists()
} catch (error) {

View File

@@ -56,6 +56,8 @@
v-model="formData.content"
:autosize="{ minRows: 4, maxRows: 4 }"
type="textarea"
maxlength="200"
show-word-limit
placeholder="请输入回复内容"
/>
</div>
@@ -70,7 +72,7 @@
</el-form-item> -->
<el-form-item label="排序">
<div class="flex-1">
<el-input v-model="formData.sort" placeholder="请输入" />
<el-input-number v-model="formData.sort" :min="0"/>
</div>
</el-form-item>
<el-form-item label="启用状态">
@@ -170,7 +172,8 @@ const setFormData = (data: Record<any, any>) => {
const getDetail = async (row: Record<string, any>) => {
const data = await getOaReplyDetail({
id: row.id
id: row.id,
type: formData.type
})
setFormData(data)
}

View File

@@ -10,14 +10,19 @@
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div>
<el-button class="mb-4" type="primary" @click="handleAdd()">
<el-button
v-perms="['channel:oaReplyFollow:add']"
class="mb-4"
type="primary"
@click="handleAdd()"
>
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
</div>
<el-table size="large" :data="lists">
<el-table size="large" :data="pager.lists" v-loading="pager.loading">
<el-table-column label="规则名称" prop="name" min-width="120" />
<el-table-column label="回复类型" min-width="120">
<template #default="{ row }">
@@ -28,6 +33,7 @@
<el-table-column label="状态" min-width="120">
<template #default="{ row }">
<el-switch
v-perms="['channel:oaReplyFollow:status']"
v-model="row.status"
:active-value="1"
:inactive-value="0"
@@ -38,25 +44,41 @@
<el-table-column label="排序" prop="sort" min-width="120" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)"> 编辑 </el-button>
<el-button type="danger" link @click="handleDelete(row.id)">
<el-button
v-perms="['channel:oaReplyFollow:edit']"
type="primary"
link
@click="handleEdit(row)"
>
编辑
</el-button>
<el-button
v-perms="['channel:oaReplyFollow:del']"
type="danger"
link
@click="handleDelete(row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup>
import { oaReplyDel, getOaReplyList, changeOaReplyStatus } from '@/api/channel/wx_oa'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const showEdit = ref(false)
const lists = ref()
const type = 'follow'
const getContentType = computed(() => {
return (val: number) => {
switch (val) {
@@ -66,33 +88,36 @@ const getContentType = computed(() => {
}
})
const getLists = async () => {
lists.value = await getOaReplyList({ type: 'follow' })
}
const { pager, getLists } = usePaging({
fetchFun: getOaReplyList,
params: {
type
}
})
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add', 'follow')
editRef.value?.open('add', type)
}
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit', 'follow')
editRef.value?.open('edit', type)
editRef.value?.getDetail(data)
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await oaReplyDel({ id })
await oaReplyDel({ id, type })
feedback.msgSuccess('删除成功')
getLists()
}
const changeStatus = async (id: number) => {
try {
await changeOaReplyStatus({ id })
await changeOaReplyStatus({ id, type })
feedback.msgSuccess('修改成功')
getLists()
} catch (error) {

View File

@@ -10,14 +10,19 @@
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div>
<el-button class="mb-4" type="primary" @click="handleAdd()">
<el-button
v-perms="['channel:oaReplyKeyword:add']"
class="mb-4"
type="primary"
@click="handleAdd()"
>
<template #icon>
<icon name="el-icon-Plus" />
</template>
新增
</el-button>
</div>
<el-table size="large" :data="lists">
<el-table size="large" :data="pager.lists" v-loading="pager.loading">
<el-table-column label="规则名称" prop="name" min-width="120" />
<el-table-column label="关键词" prop="keyword" min-width="120" />
@@ -34,6 +39,7 @@
<el-table-column label="状态" min-width="120">
<template #default="{ row }">
<el-switch
v-perms="['channel:oaReplyKeyword:status']"
v-model="row.status"
:active-value="1"
:inactive-value="0"
@@ -44,24 +50,39 @@
<el-table-column label="排序" prop="sort" min-width="120" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
<el-button type="primary" link @click="handleEdit(row)"> 编辑 </el-button>
<el-button type="danger" link @click="handleDelete(row.id)">
<el-button
v-perms="['channel:oaReplyKeyword:edit']"
type="primary"
link
@click="handleEdit(row)"
>
编辑
</el-button>
<el-button
v-perms="['channel:oaReplyKeyword:del']"
type="danger"
link
@click="handleDelete(row.id)"
>
删除
</el-button>
</template>
</el-table-column>
</el-table>
<div class="flex justify-end mt-4">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup>
import { oaReplyDel, getOaReplyList, changeOaReplyStatus } from '@/api/channel/wx_oa'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()
const showEdit = ref(false)
const lists = ref()
const getMatchingType = computed(() => {
return (val: number) => {
@@ -82,34 +103,37 @@ const getContentType = computed(() => {
}
}
})
const getLists = async () => {
lists.value = await getOaReplyList({ type: 'keyword' })
}
const type = 'keyword'
const { pager, getLists } = usePaging({
fetchFun: getOaReplyList,
params: {
type
}
})
const handleAdd = async () => {
showEdit.value = true
await nextTick()
editRef.value?.open('add', 'keyword')
editRef.value?.open('add', type)
}
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()
editRef.value?.open('edit', 'keyword')
editRef.value?.open('edit', type)
editRef.value?.getDetail(data)
}
const handleDelete = async (id: number) => {
await feedback.confirm('确定要删除?')
await oaReplyDel({ id })
await oaReplyDel({ id, type })
feedback.msgSuccess('删除成功')
getLists()
}
const changeStatus = async (id: number) => {
try {
await changeOaReplyStatus({ id })
await changeOaReplyStatus({ id, type })
feedback.msgSuccess('修改成功')
getLists()
} catch (error) {

View File

@@ -75,7 +75,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="consumerDetail">
import type { FormInstance } from 'element-plus'
import { getUserDetail, userEdit } from '@/api/consumer'
import feedback from '@/utils/feedback'

View File

@@ -4,7 +4,7 @@
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
<el-form-item label="用户信息">
<el-input
class="w-56"
class="w-[280px]"
v-model="queryParams.keyword"
placeholder="用户编号/昵称/手机号码"
clearable
@@ -18,7 +18,7 @@
/>
</el-form-item>
<el-form-item label="注册来源">
<el-select class="w-56" v-model="queryParams.channel">
<el-select class="w-[280px]" v-model="queryParams.channel">
<el-option
v-for="(item, key) in ClientMap"
:key="key"
@@ -70,7 +70,7 @@
</el-card>
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="consumerLists">
import { usePaging } from '@/hooks/usePaging'
import { getRoutePath } from '@/router'
import { getUserList } from '@/api/consumer'
@@ -86,6 +86,9 @@ const { pager, getLists, resetPage, resetParams } = usePaging({
fetchFun: getUserList,
params: queryParams
})
onActivated(() => {
getLists()
})
getLists()
</script>

View File

@@ -12,7 +12,7 @@
</footer-btns>
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="decorationPages">
import Menu from '../component/pages/menu.vue'
import Preview from '../component/pages/preview.vue'
import AttrSetting from '../component/pages/attr-setting.vue'

View File

@@ -132,7 +132,7 @@
</footer-btns>
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="decorationTabbar">
import { getDecorateTabbar, setDecorateTabbar } from '@/api/decoration'
import feedback from '@/utils/feedback'
import Draggable from 'vuedraggable'

View File

@@ -18,6 +18,7 @@
<el-input
v-model="formData.base.tableName"
placeholder="请输入表名称"
clearable
/>
</div>
</el-form-item>
@@ -26,6 +27,7 @@
<el-input
v-model="formData.base.tableComment"
placeholder="请输入表描述"
clearable
/>
</div>
</el-form-item>
@@ -34,6 +36,7 @@
<el-input
v-model="formData.base.entityName"
placeholder="请输入实体类名称"
clearable
/>
</div>
</el-form-item>
@@ -43,6 +46,7 @@
<el-input
v-model="formData.base.authorName"
placeholder="请输入作者"
clearable
/>
</div>
</el-form-item>
@@ -50,9 +54,12 @@
<div class="w-80">
<el-input
v-model="formData.base.remarks"
class="el-input"
class="w-full"
type="textarea"
:rows="4"
:autosize="{ minRows: 4, maxRows: 4 }"
maxlength="200"
show-word-limit
clearable
/>
</div>
</el-form-item>
@@ -90,7 +97,7 @@
v-model="row.isRequired"
:true-label="1"
:false-label="0"
></el-checkbox>
/>
</template>
</el-table-column>
<el-table-column label="插入" width="80">
@@ -99,7 +106,7 @@
v-model="row.isInsert"
:true-label="1"
:false-label="0"
></el-checkbox>
/>
</template>
</el-table-column>
<el-table-column label="编辑" width="80">
@@ -108,7 +115,7 @@
v-model="row.isEdit"
:true-label="1"
:false-label="0"
></el-checkbox>
/>
</template>
</el-table-column>
<el-table-column label="列表" width="80">
@@ -117,7 +124,7 @@
v-model="row.isList"
:true-label="1"
:false-label="0"
></el-checkbox>
/>
</template>
</el-table-column>
<el-table-column label="查询" width="80">
@@ -126,7 +133,7 @@
v-model="row.isQuery"
:true-label="1"
:false-label="0"
></el-checkbox>
/>
</template>
</el-table-column>
<el-table-column label="查询方式">
@@ -196,6 +203,7 @@
<el-input
v-model="formData.gen.moduleName"
placeholder="请输入模块名"
clearable
/>
<div class="form-tips">生成文件所在模块名</div>
</div>
@@ -205,6 +213,7 @@
<el-input
v-model="formData.gen.functionName"
placeholder="请输入功能名称"
clearable
/>
</div>
</el-form-item>
@@ -223,6 +232,7 @@
<el-input
v-model="formData.gen.genPath"
placeholder="请输入自定义路径"
clearable
/>
</div>
</el-form-item>
@@ -272,14 +282,14 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="tableEdit">
import { generateEdit, tableDetail } from '@/api/tools/code'
import { dictTypeAll } from '@/api/setting/dict'
import type { FormInstance } from 'element-plus'
import feedback from '@/utils/feedback'
import { menuLists } from '@/api/perms/menu'
import { useDictOptions } from '@/hooks/useDictOptions'
import useMultipleTabs from '@/hooks/useMultipleTabs'
enum GenTpl {
CRUD = 'crud',
TREE = 'tree'
@@ -292,6 +302,7 @@ enum GenType {
const route = useRoute()
const router = useRouter()
const { removeTab } = useMultipleTabs()
const activeName = ref('column')
const formData = reactive({
base: {
@@ -363,6 +374,7 @@ const handleSave = async () => {
const { base, column, gen } = formData
await generateEdit({ ...base, ...gen, column })
feedback.msgSuccess('操作成功')
removeTab()
router.back()
} catch (error: any) {
for (const err in error) {

View File

@@ -3,10 +3,20 @@
<el-card class="!border-none" shadow="never">
<el-form class="mb-[-16px]" :model="formData" inline>
<el-form-item label="表名称">
<el-input class="w-56" v-model="formData.tableName" />
<el-input
class="w-[280px]"
v-model="formData.tableName"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="表描述">
<el-input class="w-56" v-model="formData.tableComment" />
<el-input
class="w-[280px]"
v-model="formData.tableComment"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
@@ -138,7 +148,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="codeGenerate">
import {
generateTable,
syncColumn,
@@ -228,5 +238,9 @@ const handleCommand = (command: any, row: any) => {
}
}
onActivated(() => {
getLists()
})
getLists()
</script>

View File

@@ -13,10 +13,20 @@
</template>
<el-form class="ls-form" :model="formData" inline>
<el-form-item label="表名称">
<el-input class="w-56" v-model="formData.tableName" />
<el-input
class="w-[280px]"
v-model="formData.tableName"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="表描述">
<el-input class="w-56" v-model="formData.tableComment" />
<el-input
class="w-[280px]"
v-model="formData.tableComment"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>

View File

@@ -1,10 +1,12 @@
<template>
<div class="error404">
<error
code="403"
title="您的账号权限不足,请联系管理员添加权限!"
:show-btn="false"
></error>
<error code="403" title="您的账号权限不足,请联系管理员添加权限!" :show-btn="false">
<template #content>
<div class="flex justify-center">
<img class="w-[150px] h-[150px]" src="@/assets/images/no_perms.png" alt="" />
</div>
</template>
</error>
</div>
</template>

View File

@@ -1,8 +1,10 @@
<template>
<div class="error">
<div>
<div class="error-code">{{ code }}</div>
<div class="lg lighter mt-7 mb-7">{{ title }}</div>
<slot name="content">
<div class="error-code">{{ code }}</div>
</slot>
<div class="text-lg text-tx-secondary mt-7 mb-7">{{ title }}</div>
<el-button v-if="showBtn" type="primary" @click="router.go(-1)">
{{ second }} 秒后返回上一页
</el-button>

View File

@@ -23,7 +23,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="materialCenter">
const tabsMap = [
{
type: 'image',

View File

@@ -1,7 +1,7 @@
<template>
<div>
<el-card class="!border-none" shadow="never">
<el-page-header content="编辑通知设置" @back="$router.back()" />
<el-page-header :content="$route.meta.title" @back="$router.back()" />
</el-card>
<el-form
ref="formRef"
@@ -37,16 +37,14 @@
<div class="w-full max-w-[320px]">
<el-input
type="textarea"
:rows="6"
:autosize="{ minRows: 6, maxRows: 6 }"
v-model="formData.smsNotice.content"
/>
</div>
<div class="form-tips">
可选变量 用户昵称:nickname 订单编号:order_sn 支付时间:pay_time
<br />
示例亲爱的${nickname}您的订单${order_sn}已支付成功商家正在快马加鞭为您安排发货
<br />
生效条件1管理后台完成短信设置2第三方短信平台申请模板
<div v-for="(item, index) in formData.smsNotice.tips" :key="index">
{{ item }}
</div>
</div>
</div>
</el-form-item>
@@ -58,10 +56,11 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="noticeEdit">
import type { FormInstance } from 'element-plus'
import feedback from '@/utils/feedback'
import { noticeDetail, setNoticeConfig } from '@/api/message'
import useMultipleTabs from '@/hooks/useMultipleTabs'
const route = useRoute()
const router = useRouter()
@@ -75,7 +74,8 @@ const formData = reactive({
smsNotice: {
status: 0,
templateId: '',
content: ''
content: '',
tips: []
}
})
@@ -95,7 +95,7 @@ const rules = {
}
]
}
const { removeTab } = useMultipleTabs()
const formRef = shallowRef<FormInstance>()
const getDetails = async () => {
@@ -114,6 +114,7 @@ const handleSave = async () => {
await formRef.value?.validate()
await setNoticeConfig(formData)
feedback.msgSuccess('操作成功')
removeTab()
router.back()
}

View File

@@ -47,7 +47,7 @@
</el-card>
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="notice">
import { noticeLists } from '@/api/message'
import { getRoutePath } from '@/router'
@@ -87,5 +87,9 @@ const getLists = async () => {
}
}
onActivated(() => {
getLists()
})
getLists()
</script>

View File

@@ -26,7 +26,7 @@
<edit-popup ref="editRef" @success="getLists" />
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="shortLetter">
import { smsLists } from '@/api/message'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()

View File

@@ -71,7 +71,7 @@ const formData = reactive({
})
const checkMobile = (rule: any, value: any, callback: any) => {
if (!value) {
return callback(new Error('手机号不能为空'))
return callback()
} else {
const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/
console.log(reg.test(value))

View File

@@ -4,14 +4,14 @@
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
<el-form-item label="部门名称" prop="name">
<el-input
class="w-56"
class="w-[280px]"
v-model="queryParams.name"
clearable
@keyup.enter="getLists"
/>
</el-form-item>
<el-form-item label="部门状态" prop="isStop">
<el-select class="w-56" v-model="queryParams.isStop">
<el-select class="w-[280px]" v-model="queryParams.isStop">
<el-option label="全部" value />
<el-option label="正常" value="0" />
<el-option label="停用" value="1" />
@@ -91,7 +91,7 @@
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="department">
import type { ElTable, FormInstance } from 'element-plus'
import EditPopup from './edit.vue'
import { deptDelete, deptLists } from '@/api/org/department'

View File

@@ -27,6 +27,8 @@
placeholder="请输入备注"
type="textarea"
:autosize="{ minRows: 4, maxRows: 6 }"
maxlength="200"
show-word-limit
/>
</el-form-item>
<el-form-item label="岗位状态" prop="isStop">

View File

@@ -4,7 +4,7 @@
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" :inline="true">
<el-form-item label="岗位编码">
<el-input
class="w-56"
class="w-[280px]"
v-model="queryParams.code"
clearable
@keyup.enter="resetPage"
@@ -12,14 +12,14 @@
</el-form-item>
<el-form-item label="岗位名称">
<el-input
class="w-56"
class="w-[280px]"
v-model="queryParams.name"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="岗位状态">
<el-select class="w-56" v-model="queryParams.isStop">
<el-select class="w-[280px]" v-model="queryParams.isStop">
<el-option label="全部" value />
<el-option label="正常" :value="0" />
<el-option label="停用" :value="1" />
@@ -51,7 +51,7 @@
show-overflow-tooltip
/>
<el-table-column label="添加时间" prop="createTime" min-width="180" />
<el-table-column label="部门状态" prop="isStop" min-width="100">
<el-table-column label="岗位状态" prop="isStop" min-width="100">
<template #default="{ row }">
<el-tag class="ml-2" :type="row.isStop ? 'danger' : ''">
{{ row.isStop ? '停用' : '正常' }}
@@ -86,7 +86,7 @@
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="post">
import { postDelete, postLists } from '@/api/org/post'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'

View File

@@ -5,7 +5,7 @@
<el-form-item label="管理员账号">
<el-input
v-model="formData.username"
class="w-56"
class="w-[280px]"
clearable
@keyup.enter="resetPage"
/>
@@ -13,13 +13,13 @@
<el-form-item label="管理员名称">
<el-input
v-model="formData.nickname"
class="w-56"
class="w-[280px]"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="管理员角色">
<el-select class="w-56" v-model="formData.role">
<el-select class="w-[280px]" v-model="formData.role">
<el-option label="全部" value="" />
<el-option
v-for="(item, index) in optionsData.role"
@@ -100,7 +100,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="admin">
import { adminLists, adminDelete, adminStatus } from '@/api/perms/admin'
import { roleAll } from '@/api/perms/role'
import { useDictOptions } from '@/hooks/useDictOptions'

View File

@@ -73,7 +73,11 @@
</div>
</div>
</el-form-item>
<el-form-item label="选中菜单" prop="p" v-if="formData.menuType == MenuEnum.MENU">
<el-form-item
label="选中菜单"
prop="selected"
v-if="formData.menuType == MenuEnum.MENU"
>
<div class="flex-1">
<el-input
v-model="formData.selected"
@@ -116,20 +120,20 @@
</div>
</div>
</el-form-item>
<!-- <el-form-item
v-if="formData.menuType == MenuEnum.MENU"
label="是否缓存"
prop="isCache"
required
>
<div>
<el-radio-group v-model="formData.isCache">
<el-radio :label="1">缓存</el-radio>
<el-radio :label="0">不缓存</el-radio>
</el-radio-group>
<div class="form-tips">选择缓存则会被`keep-alive`缓存</div>
</div>
</el-form-item> -->
<el-form-item
v-if="formData.menuType == MenuEnum.MENU"
label="是否缓存"
prop="isCache"
required
>
<div>
<el-radio-group v-model="formData.isCache">
<el-radio :label="1">缓存</el-radio>
<el-radio :label="0">不缓存</el-radio>
</el-radio-group>
<div class="form-tips">选择缓存则会被`keep-alive`缓存</div>
</div>
</el-form-item>
<el-form-item
v-if="formData.menuType != MenuEnum.BUTTON"
label="是否显示"
@@ -220,7 +224,7 @@ const formData = reactive({
//路由参数
params: '',
//是否缓存 0=否, 1=是
isCache: 0,
isCache: 1,
//是否显示 0=否, 1=是
isShow: 1,
//是否禁用 0=否, 1=是
@@ -259,15 +263,12 @@ const formRules = {
}
const menuOptions = ref<any[]>([])
const pageOptions = ref<any[]>([])
const getMenu = async () => {
const data: any = await menuLists()
const menu = { id: 0, menuName: '顶级', children: [] }
pageOptions.value = arrayToTree(
const menu: any = { id: 0, menuName: '顶级', children: [] }
menu.children = arrayToTree(
treeToArray(data).filter((item) => item.menuType != MenuEnum.BUTTON)
)
menu.children = data
menuOptions.value.push(menu)
}

View File

@@ -90,7 +90,7 @@
<edit-popup v-if="showEdit" ref="editRef" @success="getLists" @close="showEdit = false" />
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="menu">
import { menuDelete, menuLists } from '@/api/perms/menu'
import type { ElTable } from 'element-plus'
import { MenuEnum } from '@/enums/appEnums'

View File

@@ -27,8 +27,10 @@
<el-input
v-model="formData.remark"
type="textarea"
:rows="4"
:autosize="{ minRows: 4, maxRows: 6 }"
placeholder="请输入备注"
maxlength="200"
show-word-limit
/>
</el-form-item>
<el-form-item label="排序" prop="sort">

View File

@@ -63,7 +63,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="role">
import { roleLists, roleDelete } from '@/api/perms/role'
import { usePaging } from '@/hooks/usePaging'
import feedback from '@/utils/feedback'

View File

@@ -31,7 +31,7 @@
</el-form-item>
<el-form-item label="排序" prop="sort">
<div>
<el-input-number v-model="formData.sort" />
<el-input-number v-model="formData.sort" :min="0" />
<div class="form-tips">数值越大越排前</div>
</div>
</el-form-item>
@@ -42,7 +42,14 @@
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" type="textarea" rows="4" clearable />
<el-input
v-model="formData.remark"
type="textarea"
:autosize="{ minRows: 4, maxRows: 6 }"
clearable
maxlength="200"
show-word-limit
/>
</el-form-item>
</el-form>
</popup>

View File

@@ -4,7 +4,7 @@
<el-page-header class="mb-4" content="数据管理" @back="$router.back()" />
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="字典名称">
<el-select class="w-56" v-model="queryParams.dictType" @change="getLists">
<el-select class="w-[280px]" v-model="queryParams.dictType" @change="getLists">
<el-option
v-for="item in optionsData.dictType"
:label="item.dictName"
@@ -15,14 +15,14 @@
</el-form-item>
<el-form-item label="数据名称">
<el-input
class="w-56"
class="w-[280px]"
v-model="queryParams.name"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="数据状态">
<el-select class="w-56" v-model="queryParams.status">
<el-select class="w-[280px]" v-model="queryParams.status">
<el-option label="全部" value />
<el-option label="正常" :value="1" />
<el-option label="停用" :value="0" />
@@ -71,7 +71,12 @@
<el-tag v-else type="danger">停用</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" prop="remark" min-width="120" />
<el-table-column
label="备注"
prop="remark"
min-width="120"
show-tooltip-when-overflow
/>
<el-table-column label="排序" prop="sort" />
<el-table-column label="操作" width="120" fixed="right">
<template #default="{ row }">
@@ -104,7 +109,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="dictData">
import { dictDataDelete, dictDataLists, dictTypeAll } from '@/api/setting/dict'
import { useDictOptions } from '@/hooks/useDictOptions'
import { usePaging } from '@/hooks/usePaging'

View File

@@ -28,7 +28,14 @@
</el-radio-group>
</el-form-item>
<el-form-item label="备注" prop="dictRemark">
<el-input v-model="formData.dictRemark" type="textarea" rows="4" clearable />
<el-input
v-model="formData.dictRemark"
type="textarea"
:autosize="{ minRows: 4, maxRows: 6 }"
clearable
maxlength="200"
show-word-limit
/>
</el-form-item>
</el-form>
</popup>

View File

@@ -4,7 +4,7 @@
<el-form ref="formRef" class="mb-[-16px]" :model="queryParams" inline>
<el-form-item label="字典名称">
<el-input
class="w-56"
class="w-[280px]"
v-model="queryParams.dictName"
clearable
@keyup.enter="resetPage"
@@ -12,14 +12,14 @@
</el-form-item>
<el-form-item label="字典类型">
<el-input
class="w-56"
class="w-[280px]"
v-model="queryParams.dictType"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="状态">
<el-select class="w-56" v-model="queryParams.dictStatus">
<el-select class="w-[280px]" v-model="queryParams.dictStatus">
<el-option label="全部" value />
<el-option label="正常" :value="1" />
<el-option label="停用" :value="0" />
@@ -68,7 +68,11 @@
<el-tag v-else type="danger">停用</el-tag>
</template>
</el-table-column>
<el-table-column label="备注" prop="dictRemark" />
<el-table-column
label="备注"
prop="dictRemark"
show-tooltip-when-overflow
/>
<el-table-column label="创建时间" prop="createTime" min-width="180" />
<el-table-column label="操作" width="190" fixed="right">
<template #default="{ row }">
@@ -80,20 +84,17 @@
>
编辑
</el-button>
<el-button
v-perms="['setting:dict:data:list']"
type="primary"
link
@click="
$router.push({
<el-button v-perms="['setting:dict:data:list']" type="primary" link>
<router-link
:to="{
path: getRoutePath('setting:dict:data:list'),
query: {
type: row.dictType
}
})
"
>
数据管理
}"
>
数据管理
</router-link>
</el-button>
<el-button
v-perms="['setting:dict:type:del']"
@@ -116,7 +117,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="dictType">
import { dictTypeDelete, dictTypeLists } from '@/api/setting/dict'
import { usePaging } from '@/hooks/usePaging'
import { getRoutePath } from '@/router'

View File

@@ -9,30 +9,36 @@
<el-radio :label="0">关闭</el-radio>
</el-radio-group>
<div class="form-tips">默认开关闭则前端不显示该功能</div>
<div class="form-tips">默认开关闭则前端不显示该功能</div>
</div>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none mt-4" shadow="never">
<div class="flex">
<div class="flex-1 w-3/5">
<el-button type="primary" class="mb-4" @click="handleAdd">添加</el-button>
<div class="lg:flex">
<div class="flex-1 min-w-0">
<el-button type="primary" class="mb-4" @click="handleAdd">
<template #icon>
<icon name="el-icon-Plus" />
</template>
添加
</el-button>
<el-table size="large" :data="formData.list">
<el-table-column label="ID" prop="id" width="120">
<template #default="{ $index }">
{{ $index }}
<el-table-column label="关键词" prop="describe" min-width="200">
<template #default="{ row }">
<el-input
v-model.trim="row.name"
clearable
placeholder="请输入关键字"
show-word-limit
maxlength="30"
/>
</template>
</el-table-column>
<el-table-column label="关键词" prop="describe" min-width="160">
<el-table-column label="排序" prop="describe" min-width="80">
<template #default="{ row }">
<el-input v-model="row.name" clearable />
</template>
</el-table-column>
<el-table-column label="排序" prop="describe" min-width="160">
<template #default="{ row }">
<el-input v-model="row.sort" type="number" />
<el-input v-model="row.sort" type="number" clearable />
</template>
</el-table-column>
<el-table-column label="操作" min-width="80" fixed="right">
@@ -50,8 +56,8 @@
</el-table>
</div>
<div class="w-2/5 hot-search-phone">
<span class="mb-4">- 热搜预览图 -</span>
<div class="flex-none hot-search-phone mt-4 lg:mt-0 lg:ml-4">
<div class="mb-4 text-center">- 热搜预览图 -</div>
<div class="hot-search-phone-content">
<!-- 搜索框 -->
<div class="search-com">
@@ -63,7 +69,12 @@
<!-- 热门搜索 -->
<div class="hot-search-title">热门搜索</div>
<div class="hot-search-text">
<span v-for="(text, index) in list" :key="index">{{ text.name }}</span>
<span
class="truncate max-w-full"
v-for="(text, index) in list"
:key="index"
>{{ text.name }}</span
>
</div>
</div>
</div>
@@ -76,7 +87,7 @@
</div>
</template>
<script setup lang="ts">
<script setup lang="ts" name="search">
import { getSearch, setSearch } from '@/api/setting/search'
import type { Search } from '@/api/setting/search'
import feedback from '@/utils/feedback'
@@ -87,7 +98,7 @@ const formData = reactive<Search>({
})
const list = computed(() => {
return [...formData.list].sort((v1, v2) => v2.sort - v1.sort)
return formData.list.filter((item) => item.name).sort((v1, v2) => v2.sort - v1.sort)
})
// 获取登录注册数据
@@ -105,7 +116,7 @@ const getData = async () => {
const handleAdd = () => {
formData.list.push({
name: '关键字',
name: '',
sort: 0
})
}
@@ -130,12 +141,10 @@ getData()
<style lang="scss" scoped>
.hot-search {
.hot-search-phone {
margin-left: 20px;
@apply flex flex-col items-center;
width: 300px;
&-content {
width: 280px;
height: 494px;
width: 100%;
height: 530px;
padding: 12px 12px;
border-radius: 10px;
border: 1px solid #e6e6e6;

View File

@@ -35,7 +35,7 @@
<edit-popup ref="editRef" @success="getLists" />
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="storage">
import { storageLists } from '@/api/setting/storage'
import EditPopup from './edit.vue'
const editRef = shallowRef<InstanceType<typeof EditPopup>>()

View File

@@ -136,7 +136,7 @@
</div>
</template>
<script setup lang="ts">
<script setup lang="ts" name="cache">
import { systemCache } from '@/api/setting/system'
import vCharts from 'vue-echarts'
import { reactive } from 'vue'

View File

@@ -113,7 +113,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="environment">
import { systemInfo } from '@/api/setting/system'
const loading = ref(false)
const info = ref({

View File

@@ -4,22 +4,34 @@
<el-card class="!border-none" shadow="never">
<el-form class="ls-form" :model="formData" inline>
<el-form-item label="管理员">
<el-input class="w-56" placeholder="请输入" v-model="formData.username" />
<el-input
class="w-[280px]"
placeholder="请输入"
v-model="formData.username"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="访问方式">
<el-select class="w-56" v-model="formData.type" placeholder="请选择">
<el-select class="w-[280px]" v-model="formData.type" placeholder="请选择">
<el-option
v-for="(item, index) in visitType"
:key="index"
:label="item.label"
:value="item.value"
></el-option>
/>
</el-select>
</el-form-item>
<el-form-item label="来源IP">
<el-input class="w-56" placeholder="请输入" v-model="formData.ip" />
<el-input
class="w-[280px]"
placeholder="请输入"
v-model="formData.ip"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="访问时间">
@@ -30,7 +42,13 @@
</el-form-item>
<el-form-item label="访问链接">
<el-input class="w-56" placeholder="请输入" v-model="formData.url" />
<el-input
class="w-[280px]"
placeholder="请输入"
v-model="formData.url"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item>
@@ -61,7 +79,7 @@
</div>
</template>
<script setup lang="ts">
<script setup lang="ts" name="journal">
import { systemLogLists } from '@/api/setting/system'
import { usePaging } from '@/hooks/usePaging'

View File

@@ -98,7 +98,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="loginRegister">
import type { LoginSetup } from '@/api/setting/user'
import { getLogin, setLogin } from '@/api/setting/user'
import feedback from '@/utils/feedback'

View File

@@ -25,7 +25,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="userSetup">
import { getUserSetup, setUserSetup } from '@/api/setting/user'
import feedback from '@/utils/feedback'
// import type { FormInstance } from 'element-plus'

View File

@@ -50,7 +50,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="webFilling">
import { getCopyright, setCopyright } from '@/api/setting/website'
import feedback from '@/utils/feedback'
// 表单数据

View File

@@ -59,7 +59,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="webInformation">
import { getWebsite, setWebsite } from '@/api/setting/website'
import useAppStore from '@/stores/modules/app'
import feedback from '@/utils/feedback'

View File

@@ -30,7 +30,7 @@
</footer-btns>
</template>
<script setup lang="ts">
<script setup lang="ts" naem="webProtocol">
import { getProtocol, setProtocol } from '@/api/setting/website'
import feedback from '@/utils/feedback'

View File

@@ -65,7 +65,7 @@
</div>
</template>
<script setup lang="ts">
<script setup lang="ts" name="userSetting">
import { setUserInfo } from '@/api/user'
import useUserStore from '@/stores/modules/user'
import feedback from '@/utils/feedback'

View File

@@ -130,7 +130,7 @@
</div>
</template>
<script lang="ts" setup>
<script lang="ts" setup name="workbench">
import { getWorkbench } from '@/api/app'
import vCharts from 'vue-echarts'
import menu_admin from './image/menu_admin.png'

View File

@@ -9,5 +9,6 @@ declare module 'vue-router' {
hidden?: boolean
activeMenu?: string
hideTab?: boolean
keepAlive?: boolean
}
}

View File

@@ -8,7 +8,7 @@ import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
// https://vitejs.dev/config/
export default defineConfig({
// base: '/admin/',
@@ -36,7 +36,8 @@ export default defineConfig({
// 配置路劲在你的src里的svg存放文件
iconDirs: [fileURLToPath(new URL('./src/assets/icons', import.meta.url))],
symbolId: 'local-icon-[dir]-[name]'
})
}),
vueSetupExtend()
],
resolve: {
alias: {

View File

@@ -692,6 +692,16 @@
estree-walker "^2.0.2"
source-map "^0.6.1"
"@vue/compiler-core@3.2.39":
version "3.2.39"
resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.2.39.tgz#0d77e635f4bdb918326669155a2dc977c053943e"
integrity sha512-mf/36OWXqWn0wsC40nwRRGheR/qoID+lZXbIuLnr4/AngM0ov8Xvv8GHunC0rKRIkh60bTqydlqTeBo49rlbqw==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/shared" "3.2.39"
estree-walker "^2.0.2"
source-map "^0.6.1"
"@vue/compiler-dom@3.2.37", "@vue/compiler-dom@^3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz#10d2427a789e7c707c872da9d678c82a0c6582b5"
@@ -700,6 +710,14 @@
"@vue/compiler-core" "3.2.37"
"@vue/shared" "3.2.37"
"@vue/compiler-dom@3.2.39":
version "3.2.39"
resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.39.tgz#bd69d35c1a48fe2cea4ab9e96d2a3a735d146fdf"
integrity sha512-HMFI25Be1C8vLEEv1hgEO1dWwG9QQ8LTTPmCkblVJY/O3OvWx6r1+zsox5mKPMGvqYEZa6l8j+xgOfUspgo7hw==
dependencies:
"@vue/compiler-core" "3.2.39"
"@vue/shared" "3.2.39"
"@vue/compiler-sfc@3.2.37", "@vue/compiler-sfc@^3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz#3103af3da2f40286edcd85ea495dcb35bc7f5ff4"
@@ -716,6 +734,22 @@
postcss "^8.1.10"
source-map "^0.6.1"
"@vue/compiler-sfc@^3.2.29":
version "3.2.39"
resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.39.tgz#8fe29990f672805b7c5a2ecfa5b05e681c862ea2"
integrity sha512-fqAQgFs1/BxTUZkd0Vakn3teKUt//J3c420BgnYgEOoVdTwYpBTSXCMJ88GOBCylmUBbtquGPli9tVs7LzsWIA==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/compiler-core" "3.2.39"
"@vue/compiler-dom" "3.2.39"
"@vue/compiler-ssr" "3.2.39"
"@vue/reactivity-transform" "3.2.39"
"@vue/shared" "3.2.39"
estree-walker "^2.0.2"
magic-string "^0.25.7"
postcss "^8.1.10"
source-map "^0.6.1"
"@vue/compiler-ssr@3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz#4899d19f3a5fafd61524a9d1aee8eb0505313cff"
@@ -724,6 +758,14 @@
"@vue/compiler-dom" "3.2.37"
"@vue/shared" "3.2.37"
"@vue/compiler-ssr@3.2.39":
version "3.2.39"
resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.39.tgz#4f3bfb535cb98b764bee45e078700e03ccc60633"
integrity sha512-EoGCJ6lincKOZGW+0Ky4WOKsSmqL7hp1ZYgen8M7u/mlvvEQUaO9tKKOy7K43M9U2aA3tPv0TuYYQFrEbK2eFQ==
dependencies:
"@vue/compiler-dom" "3.2.39"
"@vue/shared" "3.2.39"
"@vue/devtools-api@^6.1.4", "@vue/devtools-api@^6.2.1":
version "6.2.1"
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz#6f2948ff002ec46df01420dfeff91de16c5b4092"
@@ -757,6 +799,17 @@
estree-walker "^2.0.2"
magic-string "^0.25.7"
"@vue/reactivity-transform@3.2.39":
version "3.2.39"
resolved "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.2.39.tgz#da6ae6c8fd77791b9ae21976720d116591e1c4aa"
integrity sha512-HGuWu864zStiWs9wBC6JYOP1E00UjMdDWIG5W+FpUx28hV3uz9ODOKVNm/vdOy/Pvzg8+OcANxAVC85WFBbl3A==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/compiler-core" "3.2.39"
"@vue/shared" "3.2.39"
estree-walker "^2.0.2"
magic-string "^0.25.7"
"@vue/reactivity@3.2.37", "@vue/reactivity@^3.2.37":
version "3.2.37"
resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.2.37.tgz#5bc3847ac58828e2b78526e08219e0a1089f8848"
@@ -794,6 +847,11 @@
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.37.tgz#8e6adc3f2759af52f0e85863dfb0b711ecc5c702"
integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw==
"@vue/shared@3.2.39":
version "3.2.39"
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.39.tgz#302df167559a1a5156da162d8cc6760cef67f8e3"
integrity sha512-D3dl2ZB9qE6mTuWPk9RlhDeP1dgNRUKC3NJxji74A4yL8M2MwlhLKUC/49WHjrNzSPug58fWx/yFbaTzGAQSBw==
"@vue/tsconfig@^0.1.3":
version "0.1.3"
resolved "https://registry.npmmirror.com/@vue/tsconfig/-/tsconfig-0.1.3.tgz#4a61dbd29783d01ddab504276dcf0c2b6988654f"
@@ -4159,6 +4217,14 @@ vite-plugin-svg-icons@^2.0.1:
svg-baker "1.7.0"
svgo "^2.8.0"
vite-plugin-vue-setup-extend@^0.4.0:
version "0.4.0"
resolved "https://registry.npmmirror.com/vite-plugin-vue-setup-extend/-/vite-plugin-vue-setup-extend-0.4.0.tgz#ebbbe265320039b8c6a3b9fcae3b8d152ecf4a13"
integrity sha512-WMbjPCui75fboFoUTHhdbXzu4Y/bJMv5N9QT9a7do3wNMNHHqrk+Tn2jrSJU0LS5fGl/EG+FEDBYVUeWIkDqXQ==
dependencies:
"@vue/compiler-sfc" "^3.2.29"
magic-string "^0.25.7"
vite@^3.0.0:
version "3.0.8"
resolved "https://registry.npmmirror.com/vite/-/vite-3.0.8.tgz#aa095ad8e3e5da46d9ec7e878f262678965d6531"

View File

@@ -1,3 +0,0 @@
# 请求域名
VITE_APP_BASE_URL='https://likeadmin-java-api.yixiangonline.com'

View File

@@ -0,0 +1 @@
import o from"./error.2b025df1.js";import{d as r,o as i,c as p,V as m,M as e,a as t}from"./@vue.cab01781.js";import"./element-plus.8115766e.js";import"./@vueuse.724ed0af.js";import"./@element-plus.92b4185f.js";import"./lodash-es.29c53eac.js";import"./dayjs.66926594.js";import"./axios.2d915936.js";import"./async-validator.fb49d0f5.js";import"./@ctrl.82a509e0.js";import"./@popperjs.36402333.js";import"./escape-html.e5dfadb9.js";import"./normalize-wheel-es.8aeb3683.js";import"./vue-router.5046cc50.js";import"./index.53063276.js";import"./lodash.b68d77aa.js";import"./pinia.e85e8286.js";import"./vue-demi.bfae2336.js";import"./css-color-function.a8f9466d.js";import"./color.903ca10f.js";import"./clone.9d64bb7a.js";import"./color-convert.69e17089.js";import"./color-string.e356f5de.js";import"./color-name.e7a4e1d3.js";import"./nprogress.a96d99f2.js";import"./vue-clipboard3.91d4fd5f.js";import"./clipboard.c0a70c0c.js";import"./echarts.6ad8c478.js";import"./zrender.f91f2f01.js";import"./highlight.js.4ebdf9a4.js";import"./@highlightjs.0ab41b7b.js";const s="/assets/no_perms.a56e95a5.png",u={class:"error404"},a=t("div",{class:"flex justify-center"},[t("img",{class:"w-[150px] h-[150px]",src:s,alt:""})],-1),Q=r({__name:"403",setup(c){return(n,_)=>(i(),p("div",u,[m(o,{code:"403",title:"\u60A8\u7684\u8D26\u53F7\u6743\u9650\u4E0D\u8DB3\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650\uFF01","show-btn":!1},{content:e(()=>[a]),_:1})]))}});export{Q as default};

View File

@@ -1 +0,0 @@
import o from"./error.1294af0d.js";import{d as r,o as t,c as m,V as p}from"./@vue.cab01781.js";import"./element-plus.374f5afd.js";import"./@vueuse.724ed0af.js";import"./@element-plus.92b4185f.js";import"./lodash-es.29c53eac.js";import"./dayjs.66926594.js";import"./axios.2d915936.js";import"./async-validator.fb49d0f5.js";import"./@ctrl.82a509e0.js";import"./@popperjs.36402333.js";import"./escape-html.e5dfadb9.js";import"./normalize-wheel-es.8aeb3683.js";import"./vue-router.5046cc50.js";import"./index.66650ce1.js";import"./lodash.b68d77aa.js";import"./pinia.e85e8286.js";import"./vue-demi.bfae2336.js";import"./css-color-function.a8f9466d.js";import"./color.903ca10f.js";import"./clone.9d64bb7a.js";import"./color-convert.69e17089.js";import"./color-string.e356f5de.js";import"./color-name.e7a4e1d3.js";import"./nprogress.a96d99f2.js";import"./vue-clipboard3.91d4fd5f.js";import"./clipboard.c0a70c0c.js";import"./echarts.6ad8c478.js";import"./zrender.f91f2f01.js";import"./highlight.js.4ebdf9a4.js";import"./@highlightjs.0ab41b7b.js";const i={class:"error404"},L=r({__name:"403",setup(u){return(e,s)=>(t(),m("div",i,[p(o,{code:"403",title:"\u60A8\u7684\u8D26\u53F7\u6743\u9650\u4E0D\u8DB3\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650\uFF01","show-btn":!1})]))}});export{L as default};

View File

@@ -1 +1 @@
import o from"./error.1294af0d.js";import{d as r,o as t,c as m,V as p}from"./@vue.cab01781.js";import"./element-plus.374f5afd.js";import"./@vueuse.724ed0af.js";import"./@element-plus.92b4185f.js";import"./lodash-es.29c53eac.js";import"./dayjs.66926594.js";import"./axios.2d915936.js";import"./async-validator.fb49d0f5.js";import"./@ctrl.82a509e0.js";import"./@popperjs.36402333.js";import"./escape-html.e5dfadb9.js";import"./normalize-wheel-es.8aeb3683.js";import"./vue-router.5046cc50.js";import"./index.66650ce1.js";import"./lodash.b68d77aa.js";import"./pinia.e85e8286.js";import"./vue-demi.bfae2336.js";import"./css-color-function.a8f9466d.js";import"./color.903ca10f.js";import"./clone.9d64bb7a.js";import"./color-convert.69e17089.js";import"./color-string.e356f5de.js";import"./color-name.e7a4e1d3.js";import"./nprogress.a96d99f2.js";import"./vue-clipboard3.91d4fd5f.js";import"./clipboard.c0a70c0c.js";import"./echarts.6ad8c478.js";import"./zrender.f91f2f01.js";import"./highlight.js.4ebdf9a4.js";import"./@highlightjs.0ab41b7b.js";const i={class:"error404"},L=r({__name:"404",setup(e){return(u,c)=>(t(),m("div",i,[p(o,{code:"404",title:"\u54CE\u5440\uFF0C\u51FA\u9519\u4E86\uFF01\u60A8\u8BBF\u95EE\u7684\u9875\u9762\u4E0D\u5B58\u5728\u2026"})]))}});export{L as default};
import o from"./error.2b025df1.js";import{d as r,o as t,c as m,V as p}from"./@vue.cab01781.js";import"./element-plus.8115766e.js";import"./@vueuse.724ed0af.js";import"./@element-plus.92b4185f.js";import"./lodash-es.29c53eac.js";import"./dayjs.66926594.js";import"./axios.2d915936.js";import"./async-validator.fb49d0f5.js";import"./@ctrl.82a509e0.js";import"./@popperjs.36402333.js";import"./escape-html.e5dfadb9.js";import"./normalize-wheel-es.8aeb3683.js";import"./vue-router.5046cc50.js";import"./index.53063276.js";import"./lodash.b68d77aa.js";import"./pinia.e85e8286.js";import"./vue-demi.bfae2336.js";import"./css-color-function.a8f9466d.js";import"./color.903ca10f.js";import"./clone.9d64bb7a.js";import"./color-convert.69e17089.js";import"./color-string.e356f5de.js";import"./color-name.e7a4e1d3.js";import"./nprogress.a96d99f2.js";import"./vue-clipboard3.91d4fd5f.js";import"./clipboard.c0a70c0c.js";import"./echarts.6ad8c478.js";import"./zrender.f91f2f01.js";import"./highlight.js.4ebdf9a4.js";import"./@highlightjs.0ab41b7b.js";const i={class:"error404"},L=r({__name:"404",setup(e){return(u,c)=>(t(),m("div",i,[p(o,{code:"404",title:"\u54CE\u5440\uFF0C\u51FA\u9519\u4E86\uFF01\u60A8\u8BBF\u95EE\u7684\u9875\u9762\u4E0D\u5B58\u5728\u2026"})]))}});export{L as default};

View File

@@ -1 +1 @@
import"./add-nav.vue_vue_type_script_setup_true_lang.70d03ce8.js";import{_ as R}from"./add-nav.vue_vue_type_script_setup_true_lang.70d03ce8.js";import"./element-plus.374f5afd.js";import"./@vue.cab01781.js";import"./@vueuse.724ed0af.js";import"./@element-plus.92b4185f.js";import"./lodash-es.29c53eac.js";import"./dayjs.66926594.js";import"./axios.2d915936.js";import"./async-validator.fb49d0f5.js";import"./@ctrl.82a509e0.js";import"./@popperjs.36402333.js";import"./escape-html.e5dfadb9.js";import"./normalize-wheel-es.8aeb3683.js";import"./index.43820743.js";import"./index.66650ce1.js";import"./lodash.b68d77aa.js";import"./vue-router.5046cc50.js";import"./pinia.e85e8286.js";import"./vue-demi.bfae2336.js";import"./css-color-function.a8f9466d.js";import"./color.903ca10f.js";import"./clone.9d64bb7a.js";import"./color-convert.69e17089.js";import"./color-string.e356f5de.js";import"./color-name.e7a4e1d3.js";import"./nprogress.a96d99f2.js";import"./vue-clipboard3.91d4fd5f.js";import"./clipboard.c0a70c0c.js";import"./echarts.6ad8c478.js";import"./zrender.f91f2f01.js";import"./highlight.js.4ebdf9a4.js";import"./@highlightjs.0ab41b7b.js";import"./picker.f006aa63.js";import"./index.48f7fb70.js";import"./picker.69d8af88.js";import"./index.3369bc1b.js";import"./usePaging.bfe23d97.js";import"./vue3-video-play.05975c53.js";import"./vuedraggable.a5db575d.js";import"./vue.de4be77f.js";import"./sortablejs.cd7e2c7e.js";export{R as default};
import"./add-nav.vue_vue_type_script_setup_true_lang.4d0f9da8.js";import{_ as S}from"./add-nav.vue_vue_type_script_setup_true_lang.4d0f9da8.js";import"./element-plus.8115766e.js";import"./@vue.cab01781.js";import"./@vueuse.724ed0af.js";import"./@element-plus.92b4185f.js";import"./lodash-es.29c53eac.js";import"./dayjs.66926594.js";import"./axios.2d915936.js";import"./async-validator.fb49d0f5.js";import"./@ctrl.82a509e0.js";import"./@popperjs.36402333.js";import"./escape-html.e5dfadb9.js";import"./normalize-wheel-es.8aeb3683.js";import"./index.2e76481a.js";import"./index.53063276.js";import"./lodash.b68d77aa.js";import"./vue-router.5046cc50.js";import"./pinia.e85e8286.js";import"./vue-demi.bfae2336.js";import"./css-color-function.a8f9466d.js";import"./color.903ca10f.js";import"./clone.9d64bb7a.js";import"./color-convert.69e17089.js";import"./color-string.e356f5de.js";import"./color-name.e7a4e1d3.js";import"./nprogress.a96d99f2.js";import"./vue-clipboard3.91d4fd5f.js";import"./clipboard.c0a70c0c.js";import"./echarts.6ad8c478.js";import"./zrender.f91f2f01.js";import"./highlight.js.4ebdf9a4.js";import"./@highlightjs.0ab41b7b.js";import"./picker.45f93d74.js";import"./index.15556fef.js";import"./picker.6a412a5d.js";import"./index.3647ec2c.js";import"./usePaging.52ce9b34.js";import"./index.vue_vue_type_script_setup_true_lang.23d9d5f1.js";import"./vue3-video-play.05975c53.js";import"./vuedraggable.a5db575d.js";import"./vue.de4be77f.js";import"./sortablejs.cd7e2c7e.js";export{S as default};

View File

@@ -1 +1 @@
import{B as F,w as b}from"./element-plus.374f5afd.js";import{_ as v}from"./index.43820743.js";import{_ as B}from"./picker.f006aa63.js";import{_ as A}from"./picker.69d8af88.js";import{f as _,b as y}from"./index.66650ce1.js";import{d as D,o as u,c as r,a as e,W as E,a8 as C,L as w,M as m,V as t,T as U}from"./@vue.cab01781.js";const N={class:"bg-fill-light flex items-center w-full p-4 mb-4"},$={class:"upload-btn w-[60px] h-[60px]"},z={class:"ml-3 flex-1"},L={class:"flex"},T=e("span",{class:"text-tx-regular flex-none mr-3"},"\u540D\u79F0",-1),I={class:"flex mt-[18px]"},M=e("span",{class:"text-tx-regular flex-none mr-3"},"\u94FE\u63A5",-1),P=U("\u6DFB\u52A0"),K=D({__name:"add-nav",props:{modelValue:{type:Array,default:()=>[]},max:{type:Number,default:10},min:{type:Number,default:1}},setup(d){const l=d,p=()=>{var a;((a=l.modelValue)==null?void 0:a.length)<l.max?l.modelValue.push({image:"",name:"\u5BFC\u822A\u540D\u79F0",link:{}}):_.msgError(`\u6700\u591A\u6DFB\u52A0${l.max}\u4E2A`)},i=a=>{var s;if(((s=l.modelValue)==null?void 0:s.length)<=l.min)return _.msgError(`\u6700\u5C11\u4FDD\u7559${l.min}\u4E2A`);l.modelValue.splice(a,1)};return(a,s)=>{const f=y,x=A,V=F,h=B,g=v,k=b;return u(),r("div",null,[e("div",null,[(u(!0),r(E,null,C(d.modelValue,(o,c)=>(u(),w(g,{class:"max-w-[400px]",key:c,onClose:n=>i(c)},{default:m(()=>[e("div",N,[t(x,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body",size:"60px","exclude-domain":""},{upload:m(()=>[e("div",$,[t(f,{name:"el-icon-Plus",size:20})])]),_:2},1032,["modelValue","onUpdate:modelValue"]),e("div",z,[e("div",L,[T,t(V,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"\u8BF7\u8F93\u5165\u540D\u79F0"},null,8,["modelValue","onUpdate:modelValue"])]),e("div",I,[M,t(h,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])])])])]),_:2},1032,["onClose"]))),128))]),e("div",null,[t(k,{type:"primary",onClick:p},{default:m(()=>[P]),_:1})])])}}});export{K as _};
import{C as F,w as b}from"./element-plus.8115766e.js";import{_ as v}from"./index.2e76481a.js";import{_ as A}from"./picker.45f93d74.js";import{_ as B}from"./picker.6a412a5d.js";import{f as _,b as y}from"./index.53063276.js";import{d as C,o as u,c as r,a as e,W as D,a8 as E,L as w,M as m,V as t,T as U}from"./@vue.cab01781.js";const N={class:"bg-fill-light flex items-center w-full p-4 mb-4"},$={class:"upload-btn w-[60px] h-[60px]"},z={class:"ml-3 flex-1"},L={class:"flex"},T=e("span",{class:"text-tx-regular flex-none mr-3"},"\u540D\u79F0",-1),I={class:"flex mt-[18px]"},M=e("span",{class:"text-tx-regular flex-none mr-3"},"\u94FE\u63A5",-1),P=U("\u6DFB\u52A0"),K=C({__name:"add-nav",props:{modelValue:{type:Array,default:()=>[]},max:{type:Number,default:10},min:{type:Number,default:1}},setup(d){const l=d,p=()=>{var a;((a=l.modelValue)==null?void 0:a.length)<l.max?l.modelValue.push({image:"",name:"\u5BFC\u822A\u540D\u79F0",link:{}}):_.msgError(`\u6700\u591A\u6DFB\u52A0${l.max}\u4E2A`)},i=a=>{var s;if(((s=l.modelValue)==null?void 0:s.length)<=l.min)return _.msgError(`\u6700\u5C11\u4FDD\u7559${l.min}\u4E2A`);l.modelValue.splice(a,1)};return(a,s)=>{const f=y,x=B,V=F,h=A,g=v,k=b;return u(),r("div",null,[e("div",null,[(u(!0),r(D,null,E(d.modelValue,(o,c)=>(u(),w(g,{class:"max-w-[400px]",key:c,onClose:n=>i(c)},{default:m(()=>[e("div",N,[t(x,{modelValue:o.image,"onUpdate:modelValue":n=>o.image=n,"upload-class":"bg-body",size:"60px","exclude-domain":""},{upload:m(()=>[e("div",$,[t(f,{name:"el-icon-Plus",size:20})])]),_:2},1032,["modelValue","onUpdate:modelValue"]),e("div",z,[e("div",L,[T,t(V,{modelValue:o.name,"onUpdate:modelValue":n=>o.name=n,placeholder:"\u8BF7\u8F93\u5165\u540D\u79F0"},null,8,["modelValue","onUpdate:modelValue"])]),e("div",I,[M,t(h,{modelValue:o.link,"onUpdate:modelValue":n=>o.link=n},null,8,["modelValue","onUpdate:modelValue"])])])])]),_:2},1032,["onClose"]))),128))]),e("div",null,[t(k,{type:"primary",onClick:p},{default:m(()=>[P]),_:1})])])}}});export{K as _};

View File

@@ -1 +1 @@
import{r as e}from"./index.66650ce1.js";function a(t){return e.get({url:"/article/cate/list",params:t})}function l(t){return e.get({url:"/article/cate/all",params:t})}function i(t){return e.post({url:"/article/cate/add",params:t})}function c(t){return e.post({url:"/article/cate/edit",params:t})}function u(t){return e.post({url:"/article/cate/del",params:t})}function n(t){return e.get({url:"/article/cate/detail",params:t})}function s(t){return e.post({url:"/article/cate/change",params:t})}function o(t){return e.get({url:"/article/list",params:t})}function d(t){return e.post({url:"/article/add",params:t})}function f(t){return e.post({url:"/article/edit",params:t})}function p(t){return e.post({url:"/article/del",params:t})}function g(t){return e.get({url:"/article/detail",params:t})}function C(t){return e.post({url:"/article/change",params:t})}export{c as a,i as b,n as c,u as d,s as e,a as f,g,l as h,f as i,d as j,C as k,p as l,o as m};
import{r as e}from"./index.53063276.js";function a(t){return e.get({url:"/article/cate/list",params:t})}function l(t){return e.get({url:"/article/cate/all",params:t})}function i(t){return e.post({url:"/article/cate/add",params:t})}function c(t){return e.post({url:"/article/cate/edit",params:t})}function u(t){return e.post({url:"/article/cate/del",params:t})}function n(t){return e.get({url:"/article/cate/detail",params:t})}function s(t){return e.post({url:"/article/cate/change",params:t})}function o(t){return e.get({url:"/article/list",params:t})}function d(t){return e.post({url:"/article/add",params:t})}function f(t){return e.post({url:"/article/edit",params:t})}function p(t){return e.post({url:"/article/del",params:t})}function g(t){return e.get({url:"/article/detail",params:t})}function C(t){return e.post({url:"/article/change",params:t})}export{c as a,i as b,n as c,u as d,s as e,a as f,g,l as h,f as i,d as j,C as k,p as l,o as m};

View File

@@ -0,0 +1 @@
import"./attr-setting.vue_vue_type_script_setup_true_lang.173991cf.js";import{_ as cm}from"./attr-setting.vue_vue_type_script_setup_true_lang.173991cf.js";import"./index.8b3d114e.js";import"./attr.vue_vue_type_script_setup_true_lang.22676784.js";import"./element-plus.8115766e.js";import"./@vue.cab01781.js";import"./@vueuse.724ed0af.js";import"./@element-plus.92b4185f.js";import"./lodash-es.29c53eac.js";import"./dayjs.66926594.js";import"./axios.2d915936.js";import"./async-validator.fb49d0f5.js";import"./@ctrl.82a509e0.js";import"./@popperjs.36402333.js";import"./escape-html.e5dfadb9.js";import"./normalize-wheel-es.8aeb3683.js";import"./index.2e76481a.js";import"./index.53063276.js";import"./lodash.b68d77aa.js";import"./vue-router.5046cc50.js";import"./pinia.e85e8286.js";import"./vue-demi.bfae2336.js";import"./css-color-function.a8f9466d.js";import"./color.903ca10f.js";import"./clone.9d64bb7a.js";import"./color-convert.69e17089.js";import"./color-string.e356f5de.js";import"./color-name.e7a4e1d3.js";import"./nprogress.a96d99f2.js";import"./vue-clipboard3.91d4fd5f.js";import"./clipboard.c0a70c0c.js";import"./echarts.6ad8c478.js";import"./zrender.f91f2f01.js";import"./highlight.js.4ebdf9a4.js";import"./@highlightjs.0ab41b7b.js";import"./picker.45f93d74.js";import"./index.15556fef.js";import"./picker.6a412a5d.js";import"./index.3647ec2c.js";import"./usePaging.52ce9b34.js";import"./index.vue_vue_type_script_setup_true_lang.23d9d5f1.js";import"./vue3-video-play.05975c53.js";import"./vuedraggable.a5db575d.js";import"./vue.de4be77f.js";import"./sortablejs.cd7e2c7e.js";import"./content.vue_vue_type_script_setup_true_lang.c187246b.js";import"./decoration-img.e07a9eab.js";import"./attr.vue_vue_type_script_setup_true_lang.7393e332.js";import"./content.cbf0d4cf.js";import"./attr.vue_vue_type_script_setup_true_lang.dd81a142.js";import"./add-nav.vue_vue_type_script_setup_true_lang.4d0f9da8.js";import"./content.1302931d.js";import"./attr.vue_vue_type_script_setup_true_lang.bec38aae.js";import"./content.vue_vue_type_script_setup_true_lang.e5408794.js";import"./attr.vue_vue_type_script_setup_true_lang.06a2fa18.js";import"./content.250698bc.js";import"./decoration.a3e48437.js";import"./attr.vue_vue_type_script_setup_true_lang.0b87e513.js";import"./content.d99d9dd5.js";import"./attr.vue_vue_type_script_setup_true_lang.4d4e4b9a.js";import"./content.vue_vue_type_script_setup_true_lang.f8910cfe.js";import"./attr.vue_vue_type_script_setup_true_lang.0583d8bc.js";import"./content.90ee9825.js";export{cm as default};

View File

@@ -1 +0,0 @@
import"./attr-setting.vue_vue_type_script_setup_true_lang.e2ec5101.js";import{_ as em}from"./attr-setting.vue_vue_type_script_setup_true_lang.e2ec5101.js";import"./index.22f954e7.js";import"./attr.vue_vue_type_script_setup_true_lang.6fade7a2.js";import"./element-plus.374f5afd.js";import"./@vue.cab01781.js";import"./@vueuse.724ed0af.js";import"./@element-plus.92b4185f.js";import"./lodash-es.29c53eac.js";import"./dayjs.66926594.js";import"./axios.2d915936.js";import"./async-validator.fb49d0f5.js";import"./@ctrl.82a509e0.js";import"./@popperjs.36402333.js";import"./escape-html.e5dfadb9.js";import"./normalize-wheel-es.8aeb3683.js";import"./index.43820743.js";import"./index.66650ce1.js";import"./lodash.b68d77aa.js";import"./vue-router.5046cc50.js";import"./pinia.e85e8286.js";import"./vue-demi.bfae2336.js";import"./css-color-function.a8f9466d.js";import"./color.903ca10f.js";import"./clone.9d64bb7a.js";import"./color-convert.69e17089.js";import"./color-string.e356f5de.js";import"./color-name.e7a4e1d3.js";import"./nprogress.a96d99f2.js";import"./vue-clipboard3.91d4fd5f.js";import"./clipboard.c0a70c0c.js";import"./echarts.6ad8c478.js";import"./zrender.f91f2f01.js";import"./highlight.js.4ebdf9a4.js";import"./@highlightjs.0ab41b7b.js";import"./picker.f006aa63.js";import"./index.48f7fb70.js";import"./picker.69d8af88.js";import"./index.3369bc1b.js";import"./usePaging.bfe23d97.js";import"./vue3-video-play.05975c53.js";import"./vuedraggable.a5db575d.js";import"./vue.de4be77f.js";import"./sortablejs.cd7e2c7e.js";import"./content.vue_vue_type_script_setup_true_lang.19e8b204.js";import"./decoration-img.408cc614.js";import"./attr.vue_vue_type_script_setup_true_lang.813de30c.js";import"./content.ae4e83bb.js";import"./attr.vue_vue_type_script_setup_true_lang.9f826c96.js";import"./add-nav.vue_vue_type_script_setup_true_lang.70d03ce8.js";import"./content.149b5e3a.js";import"./attr.vue_vue_type_script_setup_true_lang.b9715116.js";import"./content.vue_vue_type_script_setup_true_lang.65f9983c.js";import"./attr.vue_vue_type_script_setup_true_lang.06a2fa18.js";import"./content.edf66e1e.js";import"./decoration.46adad8f.js";import"./attr.vue_vue_type_script_setup_true_lang.0b87e513.js";import"./content.6b6901ee.js";import"./attr.vue_vue_type_script_setup_true_lang.a36dcde8.js";import"./content.vue_vue_type_script_setup_true_lang.4d93935e.js";import"./attr.vue_vue_type_script_setup_true_lang.0583d8bc.js";import"./content.f4970cf1.js";export{em as default};

View File

@@ -1 +1 @@
import{w as i}from"./index.22f954e7.js";import{d as l,o as t,c as d,a as m,U as f,L as c,R as p,u as g,aK as b}from"./@vue.cab01781.js";const u={class:"pages-setting"},w={class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2"},k=l({__name:"attr-setting",props:{widget:{type:Object,default:()=>({})}},setup(e){return(y,x)=>{var s,a,n,o,r;return t(),d("div",u,[m("div",w,f((s=e.widget)==null?void 0:s.title),1),(t(),c(b,null,[(t(),c(p((n=g(i)[(a=e.widget)==null?void 0:a.name])==null?void 0:n.attr),{class:"pt-5 pr-4",content:(o=e.widget)==null?void 0:o.content,styles:(r=e.widget)==null?void 0:r.styles},null,8,["content","styles"]))],1024))])}}});export{k as _};
import{w as i}from"./index.8b3d114e.js";import{d as l,o as t,c as d,a as m,U as f,L as c,R as p,u as g,aK as b}from"./@vue.cab01781.js";const u={class:"pages-setting"},w={class:"title flex items-center before:w-[3px] before:h-[14px] before:block before:bg-primary before:mr-2"},k=l({__name:"attr-setting",props:{widget:{type:Object,default:()=>({})}},setup(e){return(y,x)=>{var s,a,n,o,r;return t(),d("div",u,[m("div",w,f((s=e.widget)==null?void 0:s.title),1),(t(),c(b,null,[(t(),c(p((n=g(i)[(a=e.widget)==null?void 0:a.name])==null?void 0:n.attr),{class:"pt-5 pr-4",content:(o=e.widget)==null?void 0:o.content,styles:(r=e.widget)==null?void 0:r.styles},null,8,["content","styles"]))],1024))])}}});export{k as _};

View File

@@ -1 +1 @@
import"./attr.vue_vue_type_script_setup_true_lang.9f826c96.js";import{_ as S}from"./attr.vue_vue_type_script_setup_true_lang.9f826c96.js";import"./element-plus.374f5afd.js";import"./@vue.cab01781.js";import"./@vueuse.724ed0af.js";import"./@element-plus.92b4185f.js";import"./lodash-es.29c53eac.js";import"./dayjs.66926594.js";import"./axios.2d915936.js";import"./async-validator.fb49d0f5.js";import"./@ctrl.82a509e0.js";import"./@popperjs.36402333.js";import"./escape-html.e5dfadb9.js";import"./normalize-wheel-es.8aeb3683.js";import"./add-nav.vue_vue_type_script_setup_true_lang.70d03ce8.js";import"./index.43820743.js";import"./index.66650ce1.js";import"./lodash.b68d77aa.js";import"./vue-router.5046cc50.js";import"./pinia.e85e8286.js";import"./vue-demi.bfae2336.js";import"./css-color-function.a8f9466d.js";import"./color.903ca10f.js";import"./clone.9d64bb7a.js";import"./color-convert.69e17089.js";import"./color-string.e356f5de.js";import"./color-name.e7a4e1d3.js";import"./nprogress.a96d99f2.js";import"./vue-clipboard3.91d4fd5f.js";import"./clipboard.c0a70c0c.js";import"./echarts.6ad8c478.js";import"./zrender.f91f2f01.js";import"./highlight.js.4ebdf9a4.js";import"./@highlightjs.0ab41b7b.js";import"./picker.f006aa63.js";import"./index.48f7fb70.js";import"./picker.69d8af88.js";import"./index.3369bc1b.js";import"./usePaging.bfe23d97.js";import"./vue3-video-play.05975c53.js";import"./vuedraggable.a5db575d.js";import"./vue.de4be77f.js";import"./sortablejs.cd7e2c7e.js";export{S as default};
import"./attr.vue_vue_type_script_setup_true_lang.dd81a142.js";import{_ as T}from"./attr.vue_vue_type_script_setup_true_lang.dd81a142.js";import"./element-plus.8115766e.js";import"./@vue.cab01781.js";import"./@vueuse.724ed0af.js";import"./@element-plus.92b4185f.js";import"./lodash-es.29c53eac.js";import"./dayjs.66926594.js";import"./axios.2d915936.js";import"./async-validator.fb49d0f5.js";import"./@ctrl.82a509e0.js";import"./@popperjs.36402333.js";import"./escape-html.e5dfadb9.js";import"./normalize-wheel-es.8aeb3683.js";import"./add-nav.vue_vue_type_script_setup_true_lang.4d0f9da8.js";import"./index.2e76481a.js";import"./index.53063276.js";import"./lodash.b68d77aa.js";import"./vue-router.5046cc50.js";import"./pinia.e85e8286.js";import"./vue-demi.bfae2336.js";import"./css-color-function.a8f9466d.js";import"./color.903ca10f.js";import"./clone.9d64bb7a.js";import"./color-convert.69e17089.js";import"./color-string.e356f5de.js";import"./color-name.e7a4e1d3.js";import"./nprogress.a96d99f2.js";import"./vue-clipboard3.91d4fd5f.js";import"./clipboard.c0a70c0c.js";import"./echarts.6ad8c478.js";import"./zrender.f91f2f01.js";import"./highlight.js.4ebdf9a4.js";import"./@highlightjs.0ab41b7b.js";import"./picker.45f93d74.js";import"./index.15556fef.js";import"./picker.6a412a5d.js";import"./index.3647ec2c.js";import"./usePaging.52ce9b34.js";import"./index.vue_vue_type_script_setup_true_lang.23d9d5f1.js";import"./vue3-video-play.05975c53.js";import"./vuedraggable.a5db575d.js";import"./vue.de4be77f.js";import"./sortablejs.cd7e2c7e.js";export{T as default};

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