完成短信列表样式

This commit is contained in:
tangxinyue 2026-03-11 18:31:57 +08:00
parent 21c79178fd
commit eefe793b8f
28 changed files with 1298 additions and 219 deletions

View File

@ -261,6 +261,7 @@
} }
.flex-column { .flex-column {
display: flex;
flex-direction: column; flex-direction: column;
} }

View File

@ -0,0 +1,275 @@
<template>
<view class="page-container flex-column" :class="`${phone}-style`">
<view class="status-placeholder w100" :style="{ height: `${data.statusBarHeight}px` }"></view>
<view class="top-box">
<slot name="top">
<view class="top-container">
<view class="flex-align-center flex-justify-between">
<view class="left flex-align-center">
<image @click="util.goBack()" :src="`/static/image/phone-message/${phone}/back.png`">
</image>
<view class="number-box">256</view>
</view>
<view class="center">
<image class="img shrink-0"
:src="chatInfo.img || `/static/image/phone-message/${phone}/default.png`">
</image>
</view>
<view class="right"></view>
</view>
<view class="text-box flex-align-center flex-justify-center">
<text class="title">{{ chatInfo.title }}</text>
<uni-icons type="right" size="10" color="#D8D8D8"></uni-icons>
</view>
</view>
</slot>
</view>
<view class="center-box flex-1">
<slot></slot>
</view>
<view class="bottom-box">
<slot name="bottom">
<view class="right-container flex-align-center">
<image class="add-img shrink-0" :src="`/static/image/phone-message/${phone}/chat-left.png`"></image>
<view class="search-box flex-1 flex-align-center">
<input class="input flex-1" placeholder="信息 · 短信" type="text">
<image v-if="phone == 'iphone'" class="right-icon"
src="/static/image/phone-message/iphone/mic.png"></image>
</view>
<view v-if="phone != 'iphone'">
<image class="right-icon" src="/static/image/phone-message/mi/mic.png"></image>
</view>
</view>
</slot>
</view>
</view>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue'
import { onLoad, onPageScroll } from "@dcloudio/uni-app";
import { stringUtil, util } from '@/utils/common.js';
const props = defineProps({
//
phone: {
type: String,
default: 'iphone'
},
chatInfo: {
type: Object,
default: {
unRead: false,
noNotice: false,
img: "",
title: "淘宝通知",
content: "您关注的商品降价啦,快来抢购吧!",
time: "2026-02-20 20:55:12"
}
}
})
const data = reactive({
statusBarHeight: 0,
})
onMounted(() => {
//
const systemInfo = uni.getSystemInfoSync();
data.statusBarHeight = systemInfo.statusBarHeight || 0;
})
</script>
<style>
@import '@/common/main.css';
</style>
<style lang="less" scoped>
.page-container {
width: 100vw;
height: 100vh;
background-color: #fff;
}
//
.iphone-style {
.top-box {
.top-container {
padding: 32rpx 24rpx 20rpx;
background-color: #F7F7F7;
border-bottom: 0.5px solid #B5B5B5;
.left {
width: 180rpx;
image {
width: 40rpx;
height: 40rpx;
}
.number-box {
height: 36rpx;
font-size: 24rpx;
line-height: 24rpx;
padding: 6rpx 10rpx;
border-radius: 18rpx;
color: #fff;
background-color: #0276FF;
margin-left: 4rpx;
}
}
.center {
.img {
width: 96rpx;
height: 96rpx;
}
}
.right {
width: 180rpx;
}
.text-box {
.title {
font-size: 20rpx;
color: #1A1A1A;
left: 20rpx;
margin-right: 6rpx;
}
}
}
}
.right-container {
padding: 10rpx 28rpx;
.add-img {
width: 66rpx;
height: 66rpx;
margin-right: 24rpx;
}
.search-box {
height: 70rpx;
border-radius: 35rpx 35rpx 35rpx 35rpx;
border: 2rpx solid #DFDFDF;
padding: 0 26rpx;
.input {
::v-deep .input-placeholder {
color: #C3C3C3;
font-size: 32rpx;
line-height: 32rpx;
}
}
.right-icon {
width: 32rpx;
height: 32rpx;
margin-left: 20rpx;
}
}
}
}
//
.mi-style {
.top-box {
.top-container {
padding: 32rpx 24rpx 20rpx;
background-color: #F7F7F7;
border-bottom: 0.5px solid #B5B5B5;
.left {
width: 180rpx;
image {
width: 40rpx;
height: 40rpx;
}
.number-box {
height: 36rpx;
font-size: 24rpx;
line-height: 24rpx;
padding: 6rpx 10rpx;
border-radius: 18rpx;
color: #fff;
background-color: #0276FF;
margin-left: 4rpx;
}
}
.center {
.img {
width: 96rpx;
height: 96rpx;
}
}
.right {
width: 180rpx;
}
.text-box {
.title {
font-size: 20rpx;
color: #1A1A1A;
left: 20rpx;
margin-right: 6rpx;
}
}
}
}
.bottom-box {
.right-container {
padding: 10rpx 28rpx;
.add-img {
width: 66rpx;
height: 66rpx;
margin-right: 24rpx;
}
.search-box {
height: 70rpx;
border-radius: 35rpx 35rpx 35rpx 35rpx;
border: 2rpx solid #DFDFDF;
padding: 0 26rpx;
.input {
::v-deep .input-placeholder {
color: #C3C3C3;
font-size: 32rpx;
line-height: 32rpx;
}
}
.right-icon {
width: 32rpx;
height: 32rpx;
margin-left: 20rpx;
}
}
.right-icon {
width: 72rpx;
height: 72rpx;
}
}
}
}
</style>

