zhengkaixin 2 лет назад
Родитель
Сommit
2d61efd432

+ 49 - 0
apis/pagejs/goods.js

@@ -0,0 +1,49 @@
+import request from '@/apis/utils/request'
+ 
+import Qs from 'qs';
+
+export function exchangeDetail(formData) {
+	return request({
+		url: '/mobile/goods/exchangeDetail',
+		data: formData,
+		method: 'post',	
+	//	header:{'Content-Type':'application/json'},
+	})
+}
+
+export function exchangeGoods(formData) {
+	return request({
+		url: '/mobile/goods/exchangeGoods',
+		data: formData,
+		method: 'post',	
+	//	header:{'Content-Type':'application/json'},
+	})
+}
+
+export function exchangeList(formData) {
+	return request({
+		url: '/mobile/goods/exchangeList',
+		data: formData,
+		method: 'post',	
+	//	header:{'Content-Type':'application/json'},
+	})
+}
+
+
+export function goodsDetail(formData) {
+	return request({
+		url: '/mobile/goods/goodsDetail',
+		data: formData,
+		method: 'post',	
+	//	header:{'Content-Type':'application/json'},
+	})
+}
+
+export function goodsList(formData) {
+	return request({
+		url: '/mobile/goods/goodsList',
+		data: formData,
+		method: 'post',	
+	//	header:{'Content-Type':'application/json'},
+	})
+}

+ 39 - 3
apis/pagejs/news.js

@@ -1,4 +1,5 @@
 import request from '@/apis/utils/requestWhite'
+ import request2 from '@/apis/utils/request'
  
 import Qs from 'qs';
 
@@ -25,10 +26,45 @@ export function tabList(formData) {
 	})
 }
 
-export function detail(id) {
+export function detail(id,userId) {
+	var url= '/open/newsApi/detail/'+id;
+	if(userId){
+		url+='/'+userId
+	}
 	return request({
-		url: '/open/newsApi/detail/'+id,
+		url:url,
 		//data: formData,
 		method: 'get',	
 	})
-}
+}
+
+export function commentNews(formData) {
+	return request2({
+		url: '/mobile/newsComments/commentNews',
+		data: formData,
+		method: 'post',	
+	})
+}
+
+export function newsCommentspageList(formData) {
+	return request2({
+		url: '/mobile/newsComments/pageList',
+		data: formData,
+		method: 'post',	
+	})
+}
+export function changeLikes(formData) {
+	return request2({
+		url: '/mobile/newsLikes/changeLikes',
+		data: formData,
+		method: 'post',	
+	})
+}
+
+export function newsCommentsdelete(id) {
+	return request2({
+		url: 'mobile/newsComments/delete/'+id,
+		
+		method: 'post',	
+	})
+}

+ 9 - 0
apis/pagejs/share.js

@@ -9,4 +9,13 @@ export function pageList(formData) {
 		method: 'post',	
 	//	header:{'Content-Type':'application/json'},
 	})
+}
+
+export function addShare(formData) {
+	return request({
+		url: '/mobile/share/addShare',
+		data: formData,
+		method: 'post',	
+	//	header:{'Content-Type':'application/json'},
+	})
 }

+ 3 - 0
apis/sysdatadictionary.js

@@ -0,0 +1,3 @@
+var obj={
+	"eaab19ae-893f-40e7-b730-85a13af00137": "未开始",
	"7d69d622-3785-470e-b36c-d0f155b79dfa": "进行中",
	"77d93870-e1e1-4369-b2b6-629e8645e8d9":	"已结束",
+}

+ 1 - 3
apis/utils/index.js

