投诉管理 问卷管理页面(home)
This commit is contained in:
parent
832c51d9ec
commit
2c20695f1d
42
pages.json
42
pages.json
|
|
@ -81,7 +81,7 @@
|
||||||
"navigationStyle": "custom",
|
"navigationStyle": "custom",
|
||||||
"navigationBarTitleText": "工单大厅"
|
"navigationBarTitleText": "工单大厅"
|
||||||
}
|
}
|
||||||
},{
|
}, {
|
||||||
"path": "task_hall/detail",
|
"path": "task_hall/detail",
|
||||||
"style": {
|
"style": {
|
||||||
"enablePullDownRefresh": false,
|
"enablePullDownRefresh": false,
|
||||||
|
|
@ -176,12 +176,50 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
}, {
|
||||||
|
"root": "pagesB",
|
||||||
|
"pages": [{
|
||||||
|
"path": "complaint/index",
|
||||||
|
"style": {
|
||||||
|
"enablePullDownRefresh": true,
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "投诉管理"
|
||||||
|
}
|
||||||
|
},{
|
||||||
|
"path": "complaint/detail",
|
||||||
|
"style": {
|
||||||
|
"enablePullDownRefresh": false,
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "投诉管理详情"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "questionnaire/list",
|
||||||
|
"style": {
|
||||||
|
"enablePullDownRefresh": false,
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "问卷列表"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "questionnaire/detail",
|
||||||
|
"style": {
|
||||||
|
"enablePullDownRefresh": false,
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationStyle": "custom",
|
||||||
|
"navigationBarTitleText": "问卷详情"
|
||||||
|
}
|
||||||
|
}]
|
||||||
}],
|
}],
|
||||||
"condition": {
|
"condition": {
|
||||||
"current": 0, // 当前激活的条件,默认为 0
|
"current": 0, // 当前激活的条件,默认为 0
|
||||||
"list": [{
|
"list": [{
|
||||||
"name": "", // 条件名称
|
"name": "", // 条件名称
|
||||||
"path": "pagesA/invite/index", // 要打开的页面路径
|
"path": "pagesB/complaint/index", // 要打开的页面路径
|
||||||
"query": "" // 可选的页面参数
|
"query": "" // 可选的页面参数
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,7 +158,7 @@
|
||||||
{
|
{
|
||||||
image: uni.$globalData?.RESOURCE_URL + 'home/grid/tousu.png',
|
image: uni.$globalData?.RESOURCE_URL + 'home/grid/tousu.png',
|
||||||
title: '投诉管理',
|
title: '投诉管理',
|
||||||
type: ''
|
type: 'complaint'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: uni.$globalData?.RESOURCE_URL + 'home/grid/yaoqing.png',
|
image: uni.$globalData?.RESOURCE_URL + 'home/grid/yaoqing.png',
|
||||||
|
|
@ -168,7 +168,7 @@
|
||||||
{
|
{
|
||||||
image: uni.$globalData?.RESOURCE_URL + 'home/grid/wenjuan.png',
|
image: uni.$globalData?.RESOURCE_URL + 'home/grid/wenjuan.png',
|
||||||
title: '问卷管理',
|
title: '问卷管理',
|
||||||
type: ''
|
type: 'questionnaire'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
image: uni.$globalData?.RESOURCE_URL + 'home/grid/fangyuan.png',
|
image: uni.$globalData?.RESOURCE_URL + 'home/grid/fangyuan.png',
|
||||||
|
|
@ -275,6 +275,18 @@
|
||||||
url: '/pagesA/invite/index'
|
url: '/pagesA/invite/index'
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
case 'complaint':
|
||||||
|
// 投诉管理
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pagesB/complaint/index'
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'questionnaire':
|
||||||
|
// 问卷管理
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pagesB/questionnaire/list'
|
||||||
|
});
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,174 +0,0 @@
|
||||||
<template>
|
|
||||||
<wd-popup v-model="innerVisible" position="bottom" :safe-area-inset-bottom="true" @close="handleClose">
|
|
||||||
<view class="share-popup">
|
|
||||||
<view class="share-header li-flex li-justify-between li-items-center li-px-30 li-py-20">
|
|
||||||
<text class="li-text-32">分享</text>
|
|
||||||
<text class="ri-close-line li-text-48 li-text-#999" @click="handleClose"></text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="share-content li-p-30">
|
|
||||||
<view class="share-methods li-flex li-justify-around">
|
|
||||||
<view class="share-item li-flex li-flex-col li-items-center" @click="handleShare('wechat')">
|
|
||||||
<view class="icon-wrapper li-bg-#07c160 li-mb-15">
|
|
||||||
<text class="ri-wechat-line li-text-white li-text-48"></text>
|
|
||||||
</view>
|
|
||||||
<text class="li-text-26">微信好友</text>
|
|
||||||
</view>
|
|
||||||
<view class="share-item li-flex li-flex-col li-items-center" @click="handleGenerate">
|
|
||||||
<view class="icon-wrapper li-bg-#0070F0 li-mb-15">
|
|
||||||
<text class="ri-image-line li-text-white li-text-48"></text>
|
|
||||||
</view>
|
|
||||||
<text class="li-text-26">生成海报</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 海报预览弹窗 -->
|
|
||||||
<wd-popup v-model="showPoster" position="center" :safe-area-inset-bottom="true">
|
|
||||||
<view class="poster-preview">
|
|
||||||
<canvas canvas-id="posterCanvas" class="poster-canvas"></canvas>
|
|
||||||
<view class="poster-actions li-flex li-justify-around li-mt-30">
|
|
||||||
<wd-button size="small" @click="showPoster = false">取消</wd-button>
|
|
||||||
<wd-button size="small" type="primary" @click="savePoster">保存图片</wd-button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</wd-popup>
|
|
||||||
</wd-popup>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, defineProps, defineEmits, watch } from 'vue'
|
|
||||||
import { useToast } from '@/uni_modules/wot-design-uni'
|
|
||||||
|
|
||||||
const Toast = useToast()
|
|
||||||
const props = defineProps({
|
|
||||||
visible: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const innerVisible = ref(false)
|
|
||||||
|
|
||||||
// 监听props的变化
|
|
||||||
watch(() => props.visible, (val) => {
|
|
||||||
innerVisible.value = val
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits(['update:visible', 'close', 'generate', 'share'])
|
|
||||||
const showPoster = ref(false)
|
|
||||||
|
|
||||||
// 关闭弹窗
|
|
||||||
const handleClose = () => {
|
|
||||||
emit('update:visible', false)
|
|
||||||
emit('close')
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理分享
|
|
||||||
const handleShare = (type) => {
|
|
||||||
emit('share', type)
|
|
||||||
handleClose()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理生成海报
|
|
||||||
const handleGenerate = async () => {
|
|
||||||
showPoster.value = true
|
|
||||||
await generatePoster()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成海报
|
|
||||||
const generatePoster = async () => {
|
|
||||||
try {
|
|
||||||
const ctx = uni.createCanvasContext('posterCanvas')
|
|
||||||
|
|
||||||
// 设置画布大小
|
|
||||||
const canvasWidth = 300
|
|
||||||
const canvasHeight = 450
|
|
||||||
|
|
||||||
// 绘制背景
|
|
||||||
ctx.setFillStyle('#ffffff')
|
|
||||||
ctx.fillRect(0, 0, canvasWidth, canvasHeight)
|
|
||||||
|
|
||||||
// 绘制标题
|
|
||||||
ctx.setFillStyle('#333333')
|
|
||||||
ctx.setFontSize(16)
|
|
||||||
ctx.setTextAlign('center')
|
|
||||||
ctx.fillText('邀请您加入我们的物业管理平台', canvasWidth / 2, 40)
|
|
||||||
|
|
||||||
// 绘制二维码(示例)
|
|
||||||
ctx.setFillStyle('#000000')
|
|
||||||
ctx.fillRect(100, 200, 100, 100)
|
|
||||||
|
|
||||||
// 绘制底部文字
|
|
||||||
ctx.setFillStyle('#666666')
|
|
||||||
ctx.setFontSize(14)
|
|
||||||
ctx.fillText('扫码加入', canvasWidth / 2, 350)
|
|
||||||
|
|
||||||
// 执行绘制
|
|
||||||
ctx.draw()
|
|
||||||
} catch (error) {
|
|
||||||
Toast.error('生成海报失败')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 保存海报
|
|
||||||
const savePoster = () => {
|
|
||||||
uni.canvasToTempFilePath({
|
|
||||||
canvasId: 'posterCanvas',
|
|
||||||
success: (res) => {
|
|
||||||
uni.saveImageToPhotosAlbum({
|
|
||||||
filePath: res.tempFilePath,
|
|
||||||
success: () => {
|
|
||||||
Toast.success('保存成功')
|
|
||||||
showPoster.value = false
|
|
||||||
handleClose()
|
|
||||||
},
|
|
||||||
fail: () => {
|
|
||||||
Toast.error('保存失败')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
fail: () => {
|
|
||||||
Toast.error('生成图片失败')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
.share-popup {
|
|
||||||
.share-header {
|
|
||||||
border-bottom: 2rpx solid rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.share-methods {
|
|
||||||
.share-item {
|
|
||||||
.icon-wrapper {
|
|
||||||
width: 100rpx;
|
|
||||||
height: 100rpx;
|
|
||||||
border-radius: 50%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.poster-preview {
|
|
||||||
background: #fff;
|
|
||||||
padding: 30rpx;
|
|
||||||
border-radius: 20rpx;
|
|
||||||
|
|
||||||
.poster-canvas {
|
|
||||||
width: 600rpx;
|
|
||||||
height: 900rpx;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.poster-actions {
|
|
||||||
padding: 0 40rpx;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -27,16 +27,17 @@
|
||||||
<view class="card-content li-mt-30">
|
<view class="card-content li-mt-30">
|
||||||
<!-- 主要返佣说明 -->
|
<!-- 主要返佣说明 -->
|
||||||
<view
|
<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">
|
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">
|
<view class="li-flex li-items-center li-mb-20">
|
||||||
<text class="ri-shopping-bag-3-line li-text-48 li-text-white"></text>
|
<text class="ri-shopping-bag-3-line li-text-48 li-text-#0a4696"></text>
|
||||||
<text class="li-text-34 li-text-white li-ml-15">业主消费返佣</text>
|
<text class="li-text-34 li-text-#0a4696 li-ml-15 li-font-medium">业主消费返佣</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="li-flex li-items-baseline li-mb-15">
|
<view class="li-flex li-items-baseline li-mb-15">
|
||||||
<text class="li-text-70 li-text-white li-font-bold">5</text>
|
<text class="li-text-70 li-text-#0a4696 li-font-bold">5</text>
|
||||||
<text class="li-text-34 li-text-white li-ml-10">%</text>
|
<text class="li-text-34 li-text-#0a4696 li-ml-10">%</text>
|
||||||
</view>
|
</view>
|
||||||
<text class="li-text-26 li-text-white li-opacity-80">邀请的业主每笔消费,您都可获得返佣</text>
|
<text class="li-text-26 li-text-#0a4696 li-opacity-100">邀请的业主每笔消费,您都可获得返佣</text>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 收益说明 -->
|
<!-- 收益说明 -->
|
||||||
|
|
@ -71,7 +72,7 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="invite-button li-mt-40">
|
<view class="invite-button li-mt-40">
|
||||||
<wd-button type="primary" block custom-class="share-btn" @click="showSharePopup">
|
<wd-button type="primary" block custom-class="share-btn">
|
||||||
<text class="ri-share-forward-line li-mr-10"></text>立即邀请
|
<text class="ri-share-forward-line li-mr-10"></text>立即邀请
|
||||||
</wd-button>
|
</wd-button>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -117,15 +118,12 @@
|
||||||
</scroll-view>
|
</scroll-view>
|
||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 分享组件 -->
|
|
||||||
<share-popup ref="sharePopupRef" :visible.sync="showShare" @update:visible="showShare = $event"
|
|
||||||
@close="showShare = false" @generate="generatePoster" @share="handleShare" />
|
|
||||||
|
|
||||||
<!-- 规则弹窗 -->
|
<!-- 规则弹窗 -->
|
||||||
<wd-popup v-model="showRulePopup" position="center" @close="showRulePopup = false">
|
<wd-popup v-model="showRulePopup" position="center" @close="showRulePopup = false">
|
||||||
<view class="rules-popup li-bg-white ">
|
<view class="rules-popup li-bg-white ">
|
||||||
<view class="rules-header li-py-20 li-px-30 li-flex li-justify-between li-items-center li-border-b">
|
<view class="rules-header li-py-20 li-px-30 li-flex li-justify-between li-items-center li-border-b">
|
||||||
<text class="li-text-34 li-font-medium">活动规则</text>
|
<text class="li-text-34 li-font-medium">邀请规则</text>
|
||||||
<text class="ri-close-line li-text-44 li-text-#999" @click="showRulePopup = false"></text>
|
<text class="ri-close-line li-text-44 li-text-#999" @click="showRulePopup = false"></text>
|
||||||
</view>
|
</view>
|
||||||
<view class="rules-content li-p-30">
|
<view class="rules-content li-p-30">
|
||||||
|
|
@ -157,53 +155,27 @@
|
||||||
useToast
|
useToast
|
||||||
} from '@/uni_modules/wot-design-uni'
|
} from '@/uni_modules/wot-design-uni'
|
||||||
import { onLoad } from '@dcloudio/uni-app'
|
import { onLoad } from '@dcloudio/uni-app'
|
||||||
import SharePopup from './components/SharePopup.vue'
|
|
||||||
import { useNavigation } from '@/hooks/useNavigation'
|
import { useNavigation } from '@/hooks/useNavigation'
|
||||||
|
declare const uni : Uni
|
||||||
|
|
||||||
const {
|
const {
|
||||||
hasMultiplePages, // 是否有多个页面在路由栈中
|
hasMultiplePages, // 是否有多个页面在路由栈中
|
||||||
isTabBarPage, // 当前页面是否为 tabBar 页面
|
isTabBarPage, // 当前页面是否为 tabBar 页面
|
||||||
checkRouteStack // 检查当前路由栈状态的方法
|
checkRouteStack // 检查当前路由栈状态的方法
|
||||||
} = useNavigation()
|
} = useNavigation()
|
||||||
const Toast = useToast()
|
const Toast = useToast()
|
||||||
const sharePopupRef = ref(null)
|
|
||||||
const showShare = ref(false)
|
|
||||||
const loading = ref(false)
|
const loading = ref(false)
|
||||||
const hasMore = ref(true)
|
const hasMore = ref(true)
|
||||||
const page = ref(1)
|
const page = ref(1)
|
||||||
const inviteList = ref([])
|
const inviteList = ref([])
|
||||||
const showRulePopup = ref(false)
|
const showRulePopup = ref(false)
|
||||||
|
|
||||||
|
const card_back = uni.$globalData?.RESOURCE_URL + 'invite/card-back.png'
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
checkRouteStack()
|
checkRouteStack()
|
||||||
})
|
})
|
||||||
|
|
||||||
// 显示分享弹窗
|
|
||||||
const showSharePopup = () => {
|
|
||||||
showShare.value = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成海报
|
|
||||||
const generatePoster = () => {
|
|
||||||
// 调用分享组件的生成海报方法
|
|
||||||
sharePopupRef.value?.generatePoster()
|
|
||||||
}
|
|
||||||
|
|
||||||
// 处理分享
|
|
||||||
const handleShare = (type) => {
|
|
||||||
if (type === 'wechat') {
|
|
||||||
// #ifdef APP-PLUS
|
|
||||||
plus.share.sendWithSystem({
|
|
||||||
type: 'text',
|
|
||||||
content: '邀请链接',
|
|
||||||
href: 'https://example.com/invite'
|
|
||||||
})
|
|
||||||
// #endif
|
|
||||||
|
|
||||||
// #ifdef MP-WEIXIN
|
|
||||||
// 小程序分享通过 onShareAppMessage 处理
|
|
||||||
// #endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载邀请记录
|
// 加载邀请记录
|
||||||
const loadInviteRecords = async () => {
|
const loadInviteRecords = async () => {
|
||||||
|
|
@ -259,19 +231,7 @@
|
||||||
showRulePopup.value = true
|
showRulePopup.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
// 微信小程序分享配置
|
|
||||||
const onShareAppMessage = () => {
|
|
||||||
return {
|
|
||||||
title: '邀请您加入我们的物业管理平台',
|
|
||||||
path: '/pagesA/invite/index',
|
|
||||||
imageUrl: '分享图片地址'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分享定义到组件实例上
|
|
||||||
defineExpose({
|
|
||||||
onShareAppMessage
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
@ -299,26 +259,22 @@
|
||||||
.invite-card {
|
.invite-card {
|
||||||
.card-content {
|
.card-content {
|
||||||
.commission-card {
|
.commission-card {
|
||||||
background: linear-gradient(135deg, #4481EB 0%, #0070F0 100%);
|
|
||||||
border-radius: 20rpx;
|
border-radius: 20rpx;
|
||||||
padding: 30rpx;
|
padding: 30rpx;
|
||||||
margin-bottom: 30rpx;
|
margin-bottom: 30rpx;
|
||||||
|
|
||||||
.ri-shopping-bag-3-line {
|
.ri-shopping-bag-3-line {
|
||||||
font-size: 48rpx;
|
font-size: 48rpx;
|
||||||
color: #fff;
|
|
||||||
margin-right: 15rpx;
|
margin-right: 15rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
.li-text-34 {
|
.li-text-34 {
|
||||||
font-size: 34rpx;
|
font-size: 34rpx;
|
||||||
color: #fff;
|
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.li-text-26 {
|
.li-text-26 {
|
||||||
font-size: 26rpx;
|
font-size: 26rpx;
|
||||||
color: #fff;
|
|
||||||
opacity: 0.8;
|
opacity: 0.8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,577 @@
|
||||||
|
<template>
|
||||||
|
<view class="complaint-detail-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">投诉详情</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</wd-navbar>
|
||||||
|
<!-- 导航栏背景 -->
|
||||||
|
<view class="nav-bg-layer"></view>
|
||||||
|
|
||||||
|
<!-- 主要内容区域 -->
|
||||||
|
<view class="li-w-92% li-mx-auto li-mt-30 li-pb-30">
|
||||||
|
<!-- 基本信息卡片 -->
|
||||||
|
<view class="detail-card li-bg-white li-rd-20 li-p-30 li-mb-20 li-shadow-sm">
|
||||||
|
<view class="li-flex li-items-center li-justify-between li-pb-15 li-bottom-border2">
|
||||||
|
<view class="li-flex li-items-center">
|
||||||
|
<text class="ri-error-warning-line li-text-34 li-mr-10 li-text-#999999"></text>
|
||||||
|
<text class="li-text-30">{{complaintDetail.complaint_no}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="status-badge" :style="{
|
||||||
|
backgroundColor: getStatusBgColor(complaintDetail.status),
|
||||||
|
color: getStatusColor(complaintDetail.status)
|
||||||
|
}">
|
||||||
|
{{getStatusText(complaintDetail.status)}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-mt-25">
|
||||||
|
<!-- 投诉内容 -->
|
||||||
|
<view class="li-flex li-items-start li-mb-20">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">投诉内容</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#333 li-flex-1">{{complaintDetail.content}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 投诉类型标签 -->
|
||||||
|
<view class="li-flex li-items-center li-flex-wrap li-mt-10 li-mb-20"
|
||||||
|
v-if="complaintDetail.tags && complaintDetail.tags.length">
|
||||||
|
<wd-tag v-for="(tag, idx) in complaintDetail.tags" :key="idx" color="#0083ff" bg-color="#d0e8ff"
|
||||||
|
custom-class="li-mr-10 li-mb-10">
|
||||||
|
{{tag}}
|
||||||
|
</wd-tag>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 投诉图片 -->
|
||||||
|
<view class="li-flex li-flex-wrap li-mt-15 li-mb-20"
|
||||||
|
v-if="complaintDetail.images && complaintDetail.images.length">
|
||||||
|
<image v-for="(img, imgIdx) in complaintDetail.images" :key="imgIdx" :src="img"
|
||||||
|
mode="aspectFill" class="detail-image li-mr-10 li-mb-10"
|
||||||
|
@click="previewImage(complaintDetail.images, imgIdx)">
|
||||||
|
</image>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 投诉详情信息 -->
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">投诉人</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#333">{{complaintDetail.user_name}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">联系电话</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#333">{{complaintDetail.user_mobile}}</text>
|
||||||
|
<text class="ri-phone-line li-text-28 li-text-#0070F0 li-ml-20"
|
||||||
|
@click="callPhone(complaintDetail.user_mobile)"></text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">所在小区</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#333">{{complaintDetail.village_name}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">具体位置</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#333">{{complaintDetail.location || '未提供'}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">提交时间</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#999">{{complaintDetail.create_time}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-flex li-items-center li-mb-15" v-if="complaintDetail.process_time">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">处理时间</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#999">{{complaintDetail.process_time}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 处理记录 -->
|
||||||
|
<view class="detail-card li-bg-white li-rd-20 li-p-30 li-mb-20 li-shadow-sm"
|
||||||
|
v-if="processRecords.length > 0">
|
||||||
|
<view class="li-flex li-items-center li-pb-15 li-bottom-border2">
|
||||||
|
<text class="ri-history-line li-text-32 li-text-#0070F0 li-mr-10"></text>
|
||||||
|
<text class="li-text-32 li-font-bold">处理记录</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="process-timeline li-mt-20">
|
||||||
|
<view v-for="(record, index) in processRecords" :key="index" class="timeline-item">
|
||||||
|
<view class="timeline-dot" :class="{'active': index === 0}"></view>
|
||||||
|
<view class="timeline-content">
|
||||||
|
<view class="li-flex li-items-center li-justify-between">
|
||||||
|
<text class="li-text-30">{{record.action}}</text>
|
||||||
|
<text class="li-text-24 li-text-#999">{{record.time}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="li-text-28 li-text-#666 li-mt-10">{{record.remark}}</view>
|
||||||
|
<view class="li-text-26 li-text-#999 li-mt-5">处理人: {{record.operator}}</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 操作按钮区域 -->
|
||||||
|
<view v-if="complaintDetail.status !== 2 && complaintDetail.status !== 3">
|
||||||
|
<view class="action-buttons li-flex li-justify-between li-mt-30 li-px-30">
|
||||||
|
<wd-button type="info" plain custom-class="action-btn" v-if="complaintDetail.status === 0"
|
||||||
|
@click="handleProcess">开始处理</wd-button>
|
||||||
|
<wd-button type="primary" custom-class="action-btn" v-if="complaintDetail.status === 1"
|
||||||
|
@click="handleComplete">处理完成</wd-button>
|
||||||
|
<wd-button type="danger" plain custom-class="action-btn" @click="handleClose">关闭投诉</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部固定操作区 -->
|
||||||
|
<view class="fixed-bottom" v-if="complaintDetail.status === 1">
|
||||||
|
<wd-button type="primary" block @click="showAddRecord = true">添加处理记录</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 处理记录弹窗 -->
|
||||||
|
<wd-popup v-model="showAddRecord" position="bottom" closable :safe-area-inset-bottom="true">
|
||||||
|
<view class="add-record-popup li-p-30">
|
||||||
|
<view class="li-text-32 li-font-bold li-mb-20">添加处理记录</view>
|
||||||
|
|
||||||
|
<view class="li-mt-20 li-mb-30">
|
||||||
|
<view class="li-text-28 li-mb-10">处理备注</view>
|
||||||
|
<wd-textarea v-model="recordForm.remark" placeholder="请输入处理信息" autosize show-word-limit
|
||||||
|
max-length="200"></wd-textarea>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-mt-20 li-mb-30">
|
||||||
|
<view class="li-text-28 li-mb-10">上传图片凭证</view>
|
||||||
|
<wd-upload v-model="recordForm.images" max-size="10485760" multiple :limit="4"
|
||||||
|
:before-preview="beforePreview"></wd-upload>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<wd-button type="primary" block :loading="submitting" @click="submitRecord">提交记录</wd-button>
|
||||||
|
</view>
|
||||||
|
</wd-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, computed, onMounted } from 'vue';
|
||||||
|
import { onLoad } from '@dcloudio/uni-app';
|
||||||
|
import { useToast } from '@/uni_modules/wot-design-uni';
|
||||||
|
import { useNavigation } from '@/hooks/useNavigation';
|
||||||
|
|
||||||
|
|
||||||
|
// 使用导航composable
|
||||||
|
const {
|
||||||
|
hasMultiplePages,
|
||||||
|
isTabBarPage,
|
||||||
|
checkRouteStack
|
||||||
|
} = useNavigation();
|
||||||
|
|
||||||
|
const Toast = useToast();
|
||||||
|
|
||||||
|
// 页面状态
|
||||||
|
const loading = ref(false);
|
||||||
|
const submitting = ref(false);
|
||||||
|
const showAddRecord = ref(false);
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const recordForm = reactive({
|
||||||
|
remark: '',
|
||||||
|
images: []
|
||||||
|
});
|
||||||
|
|
||||||
|
// 根据查询参数获取投诉ID
|
||||||
|
const complaintId = ref(null);
|
||||||
|
onLoad((option) => {
|
||||||
|
complaintId.value = option.id;
|
||||||
|
loadComplaintDetail();
|
||||||
|
checkRouteStack();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 模拟数据 - 投诉详情
|
||||||
|
const complaintDetail = ref({
|
||||||
|
complaint_id: 1,
|
||||||
|
complaint_no: 'TS20240607001',
|
||||||
|
content: '楼道灯已经坏了三天,晚上上下楼很不方便,希望物业尽快解决!由于光线问题,我家小孩差点摔倒,这是安全隐患,希望物业能够尽快修复。',
|
||||||
|
village_name: '阳光花园小区',
|
||||||
|
location: 'A栋3单元楼道',
|
||||||
|
user_name: '张三',
|
||||||
|
user_mobile: '13800138000',
|
||||||
|
create_time: '2024-06-07 10:23',
|
||||||
|
process_time: '2024-06-07 14:35',
|
||||||
|
status: 1,
|
||||||
|
urgency: 2,
|
||||||
|
tags: ['公共设施', '照明', '安全隐患'],
|
||||||
|
images: [
|
||||||
|
'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||||
|
'https://img.yzcdn.cn/vant/tree.jpeg'
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
// 模拟数据 - 处理记录
|
||||||
|
const processRecords = ref([
|
||||||
|
{
|
||||||
|
record_id: 1,
|
||||||
|
action: '开始处理',
|
||||||
|
remark: '已联系维修人员前往现场查看情况',
|
||||||
|
operator: '李维修',
|
||||||
|
time: '2024-06-07 14:35'
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 状态颜色配置
|
||||||
|
const getStatusColor = (status) => {
|
||||||
|
const colorMap = {
|
||||||
|
0: '#ff9d00', // 待处理
|
||||||
|
1: '#37A5FF', // 处理中
|
||||||
|
2: '#00b42a', // 已处理
|
||||||
|
3: '#999999' // 已关闭
|
||||||
|
};
|
||||||
|
return colorMap[status] || '#666666';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态背景色配置
|
||||||
|
const getStatusBgColor = (status) => {
|
||||||
|
const bgColorMap = {
|
||||||
|
0: '#fff6e9', // 待处理
|
||||||
|
1: '#e8f4ff', // 处理中
|
||||||
|
2: '#e8ffea', // 已处理
|
||||||
|
3: '#f5f5f5' // 已关闭
|
||||||
|
};
|
||||||
|
return bgColorMap[status] || '#f5f5f5';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态文字配置
|
||||||
|
const getStatusText = (status) => {
|
||||||
|
const textMap = {
|
||||||
|
0: '待处理',
|
||||||
|
1: '处理中',
|
||||||
|
2: '已处理',
|
||||||
|
3: '已关闭'
|
||||||
|
};
|
||||||
|
return textMap[status] || '未知状态';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载投诉详情
|
||||||
|
const loadComplaintDetail = async () => {
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
// 实际项目中这里应该调用API获取数据
|
||||||
|
// await getComplaintDetail(complaintId.value)
|
||||||
|
|
||||||
|
// 模拟加载延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 800));
|
||||||
|
loading.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载投诉详情失败', error);
|
||||||
|
Toast.fail('加载失败,请重试');
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 返回上一页
|
||||||
|
const goBack = () => {
|
||||||
|
uni.navigateBack();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 拨打电话
|
||||||
|
const callPhone = (phone) => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: phone,
|
||||||
|
success: () => {
|
||||||
|
console.log('拨打电话成功');
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.log('拨打电话失败', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 图片预览
|
||||||
|
const previewImage = (images, current) => {
|
||||||
|
uni.previewImage({
|
||||||
|
urls: images,
|
||||||
|
current: images[current]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理操作
|
||||||
|
const handleProcess = async () => {
|
||||||
|
try {
|
||||||
|
Toast.loading('处理中...');
|
||||||
|
// 实际项目中这里应该调用API
|
||||||
|
// await startProcess(complaintId.value)
|
||||||
|
|
||||||
|
// 模拟操作延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 800));
|
||||||
|
|
||||||
|
// 更新状态
|
||||||
|
complaintDetail.value.status = 1;
|
||||||
|
complaintDetail.value.process_time = new Date().toLocaleString();
|
||||||
|
|
||||||
|
// 添加处理记录
|
||||||
|
processRecords.value.unshift({
|
||||||
|
record_id: new Date().getTime(),
|
||||||
|
action: '开始处理',
|
||||||
|
remark: '物业已接单,开始处理',
|
||||||
|
operator: '当前操作员',
|
||||||
|
time: '2025-06-23'
|
||||||
|
});
|
||||||
|
|
||||||
|
Toast.success('已开始处理');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('操作失败', error);
|
||||||
|
Toast.fail('操作失败,请重试');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 完成处理
|
||||||
|
const handleComplete = async () => {
|
||||||
|
try {
|
||||||
|
Toast.loading('处理中...');
|
||||||
|
// 实际项目中这里应该调用API
|
||||||
|
// await completeProcess(complaintId.value)
|
||||||
|
|
||||||
|
// 模拟操作延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 800));
|
||||||
|
|
||||||
|
// 更新状态
|
||||||
|
complaintDetail.value.status = 2;
|
||||||
|
|
||||||
|
// 添加处理记录
|
||||||
|
processRecords.value.unshift({
|
||||||
|
record_id: new Date().getTime(),
|
||||||
|
action: '处理完成',
|
||||||
|
remark: '问题已解决,楼道灯已修复',
|
||||||
|
operator: '当前操作员',
|
||||||
|
time: '2025-06-23'
|
||||||
|
});
|
||||||
|
|
||||||
|
Toast.success('处理完成');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('操作失败', error);
|
||||||
|
Toast.fail('操作失败,请重试');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 关闭投诉
|
||||||
|
const handleClose = async () => {
|
||||||
|
try {
|
||||||
|
Toast.loading('处理中...');
|
||||||
|
// 实际项目中这里应该调用API
|
||||||
|
// await closeComplaint(complaintId.value)
|
||||||
|
|
||||||
|
// 模拟操作延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 800));
|
||||||
|
|
||||||
|
// 更新状态
|
||||||
|
complaintDetail.value.status = 3;
|
||||||
|
|
||||||
|
// 添加处理记录
|
||||||
|
processRecords.value.unshift({
|
||||||
|
record_id: new Date().getTime(),
|
||||||
|
action: '关闭投诉',
|
||||||
|
remark: '已与业主沟通,投诉已关闭',
|
||||||
|
operator: '当前操作员',
|
||||||
|
time: '2025-06-23'
|
||||||
|
});
|
||||||
|
|
||||||
|
Toast.success('投诉已关闭');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('操作失败', error);
|
||||||
|
Toast.fail('操作失败,请重试');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 预览文件
|
||||||
|
const beforePreview = (file) => {
|
||||||
|
console.log('预览文件', file);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
const toPages = (item) => {
|
||||||
|
switch (item.type) {
|
||||||
|
case 'nav':
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'home':
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/index/index'
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 提交处理记录
|
||||||
|
const submitRecord = async () => {
|
||||||
|
if (!recordForm.remark.trim()) {
|
||||||
|
return Toast.fail('请输入处理备注');
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
submitting.value = true;
|
||||||
|
|
||||||
|
// 实际项目中这里应该调用API
|
||||||
|
// await addProcessRecord({
|
||||||
|
// complaint_id: complaintId.value,
|
||||||
|
// remark: recordForm.remark,
|
||||||
|
// images: recordForm.images.map(img => img.url)
|
||||||
|
// })
|
||||||
|
|
||||||
|
// 模拟提交延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
|
||||||
|
// 添加处理记录
|
||||||
|
processRecords.value.unshift({
|
||||||
|
record_id: new Date().getTime(),
|
||||||
|
action: '处理进展',
|
||||||
|
remark: recordForm.remark,
|
||||||
|
operator: '当前操作员',
|
||||||
|
time: '2025-06-23'
|
||||||
|
});
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
recordForm.remark = '';
|
||||||
|
recordForm.images = [];
|
||||||
|
|
||||||
|
// 关闭弹窗
|
||||||
|
showAddRecord.value = false;
|
||||||
|
|
||||||
|
Toast.success('记录已添加');
|
||||||
|
submitting.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('提交记录失败', error);
|
||||||
|
Toast.fail('提交失败,请重试');
|
||||||
|
submitting.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #F7F8FA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.complaint-detail-page {
|
||||||
|
min-height: 100vh;
|
||||||
|
|
||||||
|
|
||||||
|
/* 有底部固定按钮时的底部间距 */
|
||||||
|
padding-bottom: 140rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-card {
|
||||||
|
.status-badge {
|
||||||
|
padding: 4rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.li-bottom-border2 {
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.detail-image {
|
||||||
|
width: 180rpx;
|
||||||
|
height: 180rpx;
|
||||||
|
border-radius: 8rpx;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 处理记录时间线 */
|
||||||
|
.process-timeline {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: '';
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 10rpx;
|
||||||
|
width: 2rpx;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-item {
|
||||||
|
position: relative;
|
||||||
|
padding-left: 40rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-dot {
|
||||||
|
position: absolute;
|
||||||
|
left: 0;
|
||||||
|
top: 15rpx;
|
||||||
|
width: 20rpx;
|
||||||
|
height: 20rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e0e0e0;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background-color: #0070F0;
|
||||||
|
box-shadow: 0 0 0 4rpx rgba(0, 112, 240, 0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.timeline-content {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
border-radius: 12rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 底部固定区域 */
|
||||||
|
.fixed-bottom {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
background-color: #fff;
|
||||||
|
padding: 20rpx 30rpx;
|
||||||
|
box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.05);
|
||||||
|
/* #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 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
width: 290rpx !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* 弹窗样式 */
|
||||||
|
.add-record-popup {
|
||||||
|
max-height: 80vh;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,451 @@
|
||||||
|
<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">投诉管理</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</wd-navbar>
|
||||||
|
<!-- 导航栏背景 -->
|
||||||
|
<view class="nav-bg-layer"></view>
|
||||||
|
|
||||||
|
<!-- 搜索栏 -->
|
||||||
|
<view class="li-w-90% li-mx-auto li-mt-30">
|
||||||
|
<wd-search placeholderStyle="color:#d9d9d9" v-model="searchText" placeholder="搜索投诉内容/编号" hide-cancel
|
||||||
|
placeholder-left @search="handleSearch"></wd-search>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 状态筛选 -->
|
||||||
|
<view class="li-flex li-items-center li-mx-auto li-w-96% li-mt-20 li-pl-30">
|
||||||
|
<text v-for="(item, index) in statusList" :key="index"
|
||||||
|
:class="activeStatus === item.value ? 'status-tag active' : 'status-tag'"
|
||||||
|
@click="handleStatusChange(item.value)">
|
||||||
|
{{item.label}}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 投诉列表 -->
|
||||||
|
<view class="li-w-92% li-mx-auto li-mt-30 li-pb-30">
|
||||||
|
<view v-if="complaintList.length > 0">
|
||||||
|
<view v-for="(item, index) in complaintList" :key="index" @click="toPages({type:'detail', value:item})"
|
||||||
|
class="complaint-card li-bg-white li-rd-20 li-px-30 li-py-25 li-mb-20 li-shadow-sm">
|
||||||
|
<!-- 投诉头部 -->
|
||||||
|
<view
|
||||||
|
class="complaint-header li-flex li-items-center li-justify-between li-pb-15 li-bottom-border2">
|
||||||
|
<view class="li-flex li-items-center">
|
||||||
|
<text class="ri-error-warning-line li-text-34 li-mr-10 li-text-#999999"></text>
|
||||||
|
<text class="li-text-30">{{item.complaint_no}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="status-badge" :style="{
|
||||||
|
backgroundColor: getStatusBgColor(item.status),
|
||||||
|
color: getStatusColor(item.status)
|
||||||
|
}">
|
||||||
|
{{getStatusText(item.status)}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 投诉内容 -->
|
||||||
|
<view class="complaint-content li-mt-20">
|
||||||
|
<view class="li-flex li-items-start li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">投诉内容</text>
|
||||||
|
<text
|
||||||
|
class="content-text li-text-28 li-text-#333 li-flex-1 li-line-clamp-2">{{item.content}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">小区信息</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#333">{{item.village_name}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">投诉人</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#333">{{item.user_name}}</text>
|
||||||
|
<text class="ri-phone-line li-text-28 li-text-#0070F0 li-ml-20"
|
||||||
|
@click.stop="callPhone(item.user_mobile)"></text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-flex li-items-center">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">提交时间</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#999">{{item.create_time}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 标签 -->
|
||||||
|
<view class="li-flex li-items-center li-flex-wrap li-mt-15"
|
||||||
|
v-if="item.tags && item.tags.length">
|
||||||
|
<wd-tag v-for="(tag, idx) in item.tags" :key="idx" color="#0083ff" bg-color="#d0e8ff"
|
||||||
|
custom-class="li-mr-10 li-mb-10">
|
||||||
|
{{tag}}
|
||||||
|
</wd-tag>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 附件图片预览 -->
|
||||||
|
<view class="li-flex li-mt-15" v-if="item.images && item.images.length">
|
||||||
|
<image v-for="(img, imgIdx) in item.images.slice(0, 3)" :key="imgIdx" :src="img"
|
||||||
|
mode="aspectFill" class="preview-image li-mr-10"
|
||||||
|
@click.stop="previewImage(item.images, imgIdx)">
|
||||||
|
</image>
|
||||||
|
<text v-if="item.images.length > 3" class="more-image-text li-text-28 li-text-#0070F0">
|
||||||
|
+{{item.images.length - 3}}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 空状态 -->
|
||||||
|
<view v-else class="li-mt-100">
|
||||||
|
<wd-status-tip image="search" tip="暂无投诉记录" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 加载状态 -->
|
||||||
|
<view v-if="loading" class="li-flex-center li-mt-30">
|
||||||
|
<wd-loading color="#0070F0" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部提示 -->
|
||||||
|
<view v-if="!loading && finished && complaintList.length > 0"
|
||||||
|
class="li-text-center li-text-26 li-text-#999 li-py-20">
|
||||||
|
-- 没有更多数据了 --
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, onMounted } from 'vue';
|
||||||
|
import { onLoad, onPullDownRefresh, onReachBottom } 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 searchText = ref('');
|
||||||
|
const activeStatus = ref('ALL');
|
||||||
|
const loading = ref(false);
|
||||||
|
const finished = ref(false);
|
||||||
|
const page = ref(1);
|
||||||
|
const pageSize = ref(10);
|
||||||
|
|
||||||
|
// 状态筛选选项
|
||||||
|
const statusList = ref([
|
||||||
|
{ label: '全部', value: 'ALL' },
|
||||||
|
{ label: '待处理', value: 0 },
|
||||||
|
{ label: '处理中', value: 1 },
|
||||||
|
{ label: '已处理', value: 2 },
|
||||||
|
{ label: '已关闭', value: 3 }
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 模拟数据 - 实际项目中应该是通过API获取
|
||||||
|
const complaintList = ref([
|
||||||
|
{
|
||||||
|
complaint_id: 1,
|
||||||
|
complaint_no: 'TS20240607001',
|
||||||
|
content: '楼道灯已经坏了三天,晚上上下楼很不方便,希望物业尽快解决!',
|
||||||
|
village_name: '阳光花园小区',
|
||||||
|
user_name: '张三',
|
||||||
|
user_mobile: '13800138000',
|
||||||
|
create_time: '2024-06-07 10:23',
|
||||||
|
status: 0,
|
||||||
|
urgency: 2,
|
||||||
|
tags: ['公共设施', '照明'],
|
||||||
|
images: [
|
||||||
|
'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||||
|
'https://img.yzcdn.cn/vant/tree.jpeg'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
complaint_id: 2,
|
||||||
|
complaint_no: 'TS20240606001',
|
||||||
|
content: '小区北门停车场有人乱停车,导致通道被堵,请物业及时处理。',
|
||||||
|
village_name: '阳光花园小区',
|
||||||
|
user_name: '李四',
|
||||||
|
user_mobile: '13900139000',
|
||||||
|
create_time: '2024-06-06 16:45',
|
||||||
|
status: 1,
|
||||||
|
urgency: 1,
|
||||||
|
tags: ['停车管理', '安全隐患'],
|
||||||
|
images: [
|
||||||
|
'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||||
|
'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||||
|
'https://img.yzcdn.cn/vant/cat.jpeg',
|
||||||
|
'https://img.yzcdn.cn/vant/tree.jpeg'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
complaint_id: 3,
|
||||||
|
complaint_no: 'TS20240605001',
|
||||||
|
content: '小区垃圾分类做得不到位,希望加强宣传和管理。',
|
||||||
|
village_name: '阳光花园小区',
|
||||||
|
user_name: '王五',
|
||||||
|
user_mobile: '13700137000',
|
||||||
|
create_time: '2024-06-05 09:12',
|
||||||
|
status: 2,
|
||||||
|
urgency: 1,
|
||||||
|
tags: ['环境卫生', '垃圾分类'],
|
||||||
|
images: []
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 状态颜色配置
|
||||||
|
const getStatusColor = (status) => {
|
||||||
|
const colorMap = {
|
||||||
|
0: '#ff9d00', // 待处理
|
||||||
|
1: '#37A5FF', // 处理中
|
||||||
|
2: '#00b42a', // 已处理
|
||||||
|
3: '#999999' // 已关闭
|
||||||
|
};
|
||||||
|
return colorMap[status] || '#666666';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态背景色配置
|
||||||
|
const getStatusBgColor = (status) => {
|
||||||
|
const bgColorMap = {
|
||||||
|
0: '#fff6e9', // 待处理
|
||||||
|
1: '#e8f4ff', // 处理中
|
||||||
|
2: '#e8ffea', // 已处理
|
||||||
|
3: '#f5f5f5' // 已关闭
|
||||||
|
};
|
||||||
|
return bgColorMap[status] || '#f5f5f5';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态文字配置
|
||||||
|
const getStatusText = (status) => {
|
||||||
|
const textMap = {
|
||||||
|
0: '待处理',
|
||||||
|
1: '处理中',
|
||||||
|
2: '已处理',
|
||||||
|
3: '已关闭'
|
||||||
|
};
|
||||||
|
return textMap[status] || '未知状态';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理状态切换
|
||||||
|
const handleStatusChange = (status) => {
|
||||||
|
activeStatus.value = status;
|
||||||
|
resetList();
|
||||||
|
loadComplaintList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 搜索处理
|
||||||
|
const handleSearch = () => {
|
||||||
|
resetList();
|
||||||
|
loadComplaintList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置列表
|
||||||
|
const resetList = () => {
|
||||||
|
page.value = 1;
|
||||||
|
finished.value = false;
|
||||||
|
complaintList.value = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载投诉列表数据
|
||||||
|
const loadComplaintList = async () => {
|
||||||
|
if (loading.value || finished.value) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
|
||||||
|
// 这里应该调用实际的API接口获取数据
|
||||||
|
// const params = {
|
||||||
|
// page: page.value,
|
||||||
|
// page_size: pageSize.value,
|
||||||
|
// keyword: searchText.value,
|
||||||
|
// status: activeStatus.value !== 'ALL' ? activeStatus.value : ''
|
||||||
|
// };
|
||||||
|
// const res = await getComplaintList(params);
|
||||||
|
|
||||||
|
// 模拟加载延迟
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
|
||||||
|
// 模拟数据加载完成的情况
|
||||||
|
if (page.value > 1) {
|
||||||
|
finished.value = true;
|
||||||
|
} else {
|
||||||
|
page.value++;
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载投诉列表失败', error);
|
||||||
|
Toast.fail('加载失败,请重试');
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
const toPages = (item) => {
|
||||||
|
switch (item.type) {
|
||||||
|
case 'nav':
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'home':
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/index/index'
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'detail':
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pagesB/complaint/detail?id=${item.value.complaint_id}`
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 拨打电话
|
||||||
|
const callPhone = (phone) => {
|
||||||
|
uni.makePhoneCall({
|
||||||
|
phoneNumber: phone,
|
||||||
|
success: () => {
|
||||||
|
console.log('拨打电话成功');
|
||||||
|
},
|
||||||
|
fail: (err) => {
|
||||||
|
console.log('拨打电话失败', err);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 预览图片
|
||||||
|
const previewImage = (images, current) => {
|
||||||
|
uni.previewImage({
|
||||||
|
urls: images,
|
||||||
|
current: images[current]
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 生命周期钩子
|
||||||
|
onLoad(() => {
|
||||||
|
checkRouteStack();
|
||||||
|
loadComplaintList();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
onPullDownRefresh(() => {
|
||||||
|
resetList();
|
||||||
|
loadComplaintList().then(() => {
|
||||||
|
uni.stopPullDownRefresh();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 上拉加载
|
||||||
|
onReachBottom(() => {
|
||||||
|
loadComplaintList();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</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,9 @@
|
||||||
|
<template>
|
||||||
|
问卷详情
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,486 @@
|
||||||
|
<template>
|
||||||
|
<view class="questionnaire-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">问卷管理</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<template #right>
|
||||||
|
<view class="li-flex-center li-mr-200" @click="createQuestionnaire">
|
||||||
|
<text class="ri-add-line li-text-52"></text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifndef MP-WEIXIN -->
|
||||||
|
<template #right>
|
||||||
|
<view class="li-flex-center li-mr-25" @click="createQuestionnaire">
|
||||||
|
<text class="ri-add-line li-text-52"></text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<!-- #endif -->
|
||||||
|
</wd-navbar>
|
||||||
|
<!-- 导航栏背景 -->
|
||||||
|
<view class="nav-bg-layer"></view>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 筛选区域 -->
|
||||||
|
<view class="filter-section li-w-92% li-mx-auto li-mt-30">
|
||||||
|
<!-- 小区选择 -->
|
||||||
|
<view v-if="hasPermission" class="li-mb-20">
|
||||||
|
<wd-select v-model="selectedVillage" :columns="villageList" label="选择小区" placeholder="请选择小区"
|
||||||
|
use-label-slot>
|
||||||
|
<template #label>
|
||||||
|
<text class="ri-community-line li-text-32 li-mr-10 li-text-#666"></text>
|
||||||
|
</template>
|
||||||
|
</wd-select>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 问卷状态筛选 -->
|
||||||
|
<view class="li-flex li-items-center li-flex-wrap">
|
||||||
|
<text v-for="(item, index) in statusList" :key="index"
|
||||||
|
:class="activeStatus === item.value ? 'status-tag active' : 'status-tag'"
|
||||||
|
@click="handleStatusChange(item.value)">
|
||||||
|
{{item.label}}
|
||||||
|
</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 问卷列表 -->
|
||||||
|
<view class="li-w-92% li-mx-auto li-mt-30 li-pb-30">
|
||||||
|
<view v-if="questionnaireList.length > 0">
|
||||||
|
<view v-for="(item, index) in questionnaireList" :key="index"
|
||||||
|
class="questionnaire-card li-bg-white li-rd-20 li-p-30 li-mb-20 li-shadow-sm"
|
||||||
|
@click="toPages({type:'detail', value:item})">
|
||||||
|
<!-- 问卷标题 -->
|
||||||
|
<view class="li-flex li-items-center li-justify-between li-pb-20 li-bottom-border2">
|
||||||
|
<view class="li-flex li-items-center">
|
||||||
|
<text class="ri-questionnaire-line li-text-40 li-mr-15 li-text-#0070F0"></text>
|
||||||
|
<text class="li-text-32 li-font-bold">{{item.title}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="status-badge" :style="{
|
||||||
|
backgroundColor: getStatusBgColor(item.status),
|
||||||
|
color: getStatusColor(item.status)
|
||||||
|
}">
|
||||||
|
{{getStatusText(item.status)}}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 问卷信息 -->
|
||||||
|
<view class="li-mt-20">
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">所属小区</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#333">{{item.village_name}}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">问卷类型</text>
|
||||||
|
<wd-tag color="#0083ff" bg-color="#d0e8ff">{{item.type}}</wd-tag>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">参与人数</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#333">{{item.participant_count}}人</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 修改有效期和操作按钮的布局 -->
|
||||||
|
<view class="li-flex li-flex-col">
|
||||||
|
<view class="li-flex li-items-center li-mb-15">
|
||||||
|
<text class="content-label li-text-28 li-text-#9a9a9a li-w-160">有效期</text>
|
||||||
|
<text class="content-text li-text-28 li-text-#333">{{item.start_time}} ~
|
||||||
|
{{item.end_time}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="li-flex li-items-center li-justify-between" @click.stop>
|
||||||
|
<view></view>
|
||||||
|
<view class="li-flex li-items-center ">
|
||||||
|
<wd-button type="primary" size="small" plain custom-class="action-btn"
|
||||||
|
@click="handleEdit(item)">编辑</wd-button>
|
||||||
|
<wd-button type="danger" size="small" plain custom-class="action-btn"
|
||||||
|
@click="handleDelete(item)">删除</wd-button>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 空状态 -->
|
||||||
|
<view v-else class="empty-state li-mt-100">
|
||||||
|
<image src="https://img.yzcdn.cn/vant/empty-image-default.png" mode="aspectFit" class="empty-image">
|
||||||
|
</image>
|
||||||
|
<text class="li-text-28 li-text-#999 li-mt-20">暂无问卷数据</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 加载状态 -->
|
||||||
|
<view v-if="loading" class="li-flex-center li-mt-30">
|
||||||
|
<wd-loading color="#0070F0" />
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 底部提示 -->
|
||||||
|
<view v-if="!loading && finished && questionnaireList.length > 0"
|
||||||
|
class="li-text-center li-text-26 li-text-#999 li-py-20">
|
||||||
|
-- 没有更多数据了 --
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, onMounted, watch } from 'vue';
|
||||||
|
import { onLoad, onPullDownRefresh, onReachBottom } 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 hasPermission = ref(true); // 实际项目中应该从用户信息或权限系统中获取
|
||||||
|
|
||||||
|
// 状态管理
|
||||||
|
const selectedVillage = ref('1'); // 设置默认选中的小区
|
||||||
|
const activeStatus = ref('ALL');
|
||||||
|
const loading = ref(false);
|
||||||
|
const finished = ref(false);
|
||||||
|
const page = ref(1);
|
||||||
|
const pageSize = ref(10);
|
||||||
|
|
||||||
|
// 小区列表
|
||||||
|
const villageList = ref([
|
||||||
|
{ value: '1', label: '阳光花园小区' },
|
||||||
|
{ value: '2', label: '翠湖庭院' },
|
||||||
|
{ value: '3', label: '金色家园' }
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 状态筛选选项
|
||||||
|
const statusList = ref([
|
||||||
|
{ label: '全部', value: 'ALL' },
|
||||||
|
{ label: '未开始', value: 0 },
|
||||||
|
{ label: '进行中', value: 1 },
|
||||||
|
{ label: '已结束', value: 2 }
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 模拟问卷列表数据
|
||||||
|
const questionnaireList = ref([
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: '2024年度物业服务满意度调查',
|
||||||
|
village_name: '阳光花园小区',
|
||||||
|
type: '满意度调查',
|
||||||
|
participant_count: 156,
|
||||||
|
start_time: '2024-06-01',
|
||||||
|
end_time: '2024-06-30',
|
||||||
|
status: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: '小区环境改造意见征集',
|
||||||
|
village_name: '阳光花园小区',
|
||||||
|
type: '意见征集',
|
||||||
|
participant_count: 89,
|
||||||
|
start_time: '2024-07-01',
|
||||||
|
end_time: '2024-07-15',
|
||||||
|
status: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: '业主委员会换届选举投票',
|
||||||
|
village_name: '阳光花园小区',
|
||||||
|
type: '投票选举',
|
||||||
|
participant_count: 245,
|
||||||
|
start_time: '2024-05-01',
|
||||||
|
end_time: '2024-05-15',
|
||||||
|
status: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: '业主委员会换届选举投票',
|
||||||
|
village_name: '阳光花园小区',
|
||||||
|
type: '投票选举',
|
||||||
|
participant_count: 245,
|
||||||
|
start_time: '2024-05-01',
|
||||||
|
end_time: '2024-05-15',
|
||||||
|
status: 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: '业主委员会换届选举投票',
|
||||||
|
village_name: '阳光花园小区',
|
||||||
|
type: '投票选举',
|
||||||
|
participant_count: 245,
|
||||||
|
start_time: '2024-05-01',
|
||||||
|
end_time: '2024-05-15',
|
||||||
|
status: 2
|
||||||
|
}
|
||||||
|
]);
|
||||||
|
|
||||||
|
// 状态颜色配置
|
||||||
|
const getStatusColor = (status) => {
|
||||||
|
const colorMap = {
|
||||||
|
0: '#ff9d00', // 未开始
|
||||||
|
1: '#0070F0', // 进行中
|
||||||
|
2: '#999999' // 已结束
|
||||||
|
};
|
||||||
|
return colorMap[status] || '#666666';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态背景色配置
|
||||||
|
const getStatusBgColor = (status) => {
|
||||||
|
const bgColorMap = {
|
||||||
|
0: '#fff6e9', // 未开始
|
||||||
|
1: '#e8f4ff', // 进行中
|
||||||
|
2: '#f5f5f5' // 已结束
|
||||||
|
};
|
||||||
|
return bgColorMap[status] || '#f5f5f5';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 状态文字配置
|
||||||
|
const getStatusText = (status) => {
|
||||||
|
const textMap = {
|
||||||
|
0: '未开始',
|
||||||
|
1: '进行中',
|
||||||
|
2: '已结束'
|
||||||
|
};
|
||||||
|
return textMap[status] || '未知状态';
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理状态切换
|
||||||
|
const handleStatusChange = (status) => {
|
||||||
|
activeStatus.value = status;
|
||||||
|
resetList();
|
||||||
|
loadQuestionnaireList();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 重置列表
|
||||||
|
const resetList = () => {
|
||||||
|
page.value = 1;
|
||||||
|
finished.value = false;
|
||||||
|
questionnaireList.value = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
// 加载问卷列表数据
|
||||||
|
const loadQuestionnaireList = async () => {
|
||||||
|
if (loading.value || finished.value) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
loading.value = true;
|
||||||
|
// 实际项目中这里应该调用API
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||||
|
if (page.value > 1) {
|
||||||
|
finished.value = true;
|
||||||
|
} else {
|
||||||
|
page.value++;
|
||||||
|
}
|
||||||
|
loading.value = false;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载问卷列表失败', error);
|
||||||
|
Toast.fail('加载失败,请重试');
|
||||||
|
loading.value = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 创建问卷
|
||||||
|
const createQuestionnaire = () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pagesB/questionnaire/edit'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 编辑问卷
|
||||||
|
const handleEdit = (item) => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pagesB/questionnaire/edit?id=${item.id}`
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除问卷
|
||||||
|
const handleDelete = (item) => {
|
||||||
|
uni.showModal({
|
||||||
|
title: '提示',
|
||||||
|
content: '确定要删除该问卷吗?',
|
||||||
|
success: async (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
Toast.loading('删除中...');
|
||||||
|
// 实际项目中这里应该调用API
|
||||||
|
await new Promise(resolve => setTimeout(resolve, 800));
|
||||||
|
Toast.success('删除成功');
|
||||||
|
loadQuestionnaireList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 页面跳转
|
||||||
|
const toPages = (item) => {
|
||||||
|
switch (item.type) {
|
||||||
|
case 'nav':
|
||||||
|
uni.navigateBack({
|
||||||
|
delta: 1
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'home':
|
||||||
|
uni.switchTab({
|
||||||
|
url: '/pages/index/index'
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'detail':
|
||||||
|
uni.navigateTo({
|
||||||
|
url: `/pagesB/questionnaire/detail?id=${item.value.id}`
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 生命周期钩子
|
||||||
|
onLoad(() => {
|
||||||
|
checkRouteStack();
|
||||||
|
loadQuestionnaireList();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 下拉刷新
|
||||||
|
onPullDownRefresh(() => {
|
||||||
|
resetList();
|
||||||
|
loadQuestionnaireList().then(() => {
|
||||||
|
uni.stopPullDownRefresh();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// 上拉加载
|
||||||
|
onReachBottom(() => {
|
||||||
|
loadQuestionnaireList();
|
||||||
|
});
|
||||||
|
|
||||||
|
// 监听小区选择变化
|
||||||
|
watch(selectedVillage, (newVal) => {
|
||||||
|
resetList();
|
||||||
|
loadQuestionnaireList();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
page {
|
||||||
|
background-color: #F7F8FA;
|
||||||
|
}
|
||||||
|
|
||||||
|
.questionnaire-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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.filter-section {
|
||||||
|
background: rgba(255, 255, 255, 0.8);
|
||||||
|
border-radius: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
backdrop-filter: blur(10px);
|
||||||
|
-webkit-backdrop-filter: blur(10px);
|
||||||
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag {
|
||||||
|
padding: 8rpx 24rpx;
|
||||||
|
border-radius: 30rpx;
|
||||||
|
font-size: 28rpx;
|
||||||
|
color: #666;
|
||||||
|
background: #f5f5f5;
|
||||||
|
margin-right: 16rpx;
|
||||||
|
margin-bottom: 16rpx;
|
||||||
|
transition: all 0.3s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-tag.active {
|
||||||
|
color: #0070F0;
|
||||||
|
background: rgba(0, 112, 240, 0.1);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.questionnaire-card {
|
||||||
|
transition: all 0.3s;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
transform: scale(0.98);
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge {
|
||||||
|
padding: 4rpx 20rpx;
|
||||||
|
border-radius: 20rpx;
|
||||||
|
font-size: 24rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.li-bottom-border2 {
|
||||||
|
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.empty-image {
|
||||||
|
width: 240rpx;
|
||||||
|
height: 240rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-btn {
|
||||||
|
width: 100rpx !important;
|
||||||
|
margin-left: 15rpx !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
::v-deep .wd-navbar__placeholder {
|
||||||
|
height: calc(var(--status-bar-height) + 88rpx) !important;
|
||||||
|
padding-top: constant(safe-area-inset-top) !important;
|
||||||
|
padding-top: env(safe-area-inset-top) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .wd-select {
|
||||||
|
background-color: transparent !important;
|
||||||
|
margin-bottom: 0 !important;
|
||||||
|
|
||||||
|
.wd-select__value {
|
||||||
|
color: #333 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wd-select__label {
|
||||||
|
margin-right: 20rpx !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .wd-select__right-icon {
|
||||||
|
color: #666 !important;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,134 +1,116 @@
|
||||||
|
|
||||||
|
.bg-FFFFFF{background-color:rgb(255,255,255)}
|
||||||
|
.bg-f9f9f9{background-color:rgb(249,249,249)}
|
||||||
|
.border-4-white{border-style:solid;border-color:rgb(255,255,255);border-width:4rpx}
|
||||||
.li-bg-white{background-color:rgb(255,255,255)}
|
.li-bg-white{background-color:rgb(255,255,255)}
|
||||||
.li-block{display:block}
|
|
||||||
.li-border-b{border-style:solid;border-color:b;border-width:1rpx}
|
|
||||||
.li-flex{display:flex}
|
.li-flex{display:flex}
|
||||||
.li-font-500{font-weight:500}
|
|
||||||
.li-font-bold{font-weight:bold}
|
|
||||||
.li-items-baseline{align-items:baseline}
|
|
||||||
.li-items-center{align-items:center}
|
|
||||||
.li-justify-between{justify-content:space-between}
|
|
||||||
.li-lh-44{line-height:44}
|
|
||||||
.li-mb-15{margin-bottom:15rpx}
|
|
||||||
.li-mb-20{margin-bottom:20rpx}
|
|
||||||
.li-mb-30{margin-bottom:30rpx}
|
|
||||||
.li-mb-40{margin-bottom:40rpx}
|
|
||||||
.li-mb-8{margin-bottom:8rpx}
|
|
||||||
.li-ml-10{margin-left:10rpx}
|
|
||||||
.li-ml-15{margin-left:15rpx}
|
|
||||||
.li-ml-20{margin-left:20rpx}
|
|
||||||
.li-mr-10{margin-right:10rpx}
|
|
||||||
.li-mr-15{margin-right:15rpx}
|
|
||||||
.li-mr-5{margin-right:5rpx}
|
|
||||||
.li-mt-10{margin-top:10rpx}
|
|
||||||
.li-mt-20{margin-top:20rpx}
|
|
||||||
.li-mt-30{margin-top:30rpx}
|
|
||||||
.li-mt-40{margin-top:40rpx}
|
|
||||||
.li-mt-5{margin-top:5rpx}
|
|
||||||
.li-mx-auto{margin-left:auto;margin-right:auto}
|
|
||||||
.li-opacity-80{undefined:0.8}
|
|
||||||
.li-p-15{padding:15rpx}
|
|
||||||
.li-p-30{padding:30rpx}
|
|
||||||
.li-pl-30{padding-left:30rpx}
|
|
||||||
.li-py-30{padding-top:30rpx;padding-bottom:30rpx}
|
|
||||||
.li-py-60{padding-top:60rpx;padding-bottom:60rpx}
|
|
||||||
.li-rd-12{border-radius:12rpx}
|
|
||||||
.li-rd-16{border-radius:16rpx}
|
|
||||||
.li-rd-20{border-radius:20rpx}
|
|
||||||
.li-text-0070F0-color{color:rgb(0,112,240)}
|
|
||||||
.li-text-26{font-size:26rpx}
|
|
||||||
.li-text-28{font-size:28rpx}
|
|
||||||
.li-text-30{font-size:30rpx}
|
|
||||||
.li-text-32{font-size:32rpx}
|
|
||||||
.li-text-333-color{color:rgb(51,51,51)}
|
|
||||||
.li-text-34{font-size:34rpx}
|
|
||||||
.li-text-36{font-size:36rpx}
|
|
||||||
.li-text-42{font-size:42rpx}
|
|
||||||
.li-text-48{font-size:48rpx}
|
|
||||||
.li-text-55{font-size:55rpx}
|
|
||||||
.li-text-666-color{color:rgb(102,102,102)}
|
|
||||||
.li-text-70{font-size:70rpx}
|
|
||||||
.li-text-999-color{color:rgb(153,153,153)}
|
|
||||||
.li-text-center{text-align:center}
|
|
||||||
.li-text-white{color:rgb(255,255,255)}
|
|
||||||
.li-w-650rpx{width:650rpx}
|
|
||||||
.li-w-full-92{width:92%}
|
|
||||||
.li-flex-col{flex-direction:column}
|
.li-flex-col{flex-direction:column}
|
||||||
.li-justify-around{justify-content:space-around}
|
.li-font-bold{font-weight:bold}
|
||||||
.li-px-30{padding-left:30rpx;padding-right:30rpx}
|
.li-h-100{height:100rpx}
|
||||||
.li-py-20{padding-top:20rpx;padding-bottom:20rpx}
|
.li-h-240{height:240rpx}
|
||||||
|
.li-h-250{height:250rpx}
|
||||||
|
.li-h-50{height:50rpx}
|
||||||
|
.li-h-60{height:60rpx}
|
||||||
.li-items-center{align-items:center}
|
.li-items-center{align-items:center}
|
||||||
.items-center{align-items:center}
|
.li-items-end{align-items:end}
|
||||||
|
.li-justify-between{justify-content:space-between}
|
||||||
.li-justify-center{justify-content:center}
|
.li-justify-center{justify-content:center}
|
||||||
|
.li-justify-start{justify-content:start}
|
||||||
|
.li-mb-2{margin-bottom:2rpx}
|
||||||
|
.li-ml-4{margin-left:4rpx}
|
||||||
|
.li-ml-50{margin-left:50rpx}
|
||||||
|
.li-mr-20{margin-right:20rpx}
|
||||||
|
.li-mr-50{margin-right:50rpx}
|
||||||
|
.li-mt-20{margin-top:20rpx}
|
||||||
|
.li-mt-26{margin-top:26rpx}
|
||||||
|
.li-mt-30{margin-top:30rpx}
|
||||||
|
.li-mt-6{margin-top:6rpx}
|
||||||
|
.li-mt-60{margin-top:60rpx}
|
||||||
|
.li-mx-20{margin-left:20rpx;margin-right:20rpx}
|
||||||
|
.li-mx-40{margin-left:40rpx;margin-right:40rpx}
|
||||||
|
.li-mx-auto{margin-left:auto;margin-right:auto}
|
||||||
|
.li-pb-10{padding-bottom:10rpx}
|
||||||
|
.li-pb-14{padding-bottom:14rpx}
|
||||||
|
.li-pb-20{padding-bottom:20rpx}
|
||||||
|
.li-pt-20{padding-top:20rpx}
|
||||||
|
.li-pt-8{padding-top:8rpx}
|
||||||
|
.li-py-20{padding-top:20rpx;padding-bottom:20rpx}
|
||||||
|
.li-rd-20{border-radius:20rpx}
|
||||||
|
.li-rd-full-50{border-radius:50%}
|
||||||
|
.li-rd-tl-30-important{border-top-left-radius:30rpx !important}
|
||||||
|
.li-rd-tr-30-important{border-top-right-radius:30rpx !important}
|
||||||
|
.li-text-000000-color{color:rgb(0,0,0)}
|
||||||
|
.li-text-010B3E-color{color:rgb(1,11,62)}
|
||||||
|
.li-text-19171B-color{color:rgb(25,23,27)}
|
||||||
|
.li-text-20{font-size:20rpx}
|
||||||
|
.li-text-24{font-size:24rpx}
|
||||||
|
.li-text-26{font-size:26rpx}
|
||||||
|
.li-text-32{font-size:32rpx}
|
||||||
|
.li-text-34{font-size:34rpx}
|
||||||
|
.li-text-38{font-size:38rpx}
|
||||||
|
.li-text-706e70-color{color:rgb(112,110,112)}
|
||||||
|
.li-text-B2B2B2-color{color:rgb(178,178,178)}
|
||||||
|
.li-text-BBBDDA-color{color:rgb(187,189,218)}
|
||||||
|
.li-text-F2F7FD-color{color:rgb(242,247,253)}
|
||||||
|
.li-text-F8C883-color{color:rgb(248,200,131)}
|
||||||
|
.li-text-FFFFFF-color{color:rgb(255,255,255)}
|
||||||
|
.li-text-b1bbc7-color{color:rgb(177,187,199)}
|
||||||
|
.li-w-100{width:100rpx}
|
||||||
|
.li-w-240{width:240rpx}
|
||||||
|
.li-w-50{width:50rpx}
|
||||||
|
.li-w-60{width:60rpx}
|
||||||
|
.li-w-full-70{width:70%}
|
||||||
|
.li-w-full-94{width:94%}
|
||||||
|
.li-flex-center{display:flex;align-items:center;justify-content:center}
|
||||||
|
.li-ml-20{margin-left:20rpx}
|
||||||
|
.li-ml-200{margin-left:200rpx}
|
||||||
|
.li-ml-25{margin-left:25rpx}
|
||||||
|
.li-ml-30{margin-left:30rpx}
|
||||||
|
.li-mr-10{margin-right:10rpx}
|
||||||
|
.li-mr-30{margin-right:30rpx}
|
||||||
|
.li-mt-10{margin-top:10rpx}
|
||||||
|
.li-mt-300-important{margin-top:300rpx !important}
|
||||||
|
.li-pt-2{padding-top:2rpx}
|
||||||
|
.li-px-30{padding-left:30rpx;padding-right:30rpx}
|
||||||
|
.li-text-25{font-size:25rpx}
|
||||||
|
.li-text-30{font-size:30rpx}
|
||||||
|
.li-text-35{font-size:35rpx}
|
||||||
|
.li-text-42{font-size:42rpx}
|
||||||
|
.li-text-46{font-size:46rpx}
|
||||||
|
.li-text-B1B0B0-color{color:rgb(177,176,176)}
|
||||||
|
.li-w-full-80{width:80%}
|
||||||
|
.items-center{align-items:center}
|
||||||
.justify-end{justify-content:end}
|
.justify-end{justify-content:end}
|
||||||
.justify-center{justify-content:center}
|
.justify-center{justify-content:center}
|
||||||
.li-justify-between{justify-content:space-between}
|
|
||||||
.justify-between{justify-content:space-between}
|
.justify-between{justify-content:space-between}
|
||||||
.li-bg-white{background-color:rgb(255,255,255)}
|
|
||||||
.li-flex{display:flex}
|
|
||||||
.li-flex-center{display:flex;align-items:center;justify-content:center}
|
|
||||||
.li-flex-col{flex-direction:column}
|
|
||||||
.li-font-bold{font-weight:bold}
|
|
||||||
.li-h-130{height:130rpx}
|
.li-h-130{height:130rpx}
|
||||||
.li-h-160{height:160rpx}
|
.li-h-160{height:160rpx}
|
||||||
.li-h-220{height:220rpx}
|
.li-h-220{height:220rpx}
|
||||||
.li-h-58{height:58rpx}
|
.li-h-58{height:58rpx}
|
||||||
.li-justify-around{justify-content:space-around}
|
.li-justify-around{justify-content:space-around}
|
||||||
.li-ml-22{margin-left:22rpx}
|
.li-ml-22{margin-left:22rpx}
|
||||||
.li-ml-25{margin-left:25rpx}
|
|
||||||
.li-ml-35{margin-left:35rpx}
|
.li-ml-35{margin-left:35rpx}
|
||||||
.li-mr-5{margin-right:5rpx}
|
.li-mr-5{margin-right:5rpx}
|
||||||
.li-mt-10{margin-top:10rpx}
|
|
||||||
.li-mt-12{margin-top:12rpx}
|
.li-mt-12{margin-top:12rpx}
|
||||||
.li-mt-14{margin-top:14rpx}
|
.li-mt-14{margin-top:14rpx}
|
||||||
.li-mt-15{margin-top:15rpx}
|
.li-mt-15{margin-top:15rpx}
|
||||||
.li-mt-20{margin-top:20rpx}
|
|
||||||
.li-mt-30{margin-top:30rpx}
|
|
||||||
.li-mx-auto{margin-left:auto;margin-right:auto}
|
|
||||||
.li-pt-15{padding-top:15rpx}
|
.li-pt-15{padding-top:15rpx}
|
||||||
.li-px-25{padding-left:25rpx;padding-right:25rpx}
|
.li-px-25{padding-left:25rpx;padding-right:25rpx}
|
||||||
.li-px-30{padding-left:30rpx;padding-right:30rpx}
|
|
||||||
.li-px-40{padding-left:40rpx;padding-right:40rpx}
|
.li-px-40{padding-left:40rpx;padding-right:40rpx}
|
||||||
.li-px-50{padding-left:50rpx;padding-right:50rpx}
|
.li-px-50{padding-left:50rpx;padding-right:50rpx}
|
||||||
.li-py-25{padding-top:25rpx;padding-bottom:25rpx}
|
.li-py-25{padding-top:25rpx;padding-bottom:25rpx}
|
||||||
.li-rd-10{border-radius:10rpx}
|
.li-rd-10{border-radius:10rpx}
|
||||||
.li-rd-15{border-radius:15rpx}
|
.li-rd-15{border-radius:15rpx}
|
||||||
.li-text-010B3E-color{color:rgb(1,11,62)}
|
|
||||||
.li-text-22{font-size:22rpx}
|
.li-text-22{font-size:22rpx}
|
||||||
.li-text-24{font-size:24rpx}
|
|
||||||
.li-text-26{font-size:26rpx}
|
|
||||||
.li-text-28{font-size:28rpx}
|
.li-text-28{font-size:28rpx}
|
||||||
.li-text-30{font-size:30rpx}
|
|
||||||
.li-text-343333-color{color:rgb(52,51,51)}
|
.li-text-343333-color{color:rgb(52,51,51)}
|
||||||
.li-text-43{font-size:43rpx}
|
.li-text-43{font-size:43rpx}
|
||||||
.li-text-AFB2B8-color{color:rgb(175,178,184)}
|
.li-text-AFB2B8-color{color:rgb(175,178,184)}
|
||||||
.li-text-B1B0B0-color{color:rgb(177,176,176)}
|
|
||||||
.li-text-F42429-color{color:rgb(244,36,41)}
|
.li-text-F42429-color{color:rgb(244,36,41)}
|
||||||
.li-w-130{width:130rpx}
|
.li-w-130{width:130rpx}
|
||||||
.li-w-310{width:310rpx}
|
.li-w-310{width:310rpx}
|
||||||
.li-w-58{width:58rpx}
|
.li-w-58{width:58rpx}
|
||||||
.li-w-full-70{width:70%}
|
|
||||||
.li-w-full-88{width:88%}
|
.li-w-full-88{width:88%}
|
||||||
.li-h-100{height:100rpx}
|
|
||||||
.li-ml-20{margin-left:20rpx}
|
|
||||||
.li-ml-200{margin-left:200rpx}
|
|
||||||
.li-ml-30{margin-left:30rpx}
|
|
||||||
.li-mr-10{margin-right:10rpx}
|
|
||||||
.li-mr-30{margin-right:30rpx}
|
|
||||||
.li-mt-300-important{margin-top:300rpx !important}
|
|
||||||
.li-pt-2{padding-top:2rpx}
|
|
||||||
.li-py-20{padding-top:20rpx;padding-bottom:20rpx}
|
|
||||||
.li-rd-full-50{border-radius:50%}
|
|
||||||
.li-text-25{font-size:25rpx}
|
|
||||||
.li-text-35{font-size:35rpx}
|
|
||||||
.li-text-38{font-size:38rpx}
|
|
||||||
.li-text-42{font-size:42rpx}
|
|
||||||
.li-text-46{font-size:46rpx}
|
|
||||||
.li-w-100{width:100rpx}
|
|
||||||
.li-w-full-80{width:80%}
|
|
||||||
.bg-FFFFFF{background-color:rgb(255,255,255)}
|
|
||||||
.border-4-white{border-style:solid;border-color:rgb(255,255,255);border-width:4rpx}
|
|
||||||
.bg-f9f9f9{background-color:rgb(249,249,249)}
|
|
||||||
.li-mb-8{margin-bottom:8rpx}
|
.li-mb-8{margin-bottom:8rpx}
|
||||||
.li-ml-15{margin-left:15rpx}
|
.li-ml-15{margin-left:15rpx}
|
||||||
.li-ml-6{margin-left:6rpx}
|
.li-ml-6{margin-left:6rpx}
|
||||||
|
|
@ -139,7 +121,6 @@
|
||||||
.li-pt-25{padding-top:25rpx}
|
.li-pt-25{padding-top:25rpx}
|
||||||
.li-pt-4{padding-top:4rpx}
|
.li-pt-4{padding-top:4rpx}
|
||||||
.li-text-009aff-color{color:rgb(0,154,255)}
|
.li-text-009aff-color{color:rgb(0,154,255)}
|
||||||
.li-text-32{font-size:32rpx}
|
|
||||||
.li-text-333333-color{color:rgb(51,51,51)}
|
.li-text-333333-color{color:rgb(51,51,51)}
|
||||||
.li-text-36{font-size:36rpx}
|
.li-text-36{font-size:36rpx}
|
||||||
.li-text-55{font-size:55rpx}
|
.li-text-55{font-size:55rpx}
|
||||||
|
|
@ -148,47 +129,6 @@
|
||||||
.li-text-ff0000-color{color:rgb(255,0,0)}
|
.li-text-ff0000-color{color:rgb(255,0,0)}
|
||||||
.li-w-full-100{width:100%}
|
.li-w-full-100{width:100%}
|
||||||
.li-w-full-92{width:92%}
|
.li-w-full-92{width:92%}
|
||||||
.li-h-240{height:240rpx}
|
|
||||||
.li-h-250{height:250rpx}
|
|
||||||
.li-h-50{height:50rpx}
|
|
||||||
.li-h-60{height:60rpx}
|
|
||||||
.li-items-end{align-items:end}
|
|
||||||
.li-justify-start{justify-content:start}
|
|
||||||
.li-mb-2{margin-bottom:2rpx}
|
|
||||||
.li-ml-4{margin-left:4rpx}
|
|
||||||
.li-ml-50{margin-left:50rpx}
|
|
||||||
.li-mr-20{margin-right:20rpx}
|
|
||||||
.li-mr-50{margin-right:50rpx}
|
|
||||||
.li-mt-26{margin-top:26rpx}
|
|
||||||
.li-mt-6{margin-top:6rpx}
|
|
||||||
.li-mt-60{margin-top:60rpx}
|
|
||||||
.li-mx-20{margin-left:20rpx;margin-right:20rpx}
|
|
||||||
.li-mx-40{margin-left:40rpx;margin-right:40rpx}
|
|
||||||
.li-pb-10{padding-bottom:10rpx}
|
|
||||||
.li-pb-14{padding-bottom:14rpx}
|
|
||||||
.li-pb-20{padding-bottom:20rpx}
|
|
||||||
.li-pt-20{padding-top:20rpx}
|
|
||||||
.li-pt-8{padding-top:8rpx}
|
|
||||||
.li-rd-20{border-radius:20rpx}
|
|
||||||
.li-rd-tl-30-important{border-top-left-radius:30rpx !important}
|
|
||||||
.li-rd-tr-30-important{border-top-right-radius:30rpx !important}
|
|
||||||
.li-text-000000-color{color:rgb(0,0,0)}
|
|
||||||
.li-text-19171B-color{color:rgb(25,23,27)}
|
|
||||||
.li-text-20{font-size:20rpx}
|
|
||||||
.li-text-34{font-size:34rpx}
|
|
||||||
.li-text-706e70-color{color:rgb(112,110,112)}
|
|
||||||
.li-text-B2B2B2-color{color:rgb(178,178,178)}
|
|
||||||
.li-text-BBBDDA-color{color:rgb(187,189,218)}
|
|
||||||
.li-text-F2F7FD-color{color:rgb(242,247,253)}
|
|
||||||
.li-text-F8C883-color{color:rgb(248,200,131)}
|
|
||||||
.li-text-FFFFFF-color{color:rgb(255,255,255)}
|
|
||||||
.li-text-b1bbc7-color{color:rgb(177,187,199)}
|
|
||||||
.li-w-240{width:240rpx}
|
|
||||||
.li-w-50{width:50rpx}
|
|
||||||
.li-w-60{width:60rpx}
|
|
||||||
.li-w-full-94{width:94%}
|
|
||||||
.li-mb-25{margin-bottom:25rpx}
|
|
||||||
.li-w-full-90{width:90%}
|
|
||||||
.li-font-550{font-weight:550}
|
.li-font-550{font-weight:550}
|
||||||
.li-h-68{height:68rpx}
|
.li-h-68{height:68rpx}
|
||||||
.li-mt-100{margin-top:100rpx}
|
.li-mt-100{margin-top:100rpx}
|
||||||
|
|
@ -203,9 +143,7 @@
|
||||||
.li-w-150{width:150rpx}
|
.li-w-150{width:150rpx}
|
||||||
.li-w-420{width:420rpx}
|
.li-w-420{width:420rpx}
|
||||||
.li-w-full-85{width:85%}
|
.li-w-full-85{width:85%}
|
||||||
.li-font-400{font-weight:400}
|
.li-w-full-90{width:90%}
|
||||||
.li-m-30{margin:30rpx}
|
|
||||||
.li-text-595959-color{color:rgb(89,89,89)}
|
|
||||||
|
|
||||||
.li-h-110{height:110rpx}
|
.li-h-110{height:110rpx}
|
||||||
.li-items-start{align-items:start}
|
.li-items-start{align-items:start}
|
||||||
|
|
@ -228,6 +166,13 @@
|
||||||
.li-w-400{width:400rpx}
|
.li-w-400{width:400rpx}
|
||||||
.overflow-hidden{overflow:hidden}
|
.overflow-hidden{overflow:hidden}
|
||||||
|
|
||||||
|
.li-font-400{font-weight:400}
|
||||||
|
.li-m-30{margin:30rpx}
|
||||||
|
.li-text-595959-color{color:rgb(89,89,89)}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.li-mb-25{margin-bottom:25rpx}
|
||||||
|
|
||||||
.li-mb-30{margin-bottom:30rpx}
|
.li-mb-30{margin-bottom:30rpx}
|
||||||
.li-ml-10{margin-left:10rpx}
|
.li-ml-10{margin-left:10rpx}
|
||||||
|
|
@ -248,10 +193,10 @@
|
||||||
.li-text-white{color:rgb(255,255,255)}
|
.li-text-white{color:rgb(255,255,255)}
|
||||||
.li-w-500{width:500rpx}
|
.li-w-500{width:500rpx}
|
||||||
|
|
||||||
|
|
||||||
.li-text-100{font-size:100rpx}
|
.li-text-100{font-size:100rpx}
|
||||||
.li-text-ddd-color{color:rgb(221,221,221)}
|
.li-text-ddd-color{color:rgb(221,221,221)}
|
||||||
|
|
||||||
|
|
||||||
.li-mb-10{margin-bottom:10rpx}
|
.li-mb-10{margin-bottom:10rpx}
|
||||||
.li-mb-15{margin-bottom:15rpx}
|
.li-mb-15{margin-bottom:15rpx}
|
||||||
.li-mb-40{margin-bottom:40rpx}
|
.li-mb-40{margin-bottom:40rpx}
|
||||||
|
|
@ -262,21 +207,53 @@
|
||||||
|
|
||||||
.li-block{display:block}
|
.li-block{display:block}
|
||||||
.li-border-b{border-style:solid;border-color:b;border-width:1rpx}
|
.li-border-b{border-style:solid;border-color:b;border-width:1rpx}
|
||||||
.li-font-500{font-weight:500}
|
|
||||||
.li-items-baseline{align-items:baseline}
|
.li-items-baseline{align-items:baseline}
|
||||||
.li-lh-44{line-height:44}
|
|
||||||
.li-mr-15{margin-right:15rpx}
|
.li-mr-15{margin-right:15rpx}
|
||||||
.li-mt-5{margin-top:5rpx}
|
.li-mt-5{margin-top:5rpx}
|
||||||
.li-opacity-80{undefined:0.8}
|
.li-opacity-100{undefined:1}
|
||||||
.li-py-60{padding-top:60rpx;padding-bottom:60rpx}
|
.li-py-60{padding-top:60rpx;padding-bottom:60rpx}
|
||||||
.li-rd-12{border-radius:12rpx}
|
.li-rd-12{border-radius:12rpx}
|
||||||
.li-rd-16{border-radius:16rpx}
|
.li-rd-16{border-radius:16rpx}
|
||||||
.li-w-650rpx{width:650rpx}
|
.li-text-0a4696-color{color:rgb(10,70,150)}
|
||||||
|
|
||||||
.li-h-90{height:90rpx}
|
.li-h-90{height:90rpx}
|
||||||
.li-text-47{font-size:47rpx}
|
.li-text-47{font-size:47rpx}
|
||||||
.li-w-90{width:90rpx}
|
.li-w-90{width:90rpx}
|
||||||
|
|
||||||
|
.li-flex-1{flex:1}
|
||||||
|
.li-flex-wrap{flex-wrap:wrap}
|
||||||
|
.li-line-clamp-2{overflow:hidden;display:-webkit-box;line-clamp:2;-webkit-box-orient:vertical;-webkit-line-clamp:2}
|
||||||
|
.li-text-999999-color{color:rgb(153,153,153)}
|
||||||
|
.li-w-160{width:160rpx}
|
||||||
|
.li-w-full-96{width:96%}
|
||||||
|
|
||||||
|
.li-mt-25{margin-top:25rpx}
|
||||||
|
.li-px-20{padding-left:20rpx;padding-right:20rpx}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.li-block{display:block}
|
||||||
|
.li-items-baseline{align-items:baseline}
|
||||||
|
.li-mr-15{margin-right:15rpx}
|
||||||
|
.li-opacity-100{undefined:1}
|
||||||
|
.li-p-15{padding:15rpx}
|
||||||
|
.li-py-60{padding-top:60rpx;padding-bottom:60rpx}
|
||||||
|
.li-rd-12{border-radius:12rpx}
|
||||||
|
.li-text-0a4696-color{color:rgb(10,70,150)}
|
||||||
|
|
||||||
|
.li-h-90{height:90rpx}
|
||||||
|
.li-ml-30{margin-left:30rpx}
|
||||||
|
.li-mr-6{margin-right:6rpx}
|
||||||
|
.li-mt-300-important{margin-top:300rpx !important}
|
||||||
|
.li-pt-2{padding-top:2rpx}
|
||||||
|
.li-text-25{font-size:25rpx}
|
||||||
|
.li-text-52{font-size:52rpx}
|
||||||
|
.li-w-90{width:90rpx}
|
||||||
|
.li-w-full-80{width:80%}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue