Compare commits
	
		
			5 Commits
		
	
	
		
			278684d3ff
			...
			master
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 34cebffd0c | |||
| 7cc37b0523 | |||
| 7f1d475af9 | |||
| 09302848c9 | |||
| 26bd2029e7 | 
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -13,6 +13,7 @@ | |||||||
|       ], |       ], | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "axios": "^1.8.4", |         "axios": "^1.8.4", | ||||||
|  |         "body-parser": "^2.2.0", | ||||||
|         "dotenv": "^16.5.0", |         "dotenv": "^16.5.0", | ||||||
|         "express": "^5.1.0", |         "express": "^5.1.0", | ||||||
|         "mysql": "^2.18.1", |         "mysql": "^2.18.1", | ||||||
| @@ -4755,6 +4756,7 @@ | |||||||
|     "web": { |     "web": { | ||||||
|       "version": "0.0.0", |       "version": "0.0.0", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|  |         "dayjs": "^1.11.13", | ||||||
|         "element-plus": "^2.9.8", |         "element-plus": "^2.9.8", | ||||||
|         "vue": "^3.5.13", |         "vue": "^3.5.13", | ||||||
|         "vue-router": "^4.5.0" |         "vue-router": "^4.5.0" | ||||||
|   | |||||||
| @@ -15,6 +15,7 @@ | |||||||
|   "license": "ISC", |   "license": "ISC", | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "axios": "^1.8.4", |     "axios": "^1.8.4", | ||||||
|  |     "body-parser": "^2.2.0", | ||||||
|     "dotenv": "^16.5.0", |     "dotenv": "^16.5.0", | ||||||
|     "express": "^5.1.0", |     "express": "^5.1.0", | ||||||
|     "mysql": "^2.18.1", |     "mysql": "^2.18.1", | ||||||
|   | |||||||
| @@ -1,30 +1,67 @@ | |||||||
| const express = require('express'); | const express = require("express"); | ||||||
| const { getConnection, query } = require('../utils/db.util'); | const bodyParser = require("body-parser"); // 添加 body-parser 中间件 | ||||||
|  | const { getConnection, query } = require("../utils/db.util"); | ||||||
|  | const axios = require("axios"); | ||||||
|  |  | ||||||
| const router = express.Router(); | const router = express.Router(); | ||||||
|  |  | ||||||
|  | // 添加 body-parser 中间件 | ||||||
|  | router.use(bodyParser.json()); | ||||||
|  |  | ||||||
| // 获取角色列表 | // 获取角色列表 | ||||||
| router.get('/roles', async (req, res) => { | router.get("/roles", async (req, res) => { | ||||||
|     try { |   try { | ||||||
|         const connection = await getConnection(); |     const { search = "" } = req.query; | ||||||
|         const results = await query('SELECT * FROM role', [], connection); |     const connection = await getConnection(); | ||||||
|         res.json(results); |     const results = await query(`SELECT * FROM role where name like '%${search}%'`, [], connection); | ||||||
|     } catch (error) { |     res.json(results); | ||||||
|         console.error('获取角色数据失败:', error); |   } catch (error) { | ||||||
|         res.status(500).json({ error: '获取角色数据失败' }); |     console.error("获取角色数据失败:", error); | ||||||
|     } |     res.status(500).json({ error: "获取角色数据失败" }); | ||||||
|  |   } | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | 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 == "成功") 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) => { | router.get("/recharges", async (req, res) => { | ||||||
|     try { |   try { | ||||||
|         const connection = await getConnection(); |     const connection = await getConnection(); | ||||||
|         const results = await query('SELECT * FROM recharge', [], connection); |     const results = await query("SELECT * FROM recharge", [], connection); | ||||||
|         res.json(results); |     res.json(results); | ||||||
|     } catch (error) { |   } catch (error) { | ||||||
|         console.error('获取充值列表失败:', error); |     console.error("获取充值列表失败:", error); | ||||||
|         res.status(500).json({ error: '获取充值列表失败' }); |     res.status(500).json({ error: "获取充值列表失败" }); | ||||||
|     } |   } | ||||||
| }); | }); | ||||||
|  |  | ||||||
| module.exports = router; | module.exports = router; | ||||||
|   | |||||||
| @@ -10,6 +10,7 @@ | |||||||
|     "format": "prettier --write src/" |     "format": "prettier --write src/" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|  |     "dayjs": "^1.11.13", | ||||||
|     "element-plus": "^2.9.8", |     "element-plus": "^2.9.8", | ||||||
|     "vue": "^3.5.13", |     "vue": "^3.5.13", | ||||||
|     "vue-router": "^4.5.0" |     "vue-router": "^4.5.0" | ||||||
|   | |||||||
							
								
								
									
										53
									
								
								web/src/assets/items.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								web/src/assets/items.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,53 @@ | |||||||
|  | [{"resId":3,"name":"经验","useType":1}, | ||||||
|  | {"resId":6,"name":"钻石","useType":1}, | ||||||
|  | {"resId":7,"name":"金币","useType":1}, | ||||||
|  | {"resId":8,"name":"洗炼石","useType":1}, | ||||||
|  | {"resId":9,"name":"体力","useType":1}, | ||||||
|  | {"resId":10,"name":"充值币","useType":1}, | ||||||
|  | {"resId":10002,"name":"发冠升级图纸","useType":1}, | ||||||
|  | {"resId":10003,"name":"道袍升级图纸","useType":1}, | ||||||
|  | {"resId":10004,"name":"项链升级图纸","useType":1}, | ||||||
|  | {"resId":10005,"name":"戒指升级图纸","useType":1}, | ||||||
|  | {"resId":10006,"name":"靴子升级图纸","useType":1}, | ||||||
|  | {"resId":10007,"name":"新手道书","useType":1}, | ||||||
|  | {"resId":10008,"name":"五色土","useType":1}, | ||||||
|  | {"resId":10009,"name":"女娲石","useType":1}, | ||||||
|  | {"resId":10010,"name":"突破丹","useType":1}, | ||||||
|  | {"resId":10011,"name":"随机装备图纸","useType":2}, | ||||||
|  | {"resId":10012,"name":"随机技能卷轴","useType":4}, | ||||||
|  | {"resId":10013,"name":"随机宝石箱子","useType":3}, | ||||||
|  | {"resId":10014,"name":"普通宝石箱","useType":3}, | ||||||
|  | {"resId":10015,"name":"璀璨宝石箱","useType":3}, | ||||||
|  | {"resId":10016,"name":"随机紫色宝石宝箱","useType":3}, | ||||||
|  | {"resId":10017,"name":"随机金色宝石宝箱","useType":3}, | ||||||
|  | {"resId":10018,"name":"随机红色宝石宝箱","useType":3}, | ||||||
|  | {"resId":10019,"name":"随机多彩宝石宝箱","useType":3}, | ||||||
|  | {"resId":10020,"name":"宝石抽取券","useType":1}, | ||||||
|  | {"resId":10021,"name":"灵宠抽取券","useType":1}, | ||||||
|  | {"resId":10022,"name":"随机宝石箱子","useType":3}, | ||||||
|  | {"resId":10023,"name":"随机稀有宝石","useType":3}, | ||||||
|  | {"resId":10024,"name":"随机宝石箱子","useType":3}, | ||||||
|  | {"resId":10101,"name":"御剑术卷轴","useType":1}, | ||||||
|  | {"resId":10102,"name":"毒气弹卷轴","useType":1}, | ||||||
|  | {"resId":10103,"name":"寒冰箭卷轴","useType":1}, | ||||||
|  | {"resId":10104,"name":"惊雷咒卷轴","useType":1}, | ||||||
|  | {"resId":10105,"name":"石狮子卷轴","useType":1}, | ||||||
|  | {"resId":10106,"name":"剑气斩卷轴","useType":1}, | ||||||
|  | {"resId":10107,"name":"万剑诀卷轴","useType":1}, | ||||||
|  | {"resId":10108,"name":"寒冰突刺卷轴","useType":1}, | ||||||
|  | {"resId":10109,"name":"连环闪电卷轴","useType":1}, | ||||||
|  | {"resId":10110,"name":"泰山压顶卷轴","useType":1}, | ||||||
|  | {"resId":10111,"name":"风暴术卷轴","useType":1}, | ||||||
|  | {"resId":10112,"name":"天雷网卷轴","useType":1}, | ||||||
|  | {"resId":10113,"name":"巨石突刺卷轴","useType":1}, | ||||||
|  | {"resId":10114,"name":"旋风术卷轴","useType":1}, | ||||||
|  | {"resId":10115,"name":"闪电球卷轴","useType":1}, | ||||||
|  | {"resId":10116,"name":"改名卡","useType":1}, | ||||||
|  | {"resId":10117,"name":"随机宝石箱子","useType":1}, | ||||||
|  | {"resId":10118,"name":"随机蓝色宝石宝箱","useType":3}, | ||||||
|  | {"resId":10119,"name":"晶石掉落","useType":1}, | ||||||
|  | {"resId":10120,"name":"技能卷轴自选宝箱","useType":5}, | ||||||
|  | {"resId":10121,"name":"灵宠口粮","useType":1}, | ||||||
|  | {"resId":10122,"name":"灵宠抽卡箱","useType":1}, | ||||||
|  | {"resId":10123,"name":"灵宠口粮","useType":1}, | ||||||
|  | {"resId":10999,"name":"1元代金券","useType":1}] | ||||||
| @@ -1,14 +1,20 @@ | |||||||
| <script setup> | <script setup> | ||||||
| import { ref, onMounted } from 'vue' | import { ref, onMounted } from 'vue' | ||||||
| import axios from 'axios' | 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({ | const form = ref({ | ||||||
|   playerName: '', |   playerName: '', | ||||||
|   item: '', |   item: '', | ||||||
|  |   itemNum: '', | ||||||
|   recharge: '' |   recharge: '' | ||||||
| }) | }) | ||||||
| const items = ref(['物品1', '物品2', '物品3']) | const items = ref(itemList) | ||||||
| const recharges = ref(['充值1', '充值2', '充值3']) | const recharges = ref(['充值1', '充值2', '充值3']) | ||||||
|  |  | ||||||
| // 第二个卡片:角色表格数据 | // 第二个卡片:角色表格数据 | ||||||
| @@ -16,10 +22,14 @@ const roleList = ref([]) | |||||||
| const roleSearch = ref('') | const roleSearch = ref('') | ||||||
| const fetchRoleList = async () => { | const fetchRoleList = async () => { | ||||||
|   try { |   try { | ||||||
|     const response = await axios.get('/api/role', { |     const response = await axios.get('/api/roles', { | ||||||
|       params: { search: roleSearch.value } |       params: { search: roleSearch.value } | ||||||
|     }) |     }) | ||||||
|     roleList.value = response.data |     roleList.value = response.data.map(e => { | ||||||
|  |       e.lastLoginTime = dayjs(e.lastLoginTime).format("YYYY-MM-DD HH:mm:ss") | ||||||
|  |       e.createTime = dayjs(e.createTime).format("YYYY-MM-DD HH:mm:ss") | ||||||
|  |       return { ...e } | ||||||
|  |     }) | ||||||
|   } catch (error) { |   } catch (error) { | ||||||
|     console.error('获取角色列表失败:', error) |     console.error('获取角色列表失败:', error) | ||||||
|   } |   } | ||||||
| @@ -30,7 +40,7 @@ const rechargeList = ref([]) | |||||||
| const rechargeSearch = ref('') | const rechargeSearch = ref('') | ||||||
| const fetchRechargeList = async () => { | const fetchRechargeList = async () => { | ||||||
|   try { |   try { | ||||||
|     const response = await axios.get('/api/recharge', { |     const response = await axios.get('/api/recharges', { | ||||||
|       params: { search: rechargeSearch.value } |       params: { search: rechargeSearch.value } | ||||||
|     }) |     }) | ||||||
|     rechargeList.value = response.data |     rechargeList.value = response.data | ||||||
| @@ -46,8 +56,15 @@ onMounted(() => { | |||||||
| }) | }) | ||||||
|  |  | ||||||
| // 提交表单 | // 提交表单 | ||||||
| const submitForm = () => { | const submitForm = (formEl) => { | ||||||
|   console.log('提交表单:', form.value) |   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> | </script> | ||||||
|  |  | ||||||
| @@ -58,31 +75,27 @@ const submitForm = () => { | |||||||
|       <template #header> |       <template #header> | ||||||
|         <div class="card-header"> |         <div class="card-header"> | ||||||
|           <span>GM操作台</span> |           <span>GM操作台</span> | ||||||
|           <el-button type="primary" @click="submitForm">提交</el-button> |           <el-button type="primary" @click="submitForm(gmFormRef)">提交</el-button> | ||||||
|         </div> |         </div> | ||||||
|       </template> |       </template> | ||||||
|       <el-form :model="form" label-width="100px"> |       <el-form ref="gmFormRef" :model="form" label-width="100px"> | ||||||
|         <el-row :gutter="20"> |         <div class="grid grid-cols-2"> | ||||||
|           <el-col :span="8"> |           <el-form-item label="玩家角色名" prop="playerName" required> | ||||||
|             <el-form-item label="玩家角色名"> |             <el-input v-model="form.playerName" placeholder="请输入玩家角色名"></el-input> | ||||||
|               <el-input v-model="form.playerName" placeholder="请输入玩家角色名"></el-input> |           </el-form-item> | ||||||
|             </el-form-item> |           <el-form-item label="物品道具" prop="item"> | ||||||
|           </el-col> |             <el-select-v2 v-model="form.item" placeholder="请选择物品" :options="items" | ||||||
|           <el-col :span="8"> |               :props="{ label: 'name', value: 'resId' }" filterable /> | ||||||
|             <el-form-item label="物品道具"> |           </el-form-item> | ||||||
|               <el-select v-model="form.item" placeholder="请选择物品"> |           <el-form-item label="物品数量" prop="itemNum"> | ||||||
|                 <el-option v-for="item in items" :key="item" :label="item" :value="item"></el-option> |             <el-input type="number" v-model="form.itemNum" placeholder="请输入发送的物品数量"></el-input> | ||||||
|               </el-select> |           </el-form-item> | ||||||
|             </el-form-item> |           <el-form-item label="充值" prop="recharges"> | ||||||
|           </el-col> |             <el-select v-model="form.recharge" placeholder="请选择充值"> | ||||||
|           <el-col :span="8"> |               <el-option v-for="recharge in recharges" :key="recharge" :label="recharge" :value="recharge"></el-option> | ||||||
|             <el-form-item label="充值"> |             </el-select> | ||||||
|               <el-select v-model="form.recharge" placeholder="请选择充值"> |           </el-form-item> | ||||||
|                 <el-option v-for="recharge in recharges" :key="recharge" :label="recharge" :value="recharge"></el-option> |         </div> | ||||||
|               </el-select> |  | ||||||
|             </el-form-item> |  | ||||||
|           </el-col> |  | ||||||
|         </el-row> |  | ||||||
|       </el-form> |       </el-form> | ||||||
|     </el-card> |     </el-card> | ||||||
|  |  | ||||||
| @@ -91,13 +104,21 @@ const submitForm = () => { | |||||||
|       <template #header> |       <template #header> | ||||||
|         <div class="card-header"> |         <div class="card-header"> | ||||||
|           <span>角色列表</span> |           <span>角色列表</span> | ||||||
|           <el-input style="width: 240px;" v-model="roleSearch" placeholder="请输入角色名称或ID" @input="fetchRoleList"></el-input> |           <el-input style="width: 240px;" v-model="roleSearch" placeholder="请输入角色名称或ID" @change="fetchRoleList" | ||||||
|  |             clearable /> | ||||||
|         </div> |         </div> | ||||||
|       </template> |       </template> | ||||||
|       <el-table :data="roleList" style="width: 100%" border> |       <el-table :data="roleList" style="width: 100%" border height="400"> | ||||||
|         <el-table-column prop="id" label="ID" width="180"></el-table-column> |         <el-table-column prop="id" label="ID"></el-table-column> | ||||||
|         <el-table-column prop="name" label="角色名称" width="180"></el-table-column> |         <el-table-column prop="name" label="角色名称"></el-table-column> | ||||||
|         <el-table-column prop="level" label="等级"></el-table-column> |         <el-table-column prop="lv" label="等级"></el-table-column> | ||||||
|  |         <el-table-column prop="lastLoginTime" label="上次登录" width="220" /> | ||||||
|  |         <el-table-column prop="createTime" label="创建时间" width="220" /> | ||||||
|  |         <el-table-column label="是否禁用"> | ||||||
|  |           <template v-slot="{ row }"> | ||||||
|  |             <el-switch v-model="row.ban" disabled /> | ||||||
|  |           </template> | ||||||
|  |         </el-table-column> | ||||||
|       </el-table> |       </el-table> | ||||||
|     </el-card> |     </el-card> | ||||||
|  |  | ||||||
| @@ -106,7 +127,8 @@ const submitForm = () => { | |||||||
|       <template #header> |       <template #header> | ||||||
|         <div class="card-header"> |         <div class="card-header"> | ||||||
|           <span>充值流水</span> |           <span>充值流水</span> | ||||||
|           <el-input style="width: 240px;" v-model="rechargeSearch" placeholder="请输入角色名称或流水单号" @input="fetchRechargeList"></el-input> |           <el-input style="width: 240px;" v-model="rechargeSearch" placeholder="请输入角色名称或流水单号" | ||||||
|  |             @input="fetchRechargeList"></el-input> | ||||||
|         </div> |         </div> | ||||||
|       </template> |       </template> | ||||||
|       <el-table :data="rechargeList" style="width: 100%" border> |       <el-table :data="rechargeList" style="width: 100%" border> | ||||||
| @@ -127,9 +149,11 @@ const submitForm = () => { | |||||||
|   gap: 20px; |   gap: 20px; | ||||||
|   padding: 20px; |   padding: 20px; | ||||||
| } | } | ||||||
|  |  | ||||||
| .card-item { | .card-item { | ||||||
|   width: 100%; |   width: 100%; | ||||||
| } | } | ||||||
|  |  | ||||||
| .card-header { | .card-header { | ||||||
|   display: flex; |   display: flex; | ||||||
|   justify-content: space-between; |   justify-content: space-between; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user