mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2025-10-13 03:43:50 +08:00
导出表格,升级依赖
This commit is contained in:
@@ -1,7 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-project",
|
"name": "x_admin",
|
||||||
"version": "0.0.0",
|
"version": "0.0.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"prod": "vite build",
|
"prod": "vite build",
|
||||||
@@ -13,54 +14,55 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.3.1",
|
"@element-plus/icons-vue": "^2.3.1",
|
||||||
"@highlightjs/vue-plugin": "^2.1.0",
|
"@highlightjs/vue-plugin": "^2.1.0",
|
||||||
"@logicflow/core": "^1.2.18",
|
"@logicflow/core": "^1.2.22",
|
||||||
"@logicflow/extension": "^1.2.19",
|
"@logicflow/extension": "^1.2.22",
|
||||||
"@vue/shared": "^3.4.3",
|
"@vue/shared": "^3.4.19",
|
||||||
"@vueuse/core": "^10.7.1",
|
"@vueuse/core": "^10.7.2",
|
||||||
"@wangeditor/editor": "^5.1.23",
|
"@wangeditor/editor": "^5.1.23",
|
||||||
"@wangeditor/editor-for-vue": "^5.1.12",
|
"@wangeditor/editor-for-vue": "^5.1.12",
|
||||||
"axios": "^1.6.3",
|
"axios": "^1.6.7",
|
||||||
"consola": "^3.2.3",
|
"consola": "^3.2.3",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"css-color-function": "^1.3.3",
|
"css-color-function": "^1.3.3",
|
||||||
"echarts": "^5.4.3",
|
"echarts": "^5.5.0",
|
||||||
"element-plus": "^2.4.4",
|
"element-plus": "^2.5.6",
|
||||||
"highlight.js": "^11.9.0",
|
"highlight.js": "^11.9.0",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^2.1.7",
|
"pinia": "^2.1.7",
|
||||||
|
"query-string": "^8.2.0",
|
||||||
"vform3-builds": "^3.0.10",
|
"vform3-builds": "^3.0.10",
|
||||||
"vue": "^3.4.3",
|
"vue": "^3.4.19",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-echarts": "^6.6.8",
|
"vue-echarts": "^6.6.9",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
"vue3-video-play": "^1.3.2",
|
"vue3-video-play": "^1.3.2",
|
||||||
"vuedraggable": "^4.1.0"
|
"vuedraggable": "^4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rushstack/eslint-patch": "^1.6.1",
|
"@rushstack/eslint-patch": "^1.7.2",
|
||||||
"@types/lodash-es": "^4.17.12",
|
"@types/lodash-es": "^4.17.12",
|
||||||
"@types/node": "^20.10.6",
|
"@types/node": "^20.11.19",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@vitejs/plugin-vue": "^5.0.2",
|
"@vitejs/plugin-vue": "^5.0.4",
|
||||||
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
"@vitejs/plugin-vue-jsx": "^3.1.0",
|
||||||
"@vue/eslint-config-prettier": "^9.0.0",
|
"@vue/eslint-config-prettier": "^9.0.0",
|
||||||
"@vue/eslint-config-typescript": "^12.0.0",
|
"@vue/eslint-config-typescript": "^12.0.0",
|
||||||
"@vue/tsconfig": "^0.5.1",
|
"@vue/tsconfig": "^0.5.1",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.17",
|
||||||
"eslint": "^8.56.0",
|
"eslint": "^8.56.0",
|
||||||
"eslint-plugin-vue": "^9.19.2",
|
"eslint-plugin-vue": "^9.21.1",
|
||||||
"execa": "^8.0.1",
|
"execa": "^8.0.1",
|
||||||
"fs-extra": "^11.2.0",
|
"fs-extra": "^11.2.0",
|
||||||
"postcss": "^8.4.32",
|
"postcss": "^8.4.35",
|
||||||
"prettier": "^3.1.1",
|
"prettier": "^3.2.5",
|
||||||
"rollup-plugin-visualizer": "^5.12.0",
|
"rollup-plugin-visualizer": "^5.12.0",
|
||||||
"sass": "^1.69.6",
|
"sass": "^1.71.0",
|
||||||
"tailwindcss": "^3.4.0",
|
"tailwindcss": "^3.4.1",
|
||||||
"typescript": "~5.3.3",
|
"typescript": "~5.3.3",
|
||||||
"unplugin-auto-import": "^0.17.3",
|
"unplugin-auto-import": "^0.17.5",
|
||||||
"unplugin-vue-components": "^0.26.0",
|
"unplugin-vue-components": "^0.26.0",
|
||||||
"vite": "^4.5.0",
|
"vite": "^5.1.3",
|
||||||
"vite-plugin-compression": "^0.5.1",
|
"vite-plugin-compression": "^0.5.1",
|
||||||
"vite-plugin-style-import": "^2.0.0",
|
"vite-plugin-style-import": "^2.0.0",
|
||||||
"vite-plugin-svg-icons": "^2.0.1",
|
"vite-plugin-svg-icons": "^2.0.1",
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
import request from '@/utils/request'
|
import request from '@/utils/request'
|
||||||
|
import queryString from 'query-string'
|
||||||
|
import { getToken } from '@/utils/auth'
|
||||||
// 管理员列表
|
// 管理员列表
|
||||||
export function adminLists(params: any) {
|
export function adminLists(params: any) {
|
||||||
return request.get({ url: '/system/admin/list', params })
|
return request.get({ url: '/system/admin/list', params })
|
||||||
@@ -34,3 +35,10 @@ export function adminStatus(params: any) {
|
|||||||
export function adminListByDeptId(params: any) {
|
export function adminListByDeptId(params: any) {
|
||||||
return request.get({ url: '/system/admin/ListByDeptId', params })
|
return request.get({ url: '/system/admin/ListByDeptId', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 导出
|
||||||
|
export function adminExportFile(params: any) {
|
||||||
|
// return request.get({ url: '/system/admin/ExportFile', params })
|
||||||
|
return (window.location.href =
|
||||||
|
`/api/admin/system/admin/ExportFile?token=${getToken()}&` + queryString.stringify(params))
|
||||||
|
}
|
||||||
|
@@ -8,37 +8,49 @@
|
|||||||
start-placeholder="开始时间"
|
start-placeholder="开始时间"
|
||||||
end-placeholder="结束时间"
|
end-placeholder="结束时间"
|
||||||
clearable
|
clearable
|
||||||
|
@change="changeDate"
|
||||||
></el-date-picker>
|
></el-date-picker>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { withDefaults, computed } from 'vue'
|
|
||||||
|
|
||||||
/* Props S */
|
/* Props S */
|
||||||
const props = withDefaults(
|
const props = defineProps({
|
||||||
defineProps<{
|
startTime: {
|
||||||
startTime?: string
|
type: String,
|
||||||
endTime?: string
|
default: ''
|
||||||
}>(),
|
|
||||||
{
|
|
||||||
startTime: '',
|
|
||||||
endTime: ''
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const emit = defineEmits(['update:startTime', 'update:endTime'])
|
|
||||||
|
|
||||||
const content = computed<any>({
|
|
||||||
get: () => {
|
|
||||||
return [props.startTime, props.endTime]
|
|
||||||
},
|
},
|
||||||
set: (value: Event | any) => {
|
endTime: {
|
||||||
if (value === null) {
|
type: String,
|
||||||
emit('update:startTime', '')
|
default: ''
|
||||||
emit('update:endTime', '')
|
|
||||||
} else {
|
|
||||||
emit('update:startTime', value[0])
|
|
||||||
emit('update:endTime', value[1])
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:startTime', 'update:endTime'])
|
||||||
|
const content = ref<[string, string]>([props.startTime, props.endTime])
|
||||||
|
function changeDate(value: any) {
|
||||||
|
console.log('change', value)
|
||||||
|
if (value === null) {
|
||||||
|
emit('update:startTime', '')
|
||||||
|
emit('update:endTime', '')
|
||||||
|
} else {
|
||||||
|
emit('update:startTime', value[0])
|
||||||
|
emit('update:endTime', value[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// const content = computed<any>({
|
||||||
|
// get: () => {
|
||||||
|
// return [props.startTime, props.endTime]
|
||||||
|
// },
|
||||||
|
// set: (value: Event | any) => {
|
||||||
|
// console.log('change', value)
|
||||||
|
|
||||||
|
// if (value === null) {
|
||||||
|
// emit('update:startTime', '')
|
||||||
|
// emit('update:endTime', '')
|
||||||
|
// } else {
|
||||||
|
// emit('update:startTime', value[0])
|
||||||
|
// emit('update:endTime', value[1])
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// })
|
||||||
</script>
|
</script>
|
||||||
|
@@ -2,6 +2,7 @@
|
|||||||
<el-dialog
|
<el-dialog
|
||||||
v-model="dialogVisible"
|
v-model="dialogVisible"
|
||||||
append-to-body
|
append-to-body
|
||||||
|
:mask="false"
|
||||||
:show-close="false"
|
:show-close="false"
|
||||||
:fullscreen="true"
|
:fullscreen="true"
|
||||||
:close-on-click-modal="false"
|
:close-on-click-modal="false"
|
||||||
@@ -216,6 +217,9 @@ export default {
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
|
.flow-config-dialog {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
.flow-config-dialog .el-dialog__header {
|
.flow-config-dialog .el-dialog__header {
|
||||||
font-size: var(--el-font-size-large);
|
font-size: var(--el-font-size-large);
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@@ -2,11 +2,13 @@ import { createApp } from 'vue'
|
|||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import install from './install'
|
import install from './install'
|
||||||
import './permission'
|
import './permission'
|
||||||
|
import 'element-plus/dist/index.css'
|
||||||
import './styles/index.scss'
|
import './styles/index.scss'
|
||||||
|
|
||||||
import 'virtual:svg-icons-register'
|
import 'virtual:svg-icons-register'
|
||||||
|
|
||||||
import ElementPlus from 'element-plus'
|
import ElementPlus from 'element-plus'
|
||||||
import 'element-plus/dist/index.css'
|
|
||||||
import VForm3 from 'vform3-builds' //引入VForm3库
|
import VForm3 from 'vform3-builds' //引入VForm3库
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
@@ -23,7 +23,7 @@
|
|||||||
<el-table-column label="通知类型" prop="type" min-width="160" />
|
<el-table-column label="通知类型" prop="type" min-width="160" />
|
||||||
<el-table-column label="短信通知" min-width="80">
|
<el-table-column label="短信通知" min-width="80">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag v-if="row.smsStatus == 1">开启</el-tag>
|
<el-tag type="primary" v-if="row.smsStatus == 1">开启</el-tag>
|
||||||
<el-tag type="danger" v-else>关闭</el-tag>
|
<el-tag type="danger" v-else>关闭</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
<el-table-column label="短信渠道" prop="name" min-width="120" />
|
<el-table-column label="短信渠道" prop="name" min-width="120" />
|
||||||
<el-table-column label="状态" min-width="120">
|
<el-table-column label="状态" min-width="120">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag v-if="row.status == 1">开启</el-tag>
|
<el-tag type="primary" v-if="row.status == 1">开启</el-tag>
|
||||||
<el-tag type="danger" v-else>关闭</el-tag>
|
<el-tag type="danger" v-else>关闭</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
@@ -76,7 +76,7 @@
|
|||||||
<el-table-column label="颜色" prop="color" min-width="120" />
|
<el-table-column label="颜色" prop="color" min-width="120" />
|
||||||
<el-table-column label="状态">
|
<el-table-column label="状态">
|
||||||
<template v-slot="{ row }">
|
<template v-slot="{ row }">
|
||||||
<el-tag v-if="row.status == 1">正常</el-tag>
|
<el-tag v-if="row.status == 1" type="primary">正常</el-tag>
|
||||||
<el-tag v-else type="danger">停用</el-tag>
|
<el-tag v-else type="danger">停用</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
@@ -68,7 +68,7 @@
|
|||||||
<el-table-column label="字典类型" prop="dictType" min-width="120" />
|
<el-table-column label="字典类型" prop="dictType" min-width="120" />
|
||||||
<el-table-column label="状态">
|
<el-table-column label="状态">
|
||||||
<template v-slot="{ row }">
|
<template v-slot="{ row }">
|
||||||
<el-tag v-if="row.dictStatus == 1">正常</el-tag>
|
<el-tag v-if="row.dictStatus == 1" type="primary">正常</el-tag>
|
||||||
<el-tag v-else type="danger">停用</el-tag>
|
<el-tag v-else type="danger">停用</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
@@ -52,7 +52,7 @@
|
|||||||
|
|
||||||
<el-table-column label="部门状态" prop="isStop" min-width="100">
|
<el-table-column label="部门状态" prop="isStop" min-width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag class="ml-2" :type="row.isStop ? 'danger' : ''">
|
<el-tag class="ml-2" :type="row.isStop ? 'danger' : 'primary'">
|
||||||
{{ row.isStop ? '停用' : '正常' }}
|
{{ row.isStop ? '停用' : '正常' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
|
@@ -53,7 +53,7 @@
|
|||||||
<el-table-column label="添加时间" prop="createTime" min-width="180" />
|
<el-table-column label="添加时间" prop="createTime" min-width="180" />
|
||||||
<el-table-column label="岗位状态" prop="isStop" min-width="100">
|
<el-table-column label="岗位状态" prop="isStop" min-width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag class="ml-2" :type="row.isStop ? 'danger' : ''">
|
<el-tag class="ml-2" :type="row.isStop ? 'danger' : 'primary'">
|
||||||
{{ row.isStop ? '停用' : '正常' }}
|
{{ row.isStop ? '停用' : '正常' }}
|
||||||
</el-tag>
|
</el-tag>
|
||||||
</template>
|
</template>
|
||||||
|
@@ -3,23 +3,13 @@
|
|||||||
<el-card class="!border-none" shadow="never">
|
<el-card class="!border-none" shadow="never">
|
||||||
<el-form class="mb-[-16px]" :model="formData" inline>
|
<el-form class="mb-[-16px]" :model="formData" inline>
|
||||||
<el-form-item label="管理员账号">
|
<el-form-item label="管理员账号">
|
||||||
<el-input
|
<el-input v-model="formData.username" clearable @keyup.enter="resetPage" />
|
||||||
v-model="formData.username"
|
|
||||||
class="w-[280px]"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="resetPage"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="管理员名称">
|
<el-form-item label="管理员名称">
|
||||||
<el-input
|
<el-input v-model="formData.nickname" clearable @keyup.enter="resetPage" />
|
||||||
v-model="formData.nickname"
|
|
||||||
class="w-[280px]"
|
|
||||||
clearable
|
|
||||||
@keyup.enter="resetPage"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="管理员角色">
|
<el-form-item label="管理员角色">
|
||||||
<el-select class="w-[280px]" v-model="formData.role">
|
<el-select v-model="formData.role">
|
||||||
<el-option label="全部" value="" />
|
<el-option label="全部" value="" />
|
||||||
<el-option
|
<el-option
|
||||||
v-for="(item, index) in optionsData.role"
|
v-for="(item, index) in optionsData.role"
|
||||||
@@ -42,6 +32,13 @@
|
|||||||
</template>
|
</template>
|
||||||
新增
|
新增
|
||||||
</el-button>
|
</el-button>
|
||||||
|
<el-button type="primary" @click="exportFile">
|
||||||
|
<template #icon>
|
||||||
|
<icon name="el-icon-Download" />
|
||||||
|
</template>
|
||||||
|
导出
|
||||||
|
</el-button>
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<el-table :data="pager.lists" size="large">
|
<el-table :data="pager.lists" size="large">
|
||||||
<el-table-column label="ID" prop="id" min-width="60" />
|
<el-table-column label="ID" prop="id" min-width="60" />
|
||||||
@@ -101,7 +98,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="admin">
|
<script lang="ts" setup name="admin">
|
||||||
import { adminLists, adminDelete, adminStatus } from '@/api/perms/admin'
|
import { adminLists, adminDelete, adminStatus, adminExportFile } from '@/api/perms/admin'
|
||||||
import { roleAll } from '@/api/perms/role'
|
import { roleAll } from '@/api/perms/role'
|
||||||
import { useDictOptions } from '@/hooks/useDictOptions'
|
import { useDictOptions } from '@/hooks/useDictOptions'
|
||||||
import { usePaging } from '@/hooks/usePaging'
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
@@ -135,7 +132,10 @@ const handleAdd = async () => {
|
|||||||
await nextTick()
|
await nextTick()
|
||||||
editRef.value?.open('add')
|
editRef.value?.open('add')
|
||||||
}
|
}
|
||||||
|
const exportFile = async () => {
|
||||||
|
await feedback.confirm('确定要导出?')
|
||||||
|
await adminExportFile(formData)
|
||||||
|
}
|
||||||
const handleEdit = async (data: any) => {
|
const handleEdit = async (data: any) => {
|
||||||
showEdit.value = true
|
showEdit.value = true
|
||||||
await nextTick()
|
await nextTick()
|
||||||
|
@@ -52,7 +52,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="状态" prop="isDisable" min-width="100">
|
<el-table-column label="状态" prop="isDisable" min-width="100">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag v-if="row.isDisable == 0">正常</el-tag>
|
<el-tag v-if="row.isDisable == 0" type="primary">正常</el-tag>
|
||||||
<el-tag v-else type="danger">停用</el-tag>
|
<el-tag v-else type="danger">停用</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
<el-table-column label="储存位置" prop="describe" min-width="160" />
|
<el-table-column label="储存位置" prop="describe" min-width="160" />
|
||||||
<el-table-column label="状态" min-width="80">
|
<el-table-column label="状态" min-width="80">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<el-tag v-if="row.status == 1">开启</el-tag>
|
<el-tag v-if="row.status == 1" type="primary">开启</el-tag>
|
||||||
<el-tag type="danger" v-else>关闭</el-tag>
|
<el-tag type="danger" v-else>关闭</el-tag>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
@@ -1,128 +1,118 @@
|
|||||||
<!-- 系统日志 -->
|
<!-- 系统日志 -->
|
||||||
<template>
|
<template>
|
||||||
<div class="journal">
|
<div class="journal">
|
||||||
<el-card class="!border-none" shadow="never">
|
{{ formData }}
|
||||||
<el-form class="ls-form" :model="formData" inline>
|
<el-card class="!border-none" shadow="never">
|
||||||
<el-form-item label="管理员">
|
<el-form class="ls-form" :model="formData" inline>
|
||||||
<el-input
|
<el-form-item label="管理员" class="w-[360px]">
|
||||||
class="w-[280px]"
|
<el-input
|
||||||
placeholder="请输入"
|
placeholder="请输入"
|
||||||
v-model="formData.username"
|
v-model="formData.username"
|
||||||
clearable
|
clearable
|
||||||
@keyup.enter="resetPage"
|
@keyup.enter="resetPage"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="访问方式">
|
<el-form-item label="访问方式" class="w-[360px]">
|
||||||
<el-select
|
<el-select v-model="formData.type" placeholder="请选择">
|
||||||
class="w-[280px]"
|
<el-option
|
||||||
v-model="formData.type"
|
v-for="(item, index) in visitType"
|
||||||
placeholder="请选择"
|
:key="index"
|
||||||
>
|
:label="item.label"
|
||||||
<el-option
|
:value="item.value"
|
||||||
v-for="(item, index) in visitType"
|
/>
|
||||||
:key="index"
|
</el-select>
|
||||||
:label="item.label"
|
</el-form-item>
|
||||||
:value="item.value"
|
|
||||||
/>
|
|
||||||
</el-select>
|
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="来源IP">
|
<el-form-item label="来源IP" class="w-[360px]">
|
||||||
<el-input
|
<el-input
|
||||||
class="w-[280px]"
|
placeholder="请输入"
|
||||||
placeholder="请输入"
|
v-model="formData.ip"
|
||||||
v-model="formData.ip"
|
clearable
|
||||||
clearable
|
@keyup.enter="resetPage"
|
||||||
@keyup.enter="resetPage"
|
/>
|
||||||
/>
|
</el-form-item>
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item label="访问时间">
|
<el-form-item label="访问时间" class="w-[360px]">
|
||||||
<daterange-picker
|
<daterange-picker
|
||||||
v-model:startTime="formData.startTime"
|
v-model:startTime="formData.startTime"
|
||||||
v-model:endTime="formData.endTime"
|
v-model:endTime="formData.endTime"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
|
||||||
<el-form-item label="访问链接">
|
<el-form-item label="访问链接" class="w-[360px]">
|
||||||
<el-input
|
<el-input
|
||||||
class="w-[280px]"
|
placeholder="请输入"
|
||||||
placeholder="请输入"
|
v-model="formData.url"
|
||||||
v-model="formData.url"
|
clearable
|
||||||
clearable
|
@keyup.enter="resetPage"
|
||||||
@keyup.enter="resetPage"
|
/>
|
||||||
/>
|
</el-form-item>
|
||||||
</el-form-item>
|
|
||||||
|
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="resetPage">查询</el-button>
|
<el-button type="primary" @click="resetPage">查询</el-button>
|
||||||
<el-button @click="resetParams">重置</el-button>
|
<el-button @click="resetParams">重置</el-button>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
|
|
||||||
<el-card class="!border-none mt-4" shadow="never" v-loading="pager.loading">
|
<el-card class="!border-none mt-4" shadow="never" v-loading="pager.loading">
|
||||||
<div>
|
<div>
|
||||||
<el-table :data="pager.lists" size="large">
|
<el-table :data="pager.lists" size="large">
|
||||||
<el-table-column label="记录ID" prop="id" />
|
<el-table-column label="记录ID" prop="id" />
|
||||||
<el-table-column label="操作" prop="title" min-width="120" />
|
<el-table-column label="操作" prop="title" min-width="120" />
|
||||||
<el-table-column label="管理员" prop="username" min-width="120" />
|
<el-table-column label="管理员" prop="username" min-width="120" />
|
||||||
<el-table-column label="访问链接" prop="url" min-width="160" />
|
<el-table-column label="访问链接" prop="url" min-width="160" />
|
||||||
<el-table-column label="访问方式" prop="type" min-width="100" />
|
<el-table-column label="访问方式" prop="type" min-width="100" />
|
||||||
<el-table-column label="来源IP" prop="ip" min-width="160" />
|
<el-table-column label="来源IP" prop="ip" min-width="160" />
|
||||||
<el-table-column label="错误信息" prop="error" min-width="160" />
|
<el-table-column label="错误信息" prop="error" min-width="160" />
|
||||||
<el-table-column
|
<el-table-column label="执行耗时(毫秒)" prop="taskTime" min-width="100" />
|
||||||
label="执行耗时(毫秒)"
|
<el-table-column label="日志时间" prop="createTime" min-width="180" />
|
||||||
prop="taskTime"
|
</el-table>
|
||||||
min-width="100"
|
</div>
|
||||||
/>
|
<div class="flex mt-4 justify-end">
|
||||||
<el-table-column label="日志时间" prop="createTime" min-width="180" />
|
<pagination v-model="pager" @change="getLists" />
|
||||||
</el-table>
|
</div>
|
||||||
</div>
|
</el-card>
|
||||||
<div class="flex mt-4 justify-end">
|
</div>
|
||||||
<pagination v-model="pager" @change="getLists" />
|
|
||||||
</div>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="journal">
|
<script setup lang="ts" name="journal">
|
||||||
import { systemLogLists } from "@/api/setting/system";
|
import { systemLogLists } from '@/api/setting/system'
|
||||||
import { usePaging } from "@/hooks/usePaging";
|
import { usePaging } from '@/hooks/usePaging'
|
||||||
|
|
||||||
// 查询表单
|
// 查询表单
|
||||||
const formData = ref({
|
const formData = ref({
|
||||||
username: "",
|
username: '',
|
||||||
url: "",
|
url: '',
|
||||||
ip: "",
|
ip: '',
|
||||||
type: "",
|
type: '',
|
||||||
startTime: "",
|
startTime: '',
|
||||||
endTime: "",
|
endTime: ''
|
||||||
});
|
})
|
||||||
|
|
||||||
// 访问方式
|
// 访问方式
|
||||||
const visitType = ref<Array<any>>([
|
const visitType = ref<Array<any>>([
|
||||||
{
|
{
|
||||||
label: "全部",
|
label: '全部',
|
||||||
value: "",
|
value: ''
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "get",
|
label: 'get',
|
||||||
value: "GET",
|
value: 'GET'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: "post",
|
label: 'post',
|
||||||
value: "POST",
|
value: 'POST'
|
||||||
},
|
}
|
||||||
]);
|
])
|
||||||
|
|
||||||
const { pager, getLists, resetParams, resetPage } = usePaging({
|
const { pager, getLists, resetParams, resetPage } = usePaging({
|
||||||
fetchFun: systemLogLists,
|
fetchFun: systemLogLists,
|
||||||
params: formData.value,
|
params: formData.value
|
||||||
});
|
})
|
||||||
|
|
||||||
getLists();
|
getLists()
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
@@ -7,14 +7,17 @@
|
|||||||
"auto-imports.d.ts",
|
"auto-imports.d.ts",
|
||||||
"typings/**/*.d.ts"
|
"typings/**/*.d.ts"
|
||||||
],
|
],
|
||||||
|
"exclude": ["dist"],
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"module": "esnext",
|
"module": "esnext",
|
||||||
"moduleResolution": "node",
|
"moduleResolution": "node",
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
|
"outDir": "./dist",
|
||||||
"isolatedModules": true,
|
"isolatedModules": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@/*": ["./src/*"]
|
"@/*": ["./src/*"]
|
||||||
}
|
},
|
||||||
|
"types": ["element-plus/global"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,8 +41,8 @@ export default ({ mode }) => {
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Components({
|
Components({
|
||||||
directoryAsNamespace: true
|
directoryAsNamespace: true,
|
||||||
// resolvers: [ElementPlusResolver()]
|
resolvers: [ElementPlusResolver()]
|
||||||
}),
|
}),
|
||||||
// createStyleImportPlugin({
|
// createStyleImportPlugin({
|
||||||
// resolves: [ElementPlusResolve()]
|
// resolves: [ElementPlusResolve()]
|
||||||
|
@@ -5,6 +5,7 @@ import (
|
|||||||
"x_admin/config"
|
"x_admin/config"
|
||||||
"x_admin/core/request"
|
"x_admin/core/request"
|
||||||
"x_admin/core/response"
|
"x_admin/core/response"
|
||||||
|
"x_admin/util/excel"
|
||||||
|
|
||||||
"x_admin/util"
|
"x_admin/util"
|
||||||
|
|
||||||
@@ -44,6 +45,28 @@ func (ah AdminHandler) Self(c *gin.Context) {
|
|||||||
response.CheckAndRespWithData(c, res, err)
|
response.CheckAndRespWithData(c, res, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ah AdminHandler) ExportFile(c *gin.Context) {
|
||||||
|
var listReq SystemAuthAdminListReq
|
||||||
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res, err := Service.ExportFile(listReq)
|
||||||
|
if err != nil {
|
||||||
|
response.FailWithMsg(c, response.SystemError, "查询导出失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
f, err := excel.NormalDynamicExport(res, "Sheet1", "用户信息", "", true, false, nil)
|
||||||
|
if err != nil {
|
||||||
|
response.FailWithMsg(c, response.SystemError, "导出失败")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
excel.DownLoadExcel("用户信息", c.Writer, f)
|
||||||
|
// c.Header("Content-Type", "application/octet-stream")
|
||||||
|
// c.Header("Content-Disposition", "attachment; filename="+"用户信息.xlsx")
|
||||||
|
// c.Header("Content-Transfer-Encoding", "binary")
|
||||||
|
// f.Write(c.Writer)
|
||||||
|
}
|
||||||
|
|
||||||
// list 管理员列表
|
// list 管理员列表
|
||||||
func (ah AdminHandler) List(c *gin.Context) {
|
func (ah AdminHandler) List(c *gin.Context) {
|
||||||
var page request.PageReq
|
var page request.PageReq
|
||||||
@@ -114,12 +137,12 @@ func (ah AdminHandler) Disable(c *gin.Context) {
|
|||||||
response.CheckAndResp(c, Service.Disable(c, disableReq.ID))
|
response.CheckAndResp(c, Service.Disable(c, disableReq.ID))
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary 获取部门的用户
|
// @Summary 获取部门的用户
|
||||||
// @Description 获取部门的用户
|
// @Description 获取部门的用户
|
||||||
// @Tags 管理员
|
// @Tags 管理员
|
||||||
// @Param deptId path int true "部门id"
|
// @Param deptId path int true "部门id"
|
||||||
// @Success 200 {object} response.Response "{"code": 200, "data": []}"
|
// @Success 200 {object} response.Response "{"code": 200, "data": []}"
|
||||||
// @Router /system/admin/ListByDeptId/{deptId} [get]
|
// @Router /system/admin/ListByDeptId/{deptId} [get]
|
||||||
func (ah AdminHandler) ListByDeptId(c *gin.Context) {
|
func (ah AdminHandler) ListByDeptId(c *gin.Context) {
|
||||||
deptIdStr, bool := c.GetQuery("deptId")
|
deptIdStr, bool := c.GetQuery("deptId")
|
||||||
if bool == false {
|
if bool == false {
|
||||||
|
@@ -63,20 +63,20 @@ type SystemAuthAdminDisableReq struct {
|
|||||||
|
|
||||||
//SystemAuthAdminResp 管理员返回信息
|
//SystemAuthAdminResp 管理员返回信息
|
||||||
type SystemAuthAdminResp struct {
|
type SystemAuthAdminResp struct {
|
||||||
ID uint `json:"id" structs:"id"` // 主键
|
ID uint `json:"id" structs:"id"` // 主键
|
||||||
Username string `json:"username" structs:"username"` // 账号
|
Username string `json:"username" structs:"username" excel:"name:账号;"` // 账号
|
||||||
Nickname string `json:"nickname" structs:"nickname"` // 昵称
|
Nickname string `json:"nickname" structs:"nickname" excel:"name:昵称;"` // 昵称
|
||||||
Avatar string `json:"avatar" structs:"avatar"` // 头像
|
Avatar string `json:"avatar" structs:"avatar" excel:"name:头像;"` // 头像
|
||||||
Role string `json:"role" structs:"role"` // 角色
|
Role string `json:"role" structs:"role" excel:"name:角色;"` // 角色
|
||||||
DeptId uint `json:"deptId" structs:"deptId"` // 部门ID
|
DeptId uint `json:"deptId" structs:"deptId" excel:"name:部门ID;"` // 部门ID
|
||||||
PostId uint `json:"postId" structs:"postId"` // 岗位ID
|
PostId uint `json:"postId" structs:"postId" excel:"name:岗位ID;"` // 岗位ID
|
||||||
Dept string `json:"dept" structs:"dept"` // 部门
|
Dept string `json:"dept" structs:"dept" excel:"name:部门;"` // 部门
|
||||||
IsMultipoint uint8 `json:"isMultipoint" structs:"isMultipoint"` // 多端登录: [0=否, 1=是]
|
IsMultipoint uint8 `json:"isMultipoint" structs:"isMultipoint" excel:"name:多端登录;"` // 多端登录: [0=否, 1=是]
|
||||||
IsDisable uint8 `json:"isDisable" structs:"isDisable"` // 是否禁用: [0=否, 1=是]
|
IsDisable uint8 `json:"isDisable" structs:"isDisable" excel:"name:是否禁用;"` // 是否禁用: [0=否, 1=是]
|
||||||
LastLoginIp string `json:"lastLoginIp" structs:"lastLoginIp"` // 最后登录IP
|
LastLoginIp string `json:"lastLoginIp" structs:"lastLoginIp" excel:"name:最后登录IP;"` // 最后登录IP
|
||||||
LastLoginTime core.TsTime `json:"lastLoginTime" structs:"lastLoginTime"` // 最后登录时间
|
LastLoginTime core.TsTime `json:"lastLoginTime" structs:"lastLoginTime" excel:"name:最后登录时间;"` // 最后登录时间
|
||||||
CreateTime core.TsTime `json:"createTime" structs:"createTime"` // 创建时间
|
CreateTime core.TsTime `json:"createTime" structs:"createTime" excel:"name:创建时间;"` // 创建时间
|
||||||
UpdateTime core.TsTime `json:"updateTime" structs:"updateTime"` // 更新时间
|
UpdateTime core.TsTime `json:"updateTime" structs:"updateTime" excel:"name:更新时间;"` // 更新时间
|
||||||
}
|
}
|
||||||
|
|
||||||
//SystemAuthAdminSelfOneResp 当前管理员返回部分信息
|
//SystemAuthAdminSelfOneResp 当前管理员返回部分信息
|
||||||
|
@@ -122,6 +122,39 @@ func (adminSrv systemAuthAdminService) ListByUserIdOrDeptIdPostId(userId, deptId
|
|||||||
}
|
}
|
||||||
return adminResp, nil
|
return adminResp, nil
|
||||||
}
|
}
|
||||||
|
func (adminSrv systemAuthAdminService) ExportFile(listReq SystemAuthAdminListReq) (res []SystemAuthAdminResp, e error) {
|
||||||
|
// 查询
|
||||||
|
adminTbName := core.DBTableName(&system_model.SystemAuthAdmin{})
|
||||||
|
roleTbName := core.DBTableName(&system_model.SystemAuthRole{})
|
||||||
|
deptTbName := core.DBTableName(&system_model.SystemAuthDept{})
|
||||||
|
adminModel := adminSrv.db.Table(adminTbName+" AS admin").Where("admin.is_delete = ?", 0).Joins(
|
||||||
|
fmt.Sprintf("LEFT JOIN %s ON admin.role = %s.id", roleTbName, roleTbName)).Joins(
|
||||||
|
fmt.Sprintf("LEFT JOIN %s ON admin.dept_id = %s.id", deptTbName, deptTbName)).Select(
|
||||||
|
fmt.Sprintf("admin.*, %s.name as dept, %s.name as role", deptTbName, roleTbName))
|
||||||
|
// 条件
|
||||||
|
if listReq.Username != "" {
|
||||||
|
adminModel = adminModel.Where("username like ?", "%"+listReq.Username+"%")
|
||||||
|
}
|
||||||
|
if listReq.Nickname != "" {
|
||||||
|
adminModel = adminModel.Where("nickname like ?", "%"+listReq.Nickname+"%")
|
||||||
|
}
|
||||||
|
if listReq.Role >= 0 {
|
||||||
|
adminModel = adminModel.Where("role = ?", listReq.Role)
|
||||||
|
}
|
||||||
|
// 数据
|
||||||
|
var adminResp []SystemAuthAdminResp
|
||||||
|
err := adminModel.Order("id desc, sort desc").Find(&adminResp).Error
|
||||||
|
if e = response.CheckErr(err, "List Find err"); e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for i := 0; i < len(adminResp); i++ {
|
||||||
|
adminResp[i].Avatar = util.UrlUtil.ToAbsoluteUrl(adminResp[i].Avatar)
|
||||||
|
if adminResp[i].ID == 1 {
|
||||||
|
adminResp[i].Role = "系统管理员"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return adminResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
// List 管理员列表
|
// List 管理员列表
|
||||||
func (adminSrv systemAuthAdminService) List(page request.PageReq, listReq SystemAuthAdminListReq) (res response.PageResp, e error) {
|
func (adminSrv systemAuthAdminService) List(page request.PageReq, listReq SystemAuthAdminListReq) (res response.PageResp, e error) {
|
||||||
|
@@ -30,6 +30,8 @@ func AdminRoute(rg *gin.RouterGroup) {
|
|||||||
rg.POST("/admin/del", middleware.RecordLog("管理员删除"), handle.Del)
|
rg.POST("/admin/del", middleware.RecordLog("管理员删除"), handle.Del)
|
||||||
rg.POST("/admin/disable", middleware.RecordLog("管理员状态切换"), handle.Disable)
|
rg.POST("/admin/disable", middleware.RecordLog("管理员状态切换"), handle.Disable)
|
||||||
|
|
||||||
|
rg.GET("/admin/ExportFile", middleware.RecordLog("管理员导出"), handle.ExportFile)
|
||||||
|
|
||||||
}
|
}
|
||||||
func RoleRoute(rg *gin.RouterGroup) {
|
func RoleRoute(rg *gin.RouterGroup) {
|
||||||
// db := core.GetDB()
|
// db := core.GetDB()
|
||||||
|
@@ -16,13 +16,25 @@ import (
|
|||||||
func GetExcelColumnName(columnNumber int) string {
|
func GetExcelColumnName(columnNumber int) string {
|
||||||
columnName := ""
|
columnName := ""
|
||||||
for columnNumber > 0 {
|
for columnNumber > 0 {
|
||||||
columnNumber--
|
remainder := (columnNumber - 1) % 26
|
||||||
columnName = fmt.Sprint('A'+columnNumber%26) + columnName
|
columnName = string('A'+remainder) + columnName
|
||||||
columnNumber /= 26
|
columnNumber = (columnNumber - 1) / 26
|
||||||
}
|
}
|
||||||
return columnName
|
return columnName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NormalDynamicExport 导出excel
|
||||||
|
// ** 需要在传入的结构体中的字段加上tag:excelize:"title:列头名称;index:列下标(从0开始);"
|
||||||
|
// list 需要导出的对象数组、sheet sheet名称、title 标题、isGhbj 是否设置隔行背景色
|
||||||
|
func NormalDynamicExport(list interface{}, sheet, title, fields string, isGhbj, isIgnore bool, changeHead map[string]string) (file *excelize.File, err error) {
|
||||||
|
e := ExcelInit()
|
||||||
|
err = ExportExcel(sheet, title, fields, isGhbj, isIgnore, list, changeHead, e)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return e.F, err
|
||||||
|
}
|
||||||
|
|
||||||
// ExportExcel excel导出
|
// ExportExcel excel导出
|
||||||
func ExportExcel(sheet, title, fields string, isGhbj, isIgnore bool, list interface{}, changeHead map[string]string, e *Excel) (err error) {
|
func ExportExcel(sheet, title, fields string, isGhbj, isIgnore bool, list interface{}, changeHead map[string]string, e *Excel) (err error) {
|
||||||
index, _ := e.F.GetSheetIndex(sheet)
|
index, _ := e.F.GetSheetIndex(sheet)
|
||||||
@@ -47,44 +59,6 @@ func ExportExcel(sheet, title, fields string, isGhbj, isIgnore bool, list interf
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ================================= 普通导出 =================================
|
|
||||||
|
|
||||||
// NormalDownLoad 导出excel并下载(单个sheet)
|
|
||||||
func NormalDownLoad(fileName, sheet, title string, isGhbj bool, list interface{}, res http.ResponseWriter) error {
|
|
||||||
f, err := NormalDynamicExport(list, sheet, title, "", isGhbj, false, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
DownLoadExcel(fileName, res, f)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NormalDynamicDownLoad 动态导出excel并下载(单个sheet)
|
|
||||||
// isIgnore 是否忽略指定字段(true 要忽略的字段 false 要导出的字段)
|
|
||||||
// fields 选择的字段,多个字段用逗号隔开,最后一个字段后面也要加逗号,如:字段1,字段2,字段3,
|
|
||||||
// changeHead 要改变表头的字段,格式是{"字段1":"更改的表头1","字段2":"更改的表头2"}
|
|
||||||
func NormalDynamicDownLoad(fileName, sheet, title, fields string, isGhbj, isIgnore bool,
|
|
||||||
list interface{}, changeHead map[string]string, res http.ResponseWriter) error {
|
|
||||||
f, err := NormalDynamicExport(list, sheet, title, fields, isGhbj, isIgnore, changeHead)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
DownLoadExcel(fileName, res, f)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// NormalDynamicExport 导出excel
|
|
||||||
// ** 需要在传入的结构体中的字段加上tag:excelize:"title:列头名称;index:列下标(从0开始);"
|
|
||||||
// list 需要导出的对象数组、sheet sheet名称、title 标题、isGhbj 是否设置隔行背景色
|
|
||||||
func NormalDynamicExport(list interface{}, sheet, title, fields string, isGhbj, isIgnore bool, changeHead map[string]string) (file *excelize.File, err error) {
|
|
||||||
e := ExcelInit()
|
|
||||||
err = ExportExcel(sheet, title, fields, isGhbj, isIgnore, list, changeHead, e)
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
return e.F, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构造表头(endColName 最后一列的列名 dataRow 数据行开始的行号)
|
// 构造表头(endColName 最后一列的列名 dataRow 数据行开始的行号)
|
||||||
func normalBuildTitle(e *Excel, sheet, title, fields string, isIgnore bool, changeHead map[string]string, dataValue reflect.Value) (endColName string, dataRow int, err error) {
|
func normalBuildTitle(e *Excel, sheet, title, fields string, isIgnore bool, changeHead map[string]string, dataValue reflect.Value) (endColName string, dataRow int, err error) {
|
||||||
dataType := dataValue.Type().Elem() // 获取导入目标对象的类型信息
|
dataType := dataValue.Type().Elem() // 获取导入目标对象的类型信息
|
||||||
|
@@ -66,3 +66,11 @@ func TestImports(t *testing.T) {
|
|||||||
fmt.Println(t)
|
fmt.Println(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetExcelColumnName(t *testing.T) {
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
var col = GetExcelColumnName(i)
|
||||||
|
fmt.Println("col:", col)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Binary file not shown.
Reference in New Issue
Block a user