ZaiZai 11 ヶ月 前
コミット
574373b0f7
4 ファイル変更264 行追加15 行削除
  1. 1 1
      src/layout/index.vue
  2. 92 14
      src/layout/modules/Upload.vue
  3. 145 0
      src/plugins/HcUpload.js
  4. 26 0
      src/views/project/list.vue

+ 1 - 1
src/layout/index.vue

@@ -13,8 +13,8 @@
                 <TopMenu />
             </div>
             <div class="header-content-bar">
-                <HcGlobalUpload />
                 <HcRefresh />
+                <HcGlobalUpload />
                 <HcColor />
                 <HcTheme />
                 <UserInfoBar @load="userInfoLoad" />

+ 92 - 14
src/layout/modules/Upload.vue

@@ -3,44 +3,122 @@
         <el-tooltip content="全局文件上传" placement="top">
             <hc-icon name="upload-cloud" class="header-icon" />
         </el-tooltip>
-
-        <!-- 上传文件 -->
-        <hc-upload-file ref="uploadRef" :echo-params="params" modal="drawer" :options="options" @success="success" />
     </div>
+    <!-- 上传文件 -->
+    <hc-upload-file
+        ref="uploadRef"
+        :params="params"
+        :echo-params="echoParams"
+        modal="drawer"
+        :options="options"
+        :drop="isDrop"
+        use-file
+        @progress="uploadProgress"
+        @error="uploadError"
+        @cancel="uploadCancel"
+        @item="uploadItem"
+        @finish="uploadFinish"
+        @success="uploadSuccess"
+    />
 </template>
 
 <script setup>
-import { onMounted, onUnmounted, ref } from 'vue'
+import { getObjValue } from 'js-fast-way'
+import { onMounted, onUnmounted, ref, watch } from 'vue'
 import { emitter, getHeader } from 'hc-vue3-ui'
+import HcUpload from '~src/plugins/HcUpload'
+import { useRoute } from 'vue-router'
+const useRoutes = useRoute()
+
+const EVENT_KEY = 'hc-global-upload-file'
 
 //页面渲染
 onMounted(() => {
-    //注册监听事件
-    emitter.on('hc-global-upload-file', (data) => {
-        console.log('微型事件测试:', data)
-    })
+    HcUpload.router(useRoutes?.name)
+    setEmitterData()
+})
+
+//监听路由变化
+watch(() => useRoutes?.name, (name) => {
+    HcUpload.router(name)
 })
 
 //上传文件
 const uploadRef = ref(null)
 const params = ref({})
-const options = ref({
-    headers: getHeader(),
-})
+const echoParams = ref({})
+const options = ref({})
+const isDrop = ref(false)
+
+//注册监听事件
+const setEmitterData = () => {
+    emitter.on(EVENT_KEY, ({ key, data }) => {
+        if (key === 'params') {
+            //处理请求头
+            const headers = getObjValue(data.options.headers)
+            data.options.headers = { ...headers, ...getHeader() }
+            //设置参数
+            params.value = data.params
+            echoParams.value = data.echoParams
+            options.value = data.options
+            isDrop.value = data.isDrop
+        } else if (key === 'show') {
+            uploadRef.value?.setModalShow(true)
+        } else if (key === 'close') {
+            uploadRef.value?.setModalShow(false)
+        } else if (key === 'open') {
+            uploadRef.value?.selectFile()
+        } else if (key === 'clear') {
+            uploadRef.value?.cancelUpload()
+        } else if (key === 'cancel') {
+            uploadRef.value?.allCancel()
+        } else if (key === 'getUploading') {
+            const bool = uploadRef.value?.getIsUploading()
+            emitter.emit(`${EVENT_KEY}-get-uploading`, bool)
+        }
+    })
+}
 
