cm 1 year ago
parent
commit
f1decfb6df

+ 5 - 0
src/api/request.ts

@@ -5,7 +5,12 @@ import { useUserStore } from "@/store/modules/user"
 const service = axios.create({
     // 默认请求地址,根据环境的不同可在.env 文件中进行修改
     // baseURL: import.meta.env.VUE_APP_BASE_
+<<<<<<< HEAD
     baseURL: "http://127.0.0.1:8001",
+=======
+    // baseURL: "http://192.168.123.216:8001",
+    baseURL: "http://localhost:8001",
+>>>>>>> 83777844e09988e24905ecf02745f7a18b021ade
     // 设置接口访问超时时间
     timeout: 3000000, // request timeout,
     // 跨域时候允许携带凭证

+ 35 - 0
src/api/server.ts

@@ -0,0 +1,35 @@
+import request from './request'
+
+
+export default {
+    getAll(data) {
+        return request({
+            url: '/server/all/' + data,
+            method: 'get'
+        });
+    },
+
+    update(data) {
+        return request({
+            url: '/server/update',
+            method: 'put',
+            data
+        });
+    },
+
+    updateBatch(data) {
+        return request({
+            url: '/server/update_batch',
+            method: 'put',
+            data
+        });
+    },
+
+    delete(data) {
+        return request({
+            url: '/server/delete',
+            method: 'delete',
+            data
+        });
+    }
+}

+ 2 - 9
src/routers/index.ts

@@ -22,11 +22,9 @@ import playerInfo from './modules/player'
 import serverRouter from './modules/server'
 import operationRouter from './modules/operation'
 
-
-
 // 异步组件
-// export const asyncRoutes = [
-//     ...dataScreenRouter,
+export const asyncRoutes = [
+
 //     ...echartsRouter,
 //     ...tableRouter,
 //     ...formRouter,
@@ -36,11 +34,6 @@ import operationRouter from './modules/operation'
 //     ...nestedRouter,
 //     ...excelRouter,
 //     ...externalLink,
-//     ...systemRouter,
-//     ...playerInfo,
-// ]
-
-export const asyncRoutes = [
 
   ...playerInfo,
   ...dataScreenRouter,

+ 35 - 14
src/routers/modules/operation.ts

@@ -10,34 +10,34 @@ const operationRouter = [{
     name: 'operation',
     meta: {
         title: '运营工具',
-        icon: 'School'
+        icon: 'Tools'
     },
     children: [
         {
             path: '/operation/giftcode',
             component: () => import('@/views/operation/giftcode/index.vue'),
             name: 'giftcode',
-            meta: { title: '礼包码', icon: 'MenuIcon'},
+            meta: { title: '礼包码', icon: 'Present'},
             alwaysShow:true,
             redirect: '/views/operation/giftcode/fixedGeneration',
             children: [
+                // {
+                //   path: '/views/operation/giftcode/fixedGeneration',
+                //   component: () => import('@/views/operation/giftcode/fixedGeneration/index.vue'),
+                //   name: 'fixedGeneration',
+                //   meta: { title: '固定生成'}
+                // },
                 {
-                  path: '/views/operation/giftcode/fixedGeneration',
-                  component: () => import('@/views/operation/giftcode/fixedGeneration/index.vue'),
-                  name: 'fixedGeneration',
-                  meta: { title: '固定生成' , icon: 'MenuIcon'}
-                },
-                {
-                    path: '/views/operation/giftcode/randomGeneration',
-                    component: () => import('@/views/operation/giftcode/randomGeneration/index.vue'),
-                    name: 'randomGeneration',
-                    meta: { title: '随机生成' , icon: 'MenuIcon'}
+                    path: '/views/operation/giftcode/batchGeneration',
+                    component: () => import('@/views/operation/giftcode/batchGeneration/index.vue'),
+                    name: 'batchGeneration',
+                    meta: { title: '批量生成', icon: 'CirclePlus'}
                   },
                   {
                     path: '/views/operation/giftcode/listTable',
                     component: () => import('@/views/operation/giftcode/listTable/index.vue'),
                     name: 'listTable',
-                    meta: { title: '信息列表' , icon: 'MenuIcon'}
+                    meta: { title: '礼包码列表', icon: 'List'}
                   },
             ]
         },
@@ -45,8 +45,9 @@ const operationRouter = [{
             path: '/operation/whitelist',
             component: () => import('@/views/operation/whitelist/index.vue'),
             name: 'whitelist',
-            meta: { title: '白名单', keepAlive: true , icon: 'MenuIcon'}
+            meta: { title: '白名单', keepAlive: true , icon: 'User'}
         },
+<<<<<<< HEAD
         // {
         //     path: '/operation/sendmail',
         //     component: () => import('@/views/operation/sendmail/index.vue'),
@@ -59,6 +60,26 @@ const operationRouter = [{
         //     name: 'notice',
         //     meta: { title: '游戏公告', keepAlive: true  , icon: 'MenuIcon'}
         // },
+=======
+        {
+            path: '/operation/gmmail',
+            component: () => import('@/views/operation/gmmail/index.vue'),
+            name: 'gmmail',
+            meta: { title: 'GM邮件', keepAlive: true , icon: 'Message'}
+        },
+        {
+            path: '/operation/announcement',
+            component: () => import('@/views/operation/announcement/index.vue'),
+            name: 'announcement',
+            meta: { title: '游戏公告', keepAlive: true  , icon: 'Notification'}
+        },
+        {
+          path: '/operation/sendcmd',
+          component: () => import('@/views/operation/sendcmd/index.vue'),
+          name: 'sendcmd',
+          meta: { title: '发送命令', keepAlive: true  , icon: 'Monitor'}
+      },
+>>>>>>> 83777844e09988e24905ecf02745f7a18b021ade
     ]
 }]
 

+ 1 - 1
src/routers/modules/server.ts

@@ -10,7 +10,7 @@ const serverRouter = [{
     name: 'server',
     meta: {
         title: '服务器',
-        icon: 'School'
+        icon: 'OfficeBuilding'
     },
     children: [
         {

+ 276 - 0
src/views/operation/announcement/index.vue

@@ -0,0 +1,276 @@
+<template>
+  <div class="app-container" ref="appContainer">
+    <ServerPropTable :loading="loading" @selection-change="selectionChange" :columns="column" :data="list" @reset="reset"
+      @onSubmit="onSubmit">
+      <template v-slot:btn>
+        <div style="display: flex; justify-content: flex-end">
+          <el-button type="primary" @click="add"
+          ><el-icon><plus /></el-icon> 添加</el-button>
+          <el-button type="danger" @click="batchDelete"><el-icon>
+              <delete />
+            </el-icon>删除</el-button>
+        </div>
+      </template>
+      <template v-slot:operation="scope">
+        <el-button type="primary" size="small" icon="Edit" @click="edit(scope.row)">
+          编辑
+        </el-button>
+        <el-button @click="del(scope.row)" type="danger" size="small" icon="Delete">
+          删除
+        </el-button>
+      </template>
+    </ServerPropTable>
+
+    <el-dialog v-model="dialogVisible" :title='title' width="50%">
+      <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px" class="demo-ruleForm"
+        :size="formSize">
+        <el-form-item label="ID" prop="id">
+          <el-input readonly v-model="ruleForm.id" />
+        </el-form-item>
+        <el-form-item label="公告标题" prop="title">
+          <el-input v-model="ruleForm.title" />
+        </el-form-item>
+        <el-form-item label="公告生效时间" required>
+          <el-col :span="11">
+            <el-form-item prop="validTime">
+              <el-date-picker
+                  v-model="ruleForm.validTime"
+                  type="datetime"
+                  placeholder="选择开始时间"
+                  style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col class="text-center" :span="2" style="text-align: center">
+            <span class="text-gray-500">-</span>
+          </el-col>
+          <el-col :span="11">
+            <el-form-item prop="invalidTime">
+              <el-date-picker v-model="ruleForm.invalidTime"  type="datetime" placeholder="选择结束时间" style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-form-item>
+        <el-form-item label="公告内容" prop="content">
+          <el-input v-model="ruleForm.content" :rows="10" type="textarea" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="handleClose(ruleFormRef)">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script lang="ts" setup name="comprehensive">
+import { ref, reactive, onMounted, nextTick } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import type { FormInstance } from 'element-plus'
+const loading = ref(true)
+const appContainer = ref(null)
+import ServerPropTable from '@/components/Table/ServerPropTable/index.vue'
+const data = []
+for (let i = 0; i < 100; i++) {
+  data.push({
+    id: i + 1,
+    title: '公告' + (i+1),
+    validTime: '2023-08-21 10:00:00',
+    invalidTime: '2023-09-21 10:00:00',
+    content: '公告内容',
+  })
+}
+
+const column = [
+  { type: 'selection', width: 60, fixed: 'left' },
+  { name: 'id', label: 'ID', width: 80 },
+  { name: 'title', label: '公告标题', inSearch: true, valueType: 'input' },
+  { name: 'validTime', label: '公告开始时间'},
+  { name: 'invalidTime', label: '公告截止时间'},
+  { name: 'content', label: '公告内容'},
+  { name: 'operation', slot: true, fixed: 'right', width: 200, label: '操作' },
+]
+
+const list = ref(data)
+
+const formSize = ref('default')
+const ruleFormRef = ref<FormInstance>()
+const ruleForm = reactive({
+    id: null,
+    title: null,
+    validTime: null,
+    invalidTime: null,
+    content: null,
+})
+
+const rules = reactive({
+  title: [
+    {
+      required: true,
+      message: '请输入公告标题',
+      trigger: 'change',
+    },
+  ],
+  validTime : [
+    {
+      required: true,
+      type: 'date',
+      message: '请选择公告开始时间',
+      trigger: 'change',
+    },
+  ],
+  invalidTime: [
+    {
+      required: true,
+      type: 'date',
+      message: '请选择公告截止时间',
+      trigger: 'change',
+    },
+  ],
+  content: [
+    {
+      required: true,
+      message: '请输入公告内容',
+      trigger: 'change',
+    },
+  ],
+})
+
+
+const dialogVisible = ref(false)
+const rowObj = ref({})
+const selectObj = ref([])
+const title = ref('编辑')
+
+const add = () => {
+  title.value = '新增'
+  dialogVisible.value = true
+}
+
+const handleClose = async (done: () => void) => {
+  await ruleFormRef.value.validate((valid, fields) => {
+    if (valid) {
+      list.value.forEach((item) => {
+        if (item.id === rowObj.value.id) {
+          item.title = ruleForm.title
+          item.validTime = ruleForm.validTime
+          item.invalidTime = ruleForm.invalidTime
+          item.content = ruleForm.content
+        }
+      })
+      dialogVisible.value = false
+      console.log('submit!', ruleForm.title)
+    } else {
+      console.log('error submit!', fields)
+    }
+  })
+}
+
+const batchDelete = () => {
+  if (!selectObj.value.length) {
+    return ElMessage.error('未选中任何行')
+  }
+  ElMessageBox.confirm('你确定要删除选中项吗?', '温馨提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+    draggable: true,
+  })
+    .then(() => {
+      ElMessage.success('模拟删除成功')
+      list.value = list.value.concat([])
+    })
+    .catch(() => { })
+}
+const selectionChange = (val) => {
+  selectObj.value = val
+}
+
+const edit = (row) => {
+  rowObj.value = row
+  dialogVisible.value = true
+  ruleForm.id = row.id
+  ruleForm.title = row.title
+  ruleForm.validTime = row.validTime
+  ruleForm.invalidTime = row.invalidTime
+  ruleForm.content = row.content
+}
+
+const del = (row) => {
+  console.log('row==', row)
+  ElMessageBox.confirm('你确定要删除当前项吗?', '温馨提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+    draggable: true,
+  })
+    .then(() => {
+      list.value = list.value.filter((item) => item.id !== row.id)
+      ElMessage.success('删除成功')
+      loading.value = true
+      setTimeout(() => {
+        loading.value = false
+      }, 500)
+    })
+    .catch(() => { })
+}
+
+const reset = () => {
+  loading.value = true
+  setTimeout(() => {
+    loading.value = false
+  }, 500)
+  ElMessage.success('触发重置方法')
+}
+
+const onSubmit = (val) => {
+  console.log('val===', val)
+  ElMessage.success('触发查询方法')
+  loading.value = true
+  setTimeout(() => {
+    loading.value = false
+  }, 500)
+}
+
+const onUpdate = (val) => {
+  console.log('val===', val)
+  ElMessage.success('触发修改方法')
+  loading.value = true
+  setTimeout(() => {
+    loading.value = false
+  }, 500)
+}
+
+const getHeight = () => {
+
+}
+
+onMounted(() => {
+  nextTick(() => {
+    // let data = appContainer.value.
+  })
+  setTimeout(() => {
+    loading.value = false
+  }, 500)
+})
+</script>
+
+<style scoped>
+.edit-input {
+  padding-right: 100px;
+}
+
+.app-container {
+  flex: 1;
+  display: flex;
+  width: 100%;
+  padding: 16px;
+  box-sizing: border-box;
+}
+
+.cancel-btn {
+  position: absolute;
+  right: 15px;
+  top: 10px;
+}
+</style>

+ 5 - 17
src/views/operation/giftcode/randomGeneration/index.vue → src/views/operation/giftcode/batchGeneration/index.vue

@@ -16,11 +16,8 @@
             <el-option label="通用" value="1" />
           </el-select>
         </el-form-item>
-        <el-form-item label="礼包道具ID" prop="itemIds">
-          <el-input v-model="ruleForm.itemIds" placeholder="道具ID列表,逗号间隔" />
-        </el-form-item>
-        <el-form-item label="礼包道具数量" prop="itemCounts">
-          <el-input v-model="ruleForm.itemCounts" placeholder="道具数量列表,逗号间隔" />
+        <el-form-item label="礼包道具" prop="itemInfo">
+          <el-input v-model="ruleForm.itemInfo" placeholder="可填列表,逗号间隔" />
         </el-form-item>
         <el-form-item label="礼包生效时间" required>
           <el-col :span="11">
@@ -71,8 +68,7 @@ const ruleForm = reactive({
   validTime: '',
   invalidTime: '',
   giftItems: '',
-  itemIds:[],
-  itemCounts:[],
+  itemInfo:[],
   randomCount: 0,
   result:''
 })
@@ -101,19 +97,11 @@ const rules = reactive({
       trigger: 'change',
     },
   ],
-  itemIds: [
-    {
-      type: 'array',
-      required: true,
-      message: '请输入礼包道具ID',
-      trigger: 'change',
-    },
-  ],
-  itemCounts: [
+  itemInfo: [
     {
       type: 'array',
       required: true,
-      message: '请输入礼包道具数量',
+      message: '请输入礼包道具',
       trigger: 'change',
     },
   ],

+ 1 - 1
src/views/operation/giftcode/fixedGeneration/index.vue

@@ -75,7 +75,7 @@ const rules = reactive({
   code: [
     {
       required: true,
-      message: '请选择礼包码',
+      message: '请输入礼包码',
       trigger: 'change',
     },
     { min: 3, max: 8, message: '长度在 3 到 8 个字符', trigger: 'blur' },

+ 67 - 25
src/views/operation/giftcode/listTable/index.vue

@@ -4,6 +4,8 @@
       @onSubmit="onSubmit">
       <template v-slot:btn>
         <div style="display: flex; justify-content: flex-end">
+          <el-button type="primary" @click="add"
+          ><el-icon><plus /></el-icon> 添加</el-button>
           <el-button type="danger" @click="batchDelete"><el-icon>
               <delete />
             </el-icon>删除</el-button>
@@ -26,27 +28,34 @@
         <el-form-item label="礼包码" prop="code">
           <el-input readonly :value="ruleForm.code" />
         </el-form-item>
-        <el-form-item label="礼包的道具ID" prop="itemIds">
-          <el-input v-model="ruleForm.itemIds" />
+        <el-form-item label="礼包类型" prop="codeType">
+          <el-select v-model="ruleForm.codeType" placeholder="礼包类型">
+            <el-option label="一次性" value="0" />
+            <el-option label="通用" value="1" />
+          </el-select>
         </el-form-item>
-        <el-form-item label="礼包的道具数量" prop="itemCounts">
-          <el-input v-model="ruleForm.itemCounts" />
+        <el-form-item label="礼包道具" prop="itemInfo">
+          <el-input v-model="ruleForm.itemInfo" />
         </el-form-item>
-        <el-form-item label="礼包生效时间" prop="validTime">
-          <el-date-picker
-                    v-model="ruleForm.validTime"
-                    type="datetime"
-                    value-format="YYYY-MM-DD HH:mm:ss"
-                    clearable
-                />
-        </el-form-item>
-        <el-form-item label="礼包失效时间" prop="invalidTime">
-          <el-date-picker
-                    v-model="ruleForm.invalidTime"
-                    type="datetime"
-                    value-format="YYYY-MM-DD HH:mm:ss"
-                    clearable
-                />
+        <el-form-item label="礼包生效时间" required>
+          <el-col :span="11">
+            <el-form-item prop="validTime">
+              <el-date-picker
+                  v-model="ruleForm.validTime"
+                  type="datetime"
+                  placeholder="选择开始时间"
+                  style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col class="text-center" :span="2" style="text-align: center">
+            <span class="text-gray-500">-</span>
+          </el-col>
+          <el-col :span="11">
+            <el-form-item prop="invalidTime">
+              <el-date-picker v-model="ruleForm.invalidTime"  type="datetime" placeholder="选择结束时间" style="width: 100%" />
+            </el-form-item>
+          </el-col>
         </el-form-item>
 
       </el-form>
@@ -72,8 +81,7 @@ for (let i = 0; i < 100; i++) {
   data.push({
     code: 'Code_' + i,
     codeType: i % 2,
-    itemIds:'1001,1002',
-    itemCounts:'100,200',
+    itemInfo:'1001-100,1002-200',
     validTime: '2023-8-18 10:00:00',
     invalidTime: '2023-9-18 10:00:00',
     usePlayer: '1000001',
@@ -99,8 +107,7 @@ const column = [
     ],
     valueType: 'select',
   },
-  { name: 'itemIds', label: '礼包道具ID'},
-  { name: 'itemCounts', label: '礼包道具数量'},
+  { name: 'itemInfo', label: '礼包道具'},
   { name: 'validTime', label: '礼包生效时间'},
   { name: 'invalidTime', label: '礼包失效时间'},
   { name: 'usePlayer', label: '使用的玩家', inSearch: true, valueType: 'input'},
@@ -126,10 +133,40 @@ const ruleForm = reactive({
 })
 
 const rules = reactive({
-  state: [
+  code: [
+    {
+      required: true,
+      message: '请输入礼包码',
+      trigger: 'change',
+    }
+  ],
+  codeType: [
+    {
+      required: true,
+      message: '请选择礼包类型',
+      trigger: 'change',
+    },
+  ],
+  itemInfo: [
+    {
+      required: true,
+      message: '请输入礼包道具',
+      trigger: 'change',
+    },
+  ],
+  validTime : [
+    {
+      required: true,
+      type: 'date',
+      message: '请选择礼包生效时间',
+      trigger: 'change',
+    },
+  ],
+  invalidTime: [
     {
       required: true,
-      message: '请选择状态',
+      type: 'date',
+      message: '请选择礼包失效时间',
       trigger: 'change',
     },
   ],
@@ -158,6 +195,11 @@ const handleClose = async (done: () => void) => {
   })
 }
 
+const add = () => {
+  title.value = '新增'
+  dialogVisible.value = true
+}
+
 const batchDelete = () => {
   if (!selectObj.value.length) {
     return ElMessage.error('未选中任何行')

+ 408 - 0
src/views/operation/gmmail/index.vue

@@ -0,0 +1,408 @@
+<template>
+  <div class="app-container" ref="appContainer">
+    <ServerPropTable :loading="loading" @selection-change="selectionChange" :columns="column" :data="list" @reset="reset"
+      @onSubmit="onSubmit">
+      <template v-slot:btn>
+        <div style="display: flex; justify-content: flex-end">
+          <el-button type="primary" @click="add"
+          ><el-icon><plus /></el-icon> 添加</el-button>
+          <el-button type="danger" @click="batchDelete"><el-icon>
+              <delete />
+            </el-icon>删除</el-button>
+        </div>
+      </template>
+      <template v-slot:operation="scope">
+        <el-button type="primary" size="small" icon="Edit" @click="edit(scope.row)">
+          编辑
+        </el-button>
+        <el-button @click="del(scope.row)" type="danger" size="small" icon="Delete">
+          删除
+        </el-button>
+      </template>
+    </ServerPropTable>
+
+    <el-dialog v-model="dialogVisible" :title='title' width="50%">
+      <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px" class="demo-ruleForm"
+        :size="formSize">
+        <el-form-item label="ID" prop="id">
+          <el-input readonly v-model="ruleForm.id" />
+        </el-form-item>
+        <el-form-item label="收件人服务器ID" prop="toServerIds">
+          <el-input v-model="ruleForm.toServerIds" />
+        </el-form-item>
+        <el-form-item label="收件人角色ID" prop="toPlayerIds">
+          <el-input v-model="ruleForm.toPlayerIds" />
+        </el-form-item>
+        <el-form-item label="收件人等级条件" prop="levelCondition">
+          <el-input v-model="ruleForm.levelCondition" />
+        </el-form-item>
+        <el-form-item label="收件人道具条件" prop="itemCondition">
+          <el-input v-model="ruleForm.itemCondition" />
+        </el-form-item>
+        <el-form-item label="收件人英雄条件" prop="heroCondition">
+          <el-input v-model="ruleForm.heroCondition" />
+        </el-form-item>
+
+        <el-form-item label="收件人角色创建">
+          <el-col :span="11">
+            <el-form-item prop="roleCreateTimeStart">
+              <el-date-picker
+                  v-model="ruleForm.roleCreateTimeStart"
+                  type="datetime"
+                  placeholder="选择起始时间"
+                  style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col class="text-center" :span="2" style="text-align: center">
+            <span class="text-gray-500">-</span>
+          </el-col>
+          <el-col :span="11">
+            <el-form-item prop="roleCreateTimeEnd">
+              <el-date-picker v-model="ruleForm.roleCreateTimeEnd"  type="datetime" placeholder="选择截止时间" style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-form-item>
+        <el-form-item label="邮件标题" prop="title">
+          <el-input v-model="ruleForm.title" />
+        </el-form-item>
+        <el-form-item label="发送者名称" prop="sendName">
+          <el-input v-model="ruleForm.sendName" />
+        </el-form-item>
+        <el-form-item label="邮件道具" prop="itemInfo">
+          <el-input v-model="ruleForm.itemInfo" />
+        </el-form-item>
+        <el-form-item label="邮件生效时间" required>
+          <el-col :span="11">
+            <el-form-item prop="validTime">
+              <el-date-picker
+                  v-model="ruleForm.validTime"
+                  type="datetime"
+                  placeholder="选择开始时间"
+                  style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col class="text-center" :span="2" style="text-align: center">
+            <span class="text-gray-500">-</span>
+          </el-col>
+          <el-col :span="11">
+            <el-form-item prop="invalidTime">
+              <el-date-picker v-model="ruleForm.invalidTime"  type="datetime" placeholder="选择结束时间" style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-form-item>
+        <el-form-item label="邮件内容" prop="content">
+          <el-input v-model="ruleForm.content" :rows="8" type="textarea" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">取消</el-button>
+          <el-button type="primary" @click="handleClose(ruleFormRef)">确定</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script lang="ts" setup name="comprehensive">
+import { ref, reactive, onMounted, nextTick } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import type { FormInstance } from 'element-plus'
+const loading = ref(true)
+const appContainer = ref(null)
+import ServerPropTable from '@/components/Table/ServerPropTable/index.vue'
+const data = []
+for (let i = 0; i < 100; i++) {
+  data.push({
+    id: i + 1,
+    title: 'GM邮件' + (i+1),
+    validTime: '2023-08-21 10:00:00',
+    invalidTime: '2023-09-21 10:00:00',
+    itemInfo: '1002-100,1001-200',
+    sendName: '深渊联盟',
+    toServerIds: '1,2,3,4,5',
+    toPlayerIds: '10000001, 10000001',
+  })
+}
+const column = [
+  { type: 'selection', width: 60, fixed: 'left' },
+  { name: 'id', label: 'ID', width: 80 },
+  { name: 'title', label: '邮件标题', inSearch: true, valueType: 'input' },
+  { name: 'validTime', label: '邮件生效时间'},
+  { name: 'invalidTime', label: '邮件失效时间'},
+  { name: 'itemInfo', label: '邮件道具'},
+  { name: 'sendName', label: '发送者名称'},
+  { name: 'toServerIds', label: '收件人服务器ID'},
+  { name: 'toPlayerIds', label: '收件人玩家ID'},
+  { name: 'operation', slot: true, fixed: 'right', width: 200, label: '操作' },
+]
+
+const list = ref(data)
+
+const formSize = ref('default')
+const ruleFormRef = ref<FormInstance>()
+const ruleForm = reactive({
+    id: null,
+    title: null,
+    validTime: null,
+    invalidTime: null,
+    itemInfo: null,
+    sendName: '深渊联盟',
+    toServerIds: '0',
+    toPlayerIds: '0',
+    levelCondition: null,
+    itemCondition: null,
+    heroCondition: null,
+    roleCreateTimeStart: null,
+    roleCreateTimeEnd: null,
+    content: null,
+})
+
+const rules = reactive({
+  toServerIds: [
+    {
+      message: '请输入收件人服务器ID',
+      trigger: 'change',
+    }
+  ],
+  toPlayerIds: [
+    {
+      message: '请输入收件人角色ID',
+      trigger: 'change',
+    },
+  ],
+  levelCondition: [
+    {
+      message: '请输入收件人等级条件',
+      trigger: 'change',
+    },
+  ],
+  itemCondition: [
+    {
+      message: '请输入收件人道具条件',
+      trigger: 'change',
+    },
+  ],
+  heroCondition: [
+    {
+      message: '请输入收件人英雄条件',
+      trigger: 'change',
+    },
+  ],
+  roleCreateTimeStart: [
+    {
+      type: 'date',
+      message: '请输入收件人角色创建起始时间',
+      trigger: 'change',
+    },
+  ],
+  roleCreateTimeEnd: [
+    {
+      type: 'date',
+      message: '请输入收件人角色创建截至时间',
+      trigger: 'change',
+    },
+  ],
+  title: [
+    {
+      required: true,
+      message: '请输入邮件标题',
+      trigger: 'change',
+    },
+  ],
+  sendName: [
+    {
+      required: true,
+      message: '请输入发送者名称',
+      trigger: 'change',
+    },
+  ],
+  itemInfo: [
+    {
+      required: true,
+      message: '请输入邮件道具',
+      trigger: 'change',
+    },
+  ],
+  validTime : [
+    {
+      required: true,
+      type: 'date',
+      message: '请选择邮件生效时间',
+      trigger: 'change',
+    },
+  ],
+  invalidTime: [
+    {
+      required: true,
+      type: 'date',
+      message: '请选择邮件失效时间',
+      trigger: 'change',
+    },
+  ],
+  content: [
+    {
+      required: true,
+      message: '请输入邮件内容',
+      trigger: 'change',
+    },
+  ],
+})
+
+
+const dialogVisible = ref(false)
+const rowObj = ref({})
+const selectObj = ref([])
+const title = ref('编辑')
+
+const add = () => {
+  title.value = '新增'
+  dialogVisible.value = true
+}
+
+const handleClose = async (done: () => void) => {
+  await ruleFormRef.value.validate((valid, fields) => {
+    if (valid) {
+      list.value.forEach((item) => {
+        if (item.id === rowObj.value.id) {
+          item.toServerIds = ruleForm.toServerIds
+          item.toPlayerIds = ruleForm.toPlayerIds
+          item.levelCondition = ruleForm.levelCondition
+          item.itemCondition = ruleForm.itemCondition
+          item.heroCondition = ruleForm.heroCondition
+          item.roleCreateTimeStart = ruleForm.roleCreateTimeStart
+          item.roleCreateTimeEnd = ruleForm.roleCreateTimeEnd
+          item.title = ruleForm.title
+          item.sendName = ruleForm.sendName
+          item.itemInfo = ruleForm.itemInfo
+          item.validTime = ruleForm.validTime
+          item.invalidTime = ruleForm.invalidTime
+          item.content = ruleForm.content
+        }
+      })
+      dialogVisible.value = false
+      console.log('submit!', ruleForm.title)
+    } else {
+      console.log('error submit!', fields)
+    }
+  })
+}
+
+const batchDelete = () => {
+  if (!selectObj.value.length) {
+    return ElMessage.error('未选中任何行')
+  }
+  ElMessageBox.confirm('你确定要删除选中项吗?', '温馨提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+    draggable: true,
+  })
+    .then(() => {
+      ElMessage.success('模拟删除成功')
+      list.value = list.value.concat([])
+    })
+    .catch(() => { })
+}
+const selectionChange = (val) => {
+  selectObj.value = val
+}
+
+const edit = (row) => {
+  rowObj.value = row
+  dialogVisible.value = true
+  ruleForm.id = row.id
+  ruleForm.toServerIds = row.toServerIds
+  ruleForm.toPlayerIds = row.toPlayerIds
+  ruleForm.levelCondition = row.levelCondition
+  ruleForm.itemCondition = row.itemCondition
+  ruleForm.heroCondition = row.heroCondition
+  ruleForm.roleCreateTimeStart = row.roleCreateTimeStart
+  ruleForm.roleCreateTimeEnd = row.roleCreateTimeEnd
+  ruleForm.title = row.title
+  ruleForm.sendName = row.sendName
+  ruleForm.itemInfo = row.itemInfo
+  ruleForm.validTime = row.validTime
+  ruleForm.invalidTime = row.invalidTime
+  ruleForm.content = row.content
+}
+
+const del = (row) => {
+  console.log('row==', row)
+  ElMessageBox.confirm('你确定要删除当前项吗?', '温馨提示', {
+    confirmButtonText: '确定',
+    cancelButtonText: '取消',
+    type: 'warning',
+    draggable: true,
+  })
+    .then(() => {
+      list.value = list.value.filter((item) => item.id !== row.id)
+      ElMessage.success('删除成功')
+      loading.value = true
+      setTimeout(() => {
+        loading.value = false
+      }, 500)
+    })
+    .catch(() => { })
+}
+
+const reset = () => {
+  loading.value = true
+  setTimeout(() => {
+    loading.value = false
+  }, 500)
+  ElMessage.success('触发重置方法')
+}
+
+const onSubmit = (val) => {
+  console.log('val===', val)
+  ElMessage.success('触发查询方法')
+  loading.value = true
+  setTimeout(() => {
+    loading.value = false
+  }, 500)
+}
+
+const onUpdate = (val) => {
+  console.log('val===', val)
+  ElMessage.success('触发修改方法')
+  loading.value = true
+  setTimeout(() => {
+    loading.value = false
+  }, 500)
+}
+
+const getHeight = () => {
+
+}
+
+onMounted(() => {
+  nextTick(() => {
+    // let data = appContainer.value.
+  })
+  setTimeout(() => {
+    loading.value = false
+  }, 500)
+})
+</script>
+
+<style scoped>
+.edit-input {
+  padding-right: 100px;
+}
+
+.app-container {
+  flex: 1;
+  display: flex;
+  width: 100%;
+  padding: 16px;
+  box-sizing: border-box;
+}
+
+.cancel-btn {
+  position: absolute;
+  right: 15px;
+  top: 10px;
+}
+</style>

+ 93 - 0
src/views/operation/sendcmd/index.vue

@@ -0,0 +1,93 @@
+
+<template>
+  <PageWrapLayout>
+    <div style="max-width: 800px">
+      <el-form
+          ref="ruleFormRef"
+          :model="ruleForm"
+          :rules="rules"
+          label-width="120px"
+          class="demo-ruleForm"
+          :size="formSize"
+      >
+        <el-form-item label="服务器ID" prop="toServerIds">
+          <el-input v-model="ruleForm.toServerIds" placeholder="可填列表,逗号间隔" />
+        </el-form-item>
+        <el-form-item label="角色ID" prop="toPlayerIds">
+          <el-input v-model="ruleForm.toPlayerIds" placeholder="可填列表,逗号间隔" />
+        </el-form-item>
+        <el-form-item label="命令" prop="command">
+          <el-input v-model="ruleForm.command"/>
+        </el-form-item>
+        <el-form-item label="命令参数" prop="params">
+          <el-input v-model="ruleForm.params"/>
+        </el-form-item>
+        <el-form-item label="执行结果" prop="result">
+          <el-input readonly v-model="ruleForm.result" :rows="10" type="textarea" />
+        </el-form-item>
+        <el-form-item>
+          <el-button type="primary" @click="submitForm(ruleFormRef)">发送</el-button>
+          <el-button @click="resetForm(ruleFormRef)">重置</el-button>
+        </el-form-item>
+      </el-form>
+    </div>
+  </PageWrapLayout>
+</template>
+
+<script lang="ts" setup >
+import { reactive, ref } from 'vue'
+import type { FormInstance } from 'element-plus'
+// import Upload from './components/Upload.vue'
+
+const formSize = ref('default')
+const ruleFormRef = ref<FormInstance>()
+const ruleForm = reactive({
+  toServerIds: '',
+  toPlayerIds: '',
+  command: null,
+  params: null,
+  result:'',
+})
+
+const rules = reactive({
+  toServerIds: [
+    {
+      required: true,
+      message: '请输入服务器ID',
+      trigger: 'change',
+    },
+  ],
+  toPlayerIds: [
+    {
+      required: true,
+      message: '请输入角色ID',
+      trigger: 'change',
+    },
+  ],
+  command: [
+    {
+      required: true,
+      message: '请输入命令',
+      trigger: 'change',
+    },
+  ],
+  params: [
+    {
+      required: true,
+      message: '请输入命令参数',
+      trigger: 'change',
+    },
+  ],
+})
+
+const submitForm = async (formEl: FormInstance | undefined) => {
+  console.log('--FORM---', ruleForm)
+  if (!formEl) return
+
+}
+
+const resetForm = (formEl: FormInstance | undefined) => {
+  if (!formEl) return
+  formEl.resetFields()
+}
+</script>

+ 48 - 18
src/views/server/gatewayTable/index.vue

@@ -23,8 +23,8 @@
     <el-dialog v-model="dialogVisible" :title='title' width="50%">
       <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="120px" class="demo-ruleForm"
         :size="formSize">
-        <el-form-item label="ID" prop="id">
-          <el-input readonly :value="ruleForm.id" />
+        <el-form-item label="ID" prop="_id">
+          <el-input readonly :value="ruleForm._id" />
         </el-form-item>
         <el-form-item label="状态" prop="state">
           <el-radio-group v-model="ruleForm.state">
@@ -43,27 +43,41 @@
   </div>
 </template>
 <script lang="ts" setup name="comprehensive">
-import { ref, reactive, onMounted, nextTick } from 'vue'
+import { ref, reactive, onMounted, nextTick, onBeforeMount } from 'vue'
 import * as dayjs from 'dayjs'
 import { ElMessage, ElMessageBox } from 'element-plus'
 import type { FormInstance } from 'element-plus'
+import serverApi from '@/api/server'
+
 const loading = ref(true)
 const appContainer = ref(null)
 import ServerPropTable from '@/components/Table/ServerPropTable/index.vue'
-const data = []
-for (let i = 0; i < 100; i++) {
-  data.push({
-    id: i + 1,
-    f_host: '0.0.0.0',
-    f_port: 2000 + i,
-    b_host: '127.0.0.1',
-    b_port: 3000 + i,
-    state: i % 2 ? 1 : 0
+import { da, el } from 'element-plus/es/locale'
+// const data = []
+// for (let i = 0; i < 100; i++) {
+//   data.push({
+//     _id: i + 1,
+//     f_host: '0.0.0.0',
+//     f_port: 2000 + i,
+//     b_host: '127.0.0.1',
+//     b_port: 3000 + i,
+//     state: i % 2 ? 1 : 0
+//   })
+// }
+// console.log(data)
+
+const data = ref([])
+
+onBeforeMount(()=> {
+    serverApi.getAll("gateway").then(res => {
+    data.value = res.data.result;
+    console.log(data)
   })
-}
+})
+
 const column = [
   { type: 'selection', width: 60, fixed: 'left' },
-  { name: 'id', label: 'ID', inSearch: true, valueType: 'input', width: 80 },
+  { name: '_id', label: 'ID', inSearch: true, valueType: 'input', width: 80 },
   { name: 'f_host', label: '前端主机'},
   { name: 'f_port', label: '前端端口'},
   { name: 'b_host', label: '后端主机'},
@@ -114,8 +128,20 @@ const handleClose = async (done: () => void) => {
   await ruleFormRef.value.validate((valid, fields) => {
     if (valid) {
       list.value.forEach((item) => {
-        if (item.id === rowObj.value.id) {
-          item.state = ruleForm.state
+        if (item._id === rowObj.value._id) {
+          let updateParams = reactive({
+            serverName: "gateway",
+            serverId: ruleForm._id,
+            update: ruleForm
+          })
+          serverApi.update(updateParams).then(res=>{
+              if (res.data.result > 0) {
+                item.state = ruleForm.state
+                return ElMessage.success('修改成功')
+              } else {
+                return ElMessage.error('修改失败')
+              }
+          })
         }
       })
       dialogVisible.value = false
@@ -149,7 +175,7 @@ const selectionChange = (val) => {
 const edit = (row) => {
   rowObj.value = row
   dialogVisible.value = true
-  ruleForm.id = row.id
+  ruleForm._id = row._id
   ruleForm.state = row.state
 }
 
@@ -162,7 +188,11 @@ const del = (row) => {
     draggable: true,
   })
     .then(() => {
-      list.value = list.value.filter((item) => item.id !== row.id)
+      list.value = list.value.filter((item) => item._id !== row._id)
+      let deleteParams = reactive({
+        serverId: row._id
+      })
+      serverApi.delete(deleteParams)
       ElMessage.success('删除成功')
       loading.value = true
       setTimeout(() => {