feat: 我的鱼篓/一键处理/出售鱼
This commit is contained in:
+3
-1
@@ -11,8 +11,10 @@
|
||||
"dependencies": {
|
||||
"axios": "^1.8.4",
|
||||
"element-plus": "^2.9.7",
|
||||
"tsparticles": "^3.8.1",
|
||||
"vue": "^3.5.13",
|
||||
"vue-router": "^4.5.0"
|
||||
"vue-router": "^4.5.0",
|
||||
"vue3-particles": "^2.12.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@vitejs/plugin-vue": "^5.2.1",
|
||||
|
||||
@@ -6,4 +6,25 @@ import request from '@/utils/request'
|
||||
*/
|
||||
export function myFishBaskets () {
|
||||
return request.get('/Fishing/all-fish')
|
||||
}
|
||||
|
||||
/**
|
||||
* 出售鱼
|
||||
*/
|
||||
export function sellFish (data) {
|
||||
return request.post('/Trade/sell', data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理指定鱼
|
||||
*/
|
||||
export function handleFishById (fishId) {
|
||||
return request.post(`/Trade/handle/${fishId}`)
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动处理鱼
|
||||
*/
|
||||
export function autoHandleFish () {
|
||||
return request.post(`/Trade/auto-handle`)
|
||||
}
|
||||
+2
-2
@@ -3,11 +3,11 @@ import App from './App.vue'
|
||||
import router from './router'
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
|
||||
import Particles from "vue3-particles"
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(router)
|
||||
app.use(ElementPlus)
|
||||
|
||||
app.use(Particles)
|
||||
app.mount('#app')
|
||||
|
||||
|
||||
@@ -1,36 +1,50 @@
|
||||
<!--
|
||||
* @Descripttion:
|
||||
* @version: 1.0.0
|
||||
* @Author: LyMy
|
||||
* @Date: 2025-04-11 16:33:21
|
||||
* @LastEditors: LyMy
|
||||
* @LastEditTime: 2025-04-11 18:31:55
|
||||
* @FilePath: \go_fish_web\src\pages\fishbaskets\Fishbaskets.vue
|
||||
-->
|
||||
<template>
|
||||
<div class="equipments-page">
|
||||
<h1>🎣 我的鱼篓</h1>
|
||||
<el-table :data="fishList" style="width: 100%;height: calc(100vh - 240px);" border>
|
||||
<el-table-column prop="name" label="鱼名" />
|
||||
<el-table-column prop="weight" label="重量" align="right"/>
|
||||
|
||||
<!-- 处理按钮 -->
|
||||
<div style="text-align: right; margin-bottom: 20px;">
|
||||
<el-button type="primary" @click="fetchFishList">刷新</el-button>
|
||||
<el-button type="primary" @click="handleProcessFish">一键处理鱼</el-button>
|
||||
|
||||
</div>
|
||||
|
||||
<el-tabs v-model="activeTab" type="card">
|
||||
<el-tab-pane label="所有鱼" name="all" />
|
||||
<el-tab-pane label="普通鱼" name="ordinary" />
|
||||
<el-tab-pane label="稀有鱼" name="rare" />
|
||||
</el-tabs>
|
||||
|
||||
<el-table :data="filteredFish" style="width: 100%;height:(100vh-200px)" border>
|
||||
<el-table-column prop="id" label="id" align="center" width="100" />
|
||||
<el-table-column prop="name" label="鱼名" align="center" width="200" />
|
||||
<el-table-column prop="weight" label="重量" align="right" width="150" />
|
||||
<el-table-column prop="description" label="描述" />
|
||||
<el-table-column label="是否稀有" align="center">
|
||||
<el-table-column label="是否稀有" align="center" width="150">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.isRare ? 'danger' : 'info'">
|
||||
{{ row.isRare ? '稀有' : '普通' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<!-- 出售按钮 -->
|
||||
<el-table-column label="操作" align="center" width="180">
|
||||
<template #default="{ row }">
|
||||
<el-button v-if="row.isRare" type="danger" @click="handleSell(row)">出售</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ref, onMounted, computed } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { myFishBaskets } from '@/api/fishbaskets/fishbaskets'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { myFishBaskets, handleFishById, sellFish, autoHandleFish } from '@/api/fishbaskets/fishbaskets' // 添加 sellFish 接口
|
||||
import { ElMessage, ElInput, ElMessageBox } from 'element-plus'
|
||||
|
||||
const activeTab = ref('all')
|
||||
const fishList = ref([])
|
||||
const router = useRouter()
|
||||
|
||||
@@ -38,15 +52,64 @@ const fetchFishList = async () => {
|
||||
try {
|
||||
const res = await myFishBaskets()
|
||||
if (res) {
|
||||
fishList.value = res
|
||||
fishList.value = res;
|
||||
ElMessage.success('鱼篓数据加载成功')
|
||||
}
|
||||
} catch (err) {
|
||||
ElMessage.warning('请检查网络或重试')
|
||||
}
|
||||
}
|
||||
|
||||
const goHome = () => {
|
||||
router.push('/')
|
||||
// 根据选中的标签筛选数据
|
||||
const filteredFish = computed(() => {
|
||||
switch (activeTab.value) {
|
||||
case 'all':
|
||||
return fishList.value;
|
||||
case 'ordinary':
|
||||
return fishList.value.filter(f => !f.isRare);
|
||||
case 'rare':
|
||||
return fishList.value.filter(f => f.isRare);
|
||||
}
|
||||
})
|
||||
|
||||
// 一键处理鱼的接口调用
|
||||
const handleProcessFish = async () => {
|
||||
try {
|
||||
const res = await autoHandleFish()
|
||||
if (res) {
|
||||
ElMessage.success(res)
|
||||
fetchFishList()
|
||||
}
|
||||
} catch (err) {
|
||||
console.log('====================================');
|
||||
console.log(err);
|
||||
console.log('====================================');
|
||||
ElMessage.warning('处理失败,请稍后再试')
|
||||
}
|
||||
}
|
||||
|
||||
// 处理出售操作
|
||||
const handleSell = async (fish) => {
|
||||
const { value: price } = await ElMessageBox.prompt('请输入出售价格', `出售鱼 (${fish.name})` , {
|
||||
confirmButtonText: '确认',
|
||||
cancelButtonText: '取消',
|
||||
inputPattern: /^\d+(\.\d{1,2})?$/,
|
||||
inputErrorMessage: '请输入合法的价格'
|
||||
})
|
||||
|
||||
if (price) {
|
||||
try {
|
||||
const res = await sellFish({ FishBagId: fish.id, Points: price })
|
||||
if (res.success) {
|
||||
ElMessage.success(res.message)
|
||||
fetchFishList()
|
||||
} else {
|
||||
ElMessage.error('出售失败 ' + res.message);
|
||||
}
|
||||
} catch (err) {
|
||||
ElMessage.error('出售失败,请稍后再试')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@@ -64,4 +127,4 @@ onMounted(() => {
|
||||
margin-top: 20px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
<div class="equipments-page">
|
||||
<h1>钓鱼</h1>
|
||||
|
||||
<el-button type="primary" @click="handleFish">开始钓鱼</el-button>
|
||||
<el-button @click="goHome" style="margin-left: 10px">返回</el-button>
|
||||
<div style="margin-top: 200px;">
|
||||
<el-button type="primary" @click="handleFish">开始钓鱼</el-button>
|
||||
<el-button @click="goHome" style="margin-left: 10px">返回</el-button>
|
||||
|
||||
<div class="result" v-if="resultMessage">
|
||||
<p>{{ resultMessage }}</p>
|
||||
<p v-if="nextPullTime">下次可钓鱼时间:{{ nextPullTime }}</p>
|
||||
<div class="result" v-if="resultMessage">
|
||||
<p>{{ resultMessage }}</p>
|
||||
<p v-if="nextPullTime">下次可钓鱼时间:{{ nextPullTime }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -38,6 +40,7 @@ const handleFish = async () => {
|
||||
ElMessage.warning('什么也没钓到,下次好运 🍀')
|
||||
}
|
||||
} else {
|
||||
nextPullTime.value = res.message
|
||||
ElMessage.error(res.message || '钓鱼失败')
|
||||
}
|
||||
} catch (err) {
|
||||
|
||||
+106
-34
@@ -1,26 +1,21 @@
|
||||
<!--
|
||||
* @Descripttion:
|
||||
* @version: 1.0.0
|
||||
* @Author: LyMy
|
||||
* @Date: 2025-04-11 16:51:41
|
||||
* @LastEditors: LyMy
|
||||
* @LastEditTime: 2025-04-11 18:21:25
|
||||
* @FilePath: \go_fish_web\src\pages\main\Home.vue
|
||||
-->
|
||||
<template>
|
||||
<div class="home-page">
|
||||
<h1>欢迎来到钓鱼游戏</h1>
|
||||
<!-- 粒子背景 -->
|
||||
<Particles id="tsparticles" :options="particlesOptions" />
|
||||
|
||||
<!-- 菜单栏 -->
|
||||
<div class="menu">
|
||||
<ul>
|
||||
<li @click="navigateTo('equipments')">查看装备</li>
|
||||
<li @click="navigateTo('fishing')">拉竿</li>
|
||||
<li @click="navigateTo('fishbaskets')">查看鱼篓</li>
|
||||
<li @click="navigateTo('shop')">商店</li>
|
||||
<li @click="navigateTo('market')">市场</li>
|
||||
<li @click="navigateTo('ranking')">排名系统</li>
|
||||
</ul>
|
||||
<!-- 页面内容 -->
|
||||
<div class="content">
|
||||
<h1 class="title">欢迎来到钓鱼大冒险</h1>
|
||||
|
||||
<el-card class="menu-card">
|
||||
<el-row :gutter="20" justify="center">
|
||||
<el-col :span="8" v-for="item in menuItems" :key="item.name">
|
||||
<el-button type="primary" size="large" class="menu-btn" @click="navigateTo(item.route)" plain>
|
||||
{{ item.label }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -30,30 +25,107 @@ import { useRouter } from 'vue-router'
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
// 跳转函数
|
||||
const menuItems = [
|
||||
{ label: '🎒 查看装备', route: 'equipments' },
|
||||
{ label: '🎣 拉竿钓鱼', route: 'fishing' },
|
||||
{ label: '🐟 查看鱼篓', route: 'fishbaskets' },
|
||||
{ label: '🛒 商店售卖', route: 'shop' },
|
||||
{ label: '💰 市场信息', route: 'market' },
|
||||
{ label: '🏆 游戏排名', route: 'ranking' }
|
||||
]
|
||||
|
||||
const navigateTo = (page) => {
|
||||
router.push({ name: page })
|
||||
}
|
||||
|
||||
const particlesOptions = {
|
||||
background: {
|
||||
color: { value: "#001f3f" }
|
||||
},
|
||||
particles: {
|
||||
number: { value: 40, density: { enable: true, area: 800 } },
|
||||
color: { value: "#00d9ff" },
|
||||
shape: { type: "circle" },
|
||||
opacity: {
|
||||
value: 0.7,
|
||||
random: true,
|
||||
anim: {
|
||||
enable: true,
|
||||
speed: 0.5,
|
||||
opacity_min: 0.3,
|
||||
sync: false
|
||||
}
|
||||
},
|
||||
size: {
|
||||
value: 6,
|
||||
random: true,
|
||||
anim: {
|
||||
enable: true,
|
||||
speed: 2,
|
||||
size_min: 0.3,
|
||||
sync: false
|
||||
}
|
||||
},
|
||||
move: {
|
||||
enable: true,
|
||||
speed: 1.5,
|
||||
direction: "top",
|
||||
outModes: { default: "out" }
|
||||
}
|
||||
},
|
||||
interactivity: {
|
||||
events: {
|
||||
onHover: { enable: true, mode: "bubble" },
|
||||
resize: true
|
||||
},
|
||||
modes: {
|
||||
bubble: {
|
||||
distance: 150,
|
||||
size: 12,
|
||||
duration: 2,
|
||||
opacity: 1,
|
||||
speed: 3
|
||||
}
|
||||
}
|
||||
},
|
||||
detectRetina: true
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.home-page {
|
||||
position: relative;
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
#tsparticles {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
}
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
max-width: 800px;
|
||||
margin: 60px auto;
|
||||
text-align: center;
|
||||
}
|
||||
.menu {
|
||||
margin-top: 20px;
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
font-weight: bold;
|
||||
margin-bottom: 30px;
|
||||
color: #ffffff;
|
||||
}
|
||||
.menu ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
.menu-card {
|
||||
background-color: rgba(255, 255, 255, 0.85);
|
||||
border-radius: 12px;
|
||||
}
|
||||
.menu li {
|
||||
margin: 10px 0;
|
||||
cursor: pointer;
|
||||
font-size: 18px;
|
||||
color: #007bff;
|
||||
}
|
||||
.menu li:hover {
|
||||
text-decoration: underline;
|
||||
.menu-btn {
|
||||
width: 100%;
|
||||
margin-bottom: 15px;
|
||||
font-size: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
+32
-19
@@ -1,41 +1,54 @@
|
||||
/*
|
||||
* @Descripttion:
|
||||
* @Descripttion:
|
||||
* @version: 1.0.0
|
||||
* @Author: LyMy
|
||||
* @Date: 2025-04-11 15:56:12
|
||||
* @LastEditors: LyMy
|
||||
* @LastEditTime: 2025-04-11 16:19:14
|
||||
* @FilePath: \fish_game\src\utils\request.js
|
||||
* @LastEditTime: 2025-04-11 20:26:22
|
||||
* @FilePath: \go_fish_web\src\utils\request.js
|
||||
*/
|
||||
import axios from 'axios'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import router from '@/router'
|
||||
|
||||
// 创建 axios 实例
|
||||
const request = axios.create({
|
||||
baseURL: 'http://49.235.165.171:31001', // 你的基础地址
|
||||
timeout: 5000
|
||||
baseURL: 'http://49.235.165.171:31001',
|
||||
timeout: 5000,
|
||||
})
|
||||
|
||||
// 设置默认 Content-Type
|
||||
request.defaults.headers['Content-Type'] = 'application/json'
|
||||
|
||||
// 请求拦截器
|
||||
// 请求拦截器:添加 token
|
||||
request.interceptors.request.use(
|
||||
config => {
|
||||
const token = localStorage.getItem('token')
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
return config
|
||||
},
|
||||
error => Promise.reject(error)
|
||||
(config) => {
|
||||
const token = localStorage.getItem('token')
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
return config
|
||||
},
|
||||
(error) => Promise.reject(error)
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
// 响应拦截器:统一处理错误
|
||||
request.interceptors.response.use(
|
||||
response => response.data,
|
||||
error => {
|
||||
console.error('接口请求错误:', error)
|
||||
return Promise.reject(error)
|
||||
(response) => response.data,
|
||||
(error) => {
|
||||
const status = error.response?.status
|
||||
|
||||
if (status === 401) {
|
||||
// token 失效
|
||||
ElMessage.warning('登录已过期,请重新登录')
|
||||
localStorage.removeItem('token')
|
||||
router.push('/login')
|
||||
} else {
|
||||
ElMessage.error(error.response?.data?.message || '请求失败,请稍后再试')
|
||||
}
|
||||
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
export default request
|
||||
|
||||
Reference in New Issue
Block a user