AngularJS仿微信文件缓存指令

AvicFile 是一个用于缓存和展示不同类型的文件(包括图片、视频和其他文件)的 Angular 指令组件。它支持缓存文件到本地,并提供缓存进度指示和文件打开功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 使用示例:

<avic-file file-src="{{testFileUrl}}" file-type="file"complete-callback="down">
    <div style="text-align:center;background:#eee;margin:5px;padding:25px">点击缓存附件</div>
</avic-file>

2. 参数说明:

file-src文件网络地址,缓存后下次无需重新下载,网址即为本地缓存文件名,

a. 浏览器缓存路径为:filesystem:http://{{address:port}}/temporary/avicit_portal/cache/;

b. Android缓存路径为:context.getFilesDir().toString() + "/files/avicit_portal/cache/(可自行设置AVIC_CACHE_PATH;

file-type强制文件类型,该值优先级大于后缀类型。

a. 当传入’file’或不传时,无论网络地址是否为图片都认定为文件附件,用户第一次点击时开始缓存,第二次点击则用file-openner打开;

b. 当传入’image’时,强制认定为图片格式并自动加载,适用于无后缀名的网络图片地址,如 http://dwz.cn/6Jxqci

complete-callback文件缓存展示完毕回调,此处应传入函数类型(不加括号)。

3. 样式说明:

附件样式:可自定义附件样式放于指令标签内,该内容会继续保留(ng-transclude)。

下载状态:指令添加单独的标签用于显示下载进度条及下载状态,无需设置。

图片高宽:样式直接设置在avic-file标签上即可,如<avic-file class=”myClass”></avic-file>



4. 流程图


5. 源码

