HeaderCard.vue 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. <!--
  2. * @FileDescription: 用于数据展示页面的头部位置展示信息
  3. * @Author: FFF
  4. -->
  5. <script setup lang="ts">
  6. import router from '@/router'
  7. import DropDownSelection from './DropDownSelection.vue'
  8. import type { DropDownInfo, HeaderCardProps } from '@/types/dataAnalysis'
  9. import { computed, onMounted, reactive, ref, watch } from 'vue'
  10. import WithIconSelect from '@/components/common/WithIconSelect.vue'
  11. const props = withDefaults(defineProps<HeaderCardProps>(), {
  12. openDateSelect: false,
  13. defaultPf: 'web',
  14. needPfSelect: true,
  15. needBreadcrumb: false
  16. })
  17. const emits = defineEmits(['changePf', 'changeDate'])
  18. // 平台下拉框信息
  19. const platFormOptionInfo: DropDownInfo = {
  20. defaultSelect: props.defaultPf,
  21. title: '请选择平台',
  22. optionsList: [
  23. {
  24. value: 'web',
  25. label: 'Web'
  26. },
  27. {
  28. value: 'wx',
  29. label: '微信'
  30. },
  31. {
  32. value: 'tt',
  33. label: '抖音'
  34. }
  35. ]
  36. }
  37. // {
  38. // wx: '/img/platformIcon/wx.svg',
  39. // tt: '/img/platformIcon/tt.svg',
  40. // web: '/img/platformIcon/web.svg'
  41. // }
  42. // const dropDownInfo = {
  43. // selectInfo: [
  44. // {
  45. // icon: '/img/platformIcon/wx.svg',
  46. // value: 'wx',
  47. // label: '微信',
  48. // isSelected: true
  49. // },
  50. // {
  51. // icon: '/img/platformIcon/tt.svg',
  52. // value: 'tt',
  53. // label: '抖音',
  54. // isSelected: true
  55. // }
  56. // ]
  57. // }
  58. // 快速选择日期
  59. const shortcuts = [
  60. {
  61. text: '上一周',
  62. value: () => {
  63. const end = new Date()
  64. const start = new Date()
  65. start.setTime(start.getTime() - 3600 * 1000 * 24 * 7)
  66. return [start, end]
  67. }
  68. },
  69. {
  70. text: '上个月',
  71. value: () => {
  72. const end = new Date()
  73. const start = new Date()
  74. start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
  75. return [start, end]
  76. }
  77. },
  78. {
  79. text: '近三个月',
  80. value: () => {
  81. const end = new Date()
  82. const start = new Date()
  83. start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
  84. return [start, end]
  85. }
  86. }
  87. ]
  88. // 选择的日期
  89. const selectDate = ref<Array<Date>>(shortcuts[0].value())
  90. // 日期变化
  91. const dateChange = (val: any) => {
  92. emits('changeDate', val)
  93. }
  94. // 平台变化
  95. const changePf = (val: any) => {
  96. emits('changePf', val)
  97. }
  98. // 控制日期范围
  99. /**
  100. * @description: 禁止选取今天之后的日期
  101. * @param {*} date
  102. * @return {*}
  103. */
  104. const disableDate = (time: Date) => {
  105. return time.getTime() > Date.now()
  106. }
  107. const breadcrumbList = reactive<
  108. Array<{
  109. title: string
  110. pathName: string
  111. }>
  112. >([])
  113. // 是否可点击
  114. const breadcrumbCanClick = computed(() => breadcrumbList.length > 1)
  115. // 返回总览
  116. const goBack = (index: number) => {
  117. if (breadcrumbCanClick) {
  118. router.push(breadcrumbList[index].pathName).then(() => {
  119. breadcrumbList.splice(index + 1, breadcrumbList.length - 1)
  120. })
  121. }
  122. }
  123. /**
  124. * @description: 添加导航栏的信息
  125. * @param {*} title 标题
  126. * @param {*} pathName 对应的路由name
  127. * @return {*}
  128. */
  129. const addPath = (title: string, pathName: string) => {
  130. breadcrumbList.push({ title, pathName })
  131. }
  132. /**
  133. * @description: 当跳转到其他页面的时候,就需要清除掉这里的面包屑导航
  134. * @return {*}
  135. */
  136. const clearBreadcrumb = () => {
  137. let nowName = router.currentRoute.value.name
  138. // 如果现在是第一个导航,那么清除掉,这个是为了当直接点击左侧导航栏进入table页的时候可以清空
  139. // 第二个条件是当切换到其他导航的时候,也给他清空掉
  140. if (
  141. nowName === breadcrumbList[0].pathName ||
  142. breadcrumbList.every((item) => item.pathName !== nowName)
  143. ) {
  144. breadcrumbList.splice(1, breadcrumbList.length - 1)
  145. }
  146. }
  147. const watchRoute = watch(
  148. () => [router.currentRoute.value],
  149. () => {
  150. clearBreadcrumb()
  151. },
  152. { deep: true }
  153. )
  154. if (!props.needBreadcrumb) watchRoute()
  155. defineExpose({
  156. addPath,
  157. clearBreadcrumb
  158. })
  159. onMounted(() => {
  160. breadcrumbList.push({
  161. title: props.title,
  162. pathName: router.currentRoute.value.name as string
  163. })
  164. dateChange(selectDate.value)
  165. })
  166. interface DropdownItem {
  167. value: string
  168. icon: string
  169. label: string
  170. isSelected: boolean
  171. }
  172. const selectInfo = reactive<Array<DropdownItem>>([
  173. {
  174. value: 'web',
  175. icon: '/img/platformIcon/web.svg',
  176. label: '网页',
  177. isSelected: true
  178. },
  179. {
  180. value: 'wx',
  181. icon: '/img/platformIcon/wx.svg',
  182. label: '微信',
  183. isSelected: false
  184. },
  185. {
  186. value: 'tt',
  187. icon: '/img/platformIcon/tt.svg',
  188. label: '抖音',
  189. isSelected: false
  190. }
  191. ])
  192. const changePlatForm = (val: Array<any>) => {
  193. emits('changePf', val)
  194. }
  195. watch(
  196. () => selectInfo,
  197. (newval) => {
  198. console.log('new')
  199. console.log(newval)
  200. }
  201. )
  202. </script>
  203. <template>
  204. <div class="headerCard">
  205. <p class="titleBox">
  206. <span
  207. @click="breadcrumbCanClick ? goBack(index) : ''"
  208. v-for="(item, index) in breadcrumbList"
  209. :class="[
  210. index === breadcrumbList.length - 1 ? 'activeCrumbs' : 'noActive',
  211. breadcrumbCanClick ? 'canClick' : 'unAble'
  212. ]"
  213. >
  214. <span v-if="index === 0" class="titleContent">
  215. {{ item.title }}
  216. </span>
  217. <span v-else>
  218. <span class="divLine">/</span>
  219. <span class="titleContent">{{ item.title }}</span>
  220. </span>
  221. </span>
  222. </p>
  223. <div class="selectBox" v-if="props.needPfSelect">
  224. <el-divider direction="vertical" />
  225. <div class="selectItem">
  226. <WithIconSelect @change-pf="changePlatForm" :slect-info="selectInfo"></WithIconSelect>
  227. <!-- <DropDownSelection
  228. @changeSelect="changePf"
  229. :defaultSelect="platFormOptionInfo.defaultSelect"
  230. :title="platFormOptionInfo.title"
  231. :optionsList="platFormOptionInfo.optionsList"
  232. ></DropDownSelection> -->
  233. </div>
  234. </div>
  235. <div v-if="props.openDateSelect" class="datePicker">
  236. <el-date-picker
  237. v-model="selectDate"
  238. :disabled-date="disableDate"
  239. :unlink-panels="false"
  240. @change="dateChange"
  241. type="daterange"
  242. range-separator="至"
  243. start-placeholder="Start date"
  244. end-placeholder="End date"
  245. :shortcuts="shortcuts"
  246. :size="'small'"
  247. >
  248. </el-date-picker>
  249. </div>
  250. </div>
  251. </template>
  252. <style scoped>
  253. .headerCard {
  254. box-sizing: border-box;
  255. width: 100%;
  256. height: 60px;
  257. display: flex;
  258. align-items: center;
  259. padding: 20px 24px;
  260. background-color: white;
  261. }
  262. .canClick {
  263. cursor: pointer;
  264. }
  265. .unAble {
  266. cursor: default;
  267. }
  268. .activeCrumbs {
  269. font-size: 18px;
  270. color: #17233d;
  271. font-weight: 600;
  272. }
  273. .noActive {
  274. font-size: 16px;
  275. color: rgba(23, 35, 61, 0.55);
  276. }
  277. .selectBox {
  278. display: inline-flex;
  279. }
  280. .selectItem {
  281. width: 50%;
  282. }
  283. .datePicker {
  284. display: inline-flex;
  285. align-items: center;
  286. /* 可以将他单独的右对齐 */
  287. margin-left: auto;
  288. }
  289. .dateItem {
  290. display: inline-block;
  291. width: 100%;
  292. height: 100%;
  293. border-radius: 4%;
  294. }
  295. .canSelect {
  296. background-color: #cce3f8;
  297. color: black;
  298. }
  299. .selected {
  300. background-color: #2d8cf0;
  301. }
  302. .disableSelect {
  303. color: #c7c9cc;
  304. background-color: white;
  305. }
  306. .disableSelect:hover {
  307. cursor: no-drop;
  308. }
  309. .divLine {
  310. margin: 0 5px;
  311. }
  312. </style>