Browse Source

Merge branch 'milestone-20251031-简版功能开发' of http://39.101.133.168:8807/qimaohong/deepChartVueApp into hongxilin/feature-20251023103318-行情数据及页面

lihuilin/feature-20251024095243-我的
hongxilin 3 weeks ago
parent
commit
9d4682267c
  1. 4
      .hbuilderx/launch.json
  2. 2
      api/tcpConnection.js
  3. 7
      package.json
  4. 3
      pages.json
  5. 107
      pages/customStockList/customStockList.vue
  6. 17
      pages/deepExploration/MainForceActions.vue
  7. 43
      pages/deepExploration/deepExploration.vue
  8. 46
      pages/deepExploration/stockSelectDetail.vue
  9. 16
      pages/deepMate/deepMate.vue
  10. 25
      pages/home/home.vue
  11. BIN
      static/deepExploration-images/1.png
  12. BIN
      static/deepExploration-images/2.png
  13. BIN
      static/deepExploration-images/3.png
  14. BIN
      static/deepExploration-images/4.png
  15. BIN
      static/deepExploration-images/history.png
  16. BIN
      static/deepExploration-images/icon1.png
  17. BIN
      static/deepExploration-images/icon2.png
  18. BIN
      static/deepExploration-images/icon3.png
  19. BIN
      static/deepExploration-images/icon4.png
  20. BIN
      static/deepExploration-images/kLineAll.png
  21. BIN
      static/deepExploration-images/notice.png
  22. BIN
      static/deepExploration-images/search.png
  23. BIN
      static/images/welcomeRobot@2x.png
  24. 22
      utils/http.js

4
.hbuilderx/launch.json

@ -2,9 +2,9 @@
"version" : "1.0",
"configurations" : [
{
"customPlaygroundType" : "local",
"customPlaygroundType" : "device",
"packageName" : "io.dcloud.HBuilder",
"playground" : "custom",
"playground" : "standard",
"type" : "uni-app:app-android"
}
]

2
api/tcpConnection.js

@ -6,7 +6,7 @@
*/
// 引用TCP插件
const TCPSocket = uni.requireNativePlugin('Aimer-TCPPlugin');
// const TCPSocket = uni.requireNativePlugin('Aimer-TCPPlugin');
// const TCPSocket = uni.requireNativePlugin("Aimer-TCPPlugin");
// TCP连接配置

7
package.json

@ -1,4 +1,8 @@
{
"scripts": {
"dev:h5": "cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" uni build --watch",
"build:h5": "cross-env NODE_OPTIONS=\"--max-old-space-size=4096\" uni build"
},
"dependencies": {
"@dcloudio/uni-ui": "^1.5.11",
"@element-plus/icons-vue": "^2.3.2",
@ -8,5 +12,8 @@
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.5.0",
"vue-i18n": "^9.14.5"
},
"devDependencies": {
"cross-env": "^7.0.3"
}
}

3
pages.json

