|
@@ -4,12 +4,7 @@
|
|
<el-card class="search-card">
|
|
<el-card class="search-card">
|
|
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="100px">
|
|
<el-form :model="queryParams" ref="queryRef" :inline="true" label-width="100px">
|
|
<el-form-item label="菜单名称" prop="name">
|
|
<el-form-item label="菜单名称" prop="name">
|
|
- <el-input
|
|
|
|
- v-model="queryParams.name"
|
|
|
|
- placeholder="请输入菜单名称"
|
|
|
|
- clearable
|
|
|
|
- style="width: 200px"
|
|
|
|
- />
|
|
|
|
|
|
+ <el-input v-model="queryParams.name" placeholder="请输入菜单名称" clearable style="width: 200px" />
|
|
</el-form-item>
|
|
</el-form-item>
|
|
<el-form-item label="链接类型" prop="jumpType">
|
|
<el-form-item label="链接类型" prop="jumpType">
|
|
<el-select v-model="queryParams.jumpType" placeholder="请选择链接类型" clearable style="width: 200px">
|
|
<el-select v-model="queryParams.jumpType" placeholder="请选择链接类型" clearable style="width: 200px">
|
|
@@ -29,18 +24,8 @@
|
|
<el-option label="停用" :value="1" />
|
|
<el-option label="停用" :value="1" />
|
|
</el-select>
|
|
</el-select>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
- <el-form-item label="创建时间" prop="createTime">
|
|
|
|
- <el-date-picker
|
|
|
|
- v-model="dateRange"
|
|
|
|
- type="daterange"
|
|
|
|
- range-separator="-"
|
|
|
|
- start-placeholder="开始时间"
|
|
|
|
- end-placeholder="结束时间"
|
|
|
|
- style="width: 240px"
|
|
|
|
- />
|
|
|
|
- </el-form-item>
|
|
|
|
<el-form-item>
|
|
<el-form-item>
|
|
- <el-button type="primary" icon="Search" @click="handleQuery">Q 搜索</el-button>
|
|
|
|
|
|
+ <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
|
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
|
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-form>
|
|
</el-form>
|
|
@@ -53,12 +38,12 @@
|
|
<el-button type="primary" icon="Plus" @click="handleAdd"> 添加菜单</el-button>
|
|
<el-button type="primary" icon="Plus" @click="handleAdd"> 添加菜单</el-button>
|
|
</el-col>
|
|
</el-col>
|
|
<!-- <el-col :span="1.5">
|
|
<!-- <el-col :span="1.5">
|
|
- <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
|
|
|
|
|
|
+ <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()"
|
|
>修改
|
|
>修改
|
|
</el-button>
|
|
</el-button>
|
|
</el-col>
|
|
</el-col>
|
|
<el-col :span="1.5">
|
|
<el-col :span="1.5">
|
|
- <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
|
|
|
|
|
|
+ <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"
|
|
>删除
|
|
>删除
|
|
</el-button>
|
|
</el-button>
|
|
</el-col> -->
|
|
</el-col> -->
|
|
@@ -68,30 +53,29 @@
|
|
|
|
|
|
<!-- 菜单列表 -->
|
|
<!-- 菜单列表 -->
|
|
<el-card class="list-card">
|
|
<el-card class="list-card">
|
|
- <el-table
|
|
|
|
- v-loading="loading"
|
|
|
|
- :data="navItems"
|
|
|
|
- @selection-change="handleSelectionChange"
|
|
|
|
- style="width: 100%"
|
|
|
|
- >
|
|
|
|
|
|
+ <el-table v-loading="loading" :data="navItems" @selection-change="handleSelectionChange" style="width: 100%">
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
<el-table-column type="selection" width="55" align="center" />
|
|
<el-table-column label="序号" align="center" width="80" v-if="columns[0].visible">
|
|
<el-table-column label="序号" align="center" width="80" v-if="columns[0].visible">
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
<span class="sort-number">{{ scope.row.sortNum || '0' }}</span>
|
|
<span class="sort-number">{{ scope.row.sortNum || '0' }}</span>
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- <el-table-column label="菜单名称" align="center" prop="name" width="150" v-if="columns[1].visible" />
|
|
|
|
- <el-table-column label="活动类型" align="center" prop="activityType" width="150" v-if="columns[2].visible">
|
|
|
|
|
|
+ <el-table-column label="菜单名称" align="center" prop="name" width="150" v-if="columns[1].visible" />
|
|
|
|
+ <el-table-column label="活动类型" align="center" prop="activityType" width="150" v-if="columns[2].visible">
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
- <dict-tag :options="game_activity_type" :value="scope.row.activityType" />
|
|
|
|
|
|
+ <dict-tag :options="game_activity_type" :value="scope.row.activityType" />
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- <el-table-column label="图标" align="center" prop="pic" width="150" v-if="columns[3].visible">
|
|
|
|
|
|
+ <el-table-column label="图标" align="center" prop="pic" width="150" v-if="columns[3].visible">
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
<img :src="scope.row.pic" style="width: 50px; height: 50px" />
|
|
<img :src="scope.row.pic" style="width: 50px; height: 50px" />
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
- <el-table-column label="颜色" align="center" prop="color" width="150" v-if="columns[4].visible" />
|
|
|
|
|
|
+ <el-table-column label="颜色" align="center" prop="color" width="150" v-if="columns[4].visible">
|
|
|
|
+ <template #default="scope">
|
|
|
|
+ <el-color-picker v-model="scope.row.color" size="large" :disabled="true" />
|
|
|
|
+ </template>
|
|
|
|
+ </el-table-column>
|
|
<el-table-column label="链接类别" align="center" prop="jumpType" width="150" v-if="columns[5].visible">
|
|
<el-table-column label="链接类别" align="center" prop="jumpType" width="150" v-if="columns[5].visible">
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
{{ getJumpTypeText(scope.row.jumpType) }}
|
|
{{ getJumpTypeText(scope.row.jumpType) }}
|
|
@@ -102,7 +86,7 @@
|
|
{{ scope.row.jumpPath || '-' }}
|
|
{{ scope.row.jumpPath || '-' }}
|
|
</template>
|
|
</template>
|
|
</el-table-column>
|
|
</el-table-column>
|
|
-
|
|
|
|
|
|
+
|
|
<el-table-column label="创建时间" min-width="200" v-if="columns[7].visible">
|
|
<el-table-column label="创建时间" min-width="200" v-if="columns[7].visible">
|
|
<template #default="scope">
|
|
<template #default="scope">
|
|
<div class="create-info">
|
|
<div class="create-info">
|
|
@@ -125,7 +109,10 @@
|
|
<el-button type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
|
<el-button type="primary" size="small" @click="handleEdit(scope.row)">编辑</el-button>
|
|
<el-dropdown @command="(command) => handleCommand(command, scope.row)">
|
|
<el-dropdown @command="(command) => handleCommand(command, scope.row)">
|
|
<el-button size="small">
|
|
<el-button size="small">
|
|
- 更多<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
|
|
|
|
|
+ 更多
|
|
|
|
+ <el-icon class="el-icon--right">
|
|
|
|
+ <arrow-down />
|
|
|
|
+ </el-icon>
|
|
</el-button>
|
|
</el-button>
|
|
<template #dropdown>
|
|
<template #dropdown>
|
|
<el-dropdown-menu>
|
|
<el-dropdown-menu>
|
|
@@ -140,18 +127,8 @@
|
|
</el-card>
|
|
</el-card>
|
|
|
|
|
|
<!-- 编辑/添加对话框 -->
|
|
<!-- 编辑/添加对话框 -->
|
|
- <el-dialog
|
|
|
|
- v-model="dialogVisible"
|
|
|
|
- :title="dialogTitle"
|
|
|
|
- width="720px"
|
|
|
|
- class="nav-dialog"
|
|
|
|
- >
|
|
|
|
- <el-form
|
|
|
|
- ref="formRef"
|
|
|
|
- :model="form"
|
|
|
|
- :rules="rules"
|
|
|
|
- label-width="120px"
|
|
|
|
- >
|
|
|
|
|
|
+ <el-dialog v-model="dialogVisible" :title="dialogTitle" width="720px" class="nav-dialog">
|
|
|
|
+ <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
|
|
<el-row :gutter="20">
|
|
<el-row :gutter="20">
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
<el-form-item label="菜单名称" prop="name">
|
|
<el-form-item label="菜单名称" prop="name">
|
|
@@ -169,13 +146,13 @@
|
|
<el-col :span="18">
|
|
<el-col :span="18">
|
|
<el-form-item label="活动类型" prop="activityType">
|
|
<el-form-item label="活动类型" prop="activityType">
|
|
<el-radio-group v-model="form.activityType">
|
|
<el-radio-group v-model="form.activityType">
|
|
- <el-radio v-for="dict in game_activity_type" :key="dict.value" :value="dict.value">{{ dict.label }}</el-radio>
|
|
|
|
|
|
+ <el-radio v-for="dict in game_activity_type" :key="dict.value" :value="dict.value">{{ dict.label }} </el-radio>
|
|
</el-radio-group>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-col>
|
|
</el-row>
|
|
</el-row>
|
|
-
|
|
|
|
- <el-row :gutter="20">
|
|
|
|
|
|
+
|
|
|
|
+ <el-row :gutter="20">
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
<el-form-item label="功能图标" prop="pic">
|
|
<el-form-item label="功能图标" prop="pic">
|
|
<el-upload
|
|
<el-upload
|
|
@@ -187,7 +164,9 @@
|
|
:on-success="handleIconSuccess"
|
|
:on-success="handleIconSuccess"
|
|
>
|
|
>
|
|
<img v-if="form.pic" :src="form.pic" class="icon-preview" />
|
|
<img v-if="form.pic" :src="form.pic" class="icon-preview" />
|
|
- <el-icon v-else class="icon-uploader-icon"><Plus /></el-icon>
|
|
|
|
|
|
+ <el-icon v-else class="icon-uploader-icon">
|
|
|
|
+ <Plus />
|
|
|
|
+ </el-icon>
|
|
</el-upload>
|
|
</el-upload>
|
|
<div class="upload-tip">建议尺寸 100x100</div>
|
|
<div class="upload-tip">建议尺寸 100x100</div>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
@@ -195,26 +174,13 @@
|
|
<el-col :span="12">
|
|
<el-col :span="12">
|
|
<el-form-item label="颜色" required>
|
|
<el-form-item label="颜色" required>
|
|
<div class="color-input-group">
|
|
<div class="color-input-group">
|
|
- <el-color-picker
|
|
|
|
- v-model="form.color"
|
|
|
|
- show-alpha
|
|
|
|
- size="large"
|
|
|
|
- class="color-picker"
|
|
|
|
- @change="handleColorChange"
|
|
|
|
- />
|
|
|
|
- <el-input
|
|
|
|
- v-model="colorInput"
|
|
|
|
- placeholder="#RRGGBB"
|
|
|
|
- class="color-input"
|
|
|
|
- @input="handleColorInput"
|
|
|
|
- @blur="validateColorInput"
|
|
|
|
- />
|
|
|
|
|
|
+ <el-color-picker v-model="form.color" show-alpha size="large" class="color-picker" @change="handleColorChange" />
|
|
|
|
+ <el-input v-model="colorInput" placeholder="#RRGGBB" class="color-input" @input="handleColorInput" @blur="validateColorInput" />
|
|
</div>
|
|
</div>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-col>
|
|
</el-row>
|
|
</el-row>
|
|
-
|
|
|
|
-
|
|
|
|
|
|
+
|
|
<el-form-item label="跳转类型" prop="jumpType">
|
|
<el-form-item label="跳转类型" prop="jumpType">
|
|
<el-radio-group v-model="form.jumpType" @change="handleJumpTypeChange">
|
|
<el-radio-group v-model="form.jumpType" @change="handleJumpTypeChange">
|
|
<el-radio :value="1">跳转链接</el-radio>
|
|
<el-radio :value="1">跳转链接</el-radio>
|
|
@@ -227,11 +193,11 @@
|
|
<el-radio :value="8">电话拨号</el-radio>
|
|
<el-radio :value="8">电话拨号</el-radio>
|
|
</el-radio-group>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
-
|
|
|
|
|
|
+
|
|
<el-form-item label="跳转链接" prop="jumpPath">
|
|
<el-form-item label="跳转链接" prop="jumpPath">
|
|
<el-input v-model="form.jumpPath" placeholder="请输入跳转链接" :disabled="form.jumpType === 2" />
|
|
<el-input v-model="form.jumpPath" placeholder="请输入跳转链接" :disabled="form.jumpType === 2" />
|
|
</el-form-item>
|
|
</el-form-item>
|
|
-
|
|
|
|
|
|
+
|
|
<el-form-item label="小程序AppID" prop="appId" v-if="form.jumpType === 4">
|
|
<el-form-item label="小程序AppID" prop="appId" v-if="form.jumpType === 4">
|
|
<el-input v-model="form.appId" placeholder="请输入对方小程序的AppID" />
|
|
<el-input v-model="form.appId" placeholder="请输入对方小程序的AppID" />
|
|
</el-form-item>
|
|
</el-form-item>
|
|
@@ -262,25 +228,23 @@
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-col>
|
|
</el-col>
|
|
</el-row>
|
|
</el-row>
|
|
-
|
|
|
|
|
|
+
|
|
<el-form-item label="状态" prop="status">
|
|
<el-form-item label="状态" prop="status">
|
|
<el-radio-group v-model="form.status">
|
|
<el-radio-group v-model="form.status">
|
|
<el-radio :value="0">正常</el-radio>
|
|
<el-radio :value="0">正常</el-radio>
|
|
<el-radio :value="1">停用</el-radio>
|
|
<el-radio :value="1">停用</el-radio>
|
|
</el-radio-group>
|
|
</el-radio-group>
|
|
</el-form-item>
|
|
</el-form-item>
|
|
-
|
|
|
|
|
|
+
|
|
<el-form-item label="备注">
|
|
<el-form-item label="备注">
|
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
|
<el-input v-model="form.remark" type="textarea" placeholder="请输入备注" />
|
|
</el-form-item>
|
|
</el-form-item>
|
|
</el-form>
|
|
</el-form>
|
|
-
|
|
|
|
|
|
+
|
|
<template #footer>
|
|
<template #footer>
|
|
<span class="dialog-footer">
|
|
<span class="dialog-footer">
|
|
<el-button @click="dialogVisible = false">取消</el-button>
|
|
<el-button @click="dialogVisible = false">取消</el-button>
|
|
- <el-button type="primary" @click="handleSubmit" :loading="submitting">
|
|
|
|
- 确定
|
|
|
|
- </el-button>
|
|
|
|
|
|
+ <el-button type="primary" @click="handleSubmit" :loading="submitting"> 确定 </el-button>
|
|
</span>
|
|
</span>
|
|
</template>
|
|
</template>
|
|
</el-dialog>
|
|
</el-dialog>
|
|
@@ -309,7 +273,7 @@
|
|
<span v-else class="no-image-text">暂无图标</span>
|
|
<span v-else class="no-image-text">暂无图标</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
- <div class="detail-item">
|
|
|
|
|
|
+ <div class="detail-item">
|
|
<span class="detail-label">颜色:</span>
|
|
<span class="detail-label">颜色:</span>
|
|
<span class="detail-value">{{ detailData.color }}</span>
|
|
<span class="detail-value">{{ detailData.color }}</span>
|
|
</div>
|
|
</div>
|
|
@@ -354,19 +318,19 @@
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
-import { ref, reactive, onMounted, computed } from 'vue'
|
|
|
|
-import { ElMessage, ElMessageBox } from 'element-plus'
|
|
|
|
-import { HomeFilled, Plus } from '@element-plus/icons-vue'
|
|
|
|
-import {
|
|
|
|
- getEnabledNavigator,
|
|
|
|
- getNavigator,
|
|
|
|
- addNavigator,
|
|
|
|
- updateNavigator,
|
|
|
|
|
|
+import { ref, reactive, onMounted, computed } from 'vue';
|
|
|
|
+import { ElMessage, ElMessageBox } from 'element-plus';
|
|
|
|
+import { HomeFilled, Plus } from '@element-plus/icons-vue';
|
|
|
|
+import {
|
|
|
|
+ getEnabledNavigator,
|
|
|
|
+ getNavigator,
|
|
|
|
+ addNavigator,
|
|
|
|
+ updateNavigator,
|
|
delNavigator,
|
|
delNavigator,
|
|
type GameNavigatorVo,
|
|
type GameNavigatorVo,
|
|
type GameNavigatorBo,
|
|
type GameNavigatorBo,
|
|
listNavigator
|
|
listNavigator
|
|
-} from '@/api/system/common/nav/gameNavigator'
|
|
|
|
|
|
+} from '@/api/system/common/nav/gameNavigator';
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
const { game_activity_type } = toRefs<any>(proxy?.useDict('game_activity_type'));
|
|
const { game_activity_type } = toRefs<any>(proxy?.useDict('game_activity_type'));
|
|
@@ -388,7 +352,7 @@ const columns = ref<FieldOption[]>([
|
|
{ key: 4, label: '颜色', visible: true },
|
|
{ key: 4, label: '颜色', visible: true },
|
|
{ key: 5, label: '链接类别', visible: true },
|
|
{ key: 5, label: '链接类别', visible: true },
|
|
{ key: 6, label: '链接', visible: true },
|
|
{ key: 6, label: '链接', visible: true },
|
|
- { key: 7, label: '创建时间', visible: true },
|
|
|
|
|
|
+ { key: 7, label: '创建时间', visible: true }
|
|
]);
|
|
]);
|
|
|
|
|
|
// 菜单项接口
|
|
// 菜单项接口
|
|
@@ -410,11 +374,13 @@ interface NavItem extends GameNavigatorVo {
|
|
|
|
|
|
// 表单数据
|
|
// 表单数据
|
|
const navItems = ref<NavItem[]>([]);
|
|
const navItems = ref<NavItem[]>([]);
|
|
-const formRef = ref()
|
|
|
|
-const form = reactive<GameNavigatorBo & {
|
|
|
|
- createTime?: string;
|
|
|
|
- updateTime?: string;
|
|
|
|
-}>({
|
|
|
|
|
|
+const formRef = ref();
|
|
|
|
+const form = reactive<
|
|
|
|
+ GameNavigatorBo & {
|
|
|
|
+ createTime?: string;
|
|
|
|
+ updateTime?: string;
|
|
|
|
+ }
|
|
|
|
+>({
|
|
navId: undefined,
|
|
navId: undefined,
|
|
name: '',
|
|
name: '',
|
|
pic: '',
|
|
pic: '',
|
|
@@ -427,7 +393,7 @@ const form = reactive<GameNavigatorBo & {
|
|
status: 0,
|
|
status: 0,
|
|
remark: '',
|
|
remark: '',
|
|
createTime: '',
|
|
createTime: '',
|
|
- updateTime: '',
|
|
|
|
|
|
+ updateTime: ''
|
|
});
|
|
});
|
|
|
|
|
|
// 响应式数据
|
|
// 响应式数据
|
|
@@ -450,51 +416,41 @@ const queryParams = reactive({
|
|
|
|
|
|
// 表单验证规则
|
|
// 表单验证规则
|
|
const rules = {
|
|
const rules = {
|
|
- name: [
|
|
|
|
- { required: true, message: '请输入菜单名称', trigger: 'blur' }
|
|
|
|
- ],
|
|
|
|
- pic: [
|
|
|
|
- { required: true, message: '请上传功能图标', trigger: 'change' }
|
|
|
|
- ],
|
|
|
|
- activityType: [
|
|
|
|
- { required: true, message: '请选择活动类型', trigger: 'change' }
|
|
|
|
- ],
|
|
|
|
- jumpType: [
|
|
|
|
- { required: true, message: '请选择跳转方式', trigger: 'change' }
|
|
|
|
- ],
|
|
|
|
- sortNum: [
|
|
|
|
- { required: true, message: '请输入排序', trigger: 'blur' }
|
|
|
|
- ]
|
|
|
|
-}
|
|
|
|
|
|
+ name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
|
|
|
|
+ pic: [{ required: true, message: '请上传功能图标', trigger: 'change' }],
|
|
|
|
+ activityType: [{ required: true, message: '请选择活动类型', trigger: 'change' }],
|
|
|
|
+ jumpType: [{ required: true, message: '请选择跳转方式', trigger: 'change' }],
|
|
|
|
+ sortNum: [{ required: true, message: '请输入排序', trigger: 'blur' }]
|
|
|
|
+};
|
|
|
|
|
|
// 添加跳转链接验证函数
|
|
// 添加跳转链接验证函数
|
|
function validateJumpPath(rule: any, value: string, callback: Function) {
|
|
function validateJumpPath(rule: any, value: string, callback: Function) {
|
|
if (value && !/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/.test(value)) {
|
|
if (value && !/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/.test(value)) {
|
|
- callback(new Error('请输入有效的URL'))
|
|
|
|
|
|
+ callback(new Error('请输入有效的URL'));
|
|
} else {
|
|
} else {
|
|
- callback()
|
|
|
|
|
|
+ callback();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 上传相关
|
|
// 上传相关
|
|
import { globalHeaders } from '@/utils/request';
|
|
import { globalHeaders } from '@/utils/request';
|
|
|
|
|
|
-const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload'
|
|
|
|
-const headers = globalHeaders()
|
|
|
|
|
|
+const uploadUrl = import.meta.env.VITE_APP_BASE_API + '/resource/oss/upload';
|
|
|
|
+const headers = globalHeaders();
|
|
|
|
|
|
// 格式化日期
|
|
// 格式化日期
|
|
function formatDate(date: string | Date | null | undefined): string {
|
|
function formatDate(date: string | Date | null | undefined): string {
|
|
- if (!date) return '-'
|
|
|
|
- const d = new Date(date)
|
|
|
|
- if (isNaN(d.getTime())) return '-'
|
|
|
|
- return d.toLocaleDateString('zh-CN')
|
|
|
|
|
|
+ if (!date) return '-';
|
|
|
|
+ const d = new Date(date);
|
|
|
|
+ if (isNaN(d.getTime())) return '-';
|
|
|
|
+ return d.toLocaleDateString('zh-CN');
|
|
}
|
|
}
|
|
|
|
|
|
// 格式化日期时间
|
|
// 格式化日期时间
|
|
function formatDateTime(date: string | Date | null | undefined): string {
|
|
function formatDateTime(date: string | Date | null | undefined): string {
|
|
- if (!date) return '-'
|
|
|
|
- const d = new Date(date)
|
|
|
|
- if (isNaN(d.getTime())) return '-'
|
|
|
|
|
|
+ if (!date) return '-';
|
|
|
|
+ const d = new Date(date);
|
|
|
|
+ if (isNaN(d.getTime())) return '-';
|
|
return d.toLocaleString('zh-CN', {
|
|
return d.toLocaleString('zh-CN', {
|
|
year: 'numeric',
|
|
year: 'numeric',
|
|
month: '2-digit',
|
|
month: '2-digit',
|
|
@@ -502,12 +458,12 @@ function formatDateTime(date: string | Date | null | undefined): string {
|
|
hour: '2-digit',
|
|
hour: '2-digit',
|
|
minute: '2-digit',
|
|
minute: '2-digit',
|
|
second: '2-digit'
|
|
second: '2-digit'
|
|
- })
|
|
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
// 获取跳转类型文本
|
|
// 获取跳转类型文本
|
|
function getJumpTypeText(jumpType: number | null | undefined): string {
|
|
function getJumpTypeText(jumpType: number | null | undefined): string {
|
|
- if (!jumpType) return '-'
|
|
|
|
|
|
+ if (!jumpType) return '-';
|
|
const typeMap: Record<number, string> = {
|
|
const typeMap: Record<number, string> = {
|
|
1: '跳转链接',
|
|
1: '跳转链接',
|
|
2: '不跳转',
|
|
2: '不跳转',
|
|
@@ -517,37 +473,37 @@ function getJumpTypeText(jumpType: number | null | undefined): string {
|
|
6: '公众号文章',
|
|
6: '公众号文章',
|
|
7: '公众号',
|
|
7: '公众号',
|
|
8: '电话拨号'
|
|
8: '电话拨号'
|
|
- }
|
|
|
|
- return typeMap[jumpType] || '-'
|
|
|
|
|
|
+ };
|
|
|
|
+ return typeMap[jumpType] || '-';
|
|
}
|
|
}
|
|
|
|
|
|
// 获取最大排序值
|
|
// 获取最大排序值
|
|
function getMaxSortNum(): number {
|
|
function getMaxSortNum(): number {
|
|
if (navItems.value.length === 0) {
|
|
if (navItems.value.length === 0) {
|
|
- return 0
|
|
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
- const maxSort = Math.max(...navItems.value.map(item => item.sortNum || 0))
|
|
|
|
- return maxSort
|
|
|
|
|
|
+ const maxSort = Math.max(...navItems.value.map((item) => item.sortNum || 0));
|
|
|
|
+ return maxSort;
|
|
}
|
|
}
|
|
|
|
|
|
// 加载菜单数据
|
|
// 加载菜单数据
|
|
async function loadNavData() {
|
|
async function loadNavData() {
|
|
- loading.value = true
|
|
|
|
|
|
+ loading.value = true;
|
|
try {
|
|
try {
|
|
- const response = await getEnabledNavigator()
|
|
|
|
|
|
+ const response = await getEnabledNavigator();
|
|
if (response.code === 200 && response.data) {
|
|
if (response.code === 200 && response.data) {
|
|
- navItems.value = response.data as unknown as NavItem[]
|
|
|
|
|
|
+ navItems.value = response.data as unknown as NavItem[];
|
|
} else {
|
|
} else {
|
|
- navItems.value = []
|
|
|
|
|
|
+ navItems.value = [];
|
|
}
|
|
}
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.error('加载数据失败:', error)
|
|
|
|
- navItems.value = []
|
|
|
|
|
|
+ console.error('加载数据失败:', error);
|
|
|
|
+ navItems.value = [];
|
|
} finally {
|
|
} finally {
|
|
- loading.value = false
|
|
|
|
|
|
+ loading.value = false;
|
|
// 数据加载完成后,更新排序值
|
|
// 数据加载完成后,更新排序值
|
|
if (!form.navId) {
|
|
if (!form.navId) {
|
|
- form.sortNum = nextSortNum.value
|
|
|
|
|
|
+ form.sortNum = nextSortNum.value;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -571,7 +527,7 @@ function resetQuery() {
|
|
|
|
|
|
/** 多选框选中数据 */
|
|
/** 多选框选中数据 */
|
|
function handleSelectionChange(selection: NavItem[]) {
|
|
function handleSelectionChange(selection: NavItem[]) {
|
|
- selectedIds.value = selection.map(item => item.navId!);
|
|
|
|
|
|
+ selectedIds.value = selection.map((item) => item.navId!);
|
|
}
|
|
}
|
|
|
|
|
|
/** 排序变更 */
|
|
/** 排序变更 */
|
|
@@ -579,7 +535,7 @@ async function handleSortChange(row: NavItem) {
|
|
try {
|
|
try {
|
|
const response = await updateNavigator({
|
|
const response = await updateNavigator({
|
|
navId: row.navId,
|
|
navId: row.navId,
|
|
- sortNum: row.sortNum,
|
|
|
|
|
|
+ sortNum: row.sortNum
|
|
// type: '4'
|
|
// type: '4'
|
|
});
|
|
});
|
|
if (response.code === 200) {
|
|
if (response.code === 200) {
|
|
@@ -628,7 +584,7 @@ function handleView(row: NavItem) {
|
|
|
|
|
|
// 处理编辑
|
|
// 处理编辑
|
|
function handleEdit(item: NavItem) {
|
|
function handleEdit(item: NavItem) {
|
|
- reset()
|
|
|
|
|
|
+ reset();
|
|
const formData = {
|
|
const formData = {
|
|
navId: item.navId,
|
|
navId: item.navId,
|
|
name: item.name,
|
|
name: item.name,
|
|
@@ -643,20 +599,20 @@ function handleEdit(item: NavItem) {
|
|
remark: item.remark || '',
|
|
remark: item.remark || '',
|
|
createTime: item.createTime,
|
|
createTime: item.createTime,
|
|
updateTime: item.updateTime
|
|
updateTime: item.updateTime
|
|
- }
|
|
|
|
- Object.assign(form, formData)
|
|
|
|
- colorInput.value = item.color || '#409EFF'
|
|
|
|
- dialogVisible.value = true
|
|
|
|
- dialogTitle.value = '修改菜单'
|
|
|
|
|
|
+ };
|
|
|
|
+ Object.assign(form, formData);
|
|
|
|
+ colorInput.value = item.color || '#409EFF';
|
|
|
|
+ dialogVisible.value = true;
|
|
|
|
+ dialogTitle.value = '修改菜单';
|
|
}
|
|
}
|
|
|
|
|
|
// 处理添加
|
|
// 处理添加
|
|
function handleAdd() {
|
|
function handleAdd() {
|
|
- reset()
|
|
|
|
|
|
+ reset();
|
|
// 设置排序值为当前最大值+1
|
|
// 设置排序值为当前最大值+1
|
|
- form.sortNum = nextSortNum.value
|
|
|
|
- dialogVisible.value = true
|
|
|
|
- dialogTitle.value = '添加菜单'
|
|
|
|
|
|
+ form.sortNum = nextSortNum.value;
|
|
|
|
+ dialogVisible.value = true;
|
|
|
|
+ dialogTitle.value = '添加菜单';
|
|
}
|
|
}
|
|
|
|
|
|
// 处理删除
|
|
// 处理删除
|
|
@@ -666,18 +622,18 @@ async function handleDelete(item: NavItem) {
|
|
confirmButtonText: '确定',
|
|
confirmButtonText: '确定',
|
|
cancelButtonText: '取消',
|
|
cancelButtonText: '取消',
|
|
type: 'warning'
|
|
type: 'warning'
|
|
- })
|
|
|
|
-
|
|
|
|
- const response = await delNavigator(item.navId!)
|
|
|
|
|
|
+ });
|
|
|
|
+
|
|
|
|
+ const response = await delNavigator(item.navId!);
|
|
if (response.code === 200) {
|
|
if (response.code === 200) {
|
|
- ElMessage.success('删除成功')
|
|
|
|
- loadNavData()
|
|
|
|
|
|
+ ElMessage.success('删除成功');
|
|
|
|
+ loadNavData();
|
|
} else {
|
|
} else {
|
|
- ElMessage.error(response.msg || '删除失败')
|
|
|
|
|
|
+ ElMessage.error(response.msg || '删除失败');
|
|
}
|
|
}
|
|
} catch (error) {
|
|
} catch (error) {
|
|
if (error !== 'cancel') {
|
|
if (error !== 'cancel') {
|
|
- ElMessage.error('删除失败')
|
|
|
|
|
|
+ ElMessage.error('删除失败');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -685,9 +641,9 @@ async function handleDelete(item: NavItem) {
|
|
// 处理提交
|
|
// 处理提交
|
|
async function handleSubmit() {
|
|
async function handleSubmit() {
|
|
try {
|
|
try {
|
|
- await formRef.value.validate()
|
|
|
|
- submitting.value = true
|
|
|
|
-
|
|
|
|
|
|
+ await formRef.value.validate();
|
|
|
|
+ submitting.value = true;
|
|
|
|
+
|
|
const payload: any = {
|
|
const payload: any = {
|
|
navId: form.navId,
|
|
navId: form.navId,
|
|
name: form.name,
|
|
name: form.name,
|
|
@@ -701,29 +657,29 @@ async function handleSubmit() {
|
|
status: form.status,
|
|
status: form.status,
|
|
remark: form.remark,
|
|
remark: form.remark,
|
|
createTime: form.createTime,
|
|
createTime: form.createTime,
|
|
- updateTime: form.updateTime,
|
|
|
|
|
|
+ updateTime: form.updateTime
|
|
// type: '4' // 菜单固定类型
|
|
// type: '4' // 菜单固定类型
|
|
- }
|
|
|
|
-
|
|
|
|
- let response
|
|
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ let response;
|
|
if (form.navId) {
|
|
if (form.navId) {
|
|
- response = await updateNavigator(payload)
|
|
|
|
|
|
+ response = await updateNavigator(payload);
|
|
} else {
|
|
} else {
|
|
- response = await addNavigator(payload)
|
|
|
|
|
|
+ response = await addNavigator(payload);
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
if (response.code === 200) {
|
|
if (response.code === 200) {
|
|
- ElMessage.success(form.navId ? '修改成功' : '添加成功')
|
|
|
|
- dialogVisible.value = false
|
|
|
|
- loadNavData()
|
|
|
|
|
|
+ ElMessage.success(form.navId ? '修改成功' : '添加成功');
|
|
|
|
+ dialogVisible.value = false;
|
|
|
|
+ loadNavData();
|
|
} else {
|
|
} else {
|
|
- ElMessage.error(response.msg || '操作失败')
|
|
|
|
|
|
+ ElMessage.error(response.msg || '操作失败');
|
|
}
|
|
}
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.error('提交失败:', error)
|
|
|
|
- ElMessage.error('操作失败')
|
|
|
|
|
|
+ console.error('提交失败:', error);
|
|
|
|
+ ElMessage.error('操作失败');
|
|
} finally {
|
|
} finally {
|
|
- submitting.value = false
|
|
|
|
|
|
+ submitting.value = false;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -743,101 +699,101 @@ function reset() {
|
|
remark: '',
|
|
remark: '',
|
|
createTime: '',
|
|
createTime: '',
|
|
updateTime: ''
|
|
updateTime: ''
|
|
- })
|
|
|
|
- colorInput.value = '#409EFF'
|
|
|
|
- formRef.value?.clearValidate()
|
|
|
|
|
|
+ });
|
|
|
|
+ colorInput.value = '#409EFF';
|
|
|
|
+ formRef.value?.clearValidate();
|
|
}
|
|
}
|
|
|
|
|
|
// 跳转类型变更处理
|
|
// 跳转类型变更处理
|
|
function handleJumpTypeChange() {
|
|
function handleJumpTypeChange() {
|
|
if (form.jumpType === 2) {
|
|
if (form.jumpType === 2) {
|
|
- form.jumpPath = '#'
|
|
|
|
|
|
+ form.jumpPath = '#';
|
|
} else if (form.jumpType === 4) {
|
|
} else if (form.jumpType === 4) {
|
|
- form.jumpPath = ''
|
|
|
|
|
|
+ form.jumpPath = '';
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 图片上传前验证
|
|
// 图片上传前验证
|
|
function beforeIconUpload(file: File) {
|
|
function beforeIconUpload(file: File) {
|
|
- const isImage = file.type.startsWith('image/')
|
|
|
|
- const isLt2M = file.size / 1024 / 1024 < 2
|
|
|
|
|
|
+ const isImage = file.type.startsWith('image/');
|
|
|
|
+ const isLt2M = file.size / 1024 / 1024 < 2;
|
|
|
|
|
|
if (!isImage) {
|
|
if (!isImage) {
|
|
- ElMessage.error('只能上传图片文件!')
|
|
|
|
- return false
|
|
|
|
|
|
+ ElMessage.error('只能上传图片文件!');
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
if (!isLt2M) {
|
|
if (!isLt2M) {
|
|
- ElMessage.error('图片大小不能超过 2MB!')
|
|
|
|
- return false
|
|
|
|
|
|
+ ElMessage.error('图片大小不能超过 2MB!');
|
|
|
|
+ return false;
|
|
}
|
|
}
|
|
- return true
|
|
|
|
|
|
+ return true;
|
|
}
|
|
}
|
|
|
|
|
|
// 图片上传成功
|
|
// 图片上传成功
|
|
function handleIconSuccess(response: any) {
|
|
function handleIconSuccess(response: any) {
|
|
if (response.code === 200) {
|
|
if (response.code === 200) {
|
|
- form.pic = response.data.url
|
|
|
|
- ElMessage.success('图片上传成功')
|
|
|
|
|
|
+ form.pic = response.data.url;
|
|
|
|
+ ElMessage.success('图片上传成功');
|
|
} else {
|
|
} else {
|
|
- ElMessage.error(response.msg || '图片上传失败')
|
|
|
|
|
|
+ ElMessage.error(response.msg || '图片上传失败');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// 颜色输入框的值
|
|
// 颜色输入框的值
|
|
-const colorInput = ref('#409EFF')
|
|
|
|
|
|
+const colorInput = ref('#409EFF');
|
|
|
|
|
|
// 将RGB颜色转换为16进制
|
|
// 将RGB颜色转换为16进制
|
|
const rgbToHex = (rgb: string): string => {
|
|
const rgbToHex = (rgb: string): string => {
|
|
// 如果是16进制格式,直接返回
|
|
// 如果是16进制格式,直接返回
|
|
if (rgb.startsWith('#')) {
|
|
if (rgb.startsWith('#')) {
|
|
- return rgb
|
|
|
|
|
|
+ return rgb;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
// 如果是RGB格式,转换为16进制
|
|
// 如果是RGB格式,转换为16进制
|
|
- const rgbMatch = rgb.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/)
|
|
|
|
|
|
+ const rgbMatch = rgb.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/);
|
|
if (rgbMatch) {
|
|
if (rgbMatch) {
|
|
- const r = parseInt(rgbMatch[1])
|
|
|
|
- const g = parseInt(rgbMatch[2])
|
|
|
|
- const b = parseInt(rgbMatch[3])
|
|
|
|
- return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`
|
|
|
|
|
|
+ const r = parseInt(rgbMatch[1]);
|
|
|
|
+ const g = parseInt(rgbMatch[2]);
|
|
|
|
+ const b = parseInt(rgbMatch[3]);
|
|
|
|
+ return `#${r.toString(16).padStart(2, '0')}${g.toString(16).padStart(2, '0')}${b.toString(16).padStart(2, '0')}`;
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
// 如果无法解析,返回默认值
|
|
// 如果无法解析,返回默认值
|
|
- return '#409EFF'
|
|
|
|
-}
|
|
|
|
|
|
+ return '#409EFF';
|
|
|
|
+};
|
|
|
|
|
|
// 处理颜色输入框变化
|
|
// 处理颜色输入框变化
|
|
const handleColorInput = (value: string) => {
|
|
const handleColorInput = (value: string) => {
|
|
// 实时同步到颜色选择器
|
|
// 实时同步到颜色选择器
|
|
if (value.startsWith('#')) {
|
|
if (value.startsWith('#')) {
|
|
- form.color = value
|
|
|
|
|
|
+ form.color = value;
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
+};
|
|
|
|
|
|
// 处理颜色选择器变化
|
|
// 处理颜色选择器变化
|
|
const handleColorChange = (value: string) => {
|
|
const handleColorChange = (value: string) => {
|
|
// 当颜色选择器改变时,将16进制值填充到输入框
|
|
// 当颜色选择器改变时,将16进制值填充到输入框
|
|
if (value) {
|
|
if (value) {
|
|
- const hexValue = rgbToHex(value)
|
|
|
|
- colorInput.value = hexValue
|
|
|
|
|
|
+ const hexValue = rgbToHex(value);
|
|
|
|
+ colorInput.value = hexValue;
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
+};
|
|
|
|
|
|
// 验证颜色输入框
|
|
// 验证颜色输入框
|
|
const validateColorInput = () => {
|
|
const validateColorInput = () => {
|
|
- const hexRegex = /^#[0-9A-Fa-f]{6}$/
|
|
|
|
|
|
+ const hexRegex = /^#[0-9A-Fa-f]{6}$/;
|
|
if (!hexRegex.test(colorInput.value)) {
|
|
if (!hexRegex.test(colorInput.value)) {
|
|
- ElMessage.warning('请输入正确的16进制颜色格式,如 #FF0000')
|
|
|
|
- colorInput.value = form.color
|
|
|
|
|
|
+ ElMessage.warning('请输入正确的16进制颜色格式,如 #FF0000');
|
|
|
|
+ colorInput.value = form.color;
|
|
}
|
|
}
|
|
-}
|
|
|
|
|
|
+};
|
|
|
|
|
|
// 初始化数据
|
|
// 初始化数据
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
- loadNavData()
|
|
|
|
|
|
+ loadNavData();
|
|
// 初始化排序值
|
|
// 初始化排序值
|
|
- form.sortNum = nextSortNum.value
|
|
|
|
-})
|
|
|
|
|
|
+ form.sortNum = nextSortNum.value;
|
|
|
|
+});
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
@@ -1020,4 +976,4 @@ onMounted(() => {
|
|
color: #909399;
|
|
color: #909399;
|
|
margin-top: 8px;
|
|
margin-top: 8px;
|
|
}
|
|
}
|
|
-</style>
|
|
|
|
|
|
+</style>
|