Browse Source

Merge branch 'refs/heads/milestone-20251031-简版功能开发' into lihuilin/feature-20251024095243-我的

maziyang/feature-20251025172218-智能客服中台
lihui 3 weeks ago
parent
commit
9c8931c1c9
  1. 34
      api/home/mySelections.js
  2. 50
      components/deepExploration_header.vue
  3. 22
      manifest.json
  4. 441
      pages/customStockList/customStockList.vue
  5. 1
      pages/customerServicePlatform/csPlatformIndex.vue
  6. 198
      pages/deepExploration/MainForceActions.vue
  7. 186
      pages/deepMate/deepMate.vue
  8. 18
      pages/home/home.vue
  9. 6
      pages/setting/about.vue
  10. 4
      pages/start/Registration/Registration.vue
  11. 4
      pages/start/login/login.vue
  12. 4
      pages/start/recoverPassword/recoverPassword.vue

34
api/home/mySelections.js

@ -325,6 +325,37 @@ class MySelectionsAPI {
throw error throw error
} }
} }
/**
* 更新自选股分组假接口
* @param {Function} successCallback - 成功回调函数
* @param {Function} failCallback - 失败回调函数
* @param {Object} data - 请求参数 {stockId: number, groupId: number}
* @returns {Promise}
*/
static async updateUserStockGroup(successCallback, failCallback = null, data = {}) {
const url = '/api/homePage/userStock/updateGroup'
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
}
}
} }
// 导出API类 // 导出API类
@ -341,5 +372,6 @@ export const {
updateUserStockGroupName, updateUserStockGroupName,
deleteUserStockGroup, deleteUserStockGroup,
deleteUserStock, deleteUserStock,
addUserStock
addUserStock,
updateUserStockGroup
} = MySelectionsAPI } = MySelectionsAPI

50
components/deepExploration_header.vue

