WN 1 год назад
Родитель
Сommit
8bfc89d08c
4 измененных файлов: 630 добавлений и 0 удалений
  1. +2
    -0
      src/main.js
  2. +5
    -0
      src/router/index.js
  3. +286
    -0
      src/views/psychological-modeling/index.vue
  4. +337
    -0
      src/views/psychological-questionnaire/index.vue

+ 2
- 0
src/main.js Просмотреть файл

@@ -55,6 +55,7 @@ import {
Tabs,
Toast,
ActionSheet,
Progress,
} from 'vant'; //按需加载vant组件

Vue
@@ -97,6 +98,7 @@ Vue
.use(Tabs)
.use(Toast)
.use(ActionSheet)
.use(Progress)

Vue.config.productionTip = false;
Vue.config.devtools = true;


+ 5
- 0
src/router/index.js Просмотреть файл

@@ -31,6 +31,11 @@ const routes = [
{ path: '/cardActive', name: 'cardActive', component: resolve => require(['@/views/card-active'], resolve) },

{ path: '/alarmDetails', name: 'alarmDetails', component: resolve => require(['@/views/alarm/alarm-details'], resolve) },

// 心理监测
{ path: '/PsychologicalModeling', name: 'PsychologicalModeling', component: resolve => require(['@/views/psychological-modeling'], resolve) },
{ path: '/PsychologicalQuestionnaire', name: 'PsychologicalQuestionnaire', component: resolve => require(['@/views/psychological-questionnaire'], resolve) },

];

