|
@ -32,7 +32,6 @@ |
|
|
<div class="collapsed-bottom-btn" @click="handleAnnouncementClick"> |
|
|
<div class="collapsed-bottom-btn" @click="handleAnnouncementClick"> |
|
|
<img |
|
|
<img |
|
|
class="collapsed-bottom-announcement" |
|
|
class="collapsed-bottom-announcement" |
|
|
@click="openHistory" |
|
|
|
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png" |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png" |
|
|
alt="icon" |
|
|
alt="icon" |
|
|
/> |
|
|
/> |
|
@ -60,21 +59,28 @@ |
|
|
</div> |
|
|
</div> |
|
|
<!-- 历史记录列表 --> |
|
|
<!-- 历史记录列表 --> |
|
|
<div class="history-list"> |
|
|
<div class="history-list"> |
|
|
|
|
|
<div v-for="history in categoryHistory" :key="history.name"> |
|
|
|
|
|
<div class="categoryName"> |
|
|
|
|
|
{{ history.name }} |
|
|
|
|
|
</div> |
|
|
<div |
|
|
<div |
|
|
v-for="record in historyRecords" |
|
|
|
|
|
|
|
|
v-for="record in history.list" |
|
|
:key="record.id" |
|
|
:key="record.id" |
|
|
class="history-item" |
|
|
class="history-item" |
|
|
@click="selectRecord(record)" |
|
|
@click="selectRecord(record)" |
|
|
:class="{ active: selectedRecordId === record.id }" |
|
|
:class="{ active: selectedRecordId === record.id }" |
|
|
> |
|
|
> |
|
|
<div class="record-content"> |
|
|
|
|
|
|
|
|
<div class="record-content" @click="selectRecord(record)"> |
|
|
<div class="record-img"> |
|
|
<div class="record-img"> |
|
|
<img :src="marketList[record.market]" :alt="record.market" /> |
|
|
|
|
|
|
|
|
<img |
|
|
|
|
|
:src="marketList[record.stockMarket]" |
|
|
|
|
|
:alt="record.stockMarket" |
|
|
|
|
|
/> |
|
|
</div> |
|
|
</div> |
|
|
<div class="record-msg"> |
|
|
<div class="record-msg"> |
|
|
<div class="record-text">{{ record.code }}</div> |
|
|
|
|
|
|
|
|
<div class="record-text">{{ record.stockCode }}</div> |
|
|
<div class="record-time"> |
|
|
<div class="record-time"> |
|
|
{{ moment(record.date).format("D/M/YYYY") }} |
|
|
|
|
|
|
|
|
{{ moment(record.updatedTime).format("YYYY-MM-DD HH:mm:ss") }} |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
@ -94,11 +100,13 @@ |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/9ad3617c94955bcb76e1b11db70bb80b.png" |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/9ad3617c94955bcb76e1b11db70bb80b.png" |
|
|
alt="" |
|
|
alt="" |
|
|
/> |
|
|
/> |
|
|
数据更新时间:{{ |
|
|
|
|
|
moment(record.updateTime).format("D/M/YYYY") |
|
|
|
|
|
}} |
|
|
|
|
|
|
|
|
数据更新时间:{{ moment(record.date).format("D/M/YYYY") }} |
|
|
</div> |
|
|
</div> |
|
|
<div v-if="record.isTop" class="popover-item popover-btn"> |
|
|
|
|
|
|
|
|
<div |
|
|
|
|
|
v-if="record.isTop" |
|
|
|
|
|
class="popover-item popover-btn" |
|
|
|
|
|
@click="changeTopStatus(record.isTop, record.id)" |
|
|
|
|
|
> |
|
|
<img |
|
|
<img |
|
|
class="popover-icon" |
|
|
class="popover-icon" |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/a458305d8275734cc96bf6cad29864bf.png" |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/a458305d8275734cc96bf6cad29864bf.png" |
|
@ -106,7 +114,11 @@ |
|
|
/> |
|
|
/> |
|
|
取消置顶 |
|
|
取消置顶 |
|
|
</div> |
|
|
</div> |
|
|
<div v-else class="popover-item popover-btn"> |
|
|
|
|
|
|
|
|
<div |
|
|
|
|
|
v-else |
|
|
|
|
|
class="popover-item popover-btn" |
|
|
|
|
|
@click="changeTopStatus(record.isTop, record.id)" |
|
|
|
|
|
> |
|
|
<img |
|
|
<img |
|
|
class="popover-icon" |
|
|
class="popover-icon" |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/a458305d8275734cc96bf6cad29864bf.png" |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/a458305d8275734cc96bf6cad29864bf.png" |
|
@ -114,7 +126,10 @@ |
|
|
/> |
|
|
/> |
|
|
置顶 |
|
|
置顶 |
|
|
</div> |
|
|
</div> |
|
|
<div class="popover-item popover-btn"> |
|
|
|
|
|
|
|
|
<div |
|
|
|
|
|
class="popover-item popover-btn" |
|
|
|
|
|
@click="deleteRecord(record.id)" |
|
|
|
|
|
> |
|
|
<img |
|
|
<img |
|
|
class="popover-icon" |
|
|
class="popover-icon" |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/027718d41523375a69e9cac927601cf8.png" |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/027718d41523375a69e9cac927601cf8.png" |
|
@ -131,25 +146,12 @@ |
|
|
></button> --> |
|
|
></button> --> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
<!-- 空状态 --> |
|
|
<!-- 空状态 --> |
|
|
<div v-if="historyRecords.length === 0" class="empty-state"> |
|
|
<div v-if="historyRecords.length === 0" class="empty-state"> |
|
|
<div class="empty-icon"> |
|
|
<div class="empty-icon"> |
|
|
<el-icon class="documentDelete"><DocumentDelete /></el-icon> |
|
|
<el-icon class="documentDelete"><DocumentDelete /></el-icon> |
|
|
<!-- <svg |
|
|
|
|
|
width="48" |
|
|
|
|
|
height="48" |
|
|
|
|
|
viewBox="0 0 24 24" |
|
|
|
|
|
fill="none" |
|
|
|
|
|
xmlns="http://www.w3.org/2000/svg" |
|
|
|
|
|
> |
|
|
|
|
|
<path |
|
|
|
|
|
d="M12 2C13.1 2 14 2.9 14 4C14 5.1 13.1 6 12 6C10.9 6 10 5.1 10 4C10 2.9 10.9 2 12 2ZM21 9V7L15 1H5C3.89 1 3 1.89 3 3V21C3 22.1 3.89 23 5 23H19C20.1 23 21 22.1 21 21V9M19 9H14V4" |
|
|
|
|
|
stroke="currentColor" |
|
|
|
|
|
stroke-width="1.5" |
|
|
|
|
|
stroke-linecap="round" |
|
|
|
|
|
stroke-linejoin="round" |
|
|
|
|
|
/> |
|
|
|
|
|
</svg> --> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
<p class="empty-text">暂无历史记录</p> |
|
|
<p class="empty-text">暂无历史记录</p> |
|
|
</div> |
|
|
</div> |
|
@ -166,7 +168,6 @@ |
|
|
<div class="bottom-btn" @click="handleAnnouncementClick"> |
|
|
<div class="bottom-btn" @click="handleAnnouncementClick"> |
|
|
<img |
|
|
<img |
|
|
class="bottom-announcement" |
|
|
class="bottom-announcement" |
|
|
@click="openHistory" |
|
|
|
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png" |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png" |
|
|
alt="icon" |
|
|
alt="icon" |
|
|
/> |
|
|
/> |
|
@ -203,64 +204,98 @@ |
|
|
</div> |
|
|
</div> |
|
|
<!-- 历史记录列表 --> |
|
|
<!-- 历史记录列表 --> |
|
|
<div class="history-list"> |
|
|
<div class="history-list"> |
|
|
|
|
|
<div v-for="history in categoryHistory" :key="history.name"> |
|
|
|
|
|
<div class="categoryName"> |
|
|
|
|
|
{{ history.name }} |
|
|
|
|
|
</div> |
|
|
<div |
|
|
<div |
|
|
v-for="record in historyRecords" |
|
|
|
|
|
|
|
|
v-for="record in history.list" |
|
|
:key="record.id" |
|
|
:key="record.id" |
|
|
class="history-item" |
|
|
class="history-item" |
|
|
@click="selectRecord(record)" |
|
|
|
|
|
|
|
|
:class="{ active: selectedRecordId === record.id }" |
|
|
> |
|
|
> |
|
|
<div class="record-content"> |
|
|
|
|
|
|
|
|
<div class="record-content" @click="selectRecord(record)"> |
|
|
<div class="record-img"> |
|
|
<div class="record-img"> |
|
|
<span class="type-badge" :class="record.type"> |
|
|
|
|
|
{{ record.type === "AIchat" ? "夺宝奇兵" : "AI情绪" }} |
|
|
|
|
|
</span> |
|
|
|
|
|
|
|
|
<img |
|
|
|
|
|
:src="marketList[record.stockMarket]" |
|
|
|
|
|
:alt="record.stockMarket" |
|
|
|
|
|
/> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div class="record-msg"> |
|
|
|
|
|
<div class="record-text">{{ record.stockCode }}</div> |
|
|
|
|
|
<div class="record-time"> |
|
|
|
|
|
{{ moment(record.updatedTime).format("YYYY-MM-DD HH:mm:ss") }} |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
<div class="record-text">{{ record.question }}</div> |
|
|
|
|
|
<div class="record-time">{{ formatTime(record.timestamp) }}</div> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
<div class="record-actions"> |
|
|
<div class="record-actions"> |
|
|
<button |
|
|
|
|
|
class="more-btn" |
|
|
|
|
|
@click.stop="deleteRecord(record.id)" |
|
|
|
|
|
title="删除" |
|
|
|
|
|
|
|
|
<el-popover |
|
|
|
|
|
class="box-item" |
|
|
|
|
|
placement="right-start" |
|
|
|
|
|
trigger="click" |
|
|
> |
|
|
> |
|
|
<svg |
|
|
|
|
|
width="12" |
|
|
|
|
|
height="12" |
|
|
|
|
|
viewBox="0 0 24 24" |
|
|
|
|
|
fill="none" |
|
|
|
|
|
xmlns="http://www.w3.org/2000/svg" |
|
|
|
|
|
|
|
|
<template #reference> |
|
|
|
|
|
<el-icon class="more-btn"><MoreFilled /></el-icon> |
|
|
|
|
|
</template> |
|
|
|
|
|
<div class="popover-content"> |
|
|
|
|
|
<div class="popover-item"> |
|
|
|
|
|
<img |
|
|
|
|
|
class="popover-icon" |
|
|
|
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/9ad3617c94955bcb76e1b11db70bb80b.png" |
|
|
|
|
|
alt="" |
|
|
|
|
|
/> |
|
|
|
|
|
数据更新时间:{{ moment(record.date).format("D/M/YYYY") }} |
|
|
|
|
|
</div> |
|
|
|
|
|
<div |
|
|
|
|
|
v-if="record.isTop" |
|
|
|
|
|
class="popover-item popover-btn" |
|
|
|
|
|
@click="changeTopStatus(record.isTop, record.id)" |
|
|
> |
|
|
> |
|
|
<path |
|
|
|
|
|
d="M18 6L6 18M6 6L18 18" |
|
|
|
|
|
stroke="currentColor" |
|
|
|
|
|
stroke-width="2" |
|
|
|
|
|
stroke-linecap="round" |
|
|
|
|
|
stroke-linejoin="round" |
|
|
|
|
|
|
|
|
<img |
|
|
|
|
|
class="popover-icon" |
|
|
|
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/a458305d8275734cc96bf6cad29864bf.png" |
|
|
|
|
|
alt="" |
|
|
|
|
|
/> |
|
|
|
|
|
取消置顶 |
|
|
|
|
|
</div> |
|
|
|
|
|
<div |
|
|
|
|
|
v-else |
|
|
|
|
|
class="popover-item popover-btn" |
|
|
|
|
|
@click="changeTopStatus(record.isTop, record.id)" |
|
|
|
|
|
> |
|
|
|
|
|
<img |
|
|
|
|
|
class="popover-icon" |
|
|
|
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/a458305d8275734cc96bf6cad29864bf.png" |
|
|
|
|
|
alt="" |
|
|
/> |
|
|
/> |
|
|
</svg> |
|
|
|
|
|
</button> |
|
|
|
|
|
|
|
|
置顶 |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
<div |
|
|
|
|
|
class="popover-item popover-btn" |
|
|
|
|
|
@click="deleteRecord(record.id)" |
|
|
|
|
|
> |
|
|
|
|
|
<img |
|
|
|
|
|
class="popover-icon" |
|
|
|
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/027718d41523375a69e9cac927601cf8.png" |
|
|
|
|
|
alt="" |
|
|
|
|
|
/> |
|
|
|
|
|
删除 |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</el-popover> |
|
|
|
|
|
<!-- <button |
|
|
|
|
|
|
|
|
|
|
|
@click="openDetail(record)" |
|
|
|
|
|
title="更多" |
|
|
|
|
|
></button> --> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
<!-- 空状态 --> |
|
|
<!-- 空状态 --> |
|
|
<div v-if="historyRecords.length === 0" class="empty-state"> |
|
|
<div v-if="historyRecords.length === 0" class="empty-state"> |
|
|
<div class="empty-icon"> |
|
|
<div class="empty-icon"> |
|
|
<el-icon class="documentDelete"><DocumentDelete /></el-icon> |
|
|
<el-icon class="documentDelete"><DocumentDelete /></el-icon> |
|
|
<!-- <svg |
|
|
|
|
|
width="48" |
|
|
|
|
|
height="48" |
|
|
|
|
|
viewBox="0 0 24 24" |
|
|
|
|
|
fill="none" |
|
|
|
|
|
xmlns="http://www.w3.org/2000/svg" |
|
|
|
|
|
> |
|
|
|
|
|
<path |
|
|
|
|
|
d="M12 2C13.1 2 14 2.9 14 4C14 5.1 13.1 6 12 6C10.9 6 10 5.1 10 4C10 2.9 10.9 2 12 2ZM21 9V7L15 1H5C3.89 1 3 1.89 3 3V21C3 22.1 3.89 23 5 23H19C20.1 23 21 22.1 21 21V9M19 9H14V4" |
|
|
|
|
|
stroke="currentColor" |
|
|
|
|
|
stroke-width="1.5" |
|
|
|
|
|
stroke-linecap="round" |
|
|
|
|
|
stroke-linejoin="round" |
|
|
|
|
|
/> |
|
|
|
|
|
</svg> --> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
<p class="empty-text">暂无历史记录</p> |
|
|
<p class="empty-text">暂无历史记录</p> |
|
|
</div> |
|
|
</div> |
|
@ -278,7 +313,6 @@ |
|
|
<div class="mobile-bottom-btn" @click="handleAnnouncementClick"> |
|
|
<div class="mobile-bottom-btn" @click="handleAnnouncementClick"> |
|
|
<img |
|
|
<img |
|
|
class="mobile-bottom-announcement" |
|
|
class="mobile-bottom-announcement" |
|
|
@click="openHistory" |
|
|
|
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png" |
|
|
src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png" |
|
|
alt="icon" |
|
|
alt="icon" |
|
|
/> |
|
|
/> |
|
@ -287,11 +321,31 @@ |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<el-dialog v-model="deleteDialogVisible" title="永久删除记录" width="500"> |
|
|
|
|
|
<span>删除后,该记录将不可恢复。确认删除吗?</span> |
|
|
|
|
|
<template #footer> |
|
|
|
|
|
<div class="dialog-footer"> |
|
|
|
|
|
<el-button @click="closeDeleteDialog()">取消</el-button> |
|
|
|
|
|
<el-button type="primary" @click="deleteRecordConfirm()"> |
|
|
|
|
|
删除 |
|
|
|
|
|
</el-button> |
|
|
|
|
|
</div> |
|
|
|
|
|
</template> |
|
|
|
|
|
</el-dialog> |
|
|
</template> |
|
|
</template> |
|
|
|
|
|
|
|
|
<script setup> |
|
|
<script setup> |
|
|
import { ref, computed, onMounted, watch } from "vue"; |
|
|
import { ref, computed, onMounted, watch } from "vue"; |
|
|
|
|
|
import { |
|
|
|
|
|
getHistoryListAPI, |
|
|
|
|
|
changeTopAPI, |
|
|
|
|
|
deleteRecordAPI, |
|
|
|
|
|
clickRecordAPI, |
|
|
|
|
|
} from "../../api/AIxiaocaishen"; |
|
|
import moment from "moment"; |
|
|
import moment from "moment"; |
|
|
|
|
|
import { ElMessage } from "element-plus"; |
|
|
|
|
|
|
|
|
// Props |
|
|
// Props |
|
|
const props = defineProps({ |
|
|
const props = defineProps({ |
|
|
currentType: { |
|
|
currentType: { |
|
@ -326,122 +380,141 @@ const marketList = ref({ |
|
|
}); |
|
|
}); |
|
|
const isCollapsed = ref(false); |
|
|
const isCollapsed = ref(false); |
|
|
const selectedRecordId = ref(null); |
|
|
const selectedRecordId = ref(null); |
|
|
const historyRecords = ref([ |
|
|
|
|
|
// 原有数据 |
|
|
|
|
|
{ |
|
|
|
|
|
market: "cn", |
|
|
|
|
|
code: "1A0001", |
|
|
|
|
|
date: "2023-01-01", |
|
|
|
|
|
isTop: "1", |
|
|
|
|
|
updateTime: "2025-01-01", |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
|
|
|
// 今日数据 |
|
|
|
|
|
{ |
|
|
|
|
|
market: "usa", |
|
|
|
|
|
code: "AAPL", |
|
|
|
|
|
date: "2025-01-15", |
|
|
|
|
|
isTop: "1", |
|
|
|
|
|
updateTime: "2025-01-15", |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
market: "hk", |
|
|
|
|
|
code: "00700", |
|
|
|
|
|
date: "2025-01-15", |
|
|
|
|
|
isTop: "0", |
|
|
|
|
|
updateTime: "2025-01-15", |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
const delObj = ref({}); |
|
|
|
|
|
const deleteDialogVisible = ref(false); |
|
|
|
|
|
|
|
|
// 前三日数据 |
|
|
|
|
|
{ |
|
|
|
|
|
market: "cn", |
|
|
|
|
|
code: "000001", |
|
|
|
|
|
date: "2025-01-14", |
|
|
|
|
|
isTop: "0", |
|
|
|
|
|
updateTime: "2025-01-14", |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
market: "usa", |
|
|
|
|
|
code: "TSLA", |
|
|
|
|
|
date: "2025-01-13", |
|
|
|
|
|
isTop: "1", |
|
|
|
|
|
updateTime: "2025-01-13", |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
market: "hk", |
|
|
|
|
|
code: "09988", |
|
|
|
|
|
date: "2025-01-12", |
|
|
|
|
|
isTop: "0", |
|
|
|
|
|
updateTime: "2025-01-12", |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
const openDeleteDialog = () => { |
|
|
|
|
|
deleteDialogVisible.value = true; |
|
|
|
|
|
}; |
|
|
|
|
|
const closeDeleteDialog = () => { |
|
|
|
|
|
delObj.value = {}; |
|
|
|
|
|
deleteDialogVisible.value = false; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 本周数据 |
|
|
|
|
|
{ |
|
|
|
|
|
market: "sg", |
|
|
|
|
|
code: "D05", |
|
|
|
|
|
date: "2025-01-13", |
|
|
|
|
|
isTop: "0", |
|
|
|
|
|
updateTime: "2025-01-13", |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
market: "cn", |
|
|
|
|
|
code: "600519", |
|
|
|
|
|
date: "2025-01-14", |
|
|
|
|
|
isTop: "1", |
|
|
|
|
|
updateTime: "2025-01-14", |
|
|
|
|
|
}, |
|
|
|
|
|
{ |
|
|
|
|
|
market: "usa", |
|
|
|
|
|
code: "NVDA", |
|
|
|
|
|
date: "2025-01-10", |
|
|
|
|
|
isTop: "0", |
|
|
|
|
|
updateTime: "2025-01-10", |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
const historyRecords = ref([]); |
|
|
|
|
|
const categoryHistory = ref([]); |
|
|
|
|
|
const getHistoryList = async (params) => { |
|
|
|
|
|
try { |
|
|
|
|
|
const result = await getHistoryListAPI(params); |
|
|
|
|
|
historyRecords.value = result.data.list; |
|
|
|
|
|
let remainingRecords = result.data.list; // 复制原数组 |
|
|
|
|
|
|
|
|
|
|
|
// 1. 筛选置顶记录 |
|
|
|
|
|
let topList = remainingRecords.filter((record) => record.isTop === 1); |
|
|
|
|
|
remainingRecords = remainingRecords.filter((record) => record.isTop !== 1); |
|
|
|
|
|
|
|
|
|
|
|
// 2. 筛选今日记录 |
|
|
|
|
|
let todayList = remainingRecords.filter((record) => { |
|
|
|
|
|
const today = moment().format("YYYY-MM-DD"); |
|
|
|
|
|
const recordDate = moment(record.updateTime).format("YYYY-MM-DD"); |
|
|
|
|
|
return recordDate === today; |
|
|
|
|
|
}); |
|
|
|
|
|
remainingRecords = remainingRecords.filter((record) => { |
|
|
|
|
|
const today = moment().format("YYYY-MM-DD"); |
|
|
|
|
|
const recordDate = moment(record.updateTime).format("YYYY-MM-DD"); |
|
|
|
|
|
return recordDate !== today; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
// 本月数据 |
|
|
|
|
|
{ |
|
|
|
|
|
market: "my", |
|
|
|
|
|
code: "MAYBANK", |
|
|
|
|
|
date: "2025-01-08", |
|
|
|
|
|
isTop: "0", |
|
|
|
|
|
updateTime: "2025-01-08", |
|
|
|
|
|
}, |
|
|
|
|
|
|
|
|
// 3. 筛选近3日记录(不包括今日) |
|
|
|
|
|
let recent3DaysList = remainingRecords.filter((record) => { |
|
|
|
|
|
const threeDaysAgo = moment().subtract(3, "days").startOf("day"); |
|
|
|
|
|
const yesterday = moment().subtract(1, "days").endOf("day"); |
|
|
|
|
|
const recordDate = moment(record.updateTime); |
|
|
|
|
|
return recordDate.isAfter(threeDaysAgo) && recordDate.isBefore(yesterday); |
|
|
|
|
|
}); |
|
|
|
|
|
remainingRecords = remainingRecords.filter((record) => { |
|
|
|
|
|
const threeDaysAgo = moment().subtract(3, "days").startOf("day"); |
|
|
|
|
|
const yesterday = moment().subtract(1, "days").endOf("day"); |
|
|
|
|
|
const recordDate = moment(record.updateTime); |
|
|
|
|
|
return !( |
|
|
|
|
|
recordDate.isAfter(threeDaysAgo) && recordDate.isBefore(yesterday) |
|
|
|
|
|
); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 4. 筛选近7日记录(不包括今日和近3日) |
|
|
|
|
|
let recent7DaysList = remainingRecords.filter((record) => { |
|
|
|
|
|
const sevenDaysAgo = moment().subtract(7, "days").startOf("day"); |
|
|
|
|
|
const recordDate = moment(record.updateTime); |
|
|
|
|
|
return recordDate.isAfter(sevenDaysAgo); |
|
|
|
|
|
}); |
|
|
|
|
|
remainingRecords = remainingRecords.filter((record) => { |
|
|
|
|
|
const sevenDaysAgo = moment().subtract(7, "days").startOf("day"); |
|
|
|
|
|
const recordDate = moment(record.updateTime); |
|
|
|
|
|
return !recordDate.isAfter(sevenDaysAgo); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 5. 筛选近30日记录(不包括前面已筛选的) |
|
|
|
|
|
let recent30DaysList = remainingRecords.filter((record) => { |
|
|
|
|
|
const thirtyDaysAgo = moment().subtract(30, "days").startOf("day"); |
|
|
|
|
|
const recordDate = moment(record.updateTime); |
|
|
|
|
|
return recordDate.isAfter(thirtyDaysAgo); |
|
|
|
|
|
}); |
|
|
|
|
|
remainingRecords = remainingRecords.filter((record) => { |
|
|
|
|
|
const thirtyDaysAgo = moment().subtract(30, "days").startOf("day"); |
|
|
|
|
|
const recordDate = moment(record.updateTime); |
|
|
|
|
|
return !recordDate.isAfter(thirtyDaysAgo); |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
historyRecords.value = result.data.list; |
|
|
|
|
|
|
|
|
|
|
|
categoryHistory.value = [ |
|
|
{ |
|
|
{ |
|
|
market: "th", |
|
|
|
|
|
code: "PTT", |
|
|
|
|
|
date: "2025-01-05", |
|
|
|
|
|
isTop: "1", |
|
|
|
|
|
updateTime: "2025-01-05", |
|
|
|
|
|
|
|
|
name: "置顶", |
|
|
|
|
|
list: topList, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
market: "vi", |
|
|
|
|
|
code: "VIC", |
|
|
|
|
|
date: "2025-01-03", |
|
|
|
|
|
isTop: "0", |
|
|
|
|
|
updateTime: "2025-01-03", |
|
|
|
|
|
|
|
|
name: "今日", |
|
|
|
|
|
list: todayList, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
market: "can", |
|
|
|
|
|
code: "SHOP", |
|
|
|
|
|
date: "2025-01-02", |
|
|
|
|
|
isTop: "0", |
|
|
|
|
|
updateTime: "2025-01-02", |
|
|
|
|
|
|
|
|
name: "近3日", |
|
|
|
|
|
list: recent3DaysList, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
market: "hk", |
|
|
|
|
|
code: "01299", |
|
|
|
|
|
date: "2025-01-01", |
|
|
|
|
|
isTop: "1", |
|
|
|
|
|
updateTime: "2025-01-01", |
|
|
|
|
|
|
|
|
name: "近7日", |
|
|
|
|
|
list: recent7DaysList, |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
market: "cn", |
|
|
|
|
|
code: "000858", |
|
|
|
|
|
date: "2025-01-06", |
|
|
|
|
|
isTop: "0", |
|
|
|
|
|
updateTime: "2025-01-06", |
|
|
|
|
|
|
|
|
name: "近30日", |
|
|
|
|
|
list: recent30DaysList, |
|
|
}, |
|
|
}, |
|
|
]); |
|
|
|
|
|
|
|
|
]; |
|
|
|
|
|
console.log("historyRecords", historyRecords.value); |
|
|
|
|
|
console.log("categoryHistory", categoryHistory.value); |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
console.error("获取历史记录出错", e); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const changeTop = async (param) => { |
|
|
|
|
|
try { |
|
|
|
|
|
await changeTopAPI(param); |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
console.error("置顶或取消置顶失败", e); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const changeTopStatus = async (isTop, id) => { |
|
|
|
|
|
try { |
|
|
|
|
|
if (isTop == 0 && categoryHistory.value[0].list.length >= 3) { |
|
|
|
|
|
console.log("超过置顶上线"); |
|
|
|
|
|
ElMessage.warning("最多置顶三条内容,已达上限!"); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
await changeTop({ |
|
|
|
|
|
model: props.currentType == "AIchat" ? 1 : 2, |
|
|
|
|
|
recordId: id, |
|
|
|
|
|
isTop: isTop == 1 ? 0 : 1, |
|
|
|
|
|
}); |
|
|
|
|
|
await getHistoryList({ |
|
|
|
|
|
model: props.currentType == "AIchat" ? 1 : 2, |
|
|
|
|
|
token: localStorage.getItem("localToken"), |
|
|
|
|
|
}); |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error("操作失败:", error); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
// 方法 |
|
|
// 方法 |
|
|
const toggleCollapse = () => { |
|
|
const toggleCollapse = () => { |
|
@ -451,6 +524,10 @@ const toggleCollapse = () => { |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const openHistory = () => { |
|
|
const openHistory = () => { |
|
|
|
|
|
// getHistoryList({ |
|
|
|
|
|
// model: props.currentType == "AIchat" ? 1 : 2, |
|
|
|
|
|
// token: localStorage.getItem("localToken"), |
|
|
|
|
|
// }); |
|
|
isCollapsed.value = false; |
|
|
isCollapsed.value = false; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
@ -462,103 +539,39 @@ const openDetail = (record) => { |
|
|
console.log("record", record); |
|
|
console.log("record", record); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const selectRecord = (record) => { |
|
|
|
|
|
// selectedRecordId.value = record.id; |
|
|
|
|
|
// emit("selectRecord", record); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const deleteRecord = (recordId) => { |
|
|
|
|
|
const index = historyRecords.value.findIndex( |
|
|
|
|
|
(record) => record.id === recordId |
|
|
|
|
|
); |
|
|
|
|
|
if (index > -1) { |
|
|
|
|
|
historyRecords.value.splice(index, 1); |
|
|
|
|
|
saveToLocalStorage(); |
|
|
|
|
|
|
|
|
|
|
|
// 如果删除的是当前选中的记录,清除选中状态 |
|
|
|
|
|
if (selectedRecordId.value === recordId) { |
|
|
|
|
|
selectedRecordId.value = null; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const addRecord = (question, type) => { |
|
|
|
|
|
const newRecord = { |
|
|
|
|
|
id: Date.now() + Math.random(), // 生成唯一ID |
|
|
|
|
|
question: question, |
|
|
|
|
|
type: type, |
|
|
|
|
|
timestamp: Date.now() |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
historyRecords.value.unshift(newRecord); // 添加到数组开头 |
|
|
|
|
|
saveToLocalStorage(); |
|
|
|
|
|
emit("recordAdded", newRecord); |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const clearHistory = () => { |
|
|
|
|
|
if (confirm("确定要清空所有历史记录吗?")) { |
|
|
|
|
|
historyRecords.value = []; |
|
|
|
|
|
selectedRecordId.value = null; |
|
|
|
|
|
saveToLocalStorage(); |
|
|
|
|
|
} |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
const formatTime = (timestamp) => { |
|
|
|
|
|
const date = new Date(timestamp); |
|
|
|
|
|
const now = new Date(); |
|
|
|
|
|
const diff = now - date; |
|
|
|
|
|
|
|
|
|
|
|
// 小于1分钟 |
|
|
|
|
|
if (diff < 60000) { |
|
|
|
|
|
return "刚刚"; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 小于1小时 |
|
|
|
|
|
if (diff < 3600000) { |
|
|
|
|
|
return `${Math.floor(diff / 60000)}分钟前`; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 小于1天 |
|
|
|
|
|
if (diff < 86400000) { |
|
|
|
|
|
return `${Math.floor(diff / 3600000)}小时前`; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 大于1天 |
|
|
|
|
|
if (diff < 604800000) { |
|
|
|
|
|
return `${Math.floor(diff / 86400000)}天前`; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 超过一周,显示具体日期 |
|
|
|
|
|
return date.toLocaleDateString("zh-CN", { |
|
|
|
|
|
month: "short", |
|
|
|
|
|
day: "numeric", |
|
|
|
|
|
hour: "2-digit", |
|
|
|
|
|
minute: "2-digit", |
|
|
|
|
|
|
|
|
const historyData = ref({}); |
|
|
|
|
|
const selectRecord = async (record) => { |
|
|
|
|
|
try { |
|
|
|
|
|
const result = await clickRecordAPI({ |
|
|
|
|
|
model: props.currentType == "AIchat" ? 1 : 2, |
|
|
|
|
|
parentId: record.parentId, |
|
|
|
|
|
recordId: record.id, |
|
|
}); |
|
|
}); |
|
|
|
|
|
historyData.value; |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
console.error("获取历史记录数据失败", e); |
|
|
|
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const saveToLocalStorage = () => { |
|
|
|
|
|
localStorage.setItem( |
|
|
|
|
|
"aiChatHistoryRecords", |
|
|
|
|
|
JSON.stringify(historyRecords.value) |
|
|
|
|
|
); |
|
|
|
|
|
|
|
|
const deleteRecord = (id) => { |
|
|
|
|
|
delObj.value.id = id; |
|
|
|
|
|
openDeleteDialog(); |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
const loadFromLocalStorage = () => { |
|
|
|
|
|
|
|
|
const deleteRecordConfirm = async () => { |
|
|
try { |
|
|
try { |
|
|
const saved = localStorage.getItem("aiChatHistoryRecords"); |
|
|
|
|
|
if (saved) { |
|
|
|
|
|
historyRecords.value = JSON.parse(saved); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 加载折叠状态 |
|
|
|
|
|
const collapsedState = localStorage.getItem("historyRecordCollapsed"); |
|
|
|
|
|
if (collapsedState !== null) { |
|
|
|
|
|
isCollapsed.value = collapsedState === "true"; |
|
|
|
|
|
} |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error("加载历史记录失败:", error); |
|
|
|
|
|
historyRecords.value = []; |
|
|
|
|
|
|
|
|
const result = await deleteRecordAPI({ |
|
|
|
|
|
model: props.currentType == "AIchat" ? 1 : 2, |
|
|
|
|
|
recordId: delObj.value.id, |
|
|
|
|
|
}); |
|
|
|
|
|
console.log(result.msg); |
|
|
|
|
|
closeDeleteDialog(); |
|
|
|
|
|
await getHistoryList({ |
|
|
|
|
|
model: props.currentType == "AIchat" ? 1 : 2, |
|
|
|
|
|
token: localStorage.getItem("localToken"), |
|
|
|
|
|
}); |
|
|
|
|
|
} catch (e) { |
|
|
|
|
|
console.error("删除失败", e); |
|
|
} |
|
|
} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
@ -574,25 +587,18 @@ const handleFeedbackClick = () => { |
|
|
|
|
|
|
|
|
// 暴露方法和状态给父组件 |
|
|
// 暴露方法和状态给父组件 |
|
|
defineExpose({ |
|
|
defineExpose({ |
|
|
addRecord, |
|
|
|
|
|
clearHistory, |
|
|
|
|
|
isCollapsed, |
|
|
isCollapsed, |
|
|
toggleCollapse, |
|
|
toggleCollapse, |
|
|
|
|
|
getHistoryList, |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// 生命周期 |
|
|
// 生命周期 |
|
|
onMounted(() => { |
|
|
onMounted(() => { |
|
|
// loadFromLocalStorage(); |
|
|
|
|
|
|
|
|
getHistoryList({ |
|
|
|
|
|
model: props.currentType == "AIchat" ? 1 : 2, |
|
|
|
|
|
token: localStorage.getItem("localToken"), |
|
|
|
|
|
}); |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
// 监听历史记录变化,自动保存 |
|
|
|
|
|
watch( |
|
|
|
|
|
historyRecords, |
|
|
|
|
|
() => { |
|
|
|
|
|
saveToLocalStorage(); |
|
|
|
|
|
}, |
|
|
|
|
|
{ deep: true } |
|
|
|
|
|
); |
|
|
|
|
|
</script> |
|
|
</script> |
|
|
|
|
|
|
|
|
<style scoped> |
|
|
<style scoped> |
|
@ -819,6 +825,11 @@ watch( |
|
|
background: rgba(255, 255, 255, 0.5); |
|
|
background: rgba(255, 255, 255, 0.5); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
.categoryName { |
|
|
|
|
|
color: white; |
|
|
|
|
|
padding: 12px; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
.history-item { |
|
|
.history-item { |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
background: rgba(255, 255, 255, 0.05); |
|
|
border-radius: 8px; |
|
|
border-radius: 8px; |
|
|