Program.vue 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. <template>
  2. <div class="program">
  3. <el-breadcrumb separator-class="el-icon-arrow-right">
  4. <el-breadcrumb-item>传统媒体</el-breadcrumb-item>
  5. <el-breadcrumb-item>智能电视</el-breadcrumb-item>
  6. <el-breadcrumb-item>栏目分析</el-breadcrumb-item>
  7. </el-breadcrumb>
  8. <el-card class="box-card">
  9. <el-form
  10. ref="form"
  11. :model="form"
  12. size="small"
  13. :inline="true"
  14. label-width="120px"
  15. class="demo-form-inline"
  16. >
  17. <el-form-item label="日期">
  18. <el-date-picker
  19. v-model="form.date"
  20. type="date"
  21. placeholder="日期"
  22. :disabled-date="time => disabledDate(time)"
  23. >
  24. </el-date-picker>
  25. </el-form-item>
  26. <el-form-item label="时间">
  27. <el-time-picker
  28. v-model="form.rangeTime"
  29. is-range
  30. format="HH:mm"
  31. @change="() => (form.rangeTimeRange = [])"
  32. range-separator="-"
  33. start-placeholder="开始时间"
  34. end-placeholder="结束时间"
  35. >
  36. </el-time-picker>
  37. </el-form-item>
  38. <el-form-item label="时段">
  39. <el-select
  40. v-model="form.rangeTimeRange"
  41. placeholder="请选择时段"
  42. multiple
  43. collapse-tags
  44. clearable
  45. @change="timeSelect"
  46. >
  47. <el-option
  48. v-for="item in cycle"
  49. :key="item.value"
  50. :label="item.label"
  51. :value="item.value"
  52. :disabled="item.disabled"
  53. >
  54. </el-option>
  55. </el-select>
  56. </el-form-item>
  57. <el-form-item label="频道组">
  58. <el-select
  59. v-model="form.channelGroup"
  60. placeholder="请选择频道组"
  61. @change="channelSelect"
  62. >
  63. <el-option
  64. v-for="item in channelList"
  65. :key="item.value"
  66. :label="item.label"
  67. :value="item.value"
  68. :disabled="item.disabled"
  69. >
  70. </el-option>
  71. </el-select>
  72. </el-form-item>
  73. <el-form-item label="分类">
  74. <el-select
  75. v-model="form.classification"
  76. multiple
  77. clearable
  78. collapse-tags
  79. placeholder="请选择分类"
  80. @change="classSelect"
  81. >
  82. <el-option-group
  83. v-for="group in classification"
  84. :key="group.value"
  85. :label="group.label"
  86. >
  87. <el-option
  88. v-for="item in group.options"
  89. :key="item.value"
  90. :label="item.label"
  91. :value="item.value"
  92. >
  93. </el-option>
  94. </el-option-group>
  95. </el-select>
  96. </el-form-item>
  97. <el-form-item label="区域">
  98. <el-select
  99. v-model="form.region"
  100. placeholder="请选择区域"
  101. @change="regionSelect"
  102. >
  103. <el-option-group
  104. v-for="group in region"
  105. :key="group.value"
  106. :label="group.label"
  107. >
  108. <el-option
  109. v-for="item in group.options"
  110. :key="item.value"
  111. :label="item.label"
  112. :value="item.value"
  113. >
  114. </el-option>
  115. </el-option-group>
  116. </el-select>
  117. </el-form-item>
  118. <el-form-item style="float: right">
  119. <el-button type="primary" @click="onSubmit">查询</el-button>
  120. <el-button type="primary" @click="onExport">导出</el-button>
  121. </el-form-item>
  122. </el-form>
  123. </el-card>
  124. <br />
  125. <el-card class="box-card">
  126. <bilateral-bar-chart
  127. ref="chart"
  128. v-if="tableData.length"
  129. keyName="epg_name"
  130. :list="tableData"
  131. ></bilateral-bar-chart>
  132. <el-table
  133. :data="tableData"
  134. :header-cell-style="{ backgroundColor: '#f4f5f7', color: '#606266' }"
  135. style="width: 100%"
  136. @row-click="clickRow"
  137. >
  138. <el-table-column align="center" prop="" label="" width="30">
  139. <template #default="scope">
  140. <div
  141. v-if="scope.row.heightlight === '是'"
  142. style="height: 1em;width:1em;"
  143. >
  144. <svg
  145. xmlns="http://www.w3.org/2000/svg"
  146. viewBox="0 0 1024 1024"
  147. data-v-066465b6=""
  148. >
  149. <path
  150. fill="currentColor"
  151. d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-44.672L382.592 149.376a29.12 29.12 0 0 0-41.728 0z"
  152. ></path>
  153. </svg>
  154. </div>
  155. </template>
  156. </el-table-column>
  157. <el-table-column type="index" />
  158. <el-table-column align="center" prop="epg_name" label="节目" />
  159. <el-table-column align="center" prop="tv_name" label="频道" />
  160. <el-table-column
  161. align="center"
  162. prop="tv_name"
  163. :formatter="playTime"
  164. label="播出时间"
  165. />
  166. <el-table-column
  167. align="center"
  168. prop="heightlight"
  169. :formatter="heightlightStyle"
  170. label="高光时刻"
  171. width="180"
  172. >
  173. <template #default="scope">
  174. <el-image
  175. style="width: 1em; height: 1em; vertical-align: middle;"
  176. :src="require('../assets/img/lightning.png')"
  177. fit="fit"
  178. v-if="scope.row.heightlight === '是'"
  179. ></el-image>
  180. <span style="vertical-align: middle;">
  181. {{ scope.row.heightlight }}
  182. </span>
  183. </template>
  184. </el-table-column>
  185. <el-table-column
  186. align="center"
  187. prop="tv_ratings"
  188. :formatter="matrer"
  189. label="收视率"
  190. width="180"
  191. />
  192. <el-table-column
  193. align="center"
  194. prop="market_ratings"
  195. :formatter="matrer"
  196. label="市占率"
  197. width="180"
  198. />
  199. </el-table>
  200. </el-card>
  201. </div>
  202. </template>
  203. <script>
  204. // @ is an alias to /src
  205. import bilateralBarChart from "@/components/bilateralBarChart";
  206. import { list, listcsv, heightlightApi } from "@/api/index";
  207. import config from "@/config/index";
  208. let milestone = [];
  209. export default {
  210. name: "Program",
  211. data() {
  212. return {
  213. form: {
  214. rangeTimeRange: [],
  215. rangeTime: [],
  216. channelGroup: 0,
  217. classification: [],
  218. date: new Date(new Date() - 86400000),
  219. region: -1,
  220. },
  221. tableData: [],
  222. };
  223. },
  224. mounted() {
  225. let d = this.dateFormat(this.form.date);
  226. heightlightApi({
  227. date: [d.year, d.month, d.day].join("-"),
  228. })
  229. .then(r => {
  230. milestone = r || [];
  231. this.onSubmit();
  232. })
  233. .catch(err => {
  234. console.error(err);
  235. });
  236. },
  237. computed: {
  238. cycle() {
  239. return config.cycle;
  240. },
  241. classification() {
  242. return config.classification;
  243. },
  244. channelList() {
  245. return config.channelList;
  246. },
  247. region() {
  248. return config.region;
  249. },
  250. },
  251. methods: {
  252. timeSelect(a) {
  253. let end = (a || [])[(a || []).length - 1];
  254. if (this.form.rangeTimeRange.length === config.cycle.length - 1) {
  255. this.form.rangeTimeRange = ["0000_2400"];
  256. } else {
  257. let n = (this.form.rangeTimeRange || []).sort((a, b) => {
  258. let aNum = a.split("_")[0];
  259. let bNum = b.split("_")[0];
  260. return aNum - bNum;
  261. });
  262. let isSelect = true;
  263. for (let i = 0; i < n.length - 1; i++) {
  264. let aNum = n[i].split("_")[1];
  265. let bNum = n[i + 1].split("_")[0];
  266. if (aNum !== bNum) {
  267. isSelect = false;
  268. break;
  269. }
  270. }
  271. if (!isSelect) {
  272. let arr = (n.join(",") + ",")
  273. .replace(end + ",", "")
  274. .replace(/,$/, "");
  275. this.form.rangeTimeRange = arr.split(",");
  276. }
  277. }
  278. if (!this.form.rangeTimeRange.length) return;
  279. let s = this.form.rangeTimeRange[0].split("_")[0];
  280. let e = this.form.rangeTimeRange[
  281. this.form.rangeTimeRange.length - 1
  282. ].split("_");
  283. e = e[e.length - 1];
  284. if (e == "2400") e = "2359";
  285. this.form.rangeTime = [
  286. new Date(1970, 1, 1, s[0] + s[1] - 0, s[2] + s[3] - 0),
  287. new Date(1970, 1, 1, e[0] + e[1] - 0, e[2] + e[3] - 0),
  288. ];
  289. },
  290. playTime(row) {
  291. return row.start_time.split(" ")[1] + "~" + row.end_time.split(" ")[1];
  292. },
  293. heightlightStyle(row, column, cellValue) {
  294. if (cellValue === "是") return "<el-icon><flag /></el-icon>";
  295. else return "<el-icon><document-add /></el-icon>";
  296. },
  297. clickRow(row) {
  298. if (row.heightlight === "否") return;
  299. this.$router.push({
  300. path: "/heightlight",
  301. query: { id: row.ca_id, t: row.tv_id },
  302. });
  303. },
  304. disabledDate(time) {
  305. return time.getTime() > Date.now() - 86400000;
  306. },
  307. onExport() {
  308. listcsv(this.formatListData());
  309. },
  310. formatlist(li) {
  311. let joinMilestone = milestone.join(",");
  312. return li.map(v => {
  313. const ngx = new RegExp(v.tv_id + "_" + v.ca_id, "g");
  314. v.heightlight = ngx.test(joinMilestone) ? "是" : "否";
  315. return v;
  316. });
  317. },
  318. onSubmit() {
  319. list(this.formatListData())
  320. .then(r => {
  321. this.tableData = this.formatlist(r.list);
  322. })
  323. .catch(() => {
  324. this.tableData = [];
  325. });
  326. },
  327. matrer(row, column, cellValue) {
  328. return (cellValue * 100).toFixed(4) + "%";
  329. },
  330. dateFormat(date) {
  331. let D = new Date(date);
  332. let m = D.getMonth() + 1;
  333. let d = D.getDate();
  334. let h = D.getHours();
  335. let M = D.getMinutes();
  336. let s = D.getSeconds();
  337. m > 9 ? m : (m = "0" + m);
  338. d > 9 ? d : (d = "0" + d);
  339. h > 9 ? h : (h = "0" + h);
  340. M > 9 ? M : (M = "0" + M);
  341. s > 9 ? s : (s = "0" + s);
  342. return {
  343. year: D.getFullYear(),
  344. month: m,
  345. day: d,
  346. hour: h,
  347. minutes: M,
  348. seconds: s,
  349. };
  350. },
  351. formatListData() {
  352. let d = this.dateFormat(this.form.date);
  353. let time = "";
  354. if (this.form.rangeTime.length) {
  355. let start = new Date(this.form.rangeTime[0]);
  356. let end = new Date(this.form.rangeTime[1]);
  357. let start_hour = start.getHours();
  358. let start_min = start.getMinutes();
  359. let end_hour = end.getHours();
  360. let end_min = end.getMinutes();
  361. start_hour = start_hour > 9 ? start_hour + "" : "0" + start_hour;
  362. start_min = start_min > 9 ? start_min + "" : "0" + start_min;
  363. end_hour = end_hour > 9 ? end_hour + "" : "0" + end_hour;
  364. end_min = end_min > 9 ? end_min + "" : "0" + end_min;
  365. if (end_hour + end_min === "2359") {
  366. end_hour = "24";
  367. end_min = "00";
  368. }
  369. time = start_hour + start_min + "_" + end_hour + end_min;
  370. } else {
  371. time = "0000_2400";
  372. }
  373. return {
  374. tv_type: this.form.channelGroup || this.channelList[0].value,
  375. time_range: time,
  376. date: [d.year, d.month, d.day].join("-"),
  377. ca_type: this.form.classification.join(",") || [
  378. this.classification[0].value,
  379. ],
  380. area_id: this.form.region || this.region[0].value,
  381. };
  382. },
  383. classSelect(a) {
  384. this.selectAll(a, "classification", "0");
  385. },
  386. channelSelect(a) {
  387. this.selectAll(a, "channelGroup", 0);
  388. },
  389. regionSelect(a) {
  390. this.selectAll(a, "region", -1);
  391. },
  392. selectAll(a, key, val) {
  393. if (!a.length) return;
  394. let select = a[a.length - 1];
  395. if (select === val) this.form[key] = [val];
  396. else
  397. this.form[key] = (a.join(",") + ",")
  398. .replace(val + ",", "")
  399. .replace(/,$/, "")
  400. .split(",");
  401. },
  402. },
  403. beforeUnmount: function() {
  404. milestone = null;
  405. },
  406. components: { bilateralBarChart },
  407. };
  408. </script>
  409. <style>
  410. .program {
  411. margin: 10px 15px;
  412. }
  413. </style>