diff --git a/config.json b/config.json new file mode 100644 index 0000000..926df43 --- /dev/null +++ b/config.json @@ -0,0 +1,9 @@ +{ + "mysql": { + "host": "192.168.5.190", + "port": 3306, + "database": "dormstar", + "username": "dormstar", + "password": "114477225588" + } +} \ No newline at end of file diff --git a/info_upload.sql b/info_upload.sql index 05f221f..4b32a6e 100644 --- a/info_upload.sql +++ b/info_upload.sql @@ -5,4 +5,6 @@ TRUNCATE ds_info; INSERT INTO ds_info (value, data, commit) VALUES ('title', '201京海市保护伞', '网站标题'), ('sub_title', '我们的宿舍', '网站副标题'), - ('register', true, '是否允许注册'); \ No newline at end of file + ('register', true, '是否允许注册'), + ('autoLogin', true, '是否允许自动登录'), + ('schoolLoginAddress', 'http://10.1.99.100:801/', '校园登录IP地址') \ No newline at end of file diff --git a/src/main/kotlin/com/xlf/dromstarkotlin/cache/CacheData.kt b/src/main/kotlin/com/xlf/dromstarkotlin/cache/CacheData.kt index 05b8824..1d91857 100644 --- a/src/main/kotlin/com/xlf/dromstarkotlin/cache/CacheData.kt +++ b/src/main/kotlin/com/xlf/dromstarkotlin/cache/CacheData.kt @@ -2,6 +2,11 @@ package com.xlf.dromstarkotlin.cache object CacheData { val tokenVisits = HashMap() + var autoLogin = false + var allowRegister = false + const val LOGIN_METHOD = "/eportal/portal/login?callback=dr1003&login_method=1&lang=zh-cn&v=5836" + const val LOGOUT_METHOD = "/eportal/portal/mac/unbind?callback=dr1002&lang=zh" + const val STATUS_METHOD = "/drcom/chkstatus?callback=dr1002" } data class CacheToken( diff --git a/src/main/kotlin/com/xlf/dromstarkotlin/config/InitialConfiguration.kt b/src/main/kotlin/com/xlf/dromstarkotlin/config/InitialConfiguration.kt new file mode 100644 index 0000000..1c7706e --- /dev/null +++ b/src/main/kotlin/com/xlf/dromstarkotlin/config/InitialConfiguration.kt @@ -0,0 +1,18 @@ +package com.xlf.dromstarkotlin.config + +import com.xlf.dromstarkotlin.cache.CacheData +import com.xlf.dromstarkotlin.mapper.InfoMapper +import org.springframework.boot.ApplicationArguments +import org.springframework.boot.ApplicationRunner +import org.springframework.stereotype.Component + +@Component +class InitialConfiguration( + val infoMapper: InfoMapper +): ApplicationRunner{ + + override fun run(args: ApplicationArguments?) { + CacheData.autoLogin = infoMapper.autoLogin() + CacheData.allowRegister = infoMapper.getRegister() + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/xlf/dromstarkotlin/config/MysqlConfiguration.kt b/src/main/kotlin/com/xlf/dromstarkotlin/config/MysqlConfiguration.kt new file mode 100644 index 0000000..03cfc81 --- /dev/null +++ b/src/main/kotlin/com/xlf/dromstarkotlin/config/MysqlConfiguration.kt @@ -0,0 +1,61 @@ +package com.xlf.dromstarkotlin.config + +import com.google.gson.Gson +import com.xlf.dromstarkotlin.entity.voData.ConfigVO +import com.xlf.dromstarkotlin.entity.voData.MysqlVO +import com.zaxxer.hikari.HikariConfig +import com.zaxxer.hikari.HikariDataSource +import org.apache.ibatis.session.SqlSessionFactory +import org.mybatis.spring.SqlSessionFactoryBean +import org.mybatis.spring.SqlSessionTemplate +import org.mybatis.spring.annotation.MapperScan +import org.springframework.context.ApplicationContext +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import java.io.File +import javax.sql.DataSource + + +@Configuration +@MapperScan("com.xlf.dromstarkotlin.mapper") +class MysqlConfiguration { + @Bean + @Throws(Exception::class) + fun sqlSessionFactory(dataSource: DataSource?, applicationContext: ApplicationContext?): SqlSessionFactory? { + val factoryBean = SqlSessionFactoryBean() + factoryBean.setDataSource(dataSource) + // 配置其他属性,如mapper位置等 + return factoryBean.getObject() + } + + @Bean + @Throws(Exception::class) + fun sqlSessionTemplate(sqlSessionFactory: SqlSessionFactory?): SqlSessionTemplate { + return SqlSessionTemplate(sqlSessionFactory) + } + + + @Bean + fun dataSource(): DataSource { + // 获取json配置文件中的数据库配置 + val gson = Gson() + // 读取配置文件 config.json + val getConfig: String = if (File("./config.json").exists()) { + File("./config.json").readText(Charsets.UTF_8) + } else { + File("./config.json").createNewFile() + // 输入信息进入文件 + File("./config.json").writeText(gson.toJson(ConfigVO(MysqlVO("127.0.0.1", 3306, "root", "123456", "dromstar")))) + File("./config.json").readText(Charsets.UTF_8) + } + val configVO = gson.fromJson(getConfig, ConfigVO::class.java).mysql + + // 数据库链接 + val hikariConfig = HikariConfig() + hikariConfig.driverClassName = "com.mysql.cj.jdbc.Driver" + hikariConfig.jdbcUrl = "jdbc:mysql://${configVO.host}:${configVO.port}/${configVO.database}" + hikariConfig.username = configVO.username + hikariConfig.password = configVO.password + return HikariDataSource(hikariConfig) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/xlf/dromstarkotlin/controllers/AccountController.kt b/src/main/kotlin/com/xlf/dromstarkotlin/controllers/AccountController.kt new file mode 100644 index 0000000..96a1248 --- /dev/null +++ b/src/main/kotlin/com/xlf/dromstarkotlin/controllers/AccountController.kt @@ -0,0 +1,32 @@ +package com.xlf.dromstarkotlin.controllers + +import com.frontleaves.general.utils.BaseResponse +import com.frontleaves.general.utils.ResultUtil +import com.xlf.dromstarkotlin.services.AccountService +import jakarta.servlet.http.HttpServletRequest +import org.springframework.http.ResponseEntity +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController +import java.util.regex.Pattern + +@RestController +@RequestMapping("/api/account") +class AccountController( + val accountService: AccountService +) { + @GetMapping("/info") + fun getInfo(httpServletRequest: HttpServletRequest): ResponseEntity { + val hashMap = HashMap() + val getMap = accountService.getInformation() + val matcherUid = Pattern.compile("^[0-9]+").matcher(getMap?.get("uid").toString()) + .also { it.find() } + val matcherType = Pattern.compile("[a-z]+$").matcher(getMap?.get("uid").toString()) + .also { it.find() } + hashMap["ip"] = getMap?.get("v46ip") + hashMap["time"] = getMap?.get("time") + hashMap["uid"] = matcherUid.group(0) + hashMap["type"] = matcherType.group(0) + return ResultUtil.success(hashMap, httpServletRequest) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/xlf/dromstarkotlin/mapper/AccountMapper.kt b/src/main/kotlin/com/xlf/dromstarkotlin/mapper/AccountMapper.kt index f2e1067..7793781 100644 --- a/src/main/kotlin/com/xlf/dromstarkotlin/mapper/AccountMapper.kt +++ b/src/main/kotlin/com/xlf/dromstarkotlin/mapper/AccountMapper.kt @@ -1,8 +1,15 @@ package com.xlf.dromstarkotlin.mapper +import com.xlf.dromstarkotlin.entity.doData.AccountDO import org.apache.ibatis.annotations.Mapper +import org.apache.ibatis.annotations.Select @Mapper interface AccountMapper { + @Select("SELECT COUNT(*) FROM ds_account") + fun getCountAccount(): Int + + @Select("SELECT * FROM ds_account WHERE id = #{nextInt}") + fun getAccountById(nextInt: Int): AccountDO } \ No newline at end of file diff --git a/src/main/kotlin/com/xlf/dromstarkotlin/mapper/InfoMapper.kt b/src/main/kotlin/com/xlf/dromstarkotlin/mapper/InfoMapper.kt index 4e49d9e..0124708 100644 --- a/src/main/kotlin/com/xlf/dromstarkotlin/mapper/InfoMapper.kt +++ b/src/main/kotlin/com/xlf/dromstarkotlin/mapper/InfoMapper.kt @@ -6,6 +6,12 @@ import org.apache.ibatis.annotations.Select @Mapper interface InfoMapper { - @Select("SELECT * FROM dormstar.ds_info WHERE value = 'register'") + @Select("SELECT * FROM ds_info WHERE value = 'register'") fun getRegister(): Boolean + + @Select("SELECT * FROM ds_info WHERE value = 'schoolLoginAddress'") + fun getSchoolLoginIpAddress(): String + + @Select("SELECT * FROM ds_info WHERE value = 'autoLogin'") + fun autoLogin(): Boolean } \ No newline at end of file diff --git a/src/main/kotlin/com/xlf/dromstarkotlin/services/AccountService.kt b/src/main/kotlin/com/xlf/dromstarkotlin/services/AccountService.kt new file mode 100644 index 0000000..b6ef60e --- /dev/null +++ b/src/main/kotlin/com/xlf/dromstarkotlin/services/AccountService.kt @@ -0,0 +1,152 @@ +package com.xlf.dromstarkotlin.services + +import com.google.gson.Gson +import com.xlf.dromstarkotlin.cache.CacheData +import com.xlf.dromstarkotlin.entity.doData.AccountDO +import com.xlf.dromstarkotlin.mapper.AccountMapper +import okhttp3.OkHttpClient +import okhttp3.Request +import org.springframework.stereotype.Service +import java.io.IOException +import java.text.SimpleDateFormat +import java.util.* +import java.util.regex.Pattern +import kotlin.collections.HashMap + +@Service +class AccountService( + val accountMapper: AccountMapper +) { + // 进行 okHttp 配置 + val okHttpClient = OkHttpClient() + + fun checkWhetherYouAreLoggedIn(): Boolean { + // 获取百度网站 + val request = Request.Builder() + .url("https://www.baidu.com") + .build() + try { + val response = okHttpClient.newCall(request).execute() + return if (response.code == 200) { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>CheckWhetherYouAreLoggedInSuccess") + true + } else { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <${response.code}>CheckWhetherYouAreLoggedInFailed") + false + } + } catch (e: IOException) { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <500>CheckWhetherYouAreLoggedInFailed | ${e.message}") + } + return false + } + + fun regularLogin() { + // 获取登录地址 + val getAccountDO = randomAccount() + val getLink = "http://10.1.99.100:801${CacheData.LOGIN_METHOD}&user_account=,0,${getAccountDO.user}@${getAccountDO.type}&user_password=${getAccountDO.password}" + val request = Request.Builder() + .url(getLink) + .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0") + .build() + try { + val response = okHttpClient.newCall(request).execute() + val matcher = Pattern.compile("dr1003\\(([^)]+)\\)").matcher(response.body!!.string()) + matcher.find() + val getResponseBody = Gson().fromJson(matcher.group(1), HashMap::class.java) + if (getResponseBody["result"] == "1") { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>AutoLoginSuccess | Message:${getResponseBody["msg"]}") + } else if (getResponseBody["result"] == "0") { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>AutoLoginAccountDoesNotExist | Message:${getResponseBody["msg"]}") + } else { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>AutoLoginUnknownError | Message:${getResponseBody["msg"]}") + } + } catch (e: IOException) { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <500>AutoLoginFailed | ${e.message}") + } + } + + fun regularLogout() { + // 获取信息 + val requestInfo = Request.Builder() + .url("http://localhost:8080/api/account/info") + .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0") + .build() + try { + val response = okHttpClient.newCall(requestInfo).execute() + val getResponseBody = Gson().fromJson(response.body!!.string(), HashMap::class.java) + .also { Gson().fromJson(it["data"].toString(), HashMap::class.java) } + // 获取登出地址 + val getLink = "http://10.1.99.100:801${CacheData.LOGOUT_METHOD}&user_account=${getResponseBody["uid"]}" + val request = Request.Builder() + .url(getLink) + .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)") + .build() + try { + val response = okHttpClient.newCall(request).execute() + val matcher = Pattern.compile("dr1003\\(([^)]+)\\)").matcher(response.body!!.string()) + matcher.find() + val getResponseBody = Gson().fromJson(matcher.group(1), HashMap::class.java) + if (getResponseBody["result"] == "1") { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>AutoLogoutSuccess | Message:${getResponseBody["msg"]}") + } else if (getResponseBody["result"] == "0") { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>AutoLogoutAccountDoesNotExist | Message:${getResponseBody["msg"]}") + } else { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>AutoLogoutUnknownError | Message:$getResponseBody") + } + } catch (e: IOException) { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <500>AutoLogoutFailed | ${e.message}") + } + } catch (e: IOException) { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <500>InternalServiceError | ${e.message}") + } + } + + fun getInformation(): HashMap<*, *>? { + // 获取当前信息 + val getLink = "http://" + "10.1.99.100" + CacheData.STATUS_METHOD + val request = Request.Builder() + .url(getLink) + .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)") + .build() + return try { + val response = okHttpClient.newCall(request).execute() + val matcher = Pattern.compile("dr1002\\(([^)]+)\\)").matcher(response.body!!.string()) + matcher.find() + Gson().fromJson(matcher.group(1), HashMap::class.java) + } catch (e: IOException) { + e.printStackTrace() + null + } + } + + fun switchTheCampusNetwork() { + // 获取登录地址 + val getAccountDO = randomAccount() + val getLink = "http://10.1.99.100:801${CacheData.LOGIN_METHOD}&user_account=,0,${getAccountDO.user}&user_password=${getAccountDO.password}" + val request = Request.Builder() + .url(getLink) + .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/119.0.0.0 Safari/537.36 Edg/119.0.0.0") + .build() + try { + val response = okHttpClient.newCall(request).execute() + val matcher = Pattern.compile("dr1003\\(([^)]+)\\)").matcher(response.body!!.string()) + matcher.find() + val getResponseBody = Gson().fromJson(matcher.group(1), HashMap::class.java) + if (getResponseBody["result"] == "1") { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>AutoLoginSuccess[School] | Message:${getResponseBody["msg"]}") + } else if (getResponseBody["result"] == "0") { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>AutoLoginAccountDoesNotExist[School] | Message:${getResponseBody["msg"]}") + } else { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <200>AutoLoginUnknownError[School] | Message:${getResponseBody["msg"]}") + } + } catch (e: IOException) { + println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <500>AutoLoginFailed[School] | ${e.message}") + } + } + + fun randomAccount(): AccountDO { + // 随机获取用户 + val getCount = accountMapper.getCountAccount() + return accountMapper.getAccountById(Random().nextInt(getCount)+1) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/xlf/dromstarkotlin/services/ScheduleService.kt b/src/main/kotlin/com/xlf/dromstarkotlin/services/ScheduleService.kt index f7a003e..ca3c18b 100644 --- a/src/main/kotlin/com/xlf/dromstarkotlin/services/ScheduleService.kt +++ b/src/main/kotlin/com/xlf/dromstarkotlin/services/ScheduleService.kt @@ -1,5 +1,6 @@ package com.xlf.dromstarkotlin.services +import com.xlf.dromstarkotlin.cache.CacheData import com.xlf.dromstarkotlin.mapper.TokenMapper import org.springframework.scheduling.annotation.Scheduled import org.springframework.stereotype.Component @@ -8,9 +9,13 @@ import java.util.* @Component class ScheduleService( - val tokenMapper: TokenMapper + val tokenMapper: TokenMapper, + val accountService: AccountService ) { + /** + * 清除过期的 Token + */ @Scheduled(fixedDelay = 900000) fun clearExpiredToken() { // 循环所有 Token 信息 @@ -40,4 +45,49 @@ class ScheduleService( } println("${SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Date())} [Log] <----->Scheduled | Message:clear token $i") } + + /** + * 登录校园网(5分钟自动检查) + */ + @Scheduled(fixedDelay = 300000) + fun schoolLogin() { + if (CacheData.autoLogin) { + val calendar = Calendar.getInstance() + val hour = SimpleDateFormat("HH").format(Date()).toInt() + val minute = SimpleDateFormat("mm").format(Date()).toInt() + // 检查星期 + if (calendar.get(Calendar.DAY_OF_WEEK) in 1..5) { + // 允许登录时间范围 + if (hour in 7..<23) { + // 登录 + if (!accountService.checkWhetherYouAreLoggedIn()) { + accountService.regularLogin() + } + } else { + // 切换校园网 + do { + accountService.regularLogout() + Thread.sleep(5000) + } while (accountService.getInformation()?.get("uid") == null) + accountService.switchTheCampusNetwork() + } + } else { + if (hour in 7 .. 23) { + if (hour < 23 || (hour == 23 && minute in 0..30)) { + // 登录 + if (!accountService.checkWhetherYouAreLoggedIn()) { + accountService.regularLogin() + } + } else{ + // 切换校园网 + do { + accountService.regularLogout() + Thread.sleep(5000) + } while (accountService.getInformation()?.get("uid") == null) + accountService.switchTheCampusNetwork() + } + } + } + } + } } \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 2c9eab5..e69de29 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +0,0 @@ -spring: - datasource: - driver-class-name: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://192.168.5.190:3306 - username: dormstar - password: 114477225588 \ No newline at end of file