ẢNH VÀ LƯU ẢNH
Tôi sẽ giải nén và xem cấu trúc project trước.
Mình đã đọc xong code: project đã có sẵn kho ảnh dùng chung (E.P.Images) nhưng chỉ dùng cho Motor/icon, chưa có ảnh nào kéo ra canvas được. Mình đang thêm: (1) panel “THƯ VIỆN ẢNH” trong Toolbox (kéo file từ máy vào để lưu), (2) widget “Picture” kéo từ thư viện ra canvas, (3) endpoint /img/{id} để ảnh cache nhanh. Đang viết code.
Đã xong phần C# (Models, Home.razor, endpoint /img, widget Picture). Đang viết nốt JS kéo-thả file + CSS cho thư viện ảnh, rồi kiểm tra lại cú pháp và đóng gói zip.
Mình đã thêm “THƯ VIỆN ẢNH” vào Toolbox, nhưng chưa build hay chạy thử vì môi trường này không có .NET SDK. Bạn build lại và thử một lượt; nếu có lỗi biên dịch thì gửi mình dòng lỗi, mình sửa ngay.
Trước đây project đã có kho ảnh dùng chung (E.P.Images) nhưng chỉ Motor và icon menu dùng, chưa kéo ảnh ra canvas được. Mình dùng lại kho đó nên ảnh cũ vẫn xuất hiện trong thư viện mới.
Cách dùng trong chế độ thiết kế
- Đưa ảnh vào thư viện: kéo file ảnh từ máy thả vào khung “Kéo ảnh vào đây” trong Toolbox. Bấm vào khung để chọn file cũng được, chọn nhiều file một lúc. Ảnh trùng hệt ảnh đã có thì dùng lại, không thêm bản thứ hai.
- Vẽ giao diện: kéo từng ảnh trong thư viện ra canvas. Ảnh thành widget mới tên Picture, đúng tỉ lệ ảnh gốc (tối đa 480 px cạnh dài) và nằm giữa chỗ thả.
- Thả file thẳng lên canvas: ảnh tự lưu vào thư viện và đặt luôn tại chỗ thả.
- Chỉnh ảnh: chọn ảnh, mục PROPERTIES cho đổi sang ảnh khác trong thư viện, chọn cách hiển thị (vừa khung, kéo giãn, phủ kín) và hai nút “Đúng tỉ lệ”, “Kích thước gốc”. Nút ⇩ đưa ảnh xuống dưới cùng để làm nền sơ đồ.
- Quản lý thư viện: rê chuột lên ảnh để hiện ✎ đổi tên và ✕ xoá. Ảnh đang được dùng thì phải bấm “Xoá?” lần nữa mới xoá.
Các thay đổi nhằm cho nhanh
- Widget tải ảnh qua đường dẫn
/img/{id}nên trình duyệt chỉ tải một lần dù có nhiều Picture dùng cùng ảnh. Trước đây ảnh đi dưới dạng base64 qua SignalR. - Ảnh lớn hơn 2000 px được thu nhỏ trước khi lưu để
project.jsonkhông phình ra. SVG và GIF giữ nguyên, tối đa 12 MB mỗi ảnh. Chỉ tài khoản Admin tải ảnh lên được. - Ở Runtime, ảnh Picture không chặn thao tác bấm vào các widget nằm dưới, trừ khi bạn gán Popup Screen cho ảnh đó. Trên điện thoại ở chế độ Thẻ, ảnh bị ẩn vì chỉ là hình trang trí.
Ảnh đã tải lên từ Motor hoặc icon menu trước đây chưa có kích thước gốc. Khi kéo ra canvas chúng ra cỡ 160×120 và hai nút “Đúng tỉ lệ”, “Kích thước gốc” bị tắt. Ảnh tải lên từ thư viện mới thì đầy đủ. Mình chưa làm dán ảnh bằng Ctrl+V, vì phím tắt đó đang dùng để dán widget.
Các file chính cần xem là Components/Home.razor, Components/PictureProps.razor (mới), Program.cs (thêm hai endpoint ảnh) và wwwroot/scada.js. Mình cũng thêm HUONG_DAN_THU_VIEN_ANH.md trong zip.
Files are in /tmp/claude-0/-home-claude/d09bac15-59d6-529b-b205-da5ae1f15668/scratchpad:
- ScadaWeb_thu_vien_anh.zip
- thu_vien_anh.diff
Mỗi màn hình giờ có màu nền riêng, đặt trong mục MÀN HÌNH ở bảng bên phải, ngay dưới ô icon. Mình chưa build hay chạy thử (không có .NET SDK ở đây), nên bạn build lại rồi thử giúp mình.
- Cách đặt màu: bấm ô chọn màu để lấy màu bất kỳ, hoặc bấm một trong 6 màu mẫu (xanh đậm mặc định, đen, xanh than, xám xanh, trắng, xám nhạt). Nút ↺ đưa về màu mặc định.
- Màu riêng từng màn hình: màu lưu theo từng màn hình, nên Network, Mường Hum, IEC61580… mỗi nơi đặt một màu khác nhau. Màn hình chưa đặt màu vẫn dùng màu cũ.
- Phạm vi áp dụng: màu hiện cả ở chế độ thiết kế lẫn Runtime, gồm vùng nền ngoài canvas, chế độ Thẻ trên điện thoại và cửa sổ popup screen.
- Lưới ô trong chế độ thiết kế: lưới vẫn giữ màu xanh tối, nên nếu chọn nền sáng như trắng thì lưới chỉ mờ mờ, không biến mất. Runtime không có lưới.
Gói zip vẫn là bản đầy đủ, gồm cả thư viện ảnh làm trước đó. Các chỗ sửa nằm trong
Models.cs,Components/Home.razorvàwwwroot/app.css.Files are in /tmp/claude-0/-home-claude/d09bac15-59d6-529b-b205-da5ae1f15668/scratchpad:
- ScadaWeb_thu_vien_anh.zipẢnh không lưu thành file riêng. Chúng nằm ngay trong file
project.json, mã hoá base64 trong mụcImages, cùng chỗ với các màn hình và widget.File đó nằm trong thư mục dữ liệu của ScadaWeb, không nằm cạnh
ScadaWeb.exe. Thứ tự tìm thư mục (theoDataPaths.cs):- Biến môi trường
SCADA_DATA_DIR, nếu có đặt. - Đường dẫn trong file
datapath.txtcạnh exe, nếu có. - Mặc định:
C:\ProgramData\ScadaWeb\project.json.
Vì vậy build lại hay publish đè không làm mất ảnh. Chương trình tự sao lưu vào
backup\cùng thư mục dữ liệu, và “Xuất project (.zip)” cũng mang ảnh theo. Muốn chuyển sang máy khác thì chépproject.jsonhoặc dùng bản xuất .zip.Ảnh lưu trong
project.jsonnên file sẽ to dần khi thêm nhiều ảnh. Mình đã giới hạn cạnh dài 2000 px để đỡ phình, nhưng nếu bạn dùng hàng chục ảnh lớn thì việc lưu sẽ chậm hơn. Nếu muốn, mình đổi sang lưu mỗi ảnh thành file riêng trong thư mụcimages\cạnhproject.json(project.json nhẹ hơn, bạn mở thư mục xem được ảnh). Việc này phải sửa thêm phần xuất/nhập project cho khớp.Đang làm: ảnh giờ lưu thành file riêng trongProgramData\ScadaWeb\images(project.json cũ tự chuyển sang). Đã xong phần lưu file, nút “Dọn ảnh chưa dùng”, xuất/nhập zip. Đang viết nốt phần backup (backup không ảnh, backup ảnh riêng, backup full) trong DataRecovery.cs rồi kiểm tra lại.Ảnh giờ lưu thành file riêng trong
C:\ProgramData\ScadaWeb\images, backup tách làm ba loại, và thư viện có nút dọn ảnh. Mình chưa build hay chạy thử (không có .NET SDK ở đây), nên bạn build lại rồi thử giúp mình. Lần khởi động đầu tiên nên sao lưuproject.jsonra chỗ khác trước, phòng khi lỗi.Thư mục
images- Mỗi ảnh là một file tên dạng
TenAnh_a1b2c3d4.png, mở ra xem hoặc copy được ngay. Đổi tên ảnh trong thư viện thì tên file đổi theo. project.jsonchỉ còn giữ tên, id và kích thước ảnh nên nhẹ đi nhiều.- Project cũ có ảnh nhúng trong
project.jsonsẽ tự chuyển sang file khi khởi động lại. - Ảnh của Motor và icon menu dùng chung kho này, và giờ tải qua
/img/...nên cũng nhanh hơn.
Ba loại backup trong thư mục
backup- Không ảnh:
backup\project_*.jsonvàusers_*.jsongiờ chỉ chứa cấu hình, nên rất nhỏ. - Ảnh riêng:
backup\images\chỉ chép ảnh mới hoặc ảnh đã đổi.- Ảnh bạn xoá khỏi thư viện được chuyển sang
backup\images\_da_xoa\và giữ thêm 30 ngày rồi mới xoá hẳn, để lỡ xoá nhầm vẫn lấy lại được.
- Ảnh bạn xoá khỏi thư viện được chuyển sang
- Full:
backup\full\full_*.zipgồm cấu hình, ảnh và các thư mục khác.- Tạo tối đa một bản mỗi 6 giờ và chỉ khi có thay đổi, giữ 7 bản gần nhất.
- File này dùng được thẳng ở nút “Nhập project (.zip)”.
Xoá ảnh cho thư viện khỏi phình
- Nút ✕ trên từng ảnh xoá cả file trong
images. Ảnh đang được dùng thì phải bấm “Xoá?” lần nữa. - Nút 🧹 Dọn ảnh chưa dùng liệt kê các ảnh không còn widget hay icon nào dùng, bấm lần nữa mới xoá.
- Phía trên danh sách có tổng số ảnh và dung lượng, và panel hiện đường dẫn thư mục
images.
Xuất và nhập project (.zip) giờ mang theo thư mục
images. Khi nhập, ảnh được gộp vào chứ không xoá ảnh đang có; ảnh thừa thì dọn bằng nút trên.Các file chính đã sửa là
ImageStore.cs(mới),Models.cs,DataRecovery.cs,ProjectPackage.cs,Program.csvàComponents/Home.razor. Mình cũng cập nhậtHUONG_DAN_THU_VIEN_ANH.mdtrong zip.Files are in /tmp/claude-0/-home-claude/d09bac15-59d6-529b-b205-da5ae1f15668/scratchpad:
- ScadaWeb_thu_vien_anh.zip
- Biến môi trường