@ -66,8 +66,11 @@
> >
<view class="history-left"> <view class="history-left">
<view class="flag-circle" <view class="flag-circle"
><text class="flag-emoji">🇺🇸</text></view
>
><image
class="icon-stock"
:src="stockImage(item.stockMarket)"
mode="scaleToFill"
/></view>
</view> </view>
<view class="history-main" @click="itemClick(item)"> <view class="history-main" @click="itemClick(item)">
<text class="history-query">{{ item.stockName }}</text> <text class="history-query">{{ item.stockName }}</text>
@ -159,6 +162,29 @@ const onDrawerBackClick = () => {
}, 180); }, 180);
}; };
//
function stockImage(Market) {
switch (Market) {
case "usa":
return "../../static/marketSituation-image/country-flag/us.png";
case "can":
return "../../static/marketSituation-image/country-flag/can.png";
case "vi":
return "../../static/marketSituation-image/country-flag/vi.png";
case "th":
return "../../static/marketSituation-image/country-flag/th.png";
case "my":
return "../../static/marketSituation-image/country-flag/my.png";
case "sg":
return "../../static/marketSituation-image/country-flag/sg.png";
case "hk":
return "../../static/marketSituation-image/country-flag/hk.png";
case "cn":
return "../../static/marketSituation-image/country-flag/cn.png";
}
}
// //
async function itemClick(item) { async function itemClick(item) {
const res = await RecordInfoApi({ const res = await RecordInfoApi({
@ -167,19 +193,17 @@ async function itemClick(item) {
model: 5, model: 5,
}); });
if (res.code == 200) { if (res.code == 200) {
const message = res.data; const message = res.data;
const deepExplorationStore = useDeepExplorationStore(); const deepExplorationStore = useDeepExplorationStore();
deepExplorationStore.setDeepExplorationInfo(message); deepExplorationStore.setDeepExplorationInfo(message);
console.log('点击了历史数据',deepExplorationStore.deepExplorationInfo);
console.log("点击了历史数据", deepExplorationStore.deepExplorationInfo);
onDrawerBackClick(); onDrawerBackClick();
setTimeout(() => {
uni.navigateTo({
url: '/pages/deepExploration/MainForceActions'
});
}, 200);
setTimeout(() => {
uni.navigateTo({
url: "/pages/deepExploration/MainForceActions",
});
}, 200);
} }
} }
const historyList = ref([]); const historyList = ref([]);
@ -464,6 +488,12 @@ onMounted(() => {});
height: 50rpx; height: 50rpx;
} }
.icon-stock {
width: 36rpx;
height: 36rpx;
}
.flag-circle { .flag-circle {
width: 50rpx; width: 50rpx;
height: 50rpx; height: 50rpx;

22
manifest.json

@ -1,6 +1,6 @@
{ {
"name" : "DeepChartApp", "name" : "DeepChartApp",
"appid" : "__UNI__9C9AB28",
"appid" : "__UNI__410B53B",
"description" : "", "description" : "",
"versionName" : "1.0.0", "versionName" : "1.0.0",
"versionCode" : "100", "versionCode" : "100",
@ -54,26 +54,26 @@
"google" : { "google" : {
"clientid" : "135" "clientid" : "135"
} }
},
"share" : {
"weixin" : {
"appid" : "wx6143d111fc5c9ba3",
"UniversalLinks" : ""
}
} }
} }
}, },
// "share" : {
// "weixin" : {
// "appid" : "wx6143d111fc5c9ba3",
// "UniversalLinks" : ""
// }
// }
"nativePlugins" : { "nativePlugins" : {
"Aimer-TCPPlugin" : { "Aimer-TCPPlugin" : {
"__plugin_info__" : { "__plugin_info__" : {
"name" : "TCP-Socket原生插件(支持Android和IOS) - [试用版,仅用于自定义调试基座]",
"name" : "TCP-Socket原生插件(支持Android和IOS) ",
"description" : "Uniapp实现基于TCP的数据通信,支持单片机、智能家居等硬件交互,联系QQ: 462108858", "description" : "Uniapp实现基于TCP的数据通信,支持单片机、智能家居等硬件交互,联系QQ: 462108858",
"platforms" : "Android,iOS", "platforms" : "Android,iOS",
"url" : "https://ext.dcloud.net.cn/plugin?id=2029", "url" : "https://ext.dcloud.net.cn/plugin?id=2029",
"android_package_name" : "",
"ios_bundle_id" : "",
"android_package_name" : "com.homily.deepchart",
"ios_bundle_id" : "com.homily.deepchart",
"isCloud" : true, "isCloud" : true,
"bought" : 0,
"bought" : 1,
"pid" : "2029", "pid" : "2029",
"parameters" : {} "parameters" : {}
} }

441
pages/customStockList/customStockList.vue

@ -66,7 +66,18 @@
v-for="stock in stockList" v-for="stock in stockList"
:key="stock.id" :key="stock.id"
class="stock-item" class="stock-item"
@click="handleStockClick(stock)"
> >
<!-- 多选模式下显示复选框 -->
<view v-if="isMultiSelectMode" class="checkbox-container">
<view
:class="['checkbox', selectedStockIds.includes(stock.id) ? 'checked' : '']"
@click.stop="toggleStockSelection(stock.id)"
>
<text v-if="selectedStockIds.includes(stock.id)" class="checkbox-icon"></text>
</view>
</view>
<view class="stock-info"> <view class="stock-info">
<text class="stock-name">{{ stock.name || stock.code }}</text> <text class="stock-name">{{ stock.name || stock.code }}</text>
<text class="stock-code">{{ stock.code }}</text> <text class="stock-code">{{ stock.code }}</text>
@ -74,18 +85,65 @@
<view class="stock-price"> <view class="stock-price">
<text class="price">{{ stock.price || '--' }}</text> <text class="price">{{ stock.price || '--' }}</text>
<text :class="['change', stock.change >= 0 ? 'up' : 'down']"> <text :class="['change', stock.change >= 0 ? 'up' : 'down']">
{{ stock.change >= 0 ? '+' : '' }}{{ stock.change || '--' }}
{{ stock.change >= 0 ? '+' : '-' }}{{ stock.change || '--' }}
</text> </text>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
</view> </view>
<!-- 多选模式下的底部操作栏 -->
<view v-if="isMultiSelectMode" class="bottom-toolbar">
<view class="toolbar-left">
<text class="selected-count">已选择 {{ selectedStockIds.length }} 只股票</text>
<text class="select-all-btn" @click="toggleSelectAll">
{{ isAllSelected ? '取消全选' : '全选' }}
</text>
</view>
<view class="toolbar-right">
<button
class="add-to-group-btn"
:disabled="selectedStockIds.length === 0"
@click="showGroupSelectModal = true"
>
添加至分组
</button>
</view>
</view>
<!-- 分组选择弹窗 -->
<view v-if="showGroupSelectModal" class="modal-overlay" @click="closeGroupSelectModal">
<view class="group-select-modal" @click.stop>
<view class="modal-header">
<text class="modal-title">编辑分组</text>
<text class="modal-close" @click="closeGroupSelectModal"></text>
</view>
<view class="modal-content">
<view class="group-grid">
<view
v-for="group in stockGroups"
:key="group.id"
:class="['group-item', group.id === currentGroupId ? 'current-group' : '']"
@click="selectTargetGroup(group)"
>
<text class="group-name">{{ group.name }}</text>
</view>
<view class="group-item new-group" @click="createNewGroupInModal">
<text class="new-group-text">+ 新建分组</text>
</view>
</view>
</view>
<view class="modal-footer">
<button class="confirm-btn" @click="confirmMoveToGroup">确认</button>
</view>
</view>
</view>
</view> </view>
</template> </template>
<script> <script>
import { getUserStockGroupList, addUserStockGroup, getUserStockList } from '@/api/home/mySelections.js'
import { getUserStockGroupList, addUserStockGroup, getUserStockList, updateUserStockGroup } from '@/api/home/mySelections.js'
export default { export default {
data() { data() {
@ -97,7 +155,21 @@
// //
stockList: [], stockList: [],
// //
loading: false
loading: false,
//
isMultiSelectMode: false,
// ID
selectedStockIds: [],
//
showGroupSelectModal: false,
//
selectedTargetGroup: null
}
},
computed: {
//
isAllSelected() {
return this.stockList.length > 0 && this.selectedStockIds.length === this.stockList.length
} }
}, },
onLoad() { onLoad() {
@ -251,10 +323,178 @@
}) })
}, },
//
// -
onSecondButtonClick() { onSecondButtonClick() {
console.log('第二个按钮被点击')
//
this.isMultiSelectMode = !this.isMultiSelectMode
// 退
if (!this.isMultiSelectMode) {
this.selectedStockIds = []
}
console.log('多选模式:', this.isMultiSelectMode)
},
//
handleStockClick(stock) {
if (this.isMultiSelectMode) {
//
this.toggleStockSelection(stock.id)
} else {
//
console.log('点击股票:', stock)
}
},
//
toggleStockSelection(stockId) {
const index = this.selectedStockIds.indexOf(stockId)
if (index > -1) {
//
this.selectedStockIds.splice(index, 1)
} else {
//
this.selectedStockIds.push(stockId)
}
},
// /
toggleSelectAll() {
if (this.isAllSelected) {
//
this.selectedStockIds = []
} else {
//
this.selectedStockIds = this.stockList.map(stock => stock.id)
}
},
//
closeGroupSelectModal() {
this.showGroupSelectModal = false
this.selectedTargetGroup = null
},
//
selectTargetGroup(group) {
this.selectedTargetGroup = group
},
//
createNewGroupInModal() {
uni.showModal({
title: '创建分组',
content: '请输入分组名称',
editable: true,
placeholderText: '请输入分组名称',
success: (res) => {
if (res.confirm && res.content) {
this.createNewGroupAndSelect(res.content.trim())
}
}
})
},
//
async createNewGroupAndSelect(groupName) {
try {
uni.showLoading({
title: '创建中...'
})
const response = await addUserStockGroup(null, null, {
name: groupName
})
if (response.code === 200) {
uni.showToast({
title: '创建成功',
icon: 'success'
})
//
await this.loadStockGroups()
//
if (response.data && response.data.id) {
this.selectedTargetGroup = this.stockGroups.find(g => g.id === response.data.id)
}
} else {
uni.showToast({
title: response.message || '创建失败',
icon: 'none'
})
}
} catch (error) {
console.error('创建分组失败:', error)
uni.showToast({
title: '创建失败,请重试',
icon: 'none'
})
} finally {
uni.hideLoading()
}
},
//
confirmMoveToGroup() {
if (!this.selectedTargetGroup) {
uni.showToast({
title: '请选择目标分组',
icon: 'none'
})
return
}
if (this.selectedStockIds.length === 0) {
uni.showToast({
title: '请选择要移动的股票',
icon: 'none'
})
return
}
// API
this.moveStocksToGroup(this.selectedTargetGroup.id)
},
//
async moveStocksToGroup(targetGroupId) {
try {
uni.showLoading({
title: '移动中...'
})
// APIID
const promises = this.selectedStockIds.map(stockId => {
return updateUserStockGroup(null, null, {
stockId: stockId,
groupId: targetGroupId
})
})
await Promise.all(promises)
uni.showToast({
title: '移动成功',
icon: 'success'
})
//
this.closeGroupSelectModal()
// 退
this.isMultiSelectMode = false
this.selectedStockIds = []
//
this.loadStockList()
} catch (error) {
console.error('移动股票失败:', error)
uni.showToast({
title: '移动失败,请重试',
icon: 'none'
})
} finally {
uni.hideLoading()
}
} }
} }
} }
@ -448,15 +688,15 @@
.stock-price { .stock-price {
display: flex; display: flex;
flex-direction: column;
align-items: flex-end;
flex-direction: row;
align-items: center;
gap: 8px;
} }
.price { .price {
font-size: 16px; font-size: 16px;
font-weight: 500; font-weight: 500;
color: #333333; color: #333333;
margin-bottom: 4px;
} }
.change { .change {
@ -471,4 +711,187 @@
.change.down { .change.down {
color: #34c759; color: #34c759;
} }
/* 复选框样式 */
.checkbox-container {
margin-right: 12px;
}
.checkbox {
width: 20px;
height: 20px;
border: 2px solid #ddd;
border-radius: 4px;
display: flex;
align-items: center;
justify-content: center;
background-color: #fff;
}
.checkbox.checked {
background-color: #ff3b30;
border-color: #ff3b30;
}
.checkbox-icon {
color: #fff;
font-size: 12px;
font-weight: bold;
}
/* 底部操作栏样式 */
.bottom-toolbar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #fff;
border-top: 1px solid #f0f0f0;
padding: 12px 16px;
display: flex;
align-items: center;
justify-content: space-between;
z-index: 1000;
}
.toolbar-left {
display: flex;
align-items: center;
gap: 16px;
}
.selected-count {
font-size: 14px;
color: #333;
}
.select-all-btn {
font-size: 14px;
color: #ff3b30;
padding: 4px 8px;
}
.toolbar-right {
display: flex;
align-items: center;
}
.add-to-group-btn {
background-color: #ff3b30;
color: #fff;
border: none;
border-radius: 6px;
padding: 8px 16px;
font-size: 14px;
}
.add-to-group-btn:disabled {
background-color: #ccc;
color: #999;
}
/* 弹窗样式 */
.modal-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
align-items: flex-end;
z-index: 1000;
}
.group-select-modal {
background-color: white;
border-radius: 20rpx 20rpx 0 0;
width: 100%;
max-height: 80vh;
overflow: hidden;
}
.modal-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx 40rpx;
border-bottom: 1px solid #f0f0f0;
}
.modal-title {
font-size: 36rpx;
font-weight: bold;
color: #333333;
}
.modal-close {
font-size: 40rpx;
color: #999999;
padding: 10rpx;
}
.modal-content {
padding: 40rpx;
max-height: 60vh;
overflow-y: auto;
}
.group-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
}
.group-item {
background-color: #f8f8f8;
border-radius: 16rpx;
padding: 30rpx 20rpx;
text-align: center;
border: 2rpx solid transparent;
transition: all 0.3s ease;
}
.group-item.current-group {
background-color: #fff2f0;
border-color: #ff4d4f;
}
.group-item:active {
background-color: #e6f7ff;
border-color: #1890ff;
}
.group-name {
font-size: 28rpx;
color: #333333;
font-weight: 500;
}
.group-item.new-group {
background-color: #fff;
border: 2rpx dashed #d9d9d9;
}
.new-group-text {
font-size: 28rpx;
color: #ff4d4f;
font-weight: 500;
}
.modal-footer {
padding: 30rpx 40rpx;
border-top: 1px solid #f0f0f0;
}
.confirm-btn {
width: 100%;
height: 88rpx;
background-color: #ff4d4f;
color: white;
border: none;
border-radius: 44rpx;
font-size: 32rpx;
font-weight: 500;
}
</style> </style>

