ruoyi-geek-App/pages/template.vue

577 lines
12 KiB
Vue
Raw Normal View History

2025-11-24 14:57:53 +00:00
<template>
2025-11-25 06:26:23 +00:00
<view class="standard-query-container">
<!-- 查询条件区域 -->
<view class="query-section">
<uni-forms :modelValue="queryForm" label-position="top">
<view class="query-grid">
<!-- 标准号选择 -->
<uni-forms-item label="标准号" name="standardNumber" class="query-item">
<uni-data-select v-model="queryForm.standardNumber" :localdata="standardOptions"
placeholder="请选择标准号" :clear="true" />
</uni-forms-item>
<!-- 资料分类选择 -->
<uni-forms-item label="资料分类" name="category" class="query-item">
<uni-data-select v-model="queryForm.category" :localdata="categoryOptions" placeholder="请选择资料分类"
:clear="true" />
</uni-forms-item>
<!-- 资料类型选择 -->
<uni-forms-item label="资料类型" name="materialType" class="query-item">
<uni-data-select v-model="queryForm.materialType" :localdata="materialTypeOptions"
placeholder="请选择资料类型" :clear="true" />
</uni-forms-item>
<!-- 关键词搜索 -->
<uni-forms-item label="关键词" name="keywords" class="query-item">
<uni-easyinput v-model="queryForm.keywords" placeholder="请输入关键词搜索" :clearable="true" />
</uni-forms-item>
</view>
</uni-forms>
<!-- 查询按钮 -->
<view class="query-actions">
<button class="query-btn" @click="handleQuery">查询</button>
<button class="reset-btn" @click="handleReset">重置</button>
</view>
</view>
<!-- 查询结果区域 -->
<view class="result-section">
<!-- 结果统计 -->
<view class="result-header">
<text class="result-count">共找到 {{resultList.length}} 条记录</text>
</view>
<!-- 结果列表 -->
<view class="result-list">
<view v-for="item in resultList" :key="item.id" class="result-item" @click="handleItemClick(item)">
<view class="item-header">
<text class="item-title">{{item.title}}</text>
<text class="item-standard">{{item.standardNumber}}</text>
</view>
<view class="item-content">
<text class="item-category">{{item.category}} - {{item.materialType}}</text>
<text class="item-desc">{{item.description}}</text>
</view>
<!-- 图片预览 -->
<view v-if="item.images && item.images.length > 0" class="image-preview">
<image v-for="(img, index) in item.images.slice(0, 3)" :key="index" :src="img.thumbnail"
class="preview-img" mode="aspectFill" @click.stop="previewImage(item.images, index)" />
<text v-if="item.images.length > 3" class="more-count">+{{item.images.length - 3}}</text>
</view>
<!-- 表格预览 -->
<view v-if="item.tables && item.tables.length > 0" class="table-preview">
<text class="table-count">包含 {{item.tables.length}} 个表格</text>
</view>
<view class="item-footer">
<text class="item-tags">
<text v-for="tag in item.tags" :key="tag" class="tag">{{tag}}</text>
</text>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="resultList.length === 0" class="empty-state">
<image src="/static/empty.png" class="empty-img" mode="aspectFit"></image>
<text class="empty-text">暂无查询结果</text>
</view>
</view>
<!-- 图片预览模态框 -->
<uni-popup ref="imagePopup" type="center" background-color="#000">
<view class="image-popup">
<swiper :current="currentImageIndex" class="image-swiper" @change="onSwiperChange">
<swiper-item v-for="(img, index) in currentImages" :key="index">
<image :src="img.url" class="popup-image" mode="aspectFit"
@longpress="handleImageLongPress(img)" />
</swiper-item>
</swiper>
<view class="image-info">
<text class="image-index">{{currentImageIndex + 1}} / {{currentImages.length}}</text>
<text class="image-desc">{{currentImageDesc}}</text>
</view>
<view class="popup-actions">
<button class="close-btn" @click="closeImagePopup">关闭</button>
</view>
</view>
</uni-popup>
</view>
2025-11-24 14:57:53 +00:00
</template>
2025-11-25 06:26:23 +00:00
<script setup>
import {
ref,
reactive,
onMounted
} from 'vue'
// 查询表单数据
const queryForm = reactive({
standardNumber: '',
category: '',
materialType: '',
keywords: ''
})
// 选择器选项
const standardOptions = ref([{
value: 'GB 17820-2018',
text: 'GB 17820-2018 天然气'
},
{
value: 'GB 50028-2006',
text: 'GB 50028-2006 城镇燃气设计规范'
},
{
value: 'SY/T 5922-2012',
text: 'SY/T 5922-2012 天然气管道运行规范'
},
{
value: 'JJG 1030-2007',
text: 'JJG 1030-2007 超声流量计检定规程'
},
{
value: 'GB/T 18604-2014',
text: 'GB/T 18604-2014 用气体超声流量计测量天然气流量'
}
])
const categoryOptions = ref([{
value: 'standard',
text: '标准规范'
},
{
value: 'regulation',
text: '规程规范'
},
{
value: 'safety',
text: '安全资料'
},
{
value: 'technical',
text: '技术手册'
},
{
value: 'calculation',
text: '计算图表'
}
])
const materialTypeOptions = ref([{
value: 'image',
text: '图片资料'
},
{
value: 'table',
text: '表格数据'
},
{
value: 'chart',
text: '图表曲线'
},
{
value: 'formula',
text: '计算公式'
}
])
// 查询结果列表
const resultList = ref([{
id: 1,
title: '天然气组分与热值关系图表',
standardNumber: 'GB 17820-2018',
category: 'calculation',
materialType: 'chart',
description: '展示不同天然气组分与热值之间的对应关系曲线',
images: [{
url: '/static/charts/heat-value-chart.jpg',
2025-11-26 15:41:57 +00:00
thumbnail: '',
2025-11-25 06:26:23 +00:00
description: '热值关系图表'
}],
tables: [],
tags: ['热值', '组分', '计算']
},
{
id: 2,
title: '管道流量计算参数表',
standardNumber: 'SY/T 5922-2012',
category: 'technical',
materialType: 'table',
description: '不同管径和压力下的流量计算参数参考表',
images: [],
tables: [{
title: '流量参数表',
data: []
}],
tags: ['流量', '管径', '计算']
}
])
// 图片预览相关
const imagePopup = ref(null)
const currentImages = ref([])
const currentImageIndex = ref(0)
const currentImageDesc = ref('')
// 查询操作
const handleQuery = () => {
// 模拟查询逻辑
console.log('执行查询:', queryForm)
// 实际开发中这里应该是API调用
}
const handleReset = () => {
Object.keys(queryForm).forEach(key => {
queryForm[key] = ''
})
}
// 点击结果项
const handleItemClick = (item) => {
console.log('点击项目:', item)
// 跳转到详情页或执行其他操作
uni.navigateTo({
url: `/pages/material/detail?id=${item.id}`
})
}
// 图片预览
const previewImage = (images, index) => {
currentImages.value = images
currentImageIndex.value = index
currentImageDesc.value = images[index]?.description || ''
imagePopup.value.open()
}
const onSwiperChange = (e) => {
currentImageIndex.value = e.detail.current
currentImageDesc.value = currentImages.value[currentImageIndex.value]?.description || ''
}
const closeImagePopup = () => {
imagePopup.value.close()
}
const handleImageLongPress = (img) => {
uni.showActionSheet({
itemList: ['保存图片', '分享'],
success: (res) => {
if (res.tapIndex === 0) {
// 保存图片逻辑
uni.saveImageToPhotosAlbum({
filePath: img.url,
success: () => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
}
})
}
}
})
}
onMounted(() => {
// 初始化数据
console.log('页面加载完成')
})
</script>
2025-11-24 14:57:53 +00:00
<style lang="scss" scoped>
2025-11-25 06:26:23 +00:00
.standard-query-container {
padding: 20rpx;
background-color: #f8f8f8;
min-height: 100vh;
box-sizing: border-box;
}
/* 查询区域样式 */
.query-section {
background-color: #ffffff;
border-radius: 12rpx;
padding: 24rpx;
margin-bottom: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}
.query-grid {
display: grid;
gap: 24rpx;
width: 100%;
}
.query-item {
margin-bottom: 0;
width: 100%;
}
.query-actions {
display: flex;
gap: 20rpx;
margin-top: 24rpx;
.query-btn,
.reset-btn {
flex: 1;
height: 80rpx;
line-height: 80rpx;
border-radius: 8rpx;
font-size: 28rpx;
&::after {
border: none;
}
}
.query-btn {
background-color: #007aff;
color: #ffffff;
}
.reset-btn {
background-color: #f0f0f0;
color: #333333;
}
}
/* 结果区域样式 */
.result-section {
background-color: #ffffff;
border-radius: 12rpx;
padding: 24rpx;
box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
}
.result-header {
margin-bottom: 24rpx;
.result-count {
font-size: 26rpx;
color: #666666;
}
}
.result-list {
display: flex;
flex-direction: column;
gap: 24rpx;
}
.result-item {
border: 1rpx solid #e0e0e0;
border-radius: 12rpx;
padding: 24rpx;
background-color: #fafafa;
.item-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 16rpx;
.item-title {
font-size: 30rpx;
font-weight: 600;
color: #333333;
flex: 1;
margin-right: 20rpx;
}
.item-standard {
font-size: 24rpx;
color: #007aff;
background-color: #e6f3ff;
padding: 4rpx 12rpx;
border-radius: 6rpx;
}
}
.item-content {
margin-bottom: 20rpx;
.item-category {
display: block;
font-size: 24rpx;
color: #666666;
margin-bottom: 8rpx;
}
.item-desc {
font-size: 26rpx;
color: #333333;
line-height: 1.5;
}
}
.image-preview {
display: flex;
gap: 12rpx;
margin-bottom: 16rpx;
.preview-img {
width: 120rpx;
height: 120rpx;
border-radius: 6rpx;
}
.more-count {
width: 120rpx;
height: 120rpx;
background-color: #f0f0f0;
border-radius: 6rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 24rpx;
color: #666666;
}
}
.table-preview {
margin-bottom: 16rpx;
.table-count {
font-size: 24rpx;
color: #666666;
background-color: #f0f0f0;
padding: 8rpx 16rpx;
border-radius: 6rpx;
}
}
.item-footer {
.item-tags {
display: flex;
flex-wrap: wrap;
gap: 12rpx;
.tag {
font-size: 22rpx;
color: #007aff;
background-color: #e6f3ff;
padding: 4rpx 12rpx;
border-radius: 20rpx;
}
}
}
}
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
padding: 80rpx 0;
.empty-img {
width: 200rpx;
height: 200rpx;
margin-bottom: 24rpx;
}
.empty-text {
font-size: 28rpx;
color: #999999;
}
}
/* 图片预览弹窗样式 */
.image-popup {
width: 90vw;
height: 80vh;
background-color: #000000;
border-radius: 12rpx;
overflow: hidden;
display: flex;
flex-direction: column;
.image-swiper {
flex: 1;
height: 60vh;
.popup-image {
width: 100%;
height: 100%;
}
}
.image-info {
padding: 20rpx;
background-color: rgba(0, 0, 0, 0.7);
.image-index {
font-size: 26rpx;
color: #ffffff;
margin-right: 20rpx;
}
.image-desc {
font-size: 26rpx;
color: #cccccc;
}
}
.popup-actions {
padding: 20rpx;
.close-btn {
background-color: #333333;
color: #ffffff;
height: 80rpx;
line-height: 80rpx;
border-radius: 8rpx;
&::after {
border: none;
}
}
}
}
/* 响应式布局 */
@media screen and (max-width: 768px) {
.query-grid {
grid-template-columns: 1fr;
}
}
@media screen and (min-width: 768px) {
.query-grid {
grid-template-columns: repeat(2, 1fr);
}
}
/* 表单元素深度样式 */
:deep(.uni-forms-item) {
margin-bottom: 0 !important;
}
:deep(.uni-forms-item__label) {
font-size: 26rpx;
color: #333333;
margin-bottom: 8rpx;
font-weight: 500;
}
:deep(.uni-data-select__input),
:deep(.uni-easyinput__content) {
width: 100%;
min-height: 80rpx;
box-sizing: border-box;
}
:deep(.uni-input-input),
:deep(.uni-easyinput__content input) {
font-size: 28rpx;
padding: 0 20rpx;
height: 80rpx;
line-height: 80rpx;
}
2025-11-24 14:57:53 +00:00
</style>