123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 |
- <template>
- <div v-if="list.length" class="message-bg">
- <div class="message-main clickable">
- <!-- <div class="card-title">
- <span>最新消息</span>
- <span class="message-unread" v-if="msgData.unread > 0">
- {{ setUnRead }}
- </span>
- <div class="icon-box" @click="goMore">
- <AppIcon name="youbian" size="14" color="#c0c4cc" />
- </div>
- </div> -->
- <div ref="msgCard" class="message-card">
- <div
- class="message-group"
- :style="{
- transform: `translateY(-${offsetHeight}px)`,
- height: `${groupHeight}px`,
- }"
- >
- <div
- v-for="(item, index) in list"
- :key="index"
- ref="listItem"
- v-bound-phone="bindPhoneGoMessage(item)"
- class="message-item"
- :class="{ visited: item.visited }"
- @click="goMessage(item)"
- >
- <!-- <span class="dot"></span> -->
- <van-cell class="message-item-cell" is-link>
- <template #title>
- <span class="icon iconfont icon-nav_un_message" />
- <span class="type">{{ item.type }}</span>
- <span class="flex-1 title van-ellipsis">{{ item.title }}</span>
- </template>
- <template #default>
- <span class="time">{{ item.time }}</span>
- </template>
- </van-cell>
- <!-- <div class="van-ellipsis title">{{ item.title }}</div>
- <span class="time">{{ item.time }}</span> -->
- </div>
- </div>
- </div>
- </div>
- </div>
- </template>
- <script>
- import { Cell } from 'vant'
- import { mapGetters } from 'vuex'
- import {
- ajaxMarkRead,
- ajaxMessageList,
- ajaxMessageOpenLog
- } from '@/api/modules/message'
- import { AppIcon } from '@/ui'
- import { dateMatter } from '@/utils/date'
- import { appCallReloadTab } from '@/utils/callFn/appFn'
- import { callChangeTab, openLinkOfOther, px2viewport, vw2px } from '@/utils'
- // const MSG_TYPE = ['活动通知', '服务通知', '订阅消息', '项目动态', '企业动态', '分析报告', '系统通知', '剑鱼学堂', '商机情报']
- export default {
- name: 'MessageCard',
- components: {
- [AppIcon.name]: AppIcon,
- [Cell.name]: Cell
- },
- data() {
- return {
- list: [],
- msgData: {
- rollingTiming: 10
- },
- offsetHeight: 0,
- groupHeight: 20,
- msgListParams: {
- isColumn: true,
- isColumnNewMsg: false,
- isContainLetter: false,
- isMsgList: true,
- isRead: 0,
- offset: 1,
- size: 20
- }
- }
- },
- computed: {
- ...mapGetters('user', ['isLogin']),
- setUnRead() {
- return this.msgData.unread > 99 ? '99+' : this.msgData.unread
- },
- setHeight() {
- const height = !this.msgData.unread
- if (height) {
- return 70 / 3.75
- }
- else {
- return 76 / 3.75
- }
- }
- },
- created() {
- if (this.isLogin) {
- this.loadList()
- }
- },
- mounted() {
- setTimeout(() => {
- this.$nextTick(() => {
- this.startScrolling()
- })
- }, 1000)
- },
- destroyed() {
- this.stopScrolling()
- },
- methods: {
- decimalValue(numberValue) {
- // 将数值转换为字符串并截取前两位小数
- const decimalValue = numberValue.toString().match(/^\d+(?:\.\d?)?/)
- // 返回处理后的数值字符串
- return decimalValue ? decimalValue[0] : ''
- },
- startScrolling() {
- const offsetY = 20
- const offsetYvw = px2viewport(offsetY)
- const offsetYPx = vw2px(offsetYvw)
- let listItem
- if (this.$refs.listItem) {
- listItem = this.$refs.listItem[1] // 列表项高度
- }
- else {
- listItem = {
- offsetHeight: offsetYPx
- }
- }
- const listItemHeight = listItem?.offsetHeight || offsetYPx
- this.groupHeight = this.list.length * listItemHeight
- this.scrollInterval = setInterval(() => {
- this.offsetHeight += listItemHeight // 每次滚动的距离,根据需求调整
- if (-this.offsetHeight <= -(this.list.length * listItemHeight)) {
- this.offsetHeight = 0
- }
- }, this.msgData.rollingTiming * 1000) // 滚动间隔,单位为秒
- if (this.msgData.unread && this.msgData.unread <= 2) {
- this.stopScrolling()
- }
- },
- stopScrolling() {
- clearInterval(this.scrollInterval)
- },
- loadList() {
- ajaxMessageList(this.msgListParams).then((res) => {
- this.msgData = res
- let { data = [], column } = res
- if (!Array.isArray(data)) {
- data = []
- }
- if (!column) {
- column = []
- }
- this.list = [].concat(
- data.map((v) => {
- const MSG_TYPE = column.filter(m => m.msg_type === v.msg_type)
- return {
- title: v.title,
- visited: v.isRead === 1,
- time: dateMatter(v.createtime, 'nor'),
- type: MSG_TYPE && MSG_TYPE.length !== 0 ? MSG_TYPE[0].name : '',
- data: v
- }
- })
- )
- })
- },
- goVisited(item) {
- if (item.data.realType === 14) {
- this.$router.push({
- path: '/message/materialDetail',
- query: {
- id: Number(item.data.id),
- msgLogId: Number(item.data.msgLogId)
- }
- })
- }
- else {
- this.$router.push({
- path: '/message/msgDetail',
- query: {
- id: Number(item.data.id),
- msgLogId: Number(item.data.msgLogId)
- }
- })
- }
- },
- goMore() {
- callChangeTab('message', this.$router)
- },
- // 消息点击
- async onClickMsg(logId) {
- await ajaxMessageOpenLog({
- msgLogId: logId,
- platform: this.getPlatformType()
- })
- },
- getPlatformType() {
- return this.$envs.inWX ? 3 : 2
- },
- goMessage(item) {
- this.onClickMsg(item.data.msgLogId)
- if (item.visited) {
- return this.goVisited(item)
- }
- else {
- this.changeMessageStatus(item)
- }
- },
- changeMessageStatus(item) {
- ajaxMarkRead({
- msgId: Number(item.data.id)
- }).then(() => {
- // 刷新消息中心列表小红点
- this.msgLinkAction(item)
- appCallReloadTab('message', 1)
- // appCallReloadTab('search', 0)
- })
- },
- // 链接跳转
- async msgLinkAction(item) {
- const url = item.data.url
- const { inWX, inIOS } = this.$envs
- if (inWX) {
- if (url.weChatUrl) {
- this.wxLocationTo(url.weChatUrl)
- }
- else {
- this.goVisited(item)
- }
- }
- else {
- let toLink = inIOS ? url.iosUrl : url.androidUrl
- if (toLink) {
- const hasHttp = /^http(s)?:\/\//.test(toLink)
- if (!hasHttp && toLink[0] !== '/') {
- toLink = `/${toLink}`
- }
- openLinkOfOther(toLink)
- }
- else {
- this.goVisited(item)
- }
- }
- },
- // 微信端跳转
- wxLocationTo(url) {
- // 链接中如果是www.jianyu360.cn域名,微信中会唤起app,该用window.open
- // window.open(url)
- // window.open在安卓正常,但是ios无法跳转。改为location.href跳转
- if (!url)
- return
- location.href = url
- },
- bindPhoneGoMessage(item) {
- return {
- props: {
- name: '首页-消息列表'
- },
- next: () => {
- this.goMessage(item)
- }
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- .message-bg {
- background-color: #f5f6f7;
- padding: 12px 8px;
- }
- .message-main {
- position: relative;
- display: flex;
- flex-direction: column;
- justify-content: center;
- // padding: 6px 0 10px;
- height: 100%;
- background-color: #fff;
- border-radius: 12px;
- overflow: hidden;
- box-shadow: 0px 2px 8px rgba(54, 147, 179, 0.05);
- .card-title {
- display: flex;
- justify-content: space-between;
- align-items: center;
- position: relative;
- margin-bottom: 4px;
- font-size: 12px;
- line-height: 18px;
- color: #171826;
- padding: 0 12px;
- }
- .message-unread {
- line-height: 14px;
- padding: 1px 4px 0 4px;
- border-radius: 10px;
- background: #fb483d;
- color: #fff;
- font-size: 10px;
- margin-right: 16px;
- }
- }
- .message-card {
- display: flex;
- flex-direction: row;
- align-items: flex-start;
- justify-content: space-between;
- background-color: #ffffff;
- padding: 0 12px;
- height: 40px;
- overflow: hidden;
- &.have-one {
- align-items: center;
- }
- .message-group {
- //max-width: 315px;
- width: 100%;
- transition: transform 0.5s ease; /* 添加过渡效果 */
- }
- .message-item {
- display: flex;
- flex-direction: row;
- align-items: center;
- height: 40px;
- line-height: 18px;
- &-cell {
- padding: 0;
- line-height: normal;
- display: flex;
- align-items: center;
- }
- &.visited {
- .dot {
- background-color: #c0c4cc;
- }
- }
- .dot {
- flex-shrink: 0;
- width: 4px;
- height: 4px;
- border-radius: 50%;
- background: #2abed1;
- margin-right: 4px;
- }
- .type {
- flex-shrink: 0;
- font-weight: 700;
- font-size: 12px;
- line-height: 18px;
- color: #171826;
- margin-right: 12px;
- }
- .title {
- font-size: 11px;
- line-height: 24px;
- color: #171826;
- margin-right: 12px;
- }
- .time {
- flex-shrink: 0;
- font-size: 11px;
- line-height: 24px;
- color: #9b9ca3;
- }
- .icon-nav_un_message {
- margin-right: 4px;
- color: $color_main;
- }
- ::v-deep {
- .van-cell__title {
- display: flex;
- align-items: center;
- white-space: nowrap;
- overflow: hidden;
- text-overflow: ellipsis;
- }
- .van-cell__value {
- flex: unset;
- }
- .van-cell__right-icon {
- color: $color_main;
- font-size: 12px;
- line-height: 26px;
- }
- }
- }
- .icon-youbian {
- font-size: 16px;
- color: #c0c4cc;
- }
- }
- .icon-box {
- position: absolute;
- top: 53%;
- right: 12px;
- transform: translateY(-50%);
- z-index: 2;
- }
- </style>
|