日历对接

This commit is contained in:
renzhijun
2026-01-28 14:23:25 +08:00
parent dc82f4a57c
commit 95441d649f
5 changed files with 633 additions and 249 deletions

View File

@@ -5,13 +5,14 @@
<image class="icon" src="/static/icon/home/conceptCenter/pre.png" mode="widthFix"></image> <image class="icon" src="/static/icon/home/conceptCenter/pre.png" mode="widthFix"></image>
</view> </view>
<view class="yearMonth flex1"> <view class="yearMonth flex1">
<picker mode="date" fields="month" @change="monthChange"> <picker mode="date" fields="month">
<view style="display: flex; align-items: center; justify-content: center;"> <view style="display: flex; align-items: center; justify-content: center;">
<image style="width: 26rpx; height: 26rpx; margin-right: 10rpx;" <image style="width: 26rpx; height: 26rpx; margin-right: 10rpx;"
src="/pagesStock/static/icon/all-icon-2.png" mode="widthFix"></image> src="/pagesStock/static/icon/all-icon-2.png" mode="widthFix"></image>
<view style="color: #2B2B2B; font-size: 32rpx; font-weight: bold;">{{selectDateStr}}</view> <view style="color: #2B2B2B; font-size: 32rpx; font-weight: bold;">{{selectDateStr}}</view>
</view> </view>
</picker> </picker>
</view> </view>
<view class="btn" @click="clickNextMonth()"> <view class="btn" @click="clickNextMonth()">
<image class="icon" src="/static/icon/home/conceptCenter/next.png" mode="widthFix"></image> <image class="icon" src="/static/icon/home/conceptCenter/next.png" mode="widthFix"></image>
@@ -26,14 +27,26 @@
<view class="item" v-for="(item,index) in monthDateList[selectMonthIndex]" :key="index" <view class="item" v-for="(item,index) in monthDateList[selectMonthIndex]" :key="index"
@click="clickSelectDate(item)"> @click="clickSelectDate(item)">
<block v-if="item.date==selectDateStr"> <block v-if="item.date==selectDateStr">
<view <view :class="[
:class="'date select '+(item.avg_change_pct?(getRateUpOrDown(item.avg_change_pct)?'down':'up'):'')"> 'date',
'select',
getZtCountBgClass(getCalendarItemByDate(item.date)?.zt_count)
]">
{{item.day}} {{item.day}}
<view v-if="index % 7 == 0 || index % 7 == 6" style="color: #999999; font-size: 18rpx;">休市 <view v-if="index % 7 == 0 || index % 7 == 6" style="color: #999999; font-size: 18rpx;">休市
</view> </view>
<view v-else style="text-align: center;"> <view v-else style="text-align: center;">
<view style="font-size: 18rpx;">66</view> <view v-if="getCalendarItemByDate(item.date)?.zt_count > 0">
<view style="font-size: 16rpx;">商业航天</view> <view style="font-size: 18rpx;"
:style="{color: getZtCountTextColor(getCalendarItemByDate(item.date)?.zt_count)}">
{{getCalendarItemByDate(item.date)?.zt_count}}
</view>
<!-- 板块名称文字颜色动态设置 -->
<view style="font-size: 16rpx;"
:style="{color: getZtCountTextColor(getCalendarItemByDate(item.date)?.zt_count)}">
{{getCalendarItemByDate(item.date)?.top_sector || '-'}}
</view>
</view>
</view> </view>
</view> </view>
</block> </block>
@@ -42,8 +55,10 @@
<!-- <view class="date notCurrentMonth">{{item.day}}</view> --> <!-- <view class="date notCurrentMonth">{{item.day}}</view> -->
</block> </block>
<block v-else> <block v-else>
<view <view :class="[
:class="'date '+(item.avg_change_pct?(getRateUpOrDown(item.avg_change_pct)?'down':'up'):'')"> 'date',
getZtCountBgClass(getCalendarItemByDate(item.date)?.zt_count)
]">
<view :style="{color: (index % 7 == 0 || index % 7 == 6 ? '#999999' : '#2A2A2A')}"> <view :style="{color: (index % 7 == 0 || index % 7 == 6 ? '#999999' : '#2A2A2A')}">
{{item.day}} {{item.day}}
@@ -51,10 +66,18 @@
<view v-if="index % 7 == 0 || index % 7 == 6" style="color: #999999; font-size: 18rpx;">休市 <view v-if="index % 7 == 0 || index % 7 == 6" style="color: #999999; font-size: 18rpx;">休市
</view> </view>
<view v-else style="text-align: center;"> <view v-else style="text-align: center;">
<view style="font-size: 18rpx;">66</view> <view v-if="getCalendarItemByDate(item.date)?.zt_count > 0">
<view style="font-size: 16rpx;">商业航天</view> <view style="font-size: 18rpx;"
:style="{color: getZtCountTextColor(getCalendarItemByDate(item.date)?.zt_count)}">
{{getCalendarItemByDate(item.date)?.zt_count}}
</view>
<!-- 板块名称文字颜色动态设置 -->
<view style="font-size: 16rpx;"
:style="{color: getZtCountTextColor(getCalendarItemByDate(item.date)?.zt_count)}">
{{getCalendarItemByDate(item.date)?.top_sector || '-'}}
</view>
</view>
</view> </view>
</view> </view>
</block> </block>
</block> </block>
@@ -64,6 +87,10 @@
</template> </template>
<script> <script>
import {
calendarCombinedData
} from '@/request/api'
export default { export default {
name: "LCCalendar", name: "LCCalendar",
data() { data() {
@@ -75,6 +102,9 @@
selectDateStr: '', //选中日期 selectDateStr: '', //选中日期
startDateStr: '', //开始日期 startDateStr: '', //开始日期
endDateStr: '', //结束日期 endDateStr: '', //结束日期
selectYear: '',
Month: '',
calendarApiData: [], // 新增:存储接口返回的日历数据
}; };
}, },
created() { created() {
@@ -88,12 +118,64 @@
//开始日期默认为当前月份第一天 //开始日期默认为当前月份第一天
this.startDateStr = currentYear + '-' + (currentMonth > 9 ? currentMonth : ('0' + currentMonth)) + '-' + '01' this.startDateStr = currentYear + '-' + (currentMonth > 9 ? currentMonth : ('0' + currentMonth)) + '-' + '01'
//结束日期默认为当前日期 //结束日期默认为当前日期
this.endDateStr = this.selectDateStr = currentYear + '-' + (currentMonth > 9 ? currentMonth : ('0' + // this.endDateStr = this.selectDateStr = currentYear + '-' + (currentMonth > 9 ? currentMonth : ('0' +
currentMonth)) + '-' + (currentDay > 9 ? currentDay : ('0' + currentDay)) // currentMonth)) + '-' + (currentDay > 9 ? currentDay : ('0' + currentDay))
// this.getYesterdayDateData() this.endDateStr = this.selectDateStr =
`${currentYear}-${currentMonth > 9 ? currentMonth : '0' + currentMonth}-${currentDay > 9 ? currentDay : '0' + currentDay}`
this.getYesterdayDateData()
this.generateMonthDateListData() this.generateMonthDateListData()
// 新增:初始化时触发一次事件,传递当天数据给父页面
this.emitDateChange(currentYear, currentMonth, currentDay, this.getTodayItem(currentYear, currentMonth, currentDay))
},
mounted() {
this.getCalendarCombinedData()
}, },
methods: { methods: {
/**
* 获取当天的item数据合并接口数据
*/
getTodayItem(year, month, day) {
const targetDate = `${year}-${month > 9 ? month : '0' + month}-${day > 9 ? day : '0' + day}`;
const currentMonthList = this.monthDateList[this.selectMonthIndex] || [];
// 先获取本地日期item
const localItem = currentMonthList.find(item => item.date === targetDate) || null;
if (!localItem) return null;
// 获取接口数据并合并
const apiData = this.getCalendarItemByDate(targetDate) || {};
// 合并本地item和接口数据
return {
...localItem,
zt_count: apiData.zt_count || 0,
top_sector: apiData.top_sector || '-',
// 可补充其他接口字段
zaban_rate: apiData.zaban_rate || '0%' // 示例:炸板率
};
},
/**
* 触发日期变更事件传递包含接口数据的item
*/
emitDateChange(year, month, day, item) {
const yearMonth = `${year}-${month > 9 ? month : '0' + month}`;
const fullDate = `${year}-${month > 9 ? month : '0' + month}-${day > 9 ? day : '0' + day}`;
this.$emit('date-change', {
yearMonth,
fullDate,
item: item || { // 兜底无item时赋值空对象+默认值
date: fullDate,
year,
month,
day,
zt_count: 0,
top_sector: '-',
zaban_rate: '0%'
},
year,
month,
day
});
},
/** /**
* 获取当前时间前一天的数据 * 获取当前时间前一天的数据
*/ */
@@ -104,8 +186,89 @@
let selectYear = selectDate.getFullYear(); let selectYear = selectDate.getFullYear();
let selectMonth = selectDate.getMonth() + 1; let selectMonth = selectDate.getMonth() + 1;
let selectDay = selectDate.getDate(); let selectDay = selectDate.getDate();
this.selectDateStr = selectYear + '-' + (selectMonth > 9 ? selectMonth : ('0' + selectMonth)) + '-' + ( this.selectYear = selectDate.getFullYear()
selectDay > 9 ? selectDay : ('0' + selectDay)) this.Month = selectDate.getMonth() + 1;
// this.selectDateStr = selectYear + '-' + (selectMonth > 9 ? selectMonth : ('0' + selectMonth)) + '-' + (
// selectDay > 9 ? selectDay : ('0' + selectDay))
//this.selectDateStr = selectYear + '-' + (selectMonth > 9 ? selectMonth : ('0' + selectMonth))
},
/**
* 根据日期查找接口中的日历数据
* @param {String} dateStr 格式2026-01-01
* @returns {Object} 匹配的日历数据
*/
getCalendarItemByDate(dateStr) {
if (!dateStr || !this.calendarApiData.length) return null;
// 格式化本地日期2026-01-01 → 20260101以匹配接口格式
const formatDate = dateStr.replace(/-/g, '');
// 查找匹配的数据项
return this.calendarApiData.find(item => item.date === formatDate) || null;
},
/**
* 根据zt_count和是否休市获取背景色样式类
* @param {Number} count zt_count数值
* @param {Number} index 日期下标(判断是否休市)
* @returns {String} 样式类名
*/
getZtCountBgClass(count, index) {
// 休市(周日/周六或zt_count为0/null/undefined → 默认样式
if ((index % 7 === 0 || index % 7 === 6) || count === 0 || count === null || count === undefined) {
return '';
}
// 按数值范围返回对应样式类
if (count >= 80) return 'zt-bg-80';
if (count >= 60) return 'zt-bg-60';
if (count >= 40) return 'zt-bg-40';
return 'zt-bg-40-less';
},
/**
* 根据zt_count值获取文字颜色
* @param {Number} count zt_count数值
* @param {Number} index 日期下标(用于判断周末)
* @returns {String} 文字颜色值
*/
getZtCountTextColor(count, index) {
// 周末强制显示#999999
if (index !== undefined && (index % 7 === 0 || index % 7 === 6)) {
return '#999999';
}
// 无数据或0值显示默认颜色
if (count === undefined || count === null || count === 0) {
return '#2A2A2A';
}
// 根据数值范围返回对应颜色
if (count >= 80) return '#5D288F';
if (count >= 60) return '#BE1B1B';
if (count >= 40) return '#F59B38';
return '#2958AA';
},
/**
* 获取日历接口数据
*/
async getCalendarCombinedData() {
try {
let param = {
year: this.selectYear,
month: this.Month
}
const res = await calendarCombinedData(param);
if (res.success && Array.isArray(res.data)) {
this.calendarApiData = res.data;
console.log('日历数据加载成功', this.calendarApiData);
// 接口数据加载后,重新触发一次当前选中日期的事件,更新数据
if (this.selectDateStr) {
const [year, month, day] = this.selectDateStr.split('-').map(Number);
this.emitDateChange(year, month, day, this.getTodayItem(year, month, day));
}
} else {
this.calendarApiData = [];
console.warn('日历接口返回数据格式异常', res);
}
} catch (error) {
this.calendarApiData = [];
console.error('获取日历数据失败', error);
}
}, },
/** /**
* 生成日期数组 * 生成日期数组
@@ -235,6 +398,10 @@
this.startDateStr = year + '-' + (month > 9 ? month : ('0' + month)) + '-' + '01' this.startDateStr = year + '-' + (month > 9 ? month : ('0' + month)) + '-' + '01'
this.endDateStr = year + '-' + (month > 9 ? month : ('0' + month)) + '-' + lastDay this.endDateStr = year + '-' + (month > 9 ? month : ('0' + month)) + '-' + lastDay
this.selectYear = year
this.Month = month;
this.getCalendarCombinedData()
console.log('点击上个月'); console.log('点击上个月');
} }
}, },
@@ -265,6 +432,9 @@
this.startDateStr = year + '-' + (month > 9 ? month : ('0' + month)) + '-' + '01' this.startDateStr = year + '-' + (month > 9 ? month : ('0' + month)) + '-' + '01'
this.endDateStr = year + '-' + (month > 9 ? month : ('0' + month)) + '-' + lastDay this.endDateStr = year + '-' + (month > 9 ? month : ('0' + month)) + '-' + lastDay
console.log('点击下个月'); console.log('点击下个月');
this.selectYear = year
this.Month = month;
this.getCalendarCombinedData()
} }
}, },
monthChange(e) { monthChange(e) {
@@ -282,17 +452,34 @@
this.endDateStr = selectYear + '-' + (selectMonth > 9 ? selectMonth : ('0' + selectMonth)) + '-' + this.endDateStr = selectYear + '-' + (selectMonth > 9 ? selectMonth : ('0' + selectMonth)) + '-' +
lastDayOfMonth.getDate() lastDayOfMonth.getDate()
console.log('月份变更'); console.log('月份变更');
// 月份切换时更新接口数据
this.selectYear = selectYear;
this.Month = selectMonth;
this.getCalendarCombinedData();
}, },
/** /**
* 点击选择开始日期和结束日期 * 点击选择开始日期和结束日期
* @param {Object} item * @param {Object} item
*/ */
clickSelectDate(item) { clickSelectDate(item, index) { // 新增index参数
if (!item.isCurrentMonth) return if (!item.isCurrentMonth) return
if (this.selectDateStr != item.date) { if (this.selectDateStr != item.date) {
this.selectDateStr = item.date this.selectDateStr = item.date
this.chgStockData = item // 1. 获取该日期的接口数据
console.log('点击某天'); const apiData = this.getCalendarItemByDate(item.date) || {};
// 2. 合并本地item和接口数据补充默认值
const mergedItem = {
...item, // 本地日期基础数据
zt_count: apiData.zt_count || 0, // 涨停家数默认0
top_sector: apiData.top_sector || '-', // 热门板块,默认'-'
zaban_rate: apiData.zaban_rate || '0%', // 炸板率,示例字段
isWeekend: index % 7 === 0 || index % 7 === 6 // 是否周末
};
this.chgStockData = mergedItem;
// 3. 解析日期触发事件传递合并后的item
const [year, month, day] = item.date.split('-').map(Number);
this.emitDateChange(year, month, day, mergedItem);
console.log('点击某天(含接口数据)', mergedItem);
} }
} }
} }
@@ -354,6 +541,7 @@
flex-direction: column; flex-direction: column;
height: 100%; height: 100%;
.chg { .chg {
font-size: 18rpx; font-size: 18rpx;
} }
@@ -367,6 +555,26 @@
} }
} }
// zt_count ≥80 背景色
.date.zt-bg-80 {
background-color: #FAEEFF;
}
// zt_count ≥60 背景色
.date.zt-bg-60 {
background-color: #FFE9E9;
}
// zt_count ≥40 背景色
.date.zt-bg-40 {
background-color: #FFF8F0;
}
// zt_count <40 背景色
.date.zt-bg-40-less {
background-color: #EEF4FF;
}
.date.up { .date.up {
background-color: #FFD6D9; background-color: #FFD6D9;
} }

