Browse Source

接口联调,页面完善,自测

cxmo 2 years ago
parent
commit
52899e4c82

+ 21 - 0
api/question.js

@@ -36,4 +36,25 @@ import { httpGet, httpPost } from "@/utils/request.js";
  */
  export const apiReplayAsk=params=>{
     return httpPost('/community/question/reply',params)
+}
+
+/**
+ * 问答详情
+ * @param question_id 
+ */
+ export const apiGetQuestion=params=>{
+    return httpGet('/community/question/detail',params)
+}
+/**
+ * 我的-未读数
+ */
+ export const apiGetUnread=params=>{
+    return httpGet('/community/question/unread',params)
+}
+/**
+ * 问答已读(批量)
+ * @param question_ids
+ */
+export const apiSetRead = params=>{
+    return httpPost('/community/question/reply/read',params)
 }

+ 1 - 1
mixin/index.js

@@ -5,7 +5,7 @@ moment.locale('zh-cn');
 import {globalImgUrls} from "../utils/config"
 import store from '@/store'
 
-const tabbarPathList=['pages/activity/activity','pages/buy/buy','pages/chart/chart','pages/user/user','pages/report/report']
+const tabbarPathList=['pages/activity/activity','pages/buy/buy','pages/chart/chart',/* 'pages/user/user', */'pages/report/report','pages/question/question']
 
 module.exports = {
   watch: {

+ 17 - 11
mixin/questionMixin.js

@@ -60,7 +60,6 @@ export default {
             this.innerAudio.onTimeUpdate(() => {
                 //console.log('时间更新')
                 this.currentAudioMsg.audioCurrentTime = this.innerAudio.currentTime * 1000
-                //console.log('duration',this.innerAudio.duration)
             })
             this.innerAudio.onPause(() => {
                 console.log("暂停");
@@ -112,14 +111,15 @@ export default {
                 }
             })
         },
-        //获取问答列表
-        async getQuestionList(status) {
+        //获取问答列表:status(问题状态) only_mine(只看我的)
+        async getQuestionList(status,onlyMine=0) {
             let questionData = []
             const res = await apiQuestionList({
                 page_index: this.page,
                 page_size: this.pageSize,
                 chart_permission_id: this.selectId === -1 ? '' : this.selectId,
-                reply_status: status
+                reply_status: status,
+                only_mine:onlyMine
             })
             if (res.code === 200) {
                 if (res.data) {
@@ -134,7 +134,7 @@ export default {
                 let audio_url = '',
                     audio_play_seconds = 0;
                 //问题状态为已回答,取audio_list第一项为音频
-                if (status === 3) {
+                if (item.reply_status === 3) {
                     audio_url = item.audio_list[0].audio_url
                     audio_play_seconds = item.audio_list[0].audio_play_seconds
                 }
@@ -159,10 +159,10 @@ export default {
         //点击某条音频
         handleAudio(item) {
             //如果没有权限,弹窗并return
-           /*  if (!item.auth_ok) {
+            if (!item.auth_ok) {
             	this.initPupData(item)
             	return
-            } */
+            }
             const {
                 source,
                 isplay
@@ -174,7 +174,7 @@ export default {
                 //说明是暂停->播放
                 this.innerAudio.play()
             } else {
-                console.log('aaa', source, this.innerAudio.src)
+                //console.log('aaa', source, this.innerAudio.src)
                 //说明是第一次播放或点击其他播放项
                 this.changeCurrentAudio(item)
                 this.innerAudio.stop()
@@ -242,10 +242,16 @@ export default {
                     const res = await apiApplyPermission({
                         company_name: this.pupData.customer_info.company_name,
                         real_name: this.pupData.customer_info.name,
-                        source: 2,
-                        from_page: '活动列表'
+                        source: 5,
+                        from_page: '问答社区'
                     })
-                    if (res.code === 200) {}
+                    if (res.code === 200) {
+                        //重新获取页面数据
+                        const pages = getCurrentPages();
+                        const page = pages[pages.length - 1];
+                     /*    page.onLoad(); */
+                        page.onShow();
+                    }
                     this.pupData.content = `<p>申请已提交</p><p>请等待销售人员与您联系</p>`
                     this.pupData.type = ''
 

+ 313 - 158
pages-question/answerDetail.vue

@@ -1,180 +1,223 @@
 <template>
   <view class="answerdetail-page flex-column">
-    <view class="question-wrap">
-      <view class="question-item">
-        <view class="question-info">
-          <view style="flex: 1" class="question-title">
-            <text class="item-label">{{
-              questionItem.chart_permission_name
-            }}</text>
-            {{ questionItem.question_content }}
-          </view>
-          <view class="item-answer" v-if="questionItem.reply_status === 3">
-            <view class="answer" @click.stop="handleAudio(questionItem)">
-              <template v-if="!questionItem.loading">
-                <image
-                  class="music-img"
-                  :src="questionItem.answer.isplay ? playImgSrc : pauseImgSrc"
-                  mode="widthFix"
-                />
-                <template
-                  v-if="
-                    questionItem.answer.isplay || questionItem.answer.ispause
-                  "
-                >
-                  <text>{{
-                    questionItem.answer.audioTime -
-                      currentAudioMsg.audioCurrentTime >
-                    0
-                      ? moment(
-                          questionItem.answer.audioTime -
-                            currentAudioMsg.audioCurrentTime
-                        ).format("mm:ss")
-                      : "00:00"
-                  }}</text>
+    <template v-if="questionItem">
+      <view class="question-wrap">
+        <view class="question-item">
+          <view class="question-info">
+            <view style="flex: 1" class="question-title">
+              <text class="item-label">{{
+                questionItem.chart_permission_name
+              }}</text>
+              {{ questionItem.question_content }}
+            </view>
+            <view class="item-answer" v-if="questionItem.reply_status === 3">
+              <view class="answer" @click.stop="handleAudio(questionItem)">
+                <template v-if="!questionItem.loading">
+                  <image
+                    class="music-img"
+                    :src="questionItem.answer.isplay ? playImgSrc : pauseImgSrc"
+                    mode="widthFix"
+                  />
+                  <template
+                    v-if="
+                      questionItem.answer.isplay || questionItem.answer.ispause
+                    "
+                  >
+                    <text>{{
+                      questionItem.answer.audioTime -
+                        currentAudioMsg.audioCurrentTime >
+                      0
+                        ? moment(
+                            (questionItem.answer.audioTime -
+                              currentAudioMsg.audioCurrentTime) *
+                              1000
+                          ).format("mm:ss")
+                        : "00:00"
+                    }}</text>
+                  </template>
+                  <template v-else>
+                    <text>{{
+                      moment(questionItem.answer.audioTime * 1000).format(
+                        "mm:ss"
+                      )
+                    }}</text>
+                  </template>
                 </template>
                 <template v-else>
+                  <image
+                    class="load-img"
+                    src="../static/loading.png"
+                    mode="aspectFill"
+                  />
                   <text>{{
                     moment(questionItem.answer.audioTime).format("mm:ss")
                   }}</text>
                 </template>
-              </template>
-              <template v-else>
-                <image
-                  class="load-img"
-                  src="../static/loading.png"
-                  mode="aspectFill"
-                />
-                <text>{{
-                  moment(questionItem.answer.audioTime).format("mm:ss")
-                }}</text>
-              </template>
+              </view>
             </view>
           </view>
+          <text class="item-time">提问时间:{{ questionItem.create_time }}</text>
         </view>
-        <text class="item-time">提问时间:{{ questionItem.create_time }}</text>
-      </view>
-    </view>
-    <view
-      class="record-wrap flex-column"
-      v-if="questionItem.reply_status === 2"
-    >
-      <view class="record flex-column" v-if="questionItem.recordStatus !== 4">
-        <view class="no-record" v-if="questionItem.recordStatus === 1">
-          <image src="../static/question/record.png" mode="widthFix" />
-          <view>无录音(录音时长超过三分钟自动结束)</view>
-        </view>
-        <view class="record-time" v-else>{{ audioTime }}</view>
       </view>
       <view
-        class="record-tool flex-column"
-        v-if="questionItem.recordStatus !== 4"
+        class="record-wrap flex-column"
+        v-if="questionItem.reply_status === 2"
       >
-        <view class="hint" v-if="questionItem.recordStatus === 1"
-          >点击开始录音</view
-        >
-        <view class="record-btn-wrap">
-          <text @click="handleRecode('delete')">删除</text>
-          <view class="switch" @click="changeRecodeStatus">
+        <view class="record flex-column" v-if="questionItem.recordStatus !== 4">
+          <!-- <view class="no-record" v-if="questionItem.recordStatus === 1">
             <image
-              v-if="questionItem.recordStatus >= 2"
-              :src="questionItem.recordStatus === 2 ? playImgSrc : pauseImgSrc"
-              :style="{
-                'margin-left': questionItem.recordStatus !== 2 ? '7rpx' : 0,
-              }"
+              src="../static/question/record.png"
               mode="widthFix"
+              style="width: 90rpx; height: 180rpx"
             />
+            <view>无录音(录音时长超过三分钟自动结束)</view>
+          </view>
+          <view class="record-time" v-else>{{ audioTime }}</view> -->
+          <view class="recode-image">
+            <scroll-view scroll-x style="height: 100rpx" class="scroll-view" :scroll-left="scrollTop" @scrolltolower="handleScrolltolower" :show-scrollbar="false">
+              <view style="width:100%;height:100rpx;display:inline-block;"></view>
+              <image
+                src="../static/question/record-img.png"
+                mode="scaleToFill"
+              />
+              <image
+                src="../static/question/record-img.png"
+                mode="scaleToFill"
+              />
+              <image
+                src="../static/question/record-img.png"
+                mode="scaleToFill"
+              />
+            </scroll-view>
           </view>
-          <text @click="handleRecode('finish')">完成</text>
         </view>
-      </view>
-      <view class="record-play" v-if="questionItem.recordStatus === 4">
-        <view class="audio-wrap">
-          <view v-if="pageLoading">音频生成中...</view>
-          <view class="play" v-else>
-            <van-icon
-              :name="isplay ? 'pause' : 'play'"
-              @click="handleAudioByReplay"
-              color="#E6B77DFF"
-              size="64rpx"
-              style="align-items: flex-start; margin-left: -20rpx"
-            />
-
-            <!-- 进度条 -->
-            <view class="slider-box">
-              <slider
-                :value="currentAudioMsg.audioCurrentTime"
-                :max="currentAudioMsg.audioTime"
-                @change="sliderChange($event)"
-                activeColor="#E6B77DFF"
-                backgroundColor="#EBEBEBFF"
-                block-color="#E6B77DFF"
-                block-size="12"
+        <view
+          class="record-tool flex-column"
+          v-if="questionItem.recordStatus !== 4"
+        >
+          <view class="hint" v-if="questionItem.recordStatus === 1"
+            >点击开始录音</view
+          >
+          <view class="record-time" v-else>{{ audioTime }}</view>
+          <view
+            class="record-btn-wrap center"
+            v-if="questionItem.recordStatus === 1"
+          >
+            <view class="switch" @click="changeRecodeStatus"> </view>
+          </view>
+          <view class="record-btn-wrap" v-else>
+            <text
+              @click="questionItem.recordStatus === 3 && handleRecode('delete')"
+              v-if="questionItem.recordStatus >= 2"
+              :class="{ active: questionItem.recordStatus === 3 }"
+              >删除</text
+            >
+            <view class="switch" @click="changeRecodeStatus">
+              <image
+                v-if="questionItem.recordStatus >= 2"
+                :src="
+                  questionItem.recordStatus === 2 ? playImgSrc : pauseImgSrc
+                "
+                :key="playIconKey"
+                :style="{
+                  'margin-left': questionItem.recordStatus !== 2 ? '7rpx' : 0,
+                  width: '36rpx',
+                  height: '44rpx',
+                }"
+                mode="widthFix"
               />
-              <view class="slider-time">
-                <text>{{
-                  moment(currentAudioMsg.audioCurrentTime * 1000).format(
-                    "mm:ss"
-                  )
-                }}</text>
-                <text>{{
-                  moment(currentAudioMsg.audioTime * 1000).format("mm:ss")
-                }}</text>
+            </view>
+            <text
+              @click="handleRecode('finish')"
+              v-if="questionItem.recordStatus >= 2"
+              :class="{ active: questionItem.recordStatus >= 2 }"
+              >完成</text
+            >
+          </view>
+        </view>
+        <view class="record-play" v-if="questionItem.recordStatus === 4">
+          <view class="audio-wrap">
+            <view v-if="pageLoading">音频生成中...</view>
+            <view class="play" v-else>
+              <van-icon
+                :name="isplay ? 'pause' : 'play'"
+                @click="handleAudioByReplay"
+                color="#E6B77DFF"
+                size="64rpx"
+                style="align-items: flex-start; margin-left: -20rpx"
+              />
+
+              <!-- 进度条 -->
+              <view class="slider-box">
+                <slider
+                  :value="currentAudioMsg.audioCurrentTime"
+                  :max="currentAudioMsg.audioTime"
+                  @change="sliderChange($event)"
+                  @changing="sliderChanging"
+                  activeColor="#E6B77DFF"
+                  backgroundColor="#EBEBEBFF"
+                  block-color="#E6B77DFF"
+                  block-size="12"
+                />
+                <view class="slider-time">
+                  <text>{{
+                    moment(currentAudioMsg.audioCurrentTime * 1000).format(
+                      "mm:ss.SS"
+                    )
+                  }}</text>
+                  <text>{{
+                    moment(currentAudioMsg.audioTime * 1000).format("mm:ss.SS")
+                  }}</text>
+                </view>
               </view>
             </view>
           </view>
+          <view class="audio-delete" @click="handleRecode('delete')">
+            <image
+              src="../static/question/delerecord.png"
+              mode="heightFix"
+              style="width: 32rpx; height: 35rpx"
+            />
+            <text>删除</text></view
+          >
+          <view class="audio-pub" @click="handleRecode('pub')">发布</view>
         </view>
-        <view class="audio-delete" @click="handleRecode('delete')">
-          <image src="../static/question/delerecord.png" mode="heightFix" />
-          <text>删除</text></view
-        >
-        <view class="audio-pub" @click="handleRecode('pub')">发布</view>
       </view>
-    </view>
+    </template>
   </view>
 </template>
 
 <script>
 import mixin from "../mixin/questionMixin";
-import { apiReplayAsk } from "@/api/question";
-import { uploadToServer, uploadAudioToServer } from "@/utils/upload";
+import { apiReplayAsk, apiGetQuestion, apiSetRead } from "@/api/question";
+import { uploadAudioToServer } from "@/utils/upload";
 export default {
   mixins: [mixin],
   data() {
     return {
-      questionItem: {
-        id: 1,
-        chart_permission_id: 1,
-        question_content: "疫情下全球苯乙烯市场有什么动荡和影响",
-        create_time: "2022.5.23 14:40",
-        answer: {
-          source:
-            "https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-hello-uniapp/2cc220e0-c27a-11ea-9dfb-6da8e309e0d8.mp3",
-          audioTime: 21 * 1000,
-          isplay: false,
-          ispause: false,
-        },
-        loading: false,
-        reply_status: 2,
-        chart_permission_name: "苯乙烯",
+      questionItem: null /* {
         recordStatus: 1, //1:未录音;2:正在录音;3:已暂停;4:完成录音
-      },
+      }, */,
       pauseImgSrc: "../static/question/recordplay.png",
       playImgSrc: "../static/question/recordpause.png",
       innerAudio: null, //该页面的音频
-      audioCount: 0, //录音计时
-      audioTime: "00:00", //录音时间
+      audioCount: 0, //录音计时,毫秒
+      recordStartTime: null, //录音开始时间
+      recordStopTime: null, //录音停止的时间
+      audioTime: "00:00", //录音时间(格式化后):string
       timer: null,
-      audioItem: {},
+      audioItem: null,
       pageLoading: false,
       isPlayed: false, //拖动进度条前音频是否为播放状态
       playIconKey: 0,
       isplay: false,
+      isSlider: false,
+      scrollTop:0,
     };
   },
   onLoad(options) {
     this.initAudio();
-    //this.getQuestionItem(options.id)
+    this.getQuestionItem(options.id);
   },
   methods: {
     //初始化audio
@@ -191,14 +234,16 @@ export default {
         this.questionItem.loading = false;
       });
       this.innerAudio.onTimeUpdate(() => {
-        console.log("时间更新", this.innerAudio.currentTime);
-        this.currentAudioMsg.audioCurrentTime = parseInt(
+        //console.log("时间更新", this.innerAudio.currentTime);
+        /* this.currentAudioMsg.audioCurrentTime = parseInt(
           this.innerAudio.currentTime
-        );
+        ); */
+        this.currentAudioMsg.audioCurrentTime = this.innerAudio.currentTime;
       });
       this.innerAudio.onSeeked(() => {
         //取this.innerAudio.currentTime为0
         console.log("seek完成");
+        this.isSlider = false;
       });
       this.innerAudio.onPause(() => {
         this.isplay = false;
@@ -209,28 +254,35 @@ export default {
         console.log("音频播放完毕");
         this.questionItem.answer.isplay = false;
         this.questionItem.answer.ispause = false;
-        this.changeCurrentAudio({
+        /* this.changeCurrentAudio({
           id: "",
           answer: {
             source: "",
             audioTime: 0,
           },
-        });
+        }); */
+        this.currentAudioMsg.audioCurrentTime = 0;
+        this.isplay = false;
       });
     },
     //录音事件
     handleRecorderFun() {
       this.globalRecorder.onStart(() => {
         console.log("开始录音");
+        this.clockTime();
       });
       this.globalRecorder.onPause(() => {
         console.log("暂停录音");
-        /* this.cleanTime(); */
+        this.cleanTime();
       });
       this.globalRecorder.onStop((res) => {
         console.log("录音完成");
+        //录音自动结束 和 暂停时点击删除 的情况
+        if (this.questionItem.recordStatus === 2) {
+          this.questionItem.recordStatus = 4;
+        }
+        console.log('status',this.questionItem.recordStatus)
         console.log("res", JSON.stringify(res));
-        //this.innerAudio.src = res.tempFilePath;
         this.cleanTime();
         //初始化音频播放
         this.innerAudio.src = res.tempFilePath;
@@ -250,17 +302,58 @@ export default {
         console.log("?", res);
       }); */
     },
+    async getQuestionItem(id) {
+      const res = await apiGetQuestion({
+        question_id: id,
+      });
+      if (res.code === 200) {
+        this.questionItem = res.data;
+        const { audio_list } = res.data;
+        let temp = {};
+        if (audio_list.length > 0) {
+          temp = {
+            source: res.data.audio_list[0].audio_url,
+            audioTime: parseInt(res.data.audio_list[0].audio_play_seconds),
+            isplay: false,
+            ispause: false,
+          };
+        } else {
+          temp = {
+            source: "",
+            audioTime: 0,
+            isplay: false,
+            ispause: false,
+          };
+        }
+        let readKey = "";
+        const { is_inner } = this.userInfo;
+        if (is_inner === 1) {
+          readKey = "replier_is_read";
+        } else {
+          readKey = "is_read";
+        }
+        //console.log('readKey',readKey)
+        this.questionItem[readKey] !== 1 &&
+          (await apiSetRead({
+            question_ids: this.questionItem.community_question_id + "",
+          }));
+        this.questionItem.id = res.data.community_question_id;
+        this.questionItem.answer = temp;
+        this.questionItem.loading = false;
+        this.questionItem.recordStatus = res.data.reply_status > 2 ? 4 : 1;
+      }
+    },
     changeRecodeStatus() {
       //根据questionItem.recordStatus
       if (this.questionItem.recordStatus === 1) {
         //开始录音
         this.globalRecorder.start({ duration: 180000, format: "mp3" });
-        this.clockTime();
+        //this.clockTime();
         this.questionItem.recordStatus = 2;
       } else if (this.questionItem.recordStatus === 2) {
         //暂停录音
         this.globalRecorder.pause();
-        this.cleanTime();
+        //this.cleanTime();
         this.questionItem.recordStatus = 3;
       } else if (this.questionItem.recordStatus === 3) {
         //继续录音
@@ -270,12 +363,12 @@ export default {
       } else {
         //结束录音
         this.globalRecorder.stop();
-        this.cleanTime();
+        //this.cleanTime();
       }
     },
     //上传音频
     async uploadAudio() {
-      const res = await uploadAudioToServer(this.innerAudio.src)
+      const res = await uploadAudioToServer(this.innerAudio.src);
       if (res.code === 200) {
         this.audioItem = res.data;
       } else {
@@ -285,30 +378,46 @@ export default {
         this.audioTime = this.moment(this.audioCount * 1000).format("mm:ss");
       }
     },
+    //录音操作:完成/删除/发布
     async handleRecode(type) {
-      this.questionItem.recordStatus = 4;
-      this.changeRecodeStatus();
+      if (type==='finish') {
+        this.questionItem.recordStatus = 4;
+        this.changeRecodeStatus();
+      }
       if (type === "finish") {
         //生成音频,更改页面布局
         this.pageLoading = true;
       } else if (type === "delete") {
         //重新录
+        if(this.questionItem.recordStatus===3)this.globalRecorder.stop();
         this.questionItem.recordStatus = 1;
+        this.audioItem = null;
         this.audioCount = 0;
+        this.scrollTop = 0;
+        this.recordStartTime = null;
         this.audioTime = this.moment(this.audioCount * 1000).format("mm:ss");
       } else {
         //发布
-        await this.uploadAudio();
+        if (!this.audioItem) {
+          await this.uploadAudio();
+        }
         //如果上传音频成功
         if (this.questionItem.recordStatus === 4) {
           //发布回答
           const res = await apiReplayAsk({
-            question_id: 5,
-            audio_list: [{...this.audioItem,sort:1}],
+            question_id: this.questionItem.community_question_id,
+            audio_list: [{ ...this.audioItem, sort: 1 }],
           });
           if (res.code === 200) {
-            //关闭当前页面,跳转到我的回答
-            uni.navigateBack({ delta: 1 });
+            uni.showToast({
+              title: "发布成功",
+              icon: "success",
+              duration: 500,
+            });
+            setTimeout(() => {
+              //关闭当前页面,跳转到我的回答
+              uni.navigateBack({ delta: 1 });
+            }, 500);
           }
         }
       }
@@ -327,8 +436,8 @@ export default {
         this.questionItem.answer.isplay = true;
         this.questionItem.answer.ispause = false;
       } else {
-        console.log("aaa", source, this.innerAudio.src);
-        //说明是第一次播放
+        //console.log("aaa", source, this.innerAudio.src);
+        //说明是第一次播放或播放完
         this.changeCurrentAudio(item);
         this.innerAudio.stop();
         this.innerAudio.src = source;
@@ -344,7 +453,7 @@ export default {
       } else {
         this.innerAudio.pause();
       }
-      this.playIconKey++;
+      this.playIconKey++; //更新音频播放图标
     },
     //拖动音频进度条
     sliderChange(e) {
@@ -354,6 +463,9 @@ export default {
       this.innerAudio.seek(value);
       this.currentAudioMsg.audioCurrentTime = value;
     },
+    sliderChanging() {
+      this.isSlider = true;
+    },
     //切换当前播放音频
     changeCurrentAudio(item) {
       const { id } = item;
@@ -365,24 +477,39 @@ export default {
         audioCurrentUrl: source,
       };
       if (id) {
+        console.log("?");
         this.questionItem.loading = true;
       }
     },
     //录音计时
     clockTime() {
-      console.log("开始计时");
+      console.log("开始录音计时");
+      if (!this.recordStartTime) {
+        this.recordStartTime = Date.now();
+      }
+      //console.log(this.recordStartTime);
       this.timer = setInterval(() => {
         if (this.timer) {
-          this.audioCount++;
-          this.audioTime = this.moment(this.audioCount * 1000).format("mm:ss");
+          this.audioCount += 30;
+          this.audioTime = this.moment(this.audioCount).format("mm:ss.SS");
+          //this.audioTime = this.moment(Date.now() - this.recordStartTime).format("mm:ss.SS");
+          this.scrollTop+=1;
         }
-      }, 1000);
+      }, 30);
     },
     //清除录音计时
     cleanTime() {
-      this.timer = null;
-      this.audioTime = this.moment(this.audioCount * 1000).format("mm:ss");
+      console.log("结束录音计时");
+      //console.log('aa',this.recordStopTime)
+      clearTimeout(this.timer);
+      this.playIconKey++; //更新录音暂停播放图标
+      //this.audioTime = this.moment(this.audioCount).format("mm:ss.SS");
     },
+    //scroll-view滑动到最右
+    handleScrolltolower(){
+      console.log('a',this.scrollTop)
+      this.scrollTop-=150;
+    }
   },
 };
 </script>
@@ -417,9 +544,31 @@ export default {
           width: 94rpx;
         }
       }
-      .record-time {
+    /*   .record-time {
         justify-self: flex-end;
         font-size: 60rpx;
+      } */
+      .recode-image {
+        width: 100%;
+        height: 100%;
+        background-color: #fafafaff;
+        display: flex;
+        align-items: center;
+        .scroll-view {
+          width: 100%;
+          white-space: nowrap;
+          ::-webkit-scrollbar{
+            width:0;
+            height:0;
+            display:none;
+            color:transparent;
+          }
+          image {
+            width: 421rpx;
+            height: 100rpx;
+            margin-right: 6rpx;
+          }
+        }
       }
     }
     .record-tool {
@@ -434,12 +583,18 @@ export default {
         position: absolute;
         top: 50rpx;
       }
+      .record-time{
+        font-size: 60rpx;
+      }
       .record-btn-wrap {
         margin-top: 38rpx;
         display: flex;
         width: 100%;
         justify-content: space-around;
         align-items: center;
+        &.center {
+          justify-content: center;
+        }
         text {
           color: #999999ff;
           font-size: 32rpx;

+ 37 - 20
pages-question/answerList.vue

@@ -12,7 +12,7 @@
     </view>
     <view class="answer-list">
       <view class="report-empty-box" v-if="questionList.length == 0">
-        <image :src="globalImgUrls.activityNoAuth" mode="widthFix" />
+        <image :src="globalImgUrls.activityNoAuth" mode="widthFix" style="width:100%;"/>
         <view>暂无数据</view>
       </view>
       <view
@@ -25,7 +25,7 @@
           <view style="flex: 1" class="question-title">
             <text
               class="item-label"
-              v-if="visitor.type === 1 || item.reply_status === 3"
+              v-if="userInfo.is_inner === 1 || item.reply_status === 3"
               >{{ item.chart_permission_name }}</text
             >
             {{ item.question_content }}
@@ -39,12 +39,12 @@
                   mode="widthFix"
                 />
                 <template v-if="item.answer.isplay || item.answer.ispause">
-                  <text>{{
-                    moment(
-                      item.answer.audioTime - currentAudioMsg.audioCurrentTime
-                    ).format("mm:ss")
-                  }}</text>
-                </template>
+									<text>{{
+										item.answer.audioTime - currentAudioMsg.audioCurrentTime>0?
+										moment(item.answer.audioTime - currentAudioMsg.audioCurrentTime).format('mm:ss')
+										:'00:00'}}
+									</text>
+								</template>
                 <template v-else>
                   <text>{{
                     moment(item.answer.audioTime).format("mm:ss")
@@ -85,7 +85,7 @@
               >{{ pupData.mobile || "123456" }}</text
             >
           </view>
-          <view class="apply" v-else-if="pupData.type == 'apply'">
+          <view class="apply" v-else-if="pupData.type === 'apply'">
             <view @click="handleApply">立即申请</view>
           </view>
         </view>
@@ -95,7 +95,7 @@
 </template>
 <script>
 import mixin from "../mixin/questionMixin";
-import { apiBarTotal } from "@/api/question.js";
+import { apiBarTotal ,apiSetRead} from "@/api/question.js";
 export default {
   mixins: [mixin],
   data() {
@@ -103,15 +103,17 @@ export default {
       questionList: [],
       barList: [],
       selectKey: "Wait",
-      visitor: {
-        type: 1, //1研究员,2客户
-      },
       pauseImgSrc: "../static/question/recordplay.png",
       playImgSrc: "../static/question/recordpause.png",
     };
   },
   onLoad() {
-    this.getVisitor();
+    /* this.getVisitor();
+    this.getBarList();
+    this.getQuestionData(); */
+  },
+  onShow() {
+    this.getSelectKey();
     this.getBarList();
     this.getQuestionData();
   },
@@ -123,7 +125,7 @@ export default {
   methods: {
     toDetail(item) {
       //reply_status:1-待分配 2-待回答 3-已回答
-      if (this.visitor.type === 1 && item.reply_status === 2) {
+      if (this.userInfo.is_inner === 1 && item.reply_status === 2) {
         uni.navigateTo({ url: "/pages-question/answerDetail?id=" + item.id });
       }
     },
@@ -135,8 +137,8 @@ export default {
       this.page = 1;
       this.getQuestionData();
     },
-    getVisitor() {
-      if(this.visitor.type===1){
+    getSelectKey() {
+      if(this.userInfo.is_inner === 1){
         this.selectKey = 'Wait'
       }else{
         this.selectKey = 'Replied'
@@ -182,12 +184,27 @@ export default {
           num: total,
         },
       ];
-      this.barList = this.visitor.type === 2 ? customBar : researBar;
+      this.barList = this.userInfo.is_inner === 1 ? researBar : customBar;
     },
-    getQuestionData() {
+    async getQuestionData() {
       const reply_status = { Wait: 2, Replied: 3, Total: 0 };
-      this.getQuestionList(reply_status[this.selectKey]);
+      await this.getQuestionList(reply_status[this.selectKey],1);
+      this.setQuestionsRead()
     },
+    async setQuestionsRead(){
+      //获取未读的数据,请求未读接口变为已读
+      let unReadArr = []
+      this.questionList.forEach(item=>{
+        let isReadKey = this.userInfo.is_inner===1?'replier_is_read':'is_read'
+        if(item[isReadKey]===0){
+          unReadArr.push(item.community_question_id)
+        }
+      })
+      if(unReadArr.length===0) return
+      await apiSetRead({
+        question_ids:unReadArr.join(',')
+      })
+    }
   },
 };
 </script>

+ 7 - 1
pages.json

@@ -256,11 +256,17 @@
 				"iconPath": "./static/tabbar/activity.png",
 				"selectedIconPath": "./static/tabbar/activity-s.png"
 			},
-			{
+			/* {
 				"pagePath": "pages/user/user",
 				"text": "我的",
 				"iconPath": "./static/tabbar/user.png",
 				"selectedIconPath": "./static/tabbar/user-s.png"
+			}, */
+			{
+				"pagePath": "pages/question/question",
+				"text": "问答",
+				"iconPath": "./static/tabbar/question.png",
+				"selectedIconPath": "./static/tabbar/question-s.png"
 			}
 		]
 	},

+ 51 - 35
pages/question/question.vue

@@ -1,7 +1,7 @@
 <template>
 	<view class="question-wrap">
 		<view class="question-top">
-			<view @click="showPopup" v-if="vistor.type===1||vistor.status&&!noAuth.includes(vistor.status)"
+			<view @click="showPopup" v-if="userInfo.is_inner===1||userInfo.status&&!noAuth.includes(userInfo.status)"
 				  style="display:flex;align-items: center;margin-left:30rpx;">
 				<image src="../../static/question/select.png" mode="widthFix" class="menu-icon"/>
 				<text style="color:#E3B377;font-size:28rpx;">筛选</text>
@@ -31,10 +31,10 @@
 			</van-popup>		
 		</view>
 		<view class="report-empty-box" v-if="questionList.length==0">
-      		<image :src="globalImgUrls.activityNoAuth" mode="widthFix" />
-      		<view>暂无提问<text v-if="visitor.type===2">,快试试提问功能吧</text></view>
+      		<image :src="globalImgUrls.activityNoAuth" mode="widthFix"  style="width:100%;"/>
+      		<view>暂无提问<text v-if="userInfo.is_inner!==1">,快试试提问功能吧</text></view>
     	</view>
-		<view class="question-list">
+		<view class="question-list" :class="{'last':finished}">
 			<view class="question-item" v-for="item in questionList" :key="item.community_question_id">
 				<view class="question-info">
 					<view style="flex:1;" class="question-title">
@@ -44,11 +44,13 @@
 					<view class="item-answer">
 						<view class="answer" @click="handleAudio(item)">
 							<template v-if="!item.loading">
-								<!-- <text>{{ item.answer.isplay ? '暂停' : '播放' }}</text> -->
 								<image class="music-img" :src="item.answer.isplay?playImgSrc:pauseImgSrc" mode="widthFix"/>
 								<template v-if="item.answer.isplay || item.answer.ispause">
-									<!-- <text>{{ currentAudioMsg.audioCurrentTime }}/{{ item.answer.audioTime }}</text> -->
-									<text>{{moment(item.answer.audioTime - currentAudioMsg.audioCurrentTime).format('mm:ss')}}</text>
+									<text>{{
+										item.answer.audioTime - currentAudioMsg.audioCurrentTime>0?
+										moment(item.answer.audioTime - currentAudioMsg.audioCurrentTime).format('mm:ss')
+										:'00:00'}}
+									</text>
 								</template>
 								<template v-else>
 									<text>{{ moment(item.answer.audioTime).format('mm:ss') }}</text>
@@ -64,8 +66,14 @@
 				<text class="item-time">提问时间:{{ item.create_time }}</text>
 			</view>
 		</view>
-		<view class="topage-btn" @click="toPage(vistor)" v-if="vistor.type===1||vistor.status&&!noAuth.includes(vistor.status)">
-			{{ vistor.type === 1 ? '待回答' : '我要提问' }}
+		<view class="topage-btn" @click="toPage" v-if="userInfo.is_inner===1||userInfo.status&&!noAuth.includes(userInfo.status)">
+			<image 
+				v-if=" userInfo.is_inner!==1"
+				src="../../static/question/askquestion.png"
+				mode="scaleToFill"
+				style="width:34rpx;height:34rpx;"
+			/>
+			{{ userInfo.is_inner===1 ? '待回答' : '我要提问' }} <text v-if="userInfo.is_inner===1" style="margin-left:5rpx;">{{'('+waitNum+')'}}</text>
 		</view>
 		<!-- 弹窗 -->
 		<van-popup :show="pupData.show" round @close="pupData.show = false" closeable :close-on-click-overlay="false">
@@ -73,7 +81,7 @@
 				<view class="content">
 					<rich-text style="flex:none;margin-bottom:20rpx;" :nodes="pupData.content"></rich-text>
 					<view class="contact" v-if="pupData.type == 'contact'">
-						{{pupData.saleName||'梁娜'}}:<text @click="handleCallPhone(pupData.mobile)">{{pupData.mobile||'123456'}}</text>
+						{{pupData.saleName||''}}:<text @click="handleCallPhone(pupData.mobile)">{{pupData.mobile||''}}</text>
 					</view>
 					<view class="apply" v-else-if="pupData.type == 'apply'">
 						<view @click="handleApply">立即申请</view>
@@ -86,7 +94,7 @@
 
 <script>
 import mixin from "../../mixin/questionMixin";
-import {apiOptionList} from '@/api/question'
+import {apiOptionList,apiBarTotal} from '@/api/question'
 export default {
 	mixins: [mixin],
 	data() {
@@ -96,14 +104,11 @@ export default {
 			optionList: [],
 			activeNames: [],//collapse
 			activeName:'',
-			vistor: {//用户信息
-				type: 1,//1研究员,2客户
-				status: '正式',//type为2的时候才判断
-			},
 			selectName:'',
 			pauseImgSrc:'../../static/question/recordplay.png',
 			playImgSrc:'../../static/question/recordpause.png',
-			noAuth:['潜在','流失','冻结客户','暂停试用']
+			noAuth:['潜在','流失','冻结客户','暂停试用'],
+			waitNum:0
 		}
 	},
 	watch:{
@@ -112,12 +117,14 @@ export default {
 		}
 	},
 	onLoad() {
-		this.getVistor()
+		/* this.getVistor()
 		this.getOptionList()
-		this.getQuestionList(3)
+		this.getQuestionList(3) */
 	},
 	onShow() {
-		
+		this.getWaitNum()
+		this.getOptionList()
+		this.getQuestionList(3)
 	},
 	onReachBottom() {
 		if(this.finished) return
@@ -125,16 +132,15 @@ export default {
 		this.getQuestionList(3)
  	},
 	methods: {
-		//获取访客信息:研究员/客户
-		getVistor() {
-			const {userInfo} = this.$store.state.user
-			//如果用户在ficc研究部下(departmentId:1),则为研究员.其他情况为客户
-			if(userInfo.admin_info&&userInfo.admin_info.departmentId===1){
-				this.vistor.type = 1
-			}else{
-				this.vistor.type = 2
-			}
-			//this.vistor.status = userInfo.status
+		//获取研究员问答列表数量统计
+		getWaitNum() {
+			if(this.userInfo.is_inner!==1) return
+			//如果是研究员,则请求问答列表数量统计
+			apiBarTotal().then(res=>{
+				if(res.code===200){
+					this.waitNum = res.data.wait
+				}
+			})
 		},
 		//获取筛选列表
 		async getOptionList(){
@@ -165,9 +171,9 @@ export default {
 			this.isPopupShow = false
 		},
 		//点击'我要提问' or '待回答'
-		toPage(item) {
-			const { type } = item
-			if (type === 1) {
+		toPage() {
+			const {is_inner} = userInfo
+			if (is_inner === 1) {
 				uni.navigateTo({ url: '/pages-question/answerList' })
 			} else {
 				uni.navigateTo({ url: '/pages-question/hasQuestion' })
@@ -281,9 +287,12 @@ page {
 		
 	}
 
-	/* .question-list {
-	
-	} */
+	.question-list {
+		padding-bottom: 34rpx;
+		&.last{
+			padding-bottom: 260rpx;
+		}
+	}
 
 	.topage-btn {
 		position: fixed;
@@ -298,6 +307,13 @@ page {
 		background-color: #333333;
 		box-shadow: 0px 4px 20px 1px rgba(160, 126, 84, 0.25);
 		color: #E3B377;
+		display: flex;
+		justify-content: center;
+		align-items: center;
+		image{
+			margin-right: 10rpx;
+			margin-top: -2rpx;
+		}
 	}
 	.global-pup{
 		.content{

+ 30 - 67
pages/report/report.vue

@@ -4,23 +4,24 @@
     <!-- 导航 -->
     <view class="nav-bar-wrap" :style="{height:navBarStyle.height,paddingTop:navBarStyle.paddingTop,paddingBottom:navBarStyle.paddingBottom}">
       <view class="content">
-        <van-icon custom-class="search-icon" name="search" size="24px" @click="goSearch" />
+        <!-- <van-icon custom-class="search-icon" name="search" size="24px" @click="goSearch" /> -->
         <view class="text">FICC研报</view>
       </view>
     </view>
     <!-- 分类 -->
     <view class="type-wrap">
-      <view style="display:flex;">头像
-        <van-search
+      <view style="display:flex;align-items: center;margin-bottom: 20rpx;">
+        <view class="avatar" @click="goUser">
+          <image style="width:100%;height:100%" :src="userInfo.head_img_url" mode="aspectFill"/>
+        </view>
+        <view style="flex:1" @click="goSearch">
+          <van-search
                 shape="round"
-                :value="searchVal"
+                disabled
                 placeholder="请输入报告标题或关键字"
-                @change="searchValChange"
-                @search="onSearch"
-                @clear="onClearSearch"
-                clear-trigger="always"
-                style="flex:1"
             />
+        </view>
+        
       </view>
       <view class="flex first-type-box">
         <view class="item" v-for="(item,index) in topFirstList" :key="item.classify_name" @click="handleClickTopFirst(item,index)">
@@ -77,17 +78,7 @@
             <view @click="handleCallPhone(authData.contactInfo.mobile)">拨号</view>
           </view>    
       </view>
-    </van-popup>
-
-    <!-- 问答社区入口 -->
-    <movable-area v-if="x!==0" :style="{height:movableStyle.height,top:movableStyle.top}">
-        <movable-view direction="all" :x="x" :y="y" @touchend="handleTouchEnd">
-          <view class="quesion-btn" @click="goQuesion">
-            问答社区
-          </view>
-        </movable-view>
-      </movable-area>
-    
+    </van-popup>  
   </view>
 </template>
 
@@ -108,13 +99,6 @@ export default {
         paddingTop:40+'px',
         paddingBottom:'4px'
       },
-      movableStyle:{
-        height:0,
-        top:0,
-        stickyHeight:0
-      },//movable的活动范围
-      x:0,
-      y:245,//movable的初始值位置
       authData:{
         show:false,
         isBuy:false,//是否为已购客户
@@ -149,7 +133,6 @@ export default {
 		})
   },
   onReady() {
-    this.initMovableArea()
   },
   onPullDownRefresh() {
     this.getTopAuthList()
@@ -176,40 +159,6 @@ export default {
         paddingBottom:'4px'
       }
     },
-    //初始化movable
-    initMovableArea(){
-      //确定movable-area的区域和movable-view的初始位置
-      const {windowWidth,safeAreaInsets,windowHeight} = uni.getSystemInfoSync()
-      this.x = windowWidth - 20
-      console.log('sys',uni.getSystemInfoSync())
-      const query = uni.createSelectorQuery().in(this);
-      setTimeout(()=>{
-        query.select('.top-sticky').boundingClientRect(data => {
-          console.log("得到布局位置信息" + JSON.stringify(data));
-          //49是tab-bar的高
-          this.movableStyle = {
-            top:data.height+'px',
-            height:(windowHeight - Number(data.height) - safeAreaInsets.bottom - 49)+'px',
-            stickyHeight:Number(data.height)
-          }
-        }).exec();
-      },200)
-    },
-    handleTouchEnd(e){
-      console.log('end',e)
-      /* const {clientX} */
-      const query = uni.createSelectorQuery().in(this);
-      const {windowWidth} = uni.getSystemInfoSync()
-      query.select('.quesion-btn').boundingClientRect(data => {
-          console.log("得到布局位置信息2" + JSON.stringify(data));
-          if(data.left<=windowWidth/2-25){
-            this.x = 1
-          }else{
-            this.x = windowWidth - 20
-          }
-          this.y = Number(data.top) - this.movableStyle.stickyHeight
-        }).exec();
-    },
     //顶部权限数据
     async getTopAuthList(){
       const res=await apiReportIndexPageAuthList()
@@ -302,6 +251,18 @@ export default {
     goSearch(){
       uni.navigateTo({url:'/pages-report/search'})
     },
+    
+    //跳转我的
+    goUser(){
+       uni.navigateTo({
+        url: '/pages/user/user',
+        fail () {
+          uni.switchTab({
+            url:'/pages/user/user'
+          })
+        }
+      })
+    },
 
     //跳转报告详情
     goDetail(item){
@@ -312,11 +273,6 @@ export default {
       }
     },
 
-    //跳转问答社区
-    goQuesion(){
-      uni.navigateTo({url:`/pages/question/question`})
-    },
-
     // 拨打电话
     handleCallPhone(tel){
       uni.makePhoneCall({
@@ -400,6 +356,13 @@ movable-area{
   // border-bottom: 1px solid $global-border-color;
   padding: 20rpx 34rpx 0 34rpx;
   box-shadow: 0px 4rpx 4rpx 1px rgba(198, 198, 198, 0.25);
+  .avatar{
+    width:78rpx;
+    height:78rpx;
+    border-radius: 50%;
+    overflow: hidden;
+    margin-right: 15rpx;
+  }
   .first-type-box{
     justify-content: space-between;
     .item{

+ 45 - 22
pages/user/user.vue

@@ -47,19 +47,20 @@
 				</view>
 			</view>
 			<view class="flex item-card">
-				<image src="../../static/calendar.png" mode="widthFix" />
-				<text class="label">服务截止日期</text>
-				<text class="right-text" v-if="!(userInfo.status=='冻结'||(userInfo.status=='试用'&&userInfo.is_suspend==1))">{{lastTime}}</text>
-			</view>
-			<view class="flex item-card">
-				<image src="../../static/calendar.png" mode="widthFix" />
+				<image src="../../static/question/question-icon.png" mode="widthFix" />
 				<text class="label">我的问答</text>
-				<text class="hint">1</text>
 				<view class="right-text look" @click="handleToQuestionPage">
-					<text>查看</text>
+					<!-- <text>查看</text> -->
+					<text class="hint" v-if="questionUnread!==0">{{questionUnread}}</text>
 					<van-icon name="arrow"></van-icon>
 				</view>
 			</view>
+			<view class="flex item-card">
+				<image src="../../static/calendar.png" mode="widthFix" />
+				<text class="label">服务截止日期</text>
+				<text class="right-text" v-if="!(userInfo.status=='冻结'||(userInfo.status=='试用'&&userInfo.is_suspend==1))">{{lastTime}}</text>
+			</view>
+			
 		</view>
 
 
@@ -81,6 +82,7 @@
 <script>
 	const moment=require('@/utils/moment-with-locales.min')
 	import {apiLastApplyRecord,apiApplyPermission} from '@/api/user'
+	import {apiGetUnread} from '@/api/question'
 	export default {
 		computed: {
 			lastTime(){
@@ -106,11 +108,13 @@
 				pupData:{
 					show:false,
 					content:'',//弹窗html字符串
-				}
+				},
+				questionUnread:0
 			}
 		},
 		onShow() {
 			this.$store.dispatch('getUserInfo')
+			this.getQuestionUnread()
 		},
 		methods: {
 			async handleGoApplyPermission(){
@@ -167,15 +171,30 @@
 				uni.makePhoneCall({
 					phoneNumber: this.userInfo.seal_mobile
 				});
+			},
+			getQuestionUnread(){
+				apiGetUnread().then(
+					res=>{
+						if(res.code===200){
+							this.questionUnread = res.data
+						}
+					}
+				)
+
 			}
 		}
 	}
 </script>
-
+<style>
+page{
+	padding-bottom: 0;
+}
+</style>
 <style lang="scss">
 	.user-page{
-		min-height: calc(100vh - calc(50px + constant(safe-area-inset-bottom)));
-    	min-height: calc(100vh - calc(50px + env(safe-area-inset-bottom)));
+		min-height: 100vh;
+		/* min-height: calc(100vh - calc(50px + constant(safe-area-inset-bottom)));
+    	min-height: calc(100vh - calc(50px + env(safe-area-inset-bottom))); */
 		background-color: #EDEDED;
 	}
 	.top-box{
@@ -244,16 +263,20 @@
 				height: 100rpx;
 				text-align: right;
 				line-height: 100rpx;
-			}
-			.hint{
-				width:30rpx;
-				height:30rpx;
-				background-color: red;
-				color:#fff;
-				text-align: center;
-				line-height: 30rpx;
-				border-radius: 50%;
-				align-self: center;
+				display: flex;
+    			align-items: center;
+    			justify-content: flex-end;
+				.hint{
+					width:30rpx;
+					height:30rpx;
+					background-color: #FF0000FF;
+					color:#fff;
+					font-size: 20rpx;
+					text-align: center;
+					line-height: 30rpx;
+					border-radius: 50%;
+					display: inline-block;
+				}
 			}
 		}
 		.item-card:last-child{

BIN
static/question/record-img.png


+ 1 - 1
style/common.scss

@@ -147,7 +147,7 @@ view{
                 }
                 .music-img{
                     width: 25rpx;
-                   /*  height: 34rpx; */
+                    height: 34rpx;
                     margin-right: 10rpx;
                 }
                 @keyframes circle {

+ 8 - 1
utils/config.js

@@ -63,12 +63,19 @@ const defaultTabBarListConfig=[
         iconPath: "../static/tabbar/activity.png",
         selectedIconPath: "../static/tabbar/activity-s.png",
     },
-    {
+   /*  {
         key: "user",
         pagePath: "pages/user/user",
         text: "我的",
         iconPath: "../static/tabbar/user.png",
         selectedIconPath: "../static/tabbar/user-s.png",
+    }, */
+    {
+        key: "question",
+        pagePath: "pages/question/question",
+        text: "问答",
+        iconPath: "../static/tabbar/question.png",
+        selectedIconPath: "../static/tabbar/question-s.png"
     }
 ]
 

+ 1 - 1
utils/request.js

@@ -95,7 +95,7 @@ const http=(url,params,method)=>{
 			method:method,
 			header:{
 				Authorization:store.state.user.token,
-				version:'yb3.0'
+				version:'yb5.0'
 			},
 			success(e) {
 				// 接口404