Compare commits

...

3 Commits

Author SHA1 Message Date
7cc37b0523 fix(server): 修复物品发送接口返回结果处理
- 将物品发送请求的参数格式从 { role, item: [itemId, itemNum] } 修改为 { role, item: [[itemId, itemNum]] }
- 添加对返回结果的处理,根据 result.data.result 判断发送是否成功
- 成功时返回原来的成功消息,失败时返回失败消息和具体错误内容
2025-04-24 20:07:41 +08:00
7f1d475af9 fix(server): 修复物品发送接口的跨域问题
- 在角色路由中添加了自定义请求头,以解决跨域问题
- 移除了前端的多余日志输出
2025-04-24 19:34:32 +08:00
09302848c9 feat(server): 添加 GM 操作台物品发送功能
- 在 server 端添加了 /item/send 接口,用于发送物品到指定角色
- 在前端 HomeView 中增加了 GM 操作台功能,可以选定玩家角色名、物品和数量进行发送
- 引入了 body-parser 中间件用于解析请求体
- 优化了表单布局,增加了表单验证
2025-04-24 19:27:10 +08:00
4 changed files with 71 additions and 26 deletions

1
package-lock.json generated
View File

@@ -13,6 +13,7 @@
],
"dependencies": {
"axios": "^1.8.4",
"body-parser": "^2.2.0",
"dotenv": "^16.5.0",
"express": "^5.1.0",
"mysql": "^2.18.1",

View File

@@ -15,6 +15,7 @@
"license": "ISC",
"dependencies": {
"axios": "^1.8.4",
"body-parser": "^2.2.0",
"dotenv": "^16.5.0",
"express": "^5.1.0",
"mysql": "^2.18.1",

View File

@@ -1,8 +1,13 @@
const express = require("express");
const bodyParser = require("body-parser"); // 添加 body-parser 中间件
const { getConnection, query } = require("../utils/db.util");
const axios = require("axios");
const router = express.Router();
// 添加 body-parser 中间件
router.use(bodyParser.json());
// 获取角色列表
router.get("/roles", async (req, res) => {
try {
@@ -16,6 +21,37 @@ router.get("/roles", async (req, res) => {
}
});
router.post("/item/send", async (req, res) => {
try {
const { roleName, itemId, itemNum = 1 } = req.body;
if (!roleName || !itemId) res.json({ code: 1, msg: "缺少必要参数" });
const roleId = await query(`SELECT id FROM role where name = '${roleName}' limit 1`);
if (roleId?.length != 1) res.json({ code: 1, msg: "没有找到角色" });
const role = roleId[0].id;
const result = await axios.post(
"http://192.168.25.110:19000/center/gm",
{ role, item: [[itemId, itemNum]] },
{
headers: {
Accept: "application/json, text/plain, */*",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6",
Connection: "keep-alive",
"Content-Type": "application/json",
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1 Edg/121.0.0.0",
"Accept-Encoding": "gzip",
"X-Mgip-sign": "gzip",
},
}
);
console.log("物品[%s]发送给[%s]结果:%s", itemId, roleName, result.data);
if (result.data.result) res.json({ code: 0, msg: "发送成功!" });
else res.json({ code: 1, msg: result.data.content });
} catch (error) {
console.error("获取角色数据失败:", error);
res.status(500).json({ error: "获取角色数据失败" });
}
});
// 获取充值列表
router.get("/recharges", async (req, res) => {
try {

View File

@@ -3,12 +3,15 @@ import { ref, onMounted } from 'vue'
import axios from 'axios'
import itemList from "@/assets/items.json"
import dayjs from 'dayjs'
import { ElMessage } from 'element-plus'
// 第一个卡片:表单数据
const gmFormRef = ref()
const form = ref({
playerName: '',
item: '',
itemNum: '',
recharge: ''
})
const items = ref(itemList)
@@ -53,8 +56,15 @@ onMounted(() => {
})
// 提交表单
const submitForm = () => {
console.log('提交表单:', form.value)
const submitForm = (formEl) => {
formEl.validate().then(async () => {
const params = form.value
const res = await axios.post("/api/item/send", { roleName: params.playerName, itemId: params.item, itemNum: params.itemNum })
const result = res?.data
if (res.data.code == 0) ElMessage.success(result.msg)
else ElMessage.error(result.msg)
})
}
</script>
@@ -65,31 +75,27 @@ const submitForm = () => {
<template #header>
<div class="card-header">
<span>GM操作台</span>
<el-button type="primary" @click="submitForm">提交</el-button>
<el-button type="primary" @click="submitForm(gmFormRef)">提交</el-button>
</div>
</template>
<el-form :model="form" label-width="100px">
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="玩家角色名">
<el-input v-model="form.playerName" placeholder="请输入玩家角色名"></el-input>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="物品道具">
<el-select-v2 v-model="form.item" placeholder="请选择物品" :options="items"
:props="{ label: 'name', value: 'resId' }" filterable />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="充值">
<el-select v-model="form.recharge" placeholder="请选择充值">
<el-option v-for="recharge in recharges" :key="recharge" :label="recharge"
:value="recharge"></el-option>
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-form ref="gmFormRef" :model="form" label-width="100px">
<div class="grid grid-cols-2">
<el-form-item label="玩家角色名" prop="playerName" required>
<el-input v-model="form.playerName" placeholder="请输入玩家角色名"></el-input>
</el-form-item>
<el-form-item label="物品道具" prop="item">
<el-select-v2 v-model="form.item" placeholder="请选择物品" :options="items"
:props="{ label: 'name', value: 'resId' }" filterable />
</el-form-item>
<el-form-item label="物品数量" prop="itemNum">
<el-input type="number" v-model="form.itemNum" placeholder="请输入发送的物品数量"></el-input>
</el-form-item>
<el-form-item label="充值" prop="recharges">
<el-select v-model="form.recharge" placeholder="请选择充值">
<el-option v-for="recharge in recharges" :key="recharge" :label="recharge" :value="recharge"></el-option>
</el-select>
</el-form-item>
</div>
</el-form>
</el-card>
@@ -98,7 +104,8 @@ const submitForm = () => {
<template #header>
<div class="card-header">
<span>角色列表</span>
<el-input style="width: 240px;" v-model="roleSearch" placeholder="请输入角色名称或ID" @change="fetchRoleList" clearable />
<el-input style="width: 240px;" v-model="roleSearch" placeholder="请输入角色名称或ID" @change="fetchRoleList"
clearable />
</div>
</template>
<el-table :data="roleList" style="width: 100%" border height="400">