Pārlūkot izejas kodu

类别管理接口第一次提交

maker 3 gadi atpakaļ
vecāks
revīzija
a64026560d

+ 1 - 1
package.json

@@ -30,7 +30,7 @@
     },
     "devDependencies": {
         "@vitejs/plugin-legacy": "^1.4.4",
-        "@vitejs/plugin-vue": "latest",
+        "@vitejs/plugin-vue": "^2.3.3",
         "@vue/cli-plugin-babel": "~4.5.0",
         "@vue/cli-plugin-eslint": "~4.5.0",
         "@vue/cli-plugin-router": "~4.5.0",

+ 131 - 0
src/api/gameChannel.js

@@ -0,0 +1,131 @@
+import service from '@/utils/request'
+// @Tags api
+// @Summary 分页获取角色列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body modelInterface.PageInfo true "分页获取用户列表"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/getApiList [post]
+// {
+//  page     int
+//	pageSize int
+// }
+export const getApiList = (data) => {
+  return service({
+    url: '/gameChannel/getGameChannelList',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 创建基础api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "创建api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/createApi [post]
+export const createApi = (data) => {
+  return service({
+    url: '/gameChannel/createGameChannel',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags menu
+// @Summary 根据id获取菜单
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.GetById true "根据id获取菜单"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /menu/getApiById [post]
+export const getApiById = (data) => {
+  return service({
+    url: '/gameChannel/getGameChannelById',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 更新api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "更新api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /api/updateApi [post]
+export const updateApi = (data) => {
+  return service({
+    url: '/gameChannel/updateGameChannel',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 更新api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "更新api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /api/setAuthApi [post]
+export const setAuthApi = (data) => {
+  return service({
+    url: '/api/setAuthApi',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 获取所有的Api 不分页
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/getAllApis [post]
+export const getAllApis = (data) => {
+  return service({
+    url: '/api/getAllApis',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 删除指定api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body dbModel.Api true "删除api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/deleteApi [post]
+export const deleteApi = (data) => {
+  return service({
+    url: '/gameChannel/deleteGameChannel',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags SysApi
+// @Summary 删除选中Api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "ID"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /api/deleteApisByIds [delete]
+export const deleteApisByIds = (data) => {
+  return service({
+    url: '/gameChannel/deleteGameChannelsByIds',
+    method: 'delete',
+    data
+  })
+}

+ 131 - 0
src/api/gameList.js

@@ -0,0 +1,131 @@
+import service from '@/utils/request'
+// @Tags api
+// @Summary 分页获取角色列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body modelInterface.PageInfo true "分页获取用户列表"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/getApiList [post]
+// {
+//  page     int
+//	pageSize int
+// }
+export const getApiList = (data) => {
+  return service({
+    url: '/gameList/getGameList',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 创建基础api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "创建api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/createApi [post]
+export const createApi = (data) => {
+  return service({
+    url: '/gameList/createGameList',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags menu
+// @Summary 根据id获取菜单
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.GetById true "根据id获取菜单"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /menu/getApiById [post]
+export const getApiById = (data) => {
+  return service({
+    url: '/gameList/getGameListById',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 更新api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "更新api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /api/updateApi [post]
+export const updateApi = (data) => {
+  return service({
+    url: '/gameList/updateGameList',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 更新api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "更新api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /api/setAuthApi [post]
+// export const setAuthApi = (data) => {
+//   return service({
+//     url: '/api/setAuthApi',
+//     method: 'post',
+//     data
+//   })
+// }
+
+// @Tags Api
+// @Summary 获取所有的Api 不分页
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/getAllApis [post]
+// export const getAllApis = (data) => {
+//   return service({
+//     url: '/api/getAllApis',
+//     method: 'post',
+//     data
+//   })
+// }
+
+// @Tags Api
+// @Summary 删除指定api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body dbModel.Api true "删除api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/deleteApi [post]
+export const deleteApi = (data) => {
+  return service({
+    url: '/gameList/deleteGameList',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags SysApi
+// @Summary 删除选中Api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "ID"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /api/deleteApisByIds [delete]
+export const deleteApisByIds = (data) => {
+  return service({
+    url: '/gameList/deleteGameListsByIds',
+    method: 'delete',
+    data
+  })
+}

+ 131 - 0
src/api/loginType.js

@@ -0,0 +1,131 @@
+import service from '@/utils/request'
+// @Tags api
+// @Summary 分页获取角色列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body modelInterface.PageInfo true "分页获取用户列表"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/getApiList [post]
+// {
+//  page     int
+//	pageSize int
+// }
+export const getApiList = (data) => {
+  return service({
+    url: '/loginType/getLoginType',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 创建基础api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "创建api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/createApi [post]
+export const createApi = (data) => {
+  return service({
+    url: '/loginType/createLoginType',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags menu
+// @Summary 根据id获取菜单
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.GetById true "根据id获取菜单"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /menu/getApiById [post]
+export const getApiById = (data) => {
+  return service({
+    url: '/loginType/getLoginTypeById',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 更新api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "更新api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /api/updateApi [post]
+export const updateApi = (data) => {
+  return service({
+    url: '/loginType/updateLoginType',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 更新api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "更新api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /api/setAuthApi [post]
+// export const setAuthApi = (data) => {
+//   return service({
+//     url: '/api/setAuthApi',
+//     method: 'post',
+//     data
+//   })
+// }
+
+// @Tags Api
+// @Summary 获取所有的Api 不分页
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/getAllApis [post]
+// export const getAllApis = (data) => {
+//   return service({
+//     url: '/api/getAllApis',
+//     method: 'post',
+//     data
+//   })
+// }
+
+// @Tags Api
+// @Summary 删除指定api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body dbModel.Api true "删除api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/deleteApi [post]
+export const deleteApi = (data) => {
+  return service({
+    url: '/loginType/deleteLoginType',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags SysApi
+// @Summary 删除选中Api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "ID"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /api/deleteApisByIds [delete]
+export const deleteApisByIds = (data) => {
+  return service({
+    url: '/loginType/deleteLoginTypesByIds',
+    method: 'delete',
+    data
+  })
+}

+ 131 - 0
src/api/responsiblePerson.js

@@ -0,0 +1,131 @@
+import service from '@/utils/request'
+// @Tags api
+// @Summary 分页获取角色列表
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body modelInterface.PageInfo true "分页获取用户列表"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/getApiList [post]
+// {
+//  page     int
+//	pageSize int
+// }
+export const getApiList = (data) => {
+  return service({
+    url: '/responsiblePerson/getResponsiblePerson',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 创建基础api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "创建api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/createApi [post]
+export const createApi = (data) => {
+  return service({
+    url: '/responsiblePerson/createResponsiblePerson',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags menu
+// @Summary 根据id获取菜单
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.GetById true "根据id获取菜单"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /menu/getApiById [post]
+export const getApiById = (data) => {
+  return service({
+    url: '/responsiblePerson/getResponsiblePersonById',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 更新api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "更新api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /api/updateApi [post]
+export const updateApi = (data) => {
+  return service({
+    url: '/responsiblePerson/updateResponsiblePerson',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags Api
+// @Summary 更新api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body api.CreateApiParams true "更新api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"更新成功"}"
+// @Router /api/setAuthApi [post]
+// export const setAuthApi = (data) => {
+//   return service({
+//     url: '/api/setAuthApi',
+//     method: 'post',
+//     data
+//   })
+// }
+
+// @Tags Api
+// @Summary 获取所有的Api 不分页
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/getAllApis [post]
+// export const getAllApis = (data) => {
+//   return service({
+//     url: '/api/getAllApis',
+//     method: 'post',
+//     data
+//   })
+// }
+
+// @Tags Api
+// @Summary 删除指定api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body dbModel.Api true "删除api"
+// @Success 200 {string} json "{"success":true,"data":{},"msg":"获取成功"}"
+// @Router /api/deleteApi [post]
+export const deleteApi = (data) => {
+  return service({
+    url: '/responsiblePerson/deleteResponsiblePerson',
+    method: 'post',
+    data
+  })
+}
+
+// @Tags SysApi
+// @Summary 删除选中Api
+// @Security ApiKeyAuth
+// @accept application/json
+// @Produce application/json
+// @Param data body request.IdsReq true "ID"
+// @Success 200 {string} string "{"success":true,"data":{},"msg":"删除成功"}"
+// @Router /api/deleteApisByIds [delete]
+export const deleteApisByIds = (data) => {
+  return service({
+    url: '/responsiblePerson/deleteResponsiblePersonsByIds',
+    method: 'delete',
+    data
+  })
+}

+ 78 - 0
src/components/customPic/customIndex.vue

@@ -0,0 +1,78 @@
+<template>
+    <span class="headerAvatar">
+      <template v-if="picType === 'avatar'">
+        <el-avatar v-if="userStore.userInfo.headerImg" :size="30" :src="avatar" />
+        <el-avatar v-else :size="30" :src="noAvatar" />
+      </template>
+      <template v-if="picType === 'img'">
+        <img v-if="userStore.userInfo.headerImg" :src="avatar" class="avatar">
+        <img v-else :src="noAvatar" class="avatar">
+      </template>
+      <template v-if="picType === 'file'">
+        <img :src="file" class="file">
+      </template>
+    </span>
+  </template>
+  
+  <script>
+  export default {
+    name: 'CustomPic'
+  }
+  </script>
+  
+  <script setup>
+  import noAvatarPng from '@/assets/noBody.png'
+  import { useUserStore } from '@/pinia/modules/user'
+  import { computed, ref } from 'vue'
+  const props = defineProps({
+    picType: {
+      type: String,
+      required: false,
+      default: 'avatar'
+    },
+    picSrc: {
+      type: String,
+      required: false,
+      default: ''
+    }
+  })
+  
+  const path = ref(import.meta.env.VITE_BASE_API + '/')
+  const noAvatar = ref(noAvatarPng)
+  
+  const userStore = useUserStore()
+  
+  const avatar = computed(() => {
+    if (props.picSrc === '') {
+        //只要没有传值,我就直接返回一张空图片
+      return noAvatarPng
+    } else {
+      if (props.picSrc !== '' && props.picSrc.slice(0, 4) === 'http') {
+        return props.picSrc
+      }
+      return path.value + props.picSrc
+    }
+  })
+  const file = computed(() => {
+    if (props.picSrc && props.picSrc.slice(0, 4) !== 'http') {
+      return path.value + props.picSrc
+    }
+    return props.picSrc
+  })
+  
+  </script>
+  
+  <style scoped>
+  .headerAvatar{
+      display: flex;
+      justify-content: center;
+      align-items: center;
+      margin-right: 8px;
+  }
+  .file{
+      width: 80px;
+      height: 80px;
+      position: relative;
+  }
+  </style>
+  

+ 366 - 0
src/view/typeManage/gameChannel.vue

@@ -0,0 +1,366 @@
+<template>
+    <div>
+      <div class="gva-search-box">
+        <el-form ref="searchForm" :inline="true" :model="searchInfo">
+          <el-form-item>
+            <el-select v-model="searchInfo.searchBox" >
+              <el-option
+                v-for="item in methodOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-input v-model="searchInfo.channelName" placeholder="请输入关键字" />
+          </el-form-item>
+          <el-form-item>
+            <el-button size="small" type="primary" icon="search" @click="onSubmit">搜索</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="gva-table-box">
+        <div class="gva-btn-list">
+          <el-button size="small" icon="refresh" @click="onReset">刷新</el-button>
+          <el-button size="small" type="primary" icon="plus" @click="openDialog('addGameChannel')">新增</el-button>
+          <el-popover v-model="deleteVisible" placement="top" width="160">
+            <p>确定要删除吗?</p>
+            <div style="text-align: right; margin-top: 8px;">
+              <el-button size="small" type="primary" link @click="deleteVisible = false">取消</el-button>
+              <el-button size="small" type="primary" @click="onDelete">确定</el-button>
+            </div>
+            <template #reference>
+              <el-button icon="delete" type="danger" size="small" :disabled="!apis.length" style="margin-left: 10px;" @click="deleteVisible = true">删除</el-button>
+            </template>
+          </el-popover>
+        </div>
+        <el-table :data="tableData" @sort-change="sortChange" @selection-change="handleSelectionChange">
+          <el-table-column
+            type="selection"
+            width="55"
+          />
+          <!-- <el-table-column align="left" label="厂商ID" min-width="100" prop="id" sortable="custom" aria-disabled="false"/> -->
+          <el-table-column align="left" label="厂商名称" min-width="100" prop="channelName" sortable="custom" />
+          <el-table-column align="left" label="厂商描述" min-width="150" prop="channelDesc" sortable="custom" />
+          <el-table-column align="left" label="显示顺序" min-width="150" prop="displaySequence" sortable="custom" />
+          <el-table-column align="left" label="游戏数量" min-width="150" prop="gameCounts" sortable="custom" />
+          <el-table-column align="left" label="创建时间" min-width="150" prop="createTime" sortable="custom" />
+          <el-table-column align="left" label="更新时间" min-width="150" prop="updateTime" sortable="custom" />
+  
+          <el-table-column align="left" fixed="right" label="操作" width="200">
+            <template #default="scope">
+              <el-button
+                icon="edit"
+                size="small"
+                type="primary"
+                link
+                @click="editApiFunc(scope.row)"
+              >编辑</el-button>
+              <el-button
+                icon="delete"
+                size="small"
+                type="primary"
+                link
+                @click="deleteApiFunc(scope.row)"
+              >删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="gva-pagination">
+          <el-pagination
+            :current-page="page"
+            :page-size="pageSize"
+            :page-sizes="[10, 30, 50, 100]"
+            :total="total"
+            layout="total, sizes, prev, pager, next, jumper"
+            @current-change="handleCurrentChange"
+            @size-change="handleSizeChange"
+          />
+        </div>
+  
+      </div>
+  
+      <el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="dialogTitle">
+        <!-- <warning-bar title="新增API,需要在角色管理内配置权限才可使用" /> -->
+        <el-form ref="apiForm" :model="form" :rules="rules" label-width="80px">
+          <el-form-item label="厂商名称" prop="channelName">
+            <el-input v-model="form.channelName" autocomplete="off" />
+          </el-form-item>
+          <el-form-item label="厂商描述" prop="channelDesc">
+            <el-input v-model="form.channelDesc" autocomplete="off" />
+          </el-form-item>
+          <el-form-item label="显示顺序" prop="displaySequence">
+            <el-input-number v-model="form.displaySequence" min=0 autocomplete="off"  />
+          </el-form-item>
+        </el-form>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button size="small" @click="closeDialog">取 消</el-button>
+            <el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
+          </div>
+        </template>
+      </el-dialog>
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    name: 'Api',
+  }
+  </script>
+  
+  <script setup>
+  import {
+    getApiById,
+    getApiList,
+    createApi,
+    updateApi,
+    deleteApi,
+    deleteApisByIds
+  } from '@/api/gameChannel'
+  import { toSQLLine } from '@/utils/stringFun'
+  import warningBar from '@/components/warningBar/warningBar.vue'
+  import { ref } from 'vue'
+  import { ElMessage, ElMessageBox } from 'element-plus'
+import { isNumber } from 'lodash'
+  
+  const methodFiletr = (value) => {
+    const target = methodOptions.value.filter(item => item.value === value)[0]
+    return target && `${target.label}`
+  }
+  
+  const apis = ref([])
+  const form = ref({
+    channelName: '',
+    channelDesc: '',
+    displaySequence: 1,
+    gameCounts: 0,
+  })
+  const methodOptions = ref([
+    {
+      value: 'channel_name',
+      label: '厂商名称',
+      type: ''
+    },
+  ])
+  
+  const type = ref('')
+  const rules = ref({
+    path: [{ required: true, message: '请输入api路径', trigger: 'blur' }],
+    apiGroup: [
+      { required: true, message: '请输入组名称', trigger: 'blur' }
+    ],
+    method: [
+      { required: true, message: '请选择请求方式', trigger: 'blur' }
+    ],
+    description: [
+      { required: true, message: '请输入api介绍', trigger: 'blur' }
+    ]
+  })
+  
+  const page = ref(1)
+  const total = ref(0)
+  const pageSize = ref(10)
+  const tableData = ref([])
+  const searchInfo = ref({
+    searchBox:'channel_name'
+  })
+  
+  const onReset = () => {
+    searchInfo.value = {}
+    getTableData()
+  }
+  // 搜索
+  
+  const onSubmit = () => {
+    page.value = 1
+    pageSize.value = 10
+    getTableData()
+  }
+  
+  // 分页
+  const handleSizeChange = (val) => {
+    pageSize.value = val
+    getTableData()
+  }
+  
+  const handleCurrentChange = (val) => {
+    page.value = val
+    getTableData()
+  }
+  
+  // 排序
+  const sortChange = ({ prop, order }) => {
+    if (prop) {
+      if (prop === 'ID') {
+        prop = 'id'
+      }
+      searchInfo.value.orderKey = toSQLLine(prop)
+      searchInfo.value.desc = order === 'descending'
+    }
+    getTableData()
+  }
+  
+  // 查询
+  const getTableData = async() => {
+    const table = await getApiList({ page: page.value, pageSize: pageSize.value, ...searchInfo.value })
+    if (table.code === 0) {
+      tableData.value = table.data.list
+      total.value = table.data.total
+      page.value = table.data.page
+      pageSize.value = table.data.pageSize
+    }
+  }
+  
+  getTableData()
+  
+  // 批量操作
+  const handleSelectionChange = (val) => {
+    apis.value = val
+  }
+  
+  const deleteVisible = ref(false)
+  const onDelete = async() => {
+    const ids = apis.value.map(item => item.id)
+    const res = await deleteApisByIds({ ids })
+    if (res.code === 0) {
+      ElMessage({
+        type: 'success',
+        message: res.msg
+      })
+      if (tableData.value.length === ids.length && page.value > 1) {
+        page.value--
+      }
+      deleteVisible.value = false
+      getTableData()
+    }
+  }
+  
+  // 弹窗相关
+  const apiForm = ref(null)
+  const initForm = () => {
+    apiForm.value.resetFields()
+    form.value = {
+    //   path: '',
+    //   apiGroup: '',
+    //   method: '',
+    //   description: ''
+    channelName: '',
+    channelDesc: '',
+    displaySequence: '',
+    gameCounts: ''
+    }
+  }
+  
+  const dialogTitle = ref('新增Api')
+  const dialogFormVisible = ref(false)
+  const openDialog = (key) => {
+    switch (key) {
+      case 'addGameChannel':
+        dialogTitle.value = '新增'
+        break
+      case 'editGameChannel':
+        dialogTitle.value = '编辑'
+        break
+      default:
+        break
+    }
+    type.value = key
+    dialogFormVisible.value = true
+  }
+  const closeDialog = () => {
+    initForm()
+    dialogFormVisible.value = false
+  }
+  
+  const editApiFunc = async(row) => {
+    const res = await getApiById({ id: row.id })
+    form.value = res.data.gameChannel
+    console.log(form)
+    openDialog('editGameChannel')
+  }
+  
+  const enterDialog = async() => {
+    apiForm.value.validate(async valid => {
+      if (valid) {
+        switch (type.value) {
+          case 'addGameChannel':
+            {
+              const res = await createApi(form.value)
+              if (res.code === 0) {
+                ElMessage({
+                  type: 'success',
+                  message: '添加成功',
+                  showClose: true
+                })
+              }
+              getTableData()
+              closeDialog()
+            }
+  
+            break
+          case 'editGameChannel':
+            {
+              const res = await updateApi(form.value)
+              if (res.code === 0) {
+                ElMessage({
+                  type: 'success',
+                  message: '编辑成功',
+                  showClose: true
+                })
+              }
+              getTableData()
+              closeDialog()
+            }
+            break
+          default:
+            // eslint-disable-next-line no-lone-blocks
+            {
+              ElMessage({
+                type: 'error',
+                message: '未知操作',
+                showClose: true
+              })
+            }
+            break
+        }
+      }
+    })
+  }
+  
+  const deleteApiFunc = async(row) => {
+    ElMessageBox.confirm('此操作将永久删除此渠道, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    })
+      .then(async() => {
+        const res = await deleteApi(row)
+        if (res.code === 0) {
+          ElMessage({
+            type: 'success',
+            message: '删除成功!'
+          })
+          if (tableData.value.length === 1 && page.value > 1) {
+            page.value--
+          }
+          getTableData()
+        }
+      })
+  }
+  
+  </script>
+  
+  <style scoped lang="scss">
+  .button-box {
+    padding: 10px 20px;
+    .el-button {
+      float: right;
+    }
+  }
+  .warning {
+    color: #dc143c;
+  }
+  </style>
+  

+ 450 - 0
src/view/typeManage/gameList.vue

@@ -0,0 +1,450 @@
+<template>
+    <div>
+      <div class="gva-search-box">
+        <el-form ref="searchForm" :inline="true" :model="searchInfo">
+          <el-form-item>
+            <el-select v-model="searchInfo.searchKey"  >
+              <el-option
+                v-for="item in searchOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-input v-model="searchInfo.searchValue" placeholder="请输入关键字"/>
+          </el-form-item>
+          <el-form-item>
+            <el-button size="small" type="primary" icon="search" @click="onSubmit">搜索</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="gva-table-box">
+        <div class="gva-btn-list">
+          <el-button size="small" icon="refresh" @click="onReset">刷新</el-button>
+          <el-button size="small" type="primary" icon="plus" @click="openDialog('addGameList')">新增</el-button>
+          <el-popover v-model="deleteVisible" placement="top" width="160">
+            <p>确定要删除吗?</p>
+            <div style="text-align: right; margin-top: 8px;">
+              <el-button size="small" type="primary" link @click="deleteVisible = false">取消</el-button>
+              <el-button size="small" type="primary" @click="onDelete">确定</el-button>
+            </div>
+            <template #reference>
+              <el-button icon="delete" type="danger" size="small" :disabled="!apis.length" style="margin-left: 10px;" @click="deleteVisible = true">删除</el-button>
+            </template>
+          </el-popover>
+        </div>
+        <el-table :data="tableData" @sort-change="sortChange" @selection-change="handleSelectionChange">
+          <el-table-column
+            type="selection"
+            width="55"
+          />
+          <!-- <el-table-column align="left" label="厂商ID" min-width="100" prop="id" sortable="custom" aria-disabled="false"/> -->
+          <el-table-column align="left" label="游戏名称" min-width="100" prop="game_name" sortable="custom" />
+          <el-table-column align="left" label="游戏端口" min-width="150" prop="game_port" sortable="custom" />
+          <el-table-column align="left" label="登录方式" min-width="150" prop="login_type" sortable="custom" />
+          <el-table-column align="left" label="备注" min-width="150" prop="remark" sortable="custom" />
+          <el-table-column align="left" label="创建时间" min-width="150" prop="createdAt" sortable="custom" />
+          <el-table-column align="left" label="更新时间" min-width="150" prop="updatedAt" sortable="custom" />
+  
+          <el-table-column align="left" fixed="right" label="操作" width="200">
+            <template #default="scope">
+              <el-button
+                icon="edit"
+                size="small"
+                type="primary"
+                link
+                @click="editApiFunc(scope.row)"
+              >编辑</el-button>
+              <el-button
+                icon="delete"
+                size="small"
+                type="primary"
+                link
+                @click="deleteApiFunc(scope.row)"
+              >删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="gva-pagination">
+          <el-pagination
+            :current-page="page"
+            :page-size="pageSize"
+            :page-sizes="[10, 30, 50, 100]"
+            :total="total"
+            layout="total, sizes, prev, pager, next, jumper"
+            @current-change="handleCurrentChange"
+            @size-change="handleSizeChange"
+          />
+        </div>
+  
+      </div>
+  
+      <el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="dialogTitle">
+        <!-- <warning-bar title="新增API,需要在角色管理内配置权限才可使用" /> -->
+        <el-form ref="apiForm" :model="form" :rules="rules" label-width="80px">
+          <el-form-item label="游戏名称" prop="game_name" >
+            <el-input v-model="form.game_name" autocomplete="off" />
+          </el-form-item>
+          <!-- <el-form-item label="游戏端口" prop="gamePort">
+            <el-input v-model="form.game_port" autocomplete="off" />
+          </el-form-item> -->
+        
+          <el-form-item label="游戏端口">
+            <el-select v-model="form.game_port" clearable placeholder="游戏端口">
+              <el-option
+                v-for="item in gamePortOptions"
+                :key="item"
+                :label="item"
+                :value="item"
+              />
+            </el-select>
+          </el-form-item>
+          <!-- <el-form-item label="登录方式" prop="loginType">
+            <el-input v-model="form.login_type" autocomplete="off"  />
+          </el-form-item> -->
+          <el-form-item label="登录方式">
+            <el-select v-model="form.login_type"  clearable placeholder="登录方式">
+              <el-option
+                v-for="item in loginTypeOptions"
+                :key="item"
+                :label="item"
+                :value="item"
+              />
+            </el-select>
+          </el-form-item>
+
+          <el-form-item label="备注" prop="remark">
+            <el-input v-model="form.remark" autocomplete="off"  />
+          </el-form-item>
+        </el-form>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button size="small" @click="closeDialog">取 消</el-button>
+            <el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
+          </div>
+        </template>
+      </el-dialog>
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    name: 'Api',
+    
+  }
+  </script>
+  
+  <script setup>
+  import {
+    getApiById,
+    getApiList,
+    createApi,
+    updateApi,
+    deleteApi,
+    deleteApisByIds
+  } from '@/api/gameList'
+  import { toSQLLine } from '@/utils/stringFun'
+  import warningBar from '@/components/warningBar/warningBar.vue'
+  import { ref } from 'vue'
+  import { ElMessage, ElMessageBox } from 'element-plus'
+import { isNumber } from 'lodash'
+  
+  const methodFiletr = (value) => {
+    const target = searchOptions.value.filter(item => item.value === value)[0]
+    return target && `${target.label}`
+  }
+  
+  const apis = ref([])
+  const form = ref({
+    game_name: '',
+    game_port: '',
+    login_type: '',
+    remark: '',
+  })
+  const     searchOptions = ref([
+    {
+      value: 'game_name',
+      label: '游戏名称',
+
+    },
+    {
+      value: 'game_port',
+      label: '游戏端口',
+
+    },
+    {
+      value: 'login_type',
+      label: '登录方式',
+
+    },
+  ])
+  const     gamePortOptions = ref([
+    // {
+    //   value: '魅族',
+    //   label: '魅族',
+    // },
+    // {
+    //   value: '酷派',
+    //   label: '酷派',
+    // },
+    // {
+    //   value: '网易',
+    //   label: '网易',
+    // },
+    // {
+    //   value: '360',
+    //   label: '360',
+    // },
+    // {
+    //   value: '腾讯',
+    //   label: '腾讯',
+    // },
+  ])
+  const     loginTypeOptions = ref([
+    // {
+    //   value: '微信+QQ',
+    //   label: '微信+QQ',
+    // },
+    // {
+    //   value: '微信',
+    //   label: '微信',
+    // },
+    // {
+    //   value: '网易',
+    //   label: '网易',
+    // },
+    // {
+    //   value: 'QQ',
+    //   label: 'QQ',
+    // },
+    // {
+    //   value: '魅族',
+    //   label: '魅族',
+    // },
+    // {
+    //   value: '小绵羊',
+    //   label: '小绵羊',
+    // },
+  ])
+  const type = ref('')
+  const rules = ref({
+    path: [{ required: true, message: '请输入api路径', trigger: 'blur' }],
+    apiGroup: [
+      { required: true, message: '请输入组名称', trigger: 'blur' }
+    ],
+    method: [
+      { required: true, message: '请选择请求方式', trigger: 'blur' }
+    ],
+    description: [
+      { required: true, message: '请输入api介绍', trigger: 'blur' }
+    ]
+  })
+  
+  const page = ref(1)
+  const total = ref(0)
+  const pageSize = ref(10)
+  const tableData = ref([])
+  const searchInfo = ref({
+    searchKey:"game_name",
+  })
+  
+  const onReset = () => {
+    searchInfo.value = {}
+    getTableData()
+  }
+  // 搜索
+  
+  const onSubmit = () => {
+    page.value = 1
+    pageSize.value = 10
+    getTableData()
+  }
+  
+  // 分页
+  const handleSizeChange = (val) => {
+    pageSize.value = val
+    getTableData()
+  }
+  
+  const handleCurrentChange = (val) => {
+    page.value = val
+    getTableData()
+  }
+  
+  // 排序
+  const sortChange = ({ prop, order }) => {
+    if (prop) {
+      if (prop === 'ID') {
+        prop = 'id'
+      }
+      searchInfo.value.orderKey = toSQLLine(prop)
+      searchInfo.value.desc = order === 'descending'
+    }
+    getTableData()
+  }
+  
+  // 查询
+  const getTableData = async() => {
+    const table = await getApiList({ page: page.value, pageSize: pageSize.value, ...searchInfo.value})
+    if (table.code === 0) {
+      tableData.value = table.data.list
+      gamePortOptions.value = table.data.option.channel_name
+      loginTypeOptions.value = table.data.option.login_name
+      total.value = table.data.total
+      page.value = table.data.page
+      pageSize.value = table.data.pageSize
+    }
+  }
+  
+  getTableData()
+  
+  // 批量操作
+  const handleSelectionChange = (val) => {
+    apis.value = val
+  }
+  
+  const deleteVisible = ref(false)
+  const onDelete = async() => {
+    const ids = apis.value.map(item => item.id)
+    const res = await deleteApisByIds({ ids })
+    if (res.code === 0) {
+      ElMessage({
+        type: 'success',
+        message: res.msg
+      })
+      if (tableData.value.length === ids.length && page.value > 1) {
+        page.value--
+      }
+      deleteVisible.value = false
+      getTableData()
+    }
+  }
+  
+  // 弹窗相关
+  const apiForm = ref(null)
+  const initForm = () => {
+    apiForm.value.resetFields()
+    form.value = {
+    //   path: '',
+    //   apiGroup: '',
+    //   method: '',
+    //   description: ''
+    channelName: '',
+    channelDesc: '',
+    displaySequence: '',
+    gameCounts: ''
+    }
+  }
+  
+  const dialogTitle = ref('新增Api')
+  const dialogFormVisible = ref(false)
+  const openDialog = (key) => {
+    switch (key) {
+      case 'addGameList':
+        dialogTitle.value = '新增'
+        break
+      case 'editGameList':
+        dialogTitle.value = '编辑'
+        break
+      default:
+        break
+    }
+    type.value = key
+    dialogFormVisible.value = true
+  }
+  const closeDialog = () => {
+    initForm()
+    dialogFormVisible.value = false
+  }
+  
+  const editApiFunc = async(row) => {
+    const res = await getApiById({ id: row.id })
+    form.value = res.data.gameList
+    openDialog('editGameList')
+  }
+  
+  const enterDialog = async() => {
+    apiForm.value.validate(async valid => {
+      if (valid) {
+        switch (type.value) {
+          case 'addGameList':
+            {
+              const res = await createApi(form.value)
+              if (res.code === 0) {
+                ElMessage({
+                  type: 'success',
+                  message: '添加成功',
+                  showClose: true
+                })
+              }
+              getTableData()
+              closeDialog()
+            }
+  
+            break
+          case 'editGameList':
+            {
+              const res = await updateApi(form.value)
+              if (res.code === 0) {
+                ElMessage({
+                  type: 'success',
+                  message: '编辑成功',
+                  showClose: true
+                })
+              }
+              getTableData()
+              closeDialog()
+            }
+            break
+          default:
+            // eslint-disable-next-line no-lone-blocks
+            {
+              ElMessage({
+                type: 'error',
+                message: '未知操作',
+                showClose: true
+              })
+            }
+            break
+        }
+      }
+    })
+  }
+  
+  const deleteApiFunc = async(row) => {
+    ElMessageBox.confirm('此操作将永久删除此游戏, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    })
+      .then(async() => {
+        const res = await deleteApi(row)
+        if (res.code === 0) {
+          ElMessage({
+            type: 'success',
+            message: '删除成功!'
+          })
+          if (tableData.value.length === 1 && page.value > 1) {
+            page.value--
+          }
+          getTableData()
+        }
+      })
+  }
+  
+  </script>
+  
+  <style scoped lang="scss">
+  .button-box {
+    padding: 10px 20px;
+    .el-button {
+      float: right;
+    }
+  }
+  .warning {
+    color: #dc143c;
+  }
+  </style>
+  

+ 21 - 0
src/view/typeManage/index.vue

@@ -0,0 +1,21 @@
+<template>
+  <div>
+    <router-view v-slot="{ Component }">
+      <transition mode="out-in" name="el-fade-in-linear">
+        <keep-alive :include="routerStore.keepAliveRouters">
+          <component :is="Component" />
+        </keep-alive>
+      </transition>
+    </router-view>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'TypeManage'
+}
+</script>
+<script setup>
+import { useRouterStore } from '@/pinia/modules/router'
+const routerStore = useRouterStore()
+</script>

+ 362 - 0
src/view/typeManage/loginType.vue

@@ -0,0 +1,362 @@
+<template>
+    <div>
+      <div class="gva-search-box">
+        <el-form ref="searchForm" :inline="true" :model="searchInfo">
+          <el-form-item>
+            <el-select v-model="searchInfo.searchKey"  >
+              <el-option
+                v-for="item in searchOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-input v-model="searchInfo.login_name" placeholder="请输入关键字"/>
+          </el-form-item>
+          <el-form-item>
+            <el-button size="small" type="primary" icon="search" @click="onSubmit">搜索</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="gva-table-box">
+        <div class="gva-btn-list">
+          <el-button size="small" icon="refresh" @click="onReset">刷新</el-button>
+          <el-button size="small" type="primary" icon="plus" @click="openDialog('addLoginType')">新增</el-button>
+          <el-popover v-model="deleteVisible" placement="top" width="160">
+            <p>确定要删除吗?</p>
+            <div style="text-align: right; margin-top: 8px;">
+              <el-button size="small" type="primary" link @click="deleteVisible = false">取消</el-button>
+              <el-button size="small" type="primary" @click="onDelete">确定</el-button>
+            </div>
+            <template #reference>
+              <el-button icon="delete" type="danger" size="small" :disabled="!apis.length" style="margin-left: 10px;" @click="deleteVisible = true">删除</el-button>
+            </template>
+          </el-popover>
+        </div>
+        <el-table :data="tableData" @sort-change="sortChange" @selection-change="handleSelectionChange">
+          <el-table-column
+            type="selection"
+            width="55"
+          />
+          <el-table-column align="left" label="登录名称" min-width="100" prop="login_name" sortable="custom" />
+          <el-table-column align="left" label="登录描述" min-width="150" prop="login_desc"  />
+          <el-table-column align="left" label="显示顺序" min-width="150" prop="display_sequence" sortable="custom" />
+          <el-table-column align="left" label="游戏数量" min-width="150" prop="game_counts" sortable="custom" />
+          <el-table-column align="left" label="创建时间" min-width="150" prop="createdAt" sortable="custom" />
+          <el-table-column align="left" label="更新时间" min-width="150" prop="updatedAt" sortable="custom" />
+  
+          <el-table-column align="left" fixed="right" label="操作" width="200">
+            <template #default="scope">
+              <el-button
+                icon="edit"
+                size="small"
+                type="primary"
+                link
+                @click="editApiFunc(scope.row)"
+              >编辑</el-button>
+              <el-button
+                icon="delete"
+                size="small"
+                type="primary"
+                link
+                @click="deleteApiFunc(scope.row)"
+              >删除</el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <div class="gva-pagination">
+          <el-pagination
+            :current-page="page"
+            :page-size="pageSize"
+            :page-sizes="[10, 30, 50, 100]"
+            :total="total"
+            layout="total, sizes, prev, pager, next, jumper"
+            @current-change="handleCurrentChange"
+            @size-change="handleSizeChange"
+          />
+        </div>
+  
+      </div>
+  
+      <el-dialog v-model="dialogFormVisible" :before-close="closeDialog" :title="dialogTitle">
+        <!-- <warning-bar title="新增API,需要在角色管理内配置权限才可使用" /> -->
+        <el-form ref="apiForm" :model="form" :rules="rules" label-width="80px">
+          <el-form-item label="登录名称" prop="login_name" >
+            <el-input v-model="form.login_name" autocomplete="off" />
+          </el-form-item>
+          <el-form-item label="登录描述" prop="login_desc" >
+            <el-input v-model="form.login_desc" autocomplete="off" />
+          </el-form-item>
+          <el-form-item label="显示顺序" prop="display_sequence" >
+            <el-input-number v-model="form.display_sequence" min=0 autocomplete="off" clearable placeholder="0"/>
+          </el-form-item>
+        </el-form>
+        <template #footer>
+          <div class="dialog-footer">
+            <el-button size="small" @click="closeDialog">取 消</el-button>
+            <el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
+          </div>
+        </template>
+      </el-dialog>
+    </div>
+  </template>
+  
+  <script>
+  export default {
+    name: 'Api',
+    
+  }
+  </script>
+  
+  <script setup>
+  import {
+    getApiById,
+    getApiList,
+    createApi,
+    updateApi,
+    deleteApi,
+    deleteApisByIds
+  } from '@/api/loginType'
+  import { toSQLLine } from '@/utils/stringFun'
+  import warningBar from '@/components/warningBar/warningBar.vue'
+  import { ref } from 'vue'
+  import { ElMessage, ElMessageBox } from 'element-plus'
+import { isNumber } from 'lodash'
+  
+  const methodFiletr = (value) => {
+    const target = searchOptions.value.filter(item => item.value === value)[0]
+    return target && `${target.label}`
+  }
+  
+  const apis = ref([])
+  const form = ref({
+    login_name: '',
+    login_desc: ''
+  })
+  const     searchOptions = ref([
+    {
+      value: 'login_name',
+      label: '登录名称',
+
+    },
+  ])
+  const type = ref('')
+  const rules = ref({
+    path: [{ required: true, message: '请输入api路径', trigger: 'blur' }],
+    apiGroup: [
+      { required: true, message: '请输入组名称', trigger: 'blur' }
+    ],
+    method: [
+      { required: true, message: '请选择请求方式', trigger: 'blur' }
+    ],
+    description: [
+      { required: true, message: '请输入api介绍', trigger: 'blur' }
+    ]
+  })
+  
+  const page = ref(1)
+  const total = ref(0)
+  const pageSize = ref(10)
+  const tableData = ref([])
+  const searchInfo = ref({
+    searchKey:"login_name",
+  })
+  
+  const onReset = () => {
+    searchInfo.value = {}
+    getTableData()
+  }
+  // 搜索
+  
+  const onSubmit = () => {
+    page.value = 1
+    pageSize.value = 10
+    getTableData()
+  }
+  
+  // 分页
+  const handleSizeChange = (val) => {
+    pageSize.value = val
+    getTableData()
+  }
+  
+  const handleCurrentChange = (val) => {
+    page.value = val
+    getTableData()
+  }
+  
+  // 排序
+  const sortChange = ({ prop, order }) => {
+    if (prop) {
+      if (prop === 'ID') {
+        prop = 'id'
+      }
+      searchInfo.value.orderKey = toSQLLine(prop)
+      searchInfo.value.desc = order === 'descending'
+    }
+    getTableData()
+  }
+  
+  // 查询
+  const getTableData = async() => {
+    const table = await getApiList({ page: page.value, pageSize: pageSize.value, ...searchInfo.value})
+    if (table.code === 0) {
+      tableData.value = table.data.list
+      total.value = table.data.total
+      page.value = table.data.page
+      pageSize.value = table.data.pageSize
+    }
+  }
+  
+  getTableData()
+  
+  // 批量操作
+  const handleSelectionChange = (val) => {
+    apis.value = val
+  }
+  
+  const deleteVisible = ref(false)
+  const onDelete = async() => {
+    const ids = apis.value.map(item => item.id)
+    const res = await deleteApisByIds({ ids })
+    if (res.code === 0) {
+      ElMessage({
+        type: 'success',
+        message: res.msg
+      })
+      if (tableData.value.length === ids.length && page.value > 1) {
+        page.value--
+      }
+      deleteVisible.value = false
+      getTableData()
+    }
+  }
+  
+  // 弹窗相关
+  const apiForm = ref(null)
+  const initForm = () => {
+    apiForm.value.resetFields()
+    form.value = {
+    //   path: '',
+    //   apiGroup: '',
+    //   method: '',
+    //   description: ''
+    // channelName: '',
+    // channelDesc: '',
+    // displaySequence: '',
+    // gameCounts: ''
+    }
+  }
+  
+  const dialogTitle = ref('新增Api')
+  const dialogFormVisible = ref(false)
+  const openDialog = (key) => {
+    switch (key) {
+      case 'addLoginType':
+        dialogTitle.value = '新增'
+        break
+      case 'editLoginType':
+        dialogTitle.value = '编辑'
+        break
+      default:
+        break
+    }
+    type.value = key
+    dialogFormVisible.value = true
+  }
+  const closeDialog = () => {
+    initForm()
+    dialogFormVisible.value = false
+  }
+  
+  const editApiFunc = async(row) => {
+    const res = await getApiById({ id: row.id })
+    form.value = res.data.login_type
+    openDialog('editLoginType')
+  }
+  
+  const enterDialog = async() => {
+    apiForm.value.validate(async valid => {
+      if (valid) {
+        switch (type.value) {
+          case 'addLoginType':
+            {
+              const res = await createApi(form.value)
+              if (res.code === 0) {
+                ElMessage({
+                  type: 'success',
+                  message: '添加成功',
+                  showClose: true
+                })
+              }
+              getTableData()
+              closeDialog()
+            }
+  
+            break
+          case 'editLoginType':
+            {
+              const res = await updateApi(form.value)
+              if (res.code === 0) {
+                ElMessage({
+                  type: 'success',
+                  message: '编辑成功',
+                  showClose: true
+                })
+              }
+              getTableData()
+              closeDialog()
+            }
+            break
+          default:
+            // eslint-disable-next-line no-lone-blocks
+            {
+              ElMessage({
+                type: 'error',
+                message: '未知操作',
+                showClose: true
+              })
+            }
+            break
+        }
+      }
+    })
+  }
+  
+  const deleteApiFunc = async(row) => {
+    ElMessageBox.confirm('此操作将永久删除此登录类型, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    })
+      .then(async() => {
+        const res = await deleteApi(row)
+        if (res.code === 0) {
+          ElMessage({
+            type: 'success',
+            message: '删除成功!'
+          })
+          if (tableData.value.length === 1 && page.value > 1) {
+            page.value--
+          }
+          getTableData()
+        }
+      })
+  }
+  
+  </script>
+  
+  <style scoped lang="scss">
+  .button-box {
+    padding: 10px 20px;
+    .el-button {
+      float: right;
+    }
+  }
+  .warning {
+    color: #dc143c;
+  }
+  </style>
+  

+ 447 - 0
src/view/typeManage/responsiblePerson.vue

@@ -0,0 +1,447 @@
+<template>
+  <div>
+    <div class="gva-search-box">
+        <el-form ref="searchForm" :inline="true" :model="searchInfo">
+          <el-form-item>
+            <el-select v-model="searchInfo.searchKey"  >
+              <el-option
+                v-for="item in searchOptions"
+                :key="item.value"
+                :label="item.label"
+                :value="item.value"
+              />
+            </el-select>
+          </el-form-item>
+          <el-form-item>
+            <el-input v-model="searchInfo.name" placeholder="请输入关键字"/>
+          </el-form-item>
+          <el-form-item>
+            <el-button size="small" type="primary" icon="search" @click="onSubmit">搜索</el-button>
+          </el-form-item>
+        </el-form>
+      </div>
+      <div class="gva-btn-list">
+          <el-button size="small" icon="refresh" @click="onReset">刷新</el-button>
+          <el-button size="small" type="primary" icon="plus" @click="openDialog('addResponsiblePerson')">新增</el-button>
+          <el-popover v-model="deleteVisible" placement="top" width="160">
+            <p>确定要删除吗?</p>
+            <div style="text-align: right; margin-top: 8px;">
+              <el-button size="small" type="primary" link @click="deleteVisible = false">取消</el-button>
+              <el-button size="small" type="primary" @click="onDelete">确定</el-button>
+            </div>
+            <template #reference>
+              <el-button icon="delete" type="danger" size="small" :disabled="!apis.length" style="margin-left: 10px;" @click="deleteVisible = true">删除</el-button>
+            </template>
+          </el-popover>
+        </div>
+    <div class="gva-table-box">
+      <el-table
+        :data="tableData"
+        @sort-change="sortChange" 
+        @selection-change="handleSelectionChange"
+      >
+      <el-table-column
+            type="selection"
+            width="55"
+          />
+        <el-table-column align="center" label="头像" min-width="100">
+          <template #default="scope">
+            <CustomPic style="margin-top:8px" :pic-src="scope.row.img" />
+          </template>
+        </el-table-column>
+        <el-table-column align="left" label="姓名" min-width="150" prop="name" />
+        <el-table-column align="left" label="昵称" min-width="150" prop="nickname" />
+        <el-table-column align="left" label="部门名称" min-width="150" prop="department_name" />
+        <el-table-column align="left" label="手机号码" min-width="150" prop="mobile_phone_number" />
+        <el-table-column align="left" label="游戏数量" min-width="150" prop="game_counts" />
+        <el-table-column align="left" label="备注" min-width="150" prop="remark" />
+        <el-table-column align="center" label="状态" min-width="150" prop="state" >
+          <template #default="scope">
+            <el-button size="small"
+            :type="scope.row.state == 2 ? 'danger' : 'success'">
+            {{scope.row.state == 2? '禁用' : '启用'}}
+            </el-button>
+          </template>
+        </el-table-column>
+        <el-table-column align="left" label="创建时间" min-width="200" prop="createTime" sortable="custom" />
+
+
+        <el-table-column align="left" fixed="right" label="操作" width="200">
+            <template #default="scope">
+              <el-button
+                icon="edit"
+                size="small"
+                type="primary"
+                link
+                @click="editApiFunc(scope.row)"
+              >编辑</el-button>
+              <el-button
+                icon="delete"
+                size="small"
+                type="primary"
+                link
+                @click="deleteApiFunc(scope.row)"
+              >删除</el-button>
+            </template>
+          </el-table-column>
+
+      </el-table>
+      <div class="gva-pagination">
+        <el-pagination
+          :current-page="page"
+          :page-size="pageSize"
+          :page-sizes="[10, 30, 50, 100]"
+          :total="total"
+          layout="total, sizes, prev, pager, next, jumper"
+          @current-change="handleCurrentChange"
+          @size-change="handleSizeChange"
+        />
+      </div>
+    </div>
+    <el-dialog
+      v-model="dialogFormVisible"
+      
+      custom-class="user-dialog"
+      :before-close="closeDialog"
+      :title="dialogTitle"
+      :show-close="false"
+      :close-on-press-escape="false"
+      :close-on-click-modal="false"
+    >
+      <div style="height:60vh;overflow:auto;padding:0 12px;">
+        <el-form ref="userForm" :rules="rules" :model="userInfo" label-width="80px">
+          <el-form-item label="姓名" prop="name">
+            <el-input v-model="userInfo.name" />
+          </el-form-item>
+          <el-form-item label="昵称" prop="nickname">
+            <el-input v-model="userInfo.nickname" />
+          </el-form-item>
+          <el-form-item label="部门" prop="department_name">
+            <el-input v-model="userInfo.department_name" />
+          </el-form-item>
+          <el-form-item label="手机号码" prop="mobile_phone_number">
+            <el-input v-model="userInfo.mobile_phone_number" />
+          </el-form-item>
+          <el-form-item label="备注" prop="remark">
+            <el-input v-model="userInfo.remark" />
+          </el-form-item>
+          <el-form-item label="状态" prop="state">
+            <el-radio-group v-model="userInfo.state" class="ml-4">
+              <el-radio :label="1"  size="large">开启</el-radio>
+              <el-radio :label="2"  size="large">关闭</el-radio>
+            </el-radio-group>
+          </el-form-item>
+          <el-form-item label="头像" label-width="80px">
+            <div style="display:inline-block" @click="openHeaderChange">
+              <img v-if="userInfo.img" class="header-img-box" :src="(userInfo.img && userInfo.img.slice(0, 4) !== 'http')?path+userInfo.img:userInfo.img">
+              <div v-else class="header-img-box">从媒体库选择</div>
+            </div>
+          </el-form-item>
+
+        </el-form>
+
+      </div>
+
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button size="small" @click="closeDialog">取 消</el-button>
+          <el-button size="small" type="primary" @click="enterDialog">确 定</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <ChooseImg ref="chooseImg" :target="userInfo" :target-key="`img`" />
+  </div>
+</template>
+
+<script>
+export default {
+  // name: 'User',
+  // state: 0,
+}
+</script>
+
+<script setup>
+
+import {
+  getApiById,
+  getApiList,
+  createApi,
+  updateApi,
+  deleteApi,
+  deleteApisByIds
+} from '@/api/responsiblePerson'
+import { toSQLLine } from '@/utils/stringFun'
+import CustomPic from '@/components/customPic/customIndex.vue'
+import ChooseImg from '@/components/chooseImg/index.vue'
+import warningBar from '@/components/warningBar/warningBar.vue'
+
+import { nextTick, ref, watch } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import User from '../superAdmin/user/user.vue'
+
+
+  const form = ref({
+
+  })
+  const     searchOptions = ref([
+    {
+      value: 'name',
+      label: '姓名',
+
+    },
+  ])
+  const type = ref('')
+  const page = ref(1)
+  const total = ref(0)
+  const pageSize = ref(10)
+  const tableData = ref([])
+  const searchInfo = ref({
+    searchKey:"name",
+  })
+  
+  const onReset = () => {
+    searchInfo.value = {}
+  }
+
+
+
+ // 搜索
+  
+ const onSubmit = () => {
+    page.value = 1
+    pageSize.value = 10
+    getTableData()
+  }
+  
+  // 分页
+  const handleSizeChange = (val) => {
+    pageSize.value = val
+    getTableData()
+  }
+  
+  const handleCurrentChange = (val) => {
+    page.value = val
+    getTableData()
+  }
+  
+  // 排序
+  const sortChange = ({ prop, order }) => {
+    if (prop) {
+      if (prop === 'ID') {
+        prop = 'id'
+      }
+      searchInfo.value.orderKey = toSQLLine(prop)
+      searchInfo.value.desc = order === 'descending'
+    }
+    getTableData()
+  }
+  
+  // 查询
+  const getTableData = async() => {
+    const table = await getApiList({ page: page.value, pageSize: pageSize.value, ...searchInfo.value})
+    if (table.code === 0) {
+      tableData.value = table.data.list
+      total.value = table.data.total
+      page.value = table.data.page
+      pageSize.value = table.data.pageSize
+    }
+  }
+  
+  getTableData()
+  
+  // 批量操作
+  const handleSelectionChange = (val) => {
+    apis.value = val
+  }
+  const apis = ref([])
+  const deleteVisible = ref(false)
+  const onDelete = async() => {
+    const ids = apis.value.map(item => item.id)
+    const res = await deleteApisByIds({ ids })
+    if (res.code === 0) {
+      ElMessage({
+        type: 'success',
+        message: res.msg
+      })
+      if (tableData.value.length === ids.length && page.value > 1) {
+        page.value--
+      }
+      deleteVisible.value = false
+      getTableData()
+    }
+  }
+  
+
+  // 弹窗相关
+  const userInfo = ref({
+    name: '',
+    nickname: '',
+    department_name: '',
+    mobile_phone_number: '',
+    remark: '',
+    state: 0,
+    img: '',
+  })
+  const path = ref(import.meta.env.VITE_BASE_API + '/')
+
+
+
+  const userForm = ref(null)
+  const initForm = () => {
+    userForm.value.resetFields()
+    userInfo.value = {
+      name: '',
+      nickname: '',
+      department_name: '',
+      mobile_phone_number: '',
+      remark: '',
+      state: 0,
+      img: '',
+    }
+  }
+  
+  const dialogTitle = ref('新增Api')
+  const dialogFormVisible = ref(false)
+  const openDialog = (key) => {
+    switch (key) {
+      case 'addResponsiblePerson':
+        dialogTitle.value = '新增'
+        break
+      case 'editResponsiblePerson':
+        dialogTitle.value = '编辑'
+        break
+      default:
+        break
+    }
+
+    type.value = key
+    dialogFormVisible.value = true
+  }
+  const closeDialog = () => {
+    initForm()
+    dialogFormVisible.value = false
+    userInfo.value.img = ''
+  }
+  
+  const editApiFunc = async(row) => {
+    const res = await getApiById({ id: row.id })
+    userInfo.value = res.data.responsible_person
+    openDialog('editResponsiblePerson')
+  }
+  
+  const enterDialog = async() => {
+    userForm.value.validate(async valid => {
+      if (valid) {
+        switch (type.value) {
+          case 'addResponsiblePerson':
+            {
+              const res = await createApi(userInfo.value)
+              if (res.code === 0) {
+                ElMessage({
+                  type: 'success',
+                  message: '添加成功',
+                  showClose: true
+                })
+              }
+              getTableData()
+              closeDialog()
+            }
+  
+            break
+          case 'editResponsiblePerson':
+            {
+              const res = await updateApi(userInfo.value)
+              if (res.code === 0) {
+                ElMessage({
+                  type: 'success',
+                  message: '编辑成功',
+                  showClose: true
+                })
+              }
+              getTableData()
+              closeDialog()
+            }
+            break
+          default:
+            // eslint-disable-next-line no-lone-blocks
+            {
+              ElMessage({
+                type: 'error',
+                message: '未知操作',
+                showClose: true
+              })
+            }
+            break
+        }
+      }
+    })
+  }
+  const chooseImg = ref(null)
+  const openHeaderChange = () => {
+    chooseImg.value.open()
+  } 
+
+  const deleteApiFunc = async(row) => {
+    ElMessageBox.confirm('此操作将永久删除此负责人, 是否继续?', '提示', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning'
+    })
+      .then(async() => {
+        const res = await deleteApi(row)
+        if (res.code === 0) {
+          ElMessage({
+            type: 'success',
+            message: '删除成功!'
+          })
+          if (tableData.value.length === 1 && page.value > 1) {
+            page.value--
+          }
+          getTableData()
+        }
+      })
+  }
+
+</script>
+
+<style lang="scss">
+.user-dialog {
+  .header-img-box {
+  width: 200px;
+  height: 200px;
+  border: 1px dashed #ccc;
+  border-radius: 20px;
+  text-align: center;
+  line-height: 200px;
+  cursor: pointer;
+}
+  .avatar-uploader .el-upload:hover {
+    border-color: #409eff;
+  }
+  .avatar-uploader-icon {
+    border: 1px dashed #d9d9d9 !important;
+    border-radius: 6px;
+    font-size: 28px;
+    color: #8c939d;
+    width: 178px;
+    height: 178px;
+    line-height: 178px;
+    text-align: center;
+  }
+  .avatar {
+    width: 178px;
+    height: 178px;
+    display: block;
+  }
+}
+.nickName{
+  display: flex;
+  justify-content: flex-start;
+  align-items: center;
+}
+.pointer{
+  cursor: pointer;
+  font-size: 16px;
+  margin-left: 2px;
+}
+</style>