he2802 4 年之前
父節點
當前提交
62b0fb8bf2
共有 45 個文件被更改,包括 6057 次插入233 次删除
  1. 49 0
      common/httpList/goods.js
  2. 31 0
      pages.json
  3. 351 0
      pages2/bank/collectById.vue
  4. 300 54
      pages2/bank/questionBank.vue
  5. 1270 0
      pages2/bank/questionBankExplain.vue
  6. 6 6
      pages2/bank/questionBankTest.vue
  7. 100 28
      pages2/bank/question_detail.vue
  8. 64 8
      pages2/bank/question_record.vue
  9. 18 8
      pages2/bank/question_report.vue
  10. 269 98
      pages2/bank/question_statistics.vue
  11. 348 0
      pages2/bank/wrongById.vue
  12. 15 3
      pages2/subject/collect.vue
  13. 6 6
      pages2/subject/collectBank.vue
  14. 6 6
      pages2/subject/collectTypeBank.vue
  15. 6 6
      pages2/subject/wrongBank.vue
  16. 6 6
      pages2/subject/wrongTypeBank.vue
  17. 4 4
      pages2/wd/question_bank.vue
  18. 16 0
      uni_modules/uni-icons/changelog.md
  19. 1115 0
      uni_modules/uni-icons/components/uni-icons/icons.js
  20. 89 0
      uni_modules/uni-icons/components/uni-icons/uni-icons.vue
  21. 663 0
      uni_modules/uni-icons/components/uni-icons/uniicons.css
  22. 二進制
      uni_modules/uni-icons/components/uni-icons/uniicons.ttf
  23. 86 0
      uni_modules/uni-icons/package.json
  24. 8 0
      uni_modules/uni-icons/readme.md
  25. 22 0
      uni_modules/uni-nav-bar/changelog.md
  26. 254 0
      uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue
  27. 27 0
      uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue
  28. 89 0
      uni_modules/uni-nav-bar/package.json
  29. 15 0
      uni_modules/uni-nav-bar/readme.md
  30. 6 0
      uni_modules/uni-scss/changelog.md
  31. 1 0
      uni_modules/uni-scss/index.scss
  32. 95 0
      uni_modules/uni-scss/manifest.json
  33. 82 0
      uni_modules/uni-scss/package.json
  34. 4 0
      uni_modules/uni-scss/readme.md
  35. 7 0
      uni_modules/uni-scss/styles/index.scss
  36. 3 0
      uni_modules/uni-scss/styles/setting/_border.scss
  37. 66 0
      uni_modules/uni-scss/styles/setting/_color.scss
  38. 55 0
      uni_modules/uni-scss/styles/setting/_radius.scss
  39. 56 0
      uni_modules/uni-scss/styles/setting/_space.scss
  40. 167 0
      uni_modules/uni-scss/styles/setting/_styles.scss
  41. 24 0
      uni_modules/uni-scss/styles/setting/_text.scss
  42. 146 0
      uni_modules/uni-scss/styles/setting/_variables.scss
  43. 19 0
      uni_modules/uni-scss/styles/tools/functions.scss
  44. 31 0
      uni_modules/uni-scss/theme.scss
  45. 62 0
      uni_modules/uni-scss/variables.scss

+ 49 - 0
common/httpList/goods.js

@@ -68,6 +68,30 @@ export default {
 		})
 	},
 	
