Просмотр исходного кода

Merge branch 'dev-meta' of xiongzhu/raex_back into master

sunkean 3 лет назад
Родитель
Сommit
820360df02

+ 9 - 0
src/main/java/com/izouma/nineth/domain/MetaTask.java

@@ -3,6 +3,7 @@ package com.izouma.nineth.domain;
 
 import com.alibaba.excel.annotation.ExcelProperty;
 import com.izouma.nineth.annotations.Searchable;
+import com.izouma.nineth.enums.EntryModeType;
 import com.izouma.nineth.enums.MetaTaskType;
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
@@ -56,4 +57,12 @@ public class MetaTask extends BaseEntity{
     @ApiModelProperty("奖励图片")
     @ExcelProperty("图片地址")
     private String awardPic;
+
+    @ApiModelProperty("奖励类型")
+    @ExcelProperty("奖励类型")
+    private EntryModeType awardType;
+
+    @ApiModelProperty("金币奖励数量")
+    @ExcelProperty("金币奖励数量")
+    private int goldNum;
 }

+ 3 - 1
src/main/java/com/izouma/nineth/enums/EntryModeType.java

@@ -5,7 +5,9 @@ public enum EntryModeType {
 
     NFT("NFT"),
 
-    GOLD("金币");
+    GOLD("金币"),
+
+    GOLD_OR_NFT("金币或NFT");
 
     private final String description;
 

+ 7 - 0
src/main/java/com/izouma/nineth/web/MetaTaskController.java

@@ -3,6 +3,7 @@ package com.izouma.nineth.web;
 import com.izouma.nineth.domain.MetaTask;
 import com.izouma.nineth.dto.MetaRestResult;
 import com.izouma.nineth.dto.PageQuery;
+import com.izouma.nineth.enums.EntryModeType;
 import com.izouma.nineth.enums.MetaTaskType;
 import com.izouma.nineth.exception.BusinessException;
 import com.izouma.nineth.repo.CollectionRepo;
@@ -43,6 +44,12 @@ public class MetaTaskController extends BaseController {
         if (record.getId() != null) {
             MetaTask orig = metaTaskRepo.findById(record.getId()).orElseThrow(new BusinessException("无记录"));
             ObjUtils.merge(orig, record);
+            if (EntryModeType.GOLD.equals(record.getAwardType())) {
+                orig.setAwardPic(null);
+            }
+            if (EntryModeType.NFT.equals(record.getAwardType())) {
+                orig.setGoldNum(0);
+            }
             return metaTaskRepo.save(orig);
         }
         return metaTaskRepo.save(record);

+ 6 - 1
src/main/java/com/izouma/nineth/websocket/PublicScreenChatWebsocket.java

@@ -112,13 +112,18 @@ public class PublicScreenChatWebsocket extends WebsocketCommon {
     }
 
     @OnMessage
-    public void onMessage(@PathParam("userId") String userId, String message) {
+    public void onMessage(@PathParam("userId") String userId, String message, Session session) {
         init();
         if (StringUtils.isBlank(message)) {
             String errMsg = "Illegal parameter : message can not be null";
             exceptionHandle(userId, new PublicScreenChatExceptionMsg(4, errMsg));
             return;
         }
+        if ("META_PING".equals(message)) {
+            log.info(String.format("sessionId:[%S] userId:[%S] 连接正常", session.getId(), userId));
+            sendMessageTo(clients, "META_PONG", PREFIX.concat(userId));
+            return;
+        }
         if (!contentAuditService.auditText(message)) {
             savePublicScreenChat(userId, message, false);
             exceptionHandle(userId, new PublicScreenChatExceptionMsg(3, "消息包含非法内容"));

+ 472 - 460
src/main/vue/src/views/MetaGameCopyEdit.vue

@@ -1,474 +1,486 @@
 <template>
-    <div class="edit-view">
-        <page-title>
-            <el-button @click="$router.go(-1)" :disabled="saving"> 取消 </el-button>
-            <el-button @click="onDelete" :disabled="saving" type="danger" v-if="formData.id"> 删除 </el-button>
-            <el-button @click="onSave" :loading="saving" type="primary"> 保存 </el-button>
-        </page-title>
-        <div class="edit-view__content-wrapper">
-            <div class="edit-view__content-section">
-                <el-form
-                    :model="formData"
-                    :rules="rules"
-                    ref="form"
-                    label-width="108px"
-                    label-position="right"
-                    size="small"
-                    style="max-width: 500px"
-                >
-                    <el-form-item prop="gameName" label="游戏">
-                        <el-select v-model="formData.gameName" clearable filterable placeholder="请选择">
-                            <el-option
-                                v-for="item in gameNameOptions"
-                                :key="item.value"
-                                :label="item.label"
-                                :value="item.value"
-                            >
-                            </el-option>
-                        </el-select>
-                    </el-form-item>
-                    <el-form-item prop="gameCopyType" label="副本">
-                        <el-select v-model="formData.gameCopyType" clearable filterable placeholder="请选择">
-                            <el-option
-                                v-for="item in gameCopyTypeOptions"
-                                :key="item.value"
-                                :label="item.label"
-                                :value="item.value"
-                            >
-                            </el-option>
-                        </el-select>
-                    </el-form-item>
-                    <el-form-item prop="entryModeType" label="入场方式">
-                        <el-select v-model="formData.entryModeType" clearable filterable placeholder="请选择">
-                            <el-option
-                                v-for="item in entryModeTypeOptions"
-                                :key="item.value"
-                                :label="item.label"
-                                :value="item.value"
-                            >
-                            </el-option>
-                        </el-select>
-                    </el-form-item>
-                    <el-form-item prop="goldNum" label="所需金币数量" v-if="formData.entryModeType === 'GOLD'">
-                        <el-input-number type="goldNum" v-model="formData.goldNum" :step="1" :min="1">
-                        </el-input-number>
-                        <div class="tip">输入规则:正整数,最小为1</div>
-                    </el-form-item>
-                    <el-form-item prop="audit" label="是否需要审核" v-if="formData.entryModeType === 'NFT'">
-                        <el-radio-group v-model="formData.audit">
-                            <el-radio :label="true"> 人工审核 </el-radio>
-                            <el-radio :label="false"> 自动匹配 </el-radio>
-                        </el-radio-group>
-                    </el-form-item>
-                    <el-form-item
-                        prop="collectionName"
-                        label="藏品名称"
-                        v-if="formData.entryModeType === 'NFT' && formData.audit === true"
-                    >
-                        <el-input v-model="formData.collectionName" :disabled="!canEdit" class="width"> </el-input>
-                    </el-form-item>
-                    <el-form-item
-                        prop="rule"
-                        label="匹配规则设置"
-                        v-if="formData.entryModeType === 'NFT' && formData.audit === false"
-                    >
-                        <template v-if="formData.rule && formData.rule.and">
-                            <div v-for="(item, i) in formData.rule.and" class="rule-item">
-                                <el-select v-model="item.detail.tag" value-key="id" size="mini">
-                                    <el-option v-for="item in tags" :key="item.id" :value="item" :label="item.name">
-                                    </el-option>
-                                </el-select>
-                                <span style="padding: 0 10px; color: #606266; font-weight: bold"> ×&nbsp;1 </span>
-                                <i @click="delRule(i)" class="el-icon-delete icon-del"> </i>
-                            </div>
-                        </template>
-                        <el-button size="mini" @click="addRule"> 添加 </el-button>
-                    </el-form-item>
-                    <el-form-item prop="num" label="所需nft数量" v-if="formData.entryModeType === 'NFT'">
-                        <el-input-number
-                            type="number"
-                            v-model="formData.num"
-                            :disabled="!canEdit"
-                            :step="1"
-                            :min="0"
-                            class="width1"
-                        >
-                        </el-input-number>
-                        <div class="tip">0表示不限</div>
-                    </el-form-item>
-                    <el-form-item prop="detail" label="规则详情" style="width: calc(100vw - 450px)">
-                        <el-input
-                            v-model="formData.detail"
-                            type="textarea"
-                            :autosize="{ minRows: 3, maxRows: 20 }"
-                            placeholder="请输入规则详情"
-                        >
-                        </el-input>
-                    </el-form-item>
-                    <el-form-item label="僵尸配置" prop="metaZombieIds">
-                        <el-select v-model="formData.metaZombieIds" multiple placeholder="请选择" style="width: 100%">
-                            <el-option v-for="item in metaZombie" :key="item.id" :label="item.name" :value="item.id">
-                            </el-option>
-                        </el-select>
-                    </el-form-item>
-                    <el-form-item prop="metaGameAwards" label="奖励配置" style="width: calc(100vw - 450px)" size="mini">
-                        <el-table :data="formData.metaGameAwards">
-                            <el-table-column prop="name" label="奖励名称">
-                                <template v-slot="{ row }">
-                                    <el-input v-model="row.name" style="width: 250px" placeholder="请输入奖励名称"> </el-input>
-                                </template>
-                            </el-table-column>
-                            <el-table-column prop="awardType" label="奖励类型">
-                                <template v-slot="{ row }">
-                                    <el-select
-                                        v-model="row.awardType"
-                                        clearable
-                                        filterable
-                                        placeholder="请选择"
-                                        @change="changeAwardType(row)"
-                                    >
-                                        <el-option
-                                            v-for="item in entryModeTypeOptions"
-                                            :key="item.value"
-                                            :label="item.label"
-                                            :value="item.value"
-                                        >
-                                        </el-option>
-                                    </el-select>
-                                </template>
-                            </el-table-column>
-                            <el-table-column prop="config" label="配置值(金币-数量/NFT-NFT图片)">
-                                <template v-slot="{ row }">
-                                    <template v-if="row && row.awardType === 'GOLD'">
-                                        <el-input-number v-model="row.config" :step="1" :min="1"> </el-input-number>
-                                        <div class="tip">输入规则:正整数,最小为1</div>
-                                    </template>
-                                    <template v-if="row && row.awardType === 'NFT'">
-                                        <single-upload v-model="row.config"> </single-upload>
-                                    </template>
-                                </template>
-                            </el-table-column>
-                            <el-table-column prop="probability" label="概率(%)">
-                                <template v-slot="{ row }">
-                                    <el-input-number v-model="row.probability" :step="1" :min="1" :max="100">
-                                    </el-input-number>
-                                    <div class="tip">输入规则:正整数,最小为1,最大为100</div>
-                                </template>
-                            </el-table-column>
-                            <el-table-column width="80" align="center">
-                                <template v-slot="{ row, $index }">
-                                    <el-button type="danger" plain size="mini" @click="delAward($index)">
-                                        删除
-                                    </el-button>
-                                </template>
-                            </el-table-column>
-                        </el-table>
-                    </el-form-item>
-                    <el-form-item>
-                        <el-button size="mini" @click="addAward"> 添加配置 </el-button>
-                    </el-form-item>
-                    <el-form-item prop="publish" label="是否发布">
-                        <el-switch v-model="formData.publish"> </el-switch>
-                    </el-form-item>
-                    <el-form-item class="form-submit">
-                        <el-button @click="onSave" :loading="saving" type="primary"> 保存 </el-button>
-                        <el-button @click="onDelete" :disabled="saving" type="danger" v-if="formData.id">
-                            删除
-                        </el-button>
-                        <el-button @click="$router.go(-1)" :disabled="saving"> 取消 </el-button>
-                    </el-form-item>
-                </el-form>
-            </div>
-        </div>
-    </div>
+	<div class="edit-view">
+		<page-title>
+			<el-button @click="$router.go(-1)" :disabled="saving"> 取消 </el-button>
+			<el-button @click="onDelete" :disabled="saving" type="danger" v-if="formData.id"> 删除 </el-button>
+			<el-button @click="onSave" :loading="saving" type="primary"> 保存 </el-button>
+		</page-title>
+		<div class="edit-view__content-wrapper">
+			<div class="edit-view__content-section">
+				<el-form
+					:model="formData"
+					:rules="rules"
+					ref="form"
+					label-width="108px"
+					label-position="right"
+					size="small"
+					style="max-width: 500px"
+				>
+					<el-form-item prop="gameName" label="游戏">
+						<el-select v-model="formData.gameName" clearable filterable placeholder="请选择">
+							<el-option
+								v-for="item in gameNameOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							>
+							</el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item prop="gameCopyType" label="副本">
+						<el-select v-model="formData.gameCopyType" clearable filterable placeholder="请选择">
+							<el-option
+								v-for="item in gameCopyTypeOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							>
+							</el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item label="金币入场配置">
+						<el-checkbox v-model="gold" @change="goldChange"> </el-checkbox>
+					</el-form-item>
+					<el-form-item prop="goldNum" label="所需金币数量" v-if="gold">
+						<el-input-number type="goldNum" v-model="formData.goldNum" :step="1" :min="1">
+						</el-input-number>
+						<div class="tip">输入规则:正整数,最小为1</div>
+					</el-form-item>
+					<el-form-item label="NFT入场配置">
+						<el-checkbox v-model="nft" @change="nftChange"> </el-checkbox>
+					</el-form-item>
+					<el-form-item prop="audit" label="是否需要审核" v-if="nft">
+						<el-radio-group v-model="formData.audit">
+							<el-radio :label="true"> 人工审核 </el-radio>
+							<el-radio :label="false"> 自动匹配 </el-radio>
+						</el-radio-group>
+					</el-form-item>
+					<el-form-item prop="collectionName" label="藏品名称" v-if="nft && formData.audit === true">
+						<el-input v-model="formData.collectionName" :disabled="!canEdit" class="width"> </el-input>
+					</el-form-item>
+					<el-form-item prop="rule" label="匹配规则设置" v-if="nft && formData.audit === false">
+						<template v-if="formData.rule && formData.rule.and">
+							<div v-for="(item, i) in formData.rule.and" class="rule-item">
+								<el-select v-model="item.detail.tag" value-key="id" size="mini">
+									<el-option v-for="item in tags" :key="item.id" :value="item" :label="item.name">
+									</el-option>
+								</el-select>
+								<span style="padding: 0 10px; color: #606266; font-weight: bold"> ×&nbsp;1 </span>
+								<i @click="delRule(i)" class="el-icon-delete icon-del"> </i>
+							</div>
+						</template>
+						<el-button size="mini" @click="addRule"> 添加 </el-button>
+					</el-form-item>
+					<el-form-item prop="num" label="所需nft数量" v-if="nft">
+						<el-input-number
+							type="number"
+							v-model="formData.num"
+							:disabled="!canEdit"
+							:step="1"
+							:min="0"
+							class="width1"
+						>
+						</el-input-number>
+						<div class="tip">0表示不限</div>
+					</el-form-item>
+					<el-form-item prop="detail" label="规则详情" style="width: calc(100vw - 450px)">
+						<el-input
+							v-model="formData.detail"
+							type="textarea"
+							:autosize="{ minRows: 3, maxRows: 20 }"
+							placeholder="请输入规则详情"
+						>
+						</el-input>
+					</el-form-item>
+					<el-form-item label="僵尸配置" prop="metaZombieIds">
+						<el-select v-model="formData.metaZombieIds" multiple placeholder="请选择" style="width: 100%">
+							<el-option v-for="item in metaZombie" :key="item.id" :label="item.name" :value="item.id">
+							</el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item prop="metaGameAwards" label="奖励配置" style="width: calc(100vw - 450px)" size="mini">
+						<el-table :data="formData.metaGameAwards">
+							<el-table-column prop="name" label="奖励名称">
+								<template v-slot="{ row }">
+									<el-input v-model="row.name" style="width: 250px" placeholder="请输入奖励名称">
+									</el-input>
+								</template>
+							</el-table-column>
+							<el-table-column prop="awardType" label="奖励类型">
+								<template v-slot="{ row }">
+									<el-select
+										v-model="row.awardType"
+										clearable
+										filterable
+										placeholder="请选择"
+										@change="changeAwardType(row)"
+									>
+										<el-option
+											v-for="item in entryModeTypeOptions"
+											:key="item.value"
+											:label="item.label"
+											:value="item.value"
+										>
+										</el-option>
+									</el-select>
+								</template>
+							</el-table-column>
+							<el-table-column prop="config" label="配置值(金币-数量/NFT-NFT图片)">
+								<template v-slot="{ row }">
+									<template v-if="row && row.awardType === 'GOLD'">
+										<el-input-number v-model="row.config" :step="1" :min="1"> </el-input-number>
+										<div class="tip">输入规则:正整数,最小为1</div>
+									</template>
+									<template v-if="row && row.awardType === 'NFT'">
+										<single-upload v-model="row.config"> </single-upload>
+									</template>
+								</template>
+							</el-table-column>
+							<el-table-column prop="probability" label="概率(%)">
+								<template v-slot="{ row }">
+									<el-input-number v-model="row.probability" :step="1" :min="1" :max="100">
+									</el-input-number>
+									<div class="tip">输入规则:正整数,最小为1,最大为100</div>
+								</template>
+							</el-table-column>
+							<el-table-column width="80" align="center">
+								<template v-slot="{ row, $index }">
+									<el-button type="danger" plain size="mini" @click="delAward($index)">
+										删除
+									</el-button>
+								</template>
+							</el-table-column>
+						</el-table>
+					</el-form-item>
+					<el-form-item>
+						<el-button size="mini" @click="addAward"> 添加配置 </el-button>
+					</el-form-item>
+					<el-form-item prop="publish" label="是否发布">
+						<el-switch v-model="formData.publish"> </el-switch>
+					</el-form-item>
+					<el-form-item class="form-submit">
+						<el-button @click="onSave" :loading="saving" type="primary"> 保存 </el-button>
+						<el-button @click="onDelete" :disabled="saving" type="danger" v-if="formData.id">
+							删除
+						</el-button>
+						<el-button @click="$router.go(-1)" :disabled="saving"> 取消 </el-button>
+					</el-form-item>
+				</el-form>
+			</div>
+		</div>
+	</div>
 </template>
 <script>
 export default {
-    name: 'MetaGameCopyEdit',
-    created() {
-        if (this.$route.query.id) {
-            this.$http
-                .get('metaGameCopy/get/' + this.$route.query.id)
-                .then(res => {
-                    res.metaGameAwards = res.metaGameAwards || [];
-                    this.formData = res;
-                })
-                .catch(e => {
-                    console.log(e);
-                    this.$message.error(e.error);
-                });
-        }
-        this.$http.post('/tag/all', { size: 10000 }, { body: 'json' }).then(res => {
-            this.tags = res.content;
-        });
-        this.$http.get('/metaZombie/findAll').then(res => {
-            this.metaZombie = res;
-        });
-    },
-    data() {
-        return {
-            reg: /^[1-9]\d*$/,
-            awardType: [],
-            metaZombie: [],
-            tags: [],
-            saving: false,
-            formData: {
-                metaGameAwards: []
-            },
-            rules: {
-                detail: [
-                    {
-                        required: true,
-                        message: '请输入规则详情',
-                        trigger: 'blur'
-                    }
-                ],
-                gameName: [
-                    {
-                        required: true,
-                        message: '请选择游戏',
-                        trigger: 'blur'
-                    }
-                ],
-                gameCopyType: [
-                    {
-                        required: true,
-                        message: '请选择副本',
-                        trigger: 'blur'
-                    }
-                ],
-                entryModeType: [
-                    {
-                        required: true,
-                        message: '请选择入场方式',
-                        trigger: 'blur'
-                    }
-                ],
-                goldNum: [
-                    {
-                        required: true,
-                        message: '请输入所需金币数量',
-                        trigger: 'blur'
-                    },
-                    {
-                        validator: (rule, value, callback) => {
-                            if (!this.reg.test(value)) {
-                                callback(new Error('所需金币数量必须为大于1的整数'));
-                                return;
-                            } else {
-                                callback();
-                            }
-                        }
-                    }
-                ],
-                rule: [
-                    { required: true, message: '请选择规则', trigger: 'blur' },
-                    {
-                        validator: (rule, value, callback) => {
-                            if (!this.formData.audit) {
-                                if (!this.formData.rule) {
-                                    callback(new Error('请填写规则'));
-                                } else if (!this.formData.rule.and) {
-                                    callback(new Error('请填写规则'));
-                                } else if (!this.formData.rule.and.length) {
-                                    callback(new Error('请填写规则'));
-                                } else {
-                                    for (let i = 0; i < this.formData.rule.and.length; i++) {
-                                        if (
-                                            !(this.formData.rule.and[i].detail && this.formData.rule.and[i].detail.tag)
-                                        ) {
-                                            callback(new Error('请选择'));
-                                            callback = null;
-                                            break;
-                                        }
-                                    }
-                                    if (callback) {
-                                        callback();
-                                    }
-                                }
-                            } else {
-                                callback();
-                            }
-                        }
-                    }
-                ],
-                metaGameAwards: [
-                    {
-                        validator: (rule, value, callback) => {
-                            if (value) {
-                                if (!(value instanceof Array)) {
-                                    callback(new Error('metaGameAwards must be array!'));
-                                    return;
-                                } else {
-                                    for (let i = 0; i < value.length; i++) {
-                                        if (
-                                            value[i].name === '' ||
-                                            value[i].name === undefined ||
-                                            value[i].name === null
-                                        ) {
-                                            callback(new Error('请填写奖励名称'));
-                                            return;
-                                        }
-                                        if (
-                                            value[i].awardType === '' ||
-                                            value[i].awardType === undefined ||
-                                            value[i].awardType === null
-                                        ) {
-                                            callback(new Error('请选择奖励类型'));
-                                            return;
-                                        }
-                                        if (
-                                            value[i].config === '' ||
-                                            value[i].config === undefined ||
-                                            value[i].config === null
-                                        ) {
-                                            callback(new Error('请填写奖励配置'));
-                                            return;
-                                        }
-                                        if (value[i].awardType === 'GOLD' && !this.reg.test(value[i].config)) {
-                                            callback(new Error('奖励金币数量必须为大于1的整数'));
-                                            return;
-                                        }
-                                        if (
-                                            value[i].probability === '' ||
-                                            value[i].probability === undefined ||
-                                            value[i].probability === null
-                                        ) {
-                                            callback(new Error('请填写奖励概率'));
-                                            return;
-                                        }
-                                        if (!this.reg.test(value[i].probability)) {
-                                            callback(new Error('奖励概率必须为大于1的整数'));
-                                            return;
-                                        }
-                                    }
-                                }
-                            }
-                            callback();
-                        },
-                        trigger: 'blur'
-                    }
-                ],
-                audit: [
-                    {
-                        required: true,
-                        message: '请选择是否审核',
-                        trigger: 'blur'
-                    }
-                ],
-                collectionName: [
-                    {
-                        required: true,
-                        message: '请输入藏品名称',
-                        trigger: 'blur'
-                    }
-                ],
-                num: [
-                    {
-                        required: true,
-                        message: '请输入所需nft数量',
-                        trigger: 'blur'
-                    }
-                ]
-            },
-            gameNameOptions: [{ label: '僵尸', value: 'ZOMBIE' }],
-            gameCopyTypeOptions: [
-                { label: '青铜', value: 'BRONZE' },
-                { label: '白银', value: 'SILVER' },
-                { label: '黄金', value: 'GOLD' }
-            ],
-            entryModeTypeOptions: [
-                { label: 'NFT', value: 'NFT' },
-                { label: '金币', value: 'GOLD' }
-            ]
-        };
-    },
-    computed: {
-        canEdit() {
-            return !!!this.$route.query.id;
-        }
-    },
-    methods: {
-        changeAwardType(row) {
-            row.config = '';
-        },
-        onSave() {
-            this.$refs.form.validate(valid => {
-                if (valid) {
-                    this.submit();
-                } else {
-                    return false;
-                }
-            });
-        },
-        submit() {
-            let data = { ...this.formData };
-            this.saving = true;
-            this.$http
-                .post('/metaGameCopy/save', data, { body: 'json' })
-                .then(res => {
-                    this.saving = false;
-                    this.$message.success('成功');
-                    this.$router.go(-1);
-                })
-                .catch(e => {
-                    console.log(e);
-                    this.saving = false;
-                    this.$message.error(e.error);
-                });
-        },
-        onDelete() {
-            this.$confirm('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
-                .then(() => {
-                    return this.$http.post(`/metaGameCopy/del/${this.formData.id}`);
-                })
-                .then(() => {
-                    this.$message.success('删除成功');
-                    this.$router.go(-1);
-                })
-                .catch(e => {
-                    if (e !== 'cancel') {
-                        console.log(e);
-                        this.$message.error((e || {}).error || '删除失败');
-                    }
-                });
-        },
-        addRule() {
-            if (!(this.formData.rule && this.formData.rule.and)) {
-                this.$set(this.formData, 'rule', { and: [] });
-            }
-            this.formData.rule.and.push({ detail: { tag: null, num: 1 } });
-        },
-        delRule(i) {
-            this.formData.rule.and.splice(i, 1);
-        },
-        addAward() {
-            this.formData.metaGameAwards.push({
-                awardType: '',
-                config: '',
-                probability: ''
-            });
-        },
-        delAward(i) {
-            this.formData.metaGameAwards.splice(i, 1);
-        }
-    }
+	name: 'MetaGameCopyEdit',
+	created() {
+		if (this.$route.query.id) {
+			this.$http
+				.get('metaGameCopy/get/' + this.$route.query.id)
+				.then(res => {
+					res.metaGameAwards = res.metaGameAwards || [];
+					this.formData = res;
+					if (res.entryModeType === 'GOLD') {
+						this.gold = true;
+						this.nft = false;
+					} else if (res.entryModeType === 'NFT') {
+						this.gold = false;
+						this.nft = true;
+					} else if (res.entryModeType === 'GOLD_OR_NFT') {
+						this.gold = true;
+						this.nft = true;
+					}
+				})
+				.catch(e => {
+					console.log(e);
+					this.$message.error(e.error);
+				});
+		}
+		this.$http.post('/tag/all', { size: 10000 }, { body: 'json' }).then(res => {
+			this.tags = res.content;
+		});
+		this.$http.get('/metaZombie/findAll').then(res => {
+			this.metaZombie = res;
+		});
+	},
+	data() {
+		return {
+			nft: false,
+			gold: false,
+			reg: /^[1-9]\d*$/,
+			awardType: [],
+			metaZombie: [],
+			tags: [],
+			saving: false,
+			formData: {
+				metaGameAwards: []
+			},
+			rules: {
+				detail: [
+					{
+						required: true,
+						message: '请输入规则详情',
+						trigger: 'blur'
+					}
+				],
+				gameName: [
+					{
+						required: true,
+						message: '请选择游戏',
+						trigger: 'blur'
+					}
+				],
+				gameCopyType: [
+					{
+						required: true,
+						message: '请选择副本',
+						trigger: 'blur'
+					}
+				],
+				goldNum: [
+					{
+						required: true,
+						message: '请输入所需金币数量',
+						trigger: 'blur'
+					},
+					{
+						validator: (rule, value, callback) => {
+							if (!this.reg.test(value)) {
+								callback(new Error('所需金币数量必须为大于1的整数'));
+								return;
+							} else {
+								callback();
+							}
+						}
+					}
+				],
+				rule: [
+					{ required: true, message: '请选择规则', trigger: 'blur' },
+					{
+						validator: (rule, value, callback) => {
+							if (!this.formData.audit) {
+								if (!this.formData.rule) {
+									callback(new Error('请填写规则'));
+								} else if (!this.formData.rule.and) {
+									callback(new Error('请填写规则'));
+								} else if (!this.formData.rule.and.length) {
+									callback(new Error('请填写规则'));
+								} else {
+									for (let i = 0; i < this.formData.rule.and.length; i++) {
+										if (
+											!(this.formData.rule.and[i].detail && this.formData.rule.and[i].detail.tag)
+										) {
+											callback(new Error('请选择'));
+											callback = null;
+											break;
+										}
+									}
+									if (callback) {
+										callback();
+									}
+								}
+							} else {
+								callback();
+							}
+						}
+					}
+				],
+				metaGameAwards: [
+					{
+						validator: (rule, value, callback) => {
+							if (value) {
+								if (!(value instanceof Array)) {
+									callback(new Error('metaGameAwards must be array!'));
+									return;
+								} else {
+									for (let i = 0; i < value.length; i++) {
+										if (
+											value[i].name === '' ||
+											value[i].name === undefined ||
+											value[i].name === null
+										) {
+											callback(new Error('请填写奖励名称'));
+											return;
+										}
+										if (
+											value[i].awardType === '' ||
+											value[i].awardType === undefined ||
+											value[i].awardType === null
+										) {
+											callback(new Error('请选择奖励类型'));
+											return;
+										}
+										if (
+											value[i].config === '' ||
+											value[i].config === undefined ||
+											value[i].config === null
+										) {
+											callback(new Error('请填写奖励配置'));
+											return;
+										}
+										if (value[i].awardType === 'GOLD' && !this.reg.test(value[i].config)) {
+											callback(new Error('奖励金币数量必须为大于1的整数'));
+											return;
+										}
+										if (
+											value[i].probability === '' ||
+											value[i].probability === undefined ||
+											value[i].probability === null
+										) {
+											callback(new Error('请填写奖励概率'));
+											return;
+										}
+										if (!this.reg.test(value[i].probability)) {
+											callback(new Error('奖励概率必须为大于1的整数'));
+											return;
+										}
+									}
+								}
+							}
+							callback();
+						},
+						trigger: 'blur'
+					}
+				],
+				audit: [
+					{
+						required: true,
+						message: '请选择是否审核',
+						trigger: 'blur'
+					}
+				],
+				collectionName: [
+					{
+						required: true,
+						message: '请输入藏品名称',
+						trigger: 'blur'
+					}
+				],
+				num: [
+					{
+						required: true,
+						message: '请输入所需nft数量',
+						trigger: 'blur'
+					}
+				]
+			},
+			gameNameOptions: [{ label: '僵尸', value: 'ZOMBIE' }],
+			gameCopyTypeOptions: [
+				{ label: '青铜', value: 'BRONZE' },
+				{ label: '白银', value: 'SILVER' },
+				{ label: '黄金', value: 'GOLD' }
+			],
+			entryModeTypeOptions: [
+				{ label: 'NFT', value: 'NFT' },
+				{ label: '金币', value: 'GOLD' }
+			]
+		};
+	},
+	computed: {
+		canEdit() {
+			return !!!this.$route.query.id;
+		}
+	},
+	methods: {
+		goldChange() {
+			this.$delete(this.formData, 'goldNum');
+		},
+		nftChange() {
+			this.$delete(this.formData, 'audit');
+			this.$delete(this.formData, 'collectionName');
+			this.$delete(this.formData, 'rule');
+			this.$delete(this.formData, 'num');
+		},
+		changeAwardType(row) {
+			row.config = '';
+		},
+		onSave() {
+			this.$refs.form.validate(valid => {
+				if (valid) {
+					this.submit();
+				} else {
+					return false;
+				}
+			});
+		},
+		submit() {
+			let data = { ...this.formData };
+			if (this.gold && !this.nft) {
+				data.entryModeType = 'GOLD';
+			} else if (!this.gold && this.nft) {
+				data.entryModeType = 'NFT';
+			} else if (this.gold && this.nft) {
+				data.entryModeType = 'GOLD_OR_NFT';
+			} else if (!this.gold && !this.nft) {
+				this.$message.error('请最少配置一个入场方式');
+                return;
+			}
+			this.saving = true;
+			this.$http
+				.post('/metaGameCopy/save', data, { body: 'json' })
+				.then(res => {
+					this.saving = false;
+					this.$message.success('成功');
+					this.$router.go(-1);
+				})
+				.catch(e => {
+					console.log(e);
+					this.saving = false;
+					this.$message.error(e.error);
+				});
+		},
+		onDelete() {
+			this.$confirm('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+				.then(() => {
+					return this.$http.post(`/metaGameCopy/del/${this.formData.id}`);
+				})
+				.then(() => {
+					this.$message.success('删除成功');
+					this.$router.go(-1);
+				})
+				.catch(e => {
+					if (e !== 'cancel') {
+						console.log(e);
+						this.$message.error((e || {}).error || '删除失败');
+					}
+				});
+		},
+		addRule() {
+			if (!(this.formData.rule && this.formData.rule.and)) {
+				this.$set(this.formData, 'rule', { and: [] });
+			}
+			this.formData.rule.and.push({ detail: { tag: null, num: 1 } });
+		},
+		delRule(i) {
+			this.formData.rule.and.splice(i, 1);
+		},
+		addAward() {
+			this.formData.metaGameAwards.push({
+				awardType: '',
+				config: '',
+				probability: ''
+			});
+		},
+		delAward(i) {
+			this.formData.metaGameAwards.splice(i, 1);
+		}
+	}
 };
 </script>
 <style lang="less" scoped>
 .width1 {
-	width: 150px;
+    width: 150px;
 }
 
 .rule-item {
-	display: flex;
-	align-items: center;
-	margin-bottom: 10px;
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
 
-	.icon-del {
-		color: #f56c6c;
-		cursor: pointer;
-		font-size: 18px;
-	}
+    .icon-del {
+        color: #f56c6c;
+        cursor: pointer;
+        font-size: 18px;
+    }
 }
 </style>

+ 2 - 1
src/main/vue/src/views/MetaGameCopyList.vue

@@ -119,7 +119,8 @@ export default {
 			],
 			entryModeTypeOptions: [
 				{ label: 'NFT', value: 'NFT' },
-				{ label: '金币', value: 'GOLD' }
+				{ label: '金币', value: 'GOLD' },
+				{ label: '金币或NFT', value: 'GOLD_OR_NFT' },
 			]
 		};
 	},

+ 72 - 2
src/main/vue/src/views/MetaTaskEdit.vue

@@ -28,9 +28,39 @@
 						>
 						</el-input>
 					</el-form-item>
-					<el-form-item prop="awardPic" label="奖励图片">
+					<el-form-item prop="awardType" label="奖励类型">
+						<el-select
+							v-model="formData.awardType"
+							clearable
+							filterable
+							placeholder="请选择"
+							@change="changeAwardType"
+						>
+							<el-option
+								v-for="item in awardTypeOptions"
+								:key="item.value"
+								:label="item.label"
+								:value="item.value"
+							>
+							</el-option>
+						</el-select>
+					</el-form-item>
+					<el-form-item
+						prop="awardPic"
+						label="奖励图片"
+						v-if="formData.awardType && formData.awardType === 'NFT'"
+					>
 						<single-upload v-model="formData.awardPic"> </single-upload>
 					</el-form-item>
+					<el-form-item
+						prop="goldNum"
+						label="奖励金币数量"
+						v-if="formData.awardType && formData.awardType === 'GOLD'"
+					>
+						<el-input-number type="goldNum" v-model="formData.goldNum" :step="1" :min="1">
+						</el-input-number>
+						<div class="tip">输入规则:正整数,最小为1</div>
+					</el-form-item>
 					<el-form-item prop="type" label="任务类型">
 						<el-select v-model="formData.type" clearable filterable placeholder="请选择" @change="change">
 							<el-option
@@ -108,6 +138,7 @@ export default {
 	},
 	data() {
 		return {
+			reg: /^[1-9]\d*$/,
 			saving: false,
 			formData: {},
 			rules: {
@@ -138,6 +169,37 @@ export default {
 						message: '请指定参数配置',
 						trigger: 'blur'
 					}
+				],
+				goldNum: [
+					{
+						required: true,
+						message: '请输入奖励金币数量',
+						trigger: 'blur'
+					},
+					{
+						validator: (rule, value, callback) => {
+							if (!this.reg.test(value)) {
+								callback(new Error('奖励金币数量必须为大于1的整数'));
+								return;
+							} else {
+								callback();
+							}
+						}
+					}
+				],
+				awardType: [
+					{
+						required: true,
+						message: '请选择奖励类型',
+						trigger: 'blur'
+					}
+				],
+				awardPic: [
+					{
+						required: true,
+						message: '请上传奖励图片',
+						trigger: 'blur'
+					}
 				]
 			},
 			typeOptions: [
@@ -146,13 +208,21 @@ export default {
 				{ label: '收集藏品', value: 'COLLECT_COLLECTION' },
 				{ label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
 				{ label: '累计', value: 'ACCUMULATE' }
+			],
+			awardTypeOptions: [
+				{ label: 'NFT', value: 'NFT' },
+				{ label: '金币', value: 'GOLD' }
 			]
 		};
 	},
 	methods: {
+		changeAwardType(row) {
+			this.$delete(this.formData, 'awardPic');
+			this.$delete(this.formData, 'goldNum');
+		},
 		change() {
 			if (this.formData.value) {
-				this.formData.value = undefined;
+				this.$delete(this.formData, 'value');
 			}
 		},
 		onSave() {

+ 236 - 219
src/main/vue/src/views/MetaTaskList.vue

@@ -1,231 +1,248 @@
 <template>
-	<div class="list-view">
-		<page-title>
-			<el-button
-				@click="addRow"
-				type="primary"
-				icon="el-icon-plus"
-				:disabled="fetchingData || downloading"
-				class="filter-item"
-			>
-				新增
-			</el-button>
-			<el-button
-				@click="download"
-				icon="el-icon-upload2"
-				:loading="downloading"
-				:disabled="fetchingData"
-				class="filter-item"
-			>
-				导出
-			</el-button>
-		</page-title>
-		<div class="filters-container">
-			<el-input
-				placeholder="搜索..."
-				v-model="search"
-				clearable
-				class="filter-item search"
-				@keyup.enter.native="getData"
-			>
-				<el-button @click="getData" slot="append" icon="el-icon-search"> </el-button>
-			</el-input>
-		</div>
-		<el-table
-			:data="tableData"
-			row-key="id"
-			ref="table"
-			header-row-class-name="table-header-row"
-			header-cell-class-name="table-header-cell"
-			row-class-name="table-row"
-			cell-class-name="table-cell"
-			:height="tableHeight"
-			v-loading="fetchingData"
-		>
-			<el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
-			<el-table-column prop="id" label="ID" width="100"> </el-table-column>
-			<el-table-column prop="createdAt" label="创建时间"> </el-table-column>
-			<el-table-column prop="name" label="任务名称"> </el-table-column>
-			<el-table-column prop="type" label="任务类型" :formatter="typeFormatter"> </el-table-column>
-			<el-table-column prop="value" label="配置值"> </el-table-column>
-			<el-table-column prop="detail" label="详情"> </el-table-column>
-			<el-table-column prop="awardPic" label="奖励图片">
-				<template slot-scope="{ row }">
-					<el-image
-						style="width: 30px; height: 30px"
-						:src="row.awardPic"
-						fit="cover"
-						:preview-src-list="[row.awardPic]"
-					>
-					</el-image>
-				</template>
-			</el-table-column>
-			<el-table-column prop="publish" label="是否发布">
-				<template slot-scope="{ row }">
-					<el-tag :type="row.publish ? '' : 'info'"> {{ row.publish }} </el-tag>
-				</template>
-			</el-table-column>
-			<el-table-column prop="mark" label="是否展示角标">
-				<template slot-scope="{ row }">
-					<el-tag :type="row.mark ? '' : 'info'"> {{ row.mark }} </el-tag>
-				</template>
-			</el-table-column>
+    <div class="list-view">
+        <page-title>
+            <el-button
+                @click="addRow"
+                type="primary"
+                icon="el-icon-plus"
+                :disabled="fetchingData || downloading"
+                class="filter-item"
+            >
+                新增
+            </el-button>
+            <el-button
+                @click="download"
+                icon="el-icon-upload2"
+                :loading="downloading"
+                :disabled="fetchingData"
+                class="filter-item"
+            >
+                导出
+            </el-button>
+        </page-title>
+        <div class="filters-container">
+            <el-input
+                placeholder="搜索..."
+                v-model="search"
+                clearable
+                class="filter-item search"
+                @keyup.enter.native="getData"
+            >
+                <el-button @click="getData" slot="append" icon="el-icon-search"> </el-button>
+            </el-input>
+        </div>
+        <el-table
+            :data="tableData"
+            row-key="id"
+            ref="table"
+            header-row-class-name="table-header-row"
+            header-cell-class-name="table-header-cell"
+            row-class-name="table-row"
+            cell-class-name="table-cell"
+            :height="tableHeight"
+            v-loading="fetchingData"
+        >
+            <el-table-column v-if="multipleMode" align="center" type="selection" width="50"> </el-table-column>
+            <el-table-column prop="id" label="ID" width="100"> </el-table-column>
+            <el-table-column prop="createdAt" label="创建时间"> </el-table-column>
+            <el-table-column prop="name" label="任务名称"> </el-table-column>
+            <el-table-column prop="type" label="任务类型" :formatter="typeFormatter"> </el-table-column>
+            <el-table-column prop="value" label="配置值"> </el-table-column>
+            <el-table-column prop="detail" label="详情"> </el-table-column>
+            <el-table-column prop="awardType" label="奖励金币数量" :formatter="awardTypeFormatter"> </el-table-column>
+            <el-table-column prop="awardPic" label="奖励图片">
+                <template slot-scope="{ row }">
+                    <el-image
+                        style="width: 30px; height: 30px"
+                        :src="row.awardPic"
+                        fit="cover"
+                        :preview-src-list="[row.awardPic]"
+                    >
+                    </el-image>
+                </template>
+            </el-table-column>
+            <el-table-column prop="goldNum" label="奖励金币数量"> </el-table-column>
+            <el-table-column prop="publish" label="是否发布">
+                <template slot-scope="{ row }">
+                    <el-tag :type="row.publish ? '' : 'info'"> {{ row.publish }} </el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column prop="mark" label="是否展示角标">
+                <template slot-scope="{ row }">
+                    <el-tag :type="row.mark ? '' : 'info'"> {{ row.mark }} </el-tag>
+                </template>
+            </el-table-column>
             <el-table-column prop="finish" label="是否结束">
-				<template slot-scope="{ row }">
-					<el-tag :type="row.finish ? '' : 'info'"> {{ row.finish }} </el-tag>
-				</template>
-			</el-table-column>
-			<el-table-column label="操作" align="center" fixed="right" width="250">
-				<template slot-scope="{ row }">
-					<el-button @click="editRow(row)" type="primary" size="mini" plain v-if="!row.finish"> 编辑 </el-button>
-					<el-button @click="deleteRow(row)" type="danger" size="mini" plain> 删除 </el-button>
-                    <el-button @click="finish(row)" type="danger" size="mini" plain v-if="!row.finish"> 结束任务 </el-button>
-				</template>
-			</el-table-column>
-		</el-table>
-		<div class="pagination-wrapper">
-			<el-pagination
-				background
-				@size-change="onSizeChange"
-				@current-change="onCurrentChange"
-				:current-page="page"
-				:page-sizes="[10, 20, 30, 40, 50]"
-				:page-size="pageSize"
-				layout="total, sizes, prev, pager, next, jumper"
-				:total="totalElements"
-			>
-			</el-pagination>
-		</div>
-	</div>
+                <template slot-scope="{ row }">
+                    <el-tag :type="row.finish ? '' : 'info'"> {{ row.finish }} </el-tag>
+                </template>
+            </el-table-column>
+            <el-table-column label="操作" align="center" fixed="right" width="250">
+                <template slot-scope="{ row }">
+                    <el-button @click="editRow(row)" type="primary" size="mini" plain v-if="!row.finish">
+                        编辑
+                    </el-button>
+                    <el-button @click="deleteRow(row)" type="danger" size="mini" plain> 删除 </el-button>
+                    <el-button @click="finish(row)" type="danger" size="mini" plain v-if="!row.finish">
+                        结束任务
+                    </el-button>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div class="pagination-wrapper">
+            <el-pagination
+                background
+                @size-change="onSizeChange"
+                @current-change="onCurrentChange"
+                :current-page="page"
+                :page-sizes="[10, 20, 30, 40, 50]"
+                :page-size="pageSize"
+                layout="total, sizes, prev, pager, next, jumper"
+                :total="totalElements"
+            >
+            </el-pagination>
+        </div>
+    </div>
 </template>
 <script>
 import { mapState } from 'vuex';
 import pageableTable from '@/mixins/pageableTable';
 
 export default {
-	name: 'MetaTaskList',
-	mixins: [pageableTable],
-	data() {
-		return {
-			multipleMode: false,
-			search: '',
-			url: '/metaTask/all',
-			downloading: false,
-			typeOptions: [
-				{ label: '单日签到', value: 'SIGN_IN_SINGLE_DAY' },
-				{ label: '连续多日签到', value: 'SIGN_IN_CONTINUOUS' },
-				{ label: '收集藏品', value: 'COLLECT_COLLECTION' },
-				{ label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
-				{ label: '累计', value: 'ACCUMULATE' }
-			]
-		};
-	},
-	computed: {
-		selection() {
-			return this.$refs.table.selection.map(i => i.id);
-		}
-	},
-	methods: {
-		typeFormatter(row, column, cellValue, index) {
-			let selectedOption = this.typeOptions.find(i => i.value === cellValue);
-			if (selectedOption) {
-				return selectedOption.label;
-			}
-			return '';
-		},
-		beforeGetData() {
-			return { search: this.search, query: { del: false } };
-		},
-		toggleMultipleMode(multipleMode) {
-			this.multipleMode = multipleMode;
-			if (!multipleMode) {
-				this.$refs.table.clearSelection();
-			}
-		},
-		addRow() {
-			this.$router.push({
-				path: '/metaTaskEdit',
-				query: {
-					...this.$route.query
-				}
-			});
-		},
-		editRow(row) {
-			this.$router.push({
-				path: '/metaTaskEdit',
-				query: {
-					id: row.id
-				}
-			});
-		},
-		download() {
-			this.downloading = true;
-			this.$axios
-				.get('/metaTask/excel', {
-					responseType: 'blob',
-					params: { size: 10000 ,query: { del: false }},
-				})
-				.then(res => {
-					console.log(res);
-					this.downloading = false;
-					const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
-					const link = document.createElement('a');
-					link.href = downloadUrl;
-					link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
-					document.body.appendChild(link);
-					link.click();
-					link.remove();
-				})
-				.catch(e => {
-					console.log(e);
-					this.downloading = false;
-					this.$message.error(e.error);
-				});
-		},
-		operation1() {
-			this.$notify({
-				title: '提示',
-				message: this.selection
-			});
-		},
-		operation2() {
-			this.$message('操作2');
-		},
-		deleteRow(row) {
-			if(!row.finish) {
-				this.$alert('请先结束任务!', '警告', { type: 'error' })
-				return;
-			}
-			this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
-				.then(() => {
-					return this.$http.post(`/metaTask/del/${row.id}`);
-				})
-				.then(() => {
-					this.$message.success('删除成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		},
+    name: 'MetaTaskList',
+    mixins: [pageableTable],
+    data() {
+        return {
+            multipleMode: false,
+            search: '',
+            url: '/metaTask/all',
+            downloading: false,
+            typeOptions: [
+                { label: '单日签到', value: 'SIGN_IN_SINGLE_DAY' },
+                { label: '连续多日签到', value: 'SIGN_IN_CONTINUOUS' },
+                { label: '收集藏品', value: 'COLLECT_COLLECTION' },
+                { label: '每日在线时长', value: 'ON_LINE_TIME_DAILY' },
+                { label: '累计', value: 'ACCUMULATE' }
+            ],
+            awardTypeOptions: [
+                { label: 'NFT', value: 'NFT' },
+                { label: '金币', value: 'GOLD' }
+            ]
+        };
+    },
+    computed: {
+        selection() {
+            return this.$refs.table.selection.map(i => i.id);
+        }
+    },
+    methods: {
+        typeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.typeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        awardTypeFormatter(row, column, cellValue, index) {
+            let selectedOption = this.awardTypeOptions.find(i => i.value === cellValue);
+            if (selectedOption) {
+                return selectedOption.label;
+            }
+            return '';
+        },
+        beforeGetData() {
+            return { search: this.search, query: { del: false } };
+        },
+        toggleMultipleMode(multipleMode) {
+            this.multipleMode = multipleMode;
+            if (!multipleMode) {
+                this.$refs.table.clearSelection();
+            }
+        },
+        addRow() {
+            this.$router.push({
+                path: '/metaTaskEdit',
+                query: {
+                    ...this.$route.query
+                }
+            });
+        },
+        editRow(row) {
+            this.$router.push({
+                path: '/metaTaskEdit',
+                query: {
+                    id: row.id
+                }
+            });
+        },
+        download() {
+            this.downloading = true;
+            this.$axios
+                .get('/metaTask/excel', {
+                    responseType: 'blob',
+                    params: { size: 10000, query: { del: false } }
+                })
+                .then(res => {
+                    console.log(res);
+                    this.downloading = false;
+                    const downloadUrl = window.URL.createObjectURL(new Blob([res.data]));
+                    const link = document.createElement('a');
+                    link.href = downloadUrl;
+                    link.setAttribute('download', res.headers['content-disposition'].split('filename=')[1]);
+                    document.body.appendChild(link);
+                    link.click();
+                    link.remove();
+                })
+                .catch(e => {
+                    console.log(e);
+                    this.downloading = false;
+                    this.$message.error(e.error);
+                });
+        },
+        operation1() {
+            this.$notify({
+                title: '提示',
+                message: this.selection
+            });
+        },
+        operation2() {
+            this.$message('操作2');
+        },
+        deleteRow(row) {
+            if (!row.finish) {
+                this.$alert('请先结束任务!', '警告', { type: 'error' });
+                return;
+            }
+            this.$alert('删除将无法恢复,确认要删除么?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/metaTask/del/${row.id}`);
+                })
+                .then(() => {
+                    this.$message.success('删除成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        },
         finish(row) {
-			this.$alert('任务结束后在不能再被领取,确定要结束任务吗?', '警告', { type: 'error' })
-				.then(() => {
-					return this.$http.post(`/metaTask/${row.id}/finish`);
-				})
-				.then(() => {
-					this.$message.success('结束成功');
-					this.getData();
-				})
-				.catch(e => {
-					if (e !== 'cancel') {
-						this.$message.error(e.error);
-					}
-				});
-		}
-	}
+            this.$alert('任务结束后在不能再被领取,确定要结束任务吗?', '警告', { type: 'error' })
+                .then(() => {
+                    return this.$http.post(`/metaTask/${row.id}/finish`);
+                })
+                .then(() => {
+                    this.$message.success('结束成功');
+                    this.getData();
+                })
+                .catch(e => {
+                    if (e !== 'cancel') {
+                        this.$message.error(e.error);
+                    }
+                });
+        }
+    }
 };
 </script>
 <style lang="less" scoped>