feat(项目详情): 添加项目详情页面及组件

实现项目详情页面的基础结构,包括:
- 新增BasicView、RecordView、ControlView三个组件
- 配置项目详情路由
- 完善项目列表到详情的跳转功能
- 实现风险管控实施页面的主要交互和样式
This commit is contained in:
liangbin 2026-01-19 17:58:04 +08:00
parent ab8e574c5e
commit 8821c01725
6 changed files with 488 additions and 4 deletions

View File

@ -35,6 +35,13 @@
"enablePullDownRefresh": true
}
},
{
"path": "pages/ProgectDetails/index",
"style": {
"navigationBarTitleText": "项目详情",
"navigationStyle": "custom"
}
},
{
"path": "pages/user/index",
"style": {

View File

@ -0,0 +1 @@
<!-- 项目详情-基本项目信息 -->

View File

@ -0,0 +1,141 @@
<!-- 项目详情-风险管控实施 -->
<template>
<view class="MainBox">
<view class="BoxA">
<u-row>
<u-col :span="6">
<view>今日检查项完成度</view>
<view class="blcakFont">5/6</view>
</u-col>
<u-col :span="6">
<view>待整改问题数</view>
<view class="yellowFont">10</view>
</u-col>
</u-row>
<view style="margin-top: 20rpx;">
<u-button type="primary" size="medium">提交今日风险检查项</u-button>
</view>
</view>
<view class="BoxB">
<view class="h2Box">问题反馈列表</view>
<view class="ListBox">
<u-virtual-list :list-data="dataSource" :item-height="130" height="100%">
<template #default="{ item, index }">
<view class="CardBox">
<view class="CardItem">
<view class="CardName">{{ item.name }}</view>
<view class="CardTime">{{ item.time }}</view>
</view>
<view class="CardItem">
<view>
<u-tag type="warning" plain text="待整改" shape="circle"></u-tag>
</view>
<view>
<u-button text="整改反馈" color="#2979ff" size="small"></u-button>
</view>
</view>
</view>
</template>
</u-virtual-list>
</view>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const dataSource = ref([
{ id: 1, name: 'AI返现安全帽佩戴不规范', time: '2023-08-01 10:00:00' },
{ id: 2, name: 'AI返现安全帽佩戴不规范', time: '2023-08-02 10:00:00' },
{ id: 3, name: 'AI返现安全帽佩戴不规范', time: '2023-08-03 10:00:00' },
{ id: 4, name: 'AI返现安全帽佩戴不规范', time: '2023-08-04 10:00:00' },
{ id: 5, name: 'AI返现安全帽佩戴不规范', time: '2023-08-05 10:00:00' },
{ id: 6, name: 'AI返现安全帽佩戴不规范', time: '2023-08-06 10:00:00' },
{ id: 7, name: 'AI返现安全帽佩戴不规范', time: '2023-08-07 10:00:00' },
])
</script>
<style lang="scss" scoped>
.h2Box {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.blcakFont {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.yellowFont {
font-size: 36rpx;
font-weight: bold;
color: #FFD600;
}
.MainBox {
height: 100%;
overflow: hidden;
padding: 20rpx;
background-color: #fff;
.BoxA {
padding: 20rpx;
border-radius: 10rpx;
background-color: #EFF6FF;
}
.BoxB {
padding: 20rpx;
border-radius: 10rpx;
height: calc(100% - 210rpx);
.ListBox {
height: calc(100% - 10rpx);
margin-top: 20rpx;
overflow: hidden;
.CardBox {
width: calc(100% - 30rpx);
height: 180rpx;
margin: 0 auto;
padding: 20rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08), 0 2rpx 4rpx rgba(0, 0, 0, 0.04);
margin-bottom: 20rpx;
background-color: #fff;
border-radius: 10rpx;
overflow: auto;
.CardItem {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 20rpx;
margin-bottom: 20rpx;
}
.CardName {
flex: 1;
font-size: 26rpx;
font-weight: bold;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.CardTime {
white-space: nowrap;
flex-shrink: 0;
}
}
}
}
}
</style>

View File

@ -0,0 +1 @@
<!-- 项目详情-整改记录 -->

View File

@ -0,0 +1,192 @@
<!-- 项目详情 -->
<template>
<view class="PageBox">
<view class="TopBox FlexBox">
<view class="iconBox FlexBox">
<!-- 返回上一页 -->
<u-icon name="arrow-leftward" size="24" @click="goBack"></u-icon>
</view>
<view class="Title">{{ progectInfo.name }}</view>
<view class="informBox">
<u-icon name="bell-fill" size="24"></u-icon>
<view class="MsgTxt"></view>
</view>
</view>
<view class="ContentBox">
<view class="PBasicBox">
<u-row justify="space-between">
<u-col span="4">
<view class="LabelBox">项目编号</view>
<view class="LabelBoxTxt">{{ progectInfo.code }}</view>
</u-col>
<u-col span="3">
<view class="LabelBox">作业负责人</view>
<view class="LabelBoxTxt">{{ progectInfo.leader }}</view>
</u-col>
<u-col span="5">
<view class="LabelBox">作业周期</view>
<view class="LabelBoxTxt">{{ progectInfo.period }}</view>
</u-col>
</u-row>
<u-row>
<u-col span="12">当前进度<u-line-progress :percentage="progectInfo.percentage"
activeColor="#55AAFF"></u-line-progress></u-col>
</u-row>
<u-row>
<u-col span="12">
<view class="LabelBox">风险管控类型</view>
<view class="LabelBoxTxt">{{ progectInfo.riskControlType }}</view>
</u-col>
</u-row>
</view>
<view class="TabBox">
<up-tabs :list="list1" @click="click"></up-tabs>
</view>
<view class="displayCase">
<ControlView></ControlView>
</view>
</view>
<view class="FootBox">
<u-button type="primary">项目完工确认</u-button>
<view class="FootTxt">
<view>复核进度</view>
<view class="yellow">监理复核中</view>
</view>
</view>
</view>
</template>
<script setup>
import ControlView from './components/ControlView.vue'
import { ref } from 'vue'
const progectInfo = ref({
Id: 1,
name: '北京CBD改造项目',
code: '20230801001',
leader: '张三',
period: '2023.8.1-2023.12.31',
riskControlType: '动火作业风险卡',
percentage: 30
})
const list1 = ref([
{
name: '风险管控实施',
id: 1
},
{
name: '基本项目信息',
id: 2
},
{
name: '整改记录',
id: 3
}
])
</script>
<style lang="scss" scoped>
.FlexBox {
display: flex;
align-items: center;
justify-content: space-between;
gap: 20rpx;
}
.PBasicBox {
padding: 20rpx;
background-color: #fff;
.LabelBox {
font-size: 24rpx;
color: #666;
margin-top: 20rpx;
}
.LabelBoxTxt {
font-size: 24rpx;
color: #333;
font-weight: bold;
}
}
.PageBox {
background-color: #ff9900;
height: 100vh;
overflow: hidden;
.TopBox {
height: 100rpx;
padding: 20rpx;
background-color: #fff;
.iconBox {
font-size: 32rpx;
}
.Title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.informBox {
.MsgTxt {
padding: 8rpx;
background-color: hsla(17, 100%, 50%, 0.849);
color: #fff;
position: absolute;
top: 16rpx;
right: 16rpx;
border-radius: 50%;
}
}
}
.ContentBox {
background-color: #c5d5d6;
height: calc(100vh - 250rpx);
overflow: hidden;
.TabBox {
display: flex;
align-items: center;
justify-content: center;
height: 80rpx;
background-color: #fff;
}
.displayCase {
height: calc(100% - 370rpx);
background-color: #ff9900;
overflow: hidden;
}
}
.FootBox {
height: 150rpx;
gap: 20rpx;
padding: 20rpx;
background-color: #fff;
font-weight: bold;
.FootTxt {
margin-top: 20rpx;
display: flex;
align-items: center;
justify-content: center;
gap: 10rpx;
font-size: 24rpx;
color: #666;
}
.yellow {
color: #ff9900;
}
}
}
</style>

View File

@ -1,8 +1,150 @@
<!-- 项目实施-列表页 -->
<template>
<view class="project-list">
<view class="approval-header">
<text class="approval-title">项目实施列表</text>
<view class="PageBox">
<view class="FlexBox TopBox">
<view class="SelectBox">
<u-select :current="TypeValue" :options="TypeList" placeholder="请选择工单类型" size="large" showOptionsLabel
@update:current="TypeValue = $event"></u-select>
</view>
</view>
<view class="ListBox">
<u-virtual-list :list-data="dataSource" :item-height="200" height="100%">
<template #default="{ item, index }">
<view class="CardBox">
<view class="FlexBox">
<view class="Title">{{ item.name }}</view>
<view class="DetailBtn">
<u-button text="详情" type="primary" size="small" @click="GoDetail(item.id)"></u-button>
</view>
</view>
<view class="CodeTxt">{{ item.site }}</view>
<view class="CodeTxt">剩余作业时长{{ item.remainingTime }}</view>
<view class="TagBox">
<u-tag :text="item.status" plain
:type="item.status === '实施中' ? 'primary' : item.status === '整改中' ? 'warning' : item.status === '待完工确认' ? 'info' : item.status === '已完工' ? 'success' : 'danger'"
shape="circle"></u-tag>
</view>
</view>
</template>
</u-virtual-list>
</view>
</view>
</template>
<script setup>
import { ref } from 'vue'
const TypeValue = ref('1') //
//
const TypeList = ref([
{ name: '全部实施中项目', id: '1' },
{ name: '我负责的项目', id: '2' },
{ name: '带整改', id: '3' },
{ name: '待完工确认', id: '4' },
])
const dataSource = ref([
{ id: 1, name: '北京CBD写字楼改造项目', remainingTime: '1', site: '北京市朝阳区建国路88号', status: '实施中' },
{ id: 2, name: '工单2', remainingTime: '2', site: '北京市朝阳区建国路88号', status: '整改中' },
{ id: 3, name: '工单3', remainingTime: '3', site: '北京市朝阳区建国路88号', status: '待完工确认' },
{ id: 4, name: '工单4', remainingTime: '5', site: '北京市朝阳区建国路88号', status: '实施中' },
{ id: 5, name: '工单5', remainingTime: '3', site: '北京市朝阳区建国路88号', status: '待完工确认' },
{ id: 6, name: '工单6', remainingTime: '2', site: '北京市朝阳区建国路88号', status: '已完工' },
{ id: 7, name: '工单7', remainingTime: '4', site: '北京市朝阳区建国路88号', status: '已完工' },
])
//
const GoDetail = (id) => {
uni.navigateTo({
url: '/pages/ProgectDetails/index?id=' + id
})
}
</script>
<style lang="scss" scoped>
.FlexBox {
display: flex;
align-items: center;
justify-content: space-between;
}
.PageBox {
padding: 20rpx;
background-color: #fff;
height: calc(100vh - 170rpx);
.TopBox {
.SelectBox {
width: calc(50% - 10rpx);
height: 80rpx;
border-radius: 10rpx;
border: 1rpx solid #ccc;
display: flex;
align-items: center;
justify-content: center;
padding: 10rpx;
.u-select {
width: 100%;
}
}
.BtnBox {
width: 300rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.ListBox {
padding: 20rpx 0px;
margin-top: 20rpx;
height: calc(100vh - 300rpx);
overflow: hidden;
.CardBox {
width: calc(100% - 30rpx);
height: calc(100% - 30rpx);
margin: 0 auto;
padding: 20rpx;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08), 0 2rpx 4rpx rgba(0, 0, 0, 0.04);
margin-bottom: 20rpx;
background-color: #fff;
border-radius: 10rpx;
overflow: auto;
.Title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.DetailBtn {
font-size: 24rpx;
color: #666;
}
.CodeTxt {
margin-top: 20rpx;
font-size: 24rpx;
color: #666;
}
.TagBox {
margin-top: 20rpx;
}
.BtnList {
margin-top: 20rpx;
display: flex;
align-items: center;
justify-content: space-between;
gap: 20rpx;
}
}
}
}
</style>