Compare commits
4 Commits
73dda8b648
...
f27b57ec8b
| Author | SHA1 | Date | |
|---|---|---|---|
| f27b57ec8b | |||
| 5e0773a59f | |||
| 70ea5f4dd4 | |||
| 31ea86d90c |
@@ -33,7 +33,7 @@ public class SaTokenConfig implements WebMvcConfigurer {
|
|||||||
// 排除教程接口(支持匿名查询)
|
// 排除教程接口(支持匿名查询)
|
||||||
.excludePathPatterns("/tutorial", "/tutorial/**")
|
.excludePathPatterns("/tutorial", "/tutorial/**")
|
||||||
// 排除隐私政策接口(支持匿名查询)
|
// 排除隐私政策接口(支持匿名查询)
|
||||||
.excludePathPatterns("/agreement", "/agreement/**")
|
.excludePathPatterns("/privacy_policy", "/privacy_policy/**")
|
||||||
// 排除固件查询接口(不需要登录)
|
// 排除固件查询接口(不需要登录)
|
||||||
.excludePathPatterns("/firmware/**")
|
.excludePathPatterns("/firmware/**")
|
||||||
// 排除系统登录页(不需要登录)
|
// 排除系统登录页(不需要登录)
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
package com.corewing.app.modules.app;
|
|
||||||
|
|
||||||
import org.springframework.stereotype.Controller;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 隐私政策与协议
|
|
||||||
*/
|
|
||||||
@Controller
|
|
||||||
@RequestMapping("/agreement")
|
|
||||||
public class AppAgreementController {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 隐私政策列表
|
|
||||||
* @return
|
|
||||||
*/
|
|
||||||
@GetMapping("/viewList/{lang}")
|
|
||||||
public String viewList(@PathVariable String lang) {
|
|
||||||
return "app/agreement/index";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package com.corewing.app.modules.app;
|
||||||
|
|
||||||
|
import com.corewing.app.entity.PrivacyPolicy;
|
||||||
|
import com.corewing.app.service.PrivacyPolicyService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 隐私政策与协议
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/privacy_policy")
|
||||||
|
public class AppPrivacyPolicyController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PrivacyPolicyService privacyPolicyService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 隐私政策列表
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/view_list/{lang}")
|
||||||
|
public String viewList(@PathVariable String lang, ModelMap modelMap) {
|
||||||
|
List<PrivacyPolicy> list = privacyPolicyService.list();
|
||||||
|
modelMap.put("list", list);
|
||||||
|
// 获取最新更新时间
|
||||||
|
modelMap.put("lastUpdateTime", privacyPolicyService.getLastUpdateTime());
|
||||||
|
return "app/privacyPolicy/index";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,4 +7,6 @@ import com.corewing.app.entity.PrivacyPolicy;
|
|||||||
public interface PrivacyPolicyService extends IService<PrivacyPolicy> {
|
public interface PrivacyPolicyService extends IService<PrivacyPolicy> {
|
||||||
|
|
||||||
Page<PrivacyPolicy> page(PrivacyPolicy privacyPolicy);
|
Page<PrivacyPolicy> page(PrivacyPolicy privacyPolicy);
|
||||||
|
|
||||||
|
String getLastUpdateTime();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import com.corewing.app.common.page.PageContext;
|
|||||||
import com.corewing.app.entity.PrivacyPolicy;
|
import com.corewing.app.entity.PrivacyPolicy;
|
||||||
import com.corewing.app.mapper.PrivacyPolicyMapper;
|
import com.corewing.app.mapper.PrivacyPolicyMapper;
|
||||||
import com.corewing.app.service.PrivacyPolicyService;
|
import com.corewing.app.service.PrivacyPolicyService;
|
||||||
|
import com.corewing.app.util.DateUtils;
|
||||||
import org.springframework.aop.framework.ProxyFactory;
|
import org.springframework.aop.framework.ProxyFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
@@ -21,4 +22,12 @@ public class PrivacyPolicyServiceImpl extends ServiceImpl<PrivacyPolicyMapper, P
|
|||||||
queryWrapper.eq(privacyPolicy.getVisible() != null, PrivacyPolicy::getVisible, privacyPolicy.getVisible());
|
queryWrapper.eq(privacyPolicy.getVisible() != null, PrivacyPolicy::getVisible, privacyPolicy.getVisible());
|
||||||
return page(page, queryWrapper);
|
return page(page, queryWrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getLastUpdateTime() {
|
||||||
|
LambdaQueryWrapper<PrivacyPolicy> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
queryWrapper.orderByDesc(PrivacyPolicy::getUpdateTime, PrivacyPolicy::getCreateTime);
|
||||||
|
PrivacyPolicy privacyPolicy = list(queryWrapper).get(0);
|
||||||
|
return DateUtils.format(privacyPolicy.getUpdateTime() == null ? privacyPolicy.getCreateTime() : privacyPolicy.getUpdateTime(), "yyyy年MM月dd日");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
14
src/main/java/com/corewing/app/util/DateUtils.java
Normal file
14
src/main/java/com/corewing/app/util/DateUtils.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package com.corewing.app.util;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
public class DateUtils {
|
||||||
|
|
||||||
|
// 格式化LocalDateTime为字符串
|
||||||
|
public static String format(LocalDateTime time, String pattern) {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(pattern);
|
||||||
|
return time.format(formatter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>隐私政策</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
145
src/main/resources/templates/app/privacyPolicy/index.html
Normal file
145
src/main/resources/templates/app/privacyPolicy/index.html
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh-CN" xmlns:th="http://www.thymeleaf.org">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
|
<title>隐私政策</title>
|
||||||
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<!-- 配置Tailwind自定义样式 -->
|
||||||
|
<script>
|
||||||
|
tailwind.config = {
|
||||||
|
theme: {
|
||||||
|
extend: {
|
||||||
|
colors: {
|
||||||
|
primary: '#165DFF',
|
||||||
|
secondary: '#6B7280',
|
||||||
|
light: '#F3F4F6',
|
||||||
|
dark: '#1F2937'
|
||||||
|
},
|
||||||
|
fontFamily: {
|
||||||
|
sans: ['Inter', 'system-ui', 'sans-serif'],
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style type="text/tailwindcss">
|
||||||
|
@layer utilities {
|
||||||
|
.content-auto {
|
||||||
|
content-visibility: auto;
|
||||||
|
}
|
||||||
|
.text-balance {
|
||||||
|
text-wrap: balance;
|
||||||
|
}
|
||||||
|
.transition-height {
|
||||||
|
transition: max-height 0.3s ease-out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="bg-gray-50 font-sans text-dark">
|
||||||
|
<!-- 顶部导航栏 -->
|
||||||
|
<header class="sticky top-0 z-50 bg-white shadow-sm">
|
||||||
|
<div class="container mx-auto px-4 py-4 flex justify-center items-center">
|
||||||
|
<h1 class="text-xl font-semibold text-dark">隐私政策</h1>
|
||||||
|
<!-- <button class="text-primary hover:text-primary/80 transition-colors">-->
|
||||||
|
<!-- <i class="fa fa-arrow-left text-lg"></i>-->
|
||||||
|
<!-- </button>-->
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<!-- 主要内容区 -->
|
||||||
|
<main class="container mx-auto px-4 py-6">
|
||||||
|
<!-- 政策更新信息 -->
|
||||||
|
<div class="bg-primary/10 border-l-4 border-primary p-4 rounded-r mb-6">
|
||||||
|
<p class="text-sm text-primary">
|
||||||
|
<i class="fa fa-info-circle mr-2"></i>
|
||||||
|
最后更新日期:<span th:text="${lastUpdateTime}"></span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 隐私政策列表 -->
|
||||||
|
<div class="space-y-1">
|
||||||
|
<!-- 使用Thymeleaf循环渲染列表项 -->
|
||||||
|
<div th:each="item: ${list}" class="bg-white rounded-lg shadow-sm overflow-hidden mb-3 transform hover:shadow-md transition-shadow">
|
||||||
|
<!-- 列表项标题 -->
|
||||||
|
<div class="flex justify-between items-center p-4 cursor-pointer policy-toggle">
|
||||||
|
<h2 class="text-base font-medium text-dark" th:text="${item.title}"></h2>
|
||||||
|
<i class="fa fa-chevron-down text-secondary transition-transform duration-300"></i>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 列表项内容 -->
|
||||||
|
<div class="policy-content max-h-0 overflow-hidden transition-height">
|
||||||
|
<div class="px-4 pb-4 text-sm text-secondary leading-relaxed text-balance">
|
||||||
|
<p th:utext="${item.content}">
|
||||||
|
这里将显示隐私政策的详细内容,包括我们如何收集、使用、存储和保护您的个人信息,以及您拥有的相关权利和选择。
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 示例默认项(实际使用时由Thymeleaf数据替换) -->
|
||||||
|
<div class="bg-white rounded-lg shadow-sm overflow-hidden mb-3 transform hover:shadow-md transition-shadow">
|
||||||
|
<div class="flex justify-between items-center p-4 cursor-pointer policy-toggle">
|
||||||
|
<h2 class="text-base font-medium text-dark">信息收集与使用</h2>
|
||||||
|
<i class="fa fa-chevron-down text-secondary transition-transform duration-300"></i>
|
||||||
|
</div>
|
||||||
|
<div class="policy-content max-h-0 overflow-hidden transition-height">
|
||||||
|
<div class="px-4 pb-4 text-sm text-secondary leading-relaxed text-balance">
|
||||||
|
<p>我们收集您在使用服务过程中提供的个人信息,包括但不限于姓名、联系方式、位置信息等。这些信息将用于提供、维护和改进我们的服务,开发新功能,并保护我们的用户和服务。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="bg-white rounded-lg shadow-sm overflow-hidden mb-3 transform hover:shadow-md transition-shadow">
|
||||||
|
<div class="flex justify-between items-center p-4 cursor-pointer policy-toggle">
|
||||||
|
<h2 class="text-base font-medium text-dark">信息共享与披露</h2>
|
||||||
|
<i class="fa fa-chevron-down text-secondary transition-transform duration-300"></i>
|
||||||
|
</div>
|
||||||
|
<div class="policy-content max-h-0 overflow-hidden transition-height">
|
||||||
|
<div class="px-4 pb-4 text-sm text-secondary leading-relaxed text-balance">
|
||||||
|
<p>我们不会向第三方出售您的个人信息。在以下情况下,我们可能会共享您的信息:获得您的明确同意;为提供您要求的产品或服务;遵守适用的法律法规、法律程序或政府要求;保护我们的权利、财产或安全,以及我们的用户和公众的权利。</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- 底部提示 -->
|
||||||
|
<div class="mt-8 text-center text-xs text-secondary">
|
||||||
|
<p>如有任何疑问,请联系我们的客服团队</p>
|
||||||
|
<p class="mt-1">service@example.com</p>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// 处理折叠/展开功能
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
const toggles = document.querySelectorAll('.policy-toggle');
|
||||||
|
|
||||||
|
toggles.forEach(toggle => {
|
||||||
|
toggle.addEventListener('click', function() {
|
||||||
|
const content = this.nextElementSibling;
|
||||||
|
const icon = this.querySelector('i');
|
||||||
|
|
||||||
|
// 切换内容显示状态
|
||||||
|
if (content.style.maxHeight) {
|
||||||
|
content.style.maxHeight = null;
|
||||||
|
icon.style.transform = 'rotate(0deg)';
|
||||||
|
} else {
|
||||||
|
content.style.maxHeight = content.scrollHeight + 'px';
|
||||||
|
icon.style.transform = 'rotate(180deg)';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 默认展开第一项
|
||||||
|
if (toggles.length > 0) {
|
||||||
|
toggles[0].click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -5,6 +5,6 @@
|
|||||||
<title th:text="${tutorial?.tutorialTitle}"></title>
|
<title th:text="${tutorial?.tutorialTitle}"></title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div th:utext="${tutorial.content}"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Reference in New Issue
Block a user