View File

@@ -228,7 +228,7 @@
import { import {
inject inject
} from 'vue' } from 'vue'
import { conceptsDailyTop,marketHeatmap,marketStatistics,marketHotspotOverview } from '@/request/api'
export default { export default {
data() { data() {
return { return {
@@ -310,8 +310,40 @@
onLoad(e) { onLoad(e) {
this.activeIndex = e.index this.activeIndex = e.index
this.contentTop = this.navH + (20 + 70 + 25) / 750 * inject('windowWidth') this.contentTop = this.navH + (20 + 70 + 25) / 750 * inject('windowWidth')
this.conceptsDailyTop()
this.marketHeatmap()
this.marketStatistics()
this.marketHotspotOverview()
}, },
methods: { methods: {
conceptsDailyTop(){
conceptsDailyTop().then(res=>{
}).catch(error=>{
})
},
marketHeatmap(){
marketHeatmap().then(res=>{
}).catch(error=>{
})
},
marketStatistics(){
marketStatistics().then(res=>{
}).catch(error=>{
})
},
marketHotspotOverview(){
marketHotspotOverview().then(res=>{
}).catch(error=>{
})
},
moreAction() { moreAction() {
uni.navigateTo({ uni.navigateTo({
url: '/pages/geGuCenter/detail' url: '/pages/geGuCenter/detail'

View File

@@ -35,7 +35,7 @@
<view style="margin: 25rpx;"> <view style="margin: 25rpx;">
<LCCalendar></LCCalendar> <LCCalendar @date-change="handleDateChange"></LCCalendar>
</view> </view>
@@ -103,7 +103,8 @@
<view <view
style="height: 400rpx; display: flex; align-items: center; justify-content: center; background-color: blue;"> style="height: 400rpx; display: flex; align-items: center; justify-content: center; background-color: blue;">
词云图占位 </view> <l-echart ref="chartRef"></l-echart>
</view>
<view style="color: #2B2B2B; font-weight: 500; display: flex; margin: 25rpx 20rpx;"> <view style="color: #2B2B2B; font-weight: 500; display: flex; margin: 25rpx 20rpx;">
@@ -161,19 +162,24 @@
import { import {
inject inject
} from 'vue' } from 'vue'
import { calendarCombinedData,analyseHighStocks } from '@/request/api'
const echarts = require('../../uni_modules/lime-echart/static/echarts.min.js');
export default { export default {
data() { data() {
return { return {
navH: inject('navHeight'), navH: inject('navHeight'),
contentTop: '', contentTop: '',
selectedYearMonth: '', // 年-月(去掉日)
selectedFullDate: '', // 年-月-日
selectedItem: null , // 选中的item完整数据
tabTypes: [{ tabTypes: [{
data: '1月14日', data: '',
change: 0, change: 0,
title: '当前日期' title: '当前日期'
}, },
{ {
data: '102', data: '',
change: 3, change: 3,
title: '涨停家数' title: '涨停家数'
}, },
@@ -251,15 +257,127 @@
'板块关联图', '板块关联图',
'板块分布', '板块分布',
'热门概念词云' '热门概念词云'
],
option2:{
title: {
show:false
},
legend: {
show:false
},
tooltip:{
show:true,
triggerOn:'mousemove'
},
radar: {
indicator: [
{ name: '市场地位', max: 100 },
{ name: '技术实力', max: 100 },
{ name: '品牌价值', max: 100 },
{ name: '运营效率', max: 100 },
{ name: '财务健康', max: 100 },
{ name: '创新能力', max: 100 },
{ name: '风险控制', max: 100 },
{ name: '成长潜力', max: 100 }
],
shape: 'polygon',
splitNumber: 5,
axisName: {
color: '#54555A'
},
splitLine: {
lineStyle: {
color: ['#CFD2D7']
}
},
splitArea: {
areaStyle:{
color:['#F4F6FA','white']
}
},
axisLine: {
lineStyle: {
color: '#CFD2D7'
}
}
},
series: [
{
name: 'Beijing',
type: 'radar',
lineStyle: {
width:1
},
data: [],
symbol: 'circle',
symbolSize: 4,
label:{
show:true
},
itemStyle: {
color: '#5070DD'
},
areaStyle: {
opacity: 0.1
}
},
] ]
},
} }
}, },
onLoad(e) { onLoad(e) {
this.activeIndex = e.index this.activeIndex = e.index
this.contentTop = this.navH + 20 / 750 * inject('windowWidth') this.contentTop = this.navH + 20 / 750 * inject('windowWidth')
this.analyseHighStocks()
}, },
// mounted() {
// // 初始化当天日期格式(防止日历组件事件未及时触发)
// const today = new Date();
// const month = today.getMonth() + 1;
// const day = today.getDate();
// this.tabTypes[0].data = `${month}月${day}日`;
// this.tabTypes[1].data = '0'; // 默认涨停家数为0后续会被日历数据覆盖
// },
methods: { methods: {
handleDateChange(data) {
console.log('从日历组件接收的参数:', data.item?.zt_count);
// 赋值到父页面的变量中
this.selectedYearMonth = data.yearMonth;
this.selectedFullDate = data.fullDate;
this.selectedItem = data.item;
// 2. 格式化日期:年-月-日 → 月日(如 2026-01-14 → 1月14日
if (data.fullDate) {
const [year, month, day] = data.fullDate.split('-').map(Number);
this.tabTypes[0].data = `${month}${day}`;
}
// 3. 赋值涨停家数优先取item中的zt_count无数据则显示0
const ztCount = data.item?.zt_count ?? 0;
this.tabTypes[1].data = ztCount.toString(); // 转为字符串保证格式统一
// this.analyseHighStocks()
},
analyseHighStocks(){
const formatDate = this.selectedFullDate.replace(/-/g, '');
let param = {
date: formatDate
}
analyseHighStocks(param).then(res=>{
}).catch(error=>{
})
},
async init() {
// chart 图表实例不能存在data里
const chart = await this.$refs.chartRef.init(echarts);
// chart.on('click',function (params) {
// console.log(params)
// })
chart.setOption(this.option2)
},
bkydAction(index) { bkydAction(index) {
uni.navigateTo({ uni.navigateTo({
url: `/pagesStock/stockCenterDetails/bkydmx?index=${index}` url: `/pagesStock/stockCenterDetails/bkydmx?index=${index}`

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -221,3 +221,29 @@ export const feedback = param => post('/api/user/feedback',param)
* 协议 * 协议
*/ */
export const agreements = () => get('/api/agreements') export const agreements = () => get('/api/agreements')
/**
* 热门概念接口
*/
export const conceptsDailyTop =param => get('/api/concepts/daily-top',param,true)
/**
* 市值热力图
*/
export const marketHeatmap =param => get('/api/market/heatmap',param,true)
/**
* 市场统计
*/
export const marketStatistics =param => get('/api/market/statistics',param,true)
/**
* 热点概览接口
*/
export const marketHotspotOverview =param => get('/api/market/hotspot-overview',param,true)
/**
*日历数据
*/
export const calendarCombinedData =param => get('/api/v1/calendar/combined-data',param,true)
/**
*高位股数据
*/
export const analyseHighStocks =param => get('/api/limit-analyse/high-position-stocks',param,true)