fix: update code
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -23,8 +23,8 @@ dist-ssr
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# API database
|
||||
# server/data.db
|
||||
# API database(SQLite 文件,部署时应挂载卷持久化,勿提交)
|
||||
server/data.db
|
||||
|
||||
# Env(含 token,勿提交)
|
||||
.env
|
||||
|
||||
Binary file not shown.
BIN
server/data.db
BIN
server/data.db
Binary file not shown.
@@ -8,9 +8,6 @@ const db = require('./db')
|
||||
const routes = require('./routes')
|
||||
const { getSituation } = require('./situationData')
|
||||
|
||||
const swaggerUi = require('swagger-ui-express')
|
||||
const openApiSpec = require('./openapi')
|
||||
|
||||
const app = express()
|
||||
const PORT = process.env.API_PORT || 3001
|
||||
|
||||
@@ -21,9 +18,6 @@ app.set('trust proxy', 1)
|
||||
app.use(cors())
|
||||
app.use(express.json())
|
||||
|
||||
// Swagger 文档
|
||||
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(openApiSpec))
|
||||
|
||||
app.use('/api', routes)
|
||||
app.get('/api/health', (_, res) => res.json({ ok: true }))
|
||||
app.post('/api/crawler/notify', (req, res) => {
|
||||
|
||||
@@ -155,6 +155,7 @@ export function WarMap() {
|
||||
const fordPathsRef = useRef<[number, number][][]>([])
|
||||
const israelPathsRef = useRef<[number, number][][]>([])
|
||||
const hezbollahPathsRef = useRef<[number, number][][]>([])
|
||||
const hormuzPathsRef = useRef<[number, number][][]>([])
|
||||
const situation = useReplaySituation()
|
||||
const { usForces, iranForces, conflictEvents = [] } = situation
|
||||
|
||||
@@ -220,10 +221,32 @@ export function WarMap() {
|
||||
() => EXTENDED_WAR_ZONES.activeAttacks.map((t) => parabolaPath(HEZBOLLAH_SOURCE, t.coords, 1.5)),
|
||||
[]
|
||||
)
|
||||
// 伊朗不同地点 → 霍尔木兹海峡多点攻击(黄色轨迹)
|
||||
const hormuzTargetPoints = useMemo(
|
||||
() =>
|
||||
[
|
||||
[55.7, 25.6],
|
||||
[56.0, 26.0],
|
||||
[56.4, 26.4],
|
||||
] as [number, number][],
|
||||
[]
|
||||
)
|
||||
const hormuzPaths = useMemo(() => {
|
||||
// 使用更远的伊朗腹地/纵深位置,弧线更明显
|
||||
const sources: [number, number][] = [
|
||||
TEHRAN_SOURCE, // 德黑兰
|
||||
[47.16, 34.35], // 克尔曼沙赫导弹阵地
|
||||
[50.88, 34.64], // 库姆附近
|
||||
]
|
||||
return hormuzTargetPoints.map((target, idx) =>
|
||||
parabolaPath(sources[idx % sources.length], target, 3)
|
||||
)
|
||||
}, [hormuzTargetPoints])
|
||||
lincolnPathsRef.current = lincolnPaths
|
||||
fordPathsRef.current = fordPaths
|
||||
israelPathsRef.current = israelPaths
|
||||
hezbollahPathsRef.current = hezbollahPaths
|
||||
hormuzPathsRef.current = hormuzPaths
|
||||
|
||||
const lincolnLinesGeoJson = useMemo(
|
||||
() => ({
|
||||
@@ -270,6 +293,18 @@ export function WarMap() {
|
||||
[hezbollahPaths]
|
||||
)
|
||||
|
||||
const hormuzLinesGeoJson = useMemo(
|
||||
() => ({
|
||||
type: 'FeatureCollection' as const,
|
||||
features: hormuzPaths.map((coords) => ({
|
||||
type: 'Feature' as const,
|
||||
properties: {},
|
||||
geometry: { type: 'LineString' as const, coordinates: coords },
|
||||
})),
|
||||
}),
|
||||
[hormuzPaths]
|
||||
)
|
||||
|
||||
const attackLinesGeoJson = useMemo(
|
||||
() => ({
|
||||
type: 'FeatureCollection' as const,
|
||||
@@ -295,6 +330,19 @@ export function WarMap() {
|
||||
[]
|
||||
)
|
||||
|
||||
// 霍尔木兹海峡被持续打击的海面目标(用于脉冲与标记)
|
||||
const hormuzTargetsGeoJson = useMemo(
|
||||
() => ({
|
||||
type: 'FeatureCollection' as const,
|
||||
features: hormuzTargetPoints.map((coords, idx) => ({
|
||||
type: 'Feature' as const,
|
||||
properties: { id: `H${idx + 1}` },
|
||||
geometry: { type: 'Point' as const, coordinates: coords },
|
||||
})),
|
||||
}),
|
||||
[hormuzTargetPoints]
|
||||
)
|
||||
|
||||
// 霍尔木兹海峡交战区 & 真主党势力范围(静态面)
|
||||
const hormuzZone = EXTENDED_WAR_ZONES.hormuzCombatZone
|
||||
const hezbollahZone = EXTENDED_WAR_ZONES.hezbollahZone
|
||||
@@ -461,6 +509,24 @@ export function WarMap() {
|
||||
})
|
||||
hezSrc.setData({ type: 'FeatureCollection', features })
|
||||
}
|
||||
// 伊朗对霍尔木兹海峡:黄色光点,沿海峡方向飞行
|
||||
const hormuzSrc = map.getSource('iran-hormuz-dots') as
|
||||
| { setData: (d: GeoJSON.FeatureCollection) => void }
|
||||
| undefined
|
||||
const hormuzPaths = hormuzPathsRef.current
|
||||
if (hormuzSrc && hormuzPaths.length > 0) {
|
||||
const features: GeoJSON.Feature<GeoJSON.Point>[] = hormuzPaths.map((path, i) => {
|
||||
const progress =
|
||||
(elapsed / FLIGHT_DURATION_MS + 0.15 + i / Math.max(hormuzPaths.length, 1)) % 1
|
||||
const coord = interpolateOnPath(path, progress)
|
||||
return {
|
||||
type: 'Feature' as const,
|
||||
properties: {},
|
||||
geometry: { type: 'Point' as const, coordinates: coord },
|
||||
}
|
||||
})
|
||||
hormuzSrc.setData({ type: 'FeatureCollection', features })
|
||||
}
|
||||
// 伊朗被打击目标:蓝色脉冲 (2s 周期), 半径随 zoom 缩放;phase/r/opacity 钳位
|
||||
if (map.getLayer('allied-strike-targets-pulse')) {
|
||||
const cycle = 2000
|
||||
@@ -493,6 +559,15 @@ export function WarMap() {
|
||||
map.setPaintProperty('hezbollah-attack-targets-pulse', 'circle-radius', r)
|
||||
map.setPaintProperty('hezbollah-attack-targets-pulse', 'circle-opacity', opacity)
|
||||
}
|
||||
// 霍尔木兹海峡被打击目标:琥珀黄脉冲,保持与其他被打击点一致但颜色区分
|
||||
if (map.getLayer('iran-hormuz-targets-pulse')) {
|
||||
const cycle = 2000
|
||||
const phase = Math.max(0, Math.min(1, (elapsed % cycle) / cycle))
|
||||
const r = Math.max(0, 32 * phase * zoomScale)
|
||||
const opacity = Math.min(1, Math.max(0, 1 - phase * 1.1))
|
||||
map.setPaintProperty('iran-hormuz-targets-pulse', 'circle-radius', r)
|
||||
map.setPaintProperty('iran-hormuz-targets-pulse', 'circle-opacity', opacity)
|
||||
}
|
||||
} catch (_) {}
|
||||
}
|
||||
animRef.current = requestAnimationFrame(tick)
|
||||
@@ -646,6 +721,74 @@ export function WarMap() {
|
||||
/>
|
||||
</Source>
|
||||
|
||||
{/* 伊朗对霍尔木兹海峡的打击路径(黄色轨迹) */}
|
||||
<Source id="iran-hormuz-lines" type="geojson" data={hormuzLinesGeoJson}>
|
||||
<Layer
|
||||
id="iran-hormuz-lines"
|
||||
type="line"
|
||||
paint={{
|
||||
'line-color': 'rgba(250, 204, 21, 0.55)',
|
||||
'line-width': ['interpolate', ['linear'], ['zoom'], 4, 0.6, 8, 1.2, 12, 2],
|
||||
}}
|
||||
/>
|
||||
</Source>
|
||||
{/* 伊朗对霍尔木兹的打击光点(黄色) */}
|
||||
<Source
|
||||
id="iran-hormuz-dots"
|
||||
type="geojson"
|
||||
data={{
|
||||
type: 'FeatureCollection',
|
||||
features: hormuzPaths.map((path) => ({
|
||||
type: 'Feature' as const,
|
||||
properties: {},
|
||||
geometry: { type: 'Point' as const, coordinates: path[0] },
|
||||
})),
|
||||
}}
|
||||
>
|
||||
<Layer
|
||||
id="iran-hormuz-dots-glow"
|
||||
type="circle"
|
||||
paint={{
|
||||
'circle-radius': ['interpolate', ['linear'], ['zoom'], 4, 3, 8, 5.5, 12, 9],
|
||||
'circle-color': 'rgba(250, 204, 21, 0.65)',
|
||||
'circle-blur': 0.3,
|
||||
}}
|
||||
/>
|
||||
<Layer
|
||||
id="iran-hormuz-dots-core"
|
||||
type="circle"
|
||||
paint={{
|
||||
'circle-radius': ['interpolate', ['linear'], ['zoom'], 4, 1.2, 8, 2.2, 12, 3.8],
|
||||
'circle-color': '#facc15',
|
||||
'circle-stroke-width': 0.6,
|
||||
'circle-stroke-color': '#fff',
|
||||
}}
|
||||
/>
|
||||
</Source>
|
||||
|
||||
{/* 霍尔木兹海峡被打击目标点 + 脉冲(与其他被打击点风格一致,颜色区分为琥珀黄) */}
|
||||
<Source id="iran-hormuz-targets" type="geojson" data={hormuzTargetsGeoJson}>
|
||||
<Layer
|
||||
id="iran-hormuz-targets-dot"
|
||||
type="circle"
|
||||
paint={{
|
||||
'circle-radius': ['interpolate', ['linear'], ['zoom'], 4, 2, 8, 3.5, 12, 5],
|
||||
'circle-color': '#fbbf24',
|
||||
'circle-stroke-width': 0.5,
|
||||
'circle-stroke-color': '#fff',
|
||||
}}
|
||||
/>
|
||||
<Layer
|
||||
id="iran-hormuz-targets-pulse"
|
||||
type="circle"
|
||||
paint={{
|
||||
'circle-radius': 0,
|
||||
'circle-color': 'rgba(251, 191, 36, 0.45)',
|
||||
'circle-opacity': 0,
|
||||
}}
|
||||
/>
|
||||
</Source>
|
||||
|
||||
<Source id="points-us-base-damaged" type="geojson" data={usBaseDamaged}>
|
||||
<Layer
|
||||
id="points-damaged"
|
||||
@@ -1259,14 +1402,14 @@ export function WarMap() {
|
||||
type="symbol"
|
||||
layout={{
|
||||
'text-field': ['get', 'name'],
|
||||
// 字体尽量小一些,避免遮挡
|
||||
'text-size': ['interpolate', ['linear'], ['zoom'], 4, 7, 7, 9, 10, 11],
|
||||
// 字体进一步调小,避免与该区域多重效果叠加后显得拥挤
|
||||
'text-size': ['interpolate', ['linear'], ['zoom'], 4, 5.5, 7, 7.5, 10, 9],
|
||||
'text-anchor': 'center',
|
||||
}}
|
||||
paint={{
|
||||
'text-color': '#FACC15',
|
||||
'text-halo-color': '#1a1a1a',
|
||||
'text-halo-width': 1,
|
||||
'text-halo-width': 0.8,
|
||||
}}
|
||||
/>
|
||||
</Source>
|
||||
|
||||
9
start.sh
9
start.sh
@@ -20,7 +20,14 @@ echo "==> Checking crawler Python deps..."
|
||||
pip install -q -r crawler/requirements.txt 2>/dev/null || true
|
||||
|
||||
echo "==> Seeding database (if needed)..."
|
||||
[ ! -f server/data.db ] && npm run api:seed
|
||||
# 若指定了 DB_PATH,则以 DB_PATH 为准;否则默认使用 server/data.db
|
||||
DB_FILE_PATH="${DB_PATH:-server/data.db}"
|
||||
if [ ! -f "$DB_FILE_PATH" ]; then
|
||||
echo " - DB file not found at $DB_FILE_PATH, running api:seed once"
|
||||
npm run api:seed
|
||||
else
|
||||
echo " - Existing DB detected at $DB_FILE_PATH, skip seeding"
|
||||
fi
|
||||
|
||||
echo "==> Starting API (http://localhost:3001)..."
|
||||
npm run api &
|
||||
|
||||
Reference in New Issue
Block a user