|
|
@@ -0,0 +1,502 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <div class="gva-search-box">
|
|
|
+ <el-form
|
|
|
+ ref="elSearchFormRef"
|
|
|
+ :inline="true"
|
|
|
+ :model="searchInfo"
|
|
|
+ class="demo-form-inline"
|
|
|
+ :rules="searchRule"
|
|
|
+ @keyup.enter="onSubmit"
|
|
|
+ >
|
|
|
+ <el-form-item
|
|
|
+ label="应用名称"
|
|
|
+ prop="name"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="searchInfo.name"
|
|
|
+ placeholder="搜索条件"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item
|
|
|
+ label="启用状态"
|
|
|
+ prop="status"
|
|
|
+ >
|
|
|
+ <el-select
|
|
|
+ v-model="searchInfo.status"
|
|
|
+ placeholder="请选择启用状态"
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in statusOptions"
|
|
|
+ :label="item.label"
|
|
|
+ :value="item.value"
|
|
|
+ :key="item.value"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ icon="search"
|
|
|
+ @click="onSubmit"
|
|
|
+ >查询</el-button>
|
|
|
+ <el-button
|
|
|
+ icon="refresh"
|
|
|
+ @click="onReset"
|
|
|
+ >重置</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ </div>
|
|
|
+ <div class="gva-table-box">
|
|
|
+ <div class="gva-btn-list">
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ icon="plus"
|
|
|
+ @click="openDialog"
|
|
|
+ >新增应用</el-button>
|
|
|
+ </div>
|
|
|
+ <el-table
|
|
|
+ ref="multipleTable"
|
|
|
+ style="width: 100%"
|
|
|
+ :data="tableData"
|
|
|
+ row-key="ID"
|
|
|
+ >
|
|
|
+ <el-table-column
|
|
|
+ align="left"
|
|
|
+ label="应用名称"
|
|
|
+ prop="name"
|
|
|
+ width="180"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ align="center"
|
|
|
+ label="key"
|
|
|
+ prop="apiKey"
|
|
|
+ width="320"
|
|
|
+ />
|
|
|
+ <el-table-column
|
|
|
+ align="center"
|
|
|
+ label="安全密钥"
|
|
|
+ prop="apiSecret"
|
|
|
+ width="350"
|
|
|
+ ><template #default="{ row }">
|
|
|
+ <span>
|
|
|
+ {{ row.apiSecret }}
|
|
|
+ <el-button
|
|
|
+ link
|
|
|
+ size="small"
|
|
|
+ type="primary"
|
|
|
+ style="margin-left: 10px;"
|
|
|
+ @click="distributeApplicationFunc(row.id)"
|
|
|
+ >
|
|
|
+ 复制
|
|
|
+ </el-button>
|
|
|
+ </span>
|
|
|
+ </template>
|
|
|
+
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ align="center"
|
|
|
+ label="启用状态"
|
|
|
+ prop="status"
|
|
|
+ width="120"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <el-switch
|
|
|
+ v-model="scope.row.status"
|
|
|
+ inline-prompt
|
|
|
+ :active-value="1"
|
|
|
+ :inactive-value="2"
|
|
|
+ @change="
|
|
|
+ (v) => {
|
|
|
+ switchEnable(scope.row, v);
|
|
|
+ }
|
|
|
+ "
|
|
|
+ />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ align="center"
|
|
|
+ label="创建日期"
|
|
|
+ width="220"
|
|
|
+ >
|
|
|
+ <template #default="scope">{{
|
|
|
+ formatDate(scope.row.createdAt)
|
|
|
+ }}</template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column
|
|
|
+ align="center"
|
|
|
+ label="操作"
|
|
|
+ fixed="right"
|
|
|
+ >
|
|
|
+ <template #default="scope">
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ link
|
|
|
+ icon="edit"
|
|
|
+ class="table-button"
|
|
|
+ @click="updateSysApplicationFunc(scope.row)"
|
|
|
+ >重置密钥</el-button>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ link
|
|
|
+ icon="delete"
|
|
|
+ @click="deleteRow(scope.row)"
|
|
|
+ >删除</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+ <div class="gva-pagination">
|
|
|
+ <el-pagination
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ :current-page="page"
|
|
|
+ :page-size="pageSize"
|
|
|
+ :page-sizes="[10, 30, 50, 100]"
|
|
|
+ :total="total"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ @size-change="handleSizeChange"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <el-dialog
|
|
|
+ v-model="dialogFormVisible"
|
|
|
+ :before-close="closeDialog"
|
|
|
+ :title="type === 'create' ? '添加应用' : '修改应用'"
|
|
|
+ destroy-on-close
|
|
|
+ >
|
|
|
+ <el-form
|
|
|
+ ref="elFormRef"
|
|
|
+ :model="formData"
|
|
|
+ label-position="right"
|
|
|
+ :rules="rule"
|
|
|
+ label-width="120px"
|
|
|
+ >
|
|
|
+ <el-form-item
|
|
|
+ label="应用名称"
|
|
|
+ prop="name"
|
|
|
+ >
|
|
|
+ <el-input
|
|
|
+ v-model="formData.name"
|
|
|
+ :clearable="true"
|
|
|
+ placeholder="请输入应用名称"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item
|
|
|
+ label="启用状态"
|
|
|
+ prop="status"
|
|
|
+ >
|
|
|
+ <el-radio-group
|
|
|
+ v-model="formData.status"
|
|
|
+ >
|
|
|
+ <el-radio
|
|
|
+ v-for="item in statusOptions"
|
|
|
+ :label="item.value"
|
|
|
+ :key="item.value"
|
|
|
+ >
|
|
|
+ {{ item.label }}
|
|
|
+ </el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <template #footer>
|
|
|
+ <div class="dialog-footer">
|
|
|
+ <el-button @click="closeDialog">取 消</el-button>
|
|
|
+ <el-button
|
|
|
+ type="primary"
|
|
|
+ @click="enterDialog"
|
|
|
+ >确 定</el-button>
|
|
|
+ </div>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup>
|
|
|
+import {
|
|
|
+ createSysApplication,
|
|
|
+ deleteSysApplication,
|
|
|
+ updateSysApplication,
|
|
|
+ getSysApplicationList, distributeApplication, resetApplication,
|
|
|
+} from '@/api/sys/sysApplication'
|
|
|
+
|
|
|
+// 全量引入格式化工具 请按需保留
|
|
|
+import {
|
|
|
+ formatDate,
|
|
|
+} from '@/utils/format'
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
+import { ref, reactive } from 'vue'
|
|
|
+
|
|
|
+defineOptions({
|
|
|
+ name: 'SysApplication',
|
|
|
+})
|
|
|
+
|
|
|
+const formData = ref({
|
|
|
+ name: '',
|
|
|
+ status: 1,
|
|
|
+})
|
|
|
+const detailData = ref({})
|
|
|
+const statusOptions = ref([
|
|
|
+ {
|
|
|
+ value: 1,
|
|
|
+ label: '启用',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 2,
|
|
|
+ label: '禁用',
|
|
|
+ },
|
|
|
+])
|
|
|
+// 验证规则
|
|
|
+const rule = ref({
|
|
|
+ name:
|
|
|
+ [{
|
|
|
+ required: true,
|
|
|
+ message: '请输入应用名称',
|
|
|
+ trigger: 'blur'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ max: 50,
|
|
|
+ message: '长度不能超过50个字符',
|
|
|
+ trigger: 'blur'
|
|
|
+ }],
|
|
|
+})
|
|
|
+
|
|
|
+const searchRule = reactive({
|
|
|
+ createdAt: [
|
|
|
+ {
|
|
|
+ validator: (rule, value, callback) => {
|
|
|
+ if (searchInfo.value.startCreatedAt && !searchInfo.value.endCreatedAt) {
|
|
|
+ callback(new Error('请填写结束日期'))
|
|
|
+ } else if (
|
|
|
+ !searchInfo.value.startCreatedAt &&
|
|
|
+ searchInfo.value.endCreatedAt
|
|
|
+ ) {
|
|
|
+ callback(new Error('请填写开始日期'))
|
|
|
+ } else if (
|
|
|
+ searchInfo.value.startCreatedAt &&
|
|
|
+ searchInfo.value.endCreatedAt &&
|
|
|
+ (searchInfo.value.startCreatedAt.getTime() ===
|
|
|
+ searchInfo.value.endCreatedAt.getTime() ||
|
|
|
+ searchInfo.value.startCreatedAt.getTime() >
|
|
|
+ searchInfo.value.endCreatedAt.getTime())
|
|
|
+ ) {
|
|
|
+ callback(new Error('开始日期应当早于结束日期'))
|
|
|
+ } else {
|
|
|
+ callback()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ trigger: 'change',
|
|
|
+ },
|
|
|
+ ],
|
|
|
+})
|
|
|
+
|
|
|
+const elFormRef = ref()
|
|
|
+const elSearchFormRef = ref()
|
|
|
+
|
|
|
+// =========== 表格控制部分 ===========
|
|
|
+const page = ref(1)
|
|
|
+const total = ref(0)
|
|
|
+const pageSize = ref(10)
|
|
|
+const tableData = ref([])
|
|
|
+const searchInfo = ref({})
|
|
|
+
|
|
|
+// 重置
|
|
|
+const onReset = () => {
|
|
|
+ searchInfo.value = {}
|
|
|
+ getTableData()
|
|
|
+}
|
|
|
+
|
|
|
+// 搜索
|
|
|
+const onSubmit = () => {
|
|
|
+ elSearchFormRef.value?.validate(async(valid) => {
|
|
|
+ if (!valid) return
|
|
|
+ page.value = 1
|
|
|
+ pageSize.value = 10
|
|
|
+ await getTableData()
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 分页
|
|
|
+const handleSizeChange = (val) => {
|
|
|
+ pageSize.value = val
|
|
|
+ getTableData()
|
|
|
+}
|
|
|
+
|
|
|
+// 修改页面容量
|
|
|
+const handleCurrentChange = (val) => {
|
|
|
+ page.value = val
|
|
|
+ getTableData()
|
|
|
+}
|
|
|
+
|
|
|
+// 查询
|
|
|
+const getTableData = async() => {
|
|
|
+ const table = await getSysApplicationList({
|
|
|
+ page: page.value,
|
|
|
+ pageSize: pageSize.value,
|
|
|
+ ...searchInfo.value,
|
|
|
+ })
|
|
|
+ if (table.code === 100000) {
|
|
|
+ tableData.value = table.data.applicationLists
|
|
|
+ total.value = table.data.total
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+getTableData()
|
|
|
+
|
|
|
+// ============== 表格控制部分结束 ===============
|
|
|
+
|
|
|
+// 获取需要的字典 可能为空 按需保留
|
|
|
+const setOptions = async() => {}
|
|
|
+
|
|
|
+// 获取需要的字典 可能为空 按需保留
|
|
|
+setOptions()
|
|
|
+
|
|
|
+// 删除行
|
|
|
+const deleteRow = (row) => {
|
|
|
+ ElMessageBox.confirm('确定要删除吗?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning',
|
|
|
+ }).then(() => {
|
|
|
+ deleteSysApplicationFunc(row)
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 行为控制标记(弹窗内部需要增还是改)
|
|
|
+const type = ref('')
|
|
|
+
|
|
|
+// 更新行
|
|
|
+const updateSysApplicationFunc = async(row) => {
|
|
|
+ ElMessageBox.confirm('确定要重置吗?', '提示', {
|
|
|
+ confirmButtonText: '确定',
|
|
|
+ cancelButtonText: '取消',
|
|
|
+ type: 'warning',
|
|
|
+ }).then(async() => {
|
|
|
+ const res = await resetApplication({ id: row.id })
|
|
|
+ if (res.code === 100000) {
|
|
|
+ ElMessage({
|
|
|
+ type: 'success',
|
|
|
+ message: '重置成功',
|
|
|
+ })
|
|
|
+ getTableData()
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// 删除行
|
|
|
+const deleteSysApplicationFunc = async(row) => {
|
|
|
+ const res = await deleteSysApplication({ id: row.id })
|
|
|
+ if (res.code === 100000) {
|
|
|
+ ElMessage({
|
|
|
+ type: 'success',
|
|
|
+ message: '删除成功',
|
|
|
+ })
|
|
|
+ if (tableData.value.length === 1 && page.value > 1) {
|
|
|
+ page.value--
|
|
|
+ }
|
|
|
+ await getTableData()
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 弹窗控制标记
|
|
|
+const dialogFormVisible = ref(false)
|
|
|
+
|
|
|
+const switchEnable = async(row, v) => {
|
|
|
+ const res = await updateSysApplication({
|
|
|
+ id: row.id,
|
|
|
+ status: v,
|
|
|
+ })
|
|
|
+ if (res.code === 100000) {
|
|
|
+ ElMessage({
|
|
|
+ type: 'success',
|
|
|
+ message: '修改成功',
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ getTableData()
|
|
|
+ }
|
|
|
+}
|
|
|
+// 复制文本到剪贴板
|
|
|
+const copyToClipboard = async(data) => {
|
|
|
+ // 自动处理对象类型
|
|
|
+ const text = data.apiSecret
|
|
|
+ if (navigator.clipboard) {
|
|
|
+ navigator.clipboard.writeText(text)
|
|
|
+ ElMessage({
|
|
|
+ type: 'success',
|
|
|
+ showClose: true,
|
|
|
+ message: '复制安全密钥成功,可以粘贴'
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ const textArea = document.createElement('textarea')
|
|
|
+ textArea.value = text
|
|
|
+ document.body.appendChild(textArea)
|
|
|
+ textArea.select()
|
|
|
+ try {
|
|
|
+ document.execCommand('copy')
|
|
|
+ ElMessage({
|
|
|
+ type: 'success',
|
|
|
+ showClose: true,
|
|
|
+ message: '复制json成功,可以粘贴'
|
|
|
+ })
|
|
|
+ } catch (err) {
|
|
|
+ ElMessage({
|
|
|
+ type: 'error',
|
|
|
+ showClose: true,
|
|
|
+ message: '复制失败!'
|
|
|
+ })
|
|
|
+ }
|
|
|
+ document.body.removeChild(textArea)
|
|
|
+ }
|
|
|
+}
|
|
|
+const distributeApplicationFunc = async(id) => {
|
|
|
+ const res = await distributeApplication({
|
|
|
+ id: id,
|
|
|
+ })
|
|
|
+ if (res.code === 100000) {
|
|
|
+ await copyToClipboard(res.data)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 打开弹窗
|
|
|
+const openDialog = () => {
|
|
|
+ type.value = 'create'
|
|
|
+ dialogFormVisible.value = true
|
|
|
+}
|
|
|
+
|
|
|
+// 关闭弹窗
|
|
|
+const closeDialog = () => {
|
|
|
+ dialogFormVisible.value = false
|
|
|
+ formData.value = {
|
|
|
+ status: 1,
|
|
|
+ name: '',
|
|
|
+ }
|
|
|
+}
|
|
|
+// 弹窗确定
|
|
|
+const enterDialog = async() => {
|
|
|
+ elFormRef.value?.validate(async(valid) => {
|
|
|
+ if (!valid) return
|
|
|
+ let res
|
|
|
+ switch (type.value) {
|
|
|
+ case 'create':
|
|
|
+ res = await createSysApplication(formData.value)
|
|
|
+ break
|
|
|
+ case 'update':
|
|
|
+ res = await updateSysApplication(formData.value)
|
|
|
+ break
|
|
|
+ default:
|
|
|
+ res = await createSysApplication(formData.value)
|
|
|
+ break
|
|
|
+ }
|
|
|
+ if (res.code === 100000) {
|
|
|
+ ElMessage({
|
|
|
+ type: 'success',
|
|
|
+ message: '创建/更改成功',
|
|
|
+ })
|
|
|
+ closeDialog()
|
|
|
+ await getTableData()
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style>
|
|
|
+
|
|
|
+</style>
|