mirror of
https://gitee.com/xiangheng/x_admin.git
synced 2025-10-07 17:11:05 +08:00
优化素材中心
This commit is contained in:
@@ -15,34 +15,34 @@
|
|||||||
"outdated": "pnpm outdated"
|
"outdated": "pnpm outdated"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.3.1",
|
"@element-plus/icons-vue": "^2.3.2",
|
||||||
"@highlightjs/vue-plugin": "^2.1.0",
|
"@highlightjs/vue-plugin": "^2.1.0",
|
||||||
"@logicflow/core": "^2.0.16",
|
"@logicflow/core": "^2.1.2",
|
||||||
"@logicflow/extension": "^2.0.21",
|
"@logicflow/extension": "^2.1.3",
|
||||||
"@vueuse/core": "^13.5.0",
|
"@vueuse/core": "^13.5.0",
|
||||||
"@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.8.4",
|
"axios": "^1.11.0",
|
||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"css-color-function": "^1.3.3",
|
"css-color-function": "^1.3.3",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.18",
|
||||||
"echarts": "^5.6.0",
|
"echarts": "^5.6.0",
|
||||||
"element-plus": "^2.10.4",
|
"element-plus": "^2.11.1",
|
||||||
"highlight.js": "^11.11.1",
|
"highlight.js": "^11.11.1",
|
||||||
"lodash-es": "^4.17.21",
|
"lodash-es": "^4.17.21",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"query-string": "^9.1.1",
|
"query-string": "^9.2.2",
|
||||||
"rolldown-vite": "^7.0.9",
|
"rolldown-vite": "^7.1.9",
|
||||||
"spark-md5": "^3.0.2",
|
"spark-md5": "^3.0.2",
|
||||||
"vform3-builds": "^3.0.10",
|
"vform3-builds": "^3.0.10",
|
||||||
"vue": "^3.5.16",
|
"vue": "^3.5.21",
|
||||||
"vue-clipboard3": "^2.0.0",
|
"vue-clipboard3": "^2.0.0",
|
||||||
"vue-echarts": "^7.0.3",
|
"vue-echarts": "^7.0.3",
|
||||||
"vue-router": "^4.5.1",
|
"vue-router": "^4.5.1",
|
||||||
"vue3-video-play": "^1.3.2",
|
"vue3-video-play": "^1.3.2",
|
||||||
"vuedraggable": "^4.1.0",
|
"vuedraggable": "^4.1.0",
|
||||||
"vxe-table": "^4.14.4"
|
"vxe-table": "^4.16.11"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rushstack/eslint-patch": "^1.11.0",
|
"@rushstack/eslint-patch": "^1.11.0",
|
||||||
@@ -50,10 +50,10 @@
|
|||||||
"@types/node": "^22.14.1",
|
"@types/node": "^22.14.1",
|
||||||
"@types/nprogress": "^0.2.3",
|
"@types/nprogress": "^0.2.3",
|
||||||
"@vitejs/plugin-vue": "^6.0.0",
|
"@vitejs/plugin-vue": "^6.0.0",
|
||||||
"@vitejs/plugin-vue-jsx": "^5.0.1",
|
"@vitejs/plugin-vue-jsx": "^5.1.1",
|
||||||
"@vue/eslint-config-prettier": "^9.0.0",
|
"@vue/eslint-config-prettier": "^9.0.0",
|
||||||
"@vue/eslint-config-typescript": "^13.0.0",
|
"@vue/eslint-config-typescript": "^13.0.0",
|
||||||
"@vue/tsconfig": "^0.7.0",
|
"@vue/tsconfig": "^0.8.1",
|
||||||
"autoprefixer": "^10.4.21",
|
"autoprefixer": "^10.4.21",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^8.57.0",
|
||||||
"eslint-plugin-vue": "^9.27.0",
|
"eslint-plugin-vue": "^9.27.0",
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
"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",
|
||||||
"vue-tsc": "^3.0.1"
|
"vue-tsc": "^3.0.6"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": {
|
||||||
"vite": "npm:rolldown-vite@latest"
|
"vite": "npm:rolldown-vite@latest"
|
||||||
|
@@ -35,7 +35,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts">
|
||||||
// import { Sketch } from 'vue-color'
|
// import { Sketch } from 'vue-color'
|
||||||
// import ColorFill from './icon/ColorFill.vue'
|
// import ColorFill from './icon/ColorFill.vue'
|
||||||
// import ColorText from './icon/ColorText.vue'
|
// import ColorText from './icon/ColorText.vue'
|
||||||
@@ -51,7 +51,7 @@ import AreaSelect from './icon/AreaSelect.vue'
|
|||||||
let fileHandle
|
let fileHandle
|
||||||
|
|
||||||
async function getFile() {
|
async function getFile() {
|
||||||
;[fileHandle] = await window.showOpenFilePicker()
|
;[fileHandle] = await (window as any).showOpenFilePicker()
|
||||||
console.log('fileHandle', fileHandle)
|
console.log('fileHandle', fileHandle)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,6 +149,8 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
$_changeLineType(value) {
|
$_changeLineType(value) {
|
||||||
|
console.log('value', value)
|
||||||
|
|
||||||
const { lf, activeEdges } = this.$props
|
const { lf, activeEdges } = this.$props
|
||||||
const { graphModel } = lf
|
const { graphModel } = lf
|
||||||
lf.setDefaultEdgeType(value)
|
lf.setDefaultEdgeType(value)
|
||||||
|
@@ -34,6 +34,7 @@ import UserTask from './UserTask.vue'
|
|||||||
import FieldAuth from './FieldAuth.vue'
|
import FieldAuth from './FieldAuth.vue'
|
||||||
import Gateway from './Gateway.vue'
|
import Gateway from './Gateway.vue'
|
||||||
import type { NodeType, PropertiesType, FormFieldListType, FieldListType } from './property.type'
|
import type { NodeType, PropertiesType, FormFieldListType, FieldListType } from './property.type'
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'PropertyPanel'
|
name: 'PropertyPanel'
|
||||||
})
|
})
|
||||||
|
@@ -22,13 +22,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
// Importing necessary functions and components
|
|
||||||
import { ref, onMounted, useTemplateRef } from 'vue'
|
import { ref, onMounted, useTemplateRef } from 'vue'
|
||||||
import LogicFlow from '@logicflow/core'
|
import { LogicFlow } from '@logicflow/core'
|
||||||
|
|
||||||
import { SelectionSelect, Menu, BpmnElement, MiniMap } from '@logicflow/extension'
|
import { SelectionSelect, Menu, BpmnElement, MiniMap } from '@logicflow/extension'
|
||||||
import type { NodeType, PropertiesType } from './PropertyPanel/property.type'
|
import type { NodeType, PropertiesType } from './PropertyPanel/property.type'
|
||||||
// import '@logicflow/core/dist/style/index.css'
|
|
||||||
// import '@logicflow/extension/lib/style/index.css'
|
|
||||||
import '@logicflow/core/lib/style/index.css'
|
import '@logicflow/core/lib/style/index.css'
|
||||||
import '@logicflow/extension/lib/style/index.css'
|
import '@logicflow/extension/lib/style/index.css'
|
||||||
|
|
||||||
@@ -57,7 +56,7 @@ const props = defineProps({
|
|||||||
})
|
})
|
||||||
|
|
||||||
// Define refs for reactive data and component references
|
// Define refs for reactive data and component references
|
||||||
const lf = ref(null) // Reference to LogicFlow instance
|
const lf = ref<LogicFlow>(null) // Reference to LogicFlow instance
|
||||||
const activeEdges = ref([]) // Reactive array for active edges
|
const activeEdges = ref([]) // Reactive array for active edges
|
||||||
const diagramRef = useTemplateRef<HTMLInputElement>('diagramRef') // Reference to the diagram container
|
const diagramRef = useTemplateRef<HTMLInputElement>('diagramRef') // Reference to the diagram container
|
||||||
const PropertyPanelRef = useTemplateRef<InstanceType<typeof PropertyPanel>>('PropertyPanelRef') // Reference to the PropertyPanel component
|
const PropertyPanelRef = useTemplateRef<InstanceType<typeof PropertyPanel>>('PropertyPanelRef') // Reference to the PropertyPanel component
|
||||||
@@ -69,15 +68,9 @@ onMounted(() => {
|
|||||||
|
|
||||||
// Function to initialize LogicFlow
|
// Function to initialize LogicFlow
|
||||||
function initLogicFlow(data) {
|
function initLogicFlow(data) {
|
||||||
// 引入框选插件
|
|
||||||
// LogicFlow.use(SelectionSelect)
|
|
||||||
// LogicFlow.use(Menu)
|
|
||||||
// LogicFlow.use(BpmnElement)
|
|
||||||
// LogicFlow.use(MiniMap)
|
|
||||||
// Creating a new LogicFlow instance
|
|
||||||
const logicFlowInstance = new LogicFlow({
|
const logicFlowInstance = new LogicFlow({
|
||||||
plugins: [SelectionSelect, Menu, MiniMap, BpmnElement],
|
plugins: [SelectionSelect, Menu, MiniMap, BpmnElement],
|
||||||
container: diagramRef.value, // Setting the container where LogicFlow will be rendered
|
container: diagramRef.value,
|
||||||
overlapMode: 1,
|
overlapMode: 1,
|
||||||
// allowResize: true,
|
// allowResize: true,
|
||||||
autoWrap: true,
|
autoWrap: true,
|
||||||
@@ -106,7 +99,7 @@ function initLogicFlow(data) {
|
|||||||
|
|
||||||
// Setting default edge type and rendering initial data
|
// Setting default edge type and rendering initial data
|
||||||
logicFlowInstance.setDefaultEdgeType('pro-polyline')
|
logicFlowInstance.setDefaultEdgeType('pro-polyline')
|
||||||
logicFlowInstance.extension.menu?.addMenuConfig({
|
;(logicFlowInstance.extension.menu as Menu).addMenuConfig({
|
||||||
nodeMenu: [
|
nodeMenu: [
|
||||||
{
|
{
|
||||||
text: '属性配置',
|
text: '属性配置',
|
||||||
@@ -117,14 +110,14 @@ function initLogicFlow(data) {
|
|||||||
]
|
]
|
||||||
})
|
})
|
||||||
logicFlowInstance.render(data)
|
logicFlowInstance.render(data)
|
||||||
logicFlowInstance.extension.miniMap?.show()
|
;(logicFlowInstance.extension.miniMap as MiniMap).show()
|
||||||
// Assigning the LogicFlow instance to the 'lf' ref
|
// Assigning the LogicFlow instance to the 'lf' ref
|
||||||
lf.value = logicFlowInstance
|
lf.value = logicFlowInstance
|
||||||
|
|
||||||
// Event listener for node clicks
|
// Event listener for node clicks
|
||||||
lf.value.on('node:dbclick', (e) => {
|
lf.value.on('node:dbclick', (e) => {
|
||||||
console.log('dbclick on node', e.data, props.fieldList)
|
console.log('dbclick on node', e.data, props.fieldList)
|
||||||
PropertyPanelRef.value.open(e.data, props.fieldList)
|
PropertyPanelRef.value.open(e.data as NodeType, props.fieldList)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,10 +135,7 @@ function setProperties(node: NodeType, item: PropertiesType) {
|
|||||||
|
|
||||||
lf.value.setProperties(node.id, item)
|
lf.value.setProperties(node.id, item)
|
||||||
}
|
}
|
||||||
// function setZIndex(node, type) {
|
|
||||||
// lf.value.setElementZIndex(node.id, type)
|
|
||||||
// }
|
|
||||||
// Function to import data into the LogicFlow instance
|
|
||||||
function importData(text) {
|
function importData(text) {
|
||||||
lf.value.renderRawData(text)
|
lf.value.renderRawData(text)
|
||||||
}
|
}
|
||||||
@@ -182,9 +172,9 @@ async function getData() {
|
|||||||
formData: any
|
formData: any
|
||||||
treeToList: any
|
treeToList: any
|
||||||
}>((resolve, reject) => {
|
}>((resolve, reject) => {
|
||||||
const data = lf.value.getGraphData()
|
const data: any = lf.value.getGraphData()
|
||||||
const nodes = data.nodes
|
const nodes = data?.nodes || []
|
||||||
const edges = data.edges
|
const edges = data?.edges || []
|
||||||
|
|
||||||
let haveMoreChildNode = false
|
let haveMoreChildNode = false
|
||||||
const sourceNodeIdSum = {} // Node ID -> child nodes mapping
|
const sourceNodeIdSum = {} // Node ID -> child nodes mapping
|
||||||
|
@@ -58,5 +58,6 @@ export default defineComponent({
|
|||||||
<style>
|
<style>
|
||||||
.svg-icon-container {
|
.svg-icon-container {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
line-height: 1;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,14 +1,29 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="file-item relative" :style="{ height: fileSize, width: fileSize }">
|
<div class="file-item relative" :style="{ height: fileSize, width: fileSize }">
|
||||||
<el-image class="image" v-if="type == 'image'" fit="contain" lazy :src="uri"></el-image>
|
<el-image
|
||||||
<video class="video" v-else-if="type == 'video'" :src="uri"></video>
|
class="image"
|
||||||
|
v-if="fileType == 'image'"
|
||||||
|
fit="contain"
|
||||||
|
lazy
|
||||||
|
:src="uri"
|
||||||
|
></el-image>
|
||||||
|
<video class="video" v-else-if="fileType == 'video'" :src="uri"></video>
|
||||||
<div
|
<div
|
||||||
v-if="type == 'video'"
|
v-if="fileType == 'video'"
|
||||||
class="absolute left-1/2 top-1/2 translate-x-[-50%] translate-y-[-50%] rounded-full w-5 h-5 flex justify-center items-center bg-[rgba(0,0,0,0.3)]"
|
class="absolute left-1/2 top-1/2 rounded-full w-[30px] h-[30px] flex justify-center items-center bg-[rgba(0,0,0,0.3)]"
|
||||||
|
style="transform: translate(-50%, -50%)"
|
||||||
>
|
>
|
||||||
<icon name="el-icon-CaretRight" :size="18" color="#fff" />
|
<icon name="el-icon-CaretRight" :size="18" color="#fff" />
|
||||||
</div>
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="fileType == 'audio'"
|
||||||
|
class="absolute left-1/2 top-1/2 rounded-full w-[30px] h-[30px] flex justify-center items-center bg-[rgba(0,0,0,0.3)]"
|
||||||
|
style="transform: translate(-50%, -50%)"
|
||||||
|
>
|
||||||
|
<icon name="el-icon-CaretRight" :size="16" color="#fff" />
|
||||||
|
</div>
|
||||||
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -16,6 +31,8 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
|
import { GetFileType } from '@/enums/fileEnums'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
props: {
|
props: {
|
||||||
// 图片地址
|
// 图片地址
|
||||||
@@ -35,16 +52,10 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
emits: ['close'],
|
emits: ['close'],
|
||||||
computed: {
|
computed: {
|
||||||
type() {
|
fileType() {
|
||||||
const imageExt = ['jpg', 'jpeg', 'png', 'gif', 'bmp']
|
const fileType = GetFileType(this.uri)
|
||||||
const videoExt = ['mp4', 'avi', 'mov']
|
|
||||||
if (imageExt.includes(this.ext)) {
|
return fileType
|
||||||
return 'image'
|
|
||||||
}
|
|
||||||
if (videoExt.includes(this.ext)) {
|
|
||||||
return 'video'
|
|
||||||
}
|
|
||||||
return 'file'
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@@ -85,8 +85,8 @@ export function useCate() {
|
|||||||
// 处理文件的钩子函数
|
// 处理文件的钩子函数
|
||||||
export function useFile(
|
export function useFile(
|
||||||
cateId: Ref<string | number>,
|
cateId: Ref<string | number>,
|
||||||
ext: string[],
|
ext: Ref<string[]>,
|
||||||
limit: Ref<number>,
|
limit: number,
|
||||||
size: number
|
size: number
|
||||||
) {
|
) {
|
||||||
const tableRef = shallowRef()
|
const tableRef = shallowRef()
|
||||||
@@ -99,6 +99,7 @@ export function useFile(
|
|||||||
ext: ext,
|
ext: ext,
|
||||||
cid: cateId
|
cid: cateId
|
||||||
})
|
})
|
||||||
|
|
||||||
const { pager, getLists, resetPage } = usePaging({
|
const { pager, getLists, resetPage } = usePaging({
|
||||||
fetchFun: fileList,
|
fetchFun: fileList,
|
||||||
params: fileParams,
|
params: fileParams,
|
||||||
@@ -141,8 +142,8 @@ export function useFile(
|
|||||||
select.value.splice(index, 1)
|
select.value.splice(index, 1)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (select.value.length == limit.value) {
|
if (select.value.length == limit) {
|
||||||
if (limit.value == 1) {
|
if (limit == 1) {
|
||||||
select.value = []
|
select.value = []
|
||||||
select.value.push(item)
|
select.value.push(item)
|
||||||
return
|
return
|
||||||
@@ -157,7 +158,7 @@ export function useFile(
|
|||||||
select.value = []
|
select.value = []
|
||||||
}
|
}
|
||||||
|
|
||||||
const cancelSelete = (id: number) => {
|
const cancelSelect = (id: number) => {
|
||||||
select.value = select.value.filter((item: any) => item.id != id)
|
select.value = select.value.filter((item: any) => item.id != id)
|
||||||
}
|
}
|
||||||
const selectItems = (items: any[]) => {
|
const selectItems = (items: any[]) => {
|
||||||
@@ -194,7 +195,7 @@ export function useFile(
|
|||||||
batchFileMove,
|
batchFileMove,
|
||||||
selectFile,
|
selectFile,
|
||||||
clearSelect,
|
clearSelect,
|
||||||
cancelSelete,
|
cancelSelect,
|
||||||
selectAll,
|
selectAll,
|
||||||
selectItems,
|
selectItems,
|
||||||
handleFileRename
|
handleFileRename
|
||||||
|
@@ -32,7 +32,7 @@
|
|||||||
v-if="data.id > 0"
|
v-if="data.id > 0"
|
||||||
:hide-on-click="false"
|
:hide-on-click="false"
|
||||||
>
|
>
|
||||||
<span class="muted m-r-10">···</span>
|
<span class="p-1 mr-[5px]">···</span>
|
||||||
<template #dropdown>
|
<template #dropdown>
|
||||||
<el-dropdown-menu>
|
<el-dropdown-menu>
|
||||||
<popover-input
|
<popover-input
|
||||||
@@ -67,12 +67,12 @@
|
|||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-center p-2 border-t border-br">
|
<div class="flex justify-center pt-2 border-t border-br">
|
||||||
<popover-input
|
<popover-input
|
||||||
v-perms="['admin:common:album:cateAdd']"
|
v-perms="['admin:common:album:cateAdd']"
|
||||||
@confirm="handleAddCate"
|
@confirm="handleAddCate"
|
||||||
size="default"
|
size="default"
|
||||||
width="400px"
|
width="500px"
|
||||||
:limit="20"
|
:limit="20"
|
||||||
show-limit
|
show-limit
|
||||||
teleported
|
teleported
|
||||||
@@ -82,19 +82,22 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="material__center flex flex-col">
|
<div class="material__center flex flex-col">
|
||||||
<div class="operate-btn flex">
|
<el-tabs
|
||||||
<div class="flex-1 flex">
|
v-if="mode == 'page' && defaultFileType == 'all'"
|
||||||
<upload
|
v-model="activeFileType"
|
||||||
v-perms="['admin:common:upload:image']"
|
@tab-change="handleTabChange"
|
||||||
class="mr-3"
|
|
||||||
:data="{ cid: cateId }"
|
|
||||||
:ext="ext"
|
|
||||||
:show-progress="true"
|
|
||||||
@change="refresh"
|
|
||||||
>
|
>
|
||||||
<el-button type="primary">本地上传</el-button>
|
<el-tab-pane
|
||||||
</upload>
|
v-for="item in FileTabsMap"
|
||||||
</div>
|
:label="item.name"
|
||||||
|
:name="item.fileType"
|
||||||
|
:key="item.fileType"
|
||||||
|
>
|
||||||
|
</el-tab-pane>
|
||||||
|
</el-tabs>
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<div class="operate-btn flex">
|
||||||
|
<div class="flex-1 flex"></div>
|
||||||
<el-input
|
<el-input
|
||||||
class="w-60"
|
class="w-60"
|
||||||
placeholder="请输入名称"
|
placeholder="请输入名称"
|
||||||
@@ -109,6 +112,17 @@
|
|||||||
</el-button>
|
</el-button>
|
||||||
</template>
|
</template>
|
||||||
</el-input>
|
</el-input>
|
||||||
|
<upload
|
||||||
|
v-perms="['admin:common:upload:file']"
|
||||||
|
class="ml-3"
|
||||||
|
:data="{ cid: cateId }"
|
||||||
|
:ext="ext"
|
||||||
|
:show-progress="true"
|
||||||
|
@change="refresh"
|
||||||
|
>
|
||||||
|
<el-button type="primary">本地上传</el-button>
|
||||||
|
</upload>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="material-center__content flex flex-col flex-1 mb-1 min-h-0">
|
<div class="material-center__content flex flex-col flex-1 mb-1 min-h-0">
|
||||||
@@ -127,7 +141,6 @@
|
|||||||
<file-item
|
<file-item
|
||||||
:uri="row.uri"
|
:uri="row.uri"
|
||||||
file-size="50px"
|
file-size="50px"
|
||||||
:ext="row.ext"
|
|
||||||
@click.stop="handlePreview(row.uri)"
|
@click.stop="handlePreview(row.uri)"
|
||||||
></file-item>
|
></file-item>
|
||||||
</template>
|
</template>
|
||||||
@@ -140,9 +153,9 @@
|
|||||||
</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="size" min-width="100"> </el-table-column>
|
||||||
<el-table-column label="格式" prop="ext" min-width="100"></el-table-column>
|
<el-table-column label="格式" prop="ext" min-width="80"></el-table-column>
|
||||||
|
|
||||||
<el-table-column prop="createTime" label="上传时间" min-width="100" />
|
<el-table-column prop="createTime" label="上传时间" min-width="160" />
|
||||||
<el-table-column label="操作" width="150" fixed="right">
|
<el-table-column label="操作" width="150" fixed="right">
|
||||||
<template #default="{ row }">
|
<template #default="{ row }">
|
||||||
<div class="inline-block" v-perms="['admin:common:album:albumRename']">
|
<div class="inline-block" v-perms="['admin:common:album:albumRename']">
|
||||||
@@ -150,7 +163,7 @@
|
|||||||
@confirm="handleFileRename($event, row.id)"
|
@confirm="handleFileRename($event, row.id)"
|
||||||
size="default"
|
size="default"
|
||||||
:value="row.name"
|
:value="row.name"
|
||||||
width="400px"
|
width="500px"
|
||||||
:limit="50"
|
:limit="50"
|
||||||
show-limit
|
show-limit
|
||||||
teleported
|
teleported
|
||||||
@@ -175,27 +188,10 @@
|
|||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div
|
|
||||||
class="flex flex-1 justify-center items-center"
|
|
||||||
v-if="!pager.loading && !pager.lists.length"
|
|
||||||
>
|
|
||||||
暂无数据~
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="material-center__footer flex justify-between items-center mt-2">
|
<div class="material-center__footer flex justify-between items-center mt-2">
|
||||||
<div class="flex">
|
<div class="flex">
|
||||||
<template v-if="mode == 'page'">
|
<template v-if="mode == 'page'">
|
||||||
<!-- <span class="mr-3">
|
|
||||||
<el-checkbox
|
|
||||||
:disabled="!pager.lists.length"
|
|
||||||
v-model="isCheckAll"
|
|
||||||
@change="selectAll"
|
|
||||||
:indeterminate="isIndeterminate"
|
|
||||||
>
|
|
||||||
当页全选
|
|
||||||
</el-checkbox>
|
|
||||||
</span> -->
|
|
||||||
<el-button
|
<el-button
|
||||||
v-perms="['admin:common:album:albumDel']"
|
v-perms="['admin:common:album:albumDel']"
|
||||||
:disabled="!select.length"
|
:disabled="!select.length"
|
||||||
@@ -206,9 +202,9 @@
|
|||||||
<popup
|
<popup
|
||||||
v-perms="['admin:common:album:albumMove']"
|
v-perms="['admin:common:album:albumMove']"
|
||||||
class="ml-3 inline"
|
class="ml-3 inline"
|
||||||
@confirm="batchFileMove"
|
|
||||||
:disabled="!select.length"
|
:disabled="!select.length"
|
||||||
title="移动文件"
|
title="移动文件"
|
||||||
|
@confirm="batchFileMove"
|
||||||
>
|
>
|
||||||
<template #trigger>
|
<template #trigger>
|
||||||
<el-button :disabled="!select.length">移动</el-button>
|
<el-button :disabled="!select.length">移动</el-button>
|
||||||
@@ -246,12 +242,8 @@
|
|||||||
<ul class="select-lists flex flex-col p-t-3">
|
<ul class="select-lists flex flex-col p-t-3">
|
||||||
<li class="mb-4" v-for="item in select" :key="item.id">
|
<li class="mb-4" v-for="item in select" :key="item.id">
|
||||||
<div class="select-item">
|
<div class="select-item">
|
||||||
<del-wrap @close="cancelSelete(item.id)">
|
<del-wrap @close="cancelSelect(item.id)">
|
||||||
<file-item
|
<file-item :uri="item.uri" file-size="100px"></file-item>
|
||||||
:uri="item.uri"
|
|
||||||
file-size="100px"
|
|
||||||
:ext="item.ext"
|
|
||||||
></file-item>
|
|
||||||
</del-wrap>
|
</del-wrap>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
@@ -264,29 +256,22 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, toRefs, ref, watch } from 'vue'
|
import { FileTabsMap } from '@/enums/fileEnums'
|
||||||
import type { PropType } from 'vue'
|
import { onMounted, ref, watch, computed } from 'vue'
|
||||||
|
import { FileExt } from '@/enums/fileEnums'
|
||||||
|
|
||||||
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'
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
fileSize: {
|
|
||||||
type: String,
|
|
||||||
default: '100px'
|
|
||||||
},
|
|
||||||
limit: {
|
limit: {
|
||||||
type: Number,
|
type: Number,
|
||||||
default: 1
|
default: 1
|
||||||
},
|
},
|
||||||
ext: {
|
defaultFileType: {
|
||||||
type: Array as PropType<string[]>,
|
type: String,
|
||||||
default: () => []
|
default: 'all'
|
||||||
},
|
},
|
||||||
// type: {
|
|
||||||
// type: String,
|
|
||||||
// default: 'image'
|
|
||||||
// },
|
|
||||||
mode: {
|
mode: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'picker'
|
default: 'picker'
|
||||||
@@ -297,20 +282,8 @@ const props = defineProps({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
const emit = defineEmits(['change'])
|
const emit = defineEmits(['change'])
|
||||||
const { limit } = toRefs(props)
|
// const { limit } = toRefs(props)
|
||||||
// const typeValue = computed<number>(() => {
|
|
||||||
// switch (props.type) {
|
|
||||||
// case 'image':
|
|
||||||
// return 10
|
|
||||||
// case 'video':
|
|
||||||
// return 20
|
|
||||||
// case 'file':
|
|
||||||
// return 30
|
|
||||||
// default:
|
|
||||||
// return 0
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// const visible: Ref<boolean> = inject('visible')
|
|
||||||
const previewUrl = ref('')
|
const previewUrl = ref('')
|
||||||
const showPreview = ref(false)
|
const showPreview = ref(false)
|
||||||
const {
|
const {
|
||||||
@@ -324,6 +297,23 @@ const {
|
|||||||
handleCatSelect
|
handleCatSelect
|
||||||
} = useCate()
|
} = useCate()
|
||||||
|
|
||||||
|
const activeFileType = ref(props.defaultFileType)
|
||||||
|
|
||||||
|
const ext = computed(() => {
|
||||||
|
if (activeFileType.value) {
|
||||||
|
return FileExt[activeFileType.value]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
const listExt = computed(() => {
|
||||||
|
if (activeFileType.value == 'all') {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
if (activeFileType.value) {
|
||||||
|
return FileExt[activeFileType.value]
|
||||||
|
}
|
||||||
|
return []
|
||||||
|
})
|
||||||
const {
|
const {
|
||||||
tableRef,
|
tableRef,
|
||||||
moveId,
|
moveId,
|
||||||
@@ -338,15 +328,23 @@ const {
|
|||||||
batchFileMove,
|
batchFileMove,
|
||||||
|
|
||||||
clearSelect,
|
clearSelect,
|
||||||
cancelSelete,
|
cancelSelect,
|
||||||
|
|
||||||
selectItems,
|
selectItems,
|
||||||
handleFileRename
|
handleFileRename
|
||||||
} = useFile(cateId, props.ext, limit, props.pageSize)
|
} = useFile(cateId, listExt, props.limit, props.pageSize)
|
||||||
function handleSelectionChange(val: any[]) {
|
function handleSelectionChange(val: any[]) {
|
||||||
console.log('handleSelectionChange', val)
|
// console.log('handleSelectionChange', val)
|
||||||
|
// if (props.limit && val.length > props.limit) {
|
||||||
|
// return false
|
||||||
|
// }
|
||||||
selectItems(val)
|
selectItems(val)
|
||||||
// multipleSelection.value = val
|
}
|
||||||
|
const handleTabChange = () => {
|
||||||
|
// activeFileType.value = tab
|
||||||
|
console.log('handleTabChange', activeFileType.value)
|
||||||
|
|
||||||
|
getFileList()
|
||||||
}
|
}
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
await getCateLists()
|
await getCateLists()
|
||||||
@@ -386,7 +384,8 @@ watch(
|
|||||||
)
|
)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
props.mode == 'page' && getData()
|
// props.mode == 'page' && getData()
|
||||||
|
getData()
|
||||||
})
|
})
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
|
@@ -1,8 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="material-select">
|
<div class="material-picker">
|
||||||
<popup
|
<popup
|
||||||
ref="popupRef"
|
ref="popupRef"
|
||||||
width="830px"
|
width="1200px"
|
||||||
custom-class="body-padding"
|
custom-class="body-padding"
|
||||||
:title="`选择${tipsText}`"
|
:title="`选择${tipsText}`"
|
||||||
@confirm="handleConfirm"
|
@confirm="handleConfirm"
|
||||||
@@ -24,7 +24,6 @@
|
|||||||
<file-item
|
<file-item
|
||||||
:uri="excludeDomain ? getImageUrl(element) : element"
|
:uri="excludeDomain ? getImageUrl(element) : element"
|
||||||
:file-size="size"
|
:file-size="size"
|
||||||
:type="type"
|
|
||||||
></file-item>
|
></file-item>
|
||||||
</del-wrap>
|
</del-wrap>
|
||||||
<div class="operation-btns text-xs text-center">
|
<div class="operation-btns text-xs text-center">
|
||||||
@@ -61,21 +60,21 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<el-scrollbar>
|
|
||||||
<div class="material-wrap">
|
<div class="material-wrap">
|
||||||
<material
|
<material
|
||||||
ref="materialRef"
|
ref="materialRef"
|
||||||
mode="page"
|
mode="picker"
|
||||||
:type="type"
|
defaultFileType="image"
|
||||||
|
:ext="ext"
|
||||||
:file-size="fileSize"
|
:file-size="fileSize"
|
||||||
:limit="meterialLimit"
|
:limit="materialLimit"
|
||||||
@change="selectChange"
|
@change="selectChange"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</el-scrollbar>
|
|
||||||
</popup>
|
</popup>
|
||||||
|
|
||||||
<preview v-model="showPreview" :url="previewUrl" :type="type" />
|
<preview v-model="showPreview" :url="previewUrl" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -88,6 +87,8 @@ import Material from './index.vue'
|
|||||||
import Preview from './preview.vue'
|
import Preview from './preview.vue'
|
||||||
import useAppStore from '@/stores/modules/app'
|
import useAppStore from '@/stores/modules/app'
|
||||||
import { useThrottleFn } from '@vueuse/core'
|
import { useThrottleFn } from '@vueuse/core'
|
||||||
|
import { FileExt } from '@/enums/fileEnums'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
Popup,
|
Popup,
|
||||||
@@ -154,6 +155,10 @@ export default defineComponent({
|
|||||||
const currentIndex = ref(-1)
|
const currentIndex = ref(-1)
|
||||||
const { disabled, limit, modelValue } = toRefs(props)
|
const { disabled, limit, modelValue } = toRefs(props)
|
||||||
const { getImageUrl } = useAppStore()
|
const { getImageUrl } = useAppStore()
|
||||||
|
|
||||||
|
const ext = computed(() => {
|
||||||
|
return FileExt[props.type]
|
||||||
|
})
|
||||||
const tipsText = computed(() => {
|
const tipsText = computed(() => {
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
case 'image':
|
case 'image':
|
||||||
@@ -168,7 +173,7 @@ export default defineComponent({
|
|||||||
const showUpload = computed(() => {
|
const showUpload = computed(() => {
|
||||||
return props.limit - fileList.value.length > 0
|
return props.limit - fileList.value.length > 0
|
||||||
})
|
})
|
||||||
const meterialLimit: any = computed(() => {
|
const materialLimit: any = computed(() => {
|
||||||
if (!isAdd.value) {
|
if (!isAdd.value) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
@@ -240,12 +245,13 @@ export default defineComponent({
|
|||||||
provide('limit', props.limit)
|
provide('limit', props.limit)
|
||||||
provide('hiddenUpload', props.hiddenUpload)
|
provide('hiddenUpload', props.hiddenUpload)
|
||||||
return {
|
return {
|
||||||
|
ext,
|
||||||
popupRef,
|
popupRef,
|
||||||
materialRef,
|
materialRef,
|
||||||
fileList,
|
fileList,
|
||||||
tipsText,
|
tipsText,
|
||||||
handleConfirm,
|
handleConfirm,
|
||||||
meterialLimit,
|
materialLimit,
|
||||||
showUpload,
|
showUpload,
|
||||||
showPopup,
|
showPopup,
|
||||||
selectChange,
|
selectChange,
|
||||||
@@ -261,7 +267,7 @@ export default defineComponent({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.material-select {
|
.material-picker {
|
||||||
.material-upload,
|
.material-upload,
|
||||||
.material-preview {
|
.material-preview {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -301,7 +307,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
.material-wrap {
|
.material-wrap {
|
||||||
min-width: 720px;
|
min-width: 720px;
|
||||||
height: 430px;
|
height: calc(100vh - 170px);
|
||||||
@apply border-t border-b border-br;
|
border-top: 1px var(--el-border-color) solid;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-show="modelValue">
|
<div v-show="modelValue">
|
||||||
<div v-if="type == 'image'">
|
<div v-if="fileType == 'image'">
|
||||||
<el-image-viewer
|
<el-image-viewer
|
||||||
v-if="previewLists.length"
|
v-if="previewLists.length"
|
||||||
:url-list="previewLists"
|
:url-list="previewLists"
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
@close="handleClose"
|
@close="handleClose"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="type == 'video'">
|
<div v-if="fileType == 'video' || fileType == 'audio'">
|
||||||
<el-dialog v-model="visible" width="740px" title="视频预览" :before-close="handleClose">
|
<el-dialog v-model="visible" width="900px" title="视频预览" :before-close="handleClose">
|
||||||
<video-player ref="playerRef" :src="url" width="100%" height="450px" />
|
<video-player ref="playerRef" :src="url" width="100%" height="450px" />
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref, useTemplateRef, watch, computed, nextTick } from 'vue'
|
import { ref, useTemplateRef, watch, computed, nextTick } from 'vue'
|
||||||
|
import { GetFileType } from '@/enums/fileEnums'
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -33,17 +35,8 @@ const props = defineProps({
|
|||||||
// }
|
// }
|
||||||
})
|
})
|
||||||
|
|
||||||
const type = computed(() => {
|
const fileType = computed(() => {
|
||||||
const imageExt = ['jpg', 'jpeg', 'png', 'gif', 'bmp']
|
return GetFileType(props.url)
|
||||||
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>{{ getAccept }}
|
<slot></slot>
|
||||||
</el-upload>
|
</el-upload>
|
||||||
<el-dialog
|
<el-dialog
|
||||||
v-if="showProgress && fileList.length"
|
v-if="showProgress && fileList.length"
|
||||||
@@ -59,11 +59,6 @@ export default defineComponent({
|
|||||||
type: Array as PropType<string[]>,
|
type: Array as PropType<string[]>,
|
||||||
default: () => []
|
default: () => []
|
||||||
},
|
},
|
||||||
// 上传文件类型
|
|
||||||
type: {
|
|
||||||
type: String,
|
|
||||||
default: 'image'
|
|
||||||
},
|
|
||||||
// 是否支持多选
|
// 是否支持多选
|
||||||
multiple: {
|
multiple: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
|
@@ -36,7 +36,7 @@ const options = reactive({
|
|||||||
loop: false, //循环播放
|
loop: false, //循环播放
|
||||||
mirror: false, //镜像画面
|
mirror: false, //镜像画面
|
||||||
ligthOff: false, //关灯模式
|
ligthOff: false, //关灯模式
|
||||||
volume: 0.3, //默认音量大小
|
volume: 1, //默认音量大小
|
||||||
control: true, //是否显示控制器
|
control: true, //是否显示控制器
|
||||||
title: '', //视频名称
|
title: '', //视频名称
|
||||||
poster: '', //封面
|
poster: '', //封面
|
||||||
@@ -59,7 +59,7 @@ const onPause = (event: any) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const onTimeupdate = (event: any) => {
|
const onTimeupdate = (event: any) => {
|
||||||
console.log(event, '时间更新')
|
// console.log(event, '时间更新')
|
||||||
}
|
}
|
||||||
const onCanplay = (event: any) => {
|
const onCanplay = (event: any) => {
|
||||||
console.log(event, '可以播放')
|
console.log(event, '可以播放')
|
||||||
|
87
admin/src/enums/fileEnums.ts
Normal file
87
admin/src/enums/fileEnums.ts
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
export const imageExt = ['png', 'jpg', 'jpeg', 'gif', 'ico', 'bmp', 'webp', 'avif']
|
||||||
|
export const videoExt = ['mp4', 'avi', 'mov', 'wmv', 'flv', 'rmvb']
|
||||||
|
export const audioExt = ['mp3', 'wav', 'aac', 'flac']
|
||||||
|
export const officeExt = ['doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt']
|
||||||
|
export const fileExt = ['zip', '7z', 'rar']
|
||||||
|
export const All_EXT = [...imageExt, ...videoExt, ...audioExt, ...fileExt]
|
||||||
|
|
||||||
|
// 获取文件类型
|
||||||
|
export function GetFileType(url: string) {
|
||||||
|
const ext = url.split('.').pop()
|
||||||
|
|
||||||
|
if (officeExt.includes(ext)) {
|
||||||
|
return 'office'
|
||||||
|
}
|
||||||
|
if (audioExt.includes(ext)) {
|
||||||
|
return 'audio'
|
||||||
|
}
|
||||||
|
if (imageExt.includes(ext)) {
|
||||||
|
return 'image'
|
||||||
|
}
|
||||||
|
if (videoExt.includes(ext)) {
|
||||||
|
return 'video'
|
||||||
|
}
|
||||||
|
return 'file'
|
||||||
|
}
|
||||||
|
// 获取文件类型上传的accept
|
||||||
|
function getAccept(ext: string[]) {
|
||||||
|
return ext
|
||||||
|
.map((item) => {
|
||||||
|
return `.${item}`
|
||||||
|
})
|
||||||
|
.join(',')
|
||||||
|
}
|
||||||
|
export const FileTabsMap = [
|
||||||
|
{
|
||||||
|
name: '全部',
|
||||||
|
fileType: 'all',
|
||||||
|
accept: getAccept(All_EXT),
|
||||||
|
ext: []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '图片',
|
||||||
|
fileType: 'image',
|
||||||
|
accept: getAccept(imageExt),
|
||||||
|
ext: imageExt
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '视频',
|
||||||
|
fileType: 'video',
|
||||||
|
accept: getAccept(videoExt),
|
||||||
|
ext: videoExt
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '音频',
|
||||||
|
fileType: 'audio',
|
||||||
|
accept: getAccept(audioExt),
|
||||||
|
ext: audioExt
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '文档',
|
||||||
|
fileType: 'office',
|
||||||
|
accept: getAccept(officeExt),
|
||||||
|
ext: officeExt
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '文件',
|
||||||
|
fileType: 'file',
|
||||||
|
accept: getAccept(fileExt),
|
||||||
|
ext: fileExt
|
||||||
|
}
|
||||||
|
]
|
||||||
|
export const FileExt = {
|
||||||
|
all: All_EXT,
|
||||||
|
image: imageExt,
|
||||||
|
video: videoExt,
|
||||||
|
audio: audioExt,
|
||||||
|
office: officeExt,
|
||||||
|
file: fileExt
|
||||||
|
}
|
||||||
|
export const FileAccept = {
|
||||||
|
all: getAccept(All_EXT),
|
||||||
|
image: getAccept(imageExt),
|
||||||
|
video: getAccept(videoExt),
|
||||||
|
audio: getAccept(audioExt),
|
||||||
|
office: getAccept(officeExt),
|
||||||
|
file: getAccept(fileExt)
|
||||||
|
}
|
@@ -8,6 +8,7 @@ export interface FileUploaderOptions {
|
|||||||
chunkSize?: number
|
chunkSize?: number
|
||||||
onSuccess?: (filePath: string) => void
|
onSuccess?: (filePath: string) => void
|
||||||
onError?: (error: Error) => void
|
onError?: (error: Error) => void
|
||||||
|
onCalculateMD5Progress?: (percent: number) => void
|
||||||
onUploadProgress?: (
|
onUploadProgress?: (
|
||||||
chunkIndex: number,
|
chunkIndex: number,
|
||||||
chunkCount: number,
|
chunkCount: number,
|
||||||
@@ -43,6 +44,10 @@ export default class FileUploader {
|
|||||||
this.startChunkIndex = -1
|
this.startChunkIndex = -1
|
||||||
this.onError(error)
|
this.onError(error)
|
||||||
}
|
}
|
||||||
|
calculateMD5Progress(chunkIndex: number, chunkTotal: number) {
|
||||||
|
const chunkPercent = Math.floor((chunkIndex / chunkTotal) * 100)
|
||||||
|
this.onCalculateMD5Progress(chunkPercent)
|
||||||
|
}
|
||||||
uploadProgress(chunkIndex: number, chunkLoaded: number, chunkTotal: number) {
|
uploadProgress(chunkIndex: number, chunkLoaded: number, chunkTotal: number) {
|
||||||
// 计算百分比
|
// 计算百分比
|
||||||
const chunkPercent = Math.floor((chunkLoaded / chunkTotal) * 100)
|
const chunkPercent = Math.floor((chunkLoaded / chunkTotal) * 100)
|
||||||
@@ -52,6 +57,7 @@ export default class FileUploader {
|
|||||||
onChunkSuccess: FileUploaderOptions['onChunkSuccess'] = function () {}
|
onChunkSuccess: FileUploaderOptions['onChunkSuccess'] = function () {}
|
||||||
onChunkError: FileUploaderOptions['onChunkError'] = function () {}
|
onChunkError: FileUploaderOptions['onChunkError'] = function () {}
|
||||||
onError: FileUploaderOptions['onError'] = function () {}
|
onError: FileUploaderOptions['onError'] = function () {}
|
||||||
|
onCalculateMD5Progress: FileUploaderOptions['onCalculateMD5Progress'] = function () {}
|
||||||
onUploadProgress: FileUploaderOptions['onUploadProgress'] = function () {}
|
onUploadProgress: FileUploaderOptions['onUploadProgress'] = function () {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -103,21 +109,21 @@ export default class FileUploader {
|
|||||||
this.fileSize = file.size
|
this.fileSize = file.size
|
||||||
this.chunkCount = Math.ceil(this.file.size / this.chunkSize)
|
this.chunkCount = Math.ceil(this.file.size / this.chunkSize)
|
||||||
}
|
}
|
||||||
readerFile(file: File): Promise<ArrayBuffer> {
|
// readerFile(file: File): Promise<ArrayBuffer> {
|
||||||
return new Promise((resolve, reject) => {
|
// return new Promise((resolve, reject) => {
|
||||||
if (!file) {
|
// if (!file) {
|
||||||
return reject(new Error('读取文件失败'))
|
// return reject(new Error('读取文件失败'))
|
||||||
}
|
// }
|
||||||
const reader = new FileReader()
|
// const reader = new FileReader()
|
||||||
reader.onload = (e) => {
|
// reader.onload = (e) => {
|
||||||
resolve(e.target?.result as ArrayBuffer)
|
// resolve(e.target?.result as ArrayBuffer)
|
||||||
}
|
// }
|
||||||
reader.onerror = (e) => {
|
// reader.onerror = (e) => {
|
||||||
reject(e)
|
// reject(e)
|
||||||
}
|
// }
|
||||||
reader.readAsArrayBuffer(file)
|
// reader.readAsArrayBuffer(file)
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
getAbortControllerSignal() {
|
getAbortControllerSignal() {
|
||||||
const controller = new AbortController()
|
const controller = new AbortController()
|
||||||
this.abortControllers.push(controller)
|
this.abortControllers.push(controller)
|
||||||
@@ -148,8 +154,10 @@ export default class FileUploader {
|
|||||||
}
|
}
|
||||||
this.uploading = true
|
this.uploading = true
|
||||||
|
|
||||||
const arrayBuffer = await this.readerFile(this.file)
|
// const arrayBuffer = await this.readerFile(this.file)
|
||||||
const fileMd5 = this.getMd5(arrayBuffer)
|
console.time('SparkMD5')
|
||||||
|
const fileMd5 = await this.calculateMD5(this.file)
|
||||||
|
console.timeEnd('SparkMD5')
|
||||||
this.fileMd5 = fileMd5 + '_' + this.fileSize
|
this.fileMd5 = fileMd5 + '_' + this.fileSize
|
||||||
const isExistFilePath = await this.checkFileExist()
|
const isExistFilePath = await this.checkFileExist()
|
||||||
|
|
||||||
@@ -167,19 +175,58 @@ export default class FileUploader {
|
|||||||
this.error(error)
|
this.error(error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
// 检查上传状态
|
* 计算文件的MD5值
|
||||||
getMd5(arrayBuffer: ArrayBuffer): string {
|
* @param file
|
||||||
if (!this.uploading) {
|
* @returns
|
||||||
return
|
*/
|
||||||
}
|
async calculateMD5(file: File) {
|
||||||
console.time('SparkMD5')
|
return new Promise((resolve, reject) => {
|
||||||
const spark = new SparkMD5.ArrayBuffer()
|
const spark = new SparkMD5.ArrayBuffer()
|
||||||
spark.append(arrayBuffer)
|
const reader = new FileReader()
|
||||||
const hash = spark.end()
|
const chunkSize = 10 * 1024 * 1024 // 10MB 分块
|
||||||
console.timeEnd('SparkMD5')
|
let currentChunk = 0
|
||||||
return hash
|
const chunks = Math.ceil(file.size / chunkSize)
|
||||||
|
|
||||||
|
reader.onload = function (e) {
|
||||||
|
spark.append(e.target.result) // 添加数组缓冲区
|
||||||
|
currentChunk++
|
||||||
|
|
||||||
|
if (currentChunk < chunks) {
|
||||||
|
loadNext()
|
||||||
|
} else {
|
||||||
|
resolve(spark.end())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.onerror = function () {
|
||||||
|
reject('文件读取错误')
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadNext() {
|
||||||
|
console.log('md5进度', currentChunk, chunks)
|
||||||
|
this.calculateMD5Progress(currentChunk, chunks)
|
||||||
|
|
||||||
|
const start = currentChunk * chunkSize
|
||||||
|
const end = Math.min(start + chunkSize, file.size)
|
||||||
|
reader.readAsArrayBuffer(file.slice(start, end))
|
||||||
|
}
|
||||||
|
|
||||||
|
loadNext()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 计算文件的MD5值
|
||||||
|
// getMd5(arrayBuffer: ArrayBuffer): string {
|
||||||
|
// if (!this.uploading) {
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// console.time('SparkMD5')
|
||||||
|
// const spark = new SparkMD5.ArrayBuffer()
|
||||||
|
// spark.append(arrayBuffer)
|
||||||
|
// const hash = spark.end()
|
||||||
|
// console.timeEnd('SparkMD5')
|
||||||
|
// return hash
|
||||||
|
// }
|
||||||
// 检查文件是否存在,可实现秒传
|
// 检查文件是否存在,可实现秒传
|
||||||
async checkFileExist(): Promise<string> {
|
async checkFileExist(): Promise<string> {
|
||||||
if (!this.uploading) {
|
if (!this.uploading) {
|
||||||
|
@@ -1,72 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="material-index">
|
<div class="material-index">
|
||||||
<el-card class="!border-none" shadow="never">
|
<MaterialComponent mode="page" :limit="-1" :page-size="10" />
|
||||||
<el-tabs v-model="activeTab">
|
|
||||||
<el-tab-pane
|
|
||||||
v-for="item in tabsMap"
|
|
||||||
:label="item.name"
|
|
||||||
:name="item.name"
|
|
||||||
:index="item.name"
|
|
||||||
:key="item.name"
|
|
||||||
lazy
|
|
||||||
>
|
|
||||||
<material
|
|
||||||
:ext="item.ext"
|
|
||||||
mode="page"
|
|
||||||
file-size="120px"
|
|
||||||
:limit="-1"
|
|
||||||
:page-size="10"
|
|
||||||
/>
|
|
||||||
</el-tab-pane>
|
|
||||||
</el-tabs>
|
|
||||||
</el-card>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue'
|
import MaterialComponent from '@/components/material/index.vue'
|
||||||
import material from '@/components/material/index.vue'
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
name: 'materialCenter'
|
name: 'materialCenter'
|
||||||
})
|
})
|
||||||
const tabsMap = [
|
|
||||||
{
|
|
||||||
// type: '',
|
|
||||||
name: '全部',
|
|
||||||
ext: []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// type: 'image',
|
|
||||||
name: '图片',
|
|
||||||
ext: ['jpg', 'jpeg', 'png', 'gif', 'bmp']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// type: 'video',
|
|
||||||
name: '视频',
|
|
||||||
ext: ['mp4', 'avi', 'mov']
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// type: 'pdf',
|
|
||||||
name: 'pdf',
|
|
||||||
ext: ['pdf']
|
|
||||||
}
|
|
||||||
]
|
|
||||||
const activeTab = ref('image')
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.material-index {
|
.material-index {
|
||||||
min-width: 700px;
|
height: calc(100vh - 135px);
|
||||||
:deep(.el-tabs) {
|
overflow: hidden;
|
||||||
height: calc(100vh - 180px);
|
background-color: white;
|
||||||
|
padding: 0 5px 5px;
|
||||||
.el-tabs__content,
|
|
||||||
.el-tab-pane {
|
|
||||||
min-height: 0;
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@@ -65,42 +65,6 @@
|
|||||||
</el-card>
|
</el-card>
|
||||||
<el-card class="!border-none mt-4" shadow="never">
|
<el-card class="!border-none mt-4" shadow="never">
|
||||||
<div class="text-right">
|
<div class="text-right">
|
||||||
<!-- <el-button
|
|
||||||
v-perms="['admin:monitor_client:add']"
|
|
||||||
type="primary"
|
|
||||||
@click="handleAdd()"
|
|
||||||
>
|
|
||||||
<template #icon>
|
|
||||||
<icon name="el-icon-Plus" />
|
|
||||||
</template>
|
|
||||||
新增
|
|
||||||
</el-button>
|
|
||||||
<upload
|
|
||||||
v-perms="['admin:monitor_client:ImportFile']"
|
|
||||||
class="ml-3 mr-3"
|
|
||||||
:url="monitor_client_import_file"
|
|
||||||
:data="{ cid: 0 }"
|
|
||||||
type="file"
|
|
||||||
:show-progress="true"
|
|
||||||
@change="resetPage"
|
|
||||||
>
|
|
||||||
<el-button type="primary">
|
|
||||||
<template #icon>
|
|
||||||
<icon name="el-icon-Upload" />
|
|
||||||
</template>
|
|
||||||
导入
|
|
||||||
</el-button>
|
|
||||||
</upload>
|
|
||||||
<el-button
|
|
||||||
v-perms="['admin:monitor_client:ExportFile']"
|
|
||||||
type="primary"
|
|
||||||
@click="exportFile"
|
|
||||||
>
|
|
||||||
<template #icon>
|
|
||||||
<icon name="el-icon-Download" />
|
|
||||||
</template>
|
|
||||||
导出
|
|
||||||
</el-button> -->
|
|
||||||
<el-button
|
<el-button
|
||||||
v-perms="['admin:monitor_client:delBatch']"
|
v-perms="['admin:monitor_client:delBatch']"
|
||||||
type="danger"
|
type="danger"
|
||||||
|
@@ -72,7 +72,7 @@
|
|||||||
class="ml-3 mr-3"
|
class="ml-3 mr-3"
|
||||||
:url="monitor_project_import_file"
|
:url="monitor_project_import_file"
|
||||||
:data="{ cid: 0 }"
|
:data="{ cid: 0 }"
|
||||||
type="file"
|
:ext="['xlsx']"
|
||||||
:show-progress="true"
|
:show-progress="true"
|
||||||
@change="resetPage"
|
@change="resetPage"
|
||||||
>
|
>
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
class="ml-3 mr-3"
|
class="ml-3 mr-3"
|
||||||
:url="adminImportFile"
|
:url="adminImportFile"
|
||||||
:data="{ cid: 0 }"
|
:data="{ cid: 0 }"
|
||||||
type="file"
|
:ext="['xlsx']"
|
||||||
:show-progress="true"
|
:show-progress="true"
|
||||||
@change="resetPage"
|
@change="resetPage"
|
||||||
>
|
>
|
||||||
|
@@ -47,7 +47,7 @@
|
|||||||
class="ml-3 mr-3"
|
class="ml-3 mr-3"
|
||||||
:url="user_protocol_import_file"
|
:url="user_protocol_import_file"
|
||||||
:data="{ cid: 0 }"
|
:data="{ cid: 0 }"
|
||||||
type="file"
|
:ext="['xlsx']"
|
||||||
:show-progress="true"
|
:show-progress="true"
|
||||||
@change="resetPage"
|
@change="resetPage"
|
||||||
>
|
>
|
||||||
|
@@ -69,11 +69,14 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" @click="handleSubmit">保存</el-button>
|
||||||
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
</el-card>
|
</el-card>
|
||||||
<footer-btns>
|
<!-- <footer-btns>
|
||||||
<el-button type="primary" @click="handleSubmit">保存</el-button>
|
<el-button type="primary" @click="handleSubmit">保存</el-button>
|
||||||
</footer-btns>
|
</footer-btns> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -105,7 +108,7 @@ const rules = reactive<object>({
|
|||||||
{
|
{
|
||||||
required: true,
|
required: true,
|
||||||
message: '头像不能为空',
|
message: '头像不能为空',
|
||||||
trigger: ['change']
|
trigger: ['blur']
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
nickname: [
|
nickname: [
|
||||||
|
@@ -20,13 +20,13 @@ 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, // 10MB
|
UploadImageSize: 20 * 1024 * 1024, // 20MB
|
||||||
UploadVideoSize: 500 * 1024 * 1024, // 500MB
|
UploadVideoSize: 2000 * 1024 * 1024, // 2000MB
|
||||||
UploadFileSize: 1024 * 1024 * 1024, //1GB
|
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", "avi", "flv", "wmv", "rmvb", "mov", "mp3", "wav", "flac", "m4a"},
|
||||||
|
|
||||||
UploadFileExt: []string{"pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "zip", "rar", "7z", "txt"},
|
UploadFileExt: []string{"pdf", "doc", "docx", "xls", "xlsx", "ppt", "pptx", "zip", "rar", "7z", "txt"},
|
||||||
}
|
}
|
||||||
|
@@ -11,7 +11,7 @@ type UserProtocol struct {
|
|||||||
Id int `gorm:"primarykey;comment:''"` //
|
Id int `gorm:"primarykey;comment:''"` //
|
||||||
Title string `gorm:"comment:'标题'"` // 标题
|
Title string `gorm:"comment:'标题'"` // 标题
|
||||||
Content string `gorm:"comment:'协议内容'"` // 协议内容
|
Content string `gorm:"comment:'协议内容'"` // 协议内容
|
||||||
Sort core.NullFloat `gorm:"comment:'排序'"` // 排序
|
// Sort core.NullFloat `gorm:"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;comment:'创建时间'"` // 创建时间
|
CreateTime core.NullTime `gorm:"autoCreateTime;comment:'创建时间'"` // 创建时间
|
||||||
UpdateTime core.NullTime `gorm:"autoUpdateTime;comment:'更新时间'"` // 更新时间
|
UpdateTime core.NullTime `gorm:"autoUpdateTime;comment:'更新时间'"` // 更新时间
|
||||||
|
@@ -134,7 +134,7 @@ func (sd storageDriver) checkFile(fileName string, fileSize int64) (e error) {
|
|||||||
} else if util.ToolsUtil.Contains(config.FileConfig.UploadVideoExt, fileExt) {
|
} else if util.ToolsUtil.Contains(config.FileConfig.UploadVideoExt, 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")
|
||||||
}
|
}
|
||||||
} else if util.ToolsUtil.Contains(config.FileConfig.UploadFileExt, fileExt) {
|
} else if util.ToolsUtil.Contains(config.FileConfig.UploadFileExt, fileExt) {
|
||||||
// 文件
|
// 文件
|
||||||
|
@@ -8,7 +8,7 @@ import (
|
|||||||
type UserProtocolListReq struct {
|
type UserProtocolListReq struct {
|
||||||
Title *string // 标题
|
Title *string // 标题
|
||||||
Content *string // 协议内容
|
Content *string // 协议内容
|
||||||
Sort *float64 // 排序
|
// Sort *float64 // 排序
|
||||||
CreateTimeStart *string // 开始创建时间
|
CreateTimeStart *string // 开始创建时间
|
||||||
CreateTimeEnd *string // 结束创建时间
|
CreateTimeEnd *string // 结束创建时间
|
||||||
UpdateTimeStart *string // 开始更新时间
|
UpdateTimeStart *string // 开始更新时间
|
||||||
@@ -19,7 +19,7 @@ type UserProtocolListReq struct {
|
|||||||
type UserProtocolAddReq struct {
|
type UserProtocolAddReq struct {
|
||||||
Title *string // 标题
|
Title *string // 标题
|
||||||
Content *string // 协议内容
|
Content *string // 协议内容
|
||||||
Sort core.NullFloat // 排序
|
// Sort core.NullFloat // 排序
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserProtocolEditReq 用户协议编辑参数
|
// UserProtocolEditReq 用户协议编辑参数
|
||||||
@@ -27,7 +27,7 @@ type UserProtocolEditReq struct {
|
|||||||
Id int //
|
Id int //
|
||||||
Title *string // 标题
|
Title *string // 标题
|
||||||
Content *string // 协议内容
|
Content *string // 协议内容
|
||||||
Sort core.NullFloat // 排序
|
// Sort core.NullFloat // 排序
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserProtocolDetailReq 用户协议详情参数
|
// UserProtocolDetailReq 用户协议详情参数
|
||||||
@@ -50,7 +50,7 @@ type UserProtocolResp struct {
|
|||||||
Id int //
|
Id int //
|
||||||
Title string // 标题
|
Title string // 标题
|
||||||
Content string // 协议内容
|
Content string // 协议内容
|
||||||
Sort core.NullFloat // 排序
|
// Sort core.NullFloat // 排序
|
||||||
CreateTime core.NullTime // 创建时间
|
CreateTime core.NullTime // 创建时间
|
||||||
UpdateTime core.NullTime // 更新时间
|
UpdateTime core.NullTime // 更新时间
|
||||||
}
|
}
|
||||||
|
@@ -48,9 +48,6 @@ func (albSrv albumService) AlbumList(adminId uint, page request.PageReq, listReq
|
|||||||
albumModel = albumModel.Where("ext in ?", listReq.Ext)
|
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
|
||||||
@@ -134,7 +131,7 @@ func (albSrv albumService) AlbumAdd(addReq commonSchema.CommonAlbumAddReq) (res
|
|||||||
//}
|
//}
|
||||||
convert_util.Copy(&alb, addReq)
|
convert_util.Copy(&alb, addReq)
|
||||||
err := albSrv.db.Create(&alb).Error
|
err := albSrv.db.Create(&alb).Error
|
||||||
if e = response.CheckErr(err, "Album添加失败"); e != nil {
|
if e = response.CheckErr(err, "相册添加失败"); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return alb.ID, nil
|
return alb.ID, nil
|
||||||
@@ -144,7 +141,7 @@ func (albSrv albumService) AlbumAdd(addReq commonSchema.CommonAlbumAddReq) (res
|
|||||||
func (albSrv albumService) AlbumDel(ids []uint) (e error) {
|
func (albSrv albumService) AlbumDel(ids []uint) (e error) {
|
||||||
var albums []common_model.Album
|
var albums []common_model.Album
|
||||||
err := albSrv.db.Where("id in ? AND is_delete = ?", ids, 0).Find(&albums).Error
|
err := albSrv.db.Where("id in ? AND is_delete = ?", ids, 0).Find(&albums).Error
|
||||||
if e = response.CheckErr(err, "AlbumDel Find err"); e != nil {
|
if e = response.CheckErr(err, "相册文件查找失败"); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if len(albums) == 0 {
|
if len(albums) == 0 {
|
||||||
@@ -152,7 +149,7 @@ func (albSrv albumService) AlbumDel(ids []uint) (e error) {
|
|||||||
}
|
}
|
||||||
err = albSrv.db.Model(&common_model.Album{}).Where("id in ?", ids).Updates(
|
err = albSrv.db.Model(&common_model.Album{}).Where("id in ?", ids).Updates(
|
||||||
common_model.Album{IsDelete: 1, DeleteTime: util.NullTimeUtil.Now()}).Error
|
common_model.Album{IsDelete: 1, DeleteTime: util.NullTimeUtil.Now()}).Error
|
||||||
e = response.CheckErr(err, "AlbumDel UpdateColumn err")
|
e = response.CheckErr(err, "相册文件删除失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,7 +166,7 @@ func (albSrv albumService) CateList(adminId uint, listReq commonSchema.CommonCat
|
|||||||
cateModel = cateModel.Where("name like ?", "%"+listReq.Name+"%")
|
cateModel = cateModel.Where("name like ?", "%"+listReq.Name+"%")
|
||||||
}
|
}
|
||||||
err := cateModel.Find(&cates).Error
|
err := cateModel.Find(&cates).Error
|
||||||
if e = response.CheckErr(err, "Cate列表获取失败"); e != nil {
|
if e = response.CheckErr(err, "分类列表获取失败"); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
cateResps := []commonSchema.CommonCateListResp{}
|
cateResps := []commonSchema.CommonCateListResp{}
|
||||||
@@ -181,11 +178,17 @@ func (albSrv albumService) CateList(adminId uint, listReq commonSchema.CommonCat
|
|||||||
func (albSrv albumService) CateAdd(adminId uint, 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
|
||||||
|
// 查询分类是否存在
|
||||||
|
albSrv.db.Where("admin_id = ? AND pid=? AND name = ? AND is_delete = ?", adminId, addReq.Pid, addReq.Name, 0).Limit(1).First(&cate)
|
||||||
|
if cate.ID > 0 {
|
||||||
|
return response.AssertArgumentError.SetMessage("分类已存在!")
|
||||||
|
}
|
||||||
|
|
||||||
convert_util.Copy(&cate, addReq)
|
convert_util.Copy(&cate, addReq)
|
||||||
cate.AdminId = adminId
|
cate.AdminId = adminId
|
||||||
|
|
||||||
err := albSrv.db.Create(&cate).Error
|
err := albSrv.db.Create(&cate).Error
|
||||||
e = response.CheckErr(err, "Cate添加失败")
|
e = response.CheckErr(err, "分类添加失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,12 +199,19 @@ func (albSrv albumService) CateRename(id uint, name string) (e error) {
|
|||||||
if e = response.CheckErrDBNotRecord(err, "分类已不存在!"); e != nil {
|
if e = response.CheckErrDBNotRecord(err, "分类已不存在!"); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if e = response.CheckErr(err, "CateRename First err"); e != nil {
|
if e = response.CheckErr(err, "重命名失败"); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var cate2 common_model.AlbumCate
|
||||||
|
// 查询分类是否存在
|
||||||
|
albSrv.db.Where("admin_id = ? AND pid=? AND name = ? AND is_delete = ? AND id <> ?", cate.AdminId, cate.Pid, name, 0, cate.ID).Limit(1).First(&cate2)
|
||||||
|
if cate2.ID > 0 {
|
||||||
|
return response.AssertArgumentError.SetMessage("分类“" + name + "”已存在!")
|
||||||
|
}
|
||||||
|
|
||||||
cate.Name = name
|
cate.Name = name
|
||||||
err = albSrv.db.Save(&cate).Error
|
err = albSrv.db.Save(&cate).Error
|
||||||
e = response.CheckErr(err, "CateRename Save err")
|
e = response.CheckErr(err, "分类重命名失败")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,11 +222,11 @@ func (albSrv albumService) CateDel(id uint) (e error) {
|
|||||||
if e = response.CheckErrDBNotRecord(err, "分类已不存在!"); e != nil {
|
if e = response.CheckErrDBNotRecord(err, "分类已不存在!"); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if e = response.CheckErr(err, "Cate待删除数据查找失败"); e != nil {
|
if e = response.CheckErr(err, "待删除数据查找失败"); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
r := albSrv.db.Where("cid = ? AND is_delete = ?", id, 0).Limit(1).Find(&common_model.Album{})
|
r := albSrv.db.Where("cid = ? AND is_delete = ?", id, 0).Limit(1).Find(&common_model.Album{})
|
||||||
if e = response.CheckErr(r.Error, "CateDel Find err"); e != nil {
|
if e = response.CheckErr(r.Error, "分类数据使用失败"); e != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if r.RowsAffected > 0 {
|
if r.RowsAffected > 0 {
|
||||||
|
@@ -66,7 +66,7 @@
|
|||||||
class="ml-3 mr-3"
|
class="ml-3 mr-3"
|
||||||
:url="{{{.ModuleName}}}_import_file"
|
:url="{{{.ModuleName}}}_import_file"
|
||||||
:data="{ cid: 0 }"
|
:data="{ cid: 0 }"
|
||||||
type="file"
|
:ext="['xlsx']"
|
||||||
:show-progress="true"
|
:show-progress="true"
|
||||||
@change="resetPage"
|
@change="resetPage"
|
||||||
>
|
>
|
||||||
|
@@ -42,9 +42,9 @@ func (service userProtocolService) GetModel(listReq schema.UserProtocolListReq)
|
|||||||
if listReq.Content != nil {
|
if listReq.Content != nil {
|
||||||
dbModel = dbModel.Where("content = ?", *listReq.Content)
|
dbModel = dbModel.Where("content = ?", *listReq.Content)
|
||||||
}
|
}
|
||||||
if listReq.Sort != nil {
|
// if listReq.Sort != nil {
|
||||||
dbModel = dbModel.Where("sort = ?", *listReq.Sort)
|
// dbModel = dbModel.Where("sort = ?", *listReq.Sort)
|
||||||
}
|
// }
|
||||||
if listReq.CreateTimeStart != nil {
|
if listReq.CreateTimeStart != nil {
|
||||||
dbModel = dbModel.Where("create_time >= ?", *listReq.CreateTimeStart)
|
dbModel = dbModel.Where("create_time >= ?", *listReq.CreateTimeStart)
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user