+	goodsBankQuestionNum(data) {
+		return myRequest({
+			url: '/goods/bank/questionNum/'+data,
+			data:data,
+			method: 'get',
+		})
+	},
+	
+	
+	examReport(data) {
+		return myRequest({
+			url: '/exam/record/'+data,
+			method: 'get',
+		})
+	},
+	
+	examRecordCount(data) {
+		return myRequest({
+			url: '/exam/record/count',
+			data:data,
+			method: 'GET',
+		})
+	},
+	
 	examaperList(data) {
 		return myRequest({
 			url: '/exam/paper/list',
@@ -180,6 +204,31 @@ export default {
 		})
 	},
 	
+	goodsBankDolist(data) {
+		return myRequest({
+			url: '/goods/bank/dolist',
+			method: 'get',
+			data:data
+		})
+	},
+	
+	goodsChapterDolist(data) {
+		return myRequest({
+			url: '/goods/chapter/dolist',
+			method: 'get',
+			data:data
+		})
+	},
+	goodsExamDolist(data) {
+		return myRequest({
+			url: '/goods/exam/dolist',
+			method: 'get',
+			data:data
+		})
+	},
+	
+	
+	
 	goodsCollectList(data) {
 		return myRequest({
 			url: '/collect/question/list',

+ 31 - 0
pages.json

@@ -333,6 +333,17 @@
 				"path": "bank/questionBank",
 				"style": {
 					"navigationBarTitleText": "试卷题目",
+					"navigationStyle": "custom", // 隐藏系统导航栏
+					"app-plus": {
+						"titleNView": false, //禁用原生导航栏 
+						"bounce": "none"
+					}
+				}
+			},
+			{
+				"path": "bank/questionBankExplain",
+				"style": {
+					"navigationBarTitleText": "试卷解析",
 					"app-plus": {
 						"titleNView": false, //禁用原生导航栏 
 						"bounce": "none"
@@ -510,6 +521,26 @@
 					}
 				}
 			},
+			{
+				"path": "bank/wrongById",
+				"style": {
+					"navigationBarTitleText": "错题集",
+					"app-plus": {
+						"titleNView": false, //禁用原生导航栏 
+						"bounce": "none"
+					}
+				}
+			},
+			{
+				"path": "bank/collectById",
+				"style": {
+					"navigationBarTitleText": "收藏集",
+					"app-plus": {
+						"titleNView": false, //禁用原生导航栏 
+						"bounce": "none"
+					}
+				}
+			},
 			{
 				"path": "subject/collect",
 				"style": {

+ 351 - 0
pages2/bank/collectById.vue

@@ -0,0 +1,351 @@
+<template>
+	<view class="safeArea">
+		<view class="sceenBox">
+			<view :class="['item', {'active':sceenType===2} ]" @click="showSceen(2)">全部试卷类型<u-icon class="icon" name="arrow-down"></u-icon></view>
+		</view>
+		<view class="sceenModel" v-if="sceenType">
+			<view class="sceenModelBg" @click="hideSceen"></view>
+			<view class="sceenMain">
+					<view :class="['item',{'active':item.checked}]" v-for="(item, index) in scennList2" :key="index" @click="choseType(index)">{{item.paperName}}</view>
+			</view>
+		</view>
+		<view class="wrap">
+			<view class="wrongTab">
+				<view class="item" :class="{active:type == 1}" @click="selectType(1)">试卷归类</view>
+				<view class="item" :class="{active:type == 2}" @click="selectType(2)">题型归类</view>
+			</view>
+			<view class="wrongHead">
+				<view class="title">收藏统计</view>
+				<view class="progress">
+					<text v-if="type == 1">{{testList.total}}</text>
+					<text v-if="type == 2">{{typeList.total}}</text>
+				</view>
+			</view>
+			<view class="wrongList" v-if="type == 1">
+				<view class="item" v-for="(item,index) in testList.rows" :key="index">
+					<view class="title">{{item.examName}}</view>
+					<view class="bt">
+						<view class="left">收藏数<text class="num">{{item.questionNum}}</text></view>
+						<view class="right">
+							<navigator :url="'/pages2/subject/collectBank?id='+item.examId">
+								<view class="btn">重做</view>
+							</navigator>
+							<navigator :url="'/pages2/subject/collectBank?id='+item.examId+'&explain=1'">
+								<view class="btn">解析</view>
+							</navigator>
+							<!-- <view class="btn">解析</view> -->
+						</view>
+					</view>
+				</view>
+			</view>
+			
+			<view class="wrongList" v-if="type == 2">
+				<view class="item" v-for="(item,index) in typeList.rows" :key="index">
+					<view class="title">
+						<text v-if="item.type==1">单选题</text>
+						<text v-if="item.type==2">多选题</text>
+						<text v-if="item.type==3">判断题</text>
+						<text v-if="item.type==4">案例题</text>
+						<text v-if="item.type==5">简答题</text>
+					</view>
+					<view class="bt">
+						<view class="left">收藏数<text class="num">{{item.num}}</text></view>
+						<view class="right">
+							<navigator :url="'/pages2/subject/collectTypeBank?type='+item.type">
+								<view class="btn">重做</view>
+							</navigator>
+							<navigator :url="'/pages2/subject/collectTypeBank?type='+item.type+'&explain=1'">
+								<view class="btn">解析</view>
+							</navigator>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+import { mapGetters } from 'vuex';
+export default {
+	components: {},
+	data() {
+		return {
+			sceenType: null,
+			scennList2:[
+				{paperId: '', paperName: '全部试卷类型', checked: true}
+			],
+			type:1,
+			testList:[],
+			typeList:[],
+			total:0,
+			goodsid:'',
+			paperid:''
+		};
+	},
+	onPullDownRefresh() {},
+	onLoad(option) {
+		
+		this.goodsid = option.goodsid
+		this.examaperList();
+		this.getData();
+	},
+	methods: {
+		getData() {
+			if(this.type == 1) {
+				this.goodsCollectExamList()
+			} else if(this.type == 2) {
+				this.collectQuestionTypeList();
+			}
+		},
+		examaperList() {
+			this.$api.examaperList({
+				
+			}).then(res => {
+				this.scennList2 = [...this.scennList2,...res.data.rows];
+			})
+		},
+
+		goodsCollectExamList() {
+			this.$api.goodsCollectExamList({
+				paperId:this.paperid,
+				goodsId:this.goodsid
+			}).then(res => {
+				this.testList = res.data 
+				let total = 0;
+				this.testList.rows.forEach(item => {
+					total += item.num;
+				})
+				
+				this.total = total
+			})
+		},
+		collectQuestionTypeList() {
+			this.$api.collectQuestionTypeList({
+				paperId:this.paperid,
+				goodsId:this.goodsid
+			}).then(res => {
+				this.typeList = res.data 
+				let total = 0;
+				this.typeList.rows.forEach(item => {
+					total += item.num;
+				})
+				
+				this.total = total
+			})
+		},
+		showSceen(type){
+			this.sceenType = type
+		},
+		/**
+		 * @param {Object} tab切换
+		 */
+		selectType(type) {
+			this.type = type;
+			this.getData();
+		},
+		hideSceen(){
+			this.sceenType = null
+		},
+		choseType(index) {
+			this.sceenType = null
+			this.scennList2.forEach((item,idx)=>{
+				this.$set(item, 'checked',false)
+				if(index==idx){
+					this.paperid = item.paperId
+					this.$set(item, 'checked',true)
+				}
+			})
+			this.getData()
+		},
+	}
+};
+</script>
+<style lang="scss">
+page {
+	background: #EAEEF1;
+}
+
+</style>
+<style scoped lang="scss">
+.sceenBox {
+	width:100%;
+	height: 80rpx;
+	background: #FFFFFF;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	font-size: 32rpx;
+	font-family: PingFang SC;
+	font-weight: 500;
+	color: #999999;
+	position: fixed;
+	z-index: 999;
+	border-bottom: 1px solid #eee;
+	.item{
+		flex:1;
+		text-align: center;
+		&.active{
+			color:#333;
+			font-weight: bold;
+			.icon{
+				transform: rotate(180deg);
+			}
+		}
+	}
+}
+.sceenModel{
+	width:100%;
+	height:100%;
+	position: fixed;
+	z-index: 998;
+	.sceenModelBg{
+		width:100%;
+		height:100%;
+		position: fixed;
+		background: rgba(0,0,0,.3);
+		z-index: 998;
+	}
+	.sceenMain{
+		position: relative;
+		z-index: 999;
+		background: #fff;
+		margin-top: 80rpx;
+		display: flex;
+		flex-wrap: wrap;
+		padding: 8rpx;
+		justify-content: space-between;
+		.item{
+			width: 350rpx;
+			background: #F5F5F5;
+			border-radius: 16rpx;
+			padding: 25rpx 19rpx;
+			margin: 8rpx;
+			font-size: 32rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #666666;
+			&.active{
+				background: #007AFF;
+				color:#fff;
+			}
+			&:first-child{
+				width:100%;
+				text-align: center;
+			}
+		}
+	}
+}
+.wrap{
+	padding:96rpx 16rpx 16rpx;
+}
+.wrongHead{
+	background: #FFFFFF;
+	border-radius: 16px;
+	padding:24rpx;
+	.title{
+		font-size: 30rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		.sub{
+			font-size: 20rpx;
+			font-weight: 500;
+			color: #999999;
+		}
+	}
+	.progress{
+		width: 180rpx;
+		height: 180rpx;
+		line-height: 140rpx;
+		border: 20rpx solid #EEEEEE;
+		border-radius: 50%;
+		margin: 24rpx auto;
+		font-size: 50rpx;
+		text-align: center;
+		
+	}
+}
+.wrongTab{
+	display: flex;
+	margin: 24rpx 0;
+	.item{
+		width: 144rpx;
+		height: 48rpx;
+		line-height: 48rpx;
+		text-align: center;
+		background: #fff;
+		border-radius: 16px;
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		margin-left: 15rpx;
+		&.active{
+			background: #007AFF;
+			color: #fff;
+		}
+	}
+}
+.wrongList{
+	margin-top:20rpx;
+	.item{;
+		background: #FFFFFF;
+		border-radius: 16rpx;
+		padding: 0 30rpx;
+		margin-bottom: 16rpx;
+		overflow: hidden;
+		.title{
+			font-size: 32rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #333333;
+			margin: 40rpx 0 17rpx;
+		}
+		.bt{
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			padding-bottom: 24rpx;
+			.left{
+				width: 176rpx;
+				height: 40rpx;
+				background: #FFFFFF;
+				border: 1px solid #EEEEEE;
+				border-radius: 16rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+				display: flex;
+				justify-content: center;
+				align-items: center;
+				.num{
+					font-size: 26rpx;
+					font-weight: bold;
+					color: #FF3B30;
+					margin-left: 16rpx;
+				}
+			}
+			.right{
+				display: flex;
+				.btn{
+					width: 100rpx;
+					height: 48rpx;
+					background: #FFFFFF;
+					border: 1px solid #007AFF;
+					border-radius: 16px;
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #007AFF;
+					margin-left:9rpx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
+			}
+		}
+	}
+}
+</style>

+ 300 - 54
pages2/bank/questionBank.vue

@@ -1,5 +1,6 @@
 <template>
 	<view id="questionBank">
+		<uni-nav-bar @clickLeft="clickLeft" left-icon="back" :statusBar="true" title="试卷"></uni-nav-bar>
 		<swiper class="swiper" :current="current" @change="swiperChange" :interval="interval">
 			<swiper-item v-for="(bank,bankIndex) in questionList" :key="bankIndex">
 				<view class="pageContent">
@@ -136,7 +137,7 @@
 									<view class="answerTitle">答案我的</view>
 									{{bank.ques.text}}
 									<view class="imgs">
-										<image class="img" v-for="ques in bank.ques.imageList" :src="ques"></image>
+										<image class="img" v-for="ques in bank.ques.imageList" :src="$method.splitImgHost(ques,true)"></image>
 									</view>
 								</view>
 							</view>
@@ -271,7 +272,7 @@
 											<view class="answerTitle">答案我的</view>
 											{{bank.ques[ansIndex].text}}
 											<view class="imgs">
-												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="ques"></image>
+												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="$method.splitImgHost(ques,true)"></image>
 											</view>
 										</view>
 									</view>
@@ -322,6 +323,35 @@
 			<view class="text">左右滑动切换上下题</view>
 			<view class="btn" @click="hideDialog">我知道了</view>
 		</view>
+		
+		<view class="dialog_wrap" v-if="testOver">
+			<view class="bg"></view>
+			<view class="dialog">
+				<view class="title">温馨提示</view>
+				<view class="content">
+					<view>您已完成所有题目,</view>
+					<view>快去交卷吧!</view>
+				</view>
+				<view class="btns">
+					<view class="btn" @click="noSubmit()">暂不交卷</view>
+					<view class="btn active" @click="submitNow()">立即交卷</view>
+				</view>
+			</view>
+		</view>
+		
+		<view class="dialog_wrap" v-if="isLastCount">
+			<view class="bg"></view>
+			<view class="dialog">
+				<view class="title">温馨提示</view>
+				<view class="content">
+					<view>您当前正在测试,还剩{{lastCount}}道题未完成,离开视为交卷</view>
+				</view>
+				<view class="btns">
+					<view class="btn" @click="noLeave()">暂不离开</view>
+					<view class="btn active" @click="leaveNow()">继续离开</view>
+				</view>
+			</view>
+		</view>
 	</view>
 </template>
 
@@ -346,61 +376,60 @@ export default {
 			lastTime:0,
 			timer :null,
 			wrongList:[],
-			bankType:0
+			bankType:0, //试卷类型
+			needBack:false,  //是否是考试
+			testOver:false,
+			isLastCount:false, //是否有未答题目
+			lastCount:0, //剩余没有回答的题目数
+			chapterId:0,
+			moduleId:0,
 		};
 	},
 	onLoad(option){
 		this.id = option.id;
 		this.goodsId = option.goodsid;
-		this.goodsQuestionList();
-		this.wrongRecordExamQuestionList();
-		this.bankExam();
+		this.chapterId = option.chapterId;
+		this.moduleId = option.moduleId;
+		let isBack = option.isback;
+		
+		if(isBack) {
+			console.log(getApp())
+			let app = getApp();
+			let globalData = app.globalData;
+			
+			for(var k in globalData.bankData) {
+				this[k] = globalData.bankData[k];
+			}
+		} else {
+			this.goodsQuestionList();
+			// this.wrongRecordExamQuestionList();
+			this.bankExam();
+		}
 	},
 	onUnload() {
-		console.log(this.ans)
-		this.examRecordEdit();
+		if(this.isSubmit) {
+			return;
+		}
+		//考试试卷 阻止ios手势返回,自动跳回答题页
+		if(this.needBack) {
+			let app = getApp();
+			app.globalData.bankData = this.$data;
+			uni.navigateTo({
+				 url: '/pages2/bank/questionBank?id='+this.id+'&goodsid='+this.goodsId+'&isback=true'
+			})
+		} else {
+			//点击返回按钮确认允许退出,记录答题记录
+			
+			this.examRecordEdit();
+		}
+		
 	},
 	methods: {
 		bankExam() {
 			this.$api.bankExam(this.id).then(res => {
 				this.bankType = res.data.data.doType;
-				console.log(res.data)
-				if(this.bankType == 1) { // 练习
-					wx.enableAlertBeforeUnload({
-					
-						message: "返回上页时弹出对话框1212",
-						
-						success: function (res) {
-						
-						console.log("方法注册成功:", res)
-						
-						},
-						
-						fail: function (errMsg) {
-						
-						console.log("方法注册失败:", errMsg);
-						
-						},
-					
-					});
-				} else if(this.bankType == 2){  //考试
-					wx.enableAlertBeforeUnload({
-					
-						message: "返回上页时弹出对话框1212",
-						
-						success: function (res) {
-						
-						console.log("方法注册成功:", res)
-						
-						},
-						
-						fail: function (errMsg) {
-						
-						console.log("方法注册失败:", errMsg);
-						
-						},
-					
-					});
+				if(this.bankType == 2) {
+					this.needBack = true;
 				}
 			})
 		},
@@ -415,6 +444,146 @@ export default {
 				this.wrongList = res.data.rows
 			})
 		},
+		/**
+		 * 点击后退按钮
+		 */
+		clickLeft() {
+			
+			if(this.bankType == 1) {
+				this.needBack = false;
+				uni.navigateBack({
+					delta:1
+				})
+			} else if(this.bankType == 2){
+				let ansCount = this.questionOverNum();  //已答题数
+				this.lastCount = this.questionList.length - ansCount; //统计未答完的题数
+				
+				//所有题目答完
+				if(this.lastCount == 0) {
+					this.testOver = true;
+				//未答完
+				} else {
+					this.isLastCount = true;
+				}
+			}
+			
+		},
+		/**
+		 * 获取已经回答的题目数
+		 */
+		questionOverNum() {
+			let count = 0;
+			this.questionList.forEach(item => {
+				if(item.type == 1 || item.type == 2 || item.type == 3) {
+					if(item.ques) {
+						count++;
+					}
+				} else if(item.type == 4) { //案例题
+					let isOver = item.jsonStr.every(jsonItem => {
+						if(jsonItem.type == 1 || jsonItem.type == 2 || jsonItem.type == 3) {
+							if(jsonItem.ques) {
+								return true;
+							} else {
+								return false;
+							}
+						} else if(jsonItem.type ==5) {
+							if(jsonItem.ansText.text.length || jsonItem.ansText.imageList.length) {
+								return true;
+							} else {
+								return false;
+							}
+						}
+					})
+					
+					if(isOver) {
+						count++;
+					}
+				} else if(item.type == 5) { //简答题
+					if(item.ansText.text.length || item.ansText.imageList.length) {
+						count++;
+					}
+				}
+			})
+			
+			return count;
+		},
+		/**
+		 * 暂不交卷
+		 */
+		noSubmit() {
+			//设为允许退出页面
+			this.needBack = false;
+			uni.navigateBack({
+				delta:1
+			})
+		},
+		/**
+		 * 不离开
+		 */
+		noLeave() {
+			this.isLastCount = false;
+		},
+		/**
+		 * 立即离开并交卷
+		 */
+		leaveNow() {
+			this.needBack = false;
+			uni.navigateBack({
+				delta:1
+			})
+			let score = 0; //计算总分
+			let reportStatus = 0;
+			let number = 0;
+			this.questionList.forEach((item,index) => {
+				if(item.type == 1) {
+					if(item.ques == item.ans) { 
+						score += item.score;
+						number++
+					}
+				} else if(item.type == 2) {
+					let isRight = item.ques && item.ques.every((quesItem,quesIndex) => {
+						return item.ques[quesIndex] == item.ans[quesIndex]
+					})
+					
+					if(isRight) {
+						score += item.score;
+						number++
+					}
+				} else if(item.type == 3) {
+					if(item.ques == item.ans) {
+						score += item.score;
+						number++
+					}
+				}
+			})
+			
+			// if(score >= 60) {
+			// 	reportStatus = 1
+			// } else {
+			// 	reportStatus = 0
+			// }
+			
+			this.$api.examRecordEdit({
+				examId:this.id,
+				goodsId:this.goodsId,
+				// reportStatus:reportStatus,
+				doQuestionNum:this.questionOverNum(),
+				recordId: this.recordId,
+				rightQuestionNum:number,
+				status:1,
+				score:score,
+				historyExamJson:JSON.stringify(this.questionList)
+			}).then(res => {
+
+			})
+		},
+		/**
+		 * 立即交卷
+		 */
+		submitNow() {
+			this.needBack = false;
+			this.submit();
+		},
 		/**
 		 * 离开页面统计回答正确题数
 		 */
@@ -422,6 +591,7 @@ export default {
 			if(!this.isSubmit) {
 				
 				let number = 0;
+				let score = 0;
 				this.questionList.forEach((item,index) => {
 					if(item.type == 1) {
 						if(item.ques == item.ans) { 
@@ -451,7 +621,7 @@ export default {
 					recordId: this.recordId,
 					rightQuestionNum:number,
 					status:0,
-					historyExamJson:JSON.stringify({ans:this.ans,ques:this.ques})
+					historyExamJson:JSON.stringify(this.questionList)
 				}).then(res => {
 					
 				})
@@ -462,6 +632,8 @@ export default {
 		 */
 		examRecord() {
 			this.$api.examRecord({
+				chapterExamId:this.chapterId || 0,
+				moduleExamId:this.moduleId || 0,
 				examId:this.id,
 				goodsId:this.goodsId,
 				totalQuestionNum:this.questionList.length,
@@ -582,6 +754,7 @@ export default {
 				})
 				
 				this.questionList = res.data.data;
+				this.lastCount = this.questionList.length;
 				this.examRecord()
 				this.getCollectInfo(this.current)
 				
@@ -835,9 +1008,9 @@ export default {
 					});
 					
 					setTimeout(() => {
-						uni.navigateBack({
-						    delta: 1
-						});
+						uni.redirectTo({
+							url:'/pages2/bank/question_report?id='+this.recordId
+						})
 					},2000)
 				}
 			})
@@ -1041,7 +1214,7 @@ export default {
 		 * @param {Object} bankindex
 		 * 简答题答案确认
 		 */
-		submitAns(type,bankindex) {
+		submitAns(bankindex) {
 				
 			console.log(this.questionList[bankindex])
 			if(!this.questionList[bankindex].ansText.text && !this.questionList[bankindex].ansText.imageList.length) {
@@ -1053,7 +1226,7 @@ export default {
 				return
 			}
 			
-			this.$set(this.ques,bankindex,{
+			this.$set(this.questionList[bankindex],'ques',{
 				imageList:this.questionList[bankindex].ansText.imageList,
 				text:this.questionList[bankindex].ansText.text,
 			})
@@ -1091,8 +1264,8 @@ export default {
 				//多选
 				} else if(item.type == 2) {
 					//每一项都相等
-					return this.questionList[index].ques.every((item,index) => {
-						return item == this.questionList[index].ans;
+					return this.questionList[index].ques.every((item,i) => {
+						return item == this.questionList[index].ans[i];
 					})
 				//判断
 				} else if(item.type == 3) {
@@ -1170,7 +1343,7 @@ export default {
 <style lang="scss" scoped>
 .swiper {
 	width:100%;
-	height:100vh;
+	height:calc(100vh - 44px);
 }
 .lisSty {
 	margin-bottom: 16rpx;
@@ -1512,4 +1685,77 @@ export default {
 		font-size: 32rpx;
 	}
 }
+
+.dialog_wrap {
+	position:fixed;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	z-index: 9999999999;
+	
+	.bg {
+		background:rgba(0, 0, 0, 0.3);
+		position:absolute;
+		left:0;
+		top:0;
+		width:100%;
+		height:100%;
+	}
+	
+	.dialog {
+		position:absolute;
+		left:50%;
+		top:50%;
+		transform: translate3D(-50%,-50%,0);
+		width: 640rpx;
+		height: 439rpx;
+		background: #FFFFFF;
+		border-radius: 24rpx;
+		
+		
+		.title {
+			font-size: 30rpx;
+			font-weight: bold;
+			color: #333333;
+			line-height: 48rpx;
+			text-align: center;
+			margin-top:40rpx;
+		}
+		
+		.content {
+			margin:35rpx 35rpx 0;
+			font-size: 30rpx;
+			color: #666666;
+			line-height: 48rpx;
+		}
+		
+		.btns {
+			margin-top:35rpx;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			
+			.btn {
+				width: 200rpx;
+				height: 80rpx;
+				line-height: 80rpx;
+				text-align: center;
+				background: #F5F5F5;
+				border-radius: 40rpx;
+				font-size: 30rpx;
+				color:rgba(0, 122, 255, 1);
+				background: #F5F5F5;
+				margin:0 20rpx;
+				
+				&.active {
+					color: #F5F5F5;
+					background: rgba(0, 122, 255, 1);
+				}
+			}
+		}
+		
+	}
+	
+}
 </style>

+ 1270 - 0
pages2/bank/questionBankExplain.vue

@@ -0,0 +1,1270 @@
+<template>
+	<view id="questionBank">
+		<swiper class="swiper" :current="current" @change="swiperChange" :interval="interval">
+			<swiper-item v-for="(bank,bankIndex) in questionList" :key="bankIndex">
+				<view class="pageContent">
+					<view class="pad_8 titBox" >
+						<view class="firstLetter">
+							<view class="leftLetters">
+								<view class="btnType">
+									<text v-if="bank.type==1">单选</text>
+									<text v-if="bank.type==2">多选</text>
+									<text v-if="bank.type==3">判断</text>
+									<text v-if="bank.type==4">案例题</text>
+									<text v-if="bank.type==5">简答题</text>
+								</view>
+								<text>{{bankIndex+1}}/{{questionList.length}}</text>
+							</view>
+							<view style="color: #666;font-size: 28rpx;"></view>
+							<view class="leftLetters"></view>
+						</view>
+						<view class="titles">
+							<rich-text :nodes="bank.content"></rich-text>
+						</view>		
+					</view>
+					<view class="pad_8 titBox">
+						<template v-if="bank.type == 1">
+							<view v-if="!bank.ques">
+								<view v-for="(item, index) in bank.jsonStr" :key="index" class="lisSty" @click="radioSelect(item.optionsId,bankIndex)">
+									<view class="activeTI">{{ ast[index] }}</view>
+									<view class="flex_auto">{{ item.content }}</view>
+								</view>
+							</view>
+							<view v-if="bank.ques">
+								<view v-for="(item, index) in bank.jsonStr" :key="index" class="lisSty">
+									<text :class="{right:(item.optionsId == bank.ques) || (item.optionsId == bank.ans),wrong:(item.optionsId == bank.ques) && (bank.ques != bank.ans)}"  class="activeTI">{{ ast[index] }}</text>
+									<view class="flex_auto">{{ item.content }}</view>
+								</view>
+							</view> 
+							<view v-if="bank.ques">
+								<view class="pad_8 answer">
+									<view>正确答案:{{ast[bank.ans-1]}}</view>
+									<view v-if="!explain">我的答案:{{ast[bank.ques-1]}}</view>
+								</view>
+								<view class="pad_8 answerInfos">
+									<view class="answerTitle">答案解析</view>
+									<view class="answerContent">
+										<rich-text :nodes="bank.analysisContent"></rich-text>
+									</view>
+								</view>
+							</view>
+						</template>
+						
+						<template v-if="bank.type == 2">
+							<view v-if="!bank.ques">
+								<view v-for="(item, index) in bank.jsonStr" :key="index" class="lisSty" @click="checkboxSelect(item.optionsId,bankIndex,index)">
+									<view :class="{checked:item.checked}" class="activeTI">{{ ast[index] }}</view>
+									<view class="flex_auto">{{ item.content }}</view>
+								</view>
+							</view>
+							<view v-if="!bank.ques" class="submit_checkbox" @click="checkboxSubmit(bankIndex)">
+								确认答案
+							</view>
+							<view v-if="bank.ques">
+								<view v-for="(item, index) in bank.jsonStr" :key="index" class="lisSty">
+									<text :class="{right:(bank.ques.indexOf(item.optionsId) != -1 ) || (bank.ans.indexOf(item.optionsId) != -1),wrong:(bank.ques.indexOf(item.optionsId) != -1 ) && (bank.ans.indexOf(item.optionsId) == -1)}"  class="activeTI">{{ ast[index] }}</text>
+									<view class="flex_auto">{{ item.content }}</view>
+								</view>
+							</view> 
+							<view v-if="bank.ques">
+								<view class="pad_8 answer">
+									<view>正确答案:
+										<text v-for="ansItem in bank.ans">{{ast[ansItem-1]}}</text>
+									</view>
+									<view v-if="!explain">我的答案:
+										<text v-for="quesItem in bank.ques">{{ast[quesItem-1]}}</text>
+									</view>
+								</view>
+								<view class="pad_8 answerInfos">
+									<view class="answerTitle">答案解析</view>
+									<view class="answerContent">
+										<rich-text :nodes="bank.analysisContent"></rich-text>
+									</view>
+								</view>
+							</view>
+						</template>
+						
+						<template v-if="bank.type == 3">
+							<view v-if="!bank.ques">
+								<view v-for="(item, index) in judge" :key="index" class="lisSty" @click="judgeSelect(index,bankIndex)">
+									<view class="activeTI">{{ ast[index] }}</view>
+									{{ item }}
+								</view>
+							</view>
+							<view v-if="bank.ques">
+								<view v-for="(item, index) in judge" :key="index" class="lisSty">
+									<text :class="{right:(index == bank.ques) || (index == bank.ans),wrong:(index == bank.ques) && (bank.ques != bank.ans)}"  class="activeTI">{{ ast[index] }}</text>
+									{{ item }}
+								</view>
+							</view> 
+							<view v-if="bank.ques">
+								<view class="pad_8 answer">
+									<view>正确答案:{{ast[bank.ans]}}</view>
+									<view v-if="!explain">我的答案:{{ast[bank.ques]}}</view>
+								</view>
+								<view class="pad_8 answerInfos">
+									<view class="answerTitle">答案解析</view>
+									<view class="answerContent">
+										<rich-text :nodes="bank.analysisContent"></rich-text>
+									</view>
+								</view>
+							</view>
+						</template>
+						
+						
+						<!-- 简答题 -->
+						<template v-if="bank.type == 5">
+							<view class="ans">
+								<view class="ans_input" v-if="!bank.ques">
+									<view class="top flex">
+										<image :data-index="bankIndex" class="icon" @click="chooseImg(bankIndex)" src="/static/08-10_032.jpg" mode=""></image>
+										<view class="progress">0/4</view>
+										<view class="submit"  @click="submitAns(bankIndex)" >确认答案</view>
+									</view>
+									<view class="textarea">
+										<textarea v-model="bank.ansText.text" placeholder="在此输入答案"></textarea>
+									</view>
+									<view class="imgs">
+										<view class="img" v-for="(img,imgIndex) in bank.ansText.imageList" >
+											<text @click="deleteImg(imgIndex,bankIndex)">x</text>
+											<image :src="$method.splitImgHost(img, true)"></image>
+										</view>
+									</view>
+								</view>
+								<view class="ans_submit answerInfos" v-if="bank.ques && !explain">
+									<view class="answerTitle">答案我的</view>
+									{{bank.ques.text}}
+									<view class="imgs">
+										<image class="img" v-for="ques in bank.ques.imageList" :src="$method.splitImgHost(ques,true)"></image>
+									</view>
+								</view>
+							</view>
+							<view v-if="bank.ques">
+								<view class="pad_8 answerInfos">
+									<view class="answerTitle">答案解析</view>
+									<view class="answerContent">
+										<rich-text :nodes="bank.analysisContent"></rich-text>
+									</view>
+								</view>
+							</view>
+						</template>
+						
+						<!-- 案例题 -->
+						<template v-if="bank.type == 4">
+							<view class="tabs">
+								<view class="tab" :class="{current:tabIndex == bank.current}" :key="tabIndex" v-for="(tab,tabIndex) in bank.jsonStr" @click="tabSelect(tabIndex,bankIndex)">问题{{tabIndex}}</view>
+							</view>
+							<view v-for="(ansItem,ansIndex) in bank.jsonStr" v-if="bank.current == ansIndex" :key="ansIndex">
+								<view class="titles">
+									<rich-text :nodes="ansItem.content"></rich-text>
+								</view>
+								<template v-if="ansItem.type == 1">
+									<view v-if="!bank.ques[ansIndex]">
+										<view v-for="(option, childIndex) in ansItem.optionsList" :key="childIndex" class="lisSty" @click="radioSelectChild(option.optionsId,ansIndex,bankIndex)">
+											<view class="activeTI">{{ ast[childIndex] }}</view>
+											<rich-text class="textChild" :nodes="option.content"></rich-text>
+										</view>
+									</view>
+									<view v-if="bank.ques[ansIndex]">
+										<view v-for="(option, childIndex) in ansItem.optionsList" :key="index" class="lisSty">
+											<text :class="{right:(option.optionsId == bank.ques[ansIndex]) || (option.optionsId == bank.ans[ansIndex]),wrong:(option.optionsId == bank.ques[ansIndex]) && (bank.ques[ansIndex] != bank.ans[ansIndex])}"  class="activeTI">{{ ast[childIndex] }}</text>
+											<rich-text :nodes="option.content"></rich-text>
+										</view>
+									</view> 
+									<view v-if="bank.ques[ansIndex]">
+										<view class="pad_8 answer">
+											<view>正确答案:{{ast[bank.ans[ansIndex]-1]}}</view>
+											<view v-if="!explain">我的答案:{{ast[bank.ques[ansIndex]-1]}}</view>
+										</view>
+										<view class="pad_8 answerInfos">
+											<view class="answerTitle">答案解析</view>
+											<view class="answerContent">
+												<rich-text :nodes="option.analysisContent"></rich-text>
+											</view>
+										</view>
+									</view>
+								</template>
+								
+								<template v-if="ansItem.type == 2">
+									<view v-if="!bank.ques[ansIndex]">
+										<view v-for="(option, childindex) in ansItem.optionsList" :key="childindex" class="lisSty" @click="checkboxSelectChild(bankIndex,ansIndex,childindex)">
+											<view :class="{checked:option.checked}" class="activeTI">{{ ast[childindex] }}</view>
+											<rich-text :nodes="option.content"></rich-text>
+										</view>
+									</view>
+									<view v-if="!bank.ques[ansIndex]" class="submit_checkbox" @click="checkboxSubmitChild(bankIndex,ansIndex)">
+										确认答案
+									</view>
+									<view v-if="bank.ques && bank.ques[ansIndex]">
+										<view v-for="(option, childindex) in ansItem.optionsList" :key="childindex" class="lisSty">
+											<text :class="{right:right(bankIndex,ansIndex,option),wrong:wrong(bankIndex,ansIndex,option)}"  class="activeTI">{{ ast[childindex] }}</text>
+											<rich-text :nodes="option.content"></rich-text>
+										</view>
+									</view> 
+									<view v-if="bank.ques[ansIndex]">
+										<view class="pad_8 answer">
+											<view>正确答案:
+												<text v-for="ansItem1 in bank.ans[ansIndex]">{{ast[ansItem1-1]}}</text>
+											</view>
+											<view v-if="!explain">我的答案:
+												<text v-for="quesItem in bank.ques[ansIndex]">{{ast[quesItem-1]}}</text>
+											</view>
+										</view>
+										<view class="pad_8 answerInfos">
+											<view class="answerTitle">答案解析</view>
+											<view class="answerContent">
+												<rich-text :nodes="ansItem.analysisContent"></rich-text>
+											</view>
+										</view>
+									</view>
+								</template>
+								
+								<template v-if="ansItem.type == 3">
+									<view v-if="!bank.ques[ansIndex]">
+										<view v-for="(option, childindex) in judge" :key="childindex" class="lisSty" @click="judgeSelectChild(ansIndex,childindex,bankIndex)">
+											<view class="activeTI">{{ ast[childindex] }}</view>
+											{{ option }}
+										</view>
+									</view>
+									<view v-if="bank.ques[ansIndex]">
+										<view v-for="(option, childindex) in judge" :key="childindex" class="lisSty">
+											<text :class="{right:(childindex == bank.ques[ansIndex]) || (childindex == bank.ans[ansIndex]),wrong:(childindex == bank.ques[ansIndex]) && (bank.ques[ansIndex] != bank.ans[ansIndex])}"  class="activeTI">{{ ast[childindex] }}</text>
+											{{ option }}
+										</view>
+									</view> 
+									<view v-if="bank.ques[ansIndex]">
+										<view class="pad_8 answer">
+											<view>正确答案:{{ast[bank.ans[ansIndex]]}}</view>
+											<view v-if="!explain">我的答案:{{ast[bank.ques[ansIndex]]}}</view>
+										</view>
+										<view class="pad_8 answerInfos">
+											<view class="answerTitle">答案解析</view>
+											<view class="answerContent">
+												<rich-text :nodes="ansItem.analysisContent"></rich-text>
+											</view>
+										</view>
+									</view>
+								</template>
+								
+								
+								<!-- 简答题 -->
+								<template v-if="ansItem.type == 5">
+									<view class="ans">
+										<view class="ans_input" v-if="!bank.ques[ansIndex]">
+											<view class="top flex">
+												<image class="icon" @click="chooseImgChild(bankIndex,ansIndex)" src="/static/08-10_032.jpg" mode=""></image>
+												<view class="progress">0/4</view>
+												<view class="submit"  @click="submitAnsChild(bankIndex,ansIndex)">确认答案</view>
+											</view>
+											<view class="textarea">
+												<textarea v-model="ansItem.ansText.text" placeholder="在此输入答案"></textarea>
+											</view>
+											<view class="imgs">
+												<view class="img" v-for="(img,imgIndex) in ansItem.ansText.imageList" >
+													<text @click="deleteImgChild(imgIndex,bankIndex,ansIndex)">x</text>
+													<image :src="$method.splitImgHost(img, true)"></image>
+												</view>
+											</view>
+										</view>
+										<view class="ans_submit answerInfos" v-if="bank.ques[ansIndex] && !explain">
+											<view class="answerTitle">答案我的</view>
+											{{bank.ques[ansIndex].text}}
+											<view class="imgs">
+												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="$method.splitImgHost(ques,true)"></image>
+											</view>
+										</view>
+									</view>
+									<view v-if="bank.ques[ansIndex]">
+										<view class="pad_8 answerInfos">
+											<view class="answerTitle">答案解析</view>
+											<view class="answerContent">
+												<rich-text :nodes="ansItem.analysisContent"></rich-text>
+											</view>
+										</view>
+									</view>
+								</template>
+								
+								
+							</view>
+						</template>
+						
+						
+					</view>
+					
+				
+					<view class="footer_btn" v-if="isContinue">
+						<view class="collect"></view>
+						<view @click="openFooterTab">答题卡</view>
+						<view @click="submit">交卷</view>
+					</view>
+				</view>
+			</swiper-item>
+		</swiper>
+		
+		<u-popup v-model="show" mode="bottom" border-radius="14" height="680rpx">
+			<view class="popupView">
+				<view class="popupTops">
+					<view class="topIcon"></view>
+					点击编号即可跳转至对应题目
+				</view>
+				<view class="popupContent">
+					<scroll-view scroll-y="true" style="height: 506rpx;">
+						<view class="boxSty">
+							<view v-for="(item, index) in questionList" :key="index" @click="changeIndex(index)" :class="{isRight:isRight(item,index),isWrong:isWrong(item,index)}" class="liListSty">{{ index + 1 }}</view>
+						</view>
+					</scroll-view>
+				</view>
+			</view>
+		</u-popup>
+		
+		<view class="dialog" v-if="showDialog">
+			<view class="text">左右滑动切换上下题</view>
+			<view class="btn" @click="hideDialog">我知道了</view>
+		</view>
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+			id:'',
+			current:0,
+			questionList:[],
+			ast: ['A', 'B', 'C', 'D','E','F','G'],
+			judge:['错误','正确'],
+			show: false,
+			showDialog:true,
+			bankList: [],
+			collectList:[],
+			goodsId:'',
+			explain:'',
+			isContinue:'',
+			chapterId:'',
+			moduleId:'',
+			isSubmit:false,
+		};
+	},
+	onLoad(option){
+		this.id = option.id;
+		this.explain = option.explain;
+		this.isContinue = option.continue;
+		this.goodsId = option.goodsid;
+		this.chapterId = option.chapterId;
+		this.moduleId = option.moduleId;
+		this.recordId = option.recordId;
+		this.goodsQuestionList();
+	},
+	onUnload() {
+		if(this.isSubmit) {
+			return
+		}
+		this.examRecordEdit();
+	},
+	methods: {
+		
+		goodsQuestionList() {
+			//继续答题
+			if(this.isContinue) {
+				this.$api.examReport(this.recordId).then(res => {
+					let json = JSON.parse(res.data.data.historyExamJson)
+					
+					this.questionList = json;
+				})
+			} else {  //解析
+				this.$api.goodsQuestionList({
+					examId:this.id
+				}).then(res => {
+					
+					res.data.data.forEach((item,index) => { 
+						if(typeof item.jsonStr == 'string') {
+							item.jsonStr = JSON.parse(item.jsonStr)
+							
+							if(item.type == 2) { //多选
+								item.jsonStr.forEach(str => {
+									str.optionsId = ''+str.optionsId;
+								})
+								let arr = item.answerQuestion.split(',');
+								arr.forEach((a,i) => {
+									arr[i] = ''+a;
+								})
+								item.ans = arr;
+								if(this.explain) {
+									item.ques = item.ans;
+								}
+								return;
+							} else if(item.type == 5) {
+								item.ansText = {
+									text: '',
+									imageList: []
+								}
+								
+								if(this.explain) {
+									item.ques = {
+										text:item.analysisContent
+									}
+									
+									return;
+								}
+								
+								
+							} else if(item.type == 4) {
+								console.log(item.jsonStr)
+								item.ques = []
+								item.current = 0;
+								let ansArr = []; 
+								item.jsonStr.forEach((json,index) => {
+									if(json.type == 1) {
+										ansArr[index] = json.answerQuestion;
+									} else if(json.type == 2) {
+										json.optionsList.forEach(str => {
+											str.optionsId = ''+str.optionsId;
+										})
+										let arr = json.answerQuestion.split(',');
+										arr.forEach((a,i) => {
+											arr[i] = ''+a;
+										})
+										ansArr[index] = arr
+									} else if(json.type == 3) {
+										ansArr[index] = json.answerQuestion;
+									} else if(json.type == 5) {
+										ansArr[index] = {
+											text: '',
+											imageList: []
+										}
+										json.ansText = {
+											text: '',
+											imageList: []
+										}
+									}
+								})
+								
+								item.ans = ansArr
+								if(this.explain) {
+									item.ques = item.ans;
+								}
+								return;
+								
+							}
+							
+							item.ans = item.answerQuestion
+							if(this.explain) {
+								item.ques = item.ans;
+							}
+						} else {
+							if(this.explain) {
+								item.ques = item.ans;
+							}
+						}
+						
+					})
+					
+					this.questionList = res.data.data;
+					
+				})
+			}
+			
+		},
+		/**
+		 * @param {Object} e单选点击
+		 */
+		radioSelect(optionsId,bindex) {
+			if(this.questionList[bindex].ques) return;
+			this.$set(this.questionList[bindex],'ques',optionsId)
+			
+		},
+		examRecordEdit() {
+			if(!this.isSubmit) {
+				
+				let number = 0;
+				let score = 0;
+				this.questionList.forEach((item,index) => {
+					if(item.type == 1) {
+						if(item.ques == item.ans) { 
+							score += item.score;
+							number++
+						}
+					} else if(item.type == 2) {
+						let isRight = item.ques && item.ques.every((quesItem,quesIndex) => {
+							return item.ques[quesIndex] == item.ans[quesIndex]
+						})
+						
+						if(isRight) {
+							score += item.score;
+							number++
+						}
+					} else if(item.type == 3) {
+						if(item.ques == item.ans) {
+							score += item.score;
+							number++
+						}
+					}
+				})
+				
+				this.$api.examRecordEdit({
+					examId:this.id,
+					goodsId:this.goodsId,
+					recordId: this.recordId,
+					rightQuestionNum:number,
+					status:0,
+					historyExamJson:JSON.stringify(this.questionList)
+				}).then(res => {
+					
+				})
+			}
+		},
+		
+		/**
+		 * @param {Object} e单选点击
+		 */
+		radioSelectChild(optionsId,ansIndex,bindex) {
+			if(this.questionList[bindex].ques[ansIndex]) return;
+			this.$set(this.questionList[bindex].ques,ansIndex,optionsId)
+			
+		},
+		
+		
+		/**
+		 * @param {Object} 多选点击
+		 */
+		checkboxSelect(optionsId,bindex,index) {
+			
+			this.$set(this.questionList[bindex].jsonStr[index],'checked',!this.questionList[bindex].jsonStr[index].checked)
+		},
+		
+		/**
+		 * @param {Object} 多选点击
+		 */
+		checkboxSelectChild(bindex,ansIndex,childIndex) {
+			
+			this.$set(this.questionList[bindex].jsonStr[ansIndex].optionsList[childIndex],'checked',!this.questionList[bindex].jsonStr[ansIndex].optionsList[childIndex].checked)
+		},
+		
+		/**
+		 * 提交数据
+		 */
+		submit() {
+			let score = 0; //计算总分
+			let reportStatus = 0;
+			let number = 0;
+			this.questionList.forEach((item,index) => {
+				if(item.type == 1) {
+					if(item.ques == item.ans) { 
+						score += item.score;
+						number++
+					}
+				} else if(item.type == 2) {
+					let isRight = item.ques && item.ques.every((quesItem,quesIndex) => {
+						return item.ques[quesIndex] == item.ans[quesIndex]
+					})
+					
+					if(isRight) {
+						score += item.score;
+						number++
+					}
+				} else if(item.type == 3) {
+					if(item.ques == item.ans) {
+						score += item.score;
+						number++
+					}
+				}
+			})
+			
+			// if(score >= 60) {
+			// 	reportStatus = 1
+			// } else {
+			// 	reportStatus = 0
+			// }
+			
+			this.$api.examRecordEdit({
+				examId:this.id,
+				goodsId:this.goodsId,
+				// reportStatus:reportStatus,
+				recordId: this.recordId,
+				rightQuestionNum:number,
+				status:1,
+				score:score,
+				historyExamJson:JSON.stringify(this.questionList)
+			}).then(res => {
+				this.isSubmit = true;
+				if(res.data.code == 200) {
+					
+					uni.showToast({
+						title: '交卷成功',
+						duration: 2000,
+						icon:'none'
+					});
+					
+					setTimeout(() => {
+						uni.redirectTo({
+							url:'/pages2/bank/question_report?id='+this.recordId
+						})
+					},2000)
+				}
+			})
+		},
+		
+		/**
+		 * @param {Object} 多选确认
+		 */
+		checkboxSubmit(bindex) {
+			
+			if(this.questionList[bindex].ques) return;
+			let arr = [];
+			this.questionList[bindex].jsonStr.forEach(item => {
+				if(item.checked) {
+					arr.push(item.optionsId)
+				}
+			})
+			
+			this.$set(this.questionList[bindex],'ques',arr)
+			
+		},
+		
+		/**
+		 * @param {Object} 多选确认
+		 */
+		checkboxSubmitChild(bindex,ansIndex) {
+			
+			if(this.questionList[bindex].ques[ansIndex]) return;
+			let arr = [];
+			this.questionList[bindex].jsonStr[ansIndex].optionsList.forEach(item => {
+				if(item.checked) {
+					arr.push(item.optionsId)
+				}
+			})
+			
+			this.$set(this.questionList[bindex].ques,ansIndex,arr)
+		},
+		
+		judgeSelect(index,bindex) {
+			if(this.questionList[bindex].ques) return;
+			this.$set(this.questionList[bindex],'ques',index+'')
+			
+		},
+		
+		judgeSelectChild(ansindex,childindex,bindex) {
+			if(this.questionList[bindex].ques[ansindex]) return;
+			this.$set(this.questionList[bindex].ques,ansindex,childindex+'')
+		},
+		
+		openFooterTab() {
+			this.show = true;
+		},
+		hideDialog() {
+			this.showDialog = false
+		},
+		changeIndex(index) {
+			this.current = index
+		},
+		
+		swiperChange(e) {
+			this.current = e.detail.current;
+		},
+		
+		
+		deleteImg(imgIndex,bankIndex) {
+			
+			
+			this.questionList[bankIndex].ansText.imageList.splice(imgIndex,1)
+		},
+		
+		
+		deleteImgChild(imgIndex,bankIndex,ansIndex) {
+			
+			
+			this.questionList[bankIndex].jsonStr[ansIndex].ansText.imageList.splice(imgIndex,1)
+		},
+		
+		chooseImg(bankindex) {
+			uni.chooseImage({
+				count: 1, //默认9
+				sizeType: ['compressed', ], //可以指定是原图还是压缩图,默认二者都有
+				sourceType: ['album','camera'], //从相册选择
+				success: (res) => {
+					let self = this;
+					// console.log(JSON.stringify(res.tempFilePaths));
+					let img = res.tempFilePaths[0];
+					uni.getImageInfo({
+						src: img,
+						success: async res => {
+							let canvasWidth = res.width; //图片原始长宽
+							let canvasHeight = res.height;
+							if (canvasWidth > 1000 || canvasHeight > 1000) {
+								uni.compressImage({
+									src: img,
+									quality: 75,
+									width: '50%',
+									height: '50%',
+									success: async rest => {
+										const dir = await self.uploadFile(rest.tempFilePath, 0);
+										this.questionList[bankindex].ansText.imageList.push(dir)
+									} 
+								});
+							} else {
+								const dir = await self.uploadFile(img, 0);
+								this.questionList[bankindex].ansText.imageList.push(dir)
+							}
+						}
+					});
+				}
+			})
+		},
+		
+		chooseImgChild(bankindex,ansindex) {
+			uni.chooseImage({
+				count: 1, //默认9
+				sizeType: ['compressed', ], //可以指定是原图还是压缩图,默认二者都有
+				sourceType: ['album','camera'], //从相册选择
+				success: (res) => {
+					let self = this;
+					// console.log(JSON.stringify(res.tempFilePaths));
+					let img = res.tempFilePaths[0];
+					uni.getImageInfo({
+						src: img,
+						success: async res => {
+							let canvasWidth = res.width; //图片原始长宽
+							let canvasHeight = res.height;
+							if (canvasWidth > 1000 || canvasHeight > 1000) {
+								uni.compressImage({
+									src: img,
+									quality: 75,
+									width: '50%',
+									height: '50%',
+									success: async rest => {
+										const dir = await self.uploadFile(rest.tempFilePath, 0);
+										this.questionList[bankindex].jsonStr[ansindex].ansText.imageList.push(dir)
+									} 
+								});
+							} else {
+								const dir = await self.uploadFile(img, 0);
+								this.questionList[bankindex].jsonStr[ansindex].ansText.imageList.push(dir)
+							}
+						}
+					});
+				}
+			})
+		},
+		
+		uploadFile(options, int) {
+			var self = this;
+			return new Promise((resolve, reject) => {
+				var data = {
+					imageStatus: int
+				};
+				self.$api.aliyunpolicy(data).then(res => {
+					console.log(res.data,6)
+					if(res.data.code!=200){
+						self.$method.showToast('签名错误'+JSON.stringify(res.data))
+						return
+					}
+					var ossToken = res.data.data.resultContent;
+					if(ossToken.host==null||ossToken.host==undefined){
+						self.$method.showToast('上传路径报错'+JSON.stringify(res.data))
+						return
+					}
+					uni.uploadFile({
+						url: ossToken.host,
+						name: 'file',
+						filePath: options,
+						fileType: 'image',
+						header: {
+							AuthorizationToken: 'WX ' + uni.getStorageSync('token')
+						},
+						formData: {
+							key: ossToken.dir,
+							OSSAccessKeyId: ossToken.accessid,
+							policy: ossToken.policy,
+							Signature: ossToken.signature,
+							callback: ossToken.callback,
+							success_action_status: 200
+						},
+						success: result => {
+							if (result.statusCode === 200) {
+								resolve(ossToken.dir);
+							} else {
+								uni.showToast({
+									title: '上传失败',
+									icon: 'none'
+								});
+								return;
+							}
+						},
+						fail: error => {
+							uni.showToast({
+								title: '上传接口报错'+error,
+								icon: 'none'
+							});
+							return;
+						}
+					});
+				});
+			});
+		},
+		submitAns(bankindex) {
+				
+			console.log(this.questionList[bankindex])
+			if(!this.questionList[bankindex].ansText.text && !this.questionList[bankindex].ansText.imageList.length) {
+				uni.showToast({
+					title: '请输入内容或上传图片',
+					duration: 2000,
+					icon:'none'
+				});
+				return
+			}
+			
+			this.$set(this.questionList[bankindex],'ques',{
+				imageList:this.questionList[bankindex].ansText.imageList,
+				text:this.questionList[bankindex].ansText.text,
+			})
+			
+		},
+		
+		submitAnsChild(bankindex,ansindex) {
+				
+			if(!this.questionList[bankindex].jsonStr[ansindex].ansText.text && !this.questionList[bankindex].jsonStr[ansindex].ansText.imageList.length) {
+				uni.showToast({
+					title: '请输入内容或上传图片',
+					duration: 2000,
+					icon:'none'
+				});
+				return
+			}
+			
+			this.$set(this.questionList[bankindex].ques,ansindex,{
+				imageList:this.questionList[bankindex].jsonStr[ansindex].ansText.imageList,
+				text:this.questionList[bankindex].jsonStr[ansindex].ansText.text,
+			})
+			
+		},
+		
+		isRight(item,index) {
+			//单选
+			if(this.questionList[index].ques) {
+				if(item.type == 1) {
+					return this.questionList[index].ques == this.questionList[index].ans;
+				//多选
+				} else if(item.type == 2) {
+					//每一项都相等
+					return this.questionList[index].ques.every((item,i) => {
+						console.log(item == this.questionList[index].ans[i])
+						return item == this.questionList[index].ans[i];
+					})
+				//判断
+				} else if(item.type == 3) {
+					return this.questionList[index].ques == this.questionList[index].ans;
+				} else {
+					return false;
+				}
+			} else {
+				return false;
+			}
+			
+		},
+		
+		
+		right(bankIndex,ansIndex,option) {
+			if(this.questionList[bankIndex].ques[ansIndex] && this.questionList[bankIndex].ans[ansIndex]) {
+				
+				if((this.questionList[bankIndex].ques[ansIndex].indexOf(option.optionsId) != -1 ) || (this.questionList[bankIndex].ans[ansIndex].indexOf(option.optionsId) != -1)) {
+					return true
+				} else {
+					return false;
+				}
+			} else {
+				return false;
+			}
+			
+		},
+		
+		wrong(bankIndex,ansIndex,option) {
+			if(this.questionList[bankIndex].ques[ansIndex] && this.questionList[bankIndex].ans[ansIndex]) {
+				
+				if((this.questionList[bankIndex].ques[ansIndex].indexOf(option.optionsId) != -1 ) && (this.questionList[bankIndex].ans[ansIndex].indexOf(option.optionsId) == -1)) {
+					return true;
+				} else {
+					return false;
+				}
+			} else {
+				return false;
+			}
+		},
+		
+		isWrong(item,index) {
+			if(this.questionList[index].ques) {
+				//单选
+				if(item.type == 1) {
+					return this.questionList[index].ques != this.questionList[index].ans;
+				//多选
+				} else if(item.type == 2) {
+					//每一项都相等
+					return this.questionList[index].ques.some((item,i) => {
+						return item != this.questionList[index].ans[i];
+					})
+				//判断
+				} else if(item.type == 3) {
+					return this.questionList[index].ques != this.questionList[index].ans;
+				} else {
+					return false;
+				}
+			} else {
+				return false;
+			}
+			
+		},
+		
+		tabSelect(index,bankindex) {
+			
+			this.$set(this.questionList[bankindex],'current',index)
+			
+		},
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+.swiper {
+	width:100%;
+	height:100vh;
+}
+.lisSty {
+	margin-bottom: 16rpx;
+	display: flex;
+	
+	.flex_auto {
+		flex:1;
+	}
+}
+.activeTI {
+	vertical-align: middle;
+	display: inline-block;
+	border: 1rpx solid #eee;
+	border-radius: 50rpx;
+	height: 48rpx;
+	line-height: 46rpx;
+	text-align: center;
+	width: 48rpx;
+	margin-right: 15rpx;
+	color: #666;
+	font-size: 30rpx;
+	
+	
+	&.right {
+		color:#fff;
+		background:green;
+	}
+	
+	&.wrong {
+		color:#fff;
+		background:red;
+	}
+	
+	&.checked {
+		color:#fff;
+		background:blue;
+	}
+}
+
+.submit_checkbox {
+	margin:20rpx auto;
+	width: 526rpx;
+	height: 80rpx;
+	background: rgba(0, 122, 255, 1);
+	color:#fff;
+	text-align: center;
+	line-height: 80rpx;
+	font-size: 30rpx;
+	border-radius: 40rpx;
+}
+.titles {
+	overflow: hidden;
+	margin-bottom: 24rpx;
+}
+.titBox {
+	padding: 41rpx 25rpx 24rpx 25rpx;
+}
+
+.tabs {
+	margin:10rpx;
+	display: flex;
+	.tab {
+		margin:0 10rpx;
+		width: 96rpx;
+		height: 48rpx;
+		line-height: 48rpx;
+		text-align: center;
+		color:#007AFF;
+		font-size: 28rpx;
+		border-radius: 16rpx;
+		
+		&.current {
+			color:#fff;
+			background: #007AFF;
+		}
+	}
+}
+
+.ans {
+	margin:8rpx 8rpx 8rpx;
+	
+	.ans_input {
+	    border-radius: 16rpx;
+		background:#fff;
+		.top {
+			border-bottom:1rpx solid #EEEEEE;
+			padding: 16rpx;
+			display: flex;
+			align-items: center;
+			
+			.icon {
+				margin-right:20rpx;
+				width: 40rpx;
+				height: 38rpx;
+			}
+			
+			.progress {
+				flex:1;
+			}
+			
+			.submit {
+				width: 168rpx;
+				height: 48rpx;
+				line-height: 48rpx;
+				text-align: center;
+				color:#fff;
+				font-size: 30rpx;
+				background: #007AFF;
+				border-radius: 24rpx;
+			}
+		}
+		
+		.textarea {
+			textarea {
+				width:100%;
+				height:287rpx;
+				padding:10rpx;
+			}
+		}
+		
+		.imgs {
+			overflow: hidden;
+			display: flex;
+			width:100%;
+			.img {
+				width: 104rpx;
+				height: 104rpx;
+				border-radius: 8rpx;
+				position:relative;
+				margin:20rpx;
+				
+				
+				text {
+					position:absolute;
+					right:-15rpx;
+					top:-15rpx;
+					width:30rpx;
+					height:30rpx;
+					text-align: center;
+					line-height: 30rpx;
+					color:#fff;
+					background:red;
+					border-radius:50%;
+				}
+				
+				image {
+					width:100%;
+					height:100%;
+				}
+			}
+		}
+	}
+	
+	.ans_submit {
+		padding:16rpx;
+		border-radius: 16rpx;
+		background:#fff;
+		
+		.imgs {
+			overflow: hidden;
+			display: flex;
+			width:100%;
+			.img {
+				width: 104rpx;
+				height: 104rpx;
+				border-radius: 8rpx;
+				position:relative;
+				margin:20rpx;
+				
+				image {
+					width:100%;
+					height:100%;
+				}
+			}
+		}
+	}
+}
+.firstLetter {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	margin-bottom: 30rpx;
+	.leftLetters {
+		display: flex;
+		align-items: center;
+		width: 220rpx;
+		.btnType {
+			padding: 5rpx 10rpx;
+			border: 1rpx solid #007aff;
+			border-radius: 10rpx;
+			background-color: rgba(0, 122, 255, 0.1);
+			font-size: 28rpx;
+			color: #007aff;
+			margin-right: 15rpx;
+		}
+	}
+}
+.popupView {
+	height: 100%;
+	padding-bottom: 100rpx;
+	.popupTops {
+		height: 77rpx;
+		border-bottom: 1rpx solid #eee;
+		text-align: center;
+		line-height: 77rpx;
+		font-size: 24rpx;
+		color: #999;
+		position: relative;
+		.topIcon {
+			position: absolute;
+			top: 10rpx;
+			left: 50%;
+			transform: translateX(-50%);
+			width: 80rpx;
+			height: 8rpx;
+			background-color: #999;
+			border-radius: 4rpx;
+		}
+	}
+	.popupContent {
+	}
+}
+.pageContent {
+	position:relative;
+	background-color: #eaeef1;
+	min-height: 100vh;
+	padding-top: 8rpx;
+	padding-bottom: 100rpx;
+}
+.pad_8 {
+	background-color: #fff;
+	margin: 0rpx 8rpx 8rpx;
+	border-radius: 16rpx;
+}
+.answer {
+	height: 80rpx;
+	line-height: 80rpx;
+	padding: 0rpx 24rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	color: #666;
+	font-size: 30rpx;
+}
+.footer_btn {
+	background-color: #fff;
+	z-index: 10078;
+	position: fixed;
+	bottom: 0rpx;
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	width: 100%;
+	height: 98rpx;
+	padding: 0rpx 38rpx;
+	border-top: 1rpx solid #eee;
+	
+	.collect {
+		visibility: hidden;
+		
+		&.show {
+			visibility: visible;
+		}
+	}
+}
+.boxSty {
+	padding: 44rpx 41rpx 0rpx;
+}
+.liListSty {
+	border:1rpx solid #EEEEEE;
+	width: 88rpx;
+	height: 88rpx;
+	border-radius: 32rpx;
+	text-align: center;
+	line-height: 88rpx;
+	color: #333;
+	font-size: 32rpx;
+	float: left;
+	margin: 20rpx 23rpx;
+	
+	&.isRight {
+		border:1rpx solid #EEEEEE;
+		color:#fff;
+		background: green;
+	}
+	
+	&.isWrong {
+		border:1rpx solid #EEEEEE;
+		color:#fff;
+		background: red;
+	}
+}
+.answerInfos {
+	padding: 25rpx 25rpx 25rpx 23rpx;
+}
+.answerTitle {
+	margin-bottom: 28rpx;
+	color: #666;
+	font-size: 30rpx;
+}
+.answerContent {
+	font-size: 30rpx;
+	color: #666;
+}
+
+.textChild {
+	display: inline-block;
+	vertical-align: middle;
+}
+
+.dialog {
+	position: fixed;
+	left:0;
+	top:0;
+	width:100%;
+	height:100%;
+	background-color: rgba(0,0,0,0.8);
+	display: flex;
+	flex-direction: column;
+	align-items: center;
+	justify-content: center;
+	z-index: 20000;
+	
+	.text {
+		font-size: 32rpx;
+		color: #FFFFFF;
+		text-align: center;
+	}
+	
+	.btn {
+		width: 242rpx;
+		height: 82rpx;
+		border: 2rpx solid #FFFFFF;
+		border-radius: 16rpx;
+		text-align: center;
+		line-height: 82rpx;
+		margin:41rpx auto;
+		color:#fff;
+		font-size: 32rpx;
+	}
+}
+</style>

+ 6 - 6
pages2/bank/questionBankTest.vue

@@ -135,7 +135,7 @@
 									<view class="answerTitle">答案我的</view>
 									{{bank.ques.text}}
 									<view class="imgs">
-										<image class="img" v-for="ques in bank.ques.imageList" :src="ques"></image>
+										<image class="img" v-for="ques in bank.ques.imageList" :src="$method.splitImgHost(ques,true)"></image>
 									</view>
 								</view>
 							</view>
@@ -270,7 +270,7 @@
 											<view class="answerTitle">答案我的</view>
 											{{bank.ques[ansIndex].text}}
 											<view class="imgs">
-												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="ques"></image>
+												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="$method.splitImgHost(ques,true)"></image>
 											</view>
 										</view>
 									</view>
@@ -719,7 +719,7 @@ export default {
 		 * @param {Object} bankindex
 		 * 简答题答案确认
 		 */
-		submitAns(type,bankindex) {
+		submitAns(bankindex) {
 				
 			console.log(this.questionList[bankindex])
 			if(!this.questionList[bankindex].ansText.text && !this.questionList[bankindex].ansText.imageList.length) {
@@ -731,7 +731,7 @@ export default {
 				return
 			}
 			
-			this.$set(this.ques,bankindex,{
+			this.$set(this.questionList[bankindex],'ques',{
 				imageList:this.questionList[bankindex].ansText.imageList,
 				text:this.questionList[bankindex].ansText.text,
 			})
@@ -769,8 +769,8 @@ export default {
 				//多选
 				} else if(item.type == 2) {
 					//每一项都相等
-					return this.questionList[index].ques.every((item,index) => {
-						return item == this.questionList[index].ans;
+					return this.questionList[index].ques.every((item,i) => {
+						return item == this.questionList[index].ans[i];
 					})
 				//判断
 				} else if(item.type == 3) {

+ 100 - 28
pages2/bank/question_detail.vue

@@ -1,7 +1,7 @@
 <template>
 	<view>
 		<view class="top">
-			<navigator url="/pages2/bank/question_statistics">
+			<navigator :url="'/pages2/bank/question_statistics?id='+id">
 				<view class="left">
 					<view class="title">做题统计</view>
 					<view class="progress">
@@ -10,14 +10,14 @@
 								<text>总进度</text>
 							</view>
 							<view class="percent">
-								68
+								{{goodsCount.doNum/goodsCount.totalNum * 100}}
 								<text class="per">%</text>
 							</view>
 						</view>
 						<view class="item-right">
 							<view class='up'>
-								<text class="orange">58</text>
-								<text>/100</text>
+								<text class="orange">{{goodsCount.doNum}}</text>
+								<text>/{{goodsCount.totalNum - goodsCount.doNum}}</text>
 							</view>
 							
 							<view class='down'>
@@ -28,22 +28,26 @@
 					</view>
 				</view>
 			</navigator>
-			<view class="right">
-				<view class="title">
-					错题集 >
-				</view>
-				<view class="number">
-					35
-				</view>
-			</view>
-			<view class="right">
-				<view class="title">
-					收藏集 >
+			<navigator :url="'/pages2/bank/wrongById?goodsid='+id">
+				<view class="right">
+						<view class="title">
+							错题集 <u-icon name="arrow-right"></u-icon>
+						</view>
+						<view class="number">
+							{{goodsCount.wrongNum}}
+						</view>
 				</view>
-				<view class="number">
-					1
+			</navigator>
+			<navigator :url="'/pages2/bank/collectById?goodsid='+id">
+				<view class="right">
+					<view class="title">
+						收藏集 <u-icon name="arrow-right"></u-icon>
+					</view>
+					<view class="number">
+							{{goodsCount.collectNum}}
+					</view>
 				</view>
-			</view>
+			</navigator>
 		</view>
 		<view class="title-list">
 			<view class="content">
@@ -67,9 +71,7 @@
 								<view  v-if="item2.showList">
 									<view class="article" :class="{active:index3 == 0}"  v-for="(article,index3) in item2.list" :key="index3">
 										<view class="flex_auto">{{article.examName}}</view>
-										<navigator :url="'/pages2/bank/questionBank?id='+article.examId+'&goodsid='+goodsData.goodsId">
-											<view class="btn">做题</view>
-										</navigator>
+										<view class="btn" @click="toDo(article.examId,goodsData.goodsId,item1.majorId,item2.chapterExamId)">做题</view>
 									</view>
 								</view>
 								<u-line></u-line>
@@ -88,9 +90,7 @@
 						<view v-if="item1.showList" >
 							<view class="article" :class="{active:index2 == 0}"  :key="index3" v-for="(article,index2) in item1.list">
 								<view class="flex_auto">{{item1.name}}</view>
-								<navigator :url="'/pages2/bank/questionBank?id='+article.majorId+'&goodsid='+goodsData.goodsId">
-									<view class="btn">做题</view>
-								</navigator>
+									<view class="btn"  @click="toDo(article.majorId,goodsData.goodsId,0,item1.majorId)">做题</view>
 								
 							</view>
 						</view>
@@ -99,9 +99,7 @@
 					<template v-if="item1.type ==3">
 						<view class="article active" >
 							<view class="flex_auto">{{item1.name}}</view>
-							<navigator :url="'/pages2/bank/questionBank?id='+item1.majorId+'&goodsid='+goodsData.goodsId">
-								<view class="btn">做题</view>
-							</navigator>
+								<view class="btn" @click="toDo(item1.majorId,goodsData.goodsId,0,0)">做题</view>
 							
 						</view>
 					</template>
@@ -119,6 +117,7 @@ export default {
 			goodsData:{},
 			bankList:[],
 			id:'',
+			goodsCount:{}
 		};
 	},
 	onUnload() {
@@ -128,7 +127,10 @@ export default {
 	onLoad(option) {
 		this.id = option.id
 		this.getDetail();
-		this.goodsBankList()
+		this.goodsBankList();
+		// this.getCollectNum();
+		// this.getWrongNum()
+		this.goodsBankQuestionNum();
 	},
 	onShow() {
 		
@@ -142,6 +144,52 @@ export default {
 			})
 		},
 		
+		/**
+		 * 去做题
+		 */
+		async toDo(id,goodsId,moduleId = 0, chapterId = 0) {
+			
+			if(this.goodsData.examConfigList) {
+				let count = await this.examRecordCount(id);
+				//超过答题次数
+				if(count >= this.goodsData.examConfigList) {
+					uni.showToast({
+						title:'该试卷只能答题'+this.goodsData.examConfigList+'次!'
+					})
+					return
+				}
+			}
+			
+			uni.navigateTo({
+				url:'/pages2/bank/questionBank?id='+id+'&goodsid='+goodsId+'&moduleId='+moduleId+'&chapterId='+chapterId+''
+			})
+		},
+		
+		/**
+		 * 查询试卷历史做题次数
+		 */
+		examRecordCount(examId) {
+			return new Promise(resolve => {
+				
+				this.$api.examRecordCount({
+					examId:examId,
+					goodsId:this.id
+				}).then(res => {
+					
+					resolve(res.data.data)
+				})
+			})
+		},
+		
+		/**
+		 * 获取用户商品统计数据
+		 */
+		goodsBankQuestionNum(){
+			this.$api.goodsBankQuestionNum(this.id).then(res => {
+				this.goodsCount = res.data.data
+			})
+		},
+		
 		goodsBankList() {
 			this.$api.goodsBankList({
 				goodsId:this.id
@@ -150,6 +198,30 @@ export default {
 				this.bankList = res.data.data;
 			})
 		},
+		getCollectNum() {
+			this.$api.goodsCollectExamList({
+				goodsId:this.id
+			}).then(res => {
+				let total = 0;
+				res.data.rows.forEach(item => {
+					total += item.questionNum;
+				})
+				
+				this.collectTotal = total
+			})
+		},
+		getWrongNum() {
+			this.$api.wrongRecordList({
+				goodsId:this.id
+			}).then(res => {
+				let total = 0;
+				res.data.rows.forEach(item => {
+					total += item.wrongQuestionNum;
+				})
+				
+				this.wrongTotal = total
+			})
+		},
 		clickModule(id,index) {
 			
 			

+ 64 - 8
pages2/bank/question_record.vue

@@ -20,15 +20,24 @@
 					</view>
 				</view>
 				<view class="btns">
-					<view class="btn">
+					<view class="btn" v-if="record.status == 1" @click="doRepeat(record.examId,record.goodsId,record.moduleExamId,record.chapterExamId)">
 						重做
 					</view>
-					<view class="btn">
-						解析
-					</view>
-					<view class="btn" v-if="record.status == 1">
-						报告
-					</view>
+					<navigator :url="'/pages2/bank/questionBankExplain?explain=1&id='+record.examId+'&goodsid='+record.goodsId+'&moduleId='+record.moduleExamId+'&chapterId='+record.chapterExamId+''">
+						<view class="btn" v-if="record.status == 1">
+							解析
+						</view>
+					</navigator>
+					<navigator :url="'/pages2/bank/question_report?id='+record.recordId">
+						<view class="btn" v-if="record.status == 1">
+							报告
+						</view>
+					</navigator>
+					<navigator :url="'/pages2/bank/questionBankExplain?continue=1&recordId='+record.recordId+'&id='+record.examId+'&goodsid='+record.goodsId+'&moduleId='+record.moduleExamId+'&chapterId='+record.chapterExamId+''">
+						<view class="btn" v-if="record.status == 0">
+							继续
+						</view>
+					</navigator>
 				</view>
 			</view>
 		</view>
@@ -63,7 +72,8 @@
 				index:0,
 				list:[],
 				list1:[],
-				recordList:[]
+				recordList:[],
+				goodsData:{}
 			}
 		},
 		onLoad(option) {
@@ -78,6 +88,52 @@
 			
 		},
 		methods: {
+			/**
+			 * 去做题
+			 */
+			async doRepeat (id,goodsId,moduleId = 0, chapterId = 0) {
+				await this.getDetail()
+				if(this.goodsData.examConfigList) {
+					let count = await this.examRecordCount(id);
+					//超过答题次数
+					if(count >= this.goodsData.examConfigList) {
+						uni.showToast({
+							title:'该试卷只能答题'+this.goodsData.examConfigList+'次!'
+						})
+						return
+					}
+				}
+				
+				uni.navigateTo({
+					url:'/pages2/bank/questionBankExplain?id='+id+'&goodsid='+goodsId+'&moduleId='+moduleId+'&chapterId='+chapterId+''
+				})
+			},
+			/**
+			 * 查询试卷历史做题次数
+			 */
+			examRecordCount(examId) {
+				return new Promise(resolve => {
+					
+					this.$api.examRecordCount({
+						examId:examId,
+						goodsId:this.id
+					}).then(res => {
+						
+						resolve(res.data.data)
+					})
+				})
+			},
+			
+			getDetail(){
+				return new Promise(resolve => {
+					
+					this.$api.goodsDetail(this.id).then(res => {
+						this.goodsData = res.data.data;
+						 
+						 resolve()
+					})
+				})
+			},
 			testClick(item) {
 				this.index = 0
 				this.$api.examRecordList({

+ 18 - 8
pages2/bank/question_report.vue

@@ -2,12 +2,12 @@
 	<view>
 		
 		<view class="top">
-			<view class="title">试卷名称可换行我也不知道最多多少个字</view>
-			<view class="desc">交卷时间:2021/10/22  17:24</view>
+			<view class="title">{{reportdata.examName}}</view>
+			<view class="desc">交卷时间:{{$method.timestampToTime(reportdata.updateTime,false)}}</view>
 			
 			<view class="box">
 				<view class="left">
-					<view>100%</view>
+					<view>{{(reportdata.rightQuestionNum / reportdata.totalQuestionNum * 100).toFixed(0)}}%</view>
 					<view>正确率</view>
 					<view>不含简答/案例题</view>
 				</view>
@@ -15,12 +15,12 @@
 					<view class="flex up">
 						<image src="/static/5-4_03.png" mode=""></image>
 						<view class="text">正确题数</view>
-						<text class="red">3</text>
+						<text class="red">{{reportdata.rightQuestionNum}}</text>
 					</view>
 					<view class="flex down">
 						<image src="/static/5-4_03.png" mode=""></image>
 						<view class="text">错误题数</view>
-						<text class="green">2</text>
+						<text class="green">{{reportdata.totalQuestionNum - reportdata.rightQuestionNum}}</text>
 					</view>
 				</view>
 			</view>
@@ -54,7 +54,10 @@ import { mapGetters } from 'vuex';
 export default {
 	data() {
 		return {
-			
+			id:'',
+			reportdata:{},
+			context1:null,
+			context2:null,
 		};
 	},
 	onUnload() {
@@ -62,7 +65,8 @@ export default {
 	},
 	computed: { ...mapGetters(['userInfo']) },
 	onLoad(option) {
-
+		this.id = option.id;
+		this.examReport();
 	},
 	onShow() {
 		uni.getSystemInfo({
@@ -76,6 +80,7 @@ export default {
 					  var caculateY = winH/1334;
 					  console.log(caculateX)
 					  var context1 = uni.createCanvasContext('Canvas1')
+					  this.context1 = context1;
 					  context1.setStrokeStyle("#EEEEEE")
 					  context1.setLineWidth(caculateX * 20)
 					  context1.arc(caculateX * 90, caculateX * 90, caculateX * 80, 0, 2 * Math.PI, true)
@@ -99,6 +104,7 @@ export default {
 					  
 					  
 					  var context2 = uni.createCanvasContext('Canvas2')
+					  this.context2 = context2;
 					  context2.setStrokeStyle("#EEEEEE")
 					  context2.setLineWidth(caculateX * 20)
 					  context2.arc(caculateX * 90, caculateX * 90, caculateX * 80, 0, 2 * Math.PI, true)
@@ -124,7 +130,11 @@ export default {
 		
 	},
 	methods: {
-		
+		examReport() {
+			this.$api.examReport(this.id).then(res => {
+				this.reportdata = res.data.data;
+			})
+		}
 	}
 };
 </script>

+ 269 - 98
pages2/bank/question_statistics.vue

@@ -17,8 +17,8 @@
 						<view class="text">做题进度</view>
 					</view>
 					<view class="numbers">
-						<view class="blue">已答  65</view>
-						<view>总数  650</view>
+						<view class="blue">已答  {{goodsCount.doNum}}</view>
+						<view>总数  {{goodsCount.totalNum}}</view>
 					</view>
 				</view>
 			</view>
@@ -27,37 +27,104 @@
 		
 		<view class="title-list">
 			<view class="content">
-				<view class="list" v-for="(item1,index) in outline">
-					<view class="section" :data-index="index" @click="changeItem" :class="{up:!item1.showList}">
-						2Z106010 施工承发包的模式-2Z106020 施工合同...
-					</view>
-					<view class="article" v-if="item1.showList" v-for="(article,index1) in item1.list">
-						<view class="flex-auto">
-							<view class="tit">施工承发包模式-施工合同与物资采购合同二</view>
-							<view class="desc">
-								<view class="flex-auto">
-									正确率
-									<text class="green">65%</text>
+				<view class="list" v-for="(item1,index1) in bankList" :key="index1">
+					<template v-if="item1.type==1">
+						<view class="moduleItem" @click="clickModule(item1.majorId,index1)">
+							<view class="courseName">{{item1.name}}</view>
+							<view>
+								<image src="/static/icon/up.png" class="icon_up" v-if="!item1.showList"></image>
+								<image src="/static/icon/down.png" class="icon_up" v-if="item1.showList"></image>
+							</view>
+						</view>
+						
+						<template v-if="item1.showList">
+							<view v-for="(item2,index2) in item1.list" :key="index2" >
+								<view class="section" @click="changeItem(index1,item2.chapterExamId,item1.type)">
+									<image src="/static/icon/up1.png" class="icon_up" v-if="!item2.showList"></image>
+									<image src="/static/icon/down1.png" class="icon_up" v-if="item2.showList"></image>
+									{{item2.name}}
 								</view>
-								<view class="flex-auto">
-									已完成
-									<text class="blue">65%</text>
+								<view  v-if="item2.showList">
+									<view class="article"  v-for="(article,index3) in item2.list" :key="index3">
+										<view class="flex-auto">
+											<view class="tit">{{article.examName}}</view>
+											<view class="desc">
+												<view class="flex-auto">
+													正确率
+													<text class="green">65%</text>
+												</view>
+												<view class="flex-auto">
+													已完成
+													<text class="blue">65%</text>
+												</view>
+											</view>
+										</view>
+										<navigator :url="'/pages2/bank/questionBankExplain?continue=1&recordId='+article.recordId+'&id='+article.examId+'&goodsid='+article.goodsId+'&moduleId='+article.moduleExamId+'&chapterId='+article.chapterExamId+''">
+											<view class="btn"  v-if="article.recordStatus == 0">继续</view>
+										</navigator>
+									</view>
 								</view>
+								<u-line></u-line>
 							</view>
-						</view>
+						</template>
+						
 						
-						<navigator url="/pages2/bank/questionBank">
-							<view v-if="index1 == 0" class="btn">
-								做题
+					</template>
+					
+					<template v-if="item1.type ==2">
+						<view class="section" @click="changeItem(index1,item1.majorId,item1.type)">
+							<image src="/static/icon/up1.png" class="icon_up" v-if="!item1.showList"></image>
+							<image src="/static/icon/down1.png" class="icon_up" v-if="item1.showList"></image>
+							{{item1.name}}
+						</view>
+						<view v-if="item1.showList" >
+							<view class="article" :key="index3" v-for="(article,index2) in item1.list">
+								<view class="flex-auto">
+									<view class="tit">{{article.name}}</view>
+									<view class="desc">
+										<view class="flex-auto">
+											正确率
+											<text class="green">65%</text>
+										</view>
+										<view class="flex-auto">
+											已完成
+											<text class="blue">65%</text>
+										</view>
+									</view>
+								</view>
+								<navigator :url="'/pages2/bank/questionBankExplain?continue=1&recordId='+article.recordId+'&id='+article.examId+'&goodsid='+article.goodsId+'&moduleId=0&chapterId='+article.chapterExamId+''">
+									<view class="btn" v-if="article.recordStatus == 0">继续</view>
+								</navigator>
+								
 							</view>
-							<view v-if="index1 == 1" class="btn">
-								继续
+						</view>
+					</template>
+					
+					<template v-if="item1.type ==3">
+						<view class="article" >
+							<view class="flex-auto">
+								<view class="tit">{{item1.name}}</view>
+								<view class="desc">
+									<view class="flex-auto">
+										正确率
+										<text class="green">65%</text>
+									</view>
+									<view class="flex-auto">
+										已完成
+										<text class="blue">65%</text>
+									</view>
+								</view>
 							</view>
-						</navigator>
-					</view>
+							<navigator :url="'/pages2/bank/questionBankExplain?continue=1&recordId='+item1.recordId+'&id='+item1.majorId+'&goodsid='+item1.goodsId+'&moduleId=0&chapterId=0'">
+								<view class="btn" v-if="item1.recordStatus == 0">继续</view>
+							</navigator>
+							
+						</view>
+					</template>
 				</view>
 			</view>
 		</view>
+		
 	</view>
 </template>
 
@@ -66,19 +133,13 @@ import { mapGetters } from 'vuex';
 export default {
 	data() {
 		return {
-			outline:[{
-				list:[1,2,3],
-				showList:false,
-			},{
-				list:[1,2,3],
-				showList:false,
-			},{
-				list:[1,2,3],
-				showList:false,
-			},{
-				list:[1,2,3],
-				showList:false,
-			}]
+			bankList:[],
+			goodsCount:{},
+			id:'',
+			context1:null,
+			context2:null,
+			caculateX:0,
+			caculateY:0,
 		};
 	},
 	onUnload() {
@@ -86,32 +147,26 @@ export default {
 	},
 	computed: { ...mapGetters(['userInfo']) },
 	onLoad(option) {
-
-	},
-	onShow() {
+		 this.id = option.id;
 		uni.getSystemInfo({
 			success:(res) => {
 				var winW = res.screenWidth;
 				var winH = res.screenHeight;
 				 uni.createSelectorQuery().in(this).select('.canvas').boundingClientRect().exec((newRes)=>{  
+					 
+					 this.goodsBankQuestionNum();
+						this.goodsBankDolist();
+					// this.goodsBankList();
+					 
 					  var width = newRes[0].width;
 					  var height = newRes[0].height;
-					  var caculateX = winW/750;
-					  var caculateY = winH/1334;
-					  console.log(caculateX)
+					  this.caculateX = winW/750;
+					  this.caculateY = winH/1334;
 					  var context1 = uni.createCanvasContext('Canvas1')
+					  this.context1 = context1;
 					  context1.setStrokeStyle("#EEEEEE")
-					  context1.setLineWidth(caculateX * 20)
-					  context1.arc(caculateX * 90, caculateX * 90, caculateX * 80, 0, 2 * Math.PI, true)
-					  context1.stroke()
-						context1.beginPath()
-					  context1.setStrokeStyle("#32D74B")
-					  context1.setFillStyle('#32D74B')
-					  context1.setTextAlign('center')
-					  context1.setLineCap('round')
-					  context1.setFontSize(caculateX * 32)
-					  context1.fillText('10%', caculateX * 90, caculateX * 90, caculateX * 180)
-					  context1.arc(caculateX * 90, caculateX * 90, caculateX * 80, 0,  Math.PI, true)
+					  context1.setLineWidth(this.caculateX * 20)
+					  context1.arc(this.caculateX * 90, this.caculateX * 90, this.caculateX * 80, 0, 2 * Math.PI, true)
 					  context1.stroke()
 					  context1.draw()
 					  
@@ -119,34 +174,125 @@ export default {
 					  
 					  
 					  var context2 = uni.createCanvasContext('Canvas2')
+					  this.context2 = context2;
 					  context2.setStrokeStyle("#EEEEEE")
-					  context2.setLineWidth(caculateX * 20)
-					  context2.arc(caculateX * 90, caculateX * 90, caculateX * 80, 0, 2 * Math.PI, true)
-					  context2.stroke()
-						context2.beginPath()
-					  context2.setStrokeStyle("#007AFF")
-					  context2.setFillStyle("#007AFF")
-					  context2.setTextAlign('center')
-					  context2.setLineCap('round')
-					  context2.setFontSize(caculateX * 32)
-					  context2.fillText('10%', caculateX * 90, caculateX * 90, caculateX * 180)
-					  context2.arc(caculateX * 90, caculateX * 90, caculateX * 80, 0,  Math.PI, true)
+					  context2.setLineWidth(this.caculateX * 20)
+					  context2.arc(this.caculateX * 90, this.caculateX * 90, this.caculateX * 80, 0, 2 * Math.PI, false)
 					  context2.stroke()
 					  context2.draw()
 				})  
 				
 			}
 		})
+	},
+	onShow() {
+		
 		
 	},
 	methods: {
-		changeItem(e) {
-			let index = e.currentTarget.dataset.index
-			this.outline.forEach((arrItem,i) => {
-				if(i == index) {
-					arrItem.showList = !arrItem.showList
-				}
+		goodsBankDolist() {
+			this.$api.goodsBankDolist({
+				goodsId:this.id
+			}).then(res => {
+				console.log(res)
+				this.bankList = res.data.data;
+			})
+		},
+		goodsBankList() {
+			this.$api.goodsBankList({
+				goodsId:this.id
+			}).then(res => {
+				console.log(res)
+				this.bankList = res.data.data;
+			})
+		},
+		goodsBankQuestionNum(){
+			this.$api.goodsBankQuestionNum(this.id).then(res => {
+				this.goodsCount = res.data.data
+				
+				this.context1.beginPath()
+				this.context1.setStrokeStyle("#32D74B")
+				this.context1.setFillStyle('#32D74B')
+				this.context1.setTextAlign('center')
+				this.context1.setLineCap('round')
+				this.context1.setFontSize(this.caculateX * 32)
+				this.context1.fillText((this.goodsCount.rightNum / this.goodsCount.totalNum * 100).toFixed(2)+'%', this.caculateX * 90, this.caculateX * 90, this.caculateX * 180)
+				this.context2.save()
+				this.context2.translate(this.caculateX * 90, this.caculateX * 90)
+				this.context2.rotate(-90 * Math.PI/180);
+				this.context1.arc(this.caculateX * 90, this.caculateX * 90, this.caculateX * 80, 0, (this.goodsCount.rightNum / this.goodsCount.totalNum) * 2 * Math.PI, false)
+				this.context2.restore()
+				this.context1.stroke()
+				this.context1.draw()
+				
+				this.context2.beginPath()
+				this.context2.setStrokeStyle("#007AFF")
+				this.context2.setFillStyle("#007AFF")
+				this.context2.setTextAlign('center')
+				this.context2.setLineCap('round')
+				this.context2.setFontSize(this.caculateX * 32)
+				this.context2.fillText((this.goodsCount.doNum / this.goodsCount.totalNum * 100).toFixed(2)+'%', this.caculateX * 90, this.caculateX * 90, this.caculateX * 180)
+				this.context2.save()
+				this.context2.translate(this.caculateX * 90, this.caculateX * 90)
+				this.context2.rotate(-90 * Math.PI/180);
+				this.context2.arc(this.caculateX * 90, this.caculateX * 90, this.caculateX * 80, 0, (this.goodsCount.doNum / this.goodsCount.totalNum) * 2 * Math.PI, false)
+				this.context2.restore()
+				this.context2.stroke()
+				this.context2.draw()
+			})
+		},
+		clickModule(id,index) {
+			
+			
+			if(this.bankList[index].list) {
+				this.$set(this.bankList[index],'showList',!this.bankList[index].showList)
+				return;
+			}
+			
+			this.$api.goodsChapterDolist({
+				moduleExamId:id
+			}).then(res => {
+				this.$set(this.bankList[index],'showList',true)
+				this.$set(this.bankList[index],'list',res.data.data)
+				 
 			})
+		},
+		changeItem(index1,id,type) {
+			
+			if(type == 1) {
+				if(this.bankList[index1].list[index2].list) {
+					this.$set(this.bankList[index1].list[index2],'showList',!this.bankList[index1].list[index2].showList)
+					return;
+				}
+				
+				this.$api.goodsExamList({
+					chapterExamId:id
+				}).then(res => {
+					
+					this.$set(this.bankList[index1].list[index2],'showList',true)
+					this.$set(this.bankList[index1].list[index2],'list',res.data.data)
+					
+					 
+				})
+				
+			} else if(type == 2) {
+				if(this.bankList[index1].list) {
+					this.$set(this.bankList[index1],'showList',!this.bankList[index1].showList)
+					return;
+				}
+				
+				this.$api.goodsExamDolist({
+					chapterExamId:id
+				}).then(res => {
+					
+					this.$set(this.bankList[index1],'showList',true)
+					this.$set(this.bankList[index1],'list',res.data.data)
+					
+					 
+				})
+			}
+			
+			
 			
 		}
 	}
@@ -215,6 +361,29 @@ export default {
 		}
 	}
 	
+	.courseName{
+		white-space:nowrap;
+		overflow:hidden;
+		text-overflow:ellipsis; 
+	}
+	
+	
+	.moduleItem{
+		height: 80rpx;
+		color: #333333;
+		font-size: 32rpx;
+		line-height: 80rpx;
+		font-weight: bold;
+		display: flex;
+		justify-content: space-between;
+	
+	}
+	
+	.icon_up{
+		width: 32rpx;
+		height: 32rpx;
+	}
+	
 	.title-list {
 		background: #EAEEF1;
 		padding:16rpx 16rpx 124rpx;
@@ -226,40 +395,48 @@ export default {
 				overflow: hidden;
 				border-radius: 16rpx;
 				padding:10rpx 16rpx;
-				 
-				.section {
-					padding:30rpx 0;
-					border-bottom: 1rpx solid #EEEEEE;
-					font-size: 24rpx;
-					color: #666666;
-					
-					&::before {
-						content:'^';
-						display: inline-block;
-						margin-right:20rpx;
-					}
+				
+				.module {
+					font-size: 30rpx;
+					color: #333333;
 					
-					&.up {
-						border:0;
-						&::before {
-							transform: rotate(180deg);
-						}
+					.icon {
+						margin-right:10rpx;
 					}
 				}
+				 
+				.section {
+					font-size: 30rpx;
+					font-family: PingFang SC;
+					font-weight: bold;
+					color: #333333;
+					white-space:nowrap;
+					overflow:hidden;
+					text-overflow:ellipsis; 
+					margin: 20rpx 0;
+					display: flex;
+					align-items: center;
+				}
 				
 				.article {
-					padding:24rpx 0 10rpx;
+					padding:14rpx 0 10rpx;
 					display: flex;
 					align-items: center;
-					margin-left:88rpx;
+					margin-left:40rpx;
 					font-size: 24rpx;
 					color: #666666;
 					border-bottom: 1rpx solid #EEEEEE;
 					
 					.flex-auto {
+						font-size: 26rpx;
 						flex:1;
 						margin-right:30rpx;
 						
+						
+						&:nth-last-of-type(1) {
+							border:0;
+						}
+						
 						.desc {
 							width: 480rpx;
 							padding:0 14rpx;
@@ -282,6 +459,7 @@ export default {
 						}
 					}
 					
+						
 					.btn {
 						width: 96rpx;
 						height: 48rpx;
@@ -291,16 +469,9 @@ export default {
 						font-size: 30rpx;
 						border-radius:24rpx;
 						background: #007AFF;
+						// margin-left:36rpx;
 						border-radius: 24rpx;
 					}
-					
-					&:nth-last-of-type(1) {
-						border:0;
-					}
-					
-					&.active {
-						color:#007AFF;
-					}
 				}
 			}
 		}

+ 348 - 0
pages2/bank/wrongById.vue

@@ -0,0 +1,348 @@
+<template>
+	<view class="safeArea">
+		<view class="sceenBox">
+			<view :class="['item', {'active':sceenType===2} ]" @click="showSceen(2)">全部试卷类型<u-icon class="icon" name="arrow-down"></u-icon></view>
+		</view>
+		<view class="sceenModel" v-if="sceenType">
+			<view class="sceenModelBg" @click="hideSceen"></view>
+			<view class="sceenMain">
+				<view :class="['item',{'active':item.checked}]" v-for="(item, index) in scennList2" :key="index" @click="choseType(index)">{{item.paperName}}</view>
+			</view>
+		</view>
+		<view class="wrap">
+			<view class="wrongTab">
+				<view class="item" :class="{active:type == 1}" @click="selectType(1)">试卷归类</view>
+				<view class="item" :class="{active:type == 2}" @click="selectType(2)">题型归类</view>
+			</view>
+			<view class="wrongHead">
+				<view class="title">错题统计<text class="sub">(不含简答和案例题)</text></view>
+				<view class="progress">
+					<text>{{total}}</text>
+				</view>
+			</view> 
+			<view class="wrongList" v-if="type == 1">
+				<view class="item" v-for="(item,index) in testList.rows" :key="index">
+					<view class="title">{{item.examName}}</view>
+					<view class="bt">
+						<view class="left">错题数<text class="num">{{item.wrongQuestionNum}}</text></view>
+						<view class="right">
+							<navigator :url="'/pages2/subject/wrongBank?id='+item.examId">
+								<view class="btn">重做</view>
+							</navigator>
+							<navigator :url="'/pages2/subject/wrongBank?id='+item.examId+'&explain=1'">
+								<view class="btn">解析</view>
+							</navigator>
+							<!-- <view class="btn">解析</view> -->
+						</view>
+					</view>
+				</view>
+			</view>
+			
+			<view class="wrongList" v-if="type == 2">
+				<view class="item" v-for="(item,index) in typeList.rows" :key="index">
+					<view class="title">
+						<text v-if="item.type==1">单选题</text>
+						<text v-if="item.type==2">多选题</text>
+						<text v-if="item.type==3">判断题</text>
+						<text v-if="item.type==4">案例题</text>
+						<text v-if="item.type==5">简答题</text>
+					</view>
+					<view class="bt">
+						<view class="left">错题数<text class="num">{{item.num}}</text></view>
+						<view class="right">
+							<navigator :url="'/pages2/subject/wrongTypeBank?type='+item.type">
+								<view class="btn">重做</view>
+							</navigator>
+							<navigator :url="'/pages2/subject/wrongTypeBank?type='+item.type+'&explain=1'">
+								<view class="btn">解析</view>
+							</navigator>
+						</view>
+					</view>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+import { mapGetters } from 'vuex';
+export default {
+	components: {},
+	data() {
+		return {
+			sceenType: null,
+			scennList2:[
+				{paperId: '', paperName: '全部试卷类型', checked: true}
+			],
+			type:1,
+			testList:[],
+			typeList:[],
+			goodsid:'',
+			paperid:'',
+			total:0,
+		};
+	},
+	onPullDownRefresh() {},
+	onShow() {
+		this.getData();
+	},
+	onLoad(option) {
+		this.goodsid = option.goodsid
+		this.examaperList();
+	},
+	methods: {
+		getData() {
+			if(this.type == 1) {
+				this.wrongRecordList()
+			} else if(this.type == 2) {
+				this.wrongRecordTypeList();
+			}
+		},
+		examaperList() {
+			this.$api.examaperList({
+				
+			}).then(res => {
+				this.scennList2 = [...this.scennList2,...res.data.rows];
+			})
+		},
+		
+		wrongRecordList() {
+			this.$api.wrongRecordList({
+				paperId:this.paperid,
+				goodsId:this.goodsid
+			}).then(res => {
+				this.testList = res.data;
+				let total = 0;
+				this.testList.rows.forEach(item => {
+					total += item.wrongQuestionNum;
+				})
+				
+				this.total = total
+			})
+		},
+		wrongRecordTypeList() {
+			this.$api.wrongRecordTypeList({
+				paperId:this.paperid,
+				goodsId:this.goodsid
+			}).then(res => {
+				this.typeList = res.data;
+				
+				let total = 0;
+				this.typeList.rows.forEach(item => {
+					total += item.num;
+				})
+				
+				this.total = total
+			})
+		},
+		selectType(type) {
+			this.type = type;
+			this.getData();
+		},
+		showSceen(type){
+			this.sceenType = type
+		},
+		hideSceen(){
+			this.sceenType = null
+		},
+		choseType(index) {
+			this.sceenType = null
+			this.scennList2.forEach((item,idx)=>{
+				this.$set(item, 'checked',false)
+				if(index==idx){
+					this.paperid = item.paperId
+					this.$set(item, 'checked',true)
+				}
+			})
+			this.getData()
+		},
+	}
+};
+</script>
+<style lang="scss">
+page {
+	background: #EAEEF1;
+}
+
+</style>
+<style scoped lang="scss">
+.sceenBox {
+	width:100%;
+	height: 80rpx;
+	background: #FFFFFF;
+	display: flex;
+	justify-content: center;
+	align-items: center;
+	font-size: 32rpx;
+	font-family: PingFang SC;
+	font-weight: 500;
+	color: #999999;
+	position: fixed;
+	z-index: 999;
+	border-bottom: 1px solid #eee;
+	.item{
+		flex:1;
+		text-align: center;
+		&.active{
+			color:#333;
+			font-weight: bold;
+			.icon{
+				transform: rotate(180deg);
+			}
+		}
+	}
+}
+.sceenModel{
+	width:100%;
+	height:100%;
+	position: fixed;
+	z-index: 998;
+	.sceenModelBg{
+		width:100%;
+		height:100%;
+		position: fixed;
+		background: rgba(0,0,0,.3);
+		z-index: 998;
+	}
+	.sceenMain{
+		position: relative;
+		z-index: 999;
+		background: #fff;
+		margin-top: 80rpx;
+		display: flex;
+		flex-wrap: wrap;
+		padding: 8rpx;
+		justify-content: space-between;
+		.item{
+			width: 350rpx;
+			background: #F5F5F5;
+			border-radius: 16rpx;
+			padding: 25rpx 19rpx;
+			margin: 8rpx;
+			font-size: 32rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #666666;
+			&.active{
+				background: #007AFF;
+				color:#fff;
+			}
+			&:first-child{
+				width:100%;
+				text-align: center;
+			}
+		}
+	}
+}
+.wrap{
+	padding:96rpx 16rpx 16rpx;
+}
+.wrongHead{
+	background: #FFFFFF;
+	border-radius: 16px;
+	padding:24rpx;
+	.title{
+		font-size: 30rpx;
+		font-family: PingFang SC;
+		font-weight: bold;
+		color: #333333;
+		.sub{
+			font-size: 20rpx;
+			font-weight: 500;
+			color: #999999;
+		}
+	}
+	.progress{
+		width: 180rpx;
+		height: 180rpx;
+		line-height: 140rpx;
+		border: 20rpx solid #EEEEEE;
+		border-radius: 50%;
+		margin: 24rpx auto;
+		font-size: 50rpx;
+		text-align: center;
+	}
+}
+.wrongTab{
+	display: flex;
+	margin: 24rpx 0;
+	.item{
+		width: 144rpx;
+		height: 48rpx;
+		line-height: 48rpx;
+		text-align: center;
+		background: #fff;
+		border-radius: 16px;
+		font-size: 28rpx;
+		font-family: PingFang SC;
+		font-weight: 500;
+		color: #666666;
+		margin-left: 15rpx;
+		&.active{
+			background: #007AFF;
+			color: #fff;
+		}
+	}
+}
+.wrongList{
+	margin-top:20rpx;
+	.item{;
+		background: #FFFFFF;
+		border-radius: 16rpx;
+		padding: 0 30rpx;
+		margin-bottom: 16rpx;
+		overflow: hidden;
+		.title{
+			font-size: 32rpx;
+			font-family: PingFang SC;
+			font-weight: bold;
+			color: #333333;
+			margin: 40rpx 0 17rpx;
+		}
+		.bt{
+			display: flex;
+			justify-content: space-between;
+			align-items: center;
+			padding-bottom: 24rpx;
+			.left{
+				width: 176rpx;
+				height: 40rpx;
+				background: #FFFFFF;
+				border: 1px solid #EEEEEE;
+				border-radius: 16rpx;
+				font-size: 26rpx;
+				font-family: PingFang SC;
+				font-weight: 500;
+				color: #999999;
+				display: flex;
+				justify-content: center;
+				align-items: center;
+				.num{
+					font-size: 26rpx;
+					font-weight: bold;
+					color: #FF3B30;
+					margin-left: 16rpx;
+				}
+			}
+			.right{
+				display: flex;
+				.btn{
+					width: 100rpx;
+					height: 48rpx;
+					background: #FFFFFF;
+					border: 1px solid #007AFF;
+					border-radius: 16px;
+					font-size: 24rpx;
+					font-family: PingFang SC;
+					font-weight: 500;
+					color: #007AFF;
+					margin-left:9rpx;
+					display: flex;
+					align-items: center;
+					justify-content: center;
+				}
+			}
+		}
+	}
+}
+</style>

+ 15 - 3
pages2/subject/collect.vue

@@ -23,8 +23,7 @@
 			<view class="wrongHead">
 				<view class="title">收藏统计</view>
 				<view class="progress">
-					<text v-if="type == 1">{{testList.total}}</text>
-					<text v-if="type == 2">{{typeList.total}}</text>
+					<text>{{total}}</text>
 				</view>
 			</view>
 			<view class="wrongList" v-if="type == 1">
@@ -42,7 +41,7 @@
 							<!-- <view class="btn">解析</view> -->
 						</view>
 					</view>
-				</view>
+				</view> 
 			</view>
 			
 			<view class="wrongList" v-if="type == 2">
@@ -85,6 +84,7 @@ export default {
 				{paperId: '', paperName: '全部试卷类型', checked: true}
 			],
 			type:1,
+			total:0,
 			testList:[],
 			typeList:[],
 			goodsid:'',
@@ -129,6 +129,12 @@ export default {
 				goodsId:this.goodsid
 			}).then(res => {
 				this.testList = res.data 
+				let total = 0;
+				this.testList.rows.forEach(item => {
+					total += item.questionNum;
+				})
+				
+				this.total = total
 			})
 		},
 		collectQuestionTypeList() {
@@ -137,6 +143,12 @@ export default {
 				goodsId:this.goodsid
 			}).then(res => {
 				this.typeList = res.data 
+				let total = 0;
+				this.typeList.rows.forEach(item => {
+					total += item.num;
+				})
+				
+				this.total = total
 			})
 		},
 		showSceen(type){

+ 6 - 6
pages2/subject/collectBank.vue

@@ -135,7 +135,7 @@
 									<view class="answerTitle">答案我的</view>
 									{{bank.ques.text}}
 									<view class="imgs">
-										<image class="img" v-for="ques in bank.ques.imageList" :src="ques"></image>
+										<image class="img" v-for="ques in bank.ques.imageList" :src="$method.splitImgHost(ques,true)"></image>
 									</view>
 								</view>
 							</view>
@@ -270,7 +270,7 @@
 											<view class="answerTitle">答案我的</view>
 											{{bank.ques[ansIndex].text}}
 											<view class="imgs">
-												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="ques"></image>
+												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="$method.splitImgHost(ques,true)"></image>
 											</view>
 										</view>
 									</view>
@@ -673,7 +673,7 @@ export default {
 				});
 			});
 		},
-		submitAns(type,bankindex) {
+		submitAns(bankindex) {
 				
 			console.log(this.questionList[bankindex])
 			if(!this.questionList[bankindex].ansText.text && !this.questionList[bankindex].ansText.imageList.length) {
@@ -685,7 +685,7 @@ export default {
 				return
 			}
 			
-			this.$set(this.ques,bankindex,{
+			this.$set(this.questionList[bankindex],'ques',{
 				imageList:this.questionList[bankindex].ansText.imageList,
 				text:this.questionList[bankindex].ansText.text,
 			})
@@ -718,8 +718,8 @@ export default {
 				//多选
 				} else if(item.type == 2) {
 					//每一项都相等
-					return this.questionList[index].ques.every((item,index) => {
-						return item == this.questionList[index].ans;
+					return this.questionList[index].ques.every((item,i) => {
+						return item == this.questionList[index].ans[i];
 					})
 				//判断
 				} else if(item.type == 3) {

+ 6 - 6
pages2/subject/collectTypeBank.vue

@@ -136,7 +136,7 @@
 									<view class="answerTitle">答案我的</view>
 									{{bank.ques.text}}
 									<view class="imgs">
-										<image class="img" v-for="ques in bank.ques.imageList" :src="ques"></image>
+										<image class="img" v-for="ques in bank.ques.imageList" :src="$method.splitImgHost(ques,true)"></image>
 									</view>
 								</view>
 							</view>
@@ -271,7 +271,7 @@
 											<view class="answerTitle">答案我的</view>
 											{{bank.ques[ansIndex].text}}
 											<view class="imgs">
-												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="ques"></image>
+												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="$method.splitImgHost(ques,true)"></image>
 											</view>
 										</view>
 									</view>
@@ -673,7 +673,7 @@ export default {
 				});
 			});
 		},
-		submitAns(type,bankindex) {
+		submitAns(bankindex) {
 				
 			console.log(this.questionList[bankindex])
 			if(!this.questionList[bankindex].ansText.text && !this.questionList[bankindex].ansText.imageList.length) {
@@ -685,7 +685,7 @@ export default {
 				return
 			}
 			
-			this.$set(this.ques,bankindex,{
+			this.$set(this.questionList[bankindex],'ques',{
 				imageList:this.questionList[bankindex].ansText.imageList,
 				text:this.questionList[bankindex].ansText.text,
 			})
@@ -718,8 +718,8 @@ export default {
 				//多选
 				} else if(item.type == 2) {
 					//每一项都相等
-					return this.questionList[index].ques.every((item,index) => {
-						return item == this.questionList[index].ans;
+					return this.questionList[index].ques.every((item,i) => {
+						return item == this.questionList[index].ans[i];
 					})
 				//判断
 				} else if(item.type == 3) {

+ 6 - 6
pages2/subject/wrongBank.vue

@@ -135,7 +135,7 @@
 									<view class="answerTitle">答案我的</view>
 									{{bank.ques.text}}
 									<view class="imgs">
-										<image class="img" v-for="ques in bank.ques.imageList" :src="ques"></image>
+										<image class="img" v-for="ques in bank.ques.imageList" :src="$method.splitImgHost(ques,true)"></image>
 									</view>
 								</view>
 							</view>
@@ -270,7 +270,7 @@
 											<view class="answerTitle">答案我的</view>
 											{{bank.ques[ansIndex].text}}
 											<view class="imgs">
-												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="ques"></image>
+												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="$method.splitImgHost(ques,true)"></image>
 											</view>
 										</view>
 									</view>
@@ -719,7 +719,7 @@ export default {
 				});
 			});
 		},
-		submitAns(type,bankindex) {
+		submitAns(bankindex) {
 				
 			console.log(this.questionList[bankindex])
 			if(!this.questionList[bankindex].ansText.text && !this.questionList[bankindex].ansText.imageList.length) {
@@ -731,7 +731,7 @@ export default {
 				return
 			}
 			
-			this.$set(this.ques,bankindex,{
+			this.$set(this.questionList[bankindex],'ques',{
 				imageList:this.questionList[bankindex].ansText.imageList,
 				text:this.questionList[bankindex].ansText.text,
 			})
@@ -764,8 +764,8 @@ export default {
 				//多选
 				} else if(item.type == 2) {
 					//每一项都相等
-					return this.questionList[index].ques.every((item,index) => {
-						return item == this.questionList[index].ans;
+					return this.questionList[index].ques.every((item,i) => {
+						return item == this.questionList[index].ans[i];
 					})
 				//判断
 				} else if(item.type == 3) {

+ 6 - 6
pages2/subject/wrongTypeBank.vue

@@ -135,7 +135,7 @@
 									<view class="answerTitle">答案我的</view>
 									{{bank.ques.text}}
 									<view class="imgs">
-										<image class="img" v-for="ques in bank.ques.imageList" :src="ques"></image>
+										<image class="img" v-for="ques in bank.ques.imageList" :src="$method.splitImgHost(ques,true)"></image>
 									</view>
 								</view>
 							</view>
@@ -270,7 +270,7 @@
 											<view class="answerTitle">答案我的</view>
 											{{bank.ques[ansIndex].text}}
 											<view class="imgs">
-												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="ques"></image>
+												<image class="img" v-for="ques in bank.ques[ansIndex].imageList" :src="$method.splitImgHost(ques,true)"></image>
 											</view>
 										</view>
 									</view>
@@ -719,7 +719,7 @@ export default {
 				});
 			});
 		},
-		submitAns(type,bankindex) {
+		submitAns(bankindex) {
 				
 			console.log(this.questionList[bankindex])
 			if(!this.questionList[bankindex].ansText.text && !this.questionList[bankindex].ansText.imageList.length) {
@@ -731,7 +731,7 @@ export default {
 				return
 			}
 			
-			this.$set(this.ques,bankindex,{
+			this.$set(this.questionList[bankindex],'ques',{
 				imageList:this.questionList[bankindex].ansText.imageList,
 				text:this.questionList[bankindex].ansText.text,
 			})
@@ -764,8 +764,8 @@ export default {
 				//多选
 				} else if(item.type == 2) {
 					//每一项都相等
-					return this.questionList[index].ques.every((item,index) => {
-						return item == this.questionList[index].ans;
+					return this.questionList[index].ques.every((item,i) => {
+						return item == this.questionList[index].ans[i];
 					})
 				//判断
 				} else if(item.type == 3) {

+ 4 - 4
pages2/wd/question_bank.vue

@@ -3,7 +3,7 @@
 		<navigator url="/pages2/bank/my_question">
 			<view class="my_question">
 					<view class="flex">
-						<view class="text">我的题库></view>
+						<view class="text">我的题库<u-icon name="arrow-right"></u-icon></view>
 						<image src="/static/icon/my_icon7.png" class="my_icon"></image>
 					</view>
 			</view>
@@ -11,7 +11,7 @@
 		<view class="bottom">
 			<navigator url="/pages2/subject/collect">
 				<view class="item collect">
-					<view class="text">收藏集></view>
+					<view class="text">收藏集<u-icon name="arrow-right"></u-icon></view>
 					<image class="img" src="/static/sc.png"></image>
 				</view>
 			</navigator>
@@ -19,14 +19,14 @@
 				<navigator url="/pages2/bank/question_record">
 					<view class="list-in">
 						<image class="img" src="/static/icon/wk_icon2.png" ></image>
-						做题记录 >
+						做题记录 <u-icon name="arrow-right"></u-icon>
 					</view>
 				</navigator>
 				
 				<navigator url="/pages2/subject/wrong">
 					<view class="list-in">
 						<image class="img" src="/static/icon/wk_icon2.png"></image>
-						错题集 >
+						错题集 <u-icon name="arrow-right"></u-icon>
 					</view>
 				</navigator>
 			</view>

+ 16 - 0
uni_modules/uni-icons/changelog.md

@@ -0,0 +1,16 @@
+## 1.3.2(2021-12-01)
+- 优化 示例可复制图标名称
+## 1.3.1(2021-11-23)
+- 优化 兼容旧组件 type 值
+## 1.3.0(2021-11-19)
+- 新增 更多图标
+- 优化 自定义图标使用方式
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-icons](https://uniapp.dcloud.io/component/uniui/uni-icons)
+## 1.1.7(2021-11-08)
+## 1.2.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.1.5(2021-05-12)
+- 新增 组件示例地址
+## 1.1.4(2021-02-05)
+- 调整为uni_modules目录规范

+ 1115 - 0
uni_modules/uni-icons/components/uni-icons/icons.js

@@ -0,0 +1,1115 @@
+export default {
+  "id": "2852637",
+  "name": "uniui图标库",
+  "font_family": "uniicons",
+  "css_prefix_text": "uniui-",
+  "description": "",
+  "glyphs": [
+    {
+      "icon_id": "25027049",
+      "name": "yanse",
+      "font_class": "color",
+      "unicode": "e6cf",
+      "unicode_decimal": 59087
+    },
+    {
+      "icon_id": "25027048",
+      "name": "wallet",
+      "font_class": "wallet",
+      "unicode": "e6b1",
+      "unicode_decimal": 59057
+    },
+    {
+      "icon_id": "25015720",
+      "name": "settings-filled",
+      "font_class": "settings-filled",
+      "unicode": "e6ce",
+      "unicode_decimal": 59086
+    },
+    {
+      "icon_id": "25015434",
+      "name": "shimingrenzheng-filled",
+      "font_class": "auth-filled",
+      "unicode": "e6cc",
+      "unicode_decimal": 59084
+    },
+    {
+      "icon_id": "24934246",
+      "name": "shop-filled",
+      "font_class": "shop-filled",
+      "unicode": "e6cd",
+      "unicode_decimal": 59085
+    },
+    {
+      "icon_id": "24934159",
+      "name": "staff-filled-01",
+      "font_class": "staff-filled",
+      "unicode": "e6cb",
+      "unicode_decimal": 59083
+    },
+    {
+      "icon_id": "24932461",
+      "name": "VIP-filled",
+      "font_class": "vip-filled",
+      "unicode": "e6c6",
+      "unicode_decimal": 59078
+    },
+    {
+      "icon_id": "24932462",
+      "name": "plus_circle_fill",
+      "font_class": "plus-filled",
+      "unicode": "e6c7",
+      "unicode_decimal": 59079
+    },
+    {
+      "icon_id": "24932463",
+      "name": "folder_add-filled",
+      "font_class": "folder-add-filled",
+      "unicode": "e6c8",
+      "unicode_decimal": 59080
+    },
+    {
+      "icon_id": "24932464",
+      "name": "yanse-filled",
+      "font_class": "color-filled",
+      "unicode": "e6c9",
+      "unicode_decimal": 59081
+    },
+    {
+      "icon_id": "24932465",
+      "name": "tune-filled",
+      "font_class": "tune-filled",
+      "unicode": "e6ca",
+      "unicode_decimal": 59082
+    },
+    {
+      "icon_id": "24932455",
+      "name": "a-rilidaka-filled",
+      "font_class": "calendar-filled",
+      "unicode": "e6c0",
+      "unicode_decimal": 59072
+    },
+    {
+      "icon_id": "24932456",
+      "name": "notification-filled",
+      "font_class": "notification-filled",
+      "unicode": "e6c1",
+      "unicode_decimal": 59073
+    },
+    {
+      "icon_id": "24932457",
+      "name": "wallet-filled",
+      "font_class": "wallet-filled",
+      "unicode": "e6c2",
+      "unicode_decimal": 59074
+    },
+    {
+      "icon_id": "24932458",
+      "name": "paihangbang-filled",
+      "font_class": "medal-filled",
+      "unicode": "e6c3",
+      "unicode_decimal": 59075
+    },
+    {
+      "icon_id": "24932459",
+      "name": "gift-filled",
+      "font_class": "gift-filled",
+      "unicode": "e6c4",
+      "unicode_decimal": 59076
+    },
+    {
+      "icon_id": "24932460",
+      "name": "fire-filled",
+      "font_class": "fire-filled",
+      "unicode": "e6c5",
+      "unicode_decimal": 59077
+    },
+    {
+      "icon_id": "24928001",
+      "name": "refreshempty",
+      "font_class": "refreshempty",
+      "unicode": "e6bf",
+      "unicode_decimal": 59071
+    },
+    {
+      "icon_id": "24926853",
+      "name": "location-ellipse",
+      "font_class": "location-filled",
+      "unicode": "e6af",
+      "unicode_decimal": 59055
+    },
+    {
+      "icon_id": "24926735",
+      "name": "person-filled",
+      "font_class": "person-filled",
+      "unicode": "e69d",
+      "unicode_decimal": 59037
+    },
+    {
+      "icon_id": "24926703",
+      "name": "personadd-filled",
+      "font_class": "personadd-filled",
+      "unicode": "e698",
+      "unicode_decimal": 59032
+    },
+    {
+      "icon_id": "24923351",
+      "name": "back",
+      "font_class": "back",
+      "unicode": "e6b9",
+      "unicode_decimal": 59065
+    },
+    {
+      "icon_id": "24923352",
+      "name": "forward",
+      "font_class": "forward",
+      "unicode": "e6ba",
+      "unicode_decimal": 59066
+    },
+    {
+      "icon_id": "24923353",
+      "name": "arrowthinright",
+      "font_class": "arrow-right",
+      "unicode": "e6bb",
+      "unicode_decimal": 59067
+    },
+    {
+      "icon_id": "24923354",
+      "name": "arrowthinleft",
+      "font_class": "arrow-left",
+      "unicode": "e6bc",
+      "unicode_decimal": 59068
+    },
+    {
+      "icon_id": "24923355",
+      "name": "arrowthinup",
+      "font_class": "arrow-up",
+      "unicode": "e6bd",
+      "unicode_decimal": 59069
+    },
+    {
+      "icon_id": "24923356",
+      "name": "arrowthindown",
+      "font_class": "arrow-down",
+      "unicode": "e6be",
+      "unicode_decimal": 59070
+    },
+    {
+      "icon_id": "24923349",
+      "name": "arrowdown",
+      "font_class": "bottom",
+      "unicode": "e6b8",
+      "unicode_decimal": 59064
+    },
+    {
+      "icon_id": "24923346",
+      "name": "arrowright",
+      "font_class": "right",
+      "unicode": "e6b5",
+      "unicode_decimal": 59061
+    },
+    {
+      "icon_id": "24923347",
+      "name": "arrowup",
+      "font_class": "top",
+      "unicode": "e6b6",
+      "unicode_decimal": 59062
+    },
+    {
+      "icon_id": "24923348",
+      "name": "arrowleft",
+      "font_class": "left",
+      "unicode": "e6b7",
+      "unicode_decimal": 59063
+    },
+    {
+      "icon_id": "24923334",
+      "name": "eye",
+      "font_class": "eye",
+      "unicode": "e651",
+      "unicode_decimal": 58961
+    },
+    {
+      "icon_id": "24923335",
+      "name": "eye-filled",
+      "font_class": "eye-filled",
+      "unicode": "e66a",
+      "unicode_decimal": 58986
+    },
+    {
+      "icon_id": "24923336",
+      "name": "eye-slash",
+      "font_class": "eye-slash",
+      "unicode": "e6b3",
+      "unicode_decimal": 59059
+    },
+    {
+      "icon_id": "24923337",
+      "name": "eye-slash-filled",
+      "font_class": "eye-slash-filled",
+      "unicode": "e6b4",
+      "unicode_decimal": 59060
+    },
+    {
+      "icon_id": "24923305",
+      "name": "info-filled",
+      "font_class": "info-filled",
+      "unicode": "e649",
+      "unicode_decimal": 58953
+    },
+    {
+      "icon_id": "24923299",
+      "name": "reload-01",
+      "font_class": "reload",
+      "unicode": "e6b2",
+      "unicode_decimal": 59058
+    },
+    {
+      "icon_id": "24923195",
+      "name": "mic_slash_fill",
+      "font_class": "micoff-filled",
+      "unicode": "e6b0",
+      "unicode_decimal": 59056
+    },
+    {
+      "icon_id": "24923165",
+      "name": "map-pin-ellipse",
+      "font_class": "map-pin-ellipse",
+      "unicode": "e6ac",
+      "unicode_decimal": 59052
+    },
+    {
+      "icon_id": "24923166",
+      "name": "map-pin",
+      "font_class": "map-pin",
+      "unicode": "e6ad",
+      "unicode_decimal": 59053
+    },
+    {
+      "icon_id": "24923167",
+      "name": "location",
+      "font_class": "location",
+      "unicode": "e6ae",
+      "unicode_decimal": 59054
+    },
+    {
+      "icon_id": "24923064",
+      "name": "starhalf",
+      "font_class": "starhalf",
+      "unicode": "e683",
+      "unicode_decimal": 59011
+    },
+    {
+      "icon_id": "24923065",
+      "name": "star",
+      "font_class": "star",
+      "unicode": "e688",
+      "unicode_decimal": 59016
+    },
+    {
+      "icon_id": "24923066",
+      "name": "star-filled",
+      "font_class": "star-filled",
+      "unicode": "e68f",
+      "unicode_decimal": 59023
+    },
+    {
+      "icon_id": "24899646",
+      "name": "a-rilidaka",
+      "font_class": "calendar",
+      "unicode": "e6a0",
+      "unicode_decimal": 59040
+    },
+    {
+      "icon_id": "24899647",
+      "name": "fire",
+      "font_class": "fire",
+      "unicode": "e6a1",
+      "unicode_decimal": 59041
+    },
+    {
+      "icon_id": "24899648",
+      "name": "paihangbang",
+      "font_class": "medal",
+      "unicode": "e6a2",
+      "unicode_decimal": 59042
+    },
+    {
+      "icon_id": "24899649",
+      "name": "font",
+      "font_class": "font",
+      "unicode": "e6a3",
+      "unicode_decimal": 59043
+    },
+    {
+      "icon_id": "24899650",
+      "name": "gift",
+      "font_class": "gift",
+      "unicode": "e6a4",
+      "unicode_decimal": 59044
+    },
+    {
+      "icon_id": "24899651",
+      "name": "link",
+      "font_class": "link",
+      "unicode": "e6a5",
+      "unicode_decimal": 59045
+    },
+    {
+      "icon_id": "24899652",
+      "name": "notification",
+      "font_class": "notification",
+      "unicode": "e6a6",
+      "unicode_decimal": 59046
+    },
+    {
+      "icon_id": "24899653",
+      "name": "staff",
+      "font_class": "staff",
+      "unicode": "e6a7",
+      "unicode_decimal": 59047
+    },
+    {
+      "icon_id": "24899654",
+      "name": "VIP",
+      "font_class": "vip",
+      "unicode": "e6a8",
+      "unicode_decimal": 59048
+    },
+    {
+      "icon_id": "24899655",
+      "name": "folder_add",
+      "font_class": "folder-add",
+      "unicode": "e6a9",
+      "unicode_decimal": 59049
+    },
+    {
+      "icon_id": "24899656",
+      "name": "tune",
+      "font_class": "tune",
+      "unicode": "e6aa",
+      "unicode_decimal": 59050
+    },
+    {
+      "icon_id": "24899657",
+      "name": "shimingrenzheng",
+      "font_class": "auth",
+      "unicode": "e6ab",
+      "unicode_decimal": 59051
+    },
+    {
+      "icon_id": "24899565",
+      "name": "person",
+      "font_class": "person",
+      "unicode": "e699",
+      "unicode_decimal": 59033
+    },
+    {
+      "icon_id": "24899566",
+      "name": "email-filled",
+      "font_class": "email-filled",
+      "unicode": "e69a",
+      "unicode_decimal": 59034
+    },
+    {
+      "icon_id": "24899567",
+      "name": "phone-filled",
+      "font_class": "phone-filled",
+      "unicode": "e69b",
+      "unicode_decimal": 59035
+    },
+    {
+      "icon_id": "24899568",
+      "name": "phone",
+      "font_class": "phone",
+      "unicode": "e69c",
+      "unicode_decimal": 59036
+    },
+    {
+      "icon_id": "24899570",
+      "name": "email",
+      "font_class": "email",
+      "unicode": "e69e",
+      "unicode_decimal": 59038
+    },
+    {
+      "icon_id": "24899571",
+      "name": "personadd",
+      "font_class": "personadd",
+      "unicode": "e69f",
+      "unicode_decimal": 59039
+    },
+    {
+      "icon_id": "24899558",
+      "name": "chatboxes-filled",
+      "font_class": "chatboxes-filled",
+      "unicode": "e692",
+      "unicode_decimal": 59026
+    },
+    {
+      "icon_id": "24899559",
+      "name": "contact",
+      "font_class": "contact",
+      "unicode": "e693",
+      "unicode_decimal": 59027
+    },
+    {
+      "icon_id": "24899560",
+      "name": "chatbubble-filled",
+      "font_class": "chatbubble-filled",
+      "unicode": "e694",
+      "unicode_decimal": 59028
+    },
+    {
+      "icon_id": "24899561",
+      "name": "contact-filled",
+      "font_class": "contact-filled",
+      "unicode": "e695",
+      "unicode_decimal": 59029
+    },
+    {
+      "icon_id": "24899562",
+      "name": "chatboxes",
+      "font_class": "chatboxes",
+      "unicode": "e696",
+      "unicode_decimal": 59030
+    },
+    {
+      "icon_id": "24899563",
+      "name": "chatbubble",
+      "font_class": "chatbubble",
+      "unicode": "e697",
+      "unicode_decimal": 59031
+    },
+    {
+      "icon_id": "24881290",
+      "name": "upload-filled",
+      "font_class": "upload-filled",
+      "unicode": "e68e",
+      "unicode_decimal": 59022
+    },
+    {
+      "icon_id": "24881292",
+      "name": "upload",
+      "font_class": "upload",
+      "unicode": "e690",
+      "unicode_decimal": 59024
+    },
+    {
+      "icon_id": "24881293",
+      "name": "weixin",
+      "font_class": "weixin",
+      "unicode": "e691",
+      "unicode_decimal": 59025
+    },
+    {
+      "icon_id": "24881274",
+      "name": "compose",
+      "font_class": "compose",
+      "unicode": "e67f",
+      "unicode_decimal": 59007
+    },
+    {
+      "icon_id": "24881275",
+      "name": "qq",
+      "font_class": "qq",
+      "unicode": "e680",
+      "unicode_decimal": 59008
+    },
+    {
+      "icon_id": "24881276",
+      "name": "download-filled",
+      "font_class": "download-filled",
+      "unicode": "e681",
+      "unicode_decimal": 59009
+    },
+    {
+      "icon_id": "24881277",
+      "name": "pengyouquan",
+      "font_class": "pyq",
+      "unicode": "e682",
+      "unicode_decimal": 59010
+    },
+    {
+      "icon_id": "24881279",
+      "name": "sound",
+      "font_class": "sound",
+      "unicode": "e684",
+      "unicode_decimal": 59012
+    },
+    {
+      "icon_id": "24881280",
+      "name": "trash-filled",
+      "font_class": "trash-filled",
+      "unicode": "e685",
+      "unicode_decimal": 59013
+    },
+    {
+      "icon_id": "24881281",
+      "name": "sound-filled",
+      "font_class": "sound-filled",
+      "unicode": "e686",
+      "unicode_decimal": 59014
+    },
+    {
+      "icon_id": "24881282",
+      "name": "trash",
+      "font_class": "trash",
+      "unicode": "e687",
+      "unicode_decimal": 59015
+    },
+    {
+      "icon_id": "24881284",
+      "name": "videocam-filled",
+      "font_class": "videocam-filled",
+      "unicode": "e689",
+      "unicode_decimal": 59017
+    },
+    {
+      "icon_id": "24881285",
+      "name": "spinner-cycle",
+      "font_class": "spinner-cycle",
+      "unicode": "e68a",
+      "unicode_decimal": 59018
+    },
+    {
+      "icon_id": "24881286",
+      "name": "weibo",
+      "font_class": "weibo",
+      "unicode": "e68b",
+      "unicode_decimal": 59019
+    },
+    {
+      "icon_id": "24881288",
+      "name": "videocam",
+      "font_class": "videocam",
+      "unicode": "e68c",
+      "unicode_decimal": 59020
+    },
+    {
+      "icon_id": "24881289",
+      "name": "download",
+      "font_class": "download",
+      "unicode": "e68d",
+      "unicode_decimal": 59021
+    },
+    {
+      "icon_id": "24879601",
+      "name": "help",
+      "font_class": "help",
+      "unicode": "e679",
+      "unicode_decimal": 59001
+    },
+    {
+      "icon_id": "24879602",
+      "name": "navigate-filled",
+      "font_class": "navigate-filled",
+      "unicode": "e67a",
+      "unicode_decimal": 59002
+    },
+    {
+      "icon_id": "24879603",
+      "name": "plusempty",
+      "font_class": "plusempty",
+      "unicode": "e67b",
+      "unicode_decimal": 59003
+    },
+    {
+      "icon_id": "24879604",
+      "name": "smallcircle",
+      "font_class": "smallcircle",
+      "unicode": "e67c",
+      "unicode_decimal": 59004
+    },
+    {
+      "icon_id": "24879605",
+      "name": "minus-filled",
+      "font_class": "minus-filled",
+      "unicode": "e67d",
+      "unicode_decimal": 59005
+    },
+    {
+      "icon_id": "24879606",
+      "name": "micoff",
+      "font_class": "micoff",
+      "unicode": "e67e",
+      "unicode_decimal": 59006
+    },
+    {
+      "icon_id": "24879588",
+      "name": "closeempty",
+      "font_class": "closeempty",
+      "unicode": "e66c",
+      "unicode_decimal": 58988
+    },
+    {
+      "icon_id": "24879589",
+      "name": "clear",
+      "font_class": "clear",
+      "unicode": "e66d",
+      "unicode_decimal": 58989
+    },
+    {
+      "icon_id": "24879590",
+      "name": "navigate",
+      "font_class": "navigate",
+      "unicode": "e66e",
+      "unicode_decimal": 58990
+    },
+    {
+      "icon_id": "24879591",
+      "name": "minus",
+      "font_class": "minus",
+      "unicode": "e66f",
+      "unicode_decimal": 58991
+    },
+    {
+      "icon_id": "24879592",
+      "name": "image",
+      "font_class": "image",
+      "unicode": "e670",
+      "unicode_decimal": 58992
+    },
+    {
+      "icon_id": "24879593",
+      "name": "mic",
+      "font_class": "mic",
+      "unicode": "e671",
+      "unicode_decimal": 58993
+    },
+    {
+      "icon_id": "24879594",
+      "name": "paperplane",
+      "font_class": "paperplane",
+      "unicode": "e672",
+      "unicode_decimal": 58994
+    },
+    {
+      "icon_id": "24879595",
+      "name": "close",
+      "font_class": "close",
+      "unicode": "e673",
+      "unicode_decimal": 58995
+    },
+    {
+      "icon_id": "24879596",
+      "name": "help-filled",
+      "font_class": "help-filled",
+      "unicode": "e674",
+      "unicode_decimal": 58996
+    },
+    {
+      "icon_id": "24879597",
+      "name": "plus-filled",
+      "font_class": "paperplane-filled",
+      "unicode": "e675",
+      "unicode_decimal": 58997
+    },
+    {
+      "icon_id": "24879598",
+      "name": "plus",
+      "font_class": "plus",
+      "unicode": "e676",
+      "unicode_decimal": 58998
+    },
+    {
+      "icon_id": "24879599",
+      "name": "mic-filled",
+      "font_class": "mic-filled",
+      "unicode": "e677",
+      "unicode_decimal": 58999
+    },
+    {
+      "icon_id": "24879600",
+      "name": "image-filled",
+      "font_class": "image-filled",
+      "unicode": "e678",
+      "unicode_decimal": 59000
+    },
+    {
+      "icon_id": "24855900",
+      "name": "locked-filled",
+      "font_class": "locked-filled",
+      "unicode": "e668",
+      "unicode_decimal": 58984
+    },
+    {
+      "icon_id": "24855901",
+      "name": "info",
+      "font_class": "info",
+      "unicode": "e669",
+      "unicode_decimal": 58985
+    },
+    {
+      "icon_id": "24855903",
+      "name": "locked",
+      "font_class": "locked",
+      "unicode": "e66b",
+      "unicode_decimal": 58987
+    },
+    {
+      "icon_id": "24855884",
+      "name": "camera-filled",
+      "font_class": "camera-filled",
+      "unicode": "e658",
+      "unicode_decimal": 58968
+    },
+    {
+      "icon_id": "24855885",
+      "name": "chat-filled",
+      "font_class": "chat-filled",
+      "unicode": "e659",
+      "unicode_decimal": 58969
+    },
+    {
+      "icon_id": "24855886",
+      "name": "camera",
+      "font_class": "camera",
+      "unicode": "e65a",
+      "unicode_decimal": 58970
+    },
+    {
+      "icon_id": "24855887",
+      "name": "circle",
+      "font_class": "circle",
+      "unicode": "e65b",
+      "unicode_decimal": 58971
+    },
+    {
+      "icon_id": "24855888",
+      "name": "checkmarkempty",
+      "font_class": "checkmarkempty",
+      "unicode": "e65c",
+      "unicode_decimal": 58972
+    },
+    {
+      "icon_id": "24855889",
+      "name": "chat",
+      "font_class": "chat",
+      "unicode": "e65d",
+      "unicode_decimal": 58973
+    },
+    {
+      "icon_id": "24855890",
+      "name": "circle-filled",
+      "font_class": "circle-filled",
+      "unicode": "e65e",
+      "unicode_decimal": 58974
+    },
+    {
+      "icon_id": "24855891",
+      "name": "flag",
+      "font_class": "flag",
+      "unicode": "e65f",
+      "unicode_decimal": 58975
+    },
+    {
+      "icon_id": "24855892",
+      "name": "flag-filled",
+      "font_class": "flag-filled",
+      "unicode": "e660",
+      "unicode_decimal": 58976
+    },
+    {
+      "icon_id": "24855893",
+      "name": "gear-filled",
+      "font_class": "gear-filled",
+      "unicode": "e661",
+      "unicode_decimal": 58977
+    },
+    {
+      "icon_id": "24855894",
+      "name": "home",
+      "font_class": "home",
+      "unicode": "e662",
+      "unicode_decimal": 58978
+    },
+    {
+      "icon_id": "24855895",
+      "name": "home-filled",
+      "font_class": "home-filled",
+      "unicode": "e663",
+      "unicode_decimal": 58979
+    },
+    {
+      "icon_id": "24855896",
+      "name": "gear",
+      "font_class": "gear",
+      "unicode": "e664",
+      "unicode_decimal": 58980
+    },
+    {
+      "icon_id": "24855897",
+      "name": "smallcircle-filled",
+      "font_class": "smallcircle-filled",
+      "unicode": "e665",
+      "unicode_decimal": 58981
+    },
+    {
+      "icon_id": "24855898",
+      "name": "map-filled",
+      "font_class": "map-filled",
+      "unicode": "e666",
+      "unicode_decimal": 58982
+    },
+    {
+      "icon_id": "24855899",
+      "name": "map",
+      "font_class": "map",
+      "unicode": "e667",
+      "unicode_decimal": 58983
+    },
+    {
+      "icon_id": "24855825",
+      "name": "refresh-filled",
+      "font_class": "refresh-filled",
+      "unicode": "e656",
+      "unicode_decimal": 58966
+    },
+    {
+      "icon_id": "24855826",
+      "name": "refresh",
+      "font_class": "refresh",
+      "unicode": "e657",
+      "unicode_decimal": 58967
+    },
+    {
+      "icon_id": "24855808",
+      "name": "cloud-upload",
+      "font_class": "cloud-upload",
+      "unicode": "e645",
+      "unicode_decimal": 58949
+    },
+    {
+      "icon_id": "24855809",
+      "name": "cloud-download-filled",
+      "font_class": "cloud-download-filled",
+      "unicode": "e646",
+      "unicode_decimal": 58950
+    },
+    {
+      "icon_id": "24855810",
+      "name": "cloud-download",
+      "font_class": "cloud-download",
+      "unicode": "e647",
+      "unicode_decimal": 58951
+    },
+    {
+      "icon_id": "24855811",
+      "name": "cloud-upload-filled",
+      "font_class": "cloud-upload-filled",
+      "unicode": "e648",
+      "unicode_decimal": 58952
+    },
+    {
+      "icon_id": "24855813",
+      "name": "redo",
+      "font_class": "redo",
+      "unicode": "e64a",
+      "unicode_decimal": 58954
+    },
+    {
+      "icon_id": "24855814",
+      "name": "images-filled",
+      "font_class": "images-filled",
+      "unicode": "e64b",
+      "unicode_decimal": 58955
+    },
+    {
+      "icon_id": "24855815",
+      "name": "undo-filled",
+      "font_class": "undo-filled",
+      "unicode": "e64c",
+      "unicode_decimal": 58956
+    },
+    {
+      "icon_id": "24855816",
+      "name": "more",
+      "font_class": "more",
+      "unicode": "e64d",
+      "unicode_decimal": 58957
+    },
+    {
+      "icon_id": "24855817",
+      "name": "more-filled",
+      "font_class": "more-filled",
+      "unicode": "e64e",
+      "unicode_decimal": 58958
+    },
+    {
+      "icon_id": "24855818",
+      "name": "undo",
+      "font_class": "undo",
+      "unicode": "e64f",
+      "unicode_decimal": 58959
+    },
+    {
+      "icon_id": "24855819",
+      "name": "images",
+      "font_class": "images",
+      "unicode": "e650",
+      "unicode_decimal": 58960
+    },
+    {
+      "icon_id": "24855821",
+      "name": "paperclip",
+      "font_class": "paperclip",
+      "unicode": "e652",
+      "unicode_decimal": 58962
+    },
+    {
+      "icon_id": "24855822",
+      "name": "settings",
+      "font_class": "settings",
+      "unicode": "e653",
+      "unicode_decimal": 58963
+    },
+    {
+      "icon_id": "24855823",
+      "name": "search",
+      "font_class": "search",
+      "unicode": "e654",
+      "unicode_decimal": 58964
+    },
+    {
+      "icon_id": "24855824",
+      "name": "redo-filled",
+      "font_class": "redo-filled",
+      "unicode": "e655",
+      "unicode_decimal": 58965
+    },
+    {
+      "icon_id": "24841702",
+      "name": "list",
+      "font_class": "list",
+      "unicode": "e644",
+      "unicode_decimal": 58948
+    },
+    {
+      "icon_id": "24841489",
+      "name": "mail-open-filled",
+      "font_class": "mail-open-filled",
+      "unicode": "e63a",
+      "unicode_decimal": 58938
+    },
+    {
+      "icon_id": "24841491",
+      "name": "hand-thumbsdown-filled",
+      "font_class": "hand-down-filled",
+      "unicode": "e63c",
+      "unicode_decimal": 58940
+    },
+    {
+      "icon_id": "24841492",
+      "name": "hand-thumbsdown",
+      "font_class": "hand-down",
+      "unicode": "e63d",
+      "unicode_decimal": 58941
+    },
+    {
+      "icon_id": "24841493",
+      "name": "hand-thumbsup-filled",
+      "font_class": "hand-up-filled",
+      "unicode": "e63e",
+      "unicode_decimal": 58942
+    },
+    {
+      "icon_id": "24841494",
+      "name": "hand-thumbsup",
+      "font_class": "hand-up",
+      "unicode": "e63f",
+      "unicode_decimal": 58943
+    },
+    {
+      "icon_id": "24841496",
+      "name": "heart-filled",
+      "font_class": "heart-filled",
+      "unicode": "e641",
+      "unicode_decimal": 58945
+    },
+    {
+      "icon_id": "24841498",
+      "name": "mail-open",
+      "font_class": "mail-open",
+      "unicode": "e643",
+      "unicode_decimal": 58947
+    },
+    {
+      "icon_id": "24841488",
+      "name": "heart",
+      "font_class": "heart",
+      "unicode": "e639",
+      "unicode_decimal": 58937
+    },
+    {
+      "icon_id": "24839963",
+      "name": "loop",
+      "font_class": "loop",
+      "unicode": "e633",
+      "unicode_decimal": 58931
+    },
+    {
+      "icon_id": "24839866",
+      "name": "pulldown",
+      "font_class": "pulldown",
+      "unicode": "e632",
+      "unicode_decimal": 58930
+    },
+    {
+      "icon_id": "24813798",
+      "name": "scan",
+      "font_class": "scan",
+      "unicode": "e62a",
+      "unicode_decimal": 58922
+    },
+    {
+      "icon_id": "24813786",
+      "name": "bars",
+      "font_class": "bars",
+      "unicode": "e627",
+      "unicode_decimal": 58919
+    },
+    {
+      "icon_id": "24813788",
+      "name": "cart-filled",
+      "font_class": "cart-filled",
+      "unicode": "e629",
+      "unicode_decimal": 58921
+    },
+    {
+      "icon_id": "24813790",
+      "name": "checkbox",
+      "font_class": "checkbox",
+      "unicode": "e62b",
+      "unicode_decimal": 58923
+    },
+    {
+      "icon_id": "24813791",
+      "name": "checkbox-filled",
+      "font_class": "checkbox-filled",
+      "unicode": "e62c",
+      "unicode_decimal": 58924
+    },
+    {
+      "icon_id": "24813794",
+      "name": "shop",
+      "font_class": "shop",
+      "unicode": "e62f",
+      "unicode_decimal": 58927
+    },
+    {
+      "icon_id": "24813795",
+      "name": "headphones",
+      "font_class": "headphones",
+      "unicode": "e630",
+      "unicode_decimal": 58928
+    },
+    {
+      "icon_id": "24813796",
+      "name": "cart",
+      "font_class": "cart",
+      "unicode": "e631",
+      "unicode_decimal": 58929
+    }
+  ]
+}

+ 89 - 0
uni_modules/uni-icons/components/uni-icons/uni-icons.vue

@@ -0,0 +1,89 @@
+<template>
+	<!-- #ifdef APP-NVUE -->
+	<text :style="{ color: color, 'font-size': size + 'px' }" class="uni-icons" @click="_onClick">{{unicode}}</text>
+	<!-- #endif -->
+	<!-- #ifndef APP-NVUE -->
+	<text :style="{ color: color, 'font-size': size + 'px' }" class="uni-icons" :class="['uniui-'+type,customPrefix,customPrefix?type:'']" @click="_onClick"></text>
+	<!-- #endif -->
+</template>
+
+<script>
+	import icons from './icons.js';
+	// #ifdef APP-NVUE
+	var domModule = weex.requireModule('dom');
+	import iconUrl from './uniicons.ttf'
+	domModule.addRule('fontFace', {
+		'fontFamily': "uniicons",
+		'src': "url('"+iconUrl+"')"
+	});
+	// #endif
+
+	/**
+	 * Icons 图标
+	 * @description 用于展示 icons 图标
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=28
+	 * @property {Number} size 图标大小
+	 * @property {String} type 图标图案,参考示例
+	 * @property {String} color 图标颜色
+	 * @property {String} customPrefix 自定义图标
+	 * @event {Function} click 点击 Icon 触发事件
+	 */
+	export default {
+		name: 'UniIcons',
+		emits:['click'],
+		props: {
+			type: {
+				type: String,
+				default: ''
+			},
+			color: {
+				type: String,
+				default: '#333333'
+			},
+			size: {
+				type: [Number, String],
+				default: 16
+			},
+			customPrefix:{
+				type: String,
+				default: ''
+			}
+		},
+		data() {
+			return {
+				icons: icons.glyphs
+			}
+		},
+		computed:{
+			unicode(){
+				let code = this.icons.find(v=>v.font_class === this.type)
+				if(code){
+					return unescape(`%u${code.unicode}`)
+				}
+				return ''
+			}
+		},
+		methods: {
+			_onClick() {
+				this.$emit('click')
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	/* #ifndef APP-NVUE */
+	@import './uniicons.css';
+	@font-face {
+		font-family: uniicons;
+		src: url('./uniicons.ttf') format('truetype');
+	}
+
+	/* #endif */
+	.uni-icons {
+		font-family: uniicons;
+		text-decoration: none;
+		text-align: center;
+	}
+
+</style>

+ 663 - 0
uni_modules/uni-icons/components/uni-icons/uniicons.css

@@ -0,0 +1,663 @@
+.uniui-color:before {
+  content: "\e6cf";
+}
+
+.uniui-wallet:before {
+  content: "\e6b1";
+}
+
+.uniui-settings-filled:before {
+  content: "\e6ce";
+}
+
+.uniui-auth-filled:before {
+  content: "\e6cc";
+}
+
+.uniui-shop-filled:before {
+  content: "\e6cd";
+}
+
+.uniui-staff-filled:before {
+  content: "\e6cb";
+}
+
+.uniui-vip-filled:before {
+  content: "\e6c6";
+}
+
+.uniui-plus-filled:before {
+  content: "\e6c7";
+}
+
+.uniui-folder-add-filled:before {
+  content: "\e6c8";
+}
+
+.uniui-color-filled:before {
+  content: "\e6c9";
+}
+
+.uniui-tune-filled:before {
+  content: "\e6ca";
+}
+
+.uniui-calendar-filled:before {
+  content: "\e6c0";
+}
+
+.uniui-notification-filled:before {
+  content: "\e6c1";
+}
+
+.uniui-wallet-filled:before {
+  content: "\e6c2";
+}
+
+.uniui-medal-filled:before {
+  content: "\e6c3";
+}
+
+.uniui-gift-filled:before {
+  content: "\e6c4";
+}
+
+.uniui-fire-filled:before {
+  content: "\e6c5";
+}
+
+.uniui-refreshempty:before {
+  content: "\e6bf";
+}
+
+.uniui-location-filled:before {
+  content: "\e6af";
+}
+
+.uniui-person-filled:before {
+  content: "\e69d";
+}
+
+.uniui-personadd-filled:before {
+  content: "\e698";
+}
+
+.uniui-back:before {
+  content: "\e6b9";
+}
+
+.uniui-forward:before {
+  content: "\e6ba";
+}
+
+.uniui-arrow-right:before {
+  content: "\e6bb";
+}
+
+.uniui-arrowthinright:before {
+  content: "\e6bb";
+}
+
+.uniui-arrow-left:before {
+  content: "\e6bc";
+}
+
+.uniui-arrowthinleft:before {
+  content: "\e6bc";
+}
+
+.uniui-arrow-up:before {
+  content: "\e6bd";
+}
+
+.uniui-arrowthinup:before {
+  content: "\e6bd";
+}
+
+.uniui-arrow-down:before {
+  content: "\e6be";
+}
+
+.uniui-arrowthindown:before {
+  content: "\e6be";
+}
+
+.uniui-bottom:before {
+  content: "\e6b8";
+}
+
+.uniui-arrowdown:before {
+  content: "\e6b8";
+}
+
+.uniui-right:before {
+  content: "\e6b5";
+}
+
+.uniui-arrowright:before {
+  content: "\e6b5";
+}
+
+.uniui-top:before {
+  content: "\e6b6";
+}
+
+.uniui-arrowup:before {
+  content: "\e6b6";
+}
+
+.uniui-left:before {
+  content: "\e6b7";
+}
+
+.uniui-arrowleft:before {
+  content: "\e6b7";
+}
+
+.uniui-eye:before {
+  content: "\e651";
+}
+
+.uniui-eye-filled:before {
+  content: "\e66a";
+}
+
+.uniui-eye-slash:before {
+  content: "\e6b3";
+}
+
+.uniui-eye-slash-filled:before {
+  content: "\e6b4";
+}
+
+.uniui-info-filled:before {
+  content: "\e649";
+}
+
+.uniui-reload:before {
+  content: "\e6b2";
+}
+
+.uniui-micoff-filled:before {
+  content: "\e6b0";
+}
+
+.uniui-map-pin-ellipse:before {
+  content: "\e6ac";
+}
+
+.uniui-map-pin:before {
+  content: "\e6ad";
+}
+
+.uniui-location:before {
+  content: "\e6ae";
+}
+
+.uniui-starhalf:before {
+  content: "\e683";
+}
+
+.uniui-star:before {
+  content: "\e688";
+}
+
+.uniui-star-filled:before {
+  content: "\e68f";
+}
+
+.uniui-calendar:before {
+  content: "\e6a0";
+}
+
+.uniui-fire:before {
+  content: "\e6a1";
+}
+
+.uniui-medal:before {
+  content: "\e6a2";
+}
+
+.uniui-font:before {
+  content: "\e6a3";
+}
+
+.uniui-gift:before {
+  content: "\e6a4";
+}
+
+.uniui-link:before {
+  content: "\e6a5";
+}
+
+.uniui-notification:before {
+  content: "\e6a6";
+}
+
+.uniui-staff:before {
+  content: "\e6a7";
+}
+
+.uniui-vip:before {
+  content: "\e6a8";
+}
+
+.uniui-folder-add:before {
+  content: "\e6a9";
+}
+
+.uniui-tune:before {
+  content: "\e6aa";
+}
+
+.uniui-auth:before {
+  content: "\e6ab";
+}
+
+.uniui-person:before {
+  content: "\e699";
+}
+
+.uniui-email-filled:before {
+  content: "\e69a";
+}
+
+.uniui-phone-filled:before {
+  content: "\e69b";
+}
+
+.uniui-phone:before {
+  content: "\e69c";
+}
+
+.uniui-email:before {
+  content: "\e69e";
+}
+
+.uniui-personadd:before {
+  content: "\e69f";
+}
+
+.uniui-chatboxes-filled:before {
+  content: "\e692";
+}
+
+.uniui-contact:before {
+  content: "\e693";
+}
+
+.uniui-chatbubble-filled:before {
+  content: "\e694";
+}
+
+.uniui-contact-filled:before {
+  content: "\e695";
+}
+
+.uniui-chatboxes:before {
+  content: "\e696";
+}
+
+.uniui-chatbubble:before {
+  content: "\e697";
+}
+
+.uniui-upload-filled:before {
+  content: "\e68e";
+}
+
+.uniui-upload:before {
+  content: "\e690";
+}
+
+.uniui-weixin:before {
+  content: "\e691";
+}
+
+.uniui-compose:before {
+  content: "\e67f";
+}
+
+.uniui-qq:before {
+  content: "\e680";
+}
+
+.uniui-download-filled:before {
+  content: "\e681";
+}
+
+.uniui-pyq:before {
+  content: "\e682";
+}
+
+.uniui-sound:before {
+  content: "\e684";
+}
+
+.uniui-trash-filled:before {
+  content: "\e685";
+}
+
+.uniui-sound-filled:before {
+  content: "\e686";
+}
+
+.uniui-trash:before {
+  content: "\e687";
+}
+
+.uniui-videocam-filled:before {
+  content: "\e689";
+}
+
+.uniui-spinner-cycle:before {
+  content: "\e68a";
+}
+
+.uniui-weibo:before {
+  content: "\e68b";
+}
+
+.uniui-videocam:before {
+  content: "\e68c";
+}
+
+.uniui-download:before {
+  content: "\e68d";
+}
+
+.uniui-help:before {
+  content: "\e679";
+}
+
+.uniui-navigate-filled:before {
+  content: "\e67a";
+}
+
+.uniui-plusempty:before {
+  content: "\e67b";
+}
+
+.uniui-smallcircle:before {
+  content: "\e67c";
+}
+
+.uniui-minus-filled:before {
+  content: "\e67d";
+}
+
+.uniui-micoff:before {
+  content: "\e67e";
+}
+
+.uniui-closeempty:before {
+  content: "\e66c";
+}
+
+.uniui-clear:before {
+  content: "\e66d";
+}
+
+.uniui-navigate:before {
+  content: "\e66e";
+}
+
+.uniui-minus:before {
+  content: "\e66f";
+}
+
+.uniui-image:before {
+  content: "\e670";
+}
+
+.uniui-mic:before {
+  content: "\e671";
+}
+
+.uniui-paperplane:before {
+  content: "\e672";
+}
+
+.uniui-close:before {
+  content: "\e673";
+}
+
+.uniui-help-filled:before {
+  content: "\e674";
+}
+
+.uniui-paperplane-filled:before {
+  content: "\e675";
+}
+
+.uniui-plus:before {
+  content: "\e676";
+}
+
+.uniui-mic-filled:before {
+  content: "\e677";
+}
+
+.uniui-image-filled:before {
+  content: "\e678";
+}
+
+.uniui-locked-filled:before {
+  content: "\e668";
+}
+
+.uniui-info:before {
+  content: "\e669";
+}
+
+.uniui-locked:before {
+  content: "\e66b";
+}
+
+.uniui-camera-filled:before {
+  content: "\e658";
+}
+
+.uniui-chat-filled:before {
+  content: "\e659";
+}
+
+.uniui-camera:before {
+  content: "\e65a";
+}
+
+.uniui-circle:before {
+  content: "\e65b";
+}
+
+.uniui-checkmarkempty:before {
+  content: "\e65c";
+}
+
+.uniui-chat:before {
+  content: "\e65d";
+}
+
+.uniui-circle-filled:before {
+  content: "\e65e";
+}
+
+.uniui-flag:before {
+  content: "\e65f";
+}
+
+.uniui-flag-filled:before {
+  content: "\e660";
+}
+
+.uniui-gear-filled:before {
+  content: "\e661";
+}
+
+.uniui-home:before {
+  content: "\e662";
+}
+
+.uniui-home-filled:before {
+  content: "\e663";
+}
+
+.uniui-gear:before {
+  content: "\e664";
+}
+
+.uniui-smallcircle-filled:before {
+  content: "\e665";
+}
+
+.uniui-map-filled:before {
+  content: "\e666";
+}
+
+.uniui-map:before {
+  content: "\e667";
+}
+
+.uniui-refresh-filled:before {
+  content: "\e656";
+}
+
+.uniui-refresh:before {
+  content: "\e657";
+}
+
+.uniui-cloud-upload:before {
+  content: "\e645";
+}
+
+.uniui-cloud-download-filled:before {
+  content: "\e646";
+}
+
+.uniui-cloud-download:before {
+  content: "\e647";
+}
+
+.uniui-cloud-upload-filled:before {
+  content: "\e648";
+}
+
+.uniui-redo:before {
+  content: "\e64a";
+}
+
+.uniui-images-filled:before {
+  content: "\e64b";
+}
+
+.uniui-undo-filled:before {
+  content: "\e64c";
+}
+
+.uniui-more:before {
+  content: "\e64d";
+}
+
+.uniui-more-filled:before {
+  content: "\e64e";
+}
+
+.uniui-undo:before {
+  content: "\e64f";
+}
+
+.uniui-images:before {
+  content: "\e650";
+}
+
+.uniui-paperclip:before {
+  content: "\e652";
+}
+
+.uniui-settings:before {
+  content: "\e653";
+}
+
+.uniui-search:before {
+  content: "\e654";
+}
+
+.uniui-redo-filled:before {
+  content: "\e655";
+}
+
+.uniui-list:before {
+  content: "\e644";
+}
+
+.uniui-mail-open-filled:before {
+  content: "\e63a";
+}
+
+.uniui-hand-down-filled:before {
+  content: "\e63c";
+}
+
+.uniui-hand-down:before {
+  content: "\e63d";
+}
+
+.uniui-hand-up-filled:before {
+  content: "\e63e";
+}
+
+.uniui-hand-up:before {
+  content: "\e63f";
+}
+
+.uniui-heart-filled:before {
+  content: "\e641";
+}
+
+.uniui-mail-open:before {
+  content: "\e643";
+}
+
+.uniui-heart:before {
+  content: "\e639";
+}
+
+.uniui-loop:before {
+  content: "\e633";
+}
+
+.uniui-pulldown:before {
+  content: "\e632";
+}
+
+.uniui-scan:before {
+  content: "\e62a";
+}
+
+.uniui-bars:before {
+  content: "\e627";
+}
+
+.uniui-cart-filled:before {
+  content: "\e629";
+}
+
+.uniui-checkbox:before {
+  content: "\e62b";
+}
+
+.uniui-checkbox-filled:before {
+  content: "\e62c";
+}
+
+.uniui-shop:before {
+  content: "\e62f";
+}
+
+.uniui-headphones:before {
+  content: "\e630";
+}
+
+.uniui-cart:before {
+  content: "\e631";
+}

二進制
uni_modules/uni-icons/components/uni-icons/uniicons.ttf


+ 86 - 0
uni_modules/uni-icons/package.json

@@ -0,0 +1,86 @@
+{
+  "id": "uni-icons",
+  "displayName": "uni-icons 图标",
+  "version": "1.3.2",
+  "description": "图标组件,用于展示移动端常见的图标,可自定义颜色、大小。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "icon",
+    "图标"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.2.14"
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "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"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 8 - 0
uni_modules/uni-icons/readme.md

@@ -0,0 +1,8 @@
+## Icons 图标
+> **组件名:uni-icons**
+> 代码块: `uIcons`
+
+用于展示 icons 图标 。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-icons)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 22 - 0
uni_modules/uni-nav-bar/changelog.md

@@ -0,0 +1,22 @@
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-nav-bar](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
+## 1.1.0(2021-07-30)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.11(2021-05-12)
+- 新增 组件示例地址
+## 1.0.10(2021-04-30)
+- 修复 在nvue下fixed为true,宽度不能撑满的Bug
+## 1.0.9(2021-04-21)
+- 优化 添加依赖 uni-icons, 导入后自动下载依赖
+## 1.0.8(2021-04-14)
+- uni-ui 修复 uni-nav-bar 当 fixed 属性为 true 时铺不满屏幕的 bug
+
+## 1.0.7(2021-02-25)
+- 修复 easycom 下,找不到 uni-status-bar 的bug
+
+## 1.0.6(2021-02-05)
+- 优化 组件引用关系,通过uni_modules引用组件
+
+## 1.0.5(2021-02-05)
+- 调整为uni_modules目录规范

+ 254 - 0
uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue

@@ -0,0 +1,254 @@
+<template>
+	<view class="uni-navbar">
+		<view :class="{ 'uni-navbar--fixed': fixed, 'uni-navbar--shadow': shadow, 'uni-navbar--border': border }" :style="{ 'background-color': backgroundColor }"
+		 class="uni-navbar__content">
+			<status-bar v-if="statusBar" />
+			<view :style="{ color: color,backgroundColor: backgroundColor }" class="uni-navbar__header uni-navbar__content_view">
+				<view @tap="onClickLeft" class="uni-navbar__header-btns uni-navbar__header-btns-left uni-navbar__content_view">
+					<view class="uni-navbar__content_view" v-if="leftIcon.length">
+						<uni-icons :color="color" :type="leftIcon" size="22" color="#333"/>
+					</view>
+					<view :class="{ 'uni-navbar-btn-icon-left': !leftIcon.length }" class="uni-navbar-btn-text uni-navbar__content_view"
+					 v-if="leftText.length">
+						<text :style="{ color: color, fontSize: '12px' }">{{ leftText }}</text>
+					</view>
+					<slot name="left" />
+				</view>
+				<view class="uni-navbar__header-container uni-navbar__content_view" @tap="onClickTitle">
+					<view class="uni-navbar__header-container-inner uni-navbar__content_view" v-if="title.length">
+						<text class="uni-nav-bar-text" :style="{color: color }">{{ title }}</text>
+					</view>
+					<!-- 标题插槽 -->
+					<slot />
+				</view>
+				<view :class="title.length ? 'uni-navbar__header-btns-right' : ''" @tap="onClickRight" class="uni-navbar__header-btns uni-navbar__content_view">
+					<view class="uni-navbar__content_view uni-navbar__header-btns-right" v-if="rightIcon.length">
+						<uni-icons :color="color" :type="rightIcon" size="22" />
+					</view>
+					<!-- 优先显示图标 -->
+					<view class="uni-navbar-btn-text uni-navbar__content_view" v-if="rightText.length && !rightIcon.length">
+						<text class="uni-nav-bar-right-text">{{ rightText }}</text>
+					</view>
+					<slot name="right" />
+				</view>
+			</view>
+		</view>
+		<view class="uni-navbar__placeholder" v-if="fixed">
+			<status-bar v-if="statusBar" />
+			<view class="uni-navbar__placeholder-view" />
+		</view>
+	</view>
+</template>
+
+<script>
+	import statusBar from "./uni-status-bar.vue";
+
+	/**
+	 * NavBar 自定义导航栏
+	 * @description 导航栏组件,主要用于头部导航
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=52
+	 * @property {String} title 标题文字
+	 * @property {String} leftText 左侧按钮文本
+	 * @property {String} rightText 右侧按钮文本
+	 * @property {String} leftIcon 左侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
+	 * @property {String} rightIcon 右侧按钮图标(图标类型参考 [Icon 图标](http://ext.dcloud.net.cn/plugin?id=28) type 属性)
+	 * @property {String} color 图标和文字颜色
+	 * @property {String} backgroundColor 导航栏背景颜色
+	 * @property {Boolean} fixed = [true|false] 是否固定顶部
+	 * @property {Boolean} statusBar = [true|false] 是否包含状态栏
+	 * @property {Boolean} shadow = [true|false] 导航栏下是否有阴影
+	 * @event {Function} clickLeft 左侧按钮点击时触发
+	 * @event {Function} clickRight 右侧按钮点击时触发
+	 * @event {Function} clickTitle 中间标题点击时触发
+	 */
+	export default {
+		name: "UniNavBar",
+		components: {
+			statusBar
+		},
+		emits:['clickLeft','clickRight','clickTitle'],
+		props: {
+			title: {
+				type: String,
+				default: ""
+			},
+			leftText: {
+				type: String,
+				default: ""
+			},
+			rightText: {
+				type: String,
+				default: ""
+			},
+			leftIcon: {
+				type: String,
+				default: ""
+			},
+			rightIcon: {
+				type: String,
+				default: ""
+			},
+			fixed: {
+				type: [Boolean, String],
+				default: false
+			},
+			color: {
+				type: String,
+				default: "#000000"
+			},
+			backgroundColor: {
+				type: String,
+				default: "#FFFFFF"
+			},
+			statusBar: {
+				type: [Boolean, String],
+				default: false
+			},
+			shadow: {
+				type: [Boolean, String],
+				default: false
+			},
+			border: {
+				type: [Boolean, String],
+				default: true
+			}
+		},
+        mounted() {
+          if(uni.report && this.title !== '') {
+              uni.report('title', this.title)
+          }
+        },
+		methods: {
+			onClickLeft() {
+				this.$emit("clickLeft");
+			},
+			onClickRight() {
+				this.$emit("clickRight");
+			},
+			onClickTitle() {
+				this.$emit("clickTitle");
+			}
+		}
+	};
+</script>
+
+<style lang="scss" scoped>
+	$nav-height: 44px;
+
+	.uni-nav-bar-text {
+		/* #ifdef APP-PLUS */
+		font-size: 34rpx;
+		/* #endif */
+		/* #ifndef APP-PLUS */
+		font-size: 14px;
+		/* #endif */
+	}
+
+	.uni-nav-bar-right-text {
+		font-size: 12px;
+	}
+
+	.uni-navbar__content {
+		position: relative;
+		background-color: #fff;
+		overflow: hidden;
+		// width: 750rpx;
+	}
+
+	.uni-navbar__content_view {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		align-items: center;
+		flex-direction: row;
+		// background-color: #FFFFFF;
+	}
+
+	.uni-navbar__header {
+		padding: 0 10px;
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		height: $nav-height;
+		line-height: $nav-height;
+		font-size: 12px;
+		// background-color: #ffffff;
+	}
+
+	.uni-navbar__header-btns {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-wrap: nowrap;
+		width: 120rpx;
+		// padding: 0 6px;
+		justify-content: center;
+		align-items: center;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-navbar__header-btns-left {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		width: 120rpx;
+		justify-content: flex-start;
+	}
+
+	.uni-navbar__header-btns-right {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		width: 150rpx;
+		padding-right: 30rpx;
+		justify-content: flex-end;
+	}
+
+	.uni-navbar__header-container {
+		flex: 1;
+	}
+
+	.uni-navbar__header-container-inner {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex: 1;
+		align-items: center;
+		justify-content: center;
+		font-size: 12px;
+	}
+
+
+	.uni-navbar__placeholder-view {
+		height: $nav-height;
+	}
+
+	.uni-navbar--fixed {
+		position: fixed;
+		z-index: 998;
+		/* #ifdef H5 */
+		left: var(--window-left);
+		right: var(--window-right);
+		/* #endif */
+		/* #ifndef H5 */
+		left:0;
+		right: 0;
+		/* #endif */
+
+	}
+
+	.uni-navbar--shadow {
+		/* #ifndef APP-NVUE */
+		box-shadow: 0 1px 6px #ccc;
+		/* #endif */
+	}
+
+	.uni-navbar--border {
+		border-bottom-width: 1rpx;
+		border-bottom-style: solid;
+		border-bottom-color: #eee;
+	}
+</style>

+ 27 - 0
uni_modules/uni-nav-bar/components/uni-nav-bar/uni-status-bar.vue

@@ -0,0 +1,27 @@
+<template>
+	<view :style="{ height: statusBarHeight }" class="uni-status-bar">
+		<slot />
+	</view>
+</template>
+
+<script>
+	export default {
+		name: 'UniStatusBar',
+		data() {
+			return {
+				statusBarHeight: 20
+			}
+		},
+		mounted() {
+			this.statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px'
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.uni-status-bar {
+		// width: 750rpx;
+		height: 20px;
+		// height: var(--status-bar-height);
+	}
+</style>

+ 89 - 0
uni_modules/uni-nav-bar/package.json

@@ -0,0 +1,89 @@
+{
+  "id": "uni-nav-bar",
+  "displayName": "uni-nav-bar 自定义导航栏",
+  "version": "1.2.0",
+  "description": "自定义导航栏组件,主要用于头部导航。",
+  "keywords": [
+    "uni-ui",
+    "导航",
+    "导航栏",
+    "自定义导航栏"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+  "dcloudext": {
+    "category": [
+      "前端组件",
+      "通用组件"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [
+			"uni-scss",
+			"uni-icons"
+		],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "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"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 15 - 0
uni_modules/uni-nav-bar/readme.md

@@ -0,0 +1,15 @@
+
+
+## NavBar 导航栏
+> **组件名:uni-nav-bar**
+> 代码块: `uNavBar`
+
+导航栏组件,主要用于头部导航。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-nav-bar)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+
+
+
+

+ 6 - 0
uni_modules/uni-scss/changelog.md

@@ -0,0 +1,6 @@
+## 1.0.2(2021-11-22)
+- 修复 / 符号在 vue 不同版本兼容问题引起的报错问题
+## 1.0.1(2021-11-22)
+- 修复 vue3中scss语法兼容问题
+## 1.0.0(2021-11-18)
+- init

+ 1 - 0
uni_modules/uni-scss/index.scss

@@ -0,0 +1 @@
+@import './styles/index.scss';

+ 95 - 0
uni_modules/uni-scss/manifest.json

@@ -0,0 +1,95 @@
+{
+	"name" : "",
+	"appid" : "",
+	"description": "应用描述",
+	"versionName": "1.0.0",
+	"versionCode": "100",
+	"transformPx": false,
+	/* 5+App特有相关 */
+	"app-plus": {
+		"usingComponents": true,
+		"splashscreen": {
+			"alwaysShowBeforeRender": true,
+			"waiting": true,
+			"autoclose": true,
+			"delay": 0
+		},
+		"modules": {
+			"OAuth": {},
+			"Payment": {},
+			"Push": {},
+			"Share": {},
+			"Speech": {},
+			"VideoPlayer": {}
+		},
+		/* 应用发布信息 */
+		"distribute": {
+			/* android打包配置 */
+			"android": {
+				"permissions": [
+					"<uses-feature android:name=\"android.hardware.camera\"/>",
+					"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
+					"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_MOCK_LOCATION\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
+					"<uses-permission android:name=\"android.permission.CAMERA\"/>",
+					"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
+					"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
+					"<uses-permission android:name=\"android.permission.GET_TASKS\"/>",
+					"<uses-permission android:name=\"android.permission.INTERNET\"/>",
+					"<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
+					"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
+					"<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
+					"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
+					"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
+					"<uses-permission android:name=\"android.permission.READ_SMS\"/>",
+					"<uses-permission android:name=\"android.permission.RECEIVE_BOOT_COMPLETED\"/>",
+					"<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
+					"<uses-permission android:name=\"android.permission.SEND_SMS\"/>",
+					"<uses-permission android:name=\"android.permission.SYSTEM_ALERT_WINDOW\"/>",
+					"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
+					"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
+					"<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
+					"<uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\"/>",
+					"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>",
+					"<uses-permission android:name=\"android.permission.WRITE_SMS\"/>",
+					"<uses-permission android:name=\"android.permission.RECEIVE_USER_PRESENT\"/>"
+				]
+			},
+			/* ios打包配置 */
+			"ios": {
+				"UIBackgroundModes": ["audio"]
+			},
+			/* SDK配置 */
+			"sdkConfigs": {
+				"speech": {
+					"ifly": {}
+				}
+			},
+			"orientation": ["portrait-primary"]
+		}
+	},
+	/* 快应用特有相关 */
+	"quickapp": {},
+	/* 小程序特有相关 */
+	"mp-weixin": {
+		"appid": "",
+		"setting": {
+			"urlCheck": false
+		},
+		"usingComponents": true
+	},
+	"h5": {
+		"template": "template.h5.html",
+		"router": {
+			"mode": "history",
+			"base": "/h5/"
+		}
+	}
+}

+ 82 - 0
uni_modules/uni-scss/package.json

@@ -0,0 +1,82 @@
+{
+  "id": "uni-scss",
+  "displayName": "uni-scss 辅助样式",
+  "version": "1.0.2",
+  "description": "uni-sass是uni-ui提供的一套全局样式 ,通过一些简单的类名和sass变量,实现简单的页面布局操作,比如颜色、边距、圆角等。",
+  "keywords": [
+    "uni-scss",
+    "uni-ui",
+    "辅助样式"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": "^3.1.0"
+  },
+  "dcloudext": {
+    "category": [
+        "uni-app前端模板",
+        "前端页面模板"
+    ],
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui"
+  },
+  "uni_modules": {
+    "dependencies": [],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "u"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "n",
+          "联盟": "n"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 4 - 0
uni_modules/uni-scss/readme.md

@@ -0,0 +1,4 @@
+`uni-sass` 是 `uni-ui`提供的一套全局样式 ,通过一些简单的类名和`sass`变量,实现简单的页面布局操作,比如颜色、边距、圆角等。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-sass)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 

+ 7 - 0
uni_modules/uni-scss/styles/index.scss

@@ -0,0 +1,7 @@
+@import './setting/_variables.scss';
+@import './setting/_border.scss';
+@import './setting/_color.scss';
+@import './setting/_space.scss';
+@import './setting/_radius.scss';
+@import './setting/_text.scss';
+@import './setting/_styles.scss';

+ 3 - 0
uni_modules/uni-scss/styles/setting/_border.scss

@@ -0,0 +1,3 @@
+.uni-border {
+	border: 1px $uni-border-1 solid;
+}

+ 66 - 0
uni_modules/uni-scss/styles/setting/_color.scss

@@ -0,0 +1,66 @@
+
+// TODO 暂时不需要 class ,需要用户使用变量实现 ,如果使用类名其实并不推荐
+// @mixin get-styles($k,$c) {
+// 	@if $k == size or $k == weight{
+// 		font-#{$k}:#{$c}
+// 	}@else{
+// 		#{$k}:#{$c}
+// 	}
+// }
+$uni-ui-color:(
+	// 主色
+	primary: $uni-primary,
+	primary-disable: $uni-primary-disable,
+	primary-light: $uni-primary-light,
+	// 辅助色
+	success: $uni-success,
+	success-disable: $uni-success-disable,
+	success-light: $uni-success-light,
+	warning: $uni-warning,
+	warning-disable: $uni-warning-disable,
+	warning-light: $uni-warning-light,
+	error: $uni-error,
+	error-disable: $uni-error-disable,
+	error-light: $uni-error-light,
+	info: $uni-info,
+	info-disable: $uni-info-disable,
+	info-light: $uni-info-light,
+	// 中性色
+	main-color: $uni-main-color,
+	base-color: $uni-base-color,
+	secondary-color: $uni-secondary-color,
+	extra-color: $uni-extra-color,
+	// 背景色
+	bg-color: $uni-bg-color,
+	// 边框颜色
+	border-1: $uni-border-1,
+	border-2: $uni-border-2,
+	border-3: $uni-border-3,
+	border-4: $uni-border-4,
+	// 黑色
+	black:$uni-black,
+	// 白色
+	white:$uni-white,
+	// 透明
+	transparent:$uni-transparent
+) !default;
+@each $key, $child in $uni-ui-color {
+	.uni-#{"" + $key} {
+		color: $child;
+	}
+	.uni-#{"" + $key}-bg {
+		background-color: $child;
+	}
+}
+.uni-shadow-sm {
+	box-shadow: $uni-shadow-sm;
+}
+.uni-shadow-base {
+	box-shadow: $uni-shadow-base;
+}
+.uni-shadow-lg {
+	box-shadow: $uni-shadow-lg;
+}
+.uni-mask {
+	background-color:$uni-mask;
+}

+ 55 - 0
uni_modules/uni-scss/styles/setting/_radius.scss

@@ -0,0 +1,55 @@
+@mixin radius($r,$d:null ,$important: false){
+  $radius-value:map-get($uni-radius, $r) if($important, !important, null);
+  // Key exists within the $uni-radius variable
+  @if (map-has-key($uni-radius, $r) and  $d){
+		@if $d == t {
+				border-top-left-radius:$radius-value;
+				border-top-right-radius:$radius-value;
+		}@else if $d == r {
+				border-top-right-radius:$radius-value;
+				border-bottom-right-radius:$radius-value;
+		}@else if $d == b {
+				border-bottom-left-radius:$radius-value;
+				border-bottom-right-radius:$radius-value;
+		}@else if $d == l {
+				border-top-left-radius:$radius-value;
+				border-bottom-left-radius:$radius-value;
+		}@else if $d == tl {
+				border-top-left-radius:$radius-value;
+		}@else if $d == tr {
+				border-top-right-radius:$radius-value;
+		}@else if $d == br {
+				border-bottom-right-radius:$radius-value;
+		}@else if $d == bl {
+				border-bottom-left-radius:$radius-value;
+		}
+  }@else{
+		border-radius:$radius-value;
+  }
+}
+
+@each $key, $child in $uni-radius {
+	@if($key){
+		.uni-radius-#{"" + $key} {
+				@include radius($key)
+		}
+	}@else{
+		.uni-radius {
+				@include radius($key)
+		}
+	}
+}
+
+@each $direction in t, r, b, l,tl, tr, br, bl {
+	@each $key, $child in $uni-radius {
+		@if($key){
+			.uni-radius-#{"" + $direction}-#{"" + $key} {
+				@include radius($key,$direction,false)
+			}
+		}@else{
+			.uni-radius-#{$direction} {
+				@include radius($key,$direction,false)
+			}
+		}
+	}
+}

+ 56 - 0
uni_modules/uni-scss/styles/setting/_space.scss

@@ -0,0 +1,56 @@
+
+@mixin fn($space,$direction,$size,$n) {
+	@if $n {
+		#{$space}-#{$direction}: #{$size*$uni-space-root}px
+	} @else {
+		 #{$space}-#{$direction}: #{-$size*$uni-space-root}px
+	}
+}
+@mixin get-styles($direction,$i,$space,$n){
+	@if $direction == t {
+		@include fn($space, top,$i,$n);
+	} 
+	@if $direction == r {
+		@include fn($space, right,$i,$n);
+	} 
+	@if $direction == b {
+		@include fn($space, bottom,$i,$n);
+	} 
+	@if $direction == l {
+	 @include fn($space, left,$i,$n);
+	} 
+	@if $direction == x {
+		@include fn($space, left,$i,$n);
+		@include fn($space, right,$i,$n);
+	} 
+	@if $direction == y {
+		@include fn($space, top,$i,$n);
+		@include fn($space, bottom,$i,$n);
+	} 
+	@if $direction == a {
+		@if $n {
+			#{$space}:#{$i*$uni-space-root}px;
+		} @else {
+			#{$space}:#{-$i*$uni-space-root}px;
+		}
+	} 
+}
+
+@each $orientation in m,p {
+	$space: margin;
+	@if $orientation == m {
+		$space: margin;
+	} @else {
+		$space: padding;
+	}
+	@for $i from 0 through 16 {
+		@each $direction in t, r, b, l, x, y, a {
+			.uni-#{$orientation}#{$direction}-#{$i} { 
+				@include  get-styles($direction,$i,$space,true);
+			} 
+			.uni-#{$orientation}#{$direction}-n#{$i} { 
+				@include  get-styles($direction,$i,$space,false);
+			}
+		}
+	}
+}

+ 167 - 0
uni_modules/uni-scss/styles/setting/_styles.scss

@@ -0,0 +1,167 @@
+/* #ifndef APP-NVUE */
+
+$-color-white:#fff;
+$-color-black:#000;
+@mixin base-style($color) {
+	color: #fff;
+	background-color: $color;
+	border-color: mix($-color-black, $color, 8%);
+	&:not([hover-class]):active {
+		background: mix($-color-black, $color, 10%);
+		border-color: mix($-color-black, $color, 20%);
+		color: $-color-white;
+		outline: none;
+	}
+}
+@mixin is-color($color) {
+	@include base-style($color);
+	&[loading] {
+		@include base-style($color);
+		&::before {
+			margin-right:5px;
+		}
+	}
+	&[disabled] {
+	  &,
+		&[loading],
+	  &:not([hover-class]):active {
+	    color: $-color-white;
+			border-color: mix(darken($color,10%), $-color-white);
+	    background-color: mix($color, $-color-white);
+	  }
+	}
+
+}
+@mixin base-plain-style($color) {
+	color:$color;
+	background-color: mix($-color-white, $color, 90%);
+	border-color: mix($-color-white, $color, 70%);
+	&:not([hover-class]):active {
+	  background: mix($-color-white, $color, 80%);
+	  color: $color;
+	  outline: none;
+		border-color: mix($-color-white, $color, 50%);
+	}
+}
+@mixin is-plain($color){
+	&[plain] {
+		@include base-plain-style($color);
+		&[loading] {
+			@include base-plain-style($color);
+			&::before {
+				margin-right:5px;
+			}
+		}
+		&[disabled] {
+		  &,
+		  &:active {
+		    color: mix($-color-white, $color, 40%);
+		    background-color: mix($-color-white, $color, 90%);
+				border-color: mix($-color-white, $color, 80%);
+		  }
+		}
+	}
+}
+
+
+.uni-btn {
+	margin: 5px;
+	color: #393939;
+	border:1px solid #ccc;
+	font-size: 16px;
+	font-weight: 200;
+	background-color: #F9F9F9;
+	// TODO 暂时处理边框隐藏一边的问题
+	overflow: visible;
+	&::after{
+		border: none;
+	}
+
+	&:not([type]),&[type=default] {
+		color: #999;
+		&[loading] {
+			background: none;
+			&::before {
+				margin-right:5px;
+			}
+		}
+
+
+
+		&[disabled]{
+			color: mix($-color-white, #999, 60%);
+		  &,
+			&[loading],
+		  &:active {
+				color: mix($-color-white, #999, 60%);
+		    background-color: mix($-color-white,$-color-black , 98%);
+				border-color: mix($-color-white,  #999, 85%);
+		  }
+		}
+
+		&[plain] {
+			color: #999;
+			background: none;
+			border-color: $uni-border-1;
+			&:not([hover-class]):active {
+				background: none;
+			  color: mix($-color-white, $-color-black, 80%);
+				border-color: mix($-color-white, $-color-black, 90%);
+			  outline: none;
+			}
+			&[disabled]{
+			  &,
+				&[loading],
+			  &:active {
+			    background: none;
+					color: mix($-color-white, #999, 60%);
+					border-color: mix($-color-white,  #999, 85%);
+			  }
+			}
+		}
+	}
+
+	&:not([hover-class]):active {
+	  color: mix($-color-white, $-color-black, 50%);
+	}
+
+	&[size=mini] {
+		font-size: 16px;
+		font-weight: 200;
+		border-radius: 8px;
+	}
+
+
+
+	&.uni-btn-small {
+		font-size: 14px;
+	}
+	&.uni-btn-mini {
+		font-size: 12px;
+	}
+
+	&.uni-btn-radius {
+		border-radius: 999px;
+	}
+	&[type=primary] {
+		@include is-color($uni-primary);
+		@include is-plain($uni-primary)
+	}
+	&[type=success] {
+		@include is-color($uni-success);
+		@include is-plain($uni-success)
+	}
+	&[type=error] {
+		@include is-color($uni-error);
+		@include is-plain($uni-error)
+	}
+	&[type=warning] {
+		@include is-color($uni-warning);
+		@include is-plain($uni-warning)
+	}
+	&[type=info] {
+		@include is-color($uni-info);
+		@include is-plain($uni-info)
+	}
+}
+/* #endif */

+ 24 - 0
uni_modules/uni-scss/styles/setting/_text.scss

@@ -0,0 +1,24 @@
+@mixin get-styles($k,$c) {
+	@if $k == size or $k == weight{
+		font-#{$k}:#{$c}
+	}@else{
+		#{$k}:#{$c}
+	}
+}
+
+@each $key, $child in $uni-headings {
+	/* #ifndef APP-NVUE */
+	.uni-#{$key} {
+		@each $k, $c in $child {
+			@include get-styles($k,$c)
+		}
+	}
+	/* #endif */
+	/* #ifdef APP-NVUE */
+	.container .uni-#{$key} {
+		@each $k, $c in $child {
+			@include get-styles($k,$c)
+		}
+	}
+	/* #endif */
+}

+ 146 - 0
uni_modules/uni-scss/styles/setting/_variables.scss

@@ -0,0 +1,146 @@
+// @use "sass:math";
+@import  '../tools/functions.scss';
+// 间距基础倍数
+$uni-space-root: 2 !default;
+// 边框半径默认值
+$uni-radius-root:5px !default;
+$uni-radius: () !default;
+// 边框半径断点
+$uni-radius: map-deep-merge(
+  (
+    0: 0,
+		// TODO 当前版本暂时不支持 sm 属性
+    // 'sm': math.div($uni-radius-root, 2),
+    null: $uni-radius-root,
+    'lg': $uni-radius-root * 2,
+    'xl': $uni-radius-root * 6,
+    'pill': 9999px,
+    'circle': 50%
+  ),
+  $uni-radius
+);
+// 字体家族
+$body-font-family: 'Roboto', sans-serif !default;
+// 文本
+$heading-font-family: $body-font-family !default;
+$uni-headings: () !default;
+$letterSpacing: -0.01562em;
+$uni-headings: map-deep-merge(
+  (
+    'h1': (
+      size: 32px,
+			weight: 300,
+			line-height: 50px,
+			// letter-spacing:-0.01562em
+    ),
+    'h2': (
+      size: 28px,
+      weight: 300,
+      line-height: 40px,
+      // letter-spacing: -0.00833em
+    ),
+    'h3': (
+      size: 24px,
+      weight: 400,
+      line-height: 32px,
+      // letter-spacing: normal
+    ),
+    'h4': (
+      size: 20px,
+      weight: 400,
+      line-height: 30px,
+      // letter-spacing: 0.00735em
+    ),
+    'h5': (
+      size: 16px,
+      weight: 400,
+      line-height: 24px,
+      // letter-spacing: normal
+    ),
+    'h6': (
+      size: 14px,
+      weight: 500,
+      line-height: 18px,
+      // letter-spacing: 0.0125em
+    ),
+    'subtitle': (
+      size: 12px,
+      weight: 400,
+      line-height: 20px,
+      // letter-spacing: 0.00937em
+    ),
+    'body': (
+      font-size: 14px,
+			font-weight: 400,
+			line-height: 22px,
+			// letter-spacing: 0.03125em
+    ),
+    'caption': (
+      'size': 12px,
+      'weight': 400,
+      'line-height': 20px,
+      // 'letter-spacing': 0.03333em,
+      // 'text-transform': false
+    )
+  ),
+  $uni-headings
+);
+
+
+
+// 主色
+$uni-primary: #2979ff !default;
+$uni-primary-disable:lighten($uni-primary,20%) !default;
+$uni-primary-light: lighten($uni-primary,25%) !default;
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37 !default;
+$uni-success-disable:lighten($uni-success,20%) !default;
+$uni-success-light: lighten($uni-success,25%) !default;
+
+$uni-warning: #f3a73f !default;
+$uni-warning-disable:lighten($uni-warning,20%) !default;
+$uni-warning-light: lighten($uni-warning,25%) !default;
+
+$uni-error: #e43d33 !default;
+$uni-error-disable:lighten($uni-error,20%) !default;
+$uni-error-light: lighten($uni-error,25%) !default;
+
+$uni-info: #8f939c !default;
+$uni-info-disable:lighten($uni-info,20%) !default;
+$uni-info-light: lighten($uni-info,25%) !default;
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a !default; 			// 主要文字
+$uni-base-color: #6a6a6a !default;			// 常规文字
+$uni-secondary-color: #909399 !default;	// 次要文字
+$uni-extra-color: #c7c7c7 !default;			// 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0 !default;
+$uni-border-2: #EDEDED !default;
+$uni-border-3: #DCDCDC !default;
+$uni-border-4: #B9B9B9 !default;
+
+// 常规色
+$uni-black: #000000 !default;
+$uni-white: #ffffff !default;
+$uni-transparent: rgba($color: #000000, $alpha: 0) !default;
+
+// 背景色
+$uni-bg-color: #f7f7f7 !default;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px !default;
+$uni-spacing-base: 15px !default;
+$uni-spacing-lg: 30px !default;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5) !default;
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2) !default;
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5) !default;
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4) !default;

+ 19 - 0
uni_modules/uni-scss/styles/tools/functions.scss

@@ -0,0 +1,19 @@
+// 合并 map
+@function map-deep-merge($parent-map, $child-map){
+	$result: $parent-map;
+	@each $key, $child in $child-map {
+		$parent-has-key: map-has-key($result, $key);
+		$parent-value: map-get($result, $key);
+		$parent-type: type-of($parent-value);
+		$child-type: type-of($child);
+		$parent-is-map: $parent-type == map;
+		$child-is-map: $child-type == map;
+			
+		@if (not $parent-has-key) or ($parent-type != $child-type) or (not ($parent-is-map and $child-is-map)){
+			$result: map-merge($result, ( $key: $child ));
+		}@else {
+			$result: map-merge($result, ( $key: map-deep-merge($parent-value, $child) ));
+		}
+	}
+	@return $result;
+};

+ 31 - 0
uni_modules/uni-scss/theme.scss

@@ -0,0 +1,31 @@
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+// 主色
+$uni-primary: #2979ff;
+// 辅助色
+$uni-success: #4cd964;
+// 警告色
+$uni-warning: #f0ad4e;
+// 错误色
+$uni-error: #dd524d;
+// 描述色
+$uni-info: #909399;
+// 中性色
+$uni-main-color: #303133;
+$uni-base-color: #606266;
+$uni-secondary-color: #909399;
+$uni-extra-color: #C0C4CC;
+// 背景色
+$uni-bg-color: #f5f5f5;
+// 边框颜色
+$uni-border-1: #DCDFE6;
+$uni-border-2: #E4E7ED;
+$uni-border-3: #EBEEF5;
+$uni-border-4: #F2F6FC;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);

+ 62 - 0
uni_modules/uni-scss/variables.scss

@@ -0,0 +1,62 @@
+@import './styles/setting/_variables.scss';
+// 间距基础倍数
+$uni-space-root: 2;
+// 边框半径默认值
+$uni-radius-root:5px;
+
+// 主色
+$uni-primary: #2979ff;
+$uni-primary-disable:mix(#fff,$uni-primary,50%);
+$uni-primary-light: mix(#fff,$uni-primary,80%);
+
+// 辅助色
+// 除了主色外的场景色,需要在不同的场景中使用(例如危险色表示危险的操作)。
+$uni-success: #18bc37;
+$uni-success-disable:mix(#fff,$uni-success,50%);
+$uni-success-light: mix(#fff,$uni-success,80%);
+
+$uni-warning: #f3a73f;
+$uni-warning-disable:mix(#fff,$uni-warning,50%);
+$uni-warning-light: mix(#fff,$uni-warning,80%);
+
+$uni-error: #e43d33;
+$uni-error-disable:mix(#fff,$uni-error,50%);
+$uni-error-light: mix(#fff,$uni-error,80%);
+
+$uni-info: #8f939c;
+$uni-info-disable:mix(#fff,$uni-info,50%);
+$uni-info-light: mix(#fff,$uni-info,80%);
+
+// 中性色
+// 中性色用于文本、背景和边框颜色。通过运用不同的中性色,来表现层次结构。
+$uni-main-color: #3a3a3a; 			// 主要文字
+$uni-base-color: #6a6a6a;			// 常规文字
+$uni-secondary-color: #909399;	// 次要文字
+$uni-extra-color: #c7c7c7;			// 辅助说明
+
+// 边框颜色
+$uni-border-1: #F0F0F0;
+$uni-border-2: #EDEDED;
+$uni-border-3: #DCDCDC;
+$uni-border-4: #B9B9B9;
+
+// 常规色
+$uni-black: #000000;
+$uni-white: #ffffff;
+$uni-transparent: rgba($color: #000000, $alpha: 0);
+
+// 背景色
+$uni-bg-color: #f7f7f7;
+
+/* 水平间距 */
+$uni-spacing-sm: 8px;
+$uni-spacing-base: 15px;
+$uni-spacing-lg: 30px;
+
+// 阴影
+$uni-shadow-sm:0 0 5px rgba($color: #d8d8d8, $alpha: 0.5);
+$uni-shadow-base:0 1px 8px 1px rgba($color: #a5a5a5, $alpha: 0.2);
+$uni-shadow-lg:0px 1px 10px 2px rgba($color: #a5a4a4, $alpha: 0.5);
+
+// 蒙版
+$uni-mask: rgba($color: #000000, $alpha: 0.4);