Files
aiData/static/js/app.js

137 lines
3.8 KiB
JavaScript
Raw Normal View History

2026-01-18 16:08:46 +08:00
const {createApp,onMounted,ref} = Vue
2026-01-19 13:56:47 +08:00
2026-01-18 16:08:46 +08:00
createApp({
setup(){
const apiBase = ref(window.location.origin || "http://localhost:8000")
2026-01-19 13:56:47 +08:00
const operators = ref([
{label:"新电途",value:"新电途"},
{label:"特来电",value:"特来电"},
{label:"驿来特",value:"驿来特"},
{label:"艾特吉易充",value:"艾特吉易充"}
])
const selectedOperator = ref("驿来特")
2026-01-18 16:08:46 +08:00
const aiText = ref("")
2026-01-19 13:56:47 +08:00
const placeholder = ref("点击左侧按钮查询四家供应商最新24小时分时电价,再使用右侧AI综合分析功能对各司定价策略进行对比。")
2026-01-18 16:08:46 +08:00
const loading = ref(false)
const aiLoading = ref(false)
const priceTableRows = ref([])
2026-01-19 13:56:47 +08:00
const hourlyPricesByOperator = ref({})
2026-01-18 16:08:46 +08:00
let chartInstance = null
2026-01-19 13:56:47 +08:00
2026-01-18 16:08:46 +08:00
const initChart = () => {
const dom = document.getElementById("chart")
if (dom && !chartInstance) {
chartInstance = echarts.init(dom)
}
}
2026-01-19 13:56:47 +08:00
const buildPriceTable = () => {
2026-01-18 16:08:46 +08:00
const rows = []
2026-01-19 13:56:47 +08:00
for (let h = 0; h < 24; h++) {
const row = {hour: (h.toString().padStart(2,"0") + ":00"), values: []}
operators.value.forEach(op => {
const series = hourlyPricesByOperator.value[op.value] || []
const price = series[h] !== undefined ? series[h] : null
row.values.push({operator: op.value, price})
2026-01-18 16:08:46 +08:00
})
rows.push(row)
}
priceTableRows.value = rows
2026-01-19 13:56:47 +08:00
if (chartInstance) {
const series = operators.value.map(op => {
const seriesData = []
for (let h = 0; h < 24; h++) {
const list = hourlyPricesByOperator.value[op.value] || []
seriesData.push(list[h] !== undefined ? list[h] : null)
}
return {name: op.label, type:"line", smooth:true, data:seriesData}
2026-01-18 16:08:46 +08:00
})
2026-01-19 13:56:47 +08:00
const hours = rows.map(r => r.hour)
2026-01-18 16:08:46 +08:00
const option = {
tooltip:{trigger:"axis"},
2026-01-19 13:56:47 +08:00
legend:{data:operators.value.map(o=>o.label),textStyle:{color:"#e5e7eb"}},
2026-01-18 16:08:46 +08:00
xAxis:{type:"category",data:hours,axisLine:{lineStyle:{color:"#4b5563"}},axisLabel:{color:"#9ca3af"}},
yAxis:{type:"value",name:"元/度",axisLine:{lineStyle:{color:"#4b5563"}},axisLabel:{color:"#9ca3af"},splitLine:{lineStyle:{color:"#111827"}}},
grid:{left:40,right:20,top:30,bottom:30},
series:series
}
chartInstance.setOption(option)
2026-01-19 13:56:47 +08:00
}
}
const loadAllOperatorsPrices = async () => {
loading.value = true
try{
const res = await axios.get(apiBase.value + "/api/operators/hourly-prices")
if (res && res.data && Array.isArray(res.data.operators)) {
const dict = {}
res.data.operators.forEach(item => {
dict[item.operator] = item.series || []
})
hourlyPricesByOperator.value = dict
buildPriceTable()
}
2026-01-18 16:17:09 +08:00
}catch(e){
console.error(e)
2026-01-18 16:08:46 +08:00
}finally{
loading.value = false
}
}
2026-01-19 13:56:47 +08:00
const loadOperatorPrices = async () => {
if (!selectedOperator.value) return
await loadAllOperatorsPrices()
}
const exportAllPrices = async () => {
try{
loading.value = true
const res = await axios.get(apiBase.value + "/api/export/prices-zip",{responseType:"blob"})
const blob = new Blob([res.data],{type:"application/zip"})
const url = window.URL.createObjectURL(blob)
const a = document.createElement("a")
a.href = url
a.download = "多供应商电价导出.zip"
document.body.appendChild(a)
a.click()
document.body.removeChild(a)
window.URL.revokeObjectURL(url)
}catch(e){
console.error(e)
}finally{
loading.value = false
2026-01-18 16:08:46 +08:00
}
}
2026-01-19 13:56:47 +08:00
const startAiAnalysis = async () => {
if (aiLoading.value) return
2026-01-18 16:08:46 +08:00
aiText.value = ""
aiLoading.value = true
2026-01-19 13:56:47 +08:00
try{
const res = await axios.get(apiBase.value + "/api/ai/pricing/strategy-summary")
aiText.value = res.data && res.data.summary ? res.data.summary : ""
}catch(e){
console.error(e)
}finally{
2026-01-18 16:08:46 +08:00
aiLoading.value = false
}
}
2026-01-19 13:56:47 +08:00
2026-01-18 16:08:46 +08:00
onMounted(()=>{
initChart()
2026-01-19 13:56:47 +08:00
loadAllOperatorsPrices()
2026-01-18 16:08:46 +08:00
})
2026-01-19 13:56:47 +08:00
2026-01-18 16:08:46 +08:00
const formatCell = v => {
if (v === null || v === undefined || v === "") return "-"
if (typeof v === "number") {
if (Number.isNaN(v)) return "-"
return v.toFixed(2)
}
return v
}
2026-01-19 13:56:47 +08:00
return {apiBase,operators,selectedOperator,aiText,placeholder,loading,aiLoading,priceTableRows,loadOperatorPrices,loadAllOperatorsPrices,exportAllPrices,startAiAnalysis,formatCell}
2026-01-18 16:08:46 +08:00
}
}).mount("#app")