|
|
@@ -0,0 +1,622 @@
|
|
|
+<template>
|
|
|
+ <div class="app-container channel-container">
|
|
|
+ <el-row :gutter="20" class="channel-wrapper">
|
|
|
+ <!-- 分组区域 -->
|
|
|
+ <el-col :xs="24" :sm="8" :md="6" class="group-section">
|
|
|
+ <div class="section-header">
|
|
|
+ <h3>分组管理</h3>
|
|
|
+ <el-button type="primary" size="mini" icon="el-icon-plus" @click="handleAddGroup">新增分组</el-button>
|
|
|
+ </div>
|
|
|
+ <div class="search-box">
|
|
|
+ <el-input
|
|
|
+ v-model="queryParams.groupChannelName"
|
|
|
+ placeholder="搜索分组"
|
|
|
+ clearable
|
|
|
+ size="small"
|
|
|
+ @input="getGroupList"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class="group-list">
|
|
|
+ <div
|
|
|
+ :class="['group-item', 'all-group', { active: selectedGroupId === 'all' }]"
|
|
|
+ @click="selectAllGroup"
|
|
|
+ >
|
|
|
+ <span class="group-name">全部</span>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ v-for="item in groupList"
|
|
|
+ :key="item.id"
|
|
|
+ :class="['group-item', { active: selectedGroupId === item.id }]"
|
|
|
+ @click="selectGroup(item)"
|
|
|
+ >
|
|
|
+ <span class="group-name">{{ item.channelName }}</span>
|
|
|
+ </div>
|
|
|
+ <div v-if="groupList.length === 0" class="empty-tip">暂无分组</div>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
+
|
|
|
+ <!-- 渠道区域 -->
|
|
|
+ <el-col :xs="24" :sm="16" :md="18" class="channel-section">
|
|
|
+ <div class="section-header">
|
|
|
+ <h3>{{ selectedGroupId ? '渠道管理' : '请选择分组' }}</h3>
|
|
|
+ <el-button
|
|
|
+ v-if="selectedGroupId"
|
|
|
+ type="primary"
|
|
|
+ size="mini"
|
|
|
+ icon="el-icon-plus"
|
|
|
+ @click="handleAddChannel"
|
|
|
+ >新增渠道</el-button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="selectedGroupId" class="search-box">
|
|
|
+ <el-input
|
|
|
+ v-model="queryParams.channelChannelName"
|
|
|
+ placeholder="搜索渠道"
|
|
|
+ clearable
|
|
|
+ size="small"
|
|
|
+ @input="getChannelList"
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div v-if="!selectedGroupId" class="empty-state">
|
|
|
+ <p>请在左侧选择分组后查看渠道列表</p>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-table
|
|
|
+ v-else
|
|
|
+ border
|
|
|
+ v-loading="channelLoading"
|
|
|
+ :data="channelList"
|
|
|
+ class="channel-table"
|
|
|
+ >
|
|
|
+ <el-table-column label="渠道名称" align="center" prop="channelName" min-width="150" show-overflow-tooltip />
|
|
|
+ <el-table-column label="更新时间" align="center" prop="updateTime" width="180">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <span>{{ parseTime(scope.row.updateTime) }}</span>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="160" fixed="right">
|
|
|
+ <template slot-scope="scope">
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-edit"
|
|
|
+ @click="handleEditChannel(scope.row)"
|
|
|
+ >编辑</el-button>
|
|
|
+ <el-button
|
|
|
+ size="mini"
|
|
|
+ type="text"
|
|
|
+ icon="el-icon-document-copy"
|
|
|
+ @click="handleCopyChannel(scope.row)"
|
|
|
+ >复制</el-button>
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <!-- 分页 -->
|
|
|
+ <el-pagination
|
|
|
+ v-if="channelList.length > 0"
|
|
|
+ :current-page="channelPageNum"
|
|
|
+ :page-size="channelPageSize"
|
|
|
+ :page-sizes="[10, 20, 50, 100]"
|
|
|
+ :total="channelTotal"
|
|
|
+ layout="total, sizes, prev, pager, next, jumper"
|
|
|
+ @size-change="handleChannelPageSizeChange"
|
|
|
+ @current-change="handleChannelPageChange"
|
|
|
+ style="text-align: right; margin-top: 10px;"
|
|
|
+ />
|
|
|
+ </el-col>
|
|
|
+ </el-row>
|
|
|
+
|
|
|
+ <!-- 分组对话框 -->
|
|
|
+ <el-dialog :title="groupDialogTitle" :visible.sync="groupDialogOpen" width="500px" append-to-body>
|
|
|
+ <el-form ref="groupForm" :model="groupForm" :rules="groupRules" label-width="100px">
|
|
|
+ <el-form-item label="分组名称" prop="channelName">
|
|
|
+ <el-input
|
|
|
+ v-model="groupForm.channelName"
|
|
|
+ placeholder="请输入分组名称"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="groupDialogOpen = false">取 消</el-button>
|
|
|
+ <el-button type="primary" @click="submitGroup">确 定</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 渠道对话框 -->
|
|
|
+ <el-dialog :title="channelDialogTitle" :visible.sync="channelDialogOpen" width="500px" append-to-body>
|
|
|
+ <el-form ref="channelForm" :model="channelForm" :rules="channelRules" label-width="100px">
|
|
|
+ <el-form-item label="所属分组" prop="parentId">
|
|
|
+ <el-select
|
|
|
+ v-model="channelForm.parentId"
|
|
|
+ placeholder="请选择分组"
|
|
|
+ clearable
|
|
|
+ >
|
|
|
+ <el-option
|
|
|
+ v-for="item in groupList"
|
|
|
+ :key="item.id"
|
|
|
+ :label="item.channelName"
|
|
|
+ :value="item.id"
|
|
|
+ />
|
|
|
+ </el-select>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="渠道名称" prop="channelName">
|
|
|
+ <el-input
|
|
|
+ v-model="channelForm.channelName"
|
|
|
+ placeholder="请输入渠道名称"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="channelDialogOpen = false">取 消</el-button>
|
|
|
+ <el-button type="primary" @click="submitChannel">确 定</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+
|
|
|
+ <!-- 复制渠道对话框 -->
|
|
|
+ <el-dialog title="复制渠道" :visible.sync="batchCopyDialogOpen" width="500px" append-to-body>
|
|
|
+ <el-form ref="batchCopyForm" :model="batchCopyForm" :rules="batchCopyRules" label-width="100px">
|
|
|
+ <el-form-item label="渠道名称" prop="channelName">
|
|
|
+ <el-input
|
|
|
+ v-model="batchCopyForm.channelName"
|
|
|
+ placeholder="请输入渠道名称"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="复制数量" prop="num">
|
|
|
+ <el-input-number
|
|
|
+ v-model="batchCopyForm.num"
|
|
|
+ :min="1"
|
|
|
+ :max="1000"
|
|
|
+ placeholder="请输入复制数量"
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="起始编号" prop="start">
|
|
|
+ <el-input
|
|
|
+ v-model="batchCopyForm.start"
|
|
|
+ placeholder="请输入起始编号(仅整数)"
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button @click="batchCopyDialogOpen = false">取 消</el-button>
|
|
|
+ <el-button type="primary" @click="submitBatchCopy">确 定</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { pageProject, addOrUpdateChannel, saveBatchChannel } from "@/api/adv/channel";
|
|
|
+
|
|
|
+export default {
|
|
|
+ name: "Channel",
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ // 分组列表
|
|
|
+ groupList: [],
|
|
|
+ // 选中的分组ID
|
|
|
+ selectedGroupId: null,
|
|
|
+ // 渠道列表
|
|
|
+ channelList: [],
|
|
|
+ channelLoading: false,
|
|
|
+ // 渠道分页参数
|
|
|
+ channelPageNum: 1,
|
|
|
+ channelPageSize: 10,
|
|
|
+ channelTotal: 0,
|
|
|
+ // 查询参数
|
|
|
+ queryParams: {
|
|
|
+ groupChannelName: "",
|
|
|
+ channelChannelName: ""
|
|
|
+ },
|
|
|
+ // ... existing code ...
|
|
|
+
|
|
|
+ // 分组对话框
|
|
|
+ groupDialogOpen: false,
|
|
|
+ groupDialogTitle: "新增分组",
|
|
|
+ groupForm: {
|
|
|
+ id: undefined,
|
|
|
+ channelName: ""
|
|
|
+ },
|
|
|
+ groupRules: {
|
|
|
+ channelName: [
|
|
|
+ { required: true, message: "分组名称不能为空", trigger: "blur" }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+
|
|
|
+ // 渠道对话框
|
|
|
+ channelDialogOpen: false,
|
|
|
+ channelDialogTitle: "新增渠道",
|
|
|
+ channelForm: {
|
|
|
+ id: undefined,
|
|
|
+ channelName: "",
|
|
|
+ parentId: null
|
|
|
+ },
|
|
|
+ channelRules: {
|
|
|
+ parentId: [
|
|
|
+ { required: true, message: "请选择分组", trigger: "change" }
|
|
|
+ ],
|
|
|
+ channelName: [
|
|
|
+ { required: true, message: "渠道名称不能为空", trigger: "blur" }
|
|
|
+ ]
|
|
|
+ },
|
|
|
+
|
|
|
+ // 批量复制对话框
|
|
|
+ batchCopyDialogOpen: false,
|
|
|
+ batchCopyForm: {
|
|
|
+ channelName: "",
|
|
|
+ num: 1,
|
|
|
+ start: "",
|
|
|
+ parentId: null
|
|
|
+ },
|
|
|
+ batchCopyRules: {
|
|
|
+ channelName: [
|
|
|
+ { required: true, message: "渠道名称不能为空", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ num: [
|
|
|
+ { required: true, message: "复制数量不能为空", trigger: "blur" },
|
|
|
+ { type: "number", message: "复制数量必须是整数", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ start: [
|
|
|
+ { required: true, message: "起始编号不能为空", trigger: "blur" },
|
|
|
+ { pattern: /^\d+$/, message: "起始编号只能是整数", trigger: "blur" }
|
|
|
+ ]
|
|
|
+ }
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ this.getGroupList();
|
|
|
+ // 页面加载完成后默认选中“全部”
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.selectAllGroup();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ /** 获取分组列表 */
|
|
|
+ getGroupList() {
|
|
|
+ const params = { pageNum: 1, pageSize: 1000, parentId: 0 };
|
|
|
+ // 只有输入了名称才添加到参数中
|
|
|
+ if (this.queryParams.groupChannelName) {
|
|
|
+ params.channelName = this.queryParams.groupChannelName;
|
|
|
+ }
|
|
|
+ pageProject(params).then(response => {
|
|
|
+ this.groupList = response.data.records || [];
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('加载分组列表失败:', error);
|
|
|
+ this.groupList = [];
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 选择全部分组 */
|
|
|
+ selectAllGroup() {
|
|
|
+ this.selectedGroupId = 'all';
|
|
|
+ this.channelPageNum = 1;
|
|
|
+ this.getChannelList();
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 选择分组 */
|
|
|
+ selectGroup(group) {
|
|
|
+ this.selectedGroupId = group.id;
|
|
|
+ this.channelPageNum = 1;
|
|
|
+ this.getChannelList();
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 获取渠道列表 */
|
|
|
+ getChannelList() {
|
|
|
+ if (!this.selectedGroupId) return;
|
|
|
+ this.channelLoading = true;
|
|
|
+ const params = { pageNum: this.channelPageNum, pageSize: this.channelPageSize };
|
|
|
+ // 当不是选择"全部"时,添加 parentId 参数
|
|
|
+ if (this.selectedGroupId !== 'all') {
|
|
|
+ params.parentId = this.selectedGroupId;
|
|
|
+ }
|
|
|
+ // 只有输入了名称才添加到参数中
|
|
|
+ if (this.queryParams.channelChannelName) {
|
|
|
+ params.channelName = this.queryParams.channelChannelName;
|
|
|
+ }
|
|
|
+ pageProject(params).then(response => {
|
|
|
+ this.channelList = response.data.records || [];
|
|
|
+ this.channelTotal = response.data.total || 0;
|
|
|
+ this.channelLoading = false;
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('加载渠道列表失败:', error);
|
|
|
+ this.channelList = [];
|
|
|
+ this.channelLoading = false;
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 渠道分页变更 */
|
|
|
+ handleChannelPageChange(pageNum) {
|
|
|
+ this.channelPageNum = pageNum;
|
|
|
+ this.getChannelList();
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 渠道与每页条数变更 */
|
|
|
+ handleChannelPageSizeChange(pageSize) {
|
|
|
+ this.channelPageSize = pageSize;
|
|
|
+ this.channelPageNum = 1;
|
|
|
+ this.getChannelList();
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 新增分组 */
|
|
|
+ handleAddGroup() {
|
|
|
+ this.groupForm = { id: undefined, channelName: "" };
|
|
|
+ this.groupDialogTitle = "新增分组";
|
|
|
+ this.groupDialogOpen = true;
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 提交分组 */
|
|
|
+ submitGroup() {
|
|
|
+ this.$refs["groupForm"].validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ const data = {
|
|
|
+ channelName: this.groupForm.channelName,
|
|
|
+ parentId: 0
|
|
|
+ };
|
|
|
+ addOrUpdateChannel(data).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.msgSuccess("新增成功");
|
|
|
+ this.groupDialogOpen = false;
|
|
|
+ this.getGroupList();
|
|
|
+ }
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('保存分组失败:', error);
|
|
|
+ this.msgError("保存失败");
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 新增渠道 */
|
|
|
+ handleAddChannel() {
|
|
|
+ this.channelForm = { id: undefined, channelName: "", parentId: this.selectedGroupId };
|
|
|
+ this.channelDialogTitle = "新增渠道";
|
|
|
+ this.channelDialogOpen = true;
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 编辑渠道 */
|
|
|
+ handleEditChannel(channel) {
|
|
|
+ this.channelForm = {
|
|
|
+ id: channel.id,
|
|
|
+ channelName: channel.channelName,
|
|
|
+ parentId: channel.parentId
|
|
|
+ };
|
|
|
+ this.channelDialogTitle = "编辑渠道";
|
|
|
+ this.channelDialogOpen = true;
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 提交渠道 */
|
|
|
+ submitChannel() {
|
|
|
+ this.$refs["channelForm"].validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ const data = {
|
|
|
+ channelName: this.channelForm.channelName,
|
|
|
+ parentId: this.channelForm.parentId
|
|
|
+ };
|
|
|
+ if (this.channelForm.id) {
|
|
|
+ data.id = this.channelForm.id;
|
|
|
+ }
|
|
|
+ addOrUpdateChannel(data).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.msgSuccess(this.channelForm.id ? "编辑成功" : "新增成功");
|
|
|
+ this.channelDialogOpen = false;
|
|
|
+ this.getChannelList();
|
|
|
+ }
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('保存渠道失败:', error);
|
|
|
+ this.msgError("保存失败");
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 复制渠道 */
|
|
|
+ handleCopyChannel(channel) {
|
|
|
+ this.batchCopyForm = {
|
|
|
+ channelName: channel.channelName,
|
|
|
+ num: 1,
|
|
|
+ start: "",
|
|
|
+ parentId: channel.parentId
|
|
|
+ };
|
|
|
+ this.batchCopyDialogOpen = true;
|
|
|
+ this.$nextTick(() => {
|
|
|
+ this.$refs["batchCopyForm"].clearValidate();
|
|
|
+ });
|
|
|
+ },
|
|
|
+
|
|
|
+ /** 提交批量复制 */
|
|
|
+ submitBatchCopy() {
|
|
|
+ this.$refs["batchCopyForm"].validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ // 确保 start 是整数类型
|
|
|
+ const startNum = parseInt(this.batchCopyForm.start);
|
|
|
+ const data = {
|
|
|
+ channelName: this.batchCopyForm.channelName,
|
|
|
+ num: this.batchCopyForm.num,
|
|
|
+ start: startNum,
|
|
|
+ parentId: this.batchCopyForm.parentId
|
|
|
+ };
|
|
|
+ saveBatchChannel(data).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.msgSuccess("复制成功");
|
|
|
+ this.batchCopyDialogOpen = false;
|
|
|
+ this.getChannelList();
|
|
|
+ }
|
|
|
+ }).catch(error => {
|
|
|
+ console.error('批量复制失败:', error);
|
|
|
+ this.msgError("批量复制失败");
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.channel-container {
|
|
|
+ padding: 20px;
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ min-height: calc(100vh - 100px);
|
|
|
+}
|
|
|
+
|
|
|
+.channel-wrapper {
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+
|
|
|
+.group-section,
|
|
|
+.channel-section {
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 8px;
|
|
|
+ padding: 20px;
|
|
|
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
|
|
+}
|
|
|
+
|
|
|
+.section-header {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ margin-bottom: 20px;
|
|
|
+ padding-bottom: 15px;
|
|
|
+ border-bottom: 2px solid #f0f0f0;
|
|
|
+
|
|
|
+ h3 {
|
|
|
+ margin: 0;
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 600;
|
|
|
+ color: #303133;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.group-list {
|
|
|
+ max-height: 600px;
|
|
|
+ overflow-y: auto;
|
|
|
+}
|
|
|
+
|
|
|
+.search-box {
|
|
|
+ margin-bottom: 15px;
|
|
|
+
|
|
|
+ ::v-deep .el-input__inner {
|
|
|
+ border-radius: 6px;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+
|
|
|
+ &:focus {
|
|
|
+ border-color: #667eea;
|
|
|
+ box-shadow: 0 0 0 2px rgba(102, 126, 234, 0.1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.group-item {
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ padding: 12px 15px;
|
|
|
+ margin-bottom: 8px;
|
|
|
+ border: 1px solid #dcdfe6;
|
|
|
+ border-radius: 6px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ border-color: #667eea;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background-color: rgba(102, 126, 234, 0.1);
|
|
|
+ border-color: #667eea;
|
|
|
+
|
|
|
+ .group-name {
|
|
|
+ color: #667eea;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .group-name {
|
|
|
+ flex: 1;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #606266;
|
|
|
+ word-break: break-all;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.all-group {
|
|
|
+ margin-bottom: 15px;
|
|
|
+ padding: 14px 15px;
|
|
|
+ font-weight: 600;
|
|
|
+ border-bottom: 2px solid #e8e8e8;
|
|
|
+
|
|
|
+ .group-name {
|
|
|
+ font-size: 15px;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .group-actions {
|
|
|
+ display: flex;
|
|
|
+ gap: 5px;
|
|
|
+ margin-left: 10px;
|
|
|
+
|
|
|
+ .el-button--text {
|
|
|
+ color: #909399;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: #667eea;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.empty-tip {
|
|
|
+ text-align: center;
|
|
|
+ padding: 40px 0;
|
|
|
+ color: #909399;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.empty-state {
|
|
|
+ text-align: center;
|
|
|
+ padding: 60px 0;
|
|
|
+ color: #909399;
|
|
|
+ font-size: 14px;
|
|
|
+}
|
|
|
+
|
|
|
+.channel-table {
|
|
|
+ border-radius: 8px;
|
|
|
+ overflow: hidden;
|
|
|
+ box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
|
|
|
+
|
|
|
+ ::v-deep .el-table__header {
|
|
|
+ th {
|
|
|
+ background-color: #f5f7fa;
|
|
|
+ color: #606266;
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ ::v-deep .el-table__row {
|
|
|
+ transition: all 0.3s ease;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background-color: rgba(102, 126, 234, 0.05);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.dialog-footer {
|
|
|
+ text-align: right;
|
|
|
+}
|
|
|
+
|
|
|
+// 响应式调整
|
|
|
+@media (max-width: 992px) {
|
|
|
+ .group-section,
|
|
|
+ .channel-section {
|
|
|
+ margin-bottom: 20px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|