上传工具代码

This commit is contained in:
liwei1dao 2022-11-16 17:39:18 +08:00
parent 215a29f9e2
commit a51587e608
18 changed files with 1478 additions and 619 deletions

View File

@ -8,6 +8,7 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.27.2",
"@mdi/font": "5.9.55",
"core-js": "^3.8.3",
"google-protobuf": "^3.20.1",

10
src/api/api.js Normal file
View File

@ -0,0 +1,10 @@
import request from '@/utils/request'
///发送验证码
export function upload (data) {
return request({
url: '/api/upload',
method: 'post',
data
})
}

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,27 @@
syntax = "proto3";
option go_package = ".;pb";
import "hero_db.proto";
import "comm.proto";
enum BattleType {
nil = 0;
pve = 1;
pvp = 2;
pvb = 3;
eve = 4;
}
//
enum PlayType {
moonfantasy = 0; //
mainline = 1; //线
pagoda = 2; //
viking = 3; //
rtask = 4; //
hunting = 5; //
null = 0; //
mainline = 1; //线
pagoda = 2; //
rtask = 3; //
hunting = 4; //
viking = 5; //
moonfantasy = 6; //
arena = 7; //
academy = 8; //
heroteaching = 9; //
}
//
@ -43,7 +48,9 @@ message BattleRole {
int32 mainSuitSkill = 8; ///@go_tags(`bson:"mainSuitSkill"`)
int32 subSuitSkill = 9; ///@go_tags(`bson:"subSuitSkill"`)
repeated SkillData normalSkill = 10; //@go_tags(`bson:"normalSkill"`)
map<string, int32> property = 11; //
repeated SkillData equipSkill = 11; //@go_tags(`bson:"normalSkill"`)
map<string, int32> property = 12; //
bool ishelp = 13; //
}
//

View File

