Browse Source

接口对接

zhaowenkang/feature-20251028181547-行情页面
maziyang 4 weeks ago
parent
commit
3ba6af2fd3
  1. 31
      api/customerServicePlatform/customerServicePlatform.js
  2. 187
      pages/customerServicePlatform/csPlatformIndex.vue
  3. 44
      pages/customerServicePlatform/historyRecord.vue
  4. 153
      pages/customerServicePlatform/questionDetail.vue

31
api/customerServicePlatform/customerServicePlatform.js

@ -1,29 +1,46 @@
import { http } from '@/utils/http.js' import { http } from '@/utils/http.js'
const baseFeedbackURL = "http://39.101.133.168:8828/link"
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 getQuestion = (data) => {
//问题回答
export const getAnswerApi = (data) => {
return http({ return http({
method: 'POST', method: 'POST',
url: 'http://pbb6edde.natappfree.cc' +'/api/customer/getQuestion',
url: 'http://pbb6edde.natappfree.cc' +'/api/customer/askQuestion',
data data
}) })
} }
//获取随机5条猜你想问问题
export const getQuestionApi = (data) => {
return http({
method: 'GET',
url: 'http://pbb6edde.natappfree.cc' +'/api/customer/getQuestion',
})
}
//反馈添加 //反馈添加
export const addFeedbackRecord = (data) => {
export const addFeedbackRecordApi = (data) => {
return http({ return http({
method: 'POST', method: 'POST',
url: baseFeedbackURL +'/third/dcFeedBack/feedback/add',
url: baseURL +'/link/third/dcFeedBack/feedback/add',
data data
}) })
} }
//反馈历史记录 //反馈历史记录
export const getFeedbackRecords = (data) => {
export const getFeedbackRecordsApi = (data) => {
return http({ return http({
method: 'POST', method: 'POST',
url: baseFeedbackURL+'/third/dcFeedBack/feedback/select',
url: baseURL+'/link/third/dcFeedBack/feedback/select',
data data
}) })
} }

187
pages/customerServicePlatform/csPlatformIndex.vue