angular.module('avicfile.directives', [])
    .directive('avicFile', function ($cordovaFile, $ionicPlatform, $cordovaFileTransfer, $timeout) {
        // const AVIC_CACHE_PATH = cordova.file.externalRootDirectory + 'Download/';
        // const AVIC_CACHE_PATH = 'file:///storage/emulated/0/' + 'Download/';
        const IMAGE = 'image';
        const VIDEO = 'file';
        const FILE = 'file';

        /**
         * 控制下载进度条
         * @param element
         * @param percentage 当100%时进度条消失
         */
        function changeProgress(element, percentage) {
            var template = '<div id="avic-file-cache-status" style="float: left;margin-left: 5%;margin-top: 5px;width: 90%; height: 5px; background-color: #ccc;">' +
                '<span style="display: block; width: ' + percentage + '%; height: 5px; background-color: #007aff;"></span>' +
                '</div>';
            if (element.lastChild && element.lastChild.id == 'avic-file-cache-status') {
                element.lastChild.outerHTML = template;
            } else {
                element.innerHTML += template;
            }
        }

        function showTemplate(element, src, type, status) {
            if (!fs.isCordova) {
                src = rootPath + src;
            }
            var template;
            if (!type) {
                type = getFileType(fileName);
            }
            switch (type) {
                case IMAGE:
                    template = '<img src="' + src + '" width="100%" ></img>';
                    element.innerHTML = template;
                    break;
                case FILE:
                // template = '<div><div style="text-align:center; background: #eee;margin: 5px;padding: 25px">打开' + getPointType(src) + '文件</div></div>';
                case VIDEO:
                // template = '<video src="' + src + '" width="100%" height="auto" controls="controls">您的浏览器不支持 video 标签。</video>';
                default:
                    template = '<p style="position: absolute;right: 20px;bottom: 6px;color: ' + (status == '已下载' ? '#999' : '#387ef5') + ';" id="avic-file-cache-status">' + status + '</p >';
                    if (element.lastChild && element.lastChild.id == 'avic-file-cache-status') {
                        element.lastChild.outerHTML = template;
                    } else {
                        element.innerHTML += template;
                    }
            }
        }

        /**
         * 获取后缀名
         * @param name
         * @returns {*}
         */
        function getPointType(name) {
            if (!name) {
                return 'nothing';
            }
            var arr = name.split('.');
            var type = arr[arr.length - 1];
            return type;
        }

        /**
         * 通过后缀名获取文件类型
         * @param name
         * @returns IMAGE为图片
         * @returns VIDEO为视频
         * @returns FILE为文件
         */
        function getFileType(name) {
            var type = getPointType(name);
            var res = 'unknown';
            switch (type) {
                case 'doc':
                case 'docx':
                case 'xls' :
                case 'xlsx':
                case 'txt':
                case 'ppt':
                case 'pptx':
                case 'pdf':
                    res = FILE;
                    break;
                case 'ogg':
                    ;
                case 'webm':
                    ;
                case 'mp4':
                    res = VIDEO;
                    break;
                case 'jpg':
                    ;
                case 'jpeg':
                    ;
                case 'png':
                    ;
                case 'gif':
                    ;
                case 'bmp':
                    ;
                case 'webp':
                default:
                    res = IMAGE;
            }
            return res;
        }

        /**
         * 缓存文件
         * @param url
         * @param targetPath
         */
        function downFile(url, targetPath, element, fileType, callback) {
            var trustHosts = true;
            var options = {};
            console.log('url : ' + url);
            console.log('targetPath : ' + targetPath);
            $cordovaFileTransfer.download(url, targetPath, options, trustHosts)
                .then(function (result) {
                    console.log(JSON.stringify(result));
                    $timeout(function () {
                        showTemplate(element, targetPath, fileType, '已下载');
                        if (typeof callback == 'function') {
                            callback();
                        }
                    }, 500)
                }, function (err) {
                    console.log(JSON.stringify(err));
                    alert('附件缓存失败');
                }, function (progress) {
                    $timeout(function () {
                        var percentage = (progress.loaded / progress.total) * 100;
                        console.log(percentage);
                        changeProgress(element, percentage);
                    });
                });
            // fs.download(url, targetPath, {retry: self._retry}, function (proces) {
            //     var percentage = proces.loaded / proces.total * 100;
            //     console.log(percentage + "% - loaded : " + proces.loaded + ": total : " + proces.total);
            //     changeProgress(element, percentage);
            // }).then(function (done) {
            //     console.log(JSON.stringify(done));
            //     $timeout(function(){
            //         showTemplate(element, targetPath, fileType, '已下载');
            //     },500)
            //
            // }, function (err) {
            //     console.log(JSON.stringify(err));
            //     alert('附件缓存失败');
            // });
        }

        /**
         * 通过file-opener2插件打开文件
         * @param path
         */
        function openFile(path) {
            var mime;
            var type = getPointType(path);
            switch (type) {
                case 'html':
                case 'htm':
                    mime = 'text/html';
                    break;
                case 'jpeg':
                case 'jpg':
                case 'jpe':
                    mime = 'image/jpeg';
                    break;
                case 'mp4':
                case 'mp4v':
                case 'mpg4':
                    mime = 'video/mp4';
                    break;
                case 'png':
                    mime = 'image/png';
                    break;
                case 'gif':
                    mime = 'image/gif';
                    break;
                case 'bmp':
                    mime = 'image/bmp';
                    break;
                case 'wbmp':
                    mime = 'image/vnd.wap.wbmp';
                    break;
                case 'apk':
                    mime = 'application/vnd.android.package-archive';
                    break;
                case 'json':
                    mime = 'application/json';
                    break;
                case 'dot':
                case 'doc':
                    mime = 'application/msword';
                    break;
                case 'docx':
                    mime = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
                    break;
                case 'xls' :
                    mime = 'application/vnd.ms-excel';
                    break;
                case 'xlsx':
                    mime = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
                    break;
                case 'txt':
                case 'text':
                case 'conf':
                case 'def':
                case 'list':
                case 'log':
                case 'in':
                    mime = 'text/plain';
                    break;
                case 'ppt':
                case 'pps':
                case 'pot':
                    mime = 'application/vnd.ms-powerpoint';
                    break;
                case 'pptx':
                    mime = 'application/vnd.openxmlformats-officedocument.presentationml.presentation';
                    break;
                case 'pdf':
                    mime = 'application/pdf';
                    break;
                default:
                    break;
            }
            cordova.plugins.fileOpener2.open(
                path, // You can also use a Cordova-style file uri: cdvfile://localhost/persistent/Download/starwars.pdf
                mime,
                {
                    error: function (e) {
                        console.log('Error status: ' + e.status + ' - Error message: ' + e.message);
                    },
                    success: function () {
                        console.log('file opened successfully');
                    }
                }
            );
        }

        return {
            restrict: 'E',
            template: function (elem, attr) {
                return '<div ng-click="downOrOpen()" ng-transclude=""></div>';
            },
            // scope: true,    //使用独立scope,防止指令之间的相互干扰
            scope: {
                completeCallback: '='
            },
            replace: true,
            transclude: true,
            link: function ($scope, $element, $attrs, controller) {
                var fileName = $attrs.fileSrc.replace(/\/|\\|:|\*|\||\?|%|'|"|<|>/g, '_');
                $ionicPlatform.ready(function () {
                    if (fs.isCordova) {
                        AVIC_CACHE_PATH = cordova.file.externalRootDirectory + 'Download/';
                        $cordovaFile.checkFile(AVIC_CACHE_PATH, fileName)
                            .then(function (success) {
                                console.log(JSON.stringify(success));
                                console.log('link - fileEntry:showTemplate');
                                showTemplate($element[0], AVIC_CACHE_PATH + fileName, $attrs.fileType, '已下载');
                                if (typeof $scope.completeCallback == 'function') {
                                    $scope.completeCallback();
                                }
                            }, function (error) {
                                console.log(JSON.stringify(error));
                                if ($attrs.fileType == 'image') {
                                    console.log('link - download');
                                    downFile($attrs.fileSrc, AVIC_CACHE_PATH + fileName, $element[0], $attrs.fileType, $scope.completeCallback);
                                } else {
                                    console.log('link - fail:showTemplate');
                                    showTemplate($element[0], AVIC_CACHE_PATH + fileName, $attrs.fileType, '未下载');
                                    if (typeof $scope.completeCallback == 'function') {
                                        $scope.completeCallback();
                                    }
                                }
                            });
                    } else {
                        AVIC_CACHE_PATH = APPNAME + '/cache/'
                        fs.exists(AVIC_CACHE_PATH + fileName)
                            .then(function (success) {
                                console.log(JSON.stringify(success));
                                console.log('link - fileEntry:showTemplate');
                                showTemplate($element[0], AVIC_CACHE_PATH + fileName, $attrs.fileType, '已下载');
                                if (typeof $scope.completeCallback == 'function') {
                                    $scope.completeCallback();
                                }
                            }, function (error) {
                                console.log(JSON.stringify(error));
                                if ($attrs.fileType == 'image') {
                                    console.log('link - download');
                                    downFile($attrs.fileSrc, AVIC_CACHE_PATH + fileName, $element[0], $attrs.fileType, $scope.completeCallback);
                                } else {
                                    console.log('link - fail:showTemplate');
                                    showTemplate($element[0], AVIC_CACHE_PATH + fileName, $attrs.fileType, '未下载');
                                    if (typeof $scope.completeCallback == 'function') {
                                        $scope.completeCallback();
                                    }
                                }
                            });
                    }

                });

                $scope.downOrOpen = function () {
                    console.log('downOrOpen - fileType: ' + $attrs.fileType);
                    if ('file' == $attrs.fileType) {
                        console.log('downOrOpen - ' + AVIC_CACHE_PATH + fileName)
                        // $cordovaFile.checkFile(AVIC_CACHE_PATH, fileName)
                        if (fs.isCordova) {
                            $cordovaFile.checkFile(AVIC_CACHE_PATH, fileName)
                                .then(function (fileEntry) {
                                        console.log('downOrOpen - openFile');
                                        showTemplate($element[0], AVIC_CACHE_PATH + fileName, $attrs.fileType, '已下载');//防止多个指令同一源情况显示下载状态错误
                                        openFile(AVIC_CACHE_PATH + fileName);
                                    },
                                    function (fail) {
                                        console.log('downOrOpen - download');
                                        downFile($attrs.fileSrc, AVIC_CACHE_PATH + fileName, $element[0], $attrs.fileType, $scope.completeCallback());
                                    });
                        } else {
                            fs.exists(AVIC_CACHE_PATH + fileName)
                                .then(function (fileEntry) {
                                        console.log('downOrOpen - openFile');
                                        showTemplate($element[0], AVIC_CACHE_PATH + fileName, $attrs.fileType, '已下载');
                                    },
                                    function (fail) {
                                        console.log('downOrOpen - download');
                                        downFile($attrs.fileSrc, AVIC_CACHE_PATH + fileName, $element[0], $attrs.fileType, $scope.completeCallback());
                                    });
                        }
                    }
                }
            }
        }
    });



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值