View File

@ -1,145 +0,0 @@
<template>
<view :style="`${phone}-style`">
<uni-swipe-action class="swipe-action">
<!-- 使用插槽 请自行给定插槽内容宽度-->
<uni-swipe-action-item>
<view>
<view class="item flex-align-center">
<view class="dot"></view>
<image class="img shrink-0" :src="`/static/image/phone-message/${phone}/default.png`"></image>
<view class="border-box m-l-24 flex-1 flex flex-align-start">
<view class="main-box flex-1">
<view class="title-box flex-between">
<text class="title">title</text>
<text class="time">昨天</text>
</view>
<view class="content">市燃管办温馨提示依法安全文明燃放烟花爆竹共护平安幸福家园呵呵哈哈哈还好...</view>
</view>
<view class="box-right h100 flex-column flex-align-center">
<uni-icons type="right" size="14" color="#C1C1C1"></uni-icons>
<image class="img" src="/static/image/phone-message/iphone/notice.png"></image>
</view>
</view>
</view>
</view>
<template v-slot:right>
<view><text>删除</text></view>
</template>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
</template>
<script setup>
import {
ref,
reactive,
computed
} from 'vue'
import {
util
} from '@/utils/common.js';
const props = defineProps({
//
phone: {
type: String,
default: 'iphone'
}
})
</script>
<style>
@import '@/common/main.css';
</style>
<style lang="less" scoped>
.m-t-4 {
margin-top: 4rpx;
}
.m-l-24 {
margin-left: 24rpx;
}
.iphone-style {
.swipe-action {
margin-top: 24rpx;
}
.item:first-child {
.border-box {
position: relative;
}
.border-box::before {
position: absolute;
content: '';
width: 100%;
height: 1px;
top: -1px;
left: 0;
right: 0;
box-shadow: 0 0.3px 0 0 #C2C2C2;
}
}
.item {
padding: 0 0 0 14rpx;
height: 146rpx;
.dot {
width: 20rpx;
height: 20rpx;
background-color: #007BFD;
border-radius: 50%;
}
.img {
width: 84rpx;
height: 84rpx;
margin-left: 16rpx;
}
.border-box {
padding: 18rpx 14rpx 14rpx 0;
height: 100%;
box-shadow: inset 0 -0.3px 0 0 #C2C2C2;
}
.main-box {
.title-box {
margin-bottom: 6rpx;
.title {
color: #1A1A1A;
font-size: 32rpx;
line-height: 32rpx;
}
.time {
color: #838383;
font-size: 28rpx;
line-height: 28rpx;
}
}
.content {
font-size: 28rpx;
line-height: 38rpx;
color: #838383;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
.box-right {
.img {
width: 28rpx;
height: 28rpx;
margin: 0;
}
}
}
}
</style>

View File

@ -0,0 +1,717 @@
<template>
<view :style="`${phone}-style`">
<uni-swipe-action class="swipe-action">
<!-- 使用插槽 请自行给定插槽内容宽度-->
<uni-swipe-action-item class="swipe-action-item" v-for="(item, index) in list" :key="item.id">
<view class="flex flex-align-center " @click="clickItem(item)">
<view class="item flex w100">
<view class="flex flex-align-center left-box">
<view :class="{ 'opacity-0': !item.unRead }" class="dot shrink-0"><text
v-if="phone == 'huawei' || phone == 'oppo'">{{ item.unReadNumber
> 99
? '99+' : (item.unReadNumber || 1) }}</text>
</view>
<image class="img shrink-0"
:src="item.img || `/static/image/phone-message/${phone}/default.png`">
</image>
</view>
<view class="border-box m-l-24 flex-1 flex flex-align-start">
<view class="main-box flex-1">
<view class="title-box flex-between">
<text class="title">{{ item.title }}</text>
<text class="time">{{ formatDate(item.time) }}</text>
</view>
<view class="content">{{ item.content }}</view>
</view>
<view class="box-right h100 flex-column flex-align-center">
<image v-if="phone == 'iphone'" class="m-t-4"
src="/static/image/phone-message/iphone/right.png"></image>
<image v-if="item.noNotice && phone == 'iphone'" class="m-t-8"
src="/static/image/phone-message/iphone/notice.png"></image>
</view>
</view>
</view>
</view>
<template v-slot:right>
<view class="flex flex-align-center" style="margin-left: 1px;">
<view v-if="phone == 'iphone'" class="btn flex-center flex-align-center edit">
<image src="/static/image/phone-message/iphone/mute.png"></image>
</view>
<view class="btn flex-center flex-align-center delete">
<image
:src="`/static/image/phone-message/${phone == 'huawei' || phone == 'vivo' ? 'huawei' : 'iphone'}/delete.png`">
</image>
</view>
</view>
</template>
</uni-swipe-action-item>
</uni-swipe-action>
</view>
</template>
<script>
import { stringUtil } from '@/utils/common.js';
const defaultList = [
{
id: stringUtil.uuid(),
unRead: true,
unReadNumber: 100,
noNotice: true,
img: "",
title: "系统通知",
content: "您的账户于今日 08:30 在异地登录,请确认是否为本人操作。",
time: "2026-03-11 08:31:00"
},
{
id: stringUtil.uuid(),
unRead: true,
noNotice: true,
img: "",
title: "12306",
content: "市燃管办温馨提示:依法安全文明燃放烟花爆竹,共护平安幸福家园呵呵哈哈哈还好共护平安幸福家园呵呵哈哈哈还好",
time: "2026-03-10 14:30:00"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: false,
img: "",
title: "支付宝支付",
content: "支付成功您在XX超市消费了 45.00 元。",
time: "2026-03-10 18:20:15"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: false,
img: "",
title: "花呗提醒",
content: "本月账单已出,请在 9 号前还款,避免逾期记录。",
time: "2026-03-09 09:00:00"
},
{
id: stringUtil.uuid(),
unRead: true,
noNotice: false,
img: "",
title: "顺丰速运",
content: "您的快递已到达XX驿站凭取件码 8899 取件。",
time: "2026-03-01 10:15:22"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: true,
img: "",
title: "蚂蚁森林",
content: "您的好友偷走了你 5g 绿色能量,快去看看吧!",
time: "2026-02-28 07:45:10"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: false,
img: "",
title: "余额宝",
content: "昨日收益已到账,恭喜您获得收益 0.58 元。",
time: "2026-02-27 06:30:00"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: false,
img: "",
title: "10086",
content: "【流量使用提示】您本月的套餐流量已使用达 80%,请注意余额。",
time: "2026-02-26 15:10:45"
},
{
id: stringUtil.uuid(),
unRead: true,
noNotice: false,
img: "",
title: "饿了么",
content: "您的外卖已送达,祝您用餐愉快,别忘了给骑手五星好评哦~",
time: "2026-02-25 12:40:33"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: false,
img: "",
title: "淘宝通知",
content: "您关注的商品降价啦,快来抢购吧!",
time: "2026-02-20 20:55:12"
}
]
</script>
<script setup>
import {
ref,
reactive,
computed
} from 'vue'
import {
util,
dateUtil
} from '@/utils/common.js';
//
const emit = defineEmits(['item-click'])
const props = defineProps({
//
phone: {
type: String,
default: 'iphone'
},
list: {
type: Array,
default: () => defaultList
}
})
/**
* 时间日期格式化判断
* @param date
*/
const formatDate = (date) => {
if (props.phone == 'oppo') {
return dateUtil.formatMessageTime(date, true)
} else if (props.phone == 'huawei') {
return dateUtil.formatMessageTime(date, true, 'YYYY年M月D日')
} else if (props.phone == 'vivo') {
let d = date;
if (typeof d === 'string') {
d = new Date(d.replace(/-/g, '/'));
} else if (typeof d === 'number') {
d = new Date(d);
}
const isCurrentYear = d.getFullYear() === new Date().getFullYear();
return dateUtil.formatMessageTime(date, true, isCurrentYear ? 'M月D日' : 'YYYY/M/D')
} else {
return dateUtil.formatMessageTime(date)
}
}
/**
* 点击列表元素
*/
const clickItem = (item) => {
emit('item-click', item)
}
</script>
<style>
@import '@/common/main.css';
</style>
<style lang="less" scoped>
.m-t-4 {
margin-top: 4rpx;
}
.m-t-8 {
margin-top: 8rpx;
}
.m-l-24 {
margin-left: 24rpx;
}
.opacity-0 {
opacity: 0;
}
.swipe-action-item {
background-color: #FFFFFF;
}
//
.iphone-style {
.swipe-action {
margin-top: 28rpx;
}
.swipe-action-item:first-child {
.border-box {
position: relative;
}
.border-box::before {
position: absolute;
content: '';
width: 100%;
height: 1px;
top: 0;
left: 0;
right: 0;
background-color: #D8D8D8;
transform: scaleY(0.3);
}
}
.item {
padding: 0 0 0 14rpx;
height: 146rpx;
align-items: center;
.dot {
width: 20rpx;
height: 20rpx;
background-color: #007BFD;
border-radius: 50%;
}
.img {
width: 84rpx;
height: 84rpx;
margin-left: 16rpx;
}
.border-box {
position: relative;
padding: 18rpx 14rpx 14rpx 0;
height: 100%;
// box-shadow: inset 0 -0.3px 0 0 #D8D8D8;
}
.border-box::after {
position: absolute;
content: '';
width: 100%;
height: 1px;
bottom: 0;
left: 0;
right: 0;
background-color: #D8D8D8;
transform: scaleY(0.3);
}
.main-box {
.title-box {
margin-bottom: 6rpx;
.title {
color: #1A1A1A;
font-size: 32rpx;
line-height: 32rpx;
font-weight: 600;
}
.time {
color: #838383;
font-size: 28rpx;
line-height: 28rpx;
}
}
.content {
font-size: 28rpx;
line-height: 38rpx;
color: #838383;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
.box-right {
image {
width: 28rpx;
height: 28rpx;
}
}
}
.btn {
width: 140rpx;
height: 146rpx;
image {
width: 48rpx;
height: 48rpx;
}
}
.delete {
background-color: #FC3E30;
}
.edit {
background-color: #5855D6;
}
}
//
.mi-style {
.item {
padding-top: 44rpx;
height: 170rpx;
.left-box {
position: relative;
height: 40px;
align-items: flex-start;
padding-left: 54rpx;
}
.dot {
position: absolute;
width: 20rpx;
height: 20rpx;
background-color: #FA3D30;
border-radius: 50%;
left: 16rpx;
top: 50%;
transform: translateY(-50%);
}
.img {
width: 76rpx;
height: 76rpx;
}
.border-box {
position: relative;
padding: 4rpx 52rpx 8rpx 0;
margin-left: 22rpx;
height: 100%;
}
.main-box {
.title-box {
margin-bottom: 6rpx;
.title {
color: #1A1A1A;
font-size: 32rpx;
line-height: 32rpx;
}
.time {
color: #9A9A9A;
font-size: 26rpx;
line-height: 28rpx;
}
}
.content {
font-size: 26rpx;
line-height: 38rpx;
color: #656565;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
.box-right {
image {
width: 28rpx;
height: 28rpx;
}
}
}
.btn {
width: 140rpx;
height: 146rpx;
image {
width: 48rpx;
height: 48rpx;
}
}
.delete {
background-color: #FC3E30;
}
.edit {
background-color: #5855D6;
}
}
// oppo
.oppo-style {
.item {
padding-top: 28rpx;
height: 178rpx;
.left-box {
position: relative;
height: 40px;
align-items: flex-start;
padding-left: 34rpx;
}
.dot {
position: absolute;
padding: 4rpx 10rpx;
background-color: #E93A22;
color: #FFFFFF;
line-height: 20rpx;
font-size: 20rpx;
border-radius: 16rpx;
right: -8rpx;
top: -4rpx;
z-index: 1;
border: 2rpx solid #FFFFFF;
}
.img {
width: 76rpx;
height: 76rpx;
}
.border-box {
position: relative;
padding: 4rpx 34rpx 28rpx 0;
margin-left: 32rpx;
height: 100%;
}
.main-box {
.title-box {
margin-bottom: 16rpx;
.title {
color: #1A1A1A;
font-size: 32rpx;
line-height: 32rpx;
font-weight: 500;
}
.time {
color: #656565;
font-size: 26rpx;
line-height: 28rpx;
}
}
.content {
font-size: 28rpx;
line-height: 38rpx;
color: #737373;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
.box-right {
image {
width: 28rpx;
height: 28rpx;
}
}
}
.btn {
width: 140rpx;
height: 146rpx;
image {
width: 48rpx;
height: 48rpx;
}
}
.delete {
background-color: #FC3E30;
}
}
//
.huawei-style {
.item {
padding: 0 32rpx;
height: 156rpx;
align-items: center;
.left-box {
position: relative;
height: 40px;
align-items: flex-start;
}
.dot {
position: absolute;
padding: 6rpx 10rpx;
background-color: #E93A22;
color: #FFFFFF;
line-height: 20rpx;
font-size: 20rpx;
border-radius: 16rpx;
right: -8rpx;
top: -12rpx;
z-index: 1;
}
.img {
width: 76rpx;
height: 76rpx;
}
.border-box {
padding: 18rpx 0;
position: relative;
margin-left: 30rpx;
margin-top: 2rpx;
height: 100%;
box-shadow: 0 -0.3px 0 0 #CFCFCF;
}
// .border-box::after {
// position: absolute;
// content: '';
// width: 100%;
// height: 1px;
// bottom: 0;
// left: 0;
// right: 0;
// background-color: #CFCFCF;
// transform: scaleY(0.3);
// }
.main-box {
.title-box {
margin-bottom: 6rpx;
.title {
color: #1A1A1A;
font-size: 32rpx;
line-height: 32rpx;
font-weight: 500;
}
.time {
color: #656565;
font-size: 24rpx;
line-height: 28rpx;
}
}
.content {
font-size: 28rpx;
line-height: 38rpx;
color: #6F6F6F;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
.box-right {
image {
width: 28rpx;
height: 28rpx;
}
}
}
.btn {
width: 140rpx;
height: 156rpx;
image {
width: 76rpx;
height: 76rpx;
}
}
.delete {
background-color: #F4F4F4;
}
}
// vivo
.vivo-style {
.item {
padding: 0 50rpx 0 24rpx;
height: 172rpx;
align-items: center;
.dot {
width: 12rpx;
height: 12rpx;
background-color: #409DFE;
border-radius: 50%;
flex-shrink: 0;
margin-right: 10rpx;
}
.img {
width: 80rpx;
height: 80rpx;
}
.border-box {
padding: 28rpx 0 18rpx;
position: relative;
margin-left: 24rpx;
margin-top: 2rpx;
height: 100%;
}
.main-box {
.title-box {
margin-bottom: 18rpx;
.title {
color: #1A1A1A;
font-size: 32rpx;
line-height: 32rpx;
font-weight: 500;
}
.time {
color: #7C7C7C;
font-size: 26rpx;
line-height: 26rpx;
}
}
.content {
font-size: 28rpx;
line-height: 38rpx;
color: #6F6F6F;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
}
}
.box-right {
image {
width: 28rpx;
height: 28rpx;
}
}
}
.btn {
width: 140rpx;
height: 156rpx;
image {
width: 76rpx;
height: 76rpx;
}
}
.delete {
background-color: #F4F4F4;
}
}
</style>

View File

@ -1,7 +1,8 @@
<template> <template>
<view :class="`${phone}-style`"> <view :class="`${phone}-style`">
<!-- 导航样式 --> <!-- 导航样式 -->
<NavBar :isBack="false"> <view class="nav-bar-box" :class="{ 'border-nav-bar-box': isScroll }">
<NavBar :isBack="false" :bgColor="isScroll ? data.navBar.bgColor : '#fff'">
<!-- 左侧文字图标 --> <!-- 左侧文字图标 -->
<template v-slot:left> <template v-slot:left>
<view v-if="phone == 'iphone'" class="flex flex-align-center"> <view v-if="phone == 'iphone'" class="flex flex-align-center">
@ -23,8 +24,10 @@
<template v-slot:right> <template v-slot:right>
<!-- iphone --> <!-- iphone -->
<view v-if="phone == 'iphone'"> <view v-if="phone == 'iphone'">
<image class="right-icon mg-r-30" src="/static/image/phone-message/iphone/more.png" mode=""></image> <image class="right-icon mg-r-30" src="/static/image/phone-message/iphone/more.png" mode="">
<image class="right-icon mg-r-5" src="/static/image/phone-message/iphone/edit.png" mode=""></image> </image>
<image class="right-icon mg-r-5" src="/static/image/phone-message/iphone/edit.png" mode="">
</image>
</view> </view>
<!-- mi --> <!-- mi -->
<view v-if="phone == 'mi'"> <view v-if="phone == 'mi'">
@ -32,13 +35,15 @@
</view> </view>
<!-- oppo --> <!-- oppo -->
<view v-if="phone == 'oppo'"> <view v-if="phone == 'oppo'">
<image class="right-icon mg-r-52" src="/static/image/phone-message/oppo/search.png" mode=""></image> <image class="right-icon mg-r-52" src="/static/image/phone-message/oppo/search.png" mode="">
<image class="right-icon mg-r-14" src="/static/image/phone-message/oppo/more.png" mode=""></image> </image>
<image class="right-icon mg-r-14" src="/static/image/phone-message/oppo/more.png" mode="">
</image>
</view> </view>
<!-- huawei --> <!-- huawei -->
<view v-if="phone == 'huawei'"> <view v-if="phone == 'huawei'">
<image v-if="isScroll" class="right-icon" src="/static/image/phone-message/huawei/nav-search.png" <image v-if="isScroll" class="right-icon"
mode=""> src="/static/image/phone-message/huawei/nav-search.png" mode="">
</image> </image>
<image class="right-icon" src="/static/image/phone-message/huawei/add.png" mode=""></image> <image class="right-icon" src="/static/image/phone-message/huawei/add.png" mode=""></image>
<image class="right-icon" src="/static/image/phone-message/huawei/more.png" mode=""></image> <image class="right-icon" src="/static/image/phone-message/huawei/more.png" mode=""></image>
@ -48,10 +53,13 @@
<image class="right-icon" src="/static/image/phone-message/vivo/select.png" mode=""> <image class="right-icon" src="/static/image/phone-message/vivo/select.png" mode="">
</image> </image>
<image class="right-icon" src="/static/image/phone-message/vivo/add.png" mode=""></image> <image class="right-icon" src="/static/image/phone-message/vivo/add.png" mode=""></image>
<image class="right-icon m-r-34" src="/static/image/phone-message/vivo/more.png" mode=""></image> <image class="right-icon m-r-34" src="/static/image/phone-message/vivo/more.png" mode="">
</image>
</view> </view>
</template> </template>
</NavBar> </NavBar>
</view>
<!-- 主体内容 --> <!-- 主体内容 -->
<view class="main-container"> <view class="main-container">
<!-- 顶部搜索栏样式 --> <!-- 顶部搜索栏样式 -->
@ -68,6 +76,7 @@
<slot> <slot>
</slot> </slot>
</view> </view>
<view class="bottom-placeholder"></view>
<!-- 底部样式 --> <!-- 底部样式 -->
<template v-if="phone == 'mi' || phone == 'oppo'"> <template v-if="phone == 'mi' || phone == 'oppo'">
<image class="add-message" :src="`/static/image/phone-message/${props.phone}/add-message.png`"></image> <image class="add-message" :src="`/static/image/phone-message/${props.phone}/add-message.png`"></image>
@ -110,6 +119,14 @@ const props = defineProps({
} }
}) })
const data = reactive({
navBar: {
title: '信息',
bgColor: '#FFFFFF',
}
})
// //
const showInfo = computed(() => { const showInfo = computed(() => {
let text, placeholder, secondText, bottomLtext, bottomRtext let text, placeholder, secondText, bottomLtext, bottomRtext
@ -117,6 +134,7 @@ const showInfo = computed(() => {
case "iphone": case "iphone":
text = "信息" text = "信息"
placeholder = '搜索' placeholder = '搜索'
data.navBar.bgColor = '#F8F8F8'
break; break;
case "mi": case "mi":
text = "主要" text = "主要"
@ -144,12 +162,6 @@ const showInfo = computed(() => {
return { text, placeholder, secondText, bottomLtext, bottomRtext } return { text, placeholder, secondText, bottomLtext, bottomRtext }
}) })
const data = reactive({
navBar: {
title: '信息',
bgColor: '#FFFFFF',
}
})
</script> </script>
<style> <style>
@ -177,6 +189,7 @@ page {
height: 120rpx; height: 120rpx;
border-top: 1rpx solid #E7E7E7; border-top: 1rpx solid #E7E7E7;
background-color: #ffffff; background-color: #ffffff;
z-index: 9;
.item { .item {
display: flex; display: flex;
@ -231,6 +244,12 @@ page {
color: #1a1a1a; color: #1a1a1a;
} }
.border-nav-bar-box {
::v-deep .nav-bar {
border-bottom: 1rpx solid #B5B5B5;
}
}
.main-container { .main-container {
.top-box { .top-box {
padding: 20rpx 32rpx 0; padding: 20rpx 32rpx 0;
@ -239,6 +258,7 @@ page {
color: #1A1A1A; color: #1A1A1A;
font-size: 64rpx; font-size: 64rpx;
font-weight: 700; font-weight: 700;
line-height: 72rpx;
} }
.search-box { .search-box {
@ -318,6 +338,10 @@ page {
height: 120rpx; height: 120rpx;
} }
.bottom-placeholder {
height: 120rpx;
width: 100%;
}
} }
@ -359,6 +383,12 @@ page {
right: 46rpx; right: 46rpx;
} }
.bottom-placeholder {
height: 148rpx;
width: 100%;
}
.bottom-box { .bottom-box {
height: 148rpx; height: 148rpx;
background-color: #FAFAFA; background-color: #FAFAFA;
@ -403,6 +433,12 @@ page {
margin: 0 8rpx; margin: 0 8rpx;
} }
.border-nav-bar-box {
::v-deep .nav-bar {
border-bottom: 1rpx solid #D1D1D1;
}
}
.main-container { .main-container {

View File

@ -27,7 +27,7 @@ export function createApp() {
const systemInfo = uni.getStorageSync('systemInfo') || {} const systemInfo = uni.getStorageSync('systemInfo') || {}
app.config.globalProperties.$system = systemInfo.platform == 'ios' ? 'iOS' : 'Android' app.config.globalProperties.$system = systemInfo.platform == 'ios' ? 'iOS' : 'Android'
app.config.globalProperties.$systemInfo = systemInfo app.config.globalProperties.$systemInfo = systemInfo
uni.setStorageSync('version', '1.0.3.sp1') uni.setStorageSync('version', '1.0.3.sp2')
app.config.globalProperties.$version = uni.getStorageSync('version') app.config.globalProperties.$version = uni.getStorageSync('version')
app.use(globalMethods); app.use(globalMethods);

View File

@ -28,7 +28,15 @@
"navigationBarTitleText": "短信列表首页", "navigationBarTitleText": "短信列表首页",
"navigationStyle": "custom" "navigationStyle": "custom"
} }
}] },
{
"path": "chat-page/chat-page",
"style": {
"navigationBarTitleText": "短信聊天页面",
"navigationStyle": "custom"
}
}
]
}, },
{ {
"root": "pages/balance", "root": "pages/balance",

View File

@ -0,0 +1,36 @@
<template>
<view>
<ChatLayout :phone="data.phone" :chatInfo="data.data"></ChatLayout>
</view>
</template>
<script setup>
import ChatLayout from '@/components/message/chat/chat-layout.vue'
import {
ref,
reactive
} from 'vue'
import {
onLoad,
onPageScroll
} from "@dcloudio/uni-app";
import {
stringUtil,
util
} from '@/utils/common.js';
const data = reactive({
phone: "iphone",
data: {}
})
onLoad((options) => {
console.log(options)
if (options.phone) {
data.phone = options.phone
}
if (options.data) {
data.data = JSON.parse(options.data)
}
})
</script>
<style lang="less"></style>

View File

@ -1,17 +1,14 @@
<template> <template>
<view> <view>
<MessageNavBar :phone="data.phone" :isScroll="data.isScroll"> <MessageNavBar :phone="data.phone" :isScroll="data.isScroll">
<!-- <view v-for="index in 100">{{ index }}</view> --> <MessageList :phone="data.phone" :list="defaultList" @item-click="itemClick"></MessageList>
<!-- <List :phone="data.phone"></List> -->
<MessageList></MessageList>
</MessageNavBar> </MessageNavBar>
</view> </view>
</template> </template>
<script setup> <script setup>
import MessageNavBar from '@/components/message/message-nav-bar.vue' import MessageNavBar from '@/components/message/list/message-nav-bar.vue'
import MessageList from '@/components/message/list.vue' import MessageList from '@/components/message/list/list.vue'
import { import {
ref, ref,
reactive reactive
@ -21,9 +18,103 @@ import {
onPageScroll onPageScroll
} from "@dcloudio/uni-app"; } from "@dcloudio/uni-app";
import { import {
stringUtil,
util util
} from '@/utils/common.js'; } from '@/utils/common.js';
import List from '@/components/call-log/list/list.vue';
const defaultList = [
{
id: stringUtil.uuid(),
unRead: true,
unReadNumber: 100,
noNotice: true,
img: "",
title: "系统通知",
content: "您的账户于今日 08:30 在异地登录,请确认是否为本人操作。",
time: "2026-03-11 08:31:00"
},
{
id: stringUtil.uuid(),
unRead: true,
noNotice: true,
img: "",
title: "12306",
content: "市燃管办温馨提示:依法安全文明燃放烟花爆竹,共护平安幸福家园呵呵哈哈哈还好共护平安幸福家园呵呵哈哈哈还好",
time: "2026-03-10 14:30:00"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: false,
img: "",
title: "支付宝支付",
content: "支付成功您在XX超市消费了 45.00 元。",
time: "2026-03-10 18:20:15"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: false,
img: "",
title: "花呗提醒",
content: "本月账单已出,请在 9 号前还款,避免逾期记录。",
time: "2026-03-09 09:00:00"
},
{
id: stringUtil.uuid(),
unRead: true,
noNotice: false,
img: "",
title: "顺丰速运",
content: "您的快递已到达XX驿站凭取件码 8899 取件。",
time: "2026-03-01 10:15:22"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: true,
img: "",
title: "蚂蚁森林",
content: "您的好友偷走了你 5g 绿色能量,快去看看吧!",
time: "2026-02-28 07:45:10"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: false,
img: "",
title: "余额宝",
content: "昨日收益已到账,恭喜您获得收益 0.58 元。",
time: "2026-02-27 06:30:00"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: false,
img: "",
title: "10086",
content: "【流量使用提示】您本月的套餐流量已使用达 80%,请注意余额。",
time: "2026-02-26 15:10:45"
},
{
id: stringUtil.uuid(),
unRead: true,
noNotice: false,
img: "",
title: "饿了么",
content: "您的外卖已送达,祝您用餐愉快,别忘了给骑手五星好评哦~",
time: "2026-02-25 12:40:33"
},
{
id: stringUtil.uuid(),
unRead: false,
noNotice: false,
img: "",
title: "淘宝通知",
content: "您关注的商品降价啦,快来抢购吧!",
time: "2026-02-20 20:55:12"
}
]
const data = reactive({ const data = reactive({
navBar: { navBar: {
@ -61,6 +152,10 @@ onPageScroll((e) => {
} }
}) })
const itemClick = (item) => {
util.goPage(`/pages/message/chat-page/chat-page?phone=${data.phone}&data=${JSON.stringify(item)}`)
}
</script> </script>
<style> <style>

View File

@ -525,9 +525,7 @@ const showFristAndLastNumber = (str) => {
.section_4 { .section_4 {
filter: drop-shadow(0rpx 10rpx 10rpx #00000008); filter: drop-shadow(0rpx 10rpx 10rpx #00000008);
background-image: url('https://ide.code.fun/api/image?token=69ae28bb97ce8400118178f6&name=ce4aca9097cf1d57763cc647764b458d.png'); background-color: #fff;
background-size: 100% 100%;
background-repeat: no-repeat;
.group_5 { .group_5 {
padding-bottom: 32rpx; padding-bottom: 32rpx;

View File

@ -341,7 +341,7 @@ page {
border-radius: 25rpx; border-radius: 25rpx;
width: 106rpx; width: 106rpx;
height: 50rpx; height: 50rpx;
border: solid 0.5px #28c2dd; border: solid 1rpx #28c2dd;
.text_6 { .text_6 {
color: #28c2dd; color: #28c2dd;

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 818 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 821 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 983 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -104,6 +104,64 @@ export const dateUtil = {
const day = String(date.getDate()).padStart(2, '0'); const day = String(date.getDate()).padStart(2, '0');
return `${month}-${day} ${timeStr}`; return `${month}-${day} ${timeStr}`;
} }
},
/**
* 仿支付宝消息列表时间格式化
* 今天: 原样不显示 (或者按需可显示 HH:mm) 但根据你的图示只有 昨天/星期/日期
* 昨天: 返回 "昨天"
* 近一周内且不是今天昨天: 返回 "星期X"
* 超过一周: 按照 format 返回 (或根据 hideCurrentYear 决定当年是否隐藏年份)
* @param {Date|string|number} date - 日期对象或时间戳
* @param {boolean} hideCurrentYear - 是否在当年隐藏年份默认为 true
* @param {string} format - 自定义日期格式默认为 'YYYY/M/D' (支持 YYYY, MM, M, DD, D )
* @returns {string} 格式化后的时间字符串
*/
formatMessageTime(date, hideCurrentYear = false, format = 'YYYY/M/D') {
if (!date) return '';
if (typeof date === 'string' || typeof date === 'number') {
// 兼容 iOS 的 YYYY-MM-DD 解析
if (typeof date === 'string') {
date = date.replace(/-/g, '/');
}
date = new Date(date);
}
const now = new Date();
// 将时分秒抹零,只取日期部分进行比对
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
const targetDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
const diffDays = Math.floor((today.getTime() - targetDate.getTime()) / (1000 * 60 * 60 * 24));
if (diffDays === 0) {
// 如果需要显示今天的具体时间可返回: `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`
return `${String(date.getHours()).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}`;
} else if (diffDays === 1) {
return '昨天';
} else if (diffDays > 1 && diffDays < 7) {
const weekDays = ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'];
return weekDays[date.getDay()];
} else {
// 超过7天
let resultFormat = format;
if (hideCurrentYear && targetDate.getFullYear() === now.getFullYear()) {
// 智能去除年份及紧跟的连接符、汉字或变宽空格(例如: "YYYY-", "YYYY/", "YYYY年"
resultFormat = resultFormat.replace(/YYYY[-/年\s]*/g, '');
}
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
return resultFormat
.replace(/YYYY/g, year)
.replace(/MM/g, String(month).padStart(2, '0'))
.replace(/M/g, month)
.replace(/DD/g, String(day).padStart(2, '0'))
.replace(/D/g, day);
}
} }
}; };