mirror of https://gitee.com/xiaonuobase/snowy
parent
c2552c29c8
commit
66a62cafa7
2
pom.xml
2
pom.xml
|
@ -375,7 +375,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
|
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
|
||||||
<version>4.3.0</version>
|
<version>4.3.1</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<!-- mysql -->
|
<!-- mysql -->
|
||||||
|
|
|
@ -9,3 +9,6 @@ VITE_SET_DRAWER = true
|
||||||
|
|
||||||
# 本地环境
|
# 本地环境
|
||||||
NODE_ENV = development
|
NODE_ENV = development
|
||||||
|
|
||||||
|
# 检测更新(本地建议关闭)
|
||||||
|
VITE_VERSION_UPDATE = false
|
||||||
|
|
|
@ -6,3 +6,6 @@ VITE_PORT = 81
|
||||||
|
|
||||||
# 开启设置抽屉
|
# 开启设置抽屉
|
||||||
VITE_SET_DRAWER = false
|
VITE_SET_DRAWER = false
|
||||||
|
|
||||||
|
# 检测更新(生产建议开启)
|
||||||
|
VITE_VERSION_UPDATE = true
|
||||||
|
|
|
@ -18,40 +18,40 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@amap/amap-jsapi-loader": "1.0.1",
|
"@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",
|
"@ant-design/icons-vue": "7.0.1",
|
||||||
"@antv/g2plot": "2.4.31",
|
"@antv/g2plot": "2.4.32",
|
||||||
"@chenfengyuan/vue-qrcode": "2.0.0",
|
"@chenfengyuan/vue-qrcode": "2.0.0",
|
||||||
"@highlightjs/vue-plugin": "2.1.0",
|
"@highlightjs/vue-plugin": "2.1.0",
|
||||||
"@tinymce/tinymce-vue": "5.1.1",
|
"@tinymce/tinymce-vue": "5.1.1",
|
||||||
"@vue-office/docx": "1.6.0",
|
"@vue-office/docx": "1.6.2",
|
||||||
"@vue-office/excel": "1.7.1",
|
"@vue-office/excel": "1.7.11",
|
||||||
"@vue-office/pdf": "1.6.4",
|
"@vue-office/pdf": "2.0.2",
|
||||||
"ant-design-vue": "4.1.2",
|
"ant-design-vue": "4.2.5",
|
||||||
"axios": "1.6.2",
|
"axios": "1.7.7",
|
||||||
"cropperjs": "1.6.1",
|
"cropperjs": "1.6.2",
|
||||||
"dayjs": "1.11.10",
|
"dayjs": "1.11.13",
|
||||||
"echarts": "5.4.3",
|
"echarts": "5.5.1",
|
||||||
"echarts-stat": "1.2.0",
|
"echarts-stat": "1.2.0",
|
||||||
"enquire.js": "2.1.6",
|
"enquire.js": "2.1.6",
|
||||||
"event-source-polyfill": "1.0.31",
|
"event-source-polyfill": "1.0.31",
|
||||||
"fuse.js": "7.0.0",
|
"fuse.js": "7.0.0",
|
||||||
"highlight.js": "11.9.0",
|
"highlight.js": "11.10.0",
|
||||||
"hotkeys-js": "3.12.2",
|
"hotkeys-js": "3.13.7",
|
||||||
"js-pinyin": "0.2.5",
|
"js-pinyin": "0.2.7",
|
||||||
"lodash-es": "4.17.21",
|
"lodash-es": "4.17.21",
|
||||||
"nprogress": "0.2.0",
|
"nprogress": "0.2.0",
|
||||||
"pinia": "2.1.7",
|
"pinia": "2.2.2",
|
||||||
"qs": "6.11.2",
|
"qrcode": "1.5.4",
|
||||||
"screenfull": "6.0.2",
|
"qs": "6.13.0",
|
||||||
"sm-crypto": "0.3.13",
|
"sm-crypto": "0.3.13",
|
||||||
"snowflake-id": "1.1.0",
|
"snowflake-id": "1.1.0",
|
||||||
"sortablejs": "1.15.1",
|
"sortablejs": "1.15.3",
|
||||||
"tinymce": "6.8.1",
|
"tinymce": "7.3.0",
|
||||||
"vue": "3.4.21",
|
"vue": "3.5.10",
|
||||||
"vue-cropper": "1.1.1",
|
"vue-cropper": "1.1.4",
|
||||||
"vue-i18n": "9.8.0",
|
"vue-i18n": "10.0.0",
|
||||||
"vue-router": "4.3.0",
|
"vue-router": "4.4.5",
|
||||||
"vue3-colorpicker": "2.3.0",
|
"vue3-colorpicker": "2.3.0",
|
||||||
"vue3-tree-org": "4.2.2",
|
"vue3-tree-org": "4.2.2",
|
||||||
"vuedraggable-es": "4.1.1"
|
"vuedraggable-es": "4.1.1"
|
||||||
|
@ -61,23 +61,23 @@
|
||||||
"@vitejs/plugin-legacy": "5.2.0",
|
"@vitejs/plugin-legacy": "5.2.0",
|
||||||
"@vitejs/plugin-vue": "4.5.2",
|
"@vitejs/plugin-vue": "4.5.2",
|
||||||
"@vitejs/plugin-vue-jsx": "3.1.0",
|
"@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",
|
"@vue/eslint-config-standard": "8.0.1",
|
||||||
"antd-less-to-css-variable": "1.0.5",
|
"antd-less-to-css-variable": "1.0.5",
|
||||||
"autoprefixer": "10.4.16",
|
"autoprefixer": "10.4.20",
|
||||||
"eslint": "8.55.0",
|
"eslint": "8.57.0",
|
||||||
"eslint-config-prettier": "9.1.0",
|
"eslint-config-prettier": "9.1.0",
|
||||||
"eslint-plugin-prettier": "5.0.1",
|
"eslint-plugin-prettier": "5.0.1",
|
||||||
"eslint-plugin-vue": "9.7.0",
|
"eslint-plugin-vue": "9.7.0",
|
||||||
"less": "4.1.3",
|
"less": "4.2.0",
|
||||||
"postcss": "8.4.32",
|
"postcss": "8.4.47",
|
||||||
"prettier": "3.1.0",
|
"prettier": "3.3.3",
|
||||||
"rollup-plugin-visualizer": "5.10.0",
|
"rollup-plugin-visualizer": "5.12.0",
|
||||||
"tailwindcss": "3.3.6",
|
"tailwindcss": "3.4.13",
|
||||||
"typescript": "5.3.3",
|
"typescript": "5.6.2",
|
||||||
"unplugin-auto-import": "0.17.2",
|
"unplugin-auto-import": "0.18.3",
|
||||||
"unplugin-vue-components": "0.26.0",
|
"unplugin-vue-components": "0.27.4",
|
||||||
"vite": "5.1.6",
|
"vite": "5.4.8",
|
||||||
"vite-plugin-compression": "0.5.1",
|
"vite-plugin-compression": "0.5.1",
|
||||||
"vite-plugin-vue-setup-extend": "0.4.0",
|
"vite-plugin-vue-setup-extend": "0.4.0",
|
||||||
"vue-eslint-parser": "9.3.2"
|
"vue-eslint-parser": "9.3.2"
|
||||||
|
|
|
@ -45,5 +45,13 @@ export default {
|
||||||
// 获取所有移动端模块
|
// 获取所有移动端模块
|
||||||
basicMobileModuleSelector(data) {
|
basicMobileModuleSelector(data) {
|
||||||
return request('mobileModuleSelector', data, 'get')
|
return request('mobileModuleSelector', data, 'get')
|
||||||
|
},
|
||||||
|
// 获取所有模块
|
||||||
|
basicModuleSelector(data) {
|
||||||
|
return request('moduleSelector', data, 'get')
|
||||||
|
},
|
||||||
|
// 获取所有菜单树包括未授权的
|
||||||
|
basicMenuTreeSelector(data) {
|
||||||
|
return request('menuTreeSelector', data, 'get')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,16 +9,14 @@
|
||||||
<template #nextArrow>
|
<template #nextArrow>
|
||||||
<div class="custom-slick-arrow" style="right: 10px"><RightOutlined /></div>
|
<div class="custom-slick-arrow" style="right: 10px"><RightOutlined /></div>
|
||||||
</template>
|
</template>
|
||||||
<div v-if="!isEmpty(slideshowList)">
|
<img
|
||||||
<img
|
v-for="item in slideshowList"
|
||||||
v-for="item in slideshowList"
|
:key="item.id"
|
||||||
:key="item.id"
|
:src="item.image"
|
||||||
:src="item.image"
|
class="carousel-images"
|
||||||
class="carousel-images"
|
@click="leaveForOpen(item.pathDetails)"
|
||||||
@click="leaveForOpen(item.pathDetails)"
|
/>
|
||||||
/>
|
<a-empty v-if="isEmpty(slideshowList)" :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
||||||
</div>
|
|
||||||
<a-empty v-else :image="Empty.PRESENTED_IMAGE_SIMPLE" />
|
|
||||||
</a-carousel>
|
</a-carousel>
|
||||||
</a-card>
|
</a-card>
|
||||||
</template>
|
</template>
|
||||||
|
@ -57,18 +55,18 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const detail = cloneDeep(value)
|
const detail = cloneDeep(value)
|
||||||
let detailObj = {}
|
let result = {}
|
||||||
if (typeof detail !== 'object') {
|
if (typeof detail !== 'object') {
|
||||||
detailObj = JSON.parse(detail)
|
result = JSON.parse(detail)
|
||||||
}
|
}
|
||||||
// json内包含且是开启了点击,否则不处理
|
// json内包含且是开启了点击,否则不处理
|
||||||
if (detailObj.whetherToClick && detailObj.whetherToClick === 'ENABLE') {
|
if (result.whetherToClick && result.whetherToClick === 'ENABLE') {
|
||||||
if (detailObj.skipMode && detailObj.skipMode === 'URL') {
|
if (result.skipMode && result.skipMode === 'URL') {
|
||||||
window.open(detailObj.url)
|
window.open(result.url)
|
||||||
}
|
}
|
||||||
if (detailObj.skipMode && detailObj.skipMode === 'ROUTER') {
|
if (result.skipMode && result.skipMode === 'ROUTER') {
|
||||||
router.replace({
|
router.replace({
|
||||||
path: detailObj.url
|
path: result.url
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<a-card :title="title" :bordered="false" :loading="apiLoading">
|
<a-card :title="title" :bordered="false" :loading="apiLoading">
|
||||||
<a-row>
|
<a-row>
|
||||||
|
<!-- 因租户内定时任务需解决,暂先注释 -->
|
||||||
|
<!--
|
||||||
<a-col :span="4">
|
<a-col :span="4">
|
||||||
<a-statistic :value="dataSource.jobCount">
|
<a-statistic :value="dataSource.jobCount">
|
||||||
<template #title>
|
<template #title>
|
||||||
|
@ -9,7 +11,8 @@
|
||||||
</template>
|
</template>
|
||||||
</a-statistic>
|
</a-statistic>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="4">
|
-->
|
||||||
|
<a-col :span="5">
|
||||||
<a-statistic :value="dataSource.sysDictCount">
|
<a-statistic :value="dataSource.sysDictCount">
|
||||||
<template #title>
|
<template #title>
|
||||||
<read-outlined style="color: #4b4b4b" />
|
<read-outlined style="color: #4b4b4b" />
|
||||||
|
@ -17,7 +20,7 @@
|
||||||
</template>
|
</template>
|
||||||
</a-statistic>
|
</a-statistic>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="4">
|
<a-col :span="5">
|
||||||
<a-statistic :value="dataSource.bizDictCount">
|
<a-statistic :value="dataSource.bizDictCount">
|
||||||
<template #title>
|
<template #title>
|
||||||
<read-outlined style="color: #353779" />
|
<read-outlined style="color: #353779" />
|
||||||
|
@ -25,7 +28,7 @@
|
||||||
</template>
|
</template>
|
||||||
</a-statistic>
|
</a-statistic>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="4">
|
<a-col :span="5">
|
||||||
<a-statistic :value="dataSource.backUserSessionCount">
|
<a-statistic :value="dataSource.backUserSessionCount">
|
||||||
<template #title>
|
<template #title>
|
||||||
<usergroup-delete-outlined style="color: #3ceecd" />
|
<usergroup-delete-outlined style="color: #3ceecd" />
|
||||||
|
@ -33,7 +36,7 @@
|
||||||
</template>
|
</template>
|
||||||
</a-statistic>
|
</a-statistic>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="4">
|
<a-col :span="5">
|
||||||
<a-statistic :value="dataSource.clientUserSessionCount">
|
<a-statistic :value="dataSource.clientUserSessionCount">
|
||||||
<template #title>
|
<template #title>
|
||||||
<UserSwitchOutlined style="color: rgba(229, 159, 18, 0.35)" />
|
<UserSwitchOutlined style="color: rgba(229, 159, 18, 0.35)" />
|
||||||
|
@ -58,7 +61,6 @@
|
||||||
const title = ref('运维一览')
|
const title = ref('运维一览')
|
||||||
const apiLoading = ref(false)
|
const apiLoading = ref(false)
|
||||||
const dataSource = ref({
|
const dataSource = ref({
|
||||||
jobCount: 0,
|
|
||||||
sysDictCount: 0,
|
sysDictCount: 0,
|
||||||
bizDictCount: 0,
|
bizDictCount: 0,
|
||||||
backUserSessionCount: 0,
|
backUserSessionCount: 0,
|
||||||
|
|
|
@ -1,19 +1,34 @@
|
||||||
<template>
|
<template>
|
||||||
<a-popconfirm title="批量处理此信息?" :open="batchVisible" @openChange="batchVisibleChange" @confirm="deleteBatch">
|
<div v-if="isPopconFirm">
|
||||||
<a-button :type="props.buttonType" :danger="props.buttonDanger" :size="props.size" :loading="buttonLoading">
|
<a-popconfirm title="批量处理此信息?" :open="batchVisible" @openChange="batchVisibleChange" @confirm="deleteBatch">
|
||||||
|
<a-button :type="props.buttonType" :danger="props.buttonDanger" :size="props.size" :loading="loading">
|
||||||
|
<template #icon v-if="props.icon">
|
||||||
|
<component :is="props.icon" :style="{ color: props.color }" />
|
||||||
|
</template>
|
||||||
|
{{ props.buttonName }}
|
||||||
|
</a-button>
|
||||||
|
</a-popconfirm>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<a-button
|
||||||
|
:type="props.buttonType"
|
||||||
|
:danger="props.buttonDanger"
|
||||||
|
:size="props.size"
|
||||||
|
:loading="loading"
|
||||||
|
@click="deleteBatch"
|
||||||
|
>
|
||||||
<template #icon v-if="props.icon">
|
<template #icon v-if="props.icon">
|
||||||
<component :is="props.icon" :style="{ color: props.color }" />
|
<component :is="props.icon" :style="{ color: props.color }" />
|
||||||
</template>
|
</template>
|
||||||
{{ props.buttonName }}
|
{{ props.buttonName }}
|
||||||
</a-button>
|
</a-button>
|
||||||
</a-popconfirm>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="commonBatchButton">
|
<script setup name="commonBatchButton">
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
const batchVisible = ref(false)
|
const batchVisible = ref(false)
|
||||||
const emit = defineEmits({ batchCallBack: null })
|
const emit = defineEmits({ batchCallBack: null })
|
||||||
const buttonLoading = ref(false)
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
idKey: {
|
idKey: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -46,6 +61,15 @@
|
||||||
color: {
|
color: {
|
||||||
type: String,
|
type: String,
|
||||||
default: () => ''
|
default: () => ''
|
||||||
|
},
|
||||||
|
// 是否确认提示
|
||||||
|
isPopconFirm: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => true
|
||||||
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: () => false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// 参数校验
|
// 参数校验
|
||||||
|
@ -53,17 +77,26 @@
|
||||||
if (batchVisible.value) {
|
if (batchVisible.value) {
|
||||||
batchVisible.value = false
|
batchVisible.value = false
|
||||||
return false
|
return false
|
||||||
}
|
|
||||||
if (props.selectedRowKeys.length < 1) {
|
|
||||||
message.warning('请选择一条或多条数据')
|
|
||||||
batchVisible.value = false
|
|
||||||
return false
|
|
||||||
} else {
|
} else {
|
||||||
batchVisible.value = true
|
if (props.selectedRowKeys.length < 1) {
|
||||||
|
message.warning('请选择一条或多条数据')
|
||||||
|
batchVisible.value = false
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
batchVisible.value = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 批量操作
|
// 批量操作
|
||||||
const deleteBatch = () => {
|
const deleteBatch = () => {
|
||||||
|
if (!props.isPopconFirm) {
|
||||||
|
if (props.selectedRowKeys.length < 1) {
|
||||||
|
message.warning('请选择一条或多条数据')
|
||||||
|
batchVisible.value = false
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
const params = props.selectedRowKeys.map((m) => {
|
const params = props.selectedRowKeys.map((m) => {
|
||||||
return {
|
return {
|
||||||
[props.idKey]: m
|
[props.idKey]: m
|
||||||
|
@ -72,12 +105,4 @@
|
||||||
// 发起方法调用,谁的谁来实现
|
// 发起方法调用,谁的谁来实现
|
||||||
emit('batchCallBack', params)
|
emit('batchCallBack', params)
|
||||||
}
|
}
|
||||||
// 打开loading
|
|
||||||
const openLoading = () => {
|
|
||||||
buttonLoading.value = true
|
|
||||||
}
|
|
||||||
// 关闭loading
|
|
||||||
const closeLoading = () => {
|
|
||||||
buttonLoading.value = true
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -55,10 +55,10 @@
|
||||||
})
|
})
|
||||||
const contentValue = ref()
|
const contentValue = ref()
|
||||||
const init = 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',
|
language: 'zh_CN',
|
||||||
skin_url: import.meta.env.BASE_URL + 'tinymce/skins/ui/oxide',
|
skin_url: 'tinymce/skins/ui/oxide',
|
||||||
content_css: import.meta.env.BASE_URL + 'tinymce/skins/content/default/content.css',
|
content_css: 'tinymce/skins/content/default/content.css',
|
||||||
menubar: false,
|
menubar: false,
|
||||||
statusbar: true,
|
statusbar: true,
|
||||||
plugins: props.plugins,
|
plugins: props.plugins,
|
||||||
|
|
|
@ -76,6 +76,7 @@
|
||||||
<script setup name="uploadIndex">
|
<script setup name="uploadIndex">
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
import sysConfig from '@/config/index'
|
import sysConfig from '@/config/index'
|
||||||
|
import { convertUrl } from '@/utils/apiAdaptive'
|
||||||
import { message, Upload } from 'ant-design-vue'
|
import { message, Upload } from 'ant-design-vue'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
const fileList = ref([])
|
const fileList = ref([])
|
||||||
|
@ -91,19 +92,19 @@
|
||||||
// 上传返回id
|
// 上传返回id
|
||||||
uploadReturnIdApi: {
|
uploadReturnIdApi: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '/dev/file/uploadLocalReturnId',
|
default: convertUrl('/dev/file/uploadLocalReturnId'),
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
// 上传返回url
|
// 上传返回url
|
||||||
uploadDynamicReturnUrlApi: {
|
uploadDynamicReturnUrlApi: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '/dev/file/uploadDynamicReturnUrl',
|
default: convertUrl('/dev/file/uploadDynamicReturnUrl'),
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
// 当上传接口为id的情况下,配置下载接口
|
// 当上传接口为id的情况下,配置下载接口
|
||||||
uploadIdDownloadUrl: {
|
uploadIdDownloadUrl: {
|
||||||
type: String,
|
type: String,
|
||||||
default: '/dev/file/download?id=',
|
default: convertUrl('/dev/file/download?id='),
|
||||||
required: false
|
required: false
|
||||||
},
|
},
|
||||||
// 上传样式或图片方式 file || drag || image
|
// 上传样式或图片方式 file || drag || image
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||||
*/
|
*/
|
||||||
const DEFAULT_CONFIG = {
|
const DEFAULT_CONFIG = {
|
||||||
|
// 是否是微服务cloud版本
|
||||||
|
CLOUD_SERVER: false,
|
||||||
|
|
||||||
// 首页地址
|
// 首页地址
|
||||||
DASHBOARD_URL: '/index',
|
DASHBOARD_URL: '/index',
|
||||||
|
|
||||||
|
@ -18,9 +21,6 @@ const DEFAULT_CONFIG = {
|
||||||
// 请求超时
|
// 请求超时
|
||||||
TIMEOUT: 60000,
|
TIMEOUT: 60000,
|
||||||
|
|
||||||
// 版本更新时间 默认10s
|
|
||||||
UPDATE_VERSION_TIME: 10000,
|
|
||||||
|
|
||||||
// TokenName // Authorization
|
// TokenName // Authorization
|
||||||
TOKEN_NAME: 'token',
|
TOKEN_NAME: 'token',
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ const DEFAULT_CONFIG = {
|
||||||
SNOWY_LAYOUT_TAGS_OPEN: true,
|
SNOWY_LAYOUT_TAGS_OPEN: true,
|
||||||
|
|
||||||
// 是否开启展示面包屑
|
// 是否开启展示面包屑
|
||||||
SNOWY_BREADCRUMD_OPEN: false,
|
SNOWY_BREADCRUMB_OPEN: false,
|
||||||
|
|
||||||
// 顶栏是否应用主题色
|
// 顶栏是否应用主题色
|
||||||
SNOWY_TOP_HEADER_THEME_COLOR_OPEN: false,
|
SNOWY_TOP_HEADER_THEME_COLOR_OPEN: false,
|
||||||
|
@ -61,10 +61,10 @@ const DEFAULT_CONFIG = {
|
||||||
SNOWY_LOGIN_USER_WATERMARK_OPEN: false,
|
SNOWY_LOGIN_USER_WATERMARK_OPEN: false,
|
||||||
|
|
||||||
// 页脚版权信息
|
// 页脚版权信息
|
||||||
SNOWY_FOOTER_COPYRIGHT_OPEN: true,
|
SNOWY_FOOTER_COPYRIGHT_OPEN: false,
|
||||||
|
|
||||||
// 圆角风格
|
// 圆角风格
|
||||||
SNOWY_ROUNDED_CORNER_STYLE_OPEN: true,
|
SNOWY_ROUNDED_CORNER_STYLE_OPEN: false,
|
||||||
|
|
||||||
// 语言
|
// 语言
|
||||||
LANG: 'zh-cn',
|
LANG: 'zh-cn',
|
||||||
|
|
|
@ -60,6 +60,7 @@
|
||||||
import router from '@/router'
|
import router from '@/router'
|
||||||
import { onMounted } from 'vue'
|
import { onMounted } from 'vue'
|
||||||
import sysConfig from '@/config'
|
import sysConfig from '@/config'
|
||||||
|
import { convertUrl } from '@/utils/apiAdaptive'
|
||||||
import { EventSourcePolyfill } from 'event-source-polyfill'
|
import { EventSourcePolyfill } from 'event-source-polyfill'
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
|
|
||||||
|
@ -76,7 +77,7 @@
|
||||||
const createSseConnect = () => {
|
const createSseConnect = () => {
|
||||||
if (window.EventSource) {
|
if (window.EventSource) {
|
||||||
let clientId = tool.data.get('CLIENTID') ? tool.data.get('CLIENTID') : ''
|
let clientId = tool.data.get('CLIENTID') ? tool.data.get('CLIENTID') : ''
|
||||||
let url = sysConfig.API_URL + '/dev/message/createSseConnect?clientId=' + clientId
|
let url = sysConfig.API_URL + convertUrl('/dev/message/createSseConnect?clientId=') + clientId
|
||||||
// heartbeatTimeout:心跳超时监测 30s
|
// heartbeatTimeout:心跳超时监测 30s
|
||||||
let source = new EventSourcePolyfill(url, {
|
let source = new EventSourcePolyfill(url, {
|
||||||
headers: { token: tool.data.get('TOKEN') },
|
headers: { token: tool.data.get('TOKEN') },
|
||||||
|
|
|
@ -53,7 +53,12 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<a-tab-pane v-for="tag in tagList" :key="tag.fullPath" :tab="tag.meta.title" :closable="!tag.meta.affix">
|
<a-tab-pane v-for="tag in tagList" :key="tag.fullPath" :closable="!tag.meta.affix">
|
||||||
|
<template #tab>
|
||||||
|
<span :key="tag.meta.key">
|
||||||
|
{{ tag.meta.title }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
</a-tab-pane>
|
</a-tab-pane>
|
||||||
</a-tabs>
|
</a-tabs>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -88,7 +88,6 @@
|
||||||
import sysConfig from '@/config/index'
|
import sysConfig from '@/config/index'
|
||||||
import dictApi from '@/api/dev/dictApi'
|
import dictApi from '@/api/dev/dictApi'
|
||||||
|
|
||||||
let timer = null
|
|
||||||
const store = globalStore()
|
const store = globalStore()
|
||||||
const kStore = keepAliveStore()
|
const kStore = keepAliveStore()
|
||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
|
@ -265,52 +264,47 @@
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
clearUpdateVersion()
|
|
||||||
window.removeEventListener('resize', onLayoutResize)
|
window.removeEventListener('resize', onLayoutResize)
|
||||||
window.removeEventListener('resize', getNav)
|
window.removeEventListener('resize', getNav)
|
||||||
})
|
})
|
||||||
// 新版检测
|
// 新版检测
|
||||||
const updateVersion = () => {
|
const updateVersion = () => {
|
||||||
timer = setInterval(async () => {
|
const updateVersionOpen = import.meta.env.VITE_VERSION_UPDATE
|
||||||
// 本地
|
if (updateVersionOpen) {
|
||||||
let localVersion = getLocalHash()
|
setTimeout(async () => {
|
||||||
// 线上
|
// 本地
|
||||||
let onlineVersion = await checkHash()
|
let localVersion = getLocalHash()
|
||||||
// 如果不一样,提示更新
|
// 线上
|
||||||
if (localVersion !== onlineVersion) {
|
let onlineVersion = await checkHash()
|
||||||
if (document.querySelector('.notification-update-version')) {
|
// 如果不一样,提示更新
|
||||||
return
|
if (localVersion !== onlineVersion) {
|
||||||
|
if (document.querySelector('.notification-update-version')) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const key = `open${Date.now()}`
|
||||||
|
notification.open({
|
||||||
|
type: 'info',
|
||||||
|
message: '发现新版本',
|
||||||
|
description: '检测到新版本,请刷新后使用',
|
||||||
|
duration: 0,
|
||||||
|
class: 'notification-update-version',
|
||||||
|
btn: () =>
|
||||||
|
h(
|
||||||
|
Button,
|
||||||
|
{
|
||||||
|
type: 'primary',
|
||||||
|
size: 'small',
|
||||||
|
onClick: () => {
|
||||||
|
notification.close(key)
|
||||||
|
window.location.reload()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ default: () => '立即更新' }
|
||||||
|
),
|
||||||
|
key
|
||||||
|
})
|
||||||
}
|
}
|
||||||
const key = `open${Date.now()}`
|
}, 3000)
|
||||||
notification.open({
|
|
||||||
type: 'info',
|
|
||||||
message: '发现新版本',
|
|
||||||
description: '检测到新版本,请刷新后使用',
|
|
||||||
duration: 0,
|
|
||||||
class: 'notification-update-version',
|
|
||||||
btn: () =>
|
|
||||||
h(
|
|
||||||
Button,
|
|
||||||
{
|
|
||||||
type: 'primary',
|
|
||||||
size: 'small',
|
|
||||||
onClick: () => {
|
|
||||||
notification.close(key)
|
|
||||||
window.location.reload()
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ default: () => '立即更新' }
|
|
||||||
),
|
|
||||||
key
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}, sysConfig.UPDATE_VERSION_TIME)
|
|
||||||
}
|
|
||||||
// 销毁定时器
|
|
||||||
const clearUpdateVersion = () => {
|
|
||||||
if (timer) {
|
|
||||||
clearInterval(timer)
|
|
||||||
timer = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 动态获取横向导航栏隐藏数量
|
// 动态获取横向导航栏隐藏数量
|
||||||
|
@ -339,7 +333,7 @@
|
||||||
menuList.value = menuNavList
|
menuList.value = menuNavList
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// 如果大于了课显示的区域,就将其隐藏
|
// 如果大于了显示的区域,就将其隐藏
|
||||||
const showNav = menuNavList.slice(0, startIndex)
|
const showNav = menuNavList.slice(0, startIndex)
|
||||||
const hiddenNav = menuNavList.slice(startIndex, menuNavList.length)
|
const hiddenNav = menuNavList.slice(startIndex, menuNavList.length)
|
||||||
menuList.value = showNav
|
menuList.value = showNav
|
||||||
|
|
|
@ -36,7 +36,7 @@ const routes_404 = [
|
||||||
const routes = [...systemRouter, ...whiteListRouters, ...routes_404]
|
const routes = [...systemRouter, ...whiteListRouters, ...routes_404]
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(),
|
||||||
routes
|
routes
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -45,7 +45,6 @@ const router = createRouter({
|
||||||
|
|
||||||
// 判断是否已加载过动态/静态路由
|
// 判断是否已加载过动态/静态路由
|
||||||
const isGetRouter = ref(false)
|
const isGetRouter = ref(false)
|
||||||
|
|
||||||
// 白名单校验
|
// 白名单校验
|
||||||
const exportWhiteListFromRouter = (router) => {
|
const exportWhiteListFromRouter = (router) => {
|
||||||
const res = []
|
const res = []
|
||||||
|
@ -53,7 +52,6 @@ const exportWhiteListFromRouter = (router) => {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
const whiteList = exportWhiteListFromRouter(whiteListRouters)
|
const whiteList = exportWhiteListFromRouter(whiteListRouters)
|
||||||
|
|
||||||
router.beforeEach(async (to, from, next) => {
|
router.beforeEach(async (to, from, next) => {
|
||||||
NProgress.start()
|
NProgress.start()
|
||||||
const store = globalStore()
|
const store = globalStore()
|
||||||
|
@ -70,7 +68,6 @@ router.beforeEach(async (to, from, next) => {
|
||||||
// NProgress.done()
|
// NProgress.done()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isGetRouter.value) {
|
if (!isGetRouter.value) {
|
||||||
// 初始化菜单加载,代码位置不能变动
|
// 初始化菜单加载,代码位置不能变动
|
||||||
const menuStore = useMenuStore()
|
const menuStore = useMenuStore()
|
||||||
|
@ -102,6 +99,14 @@ router.beforeEach(async (to, from, next) => {
|
||||||
if (token) {
|
if (token) {
|
||||||
// 有token的时候才保存登录之前要访问的页面
|
// 有token的时候才保存登录之前要访问的页面
|
||||||
tool.data.set('LAST_VIEWS_PATH', to.fullPath)
|
tool.data.set('LAST_VIEWS_PATH', to.fullPath)
|
||||||
|
// 验证menu或则用户信息是否存在,不存在那么就是被删除或者退出或者清理缓存了
|
||||||
|
if (!tool.data.get('MENU') || !tool.data.get('USER_INFO')) {
|
||||||
|
tool.data.remove('TOKEN')
|
||||||
|
next({
|
||||||
|
path: '/login'
|
||||||
|
})
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!token) {
|
if (!token) {
|
||||||
|
|
|
@ -40,7 +40,7 @@ export const globalStore = defineStore('global', () => {
|
||||||
// 多标签栏
|
// 多标签栏
|
||||||
const layoutTagsOpen = ref(getCacheConfig('SNOWY_LAYOUT_TAGS_OPEN'))
|
const layoutTagsOpen = ref(getCacheConfig('SNOWY_LAYOUT_TAGS_OPEN'))
|
||||||
// 是否展示面包屑
|
// 是否展示面包屑
|
||||||
const breadcrumbOpen = ref(getCacheConfig('SNOWY_BREADCRUMD_OPEN'))
|
const breadcrumbOpen = ref(getCacheConfig('SNOWY_BREADCRUMB_OPEN'))
|
||||||
// 是否开启固定宽度(顶栏菜单)
|
// 是否开启固定宽度(顶栏菜单)
|
||||||
const fixedWidth = ref(getCacheConfig('SNOWY_FIXEDWIDTH_OPEN'))
|
const fixedWidth = ref(getCacheConfig('SNOWY_FIXEDWIDTH_OPEN'))
|
||||||
// 顶栏是否应用主题色
|
// 顶栏是否应用主题色
|
||||||
|
|
|
@ -69,6 +69,7 @@ export const viewTagsStore = defineStore('viewTags', () => {
|
||||||
const nowFullPath = location.hash.substring(1)
|
const nowFullPath = location.hash.substring(1)
|
||||||
viewTags.value.forEach((item) => {
|
viewTags.value.forEach((item) => {
|
||||||
if (item.fullPath === nowFullPath) {
|
if (item.fullPath === nowFullPath) {
|
||||||
|
item.meta.key = Date.now()
|
||||||
item.meta.title = title
|
item.meta.title = title
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -116,7 +116,6 @@ a, button, input, textarea {
|
||||||
|
|
||||||
/* 头部 */
|
/* 头部 */
|
||||||
.snowy-header {
|
.snowy-header {
|
||||||
height: 50px;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
border-bottom: 1px solid var(--header-bottom);
|
border-bottom: 1px solid var(--header-bottom);
|
||||||
|
@ -481,6 +480,11 @@ body,
|
||||||
.snowy-theme-dark .odd {
|
.snowy-theme-dark .odd {
|
||||||
background-color: #1d1d1d
|
background-color: #1d1d1d
|
||||||
}
|
}
|
||||||
|
// 解决浏览器F12爆红aria-hidden问题
|
||||||
|
.ant-modal div[aria-hidden="true"] {
|
||||||
|
display: none !important
|
||||||
|
}
|
||||||
|
|
||||||
// 以下是重写表单设计器的样式
|
// 以下是重写表单设计器的样式
|
||||||
.list-main {
|
.list-main {
|
||||||
background: var(--auto-judge-before-color) !important;
|
background: var(--auto-judge-before-color) !important;
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
import config from '@/config'
|
||||||
|
// 业务自己新加了模块,当然只限制于微服务情况下,单体不用管
|
||||||
|
const bizCustomization = [
|
||||||
|
{
|
||||||
|
label: '/custom/',
|
||||||
|
value: '/custom/'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
// 微服务环境下如果拆分为多个代码模块,那他的url是网关转发,这里就要配置
|
||||||
|
const PREFIX = [
|
||||||
|
{
|
||||||
|
label: '/mobile/',
|
||||||
|
value: '/api/webapp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '/sys/',
|
||||||
|
value: '/api/webapp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '/auth/',
|
||||||
|
value: '/api/webapp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '/client/',
|
||||||
|
value: '/api/webapp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '/dev/',
|
||||||
|
value: '/api/webapp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '/gen/',
|
||||||
|
value: '/api/webapp'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '/biz/',
|
||||||
|
value: '/api/bizapp'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
// 转换url
|
||||||
|
export const convertUrl = (url) => {
|
||||||
|
if (config.CLOUD_SERVER === false) {
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
const apiArray = [...PREFIX, ...bizCustomization]
|
||||||
|
const prefixUrlArray = apiArray.filter((f) => url.indexOf(f.label) > -1)
|
||||||
|
if (prefixUrlArray && prefixUrlArray.length > 0) {
|
||||||
|
return prefixUrlArray[0].value + url
|
||||||
|
}
|
||||||
|
return url
|
||||||
|
}
|
|
@ -24,6 +24,6 @@ export default (error) => {
|
||||||
}
|
}
|
||||||
const errorName = errorMap[error.name] || '未知错误'
|
const errorName = errorMap[error.name] || '未知错误'
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
console.error(errorName)
|
console.error(errorName + ' ' + error)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import qs from 'qs'
|
||||||
import { Modal, message } from 'ant-design-vue'
|
import { Modal, message } from 'ant-design-vue'
|
||||||
import sysConfig from '@/config/index'
|
import sysConfig from '@/config/index'
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
|
import { convertUrl } from './apiAdaptive'
|
||||||
|
|
||||||
// 以下这些code需要重新登录
|
// 以下这些code需要重新登录
|
||||||
const reloadCodes = [401, 1011007, 1011008]
|
const reloadCodes = [401, 1011007, 1011008]
|
||||||
|
@ -108,7 +109,7 @@ service.interceptors.response.use(
|
||||||
// }
|
// }
|
||||||
} else {
|
} else {
|
||||||
// 统一成功提示
|
// 统一成功提示
|
||||||
const responseUrls = response.config.url.split('/')
|
const functionName = response.config.url.split('/').pop()
|
||||||
const apiNameArray = [
|
const apiNameArray = [
|
||||||
'add',
|
'add',
|
||||||
'edit',
|
'edit',
|
||||||
|
@ -129,7 +130,8 @@ service.interceptors.response.use(
|
||||||
'saveDraft'
|
'saveDraft'
|
||||||
]
|
]
|
||||||
apiNameArray.forEach((apiName) => {
|
apiNameArray.forEach((apiName) => {
|
||||||
if (responseUrls[responseUrls.length - 1] === apiName) {
|
// 上面去掉接口路径后,方法内包含内置的进行统一提示成功
|
||||||
|
if (functionName.includes(apiName)) {
|
||||||
message.success(data.msg)
|
message.success(data.msg)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -151,7 +153,7 @@ service.interceptors.response.use(
|
||||||
|
|
||||||
// 适配器, 用于适配不同的请求方式
|
// 适配器, 用于适配不同的请求方式
|
||||||
export const baseRequest = (url, value = {}, method = 'post', options = {}) => {
|
export const baseRequest = (url, value = {}, method = 'post', options = {}) => {
|
||||||
url = sysConfig.API_URL + url
|
url = sysConfig.API_URL + convertUrl(url)
|
||||||
if (method === 'post') {
|
if (method === 'post') {
|
||||||
return service.post(url, value, options)
|
return service.post(url, value, options)
|
||||||
} else if (method === 'get') {
|
} else if (method === 'get') {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<xn-form-container title="详情" :width="1000" v-model:open="open" :destroy-on-close="true" @close="onClose">
|
<xn-form-container title="详情" :width="1000" v-model:open="open" :destroy-on-close="true" @close="onClose">
|
||||||
<a-descriptions bordered>
|
<a-descriptions bordered>
|
||||||
<a-descriptions-item label="标题">{{formData.title}}</a-descriptions-item>
|
<a-descriptions-item label="标题">{{ formData.title }}</a-descriptions-item>
|
||||||
<a-descriptions-item label="类型">
|
<a-descriptions-item label="类型">
|
||||||
<a-tag :bordered="false" color="success" v-if="formData.type === 'NOTICE'">
|
<a-tag :bordered="false" color="success" v-if="formData.type === 'NOTICE'">
|
||||||
{{ $TOOL.dictTypeData('BIZ_NOTICE_TYPE', formData.type) }}
|
{{ $TOOL.dictTypeData('BIZ_NOTICE_TYPE', formData.type) }}
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="封面图">
|
<a-descriptions-item label="封面图">
|
||||||
<div v-if="formData.image">
|
<div v-if="formData.image">
|
||||||
<a-image :src="formData.image" style="width: 100px; height: 50px;margin-bottom: -10px;margin-top: -10px;" />
|
<a-image :src="formData.image" style="width: 100px; height: 50px; margin-bottom: -10px; margin-top: -10px" />
|
||||||
</div>
|
</div>
|
||||||
<span v-else>未上传</span>
|
<span v-else>未上传</span>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
|
@ -23,8 +23,12 @@
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
<a-descriptions bordered :column="2" class="mt-2">
|
<a-descriptions bordered :column="2" class="mt-2">
|
||||||
<a-descriptions-item label="摘要">{{ formData.digest }}</a-descriptions-item>
|
<a-descriptions-item label="摘要">{{ formData.digest }}</a-descriptions-item>
|
||||||
<a-descriptions-item label="备注"><span>{{ formData.remark }}</span></a-descriptions-item>
|
<a-descriptions-item label="备注"
|
||||||
<a-descriptions-item label="排序"><span>{{ formData.sortCode }}</span></a-descriptions-item>
|
><span>{{ formData.remark }}</span></a-descriptions-item
|
||||||
|
>
|
||||||
|
<a-descriptions-item label="排序"
|
||||||
|
><span>{{ formData.sortCode }}</span></a-descriptions-item
|
||||||
|
>
|
||||||
<a-descriptions-item label="发布位置">
|
<a-descriptions-item label="发布位置">
|
||||||
<div v-if="formData.place">
|
<div v-if="formData.place">
|
||||||
<a-tag v-for="textValue in JSON.parse(formData.place)" :key="textValue" color="processing">
|
<a-tag v-for="textValue in JSON.parse(formData.place)" :key="textValue" color="processing">
|
||||||
|
@ -32,48 +36,56 @@
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</div>
|
</div>
|
||||||
</a-descriptions-item>
|
</a-descriptions-item>
|
||||||
<a-descriptions-item label="创建人"><span>{{ formData.createUserName }}</span></a-descriptions-item>
|
<a-descriptions-item label="创建人"
|
||||||
<a-descriptions-item label="创建时间"><span>{{ formData.createTime }}</span></a-descriptions-item>
|
><span>{{ formData.createUserName }}</span></a-descriptions-item
|
||||||
<a-descriptions-item label="修改人"><span>{{ formData.updateUserName }}</span></a-descriptions-item>
|
>
|
||||||
<a-descriptions-item label="修改时间"><span>{{ formData.updateTime }}</span></a-descriptions-item>
|
<a-descriptions-item label="创建时间"
|
||||||
|
><span>{{ formData.createTime }}</span></a-descriptions-item
|
||||||
|
>
|
||||||
|
<a-descriptions-item label="修改人"
|
||||||
|
><span>{{ formData.updateUserName }}</span></a-descriptions-item
|
||||||
|
>
|
||||||
|
<a-descriptions-item label="修改时间"
|
||||||
|
><span>{{ formData.updateTime }}</span></a-descriptions-item
|
||||||
|
>
|
||||||
</a-descriptions>
|
</a-descriptions>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
||||||
<a-button type="primary" @click="onClose" :loading="submitLoading">确定</a-button>
|
<a-button type="primary" @click="onClose" :loading="submitLoading">确定</a-button>
|
||||||
</template>
|
</template>
|
||||||
</xn-form-container>
|
</xn-form-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="bizNoticeDetail">
|
<script setup name="bizNoticeDetail">
|
||||||
import bizNoticeApi from '@/api/biz/bizNoticeApi'
|
import bizNoticeApi from '@/api/biz/bizNoticeApi'
|
||||||
import { message } from 'ant-design-vue'
|
import { message } from 'ant-design-vue'
|
||||||
// 抽屉状态
|
// 抽屉状态
|
||||||
const open = ref(false)
|
const open = ref(false)
|
||||||
const emit = defineEmits({ successful: null })
|
const emit = defineEmits({ successful: null })
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const formData = ref({})
|
const formData = ref({})
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false)
|
||||||
// 打开抽屉
|
// 打开抽屉
|
||||||
const onOpen = (id) => {
|
const onOpen = (id) => {
|
||||||
open.value = true
|
open.value = true
|
||||||
if (id) {
|
if (id) {
|
||||||
const param = {
|
const param = {
|
||||||
id: id
|
id: id
|
||||||
}
|
}
|
||||||
bizNoticeApi.bizNoticeDetail(param).then((data) => {
|
bizNoticeApi.bizNoticeDetail(param).then((data) => {
|
||||||
formData.value = Object.assign({}, data)
|
formData.value = Object.assign({}, data)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
message.warning('未查到该信息')
|
message.warning('未查到该信息')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 关闭抽屉
|
// 关闭抽屉
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
formData.value = {}
|
formData.value = {}
|
||||||
open.value = false
|
open.value = false
|
||||||
}
|
}
|
||||||
// 抛出函数
|
// 抛出函数
|
||||||
defineExpose({
|
defineExpose({
|
||||||
onOpen
|
onOpen
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,35 +1,33 @@
|
||||||
<template>
|
<template>
|
||||||
<xn-form-container
|
<xn-form-container
|
||||||
:title="formData.id ? '编辑通知公告' : '增加通知公告'"
|
:title="formData.id ? '编辑通知公告' : '增加通知公告'"
|
||||||
:width="1000"
|
:width="1000"
|
||||||
v-model:open="open"
|
v-model:open="open"
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
@close="onClose"
|
@close="onClose"
|
||||||
>
|
>
|
||||||
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
|
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :span="19">
|
<a-col :span="19">
|
||||||
<a-form-item label="标题:" name="title">
|
<a-form-item label="标题:" name="title">
|
||||||
<a-input v-model:value="formData.title" placeholder="请输入标题" allow-clear />
|
<a-input v-model:value="formData.title" placeholder="请输入标题" allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item name="type">
|
<a-form-item name="type">
|
||||||
<template #label>
|
<template #label>
|
||||||
<a-tooltip>
|
<a-tooltip>
|
||||||
<template #title>
|
<template #title> 这里只是标签的类型 </template>
|
||||||
这里只是标签的类型
|
|
||||||
</template>
|
|
||||||
<question-circle-outlined />
|
<question-circle-outlined />
|
||||||
类型:
|
类型:
|
||||||
</a-tooltip>
|
</a-tooltip>
|
||||||
</template>
|
</template>
|
||||||
<a-radio-group v-model:value="formData.type" placeholder="请选择类型" :options="typeOptions" />
|
<a-radio-group v-model:value="formData.type" placeholder="请选择类型" :options="typeOptions" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="5">
|
<a-col :span="5">
|
||||||
<a-form-item label="封面图:" name="image">
|
<a-form-item label="封面图:" name="image">
|
||||||
<xn-upload v-model:value="formData.image" uploadMode="image" />
|
<xn-upload v-model:value="formData.image" uploadMode="image" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="内容:" name="content">
|
<a-form-item label="内容:" name="content">
|
||||||
<xn-editor v-model:value="formData.content" placeholder="请输入内容" />
|
<xn-editor v-model:value="formData.content" placeholder="请输入内容" />
|
||||||
|
@ -46,11 +44,11 @@
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="18">
|
<a-col :span="18">
|
||||||
<a-form-item label="发布位置:" name="place">
|
<a-form-item label="发布位置:" name="place">
|
||||||
<a-checkbox-group v-model:value="formData.place" placeholder="请选择发布位置" :options="placeOptions" />
|
<a-checkbox-group v-model:value="formData.place" placeholder="请选择发布位置" :options="placeOptions" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-form-item label="排序:" name="sortCode">
|
<a-form-item label="排序:" name="sortCode">
|
||||||
<a-input-number
|
<a-input-number
|
||||||
|
@ -61,88 +59,92 @@
|
||||||
/>
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<a-form-item label="备注:" name="remark">
|
<a-form-item label="备注:" name="remark">
|
||||||
<a-textarea v-model:value="formData.remark" placeholder="请输入备注" :auto-size="{ minRows: 3, maxRows: 5 }" />
|
<a-textarea
|
||||||
</a-form-item>
|
v-model:value="formData.remark"
|
||||||
</a-col>
|
placeholder="请输入备注"
|
||||||
</a-row>
|
:auto-size="{ minRows: 3, maxRows: 5 }"
|
||||||
</a-form>
|
/>
|
||||||
<template #footer>
|
</a-form-item>
|
||||||
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
</a-col>
|
||||||
<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
|
</a-row>
|
||||||
</template>
|
</a-form>
|
||||||
</xn-form-container>
|
<template #footer>
|
||||||
|
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
||||||
|
<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
|
||||||
|
</template>
|
||||||
|
</xn-form-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="bizNoticeForm">
|
<script setup name="bizNoticeForm">
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { required } from '@/utils/formRules'
|
import { required } from '@/utils/formRules'
|
||||||
import bizNoticeApi from '@/api/biz/bizNoticeApi'
|
import bizNoticeApi from '@/api/biz/bizNoticeApi'
|
||||||
// 抽屉状态
|
// 抽屉状态
|
||||||
const open = ref(false)
|
const open = ref(false)
|
||||||
const emit = defineEmits({ successful: null })
|
const emit = defineEmits({ successful: null })
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const formData = ref({})
|
const formData = ref({})
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false)
|
||||||
const typeOptions = ref([])
|
const typeOptions = ref([])
|
||||||
const placeOptions = ref([])
|
const placeOptions = ref([])
|
||||||
const statusOptions = ref([])
|
const statusOptions = ref([])
|
||||||
|
|
||||||
// 打开抽屉
|
// 打开抽屉
|
||||||
const onOpen = (record) => {
|
const onOpen = (record) => {
|
||||||
open.value = true
|
open.value = true
|
||||||
if (record) {
|
if (record) {
|
||||||
let recordData = cloneDeep(record)
|
let recordData = cloneDeep(record)
|
||||||
recordData.place = JSON.parse(recordData.place)
|
recordData.place = JSON.parse(recordData.place)
|
||||||
formData.value = Object.assign({}, recordData)
|
formData.value = Object.assign({}, recordData)
|
||||||
} else {
|
} else {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
type: 'NOTICE',
|
type: 'NOTICE',
|
||||||
place: ['BACK_MOBILE', 'BACK_INDEX'],
|
place: ['BACK_MOBILE', 'BACK_INDEX'],
|
||||||
sortCode: 99
|
sortCode: 99
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typeOptions.value = tool.dictList('BIZ_NOTICE_TYPE')
|
typeOptions.value = tool.dictList('BIZ_NOTICE_TYPE')
|
||||||
placeOptions.value = tool.dictList('BIZ_NOTICE_PLACE')
|
placeOptions.value = tool.dictList('BIZ_NOTICE_PLACE')
|
||||||
statusOptions.value = tool.dictList('BIZ_NOTICE_STATUS')
|
statusOptions.value = tool.dictList('BIZ_NOTICE_STATUS')
|
||||||
}
|
}
|
||||||
// 关闭抽屉
|
// 关闭抽屉
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
formRef.value.resetFields()
|
formRef.value.resetFields()
|
||||||
formData.value = {}
|
formData.value = {}
|
||||||
open.value = false
|
open.value = false
|
||||||
}
|
}
|
||||||
// 默认要校验的
|
// 默认要校验的
|
||||||
const formRules = {
|
const formRules = {
|
||||||
title: [required('请输入标题')],
|
title: [required('请输入标题')],
|
||||||
content: [required('请输入内容')],
|
content: [required('请输入内容')],
|
||||||
digest: [required('请输入摘要')],
|
digest: [required('请输入摘要')],
|
||||||
type: [required('请选择类型')],
|
type: [required('请选择类型')],
|
||||||
place: [required('请选择发布位置')],
|
place: [required('请选择发布位置')],
|
||||||
sortCode: [required('请输入排序')]
|
sortCode: [required('请输入排序')]
|
||||||
}
|
}
|
||||||
// 验证并提交数据
|
// 验证并提交数据
|
||||||
const onSubmit = () => {
|
const onSubmit = () => {
|
||||||
formRef.value.validate().then(() => {
|
formRef.value.validate().then(() => {
|
||||||
submitLoading.value = true
|
submitLoading.value = true
|
||||||
const formDataParam = cloneDeep(formData.value)
|
const formDataParam = cloneDeep(formData.value)
|
||||||
formDataParam.place = JSON.stringify(formDataParam.place)
|
formDataParam.place = JSON.stringify(formDataParam.place)
|
||||||
bizNoticeApi
|
bizNoticeApi
|
||||||
.bizNoticeSubmitForm(formDataParam, formDataParam.id)
|
.bizNoticeSubmitForm(formDataParam, formDataParam.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
onClose()
|
onClose()
|
||||||
emit('successful')
|
emit('successful')
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
submitLoading.value = false
|
submitLoading.value = false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 抛出函数
|
// 抛出函数
|
||||||
defineExpose({
|
defineExpose({
|
||||||
onOpen
|
onOpen
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,73 +1,76 @@
|
||||||
<template>
|
<template>
|
||||||
<a-card :bordered="false">
|
<a-card :bordered="false">
|
||||||
<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
|
<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-form-item label="标题" name="title">
|
<a-form-item label="标题" name="title">
|
||||||
<a-input v-model:value="searchFormState.title" placeholder="请输入标题" />
|
<a-input v-model:value="searchFormState.title" placeholder="请输入标题" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-form-item label="类型" name="type">
|
<a-form-item label="类型" name="type">
|
||||||
<a-select v-model:value="searchFormState.type" placeholder="请选择类型" :options="typeOptions" />
|
<a-select v-model:value="searchFormState.type" placeholder="请选择类型" :options="typeOptions" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-form-item label="发布位置" name="place">
|
<a-form-item label="发布位置" name="place">
|
||||||
<a-select v-model:value="searchFormState.place" placeholder="请选择发布位置" :options="placeOptions" />
|
<a-select v-model:value="searchFormState.place" placeholder="请选择发布位置" :options="placeOptions" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6" v-show="advanced">
|
<a-col :span="6" v-show="advanced">
|
||||||
<a-form-item label="状态" name="status">
|
<a-form-item label="状态" name="status">
|
||||||
<a-select v-model:value="searchFormState.status" placeholder="请选择状态" :options="statusOptions" />
|
<a-select v-model:value="searchFormState.status" placeholder="请选择状态" :options="statusOptions" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6" v-show="advanced">
|
<a-col :span="6" v-show="advanced">
|
||||||
<a-form-item label="创建时间" name="createTime">
|
<a-form-item label="创建时间" name="createTime">
|
||||||
<a-range-picker v-model:value="searchFormState.createTime" show-time />
|
<a-range-picker v-model:value="searchFormState.createTime" show-time />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-button type="primary" @click="tableRef.refresh(true)">查询</a-button>
|
<a-button type="primary" @click="tableRef.refresh(true)">查询</a-button>
|
||||||
<a-button style="margin: 0 8px" @click="reset">重置</a-button>
|
<a-button style="margin: 0 8px" @click="reset">重置</a-button>
|
||||||
<a @click="toggleAdvanced" style="margin-left: 8px">
|
<a @click="toggleAdvanced" style="margin-left: 8px">
|
||||||
{{ advanced ? '收起' : '展开' }}
|
{{ advanced ? '收起' : '展开' }}
|
||||||
<component :is="advanced ? 'up-outlined' : 'down-outlined'"/>
|
<component :is="advanced ? 'up-outlined' : 'down-outlined'" />
|
||||||
</a>
|
</a>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-form>
|
</a-form>
|
||||||
<s-table
|
<s-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:alert="options.alert.show"
|
:alert="options.alert.show"
|
||||||
bordered
|
bordered
|
||||||
:row-key="(record) => record.id"
|
:row-key="(record) => record.id"
|
||||||
:tool-config="toolConfig"
|
:tool-config="toolConfig"
|
||||||
:row-selection="options.rowSelection"
|
:row-selection="options.rowSelection"
|
||||||
>
|
>
|
||||||
<template #operator class="table-operator">
|
<template #operator class="table-operator">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizNoticeAdd')">
|
<a-button type="primary" @click="formRef.onOpen()" v-if="hasPerm('bizNoticeAdd')">
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete
|
<xn-batch-button
|
||||||
v-if="hasPerm('bizNoticeBatchDelete')"
|
v-if="hasPerm('bizNoticeBatchDelete')"
|
||||||
:selectedRowKeys="selectedRowKeys"
|
buttonName="批量删除"
|
||||||
@batchDelete="deleteBatchBizNotice"
|
icon="DeleteOutlined"
|
||||||
/>
|
buttonDanger
|
||||||
</a-space>
|
:selectedRowKeys="selectedRowKeys"
|
||||||
</template>
|
@batchCallBack="deleteBatchBizNotice"
|
||||||
<template #bodyCell="{ column, record }">
|
/>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.dataIndex === 'image'">
|
<template v-if="column.dataIndex === 'image'">
|
||||||
<div v-if="record.image">
|
<div v-if="record.image">
|
||||||
<a-image :src="record.image" style="width: 30px; height: 30px;" />
|
<a-image :src="record.image" style="width: 30px; height: 30px" />
|
||||||
</div>
|
</div>
|
||||||
<span v-else>未上传</span>
|
<span v-else>未上传</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'type'">
|
<template v-if="column.dataIndex === 'type'">
|
||||||
<a-tag :bordered="false" color="success" v-if="record.type === 'NOTICE'">
|
<a-tag :bordered="false" color="success" v-if="record.type === 'NOTICE'">
|
||||||
{{ $TOOL.dictTypeData('BIZ_NOTICE_TYPE', record.type) }}
|
{{ $TOOL.dictTypeData('BIZ_NOTICE_TYPE', record.type) }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
|
@ -78,12 +81,12 @@
|
||||||
{{ $TOOL.dictTypeData('BIZ_NOTICE_TYPE', record.type) }}
|
{{ $TOOL.dictTypeData('BIZ_NOTICE_TYPE', record.type) }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
<span v-else>无</span>
|
<span v-else>无</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'place'">
|
<template v-if="column.dataIndex === 'place'">
|
||||||
<a-tag v-for="textValue in JSON.parse(record.place)" :key="textValue" color="processing">
|
<a-tag v-for="textValue in JSON.parse(record.place)" :key="textValue" color="processing">
|
||||||
{{ $TOOL.dictTypeData('BIZ_NOTICE_PLACE', textValue) }}
|
{{ $TOOL.dictTypeData('BIZ_NOTICE_PLACE', textValue) }}
|
||||||
</a-tag>
|
</a-tag>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'status'">
|
<template v-if="column.dataIndex === 'status'">
|
||||||
<a-switch
|
<a-switch
|
||||||
:loading="loading"
|
:loading="loading"
|
||||||
|
@ -93,134 +96,134 @@
|
||||||
/>
|
/>
|
||||||
<span v-else>{{ $TOOL.dictTypeData('BIZ_NOTICE_STATUS', record.status) }}</span>
|
<span v-else>{{ $TOOL.dictTypeData('BIZ_NOTICE_STATUS', record.status) }}</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'action'">
|
<template v-if="column.dataIndex === 'action'">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a @click="detailRef.onOpen(record.id)" v-if="hasPerm('bizNoticeDetail')">详情</a>
|
<a @click="detailRef.onOpen(record.id)" v-if="hasPerm('bizNoticeDetail')">详情</a>
|
||||||
<a-divider type="vertical" v-if="hasPerm(['bizNoticeEdit', 'bizNoticeDetail'], 'and')" />
|
<a-divider type="vertical" v-if="hasPerm(['bizNoticeEdit', 'bizNoticeDetail'], 'and')" />
|
||||||
<a @click="formRef.onOpen(record)" v-if="hasPerm('bizNoticeEdit')">编辑</a>
|
<a @click="formRef.onOpen(record)" v-if="hasPerm('bizNoticeEdit')">编辑</a>
|
||||||
<a-divider type="vertical" v-if="hasPerm(['bizNoticeEdit', 'bizNoticeDelete'], 'and')" />
|
<a-divider type="vertical" v-if="hasPerm(['bizNoticeEdit', 'bizNoticeDelete'], 'and')" />
|
||||||
<a-popconfirm title="确定要删除吗?" @confirm="deleteBizNotice(record)">
|
<a-popconfirm title="确定要删除吗?" @confirm="deleteBizNotice(record)">
|
||||||
<a-button type="link" danger size="small" v-if="hasPerm('bizNoticeDelete')">删除</a-button>
|
<a-button type="link" danger size="small" v-if="hasPerm('bizNoticeDelete')">删除</a-button>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</s-table>
|
</s-table>
|
||||||
</a-card>
|
</a-card>
|
||||||
<Form ref="formRef" @successful="tableRef.refresh()" />
|
<Form ref="formRef" @successful="tableRef.refresh()" />
|
||||||
<detail ref="detailRef" />
|
<detail ref="detailRef" />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="notice">
|
<script setup name="notice">
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import Form from './form.vue'
|
import Form from './form.vue'
|
||||||
import Detail from './detail.vue'
|
import Detail from './detail.vue'
|
||||||
import bizNoticeApi from '@/api/biz/bizNoticeApi'
|
import bizNoticeApi from '@/api/biz/bizNoticeApi'
|
||||||
const searchFormState = ref({})
|
const searchFormState = ref({})
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const detailRef = ref()
|
const detailRef = ref()
|
||||||
const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
|
const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
// 查询区域显示更多控制
|
// 查询区域显示更多控制
|
||||||
const advanced = ref(false)
|
const advanced = ref(false)
|
||||||
const toggleAdvanced = () => {
|
const toggleAdvanced = () => {
|
||||||
advanced.value = !advanced.value
|
advanced.value = !advanced.value
|
||||||
}
|
}
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '标题',
|
title: '标题',
|
||||||
dataIndex: 'title'
|
dataIndex: 'title'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '封面图',
|
title: '封面图',
|
||||||
dataIndex: 'image',
|
dataIndex: 'image',
|
||||||
width: '100px'
|
width: '100px'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '类型',
|
title: '类型',
|
||||||
dataIndex: 'type'
|
dataIndex: 'type'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '发布位置',
|
title: '发布位置',
|
||||||
dataIndex: 'place'
|
dataIndex: 'place'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '排序',
|
title: '排序',
|
||||||
dataIndex: 'sortCode',
|
dataIndex: 'sortCode',
|
||||||
sorter: true
|
sorter: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '状态',
|
title: '状态',
|
||||||
dataIndex: 'status'
|
dataIndex: 'status'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '创建时间',
|
title: '创建时间',
|
||||||
dataIndex: 'createTime',
|
dataIndex: 'createTime',
|
||||||
width: '150px'
|
width: '150px'
|
||||||
},
|
}
|
||||||
]
|
]
|
||||||
// 操作栏通过权限判断是否显示
|
// 操作栏通过权限判断是否显示
|
||||||
if (hasPerm(['bizNoticeEdit', 'bizNoticeDelete'])) {
|
if (hasPerm(['bizNoticeEdit', 'bizNoticeDelete'])) {
|
||||||
columns.push({
|
columns.push({
|
||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'action',
|
dataIndex: 'action',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: '200px'
|
width: '200px'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
const selectedRowKeys = ref([])
|
const selectedRowKeys = ref([])
|
||||||
// 列表选择配置
|
// 列表选择配置
|
||||||
const options = {
|
const options = {
|
||||||
// columns数字类型字段加入 needTotal: true 可以勾选自动算账
|
// columns数字类型字段加入 needTotal: true 可以勾选自动算账
|
||||||
alert: {
|
alert: {
|
||||||
show: false,
|
show: false,
|
||||||
clear: () => {
|
clear: () => {
|
||||||
selectedRowKeys.value = ref([])
|
selectedRowKeys.value = ref([])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rowSelection: {
|
rowSelection: {
|
||||||
onChange: (selectedRowKey, selectedRows) => {
|
onChange: (selectedRowKey, selectedRows) => {
|
||||||
selectedRowKeys.value = selectedRowKey
|
selectedRowKeys.value = selectedRowKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const loadData = (parameter) => {
|
const loadData = (parameter) => {
|
||||||
const searchFormParam = cloneDeep(searchFormState.value)
|
const searchFormParam = cloneDeep(searchFormState.value)
|
||||||
// createTime范围查询条件重载
|
// createTime范围查询条件重载
|
||||||
if (searchFormParam.createTime) {
|
if (searchFormParam.createTime) {
|
||||||
searchFormParam.startCreateTime = searchFormParam.createTime[0]
|
searchFormParam.startCreateTime = searchFormParam.createTime[0]
|
||||||
searchFormParam.endCreateTime = searchFormParam.createTime[1]
|
searchFormParam.endCreateTime = searchFormParam.createTime[1]
|
||||||
delete searchFormParam.createTime
|
delete searchFormParam.createTime
|
||||||
}
|
}
|
||||||
return bizNoticeApi.bizNoticePage(Object.assign(parameter, searchFormParam)).then((data) => {
|
return bizNoticeApi.bizNoticePage(Object.assign(parameter, searchFormParam)).then((data) => {
|
||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
searchFormRef.value.resetFields()
|
searchFormRef.value.resetFields()
|
||||||
tableRef.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 删除
|
// 删除
|
||||||
const deleteBizNotice = (record) => {
|
const deleteBizNotice = (record) => {
|
||||||
let params = [
|
let params = [
|
||||||
{
|
{
|
||||||
id: record.id
|
id: record.id
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
bizNoticeApi.bizNoticeDelete(params).then(() => {
|
bizNoticeApi.bizNoticeDelete(params).then(() => {
|
||||||
tableRef.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 批量删除
|
// 批量删除
|
||||||
const deleteBatchBizNotice = (params) => {
|
const deleteBatchBizNotice = (params) => {
|
||||||
bizNoticeApi.bizNoticeDelete(params).then(() => {
|
bizNoticeApi.bizNoticeDelete(params).then(() => {
|
||||||
tableRef.value.clearRefreshSelected()
|
tableRef.value.clearRefreshSelected()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 修改状态
|
// 修改状态
|
||||||
const editStatus = (record) => {
|
const editStatus = (record) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
@ -244,7 +247,7 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const typeOptions = tool.dictList('BIZ_NOTICE_TYPE')
|
const typeOptions = tool.dictList('BIZ_NOTICE_TYPE')
|
||||||
const placeOptions = tool.dictList('BIZ_NOTICE_PLACE')
|
const placeOptions = tool.dictList('BIZ_NOTICE_PLACE')
|
||||||
const statusOptions = tool.dictList('BIZ_NOTICE_STATUS')
|
const statusOptions = tool.dictList('BIZ_NOTICE_STATUS')
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -57,10 +57,13 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete
|
<xn-batch-button
|
||||||
v-if="hasPerm('bizOrgBatchDelete')"
|
v-if="hasPerm('bizOrgBatchDelete')"
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
:selectedRowKeys="selectedRowKeys"
|
:selectedRowKeys="selectedRowKeys"
|
||||||
@batchDelete="deleteBatchOrg"
|
@batchCallBack="deleteBatchOrg"
|
||||||
/>
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -57,10 +57,13 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete
|
<xn-batch-button
|
||||||
v-if="hasPerm('bizPositionBatchDelete')"
|
v-if="hasPerm('bizPositionBatchDelete')"
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
:selectedRowKeys="selectedRowKeys"
|
:selectedRowKeys="selectedRowKeys"
|
||||||
@batchDelete="deleteBatchPosition"
|
@batchCallBack="deleteBatchPosition"
|
||||||
/>
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -77,11 +77,13 @@
|
||||||
<template #icon><export-outlined /></template>
|
<template #icon><export-outlined /></template>
|
||||||
{{ $t('user.batchExportButton') }}
|
{{ $t('user.batchExportButton') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete
|
<xn-batch-button
|
||||||
v-if="hasPerm('bizUserBatchDelete')"
|
v-if="hasPerm('bizUserBatchDelete')"
|
||||||
:buttonName="$t('common.batchRemoveButton')"
|
:buttonName="$t('common.batchRemoveButton')"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
:selectedRowKeys="selectedRowKeys"
|
:selectedRowKeys="selectedRowKeys"
|
||||||
@batchDelete="deleteBatchUser"
|
@batchCallBack="deleteBatchUser"
|
||||||
/>
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -183,14 +183,10 @@
|
||||||
id: record.id
|
id: record.id
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
dictApi.dictDelete(params).then((res) => {
|
dictApi.dictDelete(params).then(() => {
|
||||||
if (res.code === 200) {
|
tableRef.value.refresh()
|
||||||
tableRef.value.refresh(true)
|
refreshStoreDict()
|
||||||
} else {
|
|
||||||
res.message && tool.error(res.message)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
refreshStoreDict()
|
|
||||||
}
|
}
|
||||||
// 表单界面回调
|
// 表单界面回调
|
||||||
const formSuccessful = () => {
|
const formSuccessful = () => {
|
||||||
|
|
|
@ -48,7 +48,13 @@
|
||||||
<UploadOutlined />
|
<UploadOutlined />
|
||||||
文件上传
|
文件上传
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchFile" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchFile"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -19,6 +19,14 @@
|
||||||
<a-form-item ref="cronExpressionRef" label="表达式:" name="cronExpression">
|
<a-form-item ref="cronExpressionRef" label="表达式:" name="cronExpression">
|
||||||
<cron v-model:modelValue="formData.cronExpression" />
|
<cron v-model:modelValue="formData.cronExpression" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
<a-form-item label="扩展参数:" name="extJson">
|
||||||
|
<a-textarea
|
||||||
|
v-model:value="formData.extJson"
|
||||||
|
placeholder="请输入定时扩展参数"
|
||||||
|
:auto-size="{ minRows: 2, maxRows: 5 }"
|
||||||
|
allow-clear
|
||||||
|
/>
|
||||||
|
</a-form-item>
|
||||||
<a-form-item label="排序:" name="sortCode">
|
<a-form-item label="排序:" name="sortCode">
|
||||||
<a-input-number class="xn-wd" v-model:value="formData.sortCode" :max="100" />
|
<a-input-number class="xn-wd" v-model:value="formData.sortCode" :max="100" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -54,7 +62,18 @@
|
||||||
sortCode: 99
|
sortCode: 99
|
||||||
}
|
}
|
||||||
if (record) {
|
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) => {
|
jobApi.jobGetActionClass().then((data) => {
|
||||||
|
|
|
@ -51,7 +51,13 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchJob" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchJob"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -34,7 +34,13 @@
|
||||||
<template #operator class="table-operator">
|
<template #operator class="table-operator">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary" @click="formRef.onOpen()"> 发送站内信 </a-button>
|
<a-button type="primary" @click="formRef.onOpen()"> 发送站内信 </a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchEmail" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchEmail"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -1,90 +1,89 @@
|
||||||
<template>
|
<template>
|
||||||
<xn-form-container
|
<xn-form-container
|
||||||
:title="formData.id ? '编辑轮播图' : '增加轮播图'"
|
:title="formData.id ? '编辑轮播图' : '增加轮播图'"
|
||||||
:width="700"
|
:width="700"
|
||||||
v-model:open="open"
|
v-model:open="open"
|
||||||
:destroy-on-close="true"
|
:destroy-on-close="true"
|
||||||
@close="onClose"
|
@close="onClose"
|
||||||
>
|
>
|
||||||
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
|
<a-form ref="formRef" :model="formData" :rules="formRules" layout="vertical">
|
||||||
<a-row :gutter="16">
|
<a-row :gutter="16">
|
||||||
<a-col :span="18">
|
<a-col :span="18">
|
||||||
<a-form-item label="标题:" name="title">
|
<a-form-item label="标题:" name="title">
|
||||||
<a-input v-model:value="formData.title" placeholder="请输入标题" allow-clear />
|
<a-input v-model:value="formData.title" placeholder="请输入标题" allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="排序:" name="sortCode">
|
<a-form-item label="排序:" name="sortCode">
|
||||||
<a-input v-model:value="formData.sortCode" placeholder="请输入排序" allow-clear />
|
<a-input v-model:value="formData.sortCode" placeholder="请输入排序" allow-clear />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-form-item label="图片:" name="image">
|
<a-form-item label="图片:" name="image">
|
||||||
<xn-upload v-model:value="formData.image" uploadMode="image" />
|
<xn-upload v-model:value="formData.image" uploadMode="image" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
</a-col>
|
||||||
</a-col>
|
<a-col :span="24">
|
||||||
<a-col :span="24">
|
|
||||||
<a-form-item label="展示位置:" name="place">
|
<a-form-item label="展示位置:" name="place">
|
||||||
<a-checkbox-group v-model:value="formData.place" placeholder="请选择展示位置" :options="placeOptions" />
|
<a-checkbox-group v-model:value="formData.place" placeholder="请选择展示位置" :options="placeOptions" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<sub-form ref="sumFormRef" :data-array="formData.pathDetails" :place="formData.place" />
|
<sub-form ref="sumFormRef" :data-array="formData.pathDetails" :place="formData.place" />
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-form>
|
</a-form>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
<a-button style="margin-right: 8px" @click="onClose">关闭</a-button>
|
||||||
<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
|
<a-button type="primary" @click="onSubmit" :loading="submitLoading">保存</a-button>
|
||||||
</template>
|
</template>
|
||||||
</xn-form-container>
|
</xn-form-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="devSlideshowForm">
|
<script setup name="devSlideshowForm">
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import { required } from '@/utils/formRules'
|
import { required } from '@/utils/formRules'
|
||||||
import slideshowApi from '@/api/dev/slideshowApi'
|
import slideshowApi from '@/api/dev/slideshowApi'
|
||||||
import SubForm from './subForm.vue'
|
import SubForm from './subForm.vue'
|
||||||
// 抽屉状态
|
// 抽屉状态
|
||||||
const open = ref(false)
|
const open = ref(false)
|
||||||
const emit = defineEmits({ successful: null })
|
const emit = defineEmits({ successful: null })
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const sumFormRef = ref()
|
const sumFormRef = ref()
|
||||||
// 表单数据
|
// 表单数据
|
||||||
const formData = ref({})
|
const formData = ref({})
|
||||||
const submitLoading = ref(false)
|
const submitLoading = ref(false)
|
||||||
const placeOptions = ref([])
|
const placeOptions = ref([])
|
||||||
|
|
||||||
// 打开抽屉
|
// 打开抽屉
|
||||||
const onOpen = (record) => {
|
const onOpen = (record) => {
|
||||||
open.value = true
|
open.value = true
|
||||||
if (record) {
|
if (record) {
|
||||||
let recordData = cloneDeep(record)
|
let recordData = cloneDeep(record)
|
||||||
recordData.place = JSON.parse(recordData.place)
|
recordData.place = JSON.parse(recordData.place)
|
||||||
recordData.pathDetails = JSON.parse(recordData.pathDetails)
|
recordData.pathDetails = JSON.parse(recordData.pathDetails)
|
||||||
formData.value = Object.assign({}, recordData)
|
formData.value = Object.assign({}, recordData)
|
||||||
} else {
|
} else {
|
||||||
formData.value = {
|
formData.value = {
|
||||||
place: ['BACK_SYS_INDEX']
|
place: ['BACK_SYS_INDEX']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
placeOptions.value = tool.dictList('DEV_SLIDESHOW_PLACE')
|
placeOptions.value = tool.dictList('DEV_SLIDESHOW_PLACE')
|
||||||
}
|
}
|
||||||
// 关闭抽屉
|
// 关闭抽屉
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
formRef.value.resetFields()
|
formRef.value.resetFields()
|
||||||
formData.value = {}
|
formData.value = {}
|
||||||
open.value = false
|
open.value = false
|
||||||
}
|
}
|
||||||
// 默认要校验的
|
// 默认要校验的
|
||||||
const formRules = {
|
const formRules = {
|
||||||
title: [required('请输入标题')],
|
title: [required('请输入标题')],
|
||||||
place: [required('请输入展示位置')],
|
place: [required('请输入展示位置')],
|
||||||
sortCode: [required('请输入排序')]
|
sortCode: [required('请输入排序')]
|
||||||
}
|
}
|
||||||
// 验证并提交数据
|
// 验证并提交数据
|
||||||
const onSubmit = () => {
|
const onSubmit = () => {
|
||||||
formRef.value.validate().then(() => {
|
formRef.value.validate().then(() => {
|
||||||
const formDataParam = cloneDeep(formData.value)
|
const formDataParam = cloneDeep(formData.value)
|
||||||
formDataParam.place = JSON.stringify(formDataParam.place)
|
formDataParam.place = JSON.stringify(formDataParam.place)
|
||||||
const details = sumFormRef.value.getData()
|
const details = sumFormRef.value.getData()
|
||||||
|
@ -92,20 +91,20 @@
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
formDataParam.pathDetails = JSON.stringify(details)
|
formDataParam.pathDetails = JSON.stringify(details)
|
||||||
submitLoading.value = true
|
submitLoading.value = true
|
||||||
slideshowApi
|
slideshowApi
|
||||||
.devSlideshowSubmitForm(formDataParam, formDataParam.id)
|
.devSlideshowSubmitForm(formDataParam, formDataParam.id)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
onClose()
|
onClose()
|
||||||
emit('successful')
|
emit('successful')
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
submitLoading.value = false
|
submitLoading.value = false
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 抛出函数
|
// 抛出函数
|
||||||
defineExpose({
|
defineExpose({
|
||||||
onOpen
|
onOpen
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,38 +1,38 @@
|
||||||
<template>
|
<template>
|
||||||
<a-card :bordered="false">
|
<a-card :bordered="false">
|
||||||
<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
|
<a-form ref="searchFormRef" name="advanced_search" :model="searchFormState" class="ant-advanced-search-form">
|
||||||
<a-row :gutter="24">
|
<a-row :gutter="24">
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-form-item label="标题" name="title">
|
<a-form-item label="标题" name="title">
|
||||||
<a-input v-model:value="searchFormState.title" placeholder="请输入标题" />
|
<a-input v-model:value="searchFormState.title" placeholder="请输入标题" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-form-item label="展示位置" name="place">
|
<a-form-item label="展示位置" name="place">
|
||||||
<a-select v-model:value="searchFormState.place" placeholder="请选择展示位置" :options="placeOptions" />
|
<a-select v-model:value="searchFormState.place" placeholder="请选择展示位置" :options="placeOptions" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-form-item label="状态" name="status">
|
<a-form-item label="状态" name="status">
|
||||||
<a-select v-model:value="searchFormState.status" placeholder="请选择状态" :options="statusOptions" />
|
<a-select v-model:value="searchFormState.status" placeholder="请选择状态" :options="statusOptions" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-col>
|
</a-col>
|
||||||
<a-col :span="6">
|
<a-col :span="6">
|
||||||
<a-button type="primary" @click="tableRef.refresh(true)">查询</a-button>
|
<a-button type="primary" @click="tableRef.refresh(true)">查询</a-button>
|
||||||
<a-button style="margin: 0 8px" @click="reset">重置</a-button>
|
<a-button style="margin: 0 8px" @click="reset">重置</a-button>
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-form>
|
</a-form>
|
||||||
<s-table
|
<s-table
|
||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:data="loadData"
|
:data="loadData"
|
||||||
:alert="options.alert.show"
|
:alert="options.alert.show"
|
||||||
bordered
|
bordered
|
||||||
:row-key="(record) => record.id"
|
:row-key="(record) => record.id"
|
||||||
:tool-config="toolConfig"
|
:tool-config="toolConfig"
|
||||||
:row-selection="options.rowSelection"
|
:row-selection="options.rowSelection"
|
||||||
>
|
>
|
||||||
<template #expandColumnTitle>
|
<template #expandColumnTitle>
|
||||||
<span>更多</span>
|
<span>更多</span>
|
||||||
</template>
|
</template>
|
||||||
|
@ -59,24 +59,29 @@
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
</template>
|
</template>
|
||||||
<template #operator class="table-operator">
|
<template #operator class="table-operator">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a-button type="primary" @click="formRef.onOpen()">
|
<a-button type="primary" @click="formRef.onOpen()">
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete
|
<xn-batch-button
|
||||||
:selectedRowKeys="selectedRowKeys"
|
buttonName="批量删除"
|
||||||
@batchDelete="deleteBatchDevSlideshow"
|
icon="DeleteOutlined"
|
||||||
/>
|
buttonDanger
|
||||||
</a-space>
|
:selectedRowKeys="selectedRowKeys"
|
||||||
</template>
|
@batchCallBack="deleteBatchDevSlideshow"
|
||||||
<template #bodyCell="{ column, record }">
|
/>
|
||||||
<template v-if="column.dataIndex === 'place'">
|
</a-space>
|
||||||
<a-tag v-for="textValue in JSON.parse(record.place)" :key="textValue" color="green">{{ $TOOL.dictTypeData('DEV_SLIDESHOW_PLACE', textValue) }}</a-tag>
|
</template>
|
||||||
</template>
|
<template #bodyCell="{ column, record }">
|
||||||
|
<template v-if="column.dataIndex === 'place'">
|
||||||
|
<a-tag v-for="textValue in JSON.parse(record.place)" :key="textValue" color="green">{{
|
||||||
|
$TOOL.dictTypeData('DEV_SLIDESHOW_PLACE', textValue)
|
||||||
|
}}</a-tag>
|
||||||
|
</template>
|
||||||
<template v-if="column.dataIndex === 'image'">
|
<template v-if="column.dataIndex === 'image'">
|
||||||
<a-image :src="record.image" style="width: 50px; height: 30px;" />
|
<a-image :src="record.image" style="width: 50px; height: 30px" />
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'status'">
|
<template v-if="column.dataIndex === 'status'">
|
||||||
<a-switch
|
<a-switch
|
||||||
|
@ -86,62 +91,61 @@
|
||||||
v-if="hasPerm('bizNoticerUpdateStatus')"
|
v-if="hasPerm('bizNoticerUpdateStatus')"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'action'">
|
<template v-if="column.dataIndex === 'action'">
|
||||||
<a-space>
|
<a-space>
|
||||||
<a @click="formRef.onOpen(record)">编辑</a>
|
<a @click="formRef.onOpen(record)">编辑</a>
|
||||||
<a-divider type="vertical" />
|
<a-divider type="vertical" />
|
||||||
<a-popconfirm title="确定要删除吗?" @confirm="deleteDevSlideshow(record)">
|
<a-popconfirm title="确定要删除吗?" @confirm="deleteDevSlideshow(record)">
|
||||||
<a-button type="link" danger size="small">删除</a-button>
|
<a-button type="link" danger size="small">删除</a-button>
|
||||||
</a-popconfirm>
|
</a-popconfirm>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
</s-table>
|
||||||
</s-table>
|
</a-card>
|
||||||
</a-card>
|
<Form ref="formRef" @successful="tableRef.refresh()" />
|
||||||
<Form ref="formRef" @successful="tableRef.refresh()" />
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup name="slideshow">
|
<script setup name="slideshow">
|
||||||
import tool from '@/utils/tool'
|
import tool from '@/utils/tool'
|
||||||
import { cloneDeep } from 'lodash-es'
|
import { cloneDeep } from 'lodash-es'
|
||||||
import Form from './form.vue'
|
import Form from './form.vue'
|
||||||
import slideshowApi from '@/api/dev/slideshowApi'
|
import slideshowApi from '@/api/dev/slideshowApi'
|
||||||
const searchFormState = ref({})
|
const searchFormState = ref({})
|
||||||
const searchFormRef = ref()
|
const searchFormRef = ref()
|
||||||
const tableRef = ref()
|
const tableRef = ref()
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
|
const toolConfig = { refresh: true, height: true, columnSetting: true, striped: false }
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '标题',
|
title: '标题',
|
||||||
dataIndex: 'title'
|
dataIndex: 'title'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '图片',
|
title: '图片',
|
||||||
dataIndex: 'image'
|
dataIndex: 'image'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '展示位置',
|
title: '展示位置',
|
||||||
dataIndex: 'place'
|
dataIndex: 'place'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '状态',
|
title: '状态',
|
||||||
dataIndex: 'status'
|
dataIndex: 'status'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '排序',
|
title: '排序',
|
||||||
dataIndex: 'sortCode',
|
dataIndex: 'sortCode',
|
||||||
sorter: true
|
sorter: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'action',
|
dataIndex: 'action',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: '150px'
|
width: '150px'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
const detailsColumns = [
|
const detailsColumns = [
|
||||||
{
|
{
|
||||||
title: '位置',
|
title: '位置',
|
||||||
|
@ -161,50 +165,50 @@
|
||||||
dataIndex: 'url'
|
dataIndex: 'url'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
const selectedRowKeys = ref([])
|
const selectedRowKeys = ref([])
|
||||||
// 列表选择配置
|
// 列表选择配置
|
||||||
const options = {
|
const options = {
|
||||||
// columns数字类型字段加入 needTotal: true 可以勾选自动算账
|
// columns数字类型字段加入 needTotal: true 可以勾选自动算账
|
||||||
alert: {
|
alert: {
|
||||||
show: false,
|
show: false,
|
||||||
clear: () => {
|
clear: () => {
|
||||||
selectedRowKeys.value = ref([])
|
selectedRowKeys.value = ref([])
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
rowSelection: {
|
rowSelection: {
|
||||||
onChange: (selectedRowKey, selectedRows) => {
|
onChange: (selectedRowKey, selectedRows) => {
|
||||||
selectedRowKeys.value = selectedRowKey
|
selectedRowKeys.value = selectedRowKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const loadData = (parameter) => {
|
const loadData = (parameter) => {
|
||||||
const searchFormParam = cloneDeep(searchFormState.value)
|
const searchFormParam = cloneDeep(searchFormState.value)
|
||||||
return slideshowApi.devSlideshowPage(Object.assign(parameter, searchFormParam)).then((data) => {
|
return slideshowApi.devSlideshowPage(Object.assign(parameter, searchFormParam)).then((data) => {
|
||||||
return data
|
return data
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 重置
|
// 重置
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
searchFormRef.value.resetFields()
|
searchFormRef.value.resetFields()
|
||||||
tableRef.value.refresh(true)
|
tableRef.value.refresh(true)
|
||||||
}
|
}
|
||||||
// 删除
|
// 删除
|
||||||
const deleteDevSlideshow = (record) => {
|
const deleteDevSlideshow = (record) => {
|
||||||
let params = [
|
let params = [
|
||||||
{
|
{
|
||||||
id: record.id
|
id: record.id
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
slideshowApi.devSlideshowDelete(params).then(() => {
|
slideshowApi.devSlideshowDelete(params).then(() => {
|
||||||
tableRef.value.refresh()
|
tableRef.value.refresh()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 批量删除
|
// 批量删除
|
||||||
const deleteBatchDevSlideshow = (params) => {
|
const deleteBatchDevSlideshow = (params) => {
|
||||||
slideshowApi.devSlideshowDelete(params).then(() => {
|
slideshowApi.devSlideshowDelete(params).then(() => {
|
||||||
tableRef.value.clearRefreshSelected()
|
tableRef.value.clearRefreshSelected()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// 修改状态
|
// 修改状态
|
||||||
const editStatus = (record) => {
|
const editStatus = (record) => {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
|
@ -228,6 +232,6 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const placeOptions = tool.dictList('DEV_SLIDESHOW_PLACE')
|
const placeOptions = tool.dictList('DEV_SLIDESHOW_PLACE')
|
||||||
const statusOptions = tool.dictList('DEV_SLIDESHOW_STATUS')
|
const statusOptions = tool.dictList('DEV_SLIDESHOW_STATUS')
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,25 +1,33 @@
|
||||||
<template>
|
<template>
|
||||||
<a-form
|
<a-form :model="formData" ref="formRef" name="basic" autocomplete="off">
|
||||||
:model="formData"
|
|
||||||
ref="formRef"
|
|
||||||
name="basic"
|
|
||||||
autocomplete="off"
|
|
||||||
>
|
|
||||||
<a-table :columns="columns" :dataSource="formData" size="middle">
|
<a-table :columns="columns" :dataSource="formData" size="middle">
|
||||||
<template #bodyCell="{text, record, index, column}">
|
<template #bodyCell="{ text, record, index, column }">
|
||||||
<template v-if="column.dataIndex === 'whetherToClick'">
|
<template v-if="column.dataIndex === 'whetherToClick'">
|
||||||
<a-form-item :validate-status="validateStatus(record, 'whetherToClick')">
|
<a-form-item :validate-status="validateStatus(record, 'whetherToClick')">
|
||||||
<a-radio-group v-model:value="record.whetherToClick" placeholder="请选择跳转方式" :options="whetherToClickOptions" />
|
<a-radio-group
|
||||||
|
v-model:value="record.whetherToClick"
|
||||||
|
placeholder="请选择跳转方式"
|
||||||
|
:options="whetherToClickOptions"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'skipMode'">
|
<template v-if="column.dataIndex === 'skipMode'">
|
||||||
<a-form-item :validate-status="validateStatus(record, 'skipMode')">
|
<a-form-item :validate-status="validateStatus(record, 'skipMode')">
|
||||||
<a-select v-model:value="record.skipMode" placeholder="请选择跳转方式" :disabled="record.whetherToClick === 'DISABLE'" :options="skipModeOptions" />
|
<a-select
|
||||||
|
v-model:value="record.skipMode"
|
||||||
|
placeholder="请选择跳转方式"
|
||||||
|
:disabled="record.whetherToClick === 'DISABLE'"
|
||||||
|
:options="skipModeOptions"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'url'">
|
<template v-if="column.dataIndex === 'url'">
|
||||||
<a-form-item :validate-status="validateStatus(record, 'url')">
|
<a-form-item :validate-status="validateStatus(record, 'url')">
|
||||||
<a-input v-model:value="formData[index].url" :disabled="record.whetherToClick === 'DISABLE'" placeholder="请输入URL或路由地址"/>
|
<a-input
|
||||||
|
v-model:value="formData[index].url"
|
||||||
|
:disabled="record.whetherToClick === 'DISABLE'"
|
||||||
|
placeholder="请输入URL或路由地址"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -28,7 +36,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script name="subForm" setup>
|
<script name="subForm" setup>
|
||||||
import tool from "@/utils/tool"
|
import tool from '@/utils/tool'
|
||||||
import { remove, isEmpty, cloneDeep } from 'lodash-es'
|
import { remove, isEmpty, cloneDeep } from 'lodash-es'
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
const formData = ref([])
|
const formData = ref([])
|
||||||
|
@ -48,17 +56,17 @@
|
||||||
{
|
{
|
||||||
title: '位置',
|
title: '位置',
|
||||||
dataIndex: 'label',
|
dataIndex: 'label',
|
||||||
width: '20%',
|
width: '20%'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '点击事件',
|
title: '点击事件',
|
||||||
dataIndex: 'whetherToClick',
|
dataIndex: 'whetherToClick',
|
||||||
width: '25%',
|
width: '25%'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '跳转方式',
|
title: '跳转方式',
|
||||||
dataIndex: 'skipMode',
|
dataIndex: 'skipMode',
|
||||||
width: '20%',
|
width: '20%'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'URL',
|
title: 'URL',
|
||||||
|
@ -77,7 +85,7 @@
|
||||||
const dataFiltrate = (newVal, oldVal) => {
|
const dataFiltrate = (newVal, oldVal) => {
|
||||||
let result = ''
|
let result = ''
|
||||||
oldVal.forEach((data) => {
|
oldVal.forEach((data) => {
|
||||||
if (!newVal.some(item => item === data)) {
|
if (!newVal.some((item) => item === data)) {
|
||||||
result = data
|
result = data
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -89,11 +97,11 @@
|
||||||
if (!isEmpty(props.dataArray) && isEmpty(formData.value)) {
|
if (!isEmpty(props.dataArray) && isEmpty(formData.value)) {
|
||||||
formData.value = cloneDeep(props.dataArray)
|
formData.value = cloneDeep(props.dataArray)
|
||||||
} else {
|
} else {
|
||||||
if (typeof newVal === "object") {
|
if (typeof newVal === 'object') {
|
||||||
if (!isEmpty(formData.value)) {
|
if (!isEmpty(formData.value)) {
|
||||||
formData.value.forEach(() => {
|
formData.value.forEach(() => {
|
||||||
// 如果包含
|
// 如果包含
|
||||||
if (!newVal.some(item => item === item.key)) {
|
if (!newVal.some((item) => item === item.key)) {
|
||||||
// 需要减少的
|
// 需要减少的
|
||||||
if (formData.value.length > newVal.length) {
|
if (formData.value.length > newVal.length) {
|
||||||
const deleteData = dataFiltrate(newVal, oldVal)
|
const deleteData = dataFiltrate(newVal, oldVal)
|
||||||
|
@ -103,10 +111,10 @@
|
||||||
if (formData.value.length < newVal.length) {
|
if (formData.value.length < newVal.length) {
|
||||||
const deleteData = dataFiltrate(oldVal, newVal)
|
const deleteData = dataFiltrate(oldVal, newVal)
|
||||||
// 如果没有,就不增加
|
// 如果没有,就不增加
|
||||||
if (!formData.value.some(item => item === deleteData)) {
|
if (!formData.value.some((item) => item === deleteData)) {
|
||||||
const obj = {
|
const obj = {
|
||||||
key: deleteData,
|
key: deleteData,
|
||||||
label: tool.dictTypeData('DEV_SLIDESHOW_PLACE' , deleteData),
|
label: tool.dictTypeData('DEV_SLIDESHOW_PLACE', deleteData),
|
||||||
whetherToClick: 'DISABLE',
|
whetherToClick: 'DISABLE',
|
||||||
skipMode: 'URL',
|
skipMode: 'URL',
|
||||||
url: ''
|
url: ''
|
||||||
|
@ -120,7 +128,7 @@
|
||||||
newVal.forEach((item) => {
|
newVal.forEach((item) => {
|
||||||
const obj = {
|
const obj = {
|
||||||
key: item,
|
key: item,
|
||||||
label: tool.dictTypeData('DEV_SLIDESHOW_PLACE' , item),
|
label: tool.dictTypeData('DEV_SLIDESHOW_PLACE', item),
|
||||||
whetherToClick: 'DISABLE',
|
whetherToClick: 'DISABLE',
|
||||||
skipMode: 'URL',
|
skipMode: 'URL',
|
||||||
url: ''
|
url: ''
|
||||||
|
|
|
@ -48,7 +48,13 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
发送短信
|
发送短信
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchSms" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchSms"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -180,7 +180,6 @@
|
||||||
|
|
||||||
<script setup name="genBasic">
|
<script setup name="genBasic">
|
||||||
import { required } from '@/utils/formRules'
|
import { required } from '@/utils/formRules'
|
||||||
import tool from '@/utils/tool'
|
|
||||||
import genBasicApi from '@/api/gen/genBasicApi'
|
import genBasicApi from '@/api/gen/genBasicApi'
|
||||||
const formRef = ref()
|
const formRef = ref()
|
||||||
// 表单数据
|
// 表单数据
|
||||||
|
@ -235,10 +234,14 @@
|
||||||
// 打开抽屉
|
// 打开抽屉
|
||||||
const onOpen = (record) => {
|
const onOpen = (record) => {
|
||||||
// 加载默认的模块
|
// 加载默认的模块
|
||||||
moduleOptions.value = tool.data.get('MENU').map((item) => {
|
genBasicApi.basicModuleSelector().then((data) => {
|
||||||
return {
|
if (data) {
|
||||||
label: item.name,
|
moduleOptions.value = data.map((item) => {
|
||||||
value: item.id
|
return {
|
||||||
|
label: item.name,
|
||||||
|
value: item.id
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// 获取数据库中的所有表
|
// 获取数据库中的所有表
|
||||||
|
@ -324,19 +327,22 @@
|
||||||
formData.value.menuPid = undefined
|
formData.value.menuPid = undefined
|
||||||
}
|
}
|
||||||
// 加载默认的模块
|
// 加载默认的模块
|
||||||
const menuTree = tool.data.get('MENU').find((item) => {
|
|
||||||
if (item.id === value) {
|
|
||||||
return item
|
|
||||||
}
|
|
||||||
})
|
|
||||||
menuTreeData.value = [
|
menuTreeData.value = [
|
||||||
{
|
{
|
||||||
id: '0',
|
id: '0',
|
||||||
title: '顶级',
|
title: '顶级',
|
||||||
menuType: 'CATALOG',
|
menuType: 'CATALOG',
|
||||||
children: traverseChildren(menuTree.children)
|
children: []
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
const param = {
|
||||||
|
module: value
|
||||||
|
}
|
||||||
|
genBasicApi.basicMenuTreeSelector(param).then((data) => {
|
||||||
|
if (data) {
|
||||||
|
menuTreeData.value[0].children = traverseChildren(data)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// 遍历增加属性
|
// 遍历增加属性
|
||||||
const traverseChildren = (data = []) => {
|
const traverseChildren = (data = []) => {
|
||||||
|
|
|
@ -43,7 +43,7 @@
|
||||||
<span v-else>无</span>
|
<span v-else>无</span>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'whetherTable'">
|
<template v-if="column.dataIndex === 'whetherTable'">
|
||||||
<a-checkbox v-model:checked="record.whetherTable" @change="whetherTableChange(record)"/>
|
<a-checkbox v-model:checked="record.whetherTable" @change="whetherTableChange(record)" />
|
||||||
</template>
|
</template>
|
||||||
<template v-if="column.dataIndex === 'whetherRetract'">
|
<template v-if="column.dataIndex === 'whetherRetract'">
|
||||||
<a-checkbox v-model:checked="record.whetherRetract" :disabled="!record.whetherTable" />
|
<a-checkbox v-model:checked="record.whetherRetract" :disabled="!record.whetherTable" />
|
||||||
|
|
|
@ -17,7 +17,13 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新建
|
新建
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchCodeGen" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchCodeGen"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -41,7 +41,13 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchMobileMenu" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchMobileMenu"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -33,7 +33,13 @@
|
||||||
</template>
|
</template>
|
||||||
新增模块
|
新增模块
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchModule" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchModule"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -51,7 +51,13 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchOrg" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchOrg"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -52,7 +52,13 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchPosition" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchPosition"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -40,9 +40,23 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增菜单
|
新增菜单
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchMenu" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchMenu"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
|
<template #headerCell="{ title, column }">
|
||||||
|
<template v-if="column.dataIndex === 'visible'">
|
||||||
|
<a-tooltip>
|
||||||
|
<template #title> 如果将上级目录设置为隐藏,那么上级目录下的菜单都会被隐藏! </template>
|
||||||
|
<question-circle-outlined />  {{ title }}
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
<template v-if="column.dataIndex === 'path'">
|
<template v-if="column.dataIndex === 'path'">
|
||||||
<span v-if="record.menuType === 'MENU'">{{ record.path }}</span>
|
<span v-if="record.menuType === 'MENU'">{{ record.path }}</span>
|
||||||
|
@ -133,12 +147,12 @@
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
title: '显示名称',
|
title: '显示名称',
|
||||||
dataIndex: 'title',
|
dataIndex: 'title'
|
||||||
width: 260
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '图标',
|
title: '图标',
|
||||||
dataIndex: 'icon'
|
dataIndex: 'icon',
|
||||||
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '类型',
|
title: '类型',
|
||||||
|
@ -160,12 +174,13 @@
|
||||||
{
|
{
|
||||||
title: '是否可见',
|
title: '是否可见',
|
||||||
dataIndex: 'visible',
|
dataIndex: 'visible',
|
||||||
width: 100
|
width: 120
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '排序',
|
title: '排序',
|
||||||
dataIndex: 'sortCode',
|
dataIndex: 'sortCode',
|
||||||
sorter: true
|
sorter: true,
|
||||||
|
width: 100
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
|
|
|
@ -31,7 +31,13 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增模块
|
新增模块
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchModule" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchModule"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -56,7 +56,13 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增角色
|
新增角色
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete :selectedRowKeys="selectedRowKeys" @batchDelete="deleteBatchRole" />
|
<xn-batch-button
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
|
:selectedRowKeys="selectedRowKeys"
|
||||||
|
@batchCallBack="deleteBatchRole"
|
||||||
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
<template #bodyCell="{ column, record }">
|
<template #bodyCell="{ column, record }">
|
||||||
|
|
|
@ -76,10 +76,12 @@
|
||||||
<template #icon><export-outlined /></template>
|
<template #icon><export-outlined /></template>
|
||||||
{{ $t('user.batchExportButton') }}
|
{{ $t('user.batchExportButton') }}
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete
|
<xn-batch-button
|
||||||
:buttonName="$t('common.batchRemoveButton')"
|
:buttonName="$t('common.batchRemoveButton')"
|
||||||
|
icon="DeleteOutlined"
|
||||||
|
buttonDanger
|
||||||
:selectedRowKeys="selectedRowKeys"
|
:selectedRowKeys="selectedRowKeys"
|
||||||
@batchDelete="deleteBatchUser"
|
@batchCallBack="deleteBatchUser"
|
||||||
/>
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -33,7 +33,7 @@ public enum CommonSortOrderEnum {
|
||||||
private final String value;
|
private final String value;
|
||||||
|
|
||||||
CommonSortOrderEnum(String value) {
|
CommonSortOrderEnum(String value) {
|
||||||
this.value = value.toUpperCase();
|
this.value = value.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void validate(String value) {
|
public static void validate(String value) {
|
||||||
|
|
|
@ -26,5 +26,5 @@ public interface CommonTimerTaskRunner {
|
||||||
* @author xuyuxiang
|
* @author xuyuxiang
|
||||||
* @date 2022/8/15 16:09
|
* @date 2022/8/15 16:09
|
||||||
**/
|
**/
|
||||||
void action();
|
void action(String extJson);
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,9 +61,9 @@ public class CommonNetWorkInfoUtil {
|
||||||
input = new BufferedReader(new InputStreamReader(pro.getInputStream()));
|
input = new BufferedReader(new InputStreamReader(pro.getInputStream()));
|
||||||
long[] result2 = readInLine(input, isWindows);
|
long[] result2 = readInLine(input, isWindows);
|
||||||
String upSpeed = FileUtil.readableFileSize(Convert.toLong(NumberUtil
|
String upSpeed = FileUtil.readableFileSize(Convert.toLong(NumberUtil
|
||||||
.div(NumberUtil.sub(result2[0], result1[0]), SLEEP_SECONDS)));
|
|
||||||
String downSpeed = FileUtil.readableFileSize(Convert.toLong(NumberUtil
|
|
||||||
.div(NumberUtil.sub(result2[1], result1[1]), SLEEP_SECONDS)));
|
.div(NumberUtil.sub(result2[1], result1[1]), SLEEP_SECONDS)));
|
||||||
|
String downSpeed = FileUtil.readableFileSize(Convert.toLong(NumberUtil
|
||||||
|
.div(NumberUtil.sub(result2[0], result1[0]), SLEEP_SECONDS)));
|
||||||
result.put("UP", upSpeed + (upSpeed.endsWith("B")?"/S":"B/S"));
|
result.put("UP", upSpeed + (upSpeed.endsWith("B")?"/S":"B/S"));
|
||||||
result.put("DOWN", downSpeed + (downSpeed.endsWith("B")?"/S":"B/S"));
|
result.put("DOWN", downSpeed + (downSpeed.endsWith("B")?"/S":"B/S"));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -12,6 +12,10 @@
|
||||||
*/
|
*/
|
||||||
package vip.xiaonuo.sys.api;
|
package vip.xiaonuo.sys.api;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.tree.Tree;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单API
|
* 菜单API
|
||||||
*
|
*
|
||||||
|
@ -27,4 +31,12 @@ public interface SysMenuApi {
|
||||||
* @date 2022/11/1 13:48
|
* @date 2022/11/1 13:48
|
||||||
**/
|
**/
|
||||||
String addForGenMenu(String parentId, String busName, String module, String title, String path);
|
String addForGenMenu(String parentId, String busName, String module, String title, String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有菜单树包括未授权的
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
**/
|
||||||
|
List<Tree<String>> menuTreeSelector(String module);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||||
|
*
|
||||||
|
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||||
|
*
|
||||||
|
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||||
|
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||||
|
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||||
|
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||||
|
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||||
|
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||||
|
*/
|
||||||
|
package vip.xiaonuo.sys.api;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模块API
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
**/
|
||||||
|
public interface SysModuleApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有模块
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
**/
|
||||||
|
List<JSONObject> moduleSelector();
|
||||||
|
}
|
|
@ -44,7 +44,7 @@ public class DevJobListener implements ApplicationListener<ApplicationStartedEve
|
||||||
.forEach(devJob -> CronUtil.schedule(devJob.getId(), devJob.getCronExpression(), () -> {
|
.forEach(devJob -> CronUtil.schedule(devJob.getId(), devJob.getCronExpression(), () -> {
|
||||||
try {
|
try {
|
||||||
// 运行定时任务
|
// 运行定时任务
|
||||||
((CommonTimerTaskRunner) SpringUtil.getBean(Class.forName(devJob.getActionClass()))).action();
|
((CommonTimerTaskRunner) SpringUtil.getBean(Class.forName(devJob.getActionClass()))).action(devJob.getExtJson());
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
throw new CommonException("定时任务找不到对应的类,名称为:{}", devJob.getActionClass());
|
throw new CommonException("定时任务找不到对应的类,名称为:{}", devJob.getActionClass());
|
||||||
}
|
}
|
||||||
|
|
|
@ -61,8 +61,9 @@ public class DevApiProvider implements DevApi {
|
||||||
DevDictCategoryEnum.FRM.getValue()));
|
DevDictCategoryEnum.FRM.getValue()));
|
||||||
Long bizDictCount = devDictService.count(new LambdaQueryWrapper<DevDict>().eq(DevDict::getCategory,
|
Long bizDictCount = devDictService.count(new LambdaQueryWrapper<DevDict>().eq(DevDict::getCategory,
|
||||||
DevDictCategoryEnum.BIZ.getValue()));
|
DevDictCategoryEnum.BIZ.getValue()));
|
||||||
Long jobCount = devJobService.count(new LambdaQueryWrapper<DevJob>().eq(DevJob::getJobStatus,
|
Long jobCount = 0L;
|
||||||
DevJobStatusEnum.RUNNING.getValue()));
|
// Long jobCount = devJobService.count(new LambdaQueryWrapper<DevJob>().eq(DevJob::getJobStatus,
|
||||||
|
// DevJobStatusEnum.RUNNING.getValue()));
|
||||||
JSONObject json = new JSONObject();
|
JSONObject json = new JSONObject();
|
||||||
json.set("sysDictCount", sysDictCount);
|
json.set("sysDictCount", sysDictCount);
|
||||||
json.set("bizDictCount", bizDictCount);
|
json.set("bizDictCount", bizDictCount);
|
||||||
|
|
|
@ -70,7 +70,7 @@ public class DevEmailAliyunUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
client = new Client(new Config().setRegionId(regionId).setAccessKeyId(accessKeyId).setAccessKeySecret(accessKeySecret));
|
client = new Client(new Config().setRegionId(regionId).setEndpoint("dm.aliyuncs.com").setAccessKeyId(accessKeyId).setAccessKeySecret(accessKeySecret));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new CommonException(e.getMessage());
|
throw new CommonException(e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,7 +214,7 @@ public class DevJobServiceImpl extends ServiceImpl<DevJobMapper, DevJob> impleme
|
||||||
CronUtil.schedule(devJob.getId(), devJob.getCronExpression(), () -> {
|
CronUtil.schedule(devJob.getId(), devJob.getCronExpression(), () -> {
|
||||||
try {
|
try {
|
||||||
// 运行定时任务
|
// 运行定时任务
|
||||||
((CommonTimerTaskRunner) SpringUtil.getBean(Class.forName(devJob.getActionClass()))).action();
|
((CommonTimerTaskRunner) SpringUtil.getBean(Class.forName(devJob.getActionClass()))).action(devJob.getExtJson());
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
throw new CommonException("定时任务找不到对应的类,名称为:{}", devJob.getActionClass());
|
throw new CommonException("定时任务找不到对应的类,名称为:{}", devJob.getActionClass());
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ public class DevJobServiceImpl extends ServiceImpl<DevJobMapper, DevJob> impleme
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
// 直接运行一次
|
// 直接运行一次
|
||||||
((CommonTimerTaskRunner) SpringUtil.getBean(Class.forName(devJob.getActionClass()))).action();
|
((CommonTimerTaskRunner) SpringUtil.getBean(Class.forName(devJob.getActionClass()))).action(devJob.getExtJson());
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
throw new CommonException("定时任务找不到对应的类,名称为:{}", devJob.getActionClass());
|
throw new CommonException("定时任务找不到对应的类,名称为:{}", devJob.getActionClass());
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class DevJobTimerTaskRunner implements CommonTimerTaskRunner {
|
||||||
private int n = 1;
|
private int n = 1;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void action() {
|
public void action(String extJson) {
|
||||||
log.info("我是一个定时任务,正在在被执行第" + n + "次");
|
log.info("我是一个定时任务,正在在被执行第" + n + "次");
|
||||||
n = n + 1;
|
n = n + 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import cn.hutool.core.collection.CollStreamUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.PhoneUtil;
|
import cn.hutool.core.util.PhoneUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
@ -25,6 +26,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||||
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
|
import vip.xiaonuo.common.enums.CommonSortOrderEnum;
|
||||||
import vip.xiaonuo.common.exception.CommonException;
|
import vip.xiaonuo.common.exception.CommonException;
|
||||||
import vip.xiaonuo.common.page.CommonPageRequest;
|
import vip.xiaonuo.common.page.CommonPageRequest;
|
||||||
|
import vip.xiaonuo.dev.api.DevConfigApi;
|
||||||
import vip.xiaonuo.dev.modular.sms.entity.DevSms;
|
import vip.xiaonuo.dev.modular.sms.entity.DevSms;
|
||||||
import vip.xiaonuo.dev.modular.sms.enums.DevSmsEngineTypeEnum;
|
import vip.xiaonuo.dev.modular.sms.enums.DevSmsEngineTypeEnum;
|
||||||
import vip.xiaonuo.dev.modular.sms.mapper.DevSmsMapper;
|
import vip.xiaonuo.dev.modular.sms.mapper.DevSmsMapper;
|
||||||
|
|
|
@ -16,6 +16,7 @@ import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.dromara.sms4j.api.SmsBlend;
|
import org.dromara.sms4j.api.SmsBlend;
|
||||||
|
@ -106,7 +107,8 @@ public class DevSmsXiaonuoUtil {
|
||||||
if(smsResponse.isSuccess()) {
|
if(smsResponse.isSuccess()) {
|
||||||
return JSONUtil.toJsonStr(smsResponse.getData());
|
return JSONUtil.toJsonStr(smsResponse.getData());
|
||||||
} else {
|
} else {
|
||||||
throw new CommonException("短信发送失败");
|
JSONObject responseData = JSONUtil.parseObj(smsResponse.getData());
|
||||||
|
throw new CommonException(responseData.getStr("resInfo"));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new CommonException(e.getMessage());
|
throw new CommonException(e.getMessage());
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
package vip.xiaonuo.gen.modular.basic.controller;
|
package vip.xiaonuo.gen.modular.basic.controller;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.tree.Tree;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
@ -29,10 +30,7 @@ import vip.xiaonuo.common.annotation.CommonLog;
|
||||||
import vip.xiaonuo.common.pojo.CommonResult;
|
import vip.xiaonuo.common.pojo.CommonResult;
|
||||||
import vip.xiaonuo.gen.modular.basic.entity.GenBasic;
|
import vip.xiaonuo.gen.modular.basic.entity.GenBasic;
|
||||||
import vip.xiaonuo.gen.modular.basic.param.*;
|
import vip.xiaonuo.gen.modular.basic.param.*;
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicMobileModuleSelectorResult;
|
import vip.xiaonuo.gen.modular.basic.result.*;
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicPreviewResult;
|
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicTableColumnResult;
|
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicTableResult;
|
|
||||||
import vip.xiaonuo.gen.modular.basic.service.GenBasicService;
|
import vip.xiaonuo.gen.modular.basic.service.GenBasicService;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -192,5 +190,29 @@ public class GenBasicController {
|
||||||
public CommonResult<List<GenBasicMobileModuleSelectorResult>> mobileModuleSelector() {
|
public CommonResult<List<GenBasicMobileModuleSelectorResult>> mobileModuleSelector() {
|
||||||
return CommonResult.data(genBasicService.mobileModuleSelector());
|
return CommonResult.data(genBasicService.mobileModuleSelector());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有模块
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
*/
|
||||||
|
@Operation(summary = "获取所有模块")
|
||||||
|
@GetMapping("/gen/basic/moduleSelector")
|
||||||
|
public CommonResult<List<GenBasicModuleSelectorResult>> moduleSelector() {
|
||||||
|
return CommonResult.data(genBasicService.moduleSelector());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码生成获取所有菜单树包括未授权的
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
**/
|
||||||
|
@Operation(summary = "代码生成获取所有菜单树包括未授权的")
|
||||||
|
@GetMapping("/gen/basic/menuTreeSelector")
|
||||||
|
public CommonResult<List<Tree<String>>> menuTreeSelector(@Valid GenBasicSelectorMenuParam genBasicSelectorMenuParam) {
|
||||||
|
return CommonResult.data(genBasicService.menuTreeSelector(genBasicSelectorMenuParam));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||||
|
*
|
||||||
|
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||||
|
*
|
||||||
|
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||||
|
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||||
|
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||||
|
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||||
|
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||||
|
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||||
|
*/
|
||||||
|
package vip.xiaonuo.gen.modular.basic.param;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单选择器参数
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
**/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class GenBasicSelectorMenuParam {
|
||||||
|
|
||||||
|
/** 模块 */
|
||||||
|
@Schema(description = "模块")
|
||||||
|
@NotBlank(message = "module不能为空")
|
||||||
|
private String module;
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||||
|
*
|
||||||
|
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||||
|
*
|
||||||
|
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||||
|
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||||
|
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||||
|
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||||
|
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||||
|
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||||
|
*/
|
||||||
|
package vip.xiaonuo.gen.modular.basic.result;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码生成模块所需要用到的模块选择的结果
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
**/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class GenBasicModuleSelectorResult {
|
||||||
|
|
||||||
|
/** id */
|
||||||
|
@Schema(description = "id")
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
/** 名称 */
|
||||||
|
@Schema(description = "名称")
|
||||||
|
private String name;
|
||||||
|
}
|
|
@ -12,15 +12,13 @@
|
||||||
*/
|
*/
|
||||||
package vip.xiaonuo.gen.modular.basic.service;
|
package vip.xiaonuo.gen.modular.basic.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.tree.Tree;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import vip.xiaonuo.gen.modular.basic.entity.GenBasic;
|
import vip.xiaonuo.gen.modular.basic.entity.GenBasic;
|
||||||
import vip.xiaonuo.gen.modular.basic.param.*;
|
import vip.xiaonuo.gen.modular.basic.param.*;
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicMobileModuleSelectorResult;
|
import vip.xiaonuo.gen.modular.basic.result.*;
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicPreviewResult;
|
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicTableColumnResult;
|
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicTableResult;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -128,4 +126,20 @@ public interface GenBasicService extends IService<GenBasic> {
|
||||||
* @date 2023/7/15 22:28
|
* @date 2023/7/15 22:28
|
||||||
**/
|
**/
|
||||||
List<GenBasicMobileModuleSelectorResult> mobileModuleSelector();
|
List<GenBasicMobileModuleSelectorResult> mobileModuleSelector();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模块
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
**/
|
||||||
|
List<GenBasicModuleSelectorResult> moduleSelector();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码生成获取所有菜单树包括未授权的
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
**/
|
||||||
|
List<Tree<String>> menuTreeSelector(GenBasicSelectorMenuParam genBasicSelectorMenuParam);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.date.DateTime;
|
import cn.hutool.core.date.DateTime;
|
||||||
import cn.hutool.core.date.DateUtil;
|
import cn.hutool.core.date.DateUtil;
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.lang.tree.Tree;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
@ -51,10 +52,7 @@ import vip.xiaonuo.gen.modular.basic.enums.GenEffectTypeEnum;
|
||||||
import vip.xiaonuo.gen.modular.basic.enums.GenYesNoEnum;
|
import vip.xiaonuo.gen.modular.basic.enums.GenYesNoEnum;
|
||||||
import vip.xiaonuo.gen.modular.basic.mapper.GenBasicMapper;
|
import vip.xiaonuo.gen.modular.basic.mapper.GenBasicMapper;
|
||||||
import vip.xiaonuo.gen.modular.basic.param.*;
|
import vip.xiaonuo.gen.modular.basic.param.*;
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicMobileModuleSelectorResult;
|
import vip.xiaonuo.gen.modular.basic.result.*;
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicPreviewResult;
|
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicTableColumnResult;
|
|
||||||
import vip.xiaonuo.gen.modular.basic.result.GenBasicTableResult;
|
|
||||||
import vip.xiaonuo.gen.modular.basic.service.GenBasicService;
|
import vip.xiaonuo.gen.modular.basic.service.GenBasicService;
|
||||||
import vip.xiaonuo.gen.modular.config.entity.GenConfig;
|
import vip.xiaonuo.gen.modular.config.entity.GenConfig;
|
||||||
import vip.xiaonuo.gen.modular.config.param.GenConfigAddParam;
|
import vip.xiaonuo.gen.modular.config.param.GenConfigAddParam;
|
||||||
|
@ -62,6 +60,7 @@ import vip.xiaonuo.gen.modular.config.service.GenConfigService;
|
||||||
import vip.xiaonuo.mobile.api.MobileModuleApi;
|
import vip.xiaonuo.mobile.api.MobileModuleApi;
|
||||||
import vip.xiaonuo.sys.api.SysButtonApi;
|
import vip.xiaonuo.sys.api.SysButtonApi;
|
||||||
import vip.xiaonuo.sys.api.SysMenuApi;
|
import vip.xiaonuo.sys.api.SysMenuApi;
|
||||||
|
import vip.xiaonuo.sys.api.SysModuleApi;
|
||||||
import vip.xiaonuo.sys.api.SysRoleApi;
|
import vip.xiaonuo.sys.api.SysRoleApi;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
@ -148,6 +147,9 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
|
||||||
@Resource
|
@Resource
|
||||||
private SysMenuApi sysMenuApi;
|
private SysMenuApi sysMenuApi;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysModuleApi sysModuleApi;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SysButtonApi sysButtonApi;
|
private SysButtonApi sysButtonApi;
|
||||||
|
|
||||||
|
@ -597,7 +599,20 @@ public class GenBasicServiceImpl extends ServiceImpl<GenBasicMapper, GenBasic> i
|
||||||
@Override
|
@Override
|
||||||
public List<GenBasicMobileModuleSelectorResult> mobileModuleSelector() {
|
public List<GenBasicMobileModuleSelectorResult> mobileModuleSelector() {
|
||||||
return mobileModuleApi.mobileModuleSelector().stream()
|
return mobileModuleApi.mobileModuleSelector().stream()
|
||||||
.map(jsonObject -> JSONUtil.toBean(jsonObject, GenBasicMobileModuleSelectorResult.class)).collect(Collectors.toList());
|
.map(jsonObject -> JSONUtil.toBean(jsonObject, GenBasicMobileModuleSelectorResult.class))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<GenBasicModuleSelectorResult> moduleSelector() {
|
||||||
|
return sysModuleApi.moduleSelector().stream()
|
||||||
|
.map(jsonObject -> JSONUtil.toBean(jsonObject, GenBasicModuleSelectorResult.class))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Tree<String>> menuTreeSelector(GenBasicSelectorMenuParam genBasicSelectorMenuParam) {
|
||||||
|
return sysMenuApi.menuTreeSelector(genBasicSelectorMenuParam.getModule());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -96,10 +96,12 @@
|
||||||
<template #icon><plus-outlined /></template>
|
<template #icon><plus-outlined /></template>
|
||||||
新增
|
新增
|
||||||
</a-button>
|
</a-button>
|
||||||
<xn-batch-delete
|
<xn-batch-button
|
||||||
v-if="hasPerm('${classNameFirstLower}BatchDelete')"
|
v-if="hasPerm('${classNameFirstLower}BatchDelete')"
|
||||||
|
buttonName="批量删除"
|
||||||
|
icon="DeleteOutlined"
|
||||||
:selectedRowKeys="selectedRowKeys"
|
:selectedRowKeys="selectedRowKeys"
|
||||||
@batchDelete="deleteBatch${className}"
|
@batchCallBack="deleteBatch${className}"
|
||||||
/>
|
/>
|
||||||
</a-space>
|
</a-space>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -17,6 +17,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
@ -96,7 +97,7 @@ public class MobileButtonController {
|
||||||
@Operation(summary = "删除移动端按钮")
|
@Operation(summary = "删除移动端按钮")
|
||||||
@CommonLog("删除移动端按钮")
|
@CommonLog("删除移动端按钮")
|
||||||
@PostMapping("/mobile/button/delete")
|
@PostMapping("/mobile/button/delete")
|
||||||
public CommonResult<String> delete(@RequestBody @Valid List<MobileButtonIdParam> mobileButtonIdParamList) {
|
public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空") List<MobileButtonIdParam> mobileButtonIdParamList) {
|
||||||
mobileButtonService.delete(mobileButtonIdParamList);
|
mobileButtonService.delete(mobileButtonIdParamList);
|
||||||
return CommonResult.ok();
|
return CommonResult.ok();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
@ -96,7 +97,7 @@ public class SysButtonController {
|
||||||
@Operation(summary = "删除按钮")
|
@Operation(summary = "删除按钮")
|
||||||
@CommonLog("删除按钮")
|
@CommonLog("删除按钮")
|
||||||
@PostMapping("/sys/button/delete")
|
@PostMapping("/sys/button/delete")
|
||||||
public CommonResult<String> delete(@RequestBody @Valid List<SysButtonIdParam> sysButtonIdParamList) {
|
public CommonResult<String> delete(@RequestBody @Valid @NotEmpty(message = "集合不能为空") List<SysButtonIdParam> sysButtonIdParamList) {
|
||||||
sysButtonService.delete(sysButtonIdParamList);
|
sysButtonService.delete(sysButtonIdParamList);
|
||||||
return CommonResult.ok();
|
return CommonResult.ok();
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,11 +12,15 @@
|
||||||
*/
|
*/
|
||||||
package vip.xiaonuo.sys.modular.resource.provider;
|
package vip.xiaonuo.sys.modular.resource.provider;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.tree.Tree;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import vip.xiaonuo.sys.api.SysMenuApi;
|
import vip.xiaonuo.sys.api.SysMenuApi;
|
||||||
|
import vip.xiaonuo.sys.modular.resource.param.menu.SysMenuSelectorMenuParam;
|
||||||
import vip.xiaonuo.sys.modular.resource.service.SysMenuService;
|
import vip.xiaonuo.sys.modular.resource.service.SysMenuService;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 菜单API接口实现类
|
* 菜单API接口实现类
|
||||||
*
|
*
|
||||||
|
@ -33,4 +37,11 @@ public class SysMenuApiProvider implements SysMenuApi {
|
||||||
public String addForGenMenu(String parentId, String busName, String module, String title, String path) {
|
public String addForGenMenu(String parentId, String busName, String module, String title, String path) {
|
||||||
return sysMenuService.addForGenMenu(parentId, busName, title, module, path);
|
return sysMenuService.addForGenMenu(parentId, busName, title, module, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Tree<String>> menuTreeSelector(String module) {
|
||||||
|
SysMenuSelectorMenuParam param = new SysMenuSelectorMenuParam();
|
||||||
|
param.setModule(module);
|
||||||
|
return sysMenuService.menuTreeSelector(param);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
/*
|
||||||
|
* Copyright [2022] [https://www.xiaonuo.vip]
|
||||||
|
*
|
||||||
|
* Snowy采用APACHE LICENSE 2.0开源协议,您在使用过程中,需要注意以下几点:
|
||||||
|
*
|
||||||
|
* 1.请不要删除和修改根目录下的LICENSE文件。
|
||||||
|
* 2.请不要删除和修改Snowy源码头部的版权声明。
|
||||||
|
* 3.本项目代码可免费商业使用,商业使用请保留源码和相关描述文件的项目出处,作者声明等。
|
||||||
|
* 4.分发源码时候,请注明软件出处 https://www.xiaonuo.vip
|
||||||
|
* 5.不可二次分发开源参与同类竞品,如有想法可联系团队xiaonuobase@qq.com商议合作。
|
||||||
|
* 6.若您的项目无法满足以上几点,需要更多功能代码,获取Snowy商业授权许可,请在官网购买授权,地址为 https://www.xiaonuo.vip
|
||||||
|
*/
|
||||||
|
package vip.xiaonuo.sys.modular.resource.provider;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import vip.xiaonuo.sys.api.SysModuleApi;
|
||||||
|
import vip.xiaonuo.sys.modular.resource.service.SysModuleService;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模块API接口实现类
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
**/
|
||||||
|
@Service
|
||||||
|
public class SysModuleApiProvider implements SysModuleApi {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysModuleService sysModuleService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<JSONObject> moduleSelector() {
|
||||||
|
return sysModuleService.moduleSelector();
|
||||||
|
}
|
||||||
|
}
|
|
@ -12,6 +12,7 @@
|
||||||
*/
|
*/
|
||||||
package vip.xiaonuo.sys.modular.resource.service;
|
package vip.xiaonuo.sys.modular.resource.service;
|
||||||
|
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import vip.xiaonuo.sys.modular.resource.entity.SysModule;
|
import vip.xiaonuo.sys.modular.resource.entity.SysModule;
|
||||||
|
@ -62,6 +63,14 @@ public interface SysModuleService extends IService<SysModule> {
|
||||||
*/
|
*/
|
||||||
void delete(List<SysModuleIdParam> sysModuleIdParamList);
|
void delete(List<SysModuleIdParam> sysModuleIdParamList);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有模块
|
||||||
|
*
|
||||||
|
* @author yubaoshan
|
||||||
|
* @date 2024/9/6 01:24
|
||||||
|
*/
|
||||||
|
List<JSONObject> moduleSelector();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取模块详情
|
* 获取模块详情
|
||||||
*
|
*
|
||||||
|
|
|
@ -18,6 +18,7 @@ import cn.hutool.core.collection.CollectionUtil;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
import cn.hutool.json.JSONUtil;
|
import cn.hutool.json.JSONUtil;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
@ -150,6 +151,16 @@ public class SysModuleServiceImpl extends ServiceImpl<SysModuleMapper, SysModule
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<JSONObject> moduleSelector() {
|
||||||
|
LambdaQueryWrapper<SysModule> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
lambdaQueryWrapper.select(SysModule::getId, SysModule::getTitle);
|
||||||
|
lambdaQueryWrapper.eq(SysModule::getCategory, SysResourceCategoryEnum.MODULE.getValue());
|
||||||
|
return this.list(lambdaQueryWrapper).stream()
|
||||||
|
.map(item -> JSONUtil.createObj().set("id", item.getId()).set("name", item.getTitle()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SysModule detail(SysModuleIdParam sysModuleIdParam) {
|
public SysModule detail(SysModuleIdParam sysModuleIdParam) {
|
||||||
return this.queryEntity(sysModuleIdParam.getId());
|
return this.queryEntity(sysModuleIdParam.getId());
|
||||||
|
|
|
@ -697,19 +697,19 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
|
||||||
if (sysMenu.getCategory().equals(SysResourceCategoryEnum.MENU.getValue())) {
|
if (sysMenu.getCategory().equals(SysResourceCategoryEnum.MENU.getValue())) {
|
||||||
if (!sysMenu.getMenuType().equals(SysResourceMenuTypeEnum.CATALOG.getValue())) {
|
if (!sysMenu.getMenuType().equals(SysResourceMenuTypeEnum.CATALOG.getValue())) {
|
||||||
metaJsonObject.set("type", sysMenu.getMenuType().toLowerCase());
|
metaJsonObject.set("type", sysMenu.getMenuType().toLowerCase());
|
||||||
// 如果设置了不可见,那么设置为false,为了兼容已有,所以只是false的为不显示
|
|
||||||
if (ObjectUtil.isNotEmpty(sysMenu.getVisible()) && sysMenu.getVisible().equals("FALSE")) {
|
|
||||||
metaJsonObject.set("hidden", true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (sysMenu.getId().equals(sysMenus.orElse(null).getId())) {
|
if (sysMenu.getId().equals(sysMenus.orElse(null).getId())) {
|
||||||
// 如果是首页,则设置affix
|
// 如果是首页,则设置affix
|
||||||
metaJsonObject.set("affix", true);
|
metaJsonObject.set("affix", true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 如果设置了不可见,那么设置为false,为了兼容已有,所以只是false的为不显示
|
||||||
|
if (ObjectUtil.isNotEmpty(sysMenu.getVisible()) && sysMenu.getVisible().equals("FALSE")) {
|
||||||
|
metaJsonObject.set("hidden", true);
|
||||||
|
}
|
||||||
menuJsonObject.set("meta", metaJsonObject);
|
menuJsonObject.set("meta", metaJsonObject);
|
||||||
return menuJsonObject;
|
return menuJsonObject;
|
||||||
}).collect(Collectors.toList());
|
}).toList();
|
||||||
|
|
||||||
// 执行构造树
|
// 执行构造树
|
||||||
List<TreeNode<String>> treeNodeList = resultJsonObjectList.stream().map(jsonObject ->
|
List<TreeNode<String>> treeNodeList = resultJsonObjectList.stream().map(jsonObject ->
|
||||||
|
|
|
@ -95,7 +95,7 @@ spring.datasource.dynamic.druid.break-after-acquire-failure=false
|
||||||
spring.jackson.time-zone=GMT+8
|
spring.jackson.time-zone=GMT+8
|
||||||
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
|
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
|
||||||
spring.jackson.locale=zh_CN
|
spring.jackson.locale=zh_CN
|
||||||
spring.jackson.serialization.write-dates-as-timestamps=true
|
spring.jackson.serialization.write-dates-as-timestamps=false
|
||||||
#########################################
|
#########################################
|
||||||
# redis configuration
|
# redis configuration
|
||||||
#########################################
|
#########################################
|
||||||
|
|
Loading…
Reference in New Issue