@ -1,21 +1,48 @@
syntax = "proto3";
option go_package = ".;pb";
import "battle_db.proto";
import "hero_db.proto";
message LineUp {
string cid = 1; // id
int32 star = 2; //
int32 lv = 3; //
}
//
message BattleFormation {
int32 leadpos = 1; //
repeated string format = 2; // 0-5
repeated string friendformat = 3; //
}
// pve ( 使 )
message BattleEVEReq {
PlayType ptype = 1; //
string title = 2; //
repeated int32 redformat = 3; //
repeated int32 buleformat = 4; //
}
// pve ( 使 )
message BattlePVEReq {
PlayType ptype = 1; //
string title = 2; //
int32 leadpos = 3; //
repeated string teamids = 4; //
repeated int32 mformat = 5; //
PlayType ptype = 1; //
string title = 2; //
BattleFormation format = 4; //
repeated int32 mformat = 5; //
}
//
message PVPFormation {
string uid = 1; //id
int32 leadpos = 2; //
repeated DBHero format = 3; // 0-5
}
// pve ( 使 )
message BattlePVPReq {
PlayType ptype = 1; //
string title = 2; //
PVPFormation redformat = 4; //
PVPFormation buleformat = 5; //
}
//
message BattleInfo {
string id = 1; //id
@ -26,10 +53,13 @@ message BattleInfo {
repeated DBBattleFormt redflist = 6; //
string blueCompId = 7; //id
repeated DBBattleFormt buleflist = 8; //
repeated int32 tasks = 9; //
}
//
message BattleReport {
BattleInfo info = 1;
int32 Costtime = 2; // ms
bytes process = 3; //
repeated int32 completetask = 4; //
}

View File

@ -0,0 +1,9 @@
syntax = "proto3";
option go_package = ".;pb";
message DBCombatUser {
string uid = 1; //uid
int32 currlevel = 2; //
repeated int32 passmanster= 3; //
repeated int32 passdrop= 4; //
}

View File

@ -0,0 +1,57 @@
syntax = "proto3";
option go_package = ".;pb";
import "errorcode.proto";
import "comm.proto";
import "battle_msg.proto";
//
message CombatInReq {
int32 id = 1; //id
}
//
message CombatInResp {
int32 id = 1; //id
}
//
message CombatOutReq {
int32 id = 1; //id
}
//
message CombatOutResp {
int32 id = 1; //id
}
//
message CombatChallengeReq {
int32 manster = 1; //id
BattleFormation battle = 2; //
}
//
message CombatChallengeResp {
ErrorCode code = 1; //
int32 manster = 2;
BattleInfo info = 3;
}
//
message CombatChallengeReceiveReq {
int32 manster = 1;
BattleReport report = 2; //
}
//
message CombatChallengeReceiveResp { bool issucc = 1; }
//
message CombatDropReq {
int32 drop = 1; //id
}
//
message CombatDropResp {
ErrorCode code = 1; //
repeated UserAssets atns = 2; //
}

View File

@ -12,4 +12,6 @@ message DBMailData {
bool Check = 7; //
bool Reward = 8; //
repeated UserAssets Items = 9; //
string Cid = 10; // ID
repeated string Param = 11;
}

View File

@ -3,52 +3,36 @@ option go_package = ".;pb";
import "mail_db.proto";
import "comm.proto";
message MailGetListReq {
}
message MailGetListReq {}
//
message MailGetListResp {
repeated DBMailData Mails = 1;
}
message MailGetListResp { repeated DBMailData Mails = 1; }
//
message MailReadMailReq {
string ObjID = 1;
}
message MailReadMailReq { string ObjID = 1; }
message MailReadMailResp {
DBMailData Mail = 1;
}
message MailReadMailResp { DBMailData Mail = 1; }
//
message MailGetUserMailAttachmentReq {
string ObjID = 1;
}
message MailGetUserMailAttachmentReq { string ObjID = 1; }
message MailGetUserMailAttachmentResp {
DBMailData Mail = 1;
}
message MailGetUserMailAttachmentResp { DBMailData Mail = 1; }
//
message MailDelMailReq {
string ObjID = 1;
}
message MailDelMailReq { string ObjID = 1; }
message MailDelMailResp {
string ObjID = 1; // id
string ObjID = 1; // id
}
//
message MailGetNewMailPush{
DBMailData Mail = 1; //
message MailGetNewMailPush {
DBMailData Mail = 1; //
}
//
message MailGetAllMailAttachmentReq {
}
message MailGetAllMailAttachmentReq {}
message MailGetAllMailAttachmentResp {
repeated UserAssets res = 1; //
repeated string ids = 2; // id
repeated UserAssets res = 1; //
repeated string ids = 2; // id
}

View File

@ -0,0 +1,18 @@
syntax = "proto3";
option go_package = ".;pb";
//
message ReddotGetAllReq {}
message ReddotGetAllResp {
map<int32,bool> reddot = 1; //
}
//
message ReddotGetReq {
repeated int32 rids = 1;
}
message ReddotGetResp {
map<int32,bool> reddot = 1; //
}

View File

@ -25,9 +25,25 @@ const routes = [
{
path: 'index',
component: () => import('@/views/protocol/Index.vue'),
}
},
]
},
{
path: '/upload',
name: 'Upload',
redirect: '/upload/index',
component: layout,
meta: { title: '配置上传', icon: 'mdi-protocol' },
children: [
{
path: 'index',
component: () => import('@/views/upload/Index.vue'),
},
]
}
]

18
src/utils/md5.js Normal file
View File

@ -0,0 +1,18 @@
import md5 from 'js-md5';
function paramsStrSort (paramsStr) {
var orsign = paramsStr.split("&").sort().join("&");
orsign = orsign + '&key=@234%67g12q4*67m12#4l67!';
console.log("签名:" + orsign);
return md5(orsign).toLowerCase();
}
export function paramsign (params) {
var arr = [];
for (var i in params) {
if (i != "Sign")
arr.push((i + "=" + params[i]));
}
params.Sign = paramsStrSort(arr.join(("&")));
return params
}

