|
|
@@ -1,50 +1,137 @@
|
|
|
<template>
|
|
|
- <div :style="{backgroundColor: '#f0f2f5', paddingBottom: !extend && '20px', minHeight: '100%'}">
|
|
|
+ <div
|
|
|
+ :style="{background: 'linear-gradient(#E9F1FE, #F1F4F8)', minHeight: '100%'}">
|
|
|
<!-- 客户详情 -->
|
|
|
- <div v-if="showDetail">
|
|
|
- <div v-if="!extend" style="padding: 20px; background-color: #fff;">
|
|
|
- 客户详情
|
|
|
+ <div v-if="showDetail" style="padding: 12px;">
|
|
|
+ <div class="top-box">
|
|
|
+ <div class="left">
|
|
|
+ <img class="avatar-box" :src="qwUserInfo.avatar"/>
|
|
|
+ <div class="left-box">
|
|
|
+ <div class="title">{{qwUserDetail.name || '未知'}}</div>
|
|
|
+ <div class="age-box">
|
|
|
+ <img v-if="qwUserDetail.sex=='女'" src="@/assets/image/gender_female.png" width="12" height="12" />
|
|
|
+ <img v-else src="@/assets/image/gender_male.png" width="12" height="12" />
|
|
|
+ <div class="age-text">{{(qwUserDetail.age||'-')+'岁' || '未知'}}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="right">
|
|
|
+ <img src="@/assets/image/add_modify_icon.png" width="12" height="12" />
|
|
|
+ <div class="text" @click="updateQwDetail">修改用户信息</div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div style="background-color: #fff;padding: 12px;border-radius: 6px 6px 6px 6px;">
|
|
|
+ <div class="title-top">
|
|
|
+ <div class="title">客户信息</div>
|
|
|
+ <div class="down-text" @click="handleDown">{{isExpanded?'收起':'展开'}}
|
|
|
+ <img src="@/assets/image/sq_arrow_down.png" width="12" height="12" :class="{ 'rotate-90': !isExpanded }"/></div>
|
|
|
+ </div>
|
|
|
+ <!-- 基本信息 -->
|
|
|
+ <el-descriptions :column="2" :class="extend ? 'detail-description-extend' : 'detail-description'" :style="{display:isExpanded?'':'none'}" size="medium">
|
|
|
+ <!-- <template slot="extra">
|
|
|
+
|
|
|
+ </template> -->
|
|
|
+ <!-- <el-descriptions-item label="姓名">{{qwUserInfo.name || '未知'}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="性别">{{qwUserDetail.sex || '未知'}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="年龄">{{qwUserDetail.age || '未知'}}</el-descriptions-item> -->
|
|
|
+ <!-- <el-descriptions-item label="行为习惯">{{qwUserDetail.habits || '无'}}</el-descriptions-item> -->
|
|
|
+ <el-descriptions-item label="患病时间">{{qwUserDetail.illnessTime || '未知'}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="疾病">{{qwUserDetail.disease || '无'}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="家人的疾病">{{qwUserDetail.familyDisease || '无'}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="是否线下就诊">{{qwUserDetail.isLine || '无'}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="体质">{{qwUserDetail.constitution || '-'}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="使用药品">{{qwUserDetail.medicine || '-'}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="咨询产品">{{qwUserDetail.consultProduct || '-'}}</el-descriptions-item>
|
|
|
+ <el-descriptions-item label="是否已购产品">{{qwUserDetail.isBuy || '无'}}</el-descriptions-item>
|
|
|
+ </el-descriptions>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div :style="{backgroundColor: '#FFF',margin: !extend ? '12px 0' : '12px 0'}">
|
|
|
+ <div class="tab-box">
|
|
|
+ <div :class="activeName==index?'tabs active':'tabs'" v-for="(item,index) in tabs" :key="index"
|
|
|
+ @click="tabsClick(index)">
|
|
|
+ {{item.label}}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div v-if="activeName==0" class="tab-content">
|
|
|
+ <!-- 近七天看课记录 -->
|
|
|
+ <div style="display: flex;justify-content: space-between;align-items: center;flex-direction: row;background: #FFF;padding: 10px">
|
|
|
+ <div class="section-title">
|
|
|
+ 近七天看课记录
|
|
|
+ </div>
|
|
|
+ <el-button type="primary" @click="courseManage">课程管理</el-button>
|
|
|
+ </div>
|
|
|
+ <!-- 状态 -->
|
|
|
+ <div class="status-container">
|
|
|
+ <div v-for="(item, index) in logTypeList" :key="index" class="status-item">
|
|
|
+ <div class="status-color-block" :style="{ backgroundColor: item.color }"></div>
|
|
|
+ <span class="status-text">{{ item.text }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="course-record-container">
|
|
|
+ <div v-for="item in courseWatch7day" :key="item.id" class="course-record-item">
|
|
|
+
|
|
|
+ <div class="course-status-block" :style="{ backgroundColor: getLogTypeColor(item.logType) }"
|
|
|
+ :title="getLogTypeText(item.logType)">
|
|
|
+ <img v-if="item.logType!==2" src="@/assets/image/view_class_records.png" width="20" height="20"/>
|
|
|
+ <img v-if="item.logType==2" src="@/assets/image/end_of_class.png" width="20" height="20"/>
|
|
|
+ </div>
|
|
|
+ <span class="course-date">{{ item.date.split('-')[2] }}日</span>
|
|
|
+ </div>
|
|
|
+ <div v-if="courseWatch7day.length === 0" class="empty-record">
|
|
|
+ 暂无看课记录
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <!-- 已看过课程 -->
|
|
|
+ <div class="record-box" v-if="localExtId">
|
|
|
+ <div class="top">
|
|
|
+ <div class="title">
|
|
|
+ 用户看课记录
|
|
|
+ </div>
|
|
|
+ <div class="more" @click="courseManage">
|
|
|
+ 全部看课记录
|
|
|
+ <i class="el-icon-arrow-right" style="font-size: 14px; color: #979B9E;"></i>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <userCourseWatchLog ref="userWatchLog" />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <div v-if="activeName==1" class="tab-content">
|
|
|
+ <div v-if="localExtId">
|
|
|
+ <!-- <div style="padding: 10px;font-weight: bold">
|
|
|
+ 用户订单
|
|
|
+ </div> -->
|
|
|
+ <userStorerDetails ref="userDetails"/>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ <!-- 访问记录 -->
|
|
|
+ <div v-if="activeName==2" class="tab-content">
|
|
|
+ <div v-if="localExtId">
|
|
|
+ <userBehavior ref="userBehaviorLog"/>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+
|
|
|
</div>
|
|
|
- <!-- 基本信息 -->
|
|
|
- <el-descriptions :class="extend ? 'detail-description-extend' : 'detail-description'" title="基本信息" :column="extend ? 2 : 3" size="medium" border>
|
|
|
- <template slot="extra">
|
|
|
- <el-button size="mini" round @click="updateQwDetail">修改用户信息</el-button>
|
|
|
- </template>
|
|
|
- <el-descriptions-item label="姓名">{{qwUserInfo.name || '未知'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="性别">{{qwUserDetail.sex || '未知'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="年龄">{{qwUserDetail.age || '未知'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="行为习惯">{{qwUserDetail.habits || '无'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="患病时间">{{qwUserDetail.illnessTime || '无'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="疾病">{{qwUserDetail.disease || '无'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="家人的疾病">{{qwUserDetail.familyDisease || '无'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="是否线下就诊">{{qwUserDetail.isLine || '无'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="体质">{{qwUserDetail.constitution || '无'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="使用药品">{{qwUserDetail.medicine || '无'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="咨询产品">{{qwUserDetail.consultProduct || '无'}}</el-descriptions-item>
|
|
|
- <el-descriptions-item label="是否已购产品">{{qwUserDetail.isBuy || '无'}}</el-descriptions-item>
|
|
|
- </el-descriptions>
|
|
|
+
|
|
|
|
|
|
<!-- 看课记录 -->
|
|
|
- <div :style="{backgroundColor: '#FFF',margin: !extend ? '10px' : '5px 0'}">
|
|
|
- <div style="padding: 10px;font-weight: bold">
|
|
|
+ <!-- <div :style="{backgroundColor: '#FFF',margin: !extend ? '10px' : '5px 0'}"> -->
|
|
|
+ <!-- <div style="padding: 10px;font-weight: bold">
|
|
|
看课记录
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
<!-- 状态 -->
|
|
|
- <div class="status-container">
|
|
|
- <div
|
|
|
- v-for="(item, index) in logTypeList"
|
|
|
- :key="index"
|
|
|
- class="status-item"
|
|
|
- >
|
|
|
- <div
|
|
|
- class="status-color-block"
|
|
|
- :style="{ backgroundColor: item.color }"
|
|
|
- ></div>
|
|
|
+ <!-- <div class="status-container">
|
|
|
+ <div v-for="(item, index) in logTypeList" :key="index" class="status-item">
|
|
|
+ <div class="status-color-block" :style="{ backgroundColor: item.color }"></div>
|
|
|
<span class="status-text">{{ item.text }}</span>
|
|
|
</div>
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
<!-- 近七天看课记录 -->
|
|
|
- <div>
|
|
|
+ <!-- <div>
|
|
|
<div style="display: flex;justify-content: space-between;align-items: center;flex-direction: row;background: #FFF;padding: 10px 10px 20px">
|
|
|
<div class="section-title">
|
|
|
近七天看课记录
|
|
|
@@ -52,284 +139,495 @@
|
|
|
<el-button size="mini" round @click="courseManage">课程管理</el-button>
|
|
|
</div>
|
|
|
<div class="course-record-container">
|
|
|
- <div
|
|
|
- v-for="item in courseWatch7day"
|
|
|
- :key="item.id"
|
|
|
- class="course-record-item"
|
|
|
- >
|
|
|
+ <div v-for="item in courseWatch7day" :key="item.id" class="course-record-item">
|
|
|
<span class="course-date">{{ item.date.split('-')[2] }}日</span>
|
|
|
- <div
|
|
|
- class="course-status-block"
|
|
|
- :style="{ backgroundColor: getLogTypeColor(item.logType) }"
|
|
|
- :title="getLogTypeText(item.logType)"
|
|
|
- ></div>
|
|
|
+ <div class="course-status-block" :style="{ backgroundColor: getLogTypeColor(item.logType) }"
|
|
|
+ :title="getLogTypeText(item.logType)"></div>
|
|
|
</div>
|
|
|
<div v-if="courseWatch7day.length === 0" class="empty-record">
|
|
|
暂无看课记录
|
|
|
</div>
|
|
|
</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ </div> -->
|
|
|
+ <!-- </div> -->
|
|
|
|
|
|
<!-- 购买记录 -->
|
|
|
- <div :style="{backgroundColor: '#FFF',margin: !extend ? '10px' : '5px 0'}" v-if="qwUserInfo.fsUserId">
|
|
|
+ <!-- <div :style="{backgroundColor: '#FFF',margin: !extend ? '10px' : '5px 0'}" v-if="qwUserInfo.fsUserId">
|
|
|
<div style="padding: 10px;font-weight: bold">
|
|
|
用户订单
|
|
|
</div>
|
|
|
- <userStorerDetails ref="userDetails" />
|
|
|
- </div>
|
|
|
+ <userStorerDetails ref="userDetails" />
|
|
|
+ </div> -->
|
|
|
|
|
|
<!-- 已看过课程 -->
|
|
|
- <div :style="{backgroundColor: '#FFF',margin: extend ? '5px 0' : '10px'}" v-if="qwUserInfo.fsUserId">
|
|
|
+ <!-- <div :style="{backgroundColor: '#FFF',margin: extend ? '5px 0' : '10px'}" v-if="qwUserInfo.fsUserId">
|
|
|
<div style="padding: 10px;font-weight: bold">
|
|
|
用户看课记录
|
|
|
</div>
|
|
|
- <userCourseWatchLog ref="userWatchLog" />
|
|
|
- </div>
|
|
|
+ <userCourseWatchLog ref="userWatchLog" />
|
|
|
+ </div> -->
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<!-- 修改用户信息 -->
|
|
|
- <user-info-edit
|
|
|
- v-if="showUpdate"
|
|
|
- :userDetail="qwUserDetail"
|
|
|
- @back="handleBack"
|
|
|
- @save-success="handleSaveSuccess"
|
|
|
- />
|
|
|
+ <user-info-edit v-if="showUpdate" :userDetail="qwUserDetail" @back="handleBack" @save-success="handleSaveSuccess" />
|
|
|
|
|
|
<!-- 课程管理 -->
|
|
|
- <course-manage
|
|
|
- v-if="showCourseManage"
|
|
|
- :extend="extend"
|
|
|
- :userId="qwUserInfo.id"
|
|
|
- @back="handleBack"
|
|
|
- />
|
|
|
+ <course-manage v-if="showCourseManage" :conversationId="conversationId" :extend="extend" :userId="qwUserInfo.id" @back="handleBack" />
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import userStorerDetails from "@/views/qw/qwChat/userDetail/userStorerDetails.vue"
|
|
|
-import userCourseWatchLog from "@/views/qw/qwChat/userDetail/userCourseWatchLog.vue";
|
|
|
-import userInfoEdit from "@/views/qw/qwChat/userDetail/userInfoEdit.vue";
|
|
|
-import courseManage from "@/views/qw/qwChat/userDetail/courseManage.vue";
|
|
|
-import {getQwExternalContactDetails, getQwUserInfo, queryCourseWatchStatistics} from "@/api/qw/im";
|
|
|
-
|
|
|
-export default {
|
|
|
- name: "userDetail",
|
|
|
- props: {
|
|
|
- extId: {
|
|
|
- type: String,
|
|
|
- default: null
|
|
|
- },
|
|
|
- extend: {
|
|
|
- type: Boolean,
|
|
|
- default: false
|
|
|
- }
|
|
|
- },
|
|
|
- components: {
|
|
|
- userStorerDetails,
|
|
|
- userCourseWatchLog,
|
|
|
- userInfoEdit,
|
|
|
- courseManage,
|
|
|
- },
|
|
|
- data() {
|
|
|
- // 定义颜色常量
|
|
|
- const logTypeColors = {
|
|
|
- notWatched: '#909399', // 未看课
|
|
|
- watching: '#0bc6ff', // 看课中
|
|
|
- completed: '#67c23a', // 完课
|
|
|
- pending: '#f55a4f', // 待看课
|
|
|
- interrupted: '#ffd700' // 看课中断
|
|
|
- };
|
|
|
-
|
|
|
- return {
|
|
|
- localExtId: this.extId,
|
|
|
- qwUserInfo: {},
|
|
|
- qwUserDetail: {},
|
|
|
- showDetail: true,
|
|
|
- showUpdate: false,
|
|
|
- courseWatch7day: [],
|
|
|
- logTypeColors,
|
|
|
- // 定义状态列表用于渲染
|
|
|
- logTypeList: [
|
|
|
- { type: 0, text: '未看课', color: logTypeColors.notWatched },
|
|
|
- { type: 1, text: '看课中', color: logTypeColors.watching },
|
|
|
- { type: 2, text: '完课', color: logTypeColors.completed },
|
|
|
- { type: 3, text: '待看课', color: logTypeColors.pending },
|
|
|
- { type: 4, text: '看课中断', color: logTypeColors.interrupted }
|
|
|
- ],
|
|
|
- showCourseManage: false,
|
|
|
- }
|
|
|
- },
|
|
|
- created() {
|
|
|
- if (this.extId) {
|
|
|
- this.getDetail(this.extId)
|
|
|
- }
|
|
|
- },
|
|
|
- watch: {
|
|
|
- extId(newVal) {
|
|
|
- if (newVal) {
|
|
|
- this.getDetail(newVal);
|
|
|
+ import userStorerDetails from "@/views/qw/qwChat/userDetail/userStorerDetails.vue"
|
|
|
+ import userCourseWatchLog from "@/views/qw/qwChat/userDetail/userCourseWatchLog.vue";
|
|
|
+ import userInfoEdit from "@/views/qw/qwChat/userDetail/userInfoEdit.vue";
|
|
|
+ import courseManage from "@/views/qw/qwChat/userDetail/courseManage.vue";
|
|
|
+ import userBehavior from '@/views/qw/qwChat/userDetail/userBehavior.vue';
|
|
|
+ import {
|
|
|
+ getQwExternalContactDetails,
|
|
|
+ getQwUserInfo,
|
|
|
+ queryCourseWatchStatistics
|
|
|
+ } from "@/api/qw/im";
|
|
|
+
|
|
|
+ export default {
|
|
|
+ name: "userDetail",
|
|
|
+ props: {
|
|
|
+ extId: {
|
|
|
+ type: String,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ conversationId:{
|
|
|
+ type: String,
|
|
|
+ default: null
|
|
|
+ },
|
|
|
+ extend: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
}
|
|
|
- }
|
|
|
- },
|
|
|
- methods: {
|
|
|
- getDetail(extId) {
|
|
|
- this.localExtId = extId
|
|
|
- this.getQwExternalContactDetails()
|
|
|
- this.getQwUserInfo()
|
|
|
- this.queryCourseWatchStatistics()
|
|
|
},
|
|
|
- queryCourseWatchStatistics() {
|
|
|
- const data = {
|
|
|
- type: 0,
|
|
|
- qwExternalContactId: this.localExtId
|
|
|
- }
|
|
|
- queryCourseWatchStatistics(data).then(response => {
|
|
|
- this.courseWatch7day = response.data.data
|
|
|
- })
|
|
|
+ components: {
|
|
|
+ userStorerDetails,
|
|
|
+ userCourseWatchLog,
|
|
|
+ userInfoEdit,
|
|
|
+ courseManage,
|
|
|
+ userBehavior
|
|
|
},
|
|
|
- getQwExternalContactDetails() {
|
|
|
- const query = {
|
|
|
- qwExternalContactId: this.localExtId
|
|
|
+ data() {
|
|
|
+ // 定义颜色常量
|
|
|
+ const logTypeColors = {
|
|
|
+ notWatched: '#D9E4FF', // 未看课
|
|
|
+ watching: '#0bc6ff', // 看课中
|
|
|
+ completed: '#67c23a', // 完课
|
|
|
+ pending: '#f55a4f', // 待看课
|
|
|
+ interrupted: '#ffd700' // 看课中断
|
|
|
+ };
|
|
|
+
|
|
|
+ return {
|
|
|
+ localExtId: this.extId,
|
|
|
+ qwUserInfo: {},
|
|
|
+ qwUserDetail: {},
|
|
|
+ showDetail: true,
|
|
|
+ showUpdate: false,
|
|
|
+ courseWatch7day: [],
|
|
|
+ logTypeColors,
|
|
|
+ activeName: 0,
|
|
|
+ isExpanded: true,
|
|
|
+ tabs: [{
|
|
|
+ label: '看课记录'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '用户订单'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ label: '访问记录'
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ // 定义状态列表用于渲染
|
|
|
+ logTypeList: [{
|
|
|
+ type: 0,
|
|
|
+ text: '未看课',
|
|
|
+ color: logTypeColors.notWatched
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 1,
|
|
|
+ text: '看课中',
|
|
|
+ color: logTypeColors.watching
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 2,
|
|
|
+ text: '完课',
|
|
|
+ color: logTypeColors.completed
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 3,
|
|
|
+ text: '待看课',
|
|
|
+ color: logTypeColors.pending
|
|
|
+ },
|
|
|
+ {
|
|
|
+ type: 4,
|
|
|
+ text: '看课中断',
|
|
|
+ color: logTypeColors.interrupted
|
|
|
+ }
|
|
|
+ ],
|
|
|
+ showCourseManage: false,
|
|
|
}
|
|
|
- getQwExternalContactDetails(query).then(response => {
|
|
|
- this.qwUserInfo = response.data
|
|
|
- if (this.qwUserInfo.fsUserId) {
|
|
|
- this.$nextTick(() => {
|
|
|
- this.$refs.userDetails.getUserDetails(this.qwUserInfo.fsUserId)
|
|
|
- this.$refs.userWatchLog.getUserWatchLog(this.qwUserInfo.fsUserId)
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
},
|
|
|
- getQwUserInfo() {
|
|
|
- const query = {
|
|
|
- qwExternalContactId: this.localExtId
|
|
|
+ created() {
|
|
|
+ if (this.extId) {
|
|
|
+ this.getDetail(this.extId)
|
|
|
}
|
|
|
- getQwUserInfo(query).then(response => {
|
|
|
- this.qwUserDetail = response.moreInfo
|
|
|
- })
|
|
|
- },
|
|
|
- updateQwDetail() {
|
|
|
- this.showDetail = false
|
|
|
- this.showUpdate = true
|
|
|
- },
|
|
|
- handleBack() {
|
|
|
- this.getDetail(this.localExtId)
|
|
|
- this.showDetail = true
|
|
|
- this.showUpdate = false
|
|
|
- this.showCourseManage = false
|
|
|
},
|
|
|
- handleSaveSuccess() {
|
|
|
- this.handleBack()
|
|
|
- },
|
|
|
- getLogTypeColor(logType) {
|
|
|
- const type = parseInt(logType);
|
|
|
- // 使用对象映射替代switch语句
|
|
|
- const colorMap = {
|
|
|
- 0: this.logTypeColors.notWatched,
|
|
|
- 1: this.logTypeColors.watching,
|
|
|
- 2: this.logTypeColors.completed,
|
|
|
- 3: this.logTypeColors.pending,
|
|
|
- 4: this.logTypeColors.interrupted
|
|
|
- };
|
|
|
- return colorMap[type] || '';
|
|
|
- },
|
|
|
- getLogTypeText(logType) {
|
|
|
- const type = parseInt(logType);
|
|
|
- // 使用对象映射替代switch语句
|
|
|
- const textMap = {
|
|
|
- 0: '未看课',
|
|
|
- 1: '看课中',
|
|
|
- 2: '完课',
|
|
|
- 3: '待看课',
|
|
|
- 4: '看课中断'
|
|
|
- };
|
|
|
- return textMap[type] || '';
|
|
|
- },
|
|
|
- courseManage() {
|
|
|
- this.showDetail = false
|
|
|
- this.showCourseManage = true
|
|
|
+ watch: {
|
|
|
+ extId(newVal) {
|
|
|
+ if (newVal) {
|
|
|
+ this.getDetail(newVal);
|
|
|
+ }
|
|
|
+ }
|
|
|
},
|
|
|
+ methods: {
|
|
|
+ getDetail(extId) {
|
|
|
+ this.localExtId = extId
|
|
|
+ this.getQwExternalContactDetails()
|
|
|
+ this.getQwUserInfo()
|
|
|
+ this.queryCourseWatchStatistics()
|
|
|
+ },
|
|
|
+ queryCourseWatchStatistics() {
|
|
|
+ const data = {
|
|
|
+ type: 0,
|
|
|
+ qwExternalContactId: this.localExtId
|
|
|
+ }
|
|
|
+ queryCourseWatchStatistics(data).then(response => {
|
|
|
+ this.courseWatch7day = response.data.data
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getQwExternalContactDetails() {
|
|
|
+ const query = {
|
|
|
+ qwExternalContactId: this.localExtId
|
|
|
+ }
|
|
|
+ getQwExternalContactDetails(query).then(response => {
|
|
|
+ this.qwUserInfo = response.data
|
|
|
+ if (this.localExtId) {
|
|
|
+ this.$nextTick(() => {
|
|
|
+ // 调用 userWatchLog 前先判断
|
|
|
+ if (this.$refs.userWatchLog && this.activeName==0) {
|
|
|
+ this.$refs.userWatchLog.getUserWatchLog(this.localExtId)
|
|
|
+ }
|
|
|
+ // 调用 userDetails 前先判断
|
|
|
+ if (this.$refs.userDetails && this.activeName==1) {
|
|
|
+ this.$refs.userDetails.getUserDetails(this.localExtId)
|
|
|
+ }
|
|
|
+ if (this.$refs.userBehaviorLog && this.activeName==2) {
|
|
|
+ this.$refs.userBehaviorLog.getDetails(this.localExtId);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getQwUserInfo() {
|
|
|
+ const query = {
|
|
|
+ qwExternalContactId: this.localExtId
|
|
|
+ }
|
|
|
+ getQwUserInfo(query).then(response => {
|
|
|
+ this.qwUserDetail = response.moreInfo
|
|
|
+
|
|
|
+ })
|
|
|
+ },
|
|
|
+ updateQwDetail() {
|
|
|
+ this.showDetail = false
|
|
|
+ this.showUpdate = true
|
|
|
+ },
|
|
|
+ handleDown(){
|
|
|
+ this.isExpanded = !this.isExpanded;
|
|
|
+ },
|
|
|
+ handleBack() {
|
|
|
+ this.getDetail(this.localExtId)
|
|
|
+ this.showDetail = true
|
|
|
+ this.showUpdate = false
|
|
|
+ this.showCourseManage = false
|
|
|
+ },
|
|
|
+ handleSaveSuccess() {
|
|
|
+ this.handleBack()
|
|
|
+ },
|
|
|
+ tabsClick(index) {
|
|
|
+ this.activeName = index
|
|
|
+ this.getQwExternalContactDetails()
|
|
|
+ },
|
|
|
+ getLogTypeColor(logType) {
|
|
|
+ const type = parseInt(logType);
|
|
|
+ // 使用对象映射替代switch语句
|
|
|
+ const colorMap = {
|
|
|
+ 0: this.logTypeColors.notWatched,
|
|
|
+ 1: this.logTypeColors.watching,
|
|
|
+ 2: this.logTypeColors.completed,
|
|
|
+ 3: this.logTypeColors.pending,
|
|
|
+ 4: this.logTypeColors.interrupted
|
|
|
+ };
|
|
|
+ return colorMap[type] || '';
|
|
|
+ },
|
|
|
+ getLogTypeText(logType) {
|
|
|
+ const type = parseInt(logType);
|
|
|
+ // 使用对象映射替代switch语句
|
|
|
+ const textMap = {
|
|
|
+ 0: '未看课',
|
|
|
+ 1: '看课中',
|
|
|
+ 2: '完课',
|
|
|
+ 3: '待看课',
|
|
|
+ 4: '看课中断'
|
|
|
+ };
|
|
|
+ return textMap[type] || '';
|
|
|
+ },
|
|
|
+ courseManage() {
|
|
|
+ this.showDetail = false
|
|
|
+ this.showCourseManage = true
|
|
|
+ },
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
</script>
|
|
|
-<style scoped>
|
|
|
-.status-container {
|
|
|
- display: flex;
|
|
|
- gap: 20px;
|
|
|
- padding: 10px 0 0 20px;
|
|
|
- color: #8c939d;
|
|
|
-}
|
|
|
-
|
|
|
-.status-item {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 5px;
|
|
|
-}
|
|
|
-
|
|
|
-.status-color-block {
|
|
|
- border-radius: 4px;
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.status-text {
|
|
|
- font-size: 12px;
|
|
|
-}
|
|
|
-
|
|
|
-.section-title {
|
|
|
- padding: 10px;
|
|
|
- font-size: 12px;
|
|
|
- color: #8c939d;
|
|
|
-}
|
|
|
-
|
|
|
-.course-record-container {
|
|
|
- display: flex;
|
|
|
- padding: 0 10px 15px 10px;
|
|
|
- gap: 10px;
|
|
|
- overflow-x: auto;
|
|
|
-}
|
|
|
-
|
|
|
-.course-record-item {
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: center;
|
|
|
- min-width: 40px;
|
|
|
-}
|
|
|
-
|
|
|
-.course-date {
|
|
|
- font-size: 12px;
|
|
|
- color: #606266;
|
|
|
- margin-bottom: 5px;
|
|
|
-}
|
|
|
-
|
|
|
-.course-status-block {
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
- border-radius: 4px;
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- align-items: center;
|
|
|
-}
|
|
|
-
|
|
|
-.empty-record {
|
|
|
- width: 100%;
|
|
|
- text-align: center;
|
|
|
- color: #909399;
|
|
|
- font-size: 14px;
|
|
|
-}
|
|
|
-.detail-description {
|
|
|
- margin: 10px;
|
|
|
- padding: 10px;
|
|
|
- background-color: #FFF;
|
|
|
-}
|
|
|
-.detail-description-extend {
|
|
|
- padding: 10px;
|
|
|
- background-color: #FFF;
|
|
|
-}
|
|
|
-::v-deep .detail-description-extend .el-descriptions__title {
|
|
|
- font-size: 14px;
|
|
|
-}
|
|
|
+<style scoped lang="scss">
|
|
|
+ .rotate-90 {
|
|
|
+ transform: rotate(-90deg);
|
|
|
+ transition: transform 0.3s ease;
|
|
|
+ }
|
|
|
+ .top-box {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ padding-top: 5px;
|
|
|
+ padding-bottom: 15px;
|
|
|
+
|
|
|
+ .left {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ .avatar-box{
|
|
|
+ width: 44px;
|
|
|
+ height: 44px;
|
|
|
+ border-radius: 4px 4px 4px 4px;
|
|
|
+ object-fit:cover;
|
|
|
+ }
|
|
|
+ .left-box {
|
|
|
+ margin-left: 12px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .title {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #141F36;
|
|
|
+ margin-bottom: 4px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .age-box {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ width: 57px;
|
|
|
+ height: 20px;
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 12px 12px 12px 12px;
|
|
|
+
|
|
|
+ .age-text {
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 11px;
|
|
|
+ color: #757575;
|
|
|
+ line-height: 20px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .right {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+
|
|
|
+ .text {
|
|
|
+ margin-left: 4px;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #409EFF;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .title-top{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ .title{
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #141F36;
|
|
|
+ }
|
|
|
+ .down-text {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #84868C;
|
|
|
+ cursor: pointer;
|
|
|
+ img {
|
|
|
+ margin-left: 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .el-descriptions__extra {
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ .tab-box {
|
|
|
+ background: #FFFFFF;
|
|
|
+ border-radius: 8px 8px 8px 8px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ border-bottom: 1px solid #F1F4F8;
|
|
|
+
|
|
|
+ .tabs {
|
|
|
+ flex:1;
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #5C5F66;
|
|
|
+ text-align: center;
|
|
|
+height: 48px;
|
|
|
+line-height: 48px;
|
|
|
+ position: relative;
|
|
|
+ cursor: pointer;
|
|
|
+ &.active {
|
|
|
+ font-weight: 600;
|
|
|
+ color: #202124;
|
|
|
+ &:after {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ z-index: 9;
|
|
|
+ bottom: 0;
|
|
|
+ width: 30px;
|
|
|
+ height: 4px;
|
|
|
+ background: #409EFF;
|
|
|
+ transition: all 0.25s ease; /* 快速过渡更显灵敏 */
|
|
|
+ left: 50%; /* 水平居中 */
|
|
|
+ transform: translateX(-50%); /* 配合 left:50% 实现精确居中 */
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .record-box{
|
|
|
+ width: 100%;
|
|
|
+ padding: 10px;
|
|
|
+ .top{
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-between;
|
|
|
+ .title{
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #141F36;
|
|
|
+ }
|
|
|
+ .more{
|
|
|
+ font-weight: 400;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #84868C;
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ .status-container {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ gap: 20px;
|
|
|
+ padding: 10px 15px;
|
|
|
+ color: #8c939d;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-color-block {
|
|
|
+ border-radius: 4px;
|
|
|
+ width: 12px;
|
|
|
+ height: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .status-text {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #84868C;
|
|
|
+ }
|
|
|
+
|
|
|
+ .section-title {
|
|
|
+ line-height: 24px;
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 16px;
|
|
|
+ color: #141F36;
|
|
|
+ }
|
|
|
+
|
|
|
+ .course-record-container {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ margin:10px;
|
|
|
+ gap: 10px;
|
|
|
+ overflow-x: auto;
|
|
|
+ padding-bottom: 20px;
|
|
|
+ border-bottom: 1px solid #F1F4F8;
|
|
|
+ }
|
|
|
+
|
|
|
+ .course-record-item {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ min-width: 40px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .course-date {
|
|
|
+ font-weight: 500;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #141F36;
|
|
|
+ margin-top: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .course-status-block {
|
|
|
+ width: 32px;
|
|
|
+ height: 32px;
|
|
|
+ background: #D9E4FF;
|
|
|
+ border-radius: 6px 6px 6px 6px;
|
|
|
+ display: flex;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .empty-record {
|
|
|
+ width: 100%;
|
|
|
+ text-align: center;
|
|
|
+ color: #909399;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .detail-description {
|
|
|
+ margin-top: 20px;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ // padding: 10px;
|
|
|
+ background-color: #FFF;
|
|
|
+ }
|
|
|
+
|
|
|
+ .detail-description-extend {
|
|
|
+ // padding: 12px;
|
|
|
+ background-color: #FFF;
|
|
|
+margin-top: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .detail-description-extend .el-descriptions__title {
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .detail-description-extend {
|
|
|
+ .el-descriptions-item__label {
|
|
|
+ color: #84868C;
|
|
|
+ }
|
|
|
+
|
|
|
+ .el-descriptions-item__content {
|
|
|
+ color: #141F36;
|
|
|
+ }
|
|
|
+ }
|
|
|
</style>
|