This commit is contained in:
2026-07-20 06:01:51 +07:00
parent 1ed246eec8
commit aed692cffe
12 changed files with 67 additions and 64 deletions

View File

@@ -8,8 +8,8 @@ import (
"crypto/cipher"
"crypto/rand"
"crypto/sha256"
"encoding/json"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"html"
@@ -59,7 +59,7 @@ func getWsUrl(apiBase string) string {
return "ws://" + apiBase
}
var wifiReportLast sync.Map // ssidKey -> time.Time
var wifiReportLast sync.Map // ssidKey -> time.Time
func getDynamicEncryptionKey() []byte {
base := "simple-care-proctor-secretkey32!"
@@ -120,45 +120,45 @@ type StudentData struct {
}
type App struct {
ctx context.Context
student *StudentData
mu sync.Mutex
sessionPath string
statsPath string
webviewDataPath string
pendingViolPath string
runLockPath string
wsConn *websocket.Conn
wsConnected bool
wsConnecting bool
wsBackoff time.Duration
wsWriteMu sync.Mutex
wifiSSID string
wifiBSSID string
allowedApps string
onlineSecs int
offlineSecs int
unsyncedOn int
unsyncedOff int
lastSyncTime time.Time
isStreamingSc bool
streamScStop chan struct{}
isStreamingCam bool
streamCamStop chan struct{}
ctx context.Context
student *StudentData
mu sync.Mutex
sessionPath string
statsPath string
webviewDataPath string
pendingViolPath string
runLockPath string
wsConn *websocket.Conn
wsConnected bool
wsConnecting bool
wsBackoff time.Duration
wsWriteMu sync.Mutex
wifiSSID string
wifiBSSID string
allowedApps string
onlineSecs int
offlineSecs int
unsyncedOn int
unsyncedOff int
lastSyncTime time.Time
isStreamingSc bool
streamScStop chan struct{}
isStreamingCam bool
streamCamStop chan struct{}
statusMsg string
expectingLogin bool
needsClearPortalStorage bool
backendOnline bool
dashboard StudentDashboardSnapshot
wifiEnforce bool
acceptedWifi map[string]bool
wifiRejected bool
quitDialogShown bool
monitoringTornDown bool
localBrowserActive bool // trình duyệt local — chỉ cho phép localhost
chatUnread int
replyStaffID uint
fetchAppsMu sync.Mutex
dashboard StudentDashboardSnapshot
wifiEnforce bool
acceptedWifi map[string]bool
wifiRejected bool
quitDialogShown bool
monitoringTornDown bool
localBrowserActive bool // trình duyệt local — chỉ cho phép localhost
chatUnread int
replyStaffID uint
fetchAppsMu sync.Mutex
}
type LocalStats struct {
@@ -219,13 +219,13 @@ func NewApp() *App {
_ = os.MkdirAll(webviewDir, 0755)
return &App{
sessionPath: filepath.Join(appDir, "student_session.json"),
statsPath: filepath.Join(appDir, "student_stats.json"),
webviewDataPath: webviewDir,
pendingViolPath: filepath.Join(appDir, "pending_violations.json"),
runLockPath: filepath.Join(appDir, "monitoring.lock"),
lastSyncTime: time.Now(),
expectingLogin: false,
sessionPath: filepath.Join(appDir, "student_session.json"),
statsPath: filepath.Join(appDir, "student_stats.json"),
webviewDataPath: webviewDir,
pendingViolPath: filepath.Join(appDir, "pending_violations.json"),
runLockPath: filepath.Join(appDir, "monitoring.lock"),
lastSyncTime: time.Now(),
expectingLogin: false,
}
}
@@ -1473,12 +1473,12 @@ func (a *App) fetchAllowedApps(classId int64) {
reason = "Không đáp ứng điều kiện học tập (chưa cấu hình ứng dụng được phép hoặc ngoài giờ học)."
}
log.Printf("[CLIENT] Conditions not met: %s. Blocker suspended.", reason)
a.mu.Lock()
a.allowedApps = ""
a.statusMsg = reason
a.mu.Unlock()
blocker.Instance.Stop()
return
}
@@ -1490,7 +1490,7 @@ func (a *App) fetchAllowedApps(classId int64) {
a.statusMsg = "Đang trong giờ học"
}
a.mu.Unlock()
log.Printf("[CLIENT] Allowed apps fetched from server: %s", res.Keywords)
blocker.Instance.SetKeywords(res.Keywords)
blocker.Instance.Start()
@@ -2401,7 +2401,7 @@ func (a *App) DownloadExamResource(fileID uint) (string, error) {
// LoadExamViewFile tải file đề/tài nguyên qua Go (không mở URL trực tiếp trong WebView).
func (a *App) LoadExamViewFile(fileURL string) (map[string]any, error) {
fileURL = strings.TrimSpace(fileURL)
if !strings.HasPrefix(fileURL, API_BASE + "/api/student/exam/download") {
if !strings.HasPrefix(fileURL, API_BASE+"/api/student/exam/download") {
return nil, errors.New("URL không hợp lệ")
}
if _, _, err := a.examStudentContext(); err != nil {
@@ -2477,7 +2477,7 @@ func (a *App) SubmitExamWork() (string, error) {
}
_ = w.Close()
req, err := http.NewRequest("POST", API_BASE + "/api/student/exam/submit", &body)
req, err := http.NewRequest("POST", API_BASE+"/api/student/exam/submit", &body)
if err != nil {
return "", err
}