|
|
@@ -103,9 +103,9 @@ function _camerasToArmTypes(cameras) {
|
|
|
return result
|
|
|
}
|
|
|
|
|
|
-function _makeIntersectionConfig(id, name) {
|
|
|
+function _makeIntersectionConfig(id, name, { fixedNsGreen } = {}) {
|
|
|
const phases = ['南北直行', '东西直行', '北单放', '东单放']
|
|
|
- const nsGreen = Math.random() > 0.5
|
|
|
+ const nsGreen = fixedNsGreen !== undefined ? fixedNsGreen : true
|
|
|
const countdown = 10 + Math.floor(Math.random() * 50)
|
|
|
const seed = id ? Array.from(id).reduce((s, c, i) => s + c.charCodeAt(0) * (i + 1), 0) : 0
|
|
|
|
|
|
@@ -314,7 +314,7 @@ export async function apiGetPoints(filters = {}) {
|
|
|
* GET /api/intersections/:id — 路口详情
|
|
|
* 信号倒计时每次请求动态变化
|
|
|
*/
|
|
|
-export async function apiGetIntersectionData(id) {
|
|
|
+export async function apiGetIntersectionData(id, { fixedNsGreen } = {}) {
|
|
|
await delay(250)
|
|
|
const base = DB.intersectionConfigs[id]
|
|
|
const point = DB.points.find(p => p.id === id)
|
|
|
@@ -324,16 +324,17 @@ export async function apiGetIntersectionData(id) {
|
|
|
const nowSec = Math.floor(Date.now() / 1000)
|
|
|
const cycle = 140
|
|
|
const elapsed = nowSec % cycle
|
|
|
- const nsGreen = elapsed < cycle / 2
|
|
|
+ const nsGreenVal = fixedNsGreen !== undefined ? fixedNsGreen : true
|
|
|
+ const nsGreen = nsGreenVal
|
|
|
|
|
|
const config = base ? {
|
|
|
signals: {
|
|
|
- ns: { ...base.signals.ns, time: nsGreen ? (cycle / 2 - elapsed) : elapsed - cycle / 2, isGreen: nsGreen },
|
|
|
- ew: { ...base.signals.ew, time: nsGreen ? elapsed : (cycle - elapsed), isGreen: !nsGreen },
|
|
|
+ ns: { ...base.signals.ns, time: Math.max(1, cycle - elapsed), isGreen: nsGreen },
|
|
|
+ ew: { ...base.signals.ew, time: elapsed || 1, isGreen: !nsGreen },
|
|
|
},
|
|
|
armsConfig: base.armsConfig,
|
|
|
cameras: base.cameras,
|
|
|
- } : _makeIntersectionConfig(id, point ? point.name : id)
|
|
|
+ } : _makeIntersectionConfig(id, point ? point.name : id, { fixedNsGreen: nsGreenVal })
|
|
|
|
|
|
return ok({
|
|
|
...config,
|
|
|
@@ -686,7 +687,7 @@ export async function apiUpgradeDevice(id, file) {
|
|
|
* GET /api/special-task/:id/monitor — 特勤监控面板
|
|
|
* 信号灯倒计时随真实时间变化
|
|
|
*/
|
|
|
-export async function apiGetSpecialTaskMonitorData(id) {
|
|
|
+export async function apiGetSpecialTaskMonitorData(id, { fixedNsGreen } = {}) {
|
|
|
await delay(400)
|
|
|
|
|
|
// 用 id 生成稳定 seed,兼容数字/字符串/undefined
|
|
|
@@ -741,8 +742,8 @@ export async function apiGetSpecialTaskMonitorData(id) {
|
|
|
const jncSeed = Array.from(jnc.id).reduce((s, c, idx) => s + c.charCodeAt(0) * (idx + 1), 0)
|
|
|
const cycle = [100, 120, 130, 140, 150][jncSeed % 5]
|
|
|
const elapsed = nowSec % cycle
|
|
|
- const nsGreen = elapsed < cycle / 2
|
|
|
- const countdown = nsGreen ? (cycle / 2 - elapsed) : (cycle - elapsed)
|
|
|
+ const nsGreen = fixedNsGreen !== undefined ? fixedNsGreen : true
|
|
|
+ const countdown = Math.max(1, cycle - elapsed)
|
|
|
const laneSet = lanePresets[jncSeed % lanePresets.length]
|
|
|
|
|
|
// 用摄像机字段结构生成,再推导 cameraType
|
|
|
@@ -785,7 +786,7 @@ export async function apiGetSpecialTaskMonitorData(id) {
|
|
|
export async function apiGetCrossingPanelData(id) {
|
|
|
await delay(300)
|
|
|
const point = DB.points.find(p => p.id === id)
|
|
|
- const config = DB.intersectionConfigs[id] || _makeIntersectionConfig()
|
|
|
+ const config = DB.intersectionConfigs[id] || _makeIntersectionConfig(id, null, { fixedNsGreen: true })
|
|
|
const seed = id ? id.charCodeAt(id.length - 1) : 0
|
|
|
|
|
|
const preset = DB.signalTimings[id]
|
|
|
@@ -812,7 +813,7 @@ export async function apiGetCrossingPanelData(id) {
|
|
|
export async function apiGetCrossingDetailData(id) {
|
|
|
await delay(350)
|
|
|
const point = DB.points.find(p => p.id === id)
|
|
|
- const config = DB.intersectionConfigs[id] || _makeIntersectionConfig()
|
|
|
+ const config = DB.intersectionConfigs[id] || _makeIntersectionConfig(id, null, { fixedNsGreen: true })
|
|
|
|
|
|
// 用 id 的全部字符生成稳定 seed(加权位置避免 charCode 总和碰撞)
|
|
|
const seed = id ? Array.from(id).reduce((s, c, i) => s + c.charCodeAt(0) * (i + 1), 0) : 0
|