Browse Source

实名认证

master
wy 2 years ago
parent
commit
ed27e7a164
  1. 3
      .gitignore
  2. 2
      README.md
  3. 8
      pom.xml
  4. 1
      src/main/java/com/bt/common/JFinalClubConfig.java
  5. 5
      src/main/java/com/bt/common/_all_sqls.sql
  6. 5
      src/main/java/com/bt/common/model/Account.java
  7. 25
      src/main/java/com/bt/common/model/_Generator.java
  8. 6
      src/main/java/com/bt/common/model/_MappingKit.java
  9. 15
      src/main/java/com/bt/common/model/base/BaseAccount.java
  10. 1
      src/main/java/com/bt/common/model/base/BaseAuthCode.java
  11. 1
      src/main/java/com/bt/common/model/base/BaseDocument.java
  12. 1
      src/main/java/com/bt/common/model/base/BaseDownload.java
  13. 1
      src/main/java/com/bt/common/model/base/BaseDownloadLog.java
  14. 1
      src/main/java/com/bt/common/model/base/BaseFavorite.java
  15. 1
      src/main/java/com/bt/common/model/base/BaseFeedback.java
  16. 1
      src/main/java/com/bt/common/model/base/BaseFeedbackReply.java
  17. 1
      src/main/java/com/bt/common/model/base/BaseMessage.java
  18. 1
      src/main/java/com/bt/common/model/base/BaseNewsFeed.java
  19. 1
      src/main/java/com/bt/common/model/base/BasePermission.java
  20. 1
      src/main/java/com/bt/common/model/base/BaseProject.java
  21. 1
      src/main/java/com/bt/common/model/base/BaseReferMe.java
  22. 1
      src/main/java/com/bt/common/model/base/BaseRemind.java
  23. 1
      src/main/java/com/bt/common/model/base/BaseRole.java
  24. 1
      src/main/java/com/bt/common/model/base/BaseSession.java
  25. 1
      src/main/java/com/bt/common/model/base/BaseShare.java
  26. 1
      src/main/java/com/bt/common/model/base/BaseShareReply.java
  27. 1
      src/main/java/com/bt/common/model/base/BaseTaskList.java
  28. 225
      src/main/java/com/bt/common/realname/RealnameService.java
  29. 2
      src/main/java/com/bt/common/safe/JsoupFilter.java
  30. 10
      src/main/java/com/bt/index/IndexController.java
  31. 3
      src/main/java/com/bt/login/LoginController.java
  32. 38
      src/main/java/com/bt/my/setting/MySettingController.java
  33. 20
      src/main/java/com/bt/product/ProductController.java
  34. 51
      src/main/java/com/bt/product/ProductService.java
  35. 30
      src/main/java/com/bt/product/product.sql
  36. 7
      src/main/java/com/bt/reg/RegService.java
  37. 8
      src/main/resources/jfinal-club-config-dev.txt
  38. 3
      src/main/webapp/_view/_admin/common/_menu.html
  39. 183
      src/main/webapp/_view/_admin/product/add_edit.html
  40. 136
      src/main/webapp/_view/_admin/product/index.html
  41. 73
      src/main/webapp/_view/common/__b5layout.html
  42. 244
      src/main/webapp/_view/common/__official_layout.html
  43. 209
      src/main/webapp/_view/index/index.html
  44. 190
      src/main/webapp/_view/my/dashboard/_left_menu.html
  45. 489
      src/main/webapp/_view/my/dashboard/index.html
  46. 223
      src/main/webapp/_view/my/order/index.html
  47. 205
      src/main/webapp/_view/my/setting/realName.html
  48. 173
      src/main/webapp/_view/product/index.html
  49. 206
      src/main/webapp/_view/reg/index.html
  50. 3045
      src/main/webapp/assets/b5/css/bootstrap-admin.css
  51. 1
      src/main/webapp/assets/b5/css/bootstrap-admin.css.map
  52. 2
      src/main/webapp/assets/b5/css/bootstrap-admin.min.css
  53. 1
      src/main/webapp/assets/b5/css/bootstrap-admin.min.css.map
  54. BIN
      src/main/webapp/assets/b5/img/avatar.jpg
  55. BIN
      src/main/webapp/assets/b5/img/bootstrap-logo-shadow.png
  56. BIN
      src/main/webapp/assets/b5/img/bootstrap.png
  57. BIN
      src/main/webapp/assets/b5/img/cancel-off.png
  58. BIN
      src/main/webapp/assets/b5/img/cancel-on.png
  59. BIN
      src/main/webapp/assets/b5/img/captcha.gif
  60. BIN
      src/main/webapp/assets/b5/img/captcha.png
  61. BIN
      src/main/webapp/assets/b5/img/edge.jpg
  62. BIN
      src/main/webapp/assets/b5/img/favicon-16x16.png
  63. BIN
      src/main/webapp/assets/b5/img/favicon-32x32.png
  64. BIN
      src/main/webapp/assets/b5/img/gallery1.avif
  65. BIN
      src/main/webapp/assets/b5/img/gallery10.avif
  66. BIN
      src/main/webapp/assets/b5/img/gallery10_thumb.avif
  67. BIN
      src/main/webapp/assets/b5/img/gallery11.avif
  68. BIN
      src/main/webapp/assets/b5/img/gallery11_thumb.avif
  69. BIN
      src/main/webapp/assets/b5/img/gallery12.avif
  70. BIN
      src/main/webapp/assets/b5/img/gallery12_thumb.avif
  71. BIN
      src/main/webapp/assets/b5/img/gallery13.avif
  72. BIN
      src/main/webapp/assets/b5/img/gallery13_thumb.avif
  73. BIN
      src/main/webapp/assets/b5/img/gallery14.avif
  74. BIN
      src/main/webapp/assets/b5/img/gallery14_thumb.avif
  75. BIN
      src/main/webapp/assets/b5/img/gallery15.avif
  76. BIN
      src/main/webapp/assets/b5/img/gallery15_thumb.avif
  77. BIN
      src/main/webapp/assets/b5/img/gallery16.avif
  78. BIN
      src/main/webapp/assets/b5/img/gallery16_thumb.avif
  79. BIN
      src/main/webapp/assets/b5/img/gallery17.avif
  80. BIN
      src/main/webapp/assets/b5/img/gallery17_thumb.avif
  81. BIN
      src/main/webapp/assets/b5/img/gallery18.avif
  82. BIN
      src/main/webapp/assets/b5/img/gallery18_thumb.avif
  83. BIN
      src/main/webapp/assets/b5/img/gallery19.avif
  84. BIN
      src/main/webapp/assets/b5/img/gallery19_thumb.avif
  85. BIN
      src/main/webapp/assets/b5/img/gallery1_thumb.avif
  86. BIN
      src/main/webapp/assets/b5/img/gallery2.avif
  87. BIN
      src/main/webapp/assets/b5/img/gallery20.avif
  88. BIN
      src/main/webapp/assets/b5/img/gallery20_thumb.avif
  89. BIN
      src/main/webapp/assets/b5/img/gallery21.avif
  90. BIN
      src/main/webapp/assets/b5/img/gallery21_thumb.avif
  91. BIN
      src/main/webapp/assets/b5/img/gallery22.avif
  92. BIN
      src/main/webapp/assets/b5/img/gallery22_thumb.avif
  93. BIN
      src/main/webapp/assets/b5/img/gallery23.avif
  94. BIN
      src/main/webapp/assets/b5/img/gallery23_thumb.avif
  95. BIN
      src/main/webapp/assets/b5/img/gallery2_thumb.avif
  96. BIN
      src/main/webapp/assets/b5/img/gallery3.avif
  97. BIN
      src/main/webapp/assets/b5/img/gallery3_thumb.avif
  98. BIN
      src/main/webapp/assets/b5/img/gallery4.avif
  99. BIN
      src/main/webapp/assets/b5/img/gallery4_thumb.avif
  100. BIN
      src/main/webapp/assets/b5/img/gallery5.avif

3
.gitignore

@ -1,2 +1,3 @@
/log/ /log/
/target/ /target/
.idea/

2
README.md

@ -0,0 +1,2 @@
面板网站 https://zuramai.github.io/mazer/demo/account-profile.html

8
pom.xml

@ -50,6 +50,12 @@
<artifactId>jfinal</artifactId> <artifactId>jfinal</artifactId>
<version>5.1.2</version> <version>5.1.2</version>
</dependency> </dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.27</version>
</dependency>
@ -115,7 +121,7 @@
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version> <version>8.0.24</version>
</dependency> </dependency>
<!-- ehcache 缓存 --> <!-- ehcache 缓存 -->

1
src/main/java/com/bt/common/JFinalClubConfig.java

@ -171,6 +171,7 @@ public class JFinalClubConfig extends JFinalConfig {
me.addSharedMethod(AdminAuthKit.class); me.addSharedMethod(AdminAuthKit.class);
me.addSharedFunction("/_view/common/__layout.html"); me.addSharedFunction("/_view/common/__layout.html");
me.addSharedFunction("/_view/common/__official_layout.html");
me.addSharedFunction("/_view/common/__front_layout.html"); me.addSharedFunction("/_view/common/__front_layout.html");
me.addSharedFunction("/_view/common/__b5layout.html"); me.addSharedFunction("/_view/common/__b5layout.html");
me.addSharedFunction("/_view/common/_paginate.html"); me.addSharedFunction("/_view/common/_paginate.html");

5
src/main/java/com/bt/common/_all_sqls.sql

@ -8,6 +8,11 @@
#include("/com/bt/index/index.sql") #include("/com/bt/index/index.sql")
#end #end
#namespace("product")
#include("/com/bt/product/product.sql")
#end
#namespace("project") #namespace("project")
#include("/com/bt/project/project.sql") #include("/com/bt/project/project.sql")
#end #end

5
src/main/java/com/bt/common/model/Account.java

@ -29,6 +29,11 @@ public class Account extends BaseAccount<Account> {
public static final int STATUS_REG = 0; // 注册、未激活 public static final int STATUS_REG = 0; // 注册、未激活
public static final int STATUS_OK = 1; // 正常、已激活 public static final int STATUS_OK = 1; // 正常、已激活
public static final int REAL_NAME_YES = 1; //实名认证
public static final int REAL_NAME_NO = 0; //实名认证
public boolean isStatusOk() { public boolean isStatusOk() {
return getStatus() == STATUS_OK; return getStatus() == STATUS_OK;
} }

25
src/main/java/com/bt/common/model/_Generator.java

@ -14,9 +14,14 @@
package com.bt.common.model; package com.bt.common.model;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import com.jfinal.kit.PathKit; import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.dialect.MysqlDialect; import com.jfinal.plugin.activerecord.dialect.MysqlDialect;
import com.jfinal.plugin.activerecord.generator.Generator; import com.jfinal.plugin.activerecord.generator.Generator;
import com.jfinal.plugin.activerecord.generator.TypeMapping;
import com.jfinal.plugin.druid.DruidPlugin; import com.jfinal.plugin.druid.DruidPlugin;
import com.bt.common.JFinalClubConfig; import com.bt.common.JFinalClubConfig;
import javax.sql.DataSource; import javax.sql.DataSource;
@ -56,18 +61,15 @@ public class _Generator {
} }
public static void main(String[] args) { public static void main(String[] args) {
// base model 所使用的包名
String baseModelPackageName = "com.bt.common.model.base";
// base model 文件保存路径
String baseModelOutputDir = PathKit.getWebRootPath()
+ "/src/main/java/com/bt/common/model/base";
System.out.println("输出路径:"+ baseModelOutputDir);
// model 所使用的包名 (MappingKit 默认使用的包名) // model 所使用的包名 (MappingKit 默认使用的包名)
String modelPackageName = "com.bt.common.model"; String modelPackageName = "com.bt.common.model";
// base model 所使用的包名
String baseModelPackageName = modelPackageName + ".base";
// base model 文件保存路径
String baseModelOutputDir = System.getProperty("user.dir") + "/src/main/java/" + baseModelPackageName.replace('.', '/');;
// model 文件保存路径 (MappingKit 与 DataDictionary 文件默认保存路径) // model 文件保存路径 (MappingKit 与 DataDictionary 文件默认保存路径)
String modelOutputDir = baseModelOutputDir + "/.."; String modelOutputDir = baseModelOutputDir + "/..";
System.out.println("输出路径:"+ baseModelOutputDir);
// 创建生成器 // 创建生成器
Generator gen = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir); Generator gen = new Generator(getDataSource(), baseModelPackageName, baseModelOutputDir, modelPackageName, modelOutputDir);
@ -91,6 +93,13 @@ public class _Generator {
// 设置需要被移除的表名前缀用于生成modelName。例如表名 "osc_user",移除前缀 "osc_"后生成的model名为 "User"而非 OscUser // 设置需要被移除的表名前缀用于生成modelName。例如表名 "osc_user",移除前缀 "osc_"后生成的model名为 "User"而非 OscUser
// gernerator.setRemovedTableNamePrefixes("t_"); // gernerator.setRemovedTableNamePrefixes("t_");
// 将 mysql 8 以及其它原因之下生成 jdk 8 日期类型映射为 java.util.Date,便于兼容老项目,也便于习惯使用 java.util.Date 的同学
TypeMapping tm = new TypeMapping();
tm.addMapping(LocalDateTime.class, LocalDateTime.class);
tm.addMapping(LocalDate.class, LocalDateTime.class);
//tm.addMapping(LocalTime.class, LocalDateTime.class); // LocalTime 暂时不变
gen.setTypeMapping(tm);
// 生成 // 生成
gen.generate(); gen.generate();

6
src/main/java/com/bt/common/model/_MappingKit.java

@ -18,6 +18,7 @@ public class _MappingKit {
public static void mapping(ActiveRecordPlugin arp) { public static void mapping(ActiveRecordPlugin arp) {
arp.addMapping("account", "id", Account.class); arp.addMapping("account", "id", Account.class);
arp.addMapping("auth_code", "id", AuthCode.class); arp.addMapping("auth_code", "id", AuthCode.class);
arp.addMapping("device", "id", Device.class);
// Composite Primary Key order: mainMenu,subMenu // Composite Primary Key order: mainMenu,subMenu
arp.addMapping("document", "mainMenu,subMenu", Document.class); arp.addMapping("document", "mainMenu,subMenu", Document.class);
arp.addMapping("download", "id", Download.class); arp.addMapping("download", "id", Download.class);
@ -27,8 +28,12 @@ public class _MappingKit {
arp.addMapping("feedback_reply", "id", FeedbackReply.class); arp.addMapping("feedback_reply", "id", FeedbackReply.class);
arp.addMapping("message", "id", Message.class); arp.addMapping("message", "id", Message.class);
arp.addMapping("news_feed", "id", NewsFeed.class); arp.addMapping("news_feed", "id", NewsFeed.class);
arp.addMapping("order", "id", Order.class);
arp.addMapping("order_detail", "id", OrderDetail.class);
arp.addMapping("permission", "id", Permission.class); arp.addMapping("permission", "id", Permission.class);
arp.addMapping("product", "id", Product.class);
arp.addMapping("project", "id", Project.class); arp.addMapping("project", "id", Project.class);
arp.addMapping("realname_verification", "id", RealnameVerification.class);
arp.addMapping("refer_me", "id", ReferMe.class); arp.addMapping("refer_me", "id", ReferMe.class);
arp.addMapping("remind", "accountId", Remind.class); arp.addMapping("remind", "accountId", Remind.class);
arp.addMapping("role", "id", Role.class); arp.addMapping("role", "id", Role.class);
@ -39,3 +44,4 @@ public class _MappingKit {
} }
} }

15
src/main/java/com/bt/common/model/base/BaseAccount.java

@ -95,4 +95,19 @@ public abstract class BaseAccount<M extends BaseAccount<M>> extends Model<M> imp
return getInt("likeCount"); return getInt("likeCount");
} }
/**
* 是否实名认知 0:未完成 1完成
*/
public void setRealnameVerified(java.lang.Integer realnameVerified) {
set("realnameVerified", realnameVerified);
}
/**
* 是否实名认知 0:未完成 1完成
*/
public java.lang.Integer getRealnameVerified() {
return getInt("realnameVerified");
}
} }

1
src/main/java/com/bt/common/model/base/BaseAuthCode.java

