diff --git a/.idea/Create-a-new-fork.iml b/.idea/Create-a-new-fork.iml
new file mode 100644
index 0000000..8b8c395
--- /dev/null
+++ b/.idea/Create-a-new-fork.iml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/inspectionProfiles/profiles_settings.xml b/.idea/inspectionProfiles/profiles_settings.xml
new file mode 100644
index 0000000..105ce2d
--- /dev/null
+++ b/.idea/inspectionProfiles/profiles_settings.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..2a2c1b9
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..846052f
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..35eb1dd
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
new file mode 100644
index 0000000..02b067d
--- /dev/null
+++ b/.idea/workspace.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1762066317130
+
+
+ 1762066317130
+
+
+
+
\ No newline at end of file
diff --git a/gamecontrol-backend/pom.xml b/gamecontrol-backend/pom.xml
new file mode 100644
index 0000000..5757ce0
--- /dev/null
+++ b/gamecontrol-backend/pom.xml
@@ -0,0 +1,63 @@
+
+
+ 4.0.0
+
+ org.springframework.boot
+ spring-boot-starter-parent
+ 3.2.0
+
+
+ com.gamecontrol
+ gamecontrol-backend
+ 0.0.1-SNAPSHOT
+ gamecontrol-backend
+ Game Control Backend API
+
+ 17
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+
+
+ org.springframework.boot
+ spring-boot-starter-data-jpa
+
+
+ org.springframework.boot
+ spring-boot-starter-security
+
+
+ org.springframework.boot
+ spring-boot-starter-validation
+
+
+ com.mysql
+ mysql-connector-j
+ runtime
+
+
+ org.springframework.boot
+ spring-boot-starter-test
+ test
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
+
+
+
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+
+
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/GamecontrolBackendApplication.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/GamecontrolBackendApplication.java
new file mode 100644
index 0000000..c78f057
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/GamecontrolBackendApplication.java
@@ -0,0 +1,13 @@
+package com.gamecontrol.backend;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+public class GamecontrolBackendApplication {
+
+ public static void main(String[] args) {
+ SpringApplication.run(GamecontrolBackendApplication.class, args);
+ }
+
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/controller/AchievementController.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/controller/AchievementController.java
new file mode 100644
index 0000000..bccf381
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/controller/AchievementController.java
@@ -0,0 +1,97 @@
+package com.gamecontrol.backend.controller;
+
+import com.gamecontrol.backend.entity.Achievement;
+import com.gamecontrol.backend.service.AchievementService;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
+
+@RestController
+@RequestMapping("/achievements")
+public class AchievementController {
+
+ @Autowired
+ private AchievementService achievementService;
+
+ // 获取所有成就
+ @GetMapping
+ public List getAllAchievements() {
+ return achievementService.getAllAchievements();
+ }
+
+ // 根据ID获取成就
+ @GetMapping("/{id}")
+ public ResponseEntity getAchievementById(@PathVariable(value = "id") Long achievementId) {
+ Achievement achievement = achievementService.getAchievementById(achievementId);
+ return ResponseEntity.ok().body(achievement);
+ }
+
+ // 创建新成就
+ @PostMapping
+ public Achievement createAchievement(@Valid @RequestBody Achievement achievement) {
+ return achievementService.createAchievement(achievement);
+ }
+
+ // 更新成就
+ @PutMapping("/{id}")
+ public ResponseEntity updateAchievement(@PathVariable(value = "id") Long achievementId,
+ @Valid @RequestBody Achievement achievementDetails) {
+ Achievement updatedAchievement = achievementService.updateAchievement(achievementId, achievementDetails);
+ return ResponseEntity.ok(updatedAchievement);
+ }
+
+ // 删除成就
+ @DeleteMapping("/{id}")
+ public ResponseEntity deleteAchievement(@PathVariable(value = "id") Long achievementId) {
+ achievementService.deleteAchievement(achievementId);
+ return ResponseEntity.noContent().build();
+ }
+
+ // 根据类型获取成就
+ @GetMapping("/type/{type}")
+ public List getAchievementsByType(@PathVariable(value = "type") Achievement.AchievementType type) {
+ return achievementService.getAchievementsByType(type);
+ }
+
+ // 根据奖杯等级获取成就
+ @GetMapping("/trophy/{level}")
+ public List getAchievementsByTrophyLevel(@PathVariable(value = "level") Achievement.TrophyLevel level) {
+ return achievementService.getAchievementsByTrophyLevel(level);
+ }
+
+ // 获取已解锁成就
+ @GetMapping("/unlocked")
+ public List getUnlockedAchievements() {
+ return achievementService.getUnlockedAchievements();
+ }
+
+ // 获取未解锁成就
+ @GetMapping("/locked")
+ public List getLockedAchievements() {
+ return achievementService.getLockedAchievements();
+ }
+
+ // 解锁成就
+ @PutMapping("/{id}/unlock")
+ public ResponseEntity unlockAchievement(@PathVariable(value = "id") Long achievementId) {
+ Achievement unlockedAchievement = achievementService.unlockAchievement(achievementId);
+ return ResponseEntity.ok(unlockedAchievement);
+ }
+
+ // 更新成就进度
+ @PutMapping("/{id}/progress")
+ public ResponseEntity updateAchievementProgress(@PathVariable(value = "id") Long achievementId,
+ @RequestParam int progress) {
+ Achievement updatedAchievement = achievementService.updateAchievementProgress(achievementId, progress);
+ return ResponseEntity.ok(updatedAchievement);
+ }
+
+ // 根据用户ID获取成就
+ @GetMapping("/user/{userId}")
+ public List getAchievementsByUserId(@PathVariable(value = "userId") Long userId) {
+ return achievementService.getAchievementsByUserId(userId);
+ }
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/controller/UserSettingController.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/controller/UserSettingController.java
new file mode 100644
index 0000000..63a6308
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/controller/UserSettingController.java
@@ -0,0 +1,99 @@
+package com.gamecontrol.backend.controller;
+
+import com.gamecontrol.backend.entity.UserSetting;
+import com.gamecontrol.backend.service.UserSettingService;
+import jakarta.validation.Valid;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.*;
+
+@RestController
+@RequestMapping("/user-settings")
+public class UserSettingController {
+
+ @Autowired
+ private UserSettingService userSettingService;
+
+ // 根据ID获取用户设置
+ @GetMapping("/{id}")
+ public ResponseEntity getUserSettingById(@PathVariable(value = "id") Long userSettingId) {
+ UserSetting userSetting = userSettingService.getUserSettingById(userSettingId);
+ return ResponseEntity.ok().body(userSetting);
+ }
+
+ // 根据用户ID获取用户设置
+ @GetMapping("/user/{userId}")
+ public ResponseEntity getUserSettingByUserId(@PathVariable(value = "userId") Long userId) {
+ UserSetting userSetting = userSettingService.getUserSettingByUserId(userId);
+ return ResponseEntity.ok().body(userSetting);
+ }
+
+ // 创建新用户设置
+ @PostMapping
+ public UserSetting createUserSetting(@Valid @RequestBody UserSetting userSetting) {
+ return userSettingService.createUserSetting(userSetting);
+ }
+
+ // 更新用户设置
+ @PutMapping("/{id}")
+ public ResponseEntity updateUserSetting(@PathVariable(value = "id") Long userSettingId,
+ @Valid @RequestBody UserSetting userSettingDetails) {
+ UserSetting updatedUserSetting = userSettingService.updateUserSetting(userSettingId, userSettingDetails);
+ return ResponseEntity.ok(updatedUserSetting);
+ }
+
+ // 删除用户设置
+ @DeleteMapping("/{id}")
+ public ResponseEntity deleteUserSetting(@PathVariable(value = "id") Long userSettingId) {
+ userSettingService.deleteUserSetting(userSettingId);
+ return ResponseEntity.noContent().build();
+ }
+
+ // 更新字体大小
+ @PutMapping("/user/{userId}/font-size")
+ public ResponseEntity updateFontSize(@PathVariable(value = "userId") Long userId,
+ @RequestParam UserSetting.FontSize fontSize) {
+ UserSetting updatedUserSetting = userSettingService.updateFontSize(userId, fontSize);
+ return ResponseEntity.ok(updatedUserSetting);
+ }
+
+ // 更新分辨率
+ @PutMapping("/user/{userId}/resolution")
+ public ResponseEntity updateResolution(@PathVariable(value = "userId") Long userId,
+ @RequestParam String resolution) {
+ UserSetting updatedUserSetting = userSettingService.updateResolution(userId, resolution);
+ return ResponseEntity.ok(updatedUserSetting);
+ }
+
+ // 更新音效音量
+ @PutMapping("/user/{userId}/sound-volume")
+ public ResponseEntity updateSoundVolume(@PathVariable(value = "userId") Long userId,
+ @RequestParam int soundVolume) {
+ UserSetting updatedUserSetting = userSettingService.updateSoundVolume(userId, soundVolume);
+ return ResponseEntity.ok(updatedUserSetting);
+ }
+
+ // 更新音乐音量
+ @PutMapping("/user/{userId}/music-volume")
+ public ResponseEntity updateMusicVolume(@PathVariable(value = "userId") Long userId,
+ @RequestParam int musicVolume) {
+ UserSetting updatedUserSetting = userSettingService.updateMusicVolume(userId, musicVolume);
+ return ResponseEntity.ok(updatedUserSetting);
+ }
+
+ // 更新画面质量
+ @PutMapping("/user/{userId}/graphics-quality")
+ public ResponseEntity updateGraphicsQuality(@PathVariable(value = "userId") Long userId,
+ @RequestParam UserSetting.GraphicsQuality graphicsQuality) {
+ UserSetting updatedUserSetting = userSettingService.updateGraphicsQuality(userId, graphicsQuality);
+ return ResponseEntity.ok(updatedUserSetting);
+ }
+
+ // 更新全屏模式
+ @PutMapping("/user/{userId}/fullscreen")
+ public ResponseEntity updateFullscreen(@PathVariable(value = "userId") Long userId,
+ @RequestParam boolean fullscreen) {
+ UserSetting updatedUserSetting = userSettingService.updateFullscreen(userId, fullscreen);
+ return ResponseEntity.ok(updatedUserSetting);
+ }
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/entity/Achievement.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/entity/Achievement.java
new file mode 100644
index 0000000..7280b72
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/entity/Achievement.java
@@ -0,0 +1,59 @@
+package com.gamecontrol.backend.entity;
+
+import jakarta.persistence.*;
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.AllArgsConstructor;
+
+import java.time.LocalDateTime;
+
+@Entity
+@Table(name = "achievements")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class Achievement {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @NotBlank(message = "成就名称不能为空")
+ @Size(max = 50, message = "成就名称不能超过50个字符")
+ @Column(unique = true)
+ private String name;
+
+ @NotBlank(message = "成就描述不能为空")
+ @Size(max = 200, message = "成就描述不能超过200个字符")
+ private String description;
+
+ @NotNull(message = "成就类型不能为空")
+ @Enumerated(EnumType.STRING)
+ private AchievementType type;
+
+ @NotNull(message = "奖杯等级不能为空")
+ @Enumerated(EnumType.STRING)
+ private TrophyLevel trophyLevel;
+
+ @NotNull(message = "触发条件不能为空")
+ private String triggerCondition;
+
+ private int progress;
+ private int targetValue;
+
+ private boolean unlocked;
+ private LocalDateTime unlockedTime;
+
+ @Size(max = 100, message = "图标路径不能超过100个字符")
+ private String iconPath;
+
+ public enum AchievementType {
+ PROGRESS, CHALLENGE, EXPLORATION, COLLECTION, SPECIAL
+ }
+
+ public enum TrophyLevel {
+ BRONZE, SILVER, GOLD, PLATINUM
+ }
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/entity/UserSetting.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/entity/UserSetting.java
new file mode 100644
index 0000000..ae267b8
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/entity/UserSetting.java
@@ -0,0 +1,44 @@
+package com.gamecontrol.backend.entity;
+
+import jakarta.persistence.*;
+import jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.AllArgsConstructor;
+
+@Entity
+@Table(name = "user_settings")
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class UserSetting {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Long id;
+
+ @NotNull(message = "用户ID不能为空")
+ private Long userId;
+
+ @Enumerated(EnumType.STRING)
+ private FontSize fontSize;
+
+ @Size(max = 20, message = "分辨率不能超过20个字符")
+ private String resolution;
+
+ private int soundVolume;
+ private int musicVolume;
+
+ @Enumerated(EnumType.STRING)
+ private GraphicsQuality graphicsQuality;
+
+ private boolean fullscreen;
+
+ public enum FontSize {
+ SMALL, MEDIUM, LARGE, CUSTOM
+ }
+
+ public enum GraphicsQuality {
+ LOW, MEDIUM, HIGH, ULTRA
+ }
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/repository/AchievementRepository.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/repository/AchievementRepository.java
new file mode 100644
index 0000000..2731df9
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/repository/AchievementRepository.java
@@ -0,0 +1,23 @@
+package com.gamecontrol.backend.repository;
+
+import com.gamecontrol.backend.entity.Achievement;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+import org.springframework.stereotype.Repository;
+
+import java.util.List;
+
+@Repository
+public interface AchievementRepository extends JpaRepository {
+
+ List findByType(Achievement.AchievementType type);
+
+ List findByTrophyLevel(Achievement.TrophyLevel trophyLevel);
+
+ List findByUnlocked(boolean unlocked);
+
+ @Query("SELECT a FROM Achievement a WHERE a.progress >= a.targetValue AND a.unlocked = false")
+ List findUnlockedAchievements();
+
+ List findByUserId(Long userId);
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/repository/UserSettingRepository.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/repository/UserSettingRepository.java
new file mode 100644
index 0000000..7501c4f
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/repository/UserSettingRepository.java
@@ -0,0 +1,11 @@
+package com.gamecontrol.backend.repository;
+
+import com.gamecontrol.backend.entity.UserSetting;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.stereotype.Repository;
+
+@Repository
+public interface UserSettingRepository extends JpaRepository {
+
+ UserSetting findByUserId(Long userId);
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/AchievementService.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/AchievementService.java
new file mode 100644
index 0000000..666ae5d
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/AchievementService.java
@@ -0,0 +1,32 @@
+package com.gamecontrol.backend.service;
+
+import com.gamecontrol.backend.entity.Achievement;
+
+import java.util.List;
+
+public interface AchievementService {
+
+ List getAllAchievements();
+
+ Achievement getAchievementById(Long id);
+
+ Achievement createAchievement(Achievement achievement);
+
+ Achievement updateAchievement(Long id, Achievement achievement);
+
+ void deleteAchievement(Long id);
+
+ List getAchievementsByType(Achievement.AchievementType type);
+
+ List getAchievementsByTrophyLevel(Achievement.TrophyLevel trophyLevel);
+
+ List getUnlockedAchievements();
+
+ List getLockedAchievements();
+
+ Achievement unlockAchievement(Long id);
+
+ Achievement updateAchievementProgress(Long id, int progress);
+
+ List getAchievementsByUserId(Long userId);
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/UserSettingService.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/UserSettingService.java
new file mode 100644
index 0000000..41a7b2f
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/UserSettingService.java
@@ -0,0 +1,28 @@
+package com.gamecontrol.backend.service;
+
+import com.gamecontrol.backend.entity.UserSetting;
+
+public interface UserSettingService {
+
+ UserSetting getUserSettingById(Long id);
+
+ UserSetting getUserSettingByUserId(Long userId);
+
+ UserSetting createUserSetting(UserSetting userSetting);
+
+ UserSetting updateUserSetting(Long id, UserSetting userSetting);
+
+ void deleteUserSetting(Long id);
+
+ UserSetting updateFontSize(Long userId, UserSetting.FontSize fontSize);
+
+ UserSetting updateResolution(Long userId, String resolution);
+
+ UserSetting updateSoundVolume(Long userId, int soundVolume);
+
+ UserSetting updateMusicVolume(Long userId, int musicVolume);
+
+ UserSetting updateGraphicsQuality(Long userId, UserSetting.GraphicsQuality graphicsQuality);
+
+ UserSetting updateFullscreen(Long userId, boolean fullscreen);
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/impl/AchievementServiceImpl.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/impl/AchievementServiceImpl.java
new file mode 100644
index 0000000..d092eb5
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/impl/AchievementServiceImpl.java
@@ -0,0 +1,104 @@
+package com.gamecontrol.backend.service.impl;
+
+import com.gamecontrol.backend.entity.Achievement;
+import com.gamecontrol.backend.repository.AchievementRepository;
+import com.gamecontrol.backend.service.AchievementService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.Optional;
+
+@Service
+public class AchievementServiceImpl implements AchievementService {
+
+ @Autowired
+ private AchievementRepository achievementRepository;
+
+ @Override
+ public List getAllAchievements() {
+ return achievementRepository.findAll();
+ }
+
+ @Override
+ public Achievement getAchievementById(Long id) {
+ Optional achievement = achievementRepository.findById(id);
+ return achievement.orElseThrow(() -> new RuntimeException("Achievement not found with id: " + id));
+ }
+
+ @Override
+ public Achievement createAchievement(Achievement achievement) {
+ return achievementRepository.save(achievement);
+ }
+
+ @Override
+ public Achievement updateAchievement(Long id, Achievement achievementDetails) {
+ Achievement achievement = getAchievementById(id);
+ achievement.setName(achievementDetails.getName());
+ achievement.setDescription(achievementDetails.getDescription());
+ achievement.setType(achievementDetails.getType());
+ achievement.setTrophyLevel(achievementDetails.getTrophyLevel());
+ achievement.setTriggerCondition(achievementDetails.getTriggerCondition());
+ achievement.setProgress(achievementDetails.getProgress());
+ achievement.setTargetValue(achievementDetails.getTargetValue());
+ achievement.setUnlocked(achievementDetails.isUnlocked());
+ achievement.setUnlockedTime(achievementDetails.getUnlockedTime());
+ achievement.setIconPath(achievementDetails.getIconPath());
+ return achievementRepository.save(achievement);
+ }
+
+ @Override
+ public void deleteAchievement(Long id) {
+ Achievement achievement = getAchievementById(id);
+ achievementRepository.delete(achievement);
+ }
+
+ @Override
+ public List getAchievementsByType(Achievement.AchievementType type) {
+ return achievementRepository.findByType(type);
+ }
+
+ @Override
+ public List getAchievementsByTrophyLevel(Achievement.TrophyLevel trophyLevel) {
+ return achievementRepository.findByTrophyLevel(trophyLevel);
+ }
+
+ @Override
+ public List getUnlockedAchievements() {
+ return achievementRepository.findByUnlocked(true);
+ }
+
+ @Override
+ public List getLockedAchievements() {
+ return achievementRepository.findByUnlocked(false);
+ }
+
+ @Override
+ public Achievement unlockAchievement(Long id) {
+ Achievement achievement = getAchievementById(id);
+ if (!achievement.isUnlocked()) {
+ achievement.setUnlocked(true);
+ achievement.setUnlockedTime(LocalDateTime.now());
+ achievement.setProgress(achievement.getTargetValue());
+ return achievementRepository.save(achievement);
+ }
+ return achievement;
+ }
+
+ @Override
+ public Achievement updateAchievementProgress(Long id, int progress) {
+ Achievement achievement = getAchievementById(id);
+ achievement.setProgress(progress);
+ if (progress >= achievement.getTargetValue() && !achievement.isUnlocked()) {
+ achievement.setUnlocked(true);
+ achievement.setUnlockedTime(LocalDateTime.now());
+ }
+ return achievementRepository.save(achievement);
+ }
+
+ @Override
+ public List getAchievementsByUserId(Long userId) {
+ return achievementRepository.findByUserId(userId);
+ }
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/impl/UserSettingServiceImpl.java b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/impl/UserSettingServiceImpl.java
new file mode 100644
index 0000000..09bc8e5
--- /dev/null
+++ b/gamecontrol-backend/src/main/java/com/gamecontrol/backend/service/impl/UserSettingServiceImpl.java
@@ -0,0 +1,117 @@
+package com.gamecontrol.backend.service.impl;
+
+import com.gamecontrol.backend.entity.UserSetting;
+import com.gamecontrol.backend.repository.UserSettingRepository;
+import com.gamecontrol.backend.service.UserSettingService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.Optional;
+
+@Service
+public class UserSettingServiceImpl implements UserSettingService {
+
+ @Autowired
+ private UserSettingRepository userSettingRepository;
+
+ @Override
+ public UserSetting getUserSettingById(Long id) {
+ Optional userSetting = userSettingRepository.findById(id);
+ return userSetting.orElseThrow(() -> new RuntimeException("UserSetting not found with id: " + id));
+ }
+
+ @Override
+ public UserSetting getUserSettingByUserId(Long userId) {
+ return userSettingRepository.findByUserId(userId);
+ }
+
+ @Override
+ public UserSetting createUserSetting(UserSetting userSetting) {
+ return userSettingRepository.save(userSetting);
+ }
+
+ @Override
+ public UserSetting updateUserSetting(Long id, UserSetting userSettingDetails) {
+ UserSetting userSetting = getUserSettingById(id);
+ userSetting.setUserId(userSettingDetails.getUserId());
+ userSetting.setFontSize(userSettingDetails.getFontSize());
+ userSetting.setResolution(userSettingDetails.getResolution());
+ userSetting.setSoundVolume(userSettingDetails.getSoundVolume());
+ userSetting.setMusicVolume(userSettingDetails.getMusicVolume());
+ userSetting.setGraphicsQuality(userSettingDetails.getGraphicsQuality());
+ userSetting.setFullscreen(userSettingDetails.isFullscreen());
+ return userSettingRepository.save(userSetting);
+ }
+
+ @Override
+ public void deleteUserSetting(Long id) {
+ UserSetting userSetting = getUserSettingById(id);
+ userSettingRepository.delete(userSetting);
+ }
+
+ @Override
+ public UserSetting updateFontSize(Long userId, UserSetting.FontSize fontSize) {
+ UserSetting userSetting = getUserSettingByUserId(userId);
+ if (userSetting == null) {
+ userSetting = new UserSetting();
+ userSetting.setUserId(userId);
+ }
+ userSetting.setFontSize(fontSize);
+ return userSettingRepository.save(userSetting);
+ }
+
+ @Override
+ public UserSetting updateResolution(Long userId, String resolution) {
+ UserSetting userSetting = getUserSettingByUserId(userId);
+ if (userSetting == null) {
+ userSetting = new UserSetting();
+ userSetting.setUserId(userId);
+ }
+ userSetting.setResolution(resolution);
+ return userSettingRepository.save(userSetting);
+ }
+
+ @Override
+ public UserSetting updateSoundVolume(Long userId, int soundVolume) {
+ UserSetting userSetting = getUserSettingByUserId(userId);
+ if (userSetting == null) {
+ userSetting = new UserSetting();
+ userSetting.setUserId(userId);
+ }
+ userSetting.setSoundVolume(soundVolume);
+ return userSettingRepository.save(userSetting);
+ }
+
+ @Override
+ public UserSetting updateMusicVolume(Long userId, int musicVolume) {
+ UserSetting userSetting = getUserSettingByUserId(userId);
+ if (userSetting == null) {
+ userSetting = new UserSetting();
+ userSetting.setUserId(userId);
+ }
+ userSetting.setMusicVolume(musicVolume);
+ return userSettingRepository.save(userSetting);
+ }
+
+ @Override
+ public UserSetting updateGraphicsQuality(Long userId, UserSetting.GraphicsQuality graphicsQuality) {
+ UserSetting userSetting = getUserSettingByUserId(userId);
+ if (userSetting == null) {
+ userSetting = new UserSetting();
+ userSetting.setUserId(userId);
+ }
+ userSetting.setGraphicsQuality(graphicsQuality);
+ return userSettingRepository.save(userSetting);
+ }
+
+ @Override
+ public UserSetting updateFullscreen(Long userId, boolean fullscreen) {
+ UserSetting userSetting = getUserSettingByUserId(userId);
+ if (userSetting == null) {
+ userSetting = new UserSetting();
+ userSetting.setUserId(userId);
+ }
+ userSetting.setFullscreen(fullscreen);
+ return userSettingRepository.save(userSetting);
+ }
+}
\ No newline at end of file
diff --git a/gamecontrol-backend/src/main/resources/application.properties b/gamecontrol-backend/src/main/resources/application.properties
new file mode 100644
index 0000000..eea6a04
--- /dev/null
+++ b/gamecontrol-backend/src/main/resources/application.properties
@@ -0,0 +1,19 @@
+# Database configuration
+spring.datasource.url=jdbc:mysql://localhost:3306/gamecontrol?useSSL=false&serverTimezone=UTC&characterEncoding=utf8
+spring.datasource.username=root
+spring.datasource.password=123456
+spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
+
+# JPA configuration
+spring.jpa.hibernate.ddl-auto=update
+spring.jpa.show-sql=true
+spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
+
+# Server configuration
+server.port=8080
+server.servlet.context-path=/api
+
+# CORS configuration
+spring.web.cors.allowed-origins=*
+spring.web.cors.allowed-methods=GET,POST,PUT,DELETE,OPTIONS
+spring.web.cors.allowed-headers=*
\ No newline at end of file
diff --git a/gamecontrol-frontend/index.html b/gamecontrol-frontend/index.html
new file mode 100644
index 0000000..903b087
--- /dev/null
+++ b/gamecontrol-frontend/index.html
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+ 游戏控制页面系统
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/gamecontrol-frontend/package.json b/gamecontrol-frontend/package.json
new file mode 100644
index 0000000..cb70a58
--- /dev/null
+++ b/gamecontrol-frontend/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "gamecontrol-frontend",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite",
+ "build": "vite build",
+ "preview": "vite preview"
+ },
+ "dependencies": {
+ "vue": "^3.4.0",
+ "vue-router": "^4.2.5",
+ "pinia": "^2.1.7",
+ "matter-js": "^0.19.0",
+ "axios": "^1.6.2",
+ "bootstrap": "^5.3.2",
+ "bootstrap-icons": "^1.11.1"
+ },
+ "devDependencies": {
+ "@vitejs/plugin-vue": "^5.0.0",
+ "vite": "^5.0.0"
+ }
+}
\ No newline at end of file
diff --git a/gamecontrol-frontend/src/main.js b/gamecontrol-frontend/src/main.js
new file mode 100644
index 0000000..3d6d061
--- /dev/null
+++ b/gamecontrol-frontend/src/main.js
@@ -0,0 +1,17 @@
+import { createApp } from 'vue'
+import { createPinia } from 'pinia'
+import App from './App.vue'
+import router from './router'
+
+// 引入Bootstrap CSS
+import 'bootstrap/dist/css/bootstrap.min.css'
+// 引入Bootstrap JS
+import 'bootstrap/dist/js/bootstrap.bundle.min.js'
+
+const app = createApp(App)
+const pinia = createPinia()
+
+app.use(pinia)
+app.use(router)
+
+app.mount('#app')
\ No newline at end of file
diff --git a/gamecontrol-frontend/vite.config.js b/gamecontrol-frontend/vite.config.js
new file mode 100644
index 0000000..7778b37
--- /dev/null
+++ b/gamecontrol-frontend/vite.config.js
@@ -0,0 +1,17 @@
+import { defineConfig } from 'vite'
+import vue from '@vitejs/plugin-vue'
+
+// https://vitejs.dev/config/
+export default defineConfig({
+ plugins: [vue()],
+ server: {
+ port: 3000,
+ proxy: {
+ '/api': {
+ target: 'http://localhost:8080',
+ changeOrigin: true,
+ rewrite: (path) => path.replace(/^\/api/, '')
+ }
+ }
+ }
+})
\ No newline at end of file
diff --git a/ke b/ke
new file mode 100644
index 0000000..e69de29