diff --git a/src/main/java/xuan/controller/CoinConsumeController.java b/src/main/java/xuan/controller/CoinConsumeController.java new file mode 100644 index 0000000..5171de7 --- /dev/null +++ b/src/main/java/xuan/controller/CoinConsumeController.java @@ -0,0 +1,88 @@ +package xuan.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.web.bind.annotation.*; +import xuan.entity.CoinConsumeRecord; +import xuan.service.CoinConsumeRecordService; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/api/coin-consume") +public class CoinConsumeController { + + @Autowired + private CoinConsumeRecordService recordService; + + @PostMapping("/save") + public Map saveRecord(@RequestBody CoinConsumeRecord record) { + Map result = new HashMap<>(); + try { + CoinConsumeRecord saved = recordService.saveRecord(record); + result.put("success", true); + result.put("data", saved); + } catch (Exception e) { + result.put("success", false); + result.put("error", e.getMessage()); + } + return result; + } + + @GetMapping("/list") + public Map getRecords( + @RequestParam String userId, + @RequestParam(defaultValue = "1") int page, + @RequestParam(defaultValue = "10") int size) { + Map result = new HashMap<>(); + try { + Page pageResult = recordService.findByUserId(userId, page, size); + + Map data = new HashMap<>(); + data.put("records", pageResult.getContent()); + data.put("total", pageResult.getTotalElements()); + data.put("page", page); + data.put("size", size); + data.put("totalPages", pageResult.getTotalPages()); + + result.put("success", true); + result.put("data", data); + } catch (Exception e) { + result.put("success", false); + result.put("error", e.getMessage()); + } + return result; + } + + @GetMapping("/all") + public Map getAllRecords(@RequestParam String userId) { + Map result = new HashMap<>(); + try { + List records = recordService.findByUserId(userId); + result.put("success", true); + result.put("data", records); + } catch (Exception e) { + result.put("success", false); + result.put("error", e.getMessage()); + } + return result; + } + + @GetMapping("/type") + public Map getRecordsByType( + @RequestParam String userId, + @RequestParam String type) { + Map result = new HashMap<>(); + try { + List records = recordService.findByUserIdAndType(userId, type); + result.put("success", true); + result.put("data", records); + } catch (Exception e) { + result.put("success", false); + result.put("error", e.getMessage()); + } + return result; + } +} diff --git a/src/main/java/xuan/entity/CoinConsumeRecord.java b/src/main/java/xuan/entity/CoinConsumeRecord.java new file mode 100644 index 0000000..6eab598 --- /dev/null +++ b/src/main/java/xuan/entity/CoinConsumeRecord.java @@ -0,0 +1,55 @@ +package xuan.entity; + +import javax.persistence.*; +import java.time.LocalDateTime; + +@Entity +@Table(name = "coin_consume_record") +public class CoinConsumeRecord { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String userId; + + @Column(nullable = false) + private Integer amount; + + @Column(nullable = false) + private String type; + + private String description; + + private String relatedId; + + @Column(nullable = false, updatable = false) + private LocalDateTime createTime; + + @PrePersist + protected void onCreate() { + createTime = LocalDateTime.now(); + } + + public Long getId() { return id; } + public void setId(Long id) { this.id = id; } + + public String getUserId() { return userId; } + public void setUserId(String userId) { this.userId = userId; } + + public Integer getAmount() { return amount; } + public void setAmount(Integer amount) { this.amount = amount; } + + public String getType() { return type; } + public void setType(String type) { this.type = type; } + + public String getDescription() { return description; } + public void setDescription(String description) { this.description = description; } + + public String getRelatedId() { return relatedId; } + public void setRelatedId(String relatedId) { this.relatedId = relatedId; } + + public LocalDateTime getCreateTime() { return createTime; } + public void setCreateTime(LocalDateTime createTime) { this.createTime = createTime; } +} diff --git a/src/main/java/xuan/repository/CoinConsumeRecordRepository.java b/src/main/java/xuan/repository/CoinConsumeRecordRepository.java new file mode 100644 index 0000000..f06d21d --- /dev/null +++ b/src/main/java/xuan/repository/CoinConsumeRecordRepository.java @@ -0,0 +1,19 @@ +package xuan.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import xuan.entity.CoinConsumeRecord; + +import java.util.List; + +@Repository +public interface CoinConsumeRecordRepository extends JpaRepository { + + List findByUserIdOrderByCreateTimeDesc(String userId); + + Page findByUserIdOrderByCreateTimeDesc(String userId, Pageable pageable); + + List findByUserIdAndTypeOrderByCreateTimeDesc(String userId, String type); +} diff --git a/src/main/java/xuan/service/CoinConsumeRecordService.java b/src/main/java/xuan/service/CoinConsumeRecordService.java new file mode 100644 index 0000000..54ef1dd --- /dev/null +++ b/src/main/java/xuan/service/CoinConsumeRecordService.java @@ -0,0 +1,53 @@ +package xuan.service; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import xuan.entity.CoinConsumeRecord; +import xuan.repository.CoinConsumeRecordRepository; + +import java.util.List; +import java.util.Optional; + +@Service +public class CoinConsumeRecordService { + + @Autowired + private CoinConsumeRecordRepository recordRepository; + + @Transactional + public CoinConsumeRecord saveRecord(CoinConsumeRecord record) { + return recordRepository.save(record); + } + + public Optional findById(Long id) { + return recordRepository.findById(id); + } + + public List findByUserId(String userId) { + return recordRepository.findByUserIdOrderByCreateTimeDesc(userId); + } + + public Page findByUserId(String userId, int page, int size) { + Pageable pageable = PageRequest.of(page - 1, size); + return recordRepository.findByUserIdOrderByCreateTimeDesc(userId, pageable); + } + + public List findByUserIdAndType(String userId, String type) { + return recordRepository.findByUserIdAndTypeOrderByCreateTimeDesc(userId, type); + } + + @Transactional + public void deleteById(Long id) { + recordRepository.deleteById(id); + } + + @Transactional + public void deleteByUserId(String userId) { + List records = recordRepository.findByUserIdOrderByCreateTimeDesc(userId); + recordRepository.deleteAll(records); + } +} diff --git a/xuan-deduct-uniapp/src/pages/mine/consume-details.vue b/xuan-deduct-uniapp/src/pages/mine/consume-details.vue new file mode 100644 index 0000000..0963147 --- /dev/null +++ b/xuan-deduct-uniapp/src/pages/mine/consume-details.vue @@ -0,0 +1,382 @@ + + + + + diff --git a/xuan-deduct-uniapp/src/pages/mine/mine.vue b/xuan-deduct-uniapp/src/pages/mine/mine.vue index e55e796..8191a48 100644 --- a/xuan-deduct-uniapp/src/pages/mine/mine.vue +++ b/xuan-deduct-uniapp/src/pages/mine/mine.vue @@ -68,6 +68,7 @@ export default { menus: [ { name: '开通会员', icon: '👑', path: '/pages/mine/vip' }, { name: '金币任务', icon: '🪙', path: '/pages/mine/coins' }, + { name: '消费详情', icon: '💰', path: '/pages/mine/consume-details' }, { name: '推荐好友', icon: '🎁', action: 'share' }, { name: '设置', icon: '⚙️', path: '/pages/mine/settings' }, { name: '帮助与反馈', icon: '💬', path: '/pages/mine/feedback' }, diff --git a/xuan-deduct-uniapp/src/utils/api.js b/xuan-deduct-uniapp/src/utils/api.js index c977939..3e1d1e5 100644 --- a/xuan-deduct-uniapp/src/utils/api.js +++ b/xuan-deduct-uniapp/src/utils/api.js @@ -297,26 +297,36 @@ const toolApi = { method: 'POST', data: data }) - }, - xingzuo: (data) => { + } +} + +const coinConsumeApi = { + save: (data) => { return request({ - url: '/tools/xingzuo', + url: '/coin-consume/save', method: 'POST', data: data }) }, - wuxing: (data) => { + getRecords: (params) => { return request({ - url: '/tools/wuxing', - method: 'POST', - data: data + url: '/coin-consume/list', + method: 'GET', + data: params }) }, - jiri: (data) => { + getAll: (userId) => { return request({ - url: '/tools/jiri', - method: 'POST', - data: data + url: '/coin-consume/all', + method: 'GET', + data: { userId: userId || 'default_user' } + }) + }, + getByType: (userId, type) => { + return request({ + url: '/coin-consume/type', + method: 'GET', + data: { userId: userId || 'default_user', type: type } }) } } @@ -371,5 +381,6 @@ export default { recordApi, shareApi, toolApi, + coinConsumeApi, userApi } diff --git a/xuan-deduct-uniapp/src/utils/coinUtils.js b/xuan-deduct-uniapp/src/utils/coinUtils.js index 9fd9a36..0bd6d23 100644 --- a/xuan-deduct-uniapp/src/utils/coinUtils.js +++ b/xuan-deduct-uniapp/src/utils/coinUtils.js @@ -32,7 +32,7 @@ const checkCoinsAndConsume = () => { return { canUse: true, needCoins: false } } -const consumeCoin = async () => { +const consumeCoin = async (type = 'bazi', description = '测算消费', relatedId = null) => { const vipLevel = uni.getStorageSync('vipLevel') || 0 if (vipLevel > 0) { return @@ -53,6 +53,15 @@ const consumeCoin = async () => { if (userInfoStr) { const userInfo = JSON.parse(userInfoStr) await api.userApi.updateCoins(userInfo.userId, coins) + + const recordData = { + userId: userInfo.userId, + amount: 1, + type: type, + description: description, + relatedId: relatedId + } + await api.coinConsumeApi.save(recordData) } } catch (e) { console.error('更新金币失败:', e)