xwt
2025-08-02 efb6960d9a35857d8efa7e40a6e71504b87f5035
pages/QC/LLJ/ImageItem.vue
@@ -1,233 +1,306 @@
<template>
  <!-- #ifdef APP -->
  <scroll-view class="page-scroll-view">
    <!-- #endif -->
    <view>
      <view class="uni-common-mt">
        <view class="uni-list list-pd" style="padding: 15px;">
          <view class="uni-flex" style="margin-bottom: 10px;">
            <view class="uni-list-cell-left">点击可预览选好的图片</view>
            <view style="margin-left: auto;">
              <text class="click-t">{{ qsImage.length }}/{{ countIndex + 1 }}</text>
            </view>
          </view>
          <view class="uni-flex" style="flex-wrap: wrap;">
            <view v-for="(image,index) in qsImage" :key="index" class="uni-uploader__input-box"
                  style="position: relative; border: 0;">
              <image :src="image.img" :data-src="image.img"
                     @tap="previewImage(index)"></image>
              <image src="/static/plus.png" class="image-remove" @click="removeImage(index,image.id)"></image>
            </view>
            <image class="uni-uploader__input-box" @tap="chooseImage" src="/static/plus.png"></image>
          </view>
        </view>
      </view>
      <view class="plus-button">
        <button type="primary" class="upImg" @click="save">上传图片</button>
      </view>
    </view>
    <!-- #ifdef APP -->
  </scroll-view>
  <!-- #endif -->