@@ -136,9 +136,7 @@ export const parseUnixTime = (time, cFormat) => {
 export const getWeixinRedirectURI = (appid, url) =>
 	`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${encodeURIComponent(url)}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
 
- export const getWeixinRedirectURIInfo = (appid, url) =>
- 	`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${appid}&redirect_uri=${encodeURIComponent(url)}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
- 
+
   
 
 //支付宝获取code

BIN
assets/img/overdue.png


+ 4 - 2
config/.env.dev.js

@@ -1,9 +1,11 @@
 const UNI_APP = {  
 	ProjectName :"地方铁路",
-	//BASE_URL: 'http://36.134.122.108:8086/railroad-server/',
+	BASE_URL: 'http://36.134.122.108:8086/railroad-server/',
 	//BASE_URL: 'https://charging.xiaoxinda.com/charging-station-test/',
 	// 'http://192.168.77.162:8080/charging-station/' ,
-	BASE_URL:'http://192.168.77.162:8086/railroad-server/',
+	//BASE_URL:'http://192.168.77.162:8086/railroad-server/',
+	//BASE_URL:'http://192.168.77.222:8086/railroad-server/',
+	
 	NODE_ENV :"dev",
 	SIMPLE_RUN:true,// 无视权限控制跳转页面   , 用于样式人员快速访问各种功能 ,快速测试等
 

+ 3 - 3
config/.env.js

@@ -17,11 +17,11 @@
     } else if (process.env.NODE_ENV === "production") {  
 		
 		if(NODE_NAME=="test"){
-			ENV_VAR = require('./.env.test.js'); 
+			ENV_VAR = require('.env.test.js'); 
 		}else if(NODE_NAME=="production"){
-			ENV_VAR = require('./.env.prod.js');
+			ENV_VAR = require('.env.prod.js');
 		} else  {  
-			ENV_VAR = require('./.env.prod.js');  
+			ENV_VAR = require('.env.prod.js');  
 		} 
       
     }  

+ 1 - 0
config/.env.prod.js

@@ -5,6 +5,7 @@ const UNI_APP = {
 	NODE_ENV :"prod",
 	SIMPLE_RUN:false,
 	openId:"oHjCawigqi8SEAwutwkQ-VEgdp3k",//测试用openId
+	openId:"123456",
 	//小鹏管家appid
 	VUE_APP_WXAPPID:"wx16b726435e3b33f9",
 	VUE_APP_ALIAPPID:"2021003131641247",

+ 1 - 1
config/.env.test.js

@@ -19,7 +19,7 @@ const UNI_APP = {
 	//zq的测试openId
 	//openId:"oK9Wr55J1J1eL6BqI2tW749NTxNU"
 	//openId:"test004",
-	openId:"oK9Wr54VbEh3xvWYmD_zT5NbH4AY",
+	openId:"123456",
 	
 }  
 

+ 5 - 5
manifest.json

@@ -70,11 +70,11 @@
     },
     "vueVersion" : "2",
     "h5" : {
-        "devServer" : {
-            "port" : 8080,
-            "https" : false,
-            "disableHostCheck" : true
-        },
+		"devServer" : {
+		    "port" : 8080,
+		    "https" : false,
+		    "disableHostCheck" : true
+		},
         "router" : {
             "base" : "./"
         },

+ 1 - 15
package.json

@@ -7,21 +7,7 @@
 		"uview-ui": "^1.8.4",
 		"vconsole": "^3.4.0",
 		"vue-cropper": "^0.5.6",
-		"weixin-js-sdk": "^1.6.0",
-		"vue-cli": "^2.9.6",
-		"vue-cropper": "^0.5.6",
-		"vuex": "^3.6.2"
-	},
-	"devDependencies": {
-	 "@vue/cli-plugin-babel": "^4.0.0",
-	 "@vue/cli-plugin-eslint": "^4.0.0",
-	 "@vue/cli-service": "^4.0.0",
-	 "babel-eslint": "^10.0.3",
-	 "eslint": "^5.16.0",
-	 "eslint-plugin-vue": "^5.0.0",
-	 "node-sass": "^5.0.0",
-	 "sass-loader": "^11.0.1",
-	 "vue-template-compiler": "^2.6.10"
+		"weixin-js-sdk": "^1.6.0"
 	},
 	"uni-app": {
 		"scripts": {

+ 2 - 2
pages/homePage/homePage.vue

@@ -135,11 +135,11 @@
 			}
 		},
 		onLoad(){
-			if(process.car.SIMPLE_RUN){
+			 
 				this.getSwiperList()
 				this.getList("de3958c2-0010-4009-b7e1-15bfdcc60cef",5,"toplist");//通知公告
 				this.getList("ee0ea72a-75bf-4970-ad34-11e3132bc6a3",5,"footlist");//新闻资讯-图片新闻
-			}
+			
 			
 		},
 		computed:{

+ 2 - 1
pages/mine/feedback.vue

@@ -5,6 +5,7 @@
 			<textarea name="" id="" 
 			v-model="subForm.content"
 			cols="30" rows="10" placeholder="填写反馈内容(必填)"></textarea>
+		
 			<u-upload  :form-data="formData" :header="header" :action="action"
 			:file-list="fileList" upload-text=""></u-upload>
 
@@ -39,7 +40,7 @@
 		},onLoad() {
 			this.action=process.car.BASE_URL+"uploadPicture"
 			
-			this.formData.subFolder="/team51/message"
+			this.formData.subFolder="feedback"
 			//接口应该免登陆
 			var token=this.carhelp.getToken()
 			

+ 178 - 6
pages/mine/issue.vue

@@ -1,15 +1,24 @@
 <template>
 	<view>
 		<u-navbar title="发布内容" back-icon-name="close" >
-			<view class="slot-wrap">		 
+			<view class="slot-wrap"
+			 :class="{
+				 'slot-wrap-a':true,
+				 'slot-wrap-b':subForm.synopsis&&itemshare.label
+			 }"
+			 @click="selectvideo()">		 
 				 	发布		
 			</view>	
 		</u-navbar>
 		
-		<textarea placeholder="记录点滴生活..." name="" id="" cols="30" rows="10"></textarea>
+		<textarea placeholder="记录点滴生活..."
+		v-model="subForm.synopsis"
+		 name="" id="" cols="30" rows="10"></textarea>
 	
 	  <view class="upload">
-	  	<u-upload  :action="action" :file-list="fileList" ></u-upload>
+		
+	  	<u-upload-file  ref="uUpload" :action="action"  :form-data="formData" :header="header"
+		 :file-list="fileList" ></u-upload-file>
 	  </view>
 	  
 	  <view class="select">
@@ -17,26 +26,181 @@
 	  		<text class="sign">#</text>
 			<text class="text">参与活动</text>
 	  	</view>
-		<view class="choose">
-				<text>选择活动</text>
+		<view class="choose" @click="selectshare" >
+				<text >{{itemshare.label?itemshare.label:'选择活动'}}</text>
 				<u-icon name="arrow-right"></u-icon>
 		</view>
 	  </view>
+	  <view class="bottom"  v-if="false" >
+	  			<button>发布作品</button>
+	  </view>
+	  <u-select v-model="showshare" :default-value=[itemshare.index?itemshare.index:0] @confirm="confirmshare"
+	   value-name="index" label-name="title"
+	   :list="listshare"></u-select>
 	</view>
 </template>
 
 <script>
+	import * as API from '@/apis/pagejs/activity.js'
+	import * as API_share from '@/apis/pagejs/share.js'
+	
 	export default {
 		data() {
 			return {
+				listshare:[],
+				itemshare:{},
+				showshare:false,
+				action:"",
+				formData:{},
+				fileList:[],
+				header:{
+					
+				},
+				listForm:{
+					pageIndex:1,
+					pageSize:50,
+					status:'7d69d622-3785-470e-b36c-d0f155b79dfa',
+					
+				},
+				subForm:{
+					
+				},
+			}
+		},onLoad(op) {
+			this.action=process.car.BASE_URL+"uploadPicture"
+			
+			this.formData.subFolder="mineissue"
+			//接口应该免登陆
+			var token=this.carhelp.getToken()
+			
+			this.header={
+		
+				'Authorization':token
+			}
+			// //获取微信配置
+			// WxJsApi.getWxConfig(['getLocation','addEventListener']).then((res)=>{
+			
+			// 	this.isReady=true;
+			// 	//(res)
+			 
+			// }).catch(error => {
+			// 		//(res)
+			// })
+			if(op.id){
+				this.itemshare.id=op.id;
+				this.itemshare.index=-1;
+			}
+			this.getShareList()
+		},
+		methods:{
+			confirmshare(es){
+				
+				var e=es[0]
+				this.itemshare=e
+				this.itemshare.index=e.value;
+			},
+			getShareList(){
+				uni.showLoading({
+					title: "加载中",
+					mask: true,
+				})
+				
+				API.pageList(this.listForm).then((res) => {
+					
+					uni.hideLoading();
+					this.listshare = res.data.data;
+					
+						for(var i in this.listshare){
+							var item=this.listshare[i]
+							item.index=i;
+							if(this.itemshare.index==-1){
+								if(item.id==this.itemshare.id){
+										this.confirmshare({value:i,label:item.title})		
+								}
+							}
+						}
+					
+				}).catch(error => {
+					uni.showToast({
+						title: error,
+						icon: "none"
+					})
+				})
+			},
+			selectshare(){
+				this.showshare=true;
+			},
+			selectvideo(){
+				if(this.subForm.synopsis&&this.itemshare.label){
+					
+				}else{
+					return
+				}
+				this.subForm.activityId=this.listshare[this.itemshare.value].id;
+				var lists = this.$refs.uUpload.lists;
+				console.log(lists)
+				var urls=[]
+				var isPics=[]
 				
+				for(var i in lists){
+					var p =lists[i].response.data;
+					var fileName=p.fileName
+					urls.push(p.fileUrl)
+					if(fileName.indexOf('.mp4')>=0){
+						isPics.push(false)
+					}else{
+						isPics.push(true)
+					}
+				}
+				this.subForm.urls=urls.join()
+				this.subForm.isPics=isPics.join()
+				uni.showLoading({
+					title: "加载中",
+					mask: true,
+				})
 				
+				API_share.addShare(this.subForm).then((res) => {
+					
+					uni.hideLoading();
+					uni.showModal({
+						showCancel:false,
+											 title:"提示",
+						content:"操作成功",
+											confirmText:"确定",
+											success: res1 => {
+												this.carhelp.set("addShare",1);
+												uni.navigateBack()
+											}})
+					
+				}).catch(error => {
+					uni.showToast({
+						title: error,
+						icon: "none"
+					})
+				})
 			}
 		}
 	}
 </script>
 
 <style scoped lang="scss">
+	.bottom{
+		   padding: 16rpx 32rpx;
+		   background-color: #fff;
+		   position: fixed;
+		   bottom: 0;
+		   left: 0;
+		   right: 0;
+		   uni-button{
+			   border-radius: 8px;
+			   background-color: rgba(31, 74, 153, 1);
+			   color: rgba(255, 255, 255, 1);
+			   font-size: 16px;
+			   line-height: 40px;
+			   
+		   }
+		   
+	}
 	page{
 		background-color: #fff;
 	}
@@ -51,12 +215,20 @@
 		font-size: 32rpx !important;
 		color: #101010 !important;
 	}