108
src/utils/request.js Normal file
View File

@ -0,0 +1,108 @@
import axios from 'axios'
import router from '@/router'
import store from '@/store'
import message from '@/components/message/'
import { paramsign } from '@/utils/md5'
const showStatus = (status) => {
let message = ''
switch (status) {
case 400:
message = '请求错误(400)'
break
case 401:
message = '未授权,请重新登录(401)'
break
case 402:
message = '拒绝访问(402)'
break
case 404:
message = '请求出错(404)'
break
case 408:
message = '请求超时(408)'
break
case 500:
message = '服务器错误(500)'
break
case 501:
message = '服务未实现(501)'
break
case 502:
message = '网络错误(502)'
break
case 503:
message = '服务不可用(503)'
break
case 504:
message = '网络超时(504)'
break
case 505:
message = 'HTTP版本不受支持(505)'
break
default:
message = `连接出错(${status})!`
}
return `${message},请检查网络或联系管理员!`
}
const service = axios.create({
// 是否跨站点访问控制请求
withCredentials: true,
baseURL: process.env.VUE_APP_BASE_API,
timeout: 5000,
validateStatus () {
// 使用async-await处理reject情况较为繁琐所以全部返回resolve在业务代码中处理异常
return true
}
})
// 请求拦截器
service.interceptors.request.use(
request => {
if (request.data != null) {
request.data = paramsign(request.data)
}
if (store.getters.token != null) {
request.headers['X-Token'] = store.getters.token
console.log("X-Token" + request.headers['X-Token'])
}
console.log("req %s:%o", request.url, request.data)
return request
},
(err) => {
message.error(res.message || '服务器异常,请联系管理员!')
return Promise.reject(err)
}
)
// 响应拦截器
service.interceptors.response.use(
response => {
console.log('response:%o', response)
const status = response.status
const res = response.data
if (status === 200) {
if (res.code != 0) {
if (res.code === 101) {
router.replace('/login')
return
}
message.error("exception code:" + res.code)
Promise.reject(new Error("exception code:" + res.code))
} else {
return res
}
} else {
message.error("exception status:" + status)
return Promise.reject(new Error("exception status:" + status))
}
},
(err) => {
console.log(err)
message.error(res.message || '服务器异常,请联系管理员!')
return Promise.reject(err)
}
)
export default service

85
src/utils/upload.js Normal file
View File

@ -0,0 +1,85 @@
import axios from 'axios'
import router from '@/router'
import store from '@/store'
/*
获取文件后缀
*/
export function getfilesuffix (file) {
//获取文件的后缀名的位置
var index = file.name.lastIndexOf(".");
if (index == -1) {
return false;
}
//截取后缀名
var type = file.name.substring(index + 1);
return type
}
/*
文件上传
*/
export function uploadformData (url, formData, progress) {
return new Promise((resolve, reject) => {
axios({
method: "post",
url: url,
headers: { 'X-Token': store.getters.token },
data: formData,
onUploadProgress: (evt) => {
if (evt.lengthComputable) {
var percent = Math.round(evt.loaded * 100 / evt.total);
progress(percent)
}
else {
progress(100)
}
}
}).then(response => {
const status = response.status
const res = response.data
console.log('response:%o', response)
if (status === 200) {
if (res.code != 0) {
if (res.code === 101) {
router.replace('/login')
return
}
return reject(new Error("exception code:" + res.code))
} else {
return resolve(res)
}
} else {
return reject(new Error("exception status:" + status))
}
}).catch(err => {
reject(err)
})
})
}
///校验文件格式
export function validateFileType (files, types) {
if (files == null || types == null) {
return false
}
for (var i = 0; i < files.length; i++) {
var file = files[i]
if (file.name == "" || file.name == null) {
return false;
}
//获取文件的后缀名的位置
var index = file.name.lastIndexOf(".");
if (index == -1) {
return false;
}
//截取后缀名
var type = file.name.substring(index + 1);
for (var i = 0; i < types.length; i++) {
if (type == types[i]) {
return true
}
}
return false
}
}

