|
|
@@ -1,155 +1,195 @@
|
|
|
<template>
|
|
|
<div class="app-container">
|
|
|
- <el-card class="search-card" shadow="never">
|
|
|
- <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
|
|
|
- <el-form-item label="SOP任务" prop="channel" label-width="70px">
|
|
|
- <date-range
|
|
|
- v-model="selectedMultipleTasks"
|
|
|
- :raw-data="channelList"
|
|
|
- placeholder="请选择多个任务"
|
|
|
- :parentSelectable="true"
|
|
|
- :multiple="true"
|
|
|
- component-width="300px"
|
|
|
- :max-display-tags="3"
|
|
|
- :check-strictly="false"
|
|
|
- :return-leaf-only="false"
|
|
|
- :show-node-detail="true"
|
|
|
- @change="handleMultiChange"
|
|
|
- @dateRangeChange="dateRangeChange"
|
|
|
- ></date-range>
|
|
|
+ <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
|
|
|
+ <el-form-item label="SOP任务" prop="channel" label-width="70px">
|
|
|
+ <date-range
|
|
|
+ v-model="selectedMultipleTasks"
|
|
|
+ :raw-data="channelList"
|
|
|
+ placeholder="请选择多个任务"
|
|
|
+ :parentSelectable="true"
|
|
|
+ :multiple="true"
|
|
|
+ component-width="300px"
|
|
|
+ :max-display-tags="3"
|
|
|
+ :check-strictly="false"
|
|
|
+ :return-leaf-only="false"
|
|
|
+ :show-node-detail="true"
|
|
|
+ @change="handleMultiChange"
|
|
|
+ @dateRangeChange="dateRangeChange"
|
|
|
+ ></date-range>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
|
|
|
+ <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+
|
|
|
+
|
|
|
+ <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
|
|
|
+<!-- <el-table-column label="营期名称" align="center" prop="periodName" />-->
|
|
|
+ <el-table-column label="营期id" align="center" prop="userLogsId" />
|
|
|
+ <el-table-column label="总人数" align="center" prop="total" />
|
|
|
+ <el-table-column label="流失人数" align="center" prop="num" />
|
|
|
+<!-- <el-table-column label="营期开始时间" align="center" prop="periodStartingTime" />
|
|
|
+ <el-table-column label="营期结束时间" align="center" prop="periodEndTime" />-->
|
|
|
+
|
|
|
+ </el-table>
|
|
|
+
|
|
|
+ <pagination
|
|
|
+ v-show="total>0"
|
|
|
+ :total="total"
|
|
|
+ :page.sync="queryParams.pageNum"
|
|
|
+ :limit.sync="queryParams.pageSize"
|
|
|
+ @pagination="getList"
|
|
|
+ />
|
|
|
+
|
|
|
+ <!-- 添加或修改用户对话框 -->
|
|
|
+ <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
|
|
|
+ <el-form ref="form" :model="form" :rules="rules" label-width="120px">
|
|
|
+ <el-form-item label="用户头像" prop="avatar">
|
|
|
+ <el-popover
|
|
|
+ placement="right"
|
|
|
+ title=""
|
|
|
+ trigger="hover"
|
|
|
+ >
|
|
|
+ <img slot="reference" :src="form.avatar" width="80">
|
|
|
+ <img :src="form.avatar" style="max-width: 80px;">
|
|
|
+ </el-popover>
|
|
|
</el-form-item>
|
|
|
- <el-form-item class="search-buttons">
|
|
|
- <el-button type="primary" icon="el-icon-search" size="small" @click="handleQuery">查询</el-button>
|
|
|
- <el-button icon="el-icon-refresh" size="small" @click="resetQuery">重置</el-button>
|
|
|
+ <el-form-item label="会员昵称" prop="nickname">
|
|
|
+ <el-input v-model="form.nickname" disabled placeholder="请输入用户昵称" />
|
|
|
</el-form-item>
|
|
|
- </el-form>
|
|
|
- </el-card>
|
|
|
-
|
|
|
- <!-- 统计结果展示区域 -->
|
|
|
- <el-row :gutter="20" class="statistics-row">
|
|
|
- <el-col :span="24">
|
|
|
- <el-card class="statistics-card" shadow="hover">
|
|
|
- <div slot="header" class="clearfix">
|
|
|
- <span class="card-title">
|
|
|
- <i class="el-icon-data-analysis"></i>
|
|
|
- 详情
|
|
|
- </span>
|
|
|
- </div>
|
|
|
-
|
|
|
- <!-- 加载状态 -->
|
|
|
- <div v-if="loading" class="loading-content">
|
|
|
- <el-skeleton :rows="5" animated />
|
|
|
- </div>
|
|
|
+ <el-form-item label="手机号码" prop="phone">
|
|
|
+ <el-input v-model="form.phone" disabled placeholder="请输入手机号码" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="最后一次登录ip" prop="lastIp">
|
|
|
+ <el-input v-model="form.lastIp" disabled placeholder="请输入最后一次登录ip" />
|
|
|
+ </el-form-item>
|
|
|
+ <!-- <el-form-item label="用户余额" prop="nowMoney">
|
|
|
+ <el-input v-model="form.nowMoney" disabled placeholder="请输入用户余额" />
|
|
|
+ </el-form-item> -->
|
|
|
+ <el-form-item label="积分" prop="integral">
|
|
|
+ <el-input v-model="form.integral" disabled placeholder="请输入用户剩余积分" />
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="用户备注" prop="remark">
|
|
|
+ <el-input v-model="form.remark" placeholder="请输入用户备注" />
|
|
|
+ </el-form-item>
|
|
|
+ <!-- <el-form-item label="状态">
|
|
|
+ <el-radio-group v-model="form.status">
|
|
|
+ <el-radio :label="item.dictValue" v-for="item in statusOptions" >{{item.dictLabel}}</el-radio>
|
|
|
+ </el-radio-group>
|
|
|
+ </el-form-item> -->
|
|
|
|
|
|
- <!-- 数据展示 -->
|
|
|
- <div v-else-if="statisticsResult" class="data-content">
|
|
|
- <div class="data-display">
|
|
|
- <div class="data-value">
|
|
|
- {{ formatValue(statisticsResult.lostData) }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <!-- 无数据状态 -->
|
|
|
- <div v-else class="empty-content">
|
|
|
- <el-empty description="暂无统计数据">
|
|
|
- <el-button type="primary" size="small" @click="resetQuery">重新查询</el-button>
|
|
|
- </el-empty>
|
|
|
- </div>
|
|
|
- </el-card>
|
|
|
- </el-col>
|
|
|
- </el-row>
|
|
|
+ </el-form>
|
|
|
+ <div slot="footer" class="dialog-footer">
|
|
|
+ <el-button type="primary" @click="submitForm">确 定</el-button>
|
|
|
+ <el-button @click="cancel">取 消</el-button>
|
|
|
+ </div>
|
|
|
+ </el-dialog>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
+import { myList,updateUser,getUser,addUser } from "@/api/users/user";
|
|
|
import { shortListCamp } from '@/api/course/userCourseCamp'
|
|
|
-import { qwCourseLost } from '@/api/course/courseRedPacketLog'
|
|
|
-import {
|
|
|
- getSOPTaskData,
|
|
|
-} from '@/api/system/employeeStats'
|
|
|
-import SelectTree from '@/components/TreeSelect/index.vue'
|
|
|
+import { courseLost, qwCourseLost } from '@/api/course/courseRedPacketLog'
|
|
|
+import { getSOPTaskData } from '@/api/system/employeeStats'
|
|
|
import dateRange from '@/components/TreeSelect/dateRange.vue'
|
|
|
+import SelectTree from '@/components/TreeSelect/index.vue'
|
|
|
export default {
|
|
|
name: "CourseLostQw",
|
|
|
- components: {SelectTree,dateRange},
|
|
|
+ components: {dateRange,SelectTree},
|
|
|
data() {
|
|
|
return {
|
|
|
- // 查询相关
|
|
|
- createTime: null,
|
|
|
- courseLists: [],
|
|
|
- videoList: [],
|
|
|
+ statusOptions:[],
|
|
|
selectedMultipleTasks: [],
|
|
|
- // 选中数组
|
|
|
- ids: [],
|
|
|
- // 状态相关
|
|
|
- loading: true,
|
|
|
- exportLoading: false,
|
|
|
- infoDialogVisible: false,
|
|
|
- // 数据相关
|
|
|
- statisticsResult: null,
|
|
|
+ // 频道列表
|
|
|
+ channelList: [],
|
|
|
//课程数据
|
|
|
campData: null,
|
|
|
+ // 遮罩层
|
|
|
+ loading: false,
|
|
|
+ // 选中数组
|
|
|
+ ids: [],
|
|
|
+ // 非单个禁用
|
|
|
+ single: true,
|
|
|
+ // 非多个禁用
|
|
|
+ multiple: true,
|
|
|
+ // 显示搜索条件
|
|
|
showSearch: true,
|
|
|
+ // 总条数
|
|
|
+ total: 0,
|
|
|
+ // 用户表格数据
|
|
|
+ userList: [],
|
|
|
+ // 弹出层标题
|
|
|
+ title: "",
|
|
|
+ // 是否显示弹出层
|
|
|
+ open: false,
|
|
|
// 查询参数
|
|
|
queryParams: {
|
|
|
pageNum: 1,
|
|
|
pageSize: 10,
|
|
|
periodList: []
|
|
|
},
|
|
|
- // 频道列表
|
|
|
- channelList: [],
|
|
|
+ // 表单参数
|
|
|
+ form: {},
|
|
|
+ // 表单校验
|
|
|
+ rules: {
|
|
|
+ nowMoney: [
|
|
|
+ { required: true, message: "用户余额不能为空", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ brokeragePrice: [
|
|
|
+ { required: true, message: "佣金金额不能为空", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ integral: [
|
|
|
+ { required: true, message: "用户剩余积分不能为空", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ signNum: [
|
|
|
+ { required: true, message: "连续签到天数不能为空", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ status: [
|
|
|
+ { required: true, message: "1为正常,0为禁止不能为空", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ level: [
|
|
|
+ { required: true, message: "等级不能为空", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ userType: [
|
|
|
+ { required: true, message: "用户类型不能为空", trigger: "change" }
|
|
|
+ ],
|
|
|
+ isPromoter: [
|
|
|
+ { required: true, message: "是否为推广员不能为空", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ addres: [
|
|
|
+ { required: true, message: "详细地址不能为空", trigger: "blur" }
|
|
|
+ ],
|
|
|
+ }
|
|
|
};
|
|
|
},
|
|
|
created() {
|
|
|
getSOPTaskData({}).then(response => {
|
|
|
this.channelList = response.data;
|
|
|
});
|
|
|
+ this.getDicts("user_status").then((response) => {
|
|
|
+ this.statusOptions = response.data;
|
|
|
+ });
|
|
|
+ //this.getList();
|
|
|
},
|
|
|
methods: {
|
|
|
-
|
|
|
- // 格式化显示值
|
|
|
- formatValue(value) {
|
|
|
- if (value === null || value === undefined || value === '') {
|
|
|
- return '暂无数据';
|
|
|
- }
|
|
|
-
|
|
|
- // 如果是数字,添加千位分隔符
|
|
|
- if (typeof value === 'number' || !isNaN(value)) {
|
|
|
- const num = Number(value);
|
|
|
- return num.toLocaleString('zh-CN');
|
|
|
+ /** 查询用户列表 */
|
|
|
+ getList() {
|
|
|
+ this.loading = true;
|
|
|
+ if(this.queryParams.periodList===null){
|
|
|
+ return;
|
|
|
}
|
|
|
-
|
|
|
- return value;
|
|
|
+ qwCourseLost(this.queryParams).then(response => {
|
|
|
+ this.userList = response.rows;
|
|
|
+ this.total = response.total;
|
|
|
+ this.loading = false;
|
|
|
+ })
|
|
|
},
|
|
|
-
|
|
|
- // 获取当前时间
|
|
|
- getCurrentTime() {
|
|
|
- const now = new Date();
|
|
|
- const year = now.getFullYear();
|
|
|
- const month = String(now.getMonth() + 1).padStart(2, '0');
|
|
|
- const day = String(now.getDate()).padStart(2, '0');
|
|
|
- const hours = String(now.getHours()).padStart(2, '0');
|
|
|
- const minutes = String(now.getMinutes()).padStart(2, '0');
|
|
|
- const seconds = String(now.getSeconds()).padStart(2, '0');
|
|
|
- return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
|
|
- },
|
|
|
-
|
|
|
- // 获取统计数据
|
|
|
- getStatisticsData() {
|
|
|
- this.loading = true;
|
|
|
- qwCourseLost(this.queryParams)
|
|
|
- .then(response => {
|
|
|
- this.handleResponse(response);
|
|
|
- this.updateTime = this.getCurrentTime();
|
|
|
- })
|
|
|
- .catch(error => {
|
|
|
- console.error('获取统计数据失败:', error);
|
|
|
- this.$message.error('获取统计数据失败');
|
|
|
- this.statisticsResult = null;
|
|
|
- })
|
|
|
- .finally(() => {
|
|
|
- this.loading = false;
|
|
|
- });
|
|
|
+ // 取消按钮
|
|
|
+ cancel() {
|
|
|
+ this.open = false;
|
|
|
+ this.reset();
|
|
|
},
|
|
|
handleMultiChange(e){
|
|
|
|
|
|
@@ -162,291 +202,126 @@ export default {
|
|
|
this.channelList = response.data;
|
|
|
});
|
|
|
},
|
|
|
- // 处理接口响应
|
|
|
- handleResponse(response) {
|
|
|
- // 根据实际接口返回结构调整
|
|
|
- if (response.data && response.data.lostData !== undefined) {
|
|
|
- this.statisticsResult = response.data;
|
|
|
- } else if (response.rows && response.rows.length > 0) {
|
|
|
- this.statisticsResult = { lostData: response.rows[0].lostData };
|
|
|
- } else if (response.total !== undefined) {
|
|
|
- this.statisticsResult = { lostData: response.total };
|
|
|
- } else if (typeof response === 'object') {
|
|
|
- this.statisticsResult = { lostData: response.data };
|
|
|
- ;
|
|
|
- } else {
|
|
|
- this.statisticsResult = { lostData: response.data };
|
|
|
- }
|
|
|
- // 如果没有mockData字段,创建默认结构
|
|
|
- if (!this.statisticsResult || this.statisticsResult.lostData === undefined) {
|
|
|
- this.statisticsResult = { lostData: '暂无数据' };
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- // 刷新数据
|
|
|
- refreshData() {
|
|
|
- this.getStatisticsData();
|
|
|
- this.$message.success('数据已刷新');
|
|
|
+ // 表单重置
|
|
|
+ reset() {
|
|
|
+ this.form = {
|
|
|
+ userId: null,
|
|
|
+ username: null,
|
|
|
+ password: null,
|
|
|
+ realName: null,
|
|
|
+ birthday: null,
|
|
|
+ idCard: null,
|
|
|
+ mark: null,
|
|
|
+ nickname: null,
|
|
|
+ avatar: null,
|
|
|
+ phone: null,
|
|
|
+ createTime: null,
|
|
|
+ updateTime: null,
|
|
|
+ lastIp: null,
|
|
|
+ nowMoney: null,
|
|
|
+ brokeragePrice: null,
|
|
|
+ integral: null,
|
|
|
+ signNum: null,
|
|
|
+ status: 0,
|
|
|
+ level: null,
|
|
|
+ spreadUserId: null,
|
|
|
+ spreadTime: null,
|
|
|
+ userType: null,
|
|
|
+ isPromoter: null,
|
|
|
+ payCount: null,
|
|
|
+ spreadCount: null,
|
|
|
+ addres: null,
|
|
|
+ wxProfile: null,
|
|
|
+ isDel: null
|
|
|
+ };
|
|
|
+ this.resetForm("form");
|
|
|
},
|
|
|
-
|
|
|
- // 查询
|
|
|
+ /** 搜索按钮操作 */
|
|
|
handleQuery() {
|
|
|
- /* if (!this.queryParams.sTime || !this.queryParams.eTime) {
|
|
|
- this.$message.warning("请选择时间范围");
|
|
|
- return;
|
|
|
- } */
|
|
|
+ this.queryParams.pageNum = 1;
|
|
|
+ this.getList();
|
|
|
this.queryParams.periodList = this.selectedMultipleTasks;
|
|
|
- this.getStatisticsData();
|
|
|
+ //this.getStatisticsData();
|
|
|
},
|
|
|
-
|
|
|
- // 重置查询
|
|
|
+ /** 重置按钮操作 */
|
|
|
resetQuery() {
|
|
|
- this.$refs.queryForm.resetFields();
|
|
|
- this.createTime = null;
|
|
|
- this.queryParams.sTime = null;
|
|
|
- this.queryParams.eTime = null;
|
|
|
- this.queryParams.courseId = null;
|
|
|
- this.videoList = [];
|
|
|
- this.selectedMultipleTasks = [];
|
|
|
- this.getStatisticsData();
|
|
|
+ this.resetForm("queryForm");
|
|
|
+ this.handleQuery();
|
|
|
+ },
|
|
|
+ // 多选框选中数据
|
|
|
+ handleSelectionChange(selection) {
|
|
|
+ this.ids = selection.map(item => item.userId)
|
|
|
+ this.single = selection.length!==1
|
|
|
+ this.multiple = !selection.length
|
|
|
+ },
|
|
|
+ /** 新增按钮操作 */
|
|
|
+ handleAdd() {
|
|
|
+ this.reset();
|
|
|
+ this.open = true;
|
|
|
+ this.title = "添加用户";
|
|
|
+ },
|
|
|
+ /** 修改按钮操作 */
|
|
|
+ handleUpdate(row) {
|
|
|
+ this.reset();
|
|
|
+ const userId = row.userId || this.ids
|
|
|
+ getUser(userId).then(response => {
|
|
|
+ this.form = response.data;
|
|
|
+ this.form.status = response.data.status.toString();
|
|
|
+ this.open = true;
|
|
|
+ this.title = "修改用户";
|
|
|
+ });
|
|
|
+ },
|
|
|
+ /** 提交按钮 */
|
|
|
+ submitForm() {
|
|
|
+ this.$refs["form"].validate(valid => {
|
|
|
+ if (valid) {
|
|
|
+ if (this.form.userId != null) {
|
|
|
+ updateUser(this.form).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.msgSuccess("修改成功");
|
|
|
+ this.open = false;
|
|
|
+ this.getList();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ } else {
|
|
|
+ addUser(this.form).then(response => {
|
|
|
+ if (response.code === 200) {
|
|
|
+ this.msgSuccess("新增成功");
|
|
|
+ this.open = false;
|
|
|
+ this.getList();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ /** 删除按钮操作 */
|
|
|
+ handleDelete(row) {
|
|
|
+ const userIds = row.userId || this.ids;
|
|
|
+ this.$confirm('是否确认删除用户编号为"' + userIds + '"的数据项?', "警告", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning"
|
|
|
+ }).then(function() {
|
|
|
+ return delUser(userIds);
|
|
|
+ }).then(() => {
|
|
|
+ this.getList();
|
|
|
+ this.msgSuccess("删除成功");
|
|
|
+ }).catch(function() {});
|
|
|
+ },
|
|
|
+ /** 导出按钮操作 */
|
|
|
+ handleExport() {
|
|
|
+ const queryParams = this.queryParams;
|
|
|
+ this.$confirm('是否确认导出所有用户数据项?', "警告", {
|
|
|
+ confirmButtonText: "确定",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning"
|
|
|
+ }).then(function() {
|
|
|
+ return exportUser(queryParams);
|
|
|
+ }).then(response => {
|
|
|
+ this.download(response.msg);
|
|
|
+ }).catch(function() {});
|
|
|
}
|
|
|
}
|
|
|
};
|
|
|
</script>
|
|
|
-
|
|
|
-<style lang="scss" scoped>
|
|
|
-.app-container {
|
|
|
- padding: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-// 搜索卡片样式
|
|
|
-.search-card {
|
|
|
- margin-bottom: 20px;
|
|
|
-
|
|
|
- ::v-deep .el-card__body {
|
|
|
- padding: 20px;
|
|
|
- }
|
|
|
-
|
|
|
- .search-buttons {
|
|
|
- margin-left: 10px;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 统计卡片样式
|
|
|
-.statistics-row {
|
|
|
- margin-top: 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.statistics-card {
|
|
|
- min-height: 400px;
|
|
|
-
|
|
|
- ::v-deep .el-card__header {
|
|
|
- padding: 18px 20px;
|
|
|
- background-color: #f5f7fa;
|
|
|
- border-bottom: 1px solid #ebeef5;
|
|
|
- }
|
|
|
-
|
|
|
- .card-title {
|
|
|
- font-size: 16px;
|
|
|
- font-weight: 500;
|
|
|
- color: #303133;
|
|
|
-
|
|
|
- i {
|
|
|
- margin-right: 8px;
|
|
|
- color: #409eff;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .card-actions {
|
|
|
- float: right;
|
|
|
- margin-top: -6px;
|
|
|
-
|
|
|
- .el-button {
|
|
|
- padding: 0;
|
|
|
- margin-left: 16px;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 数据内容区域
|
|
|
-.loading-content {
|
|
|
- padding: 40px 20px;
|
|
|
-}
|
|
|
-
|
|
|
-.data-content {
|
|
|
- padding: 0px 20px;
|
|
|
- text-align: center;
|
|
|
-}
|
|
|
-
|
|
|
-.data-header {
|
|
|
- margin-bottom: 30px;
|
|
|
-
|
|
|
- .data-title {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- gap: 12px;
|
|
|
- margin-bottom: 8px;
|
|
|
-
|
|
|
- .title-text {
|
|
|
- font-size: 18px;
|
|
|
- font-weight: 500;
|
|
|
- color: #606266;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .data-subtitle {
|
|
|
- font-size: 14px;
|
|
|
- color: #909399;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.data-display {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- gap: 20px;
|
|
|
- margin: 40px 0;
|
|
|
- padding: 40px;
|
|
|
- background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
|
|
|
- border-radius: 12px;
|
|
|
-
|
|
|
- .data-value {
|
|
|
- font-size: 64px;
|
|
|
- font-weight: 700;
|
|
|
- color: #409eff;
|
|
|
- text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.1);
|
|
|
- }
|
|
|
-
|
|
|
- .data-unit {
|
|
|
- .el-tag {
|
|
|
- font-size: 14px;
|
|
|
- padding: 8px 16px;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.data-footer {
|
|
|
- margin-top: 40px;
|
|
|
- padding-top: 20px;
|
|
|
- border-top: 1px solid #ebeef5;
|
|
|
-
|
|
|
- .data-meta {
|
|
|
- display: flex;
|
|
|
- justify-content: center;
|
|
|
- gap: 30px;
|
|
|
- flex-wrap: wrap;
|
|
|
-
|
|
|
- .meta-item {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 6px;
|
|
|
- font-size: 14px;
|
|
|
- color: #909399;
|
|
|
-
|
|
|
- i {
|
|
|
- color: #409eff;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-// 空状态
|
|
|
-.empty-content {
|
|
|
- padding: 80px 20px;
|
|
|
-}
|
|
|
-
|
|
|
-// 字段信息对话框样式
|
|
|
-.field-info {
|
|
|
- .info-item {
|
|
|
- display: flex;
|
|
|
- margin-bottom: 16px;
|
|
|
- padding-bottom: 16px;
|
|
|
- border-bottom: 1px solid #ebeef5;
|
|
|
-
|
|
|
- &:last-child {
|
|
|
- margin-bottom: 0;
|
|
|
- padding-bottom: 0;
|
|
|
- border-bottom: none;
|
|
|
- }
|
|
|
-
|
|
|
- .info-label {
|
|
|
- width: 100px;
|
|
|
- font-weight: 500;
|
|
|
- color: #303133;
|
|
|
- flex-shrink: 0;
|
|
|
- }
|
|
|
-
|
|
|
- .info-value {
|
|
|
- flex: 1;
|
|
|
- color: #606266;
|
|
|
- word-break: break-word;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-.stats-card {
|
|
|
- text-align: center;
|
|
|
- margin-bottom: 16px;
|
|
|
-
|
|
|
- .stats-number {
|
|
|
- font-size: 24px;
|
|
|
- font-weight: bold;
|
|
|
- color: #409EFF;
|
|
|
-
|
|
|
- &.online {
|
|
|
- color: #67C23A;
|
|
|
- }
|
|
|
-
|
|
|
- &.offline {
|
|
|
- color: #F56C6C;
|
|
|
- }
|
|
|
-
|
|
|
- &.rate {
|
|
|
- color: #E6A23C;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-.mb8 {
|
|
|
- margin-bottom: 8px;
|
|
|
-}
|
|
|
-
|
|
|
-::v-deep .el-table .el-table__header th {
|
|
|
- background-color: #f5f7fa;
|
|
|
-}
|
|
|
-
|
|
|
-::v-deep .el-alert {
|
|
|
- margin-bottom: 16px;
|
|
|
-}
|
|
|
-// 响应式设计
|
|
|
-@media (max-width: 768px) {
|
|
|
- .search-card ::v-deep .el-card__body {
|
|
|
- padding: 15px;
|
|
|
- }
|
|
|
-
|
|
|
- .data-display {
|
|
|
- flex-direction: column;
|
|
|
- padding: 30px 20px;
|
|
|
-
|
|
|
- .data-value {
|
|
|
- font-size: 48px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .data-footer .data-meta {
|
|
|
- flex-direction: column;
|
|
|
- gap: 12px;
|
|
|
- align-items: flex-start;
|
|
|
- }
|
|
|
-
|
|
|
- .search-buttons {
|
|
|
- display: flex;
|
|
|
- flex-wrap: wrap;
|
|
|
- gap: 10px;
|
|
|
-
|
|
|
- .el-button {
|
|
|
- margin-left: 0 !important;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-</style>
|