Merge branch 'refs/heads/milestone-20251031-简版功能开发' into lihuilin/feature-20251024095243-我的
# Conflicts: # utils/http.jszhaowenkang/feature-20251028181547-行情页面
-
46api/customerServicePlatform/customerServicePlatform.js
-
185api/home/mySelections.js
-
70api/marketSituation/marketSituation.js
-
30api/start/login.js
-
196components/FeedbackModal.vue
-
64components/IndexCard.vue
-
2components/deepExploration_header.vue
-
28components/login-prompt.vue
-
28pages.json
-
687pages/customerServicePlatform/csPlatformIndex.vue
-
358pages/customerServicePlatform/historyRecord.vue
-
340pages/customerServicePlatform/questionDetail.vue
-
57pages/deepMate/deepMate.vue
-
256pages/home/home.vue
-
141pages/marketSituation/countryMarket.vue
-
382pages/marketSituation/globalIndex.vue
-
74pages/marketSituation/marketCondition.vue
-
282pages/marketSituation/marketDetail.vue
-
121pages/marketSituation/marketOverview.vue
-
252pages/marketSituation/marketSituation.vue
-
1pages/start/Registration/Registration.vue
-
93pages/start/recoverPassword/recoverPassword.vue
-
BINstatic/customer-service-platform/camera.png
-
BINstatic/customer-service-platform/cs-platform-back.png
-
BINstatic/customer-service-platform/ellipse-dc-img.png
-
BINstatic/customer-service-platform/empty-content.png
-
BINstatic/customer-service-platform/fail-icon.png
-
BINstatic/customer-service-platform/message.png
-
BINstatic/customer-service-platform/refresh-icon.png
-
BINstatic/customer-service-platform/robot-head.png
-
BINstatic/customer-service-platform/smile-icon.png
-
BINstatic/customer-service-platform/success-icon.png
-
BINstatic/marketSituation-image/country-flag/can.png
-
BINstatic/marketSituation-image/country-flag/cn.png
-
BINstatic/marketSituation-image/country-flag/global.png
-
BINstatic/marketSituation-image/country-flag/hk.png
-
BINstatic/marketSituation-image/country-flag/my.png
-
BINstatic/marketSituation-image/country-flag/sg.png
-
BINstatic/marketSituation-image/country-flag/th.png
-
BINstatic/marketSituation-image/country-flag/us.png
-
BINstatic/marketSituation-image/country-flag/vi.png
-
1stores/index.js
-
44stores/modules/login.js
-
78stores/modules/marketSituation.js
-
20utils/http.js
@ -0,0 +1,46 @@ |
|||||
|
import { http } from '@/utils/http.js' |
||||
|
|
||||
|
const baseURL = "http://39.101.133.168:8828" |
||||
|
//图片上传
|
||||
|
export const uploadImageApi = (data) => { |
||||
|
return http({ |
||||
|
method: 'POST', |
||||
|
url: baseURL +'/hljw/api/aws/upload', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//问题回答
|
||||
|
export const getAnswerApi = (data) => { |
||||
|
return http({ |
||||
|
method: 'POST', |
||||
|
url: 'http://pbb6edde.natappfree.cc' +'/api/customer/askQuestion', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
//获取随机5条猜你想问问题
|
||||
|
export const getQuestionApi = (data) => { |
||||
|
return http({ |
||||
|
method: 'GET', |
||||
|
url: 'http://pbb6edde.natappfree.cc' +'/api/customer/getQuestion', |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
//反馈添加
|
||||
|
export const addFeedbackRecordApi = (data) => { |
||||
|
return http({ |
||||
|
method: 'POST', |
||||
|
url: baseURL +'/link/third/dcFeedBack/feedback/add', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
//反馈历史记录
|
||||
|
export const getFeedbackRecordsApi = (data) => { |
||||
|
return http({ |
||||
|
method: 'POST', |
||||
|
url: baseURL+'/link/third/dcFeedBack/feedback/select', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
@ -0,0 +1,185 @@ |
|||||
|
/** |
||||
|
* 我的自选股相关API接口封装 |
||||
|
* 使用utils/http.js中的拦截器封装请求方法 |
||||
|
*/ |
||||
|
|
||||
|
import { http } from '../../utils/http.js' |
||||
|
|
||||
|
/** |
||||
|
* 我的自选股API接口类 |
||||
|
*/ |
||||
|
class MySelectionsAPI { |
||||
|
|
||||
|
/** |
||||
|
* 判断用户是否存在自选股分组 |
||||
|
* @param {Function} successCallback - 成功回调函数 |
||||
|
* @param {Function} failCallback - 失败回调函数 |
||||
|
* @param {Object} data - 请求参数 |
||||
|
* @returns {Promise} |
||||
|
*/ |
||||
|
static async checkExist(successCallback, failCallback = null, data = {}) { |
||||
|
const url = '/api/homePage/userStock/checkExist' |
||||
|
|
||||
|
try { |
||||
|
const response = await http({ |
||||
|
url: url, |
||||
|
method: 'POST', |
||||
|
data: data |
||||
|
}) |
||||
|
|
||||
|
console.log('检查用户自选股分组存在性 - 响应:', response) |
||||
|
if (successCallback && typeof successCallback === 'function') { |
||||
|
successCallback(response) |
||||
|
} |
||||
|
return response |
||||
|
} catch (error) { |
||||
|
console.error('检查用户自选股分组存在性 - 失败:', error) |
||||
|
if (failCallback && typeof failCallback === 'function') { |
||||
|
failCallback(error) |
||||
|
} |
||||
|
throw error |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询用户所有自选股分组 |
||||
|
* @param {Function} successCallback - 成功回调函数 |
||||
|
* @param {Function} failCallback - 失败回调函数 |
||||
|
* @param {Object} data - 请求参数 |
||||
|
* @returns {Promise} |
||||
|
*/ |
||||
|
static async getUserStockGroupList(successCallback, failCallback = null, data = {}) { |
||||
|
const url = '/api/homePage/userStockGroup/list' |
||||
|
|
||||
|
try { |
||||
|
const response = await http({ |
||||
|
url: url, |
||||
|
method: 'POST', |
||||
|
data: data |
||||
|
}) |
||||
|
|
||||
|
console.log('查询用户自选股分组列表 - 响应:', response) |
||||
|
if (successCallback && typeof successCallback === 'function') { |
||||
|
successCallback(response) |
||||
|
} |
||||
|
return response |
||||
|
} catch (error) { |
||||
|
console.error('查询用户自选股分组列表 - 失败:', error) |
||||
|
if (failCallback && typeof failCallback === 'function') { |
||||
|
failCallback(error) |
||||
|
} |
||||
|
throw error |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 分页查询某一个分组下的所有自选股 |
||||
|
* @param {Function} successCallback - 成功回调函数 |
||||
|
* @param {Function} failCallback - 失败回调函数 |
||||
|
* @param {Object} data - 请求参数 {groupId, pageNum, pageSize, ...} |
||||
|
* @returns {Promise} |
||||
|
*/ |
||||
|
static async getUserStockList(successCallback, failCallback = null, data = {}) { |
||||
|
const url = '/api/homePage/userStock/list' |
||||
|
|
||||
|
// 设置默认分页参数
|
||||
|
const requestData = { |
||||
|
pageNum: 1, |
||||
|
pageSize: 20, |
||||
|
...data |
||||
|
} |
||||
|
|
||||
|
try { |
||||
|
const response = await http({ |
||||
|
url: url, |
||||
|
method: 'POST', |
||||
|
data: requestData |
||||
|
}) |
||||
|
|
||||
|
console.log('分页查询分组自选股 - 响应:', response) |
||||
|
if (successCallback && typeof successCallback === 'function') { |
||||
|
successCallback(response) |
||||
|
} |
||||
|
return response |
||||
|
} catch (error) { |
||||
|
console.error('分页查询分组自选股 - 失败:', error) |
||||
|
if (failCallback && typeof failCallback === 'function') { |
||||
|
failCallback(error) |
||||
|
} |
||||
|
throw error |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 查询默认自选股 |
||||
|
* @param {Function} successCallback - 成功回调函数 |
||||
|
* @param {Function} failCallback - 失败回调函数 |
||||
|
* @param {Object} data - 请求参数 |
||||
|
* @returns {Promise} |
||||
|
*/ |
||||
|
static async getUserOrDefault(successCallback, failCallback = null, data = {}) { |
||||
|
const url = '/api/homePage/userStock/getUserOrDefault' |
||||
|
|
||||
|
try { |
||||
|
const response = await http({ |
||||
|
url: url, |
||||
|
method: 'POST', |
||||
|
data: data |
||||
|
}) |
||||
|
|
||||
|
console.log('查询默认自选股 - 响应:', response) |
||||
|
if (successCallback && typeof successCallback === 'function') { |
||||
|
successCallback(response) |
||||
|
} |
||||
|
return response |
||||
|
} catch (error) { |
||||
|
console.error('查询默认自选股 - 失败:', error) |
||||
|
if (failCallback && typeof failCallback === 'function') { |
||||
|
failCallback(error) |
||||
|
} |
||||
|
throw error |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 游客查询默认自选股 |
||||
|
* @param {Function} successCallback - 成功回调函数 |
||||
|
* @param {Function} failCallback - 失败回调函数 |
||||
|
* @returns {Promise} |
||||
|
*/ |
||||
|
static async getDefaultStocks(successCallback, failCallback = null) { |
||||
|
const url = '/api/homePage/userStock/getDefaultStocks' |
||||
|
|
||||
|
try { |
||||
|
const response = await http({ |
||||
|
url: url, |
||||
|
method: 'POST', |
||||
|
data: {} |
||||
|
}) |
||||
|
|
||||
|
console.log('游客查询默认自选股 - 响应:', response) |
||||
|
if (successCallback && typeof successCallback === 'function') { |
||||
|
successCallback(response) |
||||
|
} |
||||
|
return response |
||||
|
} catch (error) { |
||||
|
console.error('游客查询默认自选股 - 失败:', error) |
||||
|
if (failCallback && typeof failCallback === 'function') { |
||||
|
failCallback(error) |
||||
|
} |
||||
|
throw error |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// 导出API类
|
||||
|
export default MySelectionsAPI |
||||
|
|
||||
|
// 也可以导出单个方法供直接使用
|
||||
|
export const { |
||||
|
checkExist, |
||||
|
getUserStockGroupList, |
||||
|
getUserStockList, |
||||
|
getUserOrDefault, |
||||
|
getDefaultStocks |
||||
|
} = MySelectionsAPI |
||||
@ -0,0 +1,70 @@ |
|||||
|
/** @format */ |
||||
|
|
||||
|
import { http } from "../../utils/http"; |
||||
|
|
||||
|
export const getData = () => { |
||||
|
return http({ |
||||
|
method: "GET", |
||||
|
url: "/ka", |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 获取全球指数 |
||||
|
* POST /api/global/getGlobalIndex |
||||
|
*/ |
||||
|
export const getGlobalIndexAPI = (data) => { |
||||
|
return http({ |
||||
|
method: "POST", |
||||
|
url: "/api/global/getGlobalIndex", |
||||
|
data, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 获取地区分组列表 |
||||
|
* POST /api/global/regionalGroup |
||||
|
*/ |
||||
|
export const getRegionalGroupAPI = (data) => { |
||||
|
return http({ |
||||
|
method: "POST", |
||||
|
url: "/api/global/regionalGroup", |
||||
|
data, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 获取地区详情 |
||||
|
* POST /api/global/regionalGroupList |
||||
|
*/ |
||||
|
export const getRegionalGroupListAPI = (data) => { |
||||
|
return http({ |
||||
|
method: "POST", |
||||
|
url: "/api/global/regionalGroupList", |
||||
|
data, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 一次性查询所有Tab栏父子结构 |
||||
|
* POST /api/homework/tab/getAll |
||||
|
*/ |
||||
|
export const getAllTabsAPI = (data) => { |
||||
|
return http({ |
||||
|
method: "POST", |
||||
|
url: "/api/homework/tab/getAll", |
||||
|
data, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
/** |
||||
|
* 通用市场数据分页查询接口(默认1页20条) |
||||
|
* POST /api/market/data/page/query |
||||
|
*/ |
||||
|
export const queryStockDataAPI = (data) => { |
||||
|
return http({ |
||||
|
method: "POST", |
||||
|
url: "/api/market/data/page/query", |
||||
|
data, |
||||
|
}); |
||||
|
}; |
||||
@ -0,0 +1,196 @@ |
|||||
|
<template> |
||||
|
<view> |
||||
|
<view v-if="internalVisible" class="fm-overlay"></view> |
||||
|
|
||||
|
<view v-if="internalVisible" class="fm-wrap"> |
||||
|
<view class="fm-card" :style="{ width: _width }"> |
||||
|
<text class="fm-title">{{ _title }}</text> |
||||
|
|
||||
|
<view class="fm-icon-wrap"> |
||||
|
<image :src="imgSrcComputed" mode="aspectFit" class="fm-icon-img" /> |
||||
|
</view> |
||||
|
|
||||
|
<text class="fm-sub">{{ _subtitle }}</text> |
||||
|
|
||||
|
<view class="fm-btn-wrap"> |
||||
|
<button class="fm-btn" @click="onConfirm">{{ _buttonText }}</button> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
export default { |
||||
|
name: 'FeedbackModal', |
||||
|
props: { |
||||
|
title: { |
||||
|
type: String, |
||||
|
default: '提交成功' |
||||
|
}, |
||||
|
subtitle: { |
||||
|
type: String, |
||||
|
default: '— 感谢您的反馈 —' |
||||
|
}, |
||||
|
buttonText: { |
||||
|
type: String, |
||||
|
default: '确定' |
||||
|
}, |
||||
|
status: { |
||||
|
type: String, |
||||
|
default: 'success' |
||||
|
}, |
||||
|
lockScroll: { |
||||
|
type: Boolean, |
||||
|
default: true |
||||
|
}, |
||||
|
width: { |
||||
|
type: String, |
||||
|
default: '600rpx' |
||||
|
} |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
internalVisible: false, |
||||
|
_title: this.title, |
||||
|
_subtitle: this.subtitle, |
||||
|
_buttonText: this.buttonText, |
||||
|
_status: this.status, |
||||
|
_width: this.width, |
||||
|
}; |
||||
|
}, |
||||
|
computed: { |
||||
|
imgSrcComputed() { |
||||
|
return this._status === 'fail' ? |
||||
|
'/static/customer-service-platform/fail-icon.png' : |
||||
|
'/static/customer-service-platform/success-icon.png'; |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
show(options = {}) { |
||||
|
if (options.title) this._title = options.title; |
||||
|
if (options.subtitle) this._subtitle = options.subtitle; |
||||
|
if (options.buttonText) this._buttonText = options.buttonText; |
||||
|
if (options.status) this._status = options.status; |
||||
|
if (options.width) this._width = options.width; |
||||
|
if (this.lockScroll) this._lockScroll(); |
||||
|
|
||||
|
this.internalVisible = true; |
||||
|
}, |
||||
|
|
||||
|
hide() { |
||||
|
this.internalVisible = false; |
||||
|
if (this.lockScroll) this._unlockScroll(); |
||||
|
}, |
||||
|
|
||||
|
onConfirm() { |
||||
|
this.hide(); |
||||
|
this.$nextTick(() => { |
||||
|
this.$emit('confirm', { |
||||
|
status: this._status |
||||
|
}); |
||||
|
}); |
||||
|
}, |
||||
|
//整个页面的滚动条被禁用,防止用户无法上下滚动页面 |
||||
|
_lockScroll() { |
||||
|
try { |
||||
|
document.body.style.overflow = 'hidden'; |
||||
|
} catch (e) {} |
||||
|
}, |
||||
|
_unlockScroll() { |
||||
|
try { |
||||
|
document.body.style.overflow = ''; |
||||
|
} catch (e) {} |
||||
|
} |
||||
|
}, |
||||
|
beforeDestroy() { |
||||
|
if (this.lockScroll) this._unlockScroll(); |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.fm-overlay { |
||||
|
position: fixed; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
top: 0; |
||||
|
bottom: 0; |
||||
|
background: rgba(0, 0, 0, 0.35); |
||||
|
z-index: 999; |
||||
|
} |
||||
|
|
||||
|
.fm-wrap { |
||||
|
position: fixed; |
||||
|
left: 0; |
||||
|
right: 0; |
||||
|
top: 0; |
||||
|
bottom: 0; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
z-index: 1000; |
||||
|
padding: 40rpx; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.fm-card { |
||||
|
background: #fff; |
||||
|
border-radius: 24rpx; |
||||
|
padding: 40rpx; |
||||
|
box-sizing: border-box; |
||||
|
text-align: center; |
||||
|
box-shadow: 0 6rpx 30rpx rgba(0, 0, 0, 0.12); |
||||
|
} |
||||
|
|
||||
|
.fm-title { |
||||
|
display: block; |
||||
|
font-size: 48rpx; |
||||
|
font-weight: 700; |
||||
|
color: #333333; |
||||
|
margin-bottom: 40rpx; |
||||
|
} |
||||
|
|
||||
|
.fm-icon-wrap { |
||||
|
width: 200rpx; |
||||
|
height: 200rpx; |
||||
|
margin: 0 auto 40rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.fm-icon-img { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.fm-sub { |
||||
|
display: block; |
||||
|
color: #666666; |
||||
|
font-size: 32rpx; |
||||
|
margin-bottom: 40rpx; |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.fm-btn-wrap { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.fm-btn { |
||||
|
width: 220rpx; |
||||
|
height: 60rpx; |
||||
|
border-radius: 32rpx; |
||||
|
background: #000; |
||||
|
color: #ffffff; |
||||
|
font-weight: 700; |
||||
|
font-size: 32rpx; |
||||
|
font-style: normal; |
||||
|
border: none; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,687 @@ |
|||||
|
<template> |
||||
|
<view class="main"> |
||||
|
<view class="top" :style="{height:iSMT+'px'}"></view> |
||||
|
|
||||
|
<!-- 头部导航 --> |
||||
|
<view class="header"> |
||||
|
<view class="back-icon"> |
||||
|
<image @click="onBack" src="/static/customer-service-platform/cs-platform-back.png" |
||||
|
class="header-icon-image"></image> |
||||
|
</view> |
||||
|
<view class="title">{{headerTitle}}</view> |
||||
|
<view class="notification-icon"> |
||||
|
<image src="/static/customer-service-platform/message.png" class="header-icon-image"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!-- 内容区域 - 使用滚动视图 --> |
||||
|
<scroll-view scroll-y class="content-container"> |
||||
|
<view class="content-header"> |
||||
|
<view class="content-header-area"> |
||||
|
<view class="logo"> |
||||
|
<image mode="aspectFit" src="/static/customer-service-platform/ellipse-dc-img.png"></image> |
||||
|
</view> |
||||
|
<view class="greeting"> |
||||
|
<text class="greet-title">嗨,我能为你做点什么?</text> |
||||
|
<text class="greet-sub">DeepChart随时为您提供服务</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!--猜你想问卡片部分--> |
||||
|
<view class="card"> |
||||
|
<view class="suggest-header"> |
||||
|
<text class="suggest-title">猜你想问</text> |
||||
|
<view class="swap" @click="getQuestionList()"> |
||||
|
<image class="swap-icon" src="/static/customer-service-platform/refresh-icon.png"></image> |
||||
|
<text class="swap-title">换一换</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
<view class="card-line"></view> |
||||
|
<view class="suggest-list"> |
||||
|
<view class="suggest-item" v-for="(q, idx) in showQuestions" :key="idx" @click="onQuestionClick(q)"> |
||||
|
<view class="left"> |
||||
|
<view :class="['num', 'num-' + ((idx % 5) + 1)]">{{ idx + 1 }}</view> |
||||
|
<text class="q-text">{{ q }}</text> |
||||
|
</view> |
||||
|
<view class="right"> |
||||
|
<text class="arrow">›</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!--反馈卡片部分--> |
||||
|
<text class="feedback-card-title">反馈中心</text> |
||||
|
<view class="card"> |
||||
|
<view class="suggest-header"> |
||||
|
<text class="feedback-title">填写反馈内容</text> |
||||
|
</view> |
||||
|
<view class="card-line"></view> |
||||
|
<textarea class="feedback-input" placeholder="请描述您想反馈的内容 最多可输入200字" maxlength="200" |
||||
|
v-model="feedbackText" /> |
||||
|
<view class="meta-row"> |
||||
|
<text class="char-count">{{ feedbackText.length }}/200</text> |
||||
|
</view> |
||||
|
<view class="suggest-header"> |
||||
|
<text class="upload-img-tip">上传图片</text> |
||||
|
</view> |
||||
|
<view class="upload-row"> |
||||
|
<view class="img-slot" v-for="(img, index) in images" :key="index"> |
||||
|
<image :src="img" mode="scaleToFill" class="slot-img" /> |
||||
|
<button v-if="img" class="remove" @click="removeImage(index)">×</button> |
||||
|
</view> |
||||
|
<view class="img-slot" v-if="images.length < 3"> |
||||
|
<view class="slot-empty" @click="chooseImage()"> |
||||
|
<image src="/static/customer-service-platform/camera.png" class="camera-icon" /> |
||||
|
</view> |
||||
|
</view> |
||||
|
<text class="tip-text" v-if="images.length === 0">最多添加3张图片</text> |
||||
|
</view> |
||||
|
|
||||
|
<button class="feedback-btn" @click="onSumbitFeedback()">提交</button> |
||||
|
<feedback-modal ref="feedback" @confirm="onConfirm" /> |
||||
|
</view> |
||||
|
<!--历史反馈卡片部分--> |
||||
|
<view class="card"> |
||||
|
<text class="feedback-title">历史反馈内容</text> |
||||
|
<view class="card-line"></view> |
||||
|
<button class="feedback-btn" @click="viewHistory">查看</button> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { useUserStore } from "../../stores/modules/userInfo.js" |
||||
|
import { |
||||
|
getQuestionApi, |
||||
|
addFeedbackRecordApi, |
||||
|
uploadImageApi |
||||
|
} from "../../api/customerServicePlatform/customerServicePlatform"; |
||||
|
|
||||
|
import FeedbackModal from '@/components/FeedbackModal.vue' |
||||
|
export default { |
||||
|
components: { |
||||
|
FeedbackModal |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
headerTitle: '智能客服中台', |
||||
|
iSMT: 0, |
||||
|
questions: [ |
||||
|
"DeepChart 有免费功能和付费功能的区分吗?具体有哪些?", |
||||
|
"如何参与平台的用户反馈活动?反馈的问题会被采纳吗?", |
||||
|
"我的自选股最多能添加多少只?能否按市场分类管理?", |
||||
|
"注册时必须提供手机号 / 邮箱吗?能否匿名使用?", |
||||
|
"忘记登录密码了,如何找回?", |
||||
|
'如何注册账号?', |
||||
|
'为什么无法注册账户?' |
||||
|
], |
||||
|
showQuestions: [], |
||||
|
feedbackText: '', |
||||
|
images: [], |
||||
|
token:'' |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
// 状态栏高度 |
||||
|
this.iSMT = uni.getSystemInfoSync().statusBarHeight; |
||||
|
this.getQuestionList() |
||||
|
const memberStore = useUserStore() |
||||
|
this.token = memberStore.userInfo?.token |
||||
|
}, |
||||
|
methods: { |
||||
|
onSuccess() { |
||||
|
this.$refs.feedback.show({ |
||||
|
status: 'success', |
||||
|
title: '提交成功', |
||||
|
subtitle: '— 感谢您的反馈 —', |
||||
|
buttonText: '确定', |
||||
|
width: '80%', |
||||
|
}); |
||||
|
}, |
||||
|
onFail() { |
||||
|
this.$refs.feedback.show({ |
||||
|
status: 'fail', |
||||
|
title: '提交失败', |
||||
|
subtitle: '— 请重新提交 —', |
||||
|
buttonText: '确定', |
||||
|
width: '80%', |
||||
|
}); |
||||
|
}, |
||||
|
onBack() { |
||||
|
if (typeof uni !== 'undefined') uni.navigateBack(); |
||||
|
}, |
||||
|
async getQuestionList() { |
||||
|
const res = await getQuestionApi() |
||||
|
console.log(res) |
||||
|
if (res.code == 200) { |
||||
|
this.showQuestions = res.data |
||||
|
} |
||||
|
|
||||
|
}, |
||||
|
onQuestionClick(q) { |
||||
|
if (typeof uni !== 'undefined') uni.navigateTo({ |
||||
|
url: `/pages/customerServicePlatform/questionDetail?question=${encodeURIComponent(q)}` |
||||
|
}); |
||||
|
}, |
||||
|
chooseImage() { |
||||
|
const that = this; |
||||
|
if (typeof uni === 'undefined' || !uni.chooseImage) return; |
||||
|
|
||||
|
const remain = 3 - (that.images ? that.images.length : 0); |
||||
|
if (remain <= 0) { |
||||
|
if (typeof uni !== 'undefined') uni.showToast({ |
||||
|
title: '最多只能上传3张', |
||||
|
icon: 'none' |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
uni.chooseImage({ |
||||
|
count: remain, |
||||
|
sizeType: ['original', 'compressed'], |
||||
|
sourceType: ['album', 'camera'], |
||||
|
success(res) { |
||||
|
const paths = res.tempFilePaths || (res.tempFiles && res.tempFiles.map(f => f.path)) || []; |
||||
|
for (let p of paths) { |
||||
|
if (that.images.length < 3) { |
||||
|
that.images.push(p); |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
fail(err) { |
||||
|
uni.showToast({ |
||||
|
title: `选择图片失败`, |
||||
|
icon: 'none' |
||||
|
}); |
||||
|
} |
||||
|
}); |
||||
|
}, |
||||
|
|
||||
|
removeImage(index) { |
||||
|
// 删除并保持响应 |
||||
|
this.images.splice(index, 1); |
||||
|
}, |
||||
|
async onSumbitFeedback() { |
||||
|
if (!this.feedbackText.trim()) { |
||||
|
if (typeof uni !== 'undefined') uni.showToast({ |
||||
|
title: '请填写反馈内容', |
||||
|
icon: 'none' |
||||
|
}); |
||||
|
return; |
||||
|
} |
||||
|
if (typeof uni !== 'undefined') uni.showLoading({ |
||||
|
title: '提交中...' |
||||
|
}); |
||||
|
try { |
||||
|
let uploadedImages = []; |
||||
|
let imgFlag = true |
||||
|
for (let i = 0; i < this.images.length; i++) { |
||||
|
const f = this.images[i]; |
||||
|
await new Promise((resolve, reject) => { |
||||
|
uni.getImageInfo({ |
||||
|
src: f, |
||||
|
success: () => resolve(), |
||||
|
fail: reject |
||||
|
}); |
||||
|
}); |
||||
|
const uploadRes = await new Promise((resolve, reject) => { |
||||
|
uni.uploadFile({ |
||||
|
url: 'http://39.101.133.168:8828/hljw/api/aws/upload', |
||||
|
filePath: f, |
||||
|
name: 'file', |
||||
|
formData: { |
||||
|
dir: 'deepchart' |
||||
|
}, |
||||
|
success: (res) => { |
||||
|
try { |
||||
|
const data = JSON.parse(res.data); |
||||
|
if (data.code === 200) { |
||||
|
uploadedImages.push(data.data.url); |
||||
|
resolve(data); |
||||
|
} else { |
||||
|
uni.showToast({ |
||||
|
title: `第${i + 1}张图片上传失败`, |
||||
|
icon: 'none' |
||||
|
}); |
||||
|
imgFlag = false; |
||||
|
reject(data); |
||||
|
} |
||||
|
} catch (err) { |
||||
|
imgFlag = false; |
||||
|
reject(err); |
||||
|
} |
||||
|
}, |
||||
|
fail: (err) => { |
||||
|
imgFlag = false; |
||||
|
uni.showToast({ |
||||
|
title: `第${i + 1}张图片上传失败`, |
||||
|
icon: 'none' |
||||
|
}); |
||||
|
reject(err); |
||||
|
} |
||||
|
}); |
||||
|
}); |
||||
|
} |
||||
|
if (!imgFlag) { |
||||
|
return |
||||
|
} |
||||
|
const [image1 = '', image2 = '', image3 = ''] = uploadedImages; |
||||
|
const res = await addFeedbackRecordApi({ |
||||
|
token: this.token, |
||||
|
content: this.feedbackText, |
||||
|
image1, |
||||
|
image2, |
||||
|
image3 |
||||
|
}) |
||||
|
if (res.code == 200) { |
||||
|
this.onSuccess() |
||||
|
} else { |
||||
|
this.onFail() |
||||
|
} |
||||
|
} catch { |
||||
|
this.onFail() |
||||
|
} finally { |
||||
|
uni.hideLoading(); |
||||
|
this.feedbackText = ''; |
||||
|
this.images = []; |
||||
|
} |
||||
|
}, |
||||
|
viewHistory() { |
||||
|
// 跳转到历史页 |
||||
|
if (typeof uni !== 'undefined') uni.navigateTo({ |
||||
|
url: '/pages/customerServicePlatform/historyRecord' |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.main { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
height: 100vh; |
||||
|
background-color: #ffffff; |
||||
|
} |
||||
|
|
||||
|
.header { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
padding: 20rpx 30rpx; |
||||
|
background-color: #ffffff; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
color: #000000; |
||||
|
text-align: center; |
||||
|
font-size: 32rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
|
||||
|
.back-icon, |
||||
|
.notification-icon { |
||||
|
width: 40rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.header-icon-image { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
object-fit: contain; |
||||
|
} |
||||
|
|
||||
|
.content-container { |
||||
|
padding: 20rpx; |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
overflow-x: hidden; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.content-header { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
gap: 24rpx; |
||||
|
padding: 0 60rpx; |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
height: 188rpx; |
||||
|
} |
||||
|
|
||||
|
.content-header-area { |
||||
|
display: flex; |
||||
|
gap: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.logo { |
||||
|
width: 120rpx; |
||||
|
height: 120rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
flex: 0 0 112rpx; |
||||
|
} |
||||
|
|
||||
|
.greeting { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
flex: 1 1 auto; |
||||
|
} |
||||
|
|
||||
|
.greet-title { |
||||
|
color: #000; |
||||
|
font-size: 40rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 500; |
||||
|
line-height: normal; |
||||
|
margin: 0; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.greet-sub { |
||||
|
color: #838383; |
||||
|
font-size: 28rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: normal; |
||||
|
margin-top: 12rpx; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.card { |
||||
|
width: 90%; |
||||
|
margin: 0 auto; |
||||
|
border-radius: 16rpx; |
||||
|
padding: 20rpx 40rpx; |
||||
|
box-sizing: border-box; |
||||
|
border-radius: 12rpx; |
||||
|
border: 4rpx solid #FCC8D4; |
||||
|
background: linear-gradient(180deg, #FCC8D3 0%, #FEF0F3 30%, #FFF 100%); |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.suggest-header { |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.suggest-title { |
||||
|
color: #000000; |
||||
|
font-size: 32rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
.swap { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
transition: transform 0.1s ease, background-color 0.1s ease; |
||||
|
} |
||||
|
|
||||
|
.swap:active { |
||||
|
transform: scale(0.95); |
||||
|
} |
||||
|
|
||||
|
.swap-icon { |
||||
|
width: 30rpx; |
||||
|
height: 30rpx; |
||||
|
} |
||||
|
|
||||
|
.swap-title { |
||||
|
padding-left: 8rpx; |
||||
|
color: #000000; |
||||
|
font-size: 24rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
.suggest-list { |
||||
|
margin-top: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.card-line { |
||||
|
margin-top: 20rpx; |
||||
|
width: 100%; |
||||
|
height: 2rpx; |
||||
|
border-radius: 2rpx; |
||||
|
background: #FFF; |
||||
|
} |
||||
|
|
||||
|
.suggest-item { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
padding-top: 10rpx; |
||||
|
border-radius: 12rpx; |
||||
|
margin-bottom: 20rpx; |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
.left { |
||||
|
width: 90%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.num { |
||||
|
font-size: 40rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 700; |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
.num-1 { |
||||
|
color: #df5662; |
||||
|
} |
||||
|
|
||||
|
.num-2 { |
||||
|
color: #ec6d4f; |
||||
|
} |
||||
|
|
||||
|
.num-3 { |
||||
|
color: #f3ba40; |
||||
|
} |
||||
|
|
||||
|
.num-4 { |
||||
|
color: #9296a0; |
||||
|
} |
||||
|
|
||||
|
.num-5 { |
||||
|
color: #9296a0; |
||||
|
} |
||||
|
|
||||
|
.q-text { |
||||
|
padding-left: 14rpx; |
||||
|
display: block; |
||||
|
color: #333; |
||||
|
font-size: 28rpx; |
||||
|
white-space: nowrap; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
} |
||||
|
|
||||
|
.right { |
||||
|
width: 48rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: flex-end; |
||||
|
} |
||||
|
|
||||
|
.arrow { |
||||
|
color: #cfcfcf; |
||||
|
font-size: 36rpx; |
||||
|
} |
||||
|
|
||||
|
.suggest-item:active { |
||||
|
background: rgba(255, 77, 128, 0.06); |
||||
|
} |
||||
|
|
||||
|
.feedback-card-title { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
color: #000000; |
||||
|
font-size: 32rpx; |
||||
|
font-weight: 700; |
||||
|
line-height: 40rpx; |
||||
|
width: 100%; |
||||
|
margin-bottom: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.feedback-title { |
||||
|
color: #000000; |
||||
|
font-size: 32rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
.feedback-input { |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
padding: 20rpx; |
||||
|
flex-direction: column; |
||||
|
box-sizing: border-box; |
||||
|
align-items: flex-start; |
||||
|
gap: 12rpx; |
||||
|
align-self: stretch; |
||||
|
border-radius: 12rpx; |
||||
|
border: 2rpx solid #F0F1F1; |
||||
|
margin-top: 20rpx; |
||||
|
display: flex; |
||||
|
background: #FFF; |
||||
|
color: #8a8a8a; |
||||
|
font-size: 24rpx; |
||||
|
font-weight: 700; |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
.meta-row { |
||||
|
display: flex; |
||||
|
justify-content: flex-end; |
||||
|
margin-top: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.char-count { |
||||
|
color: #999 |
||||
|
} |
||||
|
|
||||
|
.upload-img-tip { |
||||
|
color: #000000; |
||||
|
font-size: 24rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
.upload-row { |
||||
|
display: flex; |
||||
|
justify-content: flex-start; |
||||
|
align-items: flex-start; |
||||
|
align-content: flex-start; |
||||
|
flex-wrap: wrap; |
||||
|
gap: 20rpx; |
||||
|
margin-top: 20rpx; |
||||
|
width: 100%; |
||||
|
} |
||||
|
|
||||
|
.img-slot { |
||||
|
width: calc((100% - 2 * 30rpx) / 3); |
||||
|
aspect-ratio: 1 / 1; |
||||
|
border-radius: 6px; |
||||
|
border: 1px solid #F0F1F1; |
||||
|
background: #FFF; |
||||
|
position: relative; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
overflow: hidden; |
||||
|
transition: transform 0.2s ease; |
||||
|
} |
||||
|
|
||||
|
.slot-empty { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.camera-icon { |
||||
|
width: 34rpx; |
||||
|
height: 34rpx; |
||||
|
} |
||||
|
|
||||
|
.slot-img { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
border-radius: 16rpx; |
||||
|
} |
||||
|
|
||||
|
.remove { |
||||
|
position: absolute; |
||||
|
right: 6rpx; |
||||
|
top: 6rpx; |
||||
|
border-radius: 50%; |
||||
|
background: #fd5c58; |
||||
|
padding: 0; |
||||
|
color: #fff; |
||||
|
width: 36rpx; |
||||
|
height: 36rpx; |
||||
|
font-size: 28rpx; |
||||
|
line-height: 36rpx; |
||||
|
text-align: center; |
||||
|
border: none; |
||||
|
outline: none; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
|
||||
|
.remove:active { |
||||
|
background: rgba(0, 0, 0, 0.75); |
||||
|
} |
||||
|
|
||||
|
.image-upload-tip { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.tip-text { |
||||
|
color: #999999; |
||||
|
font-size: 24rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: 40rpx; |
||||
|
padding-top: 64rpx; |
||||
|
} |
||||
|
|
||||
|
.feedback-btn { |
||||
|
margin-top: 24rpx; |
||||
|
width: 180rpx; |
||||
|
height: 60rpx; |
||||
|
aspect-ratio: 89/30; |
||||
|
border-radius: 30rpx; |
||||
|
background: #090A08; |
||||
|
color: #ffffff; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
font-size: 32rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 700; |
||||
|
line-height: normal; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,358 @@ |
|||||
|
<template> |
||||
|
<view class="main"> |
||||
|
<view class="top" :style="{height:iSMT+'px'}"></view> |
||||
|
<!-- 头部导航 --> |
||||
|
<view class="header"> |
||||
|
<view class="back-icon"> |
||||
|
<image @click="goBack()" src="/static/customer-service-platform/cs-platform-back.png" |
||||
|
class="header-icon-image"></image> |
||||
|
</view> |
||||
|
<view class="title">智能客服中台</view> |
||||
|
<view class="notification-icon"> |
||||
|
<image src="/static/customer-service-platform/message.png" class="header-icon-image"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
<!-- 内容区域 - 使用滚动视图 --> |
||||
|
<scroll-view scroll-y class="content-container"> |
||||
|
<view class="list-wrapper" v-if="historyList.length > 0"> |
||||
|
<view class="content-header"> |
||||
|
<text class="content-title">历史反馈内容</text> |
||||
|
</view> |
||||
|
<view class="card-line"></view> |
||||
|
<view v-for="(item, idx) in historyList" :key="item.id" class="history-item card"> |
||||
|
<view class="item-line" v-if="idx != 0"></view> |
||||
|
<view class="item-head"> |
||||
|
<view class="dot-outer"> |
||||
|
<view class="dot-inner"></view> |
||||
|
</view> |
||||
|
|
||||
|
<text class="feedback-time">{{ formatTime(item.createdAt) }}</text> |
||||
|
<text class="feedback-status"> |
||||
|
{{ statusText }} |
||||
|
<image class="smile-icon" src="/static/customer-service-platform/smile-icon.png"></image> |
||||
|
</text> |
||||
|
</view> |
||||
|
|
||||
|
<view class="content-box"> |
||||
|
<text class="content-text">{{ item.content }}</text> |
||||
|
<text class="count">{{ item.content.length }}/200</text> |
||||
|
</view> |
||||
|
<view v-if="item.images && item.images.length" class="thumb-row"> |
||||
|
<view v-for="(img, i) in item.images" :key="i" class="thumb-slot" |
||||
|
@click="previewImage(item.images, i)"> |
||||
|
<image :src="img" mode="scaleToFill" class="thumb-img" /> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 如果没有历史,显示空态 --> |
||||
|
<view v-if="historyList.length === 0" class="empty"> |
||||
|
<image mode="aspectFit" class="empty-img" src="/static/customer-service-platform/empty-content.png"> |
||||
|
</image> |
||||
|
<text class="empty-tip">暂无内容~</text> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { useUserStore } from "../../stores/modules/userInfo.js" |
||||
|
import { |
||||
|
getFeedbackRecordsApi, |
||||
|
} from "../../api/customerServicePlatform/customerServicePlatform"; |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
iSMT: 0, |
||||
|
statusText: '反馈成功', |
||||
|
historyList: [], |
||||
|
token:'' |
||||
|
}; |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.iSMT = uni.getSystemInfoSync().statusBarHeight; |
||||
|
this.loadHistoryList() |
||||
|
const memberStore = useUserStore() |
||||
|
this.token = memberStore.userInfo?.token |
||||
|
}, |
||||
|
methods: { |
||||
|
formatTime(str) { |
||||
|
if (!str) return ''; |
||||
|
const d = new Date(str); |
||||
|
const yyyy = d.getFullYear(); |
||||
|
const mm = String(d.getMonth() + 1).padStart(2, '0'); |
||||
|
const dd = String(d.getDate()).padStart(2, '0'); |
||||
|
const hh = String(d.getHours()).padStart(2, '0'); |
||||
|
const mi = String(d.getMinutes()).padStart(2, '0'); |
||||
|
return `${yyyy}-${mm}-${dd} ${hh}:${mi}`; |
||||
|
}, |
||||
|
goBack() { |
||||
|
if (typeof uni !== 'undefined' && uni.navigateBack) { |
||||
|
uni.navigateBack(); |
||||
|
} else { |
||||
|
window.history.back(); |
||||
|
} |
||||
|
}, |
||||
|
async loadHistoryList() { |
||||
|
const res = await getFeedbackRecordsApi({ |
||||
|
token: this.token |
||||
|
}) |
||||
|
console.log(res) |
||||
|
if (res.code == 200) { |
||||
|
this.historyList = res.data.map(item => { |
||||
|
const images = [item.image1, item.image2, item.image3].filter(img => !!img) |
||||
|
return { |
||||
|
id: item.id, |
||||
|
createdAt: item.createdAt, |
||||
|
content: item.content, |
||||
|
images, |
||||
|
dccode: item.dccode |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
}, |
||||
|
previewImage(list, index) { |
||||
|
if (typeof uni !== 'undefined' && uni.previewImage) { |
||||
|
uni.previewImage({ |
||||
|
current: list[index], |
||||
|
urls: list |
||||
|
}); |
||||
|
} else { |
||||
|
window.open(list[index], '_blank'); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.main { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
height: 100vh; |
||||
|
background-color: #ffffff; |
||||
|
} |
||||
|
|
||||
|
.header { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
padding: 20rpx 30rpx; |
||||
|
background-color: #ffffff; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
color: #000000; |
||||
|
text-align: center; |
||||
|
font-size: 32rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
|
||||
|
.back-icon, |
||||
|
.notification-icon { |
||||
|
width: 40rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.header-icon-image { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
object-fit: contain; |
||||
|
} |
||||
|
|
||||
|
.content-container { |
||||
|
padding: 20rpx; |
||||
|
padding-top: 0; |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
overflow-x: hidden; |
||||
|
} |
||||
|
|
||||
|
/* 列表包装器,居中卡片 */ |
||||
|
.list-wrapper { |
||||
|
width: 90%; |
||||
|
margin: 0 auto; |
||||
|
padding: 20rpx 40rpx; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
gap: 20rpx; |
||||
|
box-sizing: border-box; |
||||
|
border-radius: 12rpx; |
||||
|
border: 4rpx solid #FCC8D4; |
||||
|
background: linear-gradient(180deg, #FCC8D3 0%, #FEF0F3 30%, #FFF 100%); |
||||
|
} |
||||
|
|
||||
|
.content-header { |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: space-between; |
||||
|
} |
||||
|
|
||||
|
.content-title { |
||||
|
color: #000000; |
||||
|
font-size: 32rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
.card-line { |
||||
|
margin-top: 20rpx; |
||||
|
width: 100%; |
||||
|
height: 2rpx; |
||||
|
border-radius: 2rpx; |
||||
|
background: #FFF; |
||||
|
} |
||||
|
|
||||
|
/* 每一条历史卡片 */ |
||||
|
.history-item { |
||||
|
border-radius: 10rpx; |
||||
|
padding: 20rpx; |
||||
|
margin-bottom: 20rpx; |
||||
|
box-sizing: border-box; |
||||
|
box-shadow: 0 4rpx 12rpx rgba(255, 77, 128, 0.06); |
||||
|
} |
||||
|
.item-line{ |
||||
|
margin-bottom: 20rpx; |
||||
|
width: 100%; |
||||
|
height: 2rpx; |
||||
|
border-radius: 2rpx; |
||||
|
background: #D9D9D9; |
||||
|
} |
||||
|
.item-head { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 12rpx; |
||||
|
margin-bottom: 12rpx; |
||||
|
} |
||||
|
|
||||
|
.dot-outer { |
||||
|
width: 24rpx; |
||||
|
height: 24rpx; |
||||
|
border-radius: 50%; |
||||
|
background: rgba(255, 214, 230, 0.5); |
||||
|
/*粉色外圈*/ |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
box-shadow: 0 0 0 4rpx #ffffff; |
||||
|
/* 最外层白色 */ |
||||
|
} |
||||
|
|
||||
|
.dot-inner { |
||||
|
width: 14rpx; |
||||
|
height: 14rpx; |
||||
|
border-radius: 50%; |
||||
|
background: #ff4150; |
||||
|
/* 中心红色 */ |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.feedback-time { |
||||
|
color: #000000; |
||||
|
flex: 1; |
||||
|
font-size: 22rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: normal; |
||||
|
padding-left: 26rpx; |
||||
|
} |
||||
|
|
||||
|
.feedback-status { |
||||
|
color: #ff4150; |
||||
|
font-size: 12rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: normal; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.smile-icon { |
||||
|
width: 32rpx; |
||||
|
height: 32rpx; |
||||
|
} |
||||
|
|
||||
|
/* 内容框 */ |
||||
|
.content-box { |
||||
|
border: 2rpx solid #f0e6ea; |
||||
|
background: #fff; |
||||
|
border-radius: 8rpx; |
||||
|
padding: 18rpx; |
||||
|
position: relative; |
||||
|
box-sizing: border-box; |
||||
|
min-height: 160rpx; |
||||
|
} |
||||
|
|
||||
|
.content-text { |
||||
|
display: block; |
||||
|
white-space: pre-wrap; |
||||
|
word-break: break-word; |
||||
|
color: #8a8a8a; |
||||
|
font-size: 24rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 700; |
||||
|
line-height: normal; |
||||
|
padding-bottom: 26rpx; |
||||
|
} |
||||
|
|
||||
|
.count { |
||||
|
position: absolute; |
||||
|
right: 14rpx; |
||||
|
bottom: 10rpx; |
||||
|
color: #000000; |
||||
|
font-size: 24rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: normal; |
||||
|
} |
||||
|
|
||||
|
.thumb-row { |
||||
|
display: flex; |
||||
|
flex-wrap: wrap; |
||||
|
justify-content: flex-start; |
||||
|
align-items: flex-start; |
||||
|
align-content: flex-start; |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
gap: 20rpx; |
||||
|
margin-top: 14rpx; |
||||
|
background: #F9FAFE; |
||||
|
padding: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.thumb-slot { |
||||
|
width: calc((100% - 2 * 25rpx) / 3); |
||||
|
aspect-ratio: 1 / 1; |
||||
|
border-radius: 7rpx; |
||||
|
border: 1.2rpx solid #F0F1F1; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.thumb-img { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.empty { |
||||
|
padding: 50rpx 0; |
||||
|
text-align: center; |
||||
|
color: #afafaf; |
||||
|
font-size: 32rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 500; |
||||
|
line-height: 48rpx; |
||||
|
} |
||||
|
|
||||
|
.empty-img { |
||||
|
width: 100%; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,340 @@ |
|||||
|
<template> |
||||
|
<view class="main"> |
||||
|
<view class="top" :style="{ height: iSMT + 'px' }"></view> |
||||
|
|
||||
|
<!-- 头部导航 --> |
||||
|
<view class="header"> |
||||
|
<view class="back-icon"> |
||||
|
<image @click="onBack" src="/static/customer-service-platform/cs-platform-back.png" |
||||
|
class="header-icon-image"></image> |
||||
|
</view> |
||||
|
<view class="title">{{ headerTitle }}</view> |
||||
|
<view class="notification-icon"> |
||||
|
<image src="/static/customer-service-platform/message.png" class="header-icon-image"></image> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<scroll-view scroll-y class="content-container"> |
||||
|
|
||||
|
<view class="content-header"> |
||||
|
<view class="content-header-area"> |
||||
|
<view class="logo"> |
||||
|
<image mode="aspectFit" src="/static/customer-service-platform/ellipse-dc-img.png"></image> |
||||
|
</view> |
||||
|
<view class="greeting"> |
||||
|
<text class="greet-title">嗨,我能为你做点什么?</text> |
||||
|
<text class="greet-sub">DeepChart随时为您提供服务</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 卡片部分 --> |
||||
|
<view class="card"> |
||||
|
<!-- 问题头部--> |
||||
|
<view class="question-header"> |
||||
|
<view class="question-row"> |
||||
|
<image class="question-avatar" src="/static/customer-service-platform/robot-head.png" |
||||
|
mode="aspectFill"></image> |
||||
|
<view class="question-title">{{ questionTitle }}</view> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
<!-- 卡片内容区--> |
||||
|
<view class="card-body"> |
||||
|
<image class="card-logo" src="/static/customer-service-platform/ellipse-dc-img.png" |
||||
|
mode="aspectFit"></image> |
||||
|
|
||||
|
<view class="card-text"> |
||||
|
<text class="card-paragraph"> |
||||
|
{{answerContent}} |
||||
|
</text> |
||||
|
</view> |
||||
|
</view> |
||||
|
|
||||
|
</view> |
||||
|
|
||||
|
<view class="login-row" v-if="showLoginRegister"> |
||||
|
<button class="login-btn" @click="toLogin">登录</button> |
||||
|
<button class="register-btn" @click="toRegistration">注册</button> |
||||
|
</view> |
||||
|
</scroll-view> |
||||
|
</view> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { useUserStore } from "../../stores/modules/userInfo.js" |
||||
|
import { |
||||
|
getAnswerApi |
||||
|
} from "../../api/customerServicePlatform/customerServicePlatform"; |
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
headerTitle: '智能客服中台', |
||||
|
iSMT: 0, |
||||
|
questionTitle: '', |
||||
|
answerContent: '正在思考...', |
||||
|
showLoginRegister:false, |
||||
|
token:'' |
||||
|
}; |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.iSMT = uni.getSystemInfoSync().statusBarHeight || 0; |
||||
|
this.getAnswerContent() |
||||
|
const memberStore = useUserStore() |
||||
|
this.token = memberStore.userInfo?.token |
||||
|
}, |
||||
|
onLoad(options) { |
||||
|
if (options.question) { |
||||
|
this.questionTitle = decodeURIComponent(options.question); |
||||
|
if (this.questionTitle.includes("如何注册")) { |
||||
|
this.showLoginRegister = true |
||||
|
} else { |
||||
|
this.showLoginRegister = false |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
async getAnswerContent() { |
||||
|
let conversationId = ''; |
||||
|
try { |
||||
|
const cache = uni.getStorageSync('conversationId'); |
||||
|
if (cache) conversationId = cache; |
||||
|
} catch (e) { |
||||
|
conversationId = ''; |
||||
|
} |
||||
|
|
||||
|
const res = await getAnswerApi({ |
||||
|
question: this.questionTitle, |
||||
|
conversationId: conversationId, |
||||
|
token:this.token |
||||
|
}) |
||||
|
console.log(res) |
||||
|
|
||||
|
if (res.code == 200) { |
||||
|
uni.setStorageSync('conversationId', res.data.conversationId); |
||||
|
const answer = res.data.answer |
||||
|
this.answerContent = ''; |
||||
|
for (let i = 0; i < answer.length; i++) { |
||||
|
this.answerContent += answer[i]; |
||||
|
await this.sleepTime(150); |
||||
|
} |
||||
|
} else { |
||||
|
this.answerContent = '获取回答失败,请重试'; |
||||
|
} |
||||
|
}, |
||||
|
async sleepTime() { |
||||
|
const ms = Math.floor(Math.random() * (300 - 30 + 1)) + 30; |
||||
|
return new Promise(resolve => setTimeout(resolve, ms)); |
||||
|
}, |
||||
|
|
||||
|
toRegistration() { |
||||
|
uni.redirectTo({ |
||||
|
url: "/pages/start/Registration/Registration", |
||||
|
}); |
||||
|
}, |
||||
|
toLogin() { |
||||
|
uni.redirectTo({ |
||||
|
url: "/pages/start/login/login", |
||||
|
}); |
||||
|
}, |
||||
|
onBack() { |
||||
|
if (typeof uni !== 'undefined') uni.navigateBack(); |
||||
|
} |
||||
|
} |
||||
|
}; |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.main { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
height: 100vh; |
||||
|
background-color: #ffffff; |
||||
|
} |
||||
|
|
||||
|
.header { |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
align-items: center; |
||||
|
padding: 20rpx 30rpx; |
||||
|
background-color: #ffffff; |
||||
|
} |
||||
|
|
||||
|
.title { |
||||
|
color: #000000; |
||||
|
text-align: center; |
||||
|
font-size: 32rpx; |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
|
||||
|
.back-icon, |
||||
|
.notification-icon { |
||||
|
width: 40rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
} |
||||
|
|
||||
|
.header-icon-image { |
||||
|
width: 40rpx; |
||||
|
height: 40rpx; |
||||
|
object-fit: contain; |
||||
|
} |
||||
|
|
||||
|
.content-container { |
||||
|
padding: 20rpx; |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
overflow-x: hidden; |
||||
|
} |
||||
|
|
||||
|
.content-header { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
gap: 24rpx; |
||||
|
padding: 0 60rpx; |
||||
|
width: 100%; |
||||
|
box-sizing: border-box; |
||||
|
height: 188rpx; |
||||
|
} |
||||
|
|
||||
|
.content-header-area { |
||||
|
display: flex; |
||||
|
gap: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.logo { |
||||
|
width: 120rpx; |
||||
|
height: 120rpx; |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
flex: 0 0 112rpx; |
||||
|
} |
||||
|
|
||||
|
.greeting { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
justify-content: center; |
||||
|
flex: 1 1 auto; |
||||
|
} |
||||
|
|
||||
|
.greet-title { |
||||
|
color: #000; |
||||
|
font-size: 40rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 500; |
||||
|
line-height: normal; |
||||
|
margin: 0; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.greet-sub { |
||||
|
color: #838383; |
||||
|
font-size: 28rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 400; |
||||
|
line-height: normal; |
||||
|
margin-top: 12rpx; |
||||
|
overflow: hidden; |
||||
|
text-overflow: ellipsis; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
|
||||
|
.card { |
||||
|
width: 90%; |
||||
|
margin: 0 auto 20rpx; |
||||
|
padding: 28rpx; |
||||
|
box-sizing: border-box; |
||||
|
border-radius: 16rpx; |
||||
|
border: 4rpx solid #FF7C99; |
||||
|
background: #fff; |
||||
|
} |
||||
|
|
||||
|
/* 问题头部 */ |
||||
|
.question-header { |
||||
|
width: 100%; |
||||
|
margin-bottom: 48rpx; |
||||
|
} |
||||
|
|
||||
|
.question-row { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.question-avatar { |
||||
|
width: 52rpx; |
||||
|
height: 52rpx; |
||||
|
border-radius: 999rpx; |
||||
|
margin-right: 20rpx; |
||||
|
flex-shrink: 0; |
||||
|
} |
||||
|
|
||||
|
.question-title { |
||||
|
color: #000000; |
||||
|
font-size: 34rpx; |
||||
|
} |
||||
|
|
||||
|
/* 卡片内部布局 */ |
||||
|
.card-body { |
||||
|
display: flex; |
||||
|
gap: 20rpx; |
||||
|
align-items: flex-start; |
||||
|
} |
||||
|
|
||||
|
.card-logo { |
||||
|
width: 52rpx; |
||||
|
height: 52rpx; |
||||
|
flex: 0 0 52rpx; |
||||
|
border-radius: 8rpx; |
||||
|
} |
||||
|
|
||||
|
.card-text { |
||||
|
flex: 1 1 auto; |
||||
|
} |
||||
|
|
||||
|
.card-paragraph { |
||||
|
display: block; |
||||
|
color: #000000; |
||||
|
font-size: 28rpx; |
||||
|
margin-bottom: 14rpx; |
||||
|
font-style: normal; |
||||
|
font-weight: 500; |
||||
|
} |
||||
|
|
||||
|
.login-row { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
width: 100%; |
||||
|
margin-top: 100rpx; |
||||
|
} |
||||
|
|
||||
|
.login-btn { |
||||
|
width: 260rpx; |
||||
|
height: 100rpx; |
||||
|
border-radius: 50rpx; |
||||
|
background: #F3F3F3; |
||||
|
color: #000000; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
font-size: 28rpx; |
||||
|
margin-right: 20rpx; |
||||
|
} |
||||
|
|
||||
|
.register-btn { |
||||
|
width: 260rpx; |
||||
|
height: 100rpx; |
||||
|
border-radius: 60rpx; |
||||
|
background: #000; |
||||
|
color: #ffffff; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
font-size: 28rpx; |
||||
|
} |
||||
|
</style> |
||||
|
After Width: 18 | Height: 16 | Size: 428 B |
|
After Width: 20 | Height: 20 | Size: 247 B |
|
After Width: 60 | Height: 60 | Size: 2.1 KiB |
|
After Width: 213 | Height: 228 | Size: 18 KiB |
|
After Width: 100 | Height: 100 | Size: 4.2 KiB |
|
After Width: 18 | Height: 18 | Size: 523 B |
|
After Width: 15 | Height: 15 | Size: 339 B |
|
After Width: 21 | Height: 19 | Size: 1.2 KiB |
|
After Width: 16 | Height: 16 | Size: 440 B |
|
After Width: 100 | Height: 100 | Size: 4.2 KiB |
|
After Width: 32 | Height: 32 | Size: 1.1 KiB |
|
After Width: 32 | Height: 32 | Size: 1.1 KiB |
|
After Width: 32 | Height: 32 | Size: 2.5 KiB |
|
After Width: 32 | Height: 32 | Size: 1.7 KiB |
|
After Width: 32 | Height: 32 | Size: 1.7 KiB |
|
After Width: 32 | Height: 32 | Size: 1.1 KiB |
|
After Width: 32 | Height: 32 | Size: 703 B |
|
After Width: 32 | Height: 32 | Size: 1.4 KiB |
|
After Width: 32 | Height: 32 | Size: 1.1 KiB |
@ -0,0 +1,44 @@ |
|||||
|
import { defineStore } from 'pinia' |
||||
|
import { ref } from 'vue' |
||||
|
|
||||
|
// 定义 Store
|
||||
|
export const useLoginStore = defineStore( |
||||
|
'login', |
||||
|
() => { |
||||
|
// 会员信息
|
||||
|
const loginInfo = ref("true") |
||||
|
|
||||
|
// 保存会员信息,登录时使用
|
||||
|
const setLoginInfo = (val) => { |
||||
|
loginInfo.value = val |
||||
|
} |
||||
|
|
||||
|
// 清理会员信息,退出时使用
|
||||
|
const clearLoginInfo = () => { |
||||
|
loginInfo.value = undefined |
||||
|
} |
||||
|
|
||||
|
// 记得 return
|
||||
|
return { |
||||
|
loginInfo, |
||||
|
setLoginInfo, |
||||
|
clearLoginInfo, |
||||
|
} |
||||
|
}, |
||||
|
// TODO: 持久化
|
||||
|
{ |
||||
|
// 网页端持久化
|
||||
|
// persist: true,
|
||||
|
// 小程序端持久化
|
||||
|
persist: { |
||||
|
storage: { |
||||
|
getItem(key) { |
||||
|
return uni.getStorageSync(key) |
||||
|
}, |
||||
|
setItem(key, value) { |
||||
|
uni.setStorageSync(key, value) |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
) |
||||
@ -0,0 +1,78 @@ |
|||||
|
/** @format */ |
||||
|
|
||||
|
import { defineStore } from "pinia"; |
||||
|
import { ref } from "vue"; |
||||
|
// 定义 Store
|
||||
|
export const useMarketSituationStore = defineStore( |
||||
|
"marketSituation", |
||||
|
() => { |
||||
|
const cardData = ref([ |
||||
|
{ |
||||
|
market: "usa", |
||||
|
stockName: "道琼斯", |
||||
|
stockCode: "noCode", |
||||
|
currentPrice: "45757.90", |
||||
|
changeAmount: "-125.22", |
||||
|
changePercent: "-0.27%", |
||||
|
isRising: false, |
||||
|
}, |
||||
|
{ |
||||
|
market: "usa", |
||||
|
stockName: "纳斯达克", |
||||
|
stockCode: "noCode", |
||||
|
currentPrice: "22333.96", |
||||
|
changeAmount: "+125.22", |
||||
|
changePercent: "+0.47%", |
||||
|
isRising: true, |
||||
|
}, |
||||
|
{ |
||||
|
market: "usa", |
||||
|
stockName: "标普500", |
||||
|
stockCode: "noCode", |
||||
|
currentPrice: "6606.08", |
||||
|
changeAmount: "+125.22", |
||||
|
changePercent: "+0.27%", |
||||
|
isRising: true, |
||||
|
}, |
||||
|
{ |
||||
|
market: "cn", |
||||
|
stockName: "上证指数", |
||||
|
stockCode: "noCode", |
||||
|
currentPrice: "3333.96", |
||||
|
changeAmount: "+125.22", |
||||
|
changePercent: "+0.27%", |
||||
|
isRising: true, |
||||
|
}, |
||||
|
{ |
||||
|
market: "cn", |
||||
|
stockName: "科创50", |
||||
|
stockCode: "noCode", |
||||
|
currentPrice: "757.90", |
||||
|
changeAmount: "-25.22", |
||||
|
changePercent: "-0.27%", |
||||
|
isRising: false, |
||||
|
}, |
||||
|
]); |
||||
|
|
||||
|
// 记得 return
|
||||
|
return { |
||||
|
cardData |
||||
|
}; |
||||
|
}, |
||||
|
// TODO: 持久化
|
||||
|
{ |
||||
|
// 网页端持久化
|
||||
|
// persist: true,
|
||||
|
// 小程序端持久化
|
||||
|
persist: { |
||||
|
storage: { |
||||
|
getItem(key) { |
||||
|
return uni.getStorageSync(key); |
||||
|
}, |
||||
|
setItem(key, value) { |
||||
|
uni.setStorageSync(key, value); |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
); |
||||