View File

@ -225,6 +225,8 @@ export default defineComponent({
{ mainType: 'hunting', subs: [] },
{ mainType: 'horoscope', subs: [] },
{ mainType: 'pay', subs: [] },
{ mainType: 'reddot', subs: [] },
{ mainType: 'combat', subs: [] },
])
for (const v of Object.keys(proto)) {
for (const v1 of proto_models) {

194
src/views/upload/Index.vue Normal file
View File

@ -0,0 +1,194 @@
<template>
<v-container>
<v-card id="drop-area"
flat>
<v-card-title class="text-center">
上传游戏配置文件
</v-card-title>
<v-divider></v-divider>
<v-card-text>
<input v-show="false"
ref="fileinput"
@change="changeFile"
type="file"
multiple="multiple" />
<v-card id="drop-area"
@click="selectFile"
variant="outlined"
height="220">
<v-card-text>
<v-row justify="center"
dense>
<v-col cols="12"
class="text-center">
<v-icon size="120">mdi-cloud-upload</v-icon>
</v-col>
<v-col cols="12"
class="text-center">将文件拖到此处<strong class="blue--text text--lighten-1">点击上传</strong>
</v-col>
<v-col cols="12"
class="text-center">只能上传 .json 格式的文件</v-col>
</v-row>
</v-card-text>
</v-card>
<v-card variant="outlined"
class="mt-5">
<v-card-title>文件列表</v-card-title>
<v-card-text>
<v-row>
<v-col cols="12"
v-for="(file,i) in files"
:key="i">
<v-card>
<v-card-text class="pa-0 ">
<v-row>
<v-col cols="10">{{file.title}}</v-col>
<v-col cols="2"
class="d-flex justify-end">
<v-btn variant="outlined"
size="x-small"
icon
@click="removefile(i)">
<v-icon>
mdi-close-circle
</v-icon>
</v-btn>
</v-col>
</v-row>
</v-card-text>
</v-card>
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-row justify="center">
<v-col cols="5">
<v-btn variant="flat"
color="secondary"
:disabled="files.length == 0"
@click="uploadres"
block>提交</v-btn>
</v-col>
</v-row>
</v-card-actions>
</v-card>
</v-card-text>
</v-card>
<v-snackbar v-model="snackbar"
:timeout="2000">
{{ text }}
<template v-slot:action="{ attrs }">
<v-btn color="blue"
text
v-bind="attrs"
@click="snackbar = false">
Close
</v-btn>
</template>
</v-snackbar>
<v-overlay z-index="1000"
:value="uploading">
<v-card width="750"
height="300"
light>
<v-card-text>
<v-card height="60"
flat></v-card>
<p class="text-center text-h6">文件上传</p>
<v-progress-linear color="light-blue"
height="20"
:value="uploadprogress"
striped></v-progress-linear>
<p class="mt-2 text-center text-subtitle-2">资源上传中,请勿操作</p>
</v-card-text>
<v-card-actions class="d-flex justify-center">
<v-btn outlined
:disabled="!uploading">确定</v-btn>
</v-card-actions>
</v-card>
</v-overlay>
</v-container>
</template>
<script>
import { uploadformData } from '@/utils/upload'
export default {
name: 'upload',
data() {
return {
errstr: '',
snackbar: false,
files: [],
uploading: false,
uploadprogress: 0,
}
},
methods: {
//
changeFile(e) {
let suffixs = ['json']
console.log('suffixs:%o', suffixs)
for (let file of e.target.files) {
let filename = file.name
let isallow = false
//
var index = filename.lastIndexOf('.')
if (index == -1) {
this.$refs.fileinput.value = null
this.errstr = '目标文件格式不符合规范!'
this.snackbar = true
return
}
//
var suffix = filename.substring(index + 1)
for (var i = 0; i < suffixs.length; i++) {
if (suffix == suffixs[i]) {
isallow = true
break
}
}
if (!isallow) {
this.$refs.fileinput.value = null
this.errstr = '目标文件格式不符合规范!'
this.snackbar = true
return
}
this.files.push({
file: file,
title: file.name,
})
}
this.$refs.fileinput.value = null
},
selectFile() {
this.$refs.fileinput.dispatchEvent(new MouseEvent('click'))
},
removefile(i) {
this.files.forEach(function (item, index, arr) {
if (index == i) {
arr.splice(index, 1)
}
})
},
uploadres() {
this.uploading = true
var formData = new FormData()
for (let i = 0; i < this.files.length; ++i) {
formData.append('file_' + i, this.files[i].file)
}
formData.append('filenum', this.files.length)
uploadformData('/upload', formData, (p) => {
this.uploadprogress = p
this.$forceUpdate()
})
},
},
}
</script>
<style>
</style>

View File

@ -6,5 +6,22 @@ module.exports = defineConfig({
vuetify: {
// https://github.com/vuetifyjs/vuetify-loader/tree/next/packages/vuetify-loader
}
}
},
devServer: {
open: true,
proxy: {
'/api': {
target: 'http://127.0.0.1:8000',//要代理的本地api地址也可以换成线上测试地址
changeOrigin: true,//允许跨域
pathRewrite: { "^/api": "/api" }//将/api开头替换为/api
},
'/upload': {
target: 'http://127.0.0.1:8000',//要代理的本地api地址也可以换成线上测试地址
changeOrigin: true,//允许跨域
pathRewrite: { "^/upload": "/upload" }//将/api开头替换为/api
}
}
},
})

