222
|
|
@ -0,0 +1,26 @@
|
||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
package-lock.json
|
||||||
|
uni_modules
|
||||||
|
unpackage
|
||||||
|
/dist
|
||||||
|
|
||||||
|
|
||||||
|
# local env files
|
||||||
|
.env.local
|
||||||
|
.env.*.local
|
||||||
|
|
||||||
|
# Log files
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{ // launch.json 配置了启动调试时相关设置,configurations下节点名称可为 app-plus/h5/mp-weixin/mp-baidu/mp-alipay/mp-qq/mp-toutiao/mp-360/
|
||||||
|
// launchtype项可配置值为local或remote, local代表前端连本地云函数,remote代表前端连云端云函数
|
||||||
|
"version": "0.0",
|
||||||
|
"configurations": [{
|
||||||
|
"default" :
|
||||||
|
{
|
||||||
|
"launchtype" : "local"
|
||||||
|
},
|
||||||
|
"mp-weixin" :
|
||||||
|
{
|
||||||
|
"launchtype" : "local"
|
||||||
|
},
|
||||||
|
"type" : "uniCloud"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onShow,
|
||||||
|
onHide,
|
||||||
|
onLaunch
|
||||||
|
} from "@dcloudio/uni-app";
|
||||||
|
|
||||||
|
onLaunch(() => {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
@import '@/static/style/public.scss';
|
||||||
|
page{
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
奉节教育直播录播项目
|
||||||
|
第一步 命令运行
|
||||||
|
|
||||||
|
npm i
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
第二步
|
||||||
|
|
||||||
|
安装 sass
|
||||||
|
npm install node-sass
|
||||||
|
npm install sass --save-dev
|
||||||
|
|
||||||
|
// UI uni-ui
|
||||||
|
https://ext.dcloud.net.cn/plugin?id=55
|
||||||
|
[uni-ui地址](https://uniapp.dcloud.io/component/uniui/uni-drawer.html)
|
||||||
|
|
@ -0,0 +1,56 @@
|
||||||
|
import { Request } from '@/utils/request'
|
||||||
|
|
||||||
|
// 切换学生
|
||||||
|
export function getChangeStudent (param:any) {
|
||||||
|
return Request({
|
||||||
|
url:'/api/user/Account/switchstudent',
|
||||||
|
method:'GET',
|
||||||
|
data:param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 获取绑定的学生列表
|
||||||
|
export function getBindStudentList () {
|
||||||
|
return Request({
|
||||||
|
url:'/api/user/Student/bindstudentlist',
|
||||||
|
method:'GET'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 报告列表
|
||||||
|
export function getUserReportList (param:any) {
|
||||||
|
return Request({
|
||||||
|
url:'/api/user/Home/examrecord',
|
||||||
|
method:'GET',
|
||||||
|
data:param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 报告详情页
|
||||||
|
export function getUserReportDetails (param:any) {
|
||||||
|
return Request({
|
||||||
|
url:'/api/user/Home/userexamrecord',
|
||||||
|
method:'GET',
|
||||||
|
data:param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 测评报告
|
||||||
|
export function getTestReportData (param:any) {
|
||||||
|
return Request({
|
||||||
|
url:'/api/user/Home/report',
|
||||||
|
method:'GET',
|
||||||
|
data:param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 获取评测客服信息
|
||||||
|
export function getTestInfo () {
|
||||||
|
return Request({
|
||||||
|
url:'/api/user/Student/getstudyreportinfo',
|
||||||
|
method:'GET'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 查看答卷
|
||||||
|
export function getTestImgs (param:any) {
|
||||||
|
return Request({
|
||||||
|
url:'/api/user/Home/pagerImgs',
|
||||||
|
method:'GET',
|
||||||
|
data:param
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
import { Request } from '@/utils/request'
|
||||||
|
import { number } from 'echarts/lib/export'
|
||||||
|
|
||||||
|
// 用户登录
|
||||||
|
export const getUserLogin =async (param:any) => {
|
||||||
|
return await Request({
|
||||||
|
url: `/api/user/Account/login?code=${param}`,
|
||||||
|
method: "POST"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//注册
|
||||||
|
|
||||||
|
// 用户登录信息
|
||||||
|
export const getUserInfo = () => {
|
||||||
|
return Request({
|
||||||
|
url: '/api/user/Account',
|
||||||
|
method: "GET"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 切换学生
|
||||||
|
export const getChangeUserList = (param:any) => {
|
||||||
|
return Request({
|
||||||
|
url: `/api/user/Account/switchstudent?studentId=${param}`,
|
||||||
|
method: "GET"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//查询未绑定学生
|
||||||
|
export const getUnbindstudentinfo = (param:string) => {
|
||||||
|
return Request({
|
||||||
|
url: `/api/user/Student/unbindstudentinfo?telephone=${param}`,
|
||||||
|
method: "GET"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//获取绑定学生刘表
|
||||||
|
export const getbindstudentList = () => {
|
||||||
|
return Request({
|
||||||
|
url: `/api/user/Student/bindstudentlist`,
|
||||||
|
method: "GET"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//绑定学生 【511】跳电话尾号验证 【512】跳电话验证码验证
|
||||||
|
export const getSendbindstudent = (params) => {
|
||||||
|
return Request({
|
||||||
|
url: `/api/user/Student/bindstudent?StudentTelephone=${params.StudentTelephone}&VerifyName=${params.VerifyName}&VerifyLastTelephone=${params.VerifyLastTelephone}&VerifySMSId=${params.VerifySMSId}&VerifyCode=${params.VerifyCode}`,
|
||||||
|
method: "GET"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//发送电话验证码
|
||||||
|
export const getSendTelphoneCode = (telephone,type) => {
|
||||||
|
return Request({
|
||||||
|
url: `/api/user/Account/sms?mobile=${telephone}&smsType=${type}`,
|
||||||
|
method: "GET"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//动态令牌换取用户手机号
|
||||||
|
export const getUserPhone = (param:string) => {
|
||||||
|
return Request({
|
||||||
|
url: `/api/user/Account/getXcxMobileFlag?code=${param}`,
|
||||||
|
method: "POST"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取配置信息
|
||||||
|
export const getConfig = () => {
|
||||||
|
return Request({
|
||||||
|
url: `/api/user/Account/config`,
|
||||||
|
method: "GET"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//登录失败,注册绑定
|
||||||
|
export const postRegister = (data) => {
|
||||||
|
return Request({
|
||||||
|
url: `/api/user/Account/register`,
|
||||||
|
method: "POST",
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//接触绑定账号
|
||||||
|
export const putUnBind = (data) => {
|
||||||
|
return Request({
|
||||||
|
url: `/api/user/Student/ubind`,
|
||||||
|
method: "PUT",
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取测评客服信息
|
||||||
|
export const getSTudyReportInfo = () => {
|
||||||
|
return Request({
|
||||||
|
url: `/api/user/Student/getstudyreportinfo`,
|
||||||
|
method: "GET"
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//获取查看学生信息
|
||||||
|
export const LookStudentInfo = (data)=>{
|
||||||
|
return Request({
|
||||||
|
url:`/api/user/Account/student?studentId=${data}`,
|
||||||
|
method:'GET'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//绑定家长手机号码
|
||||||
|
export const bindMobile = (data:string)=>{
|
||||||
|
return Request({
|
||||||
|
url:`/api/user/Account/bindMobile?code=${data}`,
|
||||||
|
method:'POST'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,214 @@
|
||||||
|
<!-- 当前学生组件 -->
|
||||||
|
<template>
|
||||||
|
<view class="ech-card" :class="{'purple':props.bgIndex % 3 === 0,'green':(props.bgIndex-1) % 3 === 0,'blue':(props.bgIndex-2) % 3 === 0}">
|
||||||
|
<view class="change-stu">
|
||||||
|
<view class="person-tag" :style="{color:(props.bgIndex % 3 === 0?'#6B86FF':(props.bgIndex-1) % 3 === 0?'#45CB9F':(props.bgIndex-2) % 3 === 0?'#22C1F2':'')}">
|
||||||
|
执器于身,共建未来
|
||||||
|
</view>
|
||||||
|
<view class="change" v-if="props.isChange&&listLength!==1" @click="changeStudent">
|
||||||
|
<view class="change-icon"></view>
|
||||||
|
<view class="change-text">切换学生</view>
|
||||||
|
</view>
|
||||||
|
<view class="person-contain">
|
||||||
|
<view class="stu-img">
|
||||||
|
<image src="https://minio.23544.com:9010/data-center/gzh/Avatar.png" mode="学生头像"></image>
|
||||||
|
</view>
|
||||||
|
<view class="person-info">
|
||||||
|
<view class="school">
|
||||||
|
<view class="house-icon"></view>
|
||||||
|
<view class="school-name">{{props.datas.SchoolName}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="person-ma">
|
||||||
|
<text>{{props.datas.RealName}}</text> | {{props.datas.Grade+props.datas.ClassName}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="person-btn" v-if="!props.isChange">
|
||||||
|
<view class="look" @click="openStuInfo()">查看</view>
|
||||||
|
<view class="un-bind" @click="unBind()">解绑</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { defineProps } from 'vue'
|
||||||
|
const props = defineProps({
|
||||||
|
isChange: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
datas: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
bgIndex: {
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
listLength: {
|
||||||
|
type: Number,
|
||||||
|
// required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
const emit = defineEmits(['changeStu','onOpenStu','onUnBind'])
|
||||||
|
// 点击切换
|
||||||
|
const changeStudent=()=>{
|
||||||
|
emit('changeStu')
|
||||||
|
}
|
||||||
|
// 点击查看
|
||||||
|
const openStuInfo=()=>{
|
||||||
|
emit('onOpenStu')
|
||||||
|
}
|
||||||
|
// 点击解绑
|
||||||
|
const unBind=()=>{
|
||||||
|
emit('onUnBind')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.ech-card {
|
||||||
|
width: 343px;
|
||||||
|
height: 121px;
|
||||||
|
position: relative;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%);
|
||||||
|
margin-bottom: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.purple{
|
||||||
|
background: url('@/static/education/purple-bg.png') no-repeat !important;
|
||||||
|
background-size: 100% 100% !important;
|
||||||
|
.look{
|
||||||
|
color: #6B86FF !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.green{
|
||||||
|
background: url('@/static/education/green-bg.png') no-repeat !important;
|
||||||
|
background-size: 100% 100% !important;
|
||||||
|
.look{
|
||||||
|
color: #45CB9F !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.blue{
|
||||||
|
background: url('@/static/education/blue-bg.png') no-repeat !important;
|
||||||
|
background-size: 100% 100% !important;
|
||||||
|
.look{
|
||||||
|
color: #22C1F2 !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.person-tag{
|
||||||
|
position: absolute;
|
||||||
|
left: 38rpx;
|
||||||
|
top: 10rpx;
|
||||||
|
font-size: 20rpx;
|
||||||
|
letter-spacing: 22rpx;
|
||||||
|
}
|
||||||
|
.change-stu{
|
||||||
|
.change {
|
||||||
|
position: absolute;
|
||||||
|
right: 20px;
|
||||||
|
top: 5px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
color: #999;
|
||||||
|
font-size: 11px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: normal;
|
||||||
|
.change-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background: url('@/static/education/change.png');
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.person-contain {
|
||||||
|
position: absolute;
|
||||||
|
left: 5px;
|
||||||
|
bottom: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 95%;
|
||||||
|
.stu-img {
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
image{
|
||||||
|
width: 68px;
|
||||||
|
height: 68px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.person-info {
|
||||||
|
width: 52%;
|
||||||
|
.school {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.house-icon {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
background: url('@/static/education/house.png');
|
||||||
|
background-size: 100% 100%;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
.school-name {
|
||||||
|
height: 20px;
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 15px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 20px;
|
||||||
|
letter-spacing: 0.84px;
|
||||||
|
}
|
||||||
|
.person-ma {
|
||||||
|
margin-top: 8px;
|
||||||
|
height: 20px;
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 13px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 20px;
|
||||||
|
letter-spacing: 0.72px;
|
||||||
|
text{
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.person-btn{
|
||||||
|
margin:10px 0 0 20px;
|
||||||
|
.look {
|
||||||
|
width: 55px;
|
||||||
|
height: 22px;
|
||||||
|
border-radius: 21px;
|
||||||
|
background: #FFF;
|
||||||
|
box-shadow: 0px 1px 5px 0px rgba(182, 187, 214, 0.66);
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
letter-spacing: 0.6px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.un-bind{
|
||||||
|
margin-top: 8px;
|
||||||
|
width: 55px;
|
||||||
|
height: 22px;
|
||||||
|
border-radius: 21px;
|
||||||
|
background: rgba(0,0,0,0);
|
||||||
|
border: 1px solid #fff;
|
||||||
|
box-shadow: 0px 1px 5px 0px rgba(182, 187, 214, 0.66);
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
line-height: 22px;
|
||||||
|
letter-spacing: 0.6px;
|
||||||
|
text-align: center;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,305 @@
|
||||||
|
<!-- 学生老师共用雷达图 -->
|
||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<uniChart :option="person.option" />
|
||||||
|
<view class="cont_text">超过<text>{{props.rate}}%</text>该年龄段的学生</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, shallowRef, onMounted } from 'vue'
|
||||||
|
import * as echarts from "@/components/uniapp-echarts/static/echarts.min.js";
|
||||||
|
import uniChart from "@/components/uniapp-echarts/components/uni-chart/uni-chart.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
percentage:{
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
Title:{
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
rate:{
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let person=reactive({
|
||||||
|
option:{}
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
GetEchar()
|
||||||
|
})
|
||||||
|
|
||||||
|
const GetEchar = () => {
|
||||||
|
person.option = {
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
type: 'gauge',
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
splitNumber: 10,
|
||||||
|
radius: '99%',
|
||||||
|
endAngle: -270,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
width: '100%',
|
||||||
|
color: [[1, {
|
||||||
|
type: 'radial',
|
||||||
|
x: .5,
|
||||||
|
y: .5,
|
||||||
|
x2: 1,
|
||||||
|
y2: 1,
|
||||||
|
colorStops: [{
|
||||||
|
offset: .5, color: 'rgba(105, 132, 255, 1)' // 0% 处的颜色
|
||||||
|
}, {
|
||||||
|
offset: 1, color: 'rgba(107, 134, 255, 0.25)' // 100% 处的颜色
|
||||||
|
}],
|
||||||
|
globalCoord: false
|
||||||
|
}]]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
pointer: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
anchor: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'gauge',
|
||||||
|
radius: '60%',
|
||||||
|
endAngle: -270,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
width: '100%',
|
||||||
|
color: [[1, '#fff']]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
pointer: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
anchor: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'gauge',
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
splitNumber: 10,
|
||||||
|
radius: '85%',
|
||||||
|
endAngle: -270,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
width: 110,
|
||||||
|
color: [
|
||||||
|
[0.75, '#6984FF'],
|
||||||
|
[1, '#7A9CFF']
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
pointer: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
anchor: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'gauge',
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
splitNumber: 10,
|
||||||
|
radius: '80%',
|
||||||
|
progress: {
|
||||||
|
show: true,
|
||||||
|
width: 30
|
||||||
|
},
|
||||||
|
itemStyle: {
|
||||||
|
color: '#57DCFF'
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
distance: 50,
|
||||||
|
length: 18,
|
||||||
|
lineStyle: {
|
||||||
|
color: [[1, '#fff']],
|
||||||
|
width: 30
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
distance: -100,
|
||||||
|
color: '#ffffff',
|
||||||
|
fontSize: 40
|
||||||
|
},
|
||||||
|
anchor: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
pointer: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
offsetCenter: [0, '-22px'],
|
||||||
|
fontSize: 150,
|
||||||
|
color: '#6B86FF'
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
// 设置仪表盘中间显示文字样式
|
||||||
|
offsetCenter: [0, '30%'],
|
||||||
|
textStyle: {
|
||||||
|
fontSize: 40,
|
||||||
|
color: '#3E4E96'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: [
|
||||||
|
{
|
||||||
|
value: props.percentage,
|
||||||
|
name: props.Title.split('测评')[0]+'\n测评指数'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'gauge',
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
radius: '85%',
|
||||||
|
splitNumber: 10,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: [[1, '#57DCFF']],
|
||||||
|
width: 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
distance: -12,
|
||||||
|
length: 12,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#57DCFF'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
pointer: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
anchor: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'gauge',
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
radius: '60%',
|
||||||
|
splitNumber: 21,
|
||||||
|
startAngle: 200,
|
||||||
|
endAngle: -270,
|
||||||
|
axisLine: {
|
||||||
|
lineStyle: {
|
||||||
|
color: [[1, '#194280']],
|
||||||
|
width: 3
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
distance: 0,
|
||||||
|
length: 10,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#18EFE2'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisTick: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
pointer: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
show: false
|
||||||
|
},
|
||||||
|
anchor: {
|
||||||
|
show: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.content {
|
||||||
|
width: 220px;
|
||||||
|
height: 220px;
|
||||||
|
position: relative;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%);
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-bottom: 50rpx;
|
||||||
|
.cont_text{
|
||||||
|
position: absolute;
|
||||||
|
bottom: -60rpx;
|
||||||
|
left: 0;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
color: #414F8E;
|
||||||
|
font-size: 28rpx;
|
||||||
|
text{
|
||||||
|
color: #FFA755;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,183 @@
|
||||||
|
<template>
|
||||||
|
<view class="content">
|
||||||
|
<uniChart :option="person.option" />
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, shallowRef, onMounted, nextTick } from 'vue'
|
||||||
|
import * as echarts from "@/components/uniapp-echarts/static/echarts.min.js";
|
||||||
|
import uniChart from "@/components/uniapp-echarts/components/uni-chart/uni-chart.vue";
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
id: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
datas:{
|
||||||
|
type: Array,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
studentName:{
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
let person=reactive({
|
||||||
|
userScore:[],
|
||||||
|
userAvgScore:[],
|
||||||
|
xTime:[], // x轴数据
|
||||||
|
max: 0, // 最大数值
|
||||||
|
option: {}
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
load()
|
||||||
|
GetEchar()
|
||||||
|
})
|
||||||
|
const load=()=>{
|
||||||
|
// 指定配置项和数据
|
||||||
|
person.userScore = props.datas.map(f => { return f.Score })
|
||||||
|
person.userAvgScore = props.datas.map(f => { return f.AvgScore })
|
||||||
|
person.xTime = props.datas.map(f => { return f.Name })
|
||||||
|
person.max = Math.max.apply(null,props.datas.map(f => { return f.TotalScore }));
|
||||||
|
}
|
||||||
|
|
||||||
|
const GetEchar = () => {
|
||||||
|
person.option = {
|
||||||
|
tooltip: {
|
||||||
|
show: false,
|
||||||
|
trigger: 'axis',
|
||||||
|
formatter: function (params) {
|
||||||
|
return params[0].name+'\n'
|
||||||
|
+person.option.legend.data[0].name+':'+person.userScore[params[0].dataIndex]+'分\n'
|
||||||
|
+person.option.legend.data[1].name+':'+person.userAvgScore[params[0].dataIndex]+'分'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
legend: {
|
||||||
|
data: [
|
||||||
|
{ name: '学生/'+props.studentName },
|
||||||
|
{ name: '年级平均' }
|
||||||
|
],
|
||||||
|
icon: 'circle',
|
||||||
|
y: 'bottom',
|
||||||
|
itemWidth: 20, //宽度
|
||||||
|
itemHeight: 20, //高度
|
||||||
|
itemGap: 30, //间距
|
||||||
|
textStyle: {
|
||||||
|
color: '#333',
|
||||||
|
fontSize: 40
|
||||||
|
}
|
||||||
|
},
|
||||||
|
grid: {
|
||||||
|
top: '3%',
|
||||||
|
left: '3%',
|
||||||
|
right: '5%',
|
||||||
|
bottom: '10%',
|
||||||
|
containLabel: true
|
||||||
|
},
|
||||||
|
xAxis: [
|
||||||
|
{
|
||||||
|
type: 'category',
|
||||||
|
axisTick: {
|
||||||
|
show:false
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
onZero: false,
|
||||||
|
lineStyle: {
|
||||||
|
color: '#2A2A2A',
|
||||||
|
width: 4
|
||||||
|
}
|
||||||
|
},
|
||||||
|
axisLabel: {
|
||||||
|
//坐标轴刻度标签的相关设置。
|
||||||
|
textStyle: {
|
||||||
|
color: '#6F6F70',
|
||||||
|
fontSize: 40
|
||||||
|
},
|
||||||
|
formatter: function (params) {
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: person.xTime
|
||||||
|
}
|
||||||
|
],
|
||||||
|
yAxis: [
|
||||||
|
{
|
||||||
|
type: 'value',
|
||||||
|
axisTick: {
|
||||||
|
show:false
|
||||||
|
},
|
||||||
|
axisLine: {
|
||||||
|
show:false
|
||||||
|
},
|
||||||
|
max: person.max,
|
||||||
|
min: 0,
|
||||||
|
// y轴文字颜色
|
||||||
|
axisLabel: {
|
||||||
|
textStyle: {
|
||||||
|
color: '#6F6F70',
|
||||||
|
fontSize: 40
|
||||||
|
}
|
||||||
|
},
|
||||||
|
splitLine: {
|
||||||
|
show: true,
|
||||||
|
lineStyle: {
|
||||||
|
color: ['#5E5E5E'],
|
||||||
|
width: 2,
|
||||||
|
type: 'dashed'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
series: [
|
||||||
|
{
|
||||||
|
name: '学生/'+props.studentName,
|
||||||
|
type: 'line',
|
||||||
|
symbol: 'circle', //拐点样式
|
||||||
|
symbolSize: 8, //拐点大小
|
||||||
|
// 折线拐点的样式
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
// 静止时:
|
||||||
|
color: '#6B86FF',
|
||||||
|
borderColor: '#6B86FF', //拐点的边框颜色
|
||||||
|
borderWidth: 4
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
// 鼠标经过时:
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: person.userScore
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '年级平均',
|
||||||
|
type: 'line',
|
||||||
|
symbol: 'circle', //拐点样式
|
||||||
|
symbolSize: 8, //拐点大小
|
||||||
|
// 折线拐点的样式
|
||||||
|
itemStyle: {
|
||||||
|
normal: {
|
||||||
|
// 静止时:
|
||||||
|
color: '#FFA755',
|
||||||
|
borderColor: '#FFA755', //拐点的边框颜色
|
||||||
|
borderWidth: 4
|
||||||
|
},
|
||||||
|
emphasis: {
|
||||||
|
// 鼠标经过时:
|
||||||
|
color: '#fff'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data: person.userAvgScore
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.content {
|
||||||
|
width: 98%;
|
||||||
|
height: 260px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
<!-- 弹窗组件 -->
|
||||||
|
<template>
|
||||||
|
<view class="add_popup" v-if="person.isShowPopup">
|
||||||
|
<view class="popup_cont" :style="'background:'+props.bgColor+'!important;'">
|
||||||
|
<view class="popup_close"></view>
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, shallowRef, nextTick, onMounted, watch } from 'vue'
|
||||||
|
const props = defineProps({
|
||||||
|
isShow: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
bgColor: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
let person=reactive({
|
||||||
|
isShowPopup:false
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(()=>props.isShow,(newVal)=>{
|
||||||
|
person.isShowPopup=newVal
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
setTimeout(()=>{
|
||||||
|
person.isShowPopup=false
|
||||||
|
},3000)
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.add_popup{
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
// justify-content: start;
|
||||||
|
justify-content: flex-end;
|
||||||
|
z-index: 9999;
|
||||||
|
.popup_cont{
|
||||||
|
|
||||||
|
background: rgba(0,0,0,.4);
|
||||||
|
text-align: center;
|
||||||
|
margin: 60rpx auto 100rpx auto;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 30rpx;
|
||||||
|
padding: 40rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
.popup_close{
|
||||||
|
margin-bottom: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,156 @@
|
||||||
|
<template>
|
||||||
|
<view class="title">
|
||||||
|
<view class="title-title" :style="{
|
||||||
|
'color' : props.color,
|
||||||
|
'padding-top' : top+'rpx',
|
||||||
|
'background-color' : props.bgc,
|
||||||
|
'height' : tops+'rpx',
|
||||||
|
'line-height' : tops+'rpx'
|
||||||
|
}">
|
||||||
|
<view v-if="props.isReturn===0" class="title-return" @click="returns()">
|
||||||
|
<image src="@/static/report/back_icon.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="props.isReturn===1" class="title-return title-icon" @click="returns()">
|
||||||
|
<image :src="props.returnIcon" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view v-else-if="props.isReturn===4" class="title-return" @click="goHome()">
|
||||||
|
<image src="@/static/report/back_icon.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view v-else class="title-return"></view>
|
||||||
|
<view class="title-name"
|
||||||
|
:style="{'text-align':props.isCenter?'center;':'left;',marginLeft:props.isReturn===2?'-130rpx':''}">
|
||||||
|
{{props.title_name}}</view>
|
||||||
|
</view>
|
||||||
|
<view :style="{height: top+tops+'rpx'}"></view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
defineProps,
|
||||||
|
ref
|
||||||
|
} from 'vue'
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onShow
|
||||||
|
} from "@dcloudio/uni-app";
|
||||||
|
const props = defineProps({
|
||||||
|
title_name: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isReturn: { // 0返回 1自定义图标 2空图标文字居左 3空图标文字居中
|
||||||
|
type: Number,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
returnIcon: {
|
||||||
|
type: String,
|
||||||
|
// required: true
|
||||||
|
},
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
bgc: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
isCenter: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const isLast = ref(false)
|
||||||
|
const top = ref(0)
|
||||||
|
const tops = ref(100)
|
||||||
|
const emit = defineEmits(['iconClick'])
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
getLast()
|
||||||
|
getTopWeiXin()
|
||||||
|
})
|
||||||
|
|
||||||
|
const goHome = () => {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/index/index' //返回首页
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 返回的箭头
|
||||||
|
const returns = () => {
|
||||||
|
if (props.isReturn === 0) {
|
||||||
|
if (isLast.value) {
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/index/index' //返回首页
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1 //返回上一页
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else if (props.isReturn === 1) {
|
||||||
|
// 自定义图标操作
|
||||||
|
emit('iconClick')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取小程序安全区域的高度
|
||||||
|
const getTopWeiXin = () => {
|
||||||
|
top.value = parseInt(uni.getSystemInfoSync().statusBarHeight * 750 / uni.getSystemInfoSync().screenWidth)
|
||||||
|
uni.setStorageSync('top', top.value);
|
||||||
|
}
|
||||||
|
// 获取有无上一页
|
||||||
|
const getLast = () => {
|
||||||
|
let pages = getCurrentPages(); //当前页
|
||||||
|
if (pages.length == 1) {
|
||||||
|
isLast.value = true
|
||||||
|
} else {
|
||||||
|
isLast.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.title {
|
||||||
|
.title-title {
|
||||||
|
position: fixed;
|
||||||
|
z-index: 999;
|
||||||
|
width: 750rpx;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.title-return {
|
||||||
|
width: 60rpx;
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
z-index: 999;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
margin-top: 8rpx;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 36rpx;
|
||||||
|
height: 36rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-icon {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 46rpx !important;
|
||||||
|
height: 46rpx !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-name {
|
||||||
|
width: 560rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,93 @@
|
||||||
|
<!-- 弹窗组件 -->
|
||||||
|
<template>
|
||||||
|
<view class="add_popup" v-if="person.isShowPopup">
|
||||||
|
<view class="popup_cont" :style="{width:props.width&&props.width>0?props.width+'px;':'auto;',
|
||||||
|
height:props.height&&props.height>0?props.height+'px;':'auto;',
|
||||||
|
background:props.bgColor+'!important;'}">
|
||||||
|
<view class="popup_close" @click="cancel" v-if="props.showCancel"></view>
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { reactive, shallowRef, nextTick, onMounted, watch } from 'vue'
|
||||||
|
const props = defineProps({
|
||||||
|
isShow: {
|
||||||
|
type: Boolean,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: Number,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
bgColor: {
|
||||||
|
type: String,
|
||||||
|
required: false
|
||||||
|
},
|
||||||
|
showCancel:{
|
||||||
|
type:Boolean,
|
||||||
|
default:true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
interface Iemit{
|
||||||
|
(e:'cancelBtn'):void
|
||||||
|
}
|
||||||
|
const emit=defineEmits<Iemit>()
|
||||||
|
|
||||||
|
let person=reactive({
|
||||||
|
isShowPopup:false
|
||||||
|
})
|
||||||
|
|
||||||
|
watch(()=>props.isShow,(newVal)=>{
|
||||||
|
person.isShowPopup=newVal
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(()=>{
|
||||||
|
})
|
||||||
|
const cancel=()=>{
|
||||||
|
person.isShowPopup=!person.isShowPopup
|
||||||
|
emit('cancelBtn')
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.add_popup{
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
background: rgba(0,0,0,.4);
|
||||||
|
z-index: 99;
|
||||||
|
.popup_cont{
|
||||||
|
text-align: center;
|
||||||
|
margin: -60rpx auto 0 auto;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
color: #3D425B;
|
||||||
|
font-size: 30rpx;
|
||||||
|
padding: 40rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
position: relative;
|
||||||
|
.popup_close{
|
||||||
|
position: absolute;
|
||||||
|
bottom: -100rpx;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%);
|
||||||
|
width: 80rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
background: url('@/static/education/cancel.png') no-repeat;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 xbmlz
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
export class UniCanvas {
|
||||||
|
|
||||||
|
constructor(ctx, canvasNode) {
|
||||||
|
this.ctx = ctx
|
||||||
|
this.chart = {}
|
||||||
|
this.canvasNode = canvasNode
|
||||||
|
if (!canvasNode) {
|
||||||
|
this._initStyle(ctx)
|
||||||
|
}
|
||||||
|
this._initEvent()
|
||||||
|
}
|
||||||
|
|
||||||
|
getContext(contextType) {
|
||||||
|
if (contextType === '2d') {
|
||||||
|
return this.ctx
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setChart(chart) {
|
||||||
|
this.chart = chart
|
||||||
|
}
|
||||||
|
|
||||||
|
attachEvent() {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
detachEvent() {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
addEventListener() {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
removeEventListener() {
|
||||||
|
// noop
|
||||||
|
}
|
||||||
|
|
||||||
|
_initCanvas(zrender, ctx) {
|
||||||
|
zrender.util.getContext = () => {
|
||||||
|
return ctx
|
||||||
|
}
|
||||||
|
zrender.util.$override('measureText', (text, font) => {
|
||||||
|
ctx.font = font || '12px sans-serif'
|
||||||
|
return ctx.measureText(text)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_initStyle(ctx) {
|
||||||
|
ctx.createCircularGradient = (x, y, r) => {
|
||||||
|
return ctx.createCircularGradient(x, y, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_initEvent() {
|
||||||
|
this.event = {}
|
||||||
|
const eventNames = [{
|
||||||
|
wxName: 'touchStart',
|
||||||
|
ecName: 'mousedown',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wxName: 'touchMove',
|
||||||
|
ecName: 'mousemove',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wxName: 'touchEnd',
|
||||||
|
ecName: 'mouseup',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
wxName: 'touchEnd',
|
||||||
|
ecName: 'click',
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
eventNames.forEach((name) => {
|
||||||
|
this.event[name.wxName] = (e) => {
|
||||||
|
const touch = e.touches[0]
|
||||||
|
this.chart.getZr().handler.dispatch(name.ecName, {
|
||||||
|
zrX: name.wxName === 'tap' ? touch.clientX : touch.x,
|
||||||
|
zrY: name.wxName === 'tap' ? touch.clientY : touch.y,
|
||||||
|
preventDefault: () => {},
|
||||||
|
stopImmediatePropagation: () => {},
|
||||||
|
stopPropagation: () => {},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
get width() {
|
||||||
|
if (this.canvasNode) return this.canvasNode.width
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
set width(w) {
|
||||||
|
if (this.canvasNode) this.canvasNode.width = w
|
||||||
|
}
|
||||||
|
|
||||||
|
get height() {
|
||||||
|
if (this.canvasNode) return this.canvasNode.height
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
set height(h) {
|
||||||
|
if (this.canvasNode) this.canvasNode.height = h
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,363 @@
|
||||||
|
<template>
|
||||||
|
<!-- #ifdef APP-VUE || H5 -->
|
||||||
|
<view v-if="systemInfo.deviceType === 'pc'" :id="canvasId" class="uni-canvas" @click="emits('click', $event)" />
|
||||||
|
<view
|
||||||
|
v-else
|
||||||
|
:id="canvasId"
|
||||||
|
class="uni-canvas"
|
||||||
|
@click="click"
|
||||||
|
@touchstart="touchStart"
|
||||||
|
@touchmove.stop="touchMove"
|
||||||
|
@touchend="touchEnd"
|
||||||
|
/>
|
||||||
|
<!-- #endif -->
|
||||||
|
|
||||||
|
<!-- #ifdef MP-WEIXIN || MP-QQ -->
|
||||||
|
<scroll-view :scroll-top="scrollTop" scroll-y="true" class="scroll-Y"
|
||||||
|
@scrolltoupper="upper" @scrolltolower="lower" @scroll="scroll">
|
||||||
|
<canvas
|
||||||
|
v-if="useNewCanvas"
|
||||||
|
type="2d"
|
||||||
|
:id="canvasId"
|
||||||
|
class="uni-canvas"
|
||||||
|
:canvas-id="canvasId"
|
||||||
|
@click="click"
|
||||||
|
@touchstart="touchStart"
|
||||||
|
@touchmove.stop="touchMove"
|
||||||
|
@touchend="touchEnd"
|
||||||
|
force-use-old-canvas="true"
|
||||||
|
/>
|
||||||
|
<canvas
|
||||||
|
v-else
|
||||||
|
:id="canvasId"
|
||||||
|
class="uni-canvas"
|
||||||
|
:canvas-id="canvasId"
|
||||||
|
@click="click"
|
||||||
|
@touchstart="touchStart"
|
||||||
|
@touchmove.stop="touchMove"
|
||||||
|
@touchend="touchEnd"
|
||||||
|
force-use-old-canvas="true"
|
||||||
|
/>
|
||||||
|
</scroll-view>
|
||||||
|
<!-- #endif -->
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// #ifdef VUE3
|
||||||
|
import '../../static/echarts.min.js'
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef VUE2 || MP-WEIXIN
|
||||||
|
const echarts = require('../../static/echarts.min.js')
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
import { UniCanvas } from './uni-canvas.js'
|
||||||
|
|
||||||
|
let chart = null
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'uni-chart',
|
||||||
|
emits: ['inited', 'click', 'touchStart', 'touchMove', 'touchEnd'],
|
||||||
|
props: {
|
||||||
|
// 是否强制使用旧版本 canvas 绘制(不推荐)
|
||||||
|
forceUseOldCanvas: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
// 主题名称,内置
|
||||||
|
theme: {
|
||||||
|
type: [String, Object],
|
||||||
|
},
|
||||||
|
// 图表配置
|
||||||
|
option: {
|
||||||
|
type: Object,
|
||||||
|
require: true,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// 地图注册配置
|
||||||
|
map: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
canvasId: `uni-canvas-${Date.now()}`,
|
||||||
|
systemInfo: uni.getSystemInfoSync(),
|
||||||
|
useNewCanvas: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.registerPreprocessor()
|
||||||
|
this.registerMap()
|
||||||
|
this.$nextTick(() => {
|
||||||
|
// #ifdef APP-VUE || H5
|
||||||
|
this.initH5()
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// #ifdef MP-WEIXIN || MP-QQ
|
||||||
|
this.initMiniProgram()
|
||||||
|
// #endif
|
||||||
|
})
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
this.dispose()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
// register echarts preprocessor
|
||||||
|
registerPreprocessor() {
|
||||||
|
echarts.registerPreprocessor(option => {
|
||||||
|
if (option && option.series) {
|
||||||
|
if (option.series.length > 0) {
|
||||||
|
option.series.forEach(series => {
|
||||||
|
series.progressive = 0
|
||||||
|
})
|
||||||
|
} else if (typeof option.series === 'object') {
|
||||||
|
option.series.progressive = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
// register geo json
|
||||||
|
registerMap() {
|
||||||
|
if (JSON.stringify(this.$props.map) === '{}') return
|
||||||
|
echarts.registerMap(this.$props.map.name, this.$props.map.opt)
|
||||||
|
},
|
||||||
|
// register theme color
|
||||||
|
registerTheme(name, opt) {
|
||||||
|
console.log('registerTheme', name, opt)
|
||||||
|
echarts.registerTheme(name, opt)
|
||||||
|
},
|
||||||
|
// init H5 app-vue
|
||||||
|
initH5() {
|
||||||
|
const canvasNode = document.getElementById(this.canvasId)
|
||||||
|
chart = echarts.init(canvasNode, this.$props.theme)
|
||||||
|
this.$emit('inited', chart)
|
||||||
|
chart.setOption(this.$props.option)
|
||||||
|
},
|
||||||
|
// init mini program
|
||||||
|
initMiniProgram() {
|
||||||
|
const version = this.systemInfo.SDKVersion
|
||||||
|
console.log(`当前基础库版本为: ${version}`)
|
||||||
|
|
||||||
|
const oldVersion = '1.9.91'
|
||||||
|
const baseVersion = '2.9.0'
|
||||||
|
|
||||||
|
let canUseNewCanvas = this.compareVersion(version, baseVersion) >= 0
|
||||||
|
|
||||||
|
if (this.$props.forceUseOldCanvas) {
|
||||||
|
if (canUseNewCanvas) console.warn('开发者强制使用旧canvas,建议关闭')
|
||||||
|
canUseNewCanvas = false
|
||||||
|
}
|
||||||
|
this.useNewCanvas = canUseNewCanvas && !this.forceUseOldCanvas
|
||||||
|
if (this.useNewCanvas) {
|
||||||
|
// 2.9.0 可以使用 <canvas type="2d"></canvas>
|
||||||
|
this.initNewCanvas()
|
||||||
|
} else {
|
||||||
|
const isValid = this.compareVersion(version, oldVersion) >= 0
|
||||||
|
if (!isValid) {
|
||||||
|
console.error(`基础库版本过低,需大于等于 ${oldVersion}。`)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
console.warn(`建议将基础库调整大于等于${baseVersion}版本。升级后绘图将有更好性能`)
|
||||||
|
this.initOldCanvas()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// initNewCanvas
|
||||||
|
initNewCanvas() {
|
||||||
|
const query = uni.createSelectorQuery().in(this)
|
||||||
|
query
|
||||||
|
.select(`#${this.canvasId}`)
|
||||||
|
.node(res => {
|
||||||
|
const canvasNode = res.node
|
||||||
|
const ctx = canvasNode?.getContext('2d')
|
||||||
|
canvasNode.width = canvasNode.width * this.systemInfo.pixelRatio
|
||||||
|
canvasNode.height = canvasNode.height * this.systemInfo.pixelRatio
|
||||||
|
ctx.scale(this.pixelRatio, this.pixelRatio)
|
||||||
|
const canvas = new UniCanvas(ctx, canvasNode)
|
||||||
|
this.initECharts(canvas, canvasNode.width, canvasNode.width, this.pixelRatio)
|
||||||
|
})
|
||||||
|
.exec()
|
||||||
|
},
|
||||||
|
// initOldCanvas
|
||||||
|
initOldCanvas() {
|
||||||
|
// 1.9.91 <= sdkVersion < 2.9.0:原来的方式初始化
|
||||||
|
const ctx = uni.createCanvasContext(`#${this.canvasId}`, this)
|
||||||
|
const canvas = new UniCanvas(ctx)
|
||||||
|
const query = uni.createSelectorQuery().in(this)
|
||||||
|
query
|
||||||
|
.select(`#${this.canvasId}`)
|
||||||
|
.boundingClientRect(res => {
|
||||||
|
// 微信旧的canvas不能传入dpr
|
||||||
|
this.initECharts(res.width, res.height, 1)
|
||||||
|
})
|
||||||
|
.exec()
|
||||||
|
},
|
||||||
|
// init
|
||||||
|
initECharts(canvas, width, height, dpr) {
|
||||||
|
echarts.setPlatformAPI({ createCanvas: () => canvas })
|
||||||
|
const theme = this.$props.theme
|
||||||
|
let themeName = ''
|
||||||
|
console.log('typeof theme', typeof theme)
|
||||||
|
if (typeof theme === 'object') {
|
||||||
|
this.registerTheme(theme.name, theme.opt)
|
||||||
|
themeName = theme.name
|
||||||
|
}
|
||||||
|
if (typeof theme === 'string') {
|
||||||
|
themeName = theme
|
||||||
|
}
|
||||||
|
chart = echarts.init(canvas, themeName, {
|
||||||
|
width: width,
|
||||||
|
height: height,
|
||||||
|
devicePixelRatio: dpr
|
||||||
|
})
|
||||||
|
this.$emit('inited', chart)
|
||||||
|
this.setOption(this.$props.option)
|
||||||
|
},
|
||||||
|
canvasToTempFilePath(opt) {
|
||||||
|
if (this.useNewCanvas) {
|
||||||
|
const query = uni.createSelectorQuery().in(this)
|
||||||
|
query
|
||||||
|
.select(`#${this.canvasId}`)
|
||||||
|
.node(res => {
|
||||||
|
const canvasNode = res.node
|
||||||
|
opt.canvas = canvasNode
|
||||||
|
uni.canvasToTempFilePath(opt)
|
||||||
|
})
|
||||||
|
.exec()
|
||||||
|
} else {
|
||||||
|
if (!opt.canvasId) {
|
||||||
|
opt.canvasId = this.canvasId
|
||||||
|
}
|
||||||
|
// TODO
|
||||||
|
chart.ctx.draw(true, () => {
|
||||||
|
uni.canvasToTempFilePath(opt, this)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
setOption(opt) {
|
||||||
|
chart.setOption(opt)
|
||||||
|
},
|
||||||
|
dispose() {
|
||||||
|
chart && chart.dispose()
|
||||||
|
},
|
||||||
|
// event
|
||||||
|
wrapTouch(event) {
|
||||||
|
for (let i = 0; i < event.touches.length; ++i) {
|
||||||
|
const touch = event.touches[i]
|
||||||
|
touch.offsetX = touch.x
|
||||||
|
touch.offsetY = touch.y
|
||||||
|
}
|
||||||
|
return event
|
||||||
|
},
|
||||||
|
click(e) {
|
||||||
|
this.$emit('click', e)
|
||||||
|
},
|
||||||
|
touchStart(e) {
|
||||||
|
if (chart && e.touches.length > 0) {
|
||||||
|
const touch = e.touches[0]
|
||||||
|
const handler = chart.getZr().handler
|
||||||
|
handler.dispatch('mousedown', {
|
||||||
|
zrX: touch.x,
|
||||||
|
zrY: touch.y,
|
||||||
|
preventDefault: () => {},
|
||||||
|
stopPropagation: () => {}
|
||||||
|
})
|
||||||
|
handler.dispatch('mousemove', {
|
||||||
|
zrX: touch.x,
|
||||||
|
zrY: touch.y,
|
||||||
|
preventDefault: () => {},
|
||||||
|
stopPropagation: () => {}
|
||||||
|
})
|
||||||
|
handler.processGesture(this.wrapTouch(e), 'start')
|
||||||
|
this.$emit('touchStart', e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
touchMove(e) {
|
||||||
|
if (chart && e.touches.length > 0) {
|
||||||
|
let touch = e.touches[0]
|
||||||
|
const {
|
||||||
|
target: { offsetLeft, offsetTop }
|
||||||
|
} = e
|
||||||
|
touch.x = touch.pageX - offsetLeft
|
||||||
|
touch.y = touch.pageY - offsetTop
|
||||||
|
const handler = chart.getZr().handler
|
||||||
|
if (handler) {
|
||||||
|
handler.dispatch('mousemove', {
|
||||||
|
zrX: touch.x,
|
||||||
|
zrY: touch.y
|
||||||
|
})
|
||||||
|
handler.processGesture(this.wrapTouch(e), 'change')
|
||||||
|
}
|
||||||
|
this.$emit('touchMove', e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
touchEnd(e) {
|
||||||
|
if (chart) {
|
||||||
|
const touch = e.changedTouches ? e.changedTouches[0] : {}
|
||||||
|
const {
|
||||||
|
target: { offsetLeft, offsetTop }
|
||||||
|
} = e
|
||||||
|
touch.x = touch.pageX - offsetLeft
|
||||||
|
touch.y = touch.pageY - offsetTop
|
||||||
|
var handler = chart.getZr().handler
|
||||||
|
if (handler) {
|
||||||
|
handler.dispatch('mouseup', {
|
||||||
|
zrX: touch.x,
|
||||||
|
zrY: touch.y
|
||||||
|
})
|
||||||
|
handler.dispatch('click', {
|
||||||
|
zrX: touch.x,
|
||||||
|
zrY: touch.y
|
||||||
|
})
|
||||||
|
handler.processGesture(this.wrapTouch(e), 'end')
|
||||||
|
}
|
||||||
|
this.$emit('touchEnd', e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
// utils
|
||||||
|
compareVersion(v1, v2) {
|
||||||
|
v1 = v1.split('.')
|
||||||
|
v2 = v2.split('.')
|
||||||
|
const len = Math.max(v1.length, v2.length)
|
||||||
|
|
||||||
|
while (v1.length < len) {
|
||||||
|
v1.push('0')
|
||||||
|
}
|
||||||
|
while (v2.length < len) {
|
||||||
|
v2.push('0')
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
const num1 = parseInt(v1[i])
|
||||||
|
const num2 = parseInt(v2[i])
|
||||||
|
if (num1 > num2) {
|
||||||
|
return 1
|
||||||
|
} else if (num1 < num2) {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.scroll-Y{
|
||||||
|
height: 100%;
|
||||||
|
position: relative;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%);
|
||||||
|
}
|
||||||
|
.uni-canvas {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: block;
|
||||||
|
z-index: -1 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
{
|
||||||
|
"id": "echarts-for-uniapp",
|
||||||
|
"name": "uniapp-echarts",
|
||||||
|
"displayName": "echarts-for-uniapp",
|
||||||
|
"version": "1.0.2",
|
||||||
|
"description": "uni-app 版本 echarts, 支持 Vue2/3, 开发者可以通过熟悉的 ECharts 配置方式,快速开发图表,满足各种可视化需求.",
|
||||||
|
"keywords": [
|
||||||
|
"echarts-uniapp",
|
||||||
|
"echarts",
|
||||||
|
"echarts",
|
||||||
|
"图表",
|
||||||
|
"可视化"
|
||||||
|
],
|
||||||
|
"scripts": {
|
||||||
|
"release": "bumpp && npm publish"
|
||||||
|
},
|
||||||
|
"repository": "https://github.com/xbmlz/echarts-for-uniapp",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.2.13"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"type": "component-vue",
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": "997909544"
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": "https://www.npmjs.com/package/echarts-for-uniapp"
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "u"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "y",
|
||||||
|
"IE": "u",
|
||||||
|
"Edge": "y",
|
||||||
|
"Firefox": "y",
|
||||||
|
"Safari": "y"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": "y",
|
||||||
|
"阿里": "u",
|
||||||
|
"百度": "u",
|
||||||
|
"字节跳动": "u",
|
||||||
|
"QQ": "u",
|
||||||
|
"钉钉": "u",
|
||||||
|
"快手": "u",
|
||||||
|
"飞书": "u",
|
||||||
|
"京东": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
export const config= {
|
||||||
|
// host:"https://apifox.com/apidoc/shared-b43049a6-fed3-4025-8af9-3673b3d1c216/api-102610320",
|
||||||
|
// host:"https://mp-mk.qwit.top"
|
||||||
|
// host:"http://192.168.2.33:5011"
|
||||||
|
host:"https://mp-mk-api.23544.com"
|
||||||
|
// host:"https://mp-mk-api.23544.com"
|
||||||
|
// host:"http://192.168.2.7:8011"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
/// <reference types="vite/client" />
|
||||||
|
|
||||||
|
declare module '*.vue' {
|
||||||
|
import { DefineComponent } from 'vue'
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/ban-types
|
||||||
|
const component: DefineComponent<{}, {}, any>
|
||||||
|
export default component
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<script>
|
||||||
|
// var coverSupport = 'CSS' in window && typeof CSS.supports === 'function' && (CSS.supports('top: env(a)') ||
|
||||||
|
// CSS.supports('top: constant(a)'))
|
||||||
|
// document.write(
|
||||||
|
// '<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0' +
|
||||||
|
// (coverSupport ? ', viewport-fit=cover' : '') + '" />')
|
||||||
|
</script>
|
||||||
|
<title></title>
|
||||||
|
<!--preload-links-->
|
||||||
|
<!--app-context-->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"><!--app-html--></div>
|
||||||
|
<script type="module" src="/main.ts"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
import App from "./App.vue";
|
||||||
|
import { createSSRApp } from "vue";
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV === 'production') {
|
||||||
|
//正式环境去除
|
||||||
|
console.log = () => {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createApp() {
|
||||||
|
const app = createSSRApp(App);
|
||||||
|
return {
|
||||||
|
app,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,81 @@
|
||||||
|
{
|
||||||
|
"name" : "Yuanduan",
|
||||||
|
"appid" : "wx3979b942304174d5",
|
||||||
|
"description" : "",
|
||||||
|
"versionName" : "1.0.0",
|
||||||
|
"versionCode" : "100",
|
||||||
|
"transformPx" : false,
|
||||||
|
/* 5+App特有相关 */
|
||||||
|
"app-plus" : {
|
||||||
|
"usingComponents" : true,
|
||||||
|
"nvueStyleCompiler" : "uni-app",
|
||||||
|
"compilerVersion" : 3,
|
||||||
|
"splashscreen" : {
|
||||||
|
"alwaysShowBeforeRender" : true,
|
||||||
|
"waiting" : true,
|
||||||
|
"autoclose" : true,
|
||||||
|
"delay" : 0
|
||||||
|
},
|
||||||
|
/* 模块配置 */
|
||||||
|
"modules" : {},
|
||||||
|
/* 应用发布信息 */
|
||||||
|
"distribute" : {
|
||||||
|
/* android打包配置 */
|
||||||
|
"android" : {
|
||||||
|
"permissions" : [
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.VIBRATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CAMERA\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
|
||||||
|
"<uses-feature android:name=\"android.hardware.camera\"/>",
|
||||||
|
"<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
/* ios打包配置 */
|
||||||
|
"ios" : {},
|
||||||
|
/* SDK配置 */
|
||||||
|
"sdkConfigs" : {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
/* 快应用特有相关 */
|
||||||
|
"quickapp" : {},
|
||||||
|
/* 小程序特有相关 */
|
||||||
|
"mp-weixin" : {
|
||||||
|
"appid" : "wxe12af2df5f60bd72",
|
||||||
|
"setting" : {
|
||||||
|
"urlCheck" : false,
|
||||||
|
"es6" : false,
|
||||||
|
"minified" : false
|
||||||
|
},
|
||||||
|
"usingComponents" : true,
|
||||||
|
"permission" : {},
|
||||||
|
"lazyCodeLoading":"requiredComponents"
|
||||||
|
},
|
||||||
|
"mp-alipay" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-baidu" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"mp-toutiao" : {
|
||||||
|
"usingComponents" : true
|
||||||
|
},
|
||||||
|
"uniStatistics" : {
|
||||||
|
"enable" : false
|
||||||
|
},
|
||||||
|
"vueVersion" : "3",
|
||||||
|
"h5" : {
|
||||||
|
"devServer" : {
|
||||||
|
"port" : 6500
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,68 @@
|
||||||
|
{
|
||||||
|
"name": "uni-preset-vue",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev:app": "uni -p app",
|
||||||
|
"dev:custom": "uni -p",
|
||||||
|
"dev:h5": "uni",
|
||||||
|
"dev:h5:ssr": "uni --ssr",
|
||||||
|
"dev:mp-alipay": "uni -p mp-alipay",
|
||||||
|
"dev:mp-baidu": "uni -p mp-baidu",
|
||||||
|
"dev:mp-kuaishou": "uni -p mp-kuaishou",
|
||||||
|
"dev:mp-lark": "uni -p mp-lark",
|
||||||
|
"dev:mp-qq": "uni -p mp-qq",
|
||||||
|
"dev:mp-toutiao": "uni -p mp-toutiao",
|
||||||
|
"dev:mp-weixin": "uni -p mp-weixin",
|
||||||
|
"dev:quickapp-webview": "uni -p quickapp-webview",
|
||||||
|
"dev:quickapp-webview-huawei": "uni -p quickapp-webview-huawei",
|
||||||
|
"dev:quickapp-webview-union": "uni -p quickapp-webview-union",
|
||||||
|
"build:app": "uni build -p app",
|
||||||
|
"build:custom": "uni build -p",
|
||||||
|
"build:h5": "uni build",
|
||||||
|
"build:h5:ssr": "uni build --ssr",
|
||||||
|
"build:mp-alipay": "uni build -p mp-alipay",
|
||||||
|
"build:mp-baidu": "uni build -p mp-baidu",
|
||||||
|
"build:mp-kuaishou": "uni build -p mp-kuaishou",
|
||||||
|
"build:mp-lark": "uni build -p mp-lark",
|
||||||
|
"build:mp-qq": "uni build -p mp-qq",
|
||||||
|
"build:mp-toutiao": "uni build -p mp-toutiao",
|
||||||
|
"build:mp-weixin": "uni build -p mp-weixin",
|
||||||
|
"build:quickapp-webview": "uni build -p quickapp-webview",
|
||||||
|
"build:quickapp-webview-huawei": "uni build -p quickapp-webview-huawei",
|
||||||
|
"build:quickapp-webview-union": "uni build -p quickapp-webview-union"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@dcloudio/uni-app": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-app-plus": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-components": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-h5": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-mp-alipay": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-mp-baidu": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-mp-jd": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-mp-kuaishou": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-mp-lark": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-mp-qq": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-mp-toutiao": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-mp-weixin": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-mp-xhs": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-quickapp-webview": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@fingerprintjs/fingerprintjs": "^3.4.1",
|
||||||
|
"vue": "3.3.4",
|
||||||
|
"vuex": "^4.0.2",
|
||||||
|
"wxml2canvas": "^1.0.1"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@dcloudio/types": "3.3.3",
|
||||||
|
"@dcloudio/uni-automator": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-cli-shared": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/uni-stacktracey": "3.0.0-alpha-3080720230627002",
|
||||||
|
"@dcloudio/vite-plugin-uni": "3.0.0-alpha-3080720230627002",
|
||||||
|
"js-md5": "^0.7.3",
|
||||||
|
"postcss-loader": "^7.0.2",
|
||||||
|
"postcss-pxtorpx-pro": "^2.0.0",
|
||||||
|
"sass": "^1.52.3",
|
||||||
|
"typescript": "^4.7.3",
|
||||||
|
"vconsole": "^3.15.0",
|
||||||
|
"vite": "4.0.3"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
{
|
||||||
|
"pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||||
|
{
|
||||||
|
"path": "pages/examData/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "教育中心",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"app-plus": {
|
||||||
|
"titleNView": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/user/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "个人中心",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"app-plus": {
|
||||||
|
"titleNView": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/webview/webview",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "注册中心",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"app-plus": {
|
||||||
|
"titleNView": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
"path": "pages/examReport/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "考试报告",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"app-plus": {
|
||||||
|
"titleNView": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/examTest/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "查看原卷",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"app-plus": {
|
||||||
|
"titleNView": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/userRelated/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "关于",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"app-plus": {
|
||||||
|
"titleNView": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "pages/userAddStudent/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "添加学生",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"app-plus": {
|
||||||
|
"titleNView": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
,{
|
||||||
|
"path" : "pages/login/login",
|
||||||
|
"style" :
|
||||||
|
{
|
||||||
|
"navigationBarTitleText": "",
|
||||||
|
"enablePullDownRefresh": false
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "远端小程序",
|
||||||
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
|
"backgroundColor": "#F8F8F8"
|
||||||
|
},
|
||||||
|
"tabBar": {
|
||||||
|
"color": "#A1A9B2",
|
||||||
|
"selectedColor": "#2080F7",
|
||||||
|
"borderStyle": "black",
|
||||||
|
"height": "50px",
|
||||||
|
// "spacing": "6px",
|
||||||
|
"iconWidth": "24px",
|
||||||
|
"backgroundColor": "white",
|
||||||
|
"list": [{
|
||||||
|
"pagePath": "pages/examData/index",
|
||||||
|
"iconPath": "static/tabBar/material.png",
|
||||||
|
"selectedIconPath": "static/tabBar/material-active.png",
|
||||||
|
"text": "教育中心"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/user/index",
|
||||||
|
"iconPath": "static/tabBar/monitor.png",
|
||||||
|
"selectedIconPath": "static/tabBar/monitor-active.png",
|
||||||
|
"text": "个人中心"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"condition": { //模式配置,仅开发期间生效
|
||||||
|
"current": 0, //当前激活的模式(list 的索引项)
|
||||||
|
"list": [{
|
||||||
|
"name": "", //模式名称
|
||||||
|
"path": "", //启动页面,必选
|
||||||
|
"query": "" //启动参数,在页面的onLoad函数里面得到
|
||||||
|
}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,431 @@
|
||||||
|
<template>
|
||||||
|
<view class="page-bg">
|
||||||
|
<Navigation :title_name="'教育中心'" :isReturn="3" :color="'#000000'" :bgc="'#FFFFFF'" :isCenter="true" />
|
||||||
|
<view class="ech" v-if="person.studentList[person.studentActive]">
|
||||||
|
<CurrItem v-if="person.studentList[person.studentActive]" :datas="person.studentList[person.studentActive]"
|
||||||
|
@changeStu="getChangeStu" :isChange="true" :listLength="person.studentList.length"
|
||||||
|
:bgIndex="person.studentActive" />
|
||||||
|
<view class="ech-list">
|
||||||
|
<view class="time-logo">
|
||||||
|
<view class="time-reserve" @tap="reverseSort">排序:按时间 <view class="time-icon"
|
||||||
|
:class="showTimeIcon?'dowm-time-icon':'up-time-icon'"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<scroll-view @scrolltolower="lowerBottom" @refresherrefresh="getFresh" scroll-y="true"
|
||||||
|
class="scrollHeight">
|
||||||
|
<template v-if="person.data.list&&person.data.list.length>0">
|
||||||
|
<view class="ech-item" v-for="(rep,repIndex) in person.data.list" :key="repIndex">
|
||||||
|
<view class="ech-item-type"
|
||||||
|
:class="[rep.ExamType==='周考'?'ech-type-blue':rep.ExamType==='月考'?'ech-type-green':rep.ExamType==='期中'?'ech-type-purple':'ech-type-purple']">
|
||||||
|
{{rep.ExamType}}
|
||||||
|
</view>
|
||||||
|
<view class="left">
|
||||||
|
<view class="item-tit">{{rep.Name}}</view>
|
||||||
|
<view class="time">时间:{{rep.Time}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="right" @click="lookReport(rep,repIndex)">查看<br />报告</view>
|
||||||
|
</view>
|
||||||
|
<view class="more_text" v-if="person.showMoreData">没有数据了...</view>
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
<view class="empty_box">
|
||||||
|
<image src="@/static/null_icon.png" mode=""></image>
|
||||||
|
<text>暂无数据~</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="empty_box">
|
||||||
|
<image src="@/static/null_icon.png" mode=""></image>
|
||||||
|
<text>暂无数据~</text>
|
||||||
|
</view>
|
||||||
|
<Popups :isShow="showChangeStudent" :bgColor="'#fff'">
|
||||||
|
<view class="dio-card">
|
||||||
|
<view class="stu-item" :class="[person.studentActive===stuIndex?'active-bg':'']"
|
||||||
|
v-for="(stu,stuIndex) in person.studentList" :key="stuIndex"
|
||||||
|
@click.stop="studentChange(stu,stuIndex)">
|
||||||
|
<image src="https://minio.23544.com:9010/data-center/gzh/Avatar.png" mode=""></image>
|
||||||
|
<view class="stu-name">{{stu.RealName}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</Popups>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
reactive
|
||||||
|
} from "vue";
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onShow
|
||||||
|
} from "@dcloudio/uni-app";
|
||||||
|
import Popups from "@/components/popups/index.vue";
|
||||||
|
import CurrItem from "@/components/currItem/index.vue";
|
||||||
|
import Navigation from '@/components/navigation/index.vue'
|
||||||
|
import {
|
||||||
|
getChangeStudent,
|
||||||
|
getBindStudentList,
|
||||||
|
getUserReportList
|
||||||
|
} from "@/api/exam-data";
|
||||||
|
import {
|
||||||
|
getUserInfo,
|
||||||
|
postRegister
|
||||||
|
} from "@/api/user";
|
||||||
|
|
||||||
|
let person = reactive({
|
||||||
|
showMoreData: false,
|
||||||
|
// 学生列表
|
||||||
|
studentActive: 0,
|
||||||
|
studentList: [],
|
||||||
|
// 报告列表
|
||||||
|
data: {
|
||||||
|
list: [],
|
||||||
|
pageIndex: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
total: 0
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 刷新页面加载
|
||||||
|
onShow(() => {
|
||||||
|
person.data.pageIndex=1
|
||||||
|
person.data.list=[]
|
||||||
|
uni.pageScrollTo({
|
||||||
|
scrollTop: 0
|
||||||
|
});
|
||||||
|
GetBindStudentList()
|
||||||
|
if (person.data.pageIndex * person.data.pageSize >= person.data.total) return person.showMoreData = true
|
||||||
|
})
|
||||||
|
|
||||||
|
//点击时间排序的互动
|
||||||
|
const showTimeIcon = ref(false)
|
||||||
|
const reverseSort = () => {
|
||||||
|
showTimeIcon.value = !showTimeIcon.value
|
||||||
|
if (person.data.list && person.data.list.length > 0) {
|
||||||
|
if (showTimeIcon.value) {
|
||||||
|
// 降序
|
||||||
|
person.data.list = person.data.list.sort(dateData("Time", true))
|
||||||
|
} else {
|
||||||
|
// 升序
|
||||||
|
person.data.list = person.data.list.sort(dateData("Time", false))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 时间排序
|
||||||
|
const dateData = (property, bol) => {
|
||||||
|
return function(a, b) {
|
||||||
|
let value1 = a[property];
|
||||||
|
let value2 = b[property];
|
||||||
|
if (bol) {
|
||||||
|
// 升序
|
||||||
|
return Date.parse(value1) - Date.parse(value2);
|
||||||
|
} else {
|
||||||
|
// 降序
|
||||||
|
return Date.parse(value2) - Date.parse(value1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//关于弹窗出现和关闭
|
||||||
|
const showChangeStudent = ref(false)
|
||||||
|
const getChangeStu = () => {
|
||||||
|
showChangeStudent.value = !showChangeStudent.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 学生切换
|
||||||
|
const studentChange = (item, index) => {
|
||||||
|
person.studentActive = index
|
||||||
|
showChangeStudent.value = false
|
||||||
|
if (showChangeStudent.value === false) {
|
||||||
|
person.data.pageIndex = 1
|
||||||
|
person.data.list = []
|
||||||
|
person.data.total = 0
|
||||||
|
GetChangeStudent(item.Id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//跳转查看报告
|
||||||
|
const lookReport = (item, index) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/examReport/index?examId=' + item.ExamId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//触底加载
|
||||||
|
const lowerBottom = () => {
|
||||||
|
// 判断是否还有下一页数据
|
||||||
|
if (person.data.pageIndex * person.data.pageSize >= person.data.total) return person.showMoreData = true
|
||||||
|
// 让页码值自增 +1
|
||||||
|
person.data.pageIndex += 1
|
||||||
|
// 重新获取列表数据
|
||||||
|
// 调接口
|
||||||
|
GetUserReportList()
|
||||||
|
}
|
||||||
|
// 下拉刷新
|
||||||
|
const getFresh = () => {}
|
||||||
|
|
||||||
|
// 获取切换学生
|
||||||
|
const GetChangeStudent = (Id) => {
|
||||||
|
getChangeStudent({
|
||||||
|
studentId: Id
|
||||||
|
}).then(res => {
|
||||||
|
let {
|
||||||
|
Code,
|
||||||
|
Data
|
||||||
|
} = res
|
||||||
|
if (Code === 200 && Data) {
|
||||||
|
GetUserReportList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 获取绑定的学生列表
|
||||||
|
const GetBindStudentList = () => {
|
||||||
|
getBindStudentList().then(res => {
|
||||||
|
let {
|
||||||
|
Code,
|
||||||
|
Data,
|
||||||
|
Message
|
||||||
|
} = res
|
||||||
|
if (Code === 200 && Data) {
|
||||||
|
person.studentList = Data
|
||||||
|
if (person.studentList && person.studentList.length > 0) {
|
||||||
|
GetChangeStudent(person.studentList[person.studentActive].Id)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: Message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 获取学生报告列表
|
||||||
|
const GetUserReportList = () => {
|
||||||
|
let obj = {
|
||||||
|
PageIndex: person.data.pageIndex,
|
||||||
|
PageSize: person.data.pageSize
|
||||||
|
}
|
||||||
|
getUserReportList(obj).then(res => {
|
||||||
|
let {
|
||||||
|
Code,
|
||||||
|
Data,
|
||||||
|
Message
|
||||||
|
} = res
|
||||||
|
if (Code === 200 && Data) {
|
||||||
|
setTimeout(() => {}, 200)
|
||||||
|
person.data.list = [...person.data.list, ...Data.Data]
|
||||||
|
person.data.total = Data.Total
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: Message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page-bg {
|
||||||
|
height: calc(100vh - 4rpx);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上拉分页
|
||||||
|
.scrollHeight {
|
||||||
|
height: calc(100vh - 550rpx);
|
||||||
|
|
||||||
|
.more_text {
|
||||||
|
margin: 20rpx 0;
|
||||||
|
color: #999;
|
||||||
|
font-size: 24rpx;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.ech {
|
||||||
|
width: 100vw;
|
||||||
|
padding: 10px 20px 0 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ech-card {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ech-list {
|
||||||
|
border-radius: 0 0 10px 10px;
|
||||||
|
background: #FFF;
|
||||||
|
box-shadow: 0px 3px 7px 0px rgba(0, 0, 0, 0.15);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: flex-end;
|
||||||
|
align-items: center;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
margin-top: -15px;
|
||||||
|
|
||||||
|
.ech-item {
|
||||||
|
margin: 0 auto 10px auto;
|
||||||
|
width: 303px;
|
||||||
|
border-radius: 6px;
|
||||||
|
background: linear-gradient(180deg, rgba(228, 233, 255, 0.74) 0%, rgba(255, 255, 255, 0.49) 29.69%, rgba(128, 151, 255, 0.67) 100%);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px 10px 20px 10px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.ech-item-type {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 2px 20px;
|
||||||
|
border-radius: 6px 0 10px 0;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ech-type-blue {
|
||||||
|
color: #4F6FFF;
|
||||||
|
background: #E3E8FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ech-type-green {
|
||||||
|
color: #00B6DE;
|
||||||
|
background: #C0F4FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ech-type-purple {
|
||||||
|
color: #9361FF;
|
||||||
|
background: #E8DEFE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
width: 78%;
|
||||||
|
|
||||||
|
.item-tit {
|
||||||
|
display: -webkit-box;
|
||||||
|
-webkit-box-orient: vertical;
|
||||||
|
-webkit-line-clamp: 2;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #5B5B5B;
|
||||||
|
font-size: 15px;
|
||||||
|
font-weight: 600;
|
||||||
|
letter-spacing: 0.78px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.time {
|
||||||
|
margin-top: 7px;
|
||||||
|
height: 20px;
|
||||||
|
color: #5E5E5E !important;
|
||||||
|
font-size: 12px;
|
||||||
|
letter-spacing: 0.6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.time-logo {
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
margin: 10px 0;
|
||||||
|
|
||||||
|
.time-reserve {
|
||||||
|
margin-right: 20px;
|
||||||
|
height: 15px;
|
||||||
|
line-height: 15px;
|
||||||
|
color: #777;
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: 0.6px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.time-icon {
|
||||||
|
margin-left: 5px;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dowm-time-icon {
|
||||||
|
background: url('@/static/education/reverse.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
.up-time-icon {
|
||||||
|
background: url('@/static/education/reverse_up.png');
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
width: 50px;
|
||||||
|
height: 54px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 5px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
color: #6B86FF;
|
||||||
|
font-family: PingFang SC;
|
||||||
|
font-size: 12px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: 0.72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dio-card {
|
||||||
|
width: 202px;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 250px;
|
||||||
|
|
||||||
|
&::-webkit-scrollbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stu-item {
|
||||||
|
width: 100%;
|
||||||
|
height: 91px;
|
||||||
|
border-radius: 8px;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background: #EFEFEF;
|
||||||
|
color: #0D0A0A;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 68px;
|
||||||
|
height: 68px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stu-name {
|
||||||
|
margin-left: 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
letter-spacing: 0.9px;
|
||||||
|
width: 30%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-bg {
|
||||||
|
color: #FFF;
|
||||||
|
background: #6B86FF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,700 @@
|
||||||
|
<template>
|
||||||
|
<Navigation :title_name="person.reportInfo.ExamName"
|
||||||
|
:isReturn="person.studentId?4:0"
|
||||||
|
:color="'#000000'"
|
||||||
|
:bgc="'#FFFFFF'"
|
||||||
|
:isCenter="false"/>
|
||||||
|
<view class="page-bg">
|
||||||
|
<!-- 用户信息 -->
|
||||||
|
<view class="report_user" v-if="person.reportInfo.BaseInfoTitle">
|
||||||
|
<view class="report_user_info" v-if="person.reportInfo.BaseInfoTitle.ReachSubjctCount==0&&person.reportInfo.BaseInfoTitle.TargetLevelName=='民办本科'">
|
||||||
|
<text>{{person.reportInfo.BaseInfoTitle.UserName}}</text>同学,你本次考试超过专科线,还未达到民办本科线,还需继续努力哟
|
||||||
|
</view>
|
||||||
|
<view class="report_user_info" v-else>
|
||||||
|
<text>{{person.reportInfo.BaseInfoTitle.UserName}}</text>同学,
|
||||||
|
你本次考试有<text>{{person.reportInfo.BaseInfoTitle.ReachSubjctCount}}门</text>学科超过<text>
|
||||||
|
{{person.reportInfo.BaseInfoTitle.TargetLevelName}}</text>线,
|
||||||
|
<template v-if="person.reportInfo.BaseInfoTitle.LowerSubjctCount>0">还有<text>{{person.reportInfo.BaseInfoTitle.LowerSubjctCount}}门</text>未达到{{person.reportInfo.BaseInfoTitle.TargetLevelName}}线,</template>还需继续努力哦!
|
||||||
|
</view>
|
||||||
|
<view class="report_user_tag flex">
|
||||||
|
<view class="report_tag_item flex" v-for="(educa,edIndex) in person.educaList" :key="edIndex">
|
||||||
|
<view v-if="person.reportInfo.BaseInfoTitle.TargetLevelName===educa.name" class="tag_item_active">
|
||||||
|
<image src="../../static/report/book_icon.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="tag_item_active_txt" v-if="person.reportInfo.BaseInfoTitle.TargetLevelName===educa.name||person.educaActive-1===edIndex">
|
||||||
|
{{educa.name}}
|
||||||
|
</view>
|
||||||
|
<view v-else>{{educa.name}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="report_user_txt">(注: 本结论只针对于本次考试分数分析,<text>仅供参考</text>)</view>
|
||||||
|
</view>
|
||||||
|
<!-- echarts -->
|
||||||
|
<view class="report_echarts">
|
||||||
|
<view class="report_rate_title bold">
|
||||||
|
{{person.reportInfo.ExamType}} {{dateName}}
|
||||||
|
</view>
|
||||||
|
<view class="report_echart_cont" style="margin-top: 20rpx;">
|
||||||
|
<view class="cont_table" v-if="person.reportInfo.IsJuniorSchool">
|
||||||
|
<view class="table_title">
|
||||||
|
<view class="table_title_txt" style="'width:25%;'">
|
||||||
|
<view class="txt_item">类别</view>
|
||||||
|
<view class="txt_item">进退步(班/年)</view>
|
||||||
|
<view class="txt_item">等级</view>
|
||||||
|
<view class="txt_item">原卷</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="table_name">
|
||||||
|
<view class="table_name_txt" v-for="(tab, taIndex) in person.subjectScore" :key="taIndex">
|
||||||
|
<view class="txt_item">{{ tab.SubjectName }}</view>
|
||||||
|
<view class="txt_item flex">
|
||||||
|
<view class="flex">
|
||||||
|
{{ tab.ClassRankingChange }}
|
||||||
|
<image v-if="tab.ClassRankingChange<0" src="@/static/report/down_icon.png" mode=""></image>
|
||||||
|
<image v-else src="@/static/report/top_icon.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="flex">
|
||||||
|
{{' / '+tab.GradeRankingChange }}
|
||||||
|
<image v-if="tab.GradeRankingChange<0" src="@/static/report/down_icon.png" mode=""></image>
|
||||||
|
<image v-else src="@/static/report/top_icon.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="txt_item">{{ tab.Score }}</view>
|
||||||
|
<view class="txt_item">
|
||||||
|
<view class="txt_item_press" v-if="taIndex===0">
|
||||||
|
<slider disabled :value="((person.reportInfo.Score/person.reportInfo.TotalSocre)*100).toFixed(2)" activeColor="rgba(0,0,0,0)" block-color="rgba(0,0,0,0)" block-size="1"/>
|
||||||
|
</view>
|
||||||
|
<view class="txt_item_btn" v-else-if="tab.ExamJoin" @click.stop="seeTest(tab,person.reportInfo)">查看答卷</view>
|
||||||
|
<view class="txt_item_red" v-else>缺考</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="cont_table" v-else>
|
||||||
|
<view class="table_title">
|
||||||
|
<view class="table_title_txt" style="'width:25%;'">
|
||||||
|
<view class="txt_item">类别</view>
|
||||||
|
<view class="txt_item">分数<br/>(个人/年级)</view>
|
||||||
|
<view class="txt_item">进退步<br/>(班/年)</view>
|
||||||
|
<view class="txt_item">排名<br/>(班/年)</view>
|
||||||
|
<view class="txt_item">原卷</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="table_name">
|
||||||
|
<view class="table_name_txt" v-for="(tab, taIndex) in person.subjectScore" :key="taIndex">
|
||||||
|
<view class="txt_item">{{ tab.SubjectName }}</view>
|
||||||
|
<view class="txt_item">{{ tab.Score+'/'+tab.GradeScore }}</view>
|
||||||
|
<view class="txt_item flex">
|
||||||
|
<view class="flex">
|
||||||
|
{{ tab.ClassRankingChange }}
|
||||||
|
<image v-if="tab.ClassRankingChange<0" src="@/static/report/down_icon.png" mode=""></image>
|
||||||
|
<image v-else src="@/static/report/top_icon.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="flex">
|
||||||
|
{{' / '+tab.GradeRankingChange }}
|
||||||
|
<image v-if="tab.GradeRankingChange<0" src="@/static/report/down_icon.png" mode=""></image>
|
||||||
|
<image v-else src="@/static/report/top_icon.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="txt_item">{{ tab.ClassRanking+'/'+tab.GradeRanking }}</view>
|
||||||
|
<view class="txt_item">
|
||||||
|
<view class="txt_item_press" v-if="taIndex===0">
|
||||||
|
<slider disabled :value="((person.reportInfo.Score/person.reportInfo.TotalSocre)*100).toFixed(2)" activeColor="rgba(0,0,0,0)" block-color="rgba(0,0,0,0)" block-size="1"/>
|
||||||
|
</view>
|
||||||
|
<view class="txt_item_btn" v-else-if="tab.ExamJoin" @click.stop="seeTest(tab,person.reportInfo)">查看答卷</view>
|
||||||
|
<view class="txt_item_red" v-else>缺考</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="report_echart_cont" v-if="person.studentScore && person.studentScore.length > 0&&person.reportInfo.BaseInfoTitle.UserName">
|
||||||
|
<PublicLine v-if="person.studentScore && person.studentScore.length > 0&&person.reportInfo.BaseInfoTitle.UserName" :id="'studentGrade'"
|
||||||
|
:datas="person.studentScore" :studentName="person.reportInfo.BaseInfoTitle.UserName" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="person.testInfo">
|
||||||
|
<view class="report_echarts">
|
||||||
|
<view class="report_echart_cont">
|
||||||
|
<view class="report_rate_title bold">
|
||||||
|
{{person.testInfo.IntroTitle}}
|
||||||
|
</view>
|
||||||
|
<view class="report_ccc">{{person.testInfo.IntroDesc}}</view>
|
||||||
|
<view class="report_blue">{{person.testInfo.IntroFooter}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="report_echart_cont">
|
||||||
|
<view class="report_rate_title bold">
|
||||||
|
学习力测评
|
||||||
|
</view>
|
||||||
|
<view class="report_rate_score">{{person.testInfo.ReportName}}测评报告</view>
|
||||||
|
<view class="report_rate_info">
|
||||||
|
姓名:<text class="report_blue" v-if="person.reportInfo.BaseInfoTitle">{{person.reportInfo.BaseInfoTitle.UserName}}</text>
|
||||||
|
学校:<text class="report_blue">{{person.testInfo.schoolName}}</text><br/>
|
||||||
|
测评时间:<text class="report_blue">{{person.testInfo.ReportTime}}</text>
|
||||||
|
</view>
|
||||||
|
<PublicGauge v-if="person.testInfo.Score" :Title="person.testInfo.ReportName" :percentage="person.testInfo.Score" :rate="person.testInfo.exceedRate" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 领取报告 -->
|
||||||
|
<view class="report_receive">
|
||||||
|
<view class="report_receive_des">
|
||||||
|
<view class="report_blue" v-if="person.reportInfo.BaseInfoTitle">
|
||||||
|
{{person.reportInfo.BaseInfoTitle.UserName}}同学本月参加了学习能力测评——{{person.testInfo.ReportName}}测评
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
{{person.testInfo.ReportName}}测评:得分<text>{{person.testInfo.Score}}</text>分,超过<text>{{person.testInfo.exceedRate}}%</text>的同龄孩子
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
考试成绩:
|
||||||
|
<template v-if="person.reportInfo.IsJuniorSchool">
|
||||||
|
等级{{person.subjectScore[0].Score}}
|
||||||
|
</template>
|
||||||
|
<template v-else>
|
||||||
|
总分<text>{{person.reportInfo.TotalSocre}}</text>分,排名<text>{{person.reportInfo.TotalRanking}}</text>名
|
||||||
|
</template>
|
||||||
|
</view>
|
||||||
|
<view class="mar-top" v-if="person.testInfo.levelDescription">
|
||||||
|
<view class="receive_des_title">根据学习能力测评和考试成绩综合分析:</view>
|
||||||
|
<view class="receive_des">
|
||||||
|
{{person.testInfo.levelDescription}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="person.testInfo.methodDescription">
|
||||||
|
<view class="receive_des_title">建议您对孩子采用以下训练方法:</view>
|
||||||
|
<view class="receive_des">
|
||||||
|
{{person.testInfo.methodDescription}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="report_receive_btn flex">
|
||||||
|
<text @click="receiveReport">领取完整报告及训练工具</text>
|
||||||
|
</view>
|
||||||
|
<Popups :isShow="person.IsReceiveReport" :width="280" :height="360" :bgColor="'#6B86FF'">
|
||||||
|
<view class="p_cont">
|
||||||
|
<view class="popup_cont_title">
|
||||||
|
领取报告
|
||||||
|
</view>
|
||||||
|
<view class="popup_cont_pic" >
|
||||||
|
<image :show-menu-by-longpress="true" :src="person.cusSerInfo.EQImgUrl" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="popup_cont_des">
|
||||||
|
长按屏幕识别上方二维码
|
||||||
|
</view>
|
||||||
|
<view class="popup_list">
|
||||||
|
<view class="popup_item flex">
|
||||||
|
<text>客服电话</text>
|
||||||
|
<text>{{person.cusSerInfo.ServiceNumber}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="popup_item flex">
|
||||||
|
<text>教师电话</text>
|
||||||
|
<text>{{person.cusSerInfo.TeacherNumber}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</Popups>
|
||||||
|
</view>
|
||||||
|
<!-- 测评进度 -->
|
||||||
|
<view class="report_rate">
|
||||||
|
<view class="report_rate_title bold">
|
||||||
|
测评进度<text>(注:蓝色表示已完成)</text>
|
||||||
|
</view>
|
||||||
|
<view class="report_rate_list">
|
||||||
|
<view class="report_rate_item" :class="[rate.Score>0?'report_rate_blue':'']" v-for="(rate,raIndex) in person.testInfo.reports" :key="raIndex">
|
||||||
|
{{rate.ReportName}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-else class="lock_box">
|
||||||
|
<image src="@/static/report/lock_icon.png" mode=""></image>
|
||||||
|
您的孩子未完成测评<br/>
|
||||||
|
完成后解锁报告
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive, ref, watch } from 'vue'
|
||||||
|
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||||
|
import PublicLine from "@/components/echarts/publicLine.vue"
|
||||||
|
import PublicGauge from "@/components/echarts/publicGauge.vue"
|
||||||
|
import Popups from "@/components/popups/index.vue";
|
||||||
|
import Navigation from '@/components/navigation/index.vue'
|
||||||
|
import { getChangeStudent, getUserReportDetails, getTestReportData, getTestInfo } from "@/api/exam-data";
|
||||||
|
import {postRegister,getUserInfo} from "@/api/user";
|
||||||
|
let person=reactive({
|
||||||
|
// 学历
|
||||||
|
educaActive:0,
|
||||||
|
educaList:[
|
||||||
|
{name:'专科'},
|
||||||
|
{name:'民办本科'},
|
||||||
|
{name:'公办本科'},
|
||||||
|
{name:'211'},
|
||||||
|
{name:'985'},
|
||||||
|
{name:'C9'}
|
||||||
|
],
|
||||||
|
subjectScore:[], // 学生各科成绩
|
||||||
|
studentScore:[], // 学生总成绩
|
||||||
|
IsReceiveReport:false, // 是否领取报告
|
||||||
|
reportInfo:{}, // 考试报告信息
|
||||||
|
testInfo:null, // 测评报告信息
|
||||||
|
cusSerInfo:{}, // 客服信息
|
||||||
|
examId:0, // 获取考试Id
|
||||||
|
studentId:0 // 获取学生Id
|
||||||
|
})
|
||||||
|
|
||||||
|
onLoad((e)=>{
|
||||||
|
// e 获取路由参数
|
||||||
|
person.examId=e.examId
|
||||||
|
person.studentId=e.studentId
|
||||||
|
})
|
||||||
|
// 初始化加载
|
||||||
|
onShow(async ()=>{
|
||||||
|
if(person.studentId){
|
||||||
|
GetChangeStudent(person.studentId)
|
||||||
|
}else{
|
||||||
|
await GetUserReportDetails()
|
||||||
|
await GetTestReportData()
|
||||||
|
}
|
||||||
|
if(person.reportInfo.ExamName){
|
||||||
|
uni.setNavigationBarTitle({
|
||||||
|
title: person.reportInfo.ExamName
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// 查看试卷
|
||||||
|
const seeTest=(item,info)=>{
|
||||||
|
if(item.ExamJoin){
|
||||||
|
if(item.ExamSubjectId>0){
|
||||||
|
let infos={
|
||||||
|
examName:info.ExamName,
|
||||||
|
userName:info.BaseInfoTitle.UserName,
|
||||||
|
totalScore:info.IsJuniorSchool?'等级'+item.Score:item.Score+'分',
|
||||||
|
subject:item.SubjectName,
|
||||||
|
baseScore:item.BaseScore,
|
||||||
|
isJuniorSchool:info.IsJuniorSchool
|
||||||
|
}
|
||||||
|
uni.navigateTo({
|
||||||
|
url:'/pages/examTest/index?Id='+item.ExamSubjectId+'&info='+JSON.stringify(infos)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 领取报告
|
||||||
|
const receiveReport=()=>{
|
||||||
|
person.IsReceiveReport=!person.IsReceiveReport
|
||||||
|
if(!person.cusSerInfo.EQImgUrl){
|
||||||
|
GetTestInfo()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取切换学生
|
||||||
|
const GetChangeStudent = (Id) => {
|
||||||
|
getChangeStudent({studentId: Id}).then(res => {
|
||||||
|
let { Code, Data } = res
|
||||||
|
if (Code === 200 && Data) {
|
||||||
|
GetUserReportDetails()
|
||||||
|
GetTestReportData()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const dateName=ref('')
|
||||||
|
// 获取学生报告列表接口
|
||||||
|
const GetUserReportDetails = () => {
|
||||||
|
if(person.examId){
|
||||||
|
uni.showLoading({title: '加载中'});
|
||||||
|
getUserReportDetails({examId: person.examId}).then(res => {
|
||||||
|
let { Code, Data, Message } = res
|
||||||
|
if(Code===200&&Data){
|
||||||
|
setTimeout(()=>{
|
||||||
|
uni.hideLoading();
|
||||||
|
},100)
|
||||||
|
let { BaseInfo, ExamRecord, Study, Subjects }=res.Data
|
||||||
|
person.reportInfo = BaseInfo
|
||||||
|
dateName.value=person.reportInfo.StartTime.replace('-','年').replace('-','月')+'日'
|
||||||
|
person.studentScore = ExamRecord
|
||||||
|
person.subjectScore = Subjects
|
||||||
|
person.educaActive = person.educaList.findIndex(f=>{return f.name===BaseInfo.BaseInfoTitle.TargetLevelName})
|
||||||
|
}else{
|
||||||
|
uni.hideLoading();
|
||||||
|
uni.showToast({
|
||||||
|
title: Message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 获取测评报告接口
|
||||||
|
const GetTestReportData = () => {
|
||||||
|
getTestReportData({examId: person.examId}).then(res => {
|
||||||
|
let { Code, Data, Message } = res
|
||||||
|
if(Code===200&&Data){
|
||||||
|
person.testInfo=Data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 获取评测客服信息接口
|
||||||
|
const GetTestInfo = () => {
|
||||||
|
getTestInfo().then(res => {
|
||||||
|
let { Code, Data, Message } = res
|
||||||
|
if(Code===200&&Data){
|
||||||
|
person.cusSerInfo=Data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.page-bg{
|
||||||
|
padding-bottom: 40rpx;
|
||||||
|
}
|
||||||
|
.lock_box{
|
||||||
|
height: 500px;
|
||||||
|
background-image: radial-gradient(#6b84f4 0, #d3d5de 100%);
|
||||||
|
color: #fff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
text-align: center;
|
||||||
|
margin: 32rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
image{
|
||||||
|
width: 150rpx;
|
||||||
|
height: 150rpx;
|
||||||
|
margin: 0 auto 20rpx auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.cont_table{
|
||||||
|
.table_title{
|
||||||
|
font-size: 26rpx;
|
||||||
|
.table_title_txt{
|
||||||
|
display: flex;
|
||||||
|
text-align: center;
|
||||||
|
color: #6471AC;
|
||||||
|
font-weight: 600;
|
||||||
|
border-right: 2rpx solid #fff;
|
||||||
|
border-bottom: 2rpx dotted #8093d7;
|
||||||
|
padding: 20rpx 0rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
.txt_item{
|
||||||
|
width: 25%;
|
||||||
|
line-height: 35rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.table_name{
|
||||||
|
font-size: 26rpx;
|
||||||
|
text-align: center;
|
||||||
|
.table_name_txt{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
line-height: 70rpx;
|
||||||
|
.txt_item{
|
||||||
|
width: 25%;
|
||||||
|
height: 70rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #6F6F70;
|
||||||
|
justify-content: center;
|
||||||
|
white-space: nowrap;
|
||||||
|
image{
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
}
|
||||||
|
:deep(.txt_item_press){
|
||||||
|
uni-slider{
|
||||||
|
.uni-slider-handle-wrapper{
|
||||||
|
width: 120rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
background-image: linear-gradient(to right, #DBE1FF, #6B86FF);
|
||||||
|
}
|
||||||
|
.uni-slider-thumb{
|
||||||
|
background: rgba(0,0,0,0) !important;
|
||||||
|
border-radius: 0;
|
||||||
|
box-shadow: inherit !important;
|
||||||
|
top: 28rpx;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
&::after{
|
||||||
|
content: "";
|
||||||
|
width: 0 !important;
|
||||||
|
height: 0 !important;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0rpx 12rpx 12rpx 12rpx;
|
||||||
|
border-color: transparent transparent #6B86FF transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.uni-slider-track{
|
||||||
|
background: rgba(0,0,0,0) !important;
|
||||||
|
}
|
||||||
|
.uni-slider-wrapper {
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.uni-slider-tap-area{
|
||||||
|
flex: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
.txt_item_btn{
|
||||||
|
color: #6B86FF;
|
||||||
|
}
|
||||||
|
.txt_item_red{
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
:deep(.txt_item_press){
|
||||||
|
wx-slider{
|
||||||
|
border-radius: 40rpx;
|
||||||
|
width: 85% !important;
|
||||||
|
height: 20rpx !important;
|
||||||
|
background-image: linear-gradient(to right, #DBE1FF, #6B86FF) !important;
|
||||||
|
margin: 30rpx auto 0 auto;
|
||||||
|
border: 0;
|
||||||
|
.wx-slider-handle{
|
||||||
|
width: 1px;
|
||||||
|
height: 1px;
|
||||||
|
margin-top: -20rpx;
|
||||||
|
position: relative;
|
||||||
|
transform: rotate(180deg);
|
||||||
|
border: 0;
|
||||||
|
&::before{
|
||||||
|
position: absolute;
|
||||||
|
left: -45rpx;
|
||||||
|
content: "";
|
||||||
|
width: 0 !important;
|
||||||
|
height: 0 !important;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 0rpx 12rpx 12rpx 12rpx;
|
||||||
|
border-color: transparent transparent #6B86FF transparent;
|
||||||
|
border-radius: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.wx-slider-handle-wrapper{
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
.wx-slider-thumb{
|
||||||
|
box-shadow: inherit !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.report_user{
|
||||||
|
border-top: 2rpx solid #eee;
|
||||||
|
background: #ffffff;
|
||||||
|
padding: 32rpx;
|
||||||
|
margin: 0 0 40rpx 0;
|
||||||
|
.report_user_info{
|
||||||
|
color: #4A4A4A;
|
||||||
|
font-size: 30rpx;
|
||||||
|
text-indent: 2em;
|
||||||
|
text{
|
||||||
|
color: #FFA066;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.report_user_tag{
|
||||||
|
background-image: linear-gradient(to right, #DBE1FF, #6B86FF);
|
||||||
|
padding: 32rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
margin: 20rpx 0;
|
||||||
|
justify-content: space-between;
|
||||||
|
.report_tag_item{
|
||||||
|
color: #ffffff;
|
||||||
|
font-size: 22rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: center;
|
||||||
|
justify-content: center;
|
||||||
|
&:last-child{
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.tag_item_active_txt{
|
||||||
|
font-size: 28rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.tag_item_active{
|
||||||
|
position: relative;
|
||||||
|
// &::before{
|
||||||
|
// position: absolute;
|
||||||
|
// top: 18rpx;
|
||||||
|
// left: -32rpx;
|
||||||
|
// content: "";
|
||||||
|
// width: 0 !important;
|
||||||
|
// height: 0 !important;
|
||||||
|
// border-style: solid;
|
||||||
|
// border-width: 0rpx 10rpx 18rpx 10rpx;
|
||||||
|
// border-color: transparent transparent #fff transparent;
|
||||||
|
// border-radius: 0;
|
||||||
|
// }
|
||||||
|
image{
|
||||||
|
position: absolute;
|
||||||
|
top: -14rpx;
|
||||||
|
left: -42rpx;
|
||||||
|
width: 28rpx;
|
||||||
|
height: 26rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.report_user_txt{
|
||||||
|
color: #FF0000;
|
||||||
|
font-size: 24rpx;
|
||||||
|
text-align: right;
|
||||||
|
text{
|
||||||
|
font-size: 26rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.report_echarts{
|
||||||
|
margin: 0 32rpx;
|
||||||
|
.report_echart_cont{
|
||||||
|
border-radius: 20rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
margin-top: 40rpx;
|
||||||
|
padding: 30rpx 30rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
:deep(.cont_table){
|
||||||
|
.uni_table{
|
||||||
|
.uni-tr{
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.report_receive{
|
||||||
|
margin: 30rpx 30rpx;
|
||||||
|
.report_receive_des{
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #736F6D;
|
||||||
|
line-height: 45rpx;
|
||||||
|
.mar-top{
|
||||||
|
margin-top: 40rpx;
|
||||||
|
}
|
||||||
|
.receive_des_title{
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.receive_des{
|
||||||
|
text-indent: 2em;
|
||||||
|
}
|
||||||
|
text{
|
||||||
|
color: #FFA755;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.report_receive_btn{
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 60rpx;
|
||||||
|
text{
|
||||||
|
background: #6B86FF;
|
||||||
|
color: #ffffff;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
padding: 20rpx 100rpx;
|
||||||
|
text-align: center;
|
||||||
|
letter-spacing: 4rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.p_cont{
|
||||||
|
color: #fff;
|
||||||
|
font-size: 28rpx;
|
||||||
|
.popup_cont_title{
|
||||||
|
font-size: 38rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
.popup_cont_pic{
|
||||||
|
margin: 40rpx auto 20rpx auto;
|
||||||
|
background: #fff;
|
||||||
|
width: 380rpx;
|
||||||
|
height: 380rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
image{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.popup_cont_des{
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
.popup_list{
|
||||||
|
padding: 0rpx 20rpx;
|
||||||
|
margin-top: 70rpx;
|
||||||
|
.popup_item{
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 12rpx 0;
|
||||||
|
border-bottom: 2rpx solid rgba(255, 255, 255, 0.21);
|
||||||
|
&:last-child{
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.report_rate_score{
|
||||||
|
font-size: 30rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 38rpx;
|
||||||
|
margin: 30rpx 0;
|
||||||
|
.score_blue{
|
||||||
|
color: #152FA0;
|
||||||
|
}
|
||||||
|
text{
|
||||||
|
font-size: 28rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.report_rate_info{
|
||||||
|
font-size: 28rpx;
|
||||||
|
line-height: 38rpx;
|
||||||
|
margin-bottom: 28rpx;
|
||||||
|
text{
|
||||||
|
margin-right: 40rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.report_rate_title{
|
||||||
|
font-size: 32rpx;
|
||||||
|
text{
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.report_ccc{
|
||||||
|
color: #787878;
|
||||||
|
}
|
||||||
|
.report_blue{
|
||||||
|
color: #6B86FF;
|
||||||
|
}
|
||||||
|
.report_orange{
|
||||||
|
color: #FFA755;
|
||||||
|
}
|
||||||
|
.report_rate{
|
||||||
|
margin: 0 32rpx;
|
||||||
|
padding: 30rpx;
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
.report_rate_list{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
font-size: 28rpx;
|
||||||
|
.report_rate_item{
|
||||||
|
margin-top: 20rpx;
|
||||||
|
margin-right: 30rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
.report_rate_blue{
|
||||||
|
color: #6B86FF !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,261 @@
|
||||||
|
<template>
|
||||||
|
<Navigation :title_name="person.exam.examName"
|
||||||
|
:isReturn="0"
|
||||||
|
:color="'#000000'"
|
||||||
|
:bgc="'#FFFFFF'"
|
||||||
|
:isCenter="false" />
|
||||||
|
<view class="page-bg">
|
||||||
|
<view class="test_top">
|
||||||
|
<text>{{person.exam.userName}}</text>
|
||||||
|
<text>{{person.exam.subject}}</text>
|
||||||
|
<text>{{person.exam.totalScore}}</text>
|
||||||
|
<text class="top-score" v-if="person.exam.isJuniorSchool">{{person.exam.baseScore?person.exam.baseScore+'分':'0分'}}</text>
|
||||||
|
<text>{{person.testData.length>0?person.btnActive+1:person.btnActive}}/{{person.testData.length}}页</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="person.testData&&person.testData.length>0">
|
||||||
|
<movable-area class="movable_box" v-if="person.itemExam.PaperType===1">
|
||||||
|
<movable-view :style="{height:person.itemExam.Width*person.scaleHeight+'px;'}" direction="all" @scale="onScale" scale scale-min="0.5" scale-max="4" >
|
||||||
|
<view class="test_center" :style="{transform:'rotate(90deg);',width:person.itemExam.Width*person.scaleHeight+'px;',height:person.itemExam.Height*person.scaleHeight+'px;'}">
|
||||||
|
<image :style="{width:person.itemExam.Width*person.scaleHeight+'px;',height:person.itemExam.Height*person.scaleHeight+'px;'}" :src="person.itemExam.ImageUrl" mode=""></image>
|
||||||
|
<view class="page_item flex" v-for="(quest,quIndex) in person.itemExam.Questions" :key="quIndex"
|
||||||
|
:style="{
|
||||||
|
top:quest.Y*person.scaleHeight +'px;',
|
||||||
|
left:quest.X*person.scaleHeight+'px;',
|
||||||
|
width:quest.Width*person.scaleHeight+'px;',
|
||||||
|
height:quest.Height*person.scaleHeight+'px;'}">
|
||||||
|
<view class="text_flex flex" :style="{fontSize:quest.isObj?'24rpx':''}">
|
||||||
|
<text class="color_red">{{quest.score}}</text>/
|
||||||
|
<text class="color_blue">{{quest.totalScore}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</movable-view>
|
||||||
|
</movable-area>
|
||||||
|
<movable-area class="movable_box" v-else-if="person.itemExam.PaperType===2">
|
||||||
|
<movable-view :style="{height:person.itemExam.Height*person.scaleWidth+'px;'}" direction="all" @scale="onScale" scale scale-min="0.5" scale-max="4" >
|
||||||
|
<view class="test_center" :style="{width:person.itemExam.Width*person.scaleWidth+'px;',height:person.itemExam.Height*person.scaleWidth+'px;'}">
|
||||||
|
<image data-type="image" :src="person.itemExam.ImageUrl" mode=""></image>
|
||||||
|
<view class="page_item flex" v-for="(quest,quIndex) in person.itemExam.Questions" :key="quIndex"
|
||||||
|
:style="{
|
||||||
|
top:quest.Y*person.scaleWidth +'px;',
|
||||||
|
left:quest.X*person.scaleWidth+'px;',
|
||||||
|
width:quest.Width*person.scaleWidth+'px;',
|
||||||
|
height:quest.Height*person.scaleWidth+'px;'}">
|
||||||
|
<view class="text_flex flex" :style="{fontSize:quest.isObj?'24rpx':''}">
|
||||||
|
<text class="color_red">{{quest.score}}</text>/
|
||||||
|
<text class="color_blue">{{quest.totalScore}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</movable-view>
|
||||||
|
</movable-area>
|
||||||
|
</view>
|
||||||
|
<view v-else>
|
||||||
|
<view class="empty_box">
|
||||||
|
<image src="../../static/null_icon.png" mode=""></image>
|
||||||
|
<text>暂无数据~</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="test_bottom flex">
|
||||||
|
<view class="bottom_list">
|
||||||
|
<view class="btn_list flex" v-if="person.itemLength>1">
|
||||||
|
<view class="btn_item" :class="[person.btnActive===index?'btn_item_active':'']" v-for="(item,index) in person.itemLength" :key="index" @click="changeBtn(index)">
|
||||||
|
{{item}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bottom_list flex">
|
||||||
|
<view class="bottom_item flex">
|
||||||
|
<text class="bottom_item_red"></text>
|
||||||
|
我的得分
|
||||||
|
</view>
|
||||||
|
<view class="bottom_item flex">
|
||||||
|
<text class="bottom_item_blue"></text>
|
||||||
|
年级平均分
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { nextTick, reactive, ref, watch } from 'vue'
|
||||||
|
import { onLoad, onShow } from "@dcloudio/uni-app";
|
||||||
|
import Navigation from '@/components/navigation/index.vue'
|
||||||
|
import { getTestImgs } from "@/api/exam-data";
|
||||||
|
|
||||||
|
let person=reactive({
|
||||||
|
testData:[],
|
||||||
|
exam:{},
|
||||||
|
btnActive:0,
|
||||||
|
itemExam:{},
|
||||||
|
itemLength:0,
|
||||||
|
scaleWidth:0, // 根据宽的缩放比例
|
||||||
|
scaleHeight:0
|
||||||
|
})
|
||||||
|
onLoad((e)=>{
|
||||||
|
// e 获取路由参数
|
||||||
|
person.exam=JSON.parse(e.info)
|
||||||
|
GetTestImgs(e.Id)
|
||||||
|
load()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 初始值
|
||||||
|
const load=()=>{
|
||||||
|
if(person.testData&&person.testData.length>0){
|
||||||
|
person.itemExam=person.testData[person.btnActive]
|
||||||
|
person.itemLength=person.testData.length
|
||||||
|
// 获取屏幕宽
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success:(res)=> {
|
||||||
|
person.scaleWidth = res.windowWidth/person.itemExam.Width
|
||||||
|
person.scaleHeight = res.windowWidth/person.itemExam.Height
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取学生答卷
|
||||||
|
const GetTestImgs=(Id)=> {
|
||||||
|
getTestImgs({examSubjectId: Id}).then(res => {
|
||||||
|
let { Code, Data, Message } = res
|
||||||
|
if(Code===200&&Data){
|
||||||
|
person.testData=Data
|
||||||
|
load()
|
||||||
|
}else{
|
||||||
|
uni.showToast({
|
||||||
|
title: Message,
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const changeBtn=(index)=>{
|
||||||
|
person.btnActive=index
|
||||||
|
if(person.testData&&person.testData.length>0){
|
||||||
|
person.itemExam=person.testData[index]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.test_top{
|
||||||
|
padding: 0 32rpx;
|
||||||
|
height: 80rpx;
|
||||||
|
line-height: 80rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #888888;
|
||||||
|
text{
|
||||||
|
margin-right:30rpx;
|
||||||
|
}
|
||||||
|
.top-score{
|
||||||
|
color: red;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.page-bg{
|
||||||
|
height: calc(100vh - 230rpx);
|
||||||
|
}
|
||||||
|
.movable_box{
|
||||||
|
width: 375px;
|
||||||
|
height: calc(100vh - 340rpx);
|
||||||
|
overflow: hidden;
|
||||||
|
movable-view{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.test_center{
|
||||||
|
position: relative;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
image{
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
.page_item{
|
||||||
|
position: absolute;
|
||||||
|
border: 2rpx solid red;
|
||||||
|
.text_flex{
|
||||||
|
position: absolute;
|
||||||
|
right: 10rpx;
|
||||||
|
top: 10rpx;
|
||||||
|
font-size: 36rpx;
|
||||||
|
line-height: 30rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
text{
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.test_bottom{
|
||||||
|
background: #fff;
|
||||||
|
height: 80rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
text-align: center;
|
||||||
|
border-top: 2rpx solid #eee;
|
||||||
|
justify-content: space-between;
|
||||||
|
z-index: 999;
|
||||||
|
.bottom_list{
|
||||||
|
padding: 25rpx 32rpx;
|
||||||
|
.btn_list{
|
||||||
|
padding: 10rpx 0;
|
||||||
|
max-width: 350rpx;
|
||||||
|
display: -webkit-box;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow-x: scroll;
|
||||||
|
-webkit-overflow-scrolling:touch; // 允许独立的滚动区域和触摸回弹
|
||||||
|
.btn_item{
|
||||||
|
border: 2rpx solid #999;
|
||||||
|
color: #999;
|
||||||
|
margin-right: 25rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
line-height: 60rpx;
|
||||||
|
&:last-child{
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.btn_item_active{
|
||||||
|
background: #6B86FF !important;
|
||||||
|
color: #fff !important;
|
||||||
|
border: 2rpx solid #6B86FF !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.bottom_item{
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #888888;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
white-space: nowrap;
|
||||||
|
text{
|
||||||
|
width: 24rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-right: 8rpx;
|
||||||
|
}
|
||||||
|
.bottom_item_red{
|
||||||
|
background: #FF2929;
|
||||||
|
}
|
||||||
|
.bottom_item_blue{
|
||||||
|
background: #6B86FF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.color_red{
|
||||||
|
color: #FF2929;
|
||||||
|
}
|
||||||
|
.color_blue{
|
||||||
|
color: #6B86FF;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,90 @@
|
||||||
|
<template>
|
||||||
|
<view class="warpper-login">
|
||||||
|
<view class="img_loading"></view>
|
||||||
|
<view class="text">登录中···</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
getUserLogin,
|
||||||
|
getConfig
|
||||||
|
} from "@/api/user";
|
||||||
|
import {onShow } from "@dcloudio/uni-app";
|
||||||
|
onShow(()=>{
|
||||||
|
uni.login({
|
||||||
|
provider: 'weixin', //使用微信登录
|
||||||
|
success: (loginRes) => {
|
||||||
|
getUserLogin(loginRes.code).then((res :any) => {
|
||||||
|
console.log('APP.vue请求登录:',res);
|
||||||
|
if (res.Code == 200) {
|
||||||
|
uni.setStorageSync('TokenType', res.Data.TokenType)
|
||||||
|
uni.setStorageSync('HAS_STUDENT', res.Data.user.HasStudent)
|
||||||
|
uni.setStorageSync('HAS_BINDSTUDENT', res.Data.user.BindMobile)
|
||||||
|
if (res.Data.AccessToken) {
|
||||||
|
uni.setStorageSync('token', res.Data.AccessToken)
|
||||||
|
uni.navigateBack()
|
||||||
|
} else {
|
||||||
|
uni.setStorageSync('XCXID', res.Data.xcxId)
|
||||||
|
getConfig().then((resCig:any) => {
|
||||||
|
console.log('公众号AppId', resCig);
|
||||||
|
let url = 'https://mk-wxauth.23544.com'
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/webview/webview?appId=${resCig.Data.gzh.AppId}&url=${url}`
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.log('denglushibai', res.Code);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page{
|
||||||
|
font-family: 'PingFang SC';
|
||||||
|
border: 0 !important;
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
.warpper-login{
|
||||||
|
width: 100%;
|
||||||
|
height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background: rgba(0 , 0, 0, 0.5);
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.img_loading{
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background: url('@/static/login_loading.png');
|
||||||
|
background-size: 100% 100%;
|
||||||
|
animation: runLoginMove 2s infinite linear;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
.text{
|
||||||
|
color: #fff;
|
||||||
|
font-family: PingFang SC;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: 0.96px;
|
||||||
|
margin-bottom: 200px;
|
||||||
|
}
|
||||||
|
@keyframes runLoginMove {
|
||||||
|
0%{
|
||||||
|
transform: rotate(0turn);
|
||||||
|
}
|
||||||
|
50%{
|
||||||
|
transform: rotate(0.5turn);
|
||||||
|
}
|
||||||
|
100%{
|
||||||
|
transform: rotate(1turn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,672 @@
|
||||||
|
<template>
|
||||||
|
<Navigation :title_name="'个人中心'" :isReturn="person.userList&&person.userList.length>0?1:3"
|
||||||
|
:returnIcon="'../../static/education/add_user.png'" :color="'#000000'" :bgc="'#FFFFFF'"
|
||||||
|
@iconClick="jumpAddStudent" :isCenter="true" />
|
||||||
|
<view v-if="person.userList&&person.userList.length>0">
|
||||||
|
<view class="ech">
|
||||||
|
<view class="card-wrapper">
|
||||||
|
<view class="card-scroll">
|
||||||
|
<view v-for="(item,index) in person.userList" :key="index">
|
||||||
|
<CurrItem :datas="item" @onOpenStu="getOpenStu(item,index)" @onUnBind="getUnBind(item)"
|
||||||
|
:isChange="false" :bgIndex="index" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="option-list">
|
||||||
|
<view class="option-item" v-for="(op,opIndex) in person.optionList" :key="opIndex"
|
||||||
|
@click.stop="toRelated(op,opIndex)">
|
||||||
|
<image :src="op.icon" mode=""></image>
|
||||||
|
<view class="option-item-name">{{op.name}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 用户信息弹窗 -->
|
||||||
|
<view class="dio" v-if="showChangeStudent">
|
||||||
|
<view class="dio-contain">
|
||||||
|
<view class="dio-padding">
|
||||||
|
<view class="center" :style="{background:stuInfoBackground[backIndex]}">
|
||||||
|
<image src="https://minio.23544.com:9010/data-center/gzh/Avatar.png" mode=""></image>
|
||||||
|
<view class="stu-name">{{showLookStudentInfo.name}}</view>
|
||||||
|
</view>
|
||||||
|
<view class="id-card">
|
||||||
|
<view class="number">{{showLookStudentInfo.number}}</view>
|
||||||
|
<view class="look-btn" :style="{color:stuInfoBackground[backIndex]}" @click="seePhone">查看</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="cancel" @tap="showChangeStudent=false"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 联系客服弹窗 -->
|
||||||
|
<Popups :isShow="person.isShowService" :bgColor="'#fff'">
|
||||||
|
<view style="width: 250px;display: flex;flex-direction: column;align-items: center;">
|
||||||
|
<view class="popup_cont_des" style="font-size: 20px;margin-top: 25px;">
|
||||||
|
{{person.phoneNum}}
|
||||||
|
</view>
|
||||||
|
<view class="popup_add_btn">
|
||||||
|
<button class="flex" @tap="connectServe"
|
||||||
|
style="font-size: 16px;height: 35px;line-height: 35px;width: 100%;">
|
||||||
|
<image src="@/static/education/phone_icon.png" mode=""></image>
|
||||||
|
联系客服
|
||||||
|
</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</Popups>
|
||||||
|
</view>
|
||||||
|
<view v-else>
|
||||||
|
<view class="empty_box">
|
||||||
|
<image src="@/static/null_icon.png" mode=""></image>
|
||||||
|
<text>暂无学生个人信息~</text>
|
||||||
|
</view>
|
||||||
|
<view class="add_btn">
|
||||||
|
<button open-type="getPhoneNumber" v-if="!showReactivePhone" @getphonenumber="getPhoneNumber">添加学生</button>
|
||||||
|
<button @tap="jumpAddStudent" v-else>添加学生</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 短信验证弹窗 -->
|
||||||
|
<Popups :isShow="showDioUnbindMseeage" :width="260" height="auto" :bgColor="'#fff'"
|
||||||
|
@cancelBtn="showDioUnbindMseeage=false">
|
||||||
|
<view class="p_cont">
|
||||||
|
<view class="popup_cont_title">
|
||||||
|
短信验证
|
||||||
|
</view>
|
||||||
|
<view class="popup_cont_list">
|
||||||
|
<view class="cont_list_item1">
|
||||||
|
<view style="font-size: 18px;">向{{unBindPhone}}发送验证信息<br />请输入验证码</view>
|
||||||
|
<view class="flex">
|
||||||
|
<input v-for="(item,index) in sendYZMCode" @input="inputLastNumber(index,$event)" :key="index"
|
||||||
|
:value="item.name" :focus="item.isFocus" @blur="preventFocus(index,$event)" @click="messageFocus(index,$event)"
|
||||||
|
placeholder-style="color:#BDBDBD;" type="number" maxlength="1"
|
||||||
|
:class="{'border-indey-message':item.isFocus,'border-error':errroYZM}"
|
||||||
|
:selection-start="(item.isFocus)?0:-1" :selection-end="(item.isFocus)?item.name.length:-1"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="popup_cont_tag flex">
|
||||||
|
<button v-if="timeLast>0" class="send-btn">{{timeLast}}秒后重发</button>
|
||||||
|
<button v-else @click="retrieAgain" class="send-btn"
|
||||||
|
style="font-size: 16px;">{{showMessageText?'再次获取':'获取验证码'}}</button>
|
||||||
|
</view>
|
||||||
|
<view class="popup_add_btn">
|
||||||
|
<button @click="okClickMessage" class="massage-btn" style="font-size: 18px;">确认</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</Popups>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
ref,
|
||||||
|
reactive,
|
||||||
|
onMounted,
|
||||||
|
watch,
|
||||||
|
nextTick
|
||||||
|
} from "vue";
|
||||||
|
import Popups from "@/components/popups/index.vue";
|
||||||
|
import CurrItem from "@/components/currItem/index.vue";
|
||||||
|
import {
|
||||||
|
getUserInfo,
|
||||||
|
getUserLogin,
|
||||||
|
getUserPhone,
|
||||||
|
getConfig,
|
||||||
|
postRegister,
|
||||||
|
getbindstudentList,
|
||||||
|
getSTudyReportInfo,
|
||||||
|
putUnBind,
|
||||||
|
LookStudentInfo,
|
||||||
|
bindMobile,
|
||||||
|
getSendTelphoneCode
|
||||||
|
} from "@/api/user";
|
||||||
|
import {
|
||||||
|
onShow,
|
||||||
|
onHide
|
||||||
|
} from "@dcloudio/uni-app";
|
||||||
|
import Navigation from '@/components/navigation/index.vue'
|
||||||
|
|
||||||
|
const showDioUnbindMseeage = ref(false) //解绑用户
|
||||||
|
const showMessageText = ref(false) //解绑倒计时显示文字
|
||||||
|
const unBindPhone = ref('')
|
||||||
|
const timeLast = ref(0)
|
||||||
|
const unBindParams = { //解绑用户参数
|
||||||
|
"StudentId": 0,
|
||||||
|
"Mobile": "0",
|
||||||
|
"SmsId": "0",
|
||||||
|
"SmsCode": "0"
|
||||||
|
}
|
||||||
|
const errroYZM=ref(false) //错误短信边框提示
|
||||||
|
const sendYZMCode = ref([ //短信验证6位数字
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
])
|
||||||
|
let person = reactive({
|
||||||
|
phoneNum: '18812545252',
|
||||||
|
phoneNumAll: '',
|
||||||
|
userList: [], // 用户列表
|
||||||
|
optionList: [{
|
||||||
|
name: '联系客服',
|
||||||
|
icon: '../../static/education/phone.png'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '关于',
|
||||||
|
icon: '../../static/education/about.png'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
isShowService: false, // 是否显示联系客服
|
||||||
|
currStudent: {} // 当前学生
|
||||||
|
})
|
||||||
|
const showLookStudentInfo = reactive < {
|
||||||
|
number: string,
|
||||||
|
name: string
|
||||||
|
} > ({})
|
||||||
|
const webSrc = ref('') //webview 换取code 的UR了地址
|
||||||
|
const jumpHasConnentStudent = ref(false) //是否已有关联学生
|
||||||
|
const appId = ref('') //appId
|
||||||
|
const showStudentList = ref(false)
|
||||||
|
const showReactivePhone = ref(false) //和本机互动,展示是否授权获取手机号
|
||||||
|
const preventFocus = (index) => {
|
||||||
|
sendYZMCode.value[index].isFocus = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const focstState=ref(false)
|
||||||
|
//输入框自动失焦获取聚焦
|
||||||
|
const inputLastNumber = (index, event) => {
|
||||||
|
sendYZMCode.value[index].name = event.detail.value
|
||||||
|
if(!focstState.value){
|
||||||
|
if (sendYZMCode.value[index].name) {
|
||||||
|
if (index < 5) {
|
||||||
|
sendYZMCode.value[index + 1].isFocus = true
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if (index > 0) {
|
||||||
|
sendYZMCode.value[index - 1].isFocus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
focstState.value=false //点击状态未真
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const messageFocus=(index,event)=>{ //短信框输入聚焦
|
||||||
|
let name = sendYZMCode.value[index].name
|
||||||
|
if(!name){
|
||||||
|
focstState.value=false //点击状态未真
|
||||||
|
}else{
|
||||||
|
focstState.value=true //点击状态未真
|
||||||
|
}
|
||||||
|
errroYZM.value=false //关闭红色错误弹窗
|
||||||
|
sendYZMCode.value[index].isFocus=true
|
||||||
|
}
|
||||||
|
// 再次获取短信验证
|
||||||
|
const showTimer = ref(true) //是否60秒之后再次获取短信验证码
|
||||||
|
const timer = ref(0)
|
||||||
|
const retrieAgain = () => {
|
||||||
|
if (showTimer.value) {
|
||||||
|
showTimer.value = false
|
||||||
|
// let telephone = uni.getStorageSync('USER_PHONE')
|
||||||
|
showMessageText.value = true
|
||||||
|
timeLast.value = 60
|
||||||
|
timer.value = setInterval(() => {
|
||||||
|
timeLast.value--; // 时间减一秒
|
||||||
|
if (timeLast.value <= 0) { // 当倒计时结束时
|
||||||
|
clearInterval(timer.value); // 停止计时器
|
||||||
|
showTimer.value = true
|
||||||
|
}
|
||||||
|
}, 1000); // 每秒执行一次
|
||||||
|
console.log(unBindPhone.value);
|
||||||
|
getSendTelphoneCode(unBindPhone.value, 2).then(res => {
|
||||||
|
console.log(res);
|
||||||
|
if (res.Code == 200) {
|
||||||
|
unBindParams.SmsId = res.Data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const okClickMessage = () => {
|
||||||
|
let messageCode = ''
|
||||||
|
sendYZMCode.value.forEach(item => {
|
||||||
|
messageCode += item.name
|
||||||
|
})
|
||||||
|
unBindParams.SmsCode = messageCode
|
||||||
|
putUnBind(unBindParams).then(res => {
|
||||||
|
console.log(res);
|
||||||
|
if (res.Code == 200) {
|
||||||
|
showDioUnbindMseeage.value = false
|
||||||
|
getStudentList() //重新刷新拉取学生列表
|
||||||
|
} else {
|
||||||
|
errroYZM.value=true
|
||||||
|
uni.showToast({
|
||||||
|
title:res.Message,
|
||||||
|
position:'bottom'
|
||||||
|
});
|
||||||
|
sendYZMCode.value.forEach(item => {
|
||||||
|
item.name=''
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 解绑
|
||||||
|
const getUnBind = (item) => {
|
||||||
|
showDioUnbindMseeage.value = true
|
||||||
|
errroYZM.value=false
|
||||||
|
LookStudentInfo(item.Id).then(res => {
|
||||||
|
unBindParams.StudentId = item.Id
|
||||||
|
unBindParams.Mobile = res.Data.Telephone
|
||||||
|
unBindPhone.value = res.Data.Telephone
|
||||||
|
})
|
||||||
|
sendYZMCode.value.forEach(item => {
|
||||||
|
item.name = ''
|
||||||
|
})
|
||||||
|
}
|
||||||
|
onShow(() => {
|
||||||
|
getUserInfo().then(res => {
|
||||||
|
console.log('用户信息', res);
|
||||||
|
showReactivePhone.value = res.Data.BindMobile
|
||||||
|
})
|
||||||
|
getStudentList()
|
||||||
|
})
|
||||||
|
|
||||||
|
//查看
|
||||||
|
const showChangeStudent = ref(false)
|
||||||
|
const stuInfoBackground = ['#6B86FF', '#45CB9F', '#22C1F2']
|
||||||
|
const backIndex = ref(0)
|
||||||
|
const getOpenStu = (item, index) => {
|
||||||
|
showChangeStudent.value = true
|
||||||
|
person.currStudent = item
|
||||||
|
backIndex.value = index % 3
|
||||||
|
LookStudentInfo(item.Id).then(res => {
|
||||||
|
console.log(res);
|
||||||
|
showLookStudentInfo.name = res.Data.RealName
|
||||||
|
person.phoneNumAll = res.Data.Telephone
|
||||||
|
showLookStudentInfo.number = res.Data.Telephone.replace(res.Data.Telephone.substring(3, 7), '****')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 号码查看
|
||||||
|
const seePhone = () => {
|
||||||
|
showLookStudentInfo.number = person.phoneNumAll
|
||||||
|
}
|
||||||
|
// 跳转关于
|
||||||
|
const toRelated = (item, index) => {
|
||||||
|
if (item.name === '关于') {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pages/userRelated/index`
|
||||||
|
})
|
||||||
|
} else if (item.name === '联系客服') {
|
||||||
|
person.isShowService = !person.isShowService
|
||||||
|
6000().then(res => {
|
||||||
|
console.log(res);
|
||||||
|
if (res.Code == 200) {
|
||||||
|
person.phoneNum = res.Data.ServiceNumber
|
||||||
|
} else {
|
||||||
|
uni.showToast({
|
||||||
|
title: '暂无客服'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加学生跳转
|
||||||
|
const toAddStudent = (item, index) => {
|
||||||
|
console.log(99999);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//获取用户本机手机号
|
||||||
|
const getPhoneNumber = (e) => {
|
||||||
|
console.log(111, e.detail.code);
|
||||||
|
if (e.detail.errMsg == "getPhoneNumber:ok") {
|
||||||
|
bindMobile(e.detail.code).then(res => {
|
||||||
|
if (res.Code == 200) {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/userAddStudent/index'
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
console.log('未授权手机号')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const jumpAddStudent = (e) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/userAddStudent/index'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 获取学生列表方法
|
||||||
|
const getStudentList = () => {
|
||||||
|
getbindstudentList().then(res => {
|
||||||
|
console.log('学生列表', res);
|
||||||
|
if (res.Code == 200) {
|
||||||
|
person.userList = res.Data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//监听获取token之后 发送请求学生列表
|
||||||
|
watch(() => showStudentList.value, () => {
|
||||||
|
console.log(showStudentList.value);
|
||||||
|
if (showStudentList.value) {
|
||||||
|
getStudentList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
//联系客服
|
||||||
|
const connectServe = () => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: person.phoneNum
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.empty_box {
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
page {
|
||||||
|
overflow: hidden;
|
||||||
|
position: inherit !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_cont {
|
||||||
|
width: 211px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add_btn {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ech {
|
||||||
|
width: 100vw;
|
||||||
|
position: relative;
|
||||||
|
top: 0px;
|
||||||
|
margin-bottom: 50px;
|
||||||
|
|
||||||
|
.card-wrapper {
|
||||||
|
background: #F5F5F5;
|
||||||
|
padding: 10px 20px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-list {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
.option-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #3D425B;
|
||||||
|
font-size: 14px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: 0.72px;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-bottom: 1px solid #ECECEC;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
border-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.option-item-name {
|
||||||
|
width: 92%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dio {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100%;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
background: rgba(0, 0, 0, 0.42);
|
||||||
|
z-index: 99;
|
||||||
|
|
||||||
|
.dio-contain {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
top: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.dio-padding {
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #FFF;
|
||||||
|
padding: 40rpx;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel {
|
||||||
|
margin-top: 20px;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
background: url('@/static/education/cancel.png');
|
||||||
|
background-size: 100% 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: 250px;
|
||||||
|
height: 200px;
|
||||||
|
border-radius: 10px;
|
||||||
|
background: #6B86FF;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 90px;
|
||||||
|
height: 90px;
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stu-name {
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0.72px;
|
||||||
|
margin-top: 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.id-card {
|
||||||
|
width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px 0 0 0;
|
||||||
|
color: #3D425B;
|
||||||
|
font-family: PingFang SC;
|
||||||
|
font-size: 18px;
|
||||||
|
font-style: normal;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: normal;
|
||||||
|
letter-spacing: 0.72px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.look-btn {
|
||||||
|
color: #6B86FF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-add {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
position: absolute;
|
||||||
|
left: 10px;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p_cont {
|
||||||
|
// padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
|
||||||
|
.popup_cont_pic {
|
||||||
|
margin: 40rpx auto 20rpx auto;
|
||||||
|
background: #fff;
|
||||||
|
width: 140rpx;
|
||||||
|
height: 140rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_add_btn {
|
||||||
|
button {
|
||||||
|
width: 45%;
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
width: 55%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_cont_title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
color: #575757;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_cont_tag {
|
||||||
|
justify-content: flex-end;
|
||||||
|
width: 100%;
|
||||||
|
text-align: right;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: 2rpx solid #A5B5FA;
|
||||||
|
color: #A5B5FA;
|
||||||
|
font-size: 24rpx;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
background: #fff;
|
||||||
|
height: 45rpx;
|
||||||
|
line-height: 45rpx;
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
margin-left: 20rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_cont_list {
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
.cont_list_item {
|
||||||
|
font-size: 28rpx;
|
||||||
|
background: #F8F9FF;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
padding: 32rpx;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
input {
|
||||||
|
width: 99%;
|
||||||
|
border: 0;
|
||||||
|
padding: 10rpx 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: 2rpx solid #9C9C9C;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
width: 16.6%;
|
||||||
|
padding: 15rpx 0;
|
||||||
|
color: #2C2C2C;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cont_list_item1 {
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: 2rpx solid #9C9C9C;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
width: 16.6%;
|
||||||
|
padding: 15rpx 0;
|
||||||
|
color: #2C2C2C;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.massage-btn {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 40px !important;
|
||||||
|
line-height: 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-btn {
|
||||||
|
width: 50% !important;
|
||||||
|
height: 30px !important;
|
||||||
|
line-height: 30px !important;
|
||||||
|
}
|
||||||
|
.border-indey-message{
|
||||||
|
border: 3px solid skyblue !important;
|
||||||
|
}
|
||||||
|
.border-error{
|
||||||
|
border: 1px solid #FF0000 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,759 @@
|
||||||
|
<template>
|
||||||
|
<Navigation :title_name="'添加学生'" :isReturn="0" :color="'#000000'" :bgc="'#FFFFFF'" :isCenter="true" />
|
||||||
|
<view class="add_phone">
|
||||||
|
<view class="input_des text_right" v-if="!person.studentInfo.name">请输入办理智慧校园套餐的手机号</view>
|
||||||
|
<view class="add_phone_input flex">
|
||||||
|
<view class="input_name">
|
||||||
|
<text style="font-size:20px;">学生账号:</text>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<text v-if="!person.studentInfo.name" class="input_des">(学生绑定手机号)</text>
|
||||||
|
</view>
|
||||||
|
<view class="showAccountNumber">
|
||||||
|
{{person.keyword.length}}/11
|
||||||
|
</view>
|
||||||
|
<input placeholder-style="color:#BDBDBD;" type="number" maxlength="11" v-model="person.keyword" @focus="focusBtn" focus
|
||||||
|
placeholder="请输入手机号" />
|
||||||
|
<svg @click="clearBtn" v-if="person.clearbtn" t="1669974117863" class="icon" viewBox="0 0 1024 1024"
|
||||||
|
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3497" width="20" height="20">
|
||||||
|
<path
|
||||||
|
d="M687.603949 656.994302 541.10027 510.457878 687.603949 363.943966c8.829086-8.840342 8.829086-23.122627 0-31.961946-8.850575-8.840342-23.13286-8.840342-31.962969 0L509.138324 478.495932 362.623389 331.980997c-8.840342-8.818853-23.122627-8.818853-31.962969 0-8.840342 8.840342-8.840342 23.144116 0 31.984459l146.493445 146.514935L330.638931 656.994302c-8.819876 8.830109-8.819876 23.133883 0 31.962969 8.840342 8.829086 23.144116 8.829086 31.984459 0l146.514935-146.514935 146.502655 146.514935c8.830109 8.829086 23.112394 8.829086 31.962969 0C696.433034 680.129208 696.45657 665.824411 687.603949 656.994302z"
|
||||||
|
p-id="3498" fill="#bfbfbf"></path>
|
||||||
|
<path
|
||||||
|
d="M938.362063 510.457878c0-237.061161-192.174857-429.234995-429.247274-429.234995-237.062184 0-429.246251 192.173834-429.246251 429.234995 0 237.083673 192.185091 429.257507 429.246251 429.257507 97.345072 0 186.435133-33.110095 258.440074-87.677898 2.958378-3.354398 4.900613-7.636934 4.900613-12.449543 0-10.506285-8.521071-19.026332-19.027355-19.026332-5.431709 0-10.287297 2.162246-13.752212 5.826705l-0.2415 0c-64.456011 47.414893-143.745868 75.800383-229.876528 75.800383-214.679407 0-388.730489-174.073594-388.730489-388.719232 0-214.688617 174.051081-388.718209 388.730489-388.718209 214.688617 0 388.697743 174.029592 388.697743 388.718209 0 65.548902-15.386432 127.277802-44.081984 181.490517l0 0.309038c-0.508583 1.811252-1.104147 3.576455-1.104147 5.519714 0 10.507308 8.520047 19.028379 19.028379 19.028379 8.18952 0 15.054881-5.254677 17.703197-12.494569l0 0.132006C920.349827 648.38625 938.362063 581.536726 938.362063 510.457878z"
|
||||||
|
p-id="3499" fill="#bfbfbf"></path>
|
||||||
|
</svg>
|
||||||
|
</view>
|
||||||
|
<view class="phone_list" v-if="person.studentInfo.StudentName">
|
||||||
|
<view class="phone_item">姓名:{{person.studentInfo.StudentName}}</view>
|
||||||
|
<view class="phone_item">学校:{{person.studentInfo.SchoolName}}</view>
|
||||||
|
<view class="phone_item">年级:{{person.studentInfo.Grade}}·{{person.studentInfo.ClassName}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="add_btn">
|
||||||
|
<!-- 查询 -->
|
||||||
|
<button @click.stop="addQuery" style="font-size: 17px;height: 44px;line-height: 44px;"
|
||||||
|
v-if="!person.studentInfo.StudentName">查询</button>
|
||||||
|
<!-- 本机绑定成功 -->
|
||||||
|
<button @click.stop="addBind" style="font-size: 17px;height: 44px;line-height: 44px;"
|
||||||
|
v-if="person.studentInfo.StudentName && (!person.isShowVerifyPopup) && (!person.isShowInformPopup)">绑定</button>
|
||||||
|
<!-- 名字绑定成功 -->
|
||||||
|
<button @click.stop="isShowPopupStudent=true" style="font-size: 17px;height: 44px;line-height: 44px;"
|
||||||
|
v-if="person.isShowVerifyPopup">绑定</button>
|
||||||
|
<!-- 短信绑定成功 -->
|
||||||
|
<button @click.stop="isShowPopupMessage=true" style="font-size: 17px;height: 44px;line-height: 44px;"
|
||||||
|
v-if="person.isShowInformPopup">绑定</button>
|
||||||
|
<!-- 返回个人中心 -->
|
||||||
|
<button @click.stop="backUser" style="font-size: 17px;height: 44px;line-height: 44px;">返回个人中心</button>
|
||||||
|
</view>
|
||||||
|
<!-- 绑定成功弹窗 -->
|
||||||
|
<Popups :isShow="person.isShowBindPopup" :showCancel="false" :width="300" :height="200" :bgColor="'#fff'"
|
||||||
|
@cancelBtn="person.isShowBindPopup=false">
|
||||||
|
<view class="p_cont">
|
||||||
|
<view class="popup_cont_pic">
|
||||||
|
<image src="@/static/education/ok_icon.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="popup_cont_des" style="font-size: 20px;">
|
||||||
|
绑定成功
|
||||||
|
</view>
|
||||||
|
<view class="popup_add_btn flex">
|
||||||
|
<button @click="covAddQuery" class="send-btn">继续绑定学生</button>
|
||||||
|
<button @click="backUser" class="send-btn">返回个人中心</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</Popups>
|
||||||
|
<!-- 学生验证弹窗 -->
|
||||||
|
<!-- <Popups :isShow="true" :width="300" :bgColor="'#fff'"> -->
|
||||||
|
<Popups :isShow="isShowPopupStudent" :width="300" :bgColor="'#fff'" @cancelBtn="isShowPopupStudent=false">
|
||||||
|
<view class="p_cont">
|
||||||
|
<view class="popup_cont_title">
|
||||||
|
验证信息
|
||||||
|
</view>
|
||||||
|
<view class="popup_cont_list">
|
||||||
|
<view class="cont_list_item"
|
||||||
|
style="display: flex;flex-direction: column;align-items: center;justify-content: center;">
|
||||||
|
<view class="item_subName" style="font-size: 20px;margin-bottom: 10px;">请补充完学生姓名:</view>
|
||||||
|
<view style="display: flex;align-items: center;justify-content: center;">
|
||||||
|
<view style="margin-right:4px;color: #000;">{{nameFull.getName}}</view>
|
||||||
|
<input placeholder-style="color:#fff;" style="width:28px;background-color: #fff;padding-left: 6px;"
|
||||||
|
v-model="nameFull.inputName" focus maxlength="1" type="text"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="cont_list_item">
|
||||||
|
<view style="font-size: 19px;margin-bottom: 10px;">请输入家长手机号后六位数字:</view>
|
||||||
|
<view class="flex">
|
||||||
|
<input v-for="(item,index) in teleLastNumber"
|
||||||
|
:key="index" placeholder-style="color:#BDBDBD;"
|
||||||
|
:class="{'border-indey-message':item.isFocus}"
|
||||||
|
@blur="preventFocusInfo(index,$event)"
|
||||||
|
@click="infoFocus(index,$event)"
|
||||||
|
:value="item.name" type="number" maxlength="1"
|
||||||
|
:focus="item.isFocus" @input="lastInput(index,$event)"
|
||||||
|
:selection-start="(item.isFocus)?0:-1" :selection-end="(item.isFocus)?item.name.length:-1"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="popup_add_btn">
|
||||||
|
<button @click="addVerifyBind" class="massage-btn" style="font-size: 20px;">绑定</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</Popups>
|
||||||
|
<!-- 短信验证弹窗 -->
|
||||||
|
<!-- <Popups :isShow="true" :width="300" :bgColor="'#fff'"> -->
|
||||||
|
<Popups :isShow="isShowPopupMessage" :width="260" :bgColor="'#fff'" @cancelBtn="isShowPopupMessage =false">
|
||||||
|
<view class="p_cont">
|
||||||
|
<view class="popup_cont_title">
|
||||||
|
短信验证
|
||||||
|
</view>
|
||||||
|
<view class="popup_cont_list">
|
||||||
|
<view class="cont_list_item1">
|
||||||
|
<view style="font-size: 16px;">向{{uesrTellphone}}发送验证信息<br />请输入验证码</view>
|
||||||
|
<view class="flex">
|
||||||
|
<!-- @blur="preventFocus(index,$event)" :value="item.name" :focus="item.isFocus" @focus="messageFocus(index,$event)" -->
|
||||||
|
<input v-for="(item,index) in sendYZMCode" @input="inputLastNumber(index,$event)"
|
||||||
|
:key="index" @click="messageFocus(index,$event)" @blur="messageBlur(index)"
|
||||||
|
:value="item.name" :focus="item.isFocus"
|
||||||
|
:class="{'border-indey-message':item.isFocus,'border-error':errroYZM}"
|
||||||
|
placeholder-style="color:#BDBDBD;" type="number" maxlength="1"
|
||||||
|
:selection-start="(item.isFocus)?0:-1" :selection-end="(item.isFocus)?item.name.length:-1" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="popup_cont_tag flex">
|
||||||
|
<button v-if="person.oneTime>0" class="send-btn">{{person.oneTime}}秒后重发</button>
|
||||||
|
<button v-else @click="retrieAgain" class="send-btn">{{getSendMsgText?'再次获取':'获取验证码'}}</button>
|
||||||
|
</view>
|
||||||
|
<view class="popup_add_btn">
|
||||||
|
<button @click="okClick" class="massage-btn" style="font-size: 20px;">确认</button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</Popups>
|
||||||
|
<MessageToast :isShow="person.isShowMessage" :bgColor="'rgba(0,0,0,.4)'">
|
||||||
|
{{searchMsg}}
|
||||||
|
</MessageToast>
|
||||||
|
<!-- 信息错误提示框 -->
|
||||||
|
<MessageToast :isShow="person.isShowErrorMessage" :bgColor="'rgba(0,0,0,.7)'">
|
||||||
|
信息错误
|
||||||
|
<view class="message_red" style="font-size: 17px;margin-top: 5px;">{{InfoMessage}}</view>
|
||||||
|
</MessageToast>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
reactive,
|
||||||
|
nextTick,
|
||||||
|
ref
|
||||||
|
} from "vue";
|
||||||
|
import Popups from "@/components/popups/index.vue";
|
||||||
|
import MessageToast from "@/components/messageToast/index.vue";
|
||||||
|
import Navigation from '@/components/navigation/index.vue'
|
||||||
|
//api
|
||||||
|
import {
|
||||||
|
getUnbindstudentinfo,
|
||||||
|
getSendbindstudent,
|
||||||
|
getSendTelphoneCode
|
||||||
|
} from '@/api/user.ts'
|
||||||
|
const searchMsg = ref('')
|
||||||
|
const InfoMessage = ref('')
|
||||||
|
let person = reactive({
|
||||||
|
keyword: '', // 搜索关键字
|
||||||
|
clearbtn: false, // 清除按钮
|
||||||
|
studentInfo: {},
|
||||||
|
btnName: '查询',
|
||||||
|
isShowBindPopup: false, // 绑定成功弹窗
|
||||||
|
isShowVerifyPopup: false,
|
||||||
|
isShowInformPopup: false, // 短信验证弹窗
|
||||||
|
nameKeyword: '',
|
||||||
|
phoneKeyword: '',
|
||||||
|
timer: null, // 时间计时器
|
||||||
|
oneTime: 0,
|
||||||
|
isShowMessage: false,
|
||||||
|
isShowErrorMessage: false, // 验证错误提示框
|
||||||
|
})
|
||||||
|
const isShowPopupStudent = ref(false) // 家长验证弹窗
|
||||||
|
const isShowPopupMessage = ref(false) // 短信验证弹窗
|
||||||
|
const BindCode = ref(0) //绑定账号的返回code码,判断选择哪个参数,哪个弹框
|
||||||
|
let uesrTellphone = ''
|
||||||
|
const sendYZMCode = ref([ //短信验证6位数字
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false,
|
||||||
|
start:-1,
|
||||||
|
end:-1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false,
|
||||||
|
start:-1,
|
||||||
|
end:-1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false,
|
||||||
|
start:-1,
|
||||||
|
end:-1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false,
|
||||||
|
start:-1,
|
||||||
|
end:-1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false,
|
||||||
|
start:-1,
|
||||||
|
end:-1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false,
|
||||||
|
start:-1,
|
||||||
|
end:-1
|
||||||
|
},
|
||||||
|
])
|
||||||
|
const teleLastNumber = ref([ //手机尾号6位数字
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: '',
|
||||||
|
isFocus: false
|
||||||
|
},
|
||||||
|
])
|
||||||
|
const getSendMsgText = ref(false)
|
||||||
|
let sendCodeData = ''
|
||||||
|
const nameFull = reactive({ //名字验证加上
|
||||||
|
getName: '',
|
||||||
|
inputName: ''
|
||||||
|
})
|
||||||
|
// 清空按钮
|
||||||
|
const clearBtn = () => {
|
||||||
|
person.keyword = ''
|
||||||
|
person.clearbtn = false
|
||||||
|
}
|
||||||
|
// 获取焦点
|
||||||
|
const focusBtn = () => {
|
||||||
|
person.clearbtn = true
|
||||||
|
}
|
||||||
|
const messageBlur=(index)=>{
|
||||||
|
sendYZMCode.value[index].isFocus = false
|
||||||
|
}
|
||||||
|
//输入框自动失焦获取聚焦
|
||||||
|
const inputLastNumber = (index, event) => {
|
||||||
|
sendYZMCode.value[index].name = event.detail.value
|
||||||
|
console.log(focstState.value);
|
||||||
|
if(!focstState.value){
|
||||||
|
if (sendYZMCode.value[index].name) {
|
||||||
|
if (index < 5) {
|
||||||
|
sendYZMCode.value[index + 1].isFocus = true
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if (index > 0) {
|
||||||
|
sendYZMCode.value[index - 1].isFocus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
focstState.value=false //点击状态未真
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const focstState=ref(false)
|
||||||
|
const messageFocus=(index,event)=>{ //短信框输入聚焦
|
||||||
|
let name = sendYZMCode.value[index].name
|
||||||
|
if(!name){
|
||||||
|
focstState.value=false //点击状态未真
|
||||||
|
}else{
|
||||||
|
focstState.value=true //点击状态未真
|
||||||
|
}
|
||||||
|
errroYZM.value=false //关闭红色错误弹窗
|
||||||
|
sendYZMCode.value[index].isFocus=true
|
||||||
|
}
|
||||||
|
const focstState1=ref(false)
|
||||||
|
const infoFocus=(index,event)=>{ //手机尾号框输入聚焦
|
||||||
|
teleLastNumber.value[index].isFocus=true
|
||||||
|
let name = teleLastNumber.value[index].name
|
||||||
|
if(!name){
|
||||||
|
focstState1.value=false //点击状态未真
|
||||||
|
}else{
|
||||||
|
focstState1.value=true //点击状态未真
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const preventFocusInfo = (index) => {
|
||||||
|
teleLastNumber.value[index].isFocus = false
|
||||||
|
}
|
||||||
|
//输入框自动失焦获取聚焦
|
||||||
|
const lastInput = (index, event) => {
|
||||||
|
teleLastNumber.value[index].name = event.detail.value
|
||||||
|
if(!focstState1.value){
|
||||||
|
if (teleLastNumber.value[index].name) {
|
||||||
|
if (index < 5) {
|
||||||
|
teleLastNumber.value[index + 1].isFocus = true
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if (index > 0) {
|
||||||
|
teleLastNumber.value[index - 1].isFocus = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
focstState1.value=false //点击状态为真
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询
|
||||||
|
const addQuery = () => {
|
||||||
|
// 查询
|
||||||
|
if (person.keyword) {
|
||||||
|
person.isShowMessage = false
|
||||||
|
console.log(person.keyword);
|
||||||
|
getUnbindstudentinfo(person.keyword).then(res => {
|
||||||
|
console.log(res);
|
||||||
|
if (res.Code !== 200) {
|
||||||
|
person.isShowMessage = true
|
||||||
|
searchMsg.value = res.Message
|
||||||
|
setTimeout(()=>{
|
||||||
|
person.isShowMessage = false
|
||||||
|
},3000)
|
||||||
|
person.studentInfo = {}
|
||||||
|
} else {
|
||||||
|
person.studentInfo = res.Data
|
||||||
|
person.nameKeyword = person.studentInfo.StudentName
|
||||||
|
nameFull.getName = person.studentInfo.StudentName.replace('*', '')
|
||||||
|
let sentNumber = person.keyword
|
||||||
|
uesrTellphone = sentNumber.substring(0, 3) + '****' + sentNumber.substring(7, 11)
|
||||||
|
console.log(uesrTellphone);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const cont1 = ref(true)
|
||||||
|
const cont2 = ref(true)
|
||||||
|
const errroYZM =ref(false)
|
||||||
|
|
||||||
|
// 绑定
|
||||||
|
const addBind = () => {
|
||||||
|
// 判断该学生家长的手机号是否与 微信授权获取的手机号相等
|
||||||
|
// 相等绑定成功,反之,验证信息
|
||||||
|
let params = {
|
||||||
|
StudentTelephone: person.keyword,
|
||||||
|
VerifyName: '',
|
||||||
|
VerifyLastTelephone: '',
|
||||||
|
VerifySMSId: ''
|
||||||
|
}
|
||||||
|
switch (BindCode.value) {
|
||||||
|
case 0:
|
||||||
|
params = {
|
||||||
|
StudentTelephone: person.keyword,
|
||||||
|
VerifyName: '',
|
||||||
|
VerifyLastTelephone: '',
|
||||||
|
VerifySMSId: '',
|
||||||
|
VerifyCode: ''
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 511:
|
||||||
|
let lastNumber = ''
|
||||||
|
let VerifyName = nameFull.getName + nameFull.inputName
|
||||||
|
console.log(VerifyName)
|
||||||
|
teleLastNumber.value.forEach(item => {
|
||||||
|
lastNumber += item.name
|
||||||
|
})
|
||||||
|
params = {
|
||||||
|
StudentTelephone: person.keyword,
|
||||||
|
VerifyName: VerifyName,
|
||||||
|
VerifyLastTelephone: lastNumber,
|
||||||
|
VerifySMSId: '',
|
||||||
|
VerifyCode: ''
|
||||||
|
}
|
||||||
|
if (!nameFull.inputName) {
|
||||||
|
person.isShowMessage = true
|
||||||
|
searchMsg.value = '请补全名字'
|
||||||
|
setTimeout(() => {
|
||||||
|
person.isShowMessage = false
|
||||||
|
}, 3000)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (lastNumber.length !== 6) {
|
||||||
|
console.log('尾号的长度是不是等于');
|
||||||
|
person.isShowMessage = true
|
||||||
|
searchMsg.value = '请补全手机尾号'
|
||||||
|
setTimeout(() => {
|
||||||
|
person.isShowMessage = false
|
||||||
|
}, 3000)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
console.log('验证码1')
|
||||||
|
case 512:
|
||||||
|
let messageCode = ''
|
||||||
|
sendYZMCode.value.forEach(item => {
|
||||||
|
messageCode += item.name
|
||||||
|
})
|
||||||
|
params = {
|
||||||
|
StudentTelephone: person.keyword,
|
||||||
|
VerifyName: '',
|
||||||
|
VerifyLastTelephone: '',
|
||||||
|
VerifySMSId: sendCodeData,
|
||||||
|
VerifyCode: messageCode
|
||||||
|
}
|
||||||
|
if (messageCode.length !== 6) {
|
||||||
|
person.isShowMessage = true
|
||||||
|
searchMsg.value = '请补全验证码'
|
||||||
|
setTimeout(() => {
|
||||||
|
person.isShowMessage = false
|
||||||
|
}, 3000)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
console.log(params);
|
||||||
|
if (person.studentInfo.StudentName) {
|
||||||
|
person.isShowMessage = false
|
||||||
|
getSendbindstudent(params).then(res => {
|
||||||
|
console.log(res);
|
||||||
|
BindCode.value = res.Code
|
||||||
|
if (res.Code == 200) {
|
||||||
|
person.isShowBindPopup = true
|
||||||
|
person.isShowVerifyPopup = false
|
||||||
|
person.isShowInformPopup = false
|
||||||
|
isShowPopupStudent.value = false
|
||||||
|
isShowPopupMessage.value = false
|
||||||
|
BindCode.value=0
|
||||||
|
teleLastNumber.value.forEach(item => {
|
||||||
|
item.name=''
|
||||||
|
})
|
||||||
|
nameFull.inputName=''
|
||||||
|
sendYZMCode.value.forEach(item => {
|
||||||
|
item.name=''
|
||||||
|
})
|
||||||
|
// uni.navigateBack() //绑定成功,返回个人中心页
|
||||||
|
} else if (res.Code == 511) {
|
||||||
|
isShowPopupStudent.value = true
|
||||||
|
person.isShowVerifyPopup = true
|
||||||
|
person.isShowBindPopup = false
|
||||||
|
person.isShowInformPopup = false
|
||||||
|
//消息提示
|
||||||
|
if (cont2.value) {
|
||||||
|
cont2.value = false
|
||||||
|
} else {
|
||||||
|
person.isShowErrorMessage = true
|
||||||
|
InfoMessage.value = `您还有${res.Message}机会`
|
||||||
|
setTimeout(() => {
|
||||||
|
person.isShowErrorMessage = false
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
|
} else if ((res.Code == 512)||(res.Code == 1)) {
|
||||||
|
isShowPopupStudent.value = false
|
||||||
|
isShowPopupMessage.value = true
|
||||||
|
person.isShowInformPopup = true
|
||||||
|
person.isShowBindPopup = false
|
||||||
|
person.isShowVerifyPopup = false
|
||||||
|
person.oneTime = 0
|
||||||
|
if (cont1.value) {
|
||||||
|
cont1.value = false
|
||||||
|
person.isShowMessage = true
|
||||||
|
searchMsg.value = '信息验证有误,跳转电话验证'
|
||||||
|
setTimeout(() => {
|
||||||
|
person.isShowMessage = false
|
||||||
|
}, 3000)
|
||||||
|
} else {
|
||||||
|
errroYZM.value=true //短信边框变红
|
||||||
|
person.isShowMessage = true
|
||||||
|
searchMsg.value = '短信验证错误,请重试'
|
||||||
|
sendYZMCode.value.forEach(item=>item.name='')
|
||||||
|
setTimeout(() => {
|
||||||
|
person.isShowMessage = false
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
|
//消息提示
|
||||||
|
} else {
|
||||||
|
person.isShowMessage = true
|
||||||
|
searchMsg.value = res.Message
|
||||||
|
setTimeout(() => {
|
||||||
|
person.isShowMessage = false
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 继续绑定
|
||||||
|
const covAddQuery = () => {
|
||||||
|
person.keyword = ''
|
||||||
|
person.isShowBindPopup = false
|
||||||
|
person.isShowVerifyPopup = false
|
||||||
|
person.isShowInformPopup = false
|
||||||
|
person.studentInfo = {}
|
||||||
|
person.btnName = '查询'
|
||||||
|
}
|
||||||
|
// 信息验证绑定
|
||||||
|
const addVerifyBind = () => {
|
||||||
|
addBind()
|
||||||
|
}
|
||||||
|
// 时间计时器
|
||||||
|
|
||||||
|
// 短信验证确认
|
||||||
|
const okClick = () => {
|
||||||
|
addBind()
|
||||||
|
}
|
||||||
|
const showTimer = ref(true) //是否60秒之后再次获取短信验证码
|
||||||
|
// 再次获取短信验证
|
||||||
|
const retrieAgain = () => {
|
||||||
|
if (showTimer.value) {
|
||||||
|
showTimer.value = false
|
||||||
|
// let telephone = uni.getStorageSync('USER_PHONE')
|
||||||
|
getSendMsgText.value = true
|
||||||
|
person.oneTime = 60
|
||||||
|
person.timer = setInterval(() => {
|
||||||
|
person.oneTime--; // 时间减一秒
|
||||||
|
if (person.oneTime <= 0) { // 当倒计时结束时
|
||||||
|
clearInterval(person.timer); // 停止计时器
|
||||||
|
showTimer.value = true
|
||||||
|
}
|
||||||
|
}, 1000); // 每秒执行一次
|
||||||
|
getSendTelphoneCode(person.keyword, 1).then(res => {
|
||||||
|
console.log(res);
|
||||||
|
if (res.Code == 200) {
|
||||||
|
sendCodeData = res.Data
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 返回个人中心
|
||||||
|
const backUser = () => {
|
||||||
|
uni.reLaunch({
|
||||||
|
url: '/pages/user/index'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
page {
|
||||||
|
background: #f8f8f8 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message_red {
|
||||||
|
color: #BC0101;
|
||||||
|
font-size: 24rpx;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add_phone {
|
||||||
|
background: #fff;
|
||||||
|
padding: 32rpx 32rpx 60rpx 32rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #545454;
|
||||||
|
|
||||||
|
.input_des {
|
||||||
|
color: #727272;
|
||||||
|
font-size: 24rpx;
|
||||||
|
font-weight: 400;
|
||||||
|
letter-spacing: 0rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text_right {
|
||||||
|
margin: 0 0 15rpx 200rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add_phone_input {
|
||||||
|
position: relative;
|
||||||
|
white-space: nowrap;
|
||||||
|
.showAccountNumber{
|
||||||
|
position: absolute;
|
||||||
|
right: 10px;
|
||||||
|
}
|
||||||
|
.input_name {
|
||||||
|
width: 200rpx;
|
||||||
|
font-size: 30rpx;
|
||||||
|
font-weight: 600;
|
||||||
|
white-space: nowrap;
|
||||||
|
line-height: 35rpx;
|
||||||
|
letter-spacing: 4rpx;
|
||||||
|
|
||||||
|
text {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: 2rpx solid #BABABA;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
width: 60%;
|
||||||
|
padding: 15rpx 60rpx 15rpx 30rpx;
|
||||||
|
color: #2C2C2C;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
position: absolute;
|
||||||
|
right: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.phone_list {
|
||||||
|
margin-top: 40rpx;
|
||||||
|
margin-bottom: 50rpx;
|
||||||
|
|
||||||
|
.phone_item {
|
||||||
|
line-height: 50rpx;
|
||||||
|
font-size: 16px;
|
||||||
|
color: #545454;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.p_cont {
|
||||||
|
// padding: 20px;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
|
||||||
|
.popup_cont_pic {
|
||||||
|
margin: 40rpx auto 20rpx auto;
|
||||||
|
background: #fff;
|
||||||
|
width: 150rpx;
|
||||||
|
height: 150rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
image {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_add_btn {
|
||||||
|
button {
|
||||||
|
width: 45%;
|
||||||
|
|
||||||
|
&:nth-child(1) {
|
||||||
|
width: 55%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_cont_title {
|
||||||
|
font-size: 42rpx;
|
||||||
|
color: #575757;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_cont_tag {
|
||||||
|
justify-content: flex-end;
|
||||||
|
width: 100%;
|
||||||
|
text-align: right;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: 2rpx solid #A5B5FA;
|
||||||
|
color: #A5B5FA;
|
||||||
|
font-size: 24rpx;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 20rpx;
|
||||||
|
background: #fff;
|
||||||
|
height: 45rpx;
|
||||||
|
line-height: 45rpx;
|
||||||
|
|
||||||
|
&:nth-child(2) {
|
||||||
|
margin-left: 20rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup_cont_list {
|
||||||
|
text-align: left;
|
||||||
|
|
||||||
|
.cont_list_item {
|
||||||
|
font-size: 28rpx;
|
||||||
|
background: #F8F9FF;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
padding: 28rpx;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
color: rgba(137, 137, 137, 1);
|
||||||
|
|
||||||
|
&:first-child {
|
||||||
|
input {
|
||||||
|
width: 99%;
|
||||||
|
border: 0;
|
||||||
|
padding: 10rpx 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: 2rpx solid #9C9C9C;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
width: 16.6%;
|
||||||
|
padding: 15rpx 0;
|
||||||
|
color: #2C2C2C;
|
||||||
|
font-weight: 500;
|
||||||
|
// margin-top: 20rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.cont_list_item1 {
|
||||||
|
font-size: 28rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
margin-top: 30rpx;
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: 2rpx solid #9C9C9C;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
width: 16.6%;
|
||||||
|
padding: 15rpx 0;
|
||||||
|
color: #2C2C2C;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 20rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.massage-btn {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 40px !important;
|
||||||
|
line-height: 40px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.send-btn {
|
||||||
|
width: 50% !important;
|
||||||
|
height: 35px !important;
|
||||||
|
line-height: 35px !important;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.border-indey-message{
|
||||||
|
border: 3px solid skyblue !important;
|
||||||
|
}
|
||||||
|
.border-error{
|
||||||
|
border: 1px solid #FF0000 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,53 @@
|
||||||
|
<template>
|
||||||
|
<Navigation :title_name="'关于'"
|
||||||
|
:isReturn="0"
|
||||||
|
:color="'#000000'"
|
||||||
|
:bgc="'#FFFFFF'"
|
||||||
|
:isCenter="true" />
|
||||||
|
<view class="related-list">
|
||||||
|
<view class="related-item" v-for="(item,index) in person.relatedList" :key="index">
|
||||||
|
<view class="related-item-name">{{item.name}}</view>
|
||||||
|
<view class="related-item-time">{{item.des}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { reactive } from "vue";
|
||||||
|
import Navigation from '@/components/navigation/index.vue'
|
||||||
|
let person=reactive({
|
||||||
|
relatedList:[
|
||||||
|
{name:'智喵慧查V1.01',des:'2023年08月12日'},
|
||||||
|
{name:'更新内容:',des:'版本上线'}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
page{
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
.related-list {
|
||||||
|
width: 100%;
|
||||||
|
padding: 10px 20px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
.related-item {
|
||||||
|
color: #454545;
|
||||||
|
letter-spacing: 0.72px;
|
||||||
|
padding: 10px 0;
|
||||||
|
border-bottom: 1px solid #ECECEC;
|
||||||
|
line-height: 20px;
|
||||||
|
&:last-child{
|
||||||
|
border-bottom: 0 !important;
|
||||||
|
}
|
||||||
|
.related-item-name{
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.related-item-time{
|
||||||
|
font-size: 14px;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
<template>
|
||||||
|
<web-view :src="webSrc" @load="bindLoad" @message="receptMessage"></web-view>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import {postRegister} from "@/api/user";
|
||||||
|
const webSrc=ref('')
|
||||||
|
onLoad((option)=>{
|
||||||
|
webSrc.value =`https://open.weixin.qq.com/connect/oauth2/authorize?appid=${option.appId}&redirect_uri=${encodeURI(option.url)}&response_type=code&scope=snsapi_base&state=123#wechat_redirect`
|
||||||
|
})
|
||||||
|
const bindLoad=(e)=>{
|
||||||
|
let code =e.detail.src.split('=')[1].split('&')[0]
|
||||||
|
let XcxId = uni.getStorageSync('XCXID')
|
||||||
|
postRegister({
|
||||||
|
XcxId,
|
||||||
|
Code: code
|
||||||
|
}).then((res :any)=> {
|
||||||
|
console.log('注册', res);
|
||||||
|
if (res.Code == 200) {
|
||||||
|
uni.setStorageSync('TokenType', res.Data.TokenType)
|
||||||
|
uni.setStorageSync('HAS_STUDENT', res.Data.user.HasStudent)
|
||||||
|
uni.setStorageSync('token', res.Data.AccessToken)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
const receptMessage=(e :any)=>{
|
||||||
|
console.log('接受消息',e);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
</style>
|
||||||
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 759 B |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 406 B |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 728 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 442 B |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 514 B |
|
After Width: | Height: | Size: 519 B |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 9.6 KiB |
|
After Width: | Height: | Size: 738 B |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 414 B |
|
After Width: | Height: | Size: 440 B |
|
After Width: | Height: | Size: 302 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 322 B |
|
|
@ -0,0 +1,109 @@
|
||||||
|
page {
|
||||||
|
font-family: 'PingFang SC';
|
||||||
|
// border: 1rpx solid rgba(0,0,0,0);
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
.page-bg {
|
||||||
|
background: #f5f5f5;
|
||||||
|
}
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.bold {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
// 空提示
|
||||||
|
.empty_box {
|
||||||
|
height: 60%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
top: 100rpx;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
color: #666;
|
||||||
|
image {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 140px;
|
||||||
|
height: 120px;
|
||||||
|
}
|
||||||
|
text {
|
||||||
|
margin-top: 20rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询按钮
|
||||||
|
.add_btn {
|
||||||
|
padding: 64rpx 0;
|
||||||
|
width: 100%;
|
||||||
|
button {
|
||||||
|
width: 80%;
|
||||||
|
height: 70rpx;
|
||||||
|
line-height: 70rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
background: #6b86ff;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
&:nth-child(1) {
|
||||||
|
background: #6b86ff;
|
||||||
|
color: #fff;
|
||||||
|
&:active {
|
||||||
|
background: skyblue;
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(2) {
|
||||||
|
background: rgba(0, 0, 0, 0);
|
||||||
|
color: #6b86ff;
|
||||||
|
border: 2rpx solid #6b86ff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 继续绑定按钮
|
||||||
|
.popup_add_btn {
|
||||||
|
padding: 64rpx 0 0 0;
|
||||||
|
width: 100%;
|
||||||
|
button {
|
||||||
|
width: 80%;
|
||||||
|
height: 48rpx;
|
||||||
|
line-height: 48rpx;
|
||||||
|
border-radius: 40rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
background: #6b86ff;
|
||||||
|
margin-bottom: 20rpx;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0;
|
||||||
|
&:nth-child(1) {
|
||||||
|
background: #6b86ff;
|
||||||
|
color: #fff;
|
||||||
|
&:active {
|
||||||
|
background: skyblue;
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:nth-child(2) {
|
||||||
|
background: rgba(0, 0, 0, 0);
|
||||||
|
color: #6b86ff;
|
||||||
|
border: 2rpx solid #6b86ff;
|
||||||
|
margin-left: 20rpx;
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.95);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
image {
|
||||||
|
width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
margin-right: 10rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.popup_cont_des {
|
||||||
|
color: #3d425b;
|
||||||
|
font-size: 30rpx;
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 778 B |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 872 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 910 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1,13 @@
|
||||||
|
import { createStore } from "vuex";
|
||||||
|
export default createStore({
|
||||||
|
state: {
|
||||||
|
IsLogin:false // 是否登录
|
||||||
|
},
|
||||||
|
mutations:{
|
||||||
|
setIsLogin(state: any, data: any) {
|
||||||
|
state.IsLogin = data
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions:{},
|
||||||
|
getters:{}
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "esnext",
|
||||||
|
"useDefineForClassFields": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"strict": true,
|
||||||
|
"jsx": "preserve",
|
||||||
|
"sourceMap": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"lib": ["esnext", "dom"],
|
||||||
|
"types": ["@dcloudio/types"]
|
||||||
|
},
|
||||||
|
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"]
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,76 @@
|
||||||
|
/**
|
||||||
|
* 这里是uni-app内置的常用样式变量
|
||||||
|
*
|
||||||
|
* uni-app 官方扩展插件及插件市场(https://ext.dcloud.net.cn)上很多三方插件均使用了这些样式变量
|
||||||
|
* 如果你是插件开发者,建议你使用scss预处理,并在插件代码中直接使用这些变量(无需 import 这个文件),方便用户通过搭积木的方式开发整体风格一致的App
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 如果你是App开发者(插件使用者),你可以通过修改这些变量来定制自己的插件主题,实现自定义主题功能
|
||||||
|
*
|
||||||
|
* 如果你的项目同样使用了scss预处理,你也可以直接在你的 scss 代码中使用如下变量,同时无需 import 这个文件
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 颜色变量 */
|
||||||
|
|
||||||
|
/* 行为相关颜色 */
|
||||||
|
$uni-color-primary: #007aff;
|
||||||
|
$uni-color-success: #4cd964;
|
||||||
|
$uni-color-warning: #f0ad4e;
|
||||||
|
$uni-color-error: #dd524d;
|
||||||
|
|
||||||
|
/* 文字基本颜色 */
|
||||||
|
$uni-text-color:#333;//基本色
|
||||||
|
$uni-text-color-inverse:#fff;//反色
|
||||||
|
$uni-text-color-grey:#999;//辅助灰色,如加载更多的提示信息
|
||||||
|
$uni-text-color-placeholder: #808080;
|
||||||
|
$uni-text-color-disable:#c0c0c0;
|
||||||
|
|
||||||
|
/* 背景颜色 */
|
||||||
|
$uni-bg-color:#ffffff;
|
||||||
|
$uni-bg-color-grey:#f8f8f8;
|
||||||
|
$uni-bg-color-hover:#f1f1f1;//点击状态颜色
|
||||||
|
$uni-bg-color-mask:rgba(0, 0, 0, 0.4);//遮罩颜色
|
||||||
|
|
||||||
|
/* 边框颜色 */
|
||||||
|
$uni-border-color:#c8c7cc;
|
||||||
|
|
||||||
|
/* 尺寸变量 */
|
||||||
|
|
||||||
|
/* 文字尺寸 */
|
||||||
|
$uni-font-size-sm:24rpx;
|
||||||
|
$uni-font-size-base:28rpx;
|
||||||
|
$uni-font-size-lg:32rpx;
|
||||||
|
|
||||||
|
/* 图片尺寸 */
|
||||||
|
$uni-img-size-sm:40rpx;
|
||||||
|
$uni-img-size-base:52rpx;
|
||||||
|
$uni-img-size-lg:80rpx;
|
||||||
|
|
||||||
|
/* Border Radius */
|
||||||
|
$uni-border-radius-sm: 4rpx;
|
||||||
|
$uni-border-radius-base: 6rpx;
|
||||||
|
$uni-border-radius-lg: 12rpx;
|
||||||
|
$uni-border-radius-circle: 50%;
|
||||||
|
|
||||||
|
/* 水平间距 */
|
||||||
|
$uni-spacing-row-sm: 10px;
|
||||||
|
$uni-spacing-row-base: 20rpx;
|
||||||
|
$uni-spacing-row-lg: 30rpx;
|
||||||
|
|
||||||
|
/* 垂直间距 */
|
||||||
|
$uni-spacing-col-sm: 8rpx;
|
||||||
|
$uni-spacing-col-base: 16rpx;
|
||||||
|
$uni-spacing-col-lg: 24rpx;
|
||||||
|
|
||||||
|
/* 透明度 */
|
||||||
|
$uni-opacity-disabled: 0.3; // 组件禁用态的透明度
|
||||||
|
|
||||||
|
/* 文章场景相关 */
|
||||||
|
$uni-color-title: #2C405A; // 文章标题颜色
|
||||||
|
$uni-font-size-title:40rpx;
|
||||||
|
$uni-color-subtitle: #555555; // 二级标题颜色
|
||||||
|
$uni-font-size-subtitle:36rpx;
|
||||||
|
$uni-color-paragraph: #3F536E; // 文章段落颜色
|
||||||
|
$uni-font-size-paragraph:30rpx;
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
import { config } from '@/config/config'; //引入公用文件
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
export const Request = options => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const token = uni.getStorageSync('token');
|
||||||
|
const TokenType = uni.getStorageSync('TokenType');
|
||||||
|
uni.request({
|
||||||
|
url: config.host + options.url, //接口地址:前缀+方法中传入的地址
|
||||||
|
method: options.method || 'GET', //请求方法:传入的方法或者默认是“GET”
|
||||||
|
data: options.data || {}, //传递参数:传入的参数或者默认传递空集合
|
||||||
|
header: {
|
||||||
|
Authorization: `${TokenType || 'Bearer'} ${token || ''}`,
|
||||||
|
'Content-Type': 'application/json;charset=utf-8'
|
||||||
|
},
|
||||||
|
success: function(res) {
|
||||||
|
if (res.statusCode == 401) {
|
||||||
|
console.log('跳转');
|
||||||
|
uni.navigateTo({url:'/pages/login/login'})
|
||||||
|
} else {
|
||||||
|
resolve(res.data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
fail: err => {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请求失败,请刷新',
|
||||||
|
duration: 2000,
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
reject(err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
import { defineConfig } from "vite";
|
||||||
|
import uni from "@dcloudio/vite-plugin-uni";
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [uni()],
|
||||||
|
css: {
|
||||||
|
postcss: {
|
||||||
|
plugins: [
|
||||||
|
require('postcss-pxtorpx-pro')({
|
||||||
|
// 转化的单位
|
||||||
|
unit: 'rpx',
|
||||||
|
// 单位精度
|
||||||
|
unitPrecision: 5,
|
||||||
|
// 不需要处理的css选择器
|
||||||
|
selectorBlackList: [],
|
||||||
|
// 不需要转化的css属性
|
||||||
|
propBlackList: [],
|
||||||
|
// 直接修改px,还是新加一条css规则
|
||||||
|
replace: true,
|
||||||
|
// 是否匹配媒介查询的px
|
||||||
|
mediaQuery: false,
|
||||||
|
// 需要转化的最小的pixel值,低于该值的px单位不做转化
|
||||||
|
minPixelValue: 2,
|
||||||
|
// 不处理的文件
|
||||||
|
exclude: /node_modules/gi,
|
||||||
|
// 转化函数
|
||||||
|
// 视口375px
|
||||||
|
transform: (x: any) => 2 * x
|
||||||
|
})
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||