diff --git a/src/pages/me/index.vue b/src/pages/me/index.vue
index e3bf2b8..c4f0b23 100644
--- a/src/pages/me/index.vue
+++ b/src/pages/me/index.vue
@@ -81,11 +81,16 @@
               <img src="/static/image/mine/wdtj.png" style="width: 24px;height: 24px;">
             </template>
           </u-cell>
-        	<u-cell size="large" title="我的题库" :value="carName" isLink @tap="toChangeCarType">
+        	<u-cell size="large" title="我的题库" :value="carName" @tap="toChangeCarType">
             <template #icon>
               <img src="/static/image/mine/wdtk.png" style="width: 24px;height: 24px;">
             </template>
           </u-cell>
+					<u-cell size="large" title="联系我们" @tap="callPhoneNumber">
+					  <template #icon>
+					    <img src="/static/image/mine/callme.png" style="width: 24px;height: 24px;">
+					  </template>
+					</u-cell>
         </u-cell-group>
       </view>
       <view v-if="isLogin" class="flex ai-c jc-c mt12 br8 bc-fff" style="height: 50px;" @tap="handleLogout">
@@ -146,6 +151,12 @@ export default {
     this.carName = storage.get('carName') || '小车C1/C2/C3'
   },
   methods: {
+		// 拨打电话
+		callPhoneNumber() {
+		  uni.makePhoneCall({
+		    phoneNumber: '15105693067'
+		  });
+		},
     toChangeCarType() {
       uni.navigateTo({
         url: "/pages/me/changeCarType"
diff --git a/src/pages/questionBank/components/Question.vue b/src/pages/questionBank/components/Question.vue
index 08331a4..4777f26 100644
--- a/src/pages/questionBank/components/Question.vue
+++ b/src/pages/questionBank/components/Question.vue
@@ -7,9 +7,8 @@
 						:class="tCurrent==item.value?'checked':'unchecked'" @tap="sectionChange(item.value)">{{item.label}}</view>
 				</view>
 			</view>
-			<swiper class="swiper mt20" :current="swiperIndex" :duration="duration" :autoplay="false"
-				 @change="onChange" @animationfinish="onAnimationfinish"
-				@touchend="touchEnd">
+			<swiper class="swiper mt20" :current="swiperIndex" :duration="duration" :autoplay="false" @change="onChange"
+				@animationfinish="onAnimationfinish" @touchend="touchEnd">
 				<swiper-item v-for="(quesItem,quesIndex) in swiperList" :key="quesIndex.questionId">
 					<scroll-view scroll-y="true" class="swiper-scroll">
 						<view>
@@ -17,8 +16,10 @@
 								<text class="tag_box">{{getQuestType(quesItem.type)}}</text>
 								<text class="fs18" style="line-height: 42rpx;vertical-align: middle;">{{quesItem.question}}</text>
 							</view>
-							<view class="p14" v-if="quesItem.imageUrl">
-								<image v-show="quesItem.imageUrl" style="width: 100%;height: auto;" mode="widthFix" :lazy-load="true" @load="onoff='1'" :src="quesItem.imageUrl"></image>
+							<view class="p14 flex jc-c ai-c" v-if="quesItem.imageUrl">
+								<image v-show="quesItem.imageUrl" style="width: auto;max-height:40vh;" mode="heightFix"
+									:lazy-load="true" @load="onoff='1'" :src="quesItem.imageUrl" @click="preview(quesItem.imageUrl)">
+								</image>
 							</view>
 							<template v-if="quesItem.type!='3'">
 								<view class="flex m14lr ai-c mt20" v-for="(item,index) in quesItem.optionList" :key="item.op"
@@ -41,7 +42,8 @@
 									v-if="quesItem.clickAnswer&&!quesItem.trueAnswer.includes(quesItem.clickAnswer) || showBestAnswer">
 									<view class="answer_box">
 										<text class="fs18 fw600 cor-000">答案:{{getRightOp(quesItem.trueAnswer)}}</text>
-										<view v-if="showSkillInfo==='show'&&quesItem.skillInfo" class="fs18 cor-000 mt5">答题技巧:{{quesItem.skillInfo}}</view>
+										<view v-if="showSkillInfo==='show'&&quesItem.skillInfo" class="fs18 cor-000 mt5">
+											答题技巧:{{quesItem.skillInfo}}</view>
 									</view>
 									<view class="flex ai-c jc-c mt10">
 										<view style="height: 6rpx;width: 120rpx;background-color: rgb(232, 232, 232);"></view>
@@ -50,7 +52,10 @@
 									</view>
 									<view class="mt10">
 										<view class="fw600 cor-000 mb10 flex ai-c">
-											<view style="background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%);height: 36rpx;width: 8rpx;" class="mr5"></view>题目解析</view>
+											<view
+												style="background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%);height: 36rpx;width: 8rpx;"
+												class="mr5"></view>题目解析
+										</view>
 										<view style="text-indent:2em;">{{quesItem.bestAnswer}}</view>
 									</view>
 								</view>
@@ -92,24 +97,29 @@
 								<view class="m14lr mt30" v-if="isShowAnswer">
 									<view class="answer_box">
 										<text class="fs18 fw600 cor-000">答案:{{getRightOp(quesItem.trueAnswer)}}</text>
-										<view v-if="showSkillInfo==='show'&&quesItem.skillInfo" class="fs18 cor-000"> 答题技巧:{{quesItem.skillInfo}}</view>
-										</view>
-										<view class="flex ai-c jc-c mt10">
-											<view style="height: 6rpx;width: 120rpx;background-color: rgb(232, 232, 232);"></view>
-											<view class="fs18 fw600 cor-000 p15lr">试题详解</view>
-											<view style="height: 6rpx;width: 120rpx;background-color: rgb(232, 232, 232);"></view>
-										</view>
-										<view class="mt10">
-											<view class="fw600 cor-000 mb10 flex ai-c">
-												<view style="background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%);height: 36rpx;width: 8rpx;" class="mr5"></view>题目解析</view>
-											<view style="text-indent:2em;">{{quesItem.bestAnswer}}</view>
+										<view v-if="showSkillInfo==='show'&&quesItem.skillInfo" class="fs18 cor-000">
+											答题技巧:{{quesItem.skillInfo}}</view>
+									</view>
+									<view class="flex ai-c jc-c mt10">
+										<view style="height: 6rpx;width: 120rpx;background-color: rgb(232, 232, 232);"></view>
+										<view class="fs18 fw600 cor-000 p15lr">试题详解</view>
+										<view style="height: 6rpx;width: 120rpx;background-color: rgb(232, 232, 232);"></view>
+									</view>
+									<view class="mt10">
+										<view class="fw600 cor-000 mb10 flex ai-c">
+											<view
+												style="background: linear-gradient(90deg, #11DF20 0%, #00B74F 100%);height: 36rpx;width: 8rpx;"
+												class="mr5"></view>题目解析
 										</view>
+										<view style="text-indent:2em;">{{quesItem.bestAnswer}}</view>
+									</view>
 								</view>
 							</template>
 						</view>
 					</scroll-view>
 				</swiper-item>
 			</swiper>
+			<q-previewImage ref="previewRef" :urls="imgs" @open="open"></q-previewImage>
 			<view class="wp100 flex jc-sb ai-c p14 bc-fff" v-if="isShowAll" style="position: fixed;bottom: 0;left: 0;">
 				<view style="width: 220rpx;">
 					<view v-if="type==='practice'" style="width: 220rpx;height: 80rpx;"></view>
@@ -232,8 +242,8 @@
 						</view>
 					</view>
 					<view class="flex ai-c jc-fs p14" style="flex-wrap: wrap;max-height: 400px;overflow-y: scroll;">
-						<view v-for="(item,index) of questionList" :key="item.questionId" style="width:20%;position: relative;" class="flex ai-c jc-c"
-							@tap="chooseQueston(index)">
+						<view v-for="(item,index) of questionList" :key="item.questionId" style="width:20%;position: relative;"
+							class="flex ai-c jc-c" @tap="chooseQueston(index)">
 							<view class="tCircle mb10" :class="{
 											'active':index == topicIndex,
 											'success':type=='exam'?rightList.includes(item.questionId):storageRightList.includes(item.questionId),
@@ -241,8 +251,8 @@
 										}">
 								{{index+1}}
 							</view>
-							<u-icon name="star-fill" v-if="collectList.includes(item.questionId)" style="position: absolute;right: 5px;top:-3px"
-								color="rgb(249,236,141)" size="24"></u-icon>
+							<u-icon name="star-fill" v-if="collectList.includes(item.questionId)"
+								style="position: absolute;right: 5px;top:-3px" color="rgb(249,236,141)" size="24"></u-icon>
 						</view>
 					</view>
 				</view>
@@ -317,10 +327,11 @@
 		},
 		data() {
 			return {
-				subject:'1',
-				showSkillInfo:'hidden',
-				currentType:storage.get('carType') || '1001',
-				onoff:'0',
+				imgs: [],
+				subject: '1',
+				showSkillInfo: 'hidden',
+				currentType: storage.get('carType') || '1001',
+				onoff: '0',
 				navTitle: '',
 				originArray: '',
 				showBestAnswer: false,
@@ -333,7 +344,7 @@
 				tCurrent: 0,
 				index: 0,
 				qIndex: 0,
-				storageRightList:storage.get(`rightList_subject${this.subject}`) || [],
+				storageRightList: storage.get(`rightList_subject${this.subject}`) || [],
 				storageWrongList: storage.get(`wrongList_subject${this.subject}`) || [],
 				rightList: [],
 				wrongList: [],
@@ -348,9 +359,9 @@
 			}
 		},
 		created() {
-			const carType=storage.get('carType') || '1001'
-			querySysConfig(carType, 'NeedSkillInfo').then(resp=>{
-				if(resp.code === '0000'){
+			const carType = storage.get('carType') || '1001'
+			querySysConfig(carType, 'NeedSkillInfo').then(resp => {
+				if (resp.code === '0000') {
 					this.showSkillInfo = resp.data.configValue
 				}
 			})
@@ -377,12 +388,27 @@
 
 			},
 			timeCount() {
-				const time =  45 * 60 * 1000
+				const time = 45 * 60 * 1000
 				return time
 			}
 		},
 		methods: {
 			...mapActions(useQuestionStore, ['getCurrentIndex']),
+			open() {
+
+			},
+			preview(url) {
+				this.imgs = [url] //设置图片数组
+				// #ifdef MP-WEIXIN
+				this.$nextTick(() => {
+					this.imgs = [url]
+					setTimeout(()=>{
+						this.$refs.previewRef.open(url);
+					},500)
+				})
+				// #endif
+
+			},
 			getOriginArr(val) {
 				const arr = JSON.parse(val)
 				let arr1 = []
@@ -536,11 +562,11 @@
 			toSubmit() {
 				const restTime = this.time.hours * 60 * 60 + this.time.minutes * 60 + this.time.seconds
 				const score = (this.rightList.length / this.questionList.length * 100).toFixed(0)
-				if(this.rightList.length+this.wrongList.length==0){
+				if (this.rightList.length + this.wrongList.length == 0) {
 					uni.navigateBack({
-						delta:1
+						delta: 1
 					})
-				}else{
+				} else {
 					submitTest({
 						"carTypeId": storage.get('carType') || '1001',
 						"score": score,
@@ -769,12 +795,12 @@
 				if (title) {
 					this.navTitle = title
 				}
-				if(subject){
+				if (subject) {
 					this.subject = subject
 					console.log(this.subject);
-					this.storageRightList=storage.get(`rightList_subject${subject}`) || []
-					this.storageWrongList=storage.get(`wrongList_subject${subject}`) || []
-					this.collectList=storage.get(`collectList_subject${subject}`) || []
+					this.storageRightList = storage.get(`rightList_subject${subject}`) || []
+					this.storageWrongList = storage.get(`wrongList_subject${subject}`) || []
+					this.collectList = storage.get(`collectList_subject${subject}`) || []
 				}
 				if (val && val.length) {
 					this.questionList = JSON.parse(val)
@@ -783,12 +809,12 @@
 				}
 				console.log(this.questionList);
 				if (this.navTitle === '顺序答题') {
-					if(subject){
+					if (subject) {
 						this.pickerTopic(this[`currentIndex_subject${subject}`])
-					}else{
+					} else {
 						this.pickerTopic(this[`currentIndex_subject${this.subject}`])
 					}
-					
+
 				} else {
 					this.pickerTopic(this.topicIndex)
 				}
diff --git a/src/static/image/mine/callme.png b/src/static/image/mine/callme.png
new file mode 100644
index 0000000..fce9119
Binary files /dev/null and b/src/static/image/mine/callme.png differ
diff --git a/src/uni_modules/g-preview-img/changelog.md b/src/uni_modules/g-preview-img/changelog.md
new file mode 100644
index 0000000..a688afc
--- /dev/null
+++ b/src/uni_modules/g-preview-img/changelog.md
@@ -0,0 +1,11 @@
+## 1.0.4(2022-12-07)
+修改:判断在APP端不监听document的滚动
+## 1.0.3(2022-12-05)
+新增:支持视频预览,视频图片混用
+新增:支持预览单张,handlePreviewImg方法直接传入图片或视频地址即可单张预览
+## 1.0.2(2022-12-05)
+ 
+## 1.0.1(2022-12-05)
+文档错误修改
+## 1.0.0(2022-11-29)
+初始化插件
diff --git a/src/uni_modules/g-preview-img/components/g-preview-img/g-preview-img.vue b/src/uni_modules/g-preview-img/components/g-preview-img/g-preview-img.vue
new file mode 100644
index 0000000..f235e7f
--- /dev/null
+++ b/src/uni_modules/g-preview-img/components/g-preview-img/g-preview-img.vue
@@ -0,0 +1,235 @@
+<template>
+  <view class="pos">
+    <uni-transition :mode-class="modeClass" :show="show">
+      <!-- 多张图片预览 -->
+      <view class="content" @tap="closedPreview">
+        <swiper
+          class="swiper"
+          circular
+          :current="curDot"
+          @change="swiperChange"
+          :indicator-dots="false"
+        >
+          <swiper-item v-for="(item, idx) in selfImgList" :key="idx">
+            <movable-area scale-area>
+              <movable-view
+                :scale="!disabledScale"
+                direction="all"
+                scale="true"
+                scale-min="0.5"
+                scale-max="5"
+                :scale-value="1"
+                damping="150"
+                friction="15"
+              >
+                <image v-if="isImg(item)" :src="item" mode="widthFix"></image>
+                <view class="video-preview" v-else>
+                  <video
+                    :autoplay="true"
+                    :src="item"
+                    :enable-progress-gesture="false"
+                    :show-fullscreen-btn="false"
+                  ></video>
+                </view>
+              </movable-view>
+            </movable-area>
+          </swiper-item>
+        </swiper>
+      </view>
+      <!-- 指示器 -->
+      <slot name="indicator" v-if="imgList.length > 1 && !indicatorDotsType">
+        <view class="current-dot">
+          <view class="change-buttom" @tap.stop="previousImg">
+            <uni-icons class="font-white" type="back" size="30"></uni-icons>
+          </view>
+          <view class="font-white cur">
+            {{ curDot + 1 }}/{{ imgList.length }}
+          </view>
+          <view class="change-buttom" @tap.stop="nextImg">
+            <uni-icons class="font-white" type="forward" size="30"></uni-icons>
+          </view>
+        </view>
+      </slot>
+    </uni-transition>
+  </view>
+</template>
+<script>
+export default {
+  props: {
+    // 过渡效果
+    modeClass: {
+      type: Array,
+      default: ['fade', 'zoom-out'],
+    },
+    // 指示器类型 true 圆点 false 数字
+    indicatorDotsType: {
+      type: Boolean,
+      default: true,
+    },
+    // 图片列表
+    imgList: {
+      type: Array,
+      default: () => [],
+    },
+    // 是否禁止放大缩小 禁止后swiper可以滑动切换
+    disabledScale: {
+      type: Boolean,
+      default: false,
+    },
+  },
+  data() {
+    return {
+      show: false,
+      curDot: 0,
+      selfImgList: [],
+    };
+  },
+
+  computed: {
+    isImg() {
+      return (src) => {
+        return src.indexOf('.mp4') === -1 ? true : false;
+      };
+    },
+  },
+  watch: {
+    //监听打开时阻止下面元素的滚动事件
+    /*  #ifdef APP-PLUS*/
+    show(val) {
+      if (val) {
+        document
+          .getElementsByClassName('pos')[0]
+          .addEventListener('touchmove', function (e) {
+            e.preventDefault();
+          });
+      }
+    },
+    /* #endif */
+    imgList: {
+      handler(val) {
+        if (val.length) {
+          this.selfImgList = val.concat();
+        }
+      },
+    },
+  },
+  methods: {
+    handlePreviewImg(param) {
+      this.show = !this.show;
+      if (typeof param === 'string') {
+        this.selfImgList = [param];
+      } else {
+        if (param) {
+          this.curDot = param;
+        }
+      }
+      this.$emit('preview', this.show);
+    },
+    closedPreview() {
+      this.show = !this.show;
+      this.curDot = 0;
+      this.$emit('preview', this.show);
+    },
+    swiperChange(e) {
+      this.curDot = e.detail.current;
+      this.$emit('changeImg', e.detail.current);
+    },
+    previousImg() {
+      let num = this.imgList.length - 1;
+      if (this.curDot <= 0) {
+        this.curDot = num;
+      } else {
+        this.curDot--;
+      }
+    },
+    nextImg() {
+      let num = this.imgList.length - 1;
+      if (this.curDot >= num) {
+        this.curDot = 0;
+      } else {
+        this.curDot++;
+      }
+    },
+  },
+};
+</script>
+<style lang="scss" scoped>
+movable-view {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  width: 100%;
+  height: 100%;
+}
+
+movable-area {
+  height: 100%;
+  width: 100%;
+  position: fixed;
+  overflow: hidden;
+}
+
+movable-view image {
+  width: 100%;
+}
+.content {
+  height: 100vh;
+  width: 100vw;
+  display: flex;
+  align-items: center;
+  background: #00000076;
+}
+.pos {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 9999;
+}
+.swiper {
+  height: 100%;
+  width: 100%;
+}
+.current-dot {
+  position: absolute;
+  bottom: 10%;
+  left: 25%;
+  width: 50%;
+  display: flex;
+  align-items: center;
+  justify-content: space-around;
+  .change-buttom {
+    padding: 10rpx;
+    border-radius: 50%;
+    background: #3f3f3f;
+  }
+  .cur {
+    font-size: 20rpx;
+  }
+}
+
+.font-white {
+  color: #fff !important;
+}
+::v-deep {
+  .uni-swiper-dots-horizontal {
+    bottom: 12%;
+  }
+  .uni-swiper-dot {
+    width: 10rpx;
+    height: 10rpx;
+  }
+
+  uni-video {
+    width: 100vw;
+    height: 100vh;
+  }
+}
+.video-preview {
+  position: relative;
+  .video-close {
+    position: absolute;
+    right: 50rpx;
+    top: 50rpx;
+  }
+}
+</style>
diff --git a/src/uni_modules/g-preview-img/package.json b/src/uni_modules/g-preview-img/package.json
new file mode 100644
index 0000000..a37a659
--- /dev/null
+++ b/src/uni_modules/g-preview-img/package.json
@@ -0,0 +1,84 @@
+{
+  "id": "g-preview-img",
+  "displayName": "g-preview-img一款兼容vue2,vue3的图片预览插件,视频预览,支持单张多张,左右滑动,放大缩小",
+  "version": "1.0.4",
+  "description": "g-preview-img一款兼容vue2,vue3的图片预览插件,视频预览,支持单张多张,左右滑动,放大缩小",
+  "keywords": [
+    "vue2",
+    "vue3",
+    "图片预览",
+    "视频预览"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "type": "component-vue",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "u",
+          "阿里": "u",
+          "百度": "u",
+          "字节跳动": "u",
+          "QQ": "u",
+          "钉钉": "u",
+          "快手": "u",
+          "飞书": "u",
+          "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/uni_modules/g-preview-img/readme.md b/src/uni_modules/g-preview-img/readme.md
new file mode 100644
index 0000000..202bf5e
--- /dev/null
+++ b/src/uni_modules/g-preview-img/readme.md
@@ -0,0 +1,64 @@
+![image](https://deaon-saasvideo.oss-cn-shanghai.aliyuncs.com/11111.gif)
+### 一款兼容vue2,vue3的图片预览插件,视频预览,支持图片视频混用,支持单张多张,左右滑动,放大缩小
+
+### 基础使用方法
+
+```javascript
+    <template>
+    
+        <image v-for="(item,idx) in imgList" :src="item" :key="idx" @tap="handleClick(idx)"></image>
+        <g-preview-img :imgList="imgList" ref="preview"><g-preview-img>
+    </template>
+    
+    <script setup>
+        import { ref } from 'vue'
+        const preview = ref(null)
+        const imgList = ['图片路径1','图片路径2']
+        const handleClick = (idx)=>{
+            // idx为要打开的图片的索引,也可以不传,默认打开第一张
+			// handlePreviewImg的参数支持传入单张图片地址或单个视频地址
+            preview.value.handlePreviewImg(idx)
+        }
+    </script>
+```
+
+| 属性名/事件            | 类型           | 默认值                   | 说明                                                                                                                                                                                                 |
+| ----------------- | ------------ | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| modeClass         | Array/String | \['fade', 'zoom-out'] | uni-transition组件过渡效果,可选值见 <https://uniapp.dcloud.net.cn/component/uniui/uni-transition.html#mode-class-%E5%86%85%E7%BD%AE%E8%BF%87%E6%B8%A1%E5%8A%A8%E7%94%BB%E7%B1%BB%E5%9E%8B%E8%AF%B4%E6%98%8E> |
+| indicatorDotsType | Boolean      | false                 | 多张图片的指示器,ture为圆点,false数字,当图片列表只有一张图片时,默认不展示指示器                                                                                                                                                     |
+| imgList           | Array        |                       | 图片列表                                                                                                                                                                                               |
+| disabledScale     | Boolean      | false                 | 是否禁止双指放大缩小                                                                                                                                                            |
+| @preview          | 打开关闭事件       |                       | 接受一个参数,ture为开启,false为关闭                                                                                                                                                                            |
+| @changeImg        | 图片切换的事件      |                       | 参数为当前的图片索引                                                                                                                                                                                         |
+
+#### 插槽,自定义翻页按钮
+
+```js
+
+<g-preview-img :imgList="imgList" ref="preview">
+    <template>
+        <!--你的翻页按钮-->
+        <view @tap.stop="previousImg">上一页</view>
+        <view @tap.stop="nextImg">下一页</view>
+    </template>
+</g-preview-img>
+
+<script>
+    const preview = ref(null)
+    //上一页的方法
+    const previousImg = ()=>{
+        preview.value.previousImg()
+    }
+    //下一页的方法
+    const previousImg = ()=>{
+        preview.value.nextImg()
+    }
+</script>
+```
+
+#### 支持uniapp原生swiper的属性
+
+    插件内部swiper标签上绑定了$attrs,所以在使用时可以传入一些swiper的属性
+    注意:不要传disable-touch这个属性,会有意想不到的错误
+
+**插件bug会及时修复!!**
diff --git a/src/uni_modules/q-previewImage/changelog.md b/src/uni_modules/q-previewImage/changelog.md
new file mode 100644
index 0000000..cd4026c
--- /dev/null
+++ b/src/uni_modules/q-previewImage/changelog.md
@@ -0,0 +1,24 @@
+## 1.1.1(2023-08-01)
+优化文档
+## 1.1.0(2023-08-01)
+优化文档
+## 1.0.9(2023-07-10)
+优化文档
+## 1.0.8(2023-06-25)
+优化文档
+## 1.0.7(2023-06-25)
+优化文档
+## 1.0.6(2023-05-26)
+优化文档
+## 1.0.5(2023-05-22)
+优化文档
+## 1.0.4(2023-04-30)
+新增图片放大功能,解决原生组件和tabbar导航栏等无法覆盖的问题
+## 1.0.3(2023-04-28)
+优化文档
+## 1.0.2(2023-04-28)
+优化文档
+## 1.0.1(2023-04-28)
+新增长按事件
+## 1.0.0(2023-04-28)
+插件上线
diff --git a/src/uni_modules/q-previewImage/components/q-previewImage/q-previewImage.vue b/src/uni_modules/q-previewImage/components/q-previewImage/q-previewImage.vue
new file mode 100644
index 0000000..5386aa1
--- /dev/null
+++ b/src/uni_modules/q-previewImage/components/q-previewImage/q-previewImage.vue
@@ -0,0 +1,121 @@
+<template>
+	<view class="previewImage" v-if="show" @tap="close">
+		<view class="page" v-if="urls.length > 0">
+			<text class="text">{{ current + 1 }} / {{ urls.length }}</text>
+		</view>
+		<swiper class="swiper" :current="current" @change="swiperChange"  @touchstart="handleTouchStart" @touchend="handleTouchEnd">
+			<swiper-item v-for="(item, index) in urls" :key="index">
+				<movable-area class="movable-area" scale-area>
+					<movable-view class="movable-view" direction="all" :inertia="true" damping="100" scale="true" scale-min="1" scale-max="4" :scale-value="scale">
+						<scroll-view scroll-y="true" class="uni-scroll-view">
+							<view class="scroll-view"><image :key="index" class="image" :src="item" mode="widthFix" @longpress="onLongpress(item)" /></view>
+						</scroll-view>
+					</movable-view>
+				</movable-area>
+			</swiper-item>
+		</swiper>
+	</view>
+</template>
+
+<script>
+export default {
+	props: {
+		urls: {
+			type: Array,
+			required: true,
+			default: () => {
+				return [];
+			}
+		}
+	},
+	data() {
+		return {
+			show: false,
+			current: 0, //当前页
+			scale: 1,
+			isZooming: false // 是否处于缩放状态
+		};
+	},
+	methods: {
+		//打开
+		open(current) {
+			this.current = this.urls.findIndex(item => item === current);
+			this.show = true;
+			this.$emit('open');
+		},
+		//关闭
+		close() {
+			if (!this.isZooming) {
+				this.show = false;
+				this.current = 0;
+				this.$emit('close');
+			}
+		},
+		//图片改变
+		swiperChange(e) {
+			this.current = e.detail.current;
+		},
+		//监听长按
+		onLongpress(e) {
+			this.$emit('onLongpress', e);
+		},
+		handleTouchStart() {
+			this.isZooming = true;
+		},
+		handleTouchEnd() {
+			this.isZooming = false;
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+.previewImage {
+	z-index: 9999;
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+	background-color: #000000;
+	.swiper {
+		width: 100%;
+		height: 100vh;
+		swiper-item {
+			.movable-area {
+				height: 100%;
+				width: 100%;
+				.movable-view {
+					width: 100%;
+					min-height: 100%;
+					.scroll-view {
+						display: flex;
+						align-items: center;
+						justify-content: center;
+						height: 100vh;
+						.image {
+							width: 100%;
+							height: auto;
+						}
+					}
+				}
+			}
+		}
+	}
+	.page {
+		position: absolute;
+		z-index: 9999;
+		width: 100%;
+		top: 60rpx;
+		text-align: center;
+		.text {
+			color: #fff;
+			font-size: 32rpx;
+			background-color: rgba(0, 0, 0, 0.5);
+			padding: 3rpx 16rpx;
+			border-radius: 20rpx;
+			user-select: none;
+		}
+	}
+}
+</style>
diff --git a/src/uni_modules/q-previewImage/package.json b/src/uni_modules/q-previewImage/package.json
new file mode 100644
index 0000000..3550c3f
--- /dev/null
+++ b/src/uni_modules/q-previewImage/package.json
@@ -0,0 +1,81 @@
+{
+  "id": "q-previewImage",
+  "displayName": "图片预览、多图左右滑动、图片放大、支持覆盖原生组件、原生导航栏、tabbar",
+  "version": "1.1.1",
+  "description": "最简洁的模拟图片预览,支持长按事件,多图左右滑动,大图上下滑动查看,支持图片放大,支持覆盖原生组件/原生导航栏/tabbar  支持vue2/vue3/app/小程序/h5",
+  "keywords": [
+    "图片预览"
+],
+  "repository": "",
+  "engines": {
+    "HBuilderX": "^3.4.14"
+  },
+  "dcloudext": {
+    "type": "component-vue",
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": ""
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "Vue": {
+          "vue2": "y",
+          "vue3": "y"
+        },
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "n"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "u",
+          "微信浏览器(Android)": "u",
+          "QQ浏览器(Android)": "u"
+        },
+        "H5-pc": {
+          "Chrome": "u",
+          "IE": "u",
+          "Edge": "u",
+          "Firefox": "u",
+          "Safari": "u"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "u",
+          "百度": "u",
+          "字节跳动": "u",
+          "QQ": "u",
+          "钉钉": "u",
+          "快手": "u",
+          "飞书": "u",
+          "京东": "u"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/uni_modules/q-previewImage/readme.md b/src/uni_modules/q-previewImage/readme.md
new file mode 100644
index 0000000..76c9508
--- /dev/null
+++ b/src/uni_modules/q-previewImage/readme.md
@@ -0,0 +1,244 @@
+# 最简洁的模拟图片预览,支持长按事件,多图左右滑动,大图上下滑动查看,支持图片放大,支持覆盖原生组件/原生导航栏/tabbar  支持vue2/vue3/app/小程序/h5
+
+  - 为了解决项目中因一些特殊原因无法使用uni.previewImage,例如App.onShow或者页面的oShow中写了方法。
+  - 如果用uni.previewImage,每次预览图片都会进到onShow的方法里
+  - 可以基本实现官方的预览图片功能,但是体验不如uni.previewImage()
+  - 如没有特殊原因,还是推荐官方的uni.previewImage()
+
+## 安装指引
+
+##1. 在插件市场打开本插件页面,在右侧点击`使用 HBuilderX 导入插件`,选择要导入的项目点击确定
+
+##2. 使用方法 vue2写法
+
+```
+<template>
+	<view>
+		<video v-if="videoShow" id="myVideo" src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20200317.mp4" controls></video>
+		<image v-for="(item, index) in imgs" :key="index" :src="item" @click="preview(item)"></image>
+		<q-previewImage ref="previewImage" :urls="imgs" @onLongpress="onLongpress" @open="open" @close="close"></q-previewImage>
+	</view>
+</template>
+
+<script>
+export default {
+ 	data() {
+ 		return {
+			videoShow:true,//video组件是否显示
+ 			imgs: [],
+ 		};
+ 	},
+
+ 	methods: {
+ 		preview(url) {
+			this.imgs = ['https://web-assets.dcloud.net.cn/unidoc/zh/multiport-20210812.png', 'https://web-assets.dcloud.net.cn/unidoc/zh/uni-function-diagram.png'] //设置图片数组
+			// #ifdef MP-WEIXIN
+			this.$nextTick(()=>{
+				 this.$refs.previewImage.open(url); // 传入当前选中的图片地址(小程序必须添加$nextTick,解决组件首次加载无图)
+			})
+			// #endif
+			
+			// #ifndef MP-WEIXIN
+			this.$refs.previewImage.open(url); // 传入当前选中的图片地址
+			// #endif
+ 		},
+		onLongpress(e){ //长按事件
+			console.log('当前长按的图片是' + e);
+			uni.showActionSheet({
+				itemList: ['转发给朋友', '保存到手机'],
+				success: function (res) {
+					console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
+				},
+				fail: function (res) {
+					console.log(res.errMsg);
+				}
+			});
+		},
+		
+		/* open和close方法一般用不到,但是在一些特殊场景会用到,
+		 * 比如预览图片时你需要覆盖 NavigationBar和 TabBar,
+		 * 或者在app中需要预览图片时覆盖住原生组件,比如video或者map等,
+		 * 你可以根据open和close去做一些操作,例如隐藏导航栏或者隐藏一些原生组件等
+		 */
+		open(){ //监听组件显示 (隐藏TabBar和NavigationBar,隐藏video原生组件)
+			// uni.hideTabBar()
+			// uni.setNavigationBarColor({
+			//   frontColor: '#000000', // 设置前景色为黑色
+			//   backgroundColor: '#000000', // 设置背景色为黑色
+			// })
+			// this.videoShow = false 
+		},
+		close(){ //监听组件隐藏 (显示TabBar和NavigationBar,显示video原生组件)
+			// uni.showTabBar()
+			// uni.setNavigationBarColor({
+			//   frontColor: '#ffffff', // 设置前景色为白色
+			//   backgroundColor: '#000000', // 设置背景色为黑色
+			// })
+			// this.videoShow = true
+		}
+ 	}
+ };
+</script>
+
+
+```
+
+##3. vue3 setup写法
+
+```
+
+<template>
+	<view>
+		<video v-if="videoShow" id="myVideo" src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20200317.mp4" controls></video>
+		<image v-for="(item, index) in imgs" :key="index" :src="item" @click="preview(item)"></image>
+		<q-previewImage ref="previewImage" :urls="imgs"  @onLongpress="onLongpress" @open="open" @close="close"></q-previewImage>
+	</view>
+</template>
+
+<script setup>
+import { reactive, ref, toRefs,nextTick } from 'vue';
+
+const data = reactive({
+	videoShow:true,//video组件是否显示
+	imgs: [],
+});
+const previewImage = ref(null);
+
+const { imgs,videoShow } = toRefs(data)// 解构
+
+const preview = url => {
+	data.imgs = ['https://web-assets.dcloud.net.cn/unidoc/zh/multiport-20210812.png', 'https://web-assets.dcloud.net.cn/unidoc/zh/uni-function-diagram.png'] //设置图片数组
+	
+	
+	// #ifdef MP-WEIXIN
+	nextTick(()=>{
+		 previewImage.value.open(url); // 传入当前选中的图片地址(小程序必须添加nextTick,解决组件首次加载无图)
+	})
+	// #endif
+	
+	// #ifndef MP-WEIXIN
+	previewImage.value.open(url); // 传入当前选中的图片地址
+	// #endif
+};
+
+const onLongpress = e =>{
+	console.log('当前长按的图片是' + e);
+	uni.showActionSheet({
+		itemList: ['转发给朋友', '保存到手机'],
+		success: function (res) {
+			console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
+		},
+		fail: function (res) {
+			console.log(res.errMsg);
+		}
+	});
+}
+
+/* open和close方法一般用不到,但是在一些特殊场景会用到,
+* 比如预览图片时你需要覆盖 NavigationBar和 TabBar,
+* 或者在app中需要预览图片时覆盖住原生组件,比如video或者map等,
+* 你可以根据open和close去做一些操作,例如隐藏导航栏或者隐藏一些原生组件等
+*/
+const open = () => { //监听组件显示 (隐藏TabBar和NavigationBar,隐藏video原生组件)
+	// uni.hideTabBar()
+	// uni.setNavigationBarColor({
+	// 	frontColor: '#000000', // 设置前景色为黑色
+	// 	backgroundColor: '#000000', // 设置背景色为黑色
+	// })
+	// data.videoShow = false 
+}
+
+const close = () => { //监听组件隐藏 (显示TabBar和NavigationBar,显示video原生组件)
+	// uni.showTabBar()
+	// uni.setNavigationBarColor({
+	// 	frontColor: '#ffffff', // 设置前景色为白色
+	// 	backgroundColor: '#000000', // 设置背景色为黑色
+	// })
+	// data.videoShow = true
+}
+
+</script>
+					
+```
+
+##4. 项目示例 (一般返回的数据图片是以逗号或特殊字符分割的字符串,点击时就需要传两个参数,一个是图片数组,一个是当前图片的index)
+## 注意q-previewImage不要写在循环体中,imgs其实就是用来存放当前图片的数组,每次点击每次赋值就行
+
+```
+<template>
+	<view>
+		<video v-if="videoShow" id="myVideo" src="https://img.cdn.aliyun.dcloud.net.cn/guide/uniapp/%E7%AC%AC1%E8%AE%B2%EF%BC%88uni-app%E4%BA%A7%E5%93%81%E4%BB%8B%E7%BB%8D%EF%BC%89-%20DCloud%E5%AE%98%E6%96%B9%E8%A7%86%E9%A2%91%E6%95%99%E7%A8%8B@20200317.mp4" controls></video>
+		<view v-for="(item, index) in list" :key="index" class="list">
+			<image :src="i"  mode="aspectFill" v-for="(i,imgindex) in item.urls.split(',')" @click.stop="preimg(item.urls.split(','),imgindex)"></image>
+		<view>
+		<q-previewImage ref="previewImage" :urls="imgs" @onLongpress="onLongpress" @open="open" @close="close"></q-previewImage>
+	</view>
+</template>
+
+<script>
+export default {
+ 	data() {
+ 		return {
+			videoShow:true,//是否显示video组件
+ 			imgs: [],//imgs其实就是用来存放当前图片的数组,每次点击每次赋值就行
+			
+ 		};
+ 	},
+
+ 	methods: {
+ 		preimg(urls,index){
+ 			this.imgs = urls //imgs其实就是用来存放当前图片的数组,每次点击每次赋值就行
+			// #ifdef MP-WEIXIN
+			this.$nextTick(()=>{
+				 this.$refs.previewImage.open(this.imgs[index]); // 传入当前选中的图片地址(小程序必须添加$nextTick,解决组件首次加载无图)
+			})
+			// #endif
+			
+			// #ifndef MP-WEIXIN
+			this.$refs.previewImage.open(this.imgs[index]); // 传入当前选中的图片地址
+			// #endif
+ 		},
+		onLongpress(e){ //长按事件
+			console.log('当前长按的图片是' + e);
+			uni.showActionSheet({
+				itemList: ['转发给朋友', '保存到手机'],
+				success: function (res) {
+					console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
+				},
+				fail: function (res) {
+					console.log(res.errMsg);
+				}
+			});
+		},
+		/* open和close方法一般用不到,但是在一些特殊场景会用到,
+		 * 比如预览图片时你需要覆盖 NavigationBar和 TabBar,
+		 * 或者在app中需要预览图片时覆盖住原生组件,比如video或者map等,
+		 * 你可以根据open和close去做一些操作,例如隐藏导航栏或者隐藏一些原生组件等
+		 */
+		open(){ //监听组件显示 (隐藏TabBar和NavigationBar,隐藏video原生组件)
+			// uni.hideTabBar()
+			// uni.setNavigationBarColor({
+			//   frontColor: '#000000', // 设置前景色为黑色
+			//   backgroundColor: '#000000', // 设置背景色为黑色
+			// })
+			// this.videoShow = false 
+		},
+		close(){ //监听组件隐藏 (显示TabBar和NavigationBar,显示video原生组件)
+			// uni.showTabBar()
+			// uni.setNavigationBarColor({
+			//   frontColor: '#ffffff', // 设置前景色为白色
+			//   backgroundColor: '#000000', // 设置背景色为黑色
+			// })
+			// this.videoShow = true
+		}
+ 	}
+ };
+</script>
+
+```
+
+
+## 如果插件对您有一点帮助,请给个五星好评,感谢支持
+
+
+## 如有问题,请加qq 965969604
\ No newline at end of file