+	.slot-wrap-a{
+		
+	}
+	.slot-wrap-b{
+		background-color: #03a9f4 !important;
+	}
+	
 	.slot-wrap{
+		background-color: rgba(204, 204, 204, 1);
 		width: 104rpx;
 		height:56rpx;
 		line-height:56rpx ;
 		border-radius: 8px;
-		background-color: rgba(204, 204, 204, 1);
+		
 		color: #fff;
 		text-align: center;
 		position: absolute;

+ 1 - 1
pages/mine/points/points.vue

@@ -1,7 +1,7 @@
 <template>
 	<view>
 		<u-navbar title="积分">
-			<view class="slot-wrap">
+			<view class="slot-wrap"  v-if="false" >
 				积分规则
 			</view>	
 		</u-navbar>

+ 95 - 66
pages/mine/points/pointsExchange/pointsExchange.vue

@@ -1,7 +1,7 @@
 <template>
 	<view>
 		<u-navbar title="积分兑换">
-			<view class="slot-wrap">
+			<view class="slot-wrap" v-if="false">
 				兑换规则
 			</view>	
 		</u-navbar>
@@ -12,14 +12,14 @@
 							<img src="../../../../assets/img/riFill-vip-diamond-fill Copy@1x.png" alt="">
 						</view>
 						<view class="number">
-							150000
+							{{plusInfo.userPoints}}
 						</view>
-						<view class="button">
+						<view class="button"   @click="gotoUrl('pages/mine/points/points')">
 							兑换记录
 						</view>
 					</view>
 			<!-- 提示 -->
-			<view class="hint">
+			<view class="hint" v-if="false">
 				 <view class="img"><img src="../../../../assets/img/md-notifications@1x.png" alt=""></view>
 					 <view class="text">
 					 	积分将于1月1日0时自动清零,记得使用哦~
@@ -27,110 +27,139 @@
 			</view>
 			<!-- 标签 -->
 			<view class="tabs">
-				<u-tabs font-size="28" height="64 ":list="list" :is-scroll="false" :current="current" @change="change"></u-tabs>
+				<u-tabs font-size="28" height="64 " :list="tablist" :is-scroll="false" :current="current" @change="change"></u-tabs>
 			</view>
 		</view>
 		<!-- 奖品 -->
 		<view class="prize">
-			<view class="item" >
+			<view class="item"  v-for="(item,i) in list" :key="i" @click="ckItem(item)" >
 				<view class="picture">
-					<img src="../../../../assets/img/computer.png" alt="">
+					<img :src="item.photoUrl" alt="">
 				</view>
 				<view class="name">
-					奖品名称
+					{{item.name}}
 				</view>
 				<view class="infos">
 					<view class="points">
-						20000积分
+						{{item.needPoint}}积分
 					</view>
 					<view class="remain">
-						剩余1
-					</view>
-				</view>
-				
-			</view>
-			<view class="item" >
-				<view class="picture">
-					<img src="../../../../assets/img/prize2.png" alt="">
-				</view>
-				<view class="name">
-					奖品名称
-				</view>
-				<view class="infos">
-					<view class="points">
-						20000积分
-					</view>
-					<view class="remain">
-						剩余1
-					</view>
-				</view>
-				
-			</view>
-			<view class="item" >
-				<view class="picture">
-					<img src="../../../../assets/img/prize3.png" alt="">
-				</view>
-				<view class="name">
-					奖品名称
-				</view>
-				<view class="infos">
-					<view class="points">
-						20000积分
-					</view>
-					<view class="remain">
-						剩余100
-					</view>
-				</view>
-				
-			</view>
-			<view class="item" >
-				<view class="picture">
-					<img src="../../../../assets/img/prize4.png" alt="">
-				</view>
-				<view class="name">
-					奖品名称
-				</view>
-				<view class="infos">
-					<view class="points">
-						20000积分
-					</view>
-					<view class="remain">
-						剩余1
+						剩余{{item.quantity}}
 					</view>
 				</view>
 				
 			</view>
 			
+			
 		</view>
-		<u-divider bg-color="#B5D0F4" border-color="#A1B2D1">已经到底了</u-divider>
+		<u-divider  :isnone="list.length==0" nonetext="敬请期待" bg-color="#B5D0F4" border-color="#A1B2D1">已经到底了</u-divider>
 	</view>
 </template>
 
 <script>
+	import * as API from '@/apis/pagejs/goods.js'
+	
 	export default {
 		data() {
 			return {
-				list: [{
+				tablist: [{
 					name: '全部'
 				}, {
-					name: '1万及以上'
+					name: '1万及以上',
+					start:10000,
+						end:'',
+					
 				}, {
 					name: '5千-1万',
+					start:5000,
+					end:10000,
 					
 				}, {
 					name: '1千-5千',
+					start:1000,
+					end:5000,
 					
 				}, {
 					name: '1千以下',
-					
+					start:'',
+					end:1000,
 				}],
-				current: 0
+				current: 0,
+				plusInfo:{},
+				list:[],
+				listForm:{
+					pageIndex:1,
+					typeId:"",
+					title:"",
+					pageSize:20,
+				},
+				recordsTotal:0,
+			}
+		},
+		onLoad(){
+			//this.userInfo
+			this.plusInfo=this.carhelp.getPersonInfoPlus()
+			this.getList();
+		},
+		onReachBottom() {
+			if (this.list.length < this.recordsTotal) {			
+				this.myLoadmore();
 			}
 		},
 		methods: {
+			ckItem(item){
+				if(item.badgeId){
+					var url="/pages/staffHome/teamHonor/badgeDetails?type="+item.badgeId+"&id="+item.type;
+					uni.navigateTo({
+						url:url
+					})
+				}
+			},
+			myLoadmore(){
+				this.listForm.pageIndex += 1;
+				this.getList();
+			},
 			change(index) {
+				
 				this.current = index;
+				this.listForm.queryPointStart='';
+				this.listForm.queryPointEnd='';
+				if(index){
+					
+					this.listForm.queryPointStart=this.tablist[index].end;
+					this.listForm.queryPointEnd=this.tablist[index].start;
+				}
+				
+				this.listForm.pageIndex=1;
+				
+				this.getList();
+			},
+			getList(){
+				uni.showLoading({
+					title: "加载中",
+					mask: true,
+				})
+				
+				API.goodsList(this.listForm).then((res) => {
+					uni.hideLoading();
+									if(this.listForm.pageIndex==1){
+										this.list = res.data.data;
+									}else{
+										this.list = [
+											...this.list,
+											...res.data.data
+										];
+									}
+					
+					this.recordsTotal = res.data.recordsTotal;
+				}).catch(error => {
+					uni.showToast({
+						title: error,
+						icon: "none"
+					})
+				})
 			}
+			
 		}
 	}
 </script>

+ 12 - 3
pages/mine/points/rankingList.vue

@@ -6,7 +6,7 @@
 			积分排行榜
 			
 		</view>
-		<view class="self">
+		<view class="self" v-if="false">
 			<view class="rank">
 				105
 			</view>
@@ -20,7 +20,7 @@
 				1015积分
 			</view>
 		</view>
-		<view class="else">
+		<view class="else"  v-if="false">
 			<view class="item">
 				<view class="rank">
 					<img src="../../../assets/img/Gold Medal@1x.png" alt="">
@@ -135,7 +135,7 @@
 			</view>
 			
 		</view>
-		<u-divider bg-color="#F2F4F4" border-color="#CFD2D5">已经到底了</u-divider>
+		<u-divider   :isnone="true" nonetext="统计中,敬请期待"  bg-color="#F2F4F4" border-color="#CFD2D5">已经到底了</u-divider>
 	</view>
 </template>
 
@@ -143,9 +143,18 @@
 	export default {
 		data() {
 			return {
+				list:[],
+				listForm:{
+					pageIndex:1,
+					typeId:"",
+					title:"",
+					pageSize:20,
+				},
+				recordsTotal:0,
 				
 			}
 		},
+	
 		methods: {
 			
 		}

+ 162 - 58
pages/news/articleDetails.vue

@@ -10,7 +10,7 @@
 				<view class="date">
 					{{info.createTime}}
 				</view>
-				<view class="pageview" >
+				<view class="pageview"  >
 					<view class="icon">
 						<u-icon name="eye" size="32"></u-icon>
 					</view>
@@ -31,67 +31,33 @@
 		</view> -->
 		</view>
 		<!-- 评论 -->
-		<view class="comment" v-if="false" >
+		<view class="comment" v-if="info.title&&info.listComment"   >
 			<view class="title">
 				精华评论
 			</view>
-			<view class="comment-item">
-				<view class="photo">
-					<img src="../../assets/img/photo.png" alt="">
-				</view>
-				<view class="details">
-					<view class="name-date">
-						<view class="name">
-							赵晓婧
-						</view>
-						<view class="date">
-							2022-07-27 01:44
-						</view>
-					</view>
-					<view class="comment-content">
-						探索了5种改善移动用户体验的绝佳做法,进来学!
-					</view>
-				</view>
-			</view>
-		
-		<view class="comment-item">
-			<view class="photo">
-				<img src="../../assets/img/photo.png" alt="">
-			</view>
-			<view class="details">
-				<view class="name-date">
-					<view class="name">
-						王漫
-					</view>
-					<view class="date">
-						2022-07-27 01:44
-					</view>
-				</view>
-				<view class="comment-content">
-					最佳产品管理书籍在此,获取职场上升秘籍最佳产品管理书籍在此,获取职场上升秘籍。
-				</view>
-			</view>
-		</view>
-		<view class="comment-item">
+			
+		<view class="comment-item"  v-for="(item,i) in info.listComment" :key="i" >
 			<view class="photo">
-				<img src="../../assets/img/photo.png" alt="">
+				<img :src="item.headImg" alt="">
 			</view>
 			<view class="details">
 				<view class="name-date">
-					<view class="name">
-						王译
+					<view class="name" :class="{
+						red:!item.name
+					}" >
+						{{item.name?item.name:'用户异常'}}
 					</view>
 					<view class="date">
-						2022-07-27 01:44
+						{{item.date}}
 					</view>
 				</view>
 				<view class="comment-content">
-					探索了5种改善移动用户体验的绝佳做法,进来学!
-					<view class="mine">
+					{{item.content}}
+					<view class="mine" v-if="item.isMine">
 						<view class="my-comment">
 							我的评论
 						</view>
-						<view class="delete">
+						<view class="delete" @click="newsCommentsdelete(item.id)">
 							删除	
 						</view>
 					</view>
@@ -101,19 +67,35 @@
 		</view>
 		</view>
 		
-		<view class="bottom" v-if="false" >
-			<view class="input">
-				<input type="text" placeholder="发表评论">
+		<view class="bottom" v-if="userInfo" >
+			<view class="input" @click="showMessage=true">
+				<view class="inputT">发表评论</view>
 			</view>
-			<view class="like">
+			<view class="like" :class="{
+				red:info.iLike
+			}" @click="changeLikes()">
 				<view class="icon">
-					<u-icon name="thumb-up" size="32"></u-icon>
+					<u-icon name="thumb-up"   size="32"></u-icon>
 				</view>
 				<view class="number">
-				999
+				
 				</view>
 			</view>
 		</view>
+		<u-popup v-model="showMessage" border-radius="34" mode="bottom" >
+			<view class="showMessage">
+				<view class="showMessage1"><h3>发表评论</h3></view>
+				<view class="showMessage2">
+					<textarea name="" id=""
+					v-model="content"
+					cols="30" rows="5" placeholder="填写内容"></textarea>
+				</view>
+				<view class="showMessage3">
+					<u-button type="primary" @click="submitMessage()">提交</u-button>
+				</view>
+			</view>
+					
+			</u-popup>
 		
 	</view>
 </template>
@@ -125,24 +107,129 @@
 		data() {
 			return {
 				id:"",
+				content:"",
 				info:{},
+				showMessage:false,
+				userInfo:null,
+				list:[],
+				 
+				recordsTotal:0,
 				
 			}
 		},
 		onLoad(op){
 			this.id=op.id
-			this.getInfo()
+			this.userInfo=this.carhelp.getPersonInfo()
+			this.getInfo(true)
+			
 		},
+	
 		methods: {
-			getInfo(){
+			newsCommentsdelete(id){
+				uni.showModal({
+					title: '提示',
+					content: '是否删除评论?',
+					
+					success: res=>{
+						if (res.confirm) {
+							this.newsCommentsdeletemethods(id)
+						} else if (res.cancel) {
+							//('用户点击取消');
+						}
+					}
+				});
+			},
+			newsCommentsdeletemethods(id){
+				uni.showLoading({
+					title: "加载中",
+					mask: true,
+				})
+				
+				API.newsCommentsdelete(id).then((res) => {
 				
+					uni.showToast({
+						title: "删除成功",
+						icon: "none"
+					})
+					
+					this.getInfo();
+					
+				}).catch(error => {
+					uni.showToast({
+						title: error,
+						icon: "none"
+					})
+				})
+			},
+			submitMessage(){
+				if(!this.content){
+					uni.showToast({
+						title: "请填写内容",
+						icon: "none"
+					})
+					return
+				}
+				uni.showLoading({
+					title: "加载中",
+					mask: true,
+				})
+				
+				API.commentNews({
+					newsId:this.id,
+					content:this.content,
+				}).then((res) => {
+					this.content=""
+					uni.showToast({
+						title: "提交成功",
+						icon: "none"
+					})
+					
+					this.getInfo();
+					
+				}).catch(error => {
+					uni.showToast({
+						title: error,
+						icon: "none"
+					})
+				})
+			},
+			changeLikes(){
 				uni.showLoading({
 					title: "加载中",
 					mask: true,
 				})
 				
-				API.detail(this.id).then((res) => {
+				
+				API.changeLikes({
+					newsId:this.id
+				}).then((res) => {
 					uni.hideLoading();
+					this.getInfo()
+				}).catch(error => {
+					uni.showToast({
+						title: error,
+						icon: "none"
+					})
+				})
+			},
+			getInfo(bl){
+				if(bl){
+					uni.showLoading({
+						title: "加载中",
+						mask: true,
+					})
+				}
+				
+				var userId=null
+				if(this.userInfo){
+					userId=this.userInfo.id
+				}
+				
+				API.detail(this.id,userId).then((res) => {
+					
+					if(bl){
+						uni.hideLoading();
+					}
 					this.info=res.data;
 				}).catch(error => {
 					uni.showToast({
@@ -203,6 +290,18 @@
 			}
 		}
 	}
+	.showMessage{
+		padding: 60rpx 50rpx ;
+		.showMessage2{
+			background-color: #E5E7EA;
+			margin: 40rpx 0;
+			textarea{
+				padding: 8rpx;
+				border-radius:34px;
+			}
+		}
+		
+	}
 	// 评论
 	.comment{
 		margin-top:24rpx;
@@ -230,6 +329,7 @@
 			}
 			.details{
 				margin-left: 24rpx;
+				width: 100%;
 				.name-date{
 					display: flex;
 					justify-content: space-between;
@@ -273,7 +373,9 @@
 			
 		}
 	}
-    
+    .red{
+    	color: red !important;
+    }
 	.bottom{
 		position: fixed;
 		left: 0;
@@ -284,12 +386,13 @@
 		display: flex;
 		justify-content: space-between;
 		align-items: center;
-		uni-input{
+		.input{
 			background-color: rgba(229, 231, 234, 1);
 			height: 32px;
 			line-height: 32px;
 			border-radius: 8rpx;
 			width: 520rpx;
+			padding-left: 16rpx;
 		}
 		/deep/.uni-input-placeholder{
 			text-indent: 28rpx;
@@ -297,6 +400,7 @@
 		/deep/.uni-input-input{
 			text-indent: 28rpx;
 		}
+		
 		.like{
 			display: flex;
 			.number{

+ 3 - 3
pages/staffHome/activityCenter/activityDetail.vue

@@ -7,9 +7,9 @@
 		
 		
 		</view>
-	 <view class="bottom" v-if="false">
-	 	<button>发布作品</button>
-	 </view>
+		 <view class="bottom" @click="gotoUrl('pages/mine/issue')" >
+			<button>发布作品</button>
+		 </view>
 	</view>
 </template>
 

+ 18 - 5
pages/staffHome/filesonic.vue

@@ -29,9 +29,15 @@
 					{{item.synopsis}}
 				</view>
 				<view class="pictures" >
-					<img  v-for="(pic,i2) in item.listShareFiles" :key="i2"
-					@click="previewImage(item.listShareFiles,i2)"
-					:src="pic.url" alt="">
+					<template v-for="(pic,i2) in item.listShareFiles" >
+						<img   v-if="isPic" :key="i2"
+						@click="previewImage(item.listShareFiles,i2)"
+						:src="pic.url" alt="">
+						
+						<video  :key="i2" :src="pic.url"
+						                    enable-danmu danmu-btn controls></video>
+					</template>
+					
 					
 				</view>
 
@@ -49,7 +55,7 @@
 		</view>
 		<u-divider  :isnone="list.length==0" nonetext="没有找到相关内容" border-color="#CFD2D5">已经到底了</u-divider>
 		
-		 <view class="bottom" v-if="false">
+		 <view class="bottom"  @click="gotoUrl('pages/mine/issue')" >
 		 	<img src="../../assets/img/riFill-camera-fill@2x.png">
 		 </view>
 	</view>
@@ -217,7 +223,13 @@
 				justify-content: start;
 				flex-wrap: wrap;
 				margin-top: 16rpx;
-
+				video {
+					width: 100%;
+					height: 216rpx;
+					border-radius: 16rpx;
+					margin-bottom: 16rpx;
+					margin-left: 16rpx;
+				}
 				img {
 					width: 31%;
 					height: 216rpx;
@@ -259,6 +271,7 @@
 	}
 
    .bottom{
+	   z-index: 999;
 	   background: linear-gradient(223.81deg, rgba(0,90,217,1) 14.24%,rgba(0,52,148,1) 86.67%);
 	   width: 104rpx;
 	   height: 104rpx;

+ 2 - 2
pages/staffHome/staffHome.vue

@@ -42,13 +42,13 @@
 					</view>
 					<view class="grid-text">活动奖励</view>
 				</u-grid-item>
-				<u-grid-item v-if="false">
+				<u-grid-item    @click="gotoUrl('pages/mine/points/rankingList')" >
 					<view class="icon icon4">
 						<img src="../../assets/img/phb.png" alt="">
 					</view>
 					<view class="grid-text">排行榜</view>
 				</u-grid-item>
-				<u-grid-item  v-if="false">
+				<u-grid-item  v-if="false" @click="gotoUrl('pages/mine/points/pointsExchange/pointsExchange')" >
 					<view class="icon icon5">
 						<img src="../../assets/img/jfyh.png" alt="">
 					</view>

+ 660 - 0
uni_modules/uview-ui/components/u-upload-file/u-upload-file.vue

@@ -0,0 +1,660 @@
+<template>
+	<view class="u-upload" v-if="!disabled">
+		<view
+			v-if="showUploadList"
+			class="u-list-item u-preview-wrap"
+			v-for="(item, index) in lists"
+			:key="index"
+			:style="{
+				width: $u.addUnit(width),
+				height: $u.addUnit(height)
+			}"
+		>
+			<view
+				v-if="deletable"
+				class="u-delete-icon"
+				@tap.stop="deleteItem(index)"
+				:style="{
+					background: delBgColor
+				}"
+			>
+				<u-icon class="u-icon" :name="delIcon" size="20" :color="delColor"></u-icon>
+			</view>
+			<u-line-progress
+				v-if="showProgress && item.progress > 0 && item.progress != 100 && !item.error"
+				:show-percent="false"
+				height="16"
+				class="u-progress"
+				:percent="item.progress"
+			></u-line-progress>
+			<view @tap.stop="retry(index)" v-if="item.error" class="u-error-btn">点击重试</view>
+			<image  class="u-preview-image" :src="item.url || item.path" :mode="imageMode"></image>
+		</view>
+		<slot name="file" :file="lists"></slot>
+		<view style="display: inline-block;" @tap="selectFile" v-if="maxCount > lists.length">
+			<slot name="addBtn"></slot>
+			<view
+				v-if="!customBtn"
+				class="u-list-item u-add-wrap"
+				hover-class="u-add-wrap__hover"
+				hover-stay-time="150"
+				:style="{
+					width: $u.addUnit(width),
+					height: $u.addUnit(height)
+				}"
+			>
+				<u-icon name="plus" class="u-add-btn" size="40"></u-icon>
+				<view class="u-add-tips">{{ uploadText }}</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+/**
+ * upload 图片上传
+ * @description 该组件用于上传图片场景
+ * @tutorial https://www.uviewui.com/components/upload.html
+ * @property {String} action 服务器上传地址
+ * @property {String Number} max-count 最大选择图片的数量(默认99)
+ * @property {Boolean} custom-btn 如果需要自定义选择图片的按钮,设置为true(默认false)
+ * @property {Boolean} show-progress 是否显示进度条(默认true)
+ * @property {Boolean} disabled 是否启用(显示/移仓)组件(默认false)
+ * @property {String} image-mode 预览图片等显示模式,可选值为uni的image的mode属性值(默认aspectFill)
+ * @property {String} del-icon 右上角删除图标名称,只能为uView内置图标
+ * @property {String} del-bg-color 右上角关闭按钮的背景颜色
+ * @property {String | Number} index 在各个回调事件中的最后一个参数返回,用于区别是哪一个组件的事件
+ * @property {String} del-color 右上角关闭按钮图标的颜色
+ * @property {Object} header 上传携带的头信息,对象形式
+ * @property {Object} form-data 上传额外携带的参数
+ * @property {String} name 上传文件的字段名,供后端获取使用(默认file)
+ * @property {Array<String>} size-type original 原图,compressed 压缩图,默认二者都有(默认['original', 'compressed'])
+ * @property {Array<String>} source-type 选择图片的来源,album-从相册选图,camera-使用相机,默认二者都有(默认['album', 'camera'])
+ * @property {Boolean} preview-full-image	是否可以通过uni.previewImage预览已选择的图片(默认true)
+ * @property {Boolean} multiple	是否开启图片多选,部分安卓机型不支持(默认true)
+ * @property {Boolean} deletable 是否显示删除图片的按钮(默认true)
+ * @property {String Number} max-size 选择单个文件的最大大小,单位B(byte),默认不限制(默认Number.MAX_VALUE)
+ * @property {Array<Object>} file-list 默认显示的图片列表,数组元素为对象,必须提供url属性
+ * @property {Boolean} upload-text 选择图片按钮的提示文字(默认“选择图片”)
+ * @property {Boolean} auto-upload 选择完图片是否自动上传,见上方说明(默认true)
+ * @property {Boolean} show-tips 特殊情况下是否自动提示toast,见上方说明(默认true)
+ * @property {Boolean} show-upload-list 是否显示组件内部的图片预览(默认true)
+ * @event {Function} on-oversize 图片大小超出最大允许大小
+ * @event {Function} on-preview 全屏预览图片时触发
+ * @event {Function} on-remove 移除图片时触发
+ * @event {Function} on-success 图片上传成功时触发
+ * @event {Function} on-change 图片上传后,无论成功或者失败都会触发
+ * @event {Function} on-error 图片上传失败时触发
+ * @event {Function} on-progress 图片上传过程中的进度变化过程触发
+ * @event {Function} on-uploaded 所有图片上传完毕触发
+ * @event {Function} on-choose-complete 每次选择图片后触发,只是让外部可以得知每次选择后,内部的文件列表
+ * @example <u-upload :action="action" :file-list="fileList" ></u-upload>
+ */
+export default {
+	name: 'u-upload',
+	props: {
+		//是否显示组件自带的图片预览功能
+		showUploadList: {
+			type: Boolean,
+			default: true
+		},
+		// 后端地址
+		action: {
+			type: String,
+			default: ''
+		},
+		// 最大上传数量
+		maxCount: {
+			type: [String, Number],
+			default: 52
+		},
+		//  是否显示进度条
+		showProgress: {
+			type: Boolean,
+			default: true
+		},
+		// 是否启用
+		disabled: {
+			type: Boolean,
+			default: false
+		},
+		// 预览上传的图片时的裁剪模式,和image组件mode属性一致
+		imageMode: {
+			type: String,
+			default: 'aspectFill'
+		},
+		// 头部信息
+		header: {
+			type: Object,
+			default() {
+				return {};
+			}
+		},
+		// 额外携带的参数
+		formData: {
+			type: Object,
+			default() {
+				return {};
+			}
+		},
+		// 上传的文件字段名
+		name: {
+			type: String,
+			default: 'photoFile'
+		},
+		// 所选的图片的尺寸, 可选值为original compressed
+		sizeType: {
+			type: Array,
+			default() {
+				return ['original', 'compressed'];
+			}
+		},
+		sourceType: {
+			type: Array,
+			default() {
+				return ['album', 'camera'];
+			}
+		},
+		// 是否在点击预览图后展示全屏图片预览
+		previewFullImage: {
+			type: Boolean,
+			default: true
+		},
+		// 是否开启图片多选,部分安卓机型不支持
+		multiple: {
+			type: Boolean,
+			default: true
+		},
+		// 是否展示删除按钮
+		deletable: {
+			type: Boolean,
+			default: true
+		},
+		// 文件大小限制,单位为byte
+		maxSize: {
+			type: [String, Number],
+			default: Number.MAX_VALUE
+		},
+		// 显示已上传的文件列表
+		fileList: {
+			type: Array,
+			default() {
+				return [];
+			}
+		},
+		// 上传区域的提示文字
+		uploadText: {
+			type: String,
+			default: '选择图片'
+		},
+		// 是否自动上传
+		autoUpload: {
+			type: Boolean,
+			default: true
+		},
+		// 是否显示toast消息提示
+		showTips: {
+			type: Boolean,
+			default: true
+		},
+		// 是否通过slot自定义传入选择图标的按钮
+		customBtn: {
+			type: Boolean,
+			default: false
+		},
+		// 内部预览图片区域和选择图片按钮的区域宽度
+		width: {
+			type: [String, Number],
+			default: 200
+		},
+		// 内部预览图片区域和选择图片按钮的区域高度
+		height: {
+			type: [String, Number],
+			default: 200
+		},
+		// 右上角关闭按钮的背景颜色
+		delBgColor: {
+			type: String,
+			default: '#fa3534'
+		},
+		// 右上角关闭按钮的叉号图标的颜色
+		delColor: {
+			type: String,
+			default: '#ffffff'
+		},
+		// 右上角删除图标名称,只能为uView内置图标
+		delIcon: {
+			type: String,
+			default: 'close'
+		},
+		// 如果上传后的返回值为json字符串,是否自动转json
+		toJson: {
+			type: Boolean,
+			default: true
+		},
+		// 上传前的钩子,每个文件上传前都会执行
+		beforeUpload: {
+			type: Function,
+			default: null
+		},
+		// 移除文件前的钩子
+		beforeRemove: {
+			type: Function,
+			default: null
+		},
+		// 允许上传的图片后缀
+		limitType:{
+			type: Array,
+			default() {
+				// 支付宝小程序真机选择图片的后缀为"image"
+				// https://opendocs.alipay.com/mini/api/media-image
+				return ['png', 'jpg', 'jpeg', 'webp', 'gif', 'image','mp4'];
+			}
+		},
+		// 在各个回调事件中的最后一个参数返回,用于区别是哪一个组件的事件
+		index: {
+			type: [Number, String],
+			default: ''
+		}
+	},
+	mounted() {},
+	data() {
+		return {
+			lists: [],
+			isInCount: true,
+			uploading: false
+		};
+	},
+	watch: {
+		fileList: {
+			immediate: true,
+			handler(val) {
+				val.map(value => {
+					// 首先检查内部是否已经添加过这张图片,因为外部绑定了一个对象给fileList的话(对象引用),进行修改外部fileList
+					// 时,会触发watch,导致重新把原来的图片再次添加到this.lists
+					// 数组的some方法意思是,只要数组元素有任意一个元素条件符合,就返回true,而另一个数组的every方法的意思是数组所有元素都符合条件才返回true
+					let tmp = this.lists.some(val => {
+						return val.url == value.url;
+					})
+					// 如果内部没有这个图片(tmp为false),则添加到内部
+					!tmp && this.lists.push({ url: value.url, error: false, progress: 100 });
+				});
+			}
+		},
+		// 监听lists的变化,发出事件
+		lists(n) {
+			this.$emit('on-list-change', n, this.index);
+		}
+	},
+	methods: {
+		// 清除列表
+		clear() {
+			this.lists = [];
+		},
+		// 重新上传队列中上传失败的所有文件
+		reUpload() {
+			this.uploadFile();
+		},
+		// 选择图片
+		selectFile() {
+			if (this.disabled) return;
+			const { name = '', maxCount, multiple, maxSize, sizeType, lists, camera, compressed, maxDuration, sourceType } = this;
+			let chooseFile = null;
+			const newMaxCount = maxCount - lists.length;
+			// 设置为只选择图片的时候使用 chooseImage 来实现
+			chooseFile = new Promise((resolve, reject) => {
+				uni.chooseFile({
+					count: multiple ? (newMaxCount > 9 ? 9 : newMaxCount) : 1,
+					sourceType: sourceType,
+					sizeType,
+					extension:this.limitType,
+					success: resolve,
+					
+					fail: reject
+				});
+			});
+			chooseFile
+				.then(res => {
+					let file = null;
+					let listOldLength = this.lists.length;
+					res.tempFiles.map((val, index) => {
+						// 检查文件后缀是否允许,如果不在this.limitType内,就会返回false
+						if(!this.checkFileExt(val)) return ;
+						
+						// 如果是非多选,index大于等于1或者超出最大限制数量时,不处理
+						if (!multiple && index >= 1) return;
+						if (val.size > maxSize) {
+							this.$emit('on-oversize', val, this.lists, this.index);
+							this.showToast('超出允许的文件大小');
+						} else {
+							if (maxCount <= lists.length) {
+								this.$emit('on-exceed', val, this.lists, this.index);
+								this.showToast('超出最大允许的文件个数');
+								return;
+							}
+							lists.push({
+								url: val.path,
+								progress: 0,
+								error: false,
+								file: val
+							});
+						}
+					});
+					// 每次图片选择完,抛出一个事件,并将当前内部选择的图片数组抛出去
+					this.$emit('on-choose-complete', this.lists, this.index);
+					if (this.autoUpload) this.uploadFile(listOldLength);
+				})
+				.catch(error => {
+					this.$emit('on-choose-fail', error);
+				});
+		},
+		// 提示用户消息
+		showToast(message, force = false) {
+			if (this.showTips || force) {
+				uni.showToast({
+					title: message,
+					icon: 'none'
+				});
+			}
+		},
+		// 该方法供用户通过ref调用,手动上传
+		upload() {
+			this.uploadFile();
+		},
+		// 对失败的图片重新上传
+		retry(index) {
+			this.lists[index].progress = 0;
+			this.lists[index].error = false;
+			this.lists[index].response = null;
+			uni.showLoading({
+				title: '重新上传'
+			});
+			this.uploadFile(index);
+		},
+		// 上传图片
+		async uploadFile(index = 0) {
+			if (this.disabled) return;
+			if (this.uploading) return;
+			// 全部上传完成
+			if (index >= this.lists.length) {
+				this.$emit('on-uploaded', this.lists, this.index);
+				return;
+			}
+			// 检查是否是已上传或者正在上传中
+			if (this.lists[index].progress == 100) {
+				if (this.autoUpload == false) this.uploadFile(index + 1);
+				return;
+			}
+			// 执行before-upload钩子
+			if(this.beforeUpload && typeof(this.beforeUpload) === 'function') {
+				// 执行回调,同时传入索引和文件列表当作参数
+				// 在微信,支付宝等环境(H5正常),会导致父组件定义的customBack()函数体中的this变成子组件的this
+				// 通过bind()方法,绑定父组件的this,让this.customBack()的this为父组件的上下文
+				// 因为upload组件可能会被嵌套在其他组件内,比如u-form,这时this.$parent其实为u-form的this,
+				// 非页面的this,所以这里需要往上历遍,一直寻找到最顶端的$parent,这里用了this.$u.$parent.call(this)
+				// 明白意思即可,无需纠结this.$u.$parent.call(this)的细节
+				let beforeResponse = this.beforeUpload.bind(this.$u.$parent.call(this))(index, this.lists);
+				// 判断是否返回了promise
+				if (!!beforeResponse && typeof beforeResponse.then === 'function') {
+					await beforeResponse.then(res => {
+						// promise返回成功,不进行动作,继续上传
+					}).catch(err => {
+						// 进入catch回调的话,继续下一张
+						return this.uploadFile(index + 1);
+					})
+				} else if(beforeResponse === false) {
+					// 如果返回false,继续下一张图片的上传
+					return this.uploadFile(index + 1);
+				} else {
+					// 此处为返回"true"的情形,这里不写代码,就跳过此处,继续执行当前的上传逻辑
+				}
+			}
+			// 检查上传地址
+			if (!this.action) {
+				this.showToast('请配置上传地址', true);
+				return;
+			}
+			this.lists[index].error = false;
+			this.uploading = true;
+			// 创建上传对象
+			const task = uni.uploadFile({
+				url: this.action,
+				filePath: this.lists[index].url,
+				name: this.name,
+				formData: this.formData,
+				header: this.header,
+				// #ifdef MP-ALIPAY
+				fileType:'image',
+				// #endif
+				success: res => {
+					// 判断是否json字符串,将其转为json格式
+					
+					let data = this.toJson && this.$u.test.jsonString(res.data) ? JSON.parse(res.data) : res.data;
+					if (![200, 201, 204].includes(res.statusCode)) {
+						this.uploadError(index, data);
+					} else {
+						// 上传成功
+						this.lists[index].response = data;
+						this.lists[index].progress = 100;
+						this.lists[index].error = false;
+						this.$emit('on-success', data, index, this.lists, this.index);
+					}
+				},
+				fail: e => {
+					this.uploadError(index, e);
+				},
+				complete: res => {
+					uni.hideLoading();
+					this.uploading = false;
+					this.uploadFile(index + 1);
+					this.$emit('on-change', res, index, this.lists, this.index);
+				}
+			});
+			task.onProgressUpdate(res => {
+				if (res.progress > 0) {
+					this.lists[index].progress = res.progress;
+					this.$emit('on-progress', res, index, this.lists, this.index);
+				}
+			});
+		},
+		// 上传失败
+		uploadError(index, err) {
+			this.lists[index].progress = 0;
+			this.lists[index].error = true;
+			this.lists[index].response = null;
+			this.$emit('on-error', err, index, this.lists, this.index);
+			this.showToast('上传失败,请重试');
+		},
+		// 删除一个图片
+		deleteItem(index) {
+			uni.showModal({
+				title: '提示',
+				content: '您确定要删除此项吗?',
+				success: async (res) => {
+					if (res.confirm) {
+						// 先检查是否有定义before-remove移除前钩子
+						// 执行before-remove钩子
+						if(this.beforeRemove && typeof(this.beforeRemove) === 'function') {
+							// 此处钩子执行 原理同before-remove参数,见上方注释
+							let beforeResponse = this.beforeRemove.bind(this.$u.$parent.call(this))(index, this.lists);
+							// 判断是否返回了promise
+							if (!!beforeResponse && typeof beforeResponse.then === 'function') {
+								await beforeResponse.then(res => {
+									// promise返回成功,不进行动作,继续上传
+									this.handlerDeleteItem(index);
+								}).catch(err => {
+									// 如果进入promise的reject,终止删除操作
+									this.showToast('已终止移除');
+								})
+							} else if(beforeResponse === false) {
+								// 返回false,终止删除
+								this.showToast('已终止移除');
+							} else {
+								// 如果返回true,执行删除操作
+								this.handlerDeleteItem(index);
+							}
+						} else {
+							// 如果不存在before-remove钩子,
+							this.handlerDeleteItem(index);
+						}
+					}
+				}
+			});
+		},
+		// 执行移除图片的动作,上方代码只是判断是否可以移除
+		handlerDeleteItem(index) {
+			// 如果文件正在上传中,终止上传任务,进度在0 < progress < 100则意味着正在上传
+			if (this.lists[index].progress < 100 && this.lists[index].progress > 0) {
+				typeof this.lists[index].uploadTask != 'undefined' && this.lists[index].uploadTask.abort();
+			}
+			this.lists.splice(index, 1);
+			this.$forceUpdate();
+			this.$emit('on-remove', index, this.lists, this.index);
+			this.showToast('移除成功');
+		},
+		// 用户通过ref手动的形式,移除一张图片
+		remove(index) {
+			// 判断索引的合法范围
+			if (index >= 0 && index < this.lists.length) {
+				this.lists.splice(index, 1);
+				this.$emit('on-list-change', this.lists, this.index);
+			}
+		},
+		// 预览图片
+		doPreviewImage(url, index) {
+			if (!this.previewFullImage) return;
+			const images = this.lists.map(item => item.url || item.path);
+			uni.previewImage({
+				urls: images,
+				current: url,
+				success: () => {
+					this.$emit('on-preview', url, this.lists, this.index);
+				},
+				fail: () => {
+					uni.showToast({
+						title: '预览图片失败',
+						icon: 'none'
+					});
+				}
+			});
+		},
+		// 判断文件后缀是否允许
+		checkFileExt(file) {
+			// 检查是否在允许的后缀中
+			let noArrowExt = false;
+			// 获取后缀名
+			let fileExt = '';
+			const reg = /.+\./;
+			// 如果是H5,需要从name中判断
+			// #ifdef H5
+			fileExt = file.name.replace(reg, "").toLowerCase();
+			// #endif
+			// 非H5,需要从path中读取后缀
+			// #ifndef H5
+			fileExt = file.path.replace(reg, "").toLowerCase();
+			// #endif
+			// 使用数组的some方法,只要符合limitType中的一个,就返回true
+			noArrowExt = this.limitType.some(ext => {
+				// 转为小写
+				return ext.toLowerCase() === fileExt;
+			})
+			if(!noArrowExt) this.showToast(`不允许选择${fileExt}格式的文件`);
+			return noArrowExt;
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+@import '../../libs/css/style.components.scss';
+
+.u-upload {
+	@include vue-flex;
+	flex-wrap: wrap;
+	align-items: center;
+}
+
+.u-list-item {
+	width: 200rpx;
+	height: 200rpx;
+	overflow: hidden;
+	margin: 10rpx;
+	background: rgb(244, 245, 246);
+	position: relative;
+	border-radius: 10rpx;
+	/* #ifndef APP-NVUE */
+	display: flex;
+	/* #endif */
+	align-items: center;
+	justify-content: center;
+}
+
+.u-preview-wrap {
+	border: 1px solid rgb(235, 236, 238);
+}
+
+.u-add-wrap {
+	flex-direction: column;
+	color: $u-content-color;
+	font-size: 26rpx;
+}
+
+.u-add-tips {
+	margin-top: 20rpx;
+	line-height: 40rpx;
+}
+
+.u-add-wrap__hover {
+	background-color: rgb(235, 236, 238);
+}
+
+.u-preview-image {
+	display: block;
+	width: 100%;
+	height: 100%;
+	border-radius: 10rpx;
+}
+
+.u-delete-icon {
+	position: absolute;
+	top: 10rpx;
+	right: 10rpx;
+	z-index: 10;
+	background-color: $u-type-error;
+	border-radius: 100rpx;
+	width: 44rpx;
+	height: 44rpx;
+	@include vue-flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.u-icon {
+	@include vue-flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.u-progress {
+	position: absolute;
+	bottom: 10rpx;
+	left: 8rpx;
+	right: 8rpx;
+	z-index: 9;
+	width: auto;
+}
+
+.u-error-btn {
+	color: #ffffff;
+	background-color: $u-type-error;
+	font-size: 20rpx;
+	padding: 4px 0;
+	text-align: center;
+	position: absolute;
+	bottom: 0;
+	left: 0;
+	right: 0;
+	z-index: 9;
+	line-height: 1;
+}
+</style>