From 4a6eeb0c0fa2859c7afcabb83d3a0f291bbbaad6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BF=9E=E5=AE=9D=E5=B1=B1?= <1253070437@qq.com>
Date: Thu, 8 Aug 2024 23:29:07 +0800
Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=8D=87=E7=BA=A7=E3=80=91v3.2?=
=?UTF-8?q?=E7=89=88=E6=9C=AC=E5=8D=87=E7=BA=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 2 +
snowy-admin-web/.env.development | 9 +-
snowy-admin-web/.env.production | 6 -
snowy-admin-web/index.html | 10 +-
.../HomeCard/BizMiniMessageCard/index.vue | 7 +-
.../HomeCard/BizNoticeCard/detail.vue | 8 +-
.../HomeCard/BizNoticeCard/index.vue | 16 +-
.../HomeCard/BizScheduleCard/index.vue | 17 +-
.../HomeCard/BizShortcutCard/index.vue | 20 +-
.../HomeCard/BizSlideshowCard/index.vue | 29 +-
.../HomeCard/SysBizDataCard/index.vue | 16 +-
.../HomeCard/SysOpDataCard/index.vue | 16 +-
.../HomeCard/SysOpLogCard/index.vue | 17 +-
.../HomeCard/SysToolDataCard/index.vue | 16 +-
.../HomeCard/SysVisChartDataCard/index.vue | 28 +-
.../HomeCard/SysVisLogCard/index.vue | 19 +-
.../src/components/Table/index.vue | 111 ++--
.../src/components/XnBatchButton/index.vue | 6 +-
.../src/components/XnFilePreview/index.vue | 96 ++--
.../src/components/XnFormContainer/index.vue | 8 +-
.../src/components/XnHighlightjs/index.vue | 7 +-
.../src/components/XnPageSelect/index.vue | 16 +-
snowy-admin-web/src/components/global.less | 503 ------------------
snowy-admin-web/src/components/index.less | 6 -
snowy-admin-web/src/config/index.js | 3 +
snowy-admin-web/src/layout/index.vue | 72 ++-
snowy-admin-web/src/router/index.js | 3 +-
snowy-admin-web/src/store/menu.js | 22 +-
snowy-admin-web/src/style/index.less | 1 +
snowy-admin-web/src/utils/formRules.js | 14 +-
snowy-admin-web/src/utils/loading.js | 13 +-
snowy-admin-web/src/utils/request.js | 4 +-
snowy-admin-web/src/utils/treeHandler.js | 14 +
snowy-admin-web/src/utils/version.js | 35 ++
.../src/views/auth/findPwd/index.vue | 12 +-
.../src/views/auth/login/login.less | 212 ++++----
.../src/views/auth/login/login.vue | 27 +-
.../src/views/biz/notice/detail.vue | 8 +-
snowy-admin-web/src/views/biz/user/form.vue | 28 +-
.../src/views/dev/dict/category/frmIndex.vue | 184 -------
.../dict/category/{bizIndex.vue => index.vue} | 53 +-
snowy-admin-web/src/views/dev/dict/index.vue | 39 +-
.../src/views/dev/log/oplog/detail.vue | 8 +-
.../src/views/dev/log/vislog/detail.vue | 8 +-
.../src/views/sys/resource/menu/form.vue | 10 +-
.../sys/role/grantMobileResourceForm.vue | 26 +-
.../views/sys/role/grantPermissionForm.vue | 155 +++++-
.../src/views/sys/role/grantResourceForm.vue | 27 +-
.../src/views/sys/role/scopeDefineOrg.vue | 6 +-
snowy-admin-web/src/views/sys/user/form.vue | 22 +-
.../views/sys/user/grantPermissionForm.vue | 156 +++++-
.../src/views/sys/user/grantResourceForm.vue | 26 +-
.../src/views/sys/user/scopeDefineOrg.vue | 6 +-
.../user/service/impl/BizUserServiceImpl.java | 4 +-
.../user/service/impl/SysUserServiceImpl.java | 6 +-
.../xiaonuo/core/config/GlobalConfigure.java | 132 ++---
56 files changed, 1041 insertions(+), 1284 deletions(-)
delete mode 100644 snowy-admin-web/src/components/global.less
delete mode 100644 snowy-admin-web/src/components/index.less
create mode 100644 snowy-admin-web/src/utils/treeHandler.js
create mode 100644 snowy-admin-web/src/utils/version.js
delete mode 100644 snowy-admin-web/src/views/dev/dict/category/frmIndex.vue
rename snowy-admin-web/src/views/dev/dict/category/{bizIndex.vue => index.vue} (83%)
diff --git a/README.md b/README.md
index 84c99b92..d836b91f 100644
--- a/README.md
+++ b/README.md
@@ -53,6 +53,8 @@ gitee下载地址:[https://gitee.com/xiaonuobase/snowy](https://gitee.com/xiao
github下载地址(镜像):[https://github.com/xiaonuobase/Snowy](https://github.com/xiaonuobase/Snowy)
+gitcode下载地址:[https://gitcode.com/xiaonuobase/Snowy](https://gitcode.com/xiaonuobase/Snowy)
+
演示地址:[https://snowy.xiaonuo.vip](https://snowy.xiaonuo.vip)
文档地址:[https://xiaonuo.vip/doc](https://xiaonuo.vip/doc)
diff --git a/snowy-admin-web/.env.development b/snowy-admin-web/.env.development
index 4f5f665a..f7b453fd 100644
--- a/snowy-admin-web/.env.development
+++ b/snowy-admin-web/.env.development
@@ -1,9 +1,3 @@
-# 本地环境
-NODE_ENV = development
-
-# 标题
-VITE_TITLE = Snowy
-
# 接口地址
VITE_API_BASEURL = http://127.0.0.1:82
@@ -12,3 +6,6 @@ VITE_PORT = 81
# 开启设置抽屉
VITE_SET_DRAWER = true
+
+# 本地环境
+NODE_ENV = development
diff --git a/snowy-admin-web/.env.production b/snowy-admin-web/.env.production
index cc8d8d42..26326300 100644
--- a/snowy-admin-web/.env.production
+++ b/snowy-admin-web/.env.production
@@ -1,9 +1,3 @@
-# 生产环境
-NODE_ENV = production
-
-# 标题
-VITE_TITLE = Snowy
-
# 接口地址
VITE_API_BASEURL = http://127.0.0.1:82
diff --git a/snowy-admin-web/index.html b/snowy-admin-web/index.html
index 55d2e348..babf82cc 100644
--- a/snowy-admin-web/index.html
+++ b/snowy-admin-web/index.html
@@ -8,10 +8,10 @@
Snowy
diff --git a/snowy-admin-web/src/components/XnBatchButton/index.vue b/snowy-admin-web/src/components/XnBatchButton/index.vue
index 1fa17b89..a1591ecf 100644
--- a/snowy-admin-web/src/components/XnBatchButton/index.vue
+++ b/snowy-admin-web/src/components/XnBatchButton/index.vue
@@ -15,6 +15,10 @@
const emit = defineEmits({ batchCallBack: null })
const buttonLoading = ref(false)
const props = defineProps({
+ idKey: {
+ type: String,
+ default: () => 'id'
+ },
buttonName: {
type: String,
default: () => '批量操作'
@@ -62,7 +66,7 @@
const deleteBatch = () => {
const params = props.selectedRowKeys.map((m) => {
return {
- id: m
+ [props.idKey]: m
}
})
// 发起方法调用,谁的谁来实现
diff --git a/snowy-admin-web/src/components/XnFilePreview/index.vue b/snowy-admin-web/src/components/XnFilePreview/index.vue
index f8af5d48..d9631ea8 100644
--- a/snowy-admin-web/src/components/XnFilePreview/index.vue
+++ b/snowy-admin-web/src/components/XnFilePreview/index.vue
@@ -1,50 +1,52 @@
-
-
-
-
-
-
- 返回
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+ 返回
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/snowy-admin-web/src/views/dev/dict/category/frmIndex.vue b/snowy-admin-web/src/views/dev/dict/category/frmIndex.vue
deleted file mode 100644
index cbfa999b..00000000
--- a/snowy-admin-web/src/views/dev/dict/category/frmIndex.vue
+++ /dev/null
@@ -1,184 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 查询
-
-
-
- 重置
-
-
-
-
-
-
-
-
-
- 新增
-
-
-
-
- {{ record.level }}
- 子级
-
-
- 编辑
-
-
-
-
-
-
-
-
-
-
-
diff --git a/snowy-admin-web/src/views/dev/dict/category/bizIndex.vue b/snowy-admin-web/src/views/dev/dict/category/index.vue
similarity index 83%
rename from snowy-admin-web/src/views/dev/dict/category/bizIndex.vue
rename to snowy-admin-web/src/views/dev/dict/category/index.vue
index 43eaaef1..b7196bea 100644
--- a/snowy-admin-web/src/views/dev/dict/category/bizIndex.vue
+++ b/snowy-admin-web/src/views/dev/dict/category/index.vue
@@ -1,15 +1,17 @@
-
-
-
+
@@ -42,7 +44,7 @@
:row-key="(record) => record.id"
>
-
+
新增
@@ -53,7 +55,7 @@
子级
- 编辑
+ 编辑
删除
@@ -66,11 +68,17 @@
-
-
diff --git a/snowy-admin-web/src/views/dev/dict/index.vue b/snowy-admin-web/src/views/dev/dict/index.vue
index a126cd84..7ba501cc 100644
--- a/snowy-admin-web/src/views/dev/dict/index.vue
+++ b/snowy-admin-web/src/views/dev/dict/index.vue
@@ -1,32 +1,23 @@
- onTabChange(key, 'frmIndex')"
- >
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/snowy-admin-web/src/views/dev/log/oplog/detail.vue b/snowy-admin-web/src/views/dev/log/oplog/detail.vue
index 50d2c4d8..d79e15d3 100644
--- a/snowy-admin-web/src/views/dev/log/oplog/detail.vue
+++ b/snowy-admin-web/src/views/dev/log/oplog/detail.vue
@@ -1,11 +1,5 @@
-
+
{{ formData.name }}
{{ formData.opIp }}
diff --git a/snowy-admin-web/src/views/dev/log/vislog/detail.vue b/snowy-admin-web/src/views/dev/log/vislog/detail.vue
index 5fbb1307..825029c5 100644
--- a/snowy-admin-web/src/views/dev/log/vislog/detail.vue
+++ b/snowy-admin-web/src/views/dev/log/vislog/detail.vue
@@ -1,11 +1,5 @@
-
+
{{ formData.name }}
{{ formData.opIp }}
diff --git a/snowy-admin-web/src/views/sys/resource/menu/form.vue b/snowy-admin-web/src/views/sys/resource/menu/form.vue
index 9fea1269..23d012bc 100644
--- a/snowy-admin-web/src/views/sys/resource/menu/form.vue
+++ b/snowy-admin-web/src/views/sys/resource/menu/form.vue
@@ -51,7 +51,7 @@
- 类型为内外链条时,输入https开头的链接即可(例:https://xiaonuo.vip),正常路由前面必须有反斜杠!
+ 类型为内外链时,输入https开头的链接即可(例:https://xiaonuo.vip),正常路由前面必须有反斜杠!
@@ -122,7 +122,7 @@
diff --git a/snowy-admin-web/src/views/sys/user/grantPermissionForm.vue b/snowy-admin-web/src/views/sys/user/grantPermissionForm.vue
index fcac3394..9e6a5d98 100644
--- a/snowy-admin-web/src/views/sys/user/grantPermissionForm.vue
+++ b/snowy-admin-web/src/views/sys/user/grantPermissionForm.vue
@@ -17,13 +17,20 @@
class="mt-4"
size="middle"
:columns="columns"
- :data-source="loadDatas"
+ :data-source="tableLoadData"
bordered
:row-key="(record) => record.api"
+ :pagination="pagination"
+ @change="handleTableChange"
>
-
- onCheckAllChange(val)"> 接口
+
+ onCheckAllChange(val)">
+ {{ column.title }}
+
+
+
+ onCheckAllChange(val)"> 接口
{{ column.title }}
@@ -54,16 +61,21 @@
搜索
- 重置
+ 重置
-
+
+ changeParentApi(record, val)">
+ {{ record.prefix }}
+
+
+
changeApi(record, val)">
- {{ record.api }}
+ {{ record.suffix }}
@@ -110,6 +122,7 @@
import roleApi from '@/api/sys/roleApi'
import ScopeDefineOrg from './scopeDefineOrg.vue'
import { userStore } from '@/store/user'
+ import { cloneDeep } from 'lodash-es'
const visible = ref(false)
const spinningLoading = ref(false)
@@ -118,7 +131,7 @@
const submitLoading = ref(false)
const CustomValue = 'SCOPE_ORG_DEFINE'
// 抽屉的宽度
- const drawerWidth = 1000
+ const drawerWidth = 1050
// 自动获取宽度,默认获取浏览器的宽度的90%
//(window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) * 0.9
const loadDatas = ref([])
@@ -129,13 +142,39 @@
searchedColumn: ''
})
const searchInput = ref()
+ // 分页
+ const pagination = ref({
+ current: 1,
+ pageSize: 10,
+ total: 0,
+ showSizeChanger: true,
+ defaultPageSize: 10,
+ pageSizeOptions: ['10', '20', '50', '100']
+ })
+ const firstShowMap = ref({})
+ // 全选
+ const allChecked = ref(false)
+ const tableLoadData = ref([])
const columns = [
{
- key: 'api',
+ key: 'prefix',
+ title: '接口前缀',
+ dataIndex: 'prefix',
+ width: 140,
+ customCell: (row, index) => {
+ const indexArr = firstShowMap.value[row.prefix]
+ if (index === indexArr[0]) {
+ return { rowSpan: indexArr.length }
+ }
+ return { rowSpan: 0 }
+ }
+ },
+ {
+ key: 'suffix',
title: '接口',
- dataIndex: 'api',
- width: 380,
+ dataIndex: 'suffix',
+ width: 290,
customFilterDropdown: true,
onFilter: (value, record) => record.api.includes(value),
onFilterDropdownOpenChange: (visible) => {
@@ -162,17 +201,29 @@
}
const resOwn = await userApi.userOwnPermission(param)
// 数据转换
- echoModuleData(res, resOwn)
+ loadDatas.value = echoModuleData(res, resOwn)
+ pagination.value.total = loadDatas.value.length
+ allChecked.value = loadDatas.value.every((item) => item.parentCheck)
spinningLoading.value = false
}
+ // table事件触发
+ const handleTableChange = (pageInfo) => {
+ Object.assign(pagination.value, pageInfo)
+ }
// 数据转换
const echoModuleData = (res, resOwn) => {
+ let list = []
res.forEach((api) => {
+ const apiArr = splitByThirdSlash(api)
const obj = {
api: api,
+ prefix: apiArr[0],
+ suffix: apiArr[1],
dataScope: datascope(api),
- check: false
+ check: false,
+ parentCheck: false
}
+
if (resOwn.grantInfoList.length > 0) {
resOwn.grantInfoList.forEach((item) => {
if (item.apiUrl === subStrApi(api)) {
@@ -190,8 +241,10 @@
}
})
}
- loadDatas.value.push(obj)
+ list.push(obj)
})
+ // 设置父节点check状态
+ return setParentDataCheckedStatus(list)
}
const datascope = (id) => {
return [
@@ -278,6 +331,11 @@
const onOpen = (record) => {
grantPermissionParam.id = record.id
visible.value = true
+ firstShowMap.value = {}
+ pagination.value.current = 1
+ pagination.value.pageSize = 10
+ pagination.value.total = 0
+ allChecked.value = false
loadData()
}
// 关闭抽屉
@@ -289,15 +347,41 @@
}
// 全选
const onCheckAllChange = (value) => {
+ allChecked.value = value
spinningLoading.value = true
loadDatas.value.forEach((data) => {
- changeApi(data, value)
+ changeApi(data, value, false)
+ data.parentCheck = value
spinningLoading.value = false
})
}
-
+ // 选中接口前缀
+ const changeParentApi = (record, val) => {
+ loadDatas.value.forEach((data) => {
+ if (data.prefix === record.prefix) {
+ data.check = val
+ data.parentCheck = val
+ if (val) {
+ let isChecked = data.dataScope.some((item) => item.check)
+ if (!isChecked) {
+ data.dataScope[0].check = true
+ }
+ } else {
+ data.dataScope.forEach((item) => {
+ item.check = false
+ })
+ }
+ data.dataScope.forEach((item) => {
+ if (item.value === 'SCOPE_ORG_DEFINE') {
+ item.scopeDefineOrgIdList = []
+ }
+ })
+ }
+ })
+ allChecked.value = loadDatas.value.every((item) => item.parentCheck)
+ }
// 选中接口
- const changeApi = (record, val) => {
+ const changeApi = (record, val, isLoadData = true) => {
record.check = val
if (val) {
let checkStatus = 0
@@ -318,6 +402,7 @@
}
})
}
+ isLoadData && (loadDatas.value = setParentDataCheckedStatus(loadDatas.value))
}
// 设置选中状态
const changeChildCheckBox = (record, evt) => {
@@ -383,8 +468,9 @@
state.searchedColumn = dataIndex
}
// 标题接口列搜索重置
- const handleReset = (clearFilters) => {
+ const handleReset = (clearFilters, confirm) => {
clearFilters()
+ confirm()
state.searchText = ''
}
// 标题数据范围列radio-group事件
@@ -399,6 +485,42 @@
})
})
}
+ // 设置父节点check状态
+ const setParentDataCheckedStatus = (records) => {
+ const cloneRecords = cloneDeep(records)
+ cloneRecords.forEach((item) => {
+ let childrenList = records.filter((f) => f.prefix === item.prefix)
+ item.parentCheck = childrenList.every((e) => e.check)
+ })
+ return cloneRecords
+ }
+ // 字符串分割
+ function splitByThirdSlash(str) {
+ const arr = str.split('/').filter(Boolean)
+ const leftPart = '/' + arr.slice(0, 2).join('/')
+ const rightPart = '/' + arr.slice(2).join('/')
+ return [leftPart, rightPart]
+ }
+ // 监听分页及数据变化
+ watch(
+ () => [pagination.value, loadDatas.value],
+ (val) => {
+ const start = (pagination.value.current - 1) * pagination.value.pageSize
+ const end = start + pagination.value.pageSize
+ const tableData = loadDatas.value.slice(start, end)
+ firstShowMap.value = {}
+ // 生成map
+ tableData?.forEach((item, index) => {
+ if (firstShowMap.value[item.prefix]) {
+ firstShowMap.value[item.prefix].push(index)
+ } else {
+ firstShowMap.value[item.prefix] = [index]
+ }
+ })
+ tableLoadData.value = tableData
+ },
+ { deep: true }
+ )
// 调用这个函数将子组件的一些数据和方法暴露出去
defineExpose({
onOpen
diff --git a/snowy-admin-web/src/views/sys/user/grantResourceForm.vue b/snowy-admin-web/src/views/sys/user/grantResourceForm.vue
index b6b33619..2cfec6d2 100644
--- a/snowy-admin-web/src/views/sys/user/grantResourceForm.vue
+++ b/snowy-admin-web/src/views/sys/user/grantResourceForm.vue
@@ -105,8 +105,7 @@
// firstShowMap = {} // 重置单元格合并映射
// 如果有数据,我们再不去反复的查询
if (echoDatalist.value.length > 0) {
- let data = echoDatalist.value.find((f) => f.id === moduleId.value).menu
- loadDatas.value = data
+ loadDatas.value = echoDatalist.value.find((f) => f.id === moduleId.value).menu
} else {
// 获取表格数据
spinningLoading.value = true
@@ -143,11 +142,11 @@
if (module.menu) {
// 加入回显内容
module.menu.forEach((item) => {
- const menueCheck = ref(0)
+ const menusCheck = ref(0)
if (resEcho.grantInfoList.length > 0) {
resEcho.grantInfoList.forEach((grant) => {
if (item.id === grant.menuId) {
- menueCheck.value++
+ menusCheck.value++
// 处理按钮
if (grant.buttonInfo.length > 0) {
grant.buttonInfo.forEach((button) => {
@@ -162,15 +161,23 @@
})
}
// 回显前面的2个
- if (menueCheck.value > 0) {
+ if (menusCheck.value > 0) {
item.parentCheck = true
item.nameCheck = true
}
})
// 排序
- module.menu = module.menu.sort((a, b) => {
- return a.parentId - b.parentId
+ module.menu.sort((a, b) => {
+ // 首先比较parentName属性
+ let nameComparison = b.parentName.localeCompare(a.parentName)
+ if (nameComparison !== 0) {
+ // 如果parentName不同,直接返回parentName的比较结果
+ return nameComparison
+ } else {
+ // 如果name相同,则比较parentId属性,直接返回parentId的差值
+ return Number(a.parentId) - Number(b.parentId)
+ }
})
// 缓存加入索引
module.menu.forEach((item, index) => {
@@ -199,12 +206,11 @@
})
}
const checkAllChildNotChecked = (record) => {
- const allChecked = checkFieldKeys.every((key) => {
+ return checkFieldKeys.every((key) => {
// 遍历所有的字段
const child = record[key]
return child.every((field) => !field.check)
})
- return allChecked
}
const changeChildCheckBox = (record, evt) => {
let checked = evt.target.checked
@@ -305,7 +311,7 @@