feat: update footer with site policies, add CTA retrieval SQL, and refactor block content management
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
(function (el) {
|
||||
if (!el) {
|
||||
console.error("Vui lòng chọn thẻ HTML bên tab Elements trước!");
|
||||
return;
|
||||
}
|
||||
const clone = el.cloneNode(true);
|
||||
function applyStyles(original, cloned) {
|
||||
const computed = window.getComputedStyle(original);
|
||||
let styleString = "";
|
||||
for (let i = 0; i < computed.length; i++) {
|
||||
const prop = computed[i];
|
||||
const val = computed.getPropertyValue(prop);
|
||||
if (val && val !== "none" && val !== "normal" && val !== "auto") {
|
||||
styleString += `${prop}: ${val}; `;
|
||||
}
|
||||
}
|
||||
cloned.setAttribute("style", styleString);
|
||||
// Đệ quy quét qua tất cả các con, cháu bên trong để áp dụng CSS
|
||||
for (let i = 0; i < original.children.length; i++) {
|
||||
applyStyles(original.children[i], cloned.children[i]);
|
||||
}
|
||||
}
|
||||
applyStyles(el, clone);
|
||||
copy(clone.outerHTML);
|
||||
console.log("👉 Đã copy thành công cả THẺ CHA & CÁC THẺ CON kèm CSS!");
|
||||
})($0);
|
||||
@@ -0,0 +1,93 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
|
||||
public class CreateLivestreamPost {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Class.forName("oracle.jdbc.OracleDriver");
|
||||
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/sisvietnam", "sisvietnam", "sisvietnam");
|
||||
|
||||
// 1. Check if tag 'livestream' exists, if not create it
|
||||
long tagId = -1;
|
||||
PreparedStatement checkTag = conn.prepareStatement("SELECT id FROM sis_tag WHERE slug = 'livestream'");
|
||||
ResultSet rsTag = checkTag.executeQuery();
|
||||
if (rsTag.next()) {
|
||||
tagId = rsTag.getLong("id");
|
||||
} else {
|
||||
PreparedStatement insertTag = conn.prepareStatement(
|
||||
"INSERT INTO sis_tag (id, name, slug, created_by) VALUES (sequence_generator.NEXTVAL, ?, ?, 'system')"
|
||||
);
|
||||
insertTag.setString(1, "Livestream");
|
||||
insertTag.setString(2, "livestream");
|
||||
insertTag.executeUpdate();
|
||||
|
||||
PreparedStatement getTagId = conn.prepareStatement("SELECT id FROM sis_tag WHERE slug = 'livestream'");
|
||||
ResultSet rsTag2 = getTagId.executeQuery();
|
||||
if (rsTag2.next()) {
|
||||
tagId = rsTag2.getLong("id");
|
||||
}
|
||||
}
|
||||
|
||||
if (tagId == -1) {
|
||||
System.out.println("Failed to find or create livestream tag.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. Insert Post
|
||||
// We set Title as "Tuần 1" (so it shows nicely on the tab label)
|
||||
// We set Excerpt as the long Title they provided.
|
||||
String postTitle = "Tuần 1";
|
||||
String postExcerpt = "SIS Vì Sức khỏe Cộng đồng kỳ 134 Thoát vị đĩa đệm – Khi nào mới phẫu thuật?";
|
||||
String postContent = "Đau lưng, đau cổ, tê tay, tê chân... là những triệu chứng thường gặp của thoát vị đĩa đệm. Tuy nhiên, không phải ai mắc bệnh cũng cần phẫu thuật.\n" +
|
||||
"⚠️ Vậy khi nào nên điều trị bảo tồn? Khi nào cần phẫu thuật? Làm sao để tránh bỏ lỡ \"thời điểm vàng\" điều trị?\n" +
|
||||
"Cùng lắng nghe những chia sẻ từ các chuyên gia trong chương trình Livestream \"S.I.S vì sức khỏe cộng đồng\" vào lúc 𝟏𝟗𝐡𝟒𝟓 Thứ Ba, ngày 𝟎𝟕/𝟎𝟕/𝟐𝟎𝟐𝟔.\n" +
|
||||
"📌 Đồng hành và tư vấn trực tiếp cùng quý khán giả là các bác sĩ giàu kinh nghiệm tại Bệnh viện ĐKQT S.I.S Cần Thơ:\n" +
|
||||
"• BS.CKI Nguyễn Quang Hưng, chuyên khoa Ngoại Thần kinh\n" +
|
||||
"• BS.CKI Trương Đan Kha, chuyên khoa Vật lý trị liệu - Phục hồi chức năng \n" +
|
||||
"• ThS.BS Lê Thị Chi Lan, chuyên khoa Ngoại Thần kinh.";
|
||||
|
||||
// Convert standard youtube link to embed link
|
||||
String embedUrl = "https://www.youtube.com/embed/j63kT9Bjrb4";
|
||||
|
||||
PreparedStatement insertPost = conn.prepareStatement(
|
||||
"INSERT INTO sis_post (id, title, slug, content, excerpt, meta_description, featured_image, created_by, status) " +
|
||||
"VALUES (sequence_generator.NEXTVAL, ?, ?, ?, ?, ?, ?, 'system', 'PUBLISHED')"
|
||||
);
|
||||
insertPost.setString(1, postTitle);
|
||||
insertPost.setString(2, "sis-vi-suc-khoe-cong-dong-ky-134");
|
||||
insertPost.setString(3, postContent);
|
||||
insertPost.setString(4, postExcerpt);
|
||||
insertPost.setString(5, embedUrl);
|
||||
insertPost.setString(6, "/media/livestream/livestream_tuan1.jpg"); // uploaded image
|
||||
insertPost.executeUpdate();
|
||||
|
||||
// Get new post ID
|
||||
long postId = -1;
|
||||
PreparedStatement getPostId = conn.prepareStatement("SELECT id FROM sis_post WHERE slug = 'sis-vi-suc-khoe-cong-dong-ky-134'");
|
||||
ResultSet rsPost = getPostId.executeQuery();
|
||||
if (rsPost.next()) {
|
||||
postId = rsPost.getLong("id");
|
||||
}
|
||||
|
||||
if (postId == -1) {
|
||||
System.out.println("Failed to retrieve created post ID.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Link post with tag
|
||||
PreparedStatement linkPostTag = conn.prepareStatement(
|
||||
"INSERT INTO sis_post_tag (post_id, tag_id) VALUES (?, ?)"
|
||||
);
|
||||
linkPostTag.setLong(1, postId);
|
||||
linkPostTag.setLong(2, tagId);
|
||||
linkPostTag.executeUpdate();
|
||||
|
||||
System.out.println("Successfully created post and linked it with the 'livestream' tag.");
|
||||
conn.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
# Environment Transfer Guide
|
||||
|
||||
To transfer the development environment for this application to another PC, you need to install a few key technologies based on the project's configuration (JHipster 9.1.0, Spring Boot monolith).
|
||||
|
||||
Here is the complete list of tools and dependencies you need to install on the new PC:
|
||||
|
||||
## 1. Required Technologies
|
||||
* **Java Development Kit (JDK):** **Version 21** (The project is configured with `sourceCompatibility=21` in `build.gradle`).
|
||||
* **Node.js:** **Version >= 24.16.0** (Required for JHipster frontend tooling and code formatting, as specified in `package.json`).
|
||||
* **NPM:** Comes bundled with Node.js.
|
||||
* **Git:** To clone and transfer your source code.
|
||||
|
||||
## 2. Automatically Managed Dependencies (No installation required)
|
||||
* **Gradle:** You do **not** need to install Gradle manually. The project uses the Gradle Wrapper (`gradlew`). Running it will automatically download the correct version for you.
|
||||
* **Database (Development):** The `dev` profile uses an **H2 in-memory/file-based database**. You do not need to install an external database to run the project locally.
|
||||
* *(Note: The `prod` profile uses an Oracle Database, which is only necessary if you are running it in production mode).*
|
||||
|
||||
## 3. Recommended Tools (Optional)
|
||||
* **IDE:** IntelliJ IDEA, Eclipse, or Visual Studio Code with the Java Extension Pack.
|
||||
* **Docker Desktop:** Useful if you want to run additional services (like SonarQube or JHipster Control Center) via the `docker-compose` files located in `src/main/docker/`.
|
||||
|
||||
---
|
||||
|
||||
## How to start the project on the new PC
|
||||
Once you've installed **Java 21** and **Node.js >= 24.16.0**, you can transfer your code to the new PC and run the following commands in your project's root folder:
|
||||
|
||||
### 1. Install Node dependencies
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
### 2. Start the development server
|
||||
```bash
|
||||
./gradlew
|
||||
```
|
||||
*(On Windows Command Prompt or PowerShell, use `.\gradlew` instead).*
|
||||
|
||||
This will download all necessary Java dependencies via Gradle and start the application on `http://localhost:8080`.
|
||||
@@ -0,0 +1,40 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
public class FixNewsGrid {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/sisvietnam", "sisvietnam", "sisvietnam");
|
||||
String correctHtml = "{{#each news_posts}}\n" +
|
||||
"<div class=\"featured-grid__item\">\n" +
|
||||
" <article class=\"news-card news-card--featured\">\n" +
|
||||
" <div class=\"news-card__image\">\n" +
|
||||
" <div>\n" +
|
||||
" <img loading=\"lazy\" src=\"{{featuredImageUrl}}\" alt=\"{{title}}\">\n" +
|
||||
" </div>\n" +
|
||||
" </div>\n" +
|
||||
" <div class=\"news-card__content\">\n" +
|
||||
" <div class=\"featured-grid__category\">\n" +
|
||||
" <a href=\"#\">TIN TỨC</a>\n" +
|
||||
" </div>\n" +
|
||||
" <h3 class=\"news-card__title\">\n" +
|
||||
" <a href=\"/post/{{slug}}\" rel=\"bookmark\">\n" +
|
||||
" <span>{{title}}</span>\n" +
|
||||
" </a>\n" +
|
||||
" </h3>\n" +
|
||||
" <div class=\"news-card__date\">{{date}}</div>\n" +
|
||||
" </div>\n" +
|
||||
" </article>\n" +
|
||||
"</div>\n" +
|
||||
"{{/each}}";
|
||||
|
||||
PreparedStatement pstmt = conn.prepareStatement("UPDATE sis_component_template SET html_template = ? WHERE slug = 'news-grid'");
|
||||
pstmt.setString(1, correctHtml);
|
||||
int updated = pstmt.executeUpdate();
|
||||
System.out.println("Updated rows: " + updated);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class FixPosts {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/sisvietnam", "sisvietnam", "sisvietnam");
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT id, content FROM sis_post WHERE featured_image IS NULL");
|
||||
Pattern p = Pattern.compile("<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>");
|
||||
int count = 0;
|
||||
while (rs.next()) {
|
||||
String content = rs.getString("content");
|
||||
if (content != null) {
|
||||
Matcher m = p.matcher(content);
|
||||
if (m.find()) {
|
||||
String imgUrl = m.group(1);
|
||||
Statement updateStmt = conn.createStatement();
|
||||
updateStmt.executeUpdate("UPDATE sis_post SET featured_image = '" + imgUrl + "' WHERE id = " + rs.getLong("id"));
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("Updated " + count + " posts with featured images from content.");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
# Getting Started
|
||||
|
||||
### Reference Documentation
|
||||
For further reference, please consider the following sections:
|
||||
|
||||
* [Official Gradle documentation](https://docs.gradle.org)
|
||||
* [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/4.0.6/gradle-plugin)
|
||||
* [Create an OCI image](https://docs.spring.io/spring-boot/4.0.6/gradle-plugin/packaging-oci-image.html)
|
||||
* [Spring Web](https://docs.spring.io/spring-boot/4.0.6/reference/web/servlet.html)
|
||||
* [Thymeleaf](https://docs.spring.io/spring-boot/4.0.6/reference/web/servlet.html#web.servlet.spring-mvc.template-engines)
|
||||
* [Spring Boot DevTools](https://docs.spring.io/spring-boot/4.0.6/reference/using/devtools.html)
|
||||
|
||||
### Guides
|
||||
The following guides illustrate how to use some features concretely:
|
||||
|
||||
* [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/)
|
||||
* [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/)
|
||||
* [Building REST services with Spring](https://spring.io/guides/tutorials/rest/)
|
||||
* [Handling Form Submission](https://spring.io/guides/gs/handling-form-submission/)
|
||||
|
||||
### Additional Links
|
||||
These additional references should also help you:
|
||||
|
||||
* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle)
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# Project Knowledge Base
|
||||
|
||||
## Overview
|
||||
This project is a web application built using **Java**, **Spring Boot**, and **Thymeleaf**. It serves as the frontend layer for `sisvietnamvn`, currently rendering static-like pages with dynamic templating provided by Thymeleaf. The static assets seem to be heavily inspired by or imported from UMass Amherst website templates, integrated into a Spring Boot architecture.
|
||||
|
||||
## System Architecture
|
||||
* **Language:** Java 21
|
||||
* **Framework:** Spring Boot (Version 4.0.6 as per `build.gradle`)
|
||||
* **Build Tool:** Gradle
|
||||
* **Application Type:** Spring Web MVC application
|
||||
* **Routing:** Basic MVC routing handled by `@Controller` classes. Currently, `HomeController.java` maps endpoints to Thymeleaf templates:
|
||||
* `/` -> `index.html`
|
||||
* `/about` -> `about.html`
|
||||
* `/flex-finish` -> `flex-finish.html`
|
||||
|
||||
## Directory Structure
|
||||
The structure strictly adheres to standard Maven/Gradle Spring Boot conventions:
|
||||
* `build.gradle` / `settings.gradle`: Gradle configuration files defining dependencies and build settings.
|
||||
* `src/main/java/com/sisvietnamvn/web/`: Contains Java source code.
|
||||
* `SisvietnamvnApplication.java`: Main Spring Boot entry point.
|
||||
* `controller/HomeController.java`: Web controller managing page routing.
|
||||
* `src/main/resources/`: Contains configuration and web assets.
|
||||
* `application.properties`: Spring Boot configuration properties.
|
||||
* `static/`: Stores all static assets (CSS, JS, Images). Assets are organized into subdirectories like `css/`, `images/`, `js/`, and specific page folders like `flex-finish/` and `UMass Amherst _ UMass Amherst_files/`.
|
||||
* `templates/`: Contains Thymeleaf `.html` view templates.
|
||||
* `fragments/`: Contains reusable Thymeleaf layout components (`layout.html`, `header.html`, `footer.html`).
|
||||
|
||||
## Libraries and Dependencies
|
||||
* **Spring Boot Starter Web** (`spring-boot-starter-webmvc`): For building web, including RESTful, applications using Spring MVC.
|
||||
* **Spring Boot Starter Thymeleaf** (`spring-boot-starter-thymeleaf`): For HTML templating.
|
||||
* **Thymeleaf Layout Dialect** (`nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect`): Provides decorator pattern for Thymeleaf, allowing the use of a common layout (`layout.html`) that other pages inject content into.
|
||||
* **Spring Boot DevTools** (`spring-boot-devtools`): For fast application restarts and live reload during development.
|
||||
* **Frontend Libraries:**
|
||||
* jQuery (`jquery.min.js`)
|
||||
* Lazysizes (`lazysizes.min.js`) for lazy loading images.
|
||||
* Various Lottie scripts and custom scripts copied into static folders.
|
||||
|
||||
## Coding Conventions & Best Practices
|
||||
1. **Templating & Layouts:** The project relies on the Thymeleaf Layout Dialect. Pages should define their content within a `layout:fragment="content"` block and reference the master layout (`layout.html`). Reusable parts (like headers/footers) are stored in the `fragments` folder and included via `th:replace`.
|
||||
2. **Asset Management:** Static assets (CSS, images, JS) are referenced via absolute paths starting from the root `/` (e.g., `<script src="/Undergraduate Study _ UMass Amherst_files/base.js.download"></script>`). This relies on Spring Boot's default static resource mapping.
|
||||
3. **Controllers:** Keep controllers lightweight. Endpoints should generally just return the template name as a String.
|
||||
4. **Language Level:** The project uses Java 21, allowing for modern Java features (records, pattern matching, etc.) if backend logic is expanded in the future.
|
||||
@@ -0,0 +1,26 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class TestDb {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/sisvietnam", "sisvietnam", "sisvietnam");
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT id, slug, html_template FROM sis_component_template");
|
||||
while (rs.next()) {
|
||||
System.out.println("--- ID: " + rs.getInt("id") + " SLUG: " + rs.getString("slug") + " ---");
|
||||
String html = rs.getString("html_template");
|
||||
if (html != null && html.contains("\\n")) {
|
||||
System.out.println("CONTAINS LITERAL \\n!");
|
||||
} else if (html != null && html.contains("\n")) {
|
||||
System.out.println("Contains actual newlines.");
|
||||
}
|
||||
System.out.println(html);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
import java.net.URI;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
public class TestFileUri {
|
||||
public static void main(String[] args) throws Exception {
|
||||
String uploadPath = "/home/x79/sisvietnamvn_01/sisvietnamvn_main/uploads";
|
||||
System.out.println("Using file:/ + uploadPath:");
|
||||
try {
|
||||
URI uri1 = new URI("file:/" + uploadPath + "/");
|
||||
System.out.println(" Host: " + uri1.getHost());
|
||||
System.out.println(" Path: " + uri1.getPath());
|
||||
} catch(Exception e) { e.printStackTrace(); }
|
||||
|
||||
System.out.println("\nUsing Paths.get().toUri():");
|
||||
URI uri2 = Paths.get(uploadPath).toUri();
|
||||
System.out.println(" URI: " + uri2.toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
import org.springframework.security.crypto.password.MessageDigestPasswordEncoder;
|
||||
|
||||
public class TestOracleJDBC {
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void main(String[] args) {
|
||||
MessageDigestPasswordEncoder encoder = new MessageDigestPasswordEncoder("SHA-256");
|
||||
String hash = encoder.encode("admin");
|
||||
System.out.println("Encoded hash for admin: " + hash);
|
||||
boolean matches = encoder.matches("admin", "8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918");
|
||||
System.out.println("Does 'admin' match my hash? " + matches);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
import java.util.regex.Matcher;
|
||||
public class TestReplace {
|
||||
public static void main(String[] args) {
|
||||
String test = "Line 1\nLine 2";
|
||||
System.out.println("Original:");
|
||||
System.out.println(test);
|
||||
System.out.println("Quote:");
|
||||
System.out.println(Matcher.quoteReplacement(test));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
public class UpdateLivestreamJs {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Class.forName("oracle.jdbc.OracleDriver");
|
||||
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/sisvietnam", "sisvietnam", "sisvietnam");
|
||||
|
||||
String htmlTemplate =
|
||||
"<style>\n" +
|
||||
" .tabbed-media-content-media-item { width: 100%; aspect-ratio: 16/9; position: relative; display: flex; align-items: center; justify-content: center; }\n" +
|
||||
" .tabbed-media-content-media-item .f--video-embed { display: none; width: 100%; height: 100%; position: absolute; top: 0; left: 0; }\n" +
|
||||
" .tabbed-media-content-media-item .f--video-embed iframe { width: 100%; height: 100%; }\n" +
|
||||
" .tabbed-media-content-media-item .f--image { width: 100%; height: 100%; position: absolute; top: 0; left: 0; }\n" +
|
||||
" .tabbed-media-content-media-item .button-play { z-index: 10; }\n" +
|
||||
"</style>\n" +
|
||||
"<div class=\"cc--component-container cc--tabbed-media-content\" style=\"background-color: var(--color-gray-100);\">\n" +
|
||||
" <div class=\"c--component c--tabbed-media-content\">\n" +
|
||||
" <div class=\"tabbed-media-content-text-col\">\n" +
|
||||
" <div data-component-id=\"umass_base:section-title\" class=\"f--section-title\">\n" +
|
||||
" <h2 style=\"color: var(--color-brand);\">LiveStream</h2>\n" +
|
||||
" </div>\n" +
|
||||
" <div data-component-id=\"umass_base:tabbed-container\" data-once=\"tabbed-container\">\n" +
|
||||
" <div class=\"tab-labels-container\" role=\"tablist\">\n" +
|
||||
" <div class=\"tab-labels-inner\">\n" +
|
||||
" {{#each livestream_posts}}\n" +
|
||||
" <a href=\"#tabbed-content-{{index}}\" class=\"tab-label link-context-dark\" role=\"tab\" aria-selected=\"false\" aria-controls=\"tabbed-content-{{index}}\">{{title}}</a>\n" +
|
||||
" {{/each}}\n" +
|
||||
" </div>\n" +
|
||||
" </div>\n" +
|
||||
" <div class=\"tab-content-container\">\n" +
|
||||
" {{#each livestream_posts}}\n" +
|
||||
" <div class=\"tab-content-panel\" id=\"tabbed-content-{{index}}\" role=\"tabpanel\" aria-live=\"polite\">\n" +
|
||||
" <div class=\"f--field f--cta-title\">\n" +
|
||||
" <h2 style=\"color: var(--color-black);\"> {{excerpt}} </h2>\n" +
|
||||
" </div>\n" +
|
||||
" <div data-component-id=\"umass_base:description\" class=\"f--description\">\n" +
|
||||
" <div style=\"color:var(--color-black);\">{{content}}</div>\n" +
|
||||
" </div>\n" +
|
||||
" <div class=\"cta-container\">\n" +
|
||||
" <div class=\"f--field f--button\">\n" +
|
||||
" <a href=\"/post/{{slug}}\" class=\"button-primary button-context-light \" aria-label=\"Tìm Hiểu Thêm\" data-component-id=\"umass_base:button\">\n" +
|
||||
" <span class=\"button-text\"> Tìm Hiểu Thêm </span>\n" +
|
||||
" </a>\n" +
|
||||
" </div>\n" +
|
||||
" </div>\n" +
|
||||
" </div>\n" +
|
||||
" {{/each}}\n" +
|
||||
" </div>\n" +
|
||||
" </div>\n" +
|
||||
" </div>\n" +
|
||||
" <div class=\"tabbed-media-content-media-col\">\n" +
|
||||
" {{#each livestream_posts}}\n" +
|
||||
" <div class=\"tabbed-media-content-media-item with-video\" data-tab-id=\"tabbed-content-{{index}}\">\n" +
|
||||
" <div class=\"f--field f--image\">\n" +
|
||||
" <img src=\"{{featuredImageUrl}}\" data-src=\"{{featuredImageUrl}}\" class=\"lazyload\" alt=\"{{title}}\" style=\"width:100%;height:100%;object-fit:cover;\">\n" +
|
||||
" </div>\n" +
|
||||
" <div class=\"f--field f--button\">\n" +
|
||||
" <a href=\"#\" class=\"button-play button-context-light \" aria-label=\"Play video\" data-component-id=\"umass_base:button\">\n" +
|
||||
" <span class=\"button-icon button-icon-play\">\n" +
|
||||
" <svg width=\"18\" height=\"27\" viewBox=\"0 0 18 27\" fill=\"currentColor\" xmlns=\"http://www.w3.org/2000/svg\">\n" +
|
||||
" <path d=\"M18 13.5L0 0V27L18 13.5Z\"></path>\n" +
|
||||
" </svg>\n" +
|
||||
" </span>\n" +
|
||||
" <span class=\"button-text visually-hidden\"> Play </span>\n" +
|
||||
" </a>\n" +
|
||||
" </div>\n" +
|
||||
" <div data-component-id=\"umass_base:video-embed\" class=\"f--field f--video-embed\">\n" +
|
||||
" <iframe title=\"Video Content\" src=\"{{metaDescription}}\" frameborder=\"0\" allow=\"accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen=\"\"></iframe>\n" +
|
||||
" </div>\n" +
|
||||
" </div>\n" +
|
||||
" {{/each}}\n" +
|
||||
" </div>\n" +
|
||||
" </div>\n" +
|
||||
"</div>\n" +
|
||||
"<script>\n" +
|
||||
" document.addEventListener(\"DOMContentLoaded\", function() {\n" +
|
||||
" // Set the first tab and panel as active if they exist\n" +
|
||||
" var tabs = document.querySelectorAll('.tabbed-media-content-media-item[data-tab-id=\"tabbed-content-0\"]');\n" +
|
||||
" if(tabs.length > 0) tabs[0].classList.add('is-active');\n" +
|
||||
" \n" +
|
||||
" var panels = document.querySelectorAll('#tabbed-content-0.tab-content-panel');\n" +
|
||||
" if(panels.length > 0) panels[0].classList.add('is-active');\n" +
|
||||
"\n" +
|
||||
" var labels = document.querySelectorAll('a.tab-label[aria-controls=\"tabbed-content-0\"]');\n" +
|
||||
" if(labels.length > 0) labels[0].setAttribute('aria-selected', 'true');\n" +
|
||||
"\n" +
|
||||
" // Tab Switching Logic\n" +
|
||||
" var allLabels = document.querySelectorAll('.tab-labels-inner .tab-label');\n" +
|
||||
" allLabels.forEach(function(label) {\n" +
|
||||
" label.addEventListener('click', function(e) {\n" +
|
||||
" e.preventDefault();\n" +
|
||||
" allLabels.forEach(function(l) { l.setAttribute('aria-selected', 'false'); });\n" +
|
||||
" this.setAttribute('aria-selected', 'true');\n" +
|
||||
" \n" +
|
||||
" var targetId = this.getAttribute('aria-controls');\n" +
|
||||
" document.querySelectorAll('.tab-content-panel').forEach(function(p) { p.classList.remove('is-active'); });\n" +
|
||||
" document.querySelectorAll('.tabbed-media-content-media-item').forEach(function(m) { \n" +
|
||||
" m.classList.remove('is-active'); \n" +
|
||||
" // Reset video when switching tabs\n" +
|
||||
" var vEmbed = m.querySelector('.f--video-embed');\n" +
|
||||
" if(vEmbed) vEmbed.style.display = 'none';\n" +
|
||||
" var img = m.querySelector('.f--image');\n" +
|
||||
" if(img) img.style.display = 'block';\n" +
|
||||
" var btn = m.querySelector('.button-play');\n" +
|
||||
" if(btn) btn.style.display = 'flex'; // Or whatever default display is\n" +
|
||||
" var iframe = m.querySelector('iframe');\n" +
|
||||
" if(iframe) { \n" +
|
||||
" var src = iframe.src;\n" +
|
||||
" iframe.src = src.replace('&autoplay=1', '').replace('?autoplay=1', '');\n" +
|
||||
" }\n" +
|
||||
" });\n" +
|
||||
" \n" +
|
||||
" var targetPanel = document.getElementById(targetId);\n" +
|
||||
" if(targetPanel) targetPanel.classList.add('is-active');\n" +
|
||||
" var targetMedia = document.querySelector('.tabbed-media-content-media-item[data-tab-id=\"' + targetId + '\"]');\n" +
|
||||
" if(targetMedia) targetMedia.classList.add('is-active');\n" +
|
||||
" });\n" +
|
||||
" });\n" +
|
||||
"\n" +
|
||||
" // Play Button Logic\n" +
|
||||
" var playButtons = document.querySelectorAll('.tabbed-media-content-media-item .button-play');\n" +
|
||||
" playButtons.forEach(function(btn) {\n" +
|
||||
" btn.addEventListener('click', function(e) {\n" +
|
||||
" e.preventDefault();\n" +
|
||||
" var mediaItem = this.closest('.tabbed-media-content-media-item');\n" +
|
||||
" var img = mediaItem.querySelector('.f--image');\n" +
|
||||
" var videoEmbed = mediaItem.querySelector('.f--video-embed');\n" +
|
||||
" \n" +
|
||||
" if(img) img.style.display = 'none';\n" +
|
||||
" this.style.display = 'none';\n" +
|
||||
" if(videoEmbed) videoEmbed.style.display = 'block';\n" +
|
||||
" \n" +
|
||||
" var iframe = mediaItem.querySelector('iframe');\n" +
|
||||
" if(iframe && iframe.src.indexOf('autoplay=1') === -1) {\n" +
|
||||
" iframe.src = iframe.src + (iframe.src.indexOf('?') > -1 ? '&' : '?') + 'autoplay=1';\n" +
|
||||
" }\n" +
|
||||
" });\n" +
|
||||
" });\n" +
|
||||
" });\n" +
|
||||
"</script>";
|
||||
|
||||
PreparedStatement updateTemplate = conn.prepareStatement(
|
||||
"UPDATE sis_component_template SET html_template = ? WHERE slug = 'tabbed-livestream'"
|
||||
);
|
||||
updateTemplate.setString(1, htmlTemplate);
|
||||
|
||||
int rows = updateTemplate.executeUpdate();
|
||||
System.out.println("Updated rows: " + rows);
|
||||
|
||||
conn.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
public class UpdateLivestreamPost {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Class.forName("oracle.jdbc.OracleDriver");
|
||||
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/sisvietnam", "sisvietnam", "sisvietnam");
|
||||
|
||||
String postTitle = "Tuần 1";
|
||||
String postExcerpt = "SIS Vì Sức khỏe Cộng đồng kỳ 134 Thoát vị đĩa đệm – Khi nào mới phẫu thuật?";
|
||||
String postContent = "Đau lưng, đau cổ, tê tay, tê chân... là những triệu chứng thường gặp của thoát vị đĩa đệm. Tuy nhiên, không phải ai mắc bệnh cũng cần phẫu thuật.\n" +
|
||||
"⚠️ Vậy khi nào nên điều trị bảo tồn? Khi nào cần phẫu thuật? Làm sao để tránh bỏ lỡ \"thời điểm vàng\" điều trị?\n" +
|
||||
"Cùng lắng nghe những chia sẻ từ các chuyên gia trong chương trình Livestream \"S.I.S vì sức khỏe cộng đồng\" vào lúc 𝟏𝟗𝐡𝟒𝟓 Thứ Ba, ngày 𝟎𝟕/𝟎𝟕/𝟐𝟎𝟐𝟔.\n" +
|
||||
"📌 Đồng hành và tư vấn trực tiếp cùng quý khán giả là các bác sĩ giàu kinh nghiệm tại Bệnh viện ĐKQT S.I.S Cần Thơ:\n" +
|
||||
"• BS.CKI Nguyễn Quang Hưng, chuyên khoa Ngoại Thần kinh\n" +
|
||||
"• BS.CKI Trương Đan Kha, chuyên khoa Vật lý trị liệu - Phục hồi chức năng \n" +
|
||||
"• ThS.BS Lê Thị Chi Lan, chuyên khoa Ngoại Thần kinh.";
|
||||
|
||||
String embedUrl = "https://www.youtube.com/embed/j63kT9Bjrb4";
|
||||
|
||||
PreparedStatement updatePost = conn.prepareStatement(
|
||||
"UPDATE sis_post SET title = ?, content = ?, excerpt = ?, meta_description = ?, featured_image = ? WHERE slug = 'sis-vi-suc-khoe-cong-dong-ky-134'"
|
||||
);
|
||||
updatePost.setString(1, postTitle);
|
||||
updatePost.setString(2, postContent);
|
||||
updatePost.setString(3, postExcerpt);
|
||||
updatePost.setString(4, embedUrl);
|
||||
updatePost.setString(5, "/uploads/livestream/livestream_tuan1.jpg");
|
||||
|
||||
int rows = updatePost.executeUpdate();
|
||||
System.out.println("Updated rows: " + rows);
|
||||
|
||||
conn.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
|
||||
public class UpdateNewsGridDesktop {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/sisvietnam", "sisvietnam", "sisvietnam");
|
||||
String correctHtml = "<style>\n" +
|
||||
"@media screen and (min-width: 1024px) {\n" +
|
||||
" .featured-grid {\n" +
|
||||
" display: grid;\n" +
|
||||
" grid-template-columns: repeat(2, 1fr);\n" +
|
||||
" gap: 24px;\n" +
|
||||
" align-items: stretch;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item {\n" +
|
||||
" height: 100%;\n" +
|
||||
" display: flex;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .news-card--featured {\n" +
|
||||
" display: flex;\n" +
|
||||
" flex-direction: row;\n" +
|
||||
" border: 1px solid #881C1C;\n" +
|
||||
" border-radius: 16px;\n" +
|
||||
" padding: 16px;\n" +
|
||||
" box-sizing: border-box;\n" +
|
||||
" width: 100%;\n" +
|
||||
" height: 100%;\n" +
|
||||
" gap: 16px;\n" +
|
||||
" background: #fff;\n" +
|
||||
" margin-bottom: 0 !important;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .news-card__image {\n" +
|
||||
" flex: 0 0 45%;\n" +
|
||||
" max-width: 45%;\n" +
|
||||
" margin-bottom: 0 !important;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .news-card__image > div {\n" +
|
||||
" height: 100%;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .news-card__image img {\n" +
|
||||
" width: 100%;\n" +
|
||||
" height: 100%;\n" +
|
||||
" object-fit: cover;\n" +
|
||||
" border-radius: 8px;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .news-card__content {\n" +
|
||||
" flex: 1;\n" +
|
||||
" display: flex;\n" +
|
||||
" flex-direction: column;\n" +
|
||||
" justify-content: flex-start;\n" +
|
||||
" min-width: 0;\n" +
|
||||
" padding: 0 !important;\n" +
|
||||
" margin: 0 !important;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .featured-grid__category {\n" +
|
||||
" margin-bottom: 12px;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .featured-grid__category a {\n" +
|
||||
" display: inline-block;\n" +
|
||||
" background-color: #f2f2f2;\n" +
|
||||
" color: #881C1C;\n" +
|
||||
" padding: 4px 8px;\n" +
|
||||
" border-radius: 4px;\n" +
|
||||
" font-size: 0.75rem;\n" +
|
||||
" font-weight: bold;\n" +
|
||||
" text-decoration: none;\n" +
|
||||
" text-transform: uppercase;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .news-card__title {\n" +
|
||||
" font-size: 1.1rem;\n" +
|
||||
" font-weight: 700;\n" +
|
||||
" margin-top: 0;\n" +
|
||||
" margin-bottom: 12px;\n" +
|
||||
" line-height: 1.4;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .news-card__title a {\n" +
|
||||
" color: #000;\n" +
|
||||
" text-decoration: none;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .news-card__title a:hover {\n" +
|
||||
" color: #881C1C;\n" +
|
||||
" }\n" +
|
||||
" .featured-grid__item .news-card__date {\n" +
|
||||
" margin-top: auto;\n" +
|
||||
" color: #881C1C;\n" +
|
||||
" font-size: 0.85rem;\n" +
|
||||
" font-weight: 500;\n" +
|
||||
" }\n" +
|
||||
"}\n" +
|
||||
"</style>\n" +
|
||||
"{{#each news_posts}}\n" +
|
||||
"<div class=\"featured-grid__item\">\n" +
|
||||
" <article class=\"news-card news-card--featured\">\n" +
|
||||
" <div class=\"news-card__image\">\n" +
|
||||
" <div>\n" +
|
||||
" <img loading=\"lazy\" src=\"{{featuredImageUrl}}\" alt=\"{{title}}\">\n" +
|
||||
" </div>\n" +
|
||||
" </div>\n" +
|
||||
" <div class=\"news-card__content\">\n" +
|
||||
" <div class=\"featured-grid__category\">\n" +
|
||||
" <a href=\"#\">TIN TỨC</a>\n" +
|
||||
" </div>\n" +
|
||||
" <h3 class=\"news-card__title\">\n" +
|
||||
" <a href=\"/post/{{slug}}\" rel=\"bookmark\">\n" +
|
||||
" <span>{{title}}</span>\n" +
|
||||
" </a>\n" +
|
||||
" </h3>\n" +
|
||||
" <div class=\"news-card__date\">{{date}}</div>\n" +
|
||||
" </div>\n" +
|
||||
" </article>\n" +
|
||||
"</div>\n" +
|
||||
"{{/each}}";
|
||||
|
||||
PreparedStatement pstmt = conn.prepareStatement("UPDATE sis_component_template SET html_template = ? WHERE slug = 'news-grid'");
|
||||
pstmt.setString(1, correctHtml);
|
||||
int updated = pstmt.executeUpdate();
|
||||
System.out.println("Updated rows: " + updated);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
directory = '/home/x79/Documents/sisvietnamvn_01/sisvietnamvn_main/src/main/resources/templates/manage'
|
||||
layout = '/home/x79/Documents/sisvietnamvn_01/sisvietnamvn_main/src/main/resources/templates/fragments/manage-layout.html'
|
||||
|
||||
csrf_token = '\n <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}" />'
|
||||
|
||||
def process_file(filepath):
|
||||
with open(filepath, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
|
||||
# Check if csrf token is already present
|
||||
if '_csrf.parameterName' in content:
|
||||
print(f"Skipping {filepath} - already has CSRF token")
|
||||
return
|
||||
|
||||
# Regex to find <form ... method="post" ...>
|
||||
# It finds the end of the <form ...> tag that has method="post"
|
||||
pattern = r'(<form[^>]*?method=["\']post["\'][^>]*?>)'
|
||||
|
||||
# We want to replace the match with the match + csrf_token
|
||||
new_content = re.sub(pattern, r'\1' + csrf_token, content, flags=re.IGNORECASE)
|
||||
|
||||
if new_content != content:
|
||||
with open(filepath, 'w', encoding='utf-8') as f:
|
||||
f.write(new_content)
|
||||
print(f"Updated {filepath}")
|
||||
|
||||
for root, _, files in os.walk(directory):
|
||||
for file in files:
|
||||
if file.endswith('.html'):
|
||||
process_file(os.path.join(root, file))
|
||||
|
||||
process_file(layout)
|
||||
@@ -0,0 +1 @@
|
||||
{"username":"admin","password":"admin"}
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit on any error
|
||||
set -e
|
||||
|
||||
CONTAINER_NAME="sisvietnam-oracle-sisvietnam-oracle-1"
|
||||
DUMP_FILE="sisvietnam_backup.dmp"
|
||||
LOG_FILE="sisvietnam_backup.log"
|
||||
|
||||
echo "=== Starting Database Backup ==="
|
||||
echo "Running expdp inside container: ${CONTAINER_NAME}..."
|
||||
|
||||
# Run expdp inside the container
|
||||
docker exec ${CONTAINER_NAME} expdp sisvietnam/sisvietnam@//localhost:1521/sisvietnam \
|
||||
schemas=sisvietnam \
|
||||
directory=DATA_PUMP_DIR \
|
||||
dumpfile=${DUMP_FILE} \
|
||||
logfile=${LOG_FILE} \
|
||||
reuse_dumpfiles=y
|
||||
|
||||
echo "=== Export Completed ==="
|
||||
echo "Locating the backup file inside the container..."
|
||||
|
||||
# Find the file dynamically because the directory path contains a dynamic GUID
|
||||
CONTAINER_PATH=$(docker exec ${CONTAINER_NAME} find /opt/oracle/admin/FREE/dpdump/ -name ${DUMP_FILE} | tr -d '\r')
|
||||
|
||||
if [ -z "${CONTAINER_PATH}" ]; then
|
||||
echo "Error: Could not locate ${DUMP_FILE} inside the container."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Found backup file at: ${CONTAINER_PATH}"
|
||||
echo "Copying backup to local directory..."
|
||||
|
||||
# Copy to host
|
||||
docker cp "${CONTAINER_NAME}:${CONTAINER_PATH}" "./${DUMP_FILE}"
|
||||
|
||||
echo "=== Backup Successfully Created ==="
|
||||
echo "Saved to: ./${DUMP_FILE}"
|
||||
@@ -0,0 +1 @@
|
||||
SELECT meta_description FROM sis_post WHERE slug = 'sis-vi-suc-khoe-cong-dong-ky-134';
|
||||
@@ -0,0 +1 @@
|
||||
SELECT data_json FROM sis_page_component WHERE component_id IN (SELECT id FROM sis_component_template WHERE slug = 'tabbed-livestream');
|
||||
@@ -0,0 +1 @@
|
||||
SELECT id, title, featured_image FROM sis_post WHERE slug = 'sis-vi-suc-khoe-cong-dong-ky-134';
|
||||
@@ -0,0 +1 @@
|
||||
SELECT id, slug, title, content FROM sis_post WHERE category_id = (SELECT id FROM sis_category WHERE slug = 'livestream');
|
||||
@@ -0,0 +1 @@
|
||||
SELECT sequence_name FROM user_sequences;
|
||||
@@ -0,0 +1 @@
|
||||
SELECT table_name FROM user_tables;
|
||||
@@ -0,0 +1,5 @@
|
||||
# Netscape HTTP Cookie File
|
||||
# https://curl.se/docs/http-cookies.html
|
||||
# This file was generated by libcurl! Edit at your own risk.
|
||||
|
||||
#HttpOnly_localhost FALSE / FALSE 0 JSESSIONID 3E56DBE7CD23EAE763EA48EB5CF98B29
|
||||
@@ -0,0 +1,18 @@
|
||||
import os
|
||||
from bs4 import BeautifulSoup
|
||||
|
||||
file_path = "/home/x79/sisvietnamvn_01/sisvietnamvn_Trang chính thức hiện tại/UMass Amherst _ UMass Amherst.html"
|
||||
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
soup = BeautifulSoup(f, "html.parser")
|
||||
|
||||
content_top = soup.find(class_="content-top")
|
||||
|
||||
if content_top:
|
||||
# Let's save it to an artifact directly via python, or just print it and I will grab it.
|
||||
output_path = "/home/x79/sisvietnamvn_01/sisvietnamvn_main/content_top_snippet.html"
|
||||
with open(output_path, "w", encoding="utf-8") as f:
|
||||
f.write(content_top.prettify())
|
||||
print(f"Extracted content-top to {output_path}")
|
||||
else:
|
||||
print("Could not find class='content-top'")
|
||||
@@ -0,0 +1,36 @@
|
||||
import sys
|
||||
|
||||
file_path = "/home/x79/sisvietnamvn_01/sisvietnamvn_Trang chính thức hiện tại/UMass Amherst _ UMass Amherst.html"
|
||||
|
||||
with open(file_path, "r", encoding="utf-8") as f:
|
||||
lines = f.readlines()
|
||||
|
||||
start_idx = -1
|
||||
for i, line in enumerate(lines):
|
||||
if '<div class="content-top">' in line:
|
||||
start_idx = i
|
||||
break
|
||||
|
||||
if start_idx == -1:
|
||||
print("Could not find <div class=\"content-top\">")
|
||||
sys.exit(1)
|
||||
|
||||
extracted = []
|
||||
div_count = 0
|
||||
found_start = False
|
||||
|
||||
for line in lines[start_idx:]:
|
||||
# Simple tag counting to find the matching closing div
|
||||
# Note: this is a naive counter, it doesn't account for HTML comments or script tags containing strings that look like tags,
|
||||
# but it usually works well for standard HTML layout sections.
|
||||
div_count += line.count("<div")
|
||||
div_count -= line.count("</div")
|
||||
|
||||
extracted.append(line)
|
||||
if div_count == 0:
|
||||
break
|
||||
|
||||
output_path = "src/main/resources/templates/themes/umass/content-top.html"
|
||||
with open(output_path, "w", encoding="utf-8") as f:
|
||||
f.writelines(extracted)
|
||||
print(f"Extracted to {output_path}")
|
||||
@@ -0,0 +1,20 @@
|
||||
import java.sql.*;
|
||||
|
||||
public class get_users {
|
||||
public static void main(String[] args) {
|
||||
String url = "jdbc:oracle:thin:@localhost:1521/FREEPDB1";
|
||||
String user = "sisvietnam";
|
||||
String password = "sisvietnam";
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(url, user, password);
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT id, login, email FROM jhi_user")) {
|
||||
|
||||
while (rs.next()) {
|
||||
System.out.println("ID: " + rs.getLong("id") + ", Login: " + rs.getString("login") + ", Email: " + rs.getString("email"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,374 @@
|
||||
<header class="sticky top-0 inset-x-0 z-50">
|
||||
<div class="bg-primary-500 text-white h-[45px] z-[51] relative">
|
||||
<div class="md:container h-full">
|
||||
<div class="flex items-center justify-between h-full">
|
||||
<div class="xl:flex grid grid-cols-3 max-xl:w-full items-center md:gap-4 gap-2 h-full">
|
||||
<a data-text="Người bệnh &
|
||||
Cộng đồng" class="h-full items-center max-xl:text-center flex justify-center hover:text-primary-100 transition-colors relative before:content-[''] before:absolute before:left-0 before:bottom-0 before:h-[3px] before:bg-primary-200 before:w-0 before:transition-all hover:before:w-full max-md:whitespace-pre-line flex-col after:content-[attr(data-text)] after:h-0 after:block after:invisible after:overflow-hidden after:font-semibold after:text-[14px] text-white before:w-full title-5 max-md:!text-[12px]" href="https://bvdaihoc.com.vn/">
|
||||
Người bệnh &
|
||||
Cộng đồng</a>
|
||||
<a data-text="Chuyên gia y tế" class="h-full items-center max-xl:text-center flex justify-center hover:text-primary-100 transition-colors relative before:content-[''] before:absolute before:left-0 before:bottom-0 before:h-[3px] before:bg-primary-200 before:w-0 before:transition-all hover:before:w-full max-md:whitespace-pre-line flex-col after:content-[attr(data-text)] after:h-0 after:block after:invisible after:overflow-hidden after:font-semibold after:text-[14px] hover:text-primary-100 before:w-0 hover:before:w-full label-4 max-md:!text-[12px]" href="https://bvdaihoc.com.vn/chuyen-gia-y-te">
|
||||
Chuyên gia y tế</a>
|
||||
<a data-text="UMCers" class="h-full items-center max-xl:text-center flex justify-center hover:text-primary-100 transition-colors relative before:content-[''] before:absolute before:left-0 before:bottom-0 before:h-[3px] before:bg-primary-200 before:w-0 before:transition-all hover:before:w-full max-md:whitespace-pre-line flex-col after:content-[attr(data-text)] after:h-0 after:block after:invisible after:overflow-hidden after:font-semibold after:text-[14px] hover:text-primary-100 before:w-0 hover:before:w-full label-4 max-md:!text-[12px]" href="https://bvdaihoc.com.vn/umcers">
|
||||
UMCers</a>
|
||||
</div>
|
||||
<div class="flex items-center max-xl:hidden">
|
||||
<a class="body-3 hover:text-primary-100 transition-colors" href="https://bvdaihoc.com.vn/dat-lich-kham">
|
||||
Đặt lịch khám</a>
|
||||
<span class="text-white mx-4 font-display">
|
||||
|</span>
|
||||
<a class="body-3 hover:text-primary-100 transition-colors" href="https://bvdaihoc.com.vn/dau-thau">
|
||||
Đấu thầu</a>
|
||||
<span class="text-white mx-4 font-display">
|
||||
|</span>
|
||||
<a class="body-3 hover:text-primary-100 transition-colors mr-[22px]" href="https://bvdaihoc.com.vn/lien-he">
|
||||
Liên hệ</a>
|
||||
<div class="flex items-center">
|
||||
<div class="relative">
|
||||
<button type="button" class="w-[42px] h-[45px] cursor-pointer flex items-center justify-center lg:hover:bg-primary-700 lg:duration-150">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-user-round size-[20px]">
|
||||
<circle cx="12" cy="8" r="5">
|
||||
</circle>
|
||||
<path d="M20 21a8 8 0 0 0-16 0">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<a class="size-[45px] cursor-pointer bg-primary-400 lg:hover:bg-primary-700 flex items-center justify-center lg:duration-150" href="https://bvdaihoc.com.vn/tim-kiem">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search">
|
||||
<circle cx="11" cy="11" r="8">
|
||||
</circle>
|
||||
<path d="m21 21-4.3-4.3">
|
||||
</path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--$-->
|
||||
<header class="bg-white transition-all shadow-md duration-150">
|
||||
<div class="relative transition-colors duration-150 bg-white z-50">
|
||||
<div class="container mx-auto flex h-[77px] items-center justify-between px-4 lg:px-10">
|
||||
<div class="flex items-center xl:gap-[52px] gap-4 justify-between w-full">
|
||||
<a class="relative block xl:h-[56px] h-[48px] xl:max-w-[242px] max-w-[216px] w-full" href="https://bvdaihoc.com.vn/">
|
||||
<img alt="Logo" fetchpriority="high" loading="eager" width="242" height="56" decoding="async" data-nimg="1" style="color:transparent;object-fit:contain" sizes="100vw" srcset="/_next/image?url=%2Fimages%2Flogo.webp&w=640&q=80 640w, /_next/image?url=%2Fimages%2Flogo.webp&w=750&q=80 750w, /_next/image?url=%2Fimages%2Flogo.webp&w=828&q=80 828w, /_next/image?url=%2Fimages%2Flogo.webp&w=1080&q=80 1080w, /_next/image?url=%2Fimages%2Flogo.webp&w=1200&q=80 1200w, /_next/image?url=%2Fimages%2Flogo.webp&w=1920&q=80 1920w, /_next/image?url=%2Fimages%2Flogo.webp&w=2048&q=80 2048w, /_next/image?url=%2Fimages%2Flogo.webp&w=3840&q=80 3840w" src="./Bệnh viện Đại học Y Dược TP. Hồ Chí Minh_files/logo.jpeg">
|
||||
</a>
|
||||
<nav class="hidden h-[77px] xl:flex">
|
||||
<ul class="flex h-full items-center xl:space-x-[26px] space-x-4">
|
||||
<li class="h-full group flex-shrink-0">
|
||||
<a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/gioi-thieu-tong-quan">
|
||||
<span>
|
||||
Về Bệnh viện</span>
|
||||
<svg width="10" height="5" viewBox="0 0 10 5" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2 w-2 duration-150 ease-in-out text-gray-300 group-hover:-rotate-180">
|
||||
<path d="M0.759766 0.5L4.68906 4.42929C4.72811 4.46834 4.79142 4.46834 4.83048 4.42929L8.75977 0.5" stroke="currentColor" stroke-linecap="round">
|
||||
</path>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li class="h-full group flex-shrink-0">
|
||||
<a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/chuyen-khoa">
|
||||
<span>
|
||||
Chuyên khoa</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="h-full group flex-shrink-0">
|
||||
<a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/bac-si">
|
||||
<span>
|
||||
Bác sĩ</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="h-full group flex-shrink-0">
|
||||
<a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/dich-vu">
|
||||
<span>
|
||||
Dịch vụ</span>
|
||||
<svg width="10" height="5" viewBox="0 0 10 5" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2 w-2 duration-150 ease-in-out text-gray-300 group-hover:-rotate-180">
|
||||
<path d="M0.759766 0.5L4.68906 4.42929C4.72811 4.46834 4.79142 4.46834 4.83048 4.42929L8.75977 0.5" stroke="currentColor" stroke-linecap="round">
|
||||
</path>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li class="h-full group flex-shrink-0">
|
||||
<a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/thu-vien-suc-khoe">
|
||||
<span>
|
||||
Thư viện sức khỏe</span>
|
||||
</a>
|
||||
</li>
|
||||
<li class="h-full group flex-shrink-0">
|
||||
<a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/tin-tuc-va-su-kien">
|
||||
<span>
|
||||
Tin tức & Sự kiện</span>
|
||||
<svg width="10" height="5" viewBox="0 0 10 5" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2 w-2 duration-150 ease-in-out text-gray-300 group-hover:-rotate-180">
|
||||
<path d="M0.759766 0.5L4.68906 4.42929C4.72811 4.46834 4.79142 4.46834 4.83048 4.42929L8.75977 0.5" stroke="currentColor" stroke-linecap="round">
|
||||
</path>
|
||||
</svg>
|
||||
</a>
|
||||
</li>
|
||||
<li class="h-full group flex-shrink-0">
|
||||
<button class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 cursor-pointer ">
|
||||
<span>
|
||||
Hỗ trợ người bệnh</span>
|
||||
<svg width="10" height="5" viewBox="0 0 10 5" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2 w-2 duration-150 ease-in-out text-gray-300 group-hover:-rotate-180">
|
||||
<path d="M0.759766 0.5L4.68906 4.42929C4.72811 4.46834 4.79142 4.46834 4.83048 4.42929L8.75977 0.5" stroke="currentColor" stroke-linecap="round">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
<div class="flex xl:hidden items-center">
|
||||
<a class="size-[42px] flex items-center justify-center" href="https://bvdaihoc.com.vn/tim-kiem">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search text-black">
|
||||
<circle cx="11" cy="11" r="8">
|
||||
</circle>
|
||||
<path d="m21 21-4.3-4.3">
|
||||
</path>
|
||||
</svg>
|
||||
</a>
|
||||
<div class="relative mr-2.5">
|
||||
<button type="button" class="size-[42px] flex items-center justify-center cursor-pointer">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-user-round text-black">
|
||||
<circle cx="12" cy="8" r="5">
|
||||
</circle>
|
||||
<path d="M20 21a8 8 0 0 0-16 0">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<button class="py-[7px] px-px">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-menu h-6 w-6">
|
||||
<line x1="4" x2="20" y1="12" y2="12">
|
||||
</line>
|
||||
<line x1="4" x2="20" y1="6" y2="6">
|
||||
</line>
|
||||
<line x1="4" x2="20" y1="18" y2="18">
|
||||
</line>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed inset-x-0 top-[122px] h-[calc(100svh)] bg-gray-100 z-[49] transition-transform duration-300 xl:hidden -translate-y-full">
|
||||
<div class="relative">
|
||||
<div class="max-h-[calc(100svh-196px)] overflow-y-auto">
|
||||
<div class="p-4">
|
||||
<div class="bg-primary-600 rounded-md title-6 text-white p-4">
|
||||
<a class="flex items-center space-x-1.5 pb-3 border-b border-white" href="https://bvdaihoc.com.vn/ung-dung-umc-care">
|
||||
<img alt="logo pre header" fetchpriority="high" loading="eager" width="21" height="21" decoding="async" data-nimg="1" class="rounded" style="color:transparent;object-fit:cover" sizes="100vw" srcset="/_next/image?url=%2Fpre-logo.png&w=640&q=80 640w, /_next/image?url=%2Fpre-logo.png&w=750&q=80 750w, /_next/image?url=%2Fpre-logo.png&w=828&q=80 828w, /_next/image?url=%2Fpre-logo.png&w=1080&q=80 1080w, /_next/image?url=%2Fpre-logo.png&w=1200&q=80 1200w, /_next/image?url=%2Fpre-logo.png&w=1920&q=80 1920w, /_next/image?url=%2Fpre-logo.png&w=2048&q=80 2048w, /_next/image?url=%2Fpre-logo.png&w=3840&q=80 3840w" src="./Bệnh viện Đại học Y Dược TP. Hồ Chí Minh_files/pre-logo.png">
|
||||
<div>
|
||||
ỨNG DỤNG UMC CARE</div>
|
||||
</a>
|
||||
<a class="py-3 border-b border-white block" href="https://bvdaihoc.com.vn/dat-lich-kham">
|
||||
Đặt lịch khám</a>
|
||||
<a class="pt-3 block" href="https://bvdaihoc.com.vn/dau-thau">
|
||||
Đấu thầu</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-gray-100">
|
||||
<div class="px-4">
|
||||
<div>
|
||||
<div class="border-b border-gray-100 py-3">
|
||||
<div class="flex w-full items-center justify-between ">
|
||||
<a class="flex-1 flex items-center" href="https://bvdaihoc.com.vn/gioi-thieu-tong-quan">
|
||||
<span class="title-1 text-primary-600">
|
||||
Về Bệnh viện</span>
|
||||
</a>
|
||||
<button class="ml-2 p-1 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down w-5 h-5 transition-transform duration-200 text-gray-600 -rotate-90">
|
||||
<path d="m6 9 6 6 6-6">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="overflow-hidden transition-all duration-200 max-h-0">
|
||||
<div class="pt-3.5 space-y-2">
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/gioi-thieu-tong-quan">
|
||||
<span class="title-1 text-primary-600">
|
||||
Giới thiệu tổng quan</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/lich-su-benh-vien">
|
||||
<span class="title-1 text-primary-600">
|
||||
Lịch sử Bệnh viện</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/tam-nhin-su-menh-gia-tri-cot-loi">
|
||||
<span class="title-1 text-primary-600">
|
||||
Tầm nhìn - Sứ mệnh - Giá trị cốt lõi</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/doi-ngu-lanh-dao">
|
||||
<span class="title-1 text-primary-600">
|
||||
Ban lãnh đạo</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/cac-don-vi">
|
||||
<span class="title-1 text-primary-600">
|
||||
Các đơn vị</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/thanh-tuu-va-giai-thuong">
|
||||
<span class="title-1 text-primary-600">
|
||||
Thành tựu và giải thưởng</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/lien-he">
|
||||
<span class="title-1 text-primary-600">
|
||||
Liên hệ</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a class="flex flex-shrink-0 title-1 py-3 justify-between items-center duration-150 ease-in-out text-primary-600 border-b border-gray-100" href="https://bvdaihoc.com.vn/chuyen-khoa">
|
||||
<span>
|
||||
Chuyên khoa</span>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<a class="flex flex-shrink-0 title-1 py-3 justify-between items-center duration-150 ease-in-out text-primary-600 border-b border-gray-100" href="https://bvdaihoc.com.vn/bac-si">
|
||||
<span>
|
||||
Bác sĩ</span>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<div class="border-b border-gray-100 py-3">
|
||||
<div class="flex w-full items-center justify-between ">
|
||||
<a class="flex-1 flex items-center" href="https://bvdaihoc.com.vn/dich-vu">
|
||||
<span class="title-1 text-primary-600">
|
||||
Dịch vụ</span>
|
||||
</a>
|
||||
<button class="ml-2 p-1 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down w-5 h-5 transition-transform duration-200 text-gray-600 -rotate-90">
|
||||
<path d="m6 9 6 6 6-6">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="overflow-hidden transition-all duration-200 max-h-0">
|
||||
<div class="pt-3.5 space-y-2">
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/dich-vu#kham-benh-ngoai-tru">
|
||||
<span class="title-1 text-primary-600">
|
||||
Khám bệnh ngoại trú</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/dich-vu?tabName=inpatient-treatment#dieu-tri-noi-tru">
|
||||
<span class="title-1 text-primary-600">
|
||||
Điều trị Nội trú</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/dich-vu?tabName=emergency#dieu-tri-noi-tru">
|
||||
<span class="title-1 text-primary-600">
|
||||
Cấp cứu</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/dich-vu#bang-gia">
|
||||
<span class="title-1 text-primary-600">
|
||||
Bảng giá</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<a class="flex flex-shrink-0 title-1 py-3 justify-between items-center duration-150 ease-in-out text-primary-600 border-b border-gray-100" href="https://bvdaihoc.com.vn/thu-vien-suc-khoe">
|
||||
<span>
|
||||
Thư viện sức khỏe</span>
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<div class="border-b border-gray-100 py-3">
|
||||
<div class="flex w-full items-center justify-between ">
|
||||
<a class="flex-1 flex items-center" href="https://bvdaihoc.com.vn/tin-tuc-va-su-kien">
|
||||
<span class="title-1 text-primary-600">
|
||||
Tin tức & Sự kiện</span>
|
||||
</a>
|
||||
<button class="ml-2 p-1 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down w-5 h-5 transition-transform duration-200 text-gray-600 -rotate-90">
|
||||
<path d="m6 9 6 6 6-6">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="overflow-hidden transition-all duration-200 max-h-0">
|
||||
<div class="pt-3.5 space-y-2">
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/cong-tac-xa-hoi">
|
||||
<span class="title-1 text-primary-600">
|
||||
Công tác xã hội</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="border-b border-gray-100 py-3">
|
||||
<div class="flex w-full items-center justify-between ">
|
||||
<a class="flex-1 flex items-center" href="https://bvdaihoc.com.vn/thong-tin-can-biet">
|
||||
<span class="title-1 text-primary-600">
|
||||
Hỗ trợ người bệnh</span>
|
||||
</a>
|
||||
<button class="ml-2 p-1 flex items-center justify-center">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down w-5 h-5 transition-transform duration-200 text-gray-600 -rotate-90">
|
||||
<path d="m6 9 6 6 6-6">
|
||||
</path>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="overflow-hidden transition-all duration-200 max-h-0">
|
||||
<div class="pt-3.5 space-y-2">
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/thong-tin-can-biet">
|
||||
<span class="title-1 text-primary-600">
|
||||
Thông tin cần biết</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/dang-ky-hien-tang">
|
||||
<span class="title-1 text-primary-600">
|
||||
Đăng ký hiến tạng</span>
|
||||
</a>
|
||||
<a class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 pl-4" href="https://bvdaihoc.com.vn/cau-hoi-thuong-gap">
|
||||
<span class="title-1 text-primary-600">
|
||||
Câu hỏi thường gặp</span>
|
||||
</a>
|
||||
<button class="flex items-center justify-between lg:p-4 md:p-3 p-2 border-b border-gray-100 last:border-b-0 w-full text-left pl-4">
|
||||
<span class="title-1 text-primary-600">
|
||||
Liên hệ hỗ trợ</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="p-4 flex justify-start items-center space-x-2 bg-gray-100 sticky bottom-0">
|
||||
<div class="h-[42px] text-center flex items-center justify-center body-3 text-gray-700">
|
||||
<div class="flex items-center justify-center opacity-100">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 85.333 512 341.333" class="w-5 flex-shrink-0">
|
||||
<path fill="#D80027" d="M196.641 85.337H0v341.326h512V85.337z">
|
||||
</path>
|
||||
<path fill="#FFDA44" d="m256 157.279 22.663 69.747H352l-59.332 43.106 22.664 69.749L256 296.774l-59.332 43.107 22.664-69.749L160 227.026h73.337z">
|
||||
</path>
|
||||
</svg>
|
||||
<span class="ml-1">
|
||||
Tiếng việt</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="h-3 w-px bg-gray-200">
|
||||
</div>
|
||||
<div class="h-[42px] text-center flex items-center justify-center body-3 text-gray-700">
|
||||
<div class="flex items-center justify-center opacity-30">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 513 342" class="w-5 flex-shrink-0">
|
||||
<path fill="#FFF" d="M0 0h513v342H0z">
|
||||
</path>
|
||||
<g fill="#D80027">
|
||||
<path d="M0 0h513v26.3H0zM0 52.6h513v26.3H0zM0 105.2h513v26.3H0zM0 157.8h513v26.3H0zM0 210.5h513v26.3H0zM0 263.1h513v26.3H0zM0 315.7h513V342H0z">
|
||||
</path>
|
||||
</g>
|
||||
<path fill="#2E52B2" d="M0 0h256.5v184.1H0z">
|
||||
</path>
|
||||
<g fill="#FFF">
|
||||
<path d="m47.8 138.9-4-12.8-4.4 12.8H26.2l10.7 7.7-4 12.8 10.9-7.9 10.6 7.9-4.1-12.8 10.9-7.7zM104.1 138.9l-4.1-12.8-4.2 12.8H82.6l10.7 7.7-4 12.8 10.7-7.9 10.8 7.9-4-12.8 10.7-7.7zM160.6 138.9l-4.3-12.8-4 12.8h-13.5l11 7.7-4.2 12.8 10.7-7.9 11 7.9-4.2-12.8 10.7-7.7zM216.8 138.9l-4-12.8-4.2 12.8h-13.3l10.8 7.7-4 12.8 10.7-7.9 10.8 7.9-4.3-12.8 11-7.7zM100 75.3l-4.2 12.8H82.6L93.3 96l-4 12.6 10.7-7.8 10.8 7.8-4-12.6 10.7-7.9h-13.4zM43.8 75.3l-4.4 12.8H26.2L36.9 96l-4 12.6 10.9-7.8 10.6 7.8L50.3 96l10.9-7.9H47.8zM156.3 75.3l-4 12.8h-13.5l11 7.9-4.2 12.6 10.7-7.8 11 7.8-4.2-12.6 10.7-7.9h-13.2zM212.8 75.3l-4.2 12.8h-13.3l10.8 7.9-4 12.6 10.7-7.8 10.8 7.8-4.3-12.6 11-7.9h-13.5zM43.8 24.7l-4.4 12.6H26.2l10.7 7.9-4 12.7L43.8 50l10.6 7.9-4.1-12.7 10.9-7.9H47.8zM100 24.7l-4.2 12.6H82.6l10.7 7.9-4 12.7L100 50l10.8 7.9-4-12.7 10.7-7.9h-13.4zM156.3 24.7l-4 12.6h-13.5l11 7.9-4.2 12.7 10.7-7.9 11 7.9-4.2-12.7 10.7-7.9h-13.2zM212.8 24.7l-4.2 12.6h-13.3l10.8 7.9-4 12.7 10.7-7.9 10.8 7.9-4.3-12.7 11-7.9h-13.5z">
|
||||
</path>
|
||||
</g>
|
||||
</svg>
|
||||
<span class="ml-1">
|
||||
English</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
Executable
+1
@@ -0,0 +1 @@
|
||||
kill -9 $(lsof -t -i:8080) || true
|
||||
@@ -0,0 +1 @@
|
||||
<nav class="hidden h-[77px] xl:flex"><ul class="flex h-full items-center xl:space-x-[26px] space-x-4"><li class="h-full group flex-shrink-0"><a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/gioi-thieu-tong-quan"><span >Về Bệnh viện</span><svg width="10" height="5" viewbox="0 0 10 5" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2 w-2 duration-150 ease-in-out text-gray-300 group-hover:-rotate-180"><path d="M0.759766 0.5L4.68906 4.42929C4.72811 4.46834 4.79142 4.46834 4.83048 4.42929L8.75977 0.5" stroke="currentColor" stroke-linecap="round"></path></svg></a></li><li class="h-full group flex-shrink-0"><a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/chuyen-khoa"><span >Chuyên khoa</span></a></li><li class="h-full group flex-shrink-0"><a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/bac-si"><span >Bác sĩ</span></a></li><li class="h-full group flex-shrink-0"><a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/dich-vu"><span >Dịch vụ</span><svg width="10" height="5" viewbox="0 0 10 5" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2 w-2 duration-150 ease-in-out text-gray-300 group-hover:-rotate-180"><path d="M0.759766 0.5L4.68906 4.42929C4.72811 4.46834 4.79142 4.46834 4.83048 4.42929L8.75977 0.5" stroke="currentColor" stroke-linecap="round"></path></svg></a></li><li class="h-full group flex-shrink-0"><a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/thu-vien-suc-khoe"><span >Thư viện sức khỏe</span></a></li><li class="h-full group flex-shrink-0"><a class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 " href="https://bvdaihoc.com.vn/tin-tuc-va-su-kien"><span >Tin tức & Sự kiện</span><svg width="10" height="5" viewbox="0 0 10 5" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2 w-2 duration-150 ease-in-out text-gray-300 group-hover:-rotate-180"><path d="M0.759766 0.5L4.68906 4.42929C4.72811 4.46834 4.79142 4.46834 4.83048 4.42929L8.75977 0.5" stroke="currentColor" stroke-linecap="round"></path></svg></a></li><li class="h-full group flex-shrink-0"><button class="flex flex-shrink-0 title-2 text-primary-600 h-full items-center gap-2 duration-150 ease-in-out underline-offset-4 cursor-pointer "><span >Hỗ trợ người bệnh</span><svg width="10" height="5" viewbox="0 0 10 5" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-2 w-2 duration-150 ease-in-out text-gray-300 group-hover:-rotate-180"><path d="M0.759766 0.5L4.68906 4.42929C4.72811 4.46834 4.79142 4.46834 4.83048 4.42929L8.75977 0.5" stroke="currentColor" stroke-linecap="round"></path></svg></button></li></ul></nav>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,60 @@
|
||||
import csv
|
||||
import re
|
||||
|
||||
csv_path = '/home/x79/sisvietnamvn_01/Design/List of all WP action hooks and filters -- Adam Brown, BYU Political Science.csv'
|
||||
java_path = '/home/x79/sisvietnamvn_01/sisvietnamvn_main/src/main/java/com/sisvietnamvn/web/hook/WpHooks.java'
|
||||
|
||||
def sanitize_constant_name(hook_name):
|
||||
# Convert {$plugin} to PLUGIN
|
||||
name = re.sub(r'\{\$([a-zA-Z0-9_]+)\}', r'\1', hook_name)
|
||||
name = re.sub(r'[^a-zA-Z0-9_]', '_', name).upper()
|
||||
|
||||
# Handle multiple underscores or leading numbers
|
||||
name = re.sub(r'_+', '_', name)
|
||||
name = name.strip('_')
|
||||
|
||||
if name and name[0].isdigit():
|
||||
name = "HOOK_" + name
|
||||
|
||||
return name
|
||||
|
||||
with open(csv_path, 'r', encoding='utf-8-sig') as f:
|
||||
reader = csv.reader(f)
|
||||
next(reader) # Skip header
|
||||
|
||||
hooks = set()
|
||||
for row in reader:
|
||||
if len(row) > 1 and row[1].strip():
|
||||
hooks.add(row[1].strip())
|
||||
|
||||
with open(java_path, 'w', encoding='utf-8') as f:
|
||||
f.write("package com.sisvietnamvn.web.hook;\n\n")
|
||||
f.write("/**\n")
|
||||
f.write(" * Automatically generated dictionary of all WordPress Hooks.\n")
|
||||
f.write(" * Contains " + str(len(hooks)) + " constants.\n")
|
||||
f.write(" */\n")
|
||||
f.write("public final class WpHooks {\n\n")
|
||||
f.write(" private WpHooks() {}\n\n")
|
||||
|
||||
# Track written constants to avoid duplicates
|
||||
written = set()
|
||||
|
||||
for hook in sorted(list(hooks)):
|
||||
const_name = sanitize_constant_name(hook)
|
||||
if not const_name:
|
||||
continue
|
||||
|
||||
if const_name in written:
|
||||
const_name = const_name + "_2" # Simple deduplication
|
||||
|
||||
written.add(const_name)
|
||||
|
||||
# Add comment with original hook name
|
||||
f.write(f' /**\n')
|
||||
f.write(f' * Original hook name: {hook}\n')
|
||||
f.write(f' */\n')
|
||||
f.write(f' public static final String {const_name} = "{hook}";\n\n')
|
||||
|
||||
f.write("}\n")
|
||||
print(f"Generated {len(written)} hook constants in WpHooks.java")
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class ReadSnippets {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/sisvietnam", "sisvietnam", "sisvietnam");
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT slug, content FROM html_snippet");
|
||||
while (rs.next()) {
|
||||
System.out.println("Snippet: " + rs.getString("slug"));
|
||||
if (rs.getString("slug").equals("content_main")) {
|
||||
System.out.println(rs.getString("content"));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
import re
|
||||
|
||||
filepath = "src/main/resources/templates/themes/umass/footer.html"
|
||||
with open(filepath, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
# We want to replace the `a.logo` block with our new logo
|
||||
# Using DOTALL to match across newlines
|
||||
pattern = r'<a class="logo"[^>]*>.*?</a>'
|
||||
replacement = '<a class="logo" href="/" aria-label="Sisvietnamvn">\n <div>\n <img th:src="@{/theme-assets/umass/images/logo.png}" alt="Sisvietnamvn" style="height: 60px; width: auto;"/>\n </div>\n</a>'
|
||||
|
||||
content = re.sub(pattern, replacement, content, count=1, flags=re.DOTALL)
|
||||
|
||||
with open(filepath, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
print("Updated footer.html")
|
||||
@@ -0,0 +1,23 @@
|
||||
import re
|
||||
|
||||
filepath = "src/main/resources/templates/themes/umass/header.html"
|
||||
with open(filepath, "r", encoding="utf-8") as f:
|
||||
content = f.read()
|
||||
|
||||
# Tophat logo
|
||||
content = re.sub(
|
||||
r'<div class="tophat-logo">\s*<a href="[^"]*">\s*<img[^>]*>\s*</a>\s*</div>',
|
||||
'<div class="tophat-logo">\n <a href="/">\n <img th:src="@{/theme-assets/umass/images/logo.png}" alt="Sisvietnamvn" style="height: 35px; width: auto;"/>\n </a>\n </div>',
|
||||
content
|
||||
)
|
||||
|
||||
# Header branding logos
|
||||
content = re.sub(
|
||||
r'<div data-component-id="umass_base:header-branding">\s*<a href="[^"]*">\s*<img[^>]*>\s*<img[^>]*>\s*</a>\s*</div>',
|
||||
'<div data-component-id="umass_base:header-branding">\n <a href="/">\n <img th:src="@{/theme-assets/umass/images/logo.png}" alt="Sisvietnamvn" style="height: 60px; width: auto;"/>\n </a>\n</div>',
|
||||
content
|
||||
)
|
||||
|
||||
with open(filepath, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
print("Updated header.html")
|
||||
Binary file not shown.
@@ -0,0 +1,90 @@
|
||||
# TÀI LIỆU YÊU CẦU WEBSITE BỆNH VIỆN S.I.S CẦN THƠ
|
||||
*(Trích xuất từ file WEBSITE BENH VIEN.xlsx)*
|
||||
|
||||
Tài liệu này đóng vai trò là kim chỉ nam cho Developer (IDE Code) để thiết kế kiến trúc hệ thống, cơ sở dữ liệu và giao diện người dùng cho Website Bệnh viện Đa khoa Quốc tế S.I.S Cần Thơ.
|
||||
|
||||
---
|
||||
|
||||
## 1. TỔNG QUAN DỰ ÁN
|
||||
### 1.1. Đối tượng khách hàng mục tiêu
|
||||
* **Độ tuổi:** Trung niên (Từ 30 - 60 tuổi). Do đó, UI/UX cần rõ ràng, dễ nhìn, chữ to, dễ thao tác.
|
||||
* **Hành vi:** Có nhu cầu và quan tâm đặc biệt đến việc chăm sóc sức khỏe đối với các bệnh: **Đột quỵ, Tim mạch, Cơ xương khớp**.
|
||||
|
||||
### 1.2. Mục đích cốt lõi của Website
|
||||
1. Cung cấp thông tin Giới thiệu về Dịch vụ Bệnh viện.
|
||||
2. Quảng bá thương hiệu S.I.S.
|
||||
3. Đẩy mạnh các chiến dịch PR & Marketing trực tuyến.
|
||||
4. Cung cấp kiến thức giáo dục sức khỏe cộng đồng.
|
||||
|
||||
---
|
||||
|
||||
## 2. YÊU CẦU THIẾT KẾ VÀ KỸ THUẬT (TECHNICAL SPECS)
|
||||
* **Ngôn ngữ:** Hỗ trợ Song ngữ (Tiếng Anh - Tiếng Việt). Cần thiết lập cấu trúc i18n cho Frontend.
|
||||
* **Bố cục (Layout):**
|
||||
* Chia cột rõ ràng (Trái / Phải).
|
||||
* **Cột trái:** Hiển thị luồng Tin tức Bệnh viện.
|
||||
* **Cột phải:** Hiển thị các Banner Gói khám nổi bật hoặc Chương trình Khuyến mãi mới nhất.
|
||||
* **Đa phương tiện:** Tích hợp âm thanh vào các Banner/Cover chính.
|
||||
* **Tính năng lõi:**
|
||||
* **Tích hợp cổng Thanh toán trực tuyến** (VNPAY, Paypal... do Kế toán và IT quyết định).
|
||||
* Check chính tả tự động.
|
||||
* **Tối ưu hóa (SEO & Performance):**
|
||||
* Tốc độ tải trang nhanh (Cần tối ưu dung lượng ảnh Slider/Banner).
|
||||
* Truy xuất dữ liệu chuẩn SEO và tích hợp Google Analytics, Google Search Console.
|
||||
|
||||
---
|
||||
|
||||
## 3. CẤU TRÚC SITEMAP & TÍNH NĂNG CHI TIẾT
|
||||
|
||||
### I. VỀ CHÚNG TÔI
|
||||
Trọng tâm sử dụng đồ họa trực quan (Infographic) để gây ấn tượng.
|
||||
* **Giới thiệu Bệnh viện:** Thông tin Ban giám đốc.
|
||||
* **Giá trị cốt lõi / Tầm nhìn / Sứ mệnh**
|
||||
* **Lịch sử hình thành:** Hiển thị dưới dạng Infographic **Chuỗi thời gian (Timeline)**.
|
||||
* **Giải thưởng:** Hiển thị dưới dạng Infographic Chuỗi thời gian. Cập nhật liên tục.
|
||||
* **Sơ đồ tổ chức:** Hiển thị dưới dạng Infographic **Mạng lưới (Network/Tree)**.
|
||||
|
||||
### II. DỊCH VỤ BỆNH VIỆN
|
||||
* **Gói tầm soát sức khỏe:** Các trang giới thiệu gói khám riêng biệt. (Giá có thể thay đổi).
|
||||
* **Dịch vụ nổi bật:** Kỹ thuật đặt stent + coil, Hút huyết khối, Nội soi khớp/Super bath, Phẫu thuật bắt cầu động mạch cảnh, Phẫu thuật mở sọ giải áp, Phục hồi chức năng.
|
||||
* **Trang thiết bị:** MRI, DSA, Hệ thống xét nghiệm, Phòng mổ Hybrid, Cấp cứu di động + Ca nô.
|
||||
* **Tổng đài cấp cứu Đột quỵ**
|
||||
* **Đặt lịch khám:** Form cố định. Danh sách bác sĩ thay đổi theo tuần. Cần lấy dữ liệu từ hệ thống Call Center.
|
||||
* **Thanh toán trực tuyến:** Module thanh toán.
|
||||
|
||||
### III. TÌM BÁC SĨ
|
||||
Trang danh bạ Bác sĩ toàn viện. Cấu trúc Profile bác sĩ bao gồm:
|
||||
1. Họ và tên
|
||||
2. Chuyên khoa
|
||||
3. Kinh nghiệm làm việc
|
||||
4. **Hệ thống đánh giá/Review:** Khách hàng có thể để lại Nhận xét (Gồm Họ tên, SĐT, Email). Cam kết bảo mật thông tin.
|
||||
5. Nút "Đăng ký khám" trỏ về tính năng Đặt lịch.
|
||||
|
||||
### IV. CHUYÊN KHOA
|
||||
* Danh sách tất cả các chuyên khoa và phòng ban tại bệnh viện.
|
||||
|
||||
### V. GÓC KHÁCH HÀNG
|
||||
* **Giờ làm việc**
|
||||
* **Khám bệnh Ngoại trú:** Quy trình khám, Hướng dẫn BHYT, Hướng dẫn khám Dịch vụ.
|
||||
* **Điều trị Nội trú:** Dịch vụ phòng nội trú, Thông tin thăm bệnh, Thông tin nhập/xuất viện.
|
||||
* **Thông tin viện phí:** Bảng biểu phí (Cập nhật thường xuyên bởi Kế toán).
|
||||
* **Hỏi Bác sĩ S.I.S:** Cung cấp Form thu thập câu hỏi gồm các trường:
|
||||
* *Họ tên, SĐT, Email.*
|
||||
* *Chủ đề dropdown:* Thần kinh-Đột quỵ, Tim mạch, Cơ xương khớp, Phục hồi chức năng, Khác.
|
||||
* *Ô nhập Câu hỏi.*
|
||||
|
||||
### VI. GÓC TRUYỀN THÔNG
|
||||
Cho phép khách hàng để lại bình luận/phản hồi ở mọi bài viết.
|
||||
* **Tin tức:** Blog tin bài cập nhật hàng tuần.
|
||||
* **Cẩm nang sức khỏe:** Các lời khuyên của bác sĩ (Đột quỵ, Tim mạch, Cơ xương khớp...).
|
||||
* **Câu chuyện bệnh nhân:** Bài viết hoặc Video thực tế.
|
||||
* **Góc Tri ân:** Nơi đăng tải thư cảm ơn của bệnh nhân.
|
||||
|
||||
### VII. KHÁC
|
||||
* Hoạt động từ thiện / Hoạt động nội bộ
|
||||
* Chương trình Đào tạo / Tuyển dụng
|
||||
* Liên hệ
|
||||
|
||||
> [!IMPORTANT]
|
||||
> **Ghi chú cho Developer:**
|
||||
> Dựa trên yêu cầu này, hệ thống cần một CMS linh hoạt (như đã phân tích là WordPress hoặc hệ thống nội bộ). DB Schema cần chú trọng các bảng: `Doctors`, `Specialties`, `Services/Packages`, `News/Blogs`, `Questions`, và `Reviews`. Phân quyền Backend cần tách biệt rõ ràng cho `Team Truyền thông` (quản lý bài viết) và `Team Kế toán` (Quản lý giá dịch vụ/thanh toán).
|
||||
@@ -0,0 +1,61 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
var tabs = document.querySelectorAll('.tabbed-media-content-media-item[data-tab-id="tabbed-content-0"]');
|
||||
if(tabs.length > 0) tabs[0].classList.add('is-active');
|
||||
|
||||
var panels = document.querySelectorAll('#tabbed-content-0.tab-content-panel');
|
||||
if(panels.length > 0) panels[0].classList.add('is-active');
|
||||
|
||||
var labels = document.querySelectorAll('a.tab-label[aria-controls="tabbed-content-0"]');
|
||||
if(labels.length > 0) labels[0].setAttribute('aria-selected', 'true');
|
||||
|
||||
var allLabels = document.querySelectorAll('.tab-labels-inner .tab-label');
|
||||
allLabels.forEach(function(label) {
|
||||
label.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
allLabels.forEach(function(l) { l.setAttribute('aria-selected', 'false'); });
|
||||
this.setAttribute('aria-selected', 'true');
|
||||
|
||||
var targetId = this.getAttribute('aria-controls');
|
||||
document.querySelectorAll('.tab-content-panel').forEach(function(p) { p.classList.remove('is-active'); });
|
||||
document.querySelectorAll('.tabbed-media-content-media-item').forEach(function(m) {
|
||||
m.classList.remove('is-active');
|
||||
var img = m.querySelector('.f--image');
|
||||
if(img) img.style.display = 'block';
|
||||
var btnContainer = m.querySelector('.f--field.f--button');
|
||||
if(btnContainer) btnContainer.style.display = 'block';
|
||||
var iframe = m.querySelector('iframe');
|
||||
if(iframe) iframe.removeAttribute('src'); // Stop video playing if they switch tabs
|
||||
});
|
||||
|
||||
var targetPanel = document.getElementById(targetId);
|
||||
if(targetPanel) targetPanel.classList.add('is-active');
|
||||
var targetMedia = document.querySelector('.tabbed-media-content-media-item[data-tab-id="' + targetId + '"]');
|
||||
if(targetMedia) targetMedia.classList.add('is-active');
|
||||
});
|
||||
});
|
||||
|
||||
var playButtons = document.querySelectorAll('.tabbed-media-content-media-item .button-play');
|
||||
playButtons.forEach(function(btn) {
|
||||
btn.addEventListener('click', function(e) {
|
||||
e.preventDefault();
|
||||
var mediaItem = this.closest('.tabbed-media-content-media-item');
|
||||
var img = mediaItem.querySelector('.f--image');
|
||||
var btnContainer = mediaItem.querySelector('.f--field.f--button');
|
||||
var iframe = mediaItem.querySelector('iframe');
|
||||
|
||||
if(img) img.style.display = 'none';
|
||||
if(btnContainer) btnContainer.style.display = 'none';
|
||||
if(iframe && iframe.getAttribute('data-src')) {
|
||||
iframe.setAttribute('src', iframe.getAttribute('data-src'));
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,7 @@
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||
public class test_auth {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("hello");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.Statement;
|
||||
|
||||
public class test_db {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521/FREEPDB1", "sisvietnam", "sisvietnam");
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT name FROM jhi_authority");
|
||||
while (rs.next()) {
|
||||
System.out.println(rs.getString("name"));
|
||||
}
|
||||
conn.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
public class test_uri {
|
||||
public static void main(String[] args) {
|
||||
String base = "https://accounts.google.com/o/oauth2/v2/auth?prompt=select_account";
|
||||
String full = UriComponentsBuilder.fromUriString(base)
|
||||
.queryParam("client_id", "123")
|
||||
.build().toUriString();
|
||||
System.out.println(full);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
import java.net.URI;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
public class test_uri2 {
|
||||
public static void main(String[] args) {
|
||||
// Mock what Spring Security does
|
||||
String base = "https://accounts.google.com/o/oauth2/v2/auth?prompt=select_account";
|
||||
String full = UriComponentsBuilder.fromUriString(base)
|
||||
.queryParam("client_id", "123")
|
||||
.queryParam("response_type", "code")
|
||||
.build().toUriString();
|
||||
System.out.println(full);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
Executable
+2
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
# A dummy script just to make sure things are flushed
|
||||
@@ -0,0 +1,35 @@
|
||||
SET DEFINE OFF;
|
||||
UPDATE html_snippet SET content = '
|
||||
<div class="cc--component-container cc--stats-block bg-old-brick" style="color: white;">
|
||||
<div class="c--component c--stats-block">
|
||||
<div class="f--field f--stats-block">
|
||||
<div class="cc--component-container cc--stat">
|
||||
<div class="c--component c--stat">
|
||||
<div class="f--field f--stat-number">50.000+</div>
|
||||
<div class="f--field f--description">
|
||||
<p>Tổng số ca cấp cứu</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cc--component-container cc--stat">
|
||||
<div class="c--component c--stat">
|
||||
<div class="f--field f--stat-number">1.6tr+</div>
|
||||
<div class="f--field f--description">
|
||||
<p>Tổng số ca khám bệnh</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cc--component-container cc--stat">
|
||||
<div class="c--component c--stat">
|
||||
<div class="f--field f--stat-number">#1</div>
|
||||
<div class="f--field f--description">
|
||||
<p>Về điều trị đột quỵ</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
' WHERE slug = 'block_3_button';
|
||||
COMMIT;
|
||||
EXIT;
|
||||
@@ -0,0 +1,35 @@
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class update_theme {
|
||||
public static void main(String[] args) {
|
||||
String url = "jdbc:oracle:thin:@localhost:1521/sisvietnam";
|
||||
String user = "sisvietnam";
|
||||
String password = "sisvietnam";
|
||||
|
||||
try (Connection conn = DriverManager.getConnection(url, user, password)) {
|
||||
// Let's first see what's in sis_setting
|
||||
try (PreparedStatement checkStmt = conn.prepareStatement("SELECT ID, THEME FROM sis_setting")) {
|
||||
ResultSet rs = checkStmt.executeQuery();
|
||||
while (rs.next()) {
|
||||
System.out.println("ID: " + rs.getLong("ID") + ", THEME: " + rs.getString("THEME"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Error reading theme: " + e.getMessage());
|
||||
}
|
||||
|
||||
// Update theme
|
||||
String updateQuery = "UPDATE sis_setting SET THEME = 'umass'";
|
||||
try (PreparedStatement updateStmt = conn.prepareStatement(updateQuery)) {
|
||||
int rows = updateStmt.executeUpdate();
|
||||
System.out.println("Rows updated: " + rows);
|
||||
}
|
||||
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user