mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2025-10-07 00:52:57 +08:00
统一上传文件不区分图片、视频接口,素材中心私有化
This commit is contained in:
@@ -8,7 +8,7 @@ import { getToken } from '@/utils/auth'
|
|||||||
type album_cate = {
|
type album_cate = {
|
||||||
id?: number
|
id?: number
|
||||||
pid?: number
|
pid?: number
|
||||||
type?: number
|
// type?: number
|
||||||
name?: string
|
name?: string
|
||||||
isDelete?: number
|
isDelete?: number
|
||||||
createTime?: string
|
createTime?: string
|
||||||
@@ -18,7 +18,7 @@ type album_cate = {
|
|||||||
// 查询
|
// 查询
|
||||||
type album_cate_query = {
|
type album_cate_query = {
|
||||||
pid?: number
|
pid?: number
|
||||||
type?: number
|
// type?: number
|
||||||
name?: string
|
name?: string
|
||||||
createTimeStart?: string
|
createTimeStart?: string
|
||||||
createTimeEnd?: string
|
createTimeEnd?: string
|
||||||
@@ -29,7 +29,7 @@ type album_cate_query = {
|
|||||||
type album_cate_edit = {
|
type album_cate_edit = {
|
||||||
id?: number
|
id?: number
|
||||||
pid?: number
|
pid?: number
|
||||||
type?: number
|
// type?: number
|
||||||
name?: string
|
name?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -28,12 +28,25 @@ export default defineComponent({
|
|||||||
default: '100px'
|
default: '100px'
|
||||||
},
|
},
|
||||||
// 文件类型
|
// 文件类型
|
||||||
type: {
|
ext: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'image'
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['close']
|
emits: ['close'],
|
||||||
|
computed: {
|
||||||
|
type() {
|
||||||
|
const imageExt = ['jpg', 'jpeg', 'png', 'gif', 'bmp']
|
||||||
|
const videoExt = ['mp4', 'avi', 'mov']
|
||||||
|
if (imageExt.includes(this.ext)) {
|
||||||
|
return 'image'
|
||||||
|
}
|
||||||
|
if (videoExt.includes(this.ext)) {
|
||||||
|
return 'video'
|
||||||
|
}
|
||||||
|
return 'file'
|
||||||
|
}
|
||||||
|
}
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -15,7 +15,7 @@ import { shallowRef, ref, reactive } from 'vue'
|
|||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
|
|
||||||
// 左侧分组的钩子函数
|
// 左侧分组的钩子函数
|
||||||
export function useCate(type: number) {
|
export function useCate() {
|
||||||
const treeRef = shallowRef<InstanceType<typeof ElTree>>()
|
const treeRef = shallowRef<InstanceType<typeof ElTree>>()
|
||||||
// 分组列表
|
// 分组列表
|
||||||
const cateLists = ref<any[]>([])
|
const cateLists = ref<any[]>([])
|
||||||
@@ -25,18 +25,12 @@ export function useCate(type: number) {
|
|||||||
|
|
||||||
// 获取分组列表
|
// 获取分组列表
|
||||||
const getCateLists = async () => {
|
const getCateLists = async () => {
|
||||||
const data = await fileCateLists({
|
const data = await fileCateLists({})
|
||||||
type
|
|
||||||
})
|
|
||||||
const item: any[] = [
|
const item: any[] = [
|
||||||
{
|
{
|
||||||
name: '全部',
|
name: '全部',
|
||||||
id: 0
|
id: 0
|
||||||
}
|
}
|
||||||
// {
|
|
||||||
// name: '未分组',
|
|
||||||
// id: 0
|
|
||||||
// }
|
|
||||||
]
|
]
|
||||||
cateLists.value = data
|
cateLists.value = data
|
||||||
cateLists.value.unshift(...item)
|
cateLists.value.unshift(...item)
|
||||||
@@ -48,7 +42,6 @@ export function useCate(type: number) {
|
|||||||
// 添加分组
|
// 添加分组
|
||||||
const handleAddCate = async (value: string) => {
|
const handleAddCate = async (value: string) => {
|
||||||
await fileCateAdd({
|
await fileCateAdd({
|
||||||
type,
|
|
||||||
name: value,
|
name: value,
|
||||||
pid: 0
|
pid: 0
|
||||||
})
|
})
|
||||||
@@ -92,7 +85,7 @@ export function useCate(type: number) {
|
|||||||
// 处理文件的钩子函数
|
// 处理文件的钩子函数
|
||||||
export function useFile(
|
export function useFile(
|
||||||
cateId: Ref<string | number>,
|
cateId: Ref<string | number>,
|
||||||
type: Ref<number>,
|
ext: string[],
|
||||||
limit: Ref<number>,
|
limit: Ref<number>,
|
||||||
size: number
|
size: number
|
||||||
) {
|
) {
|
||||||
@@ -103,7 +96,7 @@ export function useFile(
|
|||||||
const isIndeterminate = ref(false)
|
const isIndeterminate = ref(false)
|
||||||
const fileParams = reactive({
|
const fileParams = reactive({
|
||||||
name: '',
|
name: '',
|
||||||
type: type,
|
ext: ext,
|
||||||
cid: cateId
|
cid: cateId
|
||||||
})
|
})
|
||||||
const { pager, getLists, resetPage } = usePaging({
|
const { pager, getLists, resetPage } = usePaging({
|
||||||
|
@@ -85,22 +85,10 @@
|
|||||||
<div class="operate-btn flex">
|
<div class="operate-btn flex">
|
||||||
<div class="flex-1 flex">
|
<div class="flex-1 flex">
|
||||||
<upload
|
<upload
|
||||||
v-if="type == 'image'"
|
|
||||||
v-perms="['admin:common:upload:image']"
|
v-perms="['admin:common:upload:image']"
|
||||||
class="mr-3"
|
class="mr-3"
|
||||||
:data="{ cid: cateId }"
|
:data="{ cid: cateId }"
|
||||||
:type="type"
|
:ext="ext"
|
||||||
:show-progress="true"
|
|
||||||
@change="refresh"
|
|
||||||
>
|
|
||||||
<el-button type="primary">本地上传</el-button>
|
|
||||||
</upload>
|
|
||||||
<upload
|
|
||||||
v-if="type == 'video'"
|
|
||||||
v-perms="['admin:common:upload:video']"
|
|
||||||
class="mr-3"
|
|
||||||
:data="{ cid: cateId }"
|
|
||||||
:type="type"
|
|
||||||
:show-progress="true"
|
:show-progress="true"
|
||||||
@change="refresh"
|
@change="refresh"
|
||||||
>
|
>
|
||||||
@@ -139,7 +127,7 @@
|
|||||||
<file-item
|
<file-item
|
||||||
:uri="row.uri"
|
:uri="row.uri"
|
||||||
file-size="50px"
|
file-size="50px"
|
||||||
:type="type"
|
:ext="row.ext"
|
||||||
@click.stop="handlePreview(row.uri)"
|
@click.stop="handlePreview(row.uri)"
|
||||||
></file-item>
|
></file-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -151,6 +139,9 @@
|
|||||||
</el-link>
|
</el-link>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
<el-table-column label="大小" prop="size" min-width="100"> </el-table-column>
|
||||||
|
<el-table-column label="格式" prop="ext" min-width="100"></el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="createTime" label="上传时间" min-width="100" />
|
<el-table-column prop="createTime" label="上传时间" min-width="100" />
|
||||||
<el-table-column label="操作" width="150" fixed="right">
|
<el-table-column label="操作" width="150" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
@@ -259,7 +250,7 @@
|
|||||||
<file-item
|
<file-item
|
||||||
:uri="item.uri"
|
:uri="item.uri"
|
||||||
file-size="100px"
|
file-size="100px"
|
||||||
:type="type"
|
:ext="item.ext"
|
||||||
></file-item>
|
></file-item>
|
||||||
</del-wrap>
|
</del-wrap>
|
||||||
</div>
|
</div>
|
||||||
@@ -268,12 +259,14 @@
|
|||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<preview v-model="showPreview" :url="previewUrl" :type="type" />
|
<preview v-model="showPreview" :url="previewUrl" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, toRefs, ref, watch } from 'vue'
|
import { onMounted, toRefs, ref, watch } from 'vue'
|
||||||
|
import type { PropType } from 'vue'
|
||||||
|
|
||||||
import { useCate, useFile } from './hook'
|
import { useCate, useFile } from './hook'
|
||||||
import FileItem from './file.vue'
|
import FileItem from './file.vue'
|
||||||
import Preview from './preview.vue'
|
import Preview from './preview.vue'
|
||||||
@@ -286,10 +279,14 @@ const props = defineProps({
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 1
|
default: 1
|
||||||
},
|
},
|
||||||
type: {
|
ext: {
|
||||||
type: String,
|
type: Array as PropType<string[]>,
|
||||||
default: 'image'
|
default: () => []
|
||||||
},
|
},
|
||||||
|
// type: {
|
||||||
|
// type: String,
|
||||||
|
// default: 'image'
|
||||||
|
// },
|
||||||
mode: {
|
mode: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'picker'
|
default: 'picker'
|
||||||
@@ -301,18 +298,18 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
const emit = defineEmits(['change'])
|
const emit = defineEmits(['change'])
|
||||||
const { limit } = toRefs(props)
|
const { limit } = toRefs(props)
|
||||||
const typeValue = computed<number>(() => {
|
// const typeValue = computed<number>(() => {
|
||||||
switch (props.type) {
|
// switch (props.type) {
|
||||||
case 'image':
|
// case 'image':
|
||||||
return 10
|
// return 10
|
||||||
case 'video':
|
// case 'video':
|
||||||
return 20
|
// return 20
|
||||||
case 'file':
|
// case 'file':
|
||||||
return 30
|
// return 30
|
||||||
default:
|
// default:
|
||||||
return 0
|
// return 0
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
// const visible: Ref<boolean> = inject('visible')
|
// const visible: Ref<boolean> = inject('visible')
|
||||||
const previewUrl = ref('')
|
const previewUrl = ref('')
|
||||||
const showPreview = ref(false)
|
const showPreview = ref(false)
|
||||||
@@ -325,7 +322,7 @@ const {
|
|||||||
handleDeleteCate,
|
handleDeleteCate,
|
||||||
getCateLists,
|
getCateLists,
|
||||||
handleCatSelect
|
handleCatSelect
|
||||||
} = useCate(typeValue.value)
|
} = useCate()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
tableRef,
|
tableRef,
|
||||||
@@ -345,7 +342,7 @@ const {
|
|||||||
|
|
||||||
selectItems,
|
selectItems,
|
||||||
handleFileRename
|
handleFileRename
|
||||||
} = useFile(cateId, typeValue, limit, props.pageSize)
|
} = useFile(cateId, props.ext, limit, props.pageSize)
|
||||||
function handleSelectionChange(val: any[]) {
|
function handleSelectionChange(val: any[]) {
|
||||||
console.log('handleSelectionChange', val)
|
console.log('handleSelectionChange', val)
|
||||||
selectItems(val)
|
selectItems(val)
|
||||||
@@ -356,22 +353,12 @@ const getData = async () => {
|
|||||||
treeRef.value?.setCurrentKey(cateId.value)
|
treeRef.value?.setCurrentKey(cateId.value)
|
||||||
getFileList()
|
getFileList()
|
||||||
}
|
}
|
||||||
// getData()
|
|
||||||
const handlePreview = (url: string) => {
|
const handlePreview = (url: string) => {
|
||||||
previewUrl.value = url
|
previewUrl.value = url
|
||||||
showPreview.value = true
|
showPreview.value = true
|
||||||
}
|
}
|
||||||
// watch(
|
|
||||||
// () => visible,
|
|
||||||
// (val) => {
|
|
||||||
// if (val) {
|
|
||||||
// getData()
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// immediate: true
|
|
||||||
// }
|
|
||||||
// )
|
|
||||||
watch(cateId, () => {
|
watch(cateId, () => {
|
||||||
fileParams.name = ''
|
fileParams.name = ''
|
||||||
refresh()
|
refresh()
|
||||||
|
@@ -17,7 +17,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, useTemplateRef, watch, nextTick } from 'vue'
|
import { ref, useTemplateRef, watch, computed, nextTick } from 'vue'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -26,11 +26,24 @@ const props = defineProps({
|
|||||||
url: {
|
url: {
|
||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: 'image'
|
|
||||||
}
|
}
|
||||||
|
// type: {
|
||||||
|
// type: String,
|
||||||
|
// default: 'image'
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
|
||||||
|
const type = computed(() => {
|
||||||
|
const imageExt = ['jpg', 'jpeg', 'png', 'gif', 'bmp']
|
||||||
|
const videoExt = ['mp4', 'avi', 'mov']
|
||||||
|
const ext = props.url.split('.').pop()
|
||||||
|
if (imageExt.includes(ext)) {
|
||||||
|
return 'image'
|
||||||
|
}
|
||||||
|
if (videoExt.includes(ext)) {
|
||||||
|
return 'video'
|
||||||
|
}
|
||||||
|
return 'file'
|
||||||
})
|
})
|
||||||
|
|
||||||
const playerRef = useTemplateRef('playerRef')
|
const playerRef = useTemplateRef('playerRef')
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
:on-error="handleError"
|
:on-error="handleError"
|
||||||
:accept="getAccept"
|
:accept="getAccept"
|
||||||
>
|
>
|
||||||
<slot></slot>
|
<slot></slot>{{ getAccept }}
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-if="showProgress && fileList.length"
|
v-if="showProgress && fileList.length"
|
||||||
@@ -41,6 +41,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, ref, toRaw, useTemplateRef } from 'vue'
|
import { computed, defineComponent, ref, toRaw, useTemplateRef } from 'vue'
|
||||||
|
import type { PropType } from 'vue'
|
||||||
import useUserStore from '@/stores/modules/user'
|
import useUserStore from '@/stores/modules/user'
|
||||||
import config from '@/config'
|
import config from '@/config'
|
||||||
import feedback from '@/utils/feedback'
|
import feedback from '@/utils/feedback'
|
||||||
@@ -54,6 +55,10 @@ export default defineComponent({
|
|||||||
type: String,
|
type: String,
|
||||||
default: ''
|
default: ''
|
||||||
},
|
},
|
||||||
|
ext: {
|
||||||
|
type: Array as PropType<string[]>,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
// 上传文件类型
|
// 上传文件类型
|
||||||
type: {
|
type: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -94,7 +99,7 @@ export default defineComponent({
|
|||||||
action = `${config.baseUrl}${config.urlPrefix}${props.url}`
|
action = `${config.baseUrl}${config.urlPrefix}${props.url}`
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
action = `${config.baseUrl}${config.urlPrefix}/common/upload/${props.type}`
|
action = `${config.baseUrl}${config.urlPrefix}/common/upload/file`
|
||||||
}
|
}
|
||||||
const headers = computed(() => ({
|
const headers = computed(() => ({
|
||||||
token: userStore.token,
|
token: userStore.token,
|
||||||
@@ -135,14 +140,15 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getAccept = computed(() => {
|
const getAccept = computed(() => {
|
||||||
switch (props.type) {
|
if (props.ext.length) {
|
||||||
case 'image':
|
// 补充前缀
|
||||||
return '.jpg,.png,.gif,.webp,.jpeg,.ico,.bmp'
|
return props.ext
|
||||||
case 'video':
|
.map((item) => {
|
||||||
return '.wmv,.avi,.mov,.mp4,.flv,.rmvb'
|
return `.${item}`
|
||||||
default:
|
})
|
||||||
return '*'
|
.join(',')
|
||||||
}
|
}
|
||||||
|
return '*'
|
||||||
})
|
})
|
||||||
return {
|
return {
|
||||||
uploadRefs,
|
uploadRefs,
|
||||||
|
@@ -5,13 +5,13 @@
|
|||||||
<el-tab-pane
|
<el-tab-pane
|
||||||
v-for="item in tabsMap"
|
v-for="item in tabsMap"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:name="item.type"
|
:name="item.name"
|
||||||
:index="item.type"
|
:index="item.name"
|
||||||
:key="item.type"
|
:key="item.name"
|
||||||
lazy
|
lazy
|
||||||
>
|
>
|
||||||
<material
|
<material
|
||||||
:type="item.type"
|
:ext="item.ext"
|
||||||
mode="page"
|
mode="page"
|
||||||
file-size="120px"
|
file-size="120px"
|
||||||
:limit="-1"
|
:limit="-1"
|
||||||
@@ -31,12 +31,24 @@ defineOptions({
|
|||||||
})
|
})
|
||||||
const tabsMap = [
|
const tabsMap = [
|
||||||
{
|
{
|
||||||
type: 'image',
|
// type: '',
|
||||||
name: '图片'
|
name: '全部',
|
||||||
|
ext: []
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'video',
|
// type: 'image',
|
||||||
name: '视频'
|
name: '图片',
|
||||||
|
ext: ['jpg', 'jpeg', 'png', 'gif', 'bmp']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// type: 'video',
|
||||||
|
name: '视频',
|
||||||
|
ext: ['mp4', 'avi', 'mov']
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// type: 'pdf',
|
||||||
|
name: 'pdf',
|
||||||
|
ext: ['pdf']
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
const activeTab = ref('image')
|
const activeTab = ref('image')
|
||||||
@@ -47,11 +59,7 @@ const activeTab = ref('image')
|
|||||||
min-width: 700px;
|
min-width: 700px;
|
||||||
:deep(.el-tabs) {
|
:deep(.el-tabs) {
|
||||||
height: calc(100vh - 180px);
|
height: calc(100vh - 180px);
|
||||||
// display: flex;
|
|
||||||
// flex-direction: column;
|
|
||||||
// .el-tabs__header {
|
|
||||||
// margin-bottom: 0 !important;
|
|
||||||
// }
|
|
||||||
.el-tabs__content,
|
.el-tabs__content,
|
||||||
.el-tab-pane {
|
.el-tab-pane {
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
|
@@ -13,3 +13,11 @@ REDIS.URL='redis://localhost:6379'
|
|||||||
|
|
||||||
# 上传文件目录
|
# 上传文件目录
|
||||||
FILE.UPLOAD_DIRECTORY='/www/wwwroot/x_admin_go/public/uploads/'
|
FILE.UPLOAD_DIRECTORY='/www/wwwroot/x_admin_go/public/uploads/'
|
||||||
|
|
||||||
|
|
||||||
|
GeTui.HOST=''
|
||||||
|
GeTui.APPID=''
|
||||||
|
GeTui.APPKEY=''
|
||||||
|
GeTui.APPSECRET=''
|
||||||
|
GeTui.MASTERSECRET=''
|
||||||
|
GeTui.PackName=''
|
@@ -3,21 +3,30 @@ package config
|
|||||||
type fileConfig struct {
|
type fileConfig struct {
|
||||||
UploadDirectory string `mapstructure:"UPLOAD_DIRECTORY"` // 文件目录
|
UploadDirectory string `mapstructure:"UPLOAD_DIRECTORY"` // 文件目录
|
||||||
PublicPrefix string `mapstructure:"PUBLIC_PREFIX"` // 资源访问前缀
|
PublicPrefix string `mapstructure:"PUBLIC_PREFIX"` // 资源访问前缀
|
||||||
|
|
||||||
UploadImageSize int64 `mapstructure:"UPLOAD_IMAGE_SIZE"` // 上传图片大小限制
|
UploadImageSize int64 `mapstructure:"UPLOAD_IMAGE_SIZE"` // 上传图片大小限制
|
||||||
UploadVideoSize int64 `mapstructure:"UPLOAD_VIDEO_SIZE"` // 上传视频大小限制
|
UploadVideoSize int64 `mapstructure:"UPLOAD_VIDEO_SIZE"` // 上传视频大小限制
|
||||||
|
UploadFileSize int64 `mapstructure:"UPLOAD_FILE_SIZE"` // 上传文件大小限制
|
||||||
|
|
||||||
UploadImageExt []string `mapstructure:"UPLOAD_IMAGE_EXT"` // 上传图片扩展
|
UploadImageExt []string `mapstructure:"UPLOAD_IMAGE_EXT"` // 上传图片扩展
|
||||||
UploadVideoExt []string `mapstructure:"UPLOAD_VIDEO_EXT"` // 上传视频扩展
|
UploadVideoExt []string `mapstructure:"UPLOAD_VIDEO_EXT"` // 上传视频扩展
|
||||||
|
UploadFileExt []string `mapstructure:"UPLOAD_FILE_EXT"` // 上传文件扩展
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// var uploadImageExtDefault = []string{"png", "jpg", "jpeg", "gif", "ico", "bmp", "webp", "avif"}
|
||||||
|
|
||||||
var FileConfig = fileConfig{
|
var FileConfig = fileConfig{
|
||||||
// 资源访问前缀
|
// 资源访问前缀
|
||||||
PublicPrefix: "/api/uploads",
|
PublicPrefix: "/api/uploads",
|
||||||
// 上传文件路径
|
// 上传文件路径
|
||||||
UploadDirectory: "/tmp/uploads/x_admin_go/",
|
UploadDirectory: "/tmp/uploads/x_admin_go/",
|
||||||
UploadImageSize: 10 * 1024 * 1024,
|
UploadImageSize: 10 * 1024 * 1024, // 10MB
|
||||||
UploadVideoSize: 30 * 1024 * 1024,
|
UploadVideoSize: 500 * 1024 * 1024, // 500MB
|
||||||
|
UploadFileSize: 1024 * 1024 * 1024, //1GB
|
||||||
// 上传图片扩展
|
// 上传图片扩展
|
||||||
UploadImageExt: []string{"png", "jpg", "jpeg", "gif", "ico", "bmp", "webp", "avif"},
|
UploadImageExt: []string{"png", "jpg", "jpeg", "gif", "ico", "bmp", "webp", "avif"},
|
||||||
// 上传视频扩展
|
// 上传视频扩展
|
||||||
UploadVideoExt: []string{"mp4", "mp3", "avi", "flv", "rmvb", "mov"},
|
UploadVideoExt: []string{"mp4", "mp3", "avi", "flv", "rmvb", "mov"},
|
||||||
|
|
||||||
|
UploadFileExt: []string{"pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "zip", "rar", "7z", "txt"},
|
||||||
}
|
}
|
||||||
|
@@ -1,6 +1,7 @@
|
|||||||
package commonController
|
package commonController
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"x_admin/config"
|
||||||
"x_admin/core/request"
|
"x_admin/core/request"
|
||||||
"x_admin/core/response"
|
"x_admin/core/response"
|
||||||
"x_admin/middleware"
|
"x_admin/middleware"
|
||||||
@@ -39,7 +40,8 @@ func (ah albumHandler) albumList(c *gin.Context) {
|
|||||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res, err := commonService.AlbumService.AlbumList(page, listReq)
|
var adminId = config.AdminConfig.GetAdminId(c)
|
||||||
|
res, err := commonService.AlbumService.AlbumList(adminId, page, listReq)
|
||||||
response.CheckAndRespWithData(c, res, err)
|
response.CheckAndRespWithData(c, res, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +78,8 @@ func (ah albumHandler) cateList(c *gin.Context) {
|
|||||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyQuery(c, &listReq)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res, err := commonService.AlbumService.CateList(listReq)
|
var adminId = config.AdminConfig.GetAdminId(c)
|
||||||
|
res, err := commonService.AlbumService.CateList(adminId, listReq)
|
||||||
response.CheckAndRespWithData(c, res, err)
|
response.CheckAndRespWithData(c, res, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +89,8 @@ func (ah albumHandler) cateAdd(c *gin.Context) {
|
|||||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &addReq)) {
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyJSON(c, &addReq)) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
response.CheckAndResp(c, commonService.AlbumService.CateAdd(addReq))
|
var adminId = config.AdminConfig.GetAdminId(c)
|
||||||
|
response.CheckAndResp(c, commonService.AlbumService.CateAdd(adminId, addReq))
|
||||||
}
|
}
|
||||||
|
|
||||||
// cateRename 类目命名
|
// cateRename 类目命名
|
||||||
|
@@ -15,28 +15,26 @@ func UploadRoute(rg *gin.RouterGroup) {
|
|||||||
handle := uploadHandler{}
|
handle := uploadHandler{}
|
||||||
|
|
||||||
rg = rg.Group("/common", middleware.TokenAuth())
|
rg = rg.Group("/common", middleware.TokenAuth())
|
||||||
rg.POST("/upload/image", middleware.RecordLog("上传图片", middleware.RequestFile), handle.uploadImage)
|
rg.POST("/upload/preUploadFile", middleware.RecordLog("文件预上传", middleware.RequestFile), handle.preUploadFile)
|
||||||
rg.POST("/upload/video", middleware.RecordLog("上传视频", middleware.RequestFile), handle.uploadVideo)
|
rg.POST("/upload/file", middleware.RecordLog("上传文件", middleware.RequestFile), handle.uploadFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
type uploadHandler struct{}
|
type uploadHandler struct{}
|
||||||
|
|
||||||
// uploadImage 上传图片
|
// 文件预上传
|
||||||
func (uh uploadHandler) uploadImage(c *gin.Context) {
|
func (uh uploadHandler) preUploadFile(c *gin.Context) {
|
||||||
var uReq commonSchema.CommonUploadImageReq
|
// md5,fileName,fileSize,cid
|
||||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyBody(c, &uReq)) {
|
// 检查MD5是否已存在
|
||||||
return
|
// 检查名称是否合规安全
|
||||||
}
|
// 检查文件大小是否超过限制
|
||||||
file, ve := util.VerifyUtil.VerifyFile(c, "file")
|
// 检查文件类型是否符合要求
|
||||||
if response.IsFailWithResp(c, ve) {
|
|
||||||
return
|
// 如果文件存在,复制到cid对应目录
|
||||||
}
|
|
||||||
res, err := commonService.UploadService.UploadImage(file, uReq.Cid, config.AdminConfig.GetAdminId(c))
|
|
||||||
response.CheckAndRespWithData(c, res, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// uploadVideo 上传视频
|
// uploadFile 上传文件
|
||||||
func (uh uploadHandler) uploadVideo(c *gin.Context) {
|
func (uh uploadHandler) uploadFile(c *gin.Context) {
|
||||||
var uReq commonSchema.CommonUploadImageReq
|
var uReq commonSchema.CommonUploadImageReq
|
||||||
if response.IsFailWithResp(c, util.VerifyUtil.VerifyBody(c, &uReq)) {
|
if response.IsFailWithResp(c, util.VerifyUtil.VerifyBody(c, &uReq)) {
|
||||||
return
|
return
|
||||||
@@ -45,6 +43,6 @@ func (uh uploadHandler) uploadVideo(c *gin.Context) {
|
|||||||
if response.IsFailWithResp(c, ve) {
|
if response.IsFailWithResp(c, ve) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
res, err := commonService.UploadService.UploadVideo(file, uReq.Cid, config.AdminConfig.GetAdminId(c))
|
res, err := commonService.UploadService.UploadFile(file, uReq.Cid, config.AdminConfig.GetAdminId(c))
|
||||||
response.CheckAndRespWithData(c, res, err)
|
response.CheckAndRespWithData(c, res, err)
|
||||||
}
|
}
|
||||||
|
@@ -10,12 +10,13 @@ import (
|
|||||||
type Album struct {
|
type Album struct {
|
||||||
ID uint `gorm:"primarykey;comment:'主键ID'"`
|
ID uint `gorm:"primarykey;comment:'主键ID'"`
|
||||||
Cid uint `gorm:"not null;default:0;comment:'类目ID'"`
|
Cid uint `gorm:"not null;default:0;comment:'类目ID'"`
|
||||||
Aid uint `gorm:"not null;default:0;comment:'管理ID'"`
|
AdminId uint `gorm:"not null;default:0;comment:'管理员ID'"`
|
||||||
Uid uint `gorm:"not null;default:0;comment:'用户ID'"`
|
Uid uint `gorm:"not null;default:0;comment:'用户ID'"`
|
||||||
Type int `gorm:"not null;default:10;comment:'文件类型: [10=图片, 20=视频]''"`
|
// Type int `gorm:"not null;default:10;comment:'文件类型: [10=图片, 20=视频]''"`
|
||||||
Name string `gorm:"not null;default:'';comment:'文件名称''"`
|
Name string `gorm:"not null;default:'';comment:'文件名称''"`
|
||||||
Uri string `gorm:"not null;comment:'文件路径'"`
|
Uri string `gorm:"not null;comment:'文件路径'"`
|
||||||
Ext string `gorm:"not null;default:'';comment:'文件扩展'"`
|
Ext string `gorm:"not null;default:'';comment:'文件扩展'"`
|
||||||
|
Hash string `gorm:"not null;default:'';comment:'文件hash'"`
|
||||||
Size int64 `gorm:"not null;default:0;comment:文件大小"`
|
Size int64 `gorm:"not null;default:0;comment:文件大小"`
|
||||||
IsDelete soft_delete.DeletedAt `gorm:"not null;default:0;softDelete:flag,DeletedAtField:DeleteTime;comment:'是否删除: 0=否, 1=是'"`
|
IsDelete soft_delete.DeletedAt `gorm:"not null;default:0;softDelete:flag,DeletedAtField:DeleteTime;comment:'是否删除: 0=否, 1=是'"`
|
||||||
CreateTime core.NullTime `gorm:"autoCreateTime;not null;comment:'创建时间'"`
|
CreateTime core.NullTime `gorm:"autoCreateTime;not null;comment:'创建时间'"`
|
||||||
@@ -26,8 +27,10 @@ type Album struct {
|
|||||||
// AlbumCate 相册分类实体
|
// AlbumCate 相册分类实体
|
||||||
type AlbumCate struct {
|
type AlbumCate struct {
|
||||||
ID uint `gorm:"primarykey;comment:'主键ID'"`
|
ID uint `gorm:"primarykey;comment:'主键ID'"`
|
||||||
|
AdminId uint `gorm:"not null;default:0;comment:'管理员ID'"`
|
||||||
|
|
||||||
Pid uint `gorm:"not null;default:0;comment:'父级ID'"`
|
Pid uint `gorm:"not null;default:0;comment:'父级ID'"`
|
||||||
Type int `gorm:"not null;default:10;comment:'文件类型: [10=图片, 20=视频]''"`
|
// Type int `gorm:"not null;default:10;comment:'文件类型: [10=图片, 20=视频]''"`
|
||||||
Name string `gorm:"not null;default:'';comment:'分类名称''"`
|
Name string `gorm:"not null;default:'';comment:'分类名称''"`
|
||||||
IsDelete soft_delete.DeletedAt `gorm:"not null;default:0;softDelete:flag,DeletedAtField:DeleteTime;comment:'是否删除: 0=否, 1=是'"`
|
IsDelete soft_delete.DeletedAt `gorm:"not null;default:0;softDelete:flag,DeletedAtField:DeleteTime;comment:'是否删除: 0=否, 1=是'"`
|
||||||
CreateTime core.NullTime `gorm:"autoCreateTime;not null;comment:'创建时间'"`
|
CreateTime core.NullTime `gorm:"autoCreateTime;not null;comment:'创建时间'"`
|
||||||
|
@@ -20,7 +20,7 @@ var StorageDriver = storageDriver{}
|
|||||||
// UploadFile 文件对象
|
// UploadFile 文件对象
|
||||||
type UploadFile struct {
|
type UploadFile struct {
|
||||||
Name string // 文件名称
|
Name string // 文件名称
|
||||||
Type int // 文件类型
|
// Type int // 文件类型
|
||||||
Size int64 // 文件大小
|
Size int64 // 文件大小
|
||||||
Ext string // 文件扩展
|
Ext string // 文件扩展
|
||||||
Uri string // 文件路径
|
Uri string // 文件路径
|
||||||
@@ -31,25 +31,34 @@ type UploadFile struct {
|
|||||||
type storageDriver struct{}
|
type storageDriver struct{}
|
||||||
|
|
||||||
// Upload 根据引擎类型上传文件
|
// Upload 根据引擎类型上传文件
|
||||||
func (sd storageDriver) Upload(file *multipart.FileHeader, folder string, fileType int) (uf *UploadFile, e error) {
|
func (sd storageDriver) Upload(file *multipart.FileHeader) (uf *UploadFile, e error) {
|
||||||
// TODO: engine默认local
|
// TODO: engine默认local
|
||||||
if e = sd.checkFile(file, fileType); e != nil {
|
|
||||||
|
fileExt := sd.getFileExt(file.Filename)
|
||||||
|
if fileExt == "" {
|
||||||
|
return nil, response.AssertArgumentError.SetMessage("文件类型错误!")
|
||||||
|
}
|
||||||
|
|
||||||
|
if e = sd.checkFile(file.Filename, file.Size); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
key := sd.buildSaveName(file)
|
var folder string = fileExt
|
||||||
|
|
||||||
|
saveName := sd.buildSaveName(file)
|
||||||
engine := "local"
|
engine := "local"
|
||||||
if engine == "local" {
|
if engine == "local" {
|
||||||
if e = sd.localUpload(file, key, folder); e != nil {
|
if e = sd.localUpload(file, folder, saveName); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
core.Logger.Errorf("storageDriver.Upload engine err: err=[unsupported engine]")
|
core.Logger.Errorf("storageDriver.Upload engine err: err=[unsupported engine]")
|
||||||
return nil, response.Failed.SetMessage(fmt.Sprintf("engine:%s 暂时不支持", engine))
|
return nil, response.Failed.SetMessage(fmt.Sprintf("engine:%s 暂时不支持", engine))
|
||||||
}
|
}
|
||||||
fileRelPath := path.Join(folder, key)
|
|
||||||
|
fileRelPath := path.Join(folder, saveName)
|
||||||
return &UploadFile{
|
return &UploadFile{
|
||||||
Name: file.Filename,
|
Name: file.Filename,
|
||||||
Type: fileType,
|
// Type: int(fileType),
|
||||||
Size: file.Size,
|
Size: file.Size,
|
||||||
Ext: strings.ToLower(strings.Replace(path.Ext(file.Filename), ".", "", 1)),
|
Ext: strings.ToLower(strings.Replace(path.Ext(file.Filename), ".", "", 1)),
|
||||||
Uri: fileRelPath,
|
Uri: fileRelPath,
|
||||||
@@ -58,7 +67,7 @@ func (sd storageDriver) Upload(file *multipart.FileHeader, folder string, fileTy
|
|||||||
}
|
}
|
||||||
|
|
||||||
// localUpload 本地上传 (临时方法)
|
// localUpload 本地上传 (临时方法)
|
||||||
func (sd storageDriver) localUpload(file *multipart.FileHeader, key string, folder string) (e error) {
|
func (sd storageDriver) localUpload(file *multipart.FileHeader, folder string, saveName string) (e error) {
|
||||||
// TODO: 临时方法,后续调整
|
// TODO: 临时方法,后续调整
|
||||||
// 映射目录
|
// 映射目录
|
||||||
directory := config.FileConfig.UploadDirectory
|
directory := config.FileConfig.UploadDirectory
|
||||||
@@ -70,8 +79,8 @@ func (sd storageDriver) localUpload(file *multipart.FileHeader, key string, fold
|
|||||||
}
|
}
|
||||||
defer src.Close()
|
defer src.Close()
|
||||||
// 文件信息
|
// 文件信息
|
||||||
savePath := path.Join(directory, folder, path.Dir(key))
|
savePath := path.Join(directory, folder, path.Dir(saveName))
|
||||||
saveFilePath := path.Join(directory, folder, key)
|
saveFilePath := path.Join(directory, folder, saveName)
|
||||||
// 创建目录
|
// 创建目录
|
||||||
err = os.MkdirAll(savePath, 0755)
|
err = os.MkdirAll(savePath, 0755)
|
||||||
if err != nil && !os.IsExist(err) {
|
if err != nil && !os.IsExist(err) {
|
||||||
@@ -94,6 +103,7 @@ func (sd storageDriver) localUpload(file *multipart.FileHeader, key string, fold
|
|||||||
"storageDriver.localUpload Copy err: file=[%s], err=[%+v]", saveFilePath, err)
|
"storageDriver.localUpload Copy err: file=[%s], err=[%+v]", saveFilePath, err)
|
||||||
return response.Failed.SetMessage("上传文件失败: " + err.Error())
|
return response.Failed.SetMessage("上传文件失败: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,35 +111,40 @@ func (sd storageDriver) localUpload(file *multipart.FileHeader, key string, fold
|
|||||||
func (sd storageDriver) buildSaveName(file *multipart.FileHeader) string {
|
func (sd storageDriver) buildSaveName(file *multipart.FileHeader) string {
|
||||||
name := file.Filename
|
name := file.Filename
|
||||||
ext := strings.ToLower(path.Ext(name))
|
ext := strings.ToLower(path.Ext(name))
|
||||||
date := time.Now().Format("20060201")
|
date := time.Now().Format("20060102")
|
||||||
return path.Join(date, util.ToolsUtil.MakeUuid()+ext)
|
return path.Join(date, util.ToolsUtil.MakeUuid()+ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkFile 文件验证
|
// getFileExt 获取文件扩展名
|
||||||
func (sd storageDriver) checkFile(file *multipart.FileHeader, fileType int) (e error) {
|
func (sd storageDriver) getFileExt(fileName string) string {
|
||||||
fileName := file.Filename
|
|
||||||
fileExt := strings.ToLower(strings.Replace(path.Ext(fileName), ".", "", 1))
|
fileExt := strings.ToLower(strings.Replace(path.Ext(fileName), ".", "", 1))
|
||||||
fileSize := file.Size
|
return fileExt
|
||||||
switch fileType {
|
}
|
||||||
case 10:
|
|
||||||
|
// checkFile 文件验证
|
||||||
|
func (sd storageDriver) checkFile(fileName string, fileSize int64) (e error) {
|
||||||
|
|
||||||
|
fileExt := sd.getFileExt(fileName)
|
||||||
|
|
||||||
|
if util.ToolsUtil.Contains(config.FileConfig.UploadImageExt, fileExt) {
|
||||||
// 图片文件
|
// 图片文件
|
||||||
if !util.ToolsUtil.Contains(config.FileConfig.UploadImageExt, fileExt) {
|
|
||||||
return response.Failed.SetMessage("不被支持的图片扩展: " + fileExt)
|
|
||||||
}
|
|
||||||
if fileSize > config.FileConfig.UploadImageSize {
|
if fileSize > config.FileConfig.UploadImageSize {
|
||||||
return response.Failed.SetMessage("上传图片不能超出限制: " + strconv.FormatInt(config.FileConfig.UploadImageSize/1024/1024, 10) + "M")
|
return response.Failed.SetMessage("上传图片不能超出限制: " + strconv.FormatInt(config.FileConfig.UploadImageSize/1024/1024, 10) + "M")
|
||||||
}
|
}
|
||||||
case 20:
|
} else if util.ToolsUtil.Contains(config.FileConfig.UploadVideoExt, fileExt) {
|
||||||
// 视频文件
|
// 视频文件
|
||||||
if !util.ToolsUtil.Contains(config.FileConfig.UploadVideoExt, fileExt) {
|
|
||||||
return response.Failed.SetMessage("不被支持的视频扩展: " + fileExt)
|
|
||||||
}
|
|
||||||
if fileSize > config.FileConfig.UploadVideoSize {
|
if fileSize > config.FileConfig.UploadVideoSize {
|
||||||
return response.Failed.SetMessage("上传视频不能超出限制: " + strconv.FormatInt(config.FileConfig.UploadVideoSize/1024/1024, 10) + "M")
|
return response.Failed.SetMessage("上传视频不能超出限制: " + strconv.FormatInt(config.FileConfig.UploadVideoSize/1024/1024, 10) + "M")
|
||||||
}
|
}
|
||||||
default:
|
} else if util.ToolsUtil.Contains(config.FileConfig.UploadFileExt, fileExt) {
|
||||||
|
// 文件
|
||||||
|
if fileSize > config.FileConfig.UploadFileSize {
|
||||||
|
return response.Failed.SetMessage("上传文件不能超出限制: " + strconv.FormatInt(config.FileConfig.UploadFileSize/1024/1024, 10) + "M")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
core.Logger.Errorf("storageDriver.checkFile fileType err: err=[unsupported fileType]")
|
core.Logger.Errorf("storageDriver.checkFile fileType err: err=[unsupported fileType]")
|
||||||
return response.Failed.SetMessage("上传文件类型错误")
|
return response.Failed.SetMessage("上传文件类型错误")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -9,8 +9,10 @@ type CommonUploadImageReq struct {
|
|||||||
//CommonAlbumListReq 相册文件列表参数
|
//CommonAlbumListReq 相册文件列表参数
|
||||||
type CommonAlbumListReq struct {
|
type CommonAlbumListReq struct {
|
||||||
Cid int `form:"cid,default=-1"` // 类目ID
|
Cid int `form:"cid,default=-1"` // 类目ID
|
||||||
Type int `form:"type" binding:"omitempty,oneof=10 20 30"` // 文件类型: [10=图片, 20=视频]
|
// Type int `form:"type" binding:"omitempty,oneof=10 20 30"` // 文件类型: [10=图片, 20=视频]
|
||||||
Name string `form:"name"` // 文件名称
|
Name string `form:"name"` // 文件名称
|
||||||
|
Ext []string `form:"ext[]"` // 文件扩展
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//CommonAlbumRenameReq 相册文件重命名参数
|
//CommonAlbumRenameReq 相册文件重命名参数
|
||||||
@@ -28,13 +30,14 @@ type CommonAlbumMoveReq struct {
|
|||||||
//CommonAlbumAddReq 相册文件新增参数
|
//CommonAlbumAddReq 相册文件新增参数
|
||||||
type CommonAlbumAddReq struct {
|
type CommonAlbumAddReq struct {
|
||||||
Cid uint `form:"cid" binding:"gte=0"` // 类目ID
|
Cid uint `form:"cid" binding:"gte=0"` // 类目ID
|
||||||
Aid uint `form:"aid" binding:"gte=0"` // 管理ID
|
AdminId uint `form:"admin_id" binding:"gte=0"` // 管理ID
|
||||||
Uid uint `form:"uid" binding:"gte=0"` // 用户ID
|
// Uid uint `form:"uid" binding:"gte=0"` // 用户ID
|
||||||
Type int `form:"type" binding:"oneof=10 20 30"` // 文件类型: [10=图片, 20=视频,30文件]
|
// Type int `form:"type" binding:"oneof=10 20 30"` // 文件类型: [10=图片, 20=视频,30文件]
|
||||||
Name string `form:"name"` // 文件名称
|
Name string `form:"name"` // 文件名称
|
||||||
Uri string `form:"uri"` // 文件路径
|
Uri string `form:"uri"` // 文件路径
|
||||||
Ext string `form:"ext"` // 文件扩展
|
Ext string `form:"ext"` // 文件扩展
|
||||||
Size int64 `form:"size"` // 文件大小
|
Size int64 `form:"size"` // 文件大小
|
||||||
|
Hash string `form:"hash"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//CommonAlbumDelReq 相册文件删除参数
|
//CommonAlbumDelReq 相册文件删除参数
|
||||||
@@ -44,14 +47,14 @@ type CommonAlbumDelReq struct {
|
|||||||
|
|
||||||
//CommonCateListReq 相册分类列表参数
|
//CommonCateListReq 相册分类列表参数
|
||||||
type CommonCateListReq struct {
|
type CommonCateListReq struct {
|
||||||
Type int `form:"type" binding:"omitempty,oneof=10 20 30"` // 分类类型: [10=图片,20=视频,30文件]
|
// Type int `form:"type" binding:"omitempty,oneof=10 20 30"` // 分类类型: [10=图片,20=视频,30文件]
|
||||||
Name string `form:"name"` // 分类名称
|
Name string `form:"name"` // 分类名称
|
||||||
}
|
}
|
||||||
|
|
||||||
//CommonCateAddReq 相册分类新增参数
|
//CommonCateAddReq 相册分类新增参数
|
||||||
type CommonCateAddReq struct {
|
type CommonCateAddReq struct {
|
||||||
Pid uint `form:"pid" binding:"gte=0"` // 父级ID
|
Pid uint `form:"pid" binding:"gte=0"` // 父级ID
|
||||||
Type int `form:"type" binding:"required,oneof=10 20 30"` // 分类类型: [10=图片,20=视频,30文件]
|
// Type int `form:"type" binding:"required,oneof=10 20 30"` // 分类类型: [10=图片,20=视频,30文件]
|
||||||
Name string `form:"name" binding:"required,min=1,max=30"` // 分类名称
|
Name string `form:"name" binding:"required,min=1,max=30"` // 分类名称
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,9 +73,9 @@ type CommonCateDelReq struct {
|
|||||||
type CommonUploadFileResp struct {
|
type CommonUploadFileResp struct {
|
||||||
ID uint `json:"id" structs:"id"` // 主键
|
ID uint `json:"id" structs:"id"` // 主键
|
||||||
Cid uint `json:"cid" structs:"cid"` // 类目ID
|
Cid uint `json:"cid" structs:"cid"` // 类目ID
|
||||||
Aid uint `json:"aid" structs:"aid"` // 管理ID
|
AdminId uint `json:"admin_id" structs:"admin_id"` // 管理ID
|
||||||
Uid uint `json:"uid" structs:"uid"` // 用户ID
|
Uid uint `json:"uid" structs:"uid"` // 用户ID
|
||||||
Type int `json:"type" structs:"type"` // 文件类型: [10=图片, 20=视频]
|
// Type int `json:"type" structs:"type"` // 文件类型: [10=图片, 20=视频]
|
||||||
Name string `json:"name" structs:"name"` // 文件名称
|
Name string `json:"name" structs:"name"` // 文件名称
|
||||||
Uri string `json:"url" structs:"url"` // 文件路径
|
Uri string `json:"url" structs:"url"` // 文件路径
|
||||||
Path string `json:"path" structs:"path"` // 访问地址
|
Path string `json:"path" structs:"path"` // 访问地址
|
||||||
|
@@ -14,22 +14,10 @@ import (
|
|||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IAlbumService interface {
|
|
||||||
AlbumList(page request.PageReq, listReq commonSchema.CommonAlbumListReq) (res response.PageResp, e error)
|
|
||||||
AlbumRename(id uint, name string) (e error)
|
|
||||||
AlbumMove(ids []uint, cid int) (e error)
|
|
||||||
AlbumAdd(addReq commonSchema.CommonAlbumAddReq) (res uint, e error)
|
|
||||||
AlbumDel(ids []uint) (e error)
|
|
||||||
CateList(listReq commonSchema.CommonCateListReq) (mapList []commonSchema.CommonCateListResp, e error)
|
|
||||||
CateAdd(addReq commonSchema.CommonCateAddReq) (e error)
|
|
||||||
CateRename(id uint, name string) (e error)
|
|
||||||
CateDel(id uint) (e error)
|
|
||||||
}
|
|
||||||
|
|
||||||
var AlbumService = NewAlbumService()
|
var AlbumService = NewAlbumService()
|
||||||
|
|
||||||
// NewAlbumService 初始化
|
// NewAlbumService 初始化
|
||||||
func NewAlbumService() IAlbumService {
|
func NewAlbumService() *albumService {
|
||||||
db := core.GetDB()
|
db := core.GetDB()
|
||||||
return &albumService{db: db}
|
return &albumService{db: db}
|
||||||
}
|
}
|
||||||
@@ -40,21 +28,29 @@ type albumService struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AlbumList 相册文件列表
|
// AlbumList 相册文件列表
|
||||||
func (albSrv albumService) AlbumList(page request.PageReq, listReq commonSchema.CommonAlbumListReq) (res response.PageResp, e error) {
|
func (albSrv albumService) AlbumList(adminId uint, page request.PageReq, listReq commonSchema.CommonAlbumListReq) (res response.PageResp, e error) {
|
||||||
|
|
||||||
// 分页信息
|
// 分页信息
|
||||||
limit := page.PageSize
|
limit := page.PageSize
|
||||||
offset := page.PageSize * (page.PageNo - 1)
|
offset := page.PageSize * (page.PageNo - 1)
|
||||||
// 查询
|
// 查询
|
||||||
albumModel := albSrv.db.Model(&common_model.Album{}).Where("is_delete = ?", 0)
|
albumModel := albSrv.db.Model(&common_model.Album{}).Where("is_delete = ?", 0)
|
||||||
|
|
||||||
|
albumModel = albumModel.Where("admin_id = ?", adminId)
|
||||||
|
|
||||||
if listReq.Cid > 0 {
|
if listReq.Cid > 0 {
|
||||||
albumModel = albumModel.Where("cid = ?", listReq.Cid)
|
albumModel = albumModel.Where("cid = ?", listReq.Cid)
|
||||||
}
|
}
|
||||||
if listReq.Name != "" {
|
if listReq.Name != "" {
|
||||||
albumModel = albumModel.Where("name like ?", "%"+listReq.Name+"%")
|
albumModel = albumModel.Where("name like ?", "%"+listReq.Name+"%")
|
||||||
}
|
}
|
||||||
if listReq.Type > 0 {
|
if len(listReq.Ext) > 0 {
|
||||||
albumModel = albumModel.Where("type = ?", listReq.Type)
|
albumModel = albumModel.Where("ext in ?", listReq.Ext)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if listReq.Type > 0 {
|
||||||
|
// albumModel = albumModel.Where("type = ?", listReq.Type)
|
||||||
|
// }
|
||||||
// 总数
|
// 总数
|
||||||
var count int64
|
var count int64
|
||||||
err := albumModel.Count(&count).Error
|
err := albumModel.Count(&count).Error
|
||||||
@@ -161,12 +157,14 @@ func (albSrv albumService) AlbumDel(ids []uint) (e error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CateList 相册分类列表
|
// CateList 相册分类列表
|
||||||
func (albSrv albumService) CateList(listReq commonSchema.CommonCateListReq) (mapList []commonSchema.CommonCateListResp, e error) {
|
func (albSrv albumService) CateList(adminId uint, listReq commonSchema.CommonCateListReq) (mapList []commonSchema.CommonCateListResp, e error) {
|
||||||
|
|
||||||
var cates []common_model.AlbumCate
|
var cates []common_model.AlbumCate
|
||||||
cateModel := albSrv.db.Where("is_delete = ?", 0).Order("id desc")
|
cateModel := albSrv.db.Where("is_delete = ?", 0).Order("id desc")
|
||||||
if listReq.Type > 0 {
|
// if listReq.Type > 0 {
|
||||||
cateModel = cateModel.Where("type = ?", listReq.Type)
|
// cateModel = cateModel.Where("type = ?", listReq.Type)
|
||||||
}
|
// }
|
||||||
|
cateModel = cateModel.Where("admin_id = ?", adminId)
|
||||||
if listReq.Name != "" {
|
if listReq.Name != "" {
|
||||||
cateModel = cateModel.Where("name like ?", "%"+listReq.Name+"%")
|
cateModel = cateModel.Where("name like ?", "%"+listReq.Name+"%")
|
||||||
}
|
}
|
||||||
@@ -180,9 +178,12 @@ func (albSrv albumService) CateList(listReq commonSchema.CommonCateListReq) (map
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CateAdd 分类新增
|
// CateAdd 分类新增
|
||||||
func (albSrv albumService) CateAdd(addReq commonSchema.CommonCateAddReq) (e error) {
|
func (albSrv albumService) CateAdd(adminId uint, addReq commonSchema.CommonCateAddReq) (e error) {
|
||||||
|
|
||||||
var cate common_model.AlbumCate
|
var cate common_model.AlbumCate
|
||||||
convert_util.Copy(&cate, addReq)
|
convert_util.Copy(&cate, addReq)
|
||||||
|
cate.AdminId = adminId
|
||||||
|
|
||||||
err := albSrv.db.Create(&cate).Error
|
err := albSrv.db.Create(&cate).Error
|
||||||
e = response.CheckErr(err, "Cate添加失败")
|
e = response.CheckErr(err, "Cate添加失败")
|
||||||
return
|
return
|
||||||
|
@@ -1,18 +1,16 @@
|
|||||||
package commonService
|
package commonService
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
|
"time"
|
||||||
|
|
||||||
"x_admin/plugin"
|
"x_admin/plugin"
|
||||||
"x_admin/schema/commonSchema"
|
"x_admin/schema/commonSchema"
|
||||||
|
"x_admin/util"
|
||||||
"x_admin/util/convert_util"
|
"x_admin/util/convert_util"
|
||||||
)
|
)
|
||||||
|
|
||||||
type IUploadService interface {
|
|
||||||
UploadImage(file *multipart.FileHeader, cid uint, aid uint) (res commonSchema.CommonUploadFileResp, e error)
|
|
||||||
UploadVideo(file *multipart.FileHeader, cid uint, aid uint) (res commonSchema.CommonUploadFileResp, e error)
|
|
||||||
}
|
|
||||||
|
|
||||||
var UploadService = NewUploadService()
|
var UploadService = NewUploadService()
|
||||||
|
|
||||||
// NewUploadService 初始化
|
// NewUploadService 初始化
|
||||||
@@ -23,26 +21,34 @@ func NewUploadService() *uploadService {
|
|||||||
// uploadService 上传服务实现类
|
// uploadService 上传服务实现类
|
||||||
type uploadService struct{}
|
type uploadService struct{}
|
||||||
|
|
||||||
// UploadImage 上传图片
|
// UploadFile 上传
|
||||||
func (upSrv uploadService) UploadImage(file *multipart.FileHeader, cid uint, aid uint) (res commonSchema.CommonUploadFileResp, e error) {
|
// cid 分类id
|
||||||
return upSrv.uploadFile(file, "image", 10, cid, aid)
|
// AdminId 用户id
|
||||||
}
|
func (upSrv uploadService) UploadFile(file *multipart.FileHeader, cid uint, AdminId uint) (res commonSchema.CommonUploadFileResp, e error) {
|
||||||
|
|
||||||
// UploadVideo 上传视频
|
|
||||||
func (upSrv uploadService) UploadVideo(file *multipart.FileHeader, cid uint, aid uint) (res commonSchema.CommonUploadFileResp, e error) {
|
|
||||||
return upSrv.uploadFile(file, "video", 20, cid, aid)
|
|
||||||
}
|
|
||||||
|
|
||||||
// uploadFile 上传文件
|
|
||||||
func (upSrv uploadService) uploadFile(file *multipart.FileHeader, folder string, fileType int, cid uint, aid uint) (res commonSchema.CommonUploadFileResp, e error) {
|
|
||||||
var upRes *plugin.UploadFile
|
var upRes *plugin.UploadFile
|
||||||
if upRes, e = plugin.StorageDriver.Upload(file, folder, fileType); e != nil {
|
if upRes, e = plugin.StorageDriver.Upload(file); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var startTime = time.Now()
|
||||||
|
|
||||||
|
// 计算文件MD5
|
||||||
|
md5, e := util.ToolsUtil.GetFileMD5(file)
|
||||||
|
if e != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var endTime = time.Now()
|
||||||
|
var costTime = endTime.UnixNano() - startTime.UnixNano()
|
||||||
|
// 毫秒
|
||||||
|
costTime = costTime / 1000000
|
||||||
|
|
||||||
|
fmt.Printf("\n文件大小%d , md5时间: %d毫秒\n", file.Size, costTime)
|
||||||
|
|
||||||
var addReq commonSchema.CommonAlbumAddReq
|
var addReq commonSchema.CommonAlbumAddReq
|
||||||
convert_util.Copy(&addReq, upRes)
|
convert_util.Copy(&addReq, upRes)
|
||||||
addReq.Aid = aid
|
addReq.AdminId = AdminId //管理员
|
||||||
addReq.Cid = cid
|
addReq.Cid = cid // 分类id
|
||||||
|
addReq.Hash = md5
|
||||||
|
|
||||||
var albumId uint
|
var albumId uint
|
||||||
if albumId, e = AlbumService.AlbumAdd(addReq); e != nil {
|
if albumId, e = AlbumService.AlbumAdd(addReq); e != nil {
|
||||||
return
|
return
|
||||||
|
@@ -4,8 +4,10 @@ import (
|
|||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"io"
|
||||||
"math"
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"mime/multipart"
|
||||||
"os"
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -45,6 +47,20 @@ func (tu toolsUtil) MakeMd5(data string) string {
|
|||||||
return hex.EncodeToString(sum[:])
|
return hex.EncodeToString(sum[:])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetFileMD5 获取文件MD5
|
||||||
|
func (tu toolsUtil) GetFileMD5(file *multipart.FileHeader) (string, error) {
|
||||||
|
f, err := file.Open()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
hash := md5.New()
|
||||||
|
if _, err := io.Copy(hash, f); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return hex.EncodeToString(hash.Sum(nil)), nil
|
||||||
|
}
|
||||||
|
|
||||||
// MakeToken 生成唯一Token
|
// MakeToken 生成唯一Token
|
||||||
func (tu toolsUtil) MakeToken() string {
|
func (tu toolsUtil) MakeToken() string {
|
||||||
ms := time.Now().UnixMilli()
|
ms := time.Now().UnixMilli()
|
||||||
|
Reference in New Issue
Block a user