1865 lines
44 KiB
Vue
1865 lines
44 KiB
Vue
<template>
|
||
<view class="call-list" :class="['call-list-' + type]">
|
||
<view v-for="(item, index) in list" :key="index" class="item" @touchstart="touchStart($event, index)"
|
||
@touchmove="touchMove($event, index)" @touchend="touchEnd($event, index)"
|
||
:style="{ 'transform': 'translateX(' + swiperList[index] + 'px)', 'transition': swiperList[index] == 0 ? 'all 0.3s' : '' }">
|
||
<view class="avatar" v-if="type != 'xiaomi'">
|
||
<!-- 显示图片头像 -->
|
||
<image class="iosAvatar" v-if="type == 'ios' && item.avatar" :src="item.avatar" mode=""></image>
|
||
<!-- 显示文字头像 -->
|
||
<view v-else-if="type == 'ios' && item.name && item.avatarType === 'text'" class="text-avatar">
|
||
{{ getAvatarText(item.name) }}
|
||
</view>
|
||
<!-- 默认头像 -->
|
||
<image v-else-if="type == 'ios'" src="/static/image/call/iosAvatar.png" mode=""></image>
|
||
<!-- 其他类型的状态图标 -->
|
||
<image v-else-if="type == 'oppo'&&item.status==3" :src="`/static/image/call/oppoStatusIcon1.png`"
|
||
mode="widthFix"> </image>
|
||
<image v-else-if="type == 'oppo'&&(item.status==0||item.status==1)"
|
||
:src="`/static/image/call/oppoStatusIcon2.png`" mode="widthFix"> </image>
|
||
<image v-else-if="type == 'oppo'&&(item.status==4||item.status==5)"
|
||
:src="`/static/image/call/oppoStatusIcon3.png`" mode="widthFix"> </image>
|
||
<image v-else-if="type == 'oppo'&&item.status==2" :src="`/static/image/call/oppoStatusIcon4.png`"
|
||
mode="widthFix"> </image>
|
||
<image v-else-if="type == 'huawei'&&item.status==3" :src="`/static/image/call/huaweiStatusIcon2.png`"
|
||
mode="widthFix"></image>
|
||
<image v-else-if="type == 'huawei'&&item.status<3" :src="`/static/image/call/huaweiStatusIcon1.png`"
|
||
mode="widthFix"></image>
|
||
<image v-else-if="type == 'vivo'&&item.status==3" :src="`/static/image/call/vivoStatusIcon2.png`"
|
||
mode="widthFix"> </image>
|
||
<image v-else-if="type == 'vivo'&&(item.status==1||item.status==2)"
|
||
:src="`/static/image/call/vivoStatusIcon1.png`" mode="widthFix"> </image>
|
||
</view>
|
||
<view class="infoBox">
|
||
<view class="left-box">
|
||
<view class="leftInfo">
|
||
<view class="title" :class="{ 'title-red': item.status == 3 }">
|
||
<!-- ios -->
|
||
<view class="notes" v-if="type == 'ios'">
|
||
{{ item.name || formatString(item.phone) }}
|
||
</view>
|
||
<!-- xiaomi -->
|
||
<view class="notes" v-else-if="type == 'xiaomi'">
|
||
{{ item.name || item.notes || formatString(item.phone) }}
|
||
<text v-if="!item.name && item.notes">{{ formatString(item.phone) }}</text>
|
||
</view>
|
||
<view class="notes" v-else-if="type == 'oppo'">
|
||
{{ item.name || formatString(item.phone) }}
|
||
</view>
|
||
<view class="notes" v-else-if="type == 'huawei'">
|
||
{{ item.name || formatString(item.phone) }}
|
||
</view>
|
||
<view class="notes" v-else-if="type == 'vivo'">
|
||
{{ item.name || formatString(item.phone) }}
|
||
</view>
|
||
</view>
|
||
<view class="info">
|
||
|
||
<!-- 电话 -->
|
||
<view class="phone" v-if="type == 'vivo'">
|
||
{{ item.notes || formatString(item.phone) }}
|
||
</view>
|
||
<!-- 卡几 -->
|
||
<view class="kj" v-if="type == 'oppo' || type == 'huawei'">
|
||
<image :src="`/static/image/call/${type}KJ${item.kj}.png`" mode=""></image>
|
||
</view>
|
||
<!-- 时间 -->
|
||
<view class="time" v-if="type == 'xiaomi'">
|
||
{{ formatTime(item.time) }}
|
||
</view>
|
||
<!-- icon -->
|
||
<view class="status-icon" v-if="type == 'ios' && Number(item.status) > 2">
|
||
<image src="/static/image/call/iosStatusIcon.png" mode=""></image>
|
||
</view>
|
||
<!-- 地址 -->
|
||
<view class="address" v-if="type != 'ios'">
|
||
{{ item.address }}
|
||
</view>
|
||
<!-- 运营商 -->
|
||
<view class="yys" v-if="!(type == 'huawei'&&item.notes)">
|
||
{{ item.yys }}
|
||
</view>
|
||
<!-- 电话 -->
|
||
<view class="phone" v-if="type == 'ios' && item.name">
|
||
{{ formatString(item.phone) }}
|
||
</view>
|
||
<!-- 备注 -->
|
||
<view class="notes" v-if="type == 'oppo' || type == 'huawei'">
|
||
{{ item.notes }}
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="right-box">
|
||
<!-- 时间 -->
|
||
<view class="time" v-if="type != 'xiaomi'">
|
||
{{ formatTime(item.time) }}
|
||
</view>
|
||
<!-- 图标 -->
|
||
<view class="icon">
|
||
<image :src="`/static/image/call/${type}RightIcon.png`" mode=""></image>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 编辑按钮 -->
|
||
<view class="edit-btn" @click="editItem(index)">
|
||
<text class="edit-text">编辑</text>
|
||
</view>
|
||
<!-- 删除按钮 -->
|
||
<view class="delete-btn" @click="deleteItem(index)">
|
||
<text class="delete-text">删除</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 编辑弹窗 -->
|
||
<view class="modal-mask" v-if="showEditModal">
|
||
<view class="modal-content" @click.stop>
|
||
<view class="modal-header">
|
||
<text class="modal-title">编辑通话记录</text>
|
||
</view>
|
||
<view class="modal-body">
|
||
<view class="form-item">
|
||
<text class="form-label">姓名</text>
|
||
<input class="form-input" v-model="editForm.name" placeholder="请输入姓名" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">电话</text>
|
||
<input class="form-input" v-model="editForm.phone" placeholder="请输入电话" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">备注</text>
|
||
<input class="form-input" v-model="editForm.notes" placeholder="请输入备注(骚扰电话)" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">运营商</text>
|
||
<uni-data-select v-model="editForm.yys" :localdata="yysOptions" @change="onYysChange"
|
||
:clear="false"></uni-data-select>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">地址</text>
|
||
<input class="form-input" v-model="editForm.address" placeholder="请输入地址" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">时间</text>
|
||
<view class="form-input form-input-time" @click="setTimeType">
|
||
{{ editForm.time }}
|
||
</view>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">卡几</text>
|
||
<uni-data-select v-model="editForm.kj" :localdata="kjOptions" @change="onKjChange"
|
||
:clear="false"></uni-data-select>
|
||
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">状态</text>
|
||
<uni-data-select v-model="editForm.status" :localdata="statusOptions" @change="onStatusChange"
|
||
:clear="false"></uni-data-select>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">电话备注</text>
|
||
<input class="form-input" v-model="editForm.phoneNotes" placeholder="请输入电话备注" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">头像类型</text>
|
||
<uni-data-select v-model="editForm.avatarType" :localdata="avatarTypeOptions" @change="onAvatarTypeChange"
|
||
:clear="false"></uni-data-select>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">头像</text>
|
||
<view class="form-avatar-container">
|
||
<view v-if="editForm.avatarType === 'image'" class="form-avatar" @click="choose()">
|
||
<image :src="editForm.avatar||'/static/image/call/iosAvatar.png'" mode=""></image>
|
||
</view>
|
||
<view v-else-if="editForm.avatarType === 'text'" class="form-text-avatar">
|
||
{{ editForm.name ? getAvatarText(editForm.name) : '请输入姓名' }}
|
||
</view>
|
||
<view v-if="editForm.avatar" class="avatar-clear" @click="clearAvatar">清除</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="modal-footer">
|
||
<view class="btn btn-cancel" @click="closeEditModal">取消</view>
|
||
<view class="btn btn-confirm" @click="saveEdit">保存</view>
|
||
</view>
|
||
</view>
|
||
|
||
<uni-popup ref="timepopup" type="bottom">
|
||
<view class="timeBox">
|
||
<view class="titleBox">
|
||
<view class="title">
|
||
|
||
</view>
|
||
<view class="btns" @click="settmes">
|
||
确定
|
||
</view>
|
||
</view>
|
||
<DateTimePicker :defaultDate="data.startDate" :maxDate="data.endDate" :mode="4" @onChange="onChangeStartDate" />
|
||
</view>
|
||
</uni-popup>
|
||
</view>
|
||
<!-- 添加联系人弹窗 -->
|
||
<view class="modal-mask" v-if="showAddModal">
|
||
<view class="modal-content" @click.stop>
|
||
<view class="modal-header">
|
||
<text class="modal-title">添加联系人</text>
|
||
</view>
|
||
<view class="modal-body">
|
||
<view class="form-item">
|
||
<text class="form-label">姓名</text>
|
||
<input class="form-input" v-model="addForm.name" placeholder="请输入姓名" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">电话 *</text>
|
||
<input class="form-input" v-model="addForm.phone" placeholder="请输入电话" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">运营商 *</text>
|
||
<uni-data-select v-model="addForm.yys" :localdata="yysOptions" @change="onAddYysChange"
|
||
:clear="false"></uni-data-select>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">时间 *</text>
|
||
<view class="form-input form-input-time" @click="setAddTimeType">
|
||
{{ addForm.time }}
|
||
</view>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">状态 *</text>
|
||
<uni-data-select v-model="addForm.status" :localdata="statusOptions" @change="onAddStatusChange"
|
||
:clear="false"></uni-data-select>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">卡几</text>
|
||
<uni-data-select v-model="addForm.kj" :localdata="kjOptions" @change="onAddKjChange"
|
||
:clear="false"></uni-data-select>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">地址</text>
|
||
<input class="form-input" v-model="addForm.address" placeholder="请输入地址" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">备注</text>
|
||
<input class="form-input" v-model="addForm.notes" placeholder="请输入备注" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">电话备注</text>
|
||
<input class="form-input" v-model="addForm.phoneNotes" placeholder="请输入电话备注" />
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">头像类型</text>
|
||
<uni-data-select v-model="addForm.avatarType" :localdata="avatarTypeOptions" @change="onAddAvatarTypeChange"
|
||
:clear="false"></uni-data-select>
|
||
</view>
|
||
<view class="form-item">
|
||
<text class="form-label">头像</text>
|
||
<view class="form-avatar-container">
|
||
<view v-if="addForm.avatarType === 'image'" class="form-avatar" @click="choose()">
|
||
<image :src="addForm.avatar||'/static/image/call/iosAvatar.png'" mode=""></image>
|
||
</view>
|
||
<view v-else-if="addForm.avatarType === 'text'" class="form-text-avatar">
|
||
{{ addForm.name ? getAvatarText(addForm.name) : '请输入姓名' }}
|
||
</view>
|
||
<view v-if="addForm.avatar" class="avatar-clear" @click="clearAvatar">清除</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="modal-footer">
|
||
<view class="btn btn-random" @click="generateRandomData">随机数据</view>
|
||
<view class="btn btn-cancel" @click="closeAddModal">取消</view>
|
||
<view class="btn btn-confirm" @click="saveAdd">保存</view>
|
||
</view>
|
||
</view>
|
||
<uni-popup ref="timepopup" type="bottom">
|
||
<view class="timeBox">
|
||
<view class="titleBox">
|
||
<view class="title">
|
||
|
||
</view>
|
||
<view class="btns" @click="settmes">
|
||
确定
|
||
</view>
|
||
</view>
|
||
<DateTimePicker :defaultDate="data.startDate" :maxDate="data.endDate" :mode="4" @onChange="onChangeStartDate" />
|
||
</view>
|
||
</uni-popup>
|
||
</view>
|
||
|
||
</template>
|
||
|
||
<script setup>
|
||
import {
|
||
ref,
|
||
reactive,
|
||
onMounted,
|
||
watch,
|
||
computed
|
||
} from 'vue';
|
||
|
||
import {
|
||
onUnload
|
||
} from "@dcloudio/uni-app";
|
||
import DateTimePicker from '@/components/dengrq-datetime-picker/dateTimePicker/index.vue';
|
||
|
||
const props = defineProps({
|
||
isHuise: {
|
||
type: Boolean,
|
||
default: true
|
||
},
|
||
type: {
|
||
type: String,
|
||
default: 'ios'
|
||
}
|
||
});
|
||
const data = reactive({
|
||
startDate: '',
|
||
timeIndex: -1
|
||
})
|
||
const emit = defineEmits(['update:list']);
|
||
|
||
const list = ref([{
|
||
"avatar": "",
|
||
"name": "李强",
|
||
"phone": "13912345678",
|
||
"phoneNotes": "电话",
|
||
"yys": "移动",
|
||
"kj": "2",
|
||
"address": "北京",
|
||
"time": "2026-02-01 10:00:00",
|
||
"status": 1,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "工作往来"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "王芳",
|
||
"phone": "15887654321",
|
||
"phoneNotes": "电话",
|
||
"yys": "联通",
|
||
"kj": "2",
|
||
"address": "上海",
|
||
"time": "2026-02-02 14:30:00",
|
||
"status": 4,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "老朋友"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "",
|
||
"phone": "18711223344",
|
||
"phoneNotes": "电话",
|
||
"yys": "移动",
|
||
"kj": "1",
|
||
"address": "广州",
|
||
"time": "2026-03-03 16:45:00",
|
||
"status": 0,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "推销电话"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "",
|
||
"phone": "13644556677",
|
||
"phoneNotes": "电话",
|
||
"yys": "电信",
|
||
"kj": "2",
|
||
"address": "深圳",
|
||
"time": "2026-03-04 10:30:00",
|
||
"status": 2,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "快递小哥"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "陈静",
|
||
"phone": "17788889999",
|
||
"phoneNotes": "电话",
|
||
"yys": "联通",
|
||
"kj": "2",
|
||
"address": "杭州",
|
||
"time": "2026-03-05 15:00:00",
|
||
"status": 3,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "大学同学"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "赵雷",
|
||
"phone": "15133334444",
|
||
"phoneNotes": "电话",
|
||
"yys": "移动",
|
||
"kj": "1",
|
||
"address": "成都",
|
||
"time": "2026-03-01 18:00:00",
|
||
"status": 5,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "骚扰电话"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "孙丽",
|
||
"phone": "18966667777",
|
||
"phoneNotes": "电话",
|
||
"yys": "电信",
|
||
"kj": "2",
|
||
"address": "武汉",
|
||
"time": "2026-02-05 18:30:00",
|
||
"status": 1,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "客户"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "周涛",
|
||
"phone": "15555558888",
|
||
"phoneNotes": "电话",
|
||
"yys": "联通",
|
||
"kj": "1",
|
||
"address": "西安",
|
||
"time": "2026-02-05 18:30:00",
|
||
"status": 4,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "家人"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "吴杰",
|
||
"phone": "13011112222",
|
||
"phoneNotes": "电话",
|
||
"yys": "电信",
|
||
"kj": "2",
|
||
"address": "南京",
|
||
"time": "2026-02-05 18:30:00",
|
||
"status": 0,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "广告推销"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "郑爽",
|
||
"phone": "18899990000",
|
||
"phoneNotes": "电话",
|
||
"yys": "移动",
|
||
"kj": "2",
|
||
"address": "长沙",
|
||
"time": "2026-03-05 18:30:00",
|
||
"status": 2,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "同事"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "",
|
||
"phone": "15712345678",
|
||
"phoneNotes": "电话",
|
||
"yys": "移动",
|
||
"kj": "2",
|
||
"address": "天津",
|
||
"time": "2025-08-05 18:30:00",
|
||
"status": 3,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "未知号码"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "李娜",
|
||
"phone": "15287654321",
|
||
"phoneNotes": "电话",
|
||
"yys": "联通",
|
||
"kj": "1",
|
||
"address": "苏州",
|
||
"time": "2026-03-05 18:30:00",
|
||
"status": 5,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "健身房"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "张敏",
|
||
"phone": "18799887766",
|
||
"phoneNotes": "电话",
|
||
"yys": "移动",
|
||
"kj": "1",
|
||
"address": "青岛",
|
||
"time": "2026-03-05 18:30:00",
|
||
"status": 1,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "学校老师"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "",
|
||
"phone": "13655443322",
|
||
"phoneNotes": "电话",
|
||
"yys": "电信",
|
||
"kj": "2",
|
||
"address": "大连",
|
||
"time": "2026-03-05 18:30:00",
|
||
"status": 4,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "保险推销"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "",
|
||
"phone": "17722334455",
|
||
"phoneNotes": "电话",
|
||
"yys": "联通",
|
||
"kj": "2",
|
||
"address": "厦门",
|
||
"time": "2026-03-05 18:30:00",
|
||
"status": 0,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "外卖"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "赵雅",
|
||
"phone": "15166778899",
|
||
"phoneNotes": "电话",
|
||
"yys": "移动",
|
||
"kj": "2",
|
||
"address": "宁波",
|
||
"time": "2026-03-05 18:30:00",
|
||
"status": 2,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "亲戚"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "孙浩",
|
||
"phone": "18911223344",
|
||
"phoneNotes": "电话",
|
||
"yys": "电信",
|
||
"kj": "1",
|
||
"address": "郑州",
|
||
"time": "2026-03-05 18:30:00",
|
||
"status": 3,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "房产中介"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "",
|
||
"phone": "15544332211",
|
||
"phoneNotes": "电话",
|
||
"yys": "联通",
|
||
"kj": "1",
|
||
"address": "沈阳",
|
||
"time": "2026-03-05 18:30:00",
|
||
"status": 5,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "银行客服"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "吴刚",
|
||
"phone": "13099887766",
|
||
"phoneNotes": "电话",
|
||
"yys": "电信",
|
||
"kj": "2",
|
||
"address": "济南",
|
||
"time": "2026-02-05 18:30:00",
|
||
"status": 1,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "合作伙伴"
|
||
},
|
||
{
|
||
"avatar": "",
|
||
"name": "",
|
||
"phone": "18818818818",
|
||
"phoneNotes": "电话",
|
||
"yys": "移动",
|
||
"kj": "2",
|
||
"address": "重庆",
|
||
"time": "2026-03-05 18:30:00",
|
||
"status": 4,
|
||
avatarType: 'image', // image 或 text
|
||
"notes": "骚扰电话"
|
||
}
|
||
]);
|
||
|
||
const swiperList = ref([]);
|
||
const startX = ref(0);
|
||
const startY = ref(0);
|
||
const deleteWidth = ref(140);
|
||
const timepopup = ref();
|
||
|
||
const showEditModal = ref(false);
|
||
const editForm = reactive({
|
||
avatar: '',
|
||
avatarType: 'image', // image 或 text
|
||
name: '',
|
||
phone: '',
|
||
phoneNotes: '',
|
||
yys: '',
|
||
yysIndex: 0,
|
||
kj: '1',
|
||
address: '',
|
||
time: '',
|
||
status: '0',
|
||
notes: ''
|
||
});
|
||
const editIndex = ref(-1);
|
||
|
||
// 添加联系人相关
|
||
const showAddModal = ref(false);
|
||
const addForm = reactive({
|
||
avatar: '',
|
||
avatarType: 'image', // image 或 text
|
||
name: '',
|
||
phone: '',
|
||
phoneNotes: '',
|
||
yys: '',
|
||
kj: '1',
|
||
address: '',
|
||
time: '',
|
||
status: '0',
|
||
notes: ''
|
||
});
|
||
|
||
// 卡几选项
|
||
const kjOptions = ref([{
|
||
value: '1',
|
||
text: '卡1'
|
||
},
|
||
{
|
||
value: '2',
|
||
text: '卡2'
|
||
},
|
||
]);
|
||
// 状态选项(对象数组,用于显示中文文本)
|
||
const statusOptions = ref([{
|
||
value: 0,
|
||
text: '来电-未接'
|
||
},
|
||
{
|
||
value: 1,
|
||
text: '来电-已接'
|
||
},
|
||
{
|
||
value: 2,
|
||
text: '来电-拒接'
|
||
},
|
||
{
|
||
value: 3,
|
||
text: '播出-未接'
|
||
},
|
||
{
|
||
value: 4,
|
||
text: '播出-已接'
|
||
},
|
||
{
|
||
value: 5,
|
||
text: '播出-拒接'
|
||
}
|
||
]);
|
||
// 运营商选项
|
||
const yysOptions = ref([
|
||
|
||
{
|
||
value: '移动',
|
||
text: '移动'
|
||
},
|
||
{
|
||
value: '联通',
|
||
text: '联通'
|
||
},
|
||
{
|
||
value: '电信',
|
||
text: '电信'
|
||
},
|
||
{
|
||
value: '广电',
|
||
text: '广电'
|
||
}
|
||
]);
|
||
|
||
// 头像类型选项
|
||
const avatarTypeOptions = ref([{
|
||
value: 'image',
|
||
text: '图片头像'
|
||
},
|
||
{
|
||
value: 'text',
|
||
text: '文字头像'
|
||
}
|
||
]);
|
||
|
||
// 获取卡几文本
|
||
const getKjText = (value) => {
|
||
return value || '请选择';
|
||
};
|
||
|
||
// 获取状态文本
|
||
const getStatusText = (value) => {
|
||
const item = statusOptions.value.find(option => option.value === value.toString());
|
||
return item ? item.text : '请选择';
|
||
};
|
||
onMounted(() => {
|
||
let listArr = uni.getStorageSync('callLog')
|
||
if (Array.isArray(listArr) && listArr.length > 0) {
|
||
list.value = simpleSortByTime(listArr, 'time', true)
|
||
} else {
|
||
list.value = simpleSortByTime(list.value, 'time', true)
|
||
uni.setStorageSync('callLog', list.value)
|
||
}
|
||
swiperList.value = new Array(list.value.length).fill(0);
|
||
|
||
uni.$on('setActive', (status) => {
|
||
let listArr2 = uni.getStorageSync('callLog') || list.value
|
||
if (!status) {
|
||
listArr2 = listArr2.filter(item => item.status == 3)
|
||
}
|
||
if (Array.isArray(listArr2) && listArr2.length > 0) {
|
||
list.value = simpleSortByTime(listArr2, 'time', true)
|
||
} else {
|
||
list.value = simpleSortByTime(list.value, 'time', true)
|
||
}
|
||
swiperList.value = new Array(list.value.length).fill(0);
|
||
|
||
})
|
||
});
|
||
|
||
onUnload(() => {
|
||
uni.$off('setActive')
|
||
})
|
||
watch(() => props.isHuise, (newValue, oldValue) => {
|
||
console.log(newValue);
|
||
});
|
||
|
||
const touchStart = (e, index) => {
|
||
startX.value = e.changedTouches[0].clientX;
|
||
startY.value = e.changedTouches[0].clientY;
|
||
swiperList.value.forEach((item, i) => {
|
||
if (i !== index) {
|
||
swiperList.value[i] = 0;
|
||
}
|
||
});
|
||
};
|
||
|
||
const touchMove = (e, index) => {
|
||
const moveX = e.changedTouches[0].clientX;
|
||
const moveY = e.changedTouches[0].clientY;
|
||
const disX = moveX - startX.value;
|
||
const disY = moveY - startY.value;
|
||
if (Math.abs(disX) > Math.abs(disY)) {
|
||
e.preventDefault();
|
||
let distance = Math.max(-deleteWidth.value, Math.min(0, disX));
|
||
swiperList.value[index] = distance;
|
||
}
|
||
};
|
||
|
||
const touchEnd = (e, index) => {
|
||
const endX = e.changedTouches[0].clientX;
|
||
const disX = endX - startX.value;
|
||
if (disX < -deleteWidth.value / 2) {
|
||
swiperList.value[index] = -deleteWidth.value;
|
||
} else {
|
||
swiperList.value[index] = 0;
|
||
}
|
||
};
|
||
|
||
const deleteItem = (index) => {
|
||
uni.showModal({
|
||
title: '确认删除',
|
||
content: '确定要删除这条通话记录吗?',
|
||
confirmText: '删除',
|
||
cancelText: '取消',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
list.value.splice(index, 1);
|
||
swiperList.value.splice(index, 1);
|
||
uni.setStorageSync('callLog', list.value)
|
||
// emit('update:list', list.value);
|
||
}
|
||
}
|
||
});
|
||
};
|
||
|
||
const editItem = (index) => {
|
||
editIndex.value = index;
|
||
const item = list.value[index];
|
||
editForm.avatar = item.avatar || '';
|
||
editForm.avatarType = item.avatarType || 'image';
|
||
editForm.name = item.name || '';
|
||
editForm.phone = item.phone || '';
|
||
editForm.phoneNotes = item.phoneNotes || '';
|
||
editForm.yys = item.yys || '';
|
||
editForm.yysIndex = yysOptions.value.indexOf(item.yys || '移动');
|
||
editForm.kj = item.kj || '1';
|
||
editForm.address = item.address || '';
|
||
editForm.time = item.time || '';
|
||
editForm.status = item.status || '0';
|
||
editForm.notes = item.notes || '';
|
||
showEditModal.value = true;
|
||
};
|
||
|
||
function setTimeType() {
|
||
data.startDate = editForm.time
|
||
timepopup.value.open()
|
||
}
|
||
|
||
function onChangeStartDate(date) {
|
||
console.log('onChangeDate', date);
|
||
data.startDate = date
|
||
}
|
||
|
||
function settmes() {
|
||
timepopup.value.close()
|
||
// 检查当前是编辑还是添加模式
|
||
if (showEditModal.value) {
|
||
editForm.time = data.startDate
|
||
} else if (showAddModal.value) {
|
||
addForm.time = data.startDate
|
||
}
|
||
}
|
||
// 运营商选择变化处理
|
||
const onYysChange = (e) => {
|
||
const index = e.detail.value;
|
||
editForm.yys = yysOptions.value[index];
|
||
};
|
||
|
||
const closeEditModal = () => {
|
||
showEditModal.value = false;
|
||
editIndex.value = -1;
|
||
};
|
||
|
||
// 状态选择变化处理
|
||
const onStatusChange = (e) => {
|
||
const index = e.detail.value;
|
||
editForm.status = statusOptions.value[index].value;
|
||
};
|
||
// 卡几选择变化处理
|
||
const onKjChange = (e) => {
|
||
const index = e.detail.value;
|
||
editForm.kj = kjOptions.value[index];
|
||
};
|
||
|
||
const saveEdit = () => {
|
||
if (!editForm.name && !editForm.phone) {
|
||
uni.showToast({
|
||
title: '请填写姓名或电话',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
const item = list.value[editIndex.value];
|
||
item.avatar = editForm.avatar;
|
||
item.avatarType = editForm.avatarType;
|
||
item.title = editForm.title;
|
||
item.name = editForm.name;
|
||
item.phone = editForm.phone;
|
||
item.phoneNotes = editForm.phoneNotes;
|
||
item.yys = editForm.yys;
|
||
item.kj = editForm.kj;
|
||
item.address = editForm.address;
|
||
item.time = editForm.time;
|
||
item.icon = editForm.icon;
|
||
item.status = editForm.status;
|
||
item.notes = editForm.notes;
|
||
// emit('update:list', list.value);
|
||
closeEditModal();
|
||
|
||
list.value = simpleSortByTime(list.value, 'time', true)
|
||
uni.setStorageSync('callLog', list.value)
|
||
swiperList.value[editIndex.value] = 0;
|
||
};
|
||
|
||
// 添加联系人相关方法
|
||
const openAddModal = () => {
|
||
|
||
const now = new Date();
|
||
|
||
// 获取当前时间的年月日
|
||
const currentYear = now.getFullYear();
|
||
const currentMonth = now.getMonth();
|
||
const currentDay = now.getDate();
|
||
// 重置表单
|
||
addForm.avatar = '';
|
||
addForm.avatarType = 'image';
|
||
addForm.name = '';
|
||
addForm.phone = '';
|
||
addForm.phoneNotes = '电话';
|
||
addForm.yys = '';
|
||
addForm.kj = '1';
|
||
addForm.address = '';
|
||
addForm.time =
|
||
`${currentYear}-${currentMonth + 1}-${currentDay} ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()}`;
|
||
addForm.status = '0';
|
||
addForm.notes = '';
|
||
showAddModal.value = true;
|
||
console.log(showAddModal.value)
|
||
};
|
||
|
||
const closeAddModal = () => {
|
||
showAddModal.value = false;
|
||
};
|
||
|
||
const saveAdd = () => {
|
||
// 验证必填项
|
||
if (!addForm.phone) {
|
||
uni.showToast({
|
||
title: '请输入电话',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
if (!addForm.yys) {
|
||
uni.showToast({
|
||
title: '请选择运营商',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
if (!addForm.time) {
|
||
uni.showToast({
|
||
title: '请输入时间',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
if (!addForm.status) {
|
||
uni.showToast({
|
||
title: '请选择状态',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 创建新联系人
|
||
const newItem = {
|
||
avatar: addForm.avatar || '',
|
||
avatarType: addForm.avatarType || 'image',
|
||
title: addForm.name || addForm.phone,
|
||
name: addForm.name || '',
|
||
phone: addForm.phone,
|
||
phoneNotes: addForm.phoneNotes || '电话',
|
||
yys: addForm.yys,
|
||
kj: addForm.kj,
|
||
address: addForm.address || '',
|
||
time: addForm.time,
|
||
icon: addForm.icon || '',
|
||
status: addForm.status,
|
||
notes: addForm.notes || ''
|
||
};
|
||
|
||
// 添加到列表
|
||
list.value.unshift(newItem);
|
||
swiperList.value.unshift(0);
|
||
// emit('update:list', list.value);
|
||
closeAddModal();
|
||
|
||
list.value = simpleSortByTime(list.value, 'time', true)
|
||
uni.setStorageSync('callLog', list.value);
|
||
};
|
||
|
||
// 设置添加联系人时间
|
||
function setAddTimeType() {
|
||
data.startDate = addForm.time
|
||
timepopup.value.open()
|
||
}
|
||
|
||
// 添加联系人时的运营商选择变化处理
|
||
const onAddYysChange = (e) => {
|
||
addForm.yys = e.detail.value;
|
||
};
|
||
|
||
// 添加联系人时的状态选择变化处理
|
||
const onAddStatusChange = (e) => {
|
||
addForm.status = e.detail.value;
|
||
};
|
||
|
||
// 添加联系人时的卡几选择变化处理
|
||
const onAddKjChange = (e) => {
|
||
addForm.kj = e.detail.value;
|
||
};
|
||
|
||
// 头像类型选择变化处理
|
||
const onAvatarTypeChange = (e) => {
|
||
editForm.avatarType = e.detail.value;
|
||
};
|
||
|
||
// 添加联系人时的头像类型选择变化处理
|
||
const onAddAvatarTypeChange = (e) => {
|
||
addForm.avatarType = e.detail.value;
|
||
};
|
||
|
||
// 暴露方法给父组件
|
||
defineExpose({
|
||
openAddModal
|
||
});
|
||
/**
|
||
* 格式化时间显示
|
||
* @param {string|number|Date} time - 需要格式化的时间
|
||
* @returns {string} 格式化后的时间字符串
|
||
*/
|
||
const formatTime = (time) => {
|
||
// 如果传入的是空值,返回空字符串
|
||
if (!time) return '';
|
||
|
||
// 将传入的时间转换为Date对象
|
||
const date = new Date(time);
|
||
|
||
// 检查日期是否有效
|
||
if (isNaN(date.getTime())) {
|
||
return '';
|
||
}
|
||
|
||
const now = new Date();
|
||
|
||
// 获取传入时间的年月日
|
||
const targetYear = date.getFullYear();
|
||
const targetMonth = date.getMonth();
|
||
const targetDay = date.getDate();
|
||
|
||
// 获取当前时间的年月日
|
||
const currentYear = now.getFullYear();
|
||
const currentMonth = now.getMonth();
|
||
const currentDay = now.getDate();
|
||
|
||
// 判断是否为今天
|
||
if (targetYear === currentYear && targetMonth === currentMonth && targetDay === currentDay) {
|
||
// 今天:显示时分
|
||
const hours = date.getHours().toString().padStart(2, '0');
|
||
const minutes = date.getMinutes().toString().padStart(2, '0');
|
||
return `${hours}:${minutes}`;
|
||
}
|
||
|
||
// 判断是否为昨天
|
||
const yesterday = new Date(now);
|
||
yesterday.setDate(currentDay - 1);
|
||
if (targetYear === yesterday.getFullYear() &&
|
||
targetMonth === yesterday.getMonth() &&
|
||
targetDay === yesterday.getDate()) {
|
||
return '昨天';
|
||
}
|
||
let ym = '-'
|
||
let md = '-'
|
||
let d = ''
|
||
if (props.type == 'ios' || props.type == 'oppo' || props.type == 'huawei') {
|
||
ym = '/'
|
||
md = '/'
|
||
} else {
|
||
ym = '年'
|
||
md = '月'
|
||
d = '日'
|
||
}
|
||
// 判断是否为今年
|
||
if (targetYear === currentYear) {
|
||
// 判断是否为近一周(当前时间往前推7天内)
|
||
const oneWeekAgo = new Date(now);
|
||
oneWeekAgo.setDate(currentDay - 6);
|
||
|
||
// 重置时间部分为0点,只比较日期
|
||
const targetDateOnly = new Date(targetYear, targetMonth, targetDay);
|
||
const oneWeekAgoDateOnly = new Date(oneWeekAgo.getFullYear(), oneWeekAgo.getMonth(), oneWeekAgo.getDate());
|
||
const nowDateOnly = new Date(currentYear, currentMonth, currentDay);
|
||
|
||
if (targetDateOnly >= oneWeekAgoDateOnly && targetDateOnly <= nowDateOnly) {
|
||
// 近一周:显示星期几
|
||
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
||
return weekdays[date.getDay()];
|
||
} else {
|
||
// 今年但不在近一周:显示月-日
|
||
// 去年及以前:显示年-月-日.padStart(2, '0');
|
||
const year = targetYear.toString();
|
||
const month = (targetMonth + 1).toString()
|
||
const day = targetDay.toString()
|
||
return `${props.type == 'ios' ? year + ym : ''}${month}${md}${day}${d}`;
|
||
}
|
||
}
|
||
|
||
// 去年及以前:显示年-月-日
|
||
const year = targetYear.toString();
|
||
const month = (targetMonth + 1).toString()
|
||
const day = targetDay.toString()
|
||
|
||
return `${year}${ym}${month}${md}${day}${d}`;
|
||
}
|
||
/**
|
||
* 格式化字符串:第一个3个字符后加空格,之后每4个字符加一个空格
|
||
* @param {string} str - 需要格式化的字符串
|
||
* @returns {string} 格式化后的字符串
|
||
*/
|
||
function formatString(str) {
|
||
if (!str) return '';
|
||
|
||
// 移除字符串中可能存在的空格
|
||
const cleanStr = str.replace(/\s+/g, '');
|
||
|
||
if (cleanStr.length <= 3) {
|
||
return cleanStr;
|
||
}
|
||
|
||
// 第一个3个字符
|
||
let result = cleanStr.substring(0, 3);
|
||
|
||
// 剩余部分每4个字符一组
|
||
const remaining = cleanStr.substring(3);
|
||
for (let i = 0; i < remaining.length; i += 4) {
|
||
if (i > 0 || result.length > 0) {
|
||
result += ' ';
|
||
}
|
||
result += remaining.substring(i, i + 4);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
function simpleSortByTime(arr, key = 'time', newestFirst = true) {
|
||
return [...arr].sort((a, b) => {
|
||
const timeA = new Date(a[key]).getTime();
|
||
const timeB = new Date(b[key]).getTime();
|
||
return newestFirst ? timeB - timeA : timeA - timeB;
|
||
});
|
||
}
|
||
|
||
function choose() {
|
||
uni.chooseImage({
|
||
count: 1,
|
||
sourceType: [ 'album' , 'camera'],
|
||
maxDuration: 30,
|
||
camera: 'back',
|
||
success(res) {
|
||
let tempFilePath = res.tempFiles[0].path
|
||
// 保存图片到本地
|
||
uni.saveFile({
|
||
tempFilePath: tempFilePath,
|
||
success: function(ress) {
|
||
// 使用本地保存的路径
|
||
const localPath = ress.savedFilePath;
|
||
if (showEditModal.value) {
|
||
editForm.avatar = localPath;
|
||
} else if (showAddModal.value) {
|
||
addForm.avatar = localPath;
|
||
}
|
||
// 显示成功提示
|
||
uni.showToast({
|
||
title: '图片保存成功',
|
||
icon: 'success'
|
||
});
|
||
},
|
||
fail: function(err) {
|
||
console.log('保存文件失败:', err);
|
||
// 如果保存失败,使用临时路径
|
||
if (showEditModal.value) {
|
||
editForm.avatar = tempFilePath;
|
||
} else if (showAddModal.value) {
|
||
addForm.avatar = tempFilePath;
|
||
}
|
||
uni.showToast({
|
||
title: '图片保存失败,使用临时路径',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
});
|
||
},
|
||
fail(err) {
|
||
console.log('选择图片失败:', err);
|
||
uni.showToast({
|
||
title: '选择图片失败',
|
||
icon: 'none'
|
||
});
|
||
}
|
||
})
|
||
}
|
||
|
||
// 获取头像文字
|
||
const getAvatarText = (name) => {
|
||
if (!name) return '';
|
||
// 取姓名的第一个字符
|
||
return name.charAt(0);
|
||
};
|
||
|
||
// 获取头像数字
|
||
const getAvatarNumber = (phone) => {
|
||
if (!phone) return '';
|
||
// 取电话号码的后四位
|
||
const cleanPhone = phone.replace(/\D/g, '');
|
||
return cleanPhone.slice(-4);
|
||
};
|
||
|
||
// 获取头像背景颜色
|
||
const getAvatarColor = (text) => {
|
||
if (!text) return '#999';
|
||
// 根据文本生成一个固定的颜色
|
||
const colors = [
|
||
'#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4', '#FFEAA7',
|
||
'#DDA0DD', '#98D8C8', '#F7DC6F', '#BB8FCE', '#85C1E9'
|
||
];
|
||
let hash = 0;
|
||
for (let i = 0; i < text.length; i++) {
|
||
hash = text.charCodeAt(i) + ((hash << 5) - hash);
|
||
}
|
||
const index = Math.abs(hash) % colors.length;
|
||
return colors[index];
|
||
};
|
||
|
||
// 清除头像
|
||
const clearAvatar = () => {
|
||
if (showEditModal.value) {
|
||
editForm.avatar = '';
|
||
} else if (showAddModal.value) {
|
||
addForm.avatar = '';
|
||
}
|
||
};
|
||
|
||
// 生成随机数据
|
||
const generateRandomData = () => {
|
||
const names = ['张三', '李四', '王五', '赵六', '钱七', '孙八', '周九', '吴十'];
|
||
const addresses = ['北京', '上海', '广州', '深圳', '杭州', '成都', '武汉', '西安'];
|
||
const notes = ['工作往来', '老朋友', '推销电话', '快递小哥', '大学同学', '骚扰电话', '客户', '家人'];
|
||
|
||
// 生成随机电话号码
|
||
const randomPhone = () => {
|
||
const prefixes = ['130', '131', '132', '133', '134', '135', '136', '137', '138', '139', '150', '151', '152',
|
||
'153', '155', '156', '157', '158', '159', '170', '171', '172', '173', '175', '176', '177', '178', '180',
|
||
'181', '182', '183', '184', '185', '186', '187', '188', '189'
|
||
];
|
||
const prefix = prefixes[Math.floor(Math.random() * prefixes.length)];
|
||
const suffix = Math.floor(Math.random() * 100000000).toString().padStart(8, '0');
|
||
return prefix + suffix;
|
||
};
|
||
|
||
// 生成随机时间
|
||
const randomTime = () => {
|
||
const now = new Date();
|
||
const randomDays = Math.floor(Math.random() * 30); // 30天内的随机时间
|
||
const randomDate = new Date(now.getTime() - randomDays * 24 * 60 * 60 * 1000);
|
||
const year = randomDate.getFullYear();
|
||
const month = (randomDate.getMonth() + 1).toString().padStart(2, '0');
|
||
const day = randomDate.getDate().toString().padStart(2, '0');
|
||
const hours = randomDate.getHours().toString().padStart(2, '0');
|
||
const minutes = randomDate.getMinutes().toString().padStart(2, '0');
|
||
const seconds = randomDate.getSeconds().toString().padStart(2, '0');
|
||
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
|
||
};
|
||
|
||
// 填充随机数据
|
||
addForm.name = names[Math.floor(Math.random() * names.length)];
|
||
addForm.phone = randomPhone();
|
||
addForm.phoneNotes = '电话';
|
||
addForm.yys = yysOptions.value[Math.floor(Math.random() * yysOptions.value.length)].value;
|
||
addForm.kj = Math.random() > 0.5 ? '1' : '2';
|
||
addForm.address = addresses[Math.floor(Math.random() * addresses.length)];
|
||
addForm.time = randomTime();
|
||
addForm.status = Math.floor(Math.random() * 6).toString();
|
||
addForm.notes = notes[Math.floor(Math.random() * notes.length)];
|
||
addForm.avatar = ''; // 随机数据不生成头像
|
||
addForm.avatarType = Math.random() > 0.5 ? 'image' : 'text'; // 随机选择头像类型
|
||
};
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.call-list {
|
||
width: 100vw;
|
||
overflow: hidden;
|
||
box-sizing: border-box;
|
||
background-color: #fff;
|
||
|
||
.item {
|
||
display: flex;
|
||
position: relative;
|
||
width: 100%;
|
||
|
||
.avatar {
|
||
width: 80rpx;
|
||
height: 80rpx;
|
||
|
||
image {
|
||
width: 100% !important;
|
||
height: 100% !important;
|
||
}
|
||
}
|
||
|
||
.infoBox {
|
||
width: calc(100% - 80rpx);
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
background-color: #fff;
|
||
z-index: 2;
|
||
|
||
.left-box {
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
|
||
.leftInfo {
|
||
.title {
|
||
font-size: 32rpx;
|
||
color: #333;
|
||
margin-bottom: 10rpx;
|
||
}
|
||
|
||
.info {
|
||
display: flex;
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
|
||
view {
|
||
margin-right: 10rpx;
|
||
}
|
||
|
||
.kj {
|
||
line-height: 0;
|
||
width: 22rpx;
|
||
height: 22rpx;
|
||
|
||
image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
|
||
.status-icon {
|
||
line-height: 0;
|
||
width: 22rpx;
|
||
height: 22rpx;
|
||
|
||
image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
}
|
||
|
||
.right-box {
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
align-items: center;
|
||
|
||
.time {
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
}
|
||
|
||
.icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
overflow: hidden;
|
||
margin-left: 20rpx;
|
||
|
||
image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.edit-btn {
|
||
position: absolute;
|
||
top: 0;
|
||
right: -140px;
|
||
width: 70px;
|
||
height: 100%;
|
||
background-color: #007AFF;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
z-index: 1;
|
||
|
||
.edit-text {
|
||
color: #fff;
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
|
||
.delete-btn {
|
||
position: absolute;
|
||
top: 0;
|
||
right: -70px;
|
||
width: 70px;
|
||
height: 100%;
|
||
background-color: #FF3B30;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
z-index: 1;
|
||
|
||
.delete-text {
|
||
color: #fff;
|
||
font-size: 28rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.call-list-ios {
|
||
|
||
.item {
|
||
align-items: center;
|
||
justify-content: space-between;
|
||
height: 132rpx;
|
||
}
|
||
|
||
.avatar {
|
||
width: 84rpx;
|
||
height: 84rpx;
|
||
border-radius: 50%;
|
||
margin-left: 32rpx;
|
||
overflow: hidden;
|
||
}
|
||
|
||
.infoBox {
|
||
width: calc(100% - 136rpx) !important;
|
||
padding: 24rpx 32rpx 24rpx 0;
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
|
||
box-shadow: inset 0 -0.3px 0 0 #C2C2C2;
|
||
|
||
|
||
.left-box {
|
||
.title {
|
||
font-weight: 400;
|
||
font-size: 16px;
|
||
color: #1A1A1A;
|
||
line-height: 16px;
|
||
}
|
||
|
||
.title-red {
|
||
color: #FC3E30 !important;
|
||
}
|
||
|
||
.info {
|
||
align-items: center;
|
||
}
|
||
|
||
.info .phone {
|
||
font-weight: 400;
|
||
font-size: 14px;
|
||
color: #838383;
|
||
line-height: 20px;
|
||
}
|
||
|
||
.info .yys {
|
||
height: 12px;
|
||
background: #C7C7C7;
|
||
border-radius: 2px 2px 2px 2px;
|
||
padding: 0 4rpx;
|
||
font-weight: 400;
|
||
font-size: 10px;
|
||
color: #FFFFFF;
|
||
text-align: center;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
|
||
.right-box {
|
||
.time {
|
||
font-weight: 400;
|
||
font-size: 14px;
|
||
color: #838383;
|
||
line-height: 14px;
|
||
}
|
||
|
||
.icon {
|
||
width: 40rpx;
|
||
height: 40rpx;
|
||
overflow: hidden;
|
||
margin-left: 14rpx;
|
||
|
||
image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.call-list-xiaomi {
|
||
.item {
|
||
height: 140rpx;
|
||
}
|
||
|
||
.infoBox {
|
||
width: 100% !important;
|
||
padding: 34rpx 56rpx 28rpx 56rpx;
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
|
||
.title {
|
||
font-weight: 400;
|
||
font-size: 16px;
|
||
color: #1A1A1A;
|
||
|
||
text {
|
||
font-size: 13px !important;
|
||
color: #767676 !important;
|
||
}
|
||
}
|
||
|
||
.title-red {
|
||
color: #EE0115 !important;
|
||
}
|
||
|
||
.info {
|
||
|
||
view {
|
||
font-size: 13px;
|
||
color: #767676;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.call-list-oppo {
|
||
.item {
|
||
padding: 32rpx 36rpx 0 36rpx !important;
|
||
justify-content: space-between;
|
||
height: 140rpx;
|
||
}
|
||
|
||
.infoBox {
|
||
width: calc(100% - 46rpx) !important;
|
||
padding-bottom: 36rpx;
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
box-shadow: inset 0 -0.3px 0 0 #C2C2C2;
|
||
|
||
.title {
|
||
font-weight: 400;
|
||
font-size: 16px;
|
||
color: #1A1A1A;
|
||
}
|
||
|
||
.title-red {
|
||
color: #DB2C22 !important;
|
||
}
|
||
|
||
.info {
|
||
|
||
view {
|
||
font-size: 13px;
|
||
color: #767676;
|
||
}
|
||
|
||
.notes {
|
||
color: #F17A30;
|
||
}
|
||
}
|
||
|
||
.right-box {
|
||
.time {
|
||
color: #767676;
|
||
font-size: 13px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.avatar {
|
||
width: 26rpx !important;
|
||
height: 26rpx !important;
|
||
border-radius: 0 !important;
|
||
|
||
image {
|
||
width: 100% !important;
|
||
height: 100% !important;
|
||
}
|
||
}
|
||
|
||
.info {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
}
|
||
|
||
.call-list-vivo {
|
||
.item {
|
||
padding: 36rpx 52rpx 0 36rpx !important;
|
||
justify-content: space-between;
|
||
height: 140rpx;
|
||
|
||
.infoBox {
|
||
width: calc(100% - 52rpx) !important;
|
||
padding-bottom: 32rpx;
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
box-shadow: inset 0 -0.3px 0 0 #C2C2C2;
|
||
|
||
.title {
|
||
font-weight: 400;
|
||
font-size: 16px;
|
||
color: #1A1A1A;
|
||
}
|
||
|
||
.title-red {
|
||
color: #F04E51 !important;
|
||
}
|
||
|
||
.info {
|
||
|
||
view {
|
||
font-size: 12px;
|
||
color: #8C8C8C;
|
||
}
|
||
}
|
||
|
||
.right-box {
|
||
.time {
|
||
color: #8C8C8C;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.avatar {
|
||
width: 32rpx !important;
|
||
height: 32rpx !important;
|
||
border-radius: 0 !important;
|
||
|
||
image {
|
||
width: 100% !important;
|
||
height: 100% !important;
|
||
}
|
||
}
|
||
}
|
||
|
||
.call-list-huawei {
|
||
.item {
|
||
padding: 24rpx 32rpx 0 32rpx !important;
|
||
justify-content: space-between;
|
||
height: 120rpx;
|
||
}
|
||
|
||
.infoBox {
|
||
width: calc(100% - 52rpx) !important;
|
||
padding-bottom: 24rpx;
|
||
height: 100%;
|
||
box-sizing: border-box;
|
||
box-shadow: inset 0 -0.3px 0 0 #C2C2C2;
|
||
|
||
.title {
|
||
font-weight: 400;
|
||
font-size: 16px;
|
||
color: #1A1A1A;
|
||
}
|
||
|
||
.title-red {
|
||
color: #E83F28 !important;
|
||
}
|
||
|
||
.info {
|
||
|
||
view {
|
||
font-size: 13px;
|
||
color: #696969;
|
||
}
|
||
}
|
||
|
||
.right-box {
|
||
.time {
|
||
color: #696969;
|
||
font-size: 13px;
|
||
}
|
||
}
|
||
}
|
||
|
||
.avatar {
|
||
width: 32rpx !important;
|
||
height: 32rpx !important;
|
||
border-radius: 0 !important;
|
||
|
||
image {
|
||
width: 100% !important;
|
||
height: 100% !important;
|
||
}
|
||
}
|
||
|
||
.info {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
}
|
||
|
||
.modal-mask {
|
||
position: fixed;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
background-color: rgba(0, 0, 0, 0.5);
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
z-index: 999;
|
||
}
|
||
|
||
.modal-content {
|
||
width: 600rpx;
|
||
background-color: #fff;
|
||
border-radius: 16rpx;
|
||
overflow: hidden;
|
||
max-height: 80vh;
|
||
overflow-y: auto;
|
||
}
|
||
|
||
.modal-header {
|
||
padding: 40rpx;
|
||
text-align: center;
|
||
border-bottom: 1rpx solid #f0f0f0;
|
||
}
|
||
|
||
.modal-title {
|
||
font-size: 36rpx;
|
||
font-weight: bold;
|
||
color: #333;
|
||
}
|
||
|
||
.modal-body {
|
||
padding: 40rpx;
|
||
height: calc(80vh - 260rpx);
|
||
overflow-x: scroll;
|
||
}
|
||
|
||
.form-item {
|
||
margin-bottom: 30rpx;
|
||
}
|
||
|
||
.form-label {
|
||
display: block;
|
||
font-size: 28rpx;
|
||
color: #666;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.form-input {
|
||
width: 100%;
|
||
height: 80rpx;
|
||
border: 1rpx solid #ddd;
|
||
border-radius: 8rpx;
|
||
padding: 0 20rpx;
|
||
font-size: 28rpx;
|
||
box-sizing: border-box;
|
||
color: #1A1A1A;
|
||
}
|
||
|
||
.form-avatar-container {
|
||
display: flex;
|
||
align-items: center;
|
||
}
|
||
|
||
.form-avatar {
|
||
width: 80px;
|
||
height: 80px;
|
||
border: 1px dashed #666;
|
||
|
||
image {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
}
|
||
|
||
.form-text-avatar {
|
||
width: 80px;
|
||
height: 80px;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: white;
|
||
font-size: 40rpx;
|
||
font-weight: bold;
|
||
background: linear-gradient(180deg, #A1A8B8 0%, #878B94 100%);
|
||
border: 1px dashed #666;
|
||
}
|
||
|
||
.avatar-clear {
|
||
margin-left: 20rpx;
|
||
color: #007AFF;
|
||
font-size: 28rpx;
|
||
cursor: pointer;
|
||
}
|
||
|
||
.text-avatar {
|
||
width: 84rpx;
|
||
height: 84rpx;
|
||
border-radius: 50%;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: white;
|
||
font-size: 40rpx;
|
||
font-weight: bold;
|
||
background: linear-gradient(180deg, #A1A8B8 0%, #878B94 100%);
|
||
}
|
||
|
||
.form-input-time {
|
||
line-height: 40px;
|
||
}
|
||
|
||
.form-picker {
|
||
width: 100%;
|
||
height: 80rpx;
|
||
border: 1rpx solid #ddd;
|
||
border-radius: 8rpx;
|
||
padding: 0 20rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.form-picker-content {
|
||
height: 100%;
|
||
font-size: 28rpx;
|
||
color: #333;
|
||
}
|
||
|
||
.modal-footer {
|
||
display: flex;
|
||
border-top: 1rpx solid #f0f0f0;
|
||
height: 120rpx;
|
||
}
|
||
|
||
.btn {
|
||
flex: 1;
|
||
height: 100rpx;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
font-size: 32rpx;
|
||
background: #F1F1F1;
|
||
margin: 10rpx;
|
||
border-radius: 6px 6px 6px 6px;
|
||
}
|
||
|
||
.btn-random {
|
||
border-right: 1rpx solid #f0f0f0;
|
||
background: #FF9500;
|
||
color: #fff;
|
||
}
|
||
|
||
.btn-cancel {
|
||
border-right: 1rpx solid #f0f0f0;
|
||
color: #666;
|
||
}
|
||
|
||
.btn-confirm {
|
||
color: #fff;
|
||
background: #007AFF;
|
||
}
|
||
|
||
.timeBox {
|
||
background-color: #fff;
|
||
|
||
.titleBox {
|
||
padding: 10px;
|
||
display: flex;
|
||
justify-content: flex-end;
|
||
|
||
.btns {
|
||
font-size: 12px;
|
||
color: #007AFF;
|
||
}
|
||
}
|
||
}
|
||
</style> |