1
pages/customerServicePlatform/csPlatformIndex.vue

@ -1,4 +1,5 @@
<template> <template>
<LoginPrompt ref="loginPrompt"></LoginPrompt>
<view class="main"> <view class="main">
<view class="top" :style="{height:iSMT+'px'}"></view> <view class="top" :style="{height:iSMT+'px'}"></view>

198
pages/deepExploration/MainForceActions.vue

@ -93,11 +93,19 @@
import { import {
getUserInfo getUserInfo
} from "@/api/member" } from "@/api/member"
import {
useUserStore
} from '@/stores/modules/userInfo.js'
const deepExplorationStore = useDeepExplorationStore() const deepExplorationStore = useDeepExplorationStore()
const userInfo = getUserInfo()
//
const historyData = ref({}) const historyData = ref({})
//ref
const loginPrompt = ref(null)
// //
const type = ref('deepExploration') const type = ref('deepExploration')
const iSMT = ref(0) const iSMT = ref(0)
@ -182,6 +190,13 @@
// //
const handleModels = async () => { const handleModels = async () => {
try { try {
if (userInfo.isVisitor) {
console.log('是游客');
loginPrompt.value.show()
return
}
console.log('搜了吗');
// markdownContent.value = '\n## 📊 \n\n### 🕵 \n\t1. 📊 360.249 412.577 444.330\n\t2. 🔍 \n\t3. 📈 \n\n### 📊 :\n\t- 📉 : <font color=\"#13c2c2\">443.092</font> \n - 📈 : <font color=\"#ff4d4f\">466.458</font>\n\t- 📉 : <font color=\"#13c2c2\">447.354</font>\n\t- 📈 : <font color=\"#ff4d4f\">462.514</font>\n\t<font color=\"#722ed1\">AI线</font>\n\n### \n\t\t\t<font color=\"#fa8c16\">K线</font>\n\t\t\t<font color=\"#eb2f96\"></font>\n\n---\n<font color=\"#8c8c8c\">*AI*</font>\n ' // markdownContent.value = '\n## 📊 \n\n### 🕵 \n\t1. 📊 360.249 412.577 444.330\n\t2. 🔍 \n\t3. 📈 \n\n### 📊 :\n\t- 📉 : <font color=\"#13c2c2\">443.092</font> \n - 📈 : <font color=\"#ff4d4f\">466.458</font>\n\t- 📉 : <font color=\"#13c2c2\">447.354</font>\n\t- 📈 : <font color=\"#ff4d4f\">462.514</font>\n\t<font color=\"#722ed1\">AI线</font>\n\n### \n\t\t\t<font color=\"#fa8c16\">K线</font>\n\t\t\t<font color=\"#eb2f96\"></font>\n\n---\n<font color=\"#8c8c8c\">*AI*</font>\n '
// htmlContent.value = marked.parse(markdownContent.value); // htmlContent.value = marked.parse(markdownContent.value);
loading.value = true; loading.value = true;
@ -190,94 +205,85 @@
handleDefault() handleDefault()
} else { } else {
if (currentIndex.value == 0) { if (currentIndex.value == 0) {
console.log('搜索', searchName.value);
const result = await getModel1First({
content: searchName.value,
language: "cn",
marketList: "hk,cn,usa,my,sg,vi,in,gb",
model: currentIndex.value + 1
})
console.log('result', result);
if (result.code == 200) {
stockCode.value = result.data.code
// stockName.value = result.data.name
recordId.value = result.data.recordId
parentId.value = result.data.parentId
stockId.value = result.data.stockId
language.value = result.data.language
market.value = result.data.market
const res = await getModel1Second({
language: language.value,
recordId: recordId.value,
parentId: parentId.value,
stockId: stockId.value,
token: 'pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q'
console.log('搜索', searchName.value);
const result = await getModel1First({
content: searchName.value,
language: "cn",
marketList: "hk,cn,usa,my,sg,vi,in,gb",
model: currentIndex.value + 1
}) })
if (res.code == 200) {
const rawMarkdown = res.data.markdown;
const adaptedMarkdown = rawMarkdown.replace(/^### /gm, ''); // ###
markdownContent.value = adaptedMarkdown;
// markdownContent.value = res.data.markdown
console.log('result', result);
if (result.code == 200) {
stockCode.value = result.data.code
// stockName.value = result.data.name
recordId.value = result.data.recordId
parentId.value = result.data.parentId
stockId.value = result.data.stockId
language.value = result.data.language
market.value = result.data.market
const res = await getModel1Second({
language: language.value,
recordId: recordId.value,
parentId: parentId.value,
stockId: stockId.value,
token: 'pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q'
})
if (res.code == 200) {
const rawMarkdown = res.data.markdown;
const adaptedMarkdown = rawMarkdown.replace(/^### /gm, ''); // ###
markdownContent.value = adaptedMarkdown;
// markdownContent.value = res.data.markdown
htmlContent.value = marked.parse(markdownContent.value);
await getServerData()
}
console.log('res', res);
} else if (result.code == 400) {
markdownContent.value = result.message;
htmlContent.value = marked.parse(markdownContent.value); htmlContent.value = marked.parse(markdownContent.value);
} else {
return
} }
console.log('res', res);
await getServerData()
} else if (result.code == 400) {
markdownContent.value = result.message;
htmlContent.value = marked.parse(markdownContent.value);
} else {
return
}
} else if (currentIndex.value == 1) { } else if (currentIndex.value == 1) {
console.log('搜索', searchName.value);
const result = await getModel2First({
content: searchName.value,
language: "cn",
marketList: "hk,cn,usa,my,sg,vi,in,gb",
model: currentIndex.value + 1
})
console.log('result', result);
if (result.code == 200) {
stockCode.value = result.data.code
// stockName.value = result.data.name
recordId.value = result.data.recordId
parentId.value = result.data.parentId
stockId.value = result.data.stockId
language.value = result.data.language
market.value = result.data.market
const res = await getModel2Second({
language: language.value,
recordId: recordId.value,
parentId: parentId.value,
stockId: stockId.value,
token: 'pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q'
console.log('搜索', searchName.value);
const result = await getModel2First({
content: searchName.value,
language: "cn",
marketList: "hk,cn,usa,my,sg,vi,in,gb",
model: currentIndex.value + 1
}) })
if (res.code == 200) {
const rawMarkdown = res.data.markdown;
const adaptedMarkdown = rawMarkdown.replace(/^### /gm, ''); // ###
markdownContent.value = adaptedMarkdown;
// markdownContent.value = res.data.markdown
console.log('result', result);
if (result.code == 200) {
stockCode.value = result.data.code
recordId.value = result.data.recordId
parentId.value = result.data.parentId
stockId.value = result.data.stockId
language.value = result.data.language
market.value = result.data.market
const res = await getModel2Second({
language: language.value,
recordId: recordId.value,
parentId: parentId.value,
stockId: stockId.value,
token: 'pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q'
})
if (res.code == 200) {
const rawMarkdown = res.data.markdown;
const adaptedMarkdown = rawMarkdown.replace(/^### /gm, ''); // ###
markdownContent.value = adaptedMarkdown;
// markdownContent.value = res.data.markdown
htmlContent.value = marked.parse(markdownContent.value);
await getServerData()
}
console.log('res', res);
} else if (result.code == 400) {
markdownContent.value = result.message;
htmlContent.value = marked.parse(markdownContent.value); htmlContent.value = marked.parse(markdownContent.value);
} else {
return
} }
console.log('res', res);
await getServerData()
} else if (result.code == 400) {
markdownContent.value = result.message;
htmlContent.value = marked.parse(markdownContent.value);
} else {
return
}
}else if(currentIndex.value == 2){
} else if (currentIndex.value == 2) {
console.log('搜索', searchName.value); console.log('搜索', searchName.value);
const result = await getModel3First({ const result = await getModel3First({
content: searchName.value, content: searchName.value,
@ -294,8 +300,8 @@
stockId.value = result.data.stockId stockId.value = result.data.stockId
language.value = result.data.language language.value = result.data.language
market.value = result.data.market market.value = result.data.market
const res = await getModel3Second({ const res = await getModel3Second({
language: language.value, language: language.value,
recordId: recordId.value, recordId: recordId.value,
@ -309,19 +315,16 @@
markdownContent.value = adaptedMarkdown; markdownContent.value = adaptedMarkdown;
// markdownContent.value = res.data.markdown // markdownContent.value = res.data.markdown
htmlContent.value = marked.parse(markdownContent.value); htmlContent.value = marked.parse(markdownContent.value);
await getServerData()
} }
console.log('res', res); console.log('res', res);
await getServerData()
} else if (result.code == 400) { } else if (result.code == 400) {
markdownContent.value = result.message; markdownContent.value = result.message;
htmlContent.value = marked.parse(markdownContent.value); htmlContent.value = marked.parse(markdownContent.value);
} else { } else {
return return
} }
}else if(currentIndex.value == 3){
} else if (currentIndex.value == 3) {
console.log('搜索', searchName.value); console.log('搜索', searchName.value);
const result = await getModel4First({ const result = await getModel4First({
content: searchName.value, content: searchName.value,
@ -338,8 +341,6 @@
stockId.value = result.data.stockId stockId.value = result.data.stockId
language.value = result.data.language language.value = result.data.language
market.value = result.data.market market.value = result.data.market
const res = await getModel4Second({ const res = await getModel4Second({
language: language.value, language: language.value,
recordId: recordId.value, recordId: recordId.value,
@ -353,27 +354,19 @@
markdownContent.value = adaptedMarkdown; markdownContent.value = adaptedMarkdown;
// markdownContent.value = res.data.markdown // markdownContent.value = res.data.markdown
htmlContent.value = marked.parse(markdownContent.value); htmlContent.value = marked.parse(markdownContent.value);
await getServerData()
} }
console.log('res', res); console.log('res', res);
await getServerData()
} else if (result.code == 400) { } else if (result.code == 400) {
markdownContent.value = result.message; markdownContent.value = result.message;
htmlContent.value = marked.parse(markdownContent.value); htmlContent.value = marked.parse(markdownContent.value);
} else { } else {
return return
} }
}else{
} else {
return return
} }
} }
} catch (e) { } catch (e) {
error.value = e.message || '加载失败,请重试'; error.value = e.message || '加载失败,请重试';
} finally { } finally {
@ -406,7 +399,7 @@
const getServerData = async () => { const getServerData = async () => {
const result = await getData({ const result = await getData({
market: market.value || '', market: market.value || '',
code: searchName.value || '',
code: stockCode.value || '',
language: "cn", language: "cn",
brainPrivilegeState: 1, brainPrivilegeState: 1,
marketList: "usa.sg.my.hk.cn.can.vi.th.in.gb" marketList: "usa.sg.my.hk.cn.can.vi.th.in.gb"
@ -732,13 +725,14 @@
} }
.right { .right {
margin-left: 60rpx;
margin-left: 50rpx;
color: #6a6a6a; color: #6a6a6a;
font-family: "PingFang SC"; font-family: "PingFang SC";
font-size: 13px; font-size: 13px;
font-style: normal; font-style: normal;
font-weight: 400; font-weight: 400;
line-height: 15px; line-height: 15px;
white-space: nowrap;
} }
} }

186
pages/deepMate/deepMate.vue

@ -129,13 +129,24 @@
" "
> >
<!-- 会话图标 --> <!-- 会话图标 -->
<text
<!-- <text
:class=" :class="
message.isUser message.isUser
? 'fa-solid fa-user message-icon' ? 'fa-solid fa-user message-icon'
: 'fa-solid fa-robot message-icon' : 'fa-solid fa-robot message-icon'
" "
></text>
></text> -->
<image
v-if="message.isUser"
class="message-icon"
:src="userAvatar"
mode="scaleToFill"
/><image
v-else
class="message-icon"
src="/static/icons/robot.svg"
mode="scaleToFill"
/>
<!-- 会话内容 --> <!-- 会话内容 -->
<view class="message-content"> <view class="message-content">
<!-- <text class="message-text">{{ message.content }}</text> --> <!-- <text class="message-text">{{ message.content }}</text> -->
@ -265,8 +276,11 @@
> >
<view class="history-left"> <view class="history-left">
<view class="flag-circle" <view class="flag-circle"
><text class="flag-emoji">🇺🇸</text></view
>
><image
class="icon-stock"
:src="stockImage(item.stockMarket)"
mode="scaleToFill"
/></view>
</view> </view>
<view class="history-main" @click="itemClick(item)"> <view class="history-main" @click="itemClick(item)">
<text class="history-query">{{ item.stockName }}</text> <text class="history-query">{{ item.stockName }}</text>
@ -299,6 +313,8 @@ import {
postHistoryDetail, postHistoryDetail,
} from "../../api/deepMate/deepMate"; } from "../../api/deepMate/deepMate";
import { useUserStore } from "../../stores/modules/userInfo";
const renderer = new marked.Renderer(); const renderer = new marked.Renderer();
renderer.heading = function (text, level) { renderer.heading = function (text, level) {
return `<p>${text}</p>`; return `<p>${text}</p>`;
@ -335,41 +351,18 @@ const drawerOffsetY = ref(0);
const searchHistory = ref([]); const searchHistory = ref([]);
const historyList = ref([]); const historyList = ref([]);
const hotTopics = ref([
{
id: 1,
text: "英伟达(NVDA)股票情绪温度?",
icon: "https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg",
},
{
id: 2,
text: "博通(AVGO)明天还能涨吗?",
icon: "https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg",
},
{
id: 3,
text: "为什么Fluence Energy(FLNC)会暴涨?",
icon: "https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg",
},
{
id: 4,
text: "为什么Fluence Energy(FLNC)会暴涨?",
icon: "https://d31zlh4on95l9h.cloudfront.net/images/7ed58be0f4b81aeb398d9ba2534a624b.svg",
},
]);
// //
onLoad((options) => { onLoad((options) => {
console.log('deepMate页面接收到参数:', options);
console.log("deepMate页面接收到参数:", options);
// query // query
if (options.query) { if (options.query) {
const decodedQuery = decodeURIComponent(options.query); const decodedQuery = decodeURIComponent(options.query);
console.log('解码后的查询内容:', decodedQuery);
console.log("解码后的查询内容:", decodedQuery);
// //
inputMessage.value = decodedQuery; inputMessage.value = decodedQuery;
// //
setTimeout(() => { setTimeout(() => {
sendMessage(); sendMessage();
@ -526,6 +519,12 @@ const formatTimeForHistory = (timeString) => {
return timeString; return timeString;
}; };
const userStore = useUserStore();
//
const userAvatar = computed(() => {
return userStore.userInfo.avatar;
});
// /// // ///
const groupedHistory = computed(() => { const groupedHistory = computed(() => {
const sections = []; const sections = [];
@ -656,9 +655,8 @@ const simulateBotResponse = async (userMessage) => {
"pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q", "pCtw6AYK0EHAaIexoFHsbZjtsfEAIhcmwkCFm6uKko8VPfMvyDiODL9v9c0veic9fIpQbvT8zN4sH/Si6Q",
}); });
} catch (error) { } catch (error) {
} finally {
isSending.value = false; isSending.value = false;
} finally {
} }
console.log("res" + res); console.log("res" + res);
@ -679,26 +677,48 @@ const simulateBotResponse = async (userMessage) => {
const typeWriter = () => { const typeWriter = () => {
if (index < responseText.length) { if (index < responseText.length) {
const ch = responseText.charAt(index);
let ch = responseText.charAt(index);
let charsToAdd = ch;
let newIndex = index + 1;
// HTML
if (ch === '<') {
//
let tagEndIndex = responseText.indexOf('>', index);
if (tagEndIndex !== -1) {
//
charsToAdd = responseText.substring(index, tagEndIndex + 1);
newIndex = tagEndIndex + 1;
}
}
const current = messages.value[botIndex]; const current = messages.value[botIndex];
// //
messages.value.splice(botIndex, 1, { messages.value.splice(botIndex, 1, {
...current, ...current,
content: current.content + ch,
content: current.content + charsToAdd,
isTyping: true, isTyping: true,
}); });
index++;
index = newIndex;
scrollToBottom(); scrollToBottom();
// //
const baseDelay = 5; // const baseDelay = 5; //
const slowPunct = /[。!?!?;;]/; // const slowPunct = /[。!?!?;;]/; //
const midPunct = /[,、,::]/; // const midPunct = /[,、,::]/; //
const delay = slowPunct.test(ch)
? 220
: midPunct.test(ch)
? 120
: baseDelay;
// 使
let delay;
if (charsToAdd.startsWith('<')) {
delay = 1; //
} else {
delay = slowPunct.test(ch)
? 220
: midPunct.test(ch)
? 120
: baseDelay;
}
setTimeout(typeWriter, delay); setTimeout(typeWriter, delay);
} else { } else {
// //
@ -768,7 +788,9 @@ const simulateBotResponse = async (userMessage) => {
messages.value[messages.value.length - 1].isSecond = true; messages.value[messages.value.length - 1].isSecond = true;
messages.value[messages.value.length - 1].isThinking = false;
setTimeout(() => {
messages.value[messages.value.length - 1].isThinking = false;
}, 500);
// //
nextTick(() => { nextTick(() => {
@ -780,28 +802,39 @@ const simulateBotResponse = async (userMessage) => {
let index = 0; let index = 0;
const botIndex = messages.value.length - 1; const botIndex = messages.value.length - 1;
const baseDelay = 165; //
const baseDelay = 5; //
const slowPunct = /[。!?!?;;]/; // const slowPunct = /[。!?!?;;]/; //
const midPunct = /[,、,::]/; // const midPunct = /[,、,::]/; //
const typeWriter = () => { const typeWriter = () => {
if (index < responseText.length) { if (index < responseText.length) {
const ch = responseText.charAt(index);
let ch = responseText.charAt(index);
let charsToAdd = ch;
let newIndex = index + 1;
let delay = baseDelay;
// HTML
if (ch === '<') {
//
let tagEndIndex = responseText.indexOf('>', index);
if (tagEndIndex !== -1) {
//
charsToAdd = responseText.substring(index, tagEndIndex + 1);
newIndex = tagEndIndex + 1;
delay = 1; //
}
}
const current = messages.value[botIndex]; const current = messages.value[botIndex];
// //
messages.value.splice(botIndex, 1, { messages.value.splice(botIndex, 1, {
...current, ...current,
content: current.content + ch,
content: current.content + charsToAdd,
isTyping: true, isTyping: true,
}); });
index++;
index = newIndex;
scrollToBottom(); scrollToBottom();
const delay = slowPunct.test(ch)
? 220
: midPunct.test(ch)
? 120
: baseDelay;
setTimeout(typeWriter, delay); setTimeout(typeWriter, delay);
} else { } else {
const current = messages.value[botIndex]; const current = messages.value[botIndex];
@ -949,6 +982,28 @@ const onBackTopClick = () => {
scrollToTop(); scrollToTop();
}; };
//
function stockImage(Market) {
switch (Market) {
case "usa":
return "../../static/marketSituation-image/country-flag/us.png";
case "can":
return "../../static/marketSituation-image/country-flag/can.png";
case "vi":
return "../../static/marketSituation-image/country-flag/vi.png";
case "th":
return "../../static/marketSituation-image/country-flag/th.png";
case "my":
return "../../static/marketSituation-image/country-flag/my.png";
case "sg":
return "../../static/marketSituation-image/country-flag/sg.png";
case "hk":
return "../../static/marketSituation-image/country-flag/hk.png";
case "cn":
return "../../static/marketSituation-image/country-flag/cn.png";
}
}
// //
async function itemClick(item) { async function itemClick(item) {
const res = await postHistoryDetail({ const res = await postHistoryDetail({
@ -1269,25 +1324,25 @@ async function itemClick(item) {
.message-icon { .message-icon {
font-size: 24rpx; font-size: 24rpx;
margin: 0 10rpx; margin: 0 10rpx;
padding: 10rpx;
/* padding: 10rpx; */
border-radius: 50%; border-radius: 50%;
background-color: #ddd; background-color: #ddd;
width: 40rpx;
height: 40rpx;
width: 60rpx;
height: 60rpx;
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
} }
.user-message .message-icon { .user-message .message-icon {
background-color: #007aff;
/* background-color: #007aff; */
border-radius: 50%; border-radius: 50%;
color: #fff; color: #fff;
/* box-shadow: 0 0 12rpx rgba(0, 122, 255, 0.4); */ /* box-shadow: 0 0 12rpx rgba(0, 122, 255, 0.4); */
} }
.bot-message .message-icon { .bot-message .message-icon {
background: url("/static/images/robot (1).svg");
/* background: url("/static/images/robot (1).svg"); */
color: white; color: white;
} }
@ -1643,6 +1698,11 @@ async function itemClick(item) {
margin-right: 12rpx; margin-right: 12rpx;
} }
.icon-stock {
width: 36rpx;
height: 36rpx;
}
.flag-circle { .flag-circle {
width: 36rpx; width: 36rpx;
height: 36rpx; height: 36rpx;
@ -1742,9 +1802,21 @@ async function itemClick(item) {
} }
.thinking-content { .thinking-content {
transition: transform 1s ease; /* 添加过渡效果 */
transform-origin: top center; /* 设置变换原点 */
padding: 20rpx 30rpx; padding: 20rpx 30rpx;
} }
@keyframes transform {
from {
transform: scaleY(0);
}
to {
transform: scaleY(1);
}
}
.thinking-item { .thinking-item {
display: flex; display: flex;
align-items: center; align-items: center;

18
pages/home/home.vue

@ -6,11 +6,11 @@
<LoginPrompt ref="loginPrompt"></LoginPrompt> <LoginPrompt ref="loginPrompt"></LoginPrompt>
<!-- 头部导航 --> <!-- 头部导航 -->
<view class="header"> <view class="header">
<view class="headphone-icon">
<view class="headphone-icon" @click="goToCustomerService">
<image src="https://d31zlh4on95l9h.cloudfront.net/images/bef2edba6cc0c85671fde07cfab5270d.png" class="header-icon-image"></image> <image src="https://d31zlh4on95l9h.cloudfront.net/images/bef2edba6cc0c85671fde07cfab5270d.png" class="header-icon-image"></image>
</view> </view>
<view class="title">DeepChart</view> <view class="title">DeepChart</view>
<view class="notification-icon">
<view class="notification-icon" @click="goToNotificationCenter">
<image src="https://d31zlh4on95l9h.cloudfront.net/images/2554c84b91712d2a6cb6b00380e63bac.png" class="header-icon-image"></image> <image src="https://d31zlh4on95l9h.cloudfront.net/images/2554c84b91712d2a6cb6b00380e63bac.png" class="header-icon-image"></image>
</view> </view>
</view> </view>
@ -430,6 +430,20 @@ export default {
}, },
methods: { methods: {
//
goToCustomerService() {
uni.navigateTo({
url: '/pages/customerServicePlatform/csPlatformIndex'
})
},
//
goToNotificationCenter() {
uni.navigateTo({
url: '/pages/blank/notice'
})
},
// //
goToCustomStockList() { goToCustomStockList() {
uni.navigateTo({ uni.navigateTo({

6
pages/setting/about.vue

@ -4,7 +4,7 @@
<view style="height:1.5vh" /> <view style="height:1.5vh" />
<view class="top"> <view class="top">
<image src="/static/my/aboutDC.png"></image>
<image class="img" src="/static/my/aboutDC.png"></image>
</view> </view>
<view class="bottom"> <view class="bottom">
@ -83,4 +83,8 @@
.label{ .label{
flex:1; flex:1;
} }
.img{
width:360rpx;
height:300rpx;
}
</style> </style>

4
pages/start/Registration/Registration.vue

@ -326,7 +326,7 @@ function changeAccount() {
} }
if (switchType.value === "Phone") { if (switchType.value === "Phone") {
account.value = `${country.value}${phone.value}`;
account.value = `${country.value}-${phone.value}`;
} }
if (switchType.value === "Email") { if (switchType.value === "Email") {
account.value = email.value; account.value = email.value;
@ -511,7 +511,7 @@ async function sendCode() {
if (switchType.value === "Phone") { if (switchType.value === "Phone") {
// //
const phoneAll = `${country.value}${phone.value}`;
const phoneAll = `${country.value}-${phone.value}`;
const res = await SendPhoneCodeApi({ const res = await SendPhoneCodeApi({
phone: phoneAll, phone: phoneAll,
}); });

4
pages/start/login/login.vue

@ -536,7 +536,7 @@ function changeAccount() {
} }
if (switchType.value === "Phone") { if (switchType.value === "Phone") {
account.value = `${country.value}${phone.value}`;
account.value = `${country.value}-${phone.value}`;
} }
if (switchType.value === "Email") { if (switchType.value === "Email") {
account.value = email.value; account.value = email.value;
@ -652,7 +652,7 @@ async function sendCode() {
if (switchType.value === "Phone") { if (switchType.value === "Phone") {
// //
const phoneAll = `${country.value}${phone.value}`;
const phoneAll = `${country.value}-${phone.value}`;
const res = await SendPhoneCodeApi({ const res = await SendPhoneCodeApi({
phone: phoneAll, phone: phoneAll,
}); });

4
pages/start/recoverPassword/recoverPassword.vue

@ -451,7 +451,7 @@ function changeAccount() {
} }
if (switchType.value === "Phone") { if (switchType.value === "Phone") {
account.value = `${country.value}${phone.value}`;
account.value = `${country.value}-${phone.value}`;
} }
if (switchType.value === "Email") { if (switchType.value === "Email") {
account.value = email.value; account.value = email.value;
@ -570,7 +570,7 @@ function sendCode() {
} }
} }
if (switchType.value === "Phone") { if (switchType.value === "Phone") {
const phoneAll = `${country.value}${phone.value}`;
const phoneAll = `${country.value}-${phone.value}`;
const res = SendPhoneCodeApi({ const res = SendPhoneCodeApi({
phone: phoneAll, phone: phoneAll,

Loading…
Cancel
Save