</template>
   <!-- #ifdef APP -->
   <scroll-view class="page-scroll-view">
     <!-- #endif -->
     <view>
      <view class="uni-common-mt">
        <view class="uni-list list-pd" style="padding: 15px;">
         <view class="uni-flex" style="margin-bottom: 10px;">
           <view class="uni-list-cell-left">点击可预览选好的图片</view>
           <view style="margin-left: auto;">
            <text class="click-t">{{ qsImage.length }}/{{ countIndex + 1 }}</text>
           </view>
         </view>
         <view class="uni-flex" style="flex-wrap: wrap;">
           <view v-for="(image,index) in qsImage" :key="index" class="uni-uploader__input-box"
               style="position: relative; border: 0;">
            <image :src="image.img" :data-src="image.img"
                  @tap="previewImage(index)"></image>
            <image src="/static/plus.png" class="image-remove" @click="removeImage(index,image.id)"></image>
           </view>
           <image class="uni-uploader__input-box" @tap="chooseImage" src="/static/plus.png"></image>
         </view>
        </view>
      </view>
      <view class="plus-button">
        <button type="primary" class="upImg" @click="save">上传图片</button>
      </view>
     </view>
     <!-- #ifdef APP -->
   </scroll-view>
   <!-- #endif -->
  </template>
  <script>
  import {pathToBase64, base64ToPath} from '../../../js_sdk/mmmm-image-tools/index'
  var sourceTypeArray = [
   ['camera'],
   ['album'],
   ['camera', 'album']
  ]
  var sizeTypeArray = [
   ['compressed'],
   ['original'],
   ['compressed', 'original']
  ]
  export default {
   data() {
     return {
      title: 'choose/previewImage',
      sourceTypeIndex: 2,
      sourceType: ['拍照', '相册', '拍照或相册'],
      sizeTypeIndex: 2,
      sizeType: ['压缩', '原图', '压缩或原图'],
      countIndex: 8,
      count: [1, 2, 3, 4, 5, 6, 7, 8, 9],
      isCrop: false,
      cropPercent: 80,
      cropWidth: 100,
      cropHeight: 100,
      cropResize: false,
      qsImage: [],
      fid: 0,
     }
   },
   onLoad(options) {
     //options中包含了url附带的参数
     let params = options;
     if (params["id"]) {
      this.fid = params["id"];
      //getQaItemXj02
      this.init();
     }
   },
   onUnload() {
     this.qsImage = [];
     this.sourceTypeIndex = 2
     this.sourceType = ['拍照', '相册', '拍照或相册']
     this.sizeTypeIndex = 2
     this.sizeType = ['压缩', '原图', '压缩或原图']
     this.countIndex = 8
   },
   methods: {
     removeImage(index, id) {
      this.qsImage.splice(index, 1);
      if (id) {
        this.$post({
         url: "/Base/removeImage",
         data: {
           id: id
         }
        }).then(res => {
        });
      }
     },
     chooseImage() {
      if (this.qsImage.length >= 9) {
        uni.showToast({
         position: "bottom",
         title: "已经有9张图片了,请删除部分图片之后重新选择"
        });
        return;
      }
      uni.chooseImage({
        sourceType: sourceTypeArray[this.sourceTypeIndex],
        sizeType: sizeTypeArray[this.sizeTypeIndex],
        crop: this.isCrop ? {
         "quality": this.cropPercent,
         "width": this.cropWidth,
         "height": this.cropHeight,
         "resize": this.cropResize
        } : null,
        count: this.qsImage.length + this.count[this.countIndex] > 9 ? 9 - this.qsImage.length : this.count[this.countIndex],
        success: (res) => {
         let url = res.tempFilePaths[0];
         pathToBase64(url)
            .then(base64 => {
              // 找到最后一个斜杠的位置
              let lastSlashIndex = url.lastIndexOf("/");
              // 提取文件名
              let fileName = url.substring(lastSlashIndex + 1);
              let entity = {};
              entity.img = base64;
              entity.Picturename = fileName;
              entity.fid = this.fid;
              entity.qsType = 4;
              entity.base64Date = base64.split(',')[1];
              this.qsImage.push(entity);
            })
            .catch(error => {
              console.error(error)
            })
        },
        fail: (err) => {
         console.log("err: ", JSON.stringify(err));
        }
      });
     },
     previewImage(index) {
      // 检查当前图片是否存在
      const currentImage = this.qsImage[index];
      if (!currentImage || !currentImage.img) {
         uni.showToast({
            title: '图片数据异常',
            icon: 'none'
         });
         return;
      }
<script>
      // 显示加载提示
      uni.showLoading({
         title: '加载中...'
      });
import {pathToBase64, base64ToPath} from '../../../js_sdk/mmmm-image-tools/index'
      // 如果是base64格式,需要转换为临时文件路径
      if (currentImage.img.startsWith('data:')) {
         // 转换所有base64图片为临时文件路径
         const convertPromises = this.qsImage.map(item => {
            if (item.img.startsWith('data:')) {
               return base64ToPath(item.img);
            }
            return Promise.resolve(item.img);
         });
var sourceTypeArray = [
  ['camera'],
  ['album'],
  ['camera', 'album']
]
var sizeTypeArray = [
  ['compressed'],
  ['original'],
  ['compressed', 'original']
]
export default {
  data() {
    return {
      title: 'choose/previewImage',
      sourceTypeIndex: 2,
      sourceType: ['拍照', '相册', '拍照或相册'],
      sizeTypeIndex: 2,
      sizeType: ['压缩', '原图', '压缩或原图'],
      countIndex: 8,
      count: [1, 2, 3, 4, 5, 6, 7, 8, 9],
      isCrop: false,
      cropPercent: 80,
      cropWidth: 100,
      cropHeight: 100,
      cropResize: false,
      qsImage: [],
      fid: 0,
    }
  },
  onLoad(options) {
    //options中包含了url附带的参数
    let params = options;
    if (params["id"]) {
      this.fid = params["id"];
      //getQaItemXj02
      this.init();
    }
  },
  onUnload() {
    this.qsImage = [];
    this.sourceTypeIndex = 2
    this.sourceType = ['拍照', '相册', '拍照或相册']
    this.sizeTypeIndex = 2
    this.sizeType = ['压缩', '原图', '压缩或原图']
    this.countIndex = 8
  },
  methods: {
    removeImage(index, id) {
      this.qsImage.splice(index, 1);
      if (id) {
        this.$post({
          url: "/Base/removeImage",
          data: {
            id: id
          }
        }).then(res => {
        });
      }
    },
    chooseImage() {
      if (this.qsImage.length >= 9) {
        uni.showToast({
          position: "bottom",
          title: "已经有9张图片了,请删除部分图片之后重新选择"
        });
        return;
      }
      uni.chooseImage({
        sourceType: sourceTypeArray[this.sourceTypeIndex],
        sizeType: sizeTypeArray[this.sizeTypeIndex],
        crop: this.isCrop ? {
          "quality": this.cropPercent,
          "width": this.cropWidth,
          "height": this.cropHeight,
          "resize": this.cropResize
        } : null,
        count: this.qsImage.length + this.count[this.countIndex] > 9 ? 9 - this.qsImage.length : this.count[this.countIndex],
        success: (res) => {
          let url = res.tempFilePaths[0];
          pathToBase64(url)
              .then(base64 => {
                // 找到最后一个斜杠的位置
                let lastSlashIndex = url.lastIndexOf("/");
                // 提取文件名
                let fileName = url.substring(lastSlashIndex + 1);
                let entity = {};
                entity.img = base64;
                entity.Picturename = fileName;
                entity.fid = this.fid;
                entity.qsType = 4;
                entity.base64Date = base64.split(',')[1];
                this.qsImage.push(entity);
              })
              .catch(error => {
                console.error(error)
              })
        },
        fail: (err) => {
          console.log("err: ", JSON.stringify(err));
        }
      });
    },
    previewImage(index) {
      // uni.previewImage({
      //   current: index, // 设置当前显示图片的链接
      //   urls: this.qsImage.map(s=>s.img), // 需要预览的图片链接列表
      //   loop: false, // 是否开启图片轮播,默认为 false
      //   indicator: 'default',// 图片指示器类型,可选值为 "default"、"number"、"pointer",默认为 "default"
      // });
    },
    init() {
      this.$post({
        url: "/Base/getByFid",
        data: {
          fid: this.fid,
          qsType: 4
        }
      }).then(res => {
        let tableData = res.data.tbBillList;
        this.qsImage = tableData;
        this.qsImage.forEach(s => {
          s.img = 'data:image/png;base64,' + s.base64Date;
        });
      });
    },
    save() {
      this.$post({
        url: "/Base/saveImage",
        data: {
          entity: this.qsImage
        }
      }).then(res => {
        this.init();
        this.$showMessage("保存成功");
      });
    }
         Promise.all(convertPromises)
            .then(tempFilePaths => {
               uni.hideLoading();
               uni.previewImage({
                  current: tempFilePaths[index],
                  urls: tempFilePaths,
                  loop: false,
                  indicator: 'default',
                  fail: (err) => {
                     console.error('预览失败:', err);
                     uni.showToast({
                        title: '预览失败',
                        icon: 'none'
                     });
                  }
               });
            })
            .catch(error => {
               uni.hideLoading();
               console.error('转换失败:', error);
               uni.showToast({
                  title: '图片转换失败',
                  icon: 'none'
               });
            });
      } else {
         // 如果不是base64格式,直接预览
         uni.hideLoading();
         uni.previewImage({
            current: index,
            urls: this.qsImage.map(s => s.img),
            loop: false,
            indicator: 'default',
            fail: (err) => {
               console.error('预览失败:', err);
               uni.showToast({
                  title: '预览失败',
                  icon: 'none'
               });
            }
         });
      }
     },
     init() {
      this.$post({
        url: "/Base/getByFid",
        data: {
         fid: this.fid,
         qsType: 4
        }
      }).then(res => {
        let tableData = res.data.tbBillList;
        this.qsImage = tableData;
        this.qsImage.forEach(s => {
         // 根据文件扩展名判断图片类型,默认为jpeg
         let imageType = 'jpeg';
         if (s.Picturename) {
            const ext = s.Picturename.toLowerCase().split('.').pop();
            if (ext === 'png') {
               imageType = 'png';
            } else if (ext === 'gif') {
               imageType = 'gif';
            } else if (ext === 'webp') {
               imageType = 'webp';
            }
         }
         s.img = `data:image/${imageType};base64,${s.base64Date}`;
        });
      });
     },
     save() {
      this.$post({
        url: "/Base/saveImage",
        data: {
         entity: this.qsImage
        }
      }).then(res => {
        this.init();
        this.$showMessage("保存成功");
      });
     }
   }
  }
}
</script>
<style>
.click-t {
  color: darkgray;
}
.list-pd {
  margin-top: 25px;
}
.uni-uploader__input-box {
  margin: 5px;
  border: 1px solid #D9D9D9;
}
.image-remove {
  transform: rotate(45deg);
  width: 25px;
  height: 25px;
  position: absolute;
  top: 0;
  right: 0;
  border-radius: 13px;
  background-color: #FF0000;
}
.uni-common-mt {
  background-color: #ffffff;
  /* 红色背景 */
}
.plus-button {
  position: fixed;
  left: 0;
  bottom: 0;
  width: 100%;
  background-color: #ffffff; /* 背景颜色 */
  /* padding: 10px; */
  box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1); /* 添加底部阴影效果 */
  z-index: 999; /* 确保按钮位于顶层 */
}
.uni-flex {
  max-height: calc(100vh - 240px); /* 屏幕高度减去上传按钮高度 */
  overflow-y: auto; /* 当内容超出高度时出现垂直滚动条 */
}
.upImg{
     background-color: #3498db;
     color: white;
}
</style>
  </script>
  <style>
  .click-t {
   color: darkgray;
  }
  .list-pd {
   margin-top: 25px;
  }
  .uni-uploader__input-box {
   margin: 5px;
   border: 1px solid #D9D9D9;
  }
  .image-remove {
   transform: rotate(45deg);
   width: 25px;
   height: 25px;
   position: absolute;
   top: 0;
   right: 0;
   border-radius: 13px;
   background-color: #FF0000;
  }
  .uni-common-mt {
   background-color: #ffffff;
   /* 红色背景 */
  }
  .plus-button {
   position: fixed;
   left: 0;
   bottom: 0;
   width: 100%;
   background-color: #ffffff; /* 背景颜色 */
   /* padding: 10px; */
   box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1); /* 添加底部阴影效果 */
   z-index: 999; /* 确保按钮位于顶层 */
  }
  .uni-flex {
   max-height: calc(100vh - 240px); /* 屏幕高度减去上传按钮高度 */
   overflow-y: auto; /* 当内容超出高度时出现垂直滚动条 */
  }
  .upImg{
      background-color: #3498db;
      color: white;
  }
  </style>