@ -5,7 +5,8 @@
<!-- 头部导航 --> <!-- 头部导航 -->
<view class="header"> <view class="header">
<view class="back-icon"> <view class="back-icon">
<image @click="onBack" src="/static/customer-service-platform/cs-platform-back.png" class="header-icon-image"></image>
<image @click="onBack" src="/static/customer-service-platform/cs-platform-back.png"
class="header-icon-image"></image>
</view> </view>
<view class="title">{{headerTitle}}</view> <view class="title">{{headerTitle}}</view>
<view class="notification-icon"> <view class="notification-icon">
@ -29,18 +30,17 @@
<view class="card"> <view class="card">
<view class="suggest-header"> <view class="suggest-header">
<text class="suggest-title">猜你想问</text> <text class="suggest-title">猜你想问</text>
<view class="swap" @click="shuffleQuestions">
<view class="swap" @click="getQuestionList()">
<image class="swap-icon" src="/static/customer-service-platform/refresh-icon.png"></image> <image class="swap-icon" src="/static/customer-service-platform/refresh-icon.png"></image>
<text class="swap-title">换一换</text> <text class="swap-title">换一换</text>
</view> </view>
</view> </view>
<view class="card-line"></view> <view class="card-line"></view>
<view class="suggest-list"> <view class="suggest-list">
<view class="suggest-item" v-for="(q, idx) in showQuestions" :key="idx"
@click="onQuestionClick(q)">
<view class="suggest-item" v-for="(q, idx) in showQuestions" :key="idx" @click="onQuestionClick(q)">
<view class="left"> <view class="left">
<view :class="['num', 'num-' + ((idx % 5) + 1)]">{{ idx + 1 }}</view> <view :class="['num', 'num-' + ((idx % 5) + 1)]">{{ idx + 1 }}</view>
<text class="q-text">{{ q }}</text>
<text class="q-text">{{ q }}</text>
</view> </view>
<view class="right"> <view class="right">
<text class="arrow"></text> <text class="arrow"></text>
@ -90,11 +90,17 @@
</template> </template>
<script> <script>
import { getQuestion} from "../../api/customerServicePlatform/customerServicePlatform";
import FeedbackModal from '@/components/FeedbackModal.vue'
import {
getQuestionApi,
addFeedbackRecordApi,
uploadImageApi
} from "../../api/customerServicePlatform/customerServicePlatform";
import FeedbackModal from '@/components/FeedbackModal.vue'
export default { export default {
components: { FeedbackModal },
components: {
FeedbackModal
},
data() { data() {
return { return {
headerTitle: '智能客服中台', headerTitle: '智能客服中台',
@ -116,54 +122,45 @@
mounted() { mounted() {
// //
this.iSMT = uni.getSystemInfoSync().statusBarHeight; this.iSMT = uni.getSystemInfoSync().statusBarHeight;
this.getQuestionList()
}, },
created() { created() {
this.shuffleQuestions();
}, },
methods: { methods: {
onSumbitFeedback(){
this.onSuccess();
},
onSuccess() { onSuccess() {
this.$refs.feedback.show({
status: 'success',
title: '提交成功',
subtitle: '— 感谢您的反馈 —',
buttonText: '确定',
width:'80%',
});
},
onFail() {
this.$refs.feedback.show({
status: 'fail',
title: '提交失败',
subtitle: '— 请重新提交 —',
buttonText: '确定',
width:'80%',
});
},
this.$refs.feedback.show({
status: 'success',
title: '提交成功',
subtitle: '— 感谢您的反馈 —',
buttonText: '确定',
width: '80%',
});
},
onFail() {
this.$refs.feedback.show({
status: 'fail',
title: '提交失败',
subtitle: '— 请重新提交 —',
buttonText: '确定',
width: '80%',
});
},
onBack() { onBack() {
if (typeof uni !== 'undefined') uni.navigateBack(); if (typeof uni !== 'undefined') uni.navigateBack();
}, },
async getQuestionList(){
const res = await getQuestion()
if(res.code == 200){
this.showQuestions =res.data
async getQuestionList() {
const res = await getQuestionApi()
console.log(res)
if (res.code == 200) {
this.showQuestions = res.data
} }
},
shuffleQuestions() {
// 45
const arr = this.questions.slice();
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
this.showQuestions = arr.slice(0, 5);
}, },
onQuestionClick(q) { onQuestionClick(q) {
//
this.feedbackText = q;
if (typeof uni !== 'undefined') uni.navigateTo({
url: `/pages/customerServicePlatform/questionDetail?question=${encodeURIComponent(q)}`
});
}, },
chooseImage() { chooseImage() {
const that = this; const that = this;
@ -179,23 +176,22 @@
} }
uni.chooseImage({ uni.chooseImage({
count: remain, //
count: remain,
sizeType: ['original', 'compressed'], sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'], sourceType: ['album', 'camera'],
success(res) { success(res) {
// res.tempFilePaths /APP
const paths = res.tempFilePaths || (res.tempFiles && res.tempFiles.map(f => f.path)) || []; const paths = res.tempFilePaths || (res.tempFiles && res.tempFiles.map(f => f.path)) || [];
// imagesVue2 push
for (let p of paths) { for (let p of paths) {
if (that.images.length < 3) { if (that.images.length < 3) {
that.images.push(p); that.images.push(p);
} }
} }
// uni.uploadFile
}, },
fail(err) { fail(err) {
//
// console.log('chooseImage fail', err)
uni.showToast({
title: `选择图片失败`,
icon: 'none'
});
} }
}); });
}, },
@ -204,7 +200,7 @@
// //
this.images.splice(index, 1); this.images.splice(index, 1);
}, },
submit() {
async onSumbitFeedback() {
if (!this.feedbackText.trim()) { if (!this.feedbackText.trim()) {
if (typeof uni !== 'undefined') uni.showToast({ if (typeof uni !== 'undefined') uni.showToast({
title: '请填写反馈内容', title: '请填写反馈内容',
@ -212,32 +208,87 @@
}); });
return; return;
} }
//
if (typeof uni !== 'undefined') uni.showLoading({ if (typeof uni !== 'undefined') uni.showLoading({
title: '提交中...' title: '提交中...'
}); });
setTimeout(() => {
if (typeof uni !== 'undefined') {
uni.hideLoading();
uni.showToast({
title: '提交成功',
icon: 'success'
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
});
}); });
} else {
console.log('提交数据', {
text: this.feedbackText,
images: this.images
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: "a1bef735d336831ccb0cc3f532093b60",
content: this.feedbackText,
image1,
image2,
image3
})
if (res.code == 200) {
this.onSuccess()
} else {
this.onFail()
}
} catch {
this.onFail()
} finally {
uni.hideLoading();
this.feedbackText = ''; this.feedbackText = '';
this.images = [null, null];
}, 1000);
this.images = [];
}
}, },
viewHistory() { viewHistory() {
// //
if (typeof uni !== 'undefined') uni.navigateTo({ if (typeof uni !== 'undefined') uni.navigateTo({
url: '/pages/customerServicePlatform/questionDetail'
url: '/pages/customerServicePlatform/historyRecord'
}); });
} }
} }