const router = new VueRouter({


+ 286
- 0
src/views/psychological-modeling/index.vue Просмотреть файл

@@ -0,0 +1,286 @@
<template>
<div class="page">
<div class="tip">
<div class="icon">
<i class="iconfont icon-tishi"></i>
</div>
<div class="info">
<div class="titie">温馨提醒:</div>
<div class="content">
首次佩戴,需完成以下2步,建立情绪模型。完成初始化建模后,将为您计算抑郁、压力、疲劳分值。
</div>
</div>
</div>
<div v-if="info">
<div class="step">
<div class="name">第一步</div>
<div class="title">
<div class="text">连续佩戴两小时</div>
<div class="status success" v-if="info.progress === 1">
<span class="icon"
><i class="iconfont icon-caozuochenggong"></i
></span>
<span>已完成</span>
</div>
<div class="status" v-else>待完成</div>
</div>
<div class="schedule">
<van-progress
:percentage="info.progress"
stroke-width="10px"
color="#638ee4"
:show-pivot="false"
></van-progress>
</div>
<div class="sub_title">
请连续佩戴不低于2小时,有助于为您输出更加精准的情绪分析指标。
</div>
</div>
<div class="step">
<div class="name">第二步</div>
<div class="title">
<div class="text">情绪初始化评估</div>
<div class="status success" v-if="info.initScaleState === 1">
<span class="icon"
><i class="iconfont icon-caozuochenggong"></i
></span>
<span>已完成</span>
</div>
<div class="status" v-else>待完成</div>
</div>
<div class="sub_title">
完成一次“情绪初始化评估”,有助于建立您的个人情绪模型。
</div>
</div>
<div class="button">
<van-button
round
type="info"
style="width: 100%; height: 100%"
@click="toQuestion"
v-if="info.initScaleState !== 1"
>情绪初始化评估</van-button
>
</div>
</div>
</div>
</template>

<script>
import axios from 'axios'

export default {
name: 'PsychologicalModeling',
data() {
return {
info: null,
}
},
mounted() {
//页面标题
window.document.title = '情绪初始化建模'

//页面传参
let params = { ...this.$route.query }

if (params.uid) {
this.uid = params.uid

//初始化
this.init()
} else {
this.$toast('参数错误')
}
},
methods: {
async init() {
let re = await this.api('/api/Question/Progress', {
method: 'GET',
sslVerify: false,
withCredentials: false,
params: {
uid: this.uid,
},
})
if (re.success) {
if (re.response && re.response.state === -1) {
this.$toast('用户不存在或未绑定手表')
} else {
this.info = re.response
}
} else {
this.$toast(re.msg)
}
},
toQuestion() {
this.$router.push(`/PsychologicalQuestionnaire?uid=${this.uid}`)
},
api(url, config) {
let baseUrl = 'http://172.16.1.97:9291'
setTimeout(() => {
this.$toast.loading({
message: '',
forbidClick: true,
duration: 0,
})
}, 100)
return new Promise((res) => {
axios({
url: `${baseUrl}${url}`,
...config,
})
.then((re) => {
if (re) {
if (re.data) {
console.log(re.data)
res(re.data)
this.$toast.clear()
return
}
this.$toast(`信息获取失败-${re.status}`)
res(true)
this.$toast.clear()
return
}
this.$toast(`信息获取失败-${url}`)
res(true)
this.$toast.clear()
})
.catch((e) => {
this.$toast(`信息获取失败-${url}`)
res(true)
this.$toast.clear()
console.log(e)
})
})
},
},
}
</script>

<style lang="scss" scoped>
@font-face {
font-family: 'iconfont'; /* Project id 2652084 */
src: url('data:application/x-font-woff2;charset=utf-8;base64,d09GMgABAAAAAAQoAAsAAAAACFQAAAPaAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHFQGYACDBgqEIIQDATYCJAMMCwgABCAFhGcHQRtqBxEVnBvJPhLjmMRz8aCJJho3wfN8ne+5817QmS/XTApqUAGT1kmpHaidloBWXGdzOaZE+Aj1S75l+ek70v5OL82zLE6hFEIiJEbx96dyFkjAnwUAJnXNTcUP1HiBAtaxhhUr2KsXyLuo1/rCrIx6BgFM6tACo12HbjZpk4bPmkIRGksqkFbKpPFjhxOWRnRLpRBGCEKXamQTATDWGo+AjeHn5RdRCYNBQGHt0mtM+1Hc+Zr+1VZ+0gf1Gl+CgIcbQABQQI2NmWVIu7MfKk7WQGHWKTUpDKIRjEkjySSEglIHt/zHM0CCWMoUTFVRGBclugwEvto8VnH9qyAIhIDrIApTOVMVOr2mNDQjKSPHeM4zz6ZrPrYDY3fjR7a4+xTrY15tvZVw5KkZtx/X+HznyRPHnvCeqZskVmTOjMmRnF1girdzz7F4ju3uiB/xc53CoFi1HdXMW9Vu1TonY+gTzqB98OucaHakkW3GjxWJhX9kQXymq/AjJ5sfbS5Hc9nm5+KfvW9ZiYfnRXbG8tzG6nK7+u265yW2Hv38lNG3PmqlJo7Hjv0enTXu0fJ0ouuAIf1WL94ysHiw9aA5vca2mth0ZPGOvtu99JioF7HtiBd95LA4E7Gj3qPSVmO6tC3erV1e54F9yvUsu3Bh2Z7l+lwiLGETNtvRp9ylmtsGlm7eieOF8GLvn+zifT/067/LLFd8TdeujrureHTFyFEf+hbPVft+SK96RrBXE7tqx8rt21XpUO2QwwZswmZvsZsOz8+pN3TsrzXZ143c71m5NwLL+4xyo30jdTbxttGdTvRcMG4rPzrU0SFdrfTjHqXWlOrxuHR1FdK1219m/7yFvU52Hh3x6th9I25U9b0QTS1XvFyq35thACTvqtuqZZiOq5kq9v9/w/jtj8cOTW/2P2xpAN5vbXsP+5NxDcwN4RfjFPjbqkFApFYhULpOcFsQQLEkk4cBmLYJfm81QBZvh6uzweUghMlOwSBEcVCEKYdpqhoEsIhCkDDNwaQ67VdbZPsIzBFdDKjEC4GQwRsM0rgKigw+mKa+ECCPHwTJ4A8mrqy2s6gkZs2oBC3oB9SGBudoJJR7QD92iqtiF+RY4wjkSVbM7HFAHmNGvPpCxIFj6mHHT8OuIwhMDRpJKpFQpqmre0liqJ+sYRCFgFgAzQOgxkAMOB8t+e87gHhGOhQMxC52JlKeyAdyEjIAtlcOoLYb6R254ikQBEdHORiiB9gpO9LZSQII9YMaEIOQUA2IB0pSgnJQZbK8un+5XYCJtaUSQ5Ro0kcqeo5kKhy8J7dhKXWs6skEAAA=');
}

.iconfont {
font-family: 'iconfont' !important;
// font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}

.icon-caozuochenggong:before {
content: '\e60f';
}

.icon-tishi:before {
content: '\e654';
}

.page {
width: 100%;
min-height: 100%;
box-sizing: border-box;
font-size: 3.6vw;
text-align: left;
background: #f4f4f4;
padding-bottom: 30vw;

.tip {
display: flex;
font-size: 3.3vw;
padding: 6vw 4vw;
justify-content: space-between;
align-items: center;
background: white;

.icon {
overflow: hidden;
display: flex;
justify-content: center;
align-items: center;
width: 40px;
height: 40px;
color: #ff865a;
font-size: 6vw;
border-radius: 50%;
background: #fff5f1;
}
.info {
width: calc(100% - 50px);
line-height: 20px;
text-align: left;
.titie {
color: #ff865a;
}
.content {
color: gray;
}
}
}

.step {
margin-top: 3vw;
padding: 4vw 8vw;
padding-right: 4vw;
background: white;

.name {
display: flex;
align-items: center;
font-size: 3.8vw;
padding-bottom: 2vw;

&::before {
content: '';
display: block;
width: 1vw;
height: 1vw;
border: 2px solid #638ee4;
border-radius: 50%;
margin-left: calc(-2vw - 4px);
margin-right: 1vw;
}
}
.title {
display: flex;
justify-content: space-between;
padding: 3vw 0;

.status {
color: #ff865a;
}
.success {
color: #638ee4;

.icon {
font-size: 4vw;
margin-right: 1vw;
}
}
}
.sub_title {
padding: 3vw 0;
color: gray;
}
}

.button {
position: fixed;
left: 0;
right: 0;
bottom: 15vw;
width: 75vw;
height: 14vw;
margin: auto;

.van-button--info {
background-color: #638ee4;
border: 1px solid #638ee4;
}
}
}
</style>

+ 337
- 0
src/views/psychological-questionnaire/index.vue Просмотреть файл

@@ -0,0 +1,337 @@
<template>
<div class="page" v-if="topic.length">
<div class="top">
<div class="schedule">
<div class="progress">
<van-progress
:percentage="(select.length / topic.length) * 100"
stroke-width="10px"
color="#638ee4"
:show-pivot="false"
v-if="select.length / topic.length"
></van-progress>
</div>
<div class="text">
<span class="val">{{ select.length }}</span
>/<span class="total">{{ topic.length }}</span>
</div>
</div>
<div class="title">{{ title }}</div>
</div>
<div class="list_box">
<div class="item" v-for="(item, index) in topic" :key="index">
<div class="label">
<span>{{ item.Title }}</span>
<span>({{ item.Type }})</span>
</div>
<van-radio-group
class="radio"
v-model="item.select"
v-if="item.Type == '单选题'"
>
<van-cell-group>
<van-cell
clickable
v-for="(ite, idx) in item.Option"
:key="idx"
:title="ite.label"
@click="onRadio(index, ite.value)"
>
<template #right-icon>
<van-radio :name="ite.value" />
</template>
</van-cell>
</van-cell-group>
</van-radio-group>
<van-checkbox-group class="checkbox" v-model="item.select" v-else>
<van-cell-group>
<van-cell
v-for="(ite, idx) in item.Option"
clickable
:key="idx"
:title="ite.label"
@click="onCheckbox(`checkboxes${item.QId}`, idx)"
>
<template #right-icon>
<van-checkbox
:name="ite.value"
:ref="`checkboxes${item.QId}`"
/>
</template>
</van-cell>
</van-cell-group>
</van-checkbox-group>
</div>
</div>
<div class="button">
<van-button
round
type="info"
:disabled="topic.length != select.length"
style="width: 100%; height: 100%"
@click="submit"
>提交问卷</van-button
>
</div>
</div>
</template>

<script>
import axios from 'axios'

export default {
name: 'PsychologicalModeling',
data() {
return {
uid: '',
keyCode: '',
title: '',
topic: [], //题目列表
select: [],
}
},
mounted() {
//页面标题
window.document.title = '情绪初始化评估'

//页面传参
let params = { ...this.$route.query }

if (params.uid) {
this.uid = params.uid

//初始化
this.init()
} else {
this.$toast('参数错误')
}
},
watch: {
selects(val) {
let temp = JSON.parse(val)
let tempt = temp.filter((item) => {
if (item.select) {
return true
}
})
this.select = tempt
},
},
computed: {
selects() {
return JSON.stringify(this.topic)
},
},
methods: {
async init() {
let re = await this.api('/api/Question/Get', {
method: 'GET',
sslVerify: false,
withCredentials: false,
params: {
// uid: this.uid,
},
})
if (re.success) {
if (re.response && re.response.length) {
let temp = re.response[0]
let code = temp.Code
this.title = temp.Memo
this.keyCode = temp.Code
let re1 = await this.api('/api/Question/GetQuestion', {
method: 'GET',
sslVerify: false,
withCredentials: false,
params: {
code: code,
},
})
if (re1.success) {
if (re1.response && re1.response.length) {
let topic = []
re1.response.forEach((item) => {
let tempt = { ...item }
let a1 = tempt.Option.split('#&')
let a2 = tempt.Score.split('#&')
let option = []
for (let index = 0; index < a1.length; index++) {
option.push({
label: a1[index],
value: a2[index],
})
}
tempt.Option = option
tempt.value = ''
topic.push(tempt)
})
this.topic = topic
} else {
this.$toast('问卷暂无题目')
}
} else {
this.$toast(re1.msg)
}
} else {
this.$toast('问卷不存在')
}
} else {
this.$toast(re.msg)
}
},
async submit() {
let temp = {
uid: this.uid, //客户端系统用户id
keyCode: this.keyCode, //问卷编号
answer: [],
}
this.topic.forEach((item) => {
temp.answer.push({
qid: item.QId, //问卷题目编号
value: typeof item.select == 'object' ? item.select.join(',') : item.select, //用户所选答案的 id
})
})
let re = await this.api('/api/Question/Rsults', {
method: 'POST',
sslVerify: false,
withCredentials: false,
data: temp,
})
if (re.success) {
this.$toast('问卷提交成功', 3000)
setTimeout(() => {
window.history.back(-1)
}, 3000)
} else {
this.$toast(re.msg)
}
},
onRadio(index, value) {
let temp = { ...this.topic[index] }
temp.select = value
this.$set(this.topic, index, temp)
},
onCheckbox(key, index) {
try {
this.$refs[`${key}`][index].toggle()
} catch (error) {
console.log(error)
}
},
api(url, config) {
setTimeout(() => {
this.$toast.loading({
message: '',
forbidClick: true,
duration: 0,
})
}, 100)
let baseUrl = 'http://172.16.1.97:9291'
return new Promise((res) => {
axios({
url: `${baseUrl}${url}`,
...config,
})
.then((re) => {
if (re) {
if (re.data) {
console.log(re.data)
res(re.data)
this.$toast.clear()
return
}
this.$toast(`信息获取失败-${re.status}`)
res(true)
this.$toast.clear()
return
}
this.$toast(`信息获取失败-${url}`)
res(true)
this.$toast.clear()
})
.catch((e) => {
this.$toast(`信息获取失败-${url}`)
res(true)
this.$toast.clear()
console.log(e)
})
})
},
},
}
</script>

<style lang="scss" scoped>
.page {
width: 100%;
min-height: 100%;
box-sizing: border-box;
font-size: 3.6vw;
text-align: left;
background: #f4f4f4;
padding-bottom: 8vw;
padding-top: 24vw;

.top {
box-sizing: border-box;
position: fixed;
top: 0;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 3vw;
width: 100vw;
height: 24vw;
background: white;
z-index: 99;

.schedule {
display: flex;
align-items: center;

.progress {
width: 85%;
}
.text {
width: 15%;
font-size: 4.5vw;
text-align: center;

.val {
font-size: 5vw;
font-weight: bold;
}
}
}
.title {
color: #638ee4;
}
}

.list_box {
width: 100%;
margin-top: 3vw;

.item {
margin-top: 3vw;
padding: 3vw;
background: white;

.label {
font-size: 4vw;
}
}
}

.button {
width: 75vw;
height: 14vw;
margin: 0 auto;
margin-top: 8vw;

.van-button--info {
background-color: #638ee4;
border: 1px solid #638ee4;
}
}
}
</style>

Загрузка…
Отмена
Сохранить