|
|
@@ -0,0 +1,221 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <el-button type="primary" @click="dialogVisible = true">选择轮播组</el-button>
|
|
|
+ <div v-if="showSelected && selectedGroup" class="selected-group">
|
|
|
+ <el-tag closable @close="removeGroup" style="margin: 2px">
|
|
|
+ {{ selectedGroup.name }}
|
|
|
+ </el-tag>
|
|
|
+ </div>
|
|
|
+ <el-dialog title="选择轮播组" v-model="dialogVisible" width="900px" append-to-body>
|
|
|
+ <el-form :inline="true" :model="queryParams" class="mb-2">
|
|
|
+ <el-form-item label="名称">
|
|
|
+ <el-input v-model="queryParams.itemName" placeholder="轮播组名称" clearable style="width: 180px"
|
|
|
+ @keyup.enter="getCarouselList" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" @click="getCarouselList">搜索</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <el-table v-loading="dialogLoading" :data="carouselList" @row-click="handleRowClick" highlight-current-row>
|
|
|
+ <el-table-column width="50">
|
|
|
+ <template #default="{ row }">
|
|
|
+ <el-checkbox v-model="row.selected" @click.stop @change="handleSelectChange(row)" />
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column prop="name" label="轮播组名称" min-width="150" />
|
|
|
+ <el-table-column prop="itemCount" label="轮播项数量" width="100" />
|
|
|
+ <el-table-column prop="duration" label="轮播间隔(秒)" width="120" />
|
|
|
+ <el-table-column prop="createTime" label="创建时间" width="180" />
|
|
|
+ </el-table>
|
|
|
+ <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
|
|
|
+ v-model:limit="queryParams.pageSize" @pagination="getCarouselList" />
|
|
|
+ <template #footer>
|
|
|
+ <el-button @click="dialogVisible = false">取消</el-button>
|
|
|
+ <el-button type="primary" @click="confirmSelect" :disabled="!currentRow">确定</el-button>
|
|
|
+ </template>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script setup lang="ts">
|
|
|
+import { ref, watch, defineProps, defineEmits, nextTick } from 'vue';
|
|
|
+import { listItem } from '@/api/smsb/source/item';
|
|
|
+import type { ItemVO, ItemQuery } from '@/api/smsb/source/item_type';
|
|
|
+
|
|
|
+export interface CarouselGroup {
|
|
|
+ id: string | number;
|
|
|
+ name: string;
|
|
|
+ itemCount: number;
|
|
|
+ duration: number;
|
|
|
+ createTime: string;
|
|
|
+ items: any[];
|
|
|
+ selected?: boolean;
|
|
|
+ [key: string]: any; // Allow additional properties
|
|
|
+}
|
|
|
+
|
|
|
+const props = defineProps<{
|
|
|
+ modelValue: string;
|
|
|
+ showSelected?: boolean;
|
|
|
+}>();
|
|
|
+
|
|
|
+const emit = defineEmits(['update:modelValue']);
|
|
|
+
|
|
|
+const dialogVisible = ref(false);
|
|
|
+const dialogLoading = ref(false);
|
|
|
+const carouselList = ref<CarouselGroup[]>([]);
|
|
|
+const total = ref(0);
|
|
|
+const currentRow = ref<CarouselGroup | null>(null);
|
|
|
+const selectedGroup = ref<CarouselGroup | null>(null);
|
|
|
+
|
|
|
+// 定义查询参数类型
|
|
|
+interface CarouselQuery extends ItemQuery {
|
|
|
+ pageNum: number;
|
|
|
+ pageSize: number;
|
|
|
+ itemName: string;
|
|
|
+ itemType: number;
|
|
|
+}
|
|
|
+
|
|
|
+const queryParams = ref<CarouselQuery>({
|
|
|
+ pageNum: 1,
|
|
|
+ pageSize: 10,
|
|
|
+ itemName: '',
|
|
|
+ itemType: 1 // 1表示轮播组类型
|
|
|
+});
|
|
|
+
|
|
|
+// 初始化时,如果有值,反序列化
|
|
|
+watch(
|
|
|
+ () => props.modelValue,
|
|
|
+ (val) => {
|
|
|
+ if (val) {
|
|
|
+ try {
|
|
|
+ const parsedValue = JSON.parse(val);
|
|
|
+ selectedGroup.value = {
|
|
|
+ id: parsedValue.id,
|
|
|
+ name: parsedValue.name,
|
|
|
+ itemCount: parsedValue.itemCount,
|
|
|
+ duration: parsedValue.duration,
|
|
|
+ createTime: parsedValue.createTime,
|
|
|
+ items: parsedValue.items
|
|
|
+ };
|
|
|
+ } catch {
|
|
|
+ selectedGroup.value = null;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ selectedGroup.value = null;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ { immediate: true }
|
|
|
+);
|
|
|
+
|
|
|
+// 查询轮播组列表
|
|
|
+const getCarouselList = async () => {
|
|
|
+ dialogLoading.value = true;
|
|
|
+ try {
|
|
|
+ // 构建查询参数,确保类型安全
|
|
|
+ const query: ItemQuery = {
|
|
|
+ itemName: queryParams.value.itemName,
|
|
|
+ itemType: 1, // 1表示轮播组类型
|
|
|
+ pageNum: queryParams.value.pageNum,
|
|
|
+ pageSize: queryParams.value.pageSize
|
|
|
+ };
|
|
|
+
|
|
|
+ const res = await listItem(query);
|
|
|
+
|
|
|
+ // 转换数据格式,并标记已选中的项
|
|
|
+ carouselList.value = (res.rows || []).map((item: ItemVO) => ({
|
|
|
+ id: item.id,
|
|
|
+ name: item.itemName || '',
|
|
|
+ itemName: item.itemName || '', // 保持与API返回的字段名一致
|
|
|
+ itemCount: item.sourceNum || 0,
|
|
|
+ duration: 5, // 默认5秒,可以根据实际需求调整
|
|
|
+ createTime: item.createTime || '',
|
|
|
+ selected: selectedGroup.value?.id === item.id,
|
|
|
+ items: [] // 不需要在UI中显示,仅用于内部处理
|
|
|
+ }));
|
|
|
+
|
|
|
+ // 如果当前有选中的组,确保它在列表中也被选中
|
|
|
+ if (selectedGroup.value?.id) {
|
|
|
+ const selectedItem = carouselList.value.find((item) => item.id === selectedGroup.value?.id);
|
|
|
+ if (selectedItem) {
|
|
|
+ selectedItem.selected = true;
|
|
|
+ currentRow.value = selectedItem;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ total.value = res.total || 0;
|
|
|
+ } finally {
|
|
|
+ dialogLoading.value = false;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 行点击
|
|
|
+const handleRowClick = (row: CarouselGroup) => {
|
|
|
+ currentRow.value = row;
|
|
|
+};
|
|
|
+
|
|
|
+// 处理选择变化
|
|
|
+const handleSelectChange = (row: CarouselGroup) => {
|
|
|
+ // 确保只有一个被选中
|
|
|
+ carouselList.value.forEach((item) => {
|
|
|
+ if (item.id !== row.id) {
|
|
|
+ item.selected = false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ currentRow.value = row.selected ? row : null;
|
|
|
+};
|
|
|
+
|
|
|
+// 选择轮播组
|
|
|
+const selectGroup = (row: CarouselGroup) => {
|
|
|
+ row.selected = true;
|
|
|
+ handleSelectChange(row);
|
|
|
+ confirmSelect();
|
|
|
+};
|
|
|
+
|
|
|
+// 移除已选轮播组
|
|
|
+const removeGroup = () => {
|
|
|
+ selectedGroup.value = null;
|
|
|
+ emit('update:modelValue', '');
|
|
|
+};
|
|
|
+
|
|
|
+// 确认选择
|
|
|
+const confirmSelect = () => {
|
|
|
+ if (!currentRow.value) return;
|
|
|
+
|
|
|
+ // 确保ID是数字类型
|
|
|
+ const id = typeof currentRow.value.id === 'string' ? parseInt(currentRow.value.id, 10) : currentRow.value.id;
|
|
|
+
|
|
|
+ if (isNaN(id)) {
|
|
|
+ console.error('Invalid group ID:', currentRow.value.id);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 只存储必要的信息
|
|
|
+ selectedGroup.value = {
|
|
|
+ id,
|
|
|
+ name: currentRow.value.name,
|
|
|
+ itemCount: 0,
|
|
|
+ duration: 0,
|
|
|
+ createTime: '',
|
|
|
+ items: []
|
|
|
+ };
|
|
|
+
|
|
|
+ // 更新所有行的选中状态
|
|
|
+ carouselList.value.forEach((item) => {
|
|
|
+ item.selected = item.id === currentRow.value.id;
|
|
|
+ });
|
|
|
+
|
|
|
+ emit('update:modelValue', JSON.stringify(selectedGroup.value));
|
|
|
+ dialogVisible.value = false;
|
|
|
+};
|
|
|
+
|
|
|
+// 弹窗首次打开时自动加载
|
|
|
+watch(dialogVisible, (val) => {
|
|
|
+ if (val) getCarouselList();
|
|
|
+});
|
|
|
+</script>
|
|
|
+
|
|
|
+<style scoped>
|
|
|
+.selected-group {
|
|
|
+ margin-top: 8px;
|
|
|
+}
|
|
|
+</style>
|