@ -42,3 +42,4 @@ public abstract class BaseAuthCode<M extends BaseAuthCode<M>> extends Model<M> i
} }
} }

1
src/main/java/com/bt/common/model/base/BaseDocument.java

@ -78,3 +78,4 @@ public abstract class BaseDocument<M extends BaseDocument<M>> extends Model<M> i
} }
} }

1
src/main/java/com/bt/common/model/base/BaseDownload.java

@ -94,3 +94,4 @@ public abstract class BaseDownload<M extends BaseDownload<M>> extends Model<M> i
} }
} }

1
src/main/java/com/bt/common/model/base/BaseDownloadLog.java

@ -50,3 +50,4 @@ public abstract class BaseDownloadLog<M extends BaseDownloadLog<M>> extends Mode
} }
} }

1
src/main/java/com/bt/common/model/base/BaseFavorite.java

@ -68,3 +68,4 @@ public abstract class BaseFavorite<M extends BaseFavorite<M>> extends Model<M> i
} }
} }

1
src/main/java/com/bt/common/model/base/BaseFeedback.java

@ -90,3 +90,4 @@ public abstract class BaseFeedback<M extends BaseFeedback<M>> extends Model<M> i
} }
} }

1
src/main/java/com/bt/common/model/base/BaseFeedbackReply.java

@ -58,3 +58,4 @@ public abstract class BaseFeedbackReply<M extends BaseFeedbackReply<M>> extends
} }
} }

1
src/main/java/com/bt/common/model/base/BaseMessage.java

@ -110,3 +110,4 @@ public abstract class BaseMessage<M extends BaseMessage<M>> extends Model<M> imp
} }
} }

1
src/main/java/com/bt/common/model/base/BaseNewsFeed.java

@ -96,3 +96,4 @@ public abstract class BaseNewsFeed<M extends BaseNewsFeed<M>> extends Model<M> i
} }
} }

1
src/main/java/com/bt/common/model/base/BasePermission.java

@ -42,3 +42,4 @@ public abstract class BasePermission<M extends BasePermission<M>> extends Model<
} }
} }

1
src/main/java/com/bt/common/model/base/BaseProject.java

@ -90,3 +90,4 @@ public abstract class BaseProject<M extends BaseProject<M>> extends Model<M> imp
} }
} }

1
src/main/java/com/bt/common/model/base/BaseReferMe.java

@ -68,3 +68,4 @@ public abstract class BaseReferMe<M extends BaseReferMe<M>> extends Model<M> imp
} }
} }

1
src/main/java/com/bt/common/model/base/BaseRemind.java

@ -66,3 +66,4 @@ public abstract class BaseRemind<M extends BaseRemind<M>> extends Model<M> imple
} }
} }

1
src/main/java/com/bt/common/model/base/BaseRole.java

@ -34,3 +34,4 @@ public abstract class BaseRole<M extends BaseRole<M>> extends Model<M> implement
} }
} }

1
src/main/java/com/bt/common/model/base/BaseSession.java

@ -34,3 +34,4 @@ public abstract class BaseSession<M extends BaseSession<M>> extends Model<M> imp
} }
} }

1
src/main/java/com/bt/common/model/base/BaseShare.java

@ -90,3 +90,4 @@ public abstract class BaseShare<M extends BaseShare<M>> extends Model<M> impleme
} }
} }

1
src/main/java/com/bt/common/model/base/BaseShareReply.java

@ -58,3 +58,4 @@ public abstract class BaseShareReply<M extends BaseShareReply<M>> extends Model<
} }
} }

1
src/main/java/com/bt/common/model/base/BaseTaskList.java

@ -62,3 +62,4 @@ public abstract class BaseTaskList<M extends BaseTaskList<M>> extends Model<M> i
} }
} }

225
src/main/java/com/bt/common/realname/RealnameService.java

@ -0,0 +1,225 @@
package com.bt.common.realname;
import java.time.LocalDateTime;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.DatadigitalFincloudGeneralsaasFaceCertifyInitializeModel;
import com.alipay.api.domain.DatadigitalFincloudGeneralsaasFaceCertifyQueryModel;
import com.alipay.api.domain.OpenCertifyIdentifyInfo;
import com.alipay.api.domain.OpenCertifyMerchantConfigs;
import com.alipay.api.request.DatadigitalFincloudGeneralsaasFaceCertifyInitializeRequest;
import com.alipay.api.request.DatadigitalFincloudGeneralsaasFaceCertifyQueryRequest;
import com.alipay.api.request.DatadigitalFincloudGeneralsaasFaceCertifyVerifyRequest;
import com.alipay.api.response.DatadigitalFincloudGeneralsaasFaceCertifyInitializeResponse;
import com.alipay.api.response.DatadigitalFincloudGeneralsaasFaceCertifyQueryResponse;
import com.alipay.api.response.DatadigitalFincloudGeneralsaasFaceCertifyVerifyResponse;
import com.bt.common.model.Account;
import com.bt.common.model.RealnameVerification;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.Ret;
/**
* 实名认证业务
*/
public class RealnameService {
private RealnameVerification dao = new RealnameVerification().dao();
public RealnameVerification getByAccountId(Integer accountId, String columns) {
return dao.findFirst("select " + columns +" from realname_verification where yn=1 and accountId=? limit 1", accountId);
}
public Ret doRealName(RealnameVerification realnameVerification){
realnameVerification.setRealname(realnameVerification.getRealname().trim());
RealnameVerification oldRealName = getByAccountId(realnameVerification.getAccountId(), "id, realname, idCard, status, submitDate, certifyId, certifyUrl,"
+ "certifyUrlExpireAt");
if (oldRealName != null) {
if (oldRealName.getStatus() == RealnameVerification.STATUS_WAIT) {
System.out.println(StrUtil.equals(realnameVerification.getRealname(), oldRealName.getRealname()));
if (StrUtil.equals(realnameVerification.getRealname(), oldRealName.getRealname())&&StrUtil.equals(realnameVerification.getIdCard(),
oldRealName.getIdCard())&&oldRealName.getCertifyUrlExpireAt()>System.currentTimeMillis()){
return Ret.ok("certifyUrl", oldRealName.getCertifyUrl()).set("certifyId", oldRealName.getCertifyId());
} else {
Ret ret = alipayFaceVerify(realnameVerification.getRealname(), realnameVerification.getIdCard());
if (ret.isOk()){
RealnameVerification upRealName = new RealnameVerification();
upRealName.setId(oldRealName.getId());
String certifyId = ret.getStr("certifyId");
String certifyUrl = ret.getStr("certifyUrl");
long et = 3600*1000; // 使用 long et 3600秒(1小时) x 20
long expireAt = System.currentTimeMillis() + (et * 20);
System.out.println(expireAt);
upRealName.setSubmitDate(LocalDateTime.now());
upRealName.setCertifyId(certifyId);
upRealName.setCertifyUrl(certifyUrl);
upRealName.setCertifyUrlExpireAt(expireAt);
upRealName.update();
return Ret.ok("certifyUrl", certifyUrl).set("certifyId", certifyId);
}else {
return Ret.fail("实名认证异常,请重试或联系管理员");
}
}
} else {
return Ret.ok("msg", "已认证过无须再次认证");
}
} else {
//调用支付宝实名获取链接
Ret ret = alipayFaceVerify(realnameVerification.getRealname(), realnameVerification.getIdCard());
System.out.println(ret);
if (ret.isOk()){
String certifyId = ret.getStr("certifyId");
String certifyUrl = ret.getStr("certifyUrl");
long et = 3600*1000; // 使用 long et 3600秒(1小时) x 20
long expireAt = System.currentTimeMillis() + (et * 20);
realnameVerification.setStatus(RealnameVerification.STATUS_WAIT);
realnameVerification.setSubmitDate(LocalDateTime.now());
realnameVerification.setCertifyId(certifyId);
realnameVerification.setCertifyUrl(certifyUrl);
realnameVerification.setCertifyUrlExpireAt(expireAt);
realnameVerification.setCreateTime(LocalDateTime.now());
realnameVerification.save();
return Ret.ok("certifyUrl", certifyUrl).set("certifyId", certifyId);
} else {
return Ret.fail("实名认证异常,请重试或联系管理员");
}
}
}
public Ret queryRealName(Integer accountId){
RealnameVerification realName = getByAccountId(accountId, "id, realname,idCard,status,submitDate, certifyId, certifyUrl");
if (realName==null){
return Ret.fail("实名认证查询异常,请联系管理员");
}
if(StrUtil.isBlank(realName.getCertifyId())){
return Ret.fail("实名认证查询异常,请联系管理员");
}
Ret ret = alipayFaceQuery(realName.getCertifyId());
if (ret.isOk()){
String passed = ret.getStr("passed");
if ("T".equals(passed)){
RealnameVerification upRealName = new RealnameVerification();
upRealName.setId(realName.getId());
upRealName.setStatus(RealnameVerification.STATUS_SUCCESS);
Account account = new Account();
account.setRealnameVerified(Account.REAL_NAME_YES);
account.setId(accountId);
account.update();
upRealName.update();
return Ret.ok();
}else {
return Ret.fail("未完成实名认证或认证不通过,请重新扫码认证");
}
}else {
return Ret.fail("实名认证查询异常,请重试或联系管理员");
}
}
private Ret alipayFaceVerify(String realName, String idCard) {
try{
String randomStr = RandomUtil.randomString(6);
String outerOrderNo = StrFormatter.format("BT{}{}", DateUtil.format(DateUtil.date(), DatePattern.PURE_DATETIME_MS_PATTERN), randomStr);
System.out.println("outerOrderNo"+ outerOrderNo);
DatadigitalFincloudGeneralsaasFaceCertifyInitializeResponse response = getDatadigitalFincloudGeneralsaasFaceCertifyInitializeResponse(
realName, idCard, outerOrderNo);
if (response.isSuccess()) {
String certifyId = response.getCertifyId();
DatadigitalFincloudGeneralsaasFaceCertifyVerifyResponse verifyResponse =
getDatadigitalFincloudGeneralsaasFaceCertifyVerifyResponse(certifyId);
if (verifyResponse.isSuccess()){
return Ret.ok("certifyUrl", verifyResponse.getCertifyUrl()).set("certifyId", certifyId);
}else {
return Ret.fail();
}
} else {
return Ret.fail();
}
}catch (AlipayApiException e){
return Ret.fail();
}
}
private Ret alipayFaceQuery(String certifyId) {
try{
DatadigitalFincloudGeneralsaasFaceCertifyQueryResponse response = getDatadigitalFincloudGeneralsaasFaceCertifyQueryResponse(certifyId);
if (response.isSuccess()) {
String passed = response.getPassed();
return Ret.ok("passed", passed);
} else {
return Ret.fail("实名认证查询异常,请重试或联系管理员");
}
} catch (AlipayApiException e){
return Ret.fail();
}
}
private DatadigitalFincloudGeneralsaasFaceCertifyInitializeResponse getDatadigitalFincloudGeneralsaasFaceCertifyInitializeResponse (String realName,
String idCard, String outerOrderNo) throws AlipayApiException {
AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
// 构造请求参数以调用接口
DatadigitalFincloudGeneralsaasFaceCertifyInitializeRequest request = new DatadigitalFincloudGeneralsaasFaceCertifyInitializeRequest();
DatadigitalFincloudGeneralsaasFaceCertifyInitializeModel model = new DatadigitalFincloudGeneralsaasFaceCertifyInitializeModel();
// 设置H5人脸核身场景码
model.setBizCode("FUTURE_TECH_BIZ_FACE_SDK");
// 设置认证信息
OpenCertifyIdentifyInfo identityParam = new OpenCertifyIdentifyInfo();
identityParam.setCertType("IDENTITY_CARD");
identityParam.setCertName(realName);
identityParam.setCertNo(idCard);
identityParam.setIdentityType("CERT_INFO");
model.setIdentityParam(identityParam);
// 设置商户请求的唯一标识 "BT20240411224901000001231"
model.setOuterOrderNo(outerOrderNo);
// 设置商户配置信息
OpenCertifyMerchantConfigs merchantConfig = new OpenCertifyMerchantConfigs();
merchantConfig.setFaceReserveStrategy("reserve");
merchantConfig.setReturnUrl("");
model.setMerchantConfig(merchantConfig);
request.setBizModel(model);
return alipayClient.execute(request);
}
private DatadigitalFincloudGeneralsaasFaceCertifyVerifyResponse getDatadigitalFincloudGeneralsaasFaceCertifyVerifyResponse(String certifyId)
throws AlipayApiException {
AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
DatadigitalFincloudGeneralsaasFaceCertifyVerifyRequest request = new DatadigitalFincloudGeneralsaasFaceCertifyVerifyRequest();
request.setBizContent("{\"certify_id\":\"" + certifyId + "\"}");
return alipayClient.execute(request);
}
private DatadigitalFincloudGeneralsaasFaceCertifyQueryResponse getDatadigitalFincloudGeneralsaasFaceCertifyQueryResponse(String certifyId)
throws AlipayApiException {
AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
DatadigitalFincloudGeneralsaasFaceCertifyQueryRequest request = new DatadigitalFincloudGeneralsaasFaceCertifyQueryRequest();
DatadigitalFincloudGeneralsaasFaceCertifyQueryModel model = new DatadigitalFincloudGeneralsaasFaceCertifyQueryModel();
// 设置本次申请操作的唯一标识
model.setCertifyId(certifyId);
request.setBizModel(model);
return alipayClient.execute(request);
}
private AlipayConfig getAlipayConfig() {
String appId = PropKit.get("alipayAppId");
String privateKey = PropKit.get("alipayPrivateKey");
String alipayPublicKey = PropKit.get("alipayPublicKey");
AlipayConfig alipayConfig = new AlipayConfig();
alipayConfig.setServerUrl("https://openapi.alipay.com/gateway.do");
alipayConfig.setAppId(appId);
alipayConfig.setPrivateKey(privateKey);
alipayConfig.setFormat("json");
alipayConfig.setAlipayPublicKey(alipayPublicKey);
alipayConfig.setCharset("UTF-8");
alipayConfig.setSignType("RSA2");
return alipayConfig;
}
}

2
src/main/java/com/bt/common/safe/JsoupFilter.java