@ -295,7 +295,8 @@
"navigationStyle": "custom",
"disableSwipeBack": true,
"titleNView": false,
"bounce": false
"bounce": false,
"pageOrientation": "auto"
}
},
{

107
pages/customStockList/customStockList.vue

@ -103,6 +103,13 @@
</view>
<view class="toolbar-right">
<button
class="delete-btn"
:disabled="selectedStockIds.length === 0"
@click="deleteSelectedStocks"
>
删除
</button>
<button
class="add-to-group-btn"
:disabled="selectedStockIds.length === 0"
@click="showGroupSelectModal = true"
@ -143,7 +150,7 @@
</template>
<script>
import { getUserStockGroupList, addUserStockGroup, getUserStockList, updateUserStockGroup } from '@/api/home/mySelections.js'
import { getUserStockGroupList, addUserStockGroup, getUserStockList, updateUserStockGroup, deleteUserStock } from '@/api/home/mySelections.js'
export default {
data() {
@ -484,7 +491,7 @@
this.selectedStockIds = []
//
this.loadStockList()
this.loadStocksByGroup(this.currentGroupId)
} catch (error) {
console.error('移动股票失败:', error)
@ -495,6 +502,69 @@
} finally {
uni.hideLoading()
}
},
//
async deleteSelectedStocks() {
//
if (this.selectedStockIds.length === 0) {
uni.showToast({
title: '请先选择要删除的股票',
icon: 'none'
})
return
}
//
uni.showModal({
title: '确认删除',
content: `确定要删除选中的 ${this.selectedStockIds.length} 只股票吗?`,
success: async (res) => {
if (res.confirm) {
await this.performDeleteStocks()
}
}
})
},
//
async performDeleteStocks() {
try {
uni.showLoading({
title: '删除中...'
})
// API
const deletePromises = this.selectedStockIds.map(stockId => {
return deleteUserStock(null, null, {
groupId: this.currentGroupId,
id: stockId
})
})
await Promise.all(deletePromises)
uni.showToast({
title: '删除成功',
icon: 'success'
})
// 退
this.isMultiSelectMode = false
this.selectedStockIds = []
//
this.loadStocksByGroup(this.currentGroupId)
} catch (error) {
console.error('删除股票失败:', error)
uni.showToast({
title: '删除失败,请重试',
icon: 'none'
})
} finally {
uni.hideLoading()
}
}
}
}
@ -599,21 +669,29 @@
flex-shrink: 0;
padding: 8px 16px;
margin-right: 10px;
border-radius: 4px;
background-color: #ff3b30;
border-radius: 20px;
background-color: #f5f5f5;
border: 1px solid #e0e0e0;
transition: all 0.3s ease;
cursor: pointer;
}
.tab-item:hover {
background-color: #e8e8e8;
}
.tab-item.active {
background-color: #ff3b30;
opacity: 1;
border-color: #ff3b30;
box-shadow: 0 2px 8px rgba(255, 59, 48, 0.3);
}
.tab-text {
font-size: 14px;
color: #ffffff;
color: #666666;
white-space: nowrap;
font-weight: 500;
font-weight: 400;
transition: all 0.3s ease;
}
.tab-item.active .tab-text {
@ -774,6 +852,21 @@
.toolbar-right {
display: flex;
align-items: center;
gap: 12px;
}
.delete-btn {
background-color: #ff6b6b;
color: #fff;
border: none;
border-radius: 6px;
padding: 8px 16px;
font-size: 14px;
}
.delete-btn:disabled {
background-color: #ccc;
color: #999;
}
.add-to-group-btn {

17
pages/deepExploration/MainForceActions.vue

@ -7,7 +7,7 @@
<view class="search">
<input v-model="searchName" class="searchInput" type="text" placeholder="请输入股票名称、股票代码"
placeholder-style="color: #A6A6A6; font-size: 22rpx;" />
placeholder-style="color: #A6A6A6; font-size: 28rpx;" />
<image @click="searchStock" class="seachIcon" src="/static/deepExploration-images/search.png"
mode="aspectFill"></image>
</view>
@ -41,6 +41,7 @@
<qiun-data-charts type="candle" :opts="opts" :chartData="chartData" :disableScroll="true"
:ontouch="true" :onzoom="true" :key="chartKey" />
</view>
<image src="/static/deepExploration-images/kLineAll.png" mode="aspectFill"></image>
</view>
</view>
<view class="txt">
@ -549,7 +550,6 @@
onMounted(async () => {
iSMT.value = uni.getSystemInfoSync().statusBarHeight
getUserInfo()
await getServerData() //
await handleModels()
unwatch = watch(
@ -635,6 +635,7 @@
.searchInput {
color: #111;
width: 100%;
}
}
@ -767,8 +768,17 @@
}
.graph_content {
position: relative;
min-height: 500rpx;
image{
position: absolute;
bottom: 20rpx;
right: 30rpx;
width: 48rpx;
height: 48rpx;
}
.charts-box {
width: 100%;
height: 100%;
@ -791,9 +801,10 @@
}
text {
margin-left: 5rpx;
background-color: #FFFFFF;
color: #000000;
padding: 0 22rpx;
padding: 5rpx 22rpx;
border-radius: 22rpx;
font-size: 28rpx;
font-weight: 400;

43
pages/deepExploration/deepExploration.vue

@ -15,7 +15,7 @@
<!-- 四大功能模块 -->
<view class="select">
<view class="selectItem" @click="toMain('主力追踪')">
<image class="img" src="/static/deepExploration-images/icon3.png" mode="aspectFill"></image>
<image class="img" src="/static/deepExploration-images/icon1.png" mode="aspectFill"></image>
<view class="txt">主力追踪</view>
</view>
<view class="selectItem" @click="toMain('主力雷达')">
@ -23,7 +23,7 @@
<view class="txt">主力雷达</view>
</view>
<view class="selectItem" @click="toMain('主力解码')">
<image class="img" src="/static/deepExploration-images/icon1.png" mode="aspectFill"></image>
<image class="img" src="/static/deepExploration-images/icon3.png" mode="aspectFill"></image>
<view class="txt">主力解码</view>
</view>
<view class="selectItem" @click="toMain('主力资金流')">
@ -46,14 +46,20 @@
</view>
<view class="stockSelection_content">
<view class="selectionItem" @click="viewAll">
<view class="selectionItem">
<view class="header">
<view class="left">
<image src="/static/deepExploration-images/plus.png" mode="aspectFill"></image>
<image
src="/static/deepExploration-images/plus.png"
mode="aspectFill"
></image>
<text>抄底卖顶</text>
</view>
<view class="right">
<image src="/static/deepExploration-images/Americle.png" mode="aspectFill"></image>
<image
src="/static/deepExploration-images/Americle.png"
mode="aspectFill"
></image>
<text>美股</text>
</view>
</view>
@ -65,7 +71,7 @@
</view>
<view class="contentItem">
<view class="row" v-for="(item, index) in stockData" :key="index">
<view class="nameItem">{{ item.tscode }}</view>
<view class="nameItem">{{ item.tscode }}{{ item.stockName }}</view>
<view class="closeItem">{{ item.close }}</view>
<view class="priceItem">{{ item.preClose }}</view>
</view>
@ -75,14 +81,20 @@
</view>
<view class="stockSelection_content">
<view class="selectionItem" @click="viewAll">
<view class="selectionItem">
<view class="header">
<view class="left">
<image src="/static/deepExploration-images/plus.png" mode="aspectFill"></image>
<image
src="/static/deepExploration-images/plus.png"
mode="aspectFill"
></image>
<text>波段行情</text>
</view>
<view class="right">
<image src="/static/deepExploration-images/Americle.png" mode="aspectFill"></image>
<image
src="/static/deepExploration-images/Americle.png"
mode="aspectFill"
></image>
<text>美股</text>
</view>
</view>
@ -94,7 +106,7 @@
</view>
<view class="contentItem">
<view class="row" v-for="(item, index) in stockDataByName" :key="index">
<view class="nameItem">{{ item.tscode }}</view>
<view class="nameItem">{{ item.tscode }}{{ item.stockName }}</view>
<view class="closeItem">{{ item.close }}</view>
<view class="priceItem">{{ item.preClose }}</view>
</view>
@ -207,6 +219,7 @@
if (Array.isArray(list) && list.length) {
const mapped = list.map(item => ({
tscode: item.tsCode ?? item.tscode ?? item.code ?? '',
stockName: item.stockName ?? item.name ?? '',
close: item.close ?? item.lastClose ?? '',
preClose: item.preClose ?? item.preclose ?? item.prevClose ?? ''
}))
@ -248,6 +261,7 @@
if (Array.isArray(list) && list.length) {
const mapped = list.map(item => ({
tscode: item.tsCode ?? item.tscode ?? item.code ?? '',
stockName: item.stockName ?? item.name ?? '',
close: item.close ?? item.lastClose ?? '',
preClose: item.preClose ?? item.preclose ?? item.prevClose ?? ''
}))
@ -363,17 +377,18 @@
}
.viewAll {
display: flex;
align-items: center;
justify-content: center;
background-color: #000000;
border-radius: 10rpx;
padding: 6rpx 20rpx;
padding: 10rpx 20rpx;
color: #ffffff;
font-family: "PingFang SC";
font-size: 24rpx;
font-style: normal;
font-weight: 100;
font-weight: 500;
line-height: 29rpx;
height: 40rpx;
width: 140rpx;
}
}

46
pages/deepExploration/stockSelectDetail.vue

@ -156,19 +156,22 @@
if (Array.isArray(list)) list = sortByPctDesc(list)
if (Array.isArray(list) && list.length) {
strategyData.value = list.map(item => ({
name: item.tsCode ?? item.tscode ?? '',
stockCode: item.tsCode ?? item.tscode ?? '',
latest: item.close ?? '',
name: item.stockName ?? item.name ?? item.tsName ?? item.tsname ?? item.secName ?? '',
stockCode: item.tsCode ?? item.tscode ?? item.code ?? item.symbol ?? '',
latest: item.close ?? item.lastClose ?? '',
increase: formatPctChg(item.pctChg),
decrease: item.change ?? '',
previousClose: item.preClose ?? item.preclose ?? '',
volume: item.vol ?? '',
turnover: item.amount ?? '',
openingPrice: item.open ?? '',
highestPrice: item.high ?? '',
lowestPrice: item.low ?? ''
decrease: item.change ?? item.chg ?? '',
previousClose: item.preClose ?? item.preclose ?? item.prevClose ?? '',
volume: item.vol ?? item.volume ?? '',
turnover: item.amount ?? item.turnover ?? '',
openingPrice: item.open ?? item.openPrice ?? '',
highestPrice: item.high ?? item.highPrice ?? '',
lowestPrice: item.low ?? item.lowPrice ?? ''
}))
console.log(`按名称(${apiName})加载成功,条数:`, strategyData.value.length, '首项:', strategyData.value[0])
if (!strategyData.value[0]?.name) {
console.warn('名称字段未命中,原始keys示例:', Object.keys(list[0] || {}))
}
} else {
console.warn('getStrategyByName 返回空列表或结构不匹配', raw)
}
@ -203,19 +206,22 @@
if (Array.isArray(list)) list = sortByPctDesc(list)
if (Array.isArray(list) && list.length) {
strategyData.value = list.map(item => ({
name: item.tsCode ?? item.tscode ?? '',
stockCode: item.tsCode ?? item.tscode ?? '',
latest: item.close ?? '',
name: item.stockName ?? item.name ?? item.tsName ?? item.tsname ?? item.secName ?? '',
stockCode: item.tsCode ?? item.tscode ?? item.code ?? item.symbol ?? '',
latest: item.close ?? item.lastClose ?? '',
increase: formatPctChg(item.pctChg),
decrease: item.change ?? '',
previousClose: item.preClose ?? item.preclose ?? '',
volume: item.vol ?? '',
turnover: item.amount ?? '',
openingPrice: item.open ?? '',
highestPrice: item.high ?? '',
lowestPrice: item.low ?? ''
decrease: item.change ?? item.chg ?? '',
previousClose: item.preClose ?? item.preclose ?? item.prevClose ?? '',
volume: item.vol ?? item.volume ?? '',
turnover: item.amount ?? item.turnover ?? '',
openingPrice: item.open ?? item.openPrice ?? '',
highestPrice: item.high ?? item.highPrice ?? '',
lowestPrice: item.low ?? item.lowPrice ?? ''
}))
console.log('stockSelectDetail 加载成功(已按涨幅降序),条数:', strategyData.value.length, '首项:', strategyData.value[0])
if (!strategyData.value[0]?.name) {
console.warn('名称字段未命中,原始keys示例:', Object.keys(list[0] || {}))
}
} else {
console.warn('stockSelectDetail 接口返回空列表或结构不匹配', raw)
}

16
pages/deepMate/deepMate.vue

@ -1226,23 +1226,23 @@ async function itemClick(item) {
/* min-height: 20rpx; */
/* border-radius: 20rpx; */
padding: 40rpx;
margin-top: 20rpx;
margin-top: 10rpx;
margin-bottom: 10rpx;
/* box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); */
}
.welcome-section {
/* 灰色卡片(recommend-card)之后展示背景图 */
margin-top: 2rem;
margin-top: 40rpx;
display: flex;
align-items: center;
justify-content: center;
background: url("https://d31zlh4on95l9h.cloudfront.net/images/eca84d9fb54712cb3bc6c6174773b83b.svg");
background: url("/static/images/welcomeRobot@2x.png");
background-repeat: no-repeat;
background-position: center top;
/* 放在容器顶部,正好在灰色卡片下方 */
background-size: 80% auto;
/* 缩放以适配宽度 */
background-position: center center;
/* 居中显示,避免顶部被裁剪 */
background-size: contain;
/* 保证整张图片完整展示 */
height: 460rpx;
/* 提供可视高度,让背景图可见 */
}
@ -1558,7 +1558,7 @@ async function itemClick(item) {
inset: 0;
/* 顶部、底部、左、右都贴合容器 */
width: 100%;
height: 81%;
height: 83%;
border-radius: 15rpx;
z-index: 1;
/* 在灰底之上、内容之下 */

25
pages/home/home.vue

@ -55,19 +55,19 @@
<!-- 下部分四个图标 -->
<view class="exploration-container">
<view class="exploration-content">
<view class="exploration-item">
<view class="exploration-item" @click="goToMainForceActions(1)">
<image class="exploration-icon" src="https://d31zlh4on95l9h.cloudfront.net/images/199472b0ee90a1c897f7c87b85accd84.png" mode="aspectFit" lazy-load="true"></image>
<text class="exploration-text">主力追踪</text>
</view>
<view class="exploration-item">
<view class="exploration-item" @click="goToMainForceActions(2)">
<image class="exploration-icon" src="https://d31zlh4on95l9h.cloudfront.net/images/c25ca5e176efc961dabfa5d0d1b486b0.png" mode="aspectFit" lazy-load="true"></image>
<text class="exploration-text">主力雷达</text>
</view>
<view class="exploration-item">
<view class="exploration-item" @click="goToMainForceActions(3)">
<image class="exploration-icon" src="https://d31zlh4on95l9h.cloudfront.net/images/c064d7066dc8129a7df7b052762f82cf.png" mode="aspectFit" lazy-load="true"></image>
<text class="exploration-text">主力解码</text>
</view>
<view class="exploration-item">
<view class="exploration-item" @click="goToMainForceActions(4)">
<image class="exploration-icon" src="https://d31zlh4on95l9h.cloudfront.net/images/9d69cceee9c515911477078af6f68d88.png" mode="aspectFit" lazy-load="true"></image>
<text class="exploration-text">主力资金流</text>
</view>
@ -223,11 +223,11 @@ export default {
//
swiperImages: [
'https://d31zlh4on95l9h.cloudfront.net/images/44ec37501cf3ecf5438d401c3d66fcd3.png',
'https://d31zlh4on95l9h.cloudfront.net/images/80274b6626bb403d717469b3672333c9.png',
'https://d31zlh4on95l9h.cloudfront.net/images/14481c76b09509977d3879ba3141ebc7.png',
'https://d31zlh4on95l9h.cloudfront.net/images/19e4c5542e5f974e1c6938897aa20ef9.png',
'https://d31zlh4on95l9h.cloudfront.net/images/d0bc1c1bb71917132865b82dab99831b.png'
'https://d31zlh4on95l9h.cloudfront.net/images/893a55bc0de424a1c9abf9f0d3eb2bb0.png',
'https://d31zlh4on95l9h.cloudfront.net/images/35b413c98b2f3b6f67f99beb29dc9017.png',
'https://d31zlh4on95l9h.cloudfront.net/images/413bd37201f13e04bb491f285b553d03.png',
'https://d31zlh4on95l9h.cloudfront.net/images/f3dde163daa842ff5818d521ce674c16.png',
'https://d31zlh4on95l9h.cloudfront.net/images/b1dae32cf36055c1c626df1eea29e6b6.png'
],
//
@ -482,6 +482,13 @@ export default {
})
},
//
goToMainForceActions(index) {
uni.navigateTo({
url: `/pages/deepExploration/MainForceActions?index=${index}`
})
},
//
handleVisitorLoginSuccess(data) {
console.log('收到游客登录成功事件:', data)

BIN
static/deepExploration-images/1.png

Before

Width: 750  |  Height: 198  |  Size: 35 KiB

After

Width: 750  |  Height: 198  |  Size: 36 KiB

BIN
static/deepExploration-images/2.png

Before

Width: 750  |  Height: 198  |  Size: 36 KiB

After

Width: 750  |  Height: 198  |  Size: 38 KiB

BIN
static/deepExploration-images/3.png

Before

Width: 750  |  Height: 198  |  Size: 37 KiB

After

Width: 750  |  Height: 198  |  Size: 38 KiB

BIN
static/deepExploration-images/4.png

Before

Width: 750  |  Height: 198  |  Size: 35 KiB

After

Width: 750  |  Height: 198  |  Size: 35 KiB

BIN
static/deepExploration-images/history.png

Before

Width: 16  |  Height: 15  |  Size: 797 B

After

Width: 32  |  Height: 30  |  Size: 2.3 KiB

BIN
static/deepExploration-images/icon1.png

Before

Width: 40  |  Height: 40  |  Size: 1.9 KiB

After

Width: 80  |  Height: 80  |  Size: 3.9 KiB

BIN
static/deepExploration-images/icon2.png

Before

Width: 40  |  Height: 40  |  Size: 2.6 KiB

After

Width: 80  |  Height: 80  |  Size: 6.9 KiB

BIN
static/deepExploration-images/icon3.png

Before

Width: 40  |  Height: 40  |  Size: 1.7 KiB

After

Width: 80  |  Height: 80  |  Size: 4.6 KiB

BIN
static/deepExploration-images/icon4.png

Before

Width: 40  |  Height: 40  |  Size: 1.5 KiB

After

Width: 80  |  Height: 80  |  Size: 3.4 KiB

BIN
static/deepExploration-images/kLineAll.png

After

Width: 48  |  Height: 48  |  Size: 1.6 KiB

BIN
static/deepExploration-images/notice.png

Before

Width: 18  |  Height: 18  |  Size: 523 B

After

Width: 36  |  Height: 36  |  Size: 1.1 KiB

BIN
static/deepExploration-images/search.png

Before

Width: 16  |  Height: 16  |  Size: 522 B

After

Width: 32  |  Height: 32  |  Size: 1.0 KiB

BIN
static/images/welcomeRobot@2x.png

After

Width: 710  |  Height: 490  |  Size: 217 KiB

22
utils/http.js

@ -75,10 +75,22 @@ export const http = (options) => {
loginStore.setLoginInfo("false")
console.log("2loginStore.loginInfo", loginStore.loginInfo);
// uni.showToast({
// title: '请先登录',
// icon: 'none'
// })
}
if (result.data.code === 400) {
const userStore = useUserStore()
userStore.clearUserInfo()
uni.showModal({
title: "登录失效",
content: "点击确定跳转登录页面",
confirmText: "确定",
cancelText: "取消",
success: (res) => {
uni.navigateTo({
url: '/pages/start/login/login'
})
},
});
}
resolve(result.data)
} else if (result.statusCode === 401) {
@ -87,7 +99,7 @@ export const http = (options) => {
memberStore.clearUserInfo()
// 提示用户重新登录
uni.navigateTo({
url: '/pages/login/login'
url: '/pages/start/login/login'
})
reject(result)
} else {

Loading…
Cancel
Save