导出表格,升级依赖

This commit is contained in:
xiangheng
2024-02-20 19:33:51 +08:00
parent 65f1f09b70
commit ef9199c2cb
26 changed files with 302 additions and 241 deletions

View File

@@ -1,7 +1,8 @@
{
"name": "vue-project",
"version": "0.0.0",
"name": "x_admin",
"version": "0.0.1",
"license": "MIT",
"type": "module",
"scripts": {
"dev": "vite",
"prod": "vite build",
@@ -13,54 +14,55 @@
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"@highlightjs/vue-plugin": "^2.1.0",
"@logicflow/core": "^1.2.18",
"@logicflow/extension": "^1.2.19",
"@vue/shared": "^3.4.3",
"@vueuse/core": "^10.7.1",
"@logicflow/core": "^1.2.22",
"@logicflow/extension": "^1.2.22",
"@vue/shared": "^3.4.19",
"@vueuse/core": "^10.7.2",
"@wangeditor/editor": "^5.1.23",
"@wangeditor/editor-for-vue": "^5.1.12",
"axios": "^1.6.3",
"axios": "^1.6.7",
"consola": "^3.2.3",
"crypto-js": "^4.2.0",
"css-color-function": "^1.3.3",
"echarts": "^5.4.3",
"element-plus": "^2.4.4",
"echarts": "^5.5.0",
"element-plus": "^2.5.6",
"highlight.js": "^11.9.0",
"lodash-es": "^4.17.21",
"nprogress": "^0.2.0",
"pinia": "^2.1.7",
"query-string": "^8.2.0",
"vform3-builds": "^3.0.10",
"vue": "^3.4.3",
"vue": "^3.4.19",
"vue-clipboard3": "^2.0.0",
"vue-echarts": "^6.6.8",
"vue-echarts": "^6.6.9",
"vue-router": "^4.2.5",
"vue3-video-play": "^1.3.2",
"vuedraggable": "^4.1.0"
},
"devDependencies": {
"@rushstack/eslint-patch": "^1.6.1",
"@rushstack/eslint-patch": "^1.7.2",
"@types/lodash-es": "^4.17.12",
"@types/node": "^20.10.6",
"@types/node": "^20.11.19",
"@types/nprogress": "^0.2.3",
"@vitejs/plugin-vue": "^5.0.2",
"@vitejs/plugin-vue": "^5.0.4",
"@vitejs/plugin-vue-jsx": "^3.1.0",
"@vue/eslint-config-prettier": "^9.0.0",
"@vue/eslint-config-typescript": "^12.0.0",
"@vue/tsconfig": "^0.5.1",
"autoprefixer": "^10.4.16",
"autoprefixer": "^10.4.17",
"eslint": "^8.56.0",
"eslint-plugin-vue": "^9.19.2",
"eslint-plugin-vue": "^9.21.1",
"execa": "^8.0.1",
"fs-extra": "^11.2.0",
"postcss": "^8.4.32",
"prettier": "^3.1.1",
"postcss": "^8.4.35",
"prettier": "^3.2.5",
"rollup-plugin-visualizer": "^5.12.0",
"sass": "^1.69.6",
"tailwindcss": "^3.4.0",
"sass": "^1.71.0",
"tailwindcss": "^3.4.1",
"typescript": "~5.3.3",
"unplugin-auto-import": "^0.17.3",
"unplugin-auto-import": "^0.17.5",
"unplugin-vue-components": "^0.26.0",
"vite": "^4.5.0",
"vite": "^5.1.3",
"vite-plugin-compression": "^0.5.1",
"vite-plugin-style-import": "^2.0.0",
"vite-plugin-svg-icons": "^2.0.1",

View File

@@ -1,5 +1,6 @@
import request from '@/utils/request'
import queryString from 'query-string'
import { getToken } from '@/utils/auth'
// 管理员列表
export function adminLists(params: any) {
return request.get({ url: '/system/admin/list', params })
@@ -34,3 +35,10 @@ export function adminStatus(params: any) {
export function adminListByDeptId(params: any) {
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))
}

View File

@@ -8,37 +8,49 @@
start-placeholder="开始时间"
end-placeholder="结束时间"
clearable
@change="changeDate"
></el-date-picker>
</template>
<script lang="ts" setup>
import { withDefaults, computed } from 'vue'
/* Props S */
const props = withDefaults(
defineProps<{
startTime?: string
endTime?: string
}>(),
{
startTime: '',
endTime: ''
}
)
const emit = defineEmits(['update:startTime', 'update:endTime'])
const content = computed<any>({
get: () => {
return [props.startTime, props.endTime]
const props = defineProps({
startTime: {
type: String,
default: ''
},
set: (value: Event | any) => {
if (value === null) {
emit('update:startTime', '')
emit('update:endTime', '')
} else {
emit('update:startTime', value[0])
emit('update:endTime', value[1])
}
endTime: {
type: String,
default: ''
}
})
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>

View File

@@ -2,6 +2,7 @@
<el-dialog
v-model="dialogVisible"
append-to-body
:mask="false"
:show-close="false"
:fullscreen="true"
:close-on-click-modal="false"
@@ -216,6 +217,9 @@ export default {
}
</script>
<style>
.flow-config-dialog {
padding: 0;
}
.flow-config-dialog .el-dialog__header {
font-size: var(--el-font-size-large);
padding: 0;

View File

@@ -2,11 +2,13 @@ import { createApp } from 'vue'
import App from './App.vue'
import install from './install'
import './permission'
import 'element-plus/dist/index.css'
import './styles/index.scss'
import 'virtual:svg-icons-register'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import VForm3 from 'vform3-builds' //引入VForm3库
const app = createApp(App)

View File

@@ -23,7 +23,7 @@
<el-table-column label="通知类型" prop="type" min-width="160" />
<el-table-column label="短信通知" min-width="80">
<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>
</template>
</el-table-column>

View File

@@ -5,7 +5,7 @@
<el-table-column label="短信渠道" prop="name" min-width="120" />
<el-table-column label="状态" min-width="120">
<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>
</template>
</el-table-column>

View File

@@ -76,7 +76,7 @@
<el-table-column label="颜色" prop="color" min-width="120" />
<el-table-column label="状态">
<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>
</template>
</el-table-column>

View File

@@ -68,7 +68,7 @@
<el-table-column label="字典类型" prop="dictType" min-width="120" />
<el-table-column label="状态">
<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>
</template>
</el-table-column>

View File

@@ -52,7 +52,7 @@
<el-table-column label="部门状态" prop="isStop" min-width="100">
<template #default="{ row }">
<el-tag class="ml-2" :type="row.isStop ? 'danger' : ''">
<el-tag class="ml-2" :type="row.isStop ? 'danger' : 'primary'">
{{ row.isStop ? '停用' : '正常' }}
</el-tag>
</template>

View File

@@ -53,7 +53,7 @@
<el-table-column label="添加时间" prop="createTime" min-width="180" />
<el-table-column label="岗位状态" prop="isStop" min-width="100">
<template #default="{ row }">
<el-tag class="ml-2" :type="row.isStop ? 'danger' : ''">
<el-tag class="ml-2" :type="row.isStop ? 'danger' : 'primary'">
{{ row.isStop ? '停用' : '正常' }}
</el-tag>
</template>

View File

@@ -3,23 +3,13 @@
<el-card class="!border-none" shadow="never">
<el-form class="mb-[-16px]" :model="formData" inline>
<el-form-item label="管理员账号">
<el-input
v-model="formData.username"
class="w-[280px]"
clearable
@keyup.enter="resetPage"
/>
<el-input v-model="formData.username" clearable @keyup.enter="resetPage" />
</el-form-item>
<el-form-item label="管理员名称">
<el-input
v-model="formData.nickname"
class="w-[280px]"
clearable
@keyup.enter="resetPage"
/>
<el-input v-model="formData.nickname" clearable @keyup.enter="resetPage" />
</el-form-item>
<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
v-for="(item, index) in optionsData.role"
@@ -42,6 +32,13 @@
</template>
新增
</el-button>
<el-button type="primary" @click="exportFile">
<template #icon>
<icon name="el-icon-Download" />
</template>
导出
</el-button>
<div class="mt-4">
<el-table :data="pager.lists" size="large">
<el-table-column label="ID" prop="id" min-width="60" />
@@ -101,7 +98,7 @@
</template>
<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 { useDictOptions } from '@/hooks/useDictOptions'
import { usePaging } from '@/hooks/usePaging'
@@ -135,7 +132,10 @@ const handleAdd = async () => {
await nextTick()
editRef.value?.open('add')
}
const exportFile = async () => {
await feedback.confirm('确定要导出?')
await adminExportFile(formData)
}
const handleEdit = async (data: any) => {
showEdit.value = true
await nextTick()

View File

@@ -52,7 +52,7 @@
</el-table-column>
<el-table-column label="状态" prop="isDisable" min-width="100">
<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>
</template>
</el-table-column>

View File

@@ -14,7 +14,7 @@
<el-table-column label="储存位置" prop="describe" min-width="160" />
<el-table-column label="状态" min-width="80">
<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>
</template>
</el-table-column>

View File

@@ -1,128 +1,118 @@
<!-- 系统日志 -->
<template>
<div class="journal">
<el-card class="!border-none" shadow="never">
<el-form class="ls-form" :model="formData" inline>
<el-form-item label="管理员">
<el-input
class="w-[280px]"
placeholder="请输入"
v-model="formData.username"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<div class="journal">
{{ formData }}
<el-card class="!border-none" shadow="never">
<el-form class="ls-form" :model="formData" inline>
<el-form-item label="管理员" class="w-[360px]">
<el-input
placeholder="请输入"
v-model="formData.username"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="访问方式">
<el-select
class="w-[280px]"
v-model="formData.type"
placeholder="请选择"
>
<el-option
v-for="(item, index) in visitType"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="访问方式" class="w-[360px]">
<el-select v-model="formData.type" placeholder="请选择">
<el-option
v-for="(item, index) in visitType"
:key="index"
:label="item.label"
:value="item.value"
/>
</el-select>
</el-form-item>
<el-form-item label="来源IP">
<el-input
class="w-[280px]"
placeholder="请输入"
v-model="formData.ip"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="来源IP" class="w-[360px]">
<el-input
placeholder="请输入"
v-model="formData.ip"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="访问时间">
<daterange-picker
v-model:startTime="formData.startTime"
v-model:endTime="formData.endTime"
/>
</el-form-item>
<el-form-item label="访问时间" class="w-[360px]">
<daterange-picker
v-model:startTime="formData.startTime"
v-model:endTime="formData.endTime"
/>
</el-form-item>
<el-form-item label="访问链接">
<el-input
class="w-[280px]"
placeholder="请输入"
v-model="formData.url"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item label="访问链接" class="w-[360px]">
<el-input
placeholder="请输入"
v-model="formData.url"
clearable
@keyup.enter="resetPage"
/>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-form-item>
<el-button type="primary" @click="resetPage">查询</el-button>
<el-button @click="resetParams">重置</el-button>
</el-form-item>
</el-form>
</el-card>
<el-card class="!border-none mt-4" shadow="never" v-loading="pager.loading">
<div>
<el-table :data="pager.lists" size="large">
<el-table-column label="记录ID" prop="id" />
<el-table-column label="操作" prop="title" 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="type" min-width="100" />
<el-table-column label="来源IP" prop="ip" min-width="160" />
<el-table-column label="错误信息" prop="error" min-width="160" />
<el-table-column
label="执行耗时(毫秒)"
prop="taskTime"
min-width="100"
/>
<el-table-column label="日志时间" prop="createTime" min-width="180" />
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
</div>
<el-card class="!border-none mt-4" shadow="never" v-loading="pager.loading">
<div>
<el-table :data="pager.lists" size="large">
<el-table-column label="记录ID" prop="id" />
<el-table-column label="操作" prop="title" 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="type" min-width="100" />
<el-table-column label="来源IP" prop="ip" min-width="160" />
<el-table-column label="错误信息" prop="error" min-width="160" />
<el-table-column label="执行耗时(毫秒)" prop="taskTime" min-width="100" />
<el-table-column label="日志时间" prop="createTime" min-width="180" />
</el-table>
</div>
<div class="flex mt-4 justify-end">
<pagination v-model="pager" @change="getLists" />
</div>
</el-card>
</div>
</template>
<script setup lang="ts" name="journal">
import { systemLogLists } from "@/api/setting/system";
import { usePaging } from "@/hooks/usePaging";
import { systemLogLists } from '@/api/setting/system'
import { usePaging } from '@/hooks/usePaging'
// 查询表单
const formData = ref({
username: "",
url: "",
ip: "",
type: "",
startTime: "",
endTime: "",
});
username: '',
url: '',
ip: '',
type: '',
startTime: '',
endTime: ''
})
// 访问方式
const visitType = ref<Array<any>>([
{
label: "全部",
value: "",
},
{
label: "get",
value: "GET",
},
{
label: "post",
value: "POST",
},
]);
{
label: '全部',
value: ''
},
{
label: 'get',
value: 'GET'
},
{
label: 'post',
value: 'POST'
}
])
const { pager, getLists, resetParams, resetPage } = usePaging({
fetchFun: systemLogLists,
params: formData.value,
});
fetchFun: systemLogLists,
params: formData.value
})
getLists();
getLists()
</script>
<style lang="scss" scoped></style>

View File

@@ -7,14 +7,17 @@
"auto-imports.d.ts",
"typings/**/*.d.ts"
],
"exclude": ["dist"],
"compilerOptions": {
"module": "esnext",
"moduleResolution": "node",
"allowJs": true,
"outDir": "./dist",
"isolatedModules": true,
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"types": ["element-plus/global"]
}
}

