тест 6
This commit is contained in:
35
app.py
35
app.py
@@ -1404,6 +1404,39 @@ def vmix_standings(session_token: str):
|
|||||||
for row in rows
|
for row in rows
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class MatchChannelPayload(BaseModel):
|
||||||
|
match_external_id: str
|
||||||
|
channel: str = ""
|
||||||
|
|
||||||
|
@app.post("/admin/session/{session_token}/schedule/channel")
|
||||||
|
def update_schedule_channel(session_token: str, payload: MatchChannelPayload):
|
||||||
|
session_row = get_match_session_by_token(session_token)
|
||||||
|
if not session_row:
|
||||||
|
return JSONResponse({"error": "session_not_found"}, status_code=404)
|
||||||
|
|
||||||
|
allowed = {"", "match", "match_premier", "match_and_premier"}
|
||||||
|
if payload.channel not in allowed:
|
||||||
|
return JSONResponse({"error": "invalid_channel"}, status_code=400)
|
||||||
|
|
||||||
|
conn = get_connection()
|
||||||
|
try:
|
||||||
|
with conn.cursor() as cur:
|
||||||
|
cur.execute(
|
||||||
|
"""
|
||||||
|
UPDATE matches
|
||||||
|
SET channel = %s
|
||||||
|
WHERE external_id = %s
|
||||||
|
""",
|
||||||
|
(payload.channel, payload.match_external_id),
|
||||||
|
)
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
return {"success": True}
|
||||||
|
except Exception as e:
|
||||||
|
conn.rollback()
|
||||||
|
return JSONResponse({"error": str(e)}, status_code=500)
|
||||||
|
finally:
|
||||||
|
conn.close()
|
||||||
|
|
||||||
@app.get("/vmix/session/{session_token}/schedule")
|
@app.get("/vmix/session/{session_token}/schedule")
|
||||||
def vmix_schedule(session_token: str):
|
def vmix_schedule(session_token: str):
|
||||||
@@ -1431,7 +1464,7 @@ def vmix_schedule(session_token: str):
|
|||||||
),
|
),
|
||||||
"mask_time": "#FFFFFF00" if row[2] is not None and row[3] is not None else "#FFFFFF",
|
"mask_time": "#FFFFFF00" if row[2] is not None and row[3] is not None else "#FFFFFF",
|
||||||
"mask_score": "#FFFFFF00" if row[2] is None and row[3] is None else "#FFFFFF",
|
"mask_score": "#FFFFFF00" if row[2] is None and row[3] is None else "#FFFFFF",
|
||||||
"channel": row[6] or "",
|
"channel": row[7] or "",
|
||||||
}
|
}
|
||||||
for row in rows
|
for row in rows
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -210,7 +210,8 @@ def get_vmix_schedule(session_token: str):
|
|||||||
m.away_score,
|
m.away_score,
|
||||||
m.match_date,
|
m.match_date,
|
||||||
m.status,
|
m.status,
|
||||||
m.id
|
m.id,
|
||||||
|
m.chanell
|
||||||
FROM matches m
|
FROM matches m
|
||||||
LEFT JOIN teams t1 ON m.home_team_id = t1.id
|
LEFT JOIN teams t1 ON m.home_team_id = t1.id
|
||||||
LEFT JOIN teams t2 ON m.away_team_id = t2.id
|
LEFT JOIN teams t2 ON m.away_team_id = t2.id
|
||||||
|
|||||||
@@ -3725,3 +3725,37 @@ function getTourChannelLogoPath(matchId) {
|
|||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function saveTourChannel(matchExternalId) {
|
||||||
|
const channel = buildChannelValue(matchExternalId);
|
||||||
|
|
||||||
|
const res = await fetch(`/admin/session/${MATCH_DATA.sessionToken}/schedule/channel`, {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
match_external_id: String(matchExternalId),
|
||||||
|
channel
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
alert("Не удалось сохранить канал");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildChannelValue(matchId) {
|
||||||
|
const checked = Array.from(
|
||||||
|
document.querySelectorAll(`.tour-channel-checkbox[data-match-id="${matchId}"]:checked`)
|
||||||
|
).map(el => el.dataset.channel);
|
||||||
|
|
||||||
|
const hasMatch = checked.includes("match");
|
||||||
|
const hasPremier = checked.includes("match_premier");
|
||||||
|
|
||||||
|
if (hasMatch && hasPremier) return "match_and_premier";
|
||||||
|
if (hasPremier) return "match_premier";
|
||||||
|
if (hasMatch) return "match";
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
@@ -978,26 +978,34 @@ data-role="{{ p.position or '' }}"
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td class="tour-channel-cell">
|
<td class="tour-channel-cell">
|
||||||
<label>
|
{% set channel = m.channel or "" %}
|
||||||
|
|
||||||
|
<label class="channel-check">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="tour-channel-checkbox"
|
class="tour-channel-checkbox"
|
||||||
data-channel="match"
|
data-channel="match"
|
||||||
data-match-id="{{ m.match_external_id }}"
|
data-match-id="{{ m.match_external_id }}"
|
||||||
|
onchange="saveTourChannel('{{ m.match_external_id }}')"
|
||||||
|
{% if channel in ['match', 'match_and_premier'] %}checked{% endif %}
|
||||||
>
|
>
|
||||||
Матч
|
Матч
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label>
|
<label class="channel-check">
|
||||||
<input
|
<input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
class="tour-channel-checkbox"
|
class="tour-channel-checkbox"
|
||||||
data-channel="match_premier"
|
data-channel="match_premier"
|
||||||
data-match-id="{{ m.match_external_id }}"
|
data-match-id="{{ m.match_external_id }}"
|
||||||
|
onchange="saveTourChannel('{{ m.match_external_id }}')"
|
||||||
|
{% if channel in ['match_premier', 'match_and_premier'] %}checked{% endif %}
|
||||||
>
|
>
|
||||||
Матч Премьер
|
Матч Премьер
|
||||||
</label>
|
</label>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
Reference in New Issue
Block a user