<template>
    <div style="display: flex;flex-direction: column;width: 100%">
        <div v-if="data.length>0" style="margin-bottom: 5px">
            <Icon name="local-system_erp_app"></Icon>
            <span style="margin-left: 5px">{{ data }}</span>
        </div>
        <input type="file" ref="inputRef" accept=".zip,.apk" @change="changFile">
    </div>

    <!--    <div v-if="showProgress">-->
    <!--        <div style="color: #92969a">正在上传升级包...</div>-->
    <!--        <el-progress :percentage="percent" :format="format" style="width: 150px" :color="colors"/>-->
    <!--    </div>-->


    <!--    <div-->
    <!--         style="width: 70px;height: 70px;position: fixed;bottom: 20px;right: 20px;z-index: 999;background-color: #e0e0e0;border-radius: 35px">-->
    <!--        <el-progress :width="70" type="circle" :percentage="percent" :color="colors">-->
    <!--            <el-button v-if="percent==100" type="success" :icon="Check" circle @click="showProgress=false"/>-->
    <!--            <div v-else>-->
    <!--                <div>{{ percent }}%</div>-->
    <!--            </div>-->
    <!--        </el-progress>-->
    <!--    </div>-->

    <el-dialog title="文件上传" v-model="showDialog" :close-on-click-modal="false" :show-close="false"
               :close-on-press-escape="false">
        <div style="margin-bottom: 20px">
            <div style="display: flex;align-items: center;margin: 10px 0">
                <icon name="el-icon-Loading" class="is-loading" style="color: #4a9ef8">
                </icon>
                <p style="margin-left: 5px">{{ uploadTxt }}</p>
            </div>
            <el-progress :percentage="percent" :format="format" style="width: 100%;" :color="colors"/>
        </div>
        <template #footer>
            <el-button v-if="uploadTxt=='上传成功'||uploadTxt=='上传失败'" @click="showDialog=false">关闭</el-button>
        </template>
    </el-dialog>

</template>

<script setup>
import OSS from 'ali-oss'
import SparkMD5 from 'spark-md5' // 依赖库，对文件进行md5加密唯一标识
import {onBeforeUnmount, onMounted, ref} from "vue";
import {Check} from '@element-plus/icons-vue'
import useCurrentInstance from '/@/utils/useCurrentInstance'
import icon from '/@/components/icon/index.vue'

const {proxy} = useCurrentInstance()

const emit = defineEmits(['update:data', 'success'])

let props = defineProps({
    data: {
        type: String,
        default: ''
    }
})


//实例化选择文件input
let inputRef = ref()

let showDialog = ref(false)
let uploadTxt = ref('')

//控制显示进度条
let showProgress = ref(false)

//进度条值
const percent = ref(0)

//进度条颜色
const colors = [
    {color: '#f56c6c', percentage: 20},
    {color: '#e6a23c', percentage: 40},
    {color: '#1989fa', percentage: 80},
    {color: '#5cb87a', percentage: 100},
]

//进度条格式化
function format(percentage) {
    return percentage === 100 ? '完成' : `${percentage}%`
}

// //在本地保存上传指针
// const pointerCache = {
//     get(file, name) {
//         const cache = localStorage.getItem('cacheKey')
//         if (!cache) return null
//         const cacheJson = JSON.parse(cache)
//         if (cacheJson.name !== name) return null
//         cacheJson.file = file
//         return cacheJson
//     },
//     set(pointer) {
//         localStorage.setItem('cacheKey', JSON.stringify(pointer))
//     },
//     remove() {
//         localStorage.removeItem('cacheKey')
//     }
// }

let file
const changFile = () => {
    file = inputRef.value.files[0]
    // console.log(file.name.split(".").pop())

    // showProgress.value = true
    showDialog.value = true
    uploadTxt.value = '为了保证文件的完整性，正在进行验证，请稍等！'
    getMd5BigFile(file).then(nameMd5 => {
        console.log('md5:' + nameMd5)
        upload(file, nameMd5)
    })

}

function getMd5(file) {
    return new Promise(resolve => {
        console.log('开始读取文件，计算MD5...')
        const spark = new SparkMD5.ArrayBuffer()
        const reader = new FileReader()
        reader.readAsArrayBuffer(file)
        // Indicator.open() // loading 文件过大的时候读取时间非常长
        reader.addEventListener('load', (e) => {
            spark.append(e.target.result);
            // Indicator.close()
            resolve(spark.end()) // 文件md5加密，放置重复上传
        })
    })
}

//大文件分片计算md5
function getMd5BigFile(file, chunkSize) {
    // 默认分片大小 2MB
    let defaultChunkSize = 1024 * 1024 * 20
    console.log('大文件分片计算')
    return new Promise((resolve, reject) => {
        chunkSize = chunkSize || defaultChunkSize

        let blobSlice =
                File.prototype.slice ||
                File.prototype.mozSlice ||
                File.prototype.webkitSlice,
            // 总分片数
            chunks = Math.ceil(file.size / chunkSize),
            currentChunk = 0,
            spark = new SparkMD5.ArrayBuffer(),
            fileReader = new FileReader()

        fileReader.onload = function (e) {
            console.log('read chunk nr', currentChunk + 1, 'of', chunks)
            spark.append(e.target.result) // Append array buffer
            currentChunk++

            if (currentChunk < chunks) {
                loadNext()
            } else {
                resolve(spark.end())
            }
        }

        fileReader.onerror = function (error) {
            reject(error)
        }

        function loadNext() {
            // 切片起始位置
            let start = currentChunk * chunkSize
            // 切片终止位置
            let end = start + chunkSize
            if (end >= file.size) {
                end = file.size
            }

            fileReader.readAsArrayBuffer(blobSlice.call(file, start, end))
        }

        loadNext()
    })
}

let ossConfig = {
    region: 'oss-cn-zhangjiakou',
    endpoint: 'oss-cn-zhangjiakou.aliyuncs.com',
    accessKeyId: 'LTAI4FxUN21uPgaoL5pxtQ89',
    accessKeySecret: 'p4GrNk6aOJ0jCfSYazRgLbnlQQPfac',
    bucket: 'shs-butket'
}

//获取当前桶下存储空间
async function listBuckets() {
    try {
        const client = new OSS(ossConfig);
        console.log(client)
        // 列举当前账号所有地域下的存储空间。
        let res = await client.listBuckets()
        console.log(res)
    } catch (err) {
        console.log(err);
    }
}

let checkpoint;//上传指针 或 断点
const upload = async (file, nameMd5) => {
    uploadTxt.value = '连接oss，开始上传...'
    const client = new OSS(ossConfig) // 阿里文件上传对象
    // checkpoint = pointerCache.get(file, nameMd5) // 断点续传指针
    // 失败后尝试五次
    for (let i = 0; i < 1; i++) {
        try {
            const result = await client.multipartUpload(nameMd5, file, {
                checkpoint,
                async progress(percentage, cpt) { // 上传进度
                    percent.value = parseInt(percentage * 100, 10)
                    // pointerCache.set(cpt)
                    checkpoint = cpt
                },
            })
            // pointerCache.remove()
            console.log('上传成功：', result)
            uploadTxt.value = '上传成功'
            emit('update:data', nameMd5)
            emit('success', {size: file.size, fileType: file.name.split(".").pop()})
            break
        } catch (e) {
            console.log('上传失败：', e)
            uploadTxt.value = '上传失败'
        }
    }
}


</script>

<style scoped>

</style>
