indexApp.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <template>
  2. <div class="app-container">
  3. <!-- Tab 切换 -->
  4. <el-tabs v-model="activeTab" @tab-click="handleTabClick">
  5. <el-tab-pane label="项目" name="project"></el-tab-pane>
  6. <el-tab-pane label="课程" name="course"></el-tab-pane>
  7. <el-tab-pane label="公开课" name="common"></el-tab-pane>
  8. </el-tabs>
  9. <!-- 查询条件 -->
  10. <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
  11. <!-- 公司选择 -->
  12. <el-form-item label="公司">
  13. <el-select v-model="queryParams.companyId" placeholder="请选择公司" filterable clearable size="small">
  14. <el-option v-for="(option, index) in companyList" :key="index" :value="option.dictValue" :label="option.dictLabel"></el-option>
  15. </el-select>
  16. </el-form-item>
  17. <!-- 项目选择 -->
  18. <el-form-item label="项目" v-if="activeTab === 'all' || activeTab === 'project'">
  19. <el-select v-model="queryParams.project" placeholder="请选择项目" filterable clearable size="small">
  20. <el-option v-for="dict in projectOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
  21. </el-select>
  22. </el-form-item>
  23. <!-- 课程选择 -->
  24. <el-form-item label="课程" v-if="activeTab === 'all' || activeTab === 'course'">
  25. <el-select v-model="queryParams.courseId" placeholder="请选择课程" filterable clearable size="small">
  26. <el-option v-for="dict in courseLists" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
  27. </el-select>
  28. </el-form-item>
  29. <el-form-item label="公开课" v-if="activeTab === 'all' || activeTab === 'common'">
  30. <el-select v-model="queryParams.courseId" placeholder="请选择公开课" filterable clearable size="small">
  31. <el-option v-for="dict in commonCourseLists" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
  32. </el-select>
  33. </el-form-item>
  34. <!-- 时间选择 -->
  35. <el-form-item label="年月">
  36. <el-date-picker
  37. v-model="timeRange"
  38. type="daterange"
  39. placeholder="选择年月"
  40. :value-format="'yyyy-MM-dd'"
  41. :picker-options="pickerOptions"
  42. @change="handleDateData"
  43. ></el-date-picker>
  44. </el-form-item>
  45. <el-form-item>
  46. <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
  47. <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
  48. <el-button type="warning" plain icon="el-icon-download" size="mini" :loading="exportLoading" @click="handleExport" >导出</el-button>
  49. </el-form-item>
  50. </el-form>
  51. <el-row :gutter="10" class="mb8">
  52. <el-col :span="1.5">
  53. <el-button
  54. type="warning"
  55. plain
  56. icon="el-icon-download"
  57. size="mini"
  58. :loading="exportLoading"
  59. @click="handleExport"
  60. v-hasPermi="['his:company:export']"
  61. >导出
  62. </el-button>
  63. </el-col>
  64. <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
  65. </el-row>
  66. <!-- 表格 -->
  67. <el-table border v-loading="loading" :data="courseTrafficLogList" @selection-change="handleSelectionChange" show-summary :summary-method="getSummaries">
  68. <el-table-column type="selection" width="55" align="center" />
  69. <!-- 公司列 -->
  70. <el-table-column label="公司" align="center" prop="companyName" v-if="activeTab !== 'common'" />
  71. <!-- 项目列 -->
  72. <el-table-column label="项目" align="center" prop="projectName" v-if="activeTab === 'all' || activeTab === 'project'" />
  73. <!-- 课程列 -->
  74. <el-table-column label="课程" align="center" prop="courseName" v-if="activeTab === 'all' || activeTab === 'course'||activeTab === 'common'" />
  75. <el-table-column label="日期" align="center" prop="month" />
  76. <el-table-column label="使用流量" align="center">
  77. <template slot-scope="scope">
  78. <span>{{ formatTrafficData(scope.row.totalInternetTraffic) }}</span>
  79. </template>
  80. </el-table-column>
  81. </el-table>
  82. <!-- 分页 -->
  83. <pagination
  84. v-show="total > 0"
  85. :total="total"
  86. :page.sync="queryParams.pageNum"
  87. :limit.sync="queryParams.pageSize"
  88. @pagination="getList"
  89. />
  90. </div>
  91. </template>
  92. <script>
  93. import { listCourseTrafficLog, exportCourseTrafficLog, commonCourseList } from "@/api/course/courseTrafficLog";
  94. import { courseList } from "@/api/course/courseRedPacketLog";
  95. import { allList } from "@/api/company/company";
  96. export default {
  97. data() {
  98. return {
  99. activeTab: "project", // 默认 tab
  100. timeRange: null, // 时间范围单独绑定
  101. companyList: [],
  102. projectOptions: [],
  103. pickerOptions: {
  104. shortcuts: [
  105. {
  106. text: '今日',
  107. onClick(picker) {
  108. const start = new Date();
  109. const end = new Date();
  110. picker.$emit('pick', [start, end]);
  111. }
  112. },
  113. {
  114. text: '昨日',
  115. onClick(picker) {
  116. const start = new Date();
  117. start.setDate(start.getDate() - 1);
  118. const end = new Date(start);
  119. picker.$emit('pick', [start, end]);
  120. }
  121. },
  122. {
  123. text: '本周',
  124. onClick(picker) {
  125. const now = new Date();
  126. const day = now.getDay() || 7;
  127. const start = new Date(now);
  128. start.setDate(now.getDate() - day + 1);
  129. const end = new Date();
  130. picker.$emit('pick', [start, end]);
  131. }
  132. },
  133. {
  134. text: '本月',
  135. onClick(picker) {
  136. const start = new Date(new Date().setDate(1));
  137. const end = new Date();
  138. picker.$emit('pick', [start, end]);
  139. }
  140. }
  141. ]
  142. },
  143. courseLists: [],
  144. commonCourseLists: [],
  145. loading: false,
  146. exportLoading: false,
  147. showSearch: true,
  148. total: 0,
  149. courseTrafficLogList: [],
  150. queryParams: {
  151. tabType: "", // 当前 tab 类型
  152. startDate: null,
  153. endDate: null,
  154. pageNum: 1,
  155. pageSize: 10,
  156. companyId: null,
  157. project: null,
  158. courseId: null,
  159. typeFlag:1
  160. }
  161. };
  162. },
  163. created() {
  164. this.queryParams.tabType = "project";
  165. courseList().then(res => this.courseLists = res.list);
  166. commonCourseList().then(res => this.commonCourseLists = res.list || res.data || []);
  167. this.getDicts("sys_course_project").then(res => this.projectOptions = res.data);
  168. this.getAllCompany();
  169. this.getList();
  170. },
  171. methods: {
  172. getSummaries(param) {
  173. const { columns, data } = param;
  174. const sums = [];
  175. columns.forEach((column, index) => {
  176. if (index === 0) {
  177. sums[index] = '合计';
  178. return;
  179. }
  180. // 根据列的位置判断,假设流量列是最后一个列(第5列,索引为4)
  181. // 或者根据列的数量判断,这里假设流量列始终是倒数第一列
  182. if (index === columns.length - 1) {
  183. if (data && data.length > 0) {
  184. const values = data.map(item => Number(item.totalInternetTraffic) || 0);
  185. const total = values.reduce((prev, curr) => prev + curr, 0);
  186. sums[index] = this.formatTrafficData(total);
  187. } else {
  188. sums[index] = '0.0000 GB';
  189. }
  190. } else {
  191. sums[index] = '';
  192. }
  193. });
  194. return sums;
  195. },
  196. handleTabClick(tab) {
  197. this.queryParams.tabType = tab.name;
  198. this.queryParams.pageNum = 1;
  199. // 清理互斥参数
  200. if (tab.name !== "project") this.queryParams.project = null;
  201. if (tab.name !== "course") this.queryParams.courseId = null;
  202. this.getList();
  203. },
  204. handleDateData() {
  205. if (this.timeRange) {
  206. this.queryParams.startDate = this.timeRange[0];
  207. this.queryParams.endDate = this.timeRange[1];
  208. } else {
  209. this.queryParams.startDate = null;
  210. this.queryParams.endDate = null;
  211. }
  212. },
  213. getAllCompany() {
  214. allList().then(res => this.companyList = res.rows);
  215. },
  216. getList() {
  217. this.loading = true;
  218. listCourseTrafficLog(this.queryParams).then(res => {
  219. this.courseTrafficLogList = res.rows;
  220. console.log('列表',this.courseTrafficLogList)
  221. this.total = res.total;
  222. }).finally(() => {
  223. this.loading = false;
  224. });
  225. },
  226. handleQuery() {
  227. this.queryParams.pageNum = 1;
  228. this.getList();
  229. },
  230. resetQuery() {
  231. this.timeRange = null;
  232. this.queryParams = {
  233. ...this.queryParams,
  234. startDate: null,
  235. endDate: null,
  236. companyId: null,
  237. project: null,
  238. courseId: null,
  239. pageNum: 1,
  240. };
  241. this.getList();
  242. },
  243. formatTrafficData(traffic) {
  244. return `${(traffic / (1024 ** 3)).toFixed(4)} GB`;
  245. },
  246. handleSelectionChange(selection) {
  247. this.ids = selection.map(item => item.logId);
  248. },
  249. handleExport() {
  250. this.$confirm("确认导出数据?", "提示").then(() => {
  251. this.exportLoading = true;
  252. return exportCourseTrafficLog(this.queryParams);
  253. }).then(res => {
  254. this.download(res.msg);
  255. }).finally(() => {
  256. this.exportLoading = false;
  257. });
  258. },
  259. }
  260. };
  261. </script>