完善内容(home)
This commit is contained in:
parent
eaab5d5c69
commit
148ca25b00
|
|
@ -0,0 +1,5 @@
|
|||
import { get, post, put, del } from '../utils/request';
|
||||
|
||||
export const inviteCode = (data : any = {}) => get('v1/invite.code', data);
|
||||
|
||||
export const inviteList = (data : any = {}) => get('v1/invite.list', data);
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
<template>
|
||||
<view class="permission-sheet">
|
||||
<view class="permission-sheet-header">
|
||||
<text class="permission-sheet-title">权限设置</text>
|
||||
<view class="permission-sheet-staff">{{ staff ? staff.name : '' }}</view>
|
||||
</view>
|
||||
|
||||
<scroll-view scroll-y class="permission-list">
|
||||
<!-- 常用权限 -->
|
||||
<view class="permission-category">
|
||||
<view class="category-title">常用权限</view>
|
||||
<view class="permission-items">
|
||||
<view
|
||||
v-for="(item, index) in commonPermissions"
|
||||
:key="index"
|
||||
class="permission-item"
|
||||
:class="{ active: hasPermission(item.value) }"
|
||||
@click="togglePermission(item.value)"
|
||||
>
|
||||
<view class="permission-icon" :class="item.colorClass">
|
||||
<text class="iconfont" :class="item.icon"></text>
|
||||
</view>
|
||||
<view class="permission-info">
|
||||
<view class="permission-name">{{ item.label }}</view>
|
||||
<view class="permission-desc">{{ item.description }}</view>
|
||||
</view>
|
||||
<view class="permission-switch">
|
||||
<text class="ri-checkbox-circle-fill" v-if="hasPermission(item.value)"></text>
|
||||
<text class="ri-checkbox-blank-circle-line" v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 其他权限 -->
|
||||
<view class="permission-category">
|
||||
<view class="category-title">其他权限</view>
|
||||
<view class="permission-items">
|
||||
<view
|
||||
v-for="(item, index) in otherPermissions"
|
||||
:key="index"
|
||||
class="permission-item"
|
||||
:class="{ active: hasPermission(item.value) }"
|
||||
@click="togglePermission(item.value)"
|
||||
>
|
||||
<view class="permission-icon" :class="item.colorClass">
|
||||
<text class="iconfont" :class="item.icon"></text>
|
||||
</view>
|
||||
<view class="permission-info">
|
||||
<view class="permission-name">{{ item.label }}</view>
|
||||
<view class="permission-desc">{{ item.description }}</view>
|
||||
</view>
|
||||
<view class="permission-switch">
|
||||
<text class="ri-checkbox-circle-fill" v-if="hasPermission(item.value)"></text>
|
||||
<text class="ri-checkbox-blank-circle-line" v-else></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
||||
<view class="permission-sheet-footer">
|
||||
<button class="btn-cancel" @click="handleCancel">取消</button>
|
||||
<button class="btn-save" @click="handleSave">保存</button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue';
|
||||
|
||||
const props = defineProps({
|
||||
staff: {
|
||||
type: Object,
|
||||
default: () => null
|
||||
},
|
||||
permissions: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['save', 'cancel']);
|
||||
|
||||
// 常用权限和其他权限
|
||||
const commonPermissions = computed(() => {
|
||||
return props.permissions.filter(perm => perm.isCommon);
|
||||
});
|
||||
|
||||
const otherPermissions = computed(() => {
|
||||
return props.permissions.filter(perm => !perm.isCommon);
|
||||
});
|
||||
|
||||
/**
|
||||
* 检查权限是否已启用
|
||||
*/
|
||||
const hasPermission = (permission) => {
|
||||
if (!props.staff) return false;
|
||||
return props.staff.permissions.includes(permission);
|
||||
};
|
||||
|
||||
/**
|
||||
* 切换权限状态
|
||||
*/
|
||||
const togglePermission = (permission) => {
|
||||
if (!props.staff) return;
|
||||
|
||||
emit('toggle', permission);
|
||||
|
||||
const index = props.staff.permissions.indexOf(permission);
|
||||
|
||||
if (index > -1) {
|
||||
// 移除已有权限
|
||||
props.staff.permissions.splice(index, 1);
|
||||
} else {
|
||||
// 添加新权限
|
||||
props.staff.permissions.push(permission);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 取消操作
|
||||
*/
|
||||
const handleCancel = () => {
|
||||
emit('cancel');
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存操作
|
||||
*/
|
||||
const handleSave = () => {
|
||||
emit('save', props.staff);
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 权限设置面板 */
|
||||
.permission-sheet {
|
||||
padding: 20rpx;
|
||||
border-radius: 20rpx 20rpx 0 0;
|
||||
max-height: 70vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #fff;
|
||||
|
||||
&-header {
|
||||
padding: 20rpx 0;
|
||||
text-align: center;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: 32rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-staff {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-top: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.permission-list {
|
||||
flex: 1;
|
||||
max-height: 50vh;
|
||||
}
|
||||
|
||||
.permission-category {
|
||||
margin: 20rpx 0;
|
||||
|
||||
.category-title {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin-bottom: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.permission-items {
|
||||
border-radius: 12rpx;
|
||||
background-color: #f8f8f8;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.permission-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 20rpx;
|
||||
border-bottom: 1px solid #eee;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba(66, 165, 255, 0.05);
|
||||
}
|
||||
}
|
||||
|
||||
.permission-icon {
|
||||
width: 70rpx;
|
||||
height: 70rpx;
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-right: 20rpx;
|
||||
|
||||
.iconfont {
|
||||
font-size: 36rpx;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* 权限图标的颜色类 */
|
||||
&.delivery-color {
|
||||
background-color: #42a5ff;
|
||||
}
|
||||
|
||||
&.maintenance-color {
|
||||
background-color: #42a5ff;
|
||||
}
|
||||
|
||||
&.finance-color {
|
||||
background-color: #42a5ff;
|
||||
}
|
||||
|
||||
&.admin-color {
|
||||
background-color: #42a5ff;
|
||||
}
|
||||
|
||||
&.general-color {
|
||||
background-color: #42a5ff;
|
||||
}
|
||||
}
|
||||
|
||||
.permission-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.permission-name {
|
||||
font-size: 28rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.permission-desc {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-top: 6rpx;
|
||||
}
|
||||
|
||||
.permission-switch {
|
||||
width: 50rpx;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
|
||||
.ri-checkbox-circle-fill {
|
||||
font-size: 40rpx;
|
||||
color: #42a5ff;
|
||||
}
|
||||
|
||||
.ri-checkbox-blank-circle-line {
|
||||
font-size: 40rpx;
|
||||
color: #ddd;
|
||||
}
|
||||
}
|
||||
|
||||
.permission-sheet-footer {
|
||||
display: flex;
|
||||
padding: 20rpx 0;
|
||||
border-top: 1px solid #f0f0f0;
|
||||
|
||||
button {
|
||||
flex: 1;
|
||||
margin: 0 10rpx;
|
||||
height: 80rpx;
|
||||
line-height: 80rpx;
|
||||
font-size: 30rpx;
|
||||
border-radius: 40rpx;
|
||||
}
|
||||
|
||||
.btn-cancel {
|
||||
background-color: #f5f5f5;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.btn-save {
|
||||
background-color: #42a5ff;
|
||||
background-image: linear-gradient(135deg, #42a5ff, #0070F0);
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,51 +1,41 @@
|
|||
<template>
|
||||
<view>
|
||||
<u-popup :safeAreaInsetBottom='false' :show="show" @close="onClose" mode="center" :round="10">
|
||||
<view style="font-family: YouSheBiaoTiHei;">
|
||||
<wd-popup custom-class="my-custom-popup" v-model="innerShow" @close="onClose">
|
||||
<view class="share-poster">
|
||||
<!-- 海报画布 -->
|
||||
<canvas class="poster-canvas" canvas-id="posterCanvas"
|
||||
:style="{width: posterWidth + 'px',height: posterHeight + 'px',}"></canvas>
|
||||
|
||||
<!-- 分享操作按钮 -->
|
||||
<view class="share-actions">
|
||||
<view class="action-item left" @click="shareToFriend">
|
||||
微信分享
|
||||
</view>
|
||||
|
||||
<view class="action-item right" @click="savePoster">
|
||||
保存相册
|
||||
</view>
|
||||
</view>
|
||||
:style="{ width: posterWidth + 'px', height: posterHeight + 'px' }"></canvas>
|
||||
</view>
|
||||
</u-popup>
|
||||
<!-- 分享操作按钮 -->
|
||||
<view class="share-actions">
|
||||
<view class="action-item left" @click="shareToFriend"> 微信好友 </view>
|
||||
<view class="action-item right" @click="savePoster"> 保存相册 </view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
RESOURCES_URL
|
||||
} from '@/config/app'
|
||||
/**
|
||||
* @property {Object} goodsInfo - 商品信息
|
||||
* @property {string} goodsInfo.title - 商品标题
|
||||
* @property {number} goodsInfo.price - 商品价格
|
||||
* @property {string} goodsInfo.image - 商品主图URL
|
||||
* @property {string} goodsInfo.qrcode - 小程序码URL
|
||||
* @property {Object} posterInfo - 商品信息
|
||||
* @property {string} posterInfo.title - 商品标题
|
||||
* @property {number} posterInfo.price - 商品价格
|
||||
* @property {string} posterInfo.image - 商品主图URL
|
||||
* @property {string} posterInfo.qrcode - 小程序码URL
|
||||
* @property {boolean} show - 控制弹窗显示隐藏
|
||||
* @event updateShare - 弹窗关闭时触发,参数为false
|
||||
*/
|
||||
export default {
|
||||
name: 'SharePoster',
|
||||
props: {
|
||||
goodsInfo: {
|
||||
posterInfo: {
|
||||
type: Object,
|
||||
required: true,
|
||||
|
||||
default: () => ({
|
||||
title: '',
|
||||
price: 0,
|
||||
image: '',
|
||||
qrcode: '', // 小程序码URL
|
||||
name: '',
|
||||
qrcode: '',
|
||||
backImage: ''
|
||||
}),
|
||||
},
|
||||
show: {
|
||||
|
|
@ -55,6 +45,7 @@
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
innerShow: false, // 内部控制弹窗显示状态
|
||||
generating: false, // 海报生成状态
|
||||
posterWidth: 300, // 减小画布宽度
|
||||
posterHeight: 450, // 减小画布高度
|
||||
|
|
@ -69,17 +60,30 @@
|
|||
watch: {
|
||||
// 监听show变化,显示时生成海报
|
||||
show(newVal) {
|
||||
if (newVal) {
|
||||
this.$nextTick(() => {
|
||||
this.generatePoster()
|
||||
})
|
||||
}
|
||||
this.innerShow = newVal;
|
||||
// if (newVal) {
|
||||
this.$nextTick(() => {
|
||||
console.log('Show changed, generating poster')
|
||||
let self = this
|
||||
self.generatePoster()
|
||||
|
||||
// uni.loadFontFace({
|
||||
// family: 'YouSheBiaoTiHei',
|
||||
// source: 'url("https://hnxix-public.oss-cn-hangzhou.aliyuncs.com/driver/wx/font/YouSheBiaoTiHei.ttf")',
|
||||
// success() {
|
||||
// console.log('success')
|
||||
// self.generatePoster()
|
||||
// },
|
||||
// scopes: ["webview", "native"],
|
||||
// })
|
||||
})
|
||||
// }
|
||||
},
|
||||
goodsInfo: {
|
||||
posterInfo: {
|
||||
immediate: true,
|
||||
deep: true,
|
||||
handler(newVal) {
|
||||
console.log('SharePoster goodsInfo changed:', newVal)
|
||||
console.log('SharePoster posterInfo changed:', newVal)
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
@ -113,7 +117,6 @@
|
|||
async generatePoster() {
|
||||
if (this.generating) return
|
||||
this.generating = true
|
||||
|
||||
try {
|
||||
const ctx = uni.createCanvasContext('posterCanvas', this)
|
||||
// 清除画布
|
||||
|
|
@ -122,51 +125,61 @@
|
|||
// 首先绘制纯色背景,确保没有透明区域
|
||||
ctx.fillStyle = '#ffffff'
|
||||
ctx.fillRect(0, 0, this.posterWidth, this.posterHeight)
|
||||
|
||||
// 绘制背景图片 - 只填充上半部分
|
||||
const imageUrl = this.goodsInfo.image || ''
|
||||
const imageUrl = this.posterInfo.backImage || ''
|
||||
if (imageUrl) {
|
||||
// 只在上半部分绘制背景图
|
||||
await this.drawImage(ctx, imageUrl, 0, 0, this.posterWidth, this.posterHeight)
|
||||
}
|
||||
|
||||
|
||||
// 添加白色半透明遮罩作为内容背景
|
||||
// ctx.fillStyle = 'rgba(255, 255, 255, 0.85)'
|
||||
// ctx.fillRect(20, 80, this.posterWidth - 40, this.posterHeight - 100)
|
||||
// 绘制logo - 放在d顶部位置
|
||||
const share_title =
|
||||
'https://hnxix-public.oss-cn-hangzhou.aliyuncs.com/driver/wx/img/share_title.png'
|
||||
if (share_title) {
|
||||
const qrSize = 50
|
||||
const qrX = 15
|
||||
const qrY = 20 // 放在中间位置
|
||||
await this.drawImage(ctx, share_title, qrX, qrY, 100, 24)
|
||||
}
|
||||
|
||||
|
||||
// 绘制标题和品牌
|
||||
const gradient = ctx.createLinearGradient(15, 110, 15, 150)
|
||||
gradient.addColorStop(0, '#1068FF'); // 底部开始
|
||||
gradient.addColorStop(0.48, '#2B497E'); // 48%位置
|
||||
gradient.addColorStop(1, '#D51BB6'); // 顶部结束
|
||||
const gradient = ctx.createLinearGradient(22, 125, 80, 125)
|
||||
gradient.addColorStop(0, '#1068FF') // 底部开始
|
||||
gradient.addColorStop(0.48, '#2B497E') // 48%位置
|
||||
gradient.addColorStop(1, '#D51BB6') // 顶部结束
|
||||
|
||||
const gradient_sec = ctx.createLinearGradient(22, 160, 130, 160)
|
||||
gradient_sec.addColorStop(0, '#1068FF') // 底部开始
|
||||
gradient_sec.addColorStop(0.48, '#2B497E') // 48%位置
|
||||
gradient_sec.addColorStop(1, '#D51BB6') // 顶部结束
|
||||
|
||||
ctx.shadowColor = 'rgba(0, 0, 0, 0.15)'
|
||||
ctx.shadowBlur = 2
|
||||
ctx.shadowOffsetX = 1
|
||||
ctx.shadowOffsetY = 1
|
||||
|
||||
|
||||
ctx.font = 'italic bold 20px sans-serif'
|
||||
ctx.setFontSize(19)
|
||||
ctx.setFontSize(15)
|
||||
ctx.setTextAlign('left')
|
||||
ctx.fillStyle = gradient
|
||||
ctx.fillText('王师傅', 15, 120)
|
||||
ctx.setFillStyle('#0060C4')
|
||||
let title = this.posterInfo.title || ''
|
||||
ctx.fillText(`${title}`, 18, 35)
|
||||
|
||||
|
||||
ctx.font = 'italic bold 20px sans-serif'
|
||||
// ctx.font = "20px bold 'YouSheBiaoTiHei'"
|
||||
ctx.setFontSize(16)
|
||||
ctx.setTextAlign('left')
|
||||
ctx.setFillStyle('#21CCF9')
|
||||
let first = this.posterInfo.name || ''
|
||||
ctx.fillText(`${first}`, 18, 136)
|
||||
|
||||
|
||||
// 绘制副标题
|
||||
ctx.font = 'italic bold 20px sans-serif'
|
||||
ctx.setFontSize(19)
|
||||
// ctx.font = "20px bold 'YouSheBiaoTiHei'"
|
||||
ctx.setFontSize(16)
|
||||
ctx.setTextAlign('left')
|
||||
ctx.fillStyle = gradient
|
||||
ctx.fillText('邀请您预约行程', 15, 150)
|
||||
ctx.setFillStyle('#21CCF9')
|
||||
ctx.fillText('邀请您入驻小区', 18, 170)
|
||||
|
||||
|
||||
// 重置阴影效果
|
||||
ctx.shadowColor = 'transparent'
|
||||
|
|
@ -174,8 +187,7 @@
|
|||
ctx.shadowOffsetX = 0
|
||||
ctx.shadowOffsetY = 0
|
||||
|
||||
// 绘制小程序码 - 放在中下部位置
|
||||
const qrcodeUrl = this.goodsInfo.qrcode
|
||||
const qrcodeUrl = this.posterInfo.qrcode || ''
|
||||
if (qrcodeUrl) {
|
||||
const qrSize = 150
|
||||
const qrX = (this.posterWidth - qrSize) / 2
|
||||
|
|
@ -187,7 +199,7 @@
|
|||
ctx.setFontSize(11)
|
||||
ctx.setFillStyle('#666666')
|
||||
ctx.setTextAlign('center')
|
||||
ctx.fillText('微信扫码,预约行程', this.posterWidth / 2, 420)
|
||||
ctx.fillText('微信扫码入驻,获取更多特权', this.posterWidth / 2, 420)
|
||||
|
||||
ctx.draw(false, () => {
|
||||
setTimeout(() => {
|
||||
|
|
@ -236,7 +248,7 @@
|
|||
x: Math.floor(x),
|
||||
y: Math.floor(y),
|
||||
width: Math.floor(finalWidth),
|
||||
height: Math.floor(finalHeight)
|
||||
height: Math.floor(finalHeight),
|
||||
}
|
||||
},
|
||||
/**
|
||||
|
|
@ -260,22 +272,11 @@
|
|||
// 背景图片,使用覆盖模式
|
||||
const rect = this.calculateImageRect(image.width, image.height, width,
|
||||
height)
|
||||
ctx.drawImage(
|
||||
image.path,
|
||||
x + rect.x,
|
||||
y + rect.y,
|
||||
rect.width,
|
||||
rect.height
|
||||
);
|
||||
ctx.drawImage(image.path, x + rect.x, y + rect.y, rect.width, rect
|
||||
.height)
|
||||
} else {
|
||||
// 其他元素(如二维码等),保持原样绘制
|
||||
ctx.drawImage(
|
||||
image.path,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height
|
||||
);
|
||||
ctx.drawImage(image.path, x, y, width, height)
|
||||
}
|
||||
resolve()
|
||||
},
|
||||
|
|
@ -341,6 +342,31 @@
|
|||
uni.canvasToTempFilePath({
|
||||
canvasId: 'posterCanvas',
|
||||
success: (res) => {
|
||||
console.log(res, '000')
|
||||
|
||||
// APP环境下,使用uni.share实现分享到微信
|
||||
// #ifdef APP-PLUS
|
||||
uni.share({
|
||||
provider: 'weixin',
|
||||
scene: 'WXSceneSession', // WXSceneSession = 好友,WXSceneTimeline = 朋友圈
|
||||
type: 2,
|
||||
imageUrl: res.tempFilePath,
|
||||
success: function() {
|
||||
console.log('分享图片成功')
|
||||
},
|
||||
fail: function(err) {
|
||||
console.log('分享图片失败:', err)
|
||||
// 提示用户
|
||||
uni.showToast({
|
||||
title: '分享失败',
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
})
|
||||
// #endif
|
||||
|
||||
// 小程序环境下使用showShareImageMenu
|
||||
// #ifdef MP-WEIXIN
|
||||
uni.showShareImageMenu({
|
||||
path: res.tempFilePath,
|
||||
success: function() {
|
||||
|
|
@ -350,32 +376,74 @@
|
|||
console.log('分享图片失败:', err)
|
||||
},
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
},
|
||||
this
|
||||
)
|
||||
},
|
||||
|
||||
/**
|
||||
* 分享到朋友圈
|
||||
*/
|
||||
// shareToTimeline() {
|
||||
// uni.canvasToTempFilePath({
|
||||
// canvasId: 'posterCanvas',
|
||||
// success: (res) => {
|
||||
// // APP环境下,使用uni.share实现分享到朋友圈
|
||||
// // #ifdef APP-PLUS
|
||||
// uni.share({
|
||||
// provider: 'weixin',
|
||||
// scene: 'WXSceneTimeline', // 分享到朋友圈
|
||||
// type: 'image',
|
||||
// imageUrl: res.tempFilePath,
|
||||
// success: function() {
|
||||
// console.log('分享到朋友圈成功')
|
||||
// },
|
||||
// fail: function(err) {
|
||||
// console.log('分享到朋友圈失败:', err)
|
||||
// // 提示用户
|
||||
// uni.showToast({
|
||||
// title: '分享失败',
|
||||
// icon: 'none'
|
||||
// })
|
||||
// }
|
||||
// })
|
||||
// // #endif
|
||||
|
||||
// // 小程序环境下提示用户
|
||||
// // #ifdef MP-WEIXIN
|
||||
// uni.showToast({
|
||||
// title: '小程序环境不支持直接分享到朋友圈,请保存图片后手动分享',
|
||||
// icon: 'none'
|
||||
// })
|
||||
// // #endif
|
||||
// },
|
||||
// },
|
||||
// this
|
||||
// )
|
||||
// },
|
||||
|
||||
/**
|
||||
* 保存到本地
|
||||
*/
|
||||
savePoster() {
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信小程序需要检查权限
|
||||
this.checkAndRequestPermission();
|
||||
this.checkAndRequestPermission()
|
||||
// #endif
|
||||
|
||||
|
||||
// #ifdef APP-PLUS || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO
|
||||
// 其他平台直接保存
|
||||
this.saveImageToAlbum();
|
||||
this.saveImageToAlbum()
|
||||
// #endif
|
||||
|
||||
|
||||
// #ifdef H5
|
||||
// H5环境下的处理
|
||||
uni.showToast({
|
||||
title: 'H5环境不支持保存到相册',
|
||||
icon: 'none'
|
||||
});
|
||||
icon: 'none',
|
||||
})
|
||||
// #endif
|
||||
},
|
||||
|
||||
|
|
@ -389,29 +457,30 @@
|
|||
uni.authorize({
|
||||
scope: 'scope.writePhotosAlbum',
|
||||
success: () => {
|
||||
this.saveImageToAlbum();
|
||||
this.saveImageToAlbum()
|
||||
},
|
||||
fail: () => {
|
||||
this.showAuthModal();
|
||||
}
|
||||
});
|
||||
this.showAuthModal()
|
||||
},
|
||||
})
|
||||
} else {
|
||||
this.saveImageToAlbum();
|
||||
this.saveImageToAlbum()
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('获取设置失败:', err);
|
||||
console.log('获取设置失败:', err)
|
||||
uni.showToast({
|
||||
title: '获取权限失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
});
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 显示授权引导弹窗
|
||||
*/
|
||||
|
||||
showAuthModal() {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
|
|
@ -420,51 +489,58 @@
|
|||
cancelText: '取消',
|
||||
success: (res) => {
|
||||
if (res.confirm) {
|
||||
uni.openSetting();
|
||||
uni.openSetting()
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
/**
|
||||
* 实际保存图片的方法
|
||||
*/
|
||||
saveImageToAlbum() {
|
||||
uni.showLoading({
|
||||
title: '保存中...',
|
||||
mask: true,
|
||||
})
|
||||
uni.canvasToTempFilePath({
|
||||
canvasId: 'posterCanvas',
|
||||
success: (res) => {
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '已保存至相册,去朋友圈分享',
|
||||
icon: 'none',
|
||||
});
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('保存失败:', err);
|
||||
// 检查是否是权限问题
|
||||
if (err.errMsg.indexOf('auth deny') > -1) {
|
||||
// #ifdef MP-WEIXIN
|
||||
this.showAuthModal();
|
||||
// #endif
|
||||
} else {
|
||||
canvasId: 'posterCanvas',
|
||||
success: (res) => {
|
||||
uni.hideLoading()
|
||||
uni.saveImageToPhotosAlbum({
|
||||
filePath: res.tempFilePath,
|
||||
success: () => {
|
||||
uni.showToast({
|
||||
title: '保存失败',
|
||||
title: '已保存至相册,去朋友圈分享',
|
||||
icon: 'none',
|
||||
});
|
||||
}
|
||||
},
|
||||
});
|
||||
})
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('保存失败:', err)
|
||||
// 检查是否是权限问题
|
||||
if (err.errMsg.indexOf('auth deny') > -1) {
|
||||
// #ifdef MP-WEIXIN
|
||||
this.showAuthModal()
|
||||
// #endif
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: '保存失败',
|
||||
icon: 'none',
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('生成临时文件失败:', err)
|
||||
uni.showToast({
|
||||
title: '生成图片失败',
|
||||
icon: 'none',
|
||||
})
|
||||
},
|
||||
},
|
||||
fail: (err) => {
|
||||
console.log('生成临时文件失败:', err);
|
||||
uni.showToast({
|
||||
title: '生成图片失败',
|
||||
icon: 'none',
|
||||
});
|
||||
}
|
||||
}, this);
|
||||
this
|
||||
)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
@ -473,18 +549,19 @@
|
|||
<style lang="scss" scoped>
|
||||
@font-face {
|
||||
font-family: 'YouSheBiaoTiHei';
|
||||
src: url('https: //hnxix-public.oss-cn-hangzhou.aliyuncs.com/driver/wx/font/YouSheBiaoTiHei.ttf');
|
||||
src: url('https://hnxix-public.oss-cn-hangzhou.aliyuncs.com/driver/wx/font/YouSheBiaoTiHei.ttf');
|
||||
}
|
||||
|
||||
.test {
|
||||
font-family: 'YouSheBiaoTiHei';
|
||||
}
|
||||
|
||||
/* 海报容器 */
|
||||
.share-poster {
|
||||
outline: none;
|
||||
// background-color: #fff;
|
||||
border-radius: 20rpx;
|
||||
overflow: hidden;
|
||||
max-height: 60vh;
|
||||
// overflow-y: auto;
|
||||
// padding-bottom: 140rpx; // 为底部按钮留出空间
|
||||
|
||||
/* 画布样式 */
|
||||
.poster-canvas {
|
||||
|
|
@ -493,35 +570,42 @@
|
|||
// background: #fff;
|
||||
}
|
||||
|
||||
/* 分享按钮组 */
|
||||
.share-actions {
|
||||
position: fixed;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 140rpx;
|
||||
}
|
||||
|
||||
/* 分享按钮组 */
|
||||
.share-actions {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: -200rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 20rpx 30rpx;
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20rpx 40rpx;
|
||||
padding: 20rpx 30rpx;
|
||||
border-radius: 40rpx;
|
||||
min-width: 80rpx;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.action-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 28rpx 40rpx;
|
||||
border-radius: 40rpx;
|
||||
.left {
|
||||
background-color: #0ed05f;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
}
|
||||
.middle {
|
||||
background-color: #1aad19;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.left {
|
||||
background-color: #0ED05F;
|
||||
color: #FFFFFF;
|
||||
}
|
||||
|
||||
.right {
|
||||
background-color: #FFFFFF;
|
||||
color: #000000;
|
||||
}
|
||||
.right {
|
||||
background-color: #ffffff;
|
||||
color: #000000;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -532,4 +616,16 @@
|
|||
// ::v-deep .u-popup__content {
|
||||
// background-color: rebeccapurple !important;
|
||||
// }
|
||||
::v-deep .wd-popup-wrapper .wd-popup {
|
||||
overflow-y: visible !important;
|
||||
}
|
||||
|
||||
::v-deep(.wd-popup-wrapper .wd-popup) {
|
||||
overflow-y: visible !important;
|
||||
}
|
||||
|
||||
:deep(.my-custom-popup.wd-popup) {
|
||||
/* 样式 */
|
||||
overflow-y: visible !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"dependencies": {
|
||||
"pinia-plugin-persistedstate": "^4.2.0",
|
||||
"crypto-js": "^4.2.0"
|
||||
"crypto-js": "^4.2.0",
|
||||
"pinia-plugin-persistedstate": "^4.2.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
54
pages.json
54
pages.json
|
|
@ -239,6 +239,60 @@
|
|||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "房源详情"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "permissions/villageList",
|
||||
"style": {
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "小区列表"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "permissions/staffList",
|
||||
"style": {
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "员工列表"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "permissions/addStaff",
|
||||
"style": {
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "添加员工"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "agreement/index",
|
||||
"style": {
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "用户协议隐私政策"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "setting/index",
|
||||
"style": {
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "用户协议隐私政策"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "setting/editInfo",
|
||||
"style": {
|
||||
"enablePullDownRefresh": false,
|
||||
"navigationBarTextStyle": "black",
|
||||
"navigationStyle": "custom",
|
||||
"navigationBarTitleText": "用户协议隐私政策"
|
||||
}
|
||||
}
|
||||
]
|
||||
}],
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@
|
|||
class="li-w-88% li-h-220 li-mx-auto li-mt-20 li-pt-15">
|
||||
<text class="li-ml-35 li-text-30 li-text-#010B3E">代处理事项</text>
|
||||
<view class="li-flex justify-between items-center li-px-50 li-mt-20">
|
||||
<view class="li-flex li-flex-col items-center" v-for="(item,index) in toDoList" :key="index">
|
||||
<view class="li-flex li-flex-col items-center" v-for="(item,index) in toDoList" :key="index"
|
||||
@click="toPages({type:'my_order'})">
|
||||
<text :class="[index==2?'li-text-#F42429':'li-text-#010B3E']"
|
||||
class="li-text-43 li-font-bold">{{item.num}}</text>
|
||||
<text class="li-text-24 li-text-#AFB2B8">{{item.desc}}</text>
|
||||
|
|
@ -85,6 +86,9 @@
|
|||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="problemList?.length === 0" class="empty-state">
|
||||
<wd-status-tip image="collect" tip="暂无常见问题解答" />
|
||||
</view>
|
||||
</view>
|
||||
<!-- 悬浮按钮 -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
|
|
@ -94,7 +98,7 @@
|
|||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
<view>
|
||||
<view v-if="problemList?.length > 0">
|
||||
<wd-loadmore loading-text="努力加载中" finished-text="没有更多了" :state="state" @reload="loadmore" />
|
||||
</view>
|
||||
</view>
|
||||
|
|
@ -129,8 +133,9 @@
|
|||
const porcelainList = ref([
|
||||
{
|
||||
image: uni.$globalData?.RESOURCE_URL + 'home/back1.png',
|
||||
title: '新建任务',
|
||||
desc: '新建工单任务'
|
||||
title: '我的工单',
|
||||
desc: '工单一键处理',
|
||||
type: 'my_order'
|
||||
},
|
||||
{
|
||||
image: uni.$globalData?.RESOURCE_URL + 'home/back2.png',
|
||||
|
|
@ -140,11 +145,11 @@
|
|||
}
|
||||
])
|
||||
const gridList = ref([
|
||||
{
|
||||
image: uni.$globalData?.RESOURCE_URL + 'home/grid/xiaoxi.png',
|
||||
title: '我的工单',
|
||||
type: 'my_order'
|
||||
},
|
||||
// {
|
||||
// image: uni.$globalData?.RESOURCE_URL + 'home/grid/xiaoxi.png',
|
||||
// title: '我的工单',
|
||||
// type: 'my_order'
|
||||
// },
|
||||
{
|
||||
image: uni.$globalData?.RESOURCE_URL + 'home/grid/yaoqing.png',
|
||||
title: '邀请业主',
|
||||
|
|
@ -160,31 +165,36 @@
|
|||
title: '投诉管理',
|
||||
type: 'complaint'
|
||||
},
|
||||
{
|
||||
image:uni.$globalData?.RESOURCE_URL + 'home/grid/fangke.png' ,
|
||||
title: '访客邀请',
|
||||
type: ''
|
||||
},
|
||||
{
|
||||
image: uni.$globalData?.RESOURCE_URL + 'home/grid/wenjuan.png',
|
||||
title: '问卷管理',
|
||||
type: 'questionnaire'
|
||||
},
|
||||
{
|
||||
image: uni.$globalData?.RESOURCE_URL + 'home/grid/fangyuan.png',
|
||||
title: '房源管理',
|
||||
type: 'housing'
|
||||
},
|
||||
// {
|
||||
// image: uni.$globalData?.RESOURCE_URL + 'home/grid/fangke.png',
|
||||
// title: '访客邀请',
|
||||
// type: ''
|
||||
// },
|
||||
// {
|
||||
// image: uni.$globalData?.RESOURCE_URL + 'home/grid/wenjuan.png',
|
||||
// title: '问卷管理',
|
||||
// type: 'questionnaire'
|
||||
// },
|
||||
// {
|
||||
// image: uni.$globalData?.RESOURCE_URL + 'home/grid/fangyuan.png',
|
||||
// title: '房源管理',
|
||||
// type: 'housing'
|
||||
// },
|
||||
// {
|
||||
// image: uni.$globalData?.RESOURCE_URL + 'home/grid/chewei.png',
|
||||
// title: '车位管理',
|
||||
// type: ''
|
||||
// },
|
||||
{
|
||||
image:uni.$globalData?.RESOURCE_URL + 'home/grid/gongdan.png' ,
|
||||
image: uni.$globalData?.RESOURCE_URL + 'home/grid/gongdan.png',
|
||||
title: '商品核销',
|
||||
type: 'verification'
|
||||
}
|
||||
},
|
||||
// {
|
||||
// image: uni.$globalData?.RESOURCE_URL + 'home/grid/gongdan.png',
|
||||
// title: '员工权限',
|
||||
// type: 'permissions'
|
||||
// }
|
||||
|
||||
])
|
||||
|
||||
|
|
@ -204,24 +214,24 @@
|
|||
])
|
||||
|
||||
const problemList = ref([
|
||||
{
|
||||
image: '/static/swiper/1.png',
|
||||
title: '如何创建工单任务',
|
||||
time: '2025-06',
|
||||
viewCount: '200'
|
||||
},
|
||||
{
|
||||
image: '/static/swiper/1.png',
|
||||
title: '巡检任务审核说明',
|
||||
time: '2025-06',
|
||||
viewCount: '200'
|
||||
},
|
||||
{
|
||||
image: '/static/swiper/1.png',
|
||||
title: '物业员工催缴流程',
|
||||
time: '2025-06',
|
||||
viewCount: '200'
|
||||
}
|
||||
// {
|
||||
// image: '/static/swiper/1.png',
|
||||
// title: '如何创建工单任务',
|
||||
// time: '2025-06',
|
||||
// viewCount: '200'
|
||||
// },
|
||||
// {
|
||||
// image: '/static/swiper/1.png',
|
||||
// title: '巡检任务审核说明',
|
||||
// time: '2025-06',
|
||||
// viewCount: '200'
|
||||
// },
|
||||
// {
|
||||
// image: '/static/swiper/1.png',
|
||||
// title: '物业员工催缴流程',
|
||||
// time: '2025-06',
|
||||
// viewCount: '200'
|
||||
// }
|
||||
])
|
||||
|
||||
const handleClick = (e) => {
|
||||
|
|
@ -240,7 +250,7 @@
|
|||
});
|
||||
break;
|
||||
case 'my_order':
|
||||
// 工单大厅
|
||||
// 我的工单
|
||||
uni.navigateTo({
|
||||
url: '/pagesA/my_order/list'
|
||||
});
|
||||
|
|
@ -299,6 +309,12 @@
|
|||
url: '/pagesB/housing/list'
|
||||
});
|
||||
break;
|
||||
case 'permissions':
|
||||
//员工权限
|
||||
uni.navigateTo({
|
||||
url: '/pagesB/permissions/villageList'
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,13 +14,13 @@
|
|||
</view>
|
||||
<image class="li-w-240 li-h-240" :src="mine_back" mode="aspectFill"></image>
|
||||
</view>
|
||||
<view class="li-w-70% li-ml-50 li-flex li-justify-between li-items-center">
|
||||
<!-- <view class="li-w-70% li-ml-50 li-flex li-justify-between li-items-center">
|
||||
<view class="li-flex li-flex-col li-justify-center li-items-center" v-for="(item,index) in incomeList"
|
||||
:key="index">
|
||||
<text class="li-text-#b1bbc7 li-text-24">{{item.title}}</text>
|
||||
<text class="li-text-#010B3E li-text-34 li-mt-6 li-font-bold">{{item.number}}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view> -->
|
||||
<!-- card -->
|
||||
<view
|
||||
class="li-w-94% li-mx-auto li-flex li-justify-between li-items-center li-py-20 !li-rd-tl-30 !li-rd-tr-30 li-mt-20"
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
</view>
|
||||
<view class="li-flex li-justify-between li-items-center li-mx-40 li-mt-30">
|
||||
<view class="li-flex li-flex-col li-justify-center li-items-center" v-for="(item,index) in workList"
|
||||
:key="index">
|
||||
:key="index" @click="toPages({type:item.type})">
|
||||
<wd-badge :hidden="item.number > 0 ? false:true" :modelValue="item.number" top='5' right="-2"
|
||||
:max='99'>
|
||||
<image class="li-w-60 li-h-60" :src="item.icon" mode=""></image>
|
||||
|
|
@ -57,10 +57,11 @@
|
|||
|
||||
<view class="li-w-94% li-mx-auto li-mt-26 li-bg-white li-rd-20 li-pb-20">
|
||||
<view class="li-flex li-justify-between li-items-center li-pt-20 li-mx-20 li-pb-10">
|
||||
<text class="li-text-#19171B li-text-32">常用功能</text>
|
||||
<text class="li-text-#19171B li-text-32">其他功能</text>
|
||||
</view>
|
||||
<wd-grid class="" :column="4" :clickable="true">
|
||||
<wd-grid-item use-icon-slot use-text-slot v-for="(item,index) in frequentlyList" :key="index">
|
||||
<wd-grid-item use-icon-slot use-text-slot v-for="(item,index) in frequentlyList" :key="index"
|
||||
@click="toPages({type:item.type})">
|
||||
<template #icon>
|
||||
<wd-badge :hidden="item.number > 0 ? false:true" :modelValue="item.number" top='5' right="-2"
|
||||
:max='99'>
|
||||
|
|
@ -109,46 +110,115 @@
|
|||
{
|
||||
title: '待入库',
|
||||
number: 12,
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/chuku.png'
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/chuku.png',
|
||||
type: 'warehousing',
|
||||
}, {
|
||||
title: '待配送',
|
||||
number: 11,
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/peisong.png'
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/peisong.png',
|
||||
type: 'my_order_F2',
|
||||
}, {
|
||||
title: '待报修',
|
||||
number: 0,
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/baoxiu.png'
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/baoxiu.png',
|
||||
type: 'my_order_F6',
|
||||
}, {
|
||||
title: '待催缴',
|
||||
number: 0,
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/cuijiao.png'
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/cuijiao.png',
|
||||
type: 'call'
|
||||
}
|
||||
])
|
||||
const frequentlyList = ref([
|
||||
// {
|
||||
// title: '投诉管理',
|
||||
// number: 0,
|
||||
// icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/tousu.png'
|
||||
// }, {
|
||||
// title: '巡检任务',
|
||||
// number: 11,
|
||||
// icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/xunjian.png'
|
||||
// }, {
|
||||
// title: '资产盘点',
|
||||
// number: 0,
|
||||
// icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/pandian.png'
|
||||
// }, {
|
||||
// title: '门禁申请',
|
||||
// number: 0,
|
||||
// icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/menjin.png'
|
||||
// },
|
||||
{
|
||||
title: '投诉管理',
|
||||
title: '用户协议',
|
||||
number: 0,
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/tousu.png'
|
||||
}, {
|
||||
title: '巡检任务',
|
||||
number: 11,
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/xunjian.png'
|
||||
}, {
|
||||
title: '资产盘点',
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/pandian.png',
|
||||
type: 'protocol'
|
||||
},
|
||||
{
|
||||
title: '隐私政策',
|
||||
number: 0,
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/pandian.png'
|
||||
}, {
|
||||
title: '门禁申请',
|
||||
number: 0,
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/menjin.png'
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/menjin.png',
|
||||
type: 'privacy'
|
||||
},
|
||||
{
|
||||
title: '设置',
|
||||
number: 0,
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/shezhi.png'
|
||||
icon: uni.$globalData?.RESOURCE_URL + 'mine/icon/shezhi.png',
|
||||
type: 'setting'
|
||||
}
|
||||
])
|
||||
|
||||
|
||||
const toPages = (item) => {
|
||||
console.log('111111111111');
|
||||
switch (item.type) {
|
||||
case 'warehousing':
|
||||
// 入库
|
||||
uni.navigateTo({
|
||||
url: '/pagesA/warehousing/index'
|
||||
});
|
||||
break;
|
||||
case 'my_order_F2':
|
||||
// 待配送
|
||||
uni.navigateTo({
|
||||
url: '/pagesA/my_order/list?type=1&status=1'
|
||||
});
|
||||
break;
|
||||
case 'my_order_F6':
|
||||
// 待维修
|
||||
uni.navigateTo({
|
||||
url: '/pagesA/my_order/list?type=2&status=1'
|
||||
});
|
||||
break;
|
||||
case 'call':
|
||||
// 入库
|
||||
uni.navigateTo({
|
||||
url: '/pagesB/call/index'
|
||||
});
|
||||
break;
|
||||
case 'protocol':
|
||||
// 用户协议
|
||||
uni.navigateTo({
|
||||
url: '/pagesB/agreement/index?type=1'
|
||||
});
|
||||
break;
|
||||
case 'privacy':
|
||||
// 隐私政策
|
||||
uni.navigateTo({
|
||||
url: '/pagesB/agreement/index?type=2'
|
||||
});
|
||||
break;
|
||||
case 'setting':
|
||||
// 隐私政策
|
||||
uni.navigateTo({
|
||||
url: '/pagesB/setting/index'
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onShow(async () => {
|
||||
const userInfo = await uni.$store.state.userInfos
|
||||
userInfo.realname && (user_info.value.realname = userInfo.realname)
|
||||
|
|
|
|||
|
|
@ -22,22 +22,27 @@
|
|||
<view class="invite-card li-w-92% li-mx-auto li-mt-40 li-bg-white li-rd-20 li-shadow-sm li-p-30">
|
||||
<view class="card-header li-flex li-justify-between li-items-center">
|
||||
<text class="li-text-36 li-text-#333">邀请福利</text>
|
||||
<text class="li-text-28 li-text-#0070F0" @click="showRules">活动规则</text>
|
||||
<!-- <text class="li-text-28 li-text-#0070F0" @click="showRules">活动规则</text> -->
|
||||
</view>
|
||||
<view class="card-content li-mt-30">
|
||||
<!-- 主要返佣说明 -->
|
||||
<view
|
||||
:style="{backgroundImage:`url(${card_back})`,backgroundSize:'cover',backgroundPosition:'center'}"
|
||||
<view :style="{backgroundImage:`url(${card_back})`,backgroundSize:'cover',backgroundPosition:'center'}"
|
||||
class="commission-card li-bg-gradient-to-r li-from-#4481EB li-to-#0070F0 li-rd-20 li-p-30 li-mb-30">
|
||||
<view class="li-flex li-items-center li-mb-20">
|
||||
<text class="ri-shopping-bag-3-line li-text-48 li-text-#0a4696"></text>
|
||||
<text class="li-text-34 li-text-#0a4696 li-ml-15 li-font-medium">业主消费返佣</text>
|
||||
<text
|
||||
class="li-text-34 li-text-#0a4696 li-ml-15 li-font-medium">{{codeInfo?.config?.shop_brokerage_mode==1?'业主消费返佣':'业主关系'}}</text>
|
||||
</view>
|
||||
<view class="li-flex li-items-baseline li-mb-15">
|
||||
<text class="li-text-70 li-text-#0a4696 li-font-bold">5</text>
|
||||
<view v-if="codeInfo?.config?.shop_brokerage_mode == 1" class="li-flex li-items-baseline li-mb-15">
|
||||
<text
|
||||
class="li-text-70 li-text-#0a4696 li-font-bold">{{codeInfo?.config?.employee_shop_brokerage_rate}}</text>
|
||||
<text class="li-text-34 li-text-#0a4696 li-ml-10">%</text>
|
||||
</view>
|
||||
<text class="li-text-26 li-text-#0a4696 li-opacity-100">邀请的业主每笔消费,您都可获得返佣</text>
|
||||
<view v-else class="li-flex li-items-baseline li-mb-15">
|
||||
<text class="li-text-70 li-text-#0a4696 li-font-bold">建立</text>
|
||||
</view>
|
||||
<text
|
||||
class="li-text-26 li-text-#0a4696 li-opacity-100">{{codeInfo?.config?.shop_brokerage_mode==1?'邀请的业主每笔消费,您都可获得返佣':'邀请业主建立联系'}}</text>
|
||||
</view>
|
||||
|
||||
<!-- 收益说明 -->
|
||||
|
|
@ -51,7 +56,8 @@
|
|||
<text class="li-text-26 li-text-#666 li-block li-mt-5">邀请业主注册并完成实名认证</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="benefit-item li-flex li-items-center li-mb-30">
|
||||
<view v-if="codeInfo?.config?.shop_brokerage_mode!=1"
|
||||
class="benefit-item li-flex li-items-center li-mb-30">
|
||||
<view class="icon-box li-bg-#E1F0FF li-rd-12 li-p-15">
|
||||
<text class="ri-link-m li-text-36 li-text-#0070F0"></text>
|
||||
</view>
|
||||
|
|
@ -60,7 +66,7 @@
|
|||
<text class="li-text-26 li-text-#666 li-block li-mt-5">与业主建立永久绑定关系</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="benefit-item li-flex li-items-center">
|
||||
<view v-if="codeInfo?.config?.shop_brokerage_mode==1" class="benefit-item li-flex li-items-center">
|
||||
<view class="icon-box li-bg-#E1F0FF li-rd-12 li-p-15">
|
||||
<text class="ri-money-cny-box-line li-text-36 li-text-#0070F0"></text>
|
||||
</view>
|
||||
|
|
@ -72,7 +78,7 @@
|
|||
</view>
|
||||
</view>
|
||||
<view class="invite-button li-mt-40">
|
||||
<wd-button type="primary" block custom-class="share-btn">
|
||||
<wd-button type="primary" block custom-class="share-btn" @click="openSharePoster">
|
||||
<text class="ri-share-forward-line li-mr-10"></text>立即邀请
|
||||
</wd-button>
|
||||
</view>
|
||||
|
|
@ -83,15 +89,15 @@
|
|||
<view class="records-header li-flex li-justify-between li-items-center">
|
||||
<view class="li-flex li-items-center">
|
||||
<text class="li-text-34 li-text-#333">邀请记录</text>
|
||||
<text class="li-text-26 li-text-#666 li-ml-15">(共{{inviteList.length}}人)</text>
|
||||
<text class="li-text-26 li-text-#666 li-ml-15">(共{{inviteListData?.length}}人)</text>
|
||||
</view>
|
||||
<view class="li-flex li-items-center">
|
||||
<view v-if="codeInfo?.config?.shop_brokerage_mode==1" class="li-flex li-items-center">
|
||||
<text class="ri-money-cny-box-line li-text-32 li-text-#0070F0"></text>
|
||||
<text class="li-text-26 li-text-#666 li-ml-10">累计返佣:¥1280.50</text>
|
||||
<text class="li-text-26 li-text-#666 li-ml-10">累计返佣:¥{{codeInfo?.sumMoney}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<scroll-view scroll-y class="records-list li-mt-20" @scrolltolower="loadMore">
|
||||
<view v-for="(item, index) in inviteList" :key="index"
|
||||
<view v-for="(item, index) in inviteListData" :key="index"
|
||||
class="record-item li-bg-white li-rd-20 li-p-30 li-mb-20 li-shadow-sm">
|
||||
<view class="li-flex li-justify-between li-items-center">
|
||||
<view class="li-flex li-items-center">
|
||||
|
|
@ -106,13 +112,12 @@
|
|||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view v-if="loading" class="loading li-text-center li-py-30 li-text-28 li-text-#999">
|
||||
加载中...
|
||||
|
||||
<view v-if="inviteListData?.length>0">
|
||||
<wd-loadmore loading-text="努力加载中" finished-text="没有更多了" :state="state" />
|
||||
</view>
|
||||
<view v-if="!hasMore && inviteList.length > 0" class="li-text-center li-py-30 li-text-28 li-text-#999">
|
||||
没有更多了
|
||||
</view>
|
||||
<view v-if="inviteList.length === 0" class="empty-state li-py-60">
|
||||
|
||||
<view v-if="inviteListData?.length === 0" class="empty-state">
|
||||
<wd-status-tip image="search" tip="暂无邀请记录" />
|
||||
</view>
|
||||
</scroll-view>
|
||||
|
|
@ -142,68 +147,94 @@
|
|||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
<zero-loading type="wobble" v-if="loading"></zero-loading>
|
||||
|
||||
<SharePoster v-model:show="showPoster" :posterInfo="posterInfo" @updateShare="handleUpdateShare"></SharePoster>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
onMounted,
|
||||
defineExpose
|
||||
} from 'vue'
|
||||
import {
|
||||
inviteList,
|
||||
inviteCode
|
||||
} from '@/api/invite'
|
||||
import {
|
||||
useToast
|
||||
} from '@/uni_modules/wot-design-uni'
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
import { useNavigation } from '@/hooks/useNavigation'
|
||||
declare const uni : Uni
|
||||
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app'
|
||||
import {
|
||||
useNavigation
|
||||
} from '@/hooks/useNavigation'
|
||||
import SharePoster from '@/components/SharePoster.vue'
|
||||
|
||||
const {
|
||||
hasMultiplePages, // 是否有多个页面在路由栈中
|
||||
isTabBarPage, // 当前页面是否为 tabBar 页面
|
||||
checkRouteStack // 检查当前路由栈状态的方法
|
||||
hasMultiplePages, // 是否有多个页面在路由栈中
|
||||
isTabBarPage, // 当前页面是否为 tabBar 页面
|
||||
checkRouteStack // 检查当前路由栈状态的方法
|
||||
} = useNavigation()
|
||||
const Toast = useToast()
|
||||
const loading = ref(false)
|
||||
const hasMore = ref(true)
|
||||
const page = ref(1)
|
||||
const inviteList = ref([])
|
||||
const inviteListData = ref([])
|
||||
const showRulePopup = ref(false)
|
||||
|
||||
const showPoster = ref(false)
|
||||
const posterInfo = ref({})
|
||||
const state = ref('loading')
|
||||
const codeInfo = ref({})
|
||||
const page = ref(1)
|
||||
const limit = ref(10)
|
||||
const userInfo = ref(uni.getStorageSync('userInfo'))
|
||||
const count = ref(0)
|
||||
|
||||
|
||||
const card_back = uni.$globalData?.RESOURCE_URL + 'invite/card-back.png'
|
||||
|
||||
onLoad(() => {
|
||||
checkRouteStack()
|
||||
getInviteCode()
|
||||
loadInviteRecords()
|
||||
})
|
||||
|
||||
const getInviteCode = async () => {
|
||||
var res = await inviteCode()
|
||||
if (res.code == 200) {
|
||||
codeInfo.value = res.data
|
||||
}
|
||||
posterInfo.value = {
|
||||
title: userInfo.value.owner.name,
|
||||
name: userInfo.value.realname,
|
||||
qrcode: codeInfo.value.code,
|
||||
backImage: uni.$globalData?.RESOURCE_URL + 'invite/poster_back.png'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 加载邀请记录
|
||||
const loadInviteRecords = async () => {
|
||||
if (loading.value || !hasMore.value) return
|
||||
|
||||
loading.value = true
|
||||
try {
|
||||
// 模拟接口调用
|
||||
await new Promise(resolve => setTimeout(resolve, 1000))
|
||||
const res = await inviteList({
|
||||
page: page.value,
|
||||
limit: limit.value,
|
||||
})
|
||||
if (res.code == 200) {
|
||||
inviteListData.value = [...inviteListData.value, ...res.data]
|
||||
count.value = res.count
|
||||
}
|
||||
|
||||
const mockData = Array(10).fill().map((_, index) => ({
|
||||
id: page.value * 10 + index,
|
||||
name: `业主${page.value * 10 + index}`,
|
||||
avatar: '/static/swiper/1.png',
|
||||
time: '2024-03-26 12:00:00',
|
||||
status: Math.random() > 0.5 ? 1 : 0
|
||||
}))
|
||||
|
||||
inviteList.value.push(...mockData)
|
||||
hasMore.value = page.value < 3 // 模拟只有3页数据
|
||||
page.value++
|
||||
} catch (error) {
|
||||
Toast.error('加载失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// 页面跳转
|
||||
const toPages = (item) => {
|
||||
if (item.type === 'nav') {
|
||||
|
|
@ -218,11 +249,19 @@
|
|||
|
||||
// 滚动加载更多
|
||||
const loadMore = () => {
|
||||
|
||||
if (inviteListData?.value.length >= count.value) {
|
||||
state.value = 'finished'
|
||||
return
|
||||
}
|
||||
page++
|
||||
loadInviteRecords()
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
loadInviteRecords()
|
||||
// loadInviteRecords()
|
||||
// 初始化海报信息
|
||||
|
||||
})
|
||||
|
||||
// 显示规则弹窗
|
||||
|
|
@ -230,8 +269,16 @@
|
|||
console.log('显示规则弹窗')
|
||||
showRulePopup.value = true
|
||||
}
|
||||
|
||||
|
||||
// 打开分享海报
|
||||
const openSharePoster = () => {
|
||||
showPoster.value = true
|
||||
}
|
||||
|
||||
// 处理分享海报关闭
|
||||
const handleUpdateShare = (val) => {
|
||||
showPoster.value = val
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
|
|
@ -242,169 +289,159 @@
|
|||
.invite-page {
|
||||
min-height: 100vh;
|
||||
padding-bottom: 40rpx;
|
||||
|
||||
// 导航背景层
|
||||
.nav-bg-layer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(var(--status-bar-height) + 88rpx);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
||||
z-index: -1;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
}
|
||||
|
||||
.invite-card {
|
||||
.card-content {
|
||||
.commission-card {
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
/* 导航背景层 */
|
||||
.nav-bg-layer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(var(--status-bar-height) + 88rpx);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
||||
z-index: -1;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.ri-shopping-bag-3-line {
|
||||
font-size: 48rpx;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
.invite-card .card-content .commission-card {
|
||||
border-radius: 20rpx;
|
||||
padding: 30rpx;
|
||||
margin-bottom: 30rpx;
|
||||
}
|
||||
|
||||
.li-text-34 {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
.invite-card .card-content .commission-card .ri-shopping-bag-3-line {
|
||||
font-size: 48rpx;
|
||||
margin-right: 15rpx;
|
||||
}
|
||||
|
||||
.li-text-26 {
|
||||
font-size: 26rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
.invite-card .card-content .commission-card .li-text-34 {
|
||||
font-size: 34rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.benefit-list {
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
background: #f8faff;
|
||||
.invite-card .card-content .commission-card .li-text-26 {
|
||||
font-size: 26rpx;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.benefit-item {
|
||||
.icon-box {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
border-radius: 12rpx;
|
||||
background: #E1F0FF;
|
||||
margin-right: 20rpx;
|
||||
padding: 15rpx;
|
||||
.invite-card .card-content .benefit-list {
|
||||
padding: 30rpx;
|
||||
border-radius: 16rpx;
|
||||
background: #f8faff;
|
||||
}
|
||||
|
||||
.ri-user-add-line,
|
||||
.ri-link-m,
|
||||
.ri-money-cny-box-line {
|
||||
font-size: 36rpx;
|
||||
color: #0070F0;
|
||||
}
|
||||
}
|
||||
.invite-card .card-content .benefit-list .benefit-item .icon-box {
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
border-radius: 12rpx;
|
||||
background: #E1F0FF;
|
||||
margin-right: 20rpx;
|
||||
padding: 15rpx;
|
||||
}
|
||||
|
||||
.li-text-30 {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
.invite-card .card-content .benefit-list .benefit-item .icon-box .ri-user-add-line,
|
||||
.invite-card .card-content .benefit-list .benefit-item .icon-box .ri-link-m,
|
||||
.invite-card .card-content .benefit-list .benefit-item .icon-box .ri-money-cny-box-line {
|
||||
font-size: 36rpx;
|
||||
color: #0070F0;
|
||||
}
|
||||
|
||||
.li-text-26 {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
display: block;
|
||||
margin-top: 5rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.invite-card .card-content .benefit-list .benefit-item .li-text-30 {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.share-btn {
|
||||
background: linear-gradient(135deg, #42a5ff 0%, #0070F0 100%) !important;
|
||||
border: none !important;
|
||||
height: 90rpx !important;
|
||||
font-size: 32rpx !important;
|
||||
}
|
||||
}
|
||||
.invite-card .card-content .benefit-list .benefit-item .li-text-26 {
|
||||
font-size: 26rpx;
|
||||
color: #666;
|
||||
display: block;
|
||||
margin-top: 5rpx;
|
||||
}
|
||||
|
||||
.invite-records {
|
||||
.records-list {
|
||||
height: calc(100vh - 600rpx);
|
||||
.invite-card .share-btn {
|
||||
background: linear-gradient(135deg, #42a5ff 0%, #0070F0 100%) !important;
|
||||
border: none !important;
|
||||
height: 90rpx !important;
|
||||
font-size: 32rpx !important;
|
||||
}
|
||||
|
||||
.record-item {
|
||||
.avatar {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
.invite-records .records-list {
|
||||
height: calc(100vh - 600rpx);
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
padding: 4rpx 20rpx;
|
||||
border-radius: 30rpx;
|
||||
font-size: 24rpx;
|
||||
.invite-records .records-list .record-item .avatar {
|
||||
width: 90rpx;
|
||||
height: 90rpx;
|
||||
border-radius: 20rpx;
|
||||
}
|
||||
|
||||
&.success {
|
||||
color: #07c160;
|
||||
background-color: rgba(7, 193, 96, 0.1);
|
||||
}
|
||||
.invite-records .records-list .record-item .status-tag {
|
||||
padding: 4rpx 20rpx;
|
||||
border-radius: 30rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
|
||||
&.pending {
|
||||
color: #f0ad4e;
|
||||
background-color: rgba(240, 173, 78, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.invite-records .records-list .record-item .status-tag.success {
|
||||
color: #07c160;
|
||||
background-color: rgba(7, 193, 96, 0.1);
|
||||
}
|
||||
|
||||
.invite-records .records-list .record-item .status-tag.pending {
|
||||
color: #f0ad4e;
|
||||
background-color: rgba(240, 173, 78, 0.1);
|
||||
}
|
||||
|
||||
.rules-popup {
|
||||
width: 580rpx;
|
||||
overflow: hidden;
|
||||
|
||||
.rules-header {
|
||||
border-color: rgba(0, 0, 0, 0.05);
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 30rpx;
|
||||
right: 30rpx;
|
||||
bottom: 0;
|
||||
height: 1px;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.ri-close-line {
|
||||
padding: 10rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.rules-content {
|
||||
padding:40rpx 30rpx 50rpx;
|
||||
|
||||
.rule-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
.rule-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border-radius: 50%;
|
||||
background: #0070F0;
|
||||
color: white;
|
||||
font-size: 24rpx;
|
||||
margin-right: 16rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.rules-popup .rules-header {
|
||||
border-color: rgba(0, 0, 0, 0.05);
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.rules-popup .rules-header::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: 30rpx;
|
||||
right: 30rpx;
|
||||
bottom: 0;
|
||||
height: 1px;
|
||||
background: rgba(0, 0, 0, 0.05);
|
||||
transform: scaleY(0.5);
|
||||
}
|
||||
|
||||
.rules-popup .rules-header .ri-close-line {
|
||||
padding: 10rpx;
|
||||
}
|
||||
|
||||
.rules-popup .rules-content {
|
||||
padding: 40rpx 30rpx 50rpx;
|
||||
}
|
||||
|
||||
.rules-popup .rules-content .rule-item {
|
||||
display: flex;
|
||||
align-items: flex-start;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.rules-popup .rules-content .rule-item .rule-icon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
border-radius: 50%;
|
||||
background: #0070F0;
|
||||
color: white;
|
||||
font-size: 24rpx;
|
||||
margin-right: 16rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.rules-popup .rules-content .rule-item:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -49,7 +49,7 @@
|
|||
{{getStatusText(item.status)}}
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 订单内容 -->
|
||||
<view class="order-content">
|
||||
<view class="info-row">
|
||||
|
|
@ -65,12 +65,12 @@
|
|||
<text v-if="item.type == 'F4'">量房</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="info-row">
|
||||
<text class="row-label">小区名称</text>
|
||||
<text class="row-value">{{item.order.village_name}}</text>
|
||||
</view>
|
||||
|
||||
|
||||
<view class="contact-info">
|
||||
<view class="contact-row">
|
||||
<text class="contact-icon ri-user-3-line"></text>
|
||||
|
|
@ -83,7 +83,7 @@
|
|||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<!-- 订单底部 -->
|
||||
<view class="order-footer">
|
||||
<view class="time-info">
|
||||
|
|
@ -94,7 +94,7 @@
|
|||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
|
||||
<view v-if="taskList.length==0" class="!li-mt-300">
|
||||
<wd-status-tip image="search" tip="您还没有待处理的订单哦~" />
|
||||
</view>
|
||||
|
|
@ -115,14 +115,18 @@
|
|||
} = useNavigation()
|
||||
|
||||
|
||||
onLoad(() => {
|
||||
onLoad((options) => {
|
||||
checkRouteStack()
|
||||
if (options.type) {
|
||||
activeTab.value = Number(options.type)
|
||||
handleStatusChange(Number(options.status))
|
||||
}
|
||||
})
|
||||
|
||||
onShow(() => {
|
||||
query.value.page = 1
|
||||
taskList.value = []
|
||||
poolList()
|
||||
// query.value.page = 1
|
||||
// taskList.value = []
|
||||
// poolList()
|
||||
})
|
||||
|
||||
onPullDownRefresh(() => {
|
||||
|
|
@ -300,10 +304,8 @@
|
|||
}
|
||||
|
||||
const handleStatusChange = (id) => {
|
||||
query.value.page = 1
|
||||
query.value.status = id
|
||||
taskList.value = []
|
||||
poolList()
|
||||
tabChange()
|
||||
}
|
||||
</script>
|
||||
|
||||
|
|
@ -393,12 +395,12 @@
|
|||
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.04);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
|
||||
&:active {
|
||||
transform: scale(0.99);
|
||||
transition: transform 0.2s;
|
||||
}
|
||||
|
||||
|
||||
/* 工单头部 */
|
||||
.order-header {
|
||||
display: flex;
|
||||
|
|
@ -407,30 +409,30 @@
|
|||
margin-bottom: 20rpx;
|
||||
padding-bottom: 20rpx;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
|
||||
|
||||
.order-id {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.id-icon {
|
||||
font-size: 32rpx;
|
||||
color: #999;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
|
||||
.id-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
.copy-icon {
|
||||
font-size: 28rpx;
|
||||
color: #009aff;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.order-status {
|
||||
font-size: 22rpx;
|
||||
padding: 4rpx 18rpx;
|
||||
|
|
@ -438,22 +440,22 @@
|
|||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 工单内容 */
|
||||
.order-content {
|
||||
padding: 10rpx 0 16rpx;
|
||||
|
||||
|
||||
.info-row {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 20rpx;
|
||||
|
||||
|
||||
.row-label {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
|
||||
.row-value {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
|
|
@ -463,7 +465,7 @@
|
|||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
|
||||
.type-tag {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
@ -473,60 +475,60 @@
|
|||
font-weight: 500;
|
||||
color: #009aff;
|
||||
background-color: rgba(0, 154, 255, 0.08);
|
||||
|
||||
|
||||
&.type-F2 {
|
||||
color: #ff9d00;
|
||||
background-color: rgba(255, 157, 0, 0.08);
|
||||
}
|
||||
|
||||
|
||||
&.type-F6 {
|
||||
color: #00b42a;
|
||||
background-color: rgba(0, 180, 42, 0.08);
|
||||
}
|
||||
|
||||
|
||||
&.type-F4 {
|
||||
color: #643bed;
|
||||
background-color: rgba(100, 59, 237, 0.08);
|
||||
}
|
||||
|
||||
|
||||
.tag-icon {
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.contact-info {
|
||||
padding: 16rpx 20rpx;
|
||||
background-color: rgba(0, 154, 255, 0.03);
|
||||
border-radius: 12rpx;
|
||||
|
||||
|
||||
.contact-row {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 12rpx;
|
||||
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
||||
.contact-icon {
|
||||
font-size: 28rpx;
|
||||
color: #009aff;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
|
||||
.contact-label {
|
||||
font-size: 26rpx;
|
||||
color: #999;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
|
||||
|
||||
.contact-name {
|
||||
font-size: 26rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
|
||||
.contact-phone {
|
||||
font-size: 26rpx;
|
||||
color: #009aff;
|
||||
|
|
@ -535,7 +537,7 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 工单底部 */
|
||||
.order-footer {
|
||||
display: flex;
|
||||
|
|
@ -543,23 +545,23 @@
|
|||
align-items: center;
|
||||
border-top: 1px dashed rgba(0, 0, 0, 0.05);
|
||||
padding-top: 16rpx;
|
||||
|
||||
|
||||
.time-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
|
||||
.time-icon {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
|
||||
|
||||
.time-text {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.detail-btn {
|
||||
padding: 8rpx 30rpx;
|
||||
background: linear-gradient(to right, #7bbfff, #009aff);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,162 @@
|
|||
<template>
|
||||
<view class="complaint-page">
|
||||
<!-- 自定义导航栏 -->
|
||||
<wd-navbar :bordered="false"
|
||||
custom-style="background: transparent !important; backdrop-filter: blur(10px) !important; -webkit-backdrop-filter: blur(10px) !important;"
|
||||
safeAreaInsetTop fixed placeholder>
|
||||
<template #left>
|
||||
<view class="li-ml-15 li-mt-10 li-flex li-items-center">
|
||||
<text v-if="hasMultiplePages" class="ri-arrow-left-s-line li-text-70"
|
||||
@click="toPages({type:'nav'})"></text>
|
||||
<text v-if="!hasMultiplePages" class="ri-home-5-line li-text-55 li-mb-8 li-mr-10"
|
||||
@click="toPages({type:'home'})"></text>
|
||||
<text class="li-text-42">{{paramsType=='1'?'用户协议':'隐私政策'}}</text>
|
||||
</view>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
<!-- 导航栏背景 -->
|
||||
<view class="nav-bg-layer"></view>
|
||||
<view v-html="rawHtml"></view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import { useNavigation } from '@/hooks/useNavigation';
|
||||
import { useToast } from '@/uni_modules/wot-design-uni';
|
||||
|
||||
const Toast = useToast();
|
||||
|
||||
// 使用导航composable
|
||||
const {
|
||||
hasMultiplePages,
|
||||
isTabBarPage,
|
||||
checkRouteStack
|
||||
} = useNavigation();
|
||||
|
||||
const paramsType = ref('1')
|
||||
const rawHtml = ref('<div style="text-align:center;background-color: #007AFF;"><div >我是内容</div><img src="https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/uni@2x.png"/></div>')
|
||||
|
||||
|
||||
// 页面跳转
|
||||
const toPages = (item) => {
|
||||
switch (item.type) {
|
||||
case 'nav':
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
break;
|
||||
case 'home':
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// 生命周期钩子
|
||||
onLoad((options) => {
|
||||
checkRouteStack();
|
||||
paramsType.value = options.type
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
page {
|
||||
background-color: #F7F8FA;
|
||||
}
|
||||
|
||||
.complaint-page {
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.nav-bg-layer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(var(--status-bar-height) + 88rpx);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
||||
z-index: -1;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.status-tag {
|
||||
padding: 8rpx 24rpx;
|
||||
border-radius: 30rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
background: #f5f5f5;
|
||||
margin-right: 16rpx;
|
||||
transition: all 0.3s;
|
||||
}
|
||||
|
||||
.status-tag.active {
|
||||
color: #0070F0;
|
||||
background: rgba(0, 112, 240, 0.1);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.complaint-card {
|
||||
transition: all 0.3s;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.98);
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
.complaint-header {
|
||||
.status-badge {
|
||||
padding: 4rpx 20rpx;
|
||||
border-radius: 20rpx;
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.li-bottom-border2 {
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.preview-image {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 8rpx;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.more-image-text {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
background-color: #f8f8f8;
|
||||
border-radius: 8rpx;
|
||||
}
|
||||
|
||||
/* 覆盖组件样式 */
|
||||
::v-deep .wd-search {
|
||||
background-color: transparent !important;
|
||||
padding: 0 !important;
|
||||
border-radius: 10rpx !important;
|
||||
}
|
||||
|
||||
::v-deep .wd-search__block {
|
||||
background-color: rgba(255, 255, 255, 0.8) !important;
|
||||
padding: 8rpx !important;
|
||||
border-radius: 10rpx !important;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.015);
|
||||
}
|
||||
|
||||
::v-deep .wd-status-tip__text {
|
||||
margin-top: 30rpx !important;
|
||||
color: #999 !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,408 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<!-- 自定义导航栏 -->
|
||||
<wd-navbar :bordered="false"
|
||||
custom-style="background: transparent !important; backdrop-filter: blur(10px) !important; -webkit-backdrop-filter: blur(20px) !important;"
|
||||
safeAreaInsetTop fixed placeholder>
|
||||
<template #left>
|
||||
<view class="li-ml-15 li-mt-10 li-flex li-items-center">
|
||||
<text class="ri-arrow-left-s-line li-text-70" @click="goBack"></text>
|
||||
<text class="li-text-42">添加员工</text>
|
||||
</view>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
<!-- 导航栏背景 -->
|
||||
<view class="nav-bg-layer"></view>
|
||||
|
||||
<!-- 页面背景 -->
|
||||
<view class="page-bg"></view>
|
||||
|
||||
<view class="content">
|
||||
<!-- 表单区域 -->
|
||||
<wd-form ref="form" :model="formData" :rules="rules" class="form-wrapper">
|
||||
<wd-cell-group border class="form-card">
|
||||
<wd-input
|
||||
v-model="formData.name"
|
||||
label="员工姓名"
|
||||
placeholder="请输入姓名"
|
||||
prop="name"
|
||||
label-width="100px"
|
||||
clearable
|
||||
/>
|
||||
<wd-input
|
||||
v-model="formData.phone"
|
||||
label="手机号码"
|
||||
type="number"
|
||||
placeholder="请输入手机号"
|
||||
prop="phone"
|
||||
label-width="100px"
|
||||
clearable
|
||||
/>
|
||||
<wd-input
|
||||
v-model="formData.password"
|
||||
label="初始密码"
|
||||
placeholder="123456"
|
||||
prop="password"
|
||||
label-width="100px"
|
||||
disabled
|
||||
/>
|
||||
<wd-cell
|
||||
title="所属小区"
|
||||
:value="villageName"
|
||||
@click="showVillagePopup = true"
|
||||
is-link
|
||||
title-width="100px"
|
||||
/>
|
||||
<wd-cell
|
||||
title="权限设置"
|
||||
@click="openPermissionPopup"
|
||||
is-link
|
||||
title-width="100px"
|
||||
>
|
||||
<view class="permission-summary">
|
||||
<text>{{ getPermissionSummary() }}</text>
|
||||
</view>
|
||||
</wd-cell>
|
||||
</wd-cell-group>
|
||||
|
||||
<!-- 提交按钮 -->
|
||||
<view class="submit-btn-wrapper">
|
||||
<wd-button type="primary" block @click="submitForm" custom-style="background: linear-gradient(135deg, #42a5ff, #0070F0);">创建员工</wd-button>
|
||||
</view>
|
||||
</wd-form>
|
||||
|
||||
<!-- 选择小区弹窗 -->
|
||||
<wd-popup v-model="showVillagePopup" position="bottom" title="选择小区" round>
|
||||
<view class="village-popup">
|
||||
<view
|
||||
v-for="(item, index) in villages"
|
||||
:key="index"
|
||||
class="village-item"
|
||||
:class="{ active: formData.villageId === item.id }"
|
||||
@click="selectVillage(item)"
|
||||
>
|
||||
<view class="village-name">{{ item.name }}</view>
|
||||
<view class="village-check">
|
||||
<text class="ri-checkbox-circle-fill" v-if="formData.villageId === item.id"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
|
||||
<!-- 权限设置弹窗 -->
|
||||
<wd-popup v-model="showPermissionPopup" position="bottom" custom-style="border-radius: 20rpx 20rpx 0 0;" :safe-area-inset-bottom="true">
|
||||
<permission-settings
|
||||
:staff="staffWithPermissions"
|
||||
:permissions="allPermissions"
|
||||
@save="savePermissions"
|
||||
@cancel="closePermissionPopup"
|
||||
/>
|
||||
</wd-popup>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, reactive } from 'vue';
|
||||
import { useNavigation } from '@/hooks/useNavigation';
|
||||
import PermissionSettings from '@/components/PermissionSettings.vue';
|
||||
|
||||
// 导航相关
|
||||
const { toPages } = useNavigation();
|
||||
|
||||
// 表单引用
|
||||
const form = ref(null);
|
||||
|
||||
// 表单数据
|
||||
const formData = reactive({
|
||||
name: '',
|
||||
phone: '',
|
||||
password: '123456',
|
||||
villageId: '',
|
||||
permissions: []
|
||||
});
|
||||
|
||||
// 表单验证规则
|
||||
const rules = {
|
||||
name: [
|
||||
{ required: true, message: '请输入员工姓名' }
|
||||
],
|
||||
phone: [
|
||||
{ required: true, message: '请输入手机号码' },
|
||||
{ pattern: /^1\d{10}$/, message: '手机号格式不正确' }
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: '默认初始密码' }
|
||||
]
|
||||
};
|
||||
|
||||
// 小区数据
|
||||
const villages = ref([
|
||||
{ id: '1', name: '阳光花园小区' },
|
||||
{ id: '2', name: '幸福家园小区' },
|
||||
{ id: '3', name: '时代广场小区' }
|
||||
]);
|
||||
|
||||
// 显示小区选择弹窗
|
||||
const showVillagePopup = ref(false);
|
||||
|
||||
// 当前选中的小区名称
|
||||
const villageName = computed(() => {
|
||||
const village = villages.value.find(v => v.id === formData.villageId);
|
||||
return village ? village.name : '请选择';
|
||||
});
|
||||
|
||||
// 选择小区
|
||||
const selectVillage = (village) => {
|
||||
formData.villageId = village.id;
|
||||
showVillagePopup.value = false;
|
||||
};
|
||||
|
||||
// 权限弹窗
|
||||
const showPermissionPopup = ref(false);
|
||||
|
||||
// 权限数据,用于传递给权限设置组件
|
||||
const staffWithPermissions = computed(() => {
|
||||
return {
|
||||
name: formData.name || '新员工',
|
||||
permissions: formData.permissions
|
||||
};
|
||||
});
|
||||
|
||||
// 所有权限列表
|
||||
const allPermissions = [
|
||||
{ value: 'delivery', label: '配送权限', icon: 'ri-truck-line', description: '允许配送相关的订单处理', colorClass: 'delivery-color', isCommon: true },
|
||||
{ value: 'maintenance', label: '维修权限', icon: 'ri-tools-line', description: '允许接受维修工单和处理', colorClass: 'maintenance-color', isCommon: true },
|
||||
{ value: 'finance', label: '财务管理', icon: 'ri-money-cny-circle-line', description: '允许处理财务相关事务', colorClass: 'finance-color', isCommon: true },
|
||||
{ value: 'resident', label: '住户管理', icon: 'ri-user-line', description: '允许管理小区住户信息', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'security', label: '安防权限', icon: 'ri-shield-line', description: '允许管理小区安防系统', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'admin', label: '管理员权限', icon: 'ri-admin-line', description: '系统管理员权限', colorClass: 'admin-color', isCommon: false },
|
||||
{ value: 'parking', label: '车位管理', icon: 'ri-parking-line', description: '允许管理小区车位', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'visitor', label: '访客管理', icon: 'ri-user-location-line', description: '允许管理小区访客', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'complaint', label: '投诉处理', icon: 'ri-customer-service-line', description: '允许处理业主投诉', colorClass: 'general-color', isCommon: true },
|
||||
{ value: 'facility', label: '设施管理', icon: 'ri-building-4-line', description: '允许管理小区公共设施', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'notice', label: '通知发布', icon: 'ri-notification-line', description: '允许发布小区通知', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'inspection', label: '巡检权限', icon: 'ri-survey-line', description: '允许进行小区巡检记录', colorClass: 'maintenance-color', isCommon: true },
|
||||
];
|
||||
|
||||
// 打开权限设置弹窗
|
||||
const openPermissionPopup = () => {
|
||||
showPermissionPopup.value = true;
|
||||
};
|
||||
|
||||
// 关闭权限设置弹窗
|
||||
const closePermissionPopup = () => {
|
||||
showPermissionPopup.value = false;
|
||||
};
|
||||
|
||||
// 保存权限设置
|
||||
const savePermissions = (staffData) => {
|
||||
formData.permissions = [...staffData.permissions];
|
||||
closePermissionPopup();
|
||||
};
|
||||
|
||||
// 获取权限摘要文本
|
||||
const getPermissionSummary = () => {
|
||||
if (formData.permissions.length === 0) {
|
||||
return '未设置权限';
|
||||
}
|
||||
|
||||
// 获取已选权限的名称
|
||||
const permNames = formData.permissions.map(code => {
|
||||
const perm = allPermissions.find(p => p.value === code);
|
||||
return perm ? perm.label : '';
|
||||
}).filter(name => name);
|
||||
|
||||
if (permNames.length <= 2) {
|
||||
return permNames.join('、');
|
||||
} else {
|
||||
return `${permNames[0]}、${permNames[1]} 等${permNames.length}项`;
|
||||
}
|
||||
};
|
||||
|
||||
// 返回上一页
|
||||
const goBack = () => {
|
||||
uni.navigateBack();
|
||||
};
|
||||
|
||||
// 提交表单
|
||||
const submitForm = () => {
|
||||
form.value.validate()
|
||||
.then(({ valid, errors }) => {
|
||||
if (valid) {
|
||||
if (!formData.villageId) {
|
||||
uni.showToast({ title: '请选择所属小区', icon: 'none' });
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示加载
|
||||
uni.showLoading({ title: '提交中...' });
|
||||
|
||||
// 模拟提交
|
||||
setTimeout(() => {
|
||||
uni.hideLoading();
|
||||
uni.showToast({ title: '添加成功', icon: 'success' });
|
||||
|
||||
// 延迟返回
|
||||
setTimeout(() => {
|
||||
uni.navigateBack();
|
||||
}, 1500);
|
||||
}, 1000);
|
||||
} else {
|
||||
console.log('表单校验失败', errors);
|
||||
}
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('表单校验异常', error);
|
||||
});
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 主容器 */
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: transparent;
|
||||
position: relative;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Segoe UI, Arial, Roboto, PingFang SC, sans-serif;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
/* 导航栏背景 */
|
||||
.nav-bg-layer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(var(--status-bar-height) + 88rpx);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
||||
z-index: -1;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* 页面背景 */
|
||||
.page-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #f8fafd 0%, #eef2f9 100%);
|
||||
z-index: -2;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 30%;
|
||||
background: linear-gradient(135deg, rgba(66, 165, 255, 0.03), rgba(0, 112, 240, 0));
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
background: linear-gradient(315deg, rgba(66, 165, 255, 0.02), rgba(0, 112, 240, 0));
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 内容区域 */
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 30rpx;
|
||||
padding-bottom: 50rpx;
|
||||
/* #ifdef MP-WEIXIN */
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
/* 表单包装器 */
|
||||
.form-wrapper {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* 表单卡片 */
|
||||
.form-card {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
margin-bottom: 40rpx;
|
||||
box-shadow: 0 8rpx 16rpx rgba(0, 112, 240, 0.06);
|
||||
}
|
||||
|
||||
/* 提交按钮 */
|
||||
.submit-btn-wrapper {
|
||||
margin-top: 60rpx;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
/* 小区选择弹窗 */
|
||||
.village-popup {
|
||||
padding: 30rpx;
|
||||
max-height: 60vh;
|
||||
}
|
||||
|
||||
.village-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 24rpx 16rpx;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: rgba(66, 165, 255, 0.05);
|
||||
}
|
||||
|
||||
.village-name {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.village-check {
|
||||
color: #42a5ff;
|
||||
font-size: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 权限摘要 */
|
||||
.permission-summary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
:deep(.wd-input__label) {
|
||||
font-size: 28rpx !important;
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
:deep(.wd-cell__title) {
|
||||
font-size: 28rpx !important;
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
:deep(.wd-cell__value) {
|
||||
color: #666 !important;
|
||||
}
|
||||
|
||||
:deep(.wd-button--primary) {
|
||||
background: linear-gradient(135deg, #42a5ff, #0070F0) !important;
|
||||
border: none !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,944 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<!-- 自定义导航栏 -->
|
||||
<wd-navbar :bordered="false"
|
||||
custom-style="background: transparent !important; backdrop-filter: blur(10px) !important; -webkit-backdrop-filter: blur(20px) !important;"
|
||||
safeAreaInsetTop fixed placeholder>
|
||||
<template #left>
|
||||
<view class="li-ml-15 li-mt-10 li-flex li-items-center">
|
||||
<text v-if="hasMultiplePages" class="ri-arrow-left-s-line li-text-70"
|
||||
@click="toPages({type:'nav'})"></text>
|
||||
<text v-if="!hasMultiplePages" class="ri-home-5-line li-text-55 li-mb-8 li-mr-10"
|
||||
@click="toPages({type:'home'})"></text>
|
||||
<text class="li-text-42">员工权限</text>
|
||||
</view>
|
||||
</template>
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<template #right>
|
||||
<view class="li-flex-center li-mr-200 li-pt-6" @click="handleAddStaff">
|
||||
<text class="ri-add-line li-text-50"></text>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<!-- #endif -->
|
||||
<!-- #ifndef MP-WEIXIN -->
|
||||
<template #right>
|
||||
<view class="li-flex-center li-mr-25 li-pt-6" @click="handleAddStaff">
|
||||
<text class="ri-add-line li-text-55"></text>
|
||||
</view>
|
||||
</template>
|
||||
<!-- #endif -->
|
||||
</wd-navbar>
|
||||
<!-- 导航栏背景 -->
|
||||
<view class="nav-bg-layer"></view>
|
||||
|
||||
<!-- 页面背景 -->
|
||||
<view class="page-bg"></view>
|
||||
|
||||
<view class="content">
|
||||
|
||||
<!-- 员工列表 -->
|
||||
<view class="staff-list li-w-92% li-mx-auto li-mt-20" v-if="filteredStaffList.length > 0">
|
||||
<view
|
||||
v-for="staff in filteredStaffList"
|
||||
:key="staff.id"
|
||||
class="staff-card"
|
||||
@tap="openPermissionSetting(staff)"
|
||||
>
|
||||
<view class="card-header">
|
||||
<view class="staff-avatar" v-if="staff.avatar">
|
||||
<image :src="staff.avatar" mode="aspectFill"></image>
|
||||
</view>
|
||||
<view class="staff-avatar default-avatar" v-else>
|
||||
<text>{{staff.name.substring(0,1)}}</text>
|
||||
</view>
|
||||
|
||||
<view class="staff-info">
|
||||
<view class="staff-name">{{ staff.name }}</view>
|
||||
<view class="staff-phone">
|
||||
<text class="ri-phone-line phone-icon"></text>
|
||||
<text>{{ staff.phone }}</text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="right-area">
|
||||
<view class="perm-count" :class="{'has-perm': staff.permissions.length > 0}">
|
||||
{{ staff.permissions.length }}
|
||||
</view>
|
||||
<text class="ri-arrow-right-s-line action-icon"></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card-content" v-if="staff.permissions.length > 0">
|
||||
<!-- 权限标签 -->
|
||||
<view class="perm-tags">
|
||||
<view
|
||||
v-for="(perm, index) in staff.permissions.slice(0, 2)"
|
||||
:key="perm"
|
||||
class="perm-tag"
|
||||
:class="getPermissionClass(perm)"
|
||||
>
|
||||
<text :class="getPermissionIcon(perm)"></text>
|
||||
<text>{{ getPermissionName(perm) }}</text>
|
||||
</view>
|
||||
<view class="perm-tag more" v-if="staff.permissions.length > 2">
|
||||
<text>+{{ staff.permissions.length - 2 }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view class="card-content" v-else>
|
||||
<view class="no-perm-tag">
|
||||
<text class="ri-lock-line"></text>
|
||||
<text>暂无权限</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view class="empty-state" v-else>
|
||||
<wd-empty description="暂无员工数据">
|
||||
<wd-button type="primary" @click="handleAddStaff">添加员工</wd-button>
|
||||
</wd-empty>
|
||||
</view>
|
||||
|
||||
<!-- 底部权限设置面板 -->
|
||||
<wd-popup v-model="showPermissionPopup" position="bottom" custom-style="border-radius: 20rpx 20rpx 0 0;" @close="handlePopupClose" :safe-area-inset-bottom="true">
|
||||
<permission-settings
|
||||
:staff="currentStaff"
|
||||
:permissions="allPermissions"
|
||||
@save="savePermissions"
|
||||
@cancel="closePermissionSheet"
|
||||
/>
|
||||
</wd-popup>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, computed, nextTick } from 'vue';
|
||||
import { useNavigation } from '@/hooks/useNavigation';
|
||||
import { onLoad, onPullDownRefresh } from '@dcloudio/uni-app';
|
||||
import PermissionSettings from '@/components/PermissionSettings.vue';
|
||||
|
||||
// 导航相关
|
||||
const { toPages, hasMultiplePages, checkRouteStack } = useNavigation();
|
||||
|
||||
// 小区信息
|
||||
const villageId = ref('');
|
||||
const villageName = ref('阳光花园小区');
|
||||
const villageAddress = ref('市政府北路123号');
|
||||
|
||||
// 搜索与筛选
|
||||
const searchKeyword = ref('');
|
||||
const currentFilter = ref('全部');
|
||||
const filterOptions = ['全部', '配送权限', '维修权限'];
|
||||
|
||||
// 权限配置弹框搜索
|
||||
const permissionSearchKeyword = ref('');
|
||||
|
||||
// 更多权限弹窗
|
||||
const showMorePermissionsPopup = ref(false);
|
||||
const currentStaffPermissions = ref([]);
|
||||
|
||||
// 弹窗管理
|
||||
const showPermissionPopup = ref(false);
|
||||
const currentStaff = ref(null);
|
||||
const tempPermissions = reactive({});
|
||||
|
||||
// 员工列表数据 - 使用更多权限
|
||||
const staffList = ref([
|
||||
{
|
||||
id: 1,
|
||||
name: '张三',
|
||||
phone: '13800138000',
|
||||
avatar: '/static/swiper/1.png',
|
||||
permissions: ['delivery', 'complaint'],
|
||||
department: '配送部'
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '李四',
|
||||
phone: '13800138001',
|
||||
avatar: '/static/swiper/1.png',
|
||||
permissions: ['delivery', 'maintenance', 'inspection', 'facility', 'visitor'],
|
||||
department: '综合部'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '王五',
|
||||
phone: '13800138002',
|
||||
avatar: '/static/swiper/1.png',
|
||||
permissions: ['maintenance', 'inspection'],
|
||||
department: '工程部'
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '赵六',
|
||||
phone: '13800138003',
|
||||
avatar: '/static/swiper/1.png',
|
||||
permissions: [],
|
||||
department: '客服部'
|
||||
}
|
||||
]);
|
||||
|
||||
// 所有权限列表
|
||||
const allPermissions = [
|
||||
{ value: 'delivery', label: '配送权限', icon: 'ri-truck-line', description: '允许配送相关的订单处理', colorClass: 'delivery-color', isCommon: true },
|
||||
{ value: 'maintenance', label: '维修权限', icon: 'ri-tools-line', description: '允许接受维修工单和处理', colorClass: 'maintenance-color', isCommon: true },
|
||||
{ value: 'finance', label: '财务管理', icon: 'ri-money-cny-circle-line', description: '允许处理财务相关事务', colorClass: 'finance-color', isCommon: true },
|
||||
{ value: 'resident', label: '住户管理', icon: 'ri-user-line', description: '允许管理小区住户信息', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'security', label: '安防权限', icon: 'ri-shield-line', description: '允许管理小区安防系统', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'admin', label: '管理员权限', icon: 'ri-admin-line', description: '系统管理员权限', colorClass: 'admin-color', isCommon: false },
|
||||
{ value: 'parking', label: '车位管理', icon: 'ri-parking-line', description: '允许管理小区车位', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'visitor', label: '访客管理', icon: 'ri-user-location-line', description: '允许管理小区访客', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'complaint', label: '投诉处理', icon: 'ri-customer-service-line', description: '允许处理业主投诉', colorClass: 'general-color', isCommon: true },
|
||||
{ value: 'facility', label: '设施管理', icon: 'ri-building-4-line', description: '允许管理小区公共设施', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'notice', label: '通知发布', icon: 'ri-notification-line', description: '允许发布小区通知', colorClass: 'general-color', isCommon: false },
|
||||
{ value: 'inspection', label: '巡检权限', icon: 'ri-survey-line', description: '允许进行小区巡检记录', colorClass: 'maintenance-color', isCommon: true },
|
||||
];
|
||||
|
||||
// 筛选后的员工列表
|
||||
const filteredStaffList = computed(() => {
|
||||
let result = staffList.value;
|
||||
|
||||
// 按关键词筛选
|
||||
if (searchKeyword.value) {
|
||||
result = result.filter(staff =>
|
||||
staff.name.includes(searchKeyword.value) ||
|
||||
staff.phone.includes(searchKeyword.value)
|
||||
);
|
||||
}
|
||||
|
||||
// 按权限筛选
|
||||
if (currentFilter.value !== '全部') {
|
||||
// 查找对应的权限代码
|
||||
const permCode = allPermissions.find(p => p.label === currentFilter.value)?.value;
|
||||
if (permCode) {
|
||||
result = result.filter(staff => staff.permissions.includes(permCode));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
// 常用权限和其他权限
|
||||
const commonPermissions = computed(() => {
|
||||
return allPermissions.filter(perm => perm.isCommon);
|
||||
});
|
||||
|
||||
const otherPermissions = computed(() => {
|
||||
return allPermissions.filter(perm => !perm.isCommon);
|
||||
});
|
||||
|
||||
/**
|
||||
* 获取权限图标
|
||||
* @param {string} permCode 权限代码
|
||||
* @returns {string} 图标class
|
||||
*/
|
||||
const getPermissionIcon = (permCode) => {
|
||||
const perm = allPermissions.find(p => p.value === permCode);
|
||||
return perm ? perm.icon : 'ri-lock-line';
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取权限名称
|
||||
* @param {string} permCode 权限代码
|
||||
* @returns {string} 权限名称
|
||||
*/
|
||||
const getPermissionName = (permCode) => {
|
||||
const perm = allPermissions.find(p => p.value === permCode);
|
||||
return perm ? perm.label : '未知权限';
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取权限样式类
|
||||
* @param {string} permCode 权限代码
|
||||
* @returns {string} 样式类名
|
||||
*/
|
||||
const getPermissionClass = (permCode) => {
|
||||
const perm = allPermissions.find(p => p.value === permCode);
|
||||
return perm ? perm.colorClass : '';
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取激活的权限数量
|
||||
*/
|
||||
const getActivePermissionsCount = () => {
|
||||
return Object.values(tempPermissions).filter(v => v === true).length;
|
||||
};
|
||||
|
||||
/**
|
||||
* 显示更多权限弹窗
|
||||
* @param {Object} staff 员工信息
|
||||
*/
|
||||
const showMorePermissions = (staff) => {
|
||||
currentStaff.value = staff;
|
||||
currentStaffPermissions.value = staff.permissions;
|
||||
showMorePermissionsPopup.value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取小区信息
|
||||
*/
|
||||
const getVillageInfo = () => {
|
||||
// 实际项目中从服务器获取小区信息
|
||||
console.log('获取小区ID为', villageId.value, '的信息');
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取员工列表
|
||||
*/
|
||||
const getStaffList = () => {
|
||||
// 实际项目中从服务器获取员工列表
|
||||
console.log('获取小区ID为', villageId.value, '的员工列表');
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理搜索
|
||||
*/
|
||||
const handleSearch = () => {
|
||||
console.log('搜索关键词:', searchKeyword.value);
|
||||
// 这里可以实现搜索逻辑
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置筛选条件
|
||||
* @param {string} filter 筛选条件
|
||||
*/
|
||||
const setFilter = (filter) => {
|
||||
currentFilter.value = filter;
|
||||
console.log('筛选条件:', filter);
|
||||
// 这里可以实现筛选逻辑
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理添加员工
|
||||
*/
|
||||
const handleAddStaff = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pagesB/permissions/addStaff'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 处理权限设置
|
||||
* @param {Object} staff 员工信息
|
||||
*/
|
||||
const handleSetPermission = (staff) => {
|
||||
currentStaff.value = staff;
|
||||
|
||||
// 重置临时权限状态
|
||||
allPermissions.forEach(perm => {
|
||||
tempPermissions[perm.value] = staff.permissions.includes(perm.value);
|
||||
});
|
||||
|
||||
showPermissionPopup.value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 保存权限设置
|
||||
*/
|
||||
const savePermissions = () => {
|
||||
if (!currentStaff.value) return;
|
||||
|
||||
// 显示加载中提示
|
||||
uni.showLoading({
|
||||
title: '保存中...',
|
||||
mask: true
|
||||
});
|
||||
|
||||
// API调用示例
|
||||
// 这里只是示例,实际项目中请替换为真实的API调用
|
||||
const requestData = {
|
||||
staffId: currentStaff.value.id,
|
||||
permissions: currentStaff.value.permissions,
|
||||
villageId: villageId.value
|
||||
};
|
||||
|
||||
// 模拟API调用
|
||||
setTimeout(() => {
|
||||
// 实际项目中这里应该是真实的API调用,例如:
|
||||
/*
|
||||
uni.request({
|
||||
url: 'https://api.example.com/staff/permissions',
|
||||
method: 'POST',
|
||||
data: requestData,
|
||||
success: (res) => {
|
||||
if (res.data.code === 0) {
|
||||
// 更新本地数据
|
||||
updateLocalStaffPermissions();
|
||||
// 关闭弹窗并显示成功提示
|
||||
closePermissionSheet();
|
||||
uni.showToast({
|
||||
title: '权限设置成功',
|
||||
icon: 'success'
|
||||
});
|
||||
} else {
|
||||
uni.showToast({
|
||||
title: res.data.message || '保存失败',
|
||||
icon: 'none'
|
||||
});
|
||||
}
|
||||
},
|
||||
fail: (err) => {
|
||||
uni.showToast({
|
||||
title: '网络错误,请重试',
|
||||
icon: 'none'
|
||||
});
|
||||
console.error('保存权限失败:', err);
|
||||
},
|
||||
complete: () => {
|
||||
uni.hideLoading();
|
||||
}
|
||||
});
|
||||
*/
|
||||
|
||||
// 更新本地数据
|
||||
updateLocalStaffPermissions();
|
||||
|
||||
// 隐藏加载提示
|
||||
uni.hideLoading();
|
||||
|
||||
// 关闭弹窗并显示成功提示
|
||||
closePermissionSheet();
|
||||
uni.showToast({
|
||||
title: '权限设置成功',
|
||||
icon: 'success'
|
||||
});
|
||||
}, 800);
|
||||
};
|
||||
|
||||
/**
|
||||
* 更新本地员工权限数据
|
||||
*/
|
||||
const updateLocalStaffPermissions = () => {
|
||||
const index = staffList.value.findIndex(item => item.id === currentStaff.value.id);
|
||||
if (index !== -1) {
|
||||
staffList.value[index] = {
|
||||
...staffList.value[index],
|
||||
permissions: [...currentStaff.value.permissions]
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// 权限操作列表
|
||||
const permissionActions = [
|
||||
{ name: '配送权限', value: 'delivery', icon: 'ri-truck-line' },
|
||||
{ name: '维修权限', value: 'maintenance', icon: 'ri-tools-line' },
|
||||
{ name: '财务管理', value: 'finance', icon: 'ri-money-cny-circle-line' },
|
||||
{ name: '住户管理', value: 'resident', icon: 'ri-user-line' },
|
||||
{ name: '安防权限', value: 'security', icon: 'ri-shield-line' },
|
||||
{ name: '管理员权限', value: 'admin', icon: 'ri-admin-line' },
|
||||
{ name: '投诉处理', value: 'complaint', icon: 'ri-customer-service-line' },
|
||||
{ name: '巡检权限', value: 'inspection', icon: 'ri-survey-line' },
|
||||
];
|
||||
|
||||
// 切换权限筛选器
|
||||
const handleFilterChange = (filter) => {
|
||||
currentFilter.value = filter;
|
||||
};
|
||||
|
||||
// 重置筛选
|
||||
const resetFilter = () => {
|
||||
currentFilter.value = '全部';
|
||||
searchKeyword.value = '';
|
||||
};
|
||||
|
||||
// 清除搜索关键词
|
||||
const clearSearchKeyword = () => {
|
||||
searchKeyword.value = '';
|
||||
};
|
||||
|
||||
// 打开权限设置
|
||||
const openPermissionSetting = (staff) => {
|
||||
// 设置当前员工
|
||||
currentStaff.value = {
|
||||
...staff,
|
||||
// 创建一个权限数组的副本,避免直接修改原始数据
|
||||
permissions: [...staff.permissions]
|
||||
};
|
||||
|
||||
// 显示弹窗
|
||||
showPermissionPopup.value = true;
|
||||
};
|
||||
|
||||
// 关闭权限设置面板
|
||||
const closePermissionSheet = () => {
|
||||
showPermissionPopup.value = false;
|
||||
};
|
||||
|
||||
// 切换权限状态
|
||||
const togglePermission = (permission) => {
|
||||
if (!currentStaff.value) return;
|
||||
|
||||
const index = currentStaff.value.permissions.indexOf(permission);
|
||||
|
||||
if (index > -1) {
|
||||
// 移除已有权限
|
||||
currentStaff.value.permissions.splice(index, 1);
|
||||
} else {
|
||||
// 添加新权限
|
||||
currentStaff.value.permissions.push(permission);
|
||||
}
|
||||
};
|
||||
|
||||
// 检查权限是否已启用
|
||||
const hasPermission = (permission) => {
|
||||
if (!currentStaff.value) return false;
|
||||
return currentStaff.value.permissions.includes(permission);
|
||||
};
|
||||
|
||||
// 页面加载
|
||||
onLoad((options) => {
|
||||
if (options.villageId) {
|
||||
villageId.value = options.villageId;
|
||||
// 获取小区信息和员工列表
|
||||
getVillageInfo();
|
||||
getStaffList();
|
||||
}
|
||||
checkRouteStack();
|
||||
});
|
||||
|
||||
// 下拉刷新
|
||||
onPullDownRefresh(() => {
|
||||
getStaffList();
|
||||
setTimeout(() => {
|
||||
uni.stopPullDownRefresh();
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
// 处理wd-popup组件的close事件
|
||||
const handlePopupClose = () => {
|
||||
// 处理逻辑
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 主容器 */
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: transparent;
|
||||
position: relative;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Segoe UI, Arial, Roboto, PingFang SC, sans-serif;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
/* 导航栏背景 */
|
||||
.nav-bg-layer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(var(--status-bar-height) + 88rpx);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
||||
z-index: -1;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* 页面背景 */
|
||||
.page-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #f8fafd 0%, #eef2f9 100%);
|
||||
z-index: -2;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 30%;
|
||||
background: linear-gradient(135deg, rgba(76, 132, 255, 0.03), rgba(76, 132, 255, 0));
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
background: linear-gradient(315deg, rgba(76, 132, 255, 0.02), rgba(76, 132, 255, 0));
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 添加按钮 */
|
||||
.add-btn {
|
||||
width: 60rpx;
|
||||
height: 60rpx;
|
||||
border-radius: 50%;
|
||||
background-color: #4080FF;
|
||||
color: #FFFFFF;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 40rpx;
|
||||
box-shadow: 0 4rpx 8rpx rgba(64, 128, 255, 0.3);
|
||||
}
|
||||
|
||||
/* 内容区域 */
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding-bottom: 30rpx;
|
||||
/* #ifdef MP-WEIXIN */
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
/* #endif */
|
||||
/* #ifdef APP-PLUS || H5 */
|
||||
padding-bottom: 50rpx;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
/* 小区卡片 */
|
||||
.village-card {
|
||||
margin: 0 30rpx 30rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 24rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10rpx 30rpx rgba(31, 35, 172, 0.05);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 36rpx 40rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
border-bottom: 1rpx solid rgba(0, 0, 0, 0.03);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background: radial-gradient(circle at top right, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0));
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.village-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.badge-container {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 6rpx 20rpx;
|
||||
background-color: rgba(76, 132, 255, 0.1);
|
||||
border-radius: 30rpx;
|
||||
color: #4C84FF;
|
||||
|
||||
.badge-num {
|
||||
font-size: 28rpx;
|
||||
font-weight: bold;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
|
||||
.badge-text {
|
||||
font-size: 24rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 25rpx 40rpx;
|
||||
|
||||
.village-address {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
|
||||
.address-icon {
|
||||
color: #999;
|
||||
margin-right: 10rpx;
|
||||
font-size: 32rpx;
|
||||
}
|
||||
|
||||
.address-text {
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 搜索容器 */
|
||||
.search-wrapper {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: -15%;
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(76, 132, 255, 0.1), rgba(76, 132, 255, 0));
|
||||
z-index: -1;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -20rpx;
|
||||
right: -5%;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(66, 211, 170, 0.06), rgba(66, 211, 170, 0));
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* 筛选容器 */
|
||||
.filter-container {
|
||||
margin: 0 0 20rpx;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
/* 筛选标签 */
|
||||
.filter-tabs {
|
||||
white-space: nowrap;
|
||||
padding: 0 30rpx 10rpx;
|
||||
|
||||
.filter-tab {
|
||||
display: inline-block;
|
||||
padding: 15rpx 32rpx;
|
||||
margin-right: 15rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 50rpx;
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
box-shadow: 0 6rpx 12rpx rgba(76, 132, 255, 0.06);
|
||||
transition: all 0.3s;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0));
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
&.active {
|
||||
background-color: #4080FF;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 8rpx 16rpx rgba(64, 128, 255, 0.3);
|
||||
|
||||
&:before {
|
||||
background: linear-gradient(135deg, rgba(255, 255, 255, 0.3), rgba(255, 255, 255, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 员工列表 */
|
||||
.staff-list {
|
||||
padding: 0 30rpx;
|
||||
}
|
||||
|
||||
/* 员工卡片 */
|
||||
.staff-card {
|
||||
padding: 24rpx;
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
margin-bottom: 16rpx;
|
||||
position: relative;
|
||||
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.03);
|
||||
transition: all 0.3s;
|
||||
// border-left: 3rpx solid #0070F0;
|
||||
|
||||
&:active {
|
||||
transform: translateY(1rpx);
|
||||
background-color: #fafafa;
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
.staff-avatar {
|
||||
width: 64rpx;
|
||||
height: 64rpx;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
margin-right: 16rpx;
|
||||
flex-shrink: 0;
|
||||
background-color: #f2f8ff;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
&.default-avatar {
|
||||
background-color: #0070F0;
|
||||
color: #fff;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 26rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.staff-info {
|
||||
flex: 1;
|
||||
|
||||
.staff-name {
|
||||
font-size: 28rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 4rpx;
|
||||
}
|
||||
|
||||
.staff-phone {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.phone-icon {
|
||||
font-size: 22rpx;
|
||||
color: #999;
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.right-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.action-icon {
|
||||
font-size: 32rpx;
|
||||
color: #ddd;
|
||||
margin-left: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-content {
|
||||
margin-top: 12rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 权限标签 */
|
||||
.perm-tags {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 2rpx;
|
||||
|
||||
.perm-tag {
|
||||
height: 38rpx;
|
||||
line-height: 38rpx;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
padding: 0 10rpx;
|
||||
background-color: #f0f7ff;
|
||||
color: #0070F0;
|
||||
font-size: 24rpx;
|
||||
border-radius: 4rpx;
|
||||
margin-right: 10rpx;
|
||||
margin-bottom: 0;
|
||||
|
||||
text {
|
||||
&:first-child {
|
||||
margin-right: 4rpx;
|
||||
font-size: 22rpx;
|
||||
}
|
||||
}
|
||||
|
||||
&.more {
|
||||
background-color: #f0f0f0;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
&.delivery-color {
|
||||
background-color: #f0f7ff;
|
||||
color: #0070F0;
|
||||
}
|
||||
|
||||
&.maintenance-color {
|
||||
background-color: #f0f7ff;
|
||||
color: #0070F0;
|
||||
}
|
||||
|
||||
&.finance-color {
|
||||
background-color: #f0f7ff;
|
||||
color: #0070F0;
|
||||
}
|
||||
|
||||
&.admin-color {
|
||||
background-color: #f0f7ff;
|
||||
color: #0070F0;
|
||||
}
|
||||
|
||||
&.general-color {
|
||||
background-color: #f0f7ff;
|
||||
color: #0070F0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.no-perm-tag {
|
||||
font-size: 24rpx;
|
||||
color: #999;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.ri-lock-line {
|
||||
margin-right: 4rpx;
|
||||
}
|
||||
}
|
||||
|
||||
/* 空状态 */
|
||||
.empty-state {
|
||||
padding: 100rpx 0;
|
||||
}
|
||||
|
||||
.perm-count {
|
||||
min-width: 32rpx;
|
||||
height: 32rpx;
|
||||
padding: 0 6rpx;
|
||||
border-radius: 16rpx;
|
||||
background-color: #0070F0;
|
||||
color: #fff;
|
||||
font-size: 22rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,596 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<!-- 自定义导航栏 -->
|
||||
<wd-navbar :bordered="false"
|
||||
custom-style="background: transparent !important; backdrop-filter: blur(10px) !important; -webkit-backdrop-filter: blur(20px) !important;"
|
||||
safeAreaInsetTop fixed placeholder>
|
||||
<template #left>
|
||||
<view class="li-ml-15 li-mt-10 li-flex li-items-center">
|
||||
<text v-if="hasMultiplePages" class="ri-arrow-left-s-line li-text-70"
|
||||
@click="toPages({type:'nav'})"></text>
|
||||
<text v-if="!hasMultiplePages" class="ri-home-5-line li-text-55 li-mb-8 li-mr-10"
|
||||
@click="toPages({type:'home'})"></text>
|
||||
<text class="li-text-42">小区列表</text>
|
||||
</view>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
<!-- 导航栏背景 -->
|
||||
<view class="nav-bg-layer"></view>
|
||||
|
||||
<!-- 页面背景 -->
|
||||
<view class="page-bg"></view>
|
||||
|
||||
<view class="content">
|
||||
<!-- 搜索区域 -->
|
||||
<view class="search-wrapper li-w-90% li-mx-auto li-mt-30">
|
||||
<wd-search placeholderStyle="color:#a0aec0" v-model="searchKeyword" placeholder="搜索小区名称或地址" hide-cancel
|
||||
placeholder-left @search="handleSearch">
|
||||
<!-- <template #prefix>
|
||||
<text class="ri-search-line li-text-36 li-text-#4C84FF"></text>
|
||||
</template> -->
|
||||
</wd-search>
|
||||
</view>
|
||||
|
||||
<!-- 小区列表 -->
|
||||
<view class="village-list li-w-92% li-mx-auto li-mt-30">
|
||||
<view class="village-card" v-for="(item, index) in villageList" :key="index"
|
||||
@click="handleSelectVillage(item)">
|
||||
<view class="card-header">
|
||||
<view class="village-name">{{item.name}}</view>
|
||||
<view class="badge-container">
|
||||
<view class="badge li-mr-20">
|
||||
<text class="badge-num">{{item.staffCount}}</text>
|
||||
<text class="badge-text">员工</text>
|
||||
</view>
|
||||
<view class="badge">
|
||||
<text class="badge-num">{{item.buildingCount}}</text>
|
||||
<text class="badge-text">楼栋</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-content">
|
||||
<view class="village-address">
|
||||
<text class="ri-map-pin-line address-icon"></text>
|
||||
<text class="address-text">{{item.address}}</text>
|
||||
</view>
|
||||
<view class="village-action">
|
||||
<text class="action-text">设置权限</text>
|
||||
<text class="ri-arrow-right-s-line action-icon"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-footer">
|
||||
<view class="footer-tag">
|
||||
<text class="ri-building-2-line"></text>
|
||||
<text>物业管理</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 空状态 -->
|
||||
<view v-if="villageList.length === 0" class="empty-state li-mt-100">
|
||||
<wd-status-tip image="search" tip="暂无小区数据" />
|
||||
<view class="empty-action">
|
||||
<wd-button type="primary" custom-class="add-village-btn" @click="handleAddVillage">添加小区</wd-button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ref
|
||||
} from 'vue';
|
||||
import {
|
||||
useNavigation
|
||||
} from '@/hooks/useNavigation';
|
||||
import {
|
||||
onLoad,
|
||||
onPullDownRefresh,
|
||||
onReachBottom
|
||||
} from '@dcloudio/uni-app';
|
||||
|
||||
// 使用导航composable
|
||||
const {
|
||||
hasMultiplePages,
|
||||
isTabBarPage,
|
||||
checkRouteStack
|
||||
} = useNavigation();
|
||||
|
||||
// 搜索关键词
|
||||
const searchKeyword = ref('');
|
||||
|
||||
// 小区列表数据
|
||||
const villageList = ref([{
|
||||
id: 1,
|
||||
name: '阳光花园小区',
|
||||
address: '市政府北路123号',
|
||||
staffCount: 12,
|
||||
buildingCount: 8
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
name: '翠湖庭院',
|
||||
address: '湖滨路456号',
|
||||
staffCount: 8,
|
||||
buildingCount: 5
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
name: '金色家园',
|
||||
address: '市政府东路789号',
|
||||
staffCount: 15,
|
||||
buildingCount: 10
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
name: '铂金公寓',
|
||||
address: '南山大道458号',
|
||||
staffCount: 9,
|
||||
buildingCount: 6
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
name: '滨江华府',
|
||||
address: '滨河路367号',
|
||||
staffCount: 18,
|
||||
buildingCount: 14
|
||||
}
|
||||
]);
|
||||
|
||||
/**
|
||||
* 处理搜索
|
||||
*/
|
||||
const handleSearch = () => {
|
||||
console.log('搜索关键词:', searchKeyword.value);
|
||||
// TODO: 实现搜索逻辑
|
||||
};
|
||||
|
||||
/**
|
||||
* 选择小区,前往权限设置页面
|
||||
* @param {Object} village 小区数据
|
||||
*/
|
||||
const handleSelectVillage = (village) => {
|
||||
// 跳转到员工列表页面
|
||||
uni.navigateTo({
|
||||
url: '/pagesB/permissions/staffList?villageId=' + village.id
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 添加小区
|
||||
*/
|
||||
const handleAddVillage = () => {
|
||||
// TODO: 实现添加小区的逻辑
|
||||
uni.showToast({
|
||||
title: '添加小区功能开发中',
|
||||
icon: 'none'
|
||||
});
|
||||
};
|
||||
|
||||
// 页面跳转
|
||||
const toPages = (item) => {
|
||||
switch (item.type) {
|
||||
case 'nav':
|
||||
uni.navigateBack({
|
||||
delta: 1
|
||||
});
|
||||
break;
|
||||
case 'home':
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
});
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// 生命周期钩子
|
||||
onLoad(() => {
|
||||
checkRouteStack();
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: transparent;
|
||||
position: relative;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Segoe UI, Arial, Roboto, PingFang SC, sans-serif;
|
||||
}
|
||||
|
||||
.page-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #f8fafd 0%, #eef2f9 100%);
|
||||
z-index: -2;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
height: 30%;
|
||||
background: linear-gradient(135deg, rgba(76, 132, 255, 0.03), rgba(76, 132, 255, 0));
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
background: linear-gradient(315deg, rgba(76, 132, 255, 0.02), rgba(76, 132, 255, 0));
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
.nav-bg-layer {
|
||||
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(var(--status-bar-height) + 88rpx);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
||||
z-index: -1;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding-bottom: 30rpx;
|
||||
/* #ifdef MP-WEIXIN */
|
||||
padding-bottom: constant(safe-area-inset-bottom);
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
/* #endif */
|
||||
/* #ifdef APP-PLUS || H5 */
|
||||
padding-bottom: 50rpx;
|
||||
/* #endif */
|
||||
}
|
||||
|
||||
.search-wrapper {
|
||||
position: relative;
|
||||
z-index: 3;
|
||||
margin-bottom: 40rpx;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: -15%;
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(76, 132, 255, 0.1), rgba(76, 132, 255, 0));
|
||||
z-index: -1;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: -20rpx;
|
||||
right: -5%;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, rgba(66, 211, 170, 0.06), rgba(66, 211, 170, 0));
|
||||
z-index: -1;
|
||||
}
|
||||
}
|
||||
|
||||
.village-list {
|
||||
.village-card {
|
||||
background-color: #fff;
|
||||
border-radius: 24rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 10rpx 30rpx rgba(31, 35, 172, 0.05);
|
||||
margin-bottom: 30rpx;
|
||||
transition: all 0.4s cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 6rpx;
|
||||
height: 100%;
|
||||
background: linear-gradient(180deg, #4C84FF, #6EAEFE);
|
||||
opacity: 0;
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: translateY(2rpx) scale(0.99);
|
||||
box-shadow: 0 6rpx 15rpx rgba(31, 35, 172, 0.03);
|
||||
|
||||
&::before {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.card-header {
|
||||
padding: 36rpx 40rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: linear-gradient(135deg, rgba(76, 132, 255, 0.06), rgba(76, 132, 255, 0.12));
|
||||
border-bottom: 1rpx solid rgba(0, 0, 0, 0.03);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 200rpx;
|
||||
height: 200rpx;
|
||||
background: radial-gradient(circle at top right, rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0));
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.village-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
background: linear-gradient(90deg, #333, #555);
|
||||
-webkit-background-clip: text;
|
||||
color: transparent;
|
||||
letter-spacing: 1rpx;
|
||||
}
|
||||
|
||||
.badge-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
|
||||
.badge {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: rgba(76, 132, 255, 0.1);
|
||||
padding: 10rpx 24rpx;
|
||||
border-radius: 12rpx;
|
||||
box-shadow: 0 4rpx 12rpx rgba(76, 132, 255, 0.1);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 1rpx;
|
||||
background: linear-gradient(90deg, rgba(255, 255, 255, 0), rgba(255, 255, 255, 0.8), rgba(255, 255, 255, 0));
|
||||
}
|
||||
|
||||
.badge-num {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #4C84FF;
|
||||
text-shadow: 0 1rpx 2rpx rgba(76, 132, 255, 0.1);
|
||||
}
|
||||
|
||||
.badge-text {
|
||||
font-size: 22rpx;
|
||||
color: #666;
|
||||
margin-top: 2rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-content {
|
||||
padding: 30rpx 40rpx;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 40rpx;
|
||||
right: 40rpx;
|
||||
height: 1px;
|
||||
background: linear-gradient(90deg, rgba(0, 0, 0, 0), rgba(0, 0, 0, 0.03), rgba(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
.village-address {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.address-text {
|
||||
font-size: 28rpx;
|
||||
color: #666;
|
||||
margin-left: 6rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.village-action {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
background: rgba(76, 132, 255, 0.06);
|
||||
padding: 10rpx 20rpx;
|
||||
border-radius: 40rpx;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:active {
|
||||
background: rgba(76, 132, 255, 0.1);
|
||||
transform: translateX(-4rpx);
|
||||
}
|
||||
|
||||
.action-text {
|
||||
font-size: 26rpx;
|
||||
color: #4C84FF;
|
||||
margin-right: 8rpx;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 覆盖组件样式 */
|
||||
::v-deep .wd-search {
|
||||
background-color: transparent !important;
|
||||
padding: 0 !important;
|
||||
}
|
||||
|
||||
::v-deep .wd-search__block {
|
||||
background-color: rgba(255, 255, 255, 0.9) !important;
|
||||
padding: 20rpx 30rpx !important;
|
||||
border-radius: 20rpx !important;
|
||||
box-shadow: 0 15rpx 30rpx rgba(31, 35, 172, 0.05);
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
border: 1rpx solid rgba(255, 255, 255, 0.8);
|
||||
}
|
||||
|
||||
::v-deep .wd-search__input {
|
||||
font-size: 28rpx !important;
|
||||
color: #333 !important;
|
||||
}
|
||||
|
||||
::v-deep .wd-search__input-inner {
|
||||
height: 70rpx !important;
|
||||
}
|
||||
|
||||
::v-deep .wd-search__placeholder {
|
||||
font-size: 28rpx !important;
|
||||
}
|
||||
|
||||
::v-deep .wd-search__label {
|
||||
color: #4C84FF !important;
|
||||
}
|
||||
|
||||
::v-deep .wd-status-tip__text {
|
||||
margin-top: 30rpx !important;
|
||||
color: #999 !important;
|
||||
font-size: 30rpx !important;
|
||||
}
|
||||
|
||||
::v-deep .wd-status-tip__image {
|
||||
opacity: 0.8 !important;
|
||||
}
|
||||
|
||||
.page-title {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 40rpx;
|
||||
margin-top: 20rpx;
|
||||
|
||||
.title-wrapper {
|
||||
.title-main {
|
||||
font-size: 44rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-right: 15rpx;
|
||||
background: linear-gradient(90deg, #333, #555);
|
||||
-webkit-background-clip: text;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.title-sub {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin-left: 15rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.add-button {
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
border-radius: 50%;
|
||||
background: linear-gradient(135deg, #4C84FF, #6EAEFE);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
box-shadow: 0 6rpx 20rpx rgba(76, 132, 255, 0.3);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.92);
|
||||
box-shadow: 0 3rpx 10rpx rgba(76, 132, 255, 0.2);
|
||||
}
|
||||
|
||||
text {
|
||||
color: white;
|
||||
font-size: 44rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.address-icon {
|
||||
color: #999;
|
||||
font-size: 32rpx;
|
||||
margin-right: 2rpx;
|
||||
}
|
||||
|
||||
.action-icon {
|
||||
color: #4C84FF;
|
||||
font-size: 36rpx;
|
||||
}
|
||||
|
||||
.card-footer {
|
||||
padding: 20rpx 40rpx;
|
||||
border-top: 1rpx solid rgba(0, 0, 0, 0.03);
|
||||
background: #fafbfc;
|
||||
|
||||
.footer-tag {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
background: rgba(76, 132, 255, 0.06);
|
||||
padding: 6rpx 16rpx;
|
||||
border-radius: 8rpx;
|
||||
|
||||
text:first-child {
|
||||
color: #4C84FF;
|
||||
font-size: 28rpx;
|
||||
margin-right: 6rpx;
|
||||
}
|
||||
|
||||
text:last-child {
|
||||
font-size: 24rpx;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
.empty-action {
|
||||
margin-top: 40rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.add-village-btn {
|
||||
background: linear-gradient(135deg, #4C84FF, #6EAEFE) !important;
|
||||
border: none !important;
|
||||
box-shadow: 0 6rpx 20rpx rgba(76, 132, 255, 0.2) !important;
|
||||
border-radius: 12rpx !important;
|
||||
font-weight: 500 !important;
|
||||
letter-spacing: 2rpx !important;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,511 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<!-- 自定义导航栏 -->
|
||||
<wd-navbar :bordered="false"
|
||||
custom-style="background: transparent !important; backdrop-filter: blur(10px) !important; -webkit-backdrop-filter: blur(20px) !important;"
|
||||
safeAreaInsetTop fixed placeholder>
|
||||
<template #left>
|
||||
<view class="li-ml-15 li-mt-10 li-flex li-items-center">
|
||||
<text v-if="hasMultiplePages" class="ri-arrow-left-s-line li-text-70"
|
||||
@click="toPages({type:'nav'})"></text>
|
||||
<text v-if="!hasMultiplePages" class="ri-home-5-line li-text-55 li-mb-8 li-mr-10"
|
||||
@click="toPages({type:'home'})"></text>
|
||||
<text class="li-text-42">个人信息</text>
|
||||
</view>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
<!-- 导航栏背景 -->
|
||||
<view class="nav-bg-layer"></view>
|
||||
|
||||
<!-- 页面背景 -->
|
||||
<view class="page-bg"></view>
|
||||
|
||||
<view class="content">
|
||||
<!-- 个人信息表单 -->
|
||||
<view class="form-container">
|
||||
<!-- 头像设置 -->
|
||||
<view class="avatar-section" @click="chooseAvatar">
|
||||
<view class="section-left">
|
||||
<text class="form-label">头像</text>
|
||||
</view>
|
||||
<view class="section-right">
|
||||
<view class="user-avatar">
|
||||
<image v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill"></image>
|
||||
<view v-else class="default-avatar">{{ userInfo.nickname.substring(0, 1) }}</view>
|
||||
</view>
|
||||
<text class="ri-arrow-right-s-line arrow-icon"></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 昵称设置 -->
|
||||
<view class="form-section">
|
||||
<view class="section-left">
|
||||
<text class="form-label">昵称</text>
|
||||
</view>
|
||||
<view class="section-right">
|
||||
<view class="input-wrapper">
|
||||
<input class="form-input" type="text" v-model="userInfo.nickname" placeholder="请输入昵称"
|
||||
@blur="validateNickname" />
|
||||
</view>
|
||||
<text class="ri-arrow-right-s-line arrow-icon"></text>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 手机号展示 -->
|
||||
<view class="form-section">
|
||||
<view class="section-left">
|
||||
<text class="form-label">手机号</text>
|
||||
</view>
|
||||
<view class="section-right">
|
||||
<text class="phone-text">{{ formatPhone(userInfo.phone) }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 保存按钮 -->
|
||||
<view class="save-btn-container">
|
||||
<button class="save-btn" @click="saveUserInfo">保存</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 头像选择弹窗 -->
|
||||
<wd-popup v-model="showAvatarPopup" position="bottom">
|
||||
<view class="avatar-popup">
|
||||
<view class="popup-title">修改头像</view>
|
||||
<view class="avatar-options">
|
||||
<view class="option-item" @click="handleSelectAlbum">
|
||||
<text class="ri-image-2-line option-icon"></text>
|
||||
<text class="option-text">从相册选择</text>
|
||||
</view>
|
||||
<view class="option-item" @click="handleTakePhoto">
|
||||
<text class="ri-camera-line option-icon"></text>
|
||||
<text class="option-text">拍照</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="cancel-btn" @click="showAvatarPopup = false">取消</view>
|
||||
</view>
|
||||
</wd-popup>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {
|
||||
ref,
|
||||
reactive,
|
||||
onMounted
|
||||
} from 'vue';
|
||||
import {
|
||||
useNavigation
|
||||
} from '@/hooks/useNavigation';
|
||||
import {
|
||||
onLoad
|
||||
} from '@dcloudio/uni-app'
|
||||
|
||||
// 使用导航 composable
|
||||
const {
|
||||
hasMultiplePages, // 是否有多个页面在路由栈中
|
||||
isTabBarPage, // 当前页面是否为 tabBar 页面
|
||||
checkRouteStack // 检查当前路由栈状态的方法
|
||||
} = useNavigation()
|
||||
|
||||
|
||||
// 用户信息
|
||||
const userInfo = reactive({
|
||||
nickname: '里派用户',
|
||||
phone: '13800138000',
|
||||
avatar: ''
|
||||
});
|
||||
|
||||
// 头像选择弹窗
|
||||
const showAvatarPopup = ref(false);
|
||||
|
||||
/**
|
||||
* 格式化手机号码为带星号格式
|
||||
*/
|
||||
const formatPhone = (phone) => {
|
||||
if (!phone) return '';
|
||||
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||
};
|
||||
|
||||
/**
|
||||
* 校验昵称
|
||||
*/
|
||||
const validateNickname = () => {
|
||||
if (!userInfo.nickname.trim()) {
|
||||
uni.showToast({
|
||||
title: '昵称不能为空',
|
||||
icon: 'none'
|
||||
});
|
||||
userInfo.nickname = '里派用户';
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 选择头像
|
||||
*/
|
||||
const chooseAvatar = () => {
|
||||
showAvatarPopup.value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 从相册选择照片
|
||||
*/
|
||||
const handleSelectAlbum = () => {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['album'],
|
||||
success: (res) => {
|
||||
// 选择成功后关闭弹窗
|
||||
showAvatarPopup.value = false;
|
||||
|
||||
// 处理选中的图片
|
||||
const tempFilePath = res.tempFilePaths[0];
|
||||
|
||||
// 在实际应用中,这里应该先上传图片到服务器,获取到图片URL后再更新用户头像
|
||||
// 这里简单模拟一下上传过程
|
||||
uni.showLoading({
|
||||
title: '上传中...'
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
uni.hideLoading();
|
||||
userInfo.avatar = tempFilePath;
|
||||
uni.showToast({
|
||||
title: '头像已更新',
|
||||
icon: 'success'
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 拍照
|
||||
*/
|
||||
const handleTakePhoto = () => {
|
||||
uni.chooseImage({
|
||||
count: 1,
|
||||
sizeType: ['compressed'],
|
||||
sourceType: ['camera'],
|
||||
success: (res) => {
|
||||
// 选择成功后关闭弹窗
|
||||
showAvatarPopup.value = false;
|
||||
|
||||
// 处理拍摄的照片
|
||||
const tempFilePath = res.tempFilePaths[0];
|
||||
|
||||
// 在实际应用中,这里应该先上传图片到服务器,获取到图片URL后再更新用户头像
|
||||
// 这里简单模拟一下上传过程
|
||||
uni.showLoading({
|
||||
title: '上传中...'
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
uni.hideLoading();
|
||||
userInfo.avatar = tempFilePath;
|
||||
uni.showToast({
|
||||
title: '头像已更新',
|
||||
icon: 'success'
|
||||
});
|
||||
}, 1000);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const toPages = (item) => {
|
||||
if (item.type === 'nav') {
|
||||
uni.navigateBack()
|
||||
} else if (item.type === 'home') {
|
||||
// 这里是项目内部的跳转逻辑
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 保存用户信息
|
||||
*/
|
||||
const saveUserInfo = () => {
|
||||
// 表单验证
|
||||
if (!userInfo.nickname.trim()) {
|
||||
uni.showToast({
|
||||
title: '昵称不能为空',
|
||||
icon: 'none'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 显示加载中
|
||||
uni.showLoading({
|
||||
title: '保存中...'
|
||||
});
|
||||
|
||||
// 模拟保存过程
|
||||
setTimeout(() => {
|
||||
// 保存成功后的处理
|
||||
uni.hideLoading();
|
||||
|
||||
// 将用户信息保存到缓存
|
||||
uni.setStorageSync('userInfo', JSON.stringify(userInfo));
|
||||
|
||||
// 显示成功提示
|
||||
uni.showToast({
|
||||
title: '保存成功',
|
||||
icon: 'success'
|
||||
});
|
||||
|
||||
// 返回上一页
|
||||
setTimeout(() => {
|
||||
goBack();
|
||||
}, 1500);
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
/**
|
||||
* 返回上一页
|
||||
*/
|
||||
const goBack = () => {
|
||||
uni.navigateBack();
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
checkRouteStack()
|
||||
// 获取用户信息
|
||||
const userInfoStorage = uni.getStorageSync('userInfo');
|
||||
if (userInfoStorage) {
|
||||
Object.assign(userInfo, JSON.parse(userInfoStorage));
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 主容器 */
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: transparent;
|
||||
position: relative;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Segoe UI, Arial, Roboto, PingFang SC, sans-serif;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
/* 导航栏背景 */
|
||||
.nav-bg-layer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(var(--status-bar-height) + 88rpx);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
||||
z-index: -1;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* 页面背景 */
|
||||
.page-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #f8fafd 0%, #eef2f9 100%);
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
/* 内容区域 */
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
/* 表单容器 */
|
||||
.form-container {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
/* 头像设置区域 */
|
||||
.avatar-section {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
.section-left {
|
||||
.form-label {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.section-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.user-avatar {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
overflow: hidden;
|
||||
margin-right: 16rpx;
|
||||
border: 2rpx solid rgba(0, 0, 0, 0.05);
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.default-avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #4080FF, #5E96FF);
|
||||
color: #fff;
|
||||
font-size: 48rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
font-size: 44rpx;
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 表单项 */
|
||||
.form-section {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 30rpx;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.section-left {
|
||||
.form-label {
|
||||
font-size: 32rpx;
|
||||
color: #333;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.section-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.input-wrapper {
|
||||
text-align: right;
|
||||
|
||||
.form-input {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
text-align: right;
|
||||
min-width: 200rpx;
|
||||
}
|
||||
}
|
||||
|
||||
.phone-text {
|
||||
font-size: 30rpx;
|
||||
color: #999;
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
font-size: 44rpx;
|
||||
color: #ccc;
|
||||
margin-left: 16rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 保存按钮 */
|
||||
.save-btn-container {
|
||||
padding: 0 20rpx;
|
||||
margin-top: 60rpx;
|
||||
|
||||
.save-btn {
|
||||
background-color: #4080FF;
|
||||
color: #fff;
|
||||
border: none;
|
||||
height: 96rpx;
|
||||
line-height: 96rpx;
|
||||
font-size: 32rpx;
|
||||
border-radius: 16rpx;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 4rpx 16rpx rgba(64, 128, 255, 0.3);
|
||||
|
||||
&:active {
|
||||
background-color: #3a75e6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 头像选择弹窗 */
|
||||
.avatar-popup {
|
||||
background-color: #fff;
|
||||
border-radius: 24rpx 24rpx 0 0;
|
||||
overflow: hidden;
|
||||
|
||||
.popup-title {
|
||||
text-align: center;
|
||||
font-size: 32rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
padding: 30rpx 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
|
||||
.avatar-options {
|
||||
padding: 20rpx 0;
|
||||
|
||||
.option-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 30rpx 0;
|
||||
|
||||
.option-icon {
|
||||
font-size: 60rpx;
|
||||
color: #4080FF;
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.option-text {
|
||||
font-size: 28rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.cancel-btn {
|
||||
border-top: 12rpx solid #f5f5f5;
|
||||
text-align: center;
|
||||
padding: 30rpx 0;
|
||||
font-size: 32rpx;
|
||||
color: #999;
|
||||
|
||||
&:active {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,489 @@
|
|||
<template>
|
||||
<view class="container">
|
||||
<!-- 自定义导航栏 -->
|
||||
<wd-navbar :bordered="false"
|
||||
custom-style="background: transparent !important; backdrop-filter: blur(10px) !important; -webkit-backdrop-filter: blur(20px) !important;"
|
||||
safeAreaInsetTop fixed placeholder>
|
||||
<template #left>
|
||||
<view class="li-ml-15 li-mt-10 li-flex li-items-center">
|
||||
<text v-if="hasMultiplePages" class="ri-arrow-left-s-line li-text-70"
|
||||
@click="toPages({type:'nav'})"></text>
|
||||
<text v-if="!hasMultiplePages" class="ri-home-5-line li-text-55 li-mb-8 li-mr-10"
|
||||
@click="toPages({type:'home'})"></text>
|
||||
<text class="li-text-42">设置</text>
|
||||
</view>
|
||||
</template>
|
||||
</wd-navbar>
|
||||
<!-- 导航栏背景 -->
|
||||
<view class="nav-bg-layer"></view>
|
||||
|
||||
<!-- 页面背景 -->
|
||||
<view class="page-bg"></view>
|
||||
|
||||
<view class="content">
|
||||
<!-- 用户信息预览 -->
|
||||
<view class="user-preview" @click="handleEditInfo">
|
||||
<view class="user-avatar">
|
||||
<image v-if="userInfo.avatar" :src="userInfo.avatar" mode="aspectFill"></image>
|
||||
<view v-else class="default-avatar">{{userInfo.nickname.substring(0,1)}}</view>
|
||||
</view>
|
||||
<view class="user-detail">
|
||||
<view class="user-name">{{userInfo.nickname || '未设置昵称'}}</view>
|
||||
<view class="user-phone">{{formatPhone(userInfo.phone)}}</view>
|
||||
</view>
|
||||
<text class="ri-arrow-right-s-line arrow-icon"></text>
|
||||
</view>
|
||||
|
||||
<view class="setting-section">
|
||||
<view class="setting-list">
|
||||
<view class="setting-item" @click="clearCache">
|
||||
<view class="item-left">
|
||||
<text class="ri-delete-bin-5-line item-icon cache-color"></text>
|
||||
<text class="item-title">清除缓存</text>
|
||||
</view>
|
||||
<view class="item-right">
|
||||
<text class="cache-size">{{cacheSize}}</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="setting-item" @click="handlePrivacyPolicy">
|
||||
<view class="item-left">
|
||||
<text class="ri-file-text-line item-icon privacy-color"></text>
|
||||
<text class="item-title">隐私政策</text>
|
||||
</view>
|
||||
<view class="item-right">
|
||||
<text class="ri-arrow-right-s-line arrow-icon"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="setting-item" @click="handleUserAgreement">
|
||||
<view class="item-left">
|
||||
<text class="ri-file-list-3-line item-icon agreement-color"></text>
|
||||
<text class="item-title">用户协议</text>
|
||||
</view>
|
||||
<view class="item-right">
|
||||
<text class="ri-arrow-right-s-line arrow-icon"></text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="setting-item" @click="checkUpdate">
|
||||
<view class="item-left">
|
||||
<text class="ri-information-line item-icon about-color"></text>
|
||||
<text class="item-title">关于我们</text>
|
||||
</view>
|
||||
<view class="item-right">
|
||||
<text class="version-text">v{{appVersion}}</text>
|
||||
<text class="ri-arrow-right-s-line arrow-icon"></text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 退出登录按钮 -->
|
||||
<view class="logout-container">
|
||||
<button class="logout-btn" @click="handleLogout">退出登录</button>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 确认弹窗 -->
|
||||
<wd-dialog v-model="showLogoutDialog" title="退出登录" :show-cancel-button="true" @confirm="confirmLogout">
|
||||
<view class="dialog-content">
|
||||
确定要退出登录吗?
|
||||
</view>
|
||||
</wd-dialog>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from 'vue';
|
||||
import { useNavigation } from '@/hooks/useNavigation';
|
||||
import { onLoad } from '@dcloudio/uni-app'
|
||||
|
||||
|
||||
// 使用导航 composable
|
||||
const {
|
||||
hasMultiplePages, // 是否有多个页面在路由栈中
|
||||
isTabBarPage, // 当前页面是否为 tabBar 页面
|
||||
checkRouteStack // 检查当前路由栈状态的方法
|
||||
} = useNavigation()
|
||||
|
||||
// 用户信息
|
||||
const userInfo = reactive({
|
||||
nickname: '里派用户',
|
||||
phone: '13800138000',
|
||||
avatar: ''
|
||||
});
|
||||
|
||||
// 缓存大小
|
||||
const cacheSize = ref('4.8MB');
|
||||
|
||||
// 应用版本
|
||||
const appVersion = ref('1.0.0');
|
||||
|
||||
// 深色模式
|
||||
const isDarkMode = ref(false);
|
||||
|
||||
// 登出对话框
|
||||
const showLogoutDialog = ref(false);
|
||||
|
||||
/**
|
||||
* 格式化手机号码为带星号格式
|
||||
*/
|
||||
const formatPhone = (phone) => {
|
||||
if (!phone) return '';
|
||||
return phone.replace(/(\d{3})\d{4}(\d{4})/, '$1****$2');
|
||||
};
|
||||
|
||||
// 页面跳转
|
||||
const toPages = (item : any) => {
|
||||
if (item.type === 'nav') {
|
||||
uni.navigateBack()
|
||||
} else if (item.type === 'home') {
|
||||
// 这里是项目内部的跳转逻辑
|
||||
uni.switchTab({
|
||||
url: '/pages/index/index'
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理修改用户信息
|
||||
*/
|
||||
const handleEditInfo = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pagesB/setting/editInfo'
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 清除缓存
|
||||
*/
|
||||
const clearCache = () => {
|
||||
uni.showLoading({
|
||||
title: '清理中...'
|
||||
});
|
||||
|
||||
// 模拟清理过程
|
||||
setTimeout(() => {
|
||||
uni.hideLoading();
|
||||
cacheSize.value = '0KB';
|
||||
uni.showToast({
|
||||
title: '缓存已清理',
|
||||
icon: 'success'
|
||||
});
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
/**
|
||||
* 查看隐私政策
|
||||
*/
|
||||
const handlePrivacyPolicy = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pagesA/other/privacy'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 查看用户协议
|
||||
*/
|
||||
const handleUserAgreement = () => {
|
||||
uni.navigateTo({
|
||||
url: '/pagesA/other/agreement'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 检查更新
|
||||
*/
|
||||
const checkUpdate = () => {
|
||||
uni.showToast({
|
||||
title: '当前已是最新版本',
|
||||
icon: 'none'
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* 显示退出登录确认框
|
||||
*/
|
||||
const handleLogout = () => {
|
||||
showLogoutDialog.value = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* 确认退出登录
|
||||
*/
|
||||
const confirmLogout = () => {
|
||||
uni.showLoading({
|
||||
title: '退出中...'
|
||||
});
|
||||
|
||||
// 模拟退出过程
|
||||
setTimeout(() => {
|
||||
uni.hideLoading();
|
||||
|
||||
// 清除登录状态及相关缓存
|
||||
uni.removeStorageSync('token');
|
||||
uni.removeStorageSync('userInfo');
|
||||
|
||||
// 跳转到登录页
|
||||
uni.reLaunch({
|
||||
url: '/pages/login/index'
|
||||
});
|
||||
}, 1000);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
checkRouteStack()
|
||||
// 获取用户信息
|
||||
const userInfoStorage = uni.getStorageSync('userInfo');
|
||||
if (userInfoStorage) {
|
||||
Object.assign(userInfo, JSON.parse(userInfoStorage));
|
||||
}
|
||||
|
||||
// 获取缓存大小
|
||||
uni.getStorageInfo({
|
||||
success: (res) => {
|
||||
const size = res.currentSize;
|
||||
if (size < 1024) {
|
||||
cacheSize.value = size + 'KB';
|
||||
} else {
|
||||
cacheSize.value = (size / 1024).toFixed(1) + 'MB';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 获取应用版本
|
||||
// #ifdef APP-PLUS
|
||||
plus.runtime.getProperty(plus.runtime.appid, (res) => {
|
||||
appVersion.value = res.version;
|
||||
});
|
||||
// #endif
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
/* 主容器 */
|
||||
.container {
|
||||
min-height: 100vh;
|
||||
background-color: transparent;
|
||||
position: relative;
|
||||
font-family: -apple-system, BlinkMacSystemFont, Helvetica Neue, Helvetica, Segoe UI, Arial, Roboto, PingFang SC, sans-serif;
|
||||
padding-bottom: env(safe-area-inset-bottom);
|
||||
}
|
||||
|
||||
/* 导航栏背景 */
|
||||
.nav-bg-layer {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: calc(var(--status-bar-height) + 88rpx);
|
||||
background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.9) 100%);
|
||||
z-index: -1;
|
||||
backdrop-filter: blur(10px);
|
||||
-webkit-backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
/* 页面背景 */
|
||||
.page-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(135deg, #f8fafd 0%, #eef2f9 100%);
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
/* 内容区域 */
|
||||
.content {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
padding: 30rpx;
|
||||
}
|
||||
|
||||
/* 用户信息预览 */
|
||||
.user-preview {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
padding: 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 30rpx;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
|
||||
|
||||
.user-avatar {
|
||||
width: 120rpx;
|
||||
height: 120rpx;
|
||||
border-radius: 60rpx;
|
||||
overflow: hidden;
|
||||
margin-right: 24rpx;
|
||||
|
||||
image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 60rpx;
|
||||
}
|
||||
|
||||
.default-avatar {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: linear-gradient(135deg, #4080FF, #5E96FF);
|
||||
color: #fff;
|
||||
font-size: 60rpx;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
|
||||
.user-detail {
|
||||
flex: 1;
|
||||
|
||||
.user-name {
|
||||
font-size: 36rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 8rpx;
|
||||
}
|
||||
|
||||
.user-phone {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
}
|
||||
}
|
||||
|
||||
.arrow-icon {
|
||||
font-size: 44rpx;
|
||||
color: #ccc;
|
||||
}
|
||||
}
|
||||
|
||||
/* 设置项区域 */
|
||||
.setting-section {
|
||||
margin-bottom: 30rpx;
|
||||
|
||||
.section-title {
|
||||
font-size: 30rpx;
|
||||
font-weight: 600;
|
||||
color: #333;
|
||||
margin-bottom: 16rpx;
|
||||
padding-left: 16rpx;
|
||||
}
|
||||
|
||||
.setting-list {
|
||||
background-color: #fff;
|
||||
border-radius: 16rpx;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.setting-item {
|
||||
padding: 28rpx 30rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid #f5f5f5;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.item-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.item-icon {
|
||||
font-size: 44rpx;
|
||||
margin-right: 20rpx;
|
||||
|
||||
&.account-color {
|
||||
color: #4080FF;
|
||||
}
|
||||
|
||||
&.security-color {
|
||||
color: #5AC8FA;
|
||||
}
|
||||
|
||||
&.notice-color {
|
||||
color: #FF9500;
|
||||
}
|
||||
|
||||
&.theme-color {
|
||||
color: #5E6687;
|
||||
}
|
||||
|
||||
&.cache-color {
|
||||
color: #FF3B30;
|
||||
}
|
||||
|
||||
&.privacy-color {
|
||||
color: #34C759;
|
||||
}
|
||||
|
||||
&.agreement-color {
|
||||
color: #9013FE;
|
||||
}
|
||||
|
||||
&.about-color {
|
||||
color: #4080FF;
|
||||
}
|
||||
}
|
||||
|
||||
.item-title {
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
|
||||
.item-right {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.arrow-icon {
|
||||
font-size: 44rpx;
|
||||
color: #ccc;
|
||||
}
|
||||
|
||||
.cache-size,
|
||||
.version-text {
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin-right: 10rpx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 退出登录按钮 */
|
||||
.logout-container {
|
||||
margin-top: 60rpx;
|
||||
padding: 0 20rpx;
|
||||
margin-bottom: 50rpx;
|
||||
|
||||
.logout-btn {
|
||||
background-color: #fff;
|
||||
color: #FF3B30;
|
||||
border: none;
|
||||
height: 96rpx;
|
||||
line-height: 96rpx;
|
||||
font-size: 32rpx;
|
||||
border-radius: 16rpx;
|
||||
font-weight: 500;
|
||||
box-shadow: 0 4rpx 16rpx rgba(0, 0, 0, 0.05);
|
||||
|
||||
&:active {
|
||||
background-color: #f8f8f8;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 弹窗内容样式 */
|
||||
.dialog-content {
|
||||
padding: 30rpx;
|
||||
text-align: center;
|
||||
font-size: 30rpx;
|
||||
color: #333;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
.wd-popup {
|
||||
position: fixed;
|
||||
max-height: 100%;
|
||||
overflow-y: auto;
|
||||
// overflow-y: auto;
|
||||
background: #fff;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,18 +1,19 @@
|
|||
|
||||
.li-mt-25{margin-top:25rpx}
|
||||
|
||||
.li-pt-6{padding-top:6rpx}
|
||||
.li-px-15{padding-left:15rpx;padding-right:15rpx}
|
||||
|
||||
.bg-0070F0{background-color:rgb(0,112,240)}
|
||||
.li-my-10{margin-top:10rpx;margin-bottom:10rpx}
|
||||
.li-p-20{padding:20rpx}
|
||||
.li-px-20{padding-left:20rpx;padding-right:20rpx}
|
||||
.li-py-10{padding-top:10rpx;padding-bottom:10rpx}
|
||||
.li-py-60{padding-top:60rpx;padding-bottom:60rpx}
|
||||
.li-rd-8{border-radius:8rpx}
|
||||
.li-text-dddddd-color{color:rgb(221,221,221)}
|
||||
.li-text-ff9900-color{color:rgb(255,153,0)}
|
||||
|
||||
.li-pt-6{padding-top:6rpx}
|
||||
.li-px-15{padding-left:15rpx;padding-right:15rpx}
|
||||
|
||||
.li-opacity-80{undefined:0.8}
|
||||
.li-pb-40{padding-bottom:40rpx}
|
||||
.li-py-100{padding-top:100rpx;padding-bottom:100rpx}
|
||||
|
|
@ -30,3 +31,11 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ export const request = (endpoint : string, options : RequestOptions = {}) => {
|
|||
if (response.statusCode >= 200 && response.statusCode < 300) {
|
||||
if (response.data.code == 500) {
|
||||
uni.$store.commit("logout")
|
||||
reject(response.data)
|
||||
reject(response.data);
|
||||
return;
|
||||
}
|
||||
resolve(response.data);
|
||||
|
|
|
|||
Loading…
Reference in New Issue