|
@@ -35,7 +35,7 @@
|
|
/>
|
|
/>
|
|
</el-form-item>
|
|
</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>
|
|
@@ -63,6 +63,12 @@
|
|
|
|
|
|
<!-- 菜单列表 -->
|
|
<!-- 菜单列表 -->
|
|
<el-card class="list-card">
|
|
<el-card class="list-card">
|
|
|
|
+ <template #header>
|
|
|
|
+ <div class="list-header">
|
|
|
|
+ <span>菜单列表</span>
|
|
|
|
+ <span class="result-count">共找到 {{ total }} 条记录</span>
|
|
|
|
+ </div>
|
|
|
|
+ </template>
|
|
<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">
|
|
@@ -180,8 +186,19 @@
|
|
<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"
|
|
|
|
+ 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>
|
|
@@ -381,6 +398,7 @@ interface NavItem extends GameNavigatorVo {
|
|
// 表单数据
|
|
// 表单数据
|
|
const navItems = ref<NavItem[]>([]);
|
|
const navItems = ref<NavItem[]>([]);
|
|
const formRef = ref();
|
|
const formRef = ref();
|
|
|
|
+const queryRef = ref()
|
|
const form = reactive<
|
|
const form = reactive<
|
|
GameNavigatorBo & {
|
|
GameNavigatorBo & {
|
|
createTime?: string;
|
|
createTime?: string;
|
|
@@ -420,6 +438,11 @@ const queryParams = reactive({
|
|
createTime: ''
|
|
createTime: ''
|
|
});
|
|
});
|
|
|
|
|
|
|
|
+// 监听查询参数变化,自动搜索(可选)
|
|
|
|
+// watch(queryParams, () => {
|
|
|
|
+// // 如果需要实时搜索,可以在这里调用 loadNavData()
|
|
|
|
+// }, { deep: true })
|
|
|
|
+
|
|
// 表单验证规则
|
|
// 表单验证规则
|
|
const rules = {
|
|
const rules = {
|
|
name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
|
|
name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
|
|
@@ -464,7 +487,15 @@ 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'
|
|
- });
|
|
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 格式化日期为查询格式 (YYYY-MM-DD)
|
|
|
|
+function formatDateForQuery(date: Date): string {
|
|
|
|
+ const year = date.getFullYear()
|
|
|
|
+ const month = String(date.getMonth() + 1).padStart(2, '0')
|
|
|
|
+ const day = String(date.getDate()).padStart(2, '0')
|
|
|
|
+ return `${year}-${month}-${day}`
|
|
}
|
|
}
|
|
|
|
|
|
// 获取跳转类型文本
|
|
// 获取跳转类型文本
|
|
@@ -496,15 +527,31 @@ function getMaxSortNum(): number {
|
|
async function loadNavData() {
|
|
async function loadNavData() {
|
|
loading.value = true;
|
|
loading.value = true;
|
|
try {
|
|
try {
|
|
- const response = await getEnabledNavigator();
|
|
|
|
- if (response.code === 200 && response.data) {
|
|
|
|
- navItems.value = response.data as unknown as NavItem[];
|
|
|
|
|
|
+ // 构建查询参数
|
|
|
|
+ const query: any = {
|
|
|
|
+ pageNum: 1,
|
|
|
|
+ pageSize: 100, // 设置一个较大的值以获取所有数据
|
|
|
|
+ ...queryParams
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 处理日期范围
|
|
|
|
+ if (dateRange.value && dateRange.value.length === 2) {
|
|
|
|
+ query.beginTime = formatDateForQuery(dateRange.value[0])
|
|
|
|
+ query.endTime = formatDateForQuery(dateRange.value[1])
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const response = await listNavigator(query)
|
|
|
|
+ if (response.code === 200 && (response as any).rows) {
|
|
|
|
+ navItems.value = (response as any).rows || []
|
|
|
|
+ total.value = (response as any).total || 0
|
|
} else {
|
|
} else {
|
|
- navItems.value = [];
|
|
|
|
|
|
+ navItems.value = []
|
|
|
|
+ total.value = 0
|
|
}
|
|
}
|
|
} catch (error) {
|
|
} catch (error) {
|
|
- console.error('加载数据失败:', error);
|
|
|
|
- navItems.value = [];
|
|
|
|
|
|
+ console.error('加载数据失败:', error)
|
|
|
|
+ navItems.value = []
|
|
|
|
+ total.value = 0
|
|
} finally {
|
|
} finally {
|
|
loading.value = false;
|
|
loading.value = false;
|
|
// 数据加载完成后,更新排序值
|
|
// 数据加载完成后,更新排序值
|
|
@@ -516,6 +563,7 @@ async function loadNavData() {
|
|
|
|
|
|
/** 搜索按钮操作 */
|
|
/** 搜索按钮操作 */
|
|
function handleQuery() {
|
|
function handleQuery() {
|
|
|
|
+ // 重置到第一页
|
|
loadNavData();
|
|
loadNavData();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -528,6 +576,10 @@ function resetQuery() {
|
|
status: undefined,
|
|
status: undefined,
|
|
createTime: ''
|
|
createTime: ''
|
|
});
|
|
});
|
|
|
|
+ // 重置查询引用
|
|
|
|
+ if (queryRef.value) {
|
|
|
|
+ queryRef.value.resetFields();
|
|
|
|
+ }
|
|
loadNavData();
|
|
loadNavData();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -590,12 +642,13 @@ function handleView(row: NavItem) {
|
|
|
|
|
|
// 处理编辑
|
|
// 处理编辑
|
|
function handleEdit(item: NavItem) {
|
|
function handleEdit(item: NavItem) {
|
|
- reset();
|
|
|
|
|
|
+ reset()
|
|
|
|
+ const normalizedColor = normalizeColor(item.color || '#409EFF')
|
|
const formData = {
|
|
const formData = {
|
|
navId: item.navId,
|
|
navId: item.navId,
|
|
name: item.name,
|
|
name: item.name,
|
|
pic: item.pic,
|
|
pic: item.pic,
|
|
- color: item.color || '#409EFF',
|
|
|
|
|
|
+ color: normalizedColor,
|
|
jumpType: item.jumpType || 1,
|
|
jumpType: item.jumpType || 1,
|
|
jumpPath: item.jumpType === 2 ? item.jumpPath || '#' : item.jumpPath,
|
|
jumpPath: item.jumpType === 2 ? item.jumpPath || '#' : item.jumpPath,
|
|
activityType: item.activityType || 1,
|
|
activityType: item.activityType || 1,
|
|
@@ -605,20 +658,23 @@ 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 = normalizedColor
|
|
|
|
+ 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
|
|
|
|
+ // 确保颜色值为16进制格式
|
|
|
|
+ form.color = normalizeColor(form.color)
|
|
|
|
+ colorInput.value = form.color
|
|
|
|
+ dialogVisible.value = true
|
|
|
|
+ dialogTitle.value = '添加菜单'
|
|
}
|
|
}
|
|
|
|
|
|
// 处理删除
|
|
// 处理删除
|
|
@@ -654,7 +710,7 @@ async function handleSubmit() {
|
|
navId: form.navId,
|
|
navId: form.navId,
|
|
name: form.name,
|
|
name: form.name,
|
|
pic: form.pic,
|
|
pic: form.pic,
|
|
- color: form.color,
|
|
|
|
|
|
+ color: normalizeColor(form.color), // 确保颜色值统一为16进制格式
|
|
jumpType: form.jumpType,
|
|
jumpType: form.jumpType,
|
|
jumpPath: form.jumpType === 2 ? form.jumpPath || '#' : form.jumpPath,
|
|
jumpPath: form.jumpType === 2 ? form.jumpPath || '#' : form.jumpPath,
|
|
activityType: form.activityType,
|
|
activityType: form.activityType,
|
|
@@ -691,11 +747,12 @@ async function handleSubmit() {
|
|
|
|
|
|
// 重置表单
|
|
// 重置表单
|
|
function reset() {
|
|
function reset() {
|
|
|
|
+ const defaultColor = '#409EFF'
|
|
Object.assign(form, {
|
|
Object.assign(form, {
|
|
navId: undefined,
|
|
navId: undefined,
|
|
name: '',
|
|
name: '',
|
|
pic: '',
|
|
pic: '',
|
|
- color: '#409EFF',
|
|
|
|
|
|
+ color: defaultColor,
|
|
jumpType: 1,
|
|
jumpType: 1,
|
|
jumpPath: '',
|
|
jumpPath: '',
|
|
activityType: 1,
|
|
activityType: 1,
|
|
@@ -705,9 +762,9 @@ function reset() {
|
|
remark: '',
|
|
remark: '',
|
|
createTime: '',
|
|
createTime: '',
|
|
updateTime: ''
|
|
updateTime: ''
|
|
- });
|
|
|
|
- colorInput.value = '#409EFF';
|
|
|
|
- formRef.value?.clearValidate();
|
|
|
|
|
|
+ })
|
|
|
|
+ colorInput.value = defaultColor
|
|
|
|
+ formRef.value?.clearValidate()
|
|
}
|
|
}
|
|
|
|
|
|
// 跳转类型变更处理
|
|
// 跳转类型变更处理
|
|
@@ -765,12 +822,34 @@ const rgbToHex = (rgb: string): string => {
|
|
}
|
|
}
|
|
|
|
|
|
// 如果无法解析,返回默认值
|
|
// 如果无法解析,返回默认值
|
|
- return '#409EFF';
|
|
|
|
-};
|
|
|
|
|
|
+ return '#409EFF'
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// 将任意颜色格式统一转换为16进制
|
|
|
|
+const normalizeColor = (color: string): string => {
|
|
|
|
+ if (!color) return '#409EFF'
|
|
|
|
+
|
|
|
|
+ // 如果已经是16进制格式,直接返回
|
|
|
|
+ if (color.startsWith('#')) {
|
|
|
|
+ return color
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 如果是RGB格式,转换为16进制
|
|
|
|
+ const rgbMatch = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*([\d.]+))?\)/)
|
|
|
|
+ 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')}`
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // 尝试解析其他格式或返回默认值
|
|
|
|
+ return '#409EFF'
|
|
|
|
+}
|
|
|
|
|
|
// 处理颜色输入框变化
|
|
// 处理颜色输入框变化
|
|
const handleColorInput = (value: string) => {
|
|
const handleColorInput = (value: string) => {
|
|
- // 实时同步到颜色选择器
|
|
|
|
|
|
+ // 实时同步到颜色选择器和表单
|
|
if (value.startsWith('#')) {
|
|
if (value.startsWith('#')) {
|
|
form.color = value;
|
|
form.color = value;
|
|
}
|
|
}
|
|
@@ -778,10 +857,11 @@ const handleColorInput = (value: string) => {
|
|
|
|
|
|
// 处理颜色选择器变化
|
|
// 处理颜色选择器变化
|
|
const handleColorChange = (value: string) => {
|
|
const handleColorChange = (value: string) => {
|
|
- // 当颜色选择器改变时,将16进制值填充到输入框
|
|
|
|
|
|
+ // 当颜色选择器改变时,将颜色统一转换为16进制格式
|
|
if (value) {
|
|
if (value) {
|
|
- const hexValue = rgbToHex(value);
|
|
|
|
- colorInput.value = hexValue;
|
|
|
|
|
|
+ const hexValue = normalizeColor(value)
|
|
|
|
+ form.color = hexValue
|
|
|
|
+ colorInput.value = hexValue
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
@@ -789,17 +869,24 @@ const handleColorChange = (value: string) => {
|
|
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
|
|
|
|
+ } else {
|
|
|
|
+ // 验证通过,确保表单中的颜色值也是16进制格式
|
|
|
|
+ form.color = colorInput.value
|
|
}
|
|
}
|
|
};
|
|
};
|
|
|
|
|
|
// 初始化数据
|
|
// 初始化数据
|
|
onMounted(() => {
|
|
onMounted(() => {
|
|
- loadNavData();
|
|
|
|
// 初始化排序值
|
|
// 初始化排序值
|
|
- form.sortNum = nextSortNum.value;
|
|
|
|
-});
|
|
|
|
|
|
+ form.sortNum = nextSortNum.value
|
|
|
|
+ // 确保初始颜色值为16进制格式
|
|
|
|
+ form.color = normalizeColor(form.color)
|
|
|
|
+ colorInput.value = form.color
|
|
|
|
+ // 加载初始数据
|
|
|
|
+ loadNavData()
|
|
|
|
+})
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<style scoped>
|
|
<style scoped>
|
|
@@ -811,6 +898,21 @@ onMounted(() => {
|
|
margin-bottom: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+.search-card .el-form {
|
|
|
|
+ padding: 20px 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.list-header {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.result-count {
|
|
|
|
+ color: #909399;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+}
|
|
|
|
+
|
|
.action-card {
|
|
.action-card {
|
|
margin-bottom: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
}
|
|
@@ -982,4 +1084,19 @@ onMounted(() => {
|
|
color: #909399;
|
|
color: #909399;
|
|
margin-top: 8px;
|
|
margin-top: 8px;
|
|
}
|
|
}
|
|
-</style>
|
|
|
|
|
|
+
|
|
|
|
+.color-input-group {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ gap: 12px;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.color-picker {
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.color-input {
|
|
|
|
+ flex: 1;
|
|
|
|
+ min-width: 120px;
|
|
|
|
+}
|
|
|
|
+</style>
|