View File

@ -2037,6 +2037,11 @@ async@^2.6.4:
dependencies:
lodash "^4.17.14"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
at-least-node@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2"
@ -2054,6 +2059,14 @@ autoprefixer@^10.2.4:
picocolors "^1.0.0"
postcss-value-parser "^4.2.0"
axios@^0.27.2:
version "0.27.2"
resolved "https://registry.npmmirror.com/axios/-/axios-0.27.2.tgz#207658cc8621606e586c85db4b41a750e756d972"
integrity sha512-t+yRIyySRTp/wua5xEr+z1q60QmLq8ABsS5O9Me1AsE5dfKqgnCFzwiCZZ/cGNd1lq4/7akDWMxdhVlucjmnOQ==
dependencies:
follow-redirects "^1.14.9"
form-data "^4.0.0"
babel-loader@^8.2.2:
version "8.2.5"
resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e"
@ -2425,6 +2438,13 @@ colorette@^2.0.10:
resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798"
integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==
combined-stream@^1.0.8:
version "1.0.8"
resolved "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f"
integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==
dependencies:
delayed-stream "~1.0.0"
commander@^2.20.0:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
@ -2776,6 +2796,11 @@ define-properties@^1.1.4:
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==
depd@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
@ -3364,6 +3389,20 @@ follow-redirects@^1.0.0:
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.1.tgz#0ca6a452306c9b276e4d3127483e29575e207ad5"
integrity sha512-yLAMQs+k0b2m7cVxpS1VKJVvoz7SS9Td1zss3XRwXj+ZDH00RJgnuLx7E44wx02kQLrdM3aOOy+FpzS7+8OizA==
follow-redirects@^1.14.9:
version "1.15.2"
resolved "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13"
integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==
form-data@^4.0.0:
version "4.0.0"
resolved "https://registry.npmmirror.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452"
integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.8"
mime-types "^2.1.12"
forwarded@0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811"
@ -4239,9 +4278,9 @@ mime-db@1.52.0, "mime-db@>= 1.43.0 < 2":
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34:
mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34:
version "2.1.35"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
resolved "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
dependencies:
mime-db "1.52.0"