View File

@@ -41,8 +41,8 @@ export default ({ mode }) => {
}
}),
Components({
directoryAsNamespace: true
// resolvers: [ElementPlusResolver()]
directoryAsNamespace: true,
resolvers: [ElementPlusResolver()]
}),
// createStyleImportPlugin({
// resolves: [ElementPlusResolve()]

View File

@@ -5,6 +5,7 @@ import (
"x_admin/config"
"x_admin/core/request"
"x_admin/core/response"
"x_admin/util/excel"
"x_admin/util"
@@ -44,6 +45,28 @@ func (ah AdminHandler) Self(c *gin.Context) {
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 管理员列表
func (ah AdminHandler) List(c *gin.Context) {
var page request.PageReq
@@ -114,12 +137,12 @@ func (ah AdminHandler) Disable(c *gin.Context) {
response.CheckAndResp(c, Service.Disable(c, disableReq.ID))
}
// @Summary 获取部门的用户
// @Description 获取部门的用户
// @Tags 管理员
// @Param deptId path int true "部门id"
// @Success 200 {object} response.Response "{"code": 200, "data": []}"
// @Router /system/admin/ListByDeptId/{deptId} [get]
// @Summary 获取部门的用户
// @Description 获取部门的用户
// @Tags 管理员
// @Param deptId path int true "部门id"
// @Success 200 {object} response.Response "{"code": 200, "data": []}"
// @Router /system/admin/ListByDeptId/{deptId} [get]
func (ah AdminHandler) ListByDeptId(c *gin.Context) {
deptIdStr, bool := c.GetQuery("deptId")
if bool == false {

View File

@@ -63,20 +63,20 @@ type SystemAuthAdminDisableReq struct {
//SystemAuthAdminResp 管理员返回信息
type SystemAuthAdminResp struct {
ID uint `json:"id" structs:"id"` // 主键
Username string `json:"username" structs:"username"` // 账号
Nickname string `json:"nickname" structs:"nickname"` // 昵称
Avatar string `json:"avatar" structs:"avatar"` // 头像
Role string `json:"role" structs:"role"` // 角色
DeptId uint `json:"deptId" structs:"deptId"` // 部门ID
PostId uint `json:"postId" structs:"postId"` // 岗位ID
Dept string `json:"dept" structs:"dept"` // 部门
IsMultipoint uint8 `json:"isMultipoint" structs:"isMultipoint"` // 多端登录: [0=否, 1=是]
IsDisable uint8 `json:"isDisable" structs:"isDisable"` // 是否禁用: [0=否, 1=是]
LastLoginIp string `json:"lastLoginIp" structs:"lastLoginIp"` // 最后登录IP
LastLoginTime core.TsTime `json:"lastLoginTime" structs:"lastLoginTime"` // 最后登录时间
CreateTime core.TsTime `json:"createTime" structs:"createTime"` // 创建时间
UpdateTime core.TsTime `json:"updateTime" structs:"updateTime"` // 更新时间
ID uint `json:"id" structs:"id"` // 主键
Username string `json:"username" structs:"username" excel:"name:账号;"` // 账号
Nickname string `json:"nickname" structs:"nickname" excel:"name:昵称;"` // 昵称
Avatar string `json:"avatar" structs:"avatar" excel:"name:头像;"` // 头像
Role string `json:"role" structs:"role" excel:"name:角色;"` // 角色
DeptId uint `json:"deptId" structs:"deptId" excel:"name:部门ID;"` // 部门ID
PostId uint `json:"postId" structs:"postId" excel:"name:岗位ID;"` // 岗位ID
Dept string `json:"dept" structs:"dept" excel:"name:部门;"` // 部门
IsMultipoint uint8 `json:"isMultipoint" structs:"isMultipoint" excel:"name:多端登录;"` // 多端登录: [0=否, 1=是]
IsDisable uint8 `json:"isDisable" structs:"isDisable" excel:"name:是否禁用;"` // 是否禁用: [0=否, 1=是]
LastLoginIp string `json:"lastLoginIp" structs:"lastLoginIp" excel:"name:最后登录IP;"` // 最后登录IP
LastLoginTime core.TsTime `json:"lastLoginTime" structs:"lastLoginTime" excel:"name:最后登录时间;"` // 最后登录时间
CreateTime core.TsTime `json:"createTime" structs:"createTime" excel:"name:创建时间;"` // 创建时间
UpdateTime core.TsTime `json:"updateTime" structs:"updateTime" excel:"name:更新时间;"` // 更新时间
}
//SystemAuthAdminSelfOneResp 当前管理员返回部分信息

View File

@@ -122,6 +122,39 @@ func (adminSrv systemAuthAdminService) ListByUserIdOrDeptIdPostId(userId, deptId
}
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 管理员列表
func (adminSrv systemAuthAdminService) List(page request.PageReq, listReq SystemAuthAdminListReq) (res response.PageResp, e error) {

View File

@@ -30,6 +30,8 @@ func AdminRoute(rg *gin.RouterGroup) {
rg.POST("/admin/del", middleware.RecordLog("管理员删除"), handle.Del)
rg.POST("/admin/disable", middleware.RecordLog("管理员状态切换"), handle.Disable)
rg.GET("/admin/ExportFile", middleware.RecordLog("管理员导出"), handle.ExportFile)
}
func RoleRoute(rg *gin.RouterGroup) {
// db := core.GetDB()

View File

@@ -16,13 +16,25 @@ import (
func GetExcelColumnName(columnNumber int) string {
columnName := ""
for columnNumber > 0 {
columnNumber--
columnName = fmt.Sprint('A'+columnNumber%26) + columnName
columnNumber /= 26
remainder := (columnNumber - 1) % 26
columnName = string('A'+remainder) + columnName
columnNumber = (columnNumber - 1) / 26
}
return columnName
}
// NormalDynamicExport 导出excel
// ** 需要在传入的结构体中的字段加上tagexcelize:"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导出
func ExportExcel(sheet, title, fields string, isGhbj, isIgnore bool, list interface{}, changeHead map[string]string, e *Excel) (err error) {
index, _ := e.F.GetSheetIndex(sheet)
@@ -47,44 +59,6 @@ func ExportExcel(sheet, title, fields string, isGhbj, isIgnore bool, list interf
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
// ** 需要在传入的结构体中的字段加上tagexcelize:"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 数据行开始的行号)
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() // 获取导入目标对象的类型信息

View File

@@ -66,3 +66,11 @@ func TestImports(t *testing.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.