@ -112,7 +112,7 @@ public class JsoupFilter {
*/ */
public static void filterArticleList(List<? extends Model> modelList, int titleLen, int contentLen) { public static void filterArticleList(List<? extends Model> modelList, int titleLen, int contentLen) {
for (Model m : modelList) { for (Model m : modelList) {
String title = getText(m.getStr("title")); String title = getText(m.getStr("name"));
if (title.length() > titleLen) { if (title.length() > titleLen) {
title = title.substring(0, titleLen - 1); title = title.substring(0, titleLen - 1);
} }

10
src/main/java/com/bt/index/IndexController.java

@ -39,16 +39,6 @@ public class IndexController extends BaseController {
DownloadService downloadSrv; DownloadService downloadSrv;
public void index() { public void index() {
List<Project> projectList = srv.getProjectList();
List<Share> shareList = srv.getShareList();
List<Feedback> feedbackList = srv.getFeedbackList();
List<Download> downloadList = downloadSrv.getDownloadList();
setAttr("projectList", projectList);
setAttr("shareList", shareList);
setAttr("feedbackList", feedbackList);
setAttr("downloadList", downloadList);
render("index.html"); render("index.html");
} }

3
src/main/java/com/bt/login/LoginController.java

@ -67,7 +67,8 @@ public class LoginController extends Controller {
public void logout() { public void logout() {
srv.logout(getCookie(LoginService.sessionIdName)); srv.logout(getCookie(LoginService.sessionIdName));
removeCookie(LoginService.sessionIdName); removeCookie(LoginService.sessionIdName);
redirect("/"); Ret ret = Ret.ok();
renderJson(ret);
} }
/** /**

38
src/main/java/com/bt/my/setting/MySettingController.java

@ -14,17 +14,19 @@
package com.bt.my.setting; package com.bt.my.setting;
import com.bt.my.like.LikeInterceptor;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.upload.UploadFile;
import com.bt.common.controller.BaseController; import com.bt.common.controller.BaseController;
import com.bt.common.interceptor.FrontAuthInterceptor; import com.bt.common.interceptor.FrontAuthInterceptor;
import com.jfinal.kit.Ret;
import com.bt.common.model.Account; import com.bt.common.model.Account;
import com.bt.common.model.RealnameVerification;
import com.bt.common.realname.RealnameService;
import com.bt.login.LoginService; import com.bt.login.LoginService;
import com.bt.my.friend.FriendInterceptor; import com.bt.my.friend.FriendInterceptor;
import com.bt.my.like.LikeInterceptor;
import com.jfinal.aop.Before;
import com.jfinal.aop.Inject;
import com.jfinal.core.Path; import com.jfinal.core.Path;
import com.jfinal.kit.Ret;
import com.jfinal.upload.UploadFile;
/** /**
* 我的设置 * 我的设置
@ -36,10 +38,11 @@ public class MySettingController extends BaseController {
@Inject @Inject
MySettingService srv; MySettingService srv;
@Inject
RealnameService realNameSrv;
public void realName(){
render("realName.html");
}
public void info() { public void info() {
render("info.html"); render("info.html");
@ -106,4 +109,23 @@ public class MySettingController extends BaseController {
public void notice() { public void notice() {
} }
public void realName(){
RealnameVerification realnameVerification = realNameSrv.getByAccountId(getLoginAccountId(), "realname,idCard,status");
setAttr("realName", realnameVerification);
render("realName.html");
}
public void doRealName(){
RealnameVerification realnameVerification = getBean(RealnameVerification.class, "realName");
realnameVerification.setAccountId(getLoginAccountId());
Ret ret = realNameSrv.doRealName(realnameVerification);
renderJson(ret);
}
public void queryRealName(){
Ret ret = realNameSrv.queryRealName(getLoginAccountId());
System.out.println(ret);
renderJson(ret);
}
} }

20
src/main/java/com/bt/product/ProductController.java

@ -15,6 +15,7 @@
package com.bt.product; package com.bt.product;
import com.bt.common.controller.BaseController; import com.bt.common.controller.BaseController;
import com.bt.common.model.Product;
import com.bt.common.model.Project; import com.bt.common.model.Project;
import com.bt.common.pageview.PageViewInterceptor; import com.bt.common.pageview.PageViewInterceptor;
import com.bt.my.favorite.FavoriteService; import com.bt.my.favorite.FavoriteService;
@ -36,7 +37,7 @@ import com.jfinal.kit.Ret;
public class ProductController extends BaseController { public class ProductController extends BaseController {
@Inject @Inject
ProjectService srv; ProductService srv;
@Inject @Inject
FavoriteService favoriteSrv; FavoriteService favoriteSrv;
@ -45,8 +46,7 @@ public class ProductController extends BaseController {
LikeService likeSrv; LikeService likeSrv;
public void index() { public void index() {
setAttr("projectPage", srv.paginate(getParaToInt("p", 1))); setAttr("productPage", srv.paginate(getParaToInt("p", 1)));
setAttr("hotProject", srv.getHotProject());
render("index.html"); render("index.html");
} }
@ -55,13 +55,13 @@ public class ProductController extends BaseController {
*/ */
@Before(PageViewInterceptor.class) @Before(PageViewInterceptor.class)
public void detail() { public void detail() {
Project project = srv.findById(getParaToInt()); Product product = srv.findById(getParaToInt());
if (project != null) { if (product != null) {
setAttr("project", project); setAttr("product", product);
setAttr("hotProject", srv.getHotProject()); setAttr("hotProject", srv.getHotProject());
render("detail.html"); render("detail.html");
setLikeAndFavoriteStatus(project); setLikeAndFavoriteStatus(product);
} else { } else {
renderError(404); renderError(404);
} }
@ -70,10 +70,10 @@ public class ProductController extends BaseController {
/** /**
* 如果用户已登录则需要显示当前 article 是否已经被该用户点赞收藏了 * 如果用户已登录则需要显示当前 article 是否已经被该用户点赞收藏了
*/ */
private void setLikeAndFavoriteStatus(Project project) { private void setLikeAndFavoriteStatus(Product product) {
Ret ret = Ret.create(); Ret ret = Ret.create();
likeSrv.setLikeStatus(getLoginAccount(), "project", project, ret); likeSrv.setLikeStatus(getLoginAccount(), "product", product, ret);
favoriteSrv.setFavoriteStatus(getLoginAccount(), "project", project, ret); favoriteSrv.setFavoriteStatus(getLoginAccount(), "product", product, ret);
setAttr("ret", ret); setAttr("ret", ret);
} }
} }

51
src/main/java/com/bt/product/ProductService.java

@ -0,0 +1,51 @@
package com.bt.product;
import java.util.List;
import com.bt.common.model.Product;
import com.bt.common.model.Project;
import com.bt.common.safe.JsoupFilter;
import com.jfinal.kit.Kv;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.ehcache.CacheKit;
/**
* ProductService
*/
public class ProductService {
private Product dao = new Product().dao();
public Page<Product> paginate(int pageNumber) {
Page<Product> productPage = dao.template("product.paginate").paginate(pageNumber, 16);
// 列表页显示 content 的摘要信息需要过滤为纯文本,去除所有标记
//JsoupFilter.filterArticleList(productPage.getList(), 50, 120);
return productPage;
}
public Product findById(int projectId) {
return dao.template("project.findById", projectId, Project.REPORT_BLOCK_NUM).findFirst();
}
public Product findById(int projectId, String columns) {
Kv para = Kv.by("columns", columns).set("id", projectId).set("report", Project.REPORT_BLOCK_NUM);
return dao.template("project.findByIdWithColumns", para).findFirst();
}
public List<Product> getHotProject() {
return dao.template("project.getHotProject", Project.REPORT_BLOCK_NUM).findByCache("hotProject", "hotProject");
}
public void clearHotProjectCache() {
CacheKit.remove("hotProject", "hotProject");
}
/**
* 暂时用于个人空间的创建更新 sharefeedback 模块用于显示关联项目的下拉列表将来改成按热度排序
* 项目数量多了以后考虑用输入框配合 autocomplete 提示输入来实现
*/
public List<Product> getAllProject(String columns) {
Kv para = Kv.by("columns", columns).set("report", Project.REPORT_BLOCK_NUM);
return dao.template("project.getAllProject", para).find();
}
}

30
src/main/java/com/bt/product/product.sql

@ -0,0 +1,30 @@
#sql("paginate")
select p.id,
substring(p.name, 1, 100) as name,
p.cpuName, p.memoryCapacity, p.graphicsCardModel, p.dataDiskCapacity, p.downloadSpeed,
substring(p.content, 1, 180) as content, p.createAt as createAt
from product p
#end
#sql("findById")
select p.* , a.avatar, a.nickName
from product p inner join account a on p.accountId = a.id
where p.id = #para(0) and p.report < #para(1) limit 1
#end
#sql("findByIdWithColumns")
select #(columns) from product where id = #para(id) and report < #para(report) limit 1
#end
#sql("getHotproduct")
select id, title from product where report < #para(0) order by createAt asc limit 10
#end
#sql("getAllproduct")
select #(columns) from product where report < #para(report) order by createAt asc
#end

7
src/main/java/com/bt/reg/RegService.java

@ -103,6 +103,7 @@ public class RegService {
account.setStatus(Account.STATUS_REG); account.setStatus(Account.STATUS_REG);
account.setCreateAt(LocalDateTime.now()); account.setCreateAt(LocalDateTime.now());
account.setIp(ip); account.setIp(ip);
account.setRealnameVerified(Account.REAL_NAME_NO);
account.setAvatar(Account.AVATAR_NO_AVATAR); // 注册时设置默认头像 account.setAvatar(Account.AVATAR_NO_AVATAR); // 注册时设置默认头像
if (account.save()) { if (account.save()) {
@ -121,9 +122,9 @@ public class RegService {
* 发送账号激活授权邮件 * 发送账号激活授权邮件
*/ */
private boolean sendRegActivateAuthEmail(String authCode, Account reg) { private boolean sendRegActivateAuthEmail(String authCode, Account reg) {
String title = "JFinal 会员激活邮件"; String title = "贝塔网络账号激活邮件";
String content = "在浏览器地址栏里输入并访问下面激活链接即可完成账户激活:\n\n" String content = "在浏览器地址栏里输入并访问下面激活链接即可完成账户激活:\n\n"
+ " https://jfinal.com/reg/activate?authCode=" + " https://bt.plus/reg/activate?authCode="
+ authCode; + authCode;
String emailServer = PropKit.get("emailServer"); String emailServer = PropKit.get("emailServer");
@ -131,7 +132,7 @@ public class RegService {
String emailPass = PropKit.get("emailPass"); String emailPass = PropKit.get("emailPass");
String toEmail = reg.getStr("userName"); String toEmail = reg.getStr("userName");
try { try {
EmailKit.sendEmail(emailServer, fromEmail, emailPass, toEmail, title, content); //EmailKit.sendEmail(emailServer, fromEmail, emailPass, toEmail, title, content);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
return false; return false;

8
src/main/resources/jfinal-club-config-dev.txt

@ -1,5 +1,6 @@
#主要配置 #主要配置
jdbcUrl=jdbc:mysql://localhost/bt_plus?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull jdbcUrl=jdbc:mysql://localhost/bt_plus?characterEncoding=utf8&useSSL=false&zeroDateTimeBehavior=convertToNull&allowPublicKeyRetrieval=true
user=root user=root
password=123456 password=123456
devMode=true devMode=true
@ -22,5 +23,10 @@ pvUpdate.cron=0 * * * *
pvUpdate.class=com.bt.common.pageview.PageViewUpdateTask pvUpdate.class=com.bt.common.pageview.PageViewUpdateTask
pvUpdate.enable=true pvUpdate.enable=true
# 支付宝
alipayAppId=2021004142623011
alipayPrivateKey=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCFD94dfCfNEzRrkSEgHzO3/nqY0bpIHbGFzVj0kED+nLJtIAO2UosKKETblVlkj111O+8YHSbH3Dz5IOembiSvTWF9mkYwAuC6Zhw7p/6wniKIDPFaLukE3dIuH8eLHC2dFtX2qMgnI2d0qUyjz3kP/Uror0qlOVkBFdPRVem7EPC//ZNs7ITfJG6703tbIc9paRQ+mnyEZj1MZRK0ARNIgQflPOedQgQJTCzShCOnuMPaflyNnYSD4zcEmByuhOFw3hBrcDPq+Jh5kixzEdriJnfbdqRaivlI/xtK819kxRD169DUCmP7nqDqyqf0BaK+rBq8q6L0PeeK2v9eACcdAgMBAAECggEAWrN7Q3v7IXZC2EQAYYYDWhtUdFEZ+siK1tsoFOUz+JrVoT8eaKyRbGYQseF3Iu361cv56eUNJ1VAFs3QOgmAZiKIHvcHevirOUQbYKreGIRio3y3FDM/0XpnJ9uvyGp3yUnkpZNdhBhFECfLPypQqo6M/llmt4OE4RGA5oP6o/EfxqXWoIgHI3s/81UaZvekEIvenXiCjpzGB+W2sDDUQtpldMGle9N95Y+YvvDUIO0j6CvL1ATaSCvLRfswlCZdFr+pj2vie7Bzzx4eKgUzyfI/BELDGzz5hFah7qkqKMqwr41N99eJy1VwYWo2V+AKEZ+3nKoZOLkOGvwr34ySPQKBgQDsug4KV4ySp3cF6WOLQAeJRaL2lT5iMvIu1fnG67xNNFPsLBaZE3SWZpciL0uJiInfeAFVS2wW5FcqE1n+ZdgYX20k/GThP/fSiVgDQ9G13RPAecXA9+8LwXUVHGz9EVBs5FRd5DDZOKShUJ09fuzM8rfQ/iOo6sbB98PPUyX8fwKBgQCP5TGSkjXtEwRW0a+uHNgu/7Bp1ecInDHcBMLgyzj+ssJXTAXF79oVNpMx/eXRgkBEnxifrK9zy30ETseJ+FbGRtbwQ52fuR+YSSR8hGSHYi69JMPmZ7napUM3VigfpVKmf0BHZT+NpRLEdsm5Ixi+aBbqkz0YtTJFw0KEW3d+YwKBgFYxMCeH1QEYxHd8kOgEujm7ByjtEjfDAPcYpcdN0dPyd5QIQXoe4VZZqDGkMsay1jBti165BXQYU7xYK247OsE1DZJn63swRVV8+HTH3rVu92AfdmdaXslS+QRkwzIpebUMNcOx8C9HNnod1gKsEiBVR6RqxCUexpudUMhOKAiVAoGAHs4EFMq0PLKLhUKSh4WpSjZ2v9GJCjDWA7IJPjKDWxNNw36E5eD5IP1z+YnPP1DRDV+518USMonnk5qB4SmG+h+EOB9hiSYKe4F9DCMTmmAMfXV3csXV5dbnUttg75Vm4jnvutkUB/DE2cZMXRQEYg7KiSFIPRfdUU4B2W/zXt0CgYEArUNBURVNwvETHlbazMLJS8HkW3kDnzSm9a7gF1qqBKO0LV7KK6dY7BgWJv1MDfFijhW4Qum3jtgnojI37lF2j6a4pYGOPk/sLEmhch9EmUgY3iTbNPpt1/uwObKlNBQtdyFIehNCCZgDyWbhbu0AXfA/ZtmBiDi0CE8tLzstIQQ=
alipayPublicKey=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqE34W1o4gIUgF26apGHT+xZHcdqQhRYFSsSGle8s6BCz7pEwHtG3bm6OHBr8VF4qbXWD7XXxi+g4hbeOwGreFU7mQd2iwyEmqsuiG4m4tzttjhMHN2yiDsTPr5dZWPCyl14RtKfDUaI/cvq565wNyaBPWASOu6Ecl4zF8qa2axLrL6pMPDNxqLpQ7NJMveeiQK//XK1KZJkm+n2yTqWzMRo9HevD1IpfH5r5LSh5s7mkJeYZRMaZ0ZjEScOk1ylkMgyOgD1OJoSqq2cJTNnv2yoJGd4mSPe2LJBu9ZJPM9CXVsiwWaTZGY0HcHKYf6F613G07QoZdUA+QjETEnOXmQIDAQAB
alipayReturnUrl=https://l9r51q8n-8087.asse.devtunnels.ms/

3
src/main/webapp/_view/_admin/common/_menu.html

@ -15,6 +15,9 @@
#permission("/admin/project") #permission("/admin/project")
<li><a href="/admin/project">项目管理</a></li> <li><a href="/admin/project">项目管理</a></li>
#end #end
#permission("/admin/product")
<li><a href="/admin/product">产品管理</a></li>
#end
<li><a href="/admin/share">分享管理</a></li> <li><a href="/admin/share">分享管理</a></li>
<li><a href="/admin/feedback">反馈管理</a></li> <li><a href="/admin/feedback">反馈管理</a></li>

183
src/main/webapp/_view/_admin/product/add_edit.html

@ -0,0 +1,183 @@
#@adminLayout()
#define main()
### isAdd 表示创建,isEdit 表示修改
#set(isAdd = product == null ? true : false, isEdit = !isAdd)
<div class="jfa-header-box" id="jfa-header-box">
<div class="jfa-crumbs" id="jfa-crumbs">
产品管理 / #(isAdd ? "创建" : "修改")
</div>
<div class="jfa-search-box"></div>
#include("/_view/_admin/common/_header_right.html")
</div>
### 内容区域
<div class="jfa-content-box" id="jfa-content-box">
<div class="jfa-content" id="jfa-content">
<form class="clearfix margin-top-25" id="myArticleForm" action="/admin/product/#(isAdd ? 'save' : 'update')" method="post">
#if (isEdit)
<input type="hidden" name="product.id" value="#(product.id)" />
#end
<div class="form-group margin-bottom-20">
<label>产品名称</label>
<input type="text" class="form-control" name="product.name" value="#(product.name??)" placeholder="产品唯一标识" />
</div>
<div class="form-group margin-bottom-20">
<label>CPU数</label>
<input type="text" class="form-control" name="product.cpuCount" value="#(product.cpuCount??)" placeholder="CPU数" />
</div>
<div class="form-group margin-bottom-20">
<label>CPU名称</label>
<input type="text" class="form-control" name="product.cpuName" value="#(product.cpuName??)" placeholder="CPU名称" />
</div>
<div class="form-group margin-bottom-20">
<label>CPU主频</label>
<input type="text" class="form-control" name="product.cpuFrequency" value="#(product.cpuFrequency??)" placeholder="CPU主频" />
</div>
<div class="form-group margin-bottom-20">
<label>单U核心数</label>
<input type="text" class="form-control" name="product.singleCoreCount" value="#(product.singleCoreCount??)" placeholder="单U核心数" />
</div>
<div class="form-group margin-bottom-20">
<label>双U核心数</label>
<input type="text" class="form-control" name="product.dualCoreCount" value="#(product.dualCoreCount??)" placeholder="双U核心数" />
</div>
<div class="form-group margin-bottom-20">
<label>单U核心数</label>
<input type="text" class="form-control" name="product.singleCoreCount" value="#(product.singleCoreCount??)" placeholder="单U核心数" />
</div>
<div class="form-group margin-bottom-20">
<label>总线程数</label>
<input type="text" class="form-control" name="product.totalThreadCount" value="#(product.totalThreadCount??)" placeholder="总线程数" />
</div>
<div class="form-group margin-bottom-20">
<label>内存容量</label>
<input type="text" class="form-control" name="product.memoryCapacity" value="#(product.memoryCapacity??)" placeholder="内存容量" />
</div>
<div class="form-group margin-bottom-20">
<label>内存速度</label>
<input type="text" class="form-control" name="product.memorySpeed" value="#(product.memorySpeed??)" placeholder="内存速度" />
</div>
<div class="form-group margin-bottom-20">
<label>物理盘</label>
<input type="text" class="form-control" name="product.physicalDisk" value="#(product.physicalDisk??)" placeholder="物理盘" />
</div>
<div class="form-group margin-bottom-20">
<label>系统盘颗粒</label>
<input type="text" class="form-control" name="product.systemDiskParticle" value="#(product.systemDiskParticle??)" placeholder="系统盘颗粒" />
</div>
<div class="form-group margin-bottom-20">
<label>数据盘容量</label>
<input type="text" class="form-control" name="product.dataDiskCapacity" value="#(product.dataDiskCapacity??)" placeholder="数据盘容量" />
</div>
<div class="form-group margin-bottom-20">
<label>数据盘读取速度</label>
<input type="text" class="form-control" name="product.dataDiskReadSpeed" value="#(product.dataDiskReadSpeed??)" placeholder="数据盘读取速度" />
</div>
<div class="form-group margin-bottom-20">
<label>数据盘写入速度</label>
<input type="text" class="form-control" name="product.dataDiskWriteSpeed" value="#(product.dataDiskWriteSpeed??)" placeholder="数据盘写入速度" />
</div>
<div class="form-group margin-bottom-20">
<label>显卡型号</label>
<input type="text" class="form-control" name="product.graphicsCardModel" value="#(product.graphicsCardModel??)" placeholder="显卡型号" />
</div>
<div class="form-group margin-bottom-20">
<label>显存容量</label>
<input type="text" class="form-control" name="product.graphicsMemoryCapacity" value="#(product.graphicsMemoryCapacity??)" placeholder="显存容量" />
</div>
<div class="form-group margin-bottom-20">
<label>下载速度</label>
<input type="text" class="form-control" name="product.downloadSpeed" value="#(product.downloadSpeed??)" placeholder="下载速度" />
</div>
<div class="form-group margin-bottom-20">
<label>上传速度</label>
<input type="text" class="form-control" name="product.uploadSpeed" value="#(product.uploadSpeed??)" placeholder="上传速度" />
</div>
<div class="form-group margin-bottom-20">
<label>内网带宽</label>
<input type="text" class="form-control" name="product.internalNetworkBandwidth" value="#(product.internalNetworkBandwidth??)" placeholder="内网带宽" />
</div>
<div class="form-group margin-bottom-20">
<label>日租费用</label>
<input type="text" class="form-control" name="product.dailyRentalFee" value="#(product.dailyRentalFee??)" placeholder="日租费用" />
</div>
<div class="form-group margin-bottom-20">
<label>月租费用</label>
<input type="text" class="form-control" name="product.monthlyRentalFee" value="#(product.monthlyRentalFee??)" placeholder="月租费用" />
</div>
<div class="form-group margin-bottom-20">
<label>单价/核心</label>
<input type="text" class="form-control" name="product.pricePerCore" value="#(product.pricePerCore??)" placeholder="单价/核心" />
</div>
<div class="form-group margin-bottom-20">
<label>单UTDP</label>
<input type="text" class="form-control" name="product.singleUtdp" value="#(product.singleUtdp??)" placeholder="单UTDP" />
</div>
<div class="form-group margin-bottom-20">
<label>总TDP</label>
<input type="text" class="form-control" name="product.totalTdp" value="#(product.totalTdp??)" placeholder="总TDP" />
</div>
<div class="form-group margin-bottom-20">
<label>附加内容</label>
<div>
<script id="container" name="product.content" style="line-height: 20px;" type="text/plain">#(project.content??)</script>
</div>
</div>
<div class="pull-right margin-bottom-20" >
<input class="btn btn-primary" type="submit" value="提交" />
</div>
</form>
</div><!-- END OF jfa-content -->
</div><!-- END OF jfa-content-box -->
<style type="text/css">
.jfa-content label {
line-height: 1;
vertical-align: baseline;
color: #23527c;
font-size: 20px;
font-weight: normal;
margin-bottom: 8px;;
}
</style>
<script type="text/javascript">
$(document).ready(function() {
initUeditor();
// 上传时在 url 中用问号挂参的方式添加额外的参数 uploadType,用于分类管理图片
env.ueditor.ready(function() {
env.ueditor.execCommand('serverparam', {
'uploadType': 'product'
});
});
$("#myArticleForm").ajaxForm({
dataType: "json"
, beforeSubmit: function(formData, jqForm, options) {
env.ueditor.sync(); // 同步一下 ueditor 中的数据到表单域
}
, success: function(ret) {
if (ret.state == "ok") {
location.href = "/admin/product?p=#(p ?? 1)";
} else {
showFailMsg(ret.msg);
}
}
, error: function(ret) {alert(ret.statusText);}
, complete: function(ret) {} // 无论是 success 还是 error,最终都会被回调
});
});
</script>
#end

136
src/main/webapp/_view/_admin/product/index.html

@ -0,0 +1,136 @@
#@adminLayout()
#define main()
<div class="jfa-header-box" id="jfa-header-box">
<div class="jfa-crumbs" id="jfa-crumbs">
产品管理
</div>
<div class="jfa-search-box">
<form action="/admin/project/search">
### <input class="jfa-search" type="text" name="keyword" placeholder="搜索" >
</form>
</div>
#include("/_view/_admin/common/_header_right.html")
</div>
### 内容区域
<div class="jfa-content-box" id="jfa-content-box">
<div class="jfa-content" id="jfa-content">
<div class="jfa-toolbar">
<a class="btn btn-primary btn-sm" href="/admin/product/add">
<i class="fa fa-plus"></i>
创建产品
</a>
</div>
<div class="jfa-table-box margin-top-30">
<table class="table table-bordered table-hover margin-bottom-10">
<thead>
<tr>
<th>id</th>
<th>名称</th>
<th>CPU数</th>
<th>CPU名称</th>
<th>单U核心数</th>
<th>双U核心数</th>
<th>总线程数</th>
<th>内存容量</th>
<th>内存速度</th>
<th>物理盘</th>
<th>系统盘颗粒</th>
<th>数据盘容量</th>
<th>数据盘读取速度</th>
<th>数据盘写入速度</th>
<th>显卡型号</th>
<th>显存容量</th>
<th>下载速度</th>
<th>上传速度</th>
<th>上传速度</th>
<th>内网带宽</th>
<th>日租费用</th>
<th>月租费用</th>
<th>单价/核心</th>
<th>单UTDP</th>
<th>总TDP</th>
<th>创建时间</th>
<th>操作</th>
</tr>
</thead>
<tbody>
#for(x : productPage.getList())
<tr>
<th scope="row">#(x.id)</th>
<td>#(x.name)</td>
<td>#(x.cpuCount)</td>
<td>#(x.cpuName)</td>
<td>#(x.cpuFrequency)</td>
<td>#(x.singleCoreCount)</td>
<td>#(x.dualCoreCount)</td>
<td>#(x.totalThreadCount)</td>
<td>#(x.memoryCapacity)</td>
<td>#(x.memorySpeed)</td>
<td>#(x.physicalDisk)</td>
<td>#(x.systemDiskParticle)</td>
<td>#(x.dataDiskCapacity)</td>
<td>#(x.dataDiskReadSpeed)</td>
<td>#(x.dataDiskWriteSpeed)</td>
<td>#(x.graphicsCardModel)</td>
<td>#(x.graphicsMemoryCapacity)</td>
<td>#(x.downloadSpeed)</td>
<td>#(x.uploadSpeed)</td>
<td>#(x.internalNetworkBandwidth)</td>
<td>#(x.dailyRentalFee)</td>
<td>#(x.monthlyRentalFee)</td>
<td>#(x.pricePerCore)</td>
<td>#(x.singleUtdp)</td>
<td>#(x.totalTdp)</td>
<td>#date(x.createAt)</td>
<td class="jfa-operation-button">
#permission("/admin/product/edit")
<a href="/admin/product/edit?id=#(x.id)&p=#(productPage.pageNumber)">
<i class="fa fa-pencil" title="修改"></i>
</a>
#end
#permission("/admin/product/delete")
<a data-delete
data-title="#escape(x.title)"
data-action="/admin/product/delete?id=#(x.id)">
<i class="fa fa-trash" title="删除"></i>
</a>
#end
</td>
</tr>
#end
</tbody>
</table>
<div>
#@adminPaginate(productPage.pageNumber, productPage.totalPage, "/admin/product?p=")
</div>
</div>
</div><!-- END OF jfa-content -->
</div><!-- END OF jfa-content-box -->
<style type="text/css">
</style>
<script type="text/javascript">
$(document).ready(function() {
initMagicInput(prepareAction);
});
function prepareAction($this, state) {
return {
url: state ? "/admin/project/lock" : "/admin/project/unlock",
data : {
id: $this.attr("data-id")
}
}
}
</script>
#end

73
src/main/webapp/_view/common/__b5layout.html

@ -8,23 +8,72 @@
<meta name="description" content="#(seoDescr ?? '贝塔网络官方网站')"> <meta name="description" content="#(seoDescr ?? '贝塔网络官方网站')">
<title>#(seoTitle ?? "贝塔网络官方网站")</title> <title>#(seoTitle ?? "贝塔网络官方网站")</title>
<link rel="shortcut icon" type="image/x-icon" href="/assets/img/favicon.ico"> <link rel="shortcut icon" type="image/x-icon" href="/assets/img/favicon.ico">
<link rel="stylesheet" href="/assets/lib/bootstrap-icons/font/bootstrap-icons.min.css"> <link rel="stylesheet" crossorigin href="/assets/b5/compiled/css/app.css">
<link rel="stylesheet" href="/assets/lib/bootstrap/dist/css/bootstrap.min.css"> <link rel="stylesheet" crossorigin href="/assets/b5/compiled/css/app-dark.css">
<link rel="stylesheet" href="/assets/b5/css/bootstrap-admin.min.css"> <link rel="stylesheet" crossorigin href="/assets/b5/compiled/css/iconly.css">
#@css?() #@css?()
</head> </head>
<body class="bg-body-tertiary py-3"> <body>
<!--主体内容--> <script src="/assets/b5/static/js/initTheme.js"></script>
#@main() <div id="app">
<div id="sidebar">
<div class="sidebar-wrapper active">
<div class="sidebar-header position-relative">
<div class="d-flex justify-content-between align-items-center">
<div class="logo">
<a href="/">
<img src="/assets/official/images/logo/logo.png" alt="Logo" srcset="">
</a>
</div>
<div class="theme-toggle d-flex gap-2 align-items-center mt-2">
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true"
role="img" class="iconify iconify--system-uicons" width="20" height="20"
preserveAspectRatio="xMidYMid meet" viewBox="0 0 21 21">
<g fill="none" fill-rule="evenodd" stroke="currentColor" stroke-linecap="round"
stroke-linejoin="round">
<path
d="M10.5 14.5c2.219 0 4-1.763 4-3.982a4.003 4.003 0 0 0-4-4.018c-2.219 0-4 1.781-4 4c0 2.219 1.781 4 4 4zM4.136 4.136L5.55 5.55m9.9 9.9l1.414 1.414M1.5 10.5h2m14 0h2M4.135 16.863L5.55 15.45m9.899-9.9l1.414-1.415M10.5 19.5v-2m0-14v-2"
opacity=".3"></path>
<g transform="translate(-210 -1)">
<path d="M220.5 2.5v2m6.5.5l-1.5 1.5"></path>
<circle cx="220.5" cy="11.5" r="4"></circle>
<path d="m214 5l1.5 1.5m5 14v-2m6.5-.5l-1.5-1.5M214 18l1.5-1.5m-4-5h2m14 0h2"></path>
</g>
</g>
</svg>
<div class="form-check form-switch fs-6">
<input class="form-check-input me-0" type="checkbox" id="toggle-dark" style="cursor: pointer">
<label class="form-check-label"></label>
</div>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true"
role="img" class="iconify iconify--mdi" width="20" height="20" preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24">
<path fill="currentColor"
d="m17.75 4.09l-2.53 1.94l.91 3.06l-2.63-1.81l-2.63 1.81l.91-3.06l-2.53-1.94L12.44 4l1.06-3l1.06 3l3.19.09m3.5 6.91l-1.64 1.25l.59 1.98l-1.7-1.17l-1.7 1.17l.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95l2.06.05m-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85c-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14c.4-.4.82-.76 1.27-1.08c.75-.53 1.93.36 1.85 1.19c-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82c-2.81 3.14-2.7 7.96.31 10.98c3.02 3.01 7.84 3.12 10.98.31Z">
</path>
</svg>
</div>
<div class="sidebar-toggler x">
<a href="#" class="sidebar-hide d-xl-none d-block"><i class="bi bi-x bi-middle"></i></a>
</div>
</div>
</div>
#@menu()
</div>
</div>
<!--主体内容-->
#@main()
</div>
<!--回到顶部开始-->
<a href="javaScript:" class="bsa-back-to-top"><i class='bi bi-arrow-up-short'></i></a>
<!--回到顶部结束-->
<script src="/assets/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/assets/b5/static/js/components/dark.js"></script>
<script src="/assets/b5/extensions/perfect-scrollbar/perfect-scrollbar.min.js"></script>
<script src="/assets/b5/compiled/js/app.js"></script>
<script src="/assets/lib/jquery/dist/jquery.min.js"></script> <script src="/assets/lib/jquery/dist/jquery.min.js"></script>
<script src="/assets/b5/js/bootstrap-admin.min.js"></script>
<script src="/assets/b5/js/app.js"></script>
#@js?() #@js?()
</body> </body>
</html> </html>

244
src/main/webapp/_view/common/__official_layout.html

@ -0,0 +1,244 @@
#define officialLayout()
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<meta name="referrer" content="always">
<meta name="keywords" content="#(seoKeywords ?? '贝塔网络')">
<meta name="description" content="#(seoDescr ?? '贝塔网络官方网站')">
<title>#(seoTitle ?? "贝塔网络官方网站")</title>
<link rel="shortcut icon" type="image/x-icon" href="/assets/img/favicon.ico">
<!-- ========================= CSS here ========================= -->
<link rel="stylesheet" href="/assets/official/css/bootstrap.min.css" />
<link rel="stylesheet" href="/assets/official/css/LineIcons.2.0.css" />
<link rel="stylesheet" href="/assets/official/css/animate.css" />
<link rel="stylesheet" href="/assets/official/css/tiny-slider.css" />
<link rel="stylesheet" href="/assets/official/css/glightbox.min.css" />
<link rel="stylesheet" href="/assets/official/css/main.css" />
#@css?()
</head>
<!--如果不需要悬浮的header 就去掉body上的class-->
<body>
<!-- Preloader -->
<div class="preloader">
<div class="preloader-inner">
<div class="preloader-icon">
<span></span>
<span></span>
</div>
</div>
</div>
<!-- /End Preloader -->
<!-- Start header部分 -->
<header class="header navbar-area">
<div class="container">
<div class="row align-items-center">
<div class="col-lg-12">
<div class="nav-inner">
<!-- Start Navbar -->
<nav class="navbar navbar-expand-lg">
<a class="navbar-brand" href="#(SSL)/">
<img src="/assets/official/images/logo/white-logo.png" alt="Logo">
</a>
<button class="navbar-toggler mobile-menu-btn" type="button" data-bs-toggle="collapse"
data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="toggler-icon"></span>
<span class="toggler-icon"></span>
<span class="toggler-icon"></span>
</button>
<div class="collapse navbar-collapse sub-menu-bar" id="navbarSupportedContent">
<ul id="nav" class="navbar-nav ms-auto">
<li class="nav-item">
<a href="#(SSL)/" class="active">首页</a>
</li>
<li class="nav-item">
<a href="#(SSL)/product" >产品</a>
</li>
<li class="nav-item">
<a href="#overview" class="page-scroll"
aria-label="Toggle navigation">Overview</a>
</li>
<li class="nav-item">
<a href="#pricing" class="page-scroll"
aria-label="Toggle navigation">Pricing</a>
</li>
<li class="nav-item">
<a href="#team" class="page-scroll" aria-label="Toggle navigation">Team</a>
</li>
<li class="nav-item">
<a class="page-scroll dd-menu collapsed" href="#blog" data-bs-toggle="collapse"
data-bs-target="#submenu-1-4" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">Blog</a>
<ul class="sub-menu collapse" id="submenu-1-4">
<li class="nav-item"><a href="blog-grid-sidebar.html">Blog Grid Sidebar</a></li>
<li class="nav-item"><a href="blog-single.html">Blog Single</a></li>
<li class="nav-item"><a href="blog-single-sidebar.html">Blog Single
Sibebar</a></li>
</ul>
</li>
<li class="nav-item">
<a href="contact.html" aria-label="Toggle navigation">Contact</a>
</li>
</ul>
</div> <!-- navbar collapse -->
#if(loginAccount)
<!--登录后用下面这个-->
<div class="button add-list-button">
<a href="#(SSL)/my" class="btn">控制台</a>
</div>
#else
<!--没登录用这个-->
<div class="button add-list-button">
<a href="#(SSL)/reg" class="btn">注册</a>
<a href="#(SSL)/login" class="btn">登录</a>
</div>
#end
</nav>
<!-- End Navbar -->
</div>
</div>
</div> <!-- row -->
</div> <!-- container -->
</header>
<!-- End header部分 -->
<!--主体内容-->
#@main()
<!-- Start Footer Area -->
<footer class="footer">
<!-- Start Footer Top -->
<div class="footer-top">
<div class="container">
<div class="row">
<div class="col-lg-4 col-md-4 col-12">
<!-- Single Widget -->
<div class="single-footer f-about">
<div class="logo">
<a href="#(SSL)/">
<img src="/assets/official/images/logo/white-logo.png" alt="#">
</a>
</div>
<p>Making the world a better place through constructing elegant hierarchies.</p>
<ul class="social">
<li><a href="javascript:void(0)"><i class="lni lni-facebook-filled"></i></a></li>
<li><a href="javascript:void(0)"><i class="lni lni-twitter-original"></i></a></li>
<li><a href="javascript:void(0)"><i class="lni lni-instagram"></i></a></li>
<li><a href="javascript:void(0)"><i class="lni lni-linkedin-original"></i></a></li>
<li><a href="javascript:void(0)"><i class="lni lni-youtube"></i></a></li>
<li><a href="javascript:void(0)"><i class="lni lni-pinterest"></i></a></li>
</ul>
<p class="copyright-text"><a target="_blank" href="http://www.mobanwang.com/" title="网页模板">网页模板</a>
</p>
</div>
<!-- End Single Widget -->
</div>
<div class="col-lg-8 col-md-8 col-12">
<div class="row">
<div class="col-lg-3 col-md-6 col-12">
<!-- Single Widget -->
<div class="single-footer f-link">
<h3>Solutions</h3>
<ul>
<li><a href="javascript:void(0)">Marketing</a></li>
<li><a href="javascript:void(0)">Analytics</a></li>
<li><a href="javascript:void(0)">Commerce</a></li>
<li><a href="javascript:void(0)">Insights</a></li>
<li><a href="javascript:void(0)">Promotion</a></li>
</ul>
</div>
<!-- End Single Widget -->
</div>
<div class="col-lg-3 col-md-6 col-12">
<!-- Single Widget -->
<div class="single-footer f-link">
<h3>Support</h3>
<ul>
<li><a href="javascript:void(0)">Pricing</a></li>
<li><a href="javascript:void(0)">Documentation</a></li>
<li><a href="javascript:void(0)">Guides</a></li>
<li><a href="javascript:void(0)">API Status</a></li>
<li><a href="javascript:void(0)">Live Support</a></li>
</ul>
</div>
<!-- End Single Widget -->
</div>
<div class="col-lg-3 col-md-6 col-12">
<!-- Single Widget -->
<div class="single-footer f-link">
<h3>Company</h3>
<ul>
<li><a href="javascript:void(0)">About Us</a></li>
<li><a href="javascript:void(0)">Our Blog</a></li>
<li><a href="javascript:void(0)">Jobs</a></li>
<li><a href="javascript:void(0)">Press</a></li>
<li><a href="javascript:void(0)">Contact Us</a></li>
</ul>
</div>
<!-- End Single Widget -->
</div>
<div class="col-lg-3 col-md-6 col-12">
<!-- Single Widget -->
<div class="single-footer f-link">
<h3>Legal</h3>
<ul>
<li><a href="javascript:void(0)">Terms & Conditions</a></li>
<li><a href="javascript:void(0)">Privacy Policy</a></li>
<li><a href="javascript:void(0)">Catering Services</a></li>
<li><a href="javascript:void(0)">Customer Relations</a></li>
<li><a href="javascript:void(0)">Innovation</a></li>
</ul>
</div>
<!-- End Single Widget -->
</div>
</div>
</div>
</div>
</div>
</div>
<!--/ End Footer Top -->
<!-- Start Footer Newsletter -->
<div class="footer-newsletter">
<div class="container">
<div class="inner-content">
<div class="row align-items-center">
<div class="col-lg-6 col-md-5 col-12">
<div class="title">
<h3>Subscribe to our newsletter</h3>
<p>The latest news, articles, and resources, sent to your inbox weekly.</p>
</div>
</div>
<div class="col-lg-6 col-md-7 col-12">
<div class="form">
<form action="#" method="get" target="_blank" class="newsletter-form">
<input name="EMAIL" placeholder="Your email address" type="email">
<div class="button">
<button class="btn">Subscribe<span class="dir-part"></span></button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- End Footer Newsletter -->
</footer>
<!--/ End Footer Area -->
<!-- ========================= 回到顶部 ========================= -->
<a href="#" class="scroll-top">
<i class="lni lni-chevron-up"></i>
</a>
#@js?()
</body>
</html>
#end

209
src/main/webapp/_view/index/index.html

@ -1,120 +1,113 @@
#set(seoTitle="JFinal 极速开发官方社区") #set(seoTitle="贝塔网络官方网站")
#@layout() #@officialLayout()
#define main() #define main()
<div class="col jf-page-main jf-pdl0"> <!-- Start Hero Area -->
<section id="home" class="hero-area">
### 首页轮播广告 <div class="container">
#include("_carousel.html") <div class="row align-items-center">
### 分享 <div class="col-lg-5 col-md-12 col-12">
<div class="jf-panel jf-article-list"> <div class="hero-content">
<div class="jf-panel-header"> <h1 class="wow fadeInLeft" data-wow-delay=".4s">Powerful solutions for your startup.</h1>
<a class="jf-more" href="/share">更多»</a> <p class="wow fadeInLeft" data-wow-delay=".6s">We are a digital agency that helps brands to
<h1>分享</h1> achieve their business outcomes. We see technology as a tool to create amazing things.</p>
</div> <div class="button wow fadeInLeft" data-wow-delay=".8s">
<div class="jf-panel-body"> <a href="contact.html" class="btn">Get Started</a>
<div class="jf-common-list">
#for(x : shareList)
<div class="jf-common-item">
<div class="row">
<a href="/user/#(x.accountId)" class="jf-common-logo">
<img src="/upload/avatar/#(x.avatar)" />
</a>
<div class="col">
<div class="jf-common-name"><a href="/share/#(x.id)">#(x.title)</a></div>
<p class="jf-common-other text-gray">
<span class="pull-left">#date(x.createAt)</span>
### <span><i class="fa fa-eye"></i>&nbsp;#(x.clickCount)</span>
<span style="text-align: right;"><i class="fa fa-thumbs-o-up"></i>&nbsp;#(x.likeCount)</span>
</p>
</div>
</div>
</div>
#end
</div>
</div>
</div>
### 反馈
<div class="jf-panel jf-article-list">
<div class="jf-panel-header">
<a class="jf-more" href="/feedback">更多»</a>
<h1>反馈</h1>
</div>
<div class="jf-panel-body">
<div class="jf-common-list">
#for(x : feedbackList)
<div class="jf-common-item">
<div class="row">
<a href="/user/#(x.accountId)" class="jf-common-logo">
<img src="/upload/avatar/#(x.avatar)" />
</a>
<div class="col">
<div class="jf-common-name"><a href="/feedback/#(x.id)">#(x.title)</a></div>
<p class="jf-common-other text-gray">
<span class="pull-left">#date(x.createAt)</span>
### <span><i class="fa fa-eye"></i>&nbsp;#(x.clickCount)</span>
<span style="text-align: right;"><i class="fa fa-thumbs-o-up"></i>&nbsp;#(x.likeCount)</span>
</p>
</div>
</div> </div>
</div> </div>
#end
</div> </div>
</div> <div class="col-lg-7 col-md-12 col-12">
</div> <div class="hero-image wow fadeInRight" data-wow-delay=".4s">
<img src="https://quick.bootmb.com/assets/img/svg/illustrations/illustration-3.svg" alt="#">
### 项目
<div class="jf-panel jf-article-list">
<div class="jf-panel-header">
<a class="jf-more" href="/project">更多»</a>
<h1>项目</h1>
</div>
<div class="jf-panel-body">
<!--项目列表 start-->
<div class="jf-project-list">
#setLocal(i=0, j=0)
#for(x : projectList)
#if(for.first || ++i % 4 == 0)
<div class="row">
#end
<div class="col-3">
<div class="jf-project-item jf-transition ">
<a href="/project/#(x.id)" class="jf-project-logo">
<img src="/upload/avatar/#(x.avatar)" />
</a>
<h1 class="jf-project-name">
<a href="/project/#(x.id)">#(x.title)</a>
</h1>
#--
<p class="jf-project-info">
###<span><i class="fa fa-eye"></i>&nbsp;305</span>
<span><i class="fa fa-star-o"></i>&nbsp;25</span>
<span><i class="fa fa-thumbs-o-up"></i>&nbsp;99</span>
</p>
--#
</div>
</div>
#if(for.last || ++j % 4 == 0)
</div> </div>
#end
#end
</div> </div>
</div> </div>
</div> </div>
</section>
<!-- End Hero Area -->
#end
#define js()
<!-- ========================= JS here ========================= -->
<script src="/assets/official/js/bootstrap.min.js"></script>
<script src="/assets/official/js/wow.min.js"></script>
<script src="/assets/official/js/tiny-slider.js"></script>
<script src="/assets/official/js/glightbox.min.js"></script>
<script src="/assets/official/js/count-up.min.js"></script>
<script src="/assets/official/js/main.js"></script>
<script type="text/javascript">
//======== tiny slider
tns({
container: '.client-logo-carousel',
autoplay: true,
autoplayButtonOutput: false,
mouseDrag: true,
gutter: 15,
nav: false,
controls: false,
responsive: {
0: {
items: 1,
},
540: {
items: 2,
},
768: {
items: 3,
},
992: {
items: 4,
}
}
});
//========= testimonial
tns({
container: '.testimonial-slider',
items: 3,
slideBy: 'page',
autoplay: false,
mouseDrag: true,
gutter: 0,
nav: true,
controls: false,
controlsText: ['<i class="lni lni-arrow-left"></i>', '<i class="lni lni-arrow-right"></i>'],
responsive: {
0: {
items: 1,
},
540: {
items: 1,
},
768: {
items: 1,
},
992: {
items: 1,
},
1170: {
items: 1,
}
}
});
</div> //========= glightbox
GLightbox({
'href': '#',
'type': 'video',
'source': 'youtube', //vimeo, youtube or local
'width': 900,
'autoplayVideos': true,
});
<!-- 包含侧边栏文件 --> //====== counter up
#include("_sidebar.html") var cu = new counterUp({
start: 0,
duration: 2000,
intvalues: true,
interval: 100,
append: " ",
});
cu.start();
</script>
#end #end

190
src/main/webapp/_view/my/dashboard/_left_menu.html

@ -1,159 +1,31 @@
<!--侧边栏--> <div class="sidebar-menu">
<div class="bsa-sidebar"> <ul class="menu">
<!-- 侧边栏头部部分(展示品牌logo) --> <li class="sidebar-item #(sidebar == 'my' ? 'active' : '')" >
<div class="bsa-sidebar-header"> <a href="/my" class='sidebar-link'>
<img src="/assets/img/bt-logo-32x32.png" class="bsa-logo-icon" alt="logo-icon"> <i class="bi bi-grid-fill"></i>
<div class="bsa-logo-text ms-2 bsa-ellipsis-2">贝塔网络BT控制台</div> <span>首页</span>
</div> </a>
<!-- 侧边栏的身体部分 --> </li>
<div class="bsa-sidebar-body" data-overlayscrollbars-initialize> <li class="sidebar-item #(sidebar == 'order' ? 'active' : '')" >
<!-- 侧边栏的菜单 --> <a href="/my/order" class='sidebar-link'>
<ul class="bsa-menu" data-bsa-toggle="sidebar" data-accordion="true" data-click-close="true"> <i class="bi bi-grid-fill"></i>
<li> <span>我的订单</span>
<a href="/my/welcome"> </a>
<i class="bi bi-house"></i>首页 </li>
</a> <li class="sidebar-item has-sub #(sidebar == 'setting' ? 'active' : '')">
</li> <a href="#" class='sidebar-link'>
<li> <i class="bi bi-person-circle"></i>
<a href="pages/order.html"> <span>账户设置</span>
<i class="bi bi-credit-card"></i>充值中心 </a>
</a> <ul class="submenu #(sidebar == 'setting' ? 'active' : '')">
</li> <li class="submenu-item #(sidebar == 'realName' ? 'active' : '')">
<li> <a href="/my/setting/realName" class="submenu-link">实名认证</a>
<a href="/product" target="_blank"> </li>
<i class="bi bi-bag-fill"></i>自助下单 <li class="submenu-item ">
</a> <a href="account-security.html" class="submenu-link">Security</a>
</li> </li>
<li> </ul>
<a href="/my/order"> </li>
<i class="bi bi-border-width"></i>订单列表
</a> </ul>
</li> </div>
<li>
<a href="pages/order.html">
<i class="bi bi-pc-horizontal"></i>设备管理
</a>
</li>
<li>
<a href="javascript:" class="has-children">
<i class="bi bi-gear"></i>个人设置
</a>
<ul>
<li><a href="/my/setting/realName">实名认知</a></li>
<li><a href="pages/sys_website.html">网站设置</a></li>
<li><a href="pages/sys_email.html">邮箱设置</a></li>
</ul>
</li>
<li>
<a href="javascript:" class="has-children">
<i class="bi bi-person-lock"></i>权限管理
</a>
<ul>
<li>
<a href="pages/user.html">用户列表</a>
</li>
<li>
<a href="pages/user2">用户列表(多部门版)</a>
</li>
<li>
<a href="pages/role.html">角色列表</a>
</li>
<li>
<a href="pages/node.html">节点列表</a>
</li>
</ul>
</li>
<li>
<a href="javascript:" class="has-children">
<i class="bi bi-filetype-html"></i>示例页面
</a>
<ul>
<li>
<a href="pages/blank.html">新页面</a>
</li>
<li>
<!-- target="_self":添加该属性可以让该页面不从tab页面里打开 -->
<a href="pages/lockscreen.html" target="_self">锁屏页</a>
</li>
<li>
<a href="pages/gallery.html">图库列表</a>
</li>
<li>
<a href="pages/errors.html">错误页面</a>
</li>
<li>
<a href="pages/login.html" target="_self">登录页面</a>
</li>
<li>
<a href="pages/timeline.html">时间轴</a>
</li>
<li>
<a href="pages/layout1.html">布局示例1</a>
</li>
<li>
<a href="pages/layout2.html">布局示例2</a>
</li>
<li>
<a href="pages/layout3.html">布局示例3</a>
</li>
</ul>
</li>
<li>
<a href="javascript:" class="has-children">
<i class="bi bi-filetype-js"></i>插件
</a>
<ul>
<li><a href="pages/plugin-day.js.html">day.js(时间格式)</a></li>
<li><a href="pages/plugin-clipboard.html">复制粘贴插件</a></li>
<li><a href="pages/plugin-shepherd.html">更新引导插件</a></li>
<li><a href="pages/plugin-fullcalendar.html">日历</a></li>
<li><a href="pages/plugin-video-js.html">视频播放器</a></li>
<li><a href="pages/plugin-pickr.html">颜色选择器</a></li>
<li><a href="pages/plugin-raty-js.html">评分插件</a></li>
<li><a href="pages/plugin-bootstrap-input-spinner.html">输入框微调插件</a></li>
<li><a href="pages/plugin-bs-stepper.html">步骤条插件</a></li>
<li><a href="pages/plugin-sweetalert2.html">sweetalert2</a></li>
<li><a href="pages/plugin-formvalidation.html">表单验证</a></li>
<li><a href="pages/plugin-tempus-dominus.html">日期时间</a></li>
<li><a href="pages/plugin-croppie.html">头像裁剪</a></li>
<li>
<a href="javascript:" class="has-children">树形组件</a>
<ul>
<li><a href="pages/plugin-ztree.html">ztree</a></li>
</ul>
</li>
<li>
<a href="javascript:" class="has-children">图表</a>
<ul>
<li><a href="pages/plugin-chart.html">chart.js</a></li>
<li><a href="pages/plugin-echarts.html">echart.js</a></li>
</ul>
</li>
<li>
<a href="javascript:" class="has-children">数据表格</a>
<ul>
<li><a href="pages/plugin-bootstrap-table.html">bootstrap-table</a></li>
<li><a href="pages/plugin-datatables.html">datatables</a></li>
</ul>
</li>
<li>
<a href="javascript:" class="has-children">编辑器</a>
<ul>
<li><a href="pages/plugin-wangeditor.html">wangeditor</a></li>
</ul>
</li>
<li>
<a href="javascript:" class="has-children">文件上传</a>
<ul>
<li><a href="pages/plugin-bootstrap-fileinput.html">bootstrap-fileinput</a></li>
<li><a href="pages/plugin-dropzone.html">dropzone</a></li>
</ul>
</li>
<li><a href="pages/plugin-select2.html">select2</a></li>
<li><a href="pages/plugin-bootstrap-select.html">bootstrap-select</a></li>
<li><a href="pages/plugin-fonticonpicker.html">图标选择器</a></li>
</ul>
</li>
</ul>
</div>
</div>

489
src/main/webapp/_view/my/dashboard/index.html

@ -1,179 +1,330 @@
<!DOCTYPE html> #set(seoTitle="贝塔网络欢迎页")
<html lang="zh-CN"> #@b5Layout()
<head> #define menu()
<meta charset="utf-8"> #include("_left_menu.html" , sidebar="my", submenu="")
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no"> #end
<meta name="keywords" content="#(seoKeywords ?? 'bt科技,贝塔科技,贝塔网络')"> #define main()
<meta name="description" content="#(seoDescr ?? '贝塔网络官方网站')"> <div id="main">
<title>贝塔网络用户面板</title> <header class="mb-3">
<meta name="author" content="bt.plus"> <a href="#" class="burger-btn d-block d-xl-none">
<link rel="stylesheet" href="/assets/lib/bootstrap-icons/font/bootstrap-icons.min.css"> <i class="bi bi-justify fs-3"></i>
<link rel="stylesheet" href="/assets/lib/bootstrap/dist/css/bootstrap.min.css"> </a>
<link rel="stylesheet" href="/assets/lib/overlayscrollbars/styles/overlayscrollbars.min.css"> </header>
<link rel="stylesheet" href="/assets/b5/css/bootstrap-admin.min.css"> <div class="page-heading">
<link rel="shortcut icon" type="image/x-icon" href="/assets/img/favicon.ico"> <h3>贝塔网络用户面板</h3>
</head> </div>
<body data-theme="light"> <div class="page-content">
<!--头部导航--> <section class="row">
<ul class="bsa-header"> <div class="col-12 col-lg-9">
<!-- 侧边栏触发按钮(移动端时显示) --> <div class="row">
<li class="bsa-sidebar-toggler" data-bsa-toggle="pushmenu"> <div class="col-6 col-lg-3 col-md-6">
<div class="bsa-header-item"> <div class="card">
<i class="bi bi-list"></i> <div class="card-body px-4 py-4-5">
</div> <div class="row">
</li> <div class="col-md-4 col-lg-12 col-xl-12 col-xxl-5 d-flex justify-content-start ">
<!-- 占位(可以让后面的li居右) --> <div class="stats-icon purple mb-2">
<li class="flex-grow-1"></li> <i class="iconly-boldShow"></i>
<!-- 通知(如果有新消息则添加类名.bsa-has-msg) --> </div>
<li> </div>
<div class="bsa-header-item" data-qt-tab='{"title":"消息中心","url":"pages/message.html"}' <div class="col-md-8 col-lg-12 col-xl-12 col-xxl-7">
data-qt-target=".qtab"> <h6 class="text-muted font-semibold">Profile Views</h6>
<i class="bi bi-bell bsa-has-msg"></i> <h6 class="font-extrabold mb-0">112.000</h6>
</div> </div>
</li> </div>
<!-- 全屏 --> </div>
<li class="bsa-fullscreen-toggler"> </div>
<div class="bsa-header-item"> </div>
<i class="bi bi-arrows-fullscreen"></i> <div class="col-6 col-lg-3 col-md-6">
</div> <div class="card">
</li> <div class="card-body px-4 py-4-5">
<!-- 主题配色 --> <div class="row">
<li class="dropdown"> <div class="col-md-4 col-lg-12 col-xl-12 col-xxl-5 d-flex justify-content-start ">
<div class="bsa-header-item" data-bs-toggle="dropdown" data-bs-auto-close="outside"> <div class="stats-icon blue mb-2">
<i class="bi bi-palette"></i> <i class="iconly-boldProfile"></i>
</div> </div>
<div class="dropdown-menu dropdown-menu-end p-0"> </div>
<div class="card shadow-sm"> <div class="col-md-8 col-lg-12 col-xl-12 col-xxl-7">
<div class="card-header d-flex justify-content-between bg-body"> <h6 class="text-muted font-semibold">Followers</h6>
<span class="bsa-fs-15">主题配色</span> <h6 class="font-extrabold mb-0">183.000</h6>
</div>
</div>
</div>
</div>
</div>
<div class="col-6 col-lg-3 col-md-6">
<div class="card">
<div class="card-body px-4 py-4-5">
<div class="row">
<div class="col-md-4 col-lg-12 col-xl-12 col-xxl-5 d-flex justify-content-start ">
<div class="stats-icon green mb-2">
<i class="iconly-boldAdd-User"></i>
</div>
</div>
<div class="col-md-8 col-lg-12 col-xl-12 col-xxl-7">
<h6 class="text-muted font-semibold">Following</h6>
<h6 class="font-extrabold mb-0">80.000</h6>
</div>
</div>
</div>
</div>
</div>
<div class="col-6 col-lg-3 col-md-6">
<div class="card">
<div class="card-body px-4 py-4-5">
<div class="row">
<div class="col-md-4 col-lg-12 col-xl-12 col-xxl-5 d-flex justify-content-start ">
<div class="stats-icon red mb-2">
<i class="iconly-boldBookmark"></i>
</div>
</div>
<div class="col-md-8 col-lg-12 col-xl-12 col-xxl-7">
<h6 class="text-muted font-semibold">Saved Post</h6>
<h6 class="font-extrabold mb-0">112</h6>
</div>
</div>
</div>
</div>
</div>
</div> </div>
<div class="card-body"> <div class="row">
<!-- 配色包裹 --> <div class="col-12">
<div class="bsa-theme-switcher-wrapper"> <div class="card">
<input class="form-check-input" type="checkbox" value="light"> <div class="card-header">
<input class="form-check-input" type="checkbox" value="dark"> <h4>Profile Visit</h4>
<input class="form-check-input" type="checkbox" value="indigo"> </div>
<input class="form-check-input" type="checkbox" value="green"> <div class="card-body">
<input class="form-check-input" type="checkbox" value="blue"> <div id="chart-profile-visit"></div>
<input class="form-check-input" type="checkbox" value="yellow"> </div>
<input class="form-check-input" type="checkbox" value="pink"> </div>
<input class="form-check-input" type="checkbox" value="red"> </div>
<input class="form-check-input" type="checkbox" value="orange"> </div>
<input class="form-check-input" type="checkbox" value="cyan"> <div class="row">
<input class="form-check-input" type="checkbox" value="teal"> <div class="col-12 col-xl-4">
<div class="card">
<div class="card-header">
<h4>Profile Visit</h4>
</div>
<div class="card-body">
<div class="row">
<div class="col-7">
<div class="d-flex align-items-center">
<svg class="bi text-primary" width="32" height="32" fill="blue"
style="width:10px">
<use
xlink:href="assets/static/images/bootstrap-icons.svg#circle-fill" />
</svg>
<h5 class="mb-0 ms-3">Europe</h5>
</div>
</div>
<div class="col-5">
<h5 class="mb-0 text-end">862</h5>
</div>
<div class="col-12">
<div id="chart-europe"></div>
</div>
</div>
<div class="row">
<div class="col-7">
<div class="d-flex align-items-center">
<svg class="bi text-success" width="32" height="32" fill="blue"
style="width:10px">
<use
xlink:href="assets/static/images/bootstrap-icons.svg#circle-fill" />
</svg>
<h5 class="mb-0 ms-3">America</h5>
</div>
</div>
<div class="col-5">
<h5 class="mb-0 text-end">375</h5>
</div>
<div class="col-12">
<div id="chart-america"></div>
</div>
</div>
<div class="row">
<div class="col-7">
<div class="d-flex align-items-center">
<svg class="bi text-success" width="32" height="32" fill="blue"
style="width:10px">
<use
xlink:href="assets/static/images/bootstrap-icons.svg#circle-fill" />
</svg>
<h5 class="mb-0 ms-3">India</h5>
</div>
</div>
<div class="col-5">
<h5 class="mb-0 text-end">625</h5>
</div>
<div class="col-12">
<div id="chart-india"></div>
</div>
</div>
<div class="row">
<div class="col-7">
<div class="d-flex align-items-center">
<svg class="bi text-danger" width="32" height="32" fill="blue"
style="width:10px">
<use
xlink:href="assets/static/images/bootstrap-icons.svg#circle-fill" />
</svg>
<h5 class="mb-0 ms-3">Indonesia</h5>
</div>
</div>
<div class="col-5">
<h5 class="mb-0 text-end">1025</h5>
</div>
<div class="col-12">
<div id="chart-indonesia"></div>
</div>
</div>
</div>
</div>
</div>
<div class="col-12 col-xl-8">
<div class="card">
<div class="card-header">
<h4>Latest Comments</h4>
</div>
<div class="card-body">
<div class="table-responsive">
<table class="table table-hover table-lg">
<thead>
<tr>
<th>Name</th>
<th>Comment</th>
</tr>
</thead>
<tbody>
<tr>
<td class="col-3">
<div class="d-flex align-items-center">
<div class="avatar avatar-md">
<img src="./assets/compiled/jpg/5.jpg">
</div>
<p class="font-bold ms-3 mb-0">Si Cantik</p>
</div>
</td>
<td class="col-auto">
<p class=" mb-0">Congratulations on your graduation!</p>
</td>
</tr>
<tr>
<td class="col-3">
<div class="d-flex align-items-center">
<div class="avatar avatar-md">
<img src="./assets/compiled/jpg/2.jpg">
</div>
<p class="font-bold ms-3 mb-0">Si Ganteng</p>
</div>
</td>
<td class="col-auto">
<p class=" mb-0">Wow amazing design! Can you make another tutorial for
this design?</p>
</td>
</tr>
<tr>
<td class="col-3">
<div class="d-flex align-items-center">
<div class="avatar avatar-md">
<img src="./assets/compiled/jpg/8.jpg">
</div>
<p class="font-bold ms-3 mb-0">Singh Eknoor</p>
</div>
</td>
<td class="col-auto">
<p class=" mb-0">What a stunning design! You are so talented and creative!</p>
</td>
</tr>
<tr>
<td class="col-3">
<div class="d-flex align-items-center">
<div class="avatar avatar-md">
<img src="./assets/compiled/jpg/3.jpg">
</div>
<p class="font-bold ms-3 mb-0">Rani Jhadav</p>
</div>
</td>
<td class="col-auto">
<p class=" mb-0">I love your design! It’s so beautiful and unique! How did you learn to do this?</p>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> <div class="col-12 col-lg-3">
</li> <div class="card">
<!-- 管理员信息 --> <div class="card-body py-4 px-4">
<li class="dropdown"> <div class="d-flex align-items-center">
<div class="bsa-header-item" data-bs-toggle="dropdown"> <div class="avatar avatar-xl">
<div class="bsa-user-area"> <img src="./assets/compiled/jpg/1.jpg" alt="Face 1">
<img src="/upload/avatar/#(loginAccount.avatar)" class="bsa-user-avatar" alt="用户头像"> </div>
<div class="bsa-user-details"> <div class="ms-3 name">
<div class="bsa-ellipsis-1 bsa-fs-15">欲饮琵琶码上催</div> <h5 class="font-bold">John Duck</h5>
<!-- 管理员角色RBAC权限设计时可用(不需要可删除,上面的用户名可自动垂直居中) --> <h6 class="text-muted mb-0">@johnducky</h6>
<div class="bsa-ellipsis-1 bsa-fs-13 text-muted">超级管理员</div> </div>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h4>Recent Messages</h4>
</div>
<div class="card-content pb-4">
<div class="recent-message d-flex px-4 py-3">
<div class="avatar avatar-lg">
<img src="./assets/compiled/jpg/4.jpg">
</div>
<div class="name ms-4">
<h5 class="mb-1">Hank Schrader</h5>
<h6 class="text-muted mb-0">@johnducky</h6>
</div>
</div>
<div class="recent-message d-flex px-4 py-3">
<div class="avatar avatar-lg">
<img src="./assets/compiled/jpg/5.jpg">
</div>
<div class="name ms-4">
<h5 class="mb-1">Dean Winchester</h5>
<h6 class="text-muted mb-0">@imdean</h6>
</div>
</div>
<div class="recent-message d-flex px-4 py-3">
<div class="avatar avatar-lg">
<img src="./assets/compiled/jpg/1.jpg">
</div>
<div class="name ms-4">
<h5 class="mb-1">John Dodol</h5>
<h6 class="text-muted mb-0">@dodoljohn</h6>
</div>
</div>
<div class="px-4">
<button class='btn btn-block btn-xl btn-outline-primary font-bold mt-3'>Start Conversation</button>
</div>
</div>
</div>
<div class="card">
<div class="card-header">
<h4>Visitors Profile</h4>
</div>
<div class="card-body">
<div id="chart-visitors-profile"></div>
</div>
</div> </div>
</div> </div>
</div> </section>
<ul class="dropdown-menu dropdown-menu-end">
<li>
<a class="dropdown-item" href="javascript:"
data-qt-tab='{"title":"个人资料","url":"#(SSL)/pages/profile.html"}'
data-qt-target=".qtab">
<i class="bi bi-person me-2"></i>个人资料
</a>
</li>
<li>
<a class="dropdown-item bsa-clear-cache" href="javascript:"
data-qt-tab='{"title":"修改密码","url":"#(SSL)/pages/password.html"}'
data-qt-target=".qtab">
<i class="bi bi-key me-2"></i>修改密码
</a>
</li>
<li>
<div class="dropdown-divider"></div>
</li>
<li class="bsa-logout"><a class="dropdown-item" href="javascript:"><i
class="bi bi-box-arrow-right me-2"></i>退出登录</a>
</li>
</ul>
</li>
</ul>
<!--header部分结束-->
#include("_left_menu.html")
<!--内容区域(用于tab选项卡插件)-->
<div class="bsa-content">
<div class="qtab" data-qt-tabs='[{"title":"首页","url":"/my/welcome","close":false}]'></div>
</div>
<!--版权信息-->
<div class="bsa-footer">
<p class="mb-0">Copyright © 2023. All right reserved.</p>
</div>
<!--加载层-->
<div class="bsa-preloader">
<div class="spinner-border text-secondary" role="status">
<span class="visually-hidden">Loading...</span>
</div> </div>
#include("_footer.html")
</div> </div>
<script src="/assets/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script> #end
<script src="/assets/lib/jquery/dist/jquery.min.js"></script>
<script src="/assets/lib/overlayscrollbars/browser/overlayscrollbars.browser.es6.min.js"></script>
<script src="/assets/lib/bootstrap-quicktab/dist/js/bootstrap-quicktab.min.js"></script>
<script src="/assets/b5/js/bootstrap-admin.min.js"></script>
<script src="/assets/b5/js/app.js"></script>
<script>
$(function () {
//头部搜索框处理(不需要可以删除,不明白的可以看bootstrap-admin官方文档)
$(document).on('search.bsa.navbar-search', function (e, inputValue, data) {
//先得到请求地址,组合后大概是这样pages/search.html?keyword=dsadsa&type=article&user=admin2
let url = data.action + '?keyword=' + inputValue + '&' + $.param(data.params);
//然后通过tab打开一个搜索结果的窗口
Quicktab.get('.qtab').addTab({
title: '<i class="bi bi-search"></i><span class="text-danger ms-2">' + inputValue + '</span>',
url: url,
close: true,
})
})
//退出登录
$(document).on('click', '.bsa-logout', function (e) {
e.preventDefault();
$.modal({
body: '确定要退出吗?',
cancelBtn: true,
ok: function () {
//请求退出路由
$.ajax({
method: 'post',
url: '/logout',
}).then(response => {
if (response.code === 200) {//跳转到后台首页 #define js()
<!-- Need: Apexcharts -->
<script src="/assets/b5/extensions/apexcharts/apexcharts.min.js"></script>
<script src="/assets/b5/static/js/pages/dashboard.js"></script>
#end
$.toasts({
type: 'success',
content: '退出成功',
onHidden: function () {
top.location.replace('/pages/login.html');
}
})
}
});
}
})
});
});
</script>
</body>
</html>

223
src/main/webapp/_view/my/order/index.html

@ -1,124 +1,157 @@
#set(seoTitle="贝塔网络订单页") #set(seoTitle="贝塔网络订单页")
#@b5Layout() #@b5Layout()
#define menu()
#include("../dashboard/_left_menu.html", sidebar="order", submenu="")
#end
#define css() #define css()
<link rel="stylesheet" href="/assets/lib/bootstrap-table/dist/bootstrap-table.min.css"> <link rel="stylesheet" href="https://www.bootstrap-admin.top/lib/bootstrap-table/dist/bootstrap-table.min.css">
<link rel="stylesheet" href="/assets/lib/bootstrap-table/dist/extensions/fixed-columns/bootstrap-table-fixed-columns.min.css">
<link rel="stylesheet" href="/assets/lib/@eonasdan/tempus-dominus/dist/css/tempus-dominus.min.css"/>
<link rel="stylesheet" href="/assets/lib/bootstrap-select/dist/css/bootstrap-select.min.css"/>
#end #end
#define main() #define main()
<div class="container-fluid"> <div id="main">
<div class="card border-0 shadow-sm"> <header class="mb-3">
<div class="card-header bg-body py-3"> <a href="#" class="burger-btn d-block d-xl-none">
<form class="row row-cols-sm-auto g-3 align-items-center"> <i class="bi bi-justify fs-3"></i>
<div class="col-12"> </a>
<div class="row"> </header>
<label for="username" class="col-sm-auto col-form-label">用户名</label> <div class="page-heading">
<div class="col"> <div class="page-title">
<input type="email" class="form-control" id="username" name="username"> <div class="row">
</div> <div class="col-12 col-md-6 order-md-1 order-last">
</div> <h3>我的订单</h3>
</div> </div>
<div class="col-12"> <div class="col-12 col-md-6 order-md-2 order-first">
<div class="row"> <nav aria-label="breadcrumb" class="breadcrumb-header float-start float-lg-end">
<label for="phone" class="col-sm-auto col-form-label">手机号</label> <ol class="breadcrumb">
<div class="col"> <li class="breadcrumb-item"><a href="/my">首页</a></li>
<input type="email" class="form-control" id="phone" name="phone"> <li class="breadcrumb-item active" aria-current="page">我的订单</li>
</div> </ol>
</div> </nav>
</div> </div>
</div>
</div>
<section class="section">
<div class="row">
<div class="col-12"> <div class="col-12">
<div class="row"> <div class="card">
<label for="beginTime" class="col-sm-auto col-form-label">创建时间</label> <div class="card-header">
<div class="col"> <h4>Basic Buttons</h4>
<div class="input-group"> </div>
<input type="text" readonly class="form-control" aria-label="q" <div class="card-body">
placeholder="开始时间"
name="beginTime" id="beginTime">
<span class="input-group-text"><i class="bi bi-arrow-left-right"></i></span> <div class="buttons">
<input type="text" readonly class="form-control" aria-label="q" <a href="#" class="btn btn-primary">Primary</a>
placeholder="结束时间" <a href="#" class="btn btn-secondary">Secondary</a>
name="endTime" id="endTime"> <a href="#" class="btn btn-info">Info</a>
<a href="#" class="btn btn-warning">Warning</a>
<a href="#" class="btn btn-danger">Danger</a>
<a href="#" class="btn btn-success">Success</a>
<a href="#" class="btn btn-light">Light</a>
<a href="#" class="btn btn-dark">Dark</a>
</div>
<hr>
<div class="buttons">
<a href="#" class="btn btn-primary rounded-pill">Primary</a>
<a href="#" class="btn btn-secondary rounded-pill">Secondary</a>
<a href="#" class="btn btn-info rounded-pill">Info</a>
<a href="#" class="btn btn-warning rounded-pill">Warning</a>
<a href="#" class="btn btn-danger rounded-pill">Danger</a>
<a href="#" class="btn btn-success rounded-pill">Success</a>
<a href="#" class="btn btn-light rounded-pill">Light</a>
<a href="#" class="btn btn-dark rounded-pill">Dark</a>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="col-12"> <div class="col-12 col-lg-12">
<div class="row"> <div class="card border-0 shadow-sm">
<label for="status" class="col-sm-auto col-form-label">用户状态</label> <div class="card-header bg-body py-3">
<div class="col"> <form class="row row-cols-sm-auto g-3 align-items-center">
<select class="selectpicker"> <div class="col-12">
<option value="0">所有</option> <div class="row">
<option value="1">正常</option> <label for="username" class="col-sm-auto col-form-label">用户名</label>
<option value="2">停用</option> <div class="col">
</select> <input type="email" class="form-control" id="username" name="username">
</div>
</div>
</div>
<div class="col-12">
<div class="row">
<label for="phone" class="col-sm-auto col-form-label">手机号</label>
<div class="col">
<input type="email" class="form-control" id="phone" name="phone">
</div>
</div>
</div>
<div class="col-12">
<div class="row">
<label for="beginTime" class="col-sm-auto col-form-label">创建时间</label>
<div class="col">
<div class="input-group">
<input type="text" readonly class="form-control" aria-label="q"
placeholder="开始时间"
name="beginTime" id="beginTime">
<span class="input-group-text"><i class="bi bi-arrow-left-right"></i></span>
<input type="text" readonly class="form-control" aria-label="q"
placeholder="结束时间"
name="endTime" id="endTime">
</div>
</div>
</div>
</div>
<div class="col-12">
<div class="row">
<label for="status" class="col-sm-auto col-form-label">用户状态</label>
<div class="col">
<select class="selectpicker">
<option value="0">所有</option>
<option value="1">正常</option>
<option value="2">停用</option>
</select>
</div>
</div>
</div>
<div class="col-12 gap-2">
<button type="button" class="btn btn-light bsa-querySearch-btn">
<i class="bi bi-search"></i>搜索
</button>
<button type="button" class="btn btn-light bsa-reset-btn">
<i class="bi bi-arrow-clockwise"></i>重置
</button>
</div>
</form>
</div>
<div class="card-body">
<!-- 表格上方左侧的工具条区域 -->
<div id="toolbar" class="d-flex flex-wrap gap-2 mb-2">
</div>
<!-- 数据表格 -->
<table id="table"></table>
</div> </div>
</div> </div>
</div> </div>
<div class="col-12 gap-2">
<button type="button" class="btn btn-light bsa-querySearch-btn">
<i class="bi bi-search"></i>搜索
</button>
<button type="button" class="btn btn-light bsa-reset-btn">
<i class="bi bi-arrow-clockwise"></i>重置
</button>
</div>
</form>
</div>
<div class="card-body">
<!-- 表格上方左侧的工具条区域 -->
<div id="toolbar" class="d-flex flex-wrap gap-2 mb-2">
<button class="btn btn-light add-btn"><i
class="bi bi-plus"></i> 新增
</button>
<button class="btn btn-light batch-btn" disabled><i class="bi bi-trash"></i> 批量删除</button>
<button class="btn btn-light"><i class="bi bi-box-arrow-down"></i> 导入</button>
<button class="btn btn-light"><i class="bi bi-box-arrow-up"></i> 导出</button>
</div> </div>
<!-- 数据表格 --> </section>
<table id="table"></table>
</div>
</div> </div>
#include("../dashboard/_footer.html")
</div> </div>
#end #end
#define js() #define js()
<script src="/assets/lib/@popperjs/core/dist/umd/popper.min.js"></script>
<script src="/assets/lib/@eonasdan/tempus-dominus/dist/js/tempus-dominus.min.js"></script>
<script src="/assets/lib/bootstrap-table/dist/bootstrap-table.min.js"></script> <script src="/assets/lib/bootstrap-table/dist/bootstrap-table.min.js"></script>
<script src="/assets/lib/bootstrap-table/dist/locale/bootstrap-table-zh-CN.min.js"></script> <script src="/assets/lib/bootstrap-table/dist/locale/bootstrap-table-zh-CN.min.js"></script>
<script src="/assets/lib/bootstrap-table/dist/extensions/fixed-columns/bootstrap-table-fixed-columns.min.js"></script> <script src="/assets/lib/bootstrap-table/dist/extensions/fixed-columns/bootstrap-table-fixed-columns.min.js"></script>
<script src="/assets/lib/bootstrap-select/dist/js/bootstrap-select.min.js"></script>
<script src="/assets/lib/bootstrap-select/dist/js/i18n/defaults-zh_CN.min.js"></script>
<script> <script>
$(document).ready(function (e) { $(document).ready(function (e) {
// 新增用户
$('.add-btn').on('click', function () {
// window :建议加上该前缀,否则在子页面中通过parent.modalInstance 获取不到该实例对象,因为它现在处于一个匿名函数里
window.modalInstance = $.modal({
url: 'user-add.html',
title: '用户添加',
//禁用掉底部的按钮区域
buttons: [],
modalDialogClass: 'modal-dialog-centered modal-lg',
onHidden: function (obj, data) {
if (data === true) {
//刷新当前数据表格
$('#table').bootstrapTable('refresh');
$('#table').bootstrapTable('selectPage', 1)//跳转到第一页
}
}
})
})
/** /**
* columns表示列,里面的对象 title是表头信息,field是服务端返回的字段名称 * columns表示列,里面的对象 title是表头信息,field是服务端返回的字段名称
* 1.不做分页,返回的数据格式是 [{},{}] * 1.不做分页,返回的数据格式是 [{},{}]

205
src/main/webapp/_view/my/setting/realName.html

@ -1,86 +1,157 @@
#set(seoTitle="贝塔网络用户实名认证") #set(seoTitle="贝塔网络用户实名认证")
#@b5Layout() #@b5Layout()
#define menu()
#include("../dashboard/_left_menu.html", sidebar="setting", submenu="realName")
#end
#define main() #define main()
<div class="container-fluid"> <div id="main">
<div class="card border-0 shadow-sm"> <header class="mb-3">
<div class="card-header bg-body"> <a href="#" class="burger-btn d-block d-xl-none">
实名认证 <i class="bi bi-justify fs-3"></i>
</a>
</header>
<div class="page-heading">
<div class="page-title">
<div class="row">
<div class="col-12 col-md-6 order-md-1 order-last">
<h3>实名认证</h3>
</div>
<div class="col-12 col-md-6 order-md-2 order-first">
<nav aria-label="breadcrumb" class="breadcrumb-header float-start float-lg-end">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/my">首页</a></li>
<li class="breadcrumb-item active" aria-current="page">实名认证</li>
</ol>
</nav>
</div>
</div>
</div> </div>
<div class="card-body"> <section class="section">
<div class="row"> <div class="row">
<div class="col-md-5"> <div class="col-12 col-lg-12">
<form id="form"> <div class="card">
<div class="row mb-3"> <div class="card-body">
<label for="oldPassword" class="col-sm-3 col-form-label text-sm-end">姓名</label> <form id="form">
<div class="col-sm-9"> <div class="form-group">
<input type="password" autocomplete class="form-control" id="oldPassword" <label for="realname" class="form-label">姓名</label>
name="oldPassword"> <input type="text" name="realName.realname" id="realname" class="form-control" placeholder="请如实填写您的姓名" value="">
</div> </div>
</div> <div class="form-group">
<div class="row mb-3"> <label for="idCard" class="form-label">身份证号</label>
<label for="password" class="col-sm-3 col-form-label text-sm-end">身份证号</label> <input type="text" name="realName.idCard" id="idCard" class="form-control" placeholder="请如实填写您的身份证号码" value="">
<div class="col-sm-9"> </div>
<input type="password" autocomplete class="form-control" id="password" name="password"> #if(realName?.status == 1)
</div> <div class="form-group">
<button type="button" class="btn btn-primary" disabled>已进行实名认证</button>
</div>
#else
<div class="form-group">
<button type="button" id="submit" class="btn btn-primary">提交实名</button>
</div>
#end
</form>
</div> </div>
<div class="row mb-3"> </div>
<div class="col-sm-9 offset-sm-3"> </div>
<button type="submit" class="btn btn-primary">认证</button> </div>
</div> </section>
</div>
<div class="modal fade text-left" id="inlineForm" tabindex="-1" role="dialog"
aria-labelledby="myModalLabel33" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered modal-dialog-scrollable"
role="document">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel33">打开支付宝扫码认证</h4>
<button type="button" class="close" data-bs-dismiss="modal"
aria-label="Close">
<i data-feather="x"></i>
</button>
</div>
<div class="modal-body">
<div class="d-flex justify-content-center align-items-center flex-column">
<div class="avatar avatar-2xl">
<div id="qrcode"></div>
</div> </div>
</form> <p class="text-small">手机扫码认证完成后请手动点击查询认证结果</p>
<button id="queryRealName" type="button" class="btn btn-primary ms-1"
data-bs-dismiss="modal">
<i class="bx bx-check d-block d-sm-none"></i>
<span class="d-none d-sm-block">认证完成查询认证结果</span>
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
#include("../dashboard/_footer.html")
</div> </div>
#end #end
#define js() #define js()
<script src="/assets/easy-qrcode/easy.qrcode.min.js" type="text/javascript" charset="utf-8"></script>
<script src="/assets/lib/formvalidation/js/formValidation.js"></script> <script type="text/javascript">
<script src="/assets/lib/formvalidation/js/framework/bootstrap.js"></script> function generateRandomString(length) {
<script src="/assets/lib/formvalidation/js/language/zh_CN.js"></script> var result = '';
<script> var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
//前端表单验证 var charactersLength = characters.length;
$('#form').formValidation({ for (var i = 0; i < length; i++) {
fields: { result += characters.charAt(Math.floor(Math.random() * charactersLength));
oldPassword: {
validators: {
notEmpty: true,
}
},
password: {
validators: {
notEmpty: true,
}
},
rePassword: {
validators: {
notEmpty: true,
}
} }
return result;
} }
}).on('success.form.fv', function (e) { var qrcode;
//阻止表单提交 $(function () {
e.preventDefault(); const myModal = new bootstrap.Modal('#inlineForm', {})
//得到表单对象 $('#submit').click(function(){
let $form = $(e.target); //获取数据
let data = $form.serialize(); let data = $("#form").serialize();
//发起ajax请求
alert('表单验证通过,即将发起ajax'); $.ajax({
//得到序列化数据 method: 'post',
$.ajax({ url: '/my/setting/doRealName',
url: "/login.php", //表单数据
method: 'POST', data: data,
data }).then(ret => {
}).then(function (res) { console.log(ret)
if (res.code === 200) { if(ret.state == "ok") {
//登录成功 if(qrcode){
} else { qrcode.clear();
//登录失败 }
} qrcode = new QRCode(document.getElementById("qrcode"), {
}); text: ret.certifyUrl,
}); width: 360,
height: 360,
colorDark : "#000000",
colorLight : "#ffffff",
correctLevel : QRCode.CorrectLevel.H,
quietZone: 20,
quietZoneColor: "rgba(0,0,0,0)",
});
myModal.show()
} else {
alert(ret.msg)
}
});
})
$("#queryRealName").click(function(){
$.ajax({
method: 'post',
url: '/my/setting/queryRealName'
}).then(ret => {
console.log(ret)
if(ret.state == "ok") {
alert("认证成功")
}else{
alert(ret.msg)
}
});
});
})
</script> </script>
#end #end

173
src/main/webapp/_view/product/index.html

@ -1,55 +1,138 @@
#@layout() #set(seoTitle="贝塔网络官方产品")
#@officialLayout()
#define main() #define main()
<!--左侧主体内容部分--> <!-- Start Breadcrumbs -->
<div class="col jf-page-main jf-pdl0"> <div class="breadcrumbs">
<div class="jf-panel jf-article-list"> <div class="container">
<div class="jf-panel-header"> <div class="row">
<h1>产品</h1> <div class="col-lg-8 offset-lg-2 col-md-12 col-12">
<div class="breadcrumbs-content">
<h1 class="page-title">产品中心</h1>
</div>
<ul class="breadcrumb-nav">
<li><a href="#(SSL)/">首页</a></li>
<li>产品中心</li>
</ul>
</div>
</div> </div>
<div class="jf-panel-body"> </div>
<!--项目列表 start--> </div>
<div class="jf-project-list"> <!-- End Breadcrumbs -->
#setLocal(i=0, j=0) <!-- Start Blog Singel Area -->
#for(x : projectPage.list) <section class="pricing-table section blog-section ">
#if(for.first || ++i % 4 == 0) <div class="container">
<div class="row"> <div class="row">
#end <div class="col-lg-9 col-md-12 col-12">
<div class="col-3"> <ul class="nav nav-pills">
<div class="jf-project-item jf-transition "> <li class="nav-item">
<a href="/project/#(x.id)" class="jf-project-logo"> <button type="button" class="nav-link btn active" aria-current="page" href="#">全部</button>
<img src="/upload/avatar/#(x.avatar)" /> </li>
</a> <li class="nav-item">
<h1 class="jf-project-name"> <button type="button" class="nav-link btn btn-link" href="#">套餐一</button>
<a href="/project/#(x.id)">#(x.title)</a> </li>
</h1> <li class="nav-item">
<button type="button" class="nav-link btn btn-link" href="#">套餐二</button>
#-- </li>
<p class="jf-project-info"> </ul>
###<span><i class="fa fa-eye"></i>&nbsp;305</span> <div class="row mt-3">
<span><i class="fa fa-star-o"></i>&nbsp;25</span> #for(x : productPage.list)
<span><i class="fa fa-thumbs-o-up"></i>&nbsp;99</span> <div class="col-lg-4 col-md-6 col-12 mb-3">
</p> <div class="card border-0 rounded-0 shadow">
--# <div class="card-body mt-3 mb-3">
<div class="row">
<div class="col-10">
<h4 class="card-title">#(x.name)</h4>
<ul class="list-group list-group-flush">
<li class="list-group-item">CPU: #(x.cpuName)</li>
<li class="list-group-item">内存:#(x.memoryCapacity)</li>
<li class="list-group-item">显卡:#(x.graphicsCardModel)</li>
<li class="list-group-item">硬盘:#(x.dataDiskCapacity)</li>
<li class="list-group-item">网络:#(x.downloadSpeed)</li>
</ul>
</div>
<div class="col-2">
<i class="bi bi-bookmark-plus fs-2"></i>
</div>
</div>
</div>
<div class="row align-items-center text-center g-0">
<div class="col-5">
<h5>$129</h5>
</div>
<div class="col-7">
<a href="/order/#(x.id)" class="btn btn-dark w-100 p-2 rounded-0 text-warning">立即购买</a>
</div>
</div>
</div> </div>
</div> </div>
#if(for.last || ++j % 4 == 0) #end
</div> </div>
#end
#end
</div> </div>
<!--项目列表 end--> <aside class="col-lg-3 col-md-12 col-12">
<div class="sidebar blog-grid-page">
<!--分页组件--> <!-- Start Single Widget -->
#@paginate(projectPage.pageNumber, projectPage.totalPage, "/project?p=") <div class="widget popular-feeds">
<h5 class="widget-title">今日特价</h5>
<div class="popular-feed-loop">
<div class="single-popular-feed">
<div class="feed-desc">
<a href="javascript:void(0)" class="cetagory">Creative</a>
<h6 class="post-title"><a href="blog-single-sidebar.html">Bringing Great Design
Ideas To Completion</a></h6>
<span class="time"><i class="lni lni-calendar"></i> 05th Nov 2023</span>
</div>
</div>
<div class="single-popular-feed">
<div class="feed-desc">
<a href="javascript:void(0)" class="cetagory">Jobs</a>
<h6 class="post-title"><a href="blog-single-sidebar.html">Live Life Smart And
Focus On The Positive</a></h6>
<span class="time"><i class="lni lni-calendar"></i> 24th March 2023</span>
</div>
</div>
<div class="single-popular-feed">
<div class="feed-desc">
<a href="javascript:void(0)" class="cetagory">Marketing</a>
<h6 class="post-title"><a href="blog-single-sidebar.html">We’re currently
acceping new projects.</a></h6>
<span class="time"><i class="lni lni-calendar"></i> 30th Jan 2023</span>
</div>
</div>
</div>
</div>
<!-- End Single Widget -->
<!-- Start Single Widget -->
<div class="widget help-call">
<h5 class="widget-title">联系方式</h5>
<div class="inner">
<h3>
<span>+(123) 456-78-90</span>
</h3>
</div>
</div>
<!-- End Single Widget -->
</div>
</aside>
</div> </div>
</div> </div>
</div> </section>
<!-- End Blog Singel Area -->
<!-- 包含侧边栏文件 -->
#include("_sidebar.html")
#end #end
#define js()
<!-- ========================= JS here ========================= -->
<script src="/assets/official/js/bootstrap.min.js"></script>
<script src="/assets/official/js/wow.min.js"></script>
<script src="/assets/official/js/tiny-slider.js"></script>
<script src="/assets/official/js/glightbox.min.js"></script>
<script src="/assets/official/js/main.js"></script>
<script type="text/javascript">
$(document).ready(function() {
});
</script>
#end

206
src/main/webapp/_view/reg/index.html

@ -1,119 +1,113 @@
#set(seoTitle="JFinal 注册账号") #set(seoTitle="贝塔网络注册")
#@layout() #@frontLayout()
#define main() #define main()
<div class="col" style="margin-bottom: 20px;"> <div class="min-vh-100 p-2 bg-body-tertiary d-flex flex-column align-items-center justify-content-center">
<h2>贝塔网络注册</h2>
<!-- 注册 panel --> <p class="text-secondary">一台长在云上的“超级电脑”</p>
<div id="regPanel" class="jf-panel"> <form id="form" class="form" style="width: 380px;max-width: 100%">
<div class="jf-panel-header"> <div class="mb-3">
<h1 class="jf-login-title text-center">注册</h1> <div class="input-group">
<span class="input-group-text bg-white "><i class="bi bi-person"></i></span>
<input type="text" class="form-control" placeholder="请输入昵称" name="nickName" id="nickName" aria-label="nickName">
</div>
</div> </div>
<div class="mb-3">
<div class="jf-panel-body mt15" style="width: 500px;margin:30px auto;"> <div class="input-group">
<!-- 内容区域 start--> <span class="input-group-text bg-white "><i class="bi bi-person"></i></span>
<form id="reg_form" action="/reg/save" method="post"> <input type="text" class="form-control" placeholder="请输入邮箱地址" name="userName" id="userName" aria-label="userName">
<div class="form-group row mb-4">
<label for="nickName" class="col-sm-2 col-form-label col-form-label-lg">昵称</label>
<div class="col-sm-10">
<input type="text" autocomplete="off" class="form-control form-control-lg" id="nickName" name="nickName" placeholder="请输入昵称">
</div>
</div>
<div class="form-group row mb-4">
<label for="userName" class="col-sm-2 col-form-label col-form-label-lg">邮箱</label>
<div class="col-sm-10">
<input type="email" autocomplete="off" class="form-control form-control-lg" id="userName" name="userName" placeholder="请输入邮箱地址">
</div>
</div>
<div class="form-group row mb-4">
<label for="password" class="col-sm-2 col-form-label col-form-label-lg">密码</label>
<div class="col-sm-10">
<input type="password" autocomplete="off" class="form-control form-control-lg" id="password" name="password" placeholder="请输入密码">
</div>
</div>
<div class="form-group row mb-4">
<label class="col-sm-2 col-form-label-lg">
<img title="点击刷新" onclick="updateRegCaptcha()" id="captchaImg" class="jf-login-captcha" src="/reg/captcha"/>
</label>
<div class="col-sm-10">
<input type="text" autocomplete="off" class="form-control form-control-lg" id="captchaInput" name="captcha" placeholder="请输入验证码">
</div>
</div>
<div class="form-group row">
<div class="col-12 text-right">
<button type="submit" class="btn btn-primary btn-lg" style="padding-left:20px;padding-right:20px;">注册账号</button>
</div>
</div>
</form>
<div class="jf-login-links">
已有账号<a href="/login">直接登录</a>
<a class="ml-2" href="/reg/notActivated">还没激活?</a>
</div> </div>
<!-- 内容区域 end-->
</div> </div>
</div>
<div class="mb-3">
<!-- 注册成功 panel --> <div class="input-group bsa-show_hide_password">
<div id="regOkPanel" class="jf-panel" style="min-height: 400px; display: none;"> <span class="input-group-text bg-white"><i class="bi bi-person-lock"></i></span>
<div class="jf-panel-header" style="margin-top:50px;"> <input type="password" class="form-control" placeholder="请输入密码" name="password" autocomplete="off" id="password" aria-label="password">
<h1 class="jf-login-title text-center">注册成功</h1> <span class="input-group-text bg-white bsa-cursor-pointer"><i class="bi bi-eye-slash"></i></span>
</div>
</div> </div>
<div class="jf-panel-body mt15" style="min-width: 500px;margin:30px auto;"> <div class="mb-3">
<!-- 内容区域 start--> <div class="input-group">
<div id="reg_ok_msg" style="text-align: center; font-size: 22px; margin-top: 40px;"> <span class="input-group-text bg-white"><i class="bi bi-shield-lock"></i></span>
请去往注册邮箱&nbsp; <input type="text" class="form-control" id="captchaInput" name="captcha" aria-label="captcha" placeholder="请输入验证码" style="min-width: 80px">
<span style="color:red;" id="regEmail">nickName</span>&nbsp; <img title="点击刷新" onclick="updateRegCaptcha()" id="captchaImg" alt="验证码" class="bsa-cursor-pointer" style="height: 38px;width: 120px"
查收激活邮件激活账号 src="/reg/captcha"/>
</div> </div>
<!-- 内容区域 end-->
</div> </div>
</div>
<div class="d-grid gap-2">
<button class="btn btn-outline-success" type="submit"><i class="bi bi-box-arrow-in-right"></i> 注册账号</button>
</div>
<div class="mb-3 d-flex align-items-center justify-content-between flex-wrap gap-3 mt-3">
已有账号<a href="#(SSL)/login" class="link-success text-decoration-none">直接登录</a>
<a class="link-success text-decoration-none" href="/reg/notActivated">还没激活?</a>
</div>
</form>
</div> </div>
#end #end
#define js() #define js()
<script type="text/javascript" src="/assets/jquery_form/jquery.form.js"></script> <script>
<script type="text/javascript" src="/assets/layer/layer/layer.js"></script> $(function () {
//前端表单验证
<script type="text/javascript"> $('#form').formValidation({
$(document).ready(function() { fields: {
$("#reg_form").ajaxForm({ userName: {
dataType: "json" validators: {
, beforeSubmit: function(formData, jqForm, options) { notEmpty: true,
// 表单提交之前回调 }
} },
, success: function(ret) { password: {
if(ret.state == "ok") { validators: {
$("#regPanel").hide(); notEmpty: true,
$("#regOkPanel").show(); }
$("#regEmail").text(ret.regEmail); },
} else { captcha: {
layer.msg(ret.msg, { validators: {
shift: 6 notEmpty: true,
, shade: 0.3 }
, time: 0 }
, offset: "165px" }
, closeBtn: 1 }).on('success.form.fv', function (e) {
, shadeClose: false //阻止表单提交
} , function() { e.preventDefault();
updateRegCaptcha(); //得到表单对象
} let $form = $(e.target);
); //获取数据
} let data = $form.serialize();
//发起ajax请求
$.ajax({
method: 'post',
url: '/reg/save',
//表单数据
data: data,
}).then(response => {
if(ret.state == "ok") {
$("#regEmail").text(ret.regEmail);
} else {
layer.msg(ret.msg, {
shift: 6
, shade: 0.3
, time: 0
, offset: "165px"
, closeBtn: 1
, shadeClose: false
} , function() {
updateRegCaptcha();
}
);
} }
, error: function(ret) { } // ret.status != 200 时回调 });
, complete: function(ret) { } // 无论是 success 还是 error,最终都会被回调 });
}); })
}); /**
* 刷新验证码
function updateRegCaptcha() { */
$("#captchaImg").attr("src", "/reg/captcha?v=" + Math.random()); function updateRegCaptcha() {
$("#captchaInput").val(""); $("#captchaImg").attr("src", "/reg/captcha?v=" + Math.random());
} $("#captchaInput").val("");
</script> }
</script>
#end #end

3045
src/main/webapp/assets/b5/css/bootstrap-admin.css

File diff suppressed because it is too large

1
src/main/webapp/assets/b5/css/bootstrap-admin.css.map

File diff suppressed because one or more lines are too long

2
src/main/webapp/assets/b5/css/bootstrap-admin.min.css

File diff suppressed because one or more lines are too long

1
src/main/webapp/assets/b5/css/bootstrap-admin.min.css.map

File diff suppressed because one or more lines are too long

BIN
src/main/webapp/assets/b5/img/avatar.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

BIN
src/main/webapp/assets/b5/img/bootstrap-logo-shadow.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

BIN
src/main/webapp/assets/b5/img/bootstrap.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

BIN
src/main/webapp/assets/b5/img/cancel-off.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

BIN
src/main/webapp/assets/b5/img/cancel-on.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

BIN
src/main/webapp/assets/b5/img/captcha.gif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

BIN
src/main/webapp/assets/b5/img/captcha.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

BIN
src/main/webapp/assets/b5/img/edge.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 95 KiB

BIN
src/main/webapp/assets/b5/img/favicon-16x16.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 525 B

BIN
src/main/webapp/assets/b5/img/favicon-32x32.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

BIN
src/main/webapp/assets/b5/img/gallery1.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery10.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery10_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery11.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery11_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery12.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery12_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery13.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery13_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery14.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery14_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery15.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery15_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery16.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery16_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery17.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery17_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery18.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery18_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery19.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery19_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery1_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery2.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery20.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery20_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery21.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery21_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery22.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery22_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery23.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery23_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery2_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery3.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery3_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery4.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery4_thumb.avif

Binary file not shown.

BIN
src/main/webapp/assets/b5/img/gallery5.avif

Binary file not shown.

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save