44
pages/customerServicePlatform/historyRecord.vue

@ -20,12 +20,13 @@
</view> </view>
<view class="card-line"></view> <view class="card-line"></view>
<view v-for="(item, idx) in historyList" :key="item.id" class="history-item card"> <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="item-head">
<view class="dot-outer"> <view class="dot-outer">
<view class="dot-inner"></view> <view class="dot-inner"></view>
</view> </view>
<text class="feedback-time">{{ item.createdAt }}</text>
<text class="feedback-time">{{ formatTime(item.createdAt) }}</text>
<text class="feedback-status"> <text class="feedback-status">
{{ statusText }} {{ statusText }}
<image class="smile-icon" src="/static/customer-service-platform/smile-icon.png"></image> <image class="smile-icon" src="/static/customer-service-platform/smile-icon.png"></image>
@ -57,28 +58,14 @@
<script> <script>
import { import {
getFeedbackRecords,
addFeedbackRecord
getFeedbackRecordsApi,
} from "../../api/customerServicePlatform/customerServicePlatform"; } from "../../api/customerServicePlatform/customerServicePlatform";
export default { export default {
data() { data() {
return { return {
iSMT: 0, iSMT: 0,
// historyList: [],
statusText: '反馈成功', statusText: '反馈成功',
historyList: [{
id: 1,
createdAt: '2025/10/16 11:46',
content: '你是不是总是看着股票回调时心里发慌,不知道什么时候进场才是最安全的?追高买错被套牢,亏得眼泪直流aaa,回调时又不敢进,错过了反弹的机会?今天,我将带你掌握一套精准确认底部的三步法——通过超卖信号、关键K线和强势启动点,帮助你轻松识别市场底部,稳健进场,避开高位追涨,赚取大波利润!我们今天会结合特斯拉(TSLA)和阿里巴巴(BABA)的经aaa典案例,帮助你更好地理解这些技巧,赶快拿起纸笔,开始学',
images: []
},
{
id: 2,
createdAt: '2025/10/16 11:46',
content: '请描述您想反馈的内容\n第二条示例文本,长度可以不一样,测试多行显示和字数统计功能。这里补充一些文字以便测试外观和换行效果。',
images: []
}
]
historyList: []
}; };
}, },
mounted() { mounted() {
@ -86,6 +73,16 @@
this.loadHistoryList() this.loadHistoryList()
}, },
methods: { 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() { goBack() {
if (typeof uni !== 'undefined' && uni.navigateBack) { if (typeof uni !== 'undefined' && uni.navigateBack) {
uni.navigateBack(); uni.navigateBack();
@ -94,8 +91,8 @@
} }
}, },
async loadHistoryList() { async loadHistoryList() {
const res = await getFeedbackRecords({
token: 'dccec0b65a94f498b8183a17589ab16e'
const res = await getFeedbackRecordsApi({
token: 'a1bef735d336831ccb0cc3f532093b60'
}) })
console.log(res) console.log(res)
if (res.code == 200) { if (res.code == 200) {
@ -118,7 +115,6 @@
urls: list urls: list
}); });
} else { } else {
// H5 fallback
window.open(list[index], '_blank'); window.open(list[index], '_blank');
} }
} }
@ -217,7 +213,13 @@
box-sizing: border-box; box-sizing: border-box;
box-shadow: 0 4rpx 12rpx rgba(255, 77, 128, 0.06); 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 { .item-head {
display: flex; display: flex;
align-items: center; align-items: center;

153
pages/customerServicePlatform/questionDetail.vue

@ -35,7 +35,7 @@
<view class="question-row"> <view class="question-row">
<image class="question-avatar" src="/static/customer-service-platform/robot-head.png" <image class="question-avatar" src="/static/customer-service-platform/robot-head.png"
mode="aspectFill"></image> mode="aspectFill"></image>
<view class="question-title">{{ questionTitle }}?</view>
<view class="question-title">{{ questionTitle }}</view>
</view> </view>
</view> </view>
@ -46,54 +46,93 @@
<view class="card-text"> <view class="card-text">
<text class="card-paragraph"> <text class="card-paragraph">
DeepChart 提供了多种注册方式具体流程如下
{{answerContent}}
</text> </text>
<view class="bullet-list">
<view class="bullet-item">
<view class="bullet-dot"></view>
<text class="bullet-text">邮箱 /
手机号注册进入注册页面后输入邮箱地址或手机号勾选接受用户协议和隐私政策点击注册即可若未勾选协议点击注册时会弹窗提示请阅读并同意服务协议和隐私权限同意后可进入下一步</text>
</view>
<view class="bullet-item">
<view class="bullet-dot"></view>
<text class="bullet-text">第三方账号注册支持通过 Apple 账号或 Google
邮箱直接注册点击对应平台按钮按提示完成授权即可</text>
</view>
<view class="bullet-item">
<view class="bullet-dot"></view>
<text class="bullet-text">若遇到问题请通过页面底部的联系客服按钮联系我们</text>
</view>
</view>
</view> </view>
</view> </view>
</view> </view>
<view class="login-row">
<button class="login-btn">登录</button>
<button class="register-btn">注册</button>
<view class="login-row" v-if="showLoginRegister">
<button class="login-btn" @click="toLogin">登录</button>
<button class="register-btn" @click="toRegistration">注册</button>
</view> </view>
</scroll-view> </scroll-view>
</view> </view>
</template> </template>
<script> <script>
import {
getAnswerApi
} from "../../api/customerServicePlatform/customerServicePlatform";
export default { export default {
data() { data() {
return { return {
headerTitle: '智能客服中台', headerTitle: '智能客服中台',
iSMT: 0, iSMT: 0,
questionTitle: '如何注册账号'
questionTitle: '',
answerContent: '正在思考...',
showLoginRegister:false
}; };
}, },
mounted() { mounted() {
this.iSMT = uni.getSystemInfoSync().statusBarHeight || 0; this.iSMT = uni.getSystemInfoSync().statusBarHeight || 0;
this.getAnswerContent()
},
onLoad(options) {
if (options.question) {
this.questionTitle = decodeURIComponent(options.question);
if (this.questionTitle.includes("如何注册")) {
this.showLoginRegister = true
} else {
this.showLoginRegister = false
}
}
}, },
methods: { 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:"f4383aec3be3c853ff5a71dfae2d061f"
})
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() { onBack() {
if (typeof uni !== 'undefined') uni.navigateBack(); if (typeof uni !== 'undefined') uni.navigateBack();
} }
@ -226,13 +265,13 @@
width: 52rpx; width: 52rpx;
height: 52rpx; height: 52rpx;
border-radius: 999rpx; border-radius: 999rpx;
margin-right: 32rpx;
margin-right: 20rpx;
flex-shrink: 0;
} }
.question-title { .question-title {
color: #000000;
font-size: 34rpx; font-size: 34rpx;
color: #222;
font-weight: 600;
} }
/* 卡片内部布局 */ /* 卡片内部布局 */
@ -255,46 +294,23 @@
.card-paragraph { .card-paragraph {
display: block; display: block;
color: #333;
color: #000000;
font-size: 28rpx; font-size: 28rpx;
margin-bottom: 14rpx; margin-bottom: 14rpx;
font-style: normal;
font-weight: 500;
} }
.bullet-list {
display: flex;
flex-direction: column;
gap: 12rpx;
}
.bullet-item {
display: flex;
align-items: flex-start;
}
.bullet-dot {
width: 8rpx;
height: 8rpx;
background: #FF7C99;
border-radius: 999rpx;
margin-top: 10rpx;
flex: 0 0 8rpx;
}
.bullet-text {
margin-left: 12rpx;
color: #666;
font-size: 28rpx;
line-height: 40rpx;
/* 提高可读性 */
}
.login-row{
.login-row {
display: flex; display: flex;
justify-content: center; justify-content: center;
width:100%;
align-items: center;
width: 100%;
margin-top: 100rpx; margin-top: 100rpx;
} }
.login-btn{
width: 300rpx;
.login-btn {
width: 260rpx;
height: 100rpx; height: 100rpx;
border-radius: 50rpx; border-radius: 50rpx;
background: #F3F3F3; background: #F3F3F3;
@ -303,12 +319,11 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
font-size: 28rpx; font-size: 28rpx;
font-style: normal;
font-weight: 400;
line-height: normal;
margin-right: 20rpx;
} }
.register-btn{
width: 300rpx;
.register-btn {
width: 260rpx;
height: 100rpx; height: 100rpx;
border-radius: 60rpx; border-radius: 60rpx;
background: #000; background: #000;
@ -317,9 +332,5 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
font-size: 28rpx; font-size: 28rpx;
font-style: normal;
font-weight: 400;
line-height: normal;
} }
</style> </style>
Loading…
Cancel
Save