-//上传成功
-const success = () => {
+//文件上传中,此事件是单个文件上传中时会触发
+const uploadProgress = ({ file, status }) => {
+    emitter.emit(`${EVENT_KEY}-progress`, { file, status })
+}
+
+//文件上传失败 ,返回一个当前文件的数据对象
+const uploadError = (file) => {
+    emitter.emit(`${EVENT_KEY}-error`, file)
+}
+
+//文件上传成功,返回一个当前文件的数据对象
+const uploadSuccess = (file) => {
+    emitter.emit(`${EVENT_KEY}-success`, file)
+}
+
+//取消上传并从列表中移除
+const uploadCancel = ({ item, index }) => {
+    emitter.emit(`${EVENT_KEY}-cancel`, { item, index })
+}
+
+//点击了使用此文件的事件
+const uploadItem = ({ item, index }) => {
+    emitter.emit(`${EVENT_KEY}-item`, { item, index })
+}
 
+//全部文件上传完成
+const uploadFinish = (files) => {
+    emitter.emit(`${EVENT_KEY}-finish`, files)
 }
 
 //展开上传文件
 const uploadClick = () => {
+    console.log('展开上传文件')
     uploadRef.value?.setModalShow(true)
 }
 
 //页面被注销,关闭监听事件
 onUnmounted(() => {
-    emitter.off('hc-global-upload-file')
+    emitter.off(EVENT_KEY)
+    HcUpload.resetAll()
 })
 </script>
 

+ 145 - 0
src/plugins/HcUpload.js

@@ -0,0 +1,145 @@
+import { emitter } from 'hc-vue3-ui'
+import { getObjVal, getObjValue, isNullES } from 'js-fast-way'
+
+//事件key
+const EVENT_KEY = 'hc-global-upload-file'
+
+//全局文件上传
+export default class HcUpload {
+
+    //功能页面key,用于找溯源
+    static routerKey = null
+    static pageKey = null
+
+    //上传文件的配置
+    static uploadOptions = {}
+
+    //发送给服务器的额外参数
+    static uploadParams = {}
+
+    //回显参数,此参数不会提交服务器,只会在事件里返回
+    static uploadEchoParams = {}
+
+    //是否为拖动上传
+    static uploadDrop = false
+
+    //初始化参数
+    static init(parameter = {}) {
+        const { options, params, echoParams, drop, key } = getObjValue(parameter)
+        //上传文件的配置
+        const options_data = getObjValue(options)
+        this.uploadOptions = {
+            //自定义小文件上传的Url
+            url: options_data.url ? options_data.url : '/api/blade-resource/oss/endpoint/put-file2',
+            //自定义文件上传参数名
+            name: options_data.name ? options_data.name : 'file',
+            //请求头,此值必须要传,否则会上传失败
+            headers: getObjValue(options_data.headers),
+            //自定义文件上传类型
+            accept: options_data.accept ? options_data.accept : '*',
+            //自定义文件上传类型提示
+            accept_tip: options_data.accept_tip ? options_data.accept_tip : '不限制',
+            //开启分片的大小,单位是MB
+            size: options_data.size ? options_data.size : 10,
+            //是否可多选文件
+            multiple: options_data.multiple ?? true,
+        }
+        //发送给服务器的额外参数
+        this.uploadParams = getObjValue(params)
+        //回显参数,此参数不会提交服务器,只会在事件里返回
+        this.pageKey = key ?? this.routerKey
+        this.uploadEchoParams = {
+            ...getObjValue(echoParams),
+            pageKey: this.pageKey,
+        }
+        //是否为拖动上传
+        this.uploadDrop = drop ?? false
+        //发送相关配置参加给文件上传
+        this.sendEmit('params', {
+            options: this.uploadOptions,
+            params: this.uploadParams,
+            echoParams: this.uploadEchoParams,
+            drop: this.uploadDrop,
+        })
+    }
+
+    //设置路由key
+    static router(key) {
+        this.routerKey = key ?? ''
+    }
+
+    //显示文件上传
+    static show(parameter = {}) {
+        if (getObjVal(parameter)) {
+            this.init(parameter)
+        }
+        this.sendEmit('show')
+    }
+
+    //关闭文件上传
+    static close() {
+        this.sendEmit('close')
+    }
+
+    //打开文件选择
+    static open(parameter = {}) {
+        if (getObjVal(parameter)) {
+            this.init(parameter)
+        }
+        this.sendEmit('open')
+    }
+
+    //清空所有文件
+    static clear() {
+        this.sendEmit('clear')
+    }
+
+    //取消并移除所有文件,包括已上传文件
+    static cancel() {
+        this.sendEmit('cancel')
+    }
+
+    //是否还有正在上传中的文件
+    static async getUploading() {
+        let _this = this
+        return new Promise((resolve) => {
+            _this.sendEmit('getUploading')
+            //监听事件
+            emitter.on(`${EVENT_KEY}-get-uploading`, (data) => {
+                resolve(data)
+            })
+        })
+    }
+
+    //监听事件
+    static on(key, fun) {
+        emitter.on(`${EVENT_KEY}-${key}`, (data) => {
+            if (typeof fun === 'function') {
+                fun(data)
+            }
+        })
+    }
+
+    //关闭监听事件
+    static off(key) {
+        if (isNullES(key)) {
+            const keys = ['progress', 'success', 'error', 'cancel', 'item', 'finish', 'get-uploading']
+            keys.forEach((item) => {
+                emitter.off(`${EVENT_KEY}-${item}`)
+            })
+        } else {
+            emitter.off(`${EVENT_KEY}-${key}`)
+        }
+    }
+
+    //发送事件给文件上传
+    static sendEmit(key, params = {}) {
+        emitter.emit(EVENT_KEY, { key: key, data: params })
+    }
+
+    //全部重置
+    static resetAll() {
+        this.off()
+        this.init()
+    }
+}

+ 26 - 0
src/views/project/list.vue

@@ -8,6 +8,7 @@
             </div>
         </template>
         <template #extra>
+            <el-button hc-btn type="primary" @click="testUpFile">测试上传文件</el-button>
             <el-button hc-btn type="primary" @click="addProjectClick">创建项目</el-button>
         </template>
         <hc-card-item v-for="item in tableData" :key="item.id" class="hc-project-list-card" @click="projectClick(item.id)">
@@ -41,6 +42,7 @@ import { getArrValue, getObjValue } from 'js-fast-way'
 import InfoDialog from './modules/list/info-dialog.vue'
 import HcWbsTree from './modules/list/wbs-tree.vue'
 import mainApi from '~api/project/project'
+import HcUpload from '~src/plugins/HcUpload'
 
 defineOptions({
     name: 'ProjectList',
@@ -48,9 +50,33 @@ defineOptions({
 
 //激活
 onActivated(() => {
+    HcUpload.init()
+    HcUpload.on('progress', (data) => {
+        console.log('上传中:', data)
+    })
+    HcUpload.on('success', (data) => {
+        console.log('上传成功:', data)
+    })
+    HcUpload.on('error', (data) => {
+        console.log('上传失败:', data)
+    })
+    HcUpload.on('cancel', (data) => {
+        console.log('取消上传:', data)
+    })
+    HcUpload.on('item', (data) => {
+        console.log('使用文件:', data)
+    })
+    HcUpload.on('finish', (data) => {
+        console.log('全部文件上传完成:', data)
+    })
     getDataApi()
 })
 
+//测试上传文件
+const testUpFile = () => {
+    HcUpload.open()
+}
+
 const getDataApi = async () => {
     await getProjectData()
     searchClick()