Skill.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519
  1. <template>
  2. <div>
  3. <el-card>
  4. <el-form :model="skillParams" ref="skillParams" class="clearfix topForm">
  5. <div class="leftForm-skill">
  6. <el-form-item
  7. style="display:flex;"
  8. prop="channel"
  9. name="channel"
  10. :rules="[{ required: true, message: '请选择渠道', trigger: 'blur' }]"
  11. label="渠道选择"
  12. >
  13. <el-select
  14. v-model="skillParams.channel"
  15. @change="channelChange"
  16. style="width:160px"
  17. placeholder="请选择渠道"
  18. >
  19. <el-option
  20. v-for="item in skillChanneList"
  21. :key="item.code"
  22. :label="item.title"
  23. :value="item.code"
  24. ></el-option>
  25. </el-select>
  26. </el-form-item>
  27. <el-form-item
  28. class="pruductForm-skill"
  29. prop="skillId"
  30. label="技能选择"
  31. v-if="skillParams.channel !== '6001'"
  32. :rules="[{ required: true, message: '请选择技能', trigger: 'blur' }]"
  33. >
  34. <!-- 兼容小度在家和学有义方不同的返回内容 -->
  35. <el-select v-model="skillParams.skillId" placeholder="请选择技能" @change="skillChange" style="width:160px">
  36. <el-option
  37. v-for="item in skillList"
  38. :key="item.skillId || item.skillId === 0 ? item.skillId : item.id"
  39. :label="item.skillName ? item.skillName : item.title"
  40. :value="item.skillId || item.skillId === 0 ? item.skillId : item.id"
  41. ></el-option>
  42. </el-select>
  43. </el-form-item>
  44. <el-form-item
  45. class="pruductForm-skill"
  46. prop="classId"
  47. label="产品包选择"
  48. v-if="skillParams.skillId === 0 || skillParams.skillId === 3"
  49. :rules="[{ required: true, message: '请选择产品包', trigger: 'blur' }]"
  50. >
  51. <!-- 兼容小度在家和学有义方不同的返回内容 -->
  52. <el-select v-model="skillParams.classId" placeholder="请选择产品包" style="width:160px">
  53. <el-option
  54. v-for="item in baiduCourseList"
  55. :key="item.id"
  56. :label="item.fullName"
  57. :value="item.id"
  58. ></el-option>
  59. </el-select>
  60. </el-form-item>
  61. <el-form-item class="dateForm-skill" name="data" label="查询日期" style="display:flex">
  62. <el-date-picker
  63. style="width:140px"
  64. v-model="skillParams.startDate"
  65. type="date"
  66. placeholder="起"
  67. ></el-date-picker>
  68. <el-date-picker
  69. style="width:140px"
  70. v-model="skillParams.endDate"
  71. type="date"
  72. placeholder="止"
  73. ></el-date-picker>
  74. </el-form-item>
  75. </div>
  76. <el-form-item>
  77. <el-button type="primary" @click="submitForm('skillParams')">搜索</el-button>
  78. </el-form-item>
  79. </el-form>
  80. <el-table :data="skillData" border style="width: 100%" :height="tableHeight" v-if="skillParams.channel === 'XYYF'" >
  81. <el-table-column
  82. label="日期"
  83. prop="day"
  84. fixed
  85. align="left"
  86. header-align="center"
  87. min-width="120px"
  88. ></el-table-column>
  89. <el-table-column label="流量与观看" header-align="center">
  90. <el-table-column
  91. label="UV"
  92. prop="uv"
  93. align="right"
  94. header-align="center"
  95. min-width="100px"
  96. ></el-table-column>
  97. <el-table-column
  98. label="VIP用户 | -UV1"
  99. align="right"
  100. header-align="center"
  101. :render-header="renderheader"
  102. prop="vipUv"
  103. min-width="120px"
  104. ></el-table-column>
  105. <el-table-column
  106. label="非VIP用户 | UV2=UV-UV1"
  107. align="right"
  108. header-align="center"
  109. :render-header="renderheader"
  110. prop="waitVipUv"
  111. min-width="140px"
  112. ></el-table-column>
  113. <el-table-column
  114. label="VIP用户占比 | =UV1/UV"
  115. align="right"
  116. header-align="center"
  117. :render-header="renderheader"
  118. prop="vipProportion"
  119. min-width="140px"
  120. ></el-table-column>
  121. <el-table-column
  122. label="VIP权限用户 | =V0"
  123. align="right"
  124. header-align="center"
  125. :render-header="renderheader"
  126. prop="vipCount"
  127. min-width="140px"
  128. ></el-table-column>
  129. <el-table-column
  130. label="VIP用户活跃率 | =UV1/V0"
  131. align="right"
  132. header-align="center"
  133. :render-header="renderheader"
  134. min-width="140px"
  135. prop="aliveVipProportion"
  136. >
  137. </el-table-column>
  138. <!-- <el-table-column
  139. label="VV"
  140. prop="vv"
  141. align="right"
  142. header-align="center"
  143. min-width="100px"
  144. ></el-table-column>-->
  145. <el-table-column
  146. label="VV"
  147. align="right"
  148. header-align="center"
  149. :render-header="renderheader"
  150. prop="totalPlay"
  151. min-width="140px"
  152. ></el-table-column>
  153. <el-table-column
  154. label="人均播放 | =VV/UV"
  155. align="right"
  156. header-align="center"
  157. :render-header="renderheader"
  158. prop="perCapitaPlay"
  159. min-width="140px"
  160. ></el-table-column>
  161. </el-table-column>
  162. <el-table-column label="拉新,付费与转换率" header-align="center">
  163. <el-table-column
  164. label="连续包月 | -Qm1"
  165. align="right"
  166. header-align="center"
  167. :render-header="renderheader"
  168. prop="consecutiveMonthly"
  169. min-width="100px"
  170. ></el-table-column>
  171. <el-table-column
  172. label="月包 | -Qm2"
  173. align="right"
  174. header-align="center"
  175. :render-header="renderheader"
  176. prop="monthlyPayment"
  177. min-width="90px"
  178. ></el-table-column>
  179. <el-table-column
  180. label="年包 | -Qy"
  181. align="right"
  182. header-align="center"
  183. :render-header="renderheader"
  184. prop="yearlyPayment"
  185. ></el-table-column>
  186. <el-table-column
  187. label="付费订单数量| Q=Qm1+Qm2+Qy"
  188. align="right"
  189. header-align="center"
  190. :render-header="renderheader"
  191. prop="totalPayment"
  192. min-width="160px"
  193. ></el-table-column>
  194. <el-table-column
  195. label="r1 | =Qm1/Q"
  196. align="right"
  197. header-align="center"
  198. :render-header="renderheader"
  199. prop="consecutiveConversion"
  200. min-width="130px"
  201. ></el-table-column>// 月包占比
  202. <el-table-column
  203. label="r2 | =Qm2/Q"
  204. align="right"
  205. header-align="center"
  206. :render-header="renderheader"
  207. prop="monthlyConversion"
  208. min-width="130px"
  209. ></el-table-column>// 年包占比
  210. <el-table-column
  211. label="r3 | =Qy/Q"
  212. align="right"
  213. header-align="center"
  214. :render-header="renderheader"
  215. prop="yearlyConversion"
  216. min-width="130px"
  217. ></el-table-column>
  218. <el-table-column
  219. label="R | =(Qm1+Qm2+Qy)/UV2"
  220. align="right"
  221. header-align="center"
  222. :render-header="renderheader"
  223. prop="totalConversion"
  224. min-width="190px"
  225. ></el-table-column>
  226. </el-table-column>
  227. </el-table>
  228. <el-table :data="skillData" border style="width: 100%" :height="tableHeight" v-else>
  229. <el-table-column
  230. label="日期"
  231. prop="day"
  232. fixed
  233. align="left"
  234. header-align="center"
  235. min-width="120px"
  236. ></el-table-column>
  237. <el-table-column label="流量与观看" header-align="center">
  238. <el-table-column
  239. label="UV"
  240. prop="uv"
  241. align="right"
  242. header-align="center"
  243. min-width="100px"
  244. ></el-table-column>
  245. <el-table-column
  246. label="VIP用户 | -UV1"
  247. align="right"
  248. header-align="center"
  249. :render-header="renderheader"
  250. prop="vipUv"
  251. min-width="120px"
  252. ></el-table-column>
  253. <el-table-column
  254. label="非VIP用户 | UV2=UV-UV1"
  255. align="right"
  256. header-align="center"
  257. :render-header="renderheader"
  258. prop="waitVipUv"
  259. min-width="140px"
  260. ></el-table-column>
  261. <el-table-column
  262. label="VIP用户占比 | =UV1/UV"
  263. align="right"
  264. header-align="center"
  265. :render-header="renderheader"
  266. prop="vipProportion"
  267. min-width="140px"
  268. ></el-table-column>
  269. <!-- <el-table-column
  270. label="VV"
  271. prop="vv"
  272. align="right"
  273. header-align="center"
  274. min-width="100px"
  275. ></el-table-column>-->
  276. <el-table-column
  277. label="VV"
  278. align="right"
  279. header-align="center"
  280. :render-header="renderheader"
  281. prop="totalPlay"
  282. min-width="140px"
  283. ></el-table-column>
  284. <el-table-column
  285. label="人均播放 | =VV/UV"
  286. align="right"
  287. header-align="center"
  288. :render-header="renderheader"
  289. prop="perCapitaPlay"
  290. min-width="140px"
  291. ></el-table-column>
  292. </el-table-column>
  293. <el-table-column label="拉新,付费与转换率" header-align="center">
  294. <el-table-column
  295. label="连续包月 | -Qm1"
  296. align="right"
  297. header-align="center"
  298. :render-header="renderheader"
  299. prop="consecutiveMonthly"
  300. min-width="100px"
  301. ></el-table-column>
  302. <el-table-column
  303. label="月包 | -Qm2"
  304. align="right"
  305. header-align="center"
  306. :render-header="renderheader"
  307. prop="monthlyPayment"
  308. min-width="90px"
  309. ></el-table-column>
  310. <el-table-column
  311. label="年包 | -Qy"
  312. align="right"
  313. header-align="center"
  314. :render-header="renderheader"
  315. prop="yearlyPayment"
  316. ></el-table-column>
  317. <el-table-column
  318. label="付费订单数量| Q=Qm1+Qm2+Qy"
  319. align="right"
  320. header-align="center"
  321. :render-header="renderheader"
  322. prop="totalPayment"
  323. min-width="160px"
  324. ></el-table-column>
  325. <el-table-column
  326. label="r1 | =Qm1/Q"
  327. align="right"
  328. header-align="center"
  329. :render-header="renderheader"
  330. prop="consecutiveConversion"
  331. min-width="130px"
  332. ></el-table-column>// 月包占比
  333. <el-table-column
  334. label="r2 | =Qm2/Q"
  335. align="right"
  336. header-align="center"
  337. :render-header="renderheader"
  338. prop="monthlyConversion"
  339. min-width="130px"
  340. ></el-table-column>// 年包占比
  341. <el-table-column
  342. label="r3 | =Qy/Q"
  343. align="right"
  344. header-align="center"
  345. :render-header="renderheader"
  346. prop="yearlyConversion"
  347. min-width="130px"
  348. ></el-table-column>
  349. <el-table-column
  350. label="R | =(Qm1+Qm2+Qy)/UV2"
  351. align="right"
  352. header-align="center"
  353. :render-header="renderheader"
  354. prop="totalConversion"
  355. min-width="190px"
  356. ></el-table-column>
  357. </el-table-column>
  358. </el-table>
  359. <!-- <el-pagination
  360. v-if="orderList.totalElements"
  361. background
  362. layout="prev, pager, next"
  363. :total="orderList.totalElements"
  364. @current-change="changePage">
  365. </el-pagination>-->
  366. </el-card>
  367. </div>
  368. </template>
  369. <script>
  370. import { mapGetters } from "vuex";
  371. import formatDate from "../../utils/formatTime";
  372. import { getBaiduCourseList } from '../../api/skill'
  373. export default {
  374. data() {
  375. return {
  376. tableHeight: 500,
  377. dateValue: "",
  378. skillParams: {
  379. skillId: "",
  380. startDate: "",
  381. endDate: "",
  382. channel: "",
  383. classId: ""
  384. },
  385. channelList: "",
  386. skillChanneList: [
  387. { title: "百度-小度在家", code: "BAIDU" },
  388. { title: "阿里-天猫精灵", code: "ALI" },
  389. { title: "百度-义方小学堂", code: "XYYF" },
  390. { title: "OPPO-小学同步辅导", code: "6001" }
  391. ],
  392. baiduCourseList: []
  393. };
  394. },
  395. computed: {
  396. ...mapGetters({
  397. skillList: "skillList",
  398. orderList: "orderList",
  399. productList: "productList",
  400. skillData: "skillData"
  401. })
  402. },
  403. created() {
  404. // this.$store.dispatch("getOrderList", this.skillParams);
  405. this.skillParams.startDate = this.getYesterDay();
  406. this.skillParams.endDate = this.getYesterDay();
  407. this.tableHeight = document.documentElement.clientHeight * 0.75;
  408. },
  409. methods: {
  410. // 搜索
  411. submitForm(formName) {
  412. this.skillParams.startDate = this.skillParams.startDate
  413. ? formatDate(this.skillParams.startDate, 2)
  414. : "";
  415. this.skillParams.endDate = this.skillParams.endDate
  416. ? formatDate(this.skillParams.endDate, 2)
  417. : "";
  418. this.$refs[formName].validate(valid => {
  419. if (valid) {
  420. if(this.skillParams.channel === '6001'){
  421. this.$store.dispatch("getOppoData", this.skillParams);
  422. } else if(this.skillParams.skillId === 0 || this.skillParams.skillId === 3){
  423. this.$store.dispatch("getBaiduData", this.skillParams);
  424. } else if(this.skillParams.channel === 'ALI') {
  425. this.$store.dispatch("getAliData", this.skillParams);
  426. } else{
  427. this.$store.dispatch("getSkillData", this.skillParams);
  428. }
  429. } else {
  430. console.log("error submit!!");
  431. return false;
  432. }
  433. });
  434. },
  435. // 渠道下课程分页
  436. changePage(e) {
  437. this.skillParams.pageNo = e;
  438. this.$store.dispatch("getSkillData", this.skillParams);
  439. },
  440. // 表头折行
  441. renderheader(h, { column, $index }) {
  442. return h("span", {}, [
  443. h("span", {}, column.label.split("|")[0]),
  444. h("br"),
  445. h("span", {}, column.label.split("|")[1])
  446. ]);
  447. },
  448. getYesterDay() {
  449. let yesterday = new Date().getTime() - 86400000;
  450. return formatDate(yesterday, 2);
  451. },
  452. channelChange(val) {
  453. this.skillParams.skillId = "";
  454. this.$store.dispatch("getSkillList", val);
  455. },
  456. skillChange(val) {
  457. this.skillParams.classId = ''
  458. if (val === 0) {
  459. getBaiduCourseList('CHINESE').then(res => {
  460. this.baiduCourseList = [{
  461. fullName: '全部',
  462. id: 100
  463. }, ...res.data]
  464. })
  465. } else if (val === 3) {
  466. getBaiduCourseList('MATH').then(res => {
  467. this.baiduCourseList = [{
  468. fullName: '全部',
  469. id: 101
  470. }, ...res.data]
  471. })
  472. }
  473. },
  474. columnZero() {
  475. return "0";
  476. },
  477. columnZeroPercent(row, column, index) {
  478. if (row.totalPayment && column.property === "yearlyConversion") {
  479. return "100.00%";
  480. } else {
  481. return "0.00%";
  482. }
  483. // if(row.)
  484. }
  485. }
  486. };
  487. </script>
  488. <style lang="less" scoped>
  489. .pruductForm-skill {
  490. margin-left: 10px;
  491. display: flex;
  492. }
  493. .topForm {
  494. display: flex;
  495. align-items: center;
  496. flex-direction: row;
  497. flex-shrink: 0;
  498. justify-content: space-between;
  499. }
  500. .leftForm-skill {
  501. display: flex;
  502. align-items: center;
  503. flex-direction: row;
  504. justify-content: space-between;
  505. }
  506. .dateForm-skill {
  507. margin-left: 18px;
  508. }
  509. </style>