From 66a62cafa76f31c7e04c55e0363b18675765bd3b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=BF=9E=E5=AE=9D=E5=B1=B1?= <1253070437@qq.com>
Date: Wed, 9 Oct 2024 21:39:35 +0800
Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=8D=87=E7=BA=A7=E3=80=91v3.3?=
=?UTF-8?q?=E7=89=88=E6=9C=AC=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
pom.xml | 2 +-
snowy-admin-web/.env.development | 3 +
snowy-admin-web/.env.production | 3 +
snowy-admin-web/package.json | 68 ++--
snowy-admin-web/src/api/gen/genBasicApi.js | 8 +
.../HomeCard/BizSlideshowCard/index.vue | 32 +-
.../HomeCard/SysOpDataCard/index.vue | 12 +-
.../src/components/XnBatchButton/index.vue | 61 ++-
.../src/components/XnEditor/index.vue | 6 +-
.../src/components/XnUpload/index.vue | 7 +-
snowy-admin-web/src/config/index.js | 12 +-
.../src/layout/components/message.vue | 3 +-
.../src/layout/components/tags.vue | 7 +-
snowy-admin-web/src/layout/index.vue | 78 ++--
snowy-admin-web/src/router/index.js | 13 +-
snowy-admin-web/src/store/global.js | 2 +-
snowy-admin-web/src/store/viewTags.js | 1 +
snowy-admin-web/src/style/index.less | 6 +-
snowy-admin-web/src/utils/apiAdaptive.js | 51 +++
snowy-admin-web/src/utils/errorHandler.js | 2 +-
snowy-admin-web/src/utils/request.js | 8 +-
.../src/views/biz/notice/detail.vue | 82 ++--
snowy-admin-web/src/views/biz/notice/form.vue | 200 +++++-----
.../src/views/biz/notice/index.vue | 369 +++++++++---------
snowy-admin-web/src/views/biz/org/index.vue | 7 +-
.../src/views/biz/position/index.vue | 7 +-
snowy-admin-web/src/views/biz/user/index.vue | 6 +-
.../src/views/dev/dict/category/index.vue | 10 +-
snowy-admin-web/src/views/dev/file/index.vue | 8 +-
snowy-admin-web/src/views/dev/job/form.vue | 21 +-
snowy-admin-web/src/views/dev/job/index.vue | 8 +-
.../src/views/dev/message/index.vue | 8 +-
.../src/views/dev/slideshow/form.vue | 159 ++++----
.../src/views/dev/slideshow/index.vue | 272 ++++++-------
.../src/views/dev/slideshow/subForm.vue | 48 ++-
snowy-admin-web/src/views/dev/sms/index.vue | 8 +-
snowy-admin-web/src/views/gen/basic.vue | 28 +-
snowy-admin-web/src/views/gen/config.vue | 2 +-
snowy-admin-web/src/views/gen/index.vue | 8 +-
.../src/views/mobile/resource/menu/index.vue | 8 +-
.../views/mobile/resource/module/index.vue | 8 +-
snowy-admin-web/src/views/sys/org/index.vue | 8 +-
.../src/views/sys/position/index.vue | 8 +-
.../src/views/sys/resource/menu/index.vue | 27 +-
.../src/views/sys/resource/module/index.vue | 8 +-
snowy-admin-web/src/views/sys/role/index.vue | 8 +-
snowy-admin-web/src/views/sys/user/index.vue | 6 +-
.../common/enums/CommonSortOrderEnum.java | 2 +-
.../common/timer/CommonTimerTaskRunner.java | 2 +-
.../common/util/CommonNetWorkInfoUtil.java | 4 +-
.../java/vip/xiaonuo/sys/api/SysMenuApi.java | 12 +
.../vip/xiaonuo/sys/api/SysModuleApi.java | 33 ++
.../dev/core/listener/DevJobListener.java | 2 +-
.../dev/modular/dev/DevApiProvider.java | 5 +-
.../email/util/DevEmailAliyunUtil.java | 2 +-
.../job/service/impl/DevJobServiceImpl.java | 4 +-
.../job/task/DevJobTimerTaskRunner.java | 2 +-
.../sms/service/impl/DevSmsServiceImpl.java | 2 +
.../modular/sms/util/DevSmsXiaonuoUtil.java | 4 +-
.../basic/controller/GenBasicController.java | 30 +-
.../param/GenBasicSelectorMenuParam.java | 34 ++
.../result/GenBasicModuleSelectorResult.java | 36 ++
.../basic/service/GenBasicService.java | 22 +-
.../service/impl/GenBasicServiceImpl.java | 25 +-
.../src/main/resources/frontend/index.vue.btl | 6 +-
.../controller/MobileButtonController.java | 3 +-
.../controller/SysButtonController.java | 3 +-
.../resource/provider/SysMenuApiProvider.java | 11 +
.../provider/SysModuleApiProvider.java | 38 ++
.../resource/service/SysModuleService.java | 9 +
.../service/impl/SysModuleServiceImpl.java | 11 +
.../user/service/impl/SysUserServiceImpl.java | 10 +-
.../src/main/resources/application.properties | 2 +-
73 files changed, 1259 insertions(+), 772 deletions(-)
create mode 100644 snowy-admin-web/src/utils/apiAdaptive.js
create mode 100644 snowy-plugin-api/snowy-plugin-sys-api/src/main/java/vip/xiaonuo/sys/api/SysModuleApi.java
create mode 100644 snowy-plugin/snowy-plugin-gen/src/main/java/vip/xiaonuo/gen/modular/basic/param/GenBasicSelectorMenuParam.java
create mode 100644 snowy-plugin/snowy-plugin-gen/src/main/java/vip/xiaonuo/gen/modular/basic/result/GenBasicModuleSelectorResult.java
create mode 100644 snowy-plugin/snowy-plugin-sys/src/main/java/vip/xiaonuo/sys/modular/resource/provider/SysModuleApiProvider.java
diff --git a/pom.xml b/pom.xml
index 1995c085..58acc2f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -375,7 +375,7 @@
com.baomidou
dynamic-datasource-spring-boot3-starter
- 4.3.0
+ 4.3.1
diff --git a/snowy-admin-web/.env.development b/snowy-admin-web/.env.development
index f7b453fd..5e3b7869 100644
--- a/snowy-admin-web/.env.development
+++ b/snowy-admin-web/.env.development
@@ -9,3 +9,6 @@ VITE_SET_DRAWER = true
# 本地环境
NODE_ENV = development
+
+# 检测更新(本地建议关闭)
+VITE_VERSION_UPDATE = false
diff --git a/snowy-admin-web/.env.production b/snowy-admin-web/.env.production
index 26326300..6b454a68 100644
--- a/snowy-admin-web/.env.production
+++ b/snowy-admin-web/.env.production
@@ -6,3 +6,6 @@ VITE_PORT = 81
# 开启设置抽屉
VITE_SET_DRAWER = false
+
+# 检测更新(生产建议开启)
+VITE_VERSION_UPDATE = true
diff --git a/snowy-admin-web/package.json b/snowy-admin-web/package.json
index abb8a77e..bdfbeea5 100644
--- a/snowy-admin-web/package.json
+++ b/snowy-admin-web/package.json
@@ -18,40 +18,40 @@
},
"dependencies": {
"@amap/amap-jsapi-loader": "1.0.1",
- "@ant-design/colors": "7.0.0",
+ "@ant-design/colors": "7.1.0",
"@ant-design/icons-vue": "7.0.1",
- "@antv/g2plot": "2.4.31",
+ "@antv/g2plot": "2.4.32",
"@chenfengyuan/vue-qrcode": "2.0.0",
"@highlightjs/vue-plugin": "2.1.0",
"@tinymce/tinymce-vue": "5.1.1",
- "@vue-office/docx": "1.6.0",
- "@vue-office/excel": "1.7.1",
- "@vue-office/pdf": "1.6.4",
- "ant-design-vue": "4.1.2",
- "axios": "1.6.2",
- "cropperjs": "1.6.1",
- "dayjs": "1.11.10",
- "echarts": "5.4.3",
+ "@vue-office/docx": "1.6.2",
+ "@vue-office/excel": "1.7.11",
+ "@vue-office/pdf": "2.0.2",
+ "ant-design-vue": "4.2.5",
+ "axios": "1.7.7",
+ "cropperjs": "1.6.2",
+ "dayjs": "1.11.13",
+ "echarts": "5.5.1",
"echarts-stat": "1.2.0",
"enquire.js": "2.1.6",
"event-source-polyfill": "1.0.31",
"fuse.js": "7.0.0",
- "highlight.js": "11.9.0",
- "hotkeys-js": "3.12.2",
- "js-pinyin": "0.2.5",
+ "highlight.js": "11.10.0",
+ "hotkeys-js": "3.13.7",
+ "js-pinyin": "0.2.7",
"lodash-es": "4.17.21",
"nprogress": "0.2.0",
- "pinia": "2.1.7",
- "qs": "6.11.2",
- "screenfull": "6.0.2",
+ "pinia": "2.2.2",
+ "qrcode": "1.5.4",
+ "qs": "6.13.0",
"sm-crypto": "0.3.13",
"snowflake-id": "1.1.0",
- "sortablejs": "1.15.1",
- "tinymce": "6.8.1",
- "vue": "3.4.21",
- "vue-cropper": "1.1.1",
- "vue-i18n": "9.8.0",
- "vue-router": "4.3.0",
+ "sortablejs": "1.15.3",
+ "tinymce": "7.3.0",
+ "vue": "3.5.10",
+ "vue-cropper": "1.1.4",
+ "vue-i18n": "10.0.0",
+ "vue-router": "4.4.5",
"vue3-colorpicker": "2.3.0",
"vue3-tree-org": "4.2.2",
"vuedraggable-es": "4.1.1"
@@ -61,23 +61,23 @@
"@vitejs/plugin-legacy": "5.2.0",
"@vitejs/plugin-vue": "4.5.2",
"@vitejs/plugin-vue-jsx": "3.1.0",
- "@vue/compiler-sfc": "3.3.10",
+ "@vue/compiler-sfc": "3.5.10",
"@vue/eslint-config-standard": "8.0.1",
"antd-less-to-css-variable": "1.0.5",
- "autoprefixer": "10.4.16",
- "eslint": "8.55.0",
+ "autoprefixer": "10.4.20",
+ "eslint": "8.57.0",
"eslint-config-prettier": "9.1.0",
"eslint-plugin-prettier": "5.0.1",
"eslint-plugin-vue": "9.7.0",
- "less": "4.1.3",
- "postcss": "8.4.32",
- "prettier": "3.1.0",
- "rollup-plugin-visualizer": "5.10.0",
- "tailwindcss": "3.3.6",
- "typescript": "5.3.3",
- "unplugin-auto-import": "0.17.2",
- "unplugin-vue-components": "0.26.0",
- "vite": "5.1.6",
+ "less": "4.2.0",
+ "postcss": "8.4.47",
+ "prettier": "3.3.3",
+ "rollup-plugin-visualizer": "5.12.0",
+ "tailwindcss": "3.4.13",
+ "typescript": "5.6.2",
+ "unplugin-auto-import": "0.18.3",
+ "unplugin-vue-components": "0.27.4",
+ "vite": "5.4.8",
"vite-plugin-compression": "0.5.1",
"vite-plugin-vue-setup-extend": "0.4.0",
"vue-eslint-parser": "9.3.2"
diff --git a/snowy-admin-web/src/api/gen/genBasicApi.js b/snowy-admin-web/src/api/gen/genBasicApi.js
index 45845c35..24abb79f 100644
--- a/snowy-admin-web/src/api/gen/genBasicApi.js
+++ b/snowy-admin-web/src/api/gen/genBasicApi.js
@@ -45,5 +45,13 @@ export default {
// 获取所有移动端模块
basicMobileModuleSelector(data) {
return request('mobileModuleSelector', data, 'get')
+ },
+ // 获取所有模块
+ basicModuleSelector(data) {
+ return request('moduleSelector', data, 'get')
+ },
+ // 获取所有菜单树包括未授权的
+ basicMenuTreeSelector(data) {
+ return request('menuTreeSelector', data, 'get')
}
}
diff --git a/snowy-admin-web/src/components/HomeCard/BizSlideshowCard/index.vue b/snowy-admin-web/src/components/HomeCard/BizSlideshowCard/index.vue
index a9cb4394..e98dbfeb 100644
--- a/snowy-admin-web/src/components/HomeCard/BizSlideshowCard/index.vue
+++ b/snowy-admin-web/src/components/HomeCard/BizSlideshowCard/index.vue
@@ -9,16 +9,14 @@
-
-
-
-
+
+
@@ -57,18 +55,18 @@
return
}
const detail = cloneDeep(value)
- let detailObj = {}
+ let result = {}
if (typeof detail !== 'object') {
- detailObj = JSON.parse(detail)
+ result = JSON.parse(detail)
}
// json内包含且是开启了点击,否则不处理
- if (detailObj.whetherToClick && detailObj.whetherToClick === 'ENABLE') {
- if (detailObj.skipMode && detailObj.skipMode === 'URL') {
- window.open(detailObj.url)
+ if (result.whetherToClick && result.whetherToClick === 'ENABLE') {
+ if (result.skipMode && result.skipMode === 'URL') {
+ window.open(result.url)
}
- if (detailObj.skipMode && detailObj.skipMode === 'ROUTER') {
+ if (result.skipMode && result.skipMode === 'ROUTER') {
router.replace({
- path: detailObj.url
+ path: result.url
})
}
}
diff --git a/snowy-admin-web/src/components/HomeCard/SysOpDataCard/index.vue b/snowy-admin-web/src/components/HomeCard/SysOpDataCard/index.vue
index f8be0299..aa552bc0 100644
--- a/snowy-admin-web/src/components/HomeCard/SysOpDataCard/index.vue
+++ b/snowy-admin-web/src/components/HomeCard/SysOpDataCard/index.vue
@@ -1,6 +1,8 @@
+
+
+
@@ -17,7 +20,7 @@
-
+
@@ -25,7 +28,7 @@
-
+
@@ -33,7 +36,7 @@
-
+
@@ -58,7 +61,6 @@
const title = ref('运维一览')
const apiLoading = ref(false)
const dataSource = ref({
- jobCount: 0,
sysDictCount: 0,
bizDictCount: 0,
backUserSessionCount: 0,
diff --git a/snowy-admin-web/src/components/XnBatchButton/index.vue b/snowy-admin-web/src/components/XnBatchButton/index.vue
index a1591ecf..24daca30 100644
--- a/snowy-admin-web/src/components/XnBatchButton/index.vue
+++ b/snowy-admin-web/src/components/XnBatchButton/index.vue
@@ -1,19 +1,34 @@
-
-
+
+
+
+
+
+
+ {{ props.buttonName }}
+
+
+
+
+
{{ props.buttonName }}
-
+
diff --git a/snowy-admin-web/src/components/XnEditor/index.vue b/snowy-admin-web/src/components/XnEditor/index.vue
index d6f114b9..58d79d83 100644
--- a/snowy-admin-web/src/components/XnEditor/index.vue
+++ b/snowy-admin-web/src/components/XnEditor/index.vue
@@ -55,10 +55,10 @@
})
const contentValue = ref()
const init = ref({
- language_url: import.meta.env.BASE_URL + 'tinymce/langs/zh_CN.js',
+ language_url: 'tinymce/langs/zh_CN.js',
language: 'zh_CN',
- skin_url: import.meta.env.BASE_URL + 'tinymce/skins/ui/oxide',
- content_css: import.meta.env.BASE_URL + 'tinymce/skins/content/default/content.css',
+ skin_url: 'tinymce/skins/ui/oxide',
+ content_css: 'tinymce/skins/content/default/content.css',
menubar: false,
statusbar: true,
plugins: props.plugins,
diff --git a/snowy-admin-web/src/components/XnUpload/index.vue b/snowy-admin-web/src/components/XnUpload/index.vue
index a30a932b..7ad914c1 100644
--- a/snowy-admin-web/src/components/XnUpload/index.vue
+++ b/snowy-admin-web/src/components/XnUpload/index.vue
@@ -76,6 +76,7 @@
diff --git a/snowy-admin-web/src/views/biz/notice/form.vue b/snowy-admin-web/src/views/biz/notice/form.vue
index fd76a693..14d50d7e 100644
--- a/snowy-admin-web/src/views/biz/notice/form.vue
+++ b/snowy-admin-web/src/views/biz/notice/form.vue
@@ -1,35 +1,33 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
- 这里只是标签的类型
-
+ 这里只是标签的类型
类型:
-
-
-
+
+
+
-
-
+
+
@@ -46,11 +44,11 @@
/>
-
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
- 关闭
- 保存
-
-
+
+
+
+
+
+
+
+
+ 关闭
+ 保存
+
+
diff --git a/snowy-admin-web/src/views/biz/notice/index.vue b/snowy-admin-web/src/views/biz/notice/index.vue
index e26eb8f4..2c633f89 100644
--- a/snowy-admin-web/src/views/biz/notice/index.vue
+++ b/snowy-admin-web/src/views/biz/notice/index.vue
@@ -1,73 +1,76 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 查询
- 重置
-
- {{ advanced ? '收起' : '展开' }}
-
-
-
-
-
-
-
-
-
-
- 新增
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+ {{ advanced ? '收起' : '展开' }}
+
+
+
+
+
+
+
+
+
+
+ 新增
+
+
+
+
+
未上传
-
+
{{ $TOOL.dictTypeData('BIZ_NOTICE_TYPE', record.type) }}
@@ -78,12 +81,12 @@
{{ $TOOL.dictTypeData('BIZ_NOTICE_TYPE', record.type) }}
无
-
-
-
+
+
+
{{ $TOOL.dictTypeData('BIZ_NOTICE_PLACE', textValue) }}
-
+
{{ $TOOL.dictTypeData('BIZ_NOTICE_STATUS', record.status) }}
-
-
+
+
详情
- 编辑
-
-
- 删除
-
-
-
-
-
-
-
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
diff --git a/snowy-admin-web/src/views/biz/org/index.vue b/snowy-admin-web/src/views/biz/org/index.vue
index 0b3afd36..eaba22c0 100644
--- a/snowy-admin-web/src/views/biz/org/index.vue
+++ b/snowy-admin-web/src/views/biz/org/index.vue
@@ -57,10 +57,13 @@
新增
-
diff --git a/snowy-admin-web/src/views/biz/position/index.vue b/snowy-admin-web/src/views/biz/position/index.vue
index 26bdb13b..f24971d2 100644
--- a/snowy-admin-web/src/views/biz/position/index.vue
+++ b/snowy-admin-web/src/views/biz/position/index.vue
@@ -57,10 +57,13 @@
新增
-
diff --git a/snowy-admin-web/src/views/biz/user/index.vue b/snowy-admin-web/src/views/biz/user/index.vue
index 522efd78..bb8eb35a 100644
--- a/snowy-admin-web/src/views/biz/user/index.vue
+++ b/snowy-admin-web/src/views/biz/user/index.vue
@@ -77,11 +77,13 @@
{{ $t('user.batchExportButton') }}
-
diff --git a/snowy-admin-web/src/views/dev/dict/category/index.vue b/snowy-admin-web/src/views/dev/dict/category/index.vue
index b7196bea..7e9968e5 100644
--- a/snowy-admin-web/src/views/dev/dict/category/index.vue
+++ b/snowy-admin-web/src/views/dev/dict/category/index.vue
@@ -183,14 +183,10 @@
id: record.id
}
]
- dictApi.dictDelete(params).then((res) => {
- if (res.code === 200) {
- tableRef.value.refresh(true)
- } else {
- res.message && tool.error(res.message)
- }
+ dictApi.dictDelete(params).then(() => {
+ tableRef.value.refresh()
+ refreshStoreDict()
})
- refreshStoreDict()
}
// 表单界面回调
const formSuccessful = () => {
diff --git a/snowy-admin-web/src/views/dev/file/index.vue b/snowy-admin-web/src/views/dev/file/index.vue
index 665b913c..d5e56b8a 100644
--- a/snowy-admin-web/src/views/dev/file/index.vue
+++ b/snowy-admin-web/src/views/dev/file/index.vue
@@ -48,7 +48,13 @@
文件上传
-
+
diff --git a/snowy-admin-web/src/views/dev/job/form.vue b/snowy-admin-web/src/views/dev/job/form.vue
index fc42c4f9..767486dc 100644
--- a/snowy-admin-web/src/views/dev/job/form.vue
+++ b/snowy-admin-web/src/views/dev/job/form.vue
@@ -19,6 +19,14 @@
+
+
+
@@ -54,7 +62,18 @@
sortCode: 99
}
if (record) {
- formData.value = Object.assign({}, record)
+ submitLoading.value = true
+ const param = {
+ id: record.id
+ }
+ jobApi
+ .jobDetail(param)
+ .then((data) => {
+ formData.value = Object.assign({}, data)
+ })
+ .finally(() => {
+ submitLoading.value = false
+ })
}
// 加载定时任务类列表
jobApi.jobGetActionClass().then((data) => {
diff --git a/snowy-admin-web/src/views/dev/job/index.vue b/snowy-admin-web/src/views/dev/job/index.vue
index 809f2652..b31a314c 100644
--- a/snowy-admin-web/src/views/dev/job/index.vue
+++ b/snowy-admin-web/src/views/dev/job/index.vue
@@ -51,7 +51,13 @@
新增
-
+
diff --git a/snowy-admin-web/src/views/dev/message/index.vue b/snowy-admin-web/src/views/dev/message/index.vue
index d13c33e4..af643058 100644
--- a/snowy-admin-web/src/views/dev/message/index.vue
+++ b/snowy-admin-web/src/views/dev/message/index.vue
@@ -34,7 +34,13 @@
发送站内信
-
+
diff --git a/snowy-admin-web/src/views/dev/slideshow/form.vue b/snowy-admin-web/src/views/dev/slideshow/form.vue
index be235876..8bd8bbe7 100644
--- a/snowy-admin-web/src/views/dev/slideshow/form.vue
+++ b/snowy-admin-web/src/views/dev/slideshow/form.vue
@@ -1,90 +1,89 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
+
-
-
-
+
+
-
-
+
+
-
-
-
-
- 关闭
- 保存
-
-
+
+
+
+
+ 关闭
+ 保存
+
+
diff --git a/snowy-admin-web/src/views/dev/slideshow/index.vue b/snowy-admin-web/src/views/dev/slideshow/index.vue
index f6c3d486..93afc624 100644
--- a/snowy-admin-web/src/views/dev/slideshow/index.vue
+++ b/snowy-admin-web/src/views/dev/slideshow/index.vue
@@ -1,38 +1,38 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
- 查询
- 重置
-
-
-
-
+
+
+
+ 查询
+ 重置
+
+
+
+
更多
@@ -59,24 +59,29 @@
-
-
-
-
- 新增
-
-
-
-
-
-
- {{ $TOOL.dictTypeData('DEV_SLIDESHOW_PLACE', textValue) }}
-
+
+
+
+
+ 新增
+
+
+
+
+
+
+ {{
+ $TOOL.dictTypeData('DEV_SLIDESHOW_PLACE', textValue)
+ }}
+
-
+
-
-
- 编辑
-
-
- 删除
-
-
-
-
-
-
-
-
+
+
+ 编辑
+
+
+ 删除
+
+
+
+
+
+
+
diff --git a/snowy-admin-web/src/views/dev/slideshow/subForm.vue b/snowy-admin-web/src/views/dev/slideshow/subForm.vue
index a3bfe3e8..a00b50d3 100644
--- a/snowy-admin-web/src/views/dev/slideshow/subForm.vue
+++ b/snowy-admin-web/src/views/dev/slideshow/subForm.vue
@@ -1,25 +1,33 @@
-
+
-
+
-
+
-
+
-
+
@@ -28,7 +36,7 @@