|
@@ -0,0 +1,352 @@
|
|
|
+<template>
|
|
|
+ <view class="media">
|
|
|
+ <!-- 图片 -->
|
|
|
+ <navigator url="#" class="item" v-for="(item, index) in files.images" :key="item.attachmentid">
|
|
|
+ <image :src="item.url" mode="aspectFill" @click="viewMedias(index, 'image')" />
|
|
|
+ <image v-if="isDelete" class="delete" src="../static/img/delete.png" @click.stop="handleDeleteFile(item)" />
|
|
|
+ </navigator>
|
|
|
+ <!-- 视频 -->
|
|
|
+ <navigator url="#" class="item" v-for="(item, index) in files.videos" :key="item.attachmentid">
|
|
|
+ <image :src="item.subfiles[0].url" mode="aspectFill" />
|
|
|
+ <view class="shade" @click="viewMedias(index, 'video')"><van-icon size='48rpx' name="play" /></view>
|
|
|
+ <image v-if="isDelete" class="delete" src="../static/img/delete.png" @click.stop="handleDeleteFile(item)" />
|
|
|
+ </navigator>
|
|
|
+ <!-- 文件 -->
|
|
|
+ <navigator url="#" class="item file" v-for="item in files.files" :key="item.attachmentid" @click="viewFlies">
|
|
|
+ <image class="image" :src="item.cover" mode="heightFix" />
|
|
|
+ <view class="name">{{ item.document }}</view>
|
|
|
+ <image v-if="isDelete" class="delete" src="../static/img/delete.png" @click.stop="handleDeleteFile(item)" />
|
|
|
+ </navigator>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+export default {
|
|
|
+ props: {
|
|
|
+ isDelete: {
|
|
|
+ type: Boolean
|
|
|
+ },
|
|
|
+ onDeteleFiles: {
|
|
|
+ type: Function
|
|
|
+ },
|
|
|
+ strict: {
|
|
|
+ type: Boolean,
|
|
|
+ default: true
|
|
|
+ },
|
|
|
+ aDeletion: {
|
|
|
+ type: Boolean,
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ files: {
|
|
|
+ images: [],
|
|
|
+ viewImages: [],
|
|
|
+ videos: [],
|
|
|
+ viewVideos: [],
|
|
|
+ files: []
|
|
|
+ },
|
|
|
+ }
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ /* 格式化附件 */
|
|
|
+ formattedFiles(list) {
|
|
|
+ if (list.length == 0) return [];
|
|
|
+ let suffixList = {
|
|
|
+ image: ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'webp', 'svg', 'tiff'],
|
|
|
+ video: ['mp4', 'ogg', 'webm'],
|
|
|
+ word: ['doc', 'docx'],
|
|
|
+ excel: ['xls', 'xlsx'],
|
|
|
+ ppt: ['ppt', 'pptx'],
|
|
|
+ txt: ['txt', 'md', 'js', 'json'],
|
|
|
+ pdf: ['pdf'],
|
|
|
+ rar: ['7z', 'zip', 'rar', 'kz', 'ace', 'arj', 'bz2', 'cab', 'gz', 'iso', 'jar', 'lzh', 'tar', 'z'],
|
|
|
+ folder: ['"folder"']
|
|
|
+ },
|
|
|
+ typeList = [];
|
|
|
+ for (let key in suffixList) typeList.push(key);
|
|
|
+ for (let i = 0; i < list.length; i++) {
|
|
|
+ list[i].fileType = 'unknown';
|
|
|
+ list[i].cover = `/static/file/unknown.png`
|
|
|
+ const suffix = list[i].postfix.toLowerCase();
|
|
|
+ if (suffix != "folder") {
|
|
|
+ for (var key in suffixList) {
|
|
|
+ if (suffixList[key].some(value => value == suffix)) {
|
|
|
+ list[i].fileType = key;
|
|
|
+ if (key == 'image') {
|
|
|
+ list[i].cover = list[i].url;
|
|
|
+ } else if (typeList.includes(key)) {
|
|
|
+ list[i].cover = `/static/file/${key}.png`;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ list[i].fileType = "folder";
|
|
|
+ list[i].cover = `/static/file/folder.png`
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ },
|
|
|
+ /* 删除文件 */
|
|
|
+ handleDeleteFile(item) {
|
|
|
+ let that = this;
|
|
|
+ if (this.strict) {
|
|
|
+ uni.showModal({
|
|
|
+ title: '提示',
|
|
|
+ content: '是否确定删除该附件',
|
|
|
+ complete: ({ confirm }) => {
|
|
|
+ if (confirm) start()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ start()
|
|
|
+ }
|
|
|
+ function start() {
|
|
|
+ if (that.aDeletion) return that.$emit("onDeteleFiles", {
|
|
|
+ deleteid: item.linksid,
|
|
|
+ attachmentid: item.attachmentid,
|
|
|
+ ...that.getFiles()
|
|
|
+ })
|
|
|
+ that.$Http.basic({
|
|
|
+ "classname": "system.attachment.Attachment",
|
|
|
+ "method": "deleteFileLink",
|
|
|
+ "content": {
|
|
|
+ "linksids": [item.linksid]
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (that.cutoff(res.msg)) return;
|
|
|
+ let files = that.files;
|
|
|
+ /* switch (item.fileType) {
|
|
|
+ case "image":
|
|
|
+ files.images = files.images.filter(v => v.url != item.url);
|
|
|
+ files.viewImages = files.viewImages.filter(v => v.url != item.url);
|
|
|
+ break;
|
|
|
+ case "video":
|
|
|
+ files.videos = files.videos.filter(v => v.url != item.url);
|
|
|
+ files.viewVideos = files.viewVideos.filter(v => v.url != item.url);
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ files.files = files.files.filter(v => v.attachmentid != item.attachmentid);
|
|
|
+ break;
|
|
|
+ };
|
|
|
+ that.files = files; */
|
|
|
+ that.$emit("onDeteleFiles", {
|
|
|
+ deleteid: item.linksid,
|
|
|
+ attachmentid: item.attachmentid,
|
|
|
+ ...that.getFiles()
|
|
|
+ })
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /* 处理附件 */
|
|
|
+ handleFiles(arr, init = false) {
|
|
|
+ let files = init ? {
|
|
|
+ images: [],
|
|
|
+ viewImages: [],
|
|
|
+ videos: [],
|
|
|
+ viewVideos: [],
|
|
|
+ files: []
|
|
|
+ } : this.files,
|
|
|
+ list = this.formattedFiles(arr);
|
|
|
+ list.forEach(v => {
|
|
|
+ switch (v.fileType) {
|
|
|
+ case "video":
|
|
|
+ files.videos.push(v)
|
|
|
+ files.viewVideos.push({
|
|
|
+ url: v.url,
|
|
|
+ type: "video",
|
|
|
+ poster: v.subfiles[0].url
|
|
|
+ })
|
|
|
+ break;
|
|
|
+ case "image":
|
|
|
+ files.images.push(v)
|
|
|
+ files.viewImages.push({
|
|
|
+ url: v.url,
|
|
|
+ type: "image"
|
|
|
+ })
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ files.files.push(v)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ this.files = files;
|
|
|
+ },
|
|
|
+ /* 初始化数据 */
|
|
|
+ initData() {
|
|
|
+ this.files = {
|
|
|
+ images: [],
|
|
|
+ viewImages: [],
|
|
|
+ videos: [],
|
|
|
+ viewVideos: [],
|
|
|
+ files: []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ /* 返回数据ID数组 用来换绑数据 */
|
|
|
+ getFiles() {
|
|
|
+ let data = {
|
|
|
+ attachmentids: [],
|
|
|
+ list: [],
|
|
|
+ },
|
|
|
+ files = this.files;
|
|
|
+ files.files.forEach(v => {
|
|
|
+ data.attachmentids.push(v.attachmentid);
|
|
|
+ data.list.push(v);
|
|
|
+ })
|
|
|
+ files.images.forEach(v => {
|
|
|
+ data.attachmentids.push(v.attachmentid);
|
|
|
+ data.list.push(v);
|
|
|
+ })
|
|
|
+ files.videos.forEach(v => {
|
|
|
+ data.attachmentids.push(v.attachmentid);
|
|
|
+ data.list.push(v);
|
|
|
+ });
|
|
|
+ return data
|
|
|
+ },
|
|
|
+ /* 预览媒体 */
|
|
|
+ viewMedias(index, type) {
|
|
|
+ // #ifndef MP
|
|
|
+ console.log(this.files.viewVideos)
|
|
|
+ if (type == 'image') {
|
|
|
+ uni.previewImage({
|
|
|
+ current: index,
|
|
|
+ urls: this.files.viewImages,
|
|
|
+ loop: true,
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ window.open(this.files.viewVideos[index].url)
|
|
|
+ }
|
|
|
+ // #endif
|
|
|
+ // #ifdef MP-WEIXIN
|
|
|
+ wx.previewMedia({
|
|
|
+ current: index,
|
|
|
+ sources: type == 'image' ? this.files.viewImages : this.files.viewVideos,
|
|
|
+ })
|
|
|
+ // #endif
|
|
|
+ },
|
|
|
+ /* 预览文档 */
|
|
|
+ viewFlies(e) {
|
|
|
+ const {
|
|
|
+ item
|
|
|
+ } = e.currentTarget.dataset;
|
|
|
+ uni.showLoading({
|
|
|
+ title: '加载中...',
|
|
|
+ })
|
|
|
+ uni.downloadFile({
|
|
|
+ url: item.url,
|
|
|
+ complete({
|
|
|
+ statusCode,
|
|
|
+ tempFilePath
|
|
|
+ }) {
|
|
|
+ if (statusCode != 200) return;
|
|
|
+ uni.openDocument({
|
|
|
+ filePath: tempFilePath,
|
|
|
+ fileType: item.postfix,
|
|
|
+ showMenu: true,
|
|
|
+ complete({
|
|
|
+ errMsg
|
|
|
+ }) {
|
|
|
+ uni.hideLoading();
|
|
|
+ if (errMsg != "openDocument:ok") uni.showToast({
|
|
|
+ title: '打开失败',
|
|
|
+ icon: "none"
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ deleteAll() {
|
|
|
+ let linksids = this.getFiles().list.map(v => v.linksid);
|
|
|
+ if (linksids.length) this.$Http.basic({
|
|
|
+ "classname": "system.attachment.Attachment",
|
|
|
+ "method": "deleteFileLink",
|
|
|
+ "content": {
|
|
|
+ linksids
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ console.log("删除所有未保存附件", linksids, res)
|
|
|
+ if (res.msg != '成功') return uni.showToast({
|
|
|
+ title: res.data,
|
|
|
+ icon: "none"
|
|
|
+ });
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.media {
|
|
|
+ width: 100%;
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ box-sizing: border-box;
|
|
|
+
|
|
|
+ .item {
|
|
|
+ position: relative;
|
|
|
+ width: 62px;
|
|
|
+ height: 62px;
|
|
|
+ margin-right: 6px;
|
|
|
+ margin-bottom: 6px;
|
|
|
+ border-radius: 4px;
|
|
|
+ overflow: hidden;
|
|
|
+
|
|
|
+ image {
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .delete {
|
|
|
+ position: absolute;
|
|
|
+ width: 20px;
|
|
|
+ height: 20px;
|
|
|
+ right: 0;
|
|
|
+ top: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .shade {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ position: absolute;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ background: rgba(0, 0, 0, 0.2);
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ color: #ffffff;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ .item:nth-child(5n) {
|
|
|
+ margin-right: 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .file {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ border: 1px solid #CCCCCC;
|
|
|
+ box-sizing: border-box;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .name {
|
|
|
+ width: 60px;
|
|
|
+ font-size: 12px;
|
|
|
+ font-family: PingFang SC-Regular, PingFang SC;
|
|
|
+ color: #333333;
|
|
|
+ margin-top: 10px;
|
|
|
+ overflow: hidden;
|
|
|
+ white-space: nowrap;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ }
|
|
|
+
|
|
|
+ .image {
|
|
|
+ height: 29px;
|
|
|
+ margin-top: 12rpx;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|