Browse Source

Merge pull request 'feat: 接口对接;' (#2) from fox into master

Reviewed-on: http://175.178.51.79:3000/Augcl/assessment-front/pulls/2
master
Fox 1 month ago
parent
commit
4c4a19f210
27 changed files with 389 additions and 401 deletions
  1. +2
    -4
      api/http.js
  2. +5
    -0
      api/model/exam.js
  3. +8
    -0
      api/model/report.js
  4. +10
    -2
      components/home/unfinishTestPopup.vue
  5. +18
    -16
      components/report/reportCard.vue
  6. +1
    -2
      pages.json
  7. +18
    -3
      pages/index/index.vue
  8. +5
    -7
      pages/index/report.vue
  9. +4
    -4
      pages_order/auth/wxLogin.vue
  10. +7
    -5
      pages_order/components/formUpload.vue
  11. +39
    -24
      pages_order/feedback/index.vue
  12. +88
    -105
      pages_order/report/index.vue
  13. +6
    -7
      pages_order/report/pay.vue
  14. +10
    -10
      pages_order/report/reportTableView.vue
  15. +33
    -17
      pages_order/report/userInfo.vue
  16. +41
    -42
      pages_order/service/index.vue
  17. +9
    -15
      pages_order/service/popupPhone.vue
  18. +1
    -8
      pages_order/service/popupQrCode.vue
  19. BIN
      pages_order/static/feedback/icon-camera.png
  20. BIN
      pages_order/static/feedback/icon-star.png
  21. +47
    -117
      pages_order/test/answer.vue
  22. +12
    -8
      pages_order/test/start.vue
  23. +20
    -5
      pages_order/test/testCard.vue
  24. BIN
      static/image/temp-01.png
  25. BIN
      static/image/temp-03.png
  26. BIN
      static/image/temp-05.png
  27. +5
    -0
      store/store.js

+ 2
- 4
api/http.js View File

@ -35,12 +35,10 @@ function http(uri, data, callback, method = 'GET', showLoading, title) {
if(res.statusCode == 401 ||
res.data.message == '操作失败,token非法无效!' ||
res.data.message == '操作失败,用户不存在!'){
store.commit('logout')
console.error('登录过期');
store.commit('clearUserInfo')
utils.toLogin()
}
if(res.statusCode == 200 && res.data.code != 200
} else if(res.statusCode == 200 && res.data.code != 200
&& res.data.code != 902){
uni.showToast({
mask: true,


+ 5
- 0
api/model/exam.js View File

@ -1,6 +1,11 @@
// 测评相关接口
const api = {
// 测评-查询答题列表
queryCategoryList: {
url: '/exam/queryCategoryList',
method: 'GET',
},
// 测评-查询答题列表
queryQuestionList: {
url: '/exam/queryQuestionList',


+ 8
- 0
api/model/report.js View File

@ -11,6 +11,14 @@ const api = {
url: '/report/queryReportById',
method: 'GET',
},
// 测评-新增测评报告基本信息
addReport: {
url: '/report/addReport',
method: 'POST',
auth: true,
limit : 500,
showLoading : true,
},
}
export default api

+ 10
- 2
components/home/unfinishTestPopup.vue View File

@ -10,7 +10,7 @@
<view class="header">您还有未完成的题是否继续答题</view>
<view class="flex flex-column content">
<image class="icon" src="@/static/image/icon-unfinish.png" mode="widthFix"></image>
<view>{{ `您还有${detail.unfinishCount}道题未完成` }}</view>
<view>{{ `您还有${unfinishCount}道题未完成` }}</view>
</view>
<view class="flex footer">
<button class="btn" @click="close">取消</button>
@ -27,6 +27,13 @@
detail: {}
}
},
computed: {
unfinishCount() {
const { allNum, finishNum } = this.detail
return allNum - finishNum
},
},
methods: {
open(data) {
this.detail = data
@ -37,7 +44,8 @@
},
onContinue() {
uni.navigateTo({
url: `/pages_order/test/answer?id=${this.detail.id}&current=${this.detail.current}`,
// url: `/pages_order/test/answer?id=${this.detail.id}&current=${this.detail.current}`,
url: `/pages_order/test/list`,
success: () => {
this.close()
},


+ 18
- 16
components/report/reportCard.vue View File

@ -7,7 +7,7 @@
<view class="card-content">
<view class="row">
<view class="row-label">手机号码</view>
<view class="row-content">{{ data.phone }}</view>
<view class="row-content">{{ data.phone || '-' }}</view>
</view>
<view class="row">
<view class="row-label">公司名称</view>
@ -15,27 +15,25 @@
</view>
<view class="row">
<view class="row-label">生成时间</view>
<view class="row-content">{{ data.createTime }}</view>
<view class="row-content">{{ $dayjs(data.createTime).format('YYYY-MM-DD HH:mm') }}</view>
</view>
</view>
<view class="flex card-footer">
<button class="btn" @click="jumpToTest">重新测评</button>
<button class="btn" @click="onRestart">重新测评</button>
<button class="btn btn-primary" @click="jumpToReport">查看报告</button>
</view>
<view class="flex tag">
<view class="flex tag-content">
{{ statusDesc }}
</view>
<view class="flex tag-content">已完成</view>
</view>
</view>
</template>
<script>
const STATUS_AND_DESC_MAPPING = {
0: '未完成',
1: '已完成',
}
// const STATUS_AND_DESC_MAPPING = {
// 0: '',
// 1: '',
// }
export default {
props: {
@ -47,19 +45,23 @@
}
},
computed: {
statusDesc() {
return STATUS_AND_DESC_MAPPING[this.data.status]
},
// statusDesc() {
// return STATUS_AND_DESC_MAPPING[this.data.isFinished] || ''
// },
},
methods: {
jumpToTest() {
onRestart() {
// uni.navigateTo({
// url: `/pages_order/test/answer?id=${this.data.paperId}`
// })
uni.navigateTo({
url: `/pages_order/test/answer?id=${this.data.paperId}`
url: `/pages_order/test/start`
})
},
jumpToReport() {
uni.navigateTo({
url: `/pages_order/report/index?id=${this.data.batchNo}`
url: `/pages_order/report/index?batchNo=${this.data.batchNo}`
})
},
},


+ 1
- 2
pages.json View File

@ -3,8 +3,7 @@
{
"path": "pages/index/index",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": true
"navigationBarTitleText": ""
}
},
{


+ 18
- 3
pages/index/index.vue View File

@ -13,7 +13,6 @@
indicatorActiveColor="#62BBFF"
indicatorInactiveColor="#FFFFFF"
height="340rpx"
:autoplay="false"
></uv-swiper>
</view>
@ -50,9 +49,13 @@
if(uni.getStorageSync('token')){
this.$store.commit('getUserInfo')
}
this.fetchUnfinish()
this.fetchBanner()
},
onShow() {
if(uni.getStorageSync('token')){
this.fetchUnfinish()
}
},
methods: {
async fetchBanner() {
try {
@ -68,7 +71,14 @@
// let data = { id: '001', unfinishCount: 15, current: 18, }
// this.$refs.unfinishTestPopup.open(data)
// todo: fetch
try {
const { records, total } = await this.$fetch('queryExamLogList', { pageNo: 1, pageSize: 1, isFinished: '0' })
total && this.$refs.unfinishTestPopup.open(records[0])
} catch (err) {
}
},
onStartTest() {
uni.navigateTo({
@ -99,6 +109,11 @@
.swiper {
border-radius: 10rpx;
overflow: hidden;
/deep/ .uv-swiper-indicator__wrapper__dot,
/deep/ .uv-swiper-indicator__wrapper__dot--active {
width: 5px;
}
}
.card {


+ 5
- 7
pages/index/report.vue View File

@ -37,7 +37,7 @@
},
data() {
return {
// mixinsListApi: 'queryReportList',
mixinsListApi: '',
}
},
onLoad() {
@ -49,12 +49,10 @@
isLogin() {
return this.userInfo && this.userInfo.id
},
mixinsListApi() {
if(uni.getStorageSync('token')){
return 'queryReportList'
}
return ''
}
},
onShow() {
this.mixinsListApi = uni.getStorageSync('token') ? 'queryReportList' : ''
this.getData()
},
methods: {
},


+ 4
- 4
pages_order/auth/wxLogin.vue View File

@ -9,9 +9,9 @@
<!-- <image class="logo" src="@/static/image/icon.png" mode="widthFix"></image> -->
<view class="name">{{ configList.app_name || '' }}</view>
<button class="btn btn-login flex" @click="wxLogin" > </button>
<button class="btn btn-login flex" @click="wxLogin" >授权手机号登录</button>
<button class="btn btn-cancel flex" @click="onCancel">取消登录</button>
<button class="btn btn-cancel flex" @click="onCancel">暂不登录</button>
<view class="agreement">
<view>
@ -28,10 +28,10 @@
</uv-checkbox-group>
</view>
<view class="desc">
我已阅读并同意
阅读并同意我们的
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_privacy', '服务协议与隐私条款')">服务协议与隐私条款</text>
以及
<!-- todo: 替换配置项key -->
<text class="highlight" @click="$refs.modal.open('config_agreement', '个人信息保护指引')">个人信息保护指引</text>
</view>


+ 7
- 5
pages_order/components/formUpload.vue View File

@ -10,8 +10,7 @@
@delete="deleteFile"
>
<button class="flex btn">
<!-- todo: 缺切图 -->
<uv-icon name="camera-fill" color="#014FA2" size="56rpx"></uv-icon>
<image class="icon" src="@/pages_order/static/feedback/icon-camera.png" mode="widthFix"></image>
</button>
</uv-upload>
</view>
@ -93,8 +92,11 @@
<style scoped lang="scss">
.btn {
width: 133rpx;
height: 133rpx;
border: 2rpx dashed #014FA2;
border-radius: 0;
.icon {
width: 133rpx;
height: auto;
}
}
</style>

+ 39
- 24
pages_order/feedback/index.vue View File

@ -2,10 +2,11 @@
<view class="page__view">
<navbar title="意见反馈" leftClick @leftClick="$utils.navigateBack" bgColor="transparent" />
<view class="bg">
<image class="bg" :src="configList.feedback_bg" mode="widthFix"></image>
<!-- <view class="bg">
<view class="title">Hello</view>
<view class="desc">有什么好的建议可以告诉我们哦</view>
</view>
</view> -->
<view class="main">
<view class="form">
@ -22,7 +23,7 @@
<view class="feedback-header-content">
<view>反馈内容</view>
<view class="feedback-icon">
<uv-icon name="star-fill" color="#FFFFFF" size="26rpx"></uv-icon>
<image class="icon" src="@/pages_order/static/feedback/icon-star.png" mode="widthFix"></image>
</view>
</view>
</view>
@ -58,6 +59,8 @@
</template>
<script>
import util from '@/utils/utils.js'
import formTextarea from '@/pages_order/components/formTextarea.vue'
import formUpload from '@/pages_order/components/formUpload.vue'
@ -82,19 +85,24 @@
'phone': {
type: 'string',
required: true,
message: '请输入手机号',
message: '请输入正确的手机号',
validator: (rule, value, callback) => {
return util.verificationPhone(value)
},
},
},
formItemStyle: { padding: 0 },
}
},
onReady() {
this.$refs.form.setRules(this.rules);
},
methods: {
async onSubmit() {
try {
await this.$refs.form.validate()
const {
content,
images,
@ -138,29 +146,31 @@
.bg {
width: 100%;
height: 501rpx;
padding-top: 203rpx;
box-sizing: border-box;
color: #FFFFFF;
background: linear-gradient(164deg, #014FA2 30%, #4C8FD6);
height: auto;
min-height: 501rpx;
// height: 501rpx;
// padding-top: 203rpx;
// box-sizing: border-box;
// color: #FFFFFF;
// background: linear-gradient(164deg, #014FA2 30%, #4C8FD6);
.title {
padding: 0 73rpx;
font-size: 64rpx;
font-weight: 600;
}
// .title {
// padding: 0 73rpx;
// font-size: 64rpx;
// font-weight: 600;
// }
.desc {
margin-top: 18rpx;
padding: 0 68rpx;
box-sizing: border-box;
font-size: 28rpx;
}
// .desc {
// margin-top: 18rpx;
// padding: 0 68rpx;
// box-sizing: border-box;
// font-size: 28rpx;
// }
}
.main {
width: 100%;
padding: 0 28rpx;
padding: 0 28rpx 200rpx 28rpx;
box-sizing: border-box;
background: #F5F5F5;
}
@ -209,7 +219,12 @@
position: absolute;
top: 0;
right: 0;
transform: translate(30rpx, -4rpx);
transform: translate(30rpx, -10rpx);
.icon {
width: 26rpx;
height: auto;
}
}
.phone {
@ -229,7 +244,7 @@
bottom: 0;
width: 100vw;
padding: 56rpx 35rpx;
padding: 0 35rpx 56rpx 35rpx;
padding-bottom: calc(env(safe-area-inset-bottom) + 35rpx);
box-sizing: border-box;


+ 88
- 105
pages_order/report/index.vue View File

@ -2,40 +2,44 @@
<view class="page__view">
<navbar title="报告" leftClick @leftClick="$utils.navigateBack" />
<view class="title">2025年9月16日xxx公司风险测评报告</view>
<template v-if="detail">
<view class="title">{{ detail.title }}</view>
<view class="section">
<view class="flex section-header">
<view class="line"></view>
<view>总概述</view>
</view>
<view class="section-content">
<view class="summary">
<view class="text">
经过本次问答信息收集的综合分析检测出风险点共<text class="highlight">12</text>其中极高风险4项高风险2项中风险4项低风险2项
<view class="section">
<view class="flex section-header">
<view class="line"></view>
<view>总概述</view>
</view>
<view class="section-content">
<view class="summary">
<view class="text">
经过本次问答信息收集的综合分析检测出风险点共<text class="highlight">{{ detail.levelAllNum }}</text>其中极高风险{{ detail.level3Num }}高风险{{ detail.level2Num }}中风险{{ detail.level1Num }}低风险{{ detail.level0Num }}
</view>
<view class="flex charts">
<progressCircle label="极高风险" :value="detail.level3Num" color="#B81C1C"></progressCircle>
<progressCircle label="高风险" :value="detail.level2Num" color="#FF0000"></progressCircle>
<progressCircle label="中风险" :value="detail.level1Num" color="#FFA800"></progressCircle>
<progressCircle label="低风险" :value="detail.level0Num" color="#014FA2"></progressCircle>
</view>
</view>
<view class="flex charts">
<progressCircle label="极高风险" value="4" color="#B81C1C"></progressCircle>
<progressCircle label="高风险" value="2" color="#FF0000"></progressCircle>
<progressCircle label="中风险" value="4" color="#FFA800"></progressCircle>
<progressCircle label="低风险" value="2" color="#014FA2"></progressCircle>
<view class="table">
<reportTableView :list="tableList"></reportTableView>
</view>
</view>
<view class="table">
<reportTableView :list="tableList"></reportTableView>
</view>
<view class="flex flex-column contact">
<view>扫下方二维码联系我们给你1V1解决方案</view>
<image class="qr" :src="configList.company_qrcode" :show-menu-by-longpress="true" mode="widthFix"></image>
</view>
<view>
<image class="img" :src="configList.company_info" mode="widthFix"></image>
<view class="logo">
<image class="img" :src="configList.company_logo" mode="widthFix"></image>
</view>
</view>
</view>
<view class="flex flex-column contact">
<view>扫下方二维码联系我们给你1V1解决方案</view>
<!-- todo: check key -->
<image class="qr" :src="configList.service" :show-menu-by-longpress="true"></image>
</view>
<view>
<uv-parse :content="content"></uv-parse>
</view>
</template>
</view>
</template>
@ -51,8 +55,8 @@
},
data() {
return {
detail: null,
tableList: [],
content: '',
}
},
onLoad(arg) {
@ -61,84 +65,52 @@
},
methods: {
async getData(batchNo) {
// todo: delete
this.tableList = [
{
id: '001',
title: '风险文字内容文字内',
children: [
{
id: '0011',
reason: '风险原因文字',
level: 0,
result: '可能导致的结果文字内容文字内容',
},
{
id: '0012',
reason: '风险原因文字',
level: 2,
result: '文字内容',
},
],
},
{
id: '002',
title: '风险文字内容文字内文字内文字内文字内文字内文字内',
children: [
{
id: '0021',
reason: '风险原因文字',
level: 3,
result: '可能导致的结果文字内容文字内容',
},
{
id: '0022',
reason: '风险原因文字',
level: 0,
result: '',
},
{
id: '0023',
reason: '风险原因文字',
level: 1,
result: '',
},
{
id: '0024',
reason: '风险原因文字',
level: 2,
result: '文字内容',
},
],
},
{
id: '003',
title: '风险文字内容文字内',
children: [
{
id: '0031',
reason: '风险原因文字',
level: 3,
result: '',
},
{
id: '0032',
reason: '风险原因文字',
level: 2,
result: '',
},
{
id: '0033',
reason: '风险原因文字',
level: 3,
result: '',
},
],
},
]
try {
await this.$fetch('queryReportById', { batchNo })
const result = await this.$fetch('queryReportById', { batchNo })
const {
title,
level0Num, //
level1Num, //
level2Num, //
level3Num, //
levelAllNum,
pageList,
} = result
this.tableList = pageList.reduce((arr, item) => {
const { id, risk, reason, level, consequence } = item
const obj = {
id,
reason,
level,
result: consequence,
}
const index = arr.findIndex(row => row.title === risk)
if (index === -1) {
arr.push({
id: arr.length,
title: risk,
children: [obj]
})
} else {
arr[index].children.push(obj)
}
return arr
}, [])
this.detail = {
title,
level0Num, //
level1Num, //
level2Num, //
level3Num, //
levelAllNum,
}
} catch (err) {
}
@ -220,4 +192,15 @@
height: auto;
}
}
.img {
width: 100%;
height: auto;
}
.logo {
width: 100%;
padding: 42rpx 127rpx 46rpx 127rpx;
box-sizing: border-box;
}
</style>

+ 6
- 7
pages_order/report/pay.vue View File

@ -11,8 +11,7 @@
</view>
<view class="flex flex-column contact">
<view>联系客服获取抵扣码</view>
<!-- todo: check key -->
<image class="qr" :src="configList.service" :show-menu-by-longpress="true"></image>
<image class="qr" :src="configList.customer_service_qrcode" :show-menu-by-longpress="true" mode="widthFix"></image>
</view>
</view>
@ -97,7 +96,7 @@
},
data() {
return {
id: null,
batchNo: null,
form: {
payment: null,
code: null,
@ -118,8 +117,8 @@
}
},
onLoad(arg) {
const { id } = arg
this.id = id
const { batchNo } = arg
this.batchNo = batchNo
},
methods: {
onPay() {
@ -129,8 +128,8 @@
// if error
// this.$refs.codeErrorPopup.open()
uni.navigateTo({
url: `/pages_order/report/userInfo?id=${this.id}`
uni.redirectTo({
url: `/pages_order/report/userInfo?batchNo=${this.batchNo}`
})
},
},


+ 10
- 10
pages_order/report/reportTableView.vue View File

@ -10,9 +10,9 @@
<view class="table-cell">{{ row.title }}</view>
<view class="table-row-cols">
<template v-for="child in row.children">
<view class="table-cell" :key="getKey(child.id, 'reason')">{{ child.reason }}</view>
<view class="table-cell" :key="getKey(child.id, 'reason')">{{ child.reason || '' }}</view>
<view :class="['table-cell', `level-${child.level}`]" :key="getKey(child.id, 'level')">{{ getLevelDesc(child.level) }}</view>
<view class="table-cell" :key="getKey(child.id, 'result')">{{ child.result }}</view>
<view class="table-cell" :key="getKey(child.id, 'result')">{{ child.result || '' }}</view>
</template>
</view>
</view>
@ -22,10 +22,10 @@
<script>
const LEVEL_AND_DESC_MAPPING = {
0: '极高风险',
1: '高风险',
2: '中风险',
3: '低风险',
'0': '低风险',
'1': '中风险',
'2': '高风险',
'3': '极高风险',
}
export default {
@ -131,16 +131,16 @@
.level {
&-0 {
color: #B81C1C;
color: #014FA2;
}
&-1 {
color: #FF0000;
color: #FFA800;
}
&-2 {
color: #FFA800;
color: #FF0000;
}
&-3 {
color: #014FA2;
color: #B81C1C;
}
}
</style>

+ 33
- 17
pages_order/report/userInfo.vue View File

@ -4,15 +4,15 @@
<view class="status">
<view class="flex status-content">
<!-- todo: 缺切图 -->
<image class="icon" src="@/pages_order/static/report/icon-info.png" mode="widthFix"></image>
<uv-icon name="checkmark-circle-fill" color="#014FA2" size="48rpx"></uv-icon>
<view>支付成功</view>
</view>
</view>
<view class="tips">
<view class="flex tips-content">
<uv-icon name="error-circle" color="#014FA2" size="36rpx"></uv-icon>
<!-- <uv-icon name="error-circle" color="#014FA2" size="36rpx"></uv-icon> -->
<image class="icon" src="@/pages_order/static/report/icon-info.png" mode="widthFix"></image>
<view>请如实填写以下信息方可获取答题情况生成风险测评报告</view>
</view>
</view>
@ -75,7 +75,7 @@
</view>
<view class="bottom">
<button :class="['btn', disabled ? 'is-disabled' : '']" :disabled="disabled" @click="onCreateReport">生成报告</button>
<button :class="['btn', disabled ? 'is-disabled' : '']" @click="onCreateReport">生成报告</button>
</view>
</view>
</template>
@ -86,9 +86,9 @@
return {
id: null,
form: {
name: null,
phone: null,
company: null,
name: '',
phone: '',
company: '',
},
rules: {
'company': {
@ -105,22 +105,38 @@
disabled() {
const { name, phone, company } = this.form
return !name || !phone || !company
return !company
}
},
onLoad(arg) {
const { id } = arg
this.id = id
const { batchNo } = arg
this.batchNo = batchNo
},
methods: {
onCreateReport() {
// todo
uni.navigateTo({
url: `/pages_order/report/index?id=${this.id}`
methods: {
async onCreateReport() {
try {
await this.$refs.form.validate()
const { name, phone, company } = this.form
const params = {
batchNo: this.batchNo,
name,
phone,
company,
}
await this.$fetch('addReport', params)
uni.redirectTo({
url: `/pages_order/report/index?batchNo=${this.batchNo}`
})
},
} catch (err) {
}
},
},
}
</script>


+ 41
- 42
pages_order/service/index.vue View File

@ -3,20 +3,19 @@
<navbar title="咨询客服" leftClick @leftClick="$utils.navigateBack" bgColor="transparent" />
<!-- todo: check is swiper ? -->
<!-- <image class="bg" src="" mode="widthFix"></image> -->
<view class="flex bg">
<image class="bg" :src="configList.customer_service_bg" mode="widthFix"></image>
<!-- <view class="flex bg">
<view class="flex bg-content">
<view class="text">
<view class="title">Hi,有什么可以帮您</view>
<view class="flex desc">
<view class="desc">
<view class="line">工作时间</view>
<view class="line">8:00-12:00 13:00-17:30</view>
</view>
</view>
<image class="icon" src="@/pages_order/static/service/icon-service.png" mode="widthFix"></image>
</view>
</view>
</view> -->
<view class="main">
<view class="content">
@ -99,44 +98,44 @@
}
.bg {
// width: 100%;
// height: auto;
// min-height: 501rpx;
width: 100%;
height: 501rpx;
background: linear-gradient(160deg, #014FA2 36%, #4C8FD6);
padding: 0 104rpx 90rpx 65rpx;
box-sizing: border-box;
align-items: flex-end;
&-content {
width: 100%;
justify-content: space-between;
}
.text {
padding: 26rpx 0 34rpx 0;
color: #FFFFFF;
.title {
font-size: 36rpx;
font-weight: 600;
}
.desc {
margin-top: 13rpx;
font-size: 22rpx;
.line + .line {
margin-top: 11rpx;
}
}
}
.icon {
width: 168rpx;
height: auto;
}
height: auto;
min-height: 501rpx;
// width: 100%;
// height: 501rpx;
// background: linear-gradient(160deg, #014FA2 36%, #4C8FD6);
// padding: 0 104rpx 90rpx 65rpx;
// box-sizing: border-box;
// align-items: flex-end;
// &-content {
// width: 100%;
// justify-content: space-between;
// }
// .text {
// padding: 26rpx 0 34rpx 0;
// color: #FFFFFF;
// .title {
// font-size: 36rpx;
// font-weight: 600;
// }
// .desc {
// margin-top: 13rpx;
// font-size: 22rpx;
// .line + .line {
// margin-top: 11rpx;
// }
// }
// }
// .icon {
// width: 168rpx;
// height: auto;
// }
}
.main {


+ 9
- 15
pages_order/service/popupPhone.vue View File

@ -10,14 +10,12 @@
<view class="flex flex-column content">
<text class="title">电话咨询</text>
<view class="flex phone">
<!-- todo: check key -->
<view class="flex icon" @click="onCall(13256541235)">
<view class="flex icon" @click="onCall">
<image class="img" src="@/pages_order/static/service/icon-phone.png" mode="widthFix"></image>
</view>
<!-- todo: check key -->
<view>13256541235</view>
<view>{{ phone }}</view>
</view>
<button class="btn" @click="onCopy">复制手机号</button>
<button class="btn" @click="onCopy()">复制手机号</button>
</view>
</view>
</uv-popup>
@ -29,14 +27,9 @@
import utils from '@/utils/utils.js'
export default {
props: {
src: {
type: String,
default: null
}
},
data() {
return {
phone: '',
}
},
computed : {
@ -44,14 +37,15 @@
},
methods: {
open() {
this.phone = this.configList.customer_service_phone
this.$refs.popup.open();
},
close() {
this.$refs.popup.close();
},
onCall(phoneNumber) {
onCall() {
uni.makePhoneCall({
phoneNumber,
phoneNumber: this.phone,
success() {
console.log('安卓拨打成功');
},
@ -60,8 +54,8 @@
}
})
},
onCopy(phone) {
utils.copyText(phone)
onCopy() {
utils.copyText(this.phone)
},
},
}


+ 1
- 8
pages_order/service/popupQrCode.vue View File

@ -9,8 +9,7 @@
<image class="bg" src="@/pages_order/static/service/bg-popup-qr.png" mode="widthFix"></image>
<view class="flex flex-column content">
<text class="title">扫码添加微信</text>
<!-- todo: check key -->
<image class="img" src="" :show-menu-by-longpress="true"></image>
<image class="img" :src="configList.customer_service_qrcode" :show-menu-by-longpress="true"></image>
<button class="btn" @click="close">已截图</button>
</view>
</view>
@ -21,12 +20,6 @@
import { mapState } from 'vuex'
export default {
props: {
src: {
type: String,
default: null
}
},
data() {
return {
}


BIN
pages_order/static/feedback/icon-camera.png View File

Before After
Width: 133  |  Height: 133  |  Size: 2.3 KiB

BIN
pages_order/static/feedback/icon-star.png View File

Before After
Width: 27  |  Height: 27  |  Size: 588 B

+ 47
- 117
pages_order/test/answer.vue View File

@ -3,7 +3,7 @@
<navbar title="答题测评" leftClick @leftClick="$utils.navigateBack" bgColor="transparent" />
<!-- 答题完成 -->
<template v-if="current === total">
<template v-if="total && current === total">
<view class="flex main is-finish">
<view class="card">
<image class="card-bg" src="@/pages_order/static/test/bg-test-finsih.png" mode="widthFix"></image>
@ -42,30 +42,16 @@
<view class="question">{{ currentQuestion.question }}</view>
</view>
<view class="card-content">
<template v-if="currentQuestion.component === 'select'">
<view class="select">
<view
v-for="item in currentQuestion.options"
:key="item.id"
:class="['select-option', item.id === value ? 'is-active' : '']"
@click="onSelect(item.id)"
>
{{ item.content }}
</view>
<view class="select">
<view
v-for="item in currentQuestion.options"
:key="item.id"
:class="['select-option', item.id === value ? 'is-active' : '']"
@click="onSelect(item.id)"
>
{{ item.content }}
</view>
</template>
<template v-else-if="currentQuestion.component === 'select-multiple'">
<view class="select">
<view
v-for="item in currentQuestion.options"
:key="item.id"
:class="['select-option', value.includes(item.id) ? 'is-active' : '']"
@click="onSelectMulitple(item.id)"
>
{{ item.content }}
</view>
</view>
</template>
</view>
</view>
</view>
@ -82,8 +68,6 @@
</template>
<script>
import { mapState } from 'vuex'
export default {
data() {
return {
@ -91,7 +75,6 @@
tabs: [],
value: null,
answers: [],
paperTags: [],
batchNo: null,
questionsList: [],
total: 0,
@ -113,65 +96,42 @@
},
},
onLoad(arg) {
this.fetchQuestionList()
this.switchQuestion(parseInt(arg.current || 0))
const { ids, examId, current } = arg
this.current = parseInt(current || 0)
this.fetchQuestionList(ids, examId)
this.value = this.answers[this.current]
console.log('paperTags', this.paperTags)
console.log('currentQuestion', this.currentQuestion)
},
methods: {
async fetchQuestionList(categories) {
async fetchQuestionList(categories, examId) {
const result = await this.$fetch('queryQuestionList', { categories })
let result
// todo: set batchNo
if (examId) {
result = await this.$fetch('queryExamById', { examId })
} else {
result = await this.$fetch('queryQuestionList', { categories })
}
// todo: transfer
const questionsList = new Array(23).fill(1).map((item, index) => {
const id = `00${index}`
const { batchNo, pageList } = result
return {
id,
text: '问题内容文字问题内容文字问题内容文字问题内容文字问题内容文字?',
type: '0',
options: new Array(4).fill(1).map((option, oIdx) => {
return {
id: `${id}${oIdx}`,
content: '答案内容',
}
}),
}
})
this.batchNo = batchNo
this.questionsList = questionsList.map((item, index) => {
const { id, text, type, options, needTag, required, multiple: _multiple, content } = item
let component = 'select'
const multiple = _multiple == 'Y'
switch(type) { // 0- 1- 2-
case '1':
component = options?.length > 1 ? 'input-group' : 'input'
break
case '2':
component = multiple ? 'select-box-multiple' : 'select-box'
break
default:
component = multiple ? 'select-multiple' : 'select'
break
}
this.questionsList = pageList.map((item, index) => {
const { id, question, answerList } = item
return {
id,
question: `${index + 1}${text}`,
type,
component,
options: options.map((option, oIdx) => ({ id: option.id, content: `${String.fromCharCode(oIdx+65)}${option.content}` })),
needTag: needTag ? JSON.parse(needTag).map(config => config.tags).filter(tags => tags.length) : null,
required: required == 'Y',
multiple,
desc: content,
// question: `${index + 1}${question}`,
question,
options: answerList.map((option, oIdx) => {
return {
id: option.id,
// content: `${String.fromCharCode(oIdx+65)}${option.answer}`
content: `${option.answerNo}${option.answer}`
}
}),
}
})
this.total = this.questionsList.length
@ -181,50 +141,10 @@
console.log('questionsList', this.questionsList)
console.log('answers', this.answers)
},
switchQuestion(current) {
console.log('current', this.current, 'target', current)
let { needTag } = this.questionsList[current]
console.log('needTag length', needTag?.length)
if (!needTag?.length) {
this.current = current
this.tabs.push(this.current)
return
}
const selectTags = this.paperTags.flat(1)
console.log('selectTags', selectTags)
console.log('needTag', needTag)
let valid = needTag.some(tags => {
return tags.every(tag => {
const { value, exclude } = tag
let include = selectTags.includes(value)
return exclude ? !include : include
})
})
console.log('valid', valid)
if (valid) {
this.current = current
this.tabs.push(this.current)
return
}
if (current + 1 < this.questionsList.length) {
current += 1
this.switchQuestion(current)
return
}
this.fetchFinish()
},
async fetchAnswer() {
try {
const { id: questionsId, type, required, multiple, options } = this.currentQuestion
const { id: questionId } = this.currentQuestion
console.log('currentQuestion', this.currentQuestion)
console.log('value', this.value)
@ -240,7 +160,7 @@
let params = {
batchNo: this.batchNo,
questionsId,
questionId,
answerId: this.value,
}
await this.$fetch('updateAnswer', params)
@ -279,7 +199,7 @@
return
}
this.switchQuestion(this.current + 1)
this.current += 1
this.value = this.answers[this.current]
},
async finish() {
@ -298,7 +218,7 @@
this.value = this.value.includes(id) ? this.value.filter(item => item !== id) : this.value.concat(id)
},
onCreateReport() {
uni.navigateTo({
uni.redirectTo({
url: `/pages_order/report/pay?batchNo=${this.batchNo}`
})
},
@ -463,10 +383,20 @@
.card {
min-height: 745rpx;
padding: 0;
&-bg {
width: 100%;
height: auto;
}
&-content {
position: absolute;
top: 0;
left: 0;
justify-content: flex-end;
width: 100%;
height: 100%;
padding: 69rpx 94rpx;
box-sizing: border-box;


+ 12
- 8
pages_order/test/start.vue View File

@ -48,8 +48,7 @@
return {
list: [],
selectedArr: [],
// todo
mixinsListApi: '',
mixinsListApi: 'queryCategoryList',
}
},
computed: {
@ -58,12 +57,17 @@
},
methods: {
onStart() {
console.log('onStartTest', this.selectedArr)
// todo: fetch
let ids = this.selectedArr.map(item => item.id).join(';')
uni.navigateTo({
if (!this.selectedArr.length) {
uni.showToast({
title: '请选择您要答题的题库(可多选)',
icon:'none'
})
return
}
let ids = this.selectedArr.join(';')
uni.redirectTo({
url: `/pages_order/test/answer?ids=${ids}`
})
},


+ 20
- 5
pages_order/test/testCard.vue View File

@ -3,7 +3,7 @@
<view class="flex card-header">
<!-- todo: 缺切图 -->
<image class="icon" src="@/static/image/icon.png" mode="widthFix"></image>
<view>{{ `您还有${data.unfinishCount}道题未完成` }}</view>
<view>{{ unfinishCount ? `您还有${unfinishCount}道题未完成` : '您已完成测评,还未获取报告' }}</view>
</view>
<view class="card-content">
<view class="row">
@ -13,7 +13,8 @@
</view>
<view class="flex card-footer">
<button class="btn" @click="onRestart">重新测评</button>
<button class="btn btn-primary" @click="onContinue">继续答题</button>
<button v-if="unfinishCount" class="btn btn-primary" @click="onContinue">继续答题</button>
<button v-else class="btn btn-primary" @click="onCreateReport">获取报告</button>
</view>
</view>
</template>
@ -30,18 +31,32 @@
}
},
computed: {
unfinishCount() {
const { allNum, finishNum } = this.data
return allNum - finishNum
},
},
methods: {
onRestart() {
// todo: fetch by this.data.paperId
let id
// let id
// uni.navigateTo({
// url: `/pages_order/test/answer?id=${id}`
// })
uni.navigateTo({
url: `/pages_order/test/answer?id=${id}`
url: `/pages_order/test/start`
})
},
onContinue() {
uni.navigateTo({
url: `/pages_order/test/answer?id=${this.data.id}&current=${this.data.current}`,
url: `/pages_order/test/answer?examId=${this.data.id}`,
})
},
onCreateReport() {
// todo: check
uni.navigateTo({
url: `/pages_order/report/pay?batchNo=${this.data.batchNo}`
})
},
},


BIN
static/image/temp-01.png View File

Before After
Width: 57  |  Height: 41  |  Size: 1.7 KiB

BIN
static/image/temp-03.png View File

Before After
Width: 213  |  Height: 285  |  Size: 82 KiB

BIN
static/image/temp-05.png View File

Before After
Width: 118  |  Height: 118  |  Size: 28 KiB

+ 5
- 0
store/store.js View File

@ -96,6 +96,11 @@ const store = new Vuex.Store({
}
})
},
clearUserInfo(state) {
state.userInfo = {}
state.role = false
uni.removeStorageSync('token')
},
setCommonQuestion(state, data) {
state.commonQuestion = data
},


Loading…
Cancel
Save