|
|
@@ -0,0 +1,306 @@
|
|
|
+<template>
|
|
|
+ <view class="jc-wrap" v-if="intent">
|
|
|
+ <view class="jc-header">
|
|
|
+ <text class="jc-title">{{ domainLabel }}</text>
|
|
|
+ <text class="jc-stage-label">{{ stageLabel }}</text>
|
|
|
+ </view>
|
|
|
+ <view class="jc-progress">
|
|
|
+ <view class="jc-bar">
|
|
|
+ <view class="jc-bar-fill" :style="'width:' + progressPct + '%'"></view>
|
|
|
+ </view>
|
|
|
+ <text class="jc-pct">{{ progressPct }}%</text>
|
|
|
+ </view>
|
|
|
+ <view class="jc-steps" v-if="intentType === 'C'">
|
|
|
+ <view class="jc-step" v-for="(s, i) in cSteps" :key="s.key" :class="{ 'jc-step-done': i <= stage, 'jc-step-cur': i === stage }">
|
|
|
+ <view class="jc-step-dot" :class="{ 'jc-step-dot-done': i <= stage }">
|
|
|
+ <text class="jc-step-num" v-if="i < stage">✓</text>
|
|
|
+ <text class="jc-step-num" v-else>{{ i + 1 }}</text>
|
|
|
+ </view>
|
|
|
+ <text class="jc-step-label">{{ s }}</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+ <view class="jc-action" v-if="nextAction && nextAction !== 'done'" @click="onAction">
|
|
|
+ <text class="jc-action-text">{{ nextLabel }}</text>
|
|
|
+ <text class="jc-action-arrow">›</text>
|
|
|
+ </view>
|
|
|
+ <view class="jc-done" v-else-if="nextAction === 'done'">
|
|
|
+ <text class="jc-done-text">✅ 全部完成,奖励已发放!</text>
|
|
|
+ </view>
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { getProblemDomainList } from '../utils/api.js'
|
|
|
+
|
|
|
+var C_STEPS = ['选问题域', '看流程', '调研', '选购方案', '物流', '出报告', '确认方案', '任务完成']
|
|
|
+var A_STEPS = ['选购', '出报告', '确认方案', '任务完成']
|
|
|
+var B_STEPS = ['问卷', '推荐']
|
|
|
+
|
|
|
+var C_ACTIONS = ['flow-intro', 'survey', 'package', 'logistics', 'report', 'plan-confirm', 'tasks', 'done']
|
|
|
+var A_ACTIONS = ['purchase', 'report', 'plan-confirm', 'tasks', 'done']
|
|
|
+var B_ACTIONS = ['survey', 'recommend', 'done']
|
|
|
+
|
|
|
+var C_LABELS = ['查看服务流程', '填写调研', '选购方案', '查看物流', '等待报告', '确认方案', '查看任务', '已完成']
|
|
|
+var A_LABELS = ['去选购', '查看报告', '确认方案', '查看任务', '已完成']
|
|
|
+var B_LABELS = ['填写问卷', '查看推荐', '已完成']
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: 'JourneyCard',
|
|
|
+ props: {
|
|
|
+ intent: {
|
|
|
+ type: Object,
|
|
|
+ default: null
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ domainMap: {}
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ intentType() {
|
|
|
+ return this.intent && this.intent.intentType
|
|
|
+ },
|
|
|
+ stage() {
|
|
|
+ return this.intent ? (this.intent.journeyStage || 0) : 0
|
|
|
+ },
|
|
|
+ maxStage() {
|
|
|
+ if (this.intentType === 'C') return 7
|
|
|
+ if (this.intentType === 'A') return 4
|
|
|
+ if (this.intentType === 'B') return 2
|
|
|
+ return 0
|
|
|
+ },
|
|
|
+ progressPct() {
|
|
|
+ if (this.maxStage === 0) return 0
|
|
|
+ return Math.round((this.stage / this.maxStage) * 100)
|
|
|
+ },
|
|
|
+ steps() {
|
|
|
+ if (this.intentType === 'C') return C_STEPS
|
|
|
+ if (this.intentType === 'A') return A_STEPS
|
|
|
+ if (this.intentType === 'B') return B_STEPS
|
|
|
+ return []
|
|
|
+ },
|
|
|
+ actions() {
|
|
|
+ if (this.intentType === 'C') return C_ACTIONS
|
|
|
+ if (this.intentType === 'A') return A_ACTIONS
|
|
|
+ if (this.intentType === 'B') return B_ACTIONS
|
|
|
+ return []
|
|
|
+ },
|
|
|
+ labels() {
|
|
|
+ if (this.intentType === 'C') return C_LABELS
|
|
|
+ if (this.intentType === 'A') return A_LABELS
|
|
|
+ if (this.intentType === 'B') return B_LABELS
|
|
|
+ return []
|
|
|
+ },
|
|
|
+ cSteps() {
|
|
|
+ if (this.intentType !== 'C') return []
|
|
|
+ var sliced = this.steps.slice(0, Math.max(this.stage + 1, 3))
|
|
|
+ return sliced.map(function(s, i) {
|
|
|
+ return { key: 's' + i, label: s }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ stageLabel() {
|
|
|
+ var idx = Math.min(this.stage, this.steps.length - 1)
|
|
|
+ if (this.stage >= this.steps.length) return '已完成'
|
|
|
+ return '第' + (this.stage + 1) + '步:' + this.steps[idx]
|
|
|
+ },
|
|
|
+ nextAction() {
|
|
|
+ var idx = Math.min(this.stage, this.actions.length - 1)
|
|
|
+ return this.actions[idx] || 'done'
|
|
|
+ },
|
|
|
+ nextLabel() {
|
|
|
+ var idx = Math.min(this.stage, this.labels.length - 1)
|
|
|
+ return this.labels[idx] || '已完成'
|
|
|
+ },
|
|
|
+ domainLabel() {
|
|
|
+ var code = this.intent && this.intent.problemDomainCode
|
|
|
+ if (code && this.domainMap[code]) {
|
|
|
+ return this.domainMap[code]
|
|
|
+ }
|
|
|
+ if (this.intentType === 'A') return 'A类 · 直达目标'
|
|
|
+ if (this.intentType === 'B') return 'B类 · 智能问卷'
|
|
|
+ if (this.intentType === 'C') return 'C类 · 解决问题'
|
|
|
+ return ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.loadDomainMap()
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ loadDomainMap() {
|
|
|
+ var self = this
|
|
|
+ getProblemDomainList().then(function(res) {
|
|
|
+ var list = res && res.data
|
|
|
+ if (Array.isArray(list)) {
|
|
|
+ var map = {}
|
|
|
+ list.forEach(function(d) {
|
|
|
+ map[d.code] = d.name
|
|
|
+ })
|
|
|
+ self.domainMap = map
|
|
|
+ }
|
|
|
+ }).catch(function() {
|
|
|
+ // 静默失败
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onAction() {
|
|
|
+ this.$emit('action', {
|
|
|
+ action: this.nextAction,
|
|
|
+ code: this.intent && this.intent.problemDomainCode
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.jc-wrap {
|
|
|
+ background: linear-gradient(135deg, #FFF7ED, #FFEDD5);
|
|
|
+ border-radius: 24rpx;
|
|
|
+ padding: 28rpx 30rpx;
|
|
|
+ margin: 20rpx 24rpx 0;
|
|
|
+ box-shadow: 0 4rpx 20rpx rgba(249, 115, 22, 0.12);
|
|
|
+}
|
|
|
+
|
|
|
+.jc-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 16rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-title {
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #333;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-stage-label {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #F97316;
|
|
|
+ background: rgba(249, 115, 22, 0.12);
|
|
|
+ padding: 4rpx 14rpx;
|
|
|
+ border-radius: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-progress {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-bar {
|
|
|
+ flex: 1;
|
|
|
+ height: 12rpx;
|
|
|
+ background: #FED7AA;
|
|
|
+ border-radius: 6rpx;
|
|
|
+ overflow: hidden;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-bar-fill {
|
|
|
+ height: 100%;
|
|
|
+ background: linear-gradient(90deg, #F97316, #FB923C);
|
|
|
+ border-radius: 6rpx;
|
|
|
+ transition: width 0.3s;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-pct {
|
|
|
+ font-size: 22rpx;
|
|
|
+ color: #F97316;
|
|
|
+ margin-left: 12rpx;
|
|
|
+ min-width: 48rpx;
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-steps {
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: nowrap;
|
|
|
+ overflow-x: auto;
|
|
|
+ margin-bottom: 20rpx;
|
|
|
+ padding-bottom: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-step {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ margin-right: 24rpx;
|
|
|
+ flex-shrink: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-step:last-child {
|
|
|
+ margin-right: 0;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-step-dot {
|
|
|
+ width: 36rpx;
|
|
|
+ height: 36rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ background: #FED7AA;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ margin-bottom: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-step-dot-done {
|
|
|
+ background: #F97316;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-step-num {
|
|
|
+ font-size: 20rpx;
|
|
|
+ color: #fff;
|
|
|
+ font-weight: bold;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-step-label {
|
|
|
+ font-size: 20rpx;
|
|
|
+ color: #999;
|
|
|
+ white-space: nowrap;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-step-cur .jc-step-label {
|
|
|
+ color: #F97316;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-step-done .jc-step-label {
|
|
|
+ color: #666;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-action {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: center;
|
|
|
+ background: #F97316;
|
|
|
+ border-radius: 40rpx;
|
|
|
+ padding: 22rpx 0;
|
|
|
+ margin-top: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-action:active {
|
|
|
+ opacity: 0.9;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-action-text {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 30rpx;
|
|
|
+ font-weight: 600;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-action-arrow {
|
|
|
+ color: #fff;
|
|
|
+ font-size: 36rpx;
|
|
|
+ margin-left: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-done {
|
|
|
+ text-align: center;
|
|
|
+ padding: 16rpx 0;
|
|
|
+ margin-top: 8rpx;
|
|
|
+}
|
|
|
+
|
|
|
+.jc-done-text {
|
|
|
+ font-size: 28rpx;
|
|
|
+ color: #16A34A;
|
|
|
+}
|
|
|
+</style>
|