feat:添加考试模块,曲阳审批添加图片,更新u-upload依赖包

This commit is contained in:
shijing 2024-08-21 11:29:41 +08:00
parent e9263cd087
commit a8703aad86
42 changed files with 2596 additions and 185 deletions

21
LICENSE
View File

@ -1,21 +0,0 @@
MIT License
Copyright (c) 2020 www.uviewui.com
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -121,6 +121,14 @@ const install = (Vue, vm) => {
let tdevice = (data={}) => vm.$u.get(`/third/tdevice/`, data); //设备列表
let eventCateList = (data={}) => vm.$u.get(`/ecm/event_cate/`, data); //算法列表
let algoCreate = (data={}) => vm.$u.post(`/ecm/algo_vchannel/`, data); //算法列表
let getExamList = (data={})=>vm.$u.get('/edu/exam/', data);//考试列表
let startExam = (id)=>vm.$u.post(`/edu/exam/${id}/attend/`);//开始考试
let submitExam = (id,data={})=>vm.$u.post(`/edu/examrecord/${id}/submit/`,data);//提交
let examRecord = (data={})=>vm.$u.get(`/edu/examrecord/`,data);//考试记录
let examRecordDetail = (id,data={})=>vm.$u.get(`/edu/examrecord/${id}/`,data);//考试记录详情
let paperDetail = (id,data={})=>vm.$u.get(`/edu/paper/${id}/`,data);//测试
let questionList = (data={})=>vm.$u.get(`/edu/question/`,data);//题目
vm.$u.api = {
getUserInfo ,
@ -224,7 +232,15 @@ const install = (Vue, vm) => {
tdevice,
eventCateList,
algoCreate
algoCreate,
getExamList,
startExam,
submitExam,
examRecord,
paperDetail,
questionList,
examRecordDetail,
};
}

View File

@ -2,8 +2,8 @@
"name" : "曲阳金隅EHS",
"appid" : "__UNI__B00D419",
"description" : "曲阳金隅EHS",
"versionName" : "2.01.03",
"versionCode" : 200103,
"versionName" : "2.01.11",
"versionCode" : 200104,
"transformPx" : false,
/* 5+App */
"app-plus" : {
@ -128,7 +128,8 @@
"disableHostCheck" : true,
"proxy" : {
"/api" : {
"target" : "http://222.222.144.147:6013/api/",
"target" : "http://49.232.14.174:2226/api/",
// "target" : "http://222.222.144.147:6013/api/",
"changeOrigin" : true,
"secure" : true,
"pathRewrite" : {

View File

@ -1,13 +0,0 @@
{
"id": "uView-UI",
"name": "uView UI已发布Sketch和Axure设计资源",
"version": "1.8.4",
"description": "uView正在研发2.0版本将会全面兼容Nvue并引入大量激动人心的创新功能",
"keywords": [
"uView",
"uViewUI",
"UI",
"UI框架",
"uni-app"
]
}

View File

@ -2,46 +2,24 @@
"easycom": {
"^u-(.*)": "@/uview-ui/components/u-$1/u-$1.vue"
},
// "condition": { //
// "current": 0, //(list )
// "list": [{
// "name": "test", //
// "path": "pages/componentsC/test/index", //
// "query": "uuid=c4bba940-f69e-11ea-a419-6bafda9d095e&__id__=1" //onLoad
// }]
// },
"pages": [{
"path": "pages/login/login_",
"style": {
"navigationBarTitleText": "曲阳金隅EHS-密码登录",
"navigationBarTitleText": "密码登录",
"enablePullDownRefresh": false
}
}, {
"path": "pages/login/userRegister",
"style": {
"navigationBarTitleText": "曲阳金隅EHS-新用户注册",
"navigationBarTitleText": "新用户注册",
"enablePullDownRefresh": false
}
},
// {
// "path" : "pages/login/login",
// "style" :
// {
// "navigationBarTitleText": "验证码登录",
// "enablePullDownRefresh": false
// }
// },
// {
// "path": "pages/login/login_password",
// "style": {
// "navigationBarTitleText": "密码登录",
// "enablePullDownRefresh": false
// }
// },
{
"path": "pages/home/home_",
"style": {
"navigationBarTitleText": "曲阳金隅EHS主页",
"navigationBarTitleText": "主页",
"enablePullDownRefresh": false
}
},
@ -350,7 +328,7 @@
{
"path": "pages/my/my",
"style": {
"navigationBarTitleText": "曲阳金隅EHS-个人中心",
"navigationBarTitleText": "个人中心",
"enablePullDownRefresh": false
}
},
@ -444,6 +422,62 @@
}
}
,{
"path" : "pages/exam/exam",
"style" :
{
"navigationBarTitleText": "考试列表",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/exam/preview",
"style" :
{
"navigationBarTitleText": "考前须知",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},{
"path" : "pages/exam/main",
"style" :
{
"navigationBarTitleText": "考试",
// "navigationStyle": "custom",
"enablePullDownRefresh": false
}
},{
"path" : "pages/exam/record",
"style" :
{
"navigationBarTitleText": "考试记录",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},{
"path" : "pages/exam/result",
"style" :
{
"navigationBarTitleText": "考试结果",
"navigationStyle": "custom",
"enablePullDownRefresh": false
}
},{
"path" : "pages/exam/detail",
"style" :
{
"navigationBarTitleText": "考试详情",
// "navigationStyle": "custom",
"enablePullDownRefresh": false
}
}
,{
"path" : "pages/my/suanfa",
"style" :

341
pages/exam/detail.vue Normal file
View File

@ -0,0 +1,341 @@
<template>
<view class="wrap">
<!-- <uni-nav-bar @clickLeft="goBack()" height="110upx" leftWidth="200upx" leftText="考试记录" leftIcon="left" border
backgroundColor="#2cade8" color="#fff" fixed statusBar shadow></uni-nav-bar> -->
<!-- 小标题栏 -->
<view class="container">
<view class="sub-header">
<u-row>
<u-col span="4">
<view><text style="color:red">{{currentExam.total_score}}</text></view>
</u-col>
<u-col span="4">
<!-- <view style="text-align: center;"><span class="header-card">{{currentQuestion.type}}</span></view> -->
</u-col>
<u-col span="4">
<view style="text-align: right;"><span>{{currentIndex+1}}/{{currentExam.detail.length}} </span></view>
</u-col>
</u-row>
</view>
<!-- <scroll-view class="content" scroll-y="true" v-bind:style="{height:scollHeight+'px'}"> -->
<scroll-view class="content" scroll-y="true">
<view class="name">
<view><text style="margin-right: 10upx;">{{currentIndex+1}} </text> {{currentQuestion.name}}</view>
<view v-if="currentQuestion.img">
{{currentQuestion.img}}
</view>
</view>
<view class="options">
<checkbox-group v-if="currentQuestion.type=='多选'">
<label class="option" v-for="item in currentOptions" :key="item.id" >
<view class="option-item1" >
<checkbox :value="item.value" :checked="item.checked" color="#2979ff" :disabled="item.disabled"/>
</view >
<view class="option-item2" >{{item.value}}.{{item.text}}</view>
</label>
</checkbox-group>
<radio-group v-else>
<label class="option" v-for="item in currentOptions" :key="item.id">
<view class="option-item1">
<radio :value="item.value" :checked="item.checked" color="#2979ff" :disabled="item.disabled"></radio>
</view>
<view class="option-item2">
{{item.value}}.{{item.text}}
</view>
</label>
</radio-group>
</view>
<view class="answer">
<view v-if="currentQuestion.type=='多选'">
<view>正确答案:{{currentQuestion.right.join("")}}</view>
<view v-if="currentQuestion.user_answer">您的答案:{{currentQuestion.user_answer.join("")}}</view>
<view v-else style="color:red">您未作答</view>
</view>
<view v-else>
<view>正确答案:{{currentQuestion.right}}</view>
<view v-if="currentQuestion.user_answer">您的答案:{{currentQuestion.user_answer}}</view>
<view v-else style="color:red">您未作答</view>
</view>
<view v-if="currentQuestion.user_answer">
<view v-if="currentQuestion.is_right" style="color:green;font-weight: bold;">回答正确!</view>
<view v-else style="color:red;font-weight: bold;">回答有误!</view>
</view>
</view>
<view style="height:20upx"></view>
</scroll-view>
<u-popup v-model="showM" mode="bottom" height="40%">
<view class="questionArea" style="display:flex">
<block v-for="(item, index) in currentExam.detail" :key="index">
<view class="questionItem questionItem-select" v-if="item.user_answer&&item.is_right" @click="jumpQuestion(index)">{{index+1}}</view>
<view class="questionItem questionItem-wrong" v-else-if="item.user_answer&&!item.is_right" @click="jumpQuestion(index)">{{index+1}}</view>
<view class="questionItem questionItem-unselect" v-else @click="jumpQuestion(index)">{{index+1}}</view>
</block>
</view>
</u-popup>
<!-- 底部栏 -->
<view class="footer" id="footer">
<u-button @click='previousQ()' throttle-time="200" :plain="true" type="primary">上一题</u-button>
<u-button @click="showM = !showM" type="primary">答题卡</u-button>
<u-button @click='nextQ()' throttle-time="200" :plain="true" type="primary">下一题</u-button>
</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
currentExam:{},
currentIndex:0,
currentOptions:[],
currentQuestion:{question_:{}},
showM:false,
keyid:0,
start_time:null,
scollHeight:0
}
},
onLoad(options) {
this.currentExam = uni.getStorageSync('currentExam');
debugger;
console.log(this.currentExam)
let res = uni.getSystemInfoSync()
let ratio = 750 / res.windowWidth;
this.scollHeight = res.windowHeight*ratio - 230
this.initQuestion()
},
methods: {
initQuestion(){
var currentQuestion = this.currentExam.detail[this.currentIndex]
this.currentQuestion = currentQuestion
let options_ = []
let origin = currentQuestion.options
this.currentOptions = []
for (let key in origin) {
let option = {
value:key,
text:origin[key],
id: this.keyid++,
checked:false,
disabled:true,
}
if (currentQuestion.user_answer) {
if (key == currentQuestion.user_answer || currentQuestion.user_answer.indexOf(key) != -1) {
option.checked = true
}
} else {
option.checked = false
}
options_.push(option)
}
this.currentOptions = options_;
},
nextQ(){
let index = this.currentIndex + 1
if(index<this.currentExam.detail.length){
this.currentIndex = index
this.initQuestion()
}
},
goBack(){
uni.navigateBack(1)
},
previousQ(){
let index = this.currentIndex - 1
if(index >= 0){
this.currentIndex = index
this.initQuestion()
}
},
jumpQuestion(index){
this.currentIndex = index
this.initQuestion()
this.showM = false
}
}
}
</script>
<style lang="scss">
page {
background-color: $u-bg-color;
}
>>>.uni-navbar__header,
>>>.uni-status-bar{
background-image: linear-gradient(270deg,
#0ca7ee 0%,
#005aff 100%,
#2a8cff 100%,
#54bdff 100%),
linear-gradient(#e60012,
#e60012);
}
.content{
margin-top:8upx;
margin-bottom: 120upx;
.name {
font-size:34upx;
padding: 8upx 20upx;
color:$u-content-color;
background-color: #FFFFFF;
}
.options {
margin-top:8upx;
background-color: #FFFFFF;
padding: 6upx 20upx;
.option {
padding: 10upx 0upx;
display: flex;
font-size: 36upx;
.option-item1{
justify-content: flex-start
}
.option-item2{
justify-content: flex-start;
color:$u-main-color;
}
}
}
.answer{
margin-top:8upx;
background-color: #FFFFFF;
padding: 6upx 20upx;
font-size: 32upx;
}
.resolution{
margin-top:8upx;
background-color: #FFFFFF;
padding: 6upx 20upx;
font-size: 32upx;
}
}
.sub-header {
//width: 750upx;
// position: fixed;
// margin-top: 130upx;
padding: 4upx 20upx;
color: #000;
font-size: 33upx;
font-weight: bold;
background-color: #FFFFFF;
}
.header-card {
padding: 6upx 20upx;
// border: 1px solid $u-type-primary-dark;
border-radius: 15upx;
color: #FFFFFF;
background-color: $u-type-primary-dark;
}
.footer {
width: 100%;
height: 100upx;
padding: 30upx 60upx;
position: fixed;
bottom: 10upx;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 32upx;
box-sizing: border-box;
color: #4c8af3;
box-shadow: 0 0 5px 1px #eee;
background-color: #FFFFFF;
&-card {
padding: 10upx 20upx;
border: 1px solid #2a8cff;
border-radius: 15upx;
color: #FFFFFF;
background-color: #2a8cff;
}
}
// .header{
// display: flex;
// height: 70upx;
// background-color: orange;
// font-size: 36upx;
// .content {
// align-self: center;
// .text{
// margin-left:10upx
// }
// }
// .rbutton {
// margin-left: auto;
// align-self: center;
// margin-right: 10upx
// }
// }
.header {
width: 750upx;
//position: fixed;
//position: relative;
text-align: center;
line-height: 60upx;
font-size: 36upx;
font-weight: 600;
color: #2a8cff;
// letter-spacing: 10upx;
background-color: #FFFFFF;
&-button {
width: 80upx;
height: 40upx;
line-height: 40upx;
position: absolute;
top: 4upx;
right: 10upx;
padding: 10upx 20upx;
border-radius: 15upx;
letter-spacing: 2upx;
font-weight: 500;
color: #FFFFFF;
background-color: #fa3534;
}
.scoreText {
color: #00b060;
font-size: 35upx;
}
}
.questionArea {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 20upx;
.questionItem {
width: 80upx;
height: 80upx;
margin: 10upx 22upx;
line-height: 80upx;
font-size: 35upx;
text-align: center;
border-radius: 50%;
color: #ffffff;
}
.questionItem-select {
// color: #FFFFFF;
background-color: #2a8cff;
}
.questionItem-unselect {
// color: #FFFFFF;
background-color: #bbbbbb;
}
.questionItem-wrong {
// color: #FFFFFF;
background-color: red;
}
}
</style>

View File

@ -0,0 +1,8 @@
<template>
</template>
<script>
</script>
<style>
</style>

226
pages/exam/exam.vue Normal file
View File

@ -0,0 +1,226 @@
<template>
<view class="wrap">
<uni-nav-bar @clickLeft="goBack()" height="110upx" leftWidth="200upx" leftText="考试列表" leftIcon="left" border
backgroundColor="#2cade8" color="#fff" fixed statusBar shadow></uni-nav-bar>
<view class="my-top-search-nav">
<!-- 主体 导航栏 -->
<view class="tabbar-title">
<view :class="{'text-title':true, 'active':type==='attend'}" @click="changeList('attend')">可参与</view>
<view :class="{'text-title':true, 'active':type==='my'}" @click="changeList('my')">我的</view>
</view>
</view>
<view class="content" v-if="examList.length>0">
<view class="item-wrap" v-for="(item,index) in examList" :key="item.id">
<view class="duty-item">
<view class="top-info">
<view class="info-title">{{item.name}}-{{item.paper_name}}</view>
</view>
<view class="center-info">
<view class="info-details">试卷总分{{item.paper_total_score}} </view>
<view class="info-details">合格分数{{item.paper_pass_score}} </view>
<view class="info-details">开启时间{{item.open_time}} </view>
<view class="info-details">结束时间{{item.close_time}} </view>
<view class="info-details">考试机会{{item.chance}} </view>
</view>
<view class="bottom-btns" v-if="type === 'attend'">
<u-button v-if="tabIndex==0" class="bottom-btn" type="primary" @click="attendExam(item)">我要参加</u-button>
</view>
</view>
</view>
<view v-if="isBottom" class="bottomText"> 已经到底了</view>
</view>
<view class="content" v-else>
<view style="text-align: center;"> 暂无数据</view>
</view>
</view>
</template>
<script>
export default {
name: 'ticket',
data() {
return {
params: {
can_attend:true,
is_my:true,
page:1
},
tabBars:[
{name:'可参与',
id:'attend'},
{name:'我的',
id:'my'},
],
type:'attend',
examList: [],
tabIndex:0,
isLoading: false,
refreshText: "",
loadingText: '加载中...',
isBottom:false,
}
},
// onLoad(params) {
// setTimeout(()=>{
// this.getExamList('attend');
// },350)
// },
//
onReachBottom() {
if (this.isBottom) {} else {
this.params.page += 1;
this.getexamList(this.type);
}
},
onShow() {
this.examList = [];
this.getExamList();
},
//
onPullDownRefresh() {
this.params.page = 1;
this.examList = [];
this.getExamList();
},
methods: {
getExamList(type) {
let that = this;
if(type=='attend'){
that.params.can_attend = true;
}else{
that.params.can_attend = false;
}
that.isLoading = true;
that.$u.api.getExamList(that.query).then(res=>{
console.log(res)
if(res.results&&res.results.length>0){
that.isBottom = false;
console.log('有数据')
that.examList = that.examList.concat(res.results)
}
}).catch(()=>{
console.log('没有数据')
that.isBottom = true;
})
},
changeList(index) {
// debugger;
this.type = index;
this.examList = [];
this.params.page = 1;
if (index === 'attend') {
this.params.can_attend = true;
} else if (index === 'my') {
this.params.can_attend = false;
}
this.getExamList(index);
},
//
attendExam(val){
console.log('currentExam',val)
uni.setStorageSync('currentExam', val)
uni.navigateTo({
url:"/pages/exam/preview"
})
},
goBack() {
uni.navigateBack({
delta: 1
})
},
searchHandle() {
this.params.page = 1;
this.examList = [];
this.getExamList()
},
resetSearch() {
this.params.page = 1;
this.params.search = "";
this.examList = [];
this.getExamList();
},
}
}
</script>
<style scoped>
.empty-view {
height: 120upx;
}
>>>.uni-navbar__header,
>>>.uni-status-bar{
background-image: linear-gradient(270deg,
#0ca7ee 0%,
#005aff 100%,
#2a8cff 100%,
#54bdff 100%),
linear-gradient(#e60012,
#e60012);
}
page{
height: 100%;
}
.wrap{
height: 100%;
background-color: #f3fbff;
}
.content {
padding: 14upx;
padding-top: 120upx;
}
.item-wrap {
margin-bottom: 14upx;
}
.duty-item {
width: 720upx;
background-color: #ffffff;
border-radius: 10upx;
margin: 0 auto;
padding: 24upx 21upx;
box-sizing: border-box;
}
.info-title {
font-family: PingFang-SC-Medium;
font-size: 30upx;
line-height: 72upx;
color: #3d3d3d;
flex: 1;
border-bottom: 1upx solid #efefef;
margin-bottom: 10upx;
}
.info-details {
font-size: 28upx;
line-height: 50upx;
color: #5b5b5b;
}
.bottom-btns {
text-align: center;
font-family: PingFang-SC-Medium;
font-size: 28upx;
line-height: 83upx;
display: flex;
}
.bottom-btn {
flex: 1;
width: 50%;
margin: 20upx 25vw 0 25vw;
border-right: 1upx solid #eeeeee;
}
.bottomText{
font-size: 20upx;
text-align: center;
height: 50upx;
}
</style>

126
pages/exam/index.vue Normal file
View File

@ -0,0 +1,126 @@
<template>
<view>
<view class="cellWrap">
<view class="cellItem" v-for="item in cellList" :index="item.id" :key="item.id" @click="intoPage(item)">
<view :class="item.class">
<image class="cellImg" :src="item.img"></image>
</view>
<text class="cellText">{{item.title}}</text>
</view>
</view>
<!-- <view class="cellWrap">
<view class="cellItem" @click="intoPage('exam')">
<view class="exam">
<image class="cellImg" src="../../static/exam/exam.png"></image>
</view>
<text class="cellText">正式考试</text>
</view>
<view class="cellItem" @click="intoPage('test')">
<view class="test">
<image class="cellImg" src="../../static/exam/test.png"></image>
</view>
<text class="cellText">考试记录</text>
</view>
</view> -->
</view>
</template>
<script>
export default {
data() {
return {
query:{
page: 1
},
cellList: [
{img:'../../static/exam/exam.png',title:'正式考试',id:'exam',class:'exam'},
{img:'../../static/exam/test.png',title:'考试记录',id:'test',class:'test'},
// {img:'../../static/exam/question.png',title:'',id:'question'},
// {img:'../../static/exam/errorIcon.png',title:'',id:'record'},
]
}
},
methods: {
intoPage(item){
switch (item.id){
case 'exam':
uni.navigateTo({
url:"/pages/exam/exam"
})
break;
case 'test':
uni.navigateTo({
url:"/pages/exam/record"
})
break;
case 'question':
uni.navigateTo({
url:"/pages/exam/question"
})
break;
case 'erroRrecord':
uni.navigateTo({
url:"/pages/exam/erroRrecord"
})
break;
}
}
}
}
</script>
<style>
.cellWrap{
display: flex;
flex-flow: wrap;
margin: auto;
margin-top: 30upx;
margin-bottom: 30upx;
justify-content: space-evenly;
}
.cellItem{
width: 35%;
display: flex;
flex-direction: column;
text-align: center;
margin-top: 50upx;
}
.cellImg{
margin: auto;
width: 120upx;
height: 120upx;
}
.cellText{
height: 60upx;
line-height: 60upx;
text-align: center;
color: #339900;
}
.cellItem:nth-of-type(2) .cellText{
color: #efb336;
}
.cellItem:nth-of-type(3) .cellText{
color: #1296db;
}
.cellItem:nth-of-type(4) .cellText{
color: #d81e06;
}
.exam{
width: 200rpx;
height: 200rpx;
background: #46bb5a;
border-radius: 40rpx;
padding: 36rpx;
margin: auto;
}
.test{
width: 200rpx;
height: 200rpx;
background: #ecc041;
border-radius: 40rpx;
padding: 36rpx;
margin: auto;
}
</style>

393
pages/exam/main.vue Normal file
View File

@ -0,0 +1,393 @@
<template>
<view>
<!-- 大标题 -->
<view class="header" id="header">
<span class="header-button">{{currentIndex+1}}/{{currentExam.questions_.length}} </span>
</view>
<!-- 小标题栏 -->
<view class="sub-header">
<u-row>
<u-col span="4">
<u-count-down :timestamp="currentExam.paper_limit*60" :show-days="false" @end="end" border-color="#2979ff">
</u-count-down>
</u-col>
<u-col span="4">
<!-- <view style="text-align: center;"><span class="header-card">{{currentQuestion.type}}</span></view> -->
</u-col>
<u-col span="4">
<view style="text-align: right;"><span class="submitButton" @click='handleSubmit()' >交卷</span></view>
</u-col>
</u-row>
</view>
<scroll-view class="content" scroll-y="true" v-bind:style="{height:scollHeight+'upx'}">
<view class="name">
<view>{{currentIndex+1}}·{{currentQuestion.name}}</view>
<!-- <rich-text :nodes="currentQuestion.name"></rich-text> -->
<view v-if="currentQuestion.img">
{{currentQuestion.img}}
</view>
</view>
<view class="options">
<checkbox-group @change="checkboxGroupChange" v-if="currentQuestion.type=='多选'">
<label class="option" v-for="item in currentOptions" :key="item.id" >
<view class="option-item1">
<checkbox :value="item.value" :checked="item.checked" color="#2979ff"/>
</view >
<view class="option-item2">{{item.value}}.{{item.text}}</view>
</label>
</checkbox-group>
<radio-group v-else @change="checkboxGroupChange">
<label class="option" v-for="item in currentOptions" :key="item.id">
<view class="option-item1">
<radio :value="item.value" :checked="item.checked" color="#2979ff"></radio>
</view>
<view class="option-item2">
{{item.value}}.{{item.text}}
</view>
</label>
</radio-group>
</view>
<view style="height:20upx"></view>
</scroll-view>
<u-popup v-model="showM" mode="bottom" height="40%">
<view class="questionArea" style="display:flex">
<block v-for="(item, index) in currentExam.questions_" :key="index">
<view class="questionItem questionItem-select" v-if="item.user_answer" @click="jumpQuestion(index)">{{index+1}}</view>
<view class="questionItem questionItem-unselect" v-else @click="jumpQuestion(index)">{{index+1}}</view>
</block>
</view>
</u-popup>
<!-- 底部栏 -->
<view class="footer" id="footer">
<u-button @click='previousQ()' throttle-time="200" :plain="true" type="primary">上一题</u-button>
<u-button @click="showM = !showM" type="primary">答题卡</u-button>
<u-button @click='nextQ()' throttle-time="200" :plain="true" type="primary">下一题</u-button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
currentExam:{questions_:[]},
currentIndex:0,
currentOptions:[],
currentQuestion:{type:'单选'},
showM:false,
keyid:0,
start_time:null,
scollHeight:0
}
},
onLoad() {
uni.setNavigationBarColor({
frontColor: '#ffffff', //
backgroundColor: '#4c8af3', //
animation: { //
duration: 400,
timingFunc: 'easeIn'
},
success: function() {
console.log('颜色设置成功');
},
fail: function(err) {
console.error('颜色设置失败', err);
}
});
//#ifdef MP-WEIXIN
uni.hideHomeButton()
//#endif
this.start_time= (new Date()).getTime()
this.currentExam = uni.getStorageSync('currentExam')
console.log('this.currentExam',this.currentExam)
let res = uni.getSystemInfoSync();
let ratio = 750 / res.windowWidth;
this.scollHeight = res.windowHeight*ratio - 230
this.initQuestion()
},
methods: {
end(){
var that = this
uni.showModal({
title: '警告',
content: '时间到,请交卷',
showCancel:false,
success: function (res) {
if (res.confirm) {
that.handIn();
}
}
});
},
change(){
},
handleSubmit(){
var that = this
let questions = that.currentExam.questions_;
for(var i=0;i<questions.length;i++){
if(!questions[i].user_answer){
uni.showModal({
title: '警告',
content: '答卷未完成,确认交卷吗?',
success: function (res) {
if (res.confirm) {
that.handIn();
}
}
});
return
}
}
uni.showModal({
title: '提示',
content: '确认交卷吗?',
success: function (res) {
if (res.confirm) {
//
that.handIn();
}
}
});
},
handIn(){
var that = this
uni.showLoading({
title:'正在提交...',
mask:true
})
let questions_ = [];
for (let i = 0; i < that.currentExam.questions_.length; i++) {
let obj = {};
obj.id=that.currentExam.questions_[i].id;
obj.user_answer=that.currentExam.questions_[i].user_answer;
questions_.push(obj);
}
that.$u.api.submitExam(that.currentExam.examrecord,{detail:questions_}).then(res=>{
uni.showToast({
title:"提交成功",
icon:"none"
})
this.currentExam.score = res.score;
console.log('this.currentExam',this.currentExam)
uni.setStorageSync('currentExam',this.currentExam)
uni.hideLoading()
uni.reLaunch({
url:'/pages/exam/result'
})
}).catch(e=>{
if(res.msg){
uni.showModal({
title:'提交失败',
content:res.msg,
showCancel:false,
success(res) {
uni.reLaunch({
url:'/pages/exam/exam'
})
}
})
}
})
},
panTi(tm_current) {
// ,
let is_right = false, score = 0
if (tm_current.type == '多选') {
if (tm_current.user_answer) {
if (tm_current.user_answer.sort().toString() == tm_current.right.sort().toString()) {
is_right = true
score = tm_current.total_score
}
}
} else {
if(tm_current.right == tm_current.user_answer){
is_right = true
score = tm_current.total_score
}
}
return {'is_right':is_right,'score':score}
},
initQuestion(){
var currentQuestion = this.currentExam.questions_[this.currentIndex];
this.currentQuestion = currentQuestion;
let options_ = [];
let origin = currentQuestion.options;
this.currentOptions = [];
for (let key in origin) {
let option = {
value:key,
text:origin[key],
id: this.keyid++,
checked:false
}
if (currentQuestion.user_answer) {
if (key == currentQuestion.user_answer || currentQuestion.user_answer.indexOf(key) != -1) {
option.checked = true
}
} else {
option.checked = false
}
options_.push(option)
}
this.currentOptions = options_
},
nextQ(){
let index = this.currentIndex + 1
if(index<this.currentExam.questions_.length){
this.currentIndex = index
this.initQuestion()
}
},
previousQ(){
let index = this.currentIndex - 1
if(index >= 0){
this.currentIndex = index
this.initQuestion()
}
},
checkboxGroupChange(e){
// debugger;
console.log(e)
this.currentExam.questions_[this.currentIndex].user_answer = e.detail.value
},
jumpQuestion(index){
this.currentIndex = index
this.initQuestion()
this.showM = false
}
}
}
</script>
<style lang="scss">
page {
background-color: #f3f4f6;
}
.content{
margin-top:8upx;
.name {
font-size:34upx;
padding: 25upx 30upx;
color:#606266;
line-height:130%;
background-color: #FFFFFF;
}
.options {
margin-top:8upx;
background-color: #FFFFFF;
padding: 6upx 30upx;
.option {
padding: 10upx 0upx;
display: flex;
font-size: 36upx;
.option-item1{
justify-content: flex-start
}
.option-item2{
justify-content: flex-start;
color:#303133;
}
}
}
}
.header {
width: 750upx;
text-align: center;
height: 60upx;
line-height: 60upx;
font-size: 36upx;
font-weight: 600;
color: #4c8af3;
background-color: #FFFFFF;
&-button {
position: absolute;
right: 10upx;
font-size:34upx;
font-weight: bold;
color: #000;
}
.scoreText {
color: #00b060;
font-size: 35upx;
}
}
.sub-header {
padding: 4upx 20upx;
color: #000;
font-size: 33upx;
font-weight: bold;
background-color: #FFFFFF;
}
.submitButton{
padding: 6upx 20upx;
border-radius: 15upx;
font-weight: bold;
color: #ffffff;
background-color: #fa3534;
}
.header-card {
padding: 6upx 20upx;
border-radius: 15upx;
color: #FFFFFF;
background-color: #2b85e4;
}
.footer {
width:100%;
height: 100upx;
padding: 30upx 60upx;
position: fixed;
bottom: 10upx;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 32upx;
box-sizing: border-box;
color: #4c8af3;
box-shadow: 0 0 5px 1px #eee;
background-color: #FFFFFF;
&-card {
padding: 10upx 20upx;
border: 1px solid #4c8af3;
border-radius: 15upx;
color: #FFFFFF;
background-color: #4c8af3;
}
}
.questionArea {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 20upx;
.questionItem {
width: 80upx;
height: 80upx;
margin: 10upx 22upx;
line-height: 80upx;
font-size: 35upx;
text-align: center;
border-radius: 50%;
color: #ffffff;
}
.questionItem-select {
background-color: #4c8af3;
}
.questionItem-unselect {
background-color: #bbbbbb;
}
}
</style>

136
pages/exam/preview.vue Normal file
View File

@ -0,0 +1,136 @@
<template>
<view class="my_duty">
<uni-nav-bar @clickLeft="goBack()" height="110rpx" leftWidth="200rpx" leftText="考前须知" leftIcon="left" border
backgroundColor="#2cade8" color="#fff" fixed statusBar shadow></uni-nav-bar>
<view class='wrap'>
<view class="subTitle">
考试信息
</view>
<view class="examContent">
<view>考试名称<text>{{currentExam.name}}</text> </view>
<view>考试总分<text>{{currentExam.paper_total_score}}</text></view>
<view v-if="currentExam.paper_limit>0">考试时长<text>{{currentExam.paper_limit}}</text>分钟</view>
<view v-else>考试时长<text>不限时长</text></view>
<!-- <view>题目分布单选<text>{{currentExam.paper_.danxuan_count}}</text>;多选<text>{{currentExam.paper_.duoxuan_count}}</text>;判断<text>{{currentExam.paper_.panduan_count}}</text></view> -->
<!-- <view>判分规则单选{{currentExam.paper_.danxuan_score}},多选{{currentExam.paper_.duoxuan_score}},多选{{currentExam.paper_.panduan_score}},错选少选均不得分</view> -->
</view>
<!-- <view class="subTitle">答题须知</view> -->
<view class="tipsArea">
<ul>
<li class="tipsTitle">答题须知</li>
<li>1.进入答题后请不要后退或返回</li>
<li>2.可点击上一题/下一题切换</li>
<li>3.可点击答题卡复查</li>
<li>4.请合理安排时间答题,可提前交卷</li>
</ul>
</view>
<u-button type="primary" @click="start()" class="start">开始答题</u-button>
</view>
</view>
</template>
<script>
export default {
name: 'ticket',
data() {
return {
currentExam:{},
}
},
onShow() {
this.currentExam = uni.getStorageSync('currentExam')
},
methods: {
start(){
this.$u.api.startExam(this.currentExam.id).then(res=>{
console.log('currentExam',res)
let currentExam =uni.getStorageSync('currentExam');
currentExam.examrecord = res.id;
currentExam.questions_ = res.detail;
uni.setStorageSync('currentExam',currentExam)
uni.reLaunch({
url:'/pages/exam/main'
})
})
},
goBack() {
uni.navigateBack({
delta: 1
})
},
}
}
</script>
<style scoped>
.empty-view {
height: 120rpx;
}
>>>.uni-navbar__header,
>>>.uni-status-bar{
background-image: linear-gradient(270deg,
#0ca7ee 0%,
#005aff 100%,
#2a8cff 100%,
#54bdff 100%),
linear-gradient(#e60012,
#e60012);
}
.wrap{
padding: 24rpx;
font-size: 30rpx;
}
.subTitle {
font-size: $u-font-size-title;
font-weight: bold;
// color: $theme-color;
text-align: center;
margin: 40rpx auto 20rpx auto;
}
.examContent {
line-height: 50rpx;
margin-left: 80rpx;
view{
margin-bottom: 6rpx;
}
text {
font-weight: bold;
color:$theme-color;;
}
}
.tipsArea {
padding: 20rpx 40rpx;
margin-left: 0rpx;
margin-bottom: 30rpx;
border: 1px solid #2581e4;
border-radius: 20rpx;
font-size: 28rpx;
margin-top: 50rpx;
.tipsTitle{
font-weight: bold;
color: #2581e4;
}
}
ul{
list-style: none;
padding-left: 0;
}
ul {
margin: 0 30rpx;
line-height: 50rpx;
}
.start{
width: 50%;
font-size: 30rpx;
height: 110rpx;
line-height: 105rpx;
color: #ffffff;
border-color: #2581e4;
background-color: #2581e4;
border-radius: 10rpx;
text-align: center;
margin: auto;
}
</style>

75
pages/exam/question.vue Normal file
View File

@ -0,0 +1,75 @@
<template>
<view>
<view class="cellWrap">
<view class="cellItem" v-for="item in typeList" :key="item" @click="intoPage(item)">
<view class="cellText">{{item}}</view>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
query:{
page: 1,
page_size:999,
type:'单选题'
},
typeList: ['单选','多选','判断']
}
},
methods: {
intoPage(item){
this.query.type=item;
this.$u.api.questionList(this.query).then(res=>{
let currentExam={};
currentExam.questions_ = res.data.results;
uni.setStorageSync('currentExam', currentExam);
uni.navigateTo({
url:"/pages/exam/testDetail"
})
})
}
}
}
</script>
<style>
.cellWrap{
display: flex;
flex-direction: column;
margin: auto;
margin-top: 30upx;
margin-bottom: 30upx;
justify-content: space-evenly;
}
.cellItem{
text-align: center;
margin-top: 50upx;
width: 60%;
margin-left: 20%;
}
.cellText{
height: 60upx;
line-height: 60upx;
text-align: center;
color: #339900;
border: 1px solid #339900;
border-radius: 15rpx;
}
.cellItem:nth-of-type(2) .cellText{
color: #efb336;
border: 1px solid #efb336;
}
.cellItem:nth-of-type(3) .cellText{
color: #1296db;
border: 1px solid #1296db;
}
</style>

210
pages/exam/record.vue Normal file
View File

@ -0,0 +1,210 @@
<template>
<view class="wrap">
<uni-nav-bar @clickLeft="goBack()" height="110upx" leftWidth="200upx" leftText="考试记录" leftIcon="left" border
backgroundColor="#2cade8" color="#fff" fixed statusBar shadow></uni-nav-bar>
<view class="content" v-if="list.length>0">
<view class="item-wrap" v-for="(item,index) in list" :key="index">
<view class="item-container" @click="goDetail(item.id)">
<view class="top-info">
<view class="info-title">{{item.exam_name}}-{{item.paper_name}}</view>
</view>
<view class="center-info">
<view class="info-details">试卷总分{{item.total_score}} </view>
<view class="info-details">合格分数{{item.pass_score}} </view>
<view class="info-details">我的得分{{item.score}} </view>
<view class="info-details">开始时间{{item.start_time}} </view>
<view class="info-details">结束时间{{item.end_time}} </view>
<!-- <view class="info-details">考试时长{{item.took}} </view> -->
</view>
</view>
</view>
<view v-if="isBottom" class="bottomText"> 已经到底了</view>
</view>
<view class="content" v-else>
<view style="text-align: center;"> 暂无数据</view>
</view>
</view>
</template>
<script>
export default {
name: 'ticket',
data() {
return {
params: {
page: 1,
page_size: 20,
is_my:true,
},
list: [],
isLoading: false,
refreshText: "",
loadingText: '加载中...',
isBottom:false,
}
},
//
onReachBottom() {
if (this.isBottom) {} else {
this.params.page = this.params.page +1;
this.getList();
}
},
onShow() {
this.params.page = 1;
this.list = [];
this.getList();
},
//
onPullDownRefresh() {
this.params.page = 1;
this.list = [];
this.getList();
},
methods: {
getList() {
var that = this;
that.$u.api.examRecord(that.params).then(res => {
uni.stopPullDownRefresh()
// uni.setNavigationBarTitle({
// title: res.count + ''
// })
if (that.params.page == 1) {
if (res.results.length == 0) {
that.isBottom = true;
that.loadingText = '暂无考试记录'
} else {
that.loadingText = ''
that.list = res.results
}
} else {
if (res.results.length == 0) {
that.isBottom = true;
}else{
that.loadingText = ''
that.list = that.list.concat(res.results)
}
}
}).catch(res => {
that.isBottom = true;
console.log('没有数据',res)
uni.stopPullDownRefresh()
// if (res.code == 404) {
// that.loadingText = ''
// }
})
},
goDetail(id) {
uni.showLoading({
title:"正在获取考试详情",
})
this.$u.api.examRecordDetail(id).then(res=>{
uni.hideLoading()
console.log('考试详情',res)
uni.setStorageSync('currentExam', res)
if (res.detail&&res.detail.length>0){
uni.navigateTo({
url:'/pages/exam/detail?examrecord='+id
})
}
else{
uni.showModal({
title: '提示',
content: '考试未结束,请考试结束后再查看',
success: function (res) {
}
});
// uni.showToast({
// title:'',
// icon:'none'
// })
return
}
}).catch(e=>{
})
},
goBack() {
uni.navigateBack({
delta: 1
})
},
searchHandle() {
this.params.page = 1;
this.list = [];
this.getList()
},
resetSearch() {
this.params.page = 1;
this.params.search = "";
this.list = [];
this.getList();
},
}
}
</script>
<style scoped>
.wrap{
height: 100%;
background-color: #f3fbff;
}
>>>.uni-navbar__header,
>>>.uni-status-bar{
background-image: linear-gradient(270deg,
#0ca7ee 0%,
#005aff 100%,
#2a8cff 100%,
#54bdff 100%),
linear-gradient(#e60012,
#e60012);
}
.content {
padding: 14upx;
/* padding-top: 120upx; */
}
.item-wrap {
margin-bottom: 14upx;
}
.item-container {
width: 720upx;
background-color: #ffffff;
border-radius: 10upx;
margin: 0 auto;
padding: 21upx 24upx;
box-sizing: border-box;
}
.info-title {
font-weight: bold;
font-family: PingFang-SC-Medium;
font-size: 30upx;
line-height: 72upx;
color: #3d3d3d;
flex: 1;
border-bottom: 1upx solid #efefef;
margin-bottom: 10upx;
}
.info-details {
font-size: 28upx;
line-height: 40upx;
color: #5b5b5b;
}
.shenhezhong {
color: #2c6fd9;
}
.bottomText{
font-size: 20upx;
text-align: center;
height: 50upx;
}
</style>

107
pages/exam/result.vue Normal file
View File

@ -0,0 +1,107 @@
<template>
<view>
<image v-if="currentExam.is_pass" class="examImage" :src="imageSrcPass" mode="aspectFit"></image>
<image v-else class="examImage" :src="imageSrc" mode="aspectFit"></image>
<view v-if="currentExam.is_pass" class="finishText">恭喜您完成考试</view>
<view v-else class="finishText">很遗憾本次考试您未达标</view>
<view class="finishText">
<view><text>{{currentExam.name}}</text></view>
<view>总分<text>{{currentExam.paper_total_score}}</text></view>
<view>得分<text>{{currentExam.score}}</text> </view>
</view>
<view class="btnArea">
<!-- <u-button class="btnClass" type="primary" :ripple="true" shape="circle" @click="goDetail">查看答卷</u-button> -->
<u-button class="btnClass" type="primary" :ripple="true" shape="circle" @click="backToHome">返回首页</u-button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
imageSrcPass: '/static/exam/cross.png',
imageSrc: '/static/exam/error.png',
currentExam:{}
}
},
methods: {
goDetail(){
this.$u.api.examRecordDetail(this.currentExam.id).then(res=>{
uni.hideLoading()
uni.setStorageSync('currentExam', res.data);
debugger;
if (res.data.questions_.length>0){
uni.navigateTo({
url:'/pages/exam/detail?examrecord='+res.data.id
})
}
else{
uni.showToast({
title:'获取失败',
icon:'none'
})
return
}
}).catch(e=>{
})
},
backToHome(){
uni.reLaunch({
url:'/pages/exam/exam'
})
}
},
onLoad(options){
this.currentExam = uni.getStorageSync('currentExam');
},
beforeRouteUpdate(){
uni.removeStorageSync('currentExam');
},
}
</script>
<style lang="scss" scoped>
.examImage {
width: 200rpx;
justify-content: center;
margin-top: 100rpx;
height: 200rpx;
margin: auto;
display: block;
margin-top: 100rpx;
}
.finishText {
// margin: 100rpx 200rpx;
padding: 50rpx;
letter-spacing: 0.2em;
font-size: 32rpx;
display: flex;
flex-direction: column;
align-items: center;
text {
color: #2979ff;
font-weight: bold;
}
}
.btnArea {
display: flex;
margin-top: 50rpx;
justify-content: center;
align-items: center;
.btnClass {
width: 300rpx;
}
}
.infoArea {
display: flex;
flex-direction: column;
justify-content: center;
}
</style>

56
pages/exam/test.vue Normal file
View File

@ -0,0 +1,56 @@
<template>
<view>
<uni-list>
<!-- 垂直排列无略缩图主标题+副标题显示 -->
<uni-list-item direction="column" :key="item.id" v-for="(item, index) in examList">
<template v-slot:header>
<view class="uni-title">{{item.name}}</view>
</template>
<template v-slot:footer>
<view class="uni-footer">
<u-button size="mini" type="primary" @click="attendTest(item)">开始练习</u-button>
</view>
</template>
</uni-list-item>
</uni-list>
</view>
</template>
<script>
export default {
data() {
return {
query:{
page: 1
},
examList: []
}
},
onLoad() {
this.getExamList();
},
methods: {
getExamList(){
this.$u.api.getExamList(this.query).then(res=>{
this.examList = res.data.results
})
},
attendTest(val){
console.log(val)
let currentExam = val;
this.$u.api.paperDetail(val.paper_.id).then(res=>{
currentExam = res.data;
uni.setStorageSync('currentExam', currentExam)
uni.navigateTo({
url:"/pages/exam/testDetail"
})
})
}
}
}
</script>
<style>
</style>

294
pages/exam/testDetail.vue Normal file
View File

@ -0,0 +1,294 @@
<template>
<view>
<!-- 大标题 -->
<view class="header" id="header">
<span class="header-button">{{currentIndex+1}}/{{currentExam.questions_.length}} </span>
</view>
<!-- 小标题栏 -->
<view class="sub-header">
<u-row>
<u-col span="4">
<view style="text-align: center;"><span class="header-card">{{currentQuestion.type}}</span></view>
</u-col>
<u-col span="4">
<view style="text-align: right;"><span class="submitButton" @click='handleSubmit()' >显示答案</span></view>
</u-col>
</u-row>
</view>
<scroll-view class="content" scroll-y="true" v-bind:style="{height:scollHeight+'rpx'}">
<view class="name">
<view>{{currentIndex}}·{{currentQuestion.name}}</view>
<!-- <rich-text :nodes="currentQuestion.name"></rich-text> -->
<view v-if="currentQuestion.img">
{{currentQuestion.img}}
</view>
</view>
<view class="options">
<checkbox-group @change="checkboxGroupChange" v-if="currentQuestion.type=='多选'">
<label class="option" v-for="item in currentOptions" :key="item.id" >
<view class="option-item1">
<checkbox :value="item.value" :checked="item.checked" color="#2979ff"/>
</view >
<view class="option-item2">{{item.value}}.{{item.text}}</view>
</label>
</checkbox-group>
<radio-group v-else @change="checkboxGroupChange">
<label class="option" v-for="item in currentOptions" :key="item.id">
<view class="option-item1">
<radio :value="item.value" :checked="item.checked" color="#2979ff"></radio>
</view>
<view class="option-item2">
{{item.value}}.{{item.text}}
</view>
</label>
</radio-group>
</view>
<view v-if="showAns">正确答案{{currentQuestion.right}}</view>
<view style="height:20rpx"></view>
</scroll-view>
<u-popup v-model="showM" mode="bottom" height="40%">
<view class="questionArea" style="display:flex">
<block v-for="(item, index) in currentExam.questions_" :key="index">
<view class="questionItem questionItem-select" v-if="item.user_answer" @click="jumpQuestion(index)">{{index+1}}</view>
<view class="questionItem questionItem-unselect" v-else @click="jumpQuestion(index)">{{index+1}}</view>
</block>
</view>
</u-popup>
<!-- 底部栏 -->
<view class="footer" id="footer">
<u-button @click='previousQ()' throttle-time="200" :plain="true" type="primary">上一题</u-button>
<u-button @click="showM = !showM" type="primary">答题卡</u-button>
<u-button @click='nextQ()' throttle-time="200" :plain="true" type="primary">下一题</u-button>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
currentExam:{questions_:[]},
currentIndex:0,
currentOptions:[],
currentQuestion:{type:'单选'},
showM:false,
keyid:0,
start_time:null,
scollHeight:0,
showAns:false,
}
},
onLoad() {
//#ifdef MP-WEIXIN
uni.hideHomeButton()
//#endif
let res = uni.getSystemInfoSync();
let ratio = 750 / res.windowWidth;
this.scollHeight = res.windowHeight*ratio - 230;
this.currentExam = uni.getStorageSync('currentExam');
this.initQuestion();
},
methods: {
handleSubmit(){
this.showAns = true;
},
panTi(tm_current) {
// ,
let is_right = false, score = 0
if (tm_current.type == '多选') {
if (tm_current.user_answer) {
if (tm_current.user_answer.sort().toString() == tm_current.right.sort().toString()) {
is_right = true
score = tm_current.total_score
}
}
} else {
if(tm_current.right == tm_current.user_answer){
is_right = true
score = tm_current.total_score
}
}
return {'is_right':is_right,'score':score}
},
initQuestion(){
var currentQuestion = this.currentExam.questions_[this.currentIndex];
this.currentQuestion = currentQuestion;
let options_ = [];
let origin = currentQuestion.options;
this.currentOptions = [];
for (let key in origin) {
let option = {
value:key,
text:origin[key],
id: this.keyid++,
checked:false
}
if (currentQuestion.user_answer) {
if (key == currentQuestion.user_answer || currentQuestion.user_answer.indexOf(key) != -1) {
option.checked = true
}
} else {
option.checked = false
}
options_.push(option)
}
this.currentOptions = options_
},
nextQ(){
this.showAns = false;
let index = this.currentIndex + 1
if(index<this.currentExam.questions_.length){
this.currentIndex = index
this.initQuestion()
}
},
previousQ(){
this.showAns = false;
let index = this.currentIndex - 1;
if(index >= 0){
this.currentIndex = index
this.initQuestion()
}
},
checkboxGroupChange(e){
// debugger;
console.log(e)
this.currentExam.questions_[this.currentIndex].user_answer = e.detail.value
},
jumpQuestion(index){
this.currentIndex = index
this.initQuestion()
this.showM = false
}
}
}
</script>
<style lang="scss">
page {
background-color: $u-bg-color;
}
.content{
margin-top:8rpx;
.name {
font-size:34rpx;
padding: 25rpx 30rpx;
color:$u-content-color;
line-height:130%;
background-color: #FFFFFF;
}
.options {
margin-top:8rpx;
background-color: #FFFFFF;
padding: 6rpx 30rpx;
.option {
padding: 10rpx 0rpx;
display: flex;
font-size: 36rpx;
.option-item1{
justify-content: flex-start
}
.option-item2{
justify-content: flex-start;
color:$u-main-color;
}
}
}
}
.header {
width: 750rpx;
text-align: center;
height: 60rpx;
line-height: 60rpx;
font-size: 36rpx;
font-weight: 600;
color: $theme-color;
background-color: #FFFFFF;
&-button {
position: absolute;
right: 10rpx;
font-size:34rpx;
font-weight: bold;
color: #000;
}
.scoreText {
color: #00b060;
font-size: 35rpx;
}
}
.sub-header {
padding: 4rpx 20rpx;
color: #000;
font-size: 33rpx;
font-weight: bold;
background-color: #FFFFFF;
}
.submitButton{
padding: 6rpx 20rpx;
border-radius: 15rpx;
font-weight: bold;
color: #ffffff;
background-color: $u-type-error;
}
.header-card {
padding: 6rpx 20rpx;
border-radius: 15rpx;
color: #FFFFFF;
background-color: $u-type-primary-dark;
}
.footer {
width: 750rpx;
height: 100rpx;
padding: 30rpx 60rpx;
position: fixed;
bottom: 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 32rpx;
box-sizing: border-box;
color: #4c8af3;
box-shadow: 0 0 5px 1px #eee;
background-color: #FFFFFF;
&-card {
padding: 10rpx 20rpx;
border: 1px solid $theme-color;
border-radius: 15rpx;
color: #FFFFFF;
background-color: $theme-color;
}
}
.questionArea {
display: flex;
flex-direction: row;
flex-wrap: wrap;
margin-bottom: 20rpx;
.questionItem {
width: 80rpx;
height: 80rpx;
margin: 10rpx 22rpx;
line-height: 80rpx;
font-size: 35rpx;
text-align: center;
border-radius: 50%;
color: #ffffff;
}
.questionItem-select {
background-color: $theme-color;
}
.questionItem-unselect {
background-color: #bbbbbb;
}
}
</style>

View File

@ -376,8 +376,24 @@
<view class="form-item" v-if="ticketDetail.state_&&ticketDetail.state_.key==='opl_close'">
<uni-data-select v-model="form.close_dos" :localdata="dosOption" label="关闭处理"></uni-data-select>
</view>
<view class="form-item" v-show="audit_imgs_show" style="margin-bottom: 30rpx;">
<view style="width: 100%;">
<text class="star">*</text>
<text>审批图片</text>
</view>
<u-upload :action="vuex_apifile" :header="header" ref="uUpload" :file-list="fileList"
max-count="9" @on-success="imgUpSuccess" @on-remove="imgRemove"></u-upload>
</view>
<view class="form-item" v-show="work_imgs_show" style="margin-bottom: 30rpx;">
<view style="width: 100%;">
<text class="star">*</text>
<text>开始图片</text>
</view>
<u-upload :action="vuex_apifile" :header="header" ref="uUpload2" :file-list="fileList2"
max-count="9" @on-success="imgUpSuccess2" @on-remove="imgRemove2"></u-upload>
</view>
<view class="form-item" style="height: 300rpx;" v-if="ticketDetail.act_state==1">
<view class="form-left-text">
<view style="width: 100%;">
<text class="star">*</text>
<text>审批意见</text>
</view>
@ -451,8 +467,10 @@
form: {
suggestion: '',
close_note: '',
close_dos: ''
close_dos: '',
},
audit_imgs:[],
work_imgs:[],
ticketId: null,
cateType: null,
operation: null,
@ -461,7 +479,8 @@
detail: false,
isDisabled: false,
btnShow: true,
work_imgs_show:false,
audit_imgs_show:true,
ticketDetail: {
intervene_type: 0
},
@ -573,7 +592,10 @@
text: '其他'
},
],
header:{},
dosOption: [],
fileList:[],
fileList2:[],
}
},
computed: {
@ -594,6 +616,7 @@
that.type = params.type;
},
mounted() {
this.getHeader();
this.$u.api.getTicketLog(this.ticketId).then((res) => {
this.tLog = res;
});
@ -611,6 +634,13 @@
},
methods: {
getHeader() {
this.header = {
Authorization: "Bearer " + this.vuex_token
}
console.log('this.header',this.header)
},
addNodeEnd() {
this.$u.api.addNodeEnd(this.ticketId, {suggestion: this.form.suggestion}).then((res) => {
uni.navigateBack()
@ -651,15 +681,41 @@
//
getOpl() {
let that = this;
this.$u.api.oplItem(this.projectId).then((res) => {
// debugger;
this.oplDetail = res;
that.audit_imgs = [];
that.fileList = [];
if(res.audit_imgs_!==null&&res.audit_imgs_.length>0){
that.audit_imgs = res.audit_imgs;
res.audit_imgs_.forEach(item=>{
that.fileList.push({
url: that.vuex_host+item.path,
id:item.id,
})
})
}
});
},
//
getBtns() {
this.$u.api.getTicketTransitions(this.ticketId).then(res => {
this.operationBtn = res;
let that = this;
that.work_imgs_show = false;
that.audit_imgs_show = false;
this.$u.api.getTicketTransitions(that.ticketId).then(res => {
that.operationBtn = res;
if(res.length>0){
for (let i=0;i<res.length;i++) {
if(res[i].on_submit_func=="apps.opm.services.check_opl_audit_imgs"){
that.audit_imgs_show = true;
}
if(res[i].on_submit_func=="apps.opm.services.check_opl_work_imgs"){
that.work_imgs_show = true;
}
}
}
})
},
onnodeclick(e) {
@ -760,19 +816,36 @@
})
},
operationSubmit(id) {
let that = this;
let params = new Object();
params.transition = id;
params.ticket_data = {};
params.suggestion = this.form.suggestion;
if (this.ticketDetail.state_.name === '作业负责人关闭') {
params.ticket_data.close_note = this.form.close_note;
params.ticket_data.close_dos = this.form.close_dos;
params.suggestion = that.form.suggestion;
if (that.ticketDetail.state_.name === '作业负责人关闭') {
params.ticket_data.close_note = that.form.close_note;
params.ticket_data.close_dos = that.form.close_dos;
}
if(that.audit_imgs_show){
if(that.audit_imgs.length>0){
console.log(that.audit_imgs)
params.ticket_data.audit_imgs = that.audit_imgs;
}else{
uni.showToast({
title: '请上传审批图片',
icon: "none"
})
return;
}
}
if(that.work_imgs.length>0){
params.ticket_data.work_imgs = that.work_imgs;
}
console.log(params);
uni.showLoading({
mask: true,
title: '正在提交...'
})
this.$u.api.ticketHandle(this.ticketId, params).then(res => {
that.$u.api.ticketHandle(that.ticketId, params).then(res => {
uni.hideLoading()
uni.navigateBack()
}).catch(e => {
@ -822,7 +895,23 @@
}
},
imgRemove(index,list,inde){
this.audit_imgs.splice(index,1);
},
imgUpSuccess(data,index,list){
console.log(data,index,list)
uni.showToast({
title:index,
icon: "none",
})
this.audit_imgs.push(data.id);
},
imgRemove2(index,list,inde){
this.work_imgs.splice(index,1);
},
imgUpSuccess2(data,index,list){
this.work_imgs.push(data.id);
},
}
}
</script>
@ -939,7 +1028,7 @@
height: 179rpx;
background-color: #f6f8fc;
border: solid 1rpx #e5e5e5;
margin-top: 21rpx;
margin-top: 0;
padding: 14rpx 24rpx;
font-size: 26rpx;
box-sizing: border-box;

View File

@ -21,7 +21,48 @@
<view class="status">事件提醒</view>
</view>
</view>
<view class="daiban">
<!-- <view class="copy">
<view class="copy01" style="margin-top: 88upx;">
<view class="title">
<view class="left-content">
<view class="img-view">
<image src="../../static/home/daiban.png" mode="" class="img"></image>
</view>
<text class="title-text-left">考试</text>
</view>
<view class="" @click="goIntoTargetPage('exam')">
<text class="title-text-right">查看更多</text>
<uni-icons type="right" :size="11" color="#ababab"></uni-icons>
</view>
</view>
<view class="line"></view>
<view class="listWrap">
<view class="emptyList">可参与{{examCount}} </view>
</view>
</view>
</view>
<view class="copy">
<view class="copy01">
<view class="title">
<view class="left-content">
<view class="img-view">
<image src="../../static/home/daiban.png" mode="" class="img"></image>
</view>
<text class="title-text-left">考试记录</text>
</view>
<view class="" @click="goIntoTargetPage('record')">
<text class="title-text-right">查看更多</text>
<uni-icons type="right" :size="11" color="#ababab"></uni-icons>
</view>
</view>
<view class="line"></view>
<view class="listWrap">
<view class="emptyList">已参加{{recordCount}} </view>
</view>
</view>
</view>
-->
<view class="daiban" style="margin-top: 88upx;">
<view class="daiban01">
<view class="title">
<view class="left-content">
@ -30,13 +71,18 @@
</view>
<text class="title-text-left">待审批</text>
</view>
<view v-if="ticketList.length>0" class="iconUp" @click="daibanChange">
<uni-icons type="top" v-if="daibanShow" :size="22" color="#ababab"></uni-icons>
<uni-icons type="bottom" v-else :size="22" color="#ababab"></uni-icons>
</view>
<view class="iconDown"></view>
<view class="" @click="goIntoTargetPage('duty')">
<text class="title-text-right">查看更多</text>
<uni-icons type="right" :size="11" color="#ababab"></uni-icons>
</view>
</view>
<view class="line"></view>
<view class="listWrap" v-if="ticketList.length>0">
<view class="listWrap" v-if="ticketList.length>0&&daibanShow">
<view v-for="item in ticketList" :key="item.id">
<view class="itemTitle">{{item.title}}</view>
<view class="itemCenter">
@ -71,7 +117,10 @@
</view>
</view>
</view>
<view class="listWrap" v-else>
<view class="listWrap" v-if="ticketList.length>0&&!daibanShow">
<view class="emptyList">展开查看</view>
</view>
<view class="listWrap" v-if="ticketList.length==0">
<view class="emptyList">暂无待办工单</view>
</view>
</view>
@ -85,13 +134,17 @@
</view>
<text class="title-text-left">抄送我</text>
</view>
<view v-if="copyList.length>0" class="iconUp" @click="copyChange">
<uni-icons type="top" v-if="copyShow" :size="22" color="#ababab"></uni-icons>
<uni-icons type="bottom" v-else :size="22" color="#ababab"></uni-icons>
</view>
<view class="" @click="goIntoTargetPage('cc')">
<text class="title-text-right">查看更多</text>
<uni-icons type="right" :size="11" color="#ababab"></uni-icons>
</view>
</view>
<view class="line"></view>
<view class="listWrap" v-if="copyList.length>0">
<view class="listWrap" v-if="copyList.length>0&&copyShow">
<view v-for="item in copyList" :key="item.id">
<view class="itemTitle">{{item.title}}</view>
<view class="itemCenter">
@ -109,7 +162,10 @@
</view>
</view>
</view>
<view class="listWrap" v-else>
<view class="listWrap" v-if="copyList.length>0&&!copyShow">
<view class="emptyList">展开查看</view>
</view>
<view class="listWrap" v-if="copyList.length==0">
<view class="emptyList">暂无待办工单</view>
</view>
</view>
@ -122,13 +178,17 @@
</view>
<text class="title-text-left">最近发生</text>
</view>
<view v-if="eventList.length>0" class="iconUp" @click="tongzhiChange">
<uni-icons type="top" v-if="tongzhiShow" :size="22" color="#ababab"></uni-icons>
<uni-icons type="bottom" v-else :size="22" color="#ababab"></uni-icons>
</view>
<view class="" @click="goIntoTargetPage('warning')">
<text class="title-text-right">查看更多</text>
<uni-icons type="right" :size="11" color="#ababab"></uni-icons>
</view>
</view>
<view class="line"></view>
<view class="listWrap" v-if="eventList.length>0">
<view class="listWrap" v-if="eventList.length>0&&tongzhiShow">
<view v-for="event in eventList" :key="event.id">
<view class="itemTitle" v-if="event.cates_">事件类型:
<text v-for="cate in event.cates_">{{cate.name}}</text>
@ -145,7 +205,10 @@
</view>
</view>
</view>
<view class="listWrap" v-else>
<view class="listWrap" v-if="eventList.length>0&&!tongzhiShow">
<view class="emptyList">展开查看</view>
</view>
<view class="listWrap" v-if="eventList.length==0">
<view class="emptyList">今日暂无事件</view>
</view>
</view>
@ -155,12 +218,6 @@
下载中 请勿退出 {{percentVal}}%
</view>
</view>
<!-- <u-popup :round="10" v-model="dShow" :mode="popupData.mode" border-radius="14" :overlay="popupData.overlay" :closeable="popupData.closeable" :closeOnClickOverlay="popupData.closeOnClickOverlay">
<view style="margin: 30rpx">
下载中 请勿退出 {{percentVal}}%
</view>
</u-popup > -->
</view>
</template>
@ -190,6 +247,8 @@
eventCount: 0,
ticketCount: 0,
copyCount:0,
examCount:0,
recordCount:0,
act_states: {
0: "草稿中",
1: "进行中",
@ -198,7 +257,9 @@
4: "已完成",
5: "已关闭",
},
// 2022218
daibanShow:true,
copyShow:true,
tongzhiShow:true,
mytopimg: require("@/static/home/bgimg-top.jpg"),
}
},
@ -220,11 +281,47 @@
this.getcopy();
this.getEventAgg();
this.getEvent();
this.getExams();
this.getExamRecord();
}
},
methods: {
closeP(){},
getExams(){
let that = this;
that.$u.api.getExamList({
can_attend:true,
is_my:true,
page:1,
page_size:1,
}).then(res=>{
if(res.count){
that.examCount = res.count;
}
})
},
getExamRecord(){
let that = this;
that.$u.api.examRecord({
page:1,
page_size:1,
is_my:true,
}).then(res=>{
if(res.count){
that.recordCount = res.count;
}
})
},
daibanChange(){
this.daibanShow = !this.daibanShow;
},
copyChange(){
this.copyShow = !this.copyShow;
},
tongzhiChange(){
this.tongzhiShow = !this.tongzhiShow;
},
checkVersion() {
let that = this;
uni.getSystemInfo({
@ -351,6 +448,16 @@
})
},
goIntoTargetPage(type) {
if (type == "exam") {
uni.navigateTo({
url: "/pages/exam/exam"
})
}
if (type == "record") {
uni.navigateTo({
url: "/pages/exam/record"
})
}
if(this.limitedVisit==true){
}else{
let params = `?type=${type}`;
@ -460,9 +567,6 @@
background-color: #ffffff;
border-radius: 10rpx;
margin: 0 auto;
margin-top: 88rpx;
}
.copy01{
margin-top: 20upx;
}
.title {

View File

@ -29,17 +29,23 @@
</view>
</view>
<view class="enter-list">
<view class="enter-item" @click="goInto('certificate')">
<image class="left-icon" src="../../static/my/wodeshenqing.png" mode=""></image>
<text class="title-text">我的证书</text>
<uni-icons size="13" color="#b9b9b9" class="right-icon" type="right"></uni-icons>
</view>
<view class="enter-item" @click="goInto('myData')">
<image style="width: 34rpx;height: 30rpx;" class="left-icon" src="../../static/my/wodeshenqing.png"
mode=""></image>
<text class="title-text">我的资料</text>
<uni-icons size="13" color="#b9b9b9" class="right-icon" type="right"></uni-icons>
</view>
<!-- <view class="enter-item" @click="goInto('exam')">
<image style="width: 34rpx;height: 30rpx;" class="left-icon" src="../../static/my/wodeshenqing.png"
mode=""></image>
<text class="title-text">考试记录</text>
<uni-icons size="13" color="#b9b9b9" class="right-icon" type="right"></uni-icons>
</view> -->
<view class="enter-item" @click="goInto('certificate')">
<image class="left-icon" src="../../static/my/wodeshenqing.png" mode=""></image>
<text class="title-text">我的证书</text>
<uni-icons size="13" color="#b9b9b9" class="right-icon" type="right"></uni-icons>
</view>
<view class="enter-item" @click="goInto('clockIn')">
<image style="width: 34rpx;height: 30rpx;" class="left-icon" src="../../static/my/wodeshenqing.png"
mode=""></image>
@ -152,6 +158,11 @@
url: '/pages/my/suanfa'
})
}
else if (type == "exam") {
uni.navigateTo({
url: '/pages/exam/record'
})
}
},
getUserInfo() {
var promise;

View File

@ -75,11 +75,23 @@
</view>
</view>
<view class="item">
<view class="title">现场照片</view>
<view class="title">申请照片</view>
<view class="content">
<u-upload :custom-btn="true" :file-list="create_imgs_list" :show-progress="false" :auto-upload="false" :deletable="false"></u-upload>
</view>
</view>
<view class="item">
<view class="title">审批照片</view>
<view class="content">
<u-upload :custom-btn="true" :file-list="audit_imgs" :show-progress="false" :auto-upload="false" :deletable="false"></u-upload>
</view>
</view>
<view class="item">
<view class="title">开始照片</view>
<view class="content">
<u-upload :custom-btn="true" :file-list="work_imgs" :show-progress="false" :auto-upload="false" :deletable="false"></u-upload>
</view>
</view>
<view class="item">
<view class="title">关闭照片</view>
<view class="content">
@ -120,7 +132,9 @@
</view>
</view>
<view class="wrap-view wrap-top" v-if="formData.cate_code=='space'||formData.cate_code=='fire'||formData.cate_code=='clear'||formData.cate_code=='preheat'">
<view class="item title"> <text class="blueLine"></text>气体检测记录</view>
<view class="item title"> <text class="blueLine"></text>气体检测记录
<text class="bindBtn gasAdd" @click="gas_add">新增</text>
</view>
<view class="checkWrap">
<view v-for="item1 in gasList" :key="item1.id" style="border-bottom: 1upx solid #dddddd;">
<view class="checkItem">
@ -203,7 +217,74 @@
<view class="preBigImgWrap" v-if="preImg" @click="cancelPreImg">
<image class="bigImg" :src="preImgSrc" mode="widthFix"></image>
</view>
<!-- <img-view ref="imgPreView" :imgSrc="preImgSrc" @cancelPreView="cancelPreView"></img-view> -->
<view class="dialogWrap" v-if="limitedDialog">
<view class="dialogCont">
<view class="dialogTitle">
<view>气体检测记录</view>
<view class="dialogCloseImg" @click="gas_add_close"></view>
</view>
<form @submit="gasformSubmit">
<view class="uni-form-item">
<view class="title">检测时间</view>
<uni-datetime-picker v-model="gasForm.check_time" type="datetime" :hide-second="true"/>
</view>
<view class="uni-form-item">
<view class="title">检测部位</view>
<input class="content" type="text" v-model="gasForm.check_place" maxlength="50"
placeholder="请输入" />
</view>
<view class="uni-form-item">
<view class="title">O2(%)</view>
<input class="content" type="text" v-model="gasForm.o2" maxlength="50"
placeholder="请输入" />
</view>
<view class="uni-form-item">
<view class="title">CO</view>
<input class="content" type="text" v-model="gasForm.co" maxlength="50"
placeholder="请输入" />
</view>
<view class="uni-form-item" v-if="formData.cate_code==='fire'">
<view class="title">可燃气体</view>
<input class="content" type="text" v-model="gasForm.lel" maxlength="50"
placeholder="请输入" />
</view>
<view class="uni-form-item" v-if="formData.cate_code==='space'">
<view class="title">h2s</view>
<input class="content" type="text" v-model="gasForm.h2s" maxlength="50"
placeholder="请输入" />
</view>
<view class="uni-form-item" v-if="formData.cate_code==='cooler'">
<view class="title">45</view>
<input class="content" type="text" v-model="gasForm.f5" maxlength="50"
placeholder="请输入" />
</view>
<view class="uni-form-item">
<view class="title">检验结论</view>
<radio-group @change="checkboxMeasuresChange" class="content">
<label style="margin-right: 20rpx;margin-bottom: 20rpx;">
<radio value="true" :checked="gasForm.is_ok" />正常
</label>
<label style="margin-right: 20rpx;margin-bottom: 20rpx;">
<radio value="false" :checked="!gasForm.is_ok" />不正常
</label>
</radio-group>
</view>
<view class="uni-form-item">
<view class="title">检测人</view>
<view class="content" style="position: relative;">
<view @click="showCheckerPicker" style="position: relative;display: flex;">
<text type="text" >{{checker_name}}</text>
<uni-icons style="position: absolute; right: 0;top: 32upx;" type="arrowright" color="#999999"/>
</view>
</view>
</view>
<view class="uni-btn-v">
<button class="mini-btn" type="primary" size="mini" form-type="submit">确定</button>
</view>
</form>
</view>
</view>
</view>
</template>
@ -226,16 +307,27 @@
mtask_uid:null
},
create_imgs_list: [],
audit_imgs: [],
work_imgs:[],
close_imgs_list: [],
msOptions:{
"REVOKED": "已停止",
"STARTED": "进行中",
"SUCCESS": "已完成"
},
gasForm: {
opl: '',
check_time: null,
check_place:'',
is_ok:true,
checker:'',
},
checker_name:'',
preImgSrc:'',
workerItem:{},
preImg:false,
detailLimited:false,
limitedDialog:false,
workerList:[],
gasList:[],
act_states: {
@ -272,10 +364,22 @@
id:item.id,
})
})
res.close_imgs_.forEach(item=>{
res.audit_imgs_.forEach(item2=>{
that.audit_imgs.push({
url: that.vuex_host+item2.path,
id:item2.id,
})
})
res.close_imgs_.forEach(item3=>{
that.close_imgs_list.push({
url: that.vuex_host+item.path,
id:item.id,
url: that.vuex_host+item3.path,
id:item3.id,
})
})
res.work_imgs_.forEach(item4=>{
that.work_imgs.push({
url: that.vuex_host+item4.path,
id:item4.id,
})
})
});
@ -295,6 +399,34 @@
that.gasList =res;
})
},
gas_add(){
console.log('gas_add')
this.limitedDialog = true;
},
gas_add_close() {
this.limitedDialog = false;
},
showCheckerPicker() {
let params='?type=checker&typeName=checker_name'
uni.navigateTo({
url:"../../comm/userSelect/index"+params
})
},
timeChange(e){
this.gasForm.check_time = e.detail.value;
},
gasformSubmit(val) {
let that = this;
that.gasForm.opl = that.oplId;
that.gasForm.checker = that.formData.checker;
that.$u.api.oplGasCreate(that.gasForm).then(res => {
if (res.err_msg) {} else {
that.getgasList();
that.limitedDialog = false;
}
})
},
mtaskStateChange(type){
let that = this;
uni.showLoading({
@ -473,6 +605,7 @@
.wrap-top{
line-height: 60upx;
margin-top: 20upx;
position: relative;
}
.item {
margin: 0rpx 32rpx;
@ -633,4 +766,79 @@
left: 50%;
transform: translate(-50% ,-50%);
}
.gasAdd{
position: absolute;
right: 15rpx;
top: 26rpx;
}
.dialogWrap {
position: fixed;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, .3);
top: 0;
left: 0;
z-index: 110;
}
.dialogCont {
width: 92vw;
position: absolute;
top: 50%;
margin: auto;
background-color: #ffffff;
left: 4vw;
transform: translateY(-50%);
padding: 20rpx;
border-radius: 20rpx;
}
.dialogTitle {
font-size: 36rpx;
padding-bottom: 20rpx;
border-bottom: 1upx solid #eeeeee;
display: flex;
justify-content: space-between;
}
.uni-form-item {
padding: 10px 0;
display: flex;
border-bottom: 1upx solid #eeeeee;
}
.uni-form-item>.title,
>>>uni-input,
>>>.uni-input,
>>>.uni-input-wrapper,
>>>.input-placeholder {
height: 80upx;
line-height: 80upx;
font-size: 32upx;
width: 160upx;
}
>>>uni-input,
>>>.uni-input,
>>>.uni-input-wrapper,
>>>.input-placeholder {
width: 100%;
}
.content {
flex: 1;
}
.uni-btn-v {
text-align: center;
}
.dialogCloseImg {
width: 52rpx;
height: 52rpx;
background-image: url('../../../static/my/my_apply/zuofei.png');
background-repeat: no-repeat;
background-size: cover;
}
</style>

BIN
static/exam/cross.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

BIN
static/exam/error.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

BIN
static/home/fafang.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

BIN
static/home/kaoqin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -39,14 +39,11 @@ const store = new Vuex.Store({
vuex_login: 'http://qyjy.ctc-zc.com/h5/',
vuex_version: '1.00.08',
vuex_host: 'http://222.222.144.147:6013',
// vuex_host: 'http://49.232.14.174:2226',
vuex_api: 'http://222.222.144.147:6013/api',
// vuex_api: 'http://49.232.14.174:2226/api',
vuex_apifile: 'http://222.222.144.147:6013/api/file/',
// vuex_api: 'http://127.0.0.1:8000/api',
// vuex_host: 'http://10.99.5.79:20309',
// vuex_api: 'http://10.99.5.79:20309/api',
// vuex_apifile: 'http://10.99.5.79:20309/api/file/',
// vuex_host: 'http://49.232.14.174:2226',
// vuex_api: 'http://49.232.14.174:2226/api',
// vuex_apifile: 'http://49.232.14.174:2226/api/file/',
},
mutations: {
$uStore(state, payload) {

View File

@ -5,3 +5,13 @@
*/
@import 'uview-ui/theme.scss';
>>>.uni-navbar__header,
>>>.uni-status-bar{
background-image: linear-gradient(270deg,
#0ca7ee 0%,
#005aff 100%,
#2a8cff 100%,
#54bdff 100%),
linear-gradient(#e60012,
#e60012);
}

View File

@ -288,6 +288,10 @@
},
init() {
let now = new Date();
let minDate = new Date(this.minDate);
let maxDate = new Date(this.maxDate);
if (now < minDate) now = minDate;
if (now > maxDate) now = maxDate;
this.year = now.getFullYear();
this.month = now.getMonth() + 1;
this.day = now.getDate();
@ -636,4 +640,4 @@
}
}
}
</style>
</style>

View File

@ -110,7 +110,8 @@
this.parent = this.$u.$parent.call(this, 'u-collapse');
if(this.parent) {
this.nameSync = this.name ? this.name : this.parent.childrens.length;
this.parent.childrens.push(this);
//
!this.parent.childrens.includes(this) && this.parent.childrens.push(this);
this.headStyle = this.parent.headStyle;
this.bodyStyle = this.parent.bodyStyle;
this.arrowColor = this.parent.arrowColor;

View File

@ -172,6 +172,7 @@ export default {
this.loading = false;
} else {
this.isError = false;
this.loading = true;
}
}
}

View File

@ -50,6 +50,7 @@
:selection-end="uSelectionEnd"
:selection-start="uSelectionStart"
:show-confirm-bar="showConfirmbar"
:adjust-position="adjustPosition"
@focus="onFocus"
@blur="handleBlur"
@input="handleInput"
@ -213,6 +214,11 @@ export default {
showConfirmbar:{
type:Boolean,
default:true
},
// uni-apptrue
adjustPosition: {
type: Boolean,
default: true
}
},
data() {
@ -300,11 +306,12 @@ export default {
handleBlur(event) {
// 使@touchstarthx2.8.4
// @blur
let value = event.detail.value;
setTimeout(() => {
this.focused = false;
}, 100)
// vue return
this.$emit('blur', event.detail.value);
this.$emit('blur', value);
setTimeout(() => {
// bug()@input
// #ifdef MP-TOUTIAO
@ -312,7 +319,7 @@ export default {
this.lastValue = value;
// #endif
// u-form-item
this.dispatch('u-form-item', 'on-form-blur', event.detail.value);
this.dispatch('u-form-item', 'on-form-blur', value);
}, 40)
},
onFormItemError(status) {

View File

@ -10,7 +10,7 @@
</view>
<input :disabled="disabledInput || disabled" :cursor-spacing="getCursorSpacing" :class="{ 'u-input-disabled': disabled }"
v-model="inputVal" class="u-number-input" @blur="onBlur" @focus="onFocus"
type="number" :style="{
type="digit" :style="{
color: color,
fontSize: size + 'rpx',
background: bgColor,

View File

@ -36,7 +36,7 @@
</view>
</view>
<view class="u-select__body">
<picker-view @change="columnChange" class="u-select__body__picker-view" :value="defaultSelector" @pickstart="pickstart" @pickend="pickend">
<picker-view @change="columnChange" class="u-select__body__picker-view" :value="defaultSelector" @pickstart="pickstart" @pickend="pickend" v-if="value">
<picker-view-column v-for="(item, index) in columnData" :key="index">
<view class="u-select__body__picker-view__item" v-for="(item1, index1) in item" :key="index1">
<view class="u-line-1">{{ item1[labelName] }}</view>
@ -278,12 +278,13 @@ export default {
let columnIndex = e.detail.value;
// push
this.selectValue = [];
this.defaultSelector = columnIndex;
if(this.mode == 'mutil-column-auto') {
//
this.lastSelectIndex.map((val, idx) => {
if (val != columnIndex[idx]) index = idx;
});
this.defaultSelector = columnIndex;
for (let i = index + 1; i < this.columnNum; i++) {
// children
//
@ -333,6 +334,8 @@ export default {
},
close() {
this.$emit('input', false);
// default-value
this.$set(this, 'defaultSelector', [0]);
},
//
getResult(event = null) {

View File

@ -3,9 +3,9 @@
background: bgColor
}">
<!-- $u.getRect()对组件根节点无效因为写了.in(this)故这里获取内层接点尺寸 -->
<view :id="id">
<view>
<scroll-view scroll-x class="u-scroll-view" :scroll-left="scrollLeft" scroll-with-animation>
<view class="u-scroll-box" :class="{'u-tabs-scorll-flex': !isScroll}">
<view class="u-scroll-box" :id="id" :class="{'u-tabs-scorll-flex': !isScroll}">
<view class="u-tab-item u-line-1" :id="'u-tab-item-' + index" v-for="(item, index) in list" :key="index" @tap="clickTab(index)"
:style="[tabItemStyle(index)]">
<u-badge :count="item[count] || item['count'] || 0" :offset="offset" size="mini"></u-badge>

View File

@ -39,7 +39,7 @@
style.padding = this.parent.padding;
style.borderBottom = `solid 1px ${this.parent.borderColor}`;
style.borderRight = `solid 1px ${this.parent.borderColor}`;
Object.assign(style, this.parent.style);
Object.assign(style, this.parent.thStyle);
this.thStyle = style;
}
}

View File

@ -21,7 +21,7 @@
<u-icon class="u-icon" :name="delIcon" size="20" :color="delColor"></u-icon>
</view>
<u-line-progress
v-if="showProgress && item.progress > 0 && !item.error"
v-if="showProgress && item.progress > 0 && item.progress != 100 && !item.error"
:show-percent="false"
height="16"
class="u-progress"
@ -265,11 +265,6 @@ export default {
uploading: false
};
},
onShow() {
debugger;
console.log(this.fileList);
this.lists = this.fileList;
},
watch: {
fileList: {
immediate: true,
@ -278,16 +273,11 @@ export default {
// fileList()fileList
// watchthis.lists
// sometrueeverytrue
if(value.url){
let tmp = this.lists.some(val => {
return val.url == value.url;
})
// (tmpfalse)
!tmp && this.lists.push({ url: value.url, error: false, progress: 100,id:value.id});
}else{
this.lists.push({ url: value, error: false, progress: 100});
}
let tmp = this.lists.some(val => {
return val.url == value.url;
})
// (tmpfalse)
!tmp && this.lists.push({ url: value.url, error: false, progress: 100 });
});
}
},
@ -431,7 +421,11 @@ export default {
name: this.name,
formData: this.formData,
header: this.header,
// #ifdef MP-ALIPAY
fileType:'image',
// #endif
success: res => {
console.log(res)
// jsonjson
let data = this.toJson && this.$u.test.jsonString(res.data) ? JSON.parse(res.data) : res.data;
if (![200, 201, 204].includes(res.statusCode)) {
@ -441,6 +435,7 @@ export default {
this.lists[index].response = data;
this.lists[index].progress = 100;
this.lists[index].error = false;
console.log(this.lists)
this.$emit('on-success', data, index, this.lists, this.index);
}
},
@ -508,7 +503,7 @@ export default {
//
handlerDeleteItem(index) {
// 0 < progress < 100
if (this.lists[index].process < 100 && this.lists[index].process > 0) {
if (this.lists[index].progress < 100 && this.lists[index].progress > 0) {
typeof this.lists[index].uploadTask != 'undefined' && this.lists[index].uploadTask.abort();
}
this.lists.splice(index, 1);

View File

@ -1,5 +1,5 @@
// 此版本发布于2020-03-17
let version = '1.8.4';
// 此版本发布于2022-04-19
let version = '1.8.6';
export default {
v: version,
@ -12,4 +12,4 @@ export default {
'error',
'warning'
]
}
}

View File

@ -6,7 +6,7 @@
* v-for的时候,推荐使用后端返回的id而不是循环的index
* @param {Number} len uuid的长度
* @param {Boolean} firstU 将返回的首字母置为"u"
* @param {Nubmer} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制
* @param {Number} radix 生成uuid的基数(意味着返回的字符串都是这个基数),2-二进制,8-八进制,10-十进制,16-十六进制
*/
function guid(len = 32, firstU = true, radix = null) {
let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
@ -29,7 +29,7 @@ function guid(len = 32, firstU = true, radix = null) {
}
}
}
// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guuid不能用作id或者class
// 移除第一个字符,并用u替代,因为第一个字符为数值时,该guid不能用作id或者class
if (firstU) {
uuid.shift();
return 'u' + uuid.join('');

View File

@ -2,7 +2,7 @@
* 验证电子邮箱格式
*/
function email(value) {
return /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/.test(value);
return /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/.test(value);
}
/**
@ -37,7 +37,7 @@ function dateISO(value) {
* 验证十进制数字
*/
function number(value) {
return /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value)
return /^[\+-]?(\d+\.?\d*|\.\d+|\d\.\d+e\+\d+)$/.test(value)
}
/**

View File

@ -48,7 +48,7 @@ module.exports = {
uni.$emit('uOnReachBottom')
},
beforeDestroy() {
// 判断当前页面是否存在parent和chldren一般在checkbox和checkbox-group父子联动的场景会有此情况
// 判断当前页面是否存在parent和children一般在checkbox和checkbox-group父子联动的场景会有此情况
// 组件销毁时移除子组件在父组件children数组中的实例释放资源避免数据混乱
if(this.parent && uni.$u.test.array(this.parent.children)) {
// 组件销毁时移除父组件中的children数组中对应的实例

View File

@ -437,7 +437,7 @@ function range(rule, value, source, errors, options) {
}
if (str) {
// 处理码点大于U+010000的文字length属性不准确的bug如"𠮷𠮷𠮷".lenght !== 3
// 处理码点大于U+010000的文字length属性不准确的bug如"𠮷𠮷𠮷".length !== 3
val = value.replace(spRegexp, '_').length;
}

View File

@ -1,39 +1,31 @@
{
"name": "uview-ui",
"version": "1.8.4",
"description": "uView UI是uni-app生态优秀的UI框架全面的组件和便捷的工具会让您信手拈来如鱼得水",
"main": "index.js",
"keywords": [
"uview",
"uView",
"uni-app",
"uni-app ui",
"uniapp",
"uviewui",
"uview ui",
"uviewUI",
"uViewui",
"uViewUI",
"uView UI",
"uni ui",
"uni UI",
"uniapp ui",
"ui",
"UI框架",
"uniapp ui框架",
"uniapp UI"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": ""
},
"devDependencies": {
"node-sass": "^4.14.0",
"sass-loader": "^8.0.2"
},
"author": "uView",
"license": "MIT"
}
"name": "uView",
"version": "1.8.6",
"description": "uView UI是uni-app生态优秀的UI框架全面的组件和便捷的工具会让您信手拈来如鱼得水",
"main": "index.js",
"keywords": [
"uview",
"ui",
"uni-app"
],
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": ""
},
"devDependencies": {
"node-sass": "^4.14.0",
"sass-loader": "^8.0.2"
},
"author": "uView",
"license": "MIT",
"id": "uview-v1",
"dcloudext": {
"category": [
"前端组件",
"通用组件"
]
}
}