修改完善首页,消除bug

This commit is contained in:
liaodeyun 2025-11-25 10:51:26 +08:00
parent e4fe05035c
commit 00ad605bc2
10 changed files with 1399 additions and 1090 deletions

64
App.vue
View File

@ -5,6 +5,7 @@
import {
listConvert
} from '@/api/system/unitConverter/sysUnitConverter.js';
const queryParams = ref({
pageNum: 1,
pageSize: 1000,
@ -16,8 +17,14 @@
status: null,
unitOrder: null
});
//
const groupByUnitType = (data) => {
if (!data || !Array.isArray(data)) {
console.warn('groupByUnitType: 数据为空或不是数组');
return {};
}
return data.reduce((acc, unit) => {
const type = unit.unitType;
if (!acc[type]) acc[type] = [];
@ -34,44 +41,65 @@
return acc;
}, {});
};
const getList = async () => {
try {
console.log('开始请求单位数据...');
const response = await listConvert(queryParams.value);
console.log('API响应:', response);
if (!response || !response.rows) {
console.error('API响应格式错误');
return;
}
if (response.rows.length === 0) {
console.warn('单位数据为空数组');
return;
}
const unitDataGrouped = groupByUnitType(response.rows);
console.log('开始缓存' + unitDataGrouped);
console.log('分组后的单位数据:', unitDataGrouped);
// #ifdef APP || APP-PLUS
uni.setStorageSync({
key: 'unitData',
data: unitDataGrouped,
success: function() {
console.log('缓存成功');
}
});
try {
// 使
uni.setStorageSync('unitData', unitDataGrouped);
console.log('APP端缓存成功');
//
const verifyData = uni.getStorageSync('unitData');
console.log('APP缓存验证:', verifyData ? '成功' : '失败', verifyData);
} catch (storageError) {
console.error('APP缓存设置失败:', storageError);
}
// #endif
// #ifdef H5
localStorage.setItem('unitData', JSON.stringify(unitDataGrouped))
try {
localStorage.setItem('unitData', JSON.stringify(unitDataGrouped));
console.log('H5端缓存成功');
} catch (storageError) {
console.error('H5缓存设置失败:', storageError);
}
// #endif
} catch (error) {
console.error('获取单位数据失败:', error);
console.error('获取单位数据失败:', error);
}
};
export default {
onLaunch: function() {
console.log('App Launch - 开始初始化');
getList();
console.log('App Launch')
},
onShow: function() {
console.log('App Show')
console.log('App Show');
},
onHide: function() {
console.log('App Hide')
},
console.log('App Hide');
}
}
</script>

View File

@ -1,123 +1,123 @@
<template>
<view class="confirm-dialog" v-if="visible">
<view class="dialog-mask"></view>
<view class="dialog-content">
<view class="dialog-header">提示</view>
<view class="dialog-title">{{ title }}</view>
<view class="dialog-buttons">
<button class="button cancel-btn" @click="handleCancel" hover-class="button-hover">{{ cancelText
<view class="confirm-dialog" v-if="visible">
<view class="dialog-mask"></view>
<view class="dialog-content">
<view class="dialog-header">提示</view>
<view class="dialog-title">{{ title }}</view>
<view class="dialog-buttons">
<button class="button cancel-btn" @click="handleCancel" hover-class="button-hover">{{ cancelText
}}</button>
<button class="button confirm-btn" @click="handleConfirm" hover-class="button-hover"
:style="{ background: color }">{{ confirmText }}</button>
</view>
</view>
</view>
<button class="button confirm-btn" @click="handleConfirm" hover-class="button-hover"
:style="{ background: color }">{{ confirmText }}</button>
</view>
</view>
</view>
</template>
<script setup>
import { defineProps, defineEmits } from 'vue'
// import { defineProps, defineEmits } from 'vue'
const props = defineProps({
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: '提示'
},
cancelText: {
type: String,
default: '取消'
},
confirmText: {
type: String,
default: '确认'
},
color: {
type: String,
default: '#1E88E5'
}
})
const emit = defineEmits(['update:visible', 'confirm', 'cancel']);
const handleConfirm = () => {
emit('update:visible', false);
emit('confirm')
}
const props = defineProps({
visible: {
type: Boolean,
default: false
},
title: {
type: String,
default: '提示'
},
cancelText: {
type: String,
default: '取消'
},
confirmText: {
type: String,
default: '确认'
},
color: {
type: String,
default: '#1E88E5'
}
})
const emit = defineEmits(['update:visible', 'confirm', 'cancel']);
const handleConfirm = () => {
emit('update:visible', false);
emit('confirm')
}
const handleCancel = () => {
emit('cancel')
emit('update:visible', false);
}
const handleCancel = () => {
emit('cancel')
emit('update:visible', false);
}
</script>
<style lang="scss" scoped>
.confirm-dialog {
.dialog-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
z-index: 999;
}
.confirm-dialog {
.dialog-mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.4);
z-index: 999;
}
.dialog-content {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 280px;
background: #FFFFFF;
border-radius: 12px;
z-index: 1000;
.dialog-content {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 280px;
background: #FFFFFF;
border-radius: 12px;
z-index: 1000;
.dialog-header {
padding: 10px;
text-align: center;
font-size: 16px;
color: #333;
}
.dialog-header {
padding: 10px;
text-align: center;
font-size: 16px;
color: #333;
}
.dialog-title {
padding: 10px 20px 20px 20px;
text-align: center;
font-size: 16px;
color: #333;
line-height: 1.4;
}
.dialog-title {
padding: 10px 20px 20px 20px;
text-align: center;
font-size: 16px;
color: #333;
line-height: 1.4;
}
.dialog-buttons {
display: flex;
justify-content: space-between;
padding: 20rpx;
gap: 20rpx;
margin-bottom: 20rpx;
.dialog-buttons {
display: flex;
justify-content: space-between;
padding: 20rpx;
gap: 20rpx;
margin-bottom: 20rpx;
.button {
flex: 1;
height: 80rpx;
line-height: 80rpx;
text-align: center;
font-size: 32rpx;
border-radius: 8rpx;
border: none;
.button {
flex: 1;
height: 80rpx;
line-height: 80rpx;
text-align: center;
font-size: 32rpx;
border-radius: 8rpx;
border: none;
&.button-hover {
opacity: 0.8;
}
}
&.button-hover {
opacity: 0.8;
}
}
.cancel-btn {
background: #F5F5F5;
color: #333333;
}
.cancel-btn {
background: #F5F5F5;
color: #333333;
}
.confirm-btn {
color: #FFFFFF;
}
}
}
}
.confirm-btn {
color: #FFFFFF;
}
}
}
}
</style>

View File

@ -1,270 +1,274 @@
<template>
<view class="upload-box">
<view>
<view class="upload-container" v-if="!videoCover" @click="chooseVideo">
<uni-icons type="cloud-upload-filled" size="60" color="#ff6634"></uni-icons>
<text class="upload-text">{{ uploadText }}</text>
<text class="upload-desc">{{ displayUploadDesc }}</text>
</view>
<view v-else class="video-preview">
<view class="cover-container">
<view class="icon-cuo" @tap.stop="delectVideo">
<uni-icons type="close" size="16" color="#ffffff"></uni-icons>
</view>
<video :src="videoCover" class="video-cover" />
</view>
</view>
</view>
</view>
<ConfirmDialog v-model:visible="showModal" title="是否要删除此视频" @confirm="confirmDelete" />
<view class="upload-box">
<view>
<view class="upload-container" v-if="!videoCover" @click="chooseVideo">
<uni-icons type="cloud-upload-filled" size="60" color="#ff6634"></uni-icons>
<text class="upload-text">{{ uploadText }}</text>
<text class="upload-desc">{{ displayUploadDesc }}</text>
</view>
<view v-else class="video-preview">
<view class="cover-container">
<view class="icon-cuo" @tap.stop="delectVideo">
<uni-icons type="close" size="16" color="#ffffff"></uni-icons>
</view>
<video :src="videoCover" class="video-cover" />
</view>
</view>
</view>
</view>
<ConfirmDialog v-model:visible="showModal" title="是否要删除此视频" @confirm="confirmDelete" />
</template>
<script setup>
import { ref, watch, computed } from 'vue'
import { defineProps, defineEmits } from 'vue'
import modal from '@/plugins/modal';
import ConfirmDialog from '@/components/geek-xd/components/geek-confirm-dialog/geek-confirm-dialog.vue'
import {
ref,
watch,
computed
} from 'vue'
// import { defineProps, defineEmits } from 'vue'
import modal from '@/plugins/modal';
import ConfirmDialog from '@/components/geek-xd/components/geek-confirm-dialog/geek-confirm-dialog.vue'
const props = defineProps({
uploadText: {
type: String,
default: '点击上传视频文件'
},
uploadDesc: {
type: String,
default: ''
},
sourceType: {
type: Array,
default: () => ['album', 'camera']
},
maxSize: {
type: Number,
default: 500 // 500M
},
supportedTypes: {
type: Array,
default: () => ['mp4', 'mov', 'avi'] //
}
})
const props = defineProps({
uploadText: {
type: String,
default: '点击上传视频文件'
},
uploadDesc: {
type: String,
default: ''
},
sourceType: {
type: Array,
default: () => ['album', 'camera']
},
maxSize: {
type: Number,
default: 500 // 500M
},
supportedTypes: {
type: Array,
default: () => ['mp4', 'mov', 'avi'] //
}
})
const emit = defineEmits(['upload', 'delete'])
const emit = defineEmits(['upload', 'delete'])
const videoCover = ref('')
const showModal = ref(false)
const videoCover = ref('')
const showModal = ref(false)
/**
* 动态生成上传描述文本
* 如果用户提供了自定义描述则使用否则根据支持的格式和文件大小限制自动生成
* @returns {string} 上传描述文本
*/
const displayUploadDesc = computed(() => {
return props.uploadDesc || `支持${props.supportedTypes.join('/')}等格式,文件大小不超过${props.maxSize}M`
})
/**
* 动态生成上传描述文本
* 如果用户提供了自定义描述则使用否则根据支持的格式和文件大小限制自动生成
* @returns {string} 上传描述文本
*/
const displayUploadDesc = computed(() => {
return props.uploadDesc || `支持${props.supportedTypes.join('/')}等格式,文件大小不超过${props.maxSize}M`
})
/**
* 删除视频处理函数
* 阻止事件冒泡并显示确认删除对话框
* @param {Event} event - 点击事件对象
*/
const delectVideo = (event) => {
event.stopPropagation();
showModal.value = true;
}
/**
* 删除视频处理函数
* 阻止事件冒泡并显示确认删除对话框
* @param {Event} event - 点击事件对象
*/
const delectVideo = (event) => {
event.stopPropagation();
showModal.value = true;
}
/**
* 确认删除视频
* 关闭确认对话框清空视频封面并触发删除事件
*/
const confirmDelete = () => {
showModal.value = false
videoCover.value = null
emit('delete')
}
/**
* 确认删除视频
* 关闭确认对话框清空视频封面并触发删除事件
*/
const confirmDelete = () => {
showModal.value = false
videoCover.value = null
emit('delete')
}
/**
* 从文件路径中提取文件扩展名
* @param {string} filePath - 文件路径
* @returns {string} 文件扩展名小写如果没有扩展名则返回空字符串
*/
const getFileExtension = (filePath) => {
if (!filePath) {
return '';
}
const dotIndex = filePath.lastIndexOf('.');
if (dotIndex === -1) {
return '';
}
return filePath.substring(dotIndex + 1).toLowerCase();
}
/**
* 从文件路径中提取文件扩展名
* @param {string} filePath - 文件路径
* @returns {string} 文件扩展名小写如果没有扩展名则返回空字符串
*/
const getFileExtension = (filePath) => {
if (!filePath) {
return '';
}
const dotIndex = filePath.lastIndexOf('.');
if (dotIndex === -1) {
return '';
}
return filePath.substring(dotIndex + 1).toLowerCase();
}
/**
* 验证视频文件类型是否符合支持的格式
* 统一的跨平台文件类型验证
* @param {string} filePath - 视频文件路径
* @returns {boolean} 验证通过返回true否则返回false
*/
const validateVideoFileType = (filePath) => {
if (!filePath) {
modal.msg('无法识别文件类型');
return false;
}
/**
* 验证视频文件类型是否符合支持的格式
* 统一的跨平台文件类型验证
* @param {string} filePath - 视频文件路径
* @returns {boolean} 验证通过返回true否则返回false
*/
const validateVideoFileType = (filePath) => {
if (!filePath) {
modal.msg('无法识别文件类型');
return false;
}
const fileExtension = getFileExtension(filePath);
console.log('文件类型:', fileExtension);
const fileExtension = getFileExtension(filePath);
console.log('文件类型:', fileExtension);
if (props.supportedTypes.includes(fileExtension)) return true;
if (props.supportedTypes.includes(fileExtension)) return true;
modal.msg(`请上传正确格式的视频`);
return false;
}
modal.msg(`请上传正确格式的视频`);
return false;
}
/**
* 检查视频文件大小是否超过限制
* @param {number} fileSize - 文件大小字节
* @returns {boolean} 文件大小符合要求返回true否则返回false
*/
const checkVideoFileSize = (fileSize) => {
const maxSize = props.maxSize * 1024 * 1024;
if (fileSize <= maxSize) return true;
modal.msg(`视频大小不能超过${props.maxSize}M`);
return false;
}
/**
* 检查视频文件大小是否超过限制
* @param {number} fileSize - 文件大小字节
* @returns {boolean} 文件大小符合要求返回true否则返回false
*/
const checkVideoFileSize = (fileSize) => {
const maxSize = props.maxSize * 1024 * 1024;
if (fileSize <= maxSize) return true;
modal.msg(`视频大小不能超过${props.maxSize}M`);
return false;
}
/**
* 组装视频数据对象
* 根据不同平台返回不同格式的视频数据
* @param {Object} res - uni.chooseVideo返回的结果对象
* @returns {Object} 组装后的视频数据对象
*/
const buildVideoData = (res) => {
let videoData = {}
console.log('选择的视频文件:', res);
/**
* 组装视频数据对象
* 根据不同平台返回不同格式的视频数据
* @param {Object} res - uni.chooseVideo返回的结果对象
* @returns {Object} 组装后的视频数据对象
*/
const buildVideoData = (res) => {
let videoData = {}
console.log('选择的视频文件:', res);
// #ifdef APP-PLUS || H5
videoData = {
path: res.tempFilePath,
size: res.size,
}
// #endif
// #ifdef APP-PLUS || H5
videoData = {
path: res.tempFilePath,
size: res.size,
}
// #endif
// #ifdef MP-WEIXIN
videoData = {
path: res.tempFilePath,
size:res.size
}
// #endif
// #ifdef MP-WEIXIN
videoData = {
path: res.tempFilePath,
size: res.size
}
// #endif
console.log('组装后的视频数据:', videoData);
console.log('组装后的视频数据:', videoData);
return videoData;
}
return videoData;
}
/**
* 选择视频文件
* 调用uni-app的chooseVideo API选择视频文件
* 包含文件类型验证大小验证和数据处理
*/
const chooseVideo = () => {
uni.chooseVideo({
count: 1,
compressed: false,
sourceType: props.sourceType,
success: (res) => {
if (!validateVideoFileType(res.tempFilePath)) return;
if (!checkVideoFileSize(res.size)) return;
videoCover.value = res.tempFilePath
const videoData = buildVideoData(res)
setTimeout(() => {
modal.msgSuccess('上传成功')
emit('upload', videoData)
}, 1000)
},
fail: (err) => {
modal.msg('选择视频失败')
}
})
}
/**
* 选择视频文件
* 调用uni-app的chooseVideo API选择视频文件
* 包含文件类型验证大小验证和数据处理
*/
const chooseVideo = () => {
uni.chooseVideo({
count: 1,
compressed: false,
sourceType: props.sourceType,
success: (res) => {
if (!validateVideoFileType(res.tempFilePath)) return;
if (!checkVideoFileSize(res.size)) return;
videoCover.value = res.tempFilePath
const videoData = buildVideoData(res)
setTimeout(() => {
modal.msgSuccess('上传成功')
emit('upload', videoData)
}, 1000)
},
fail: (err) => {
modal.msg('选择视频失败')
}
})
}
</script>
<style lang="scss" scoped>
.upload-box {
height: 350rpx;
margin: 0 20rpx;
background: #FFFCFA;
border: 2rpx dashed #ff6634;
border-radius: 8rpx;
padding: 40rpx 0;
text-align: center;
margin-bottom: 30rpx;
margin-top: 20rpx;
.upload-box {
height: 350rpx;
margin: 0 20rpx;
background: #FFFCFA;
border: 2rpx dashed #ff6634;
border-radius: 8rpx;
padding: 40rpx 0;
text-align: center;
margin-bottom: 30rpx;
margin-top: 20rpx;
.upload-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
cursor: pointer;
}
.upload-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100%;
cursor: pointer;
}
.upload-text {
display: block;
font-size: 28rpx;
color: #ff6634;
margin-bottom: 10rpx;
}
.upload-text {
display: block;
font-size: 28rpx;
color: #ff6634;
margin-bottom: 10rpx;
}
.upload-desc {
display: block;
font-size: 24rpx;
color: #999;
}
.upload-desc {
display: block;
font-size: 24rpx;
color: #999;
}
.video-preview {
position: relative;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.video-preview {
position: relative;
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.cover-container {
position: relative;
width: 80%;
height: 100%;
.cover-container {
position: relative;
width: 80%;
height: 100%;
.icon-cuo {
position: absolute;
top: -20rpx;
right: -30rpx;
width: 44rpx;
height: 44rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
border-radius: 50%;
z-index: 10;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
transition: all 0.2s ease;
.icon-cuo {
position: absolute;
top: -20rpx;
right: -30rpx;
width: 44rpx;
height: 44rpx;
display: flex;
align-items: center;
justify-content: center;
background-color: rgba(0, 0, 0, 0.7);
color: #fff;
border-radius: 50%;
z-index: 10;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.3);
transition: all 0.2s ease;
&:active {
transform: scale(0.9);
background-color: #ff4d4f;
}
}
&:active {
transform: scale(0.9);
background-color: #ff4d4f;
}
}
.video-cover {
width: 100%;
height: 220rpx;
border-radius: 8rpx;
object-fit: cover;
}
}
}
}
.video-cover {
width: 100%;
height: 220rpx;
border-radius: 8rpx;
object-fit: cover;
}
}
}
}
</style>

View File

@ -1,298 +1,296 @@
{
"easycom": {
"custom": {
"u-city-select": "@/components/u-city-select/u-city-select.vue",
"geek-(.*)": "@/components/geek-xd/components/geek-$1/geek-$1.vue",
"gx-(.*)": "@/components/geek-xd/components/geek-$1/geek-$1.vue",
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
"qiun-(.*)": "@/components/qiun-data-charts/components/qiun-$1/qiun-$1.vue"
}
},
"pages": [
{
"path": "pages/index",
"style": {
"navigationBarTitleText": "天然气工具集",
"navigationStyle": "custom"
}
},
{
"path": "pages/login",
"style": {
"navigationBarTitleText": "登录"
}
},
{
"path": "pages/work",
"style": {
"navigationBarTitleText": "工作台"
}
},
{
"path": "pages/template",
"style": {
"navigationBarTitleText": "模板"
}
},
{
"path": "pages/mine",
"style": {
"navigationBarTitleText": "我的"
}
},
{
"path": "pages/common/webview/index",
"style": {
"navigationBarTitleText": "浏览网页"
}
},
{
"path": "pages/common/textview/index",
"style": {
"navigationBarTitleText": "浏览文本"
}
}
],
"subPackages": [
{
"root": "pages_mine/pages",
"pages": [
{
"path": "avatar/index",
"style": {
"navigationBarTitleText": "修改头像"
}
},
{
"path": "info/index",
"style": {
"navigationBarTitleText": "个人信息"
}
},
{
"path": "info/edit",
"style": {
"navigationBarTitleText": "编辑资料"
}
},
{
"path": "pwd/index",
"style": {
"navigationBarTitleText": "修改密码"
}
},
{
"path": "setting/index",
"style": {
"navigationBarTitleText": "应用设置"
}
},
{
"path": "help/index",
"style": {
"navigationBarTitleText": "常见问题"
}
},
{
"path": "about/index",
"style": {
"navigationBarTitleText": "关于我们"
}
}
]
},
{
"root": "pages_template/pages",
"pages": [
{
"path": "wxCenter/index",
"style": {
"navigationBarTitleText": "wxCenter 仿微信个人中心",
"navigationStyle": "custom"
}
},
{
"path": "keyboardPay/index",
"style": {
"navigationBarTitleText": "keyboardPay 自定义键盘支付"
}
},
{
"path": "mallMenu/index2",
"style": {
"navigationBarTitleText": "mallMenu-商城分类"
}
},
{
"path": "mallMenu/index1",
"style": {
"navigationBarTitleText": "mallMenu-商城分类"
}
},
{
"path": "coupon/index",
"style": {
"navigationBarTitleText": "coupon-优惠券"
}
},
{
"path": "login/index1",
"style": {
"navigationBarTitleText": "美团登录"
}
},
{
"path": "login/index2",
"style": {
"navigationBarTitleText": "水滴登录"
}
},
{
"path": "citySelect/index",
"style": {
"navigationBarTitleText": "城市选择"
}
},
{
"path": "submitBar/index",
"style": {
"navigationBarTitleText": "提交订单栏"
}
},
{
"path": "comment/index",
"style": {
"navigationBarTitleText": "评论"
}
},
{
"path": "comment/reply",
"style": {
"navigationBarTitleText": "评论详情"
}
},
{
"path": "order/index",
"style": {
"navigationBarTitleText": "订单"
}
},
{
"path": "login/code",
"style": {
"navigationBarTitleText": "登录获取验证码"
}
},
{
"path": "address/index",
"style": {
"navigationBarTitleText": "用户地址"
}
},
{
"path": "address/addSite",
"style": {
"navigationBarTitleText": "添加用户地址"
}
}
]
},
{
"root": "pages_qiun/pages",
"pages": [
{
"path": "sport/index",
"style": {
"pageOrientation": "auto"
}
},
{
"path": "school/index",
"style": {
"pageOrientation": "auto"
}
},
{
"path": "finance/index",
"style": {
"pageOrientation": "auto"
}
},
{
"path": "main/index",
"style": {
"pageOrientation": "auto"
}
}
]
},
{
"root": "pages_geek/pages",
"pages": [
{
"path": "index/index"
},
{
"path": "code/index"
},
{
"path": "upload/index"
}
]
},
{
"root": "pages_caltools/pages",
"pages": [
{
"path": "index"
},
{
"path": "main"
}
]
"easycom": {
"custom": {
"u-city-select": "@/components/u-city-select/u-city-select.vue",
"geek-(.*)": "@/components/geek-xd/components/geek-$1/geek-$1.vue",
"gx-(.*)": "@/components/geek-xd/components/geek-$1/geek-$1.vue",
"^u--(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^up-(.*)": "uview-plus/components/u-$1/u-$1.vue",
"^u-([^-].*)": "uview-plus/components/u-$1/u-$1.vue",
"qiun-(.*)": "@/components/qiun-data-charts/components/qiun-$1/qiun-$1.vue"
}
},
"pages": [{
"path": "pages/index",
"style": {
"navigationBarTitleText": "天然气工具集",
"navigationStyle": "custom"
}
},
{
"path": "pages/login",
"style": {
"navigationBarTitleText": "登录"
}
},
{
"path": "pages/work",
"style": {
"navigationBarTitleText": "工作台"
}
},
{
"path": "pages/template",
"style": {
"navigationBarTitleText": "模板"
}
},
{
"path": "pages/mine",
"style": {
"navigationBarTitleText": "我的"
}
},
{
"path": "pages/common/webview/index",
"style": {
"navigationBarTitleText": "浏览网页"
}
},
{
"path": "pages/common/textview/index",
"style": {
"navigationBarTitleText": "浏览文本"
}
}
],
"subPackages": [{
"root": "pages_mine/pages",
"pages": [{
"path": "register/index",
"style": {
"navigationBarTitleText": "注册"
}
},
{
"path": "avatar/index",
"style": {
"navigationBarTitleText": "修改头像"
}
},
{
"path": "info/index",
"style": {
"navigationBarTitleText": "个人信息"
}
},
{
"path": "info/edit",
"style": {
"navigationBarTitleText": "编辑资料"
}
},
{
"path": "pwd/index",
"style": {
"navigationBarTitleText": "修改密码"
}
},
{
"path": "setting/index",
"style": {
"navigationBarTitleText": "应用设置"
}
},
{
"path": "help/index",
"style": {
"navigationBarTitleText": "常见问题"
}
},
{
"path": "about/index",
"style": {
"navigationBarTitleText": "关于我们"
}
}
]
},
{
"root": "pages_template/pages",
"pages": [{
"path": "wxCenter/index",
"style": {
"navigationBarTitleText": "wxCenter 仿微信个人中心",
"navigationStyle": "custom"
}
},
{
"path": "keyboardPay/index",
"style": {
"navigationBarTitleText": "keyboardPay 自定义键盘支付"
}
},
{
"path": "mallMenu/index2",
"style": {
"navigationBarTitleText": "mallMenu-商城分类"
}
},
{
"path": "mallMenu/index1",
"style": {
"navigationBarTitleText": "mallMenu-商城分类"
}
},
{
"path": "coupon/index",
"style": {
"navigationBarTitleText": "coupon-优惠券"
}
},
{
"path": "login/index1",
"style": {
"navigationBarTitleText": "美团登录"
}
},
{
"path": "login/index2",
"style": {
"navigationBarTitleText": "水滴登录"
}
},
{
"path": "citySelect/index",
"style": {
"navigationBarTitleText": "城市选择"
}
},
{
"path": "submitBar/index",
"style": {
"navigationBarTitleText": "提交订单栏"
}
},
{
"path": "comment/index",
"style": {
"navigationBarTitleText": "评论"
}
},
{
"path": "comment/reply",
"style": {
"navigationBarTitleText": "评论详情"
}
},
{
"path": "order/index",
"style": {
"navigationBarTitleText": "订单"
}
},
{
"path": "login/code",
"style": {
"navigationBarTitleText": "登录获取验证码"
}
},
{
"path": "address/index",
"style": {
"navigationBarTitleText": "用户地址"
}
},
{
"path": "address/addSite",
"style": {
"navigationBarTitleText": "添加用户地址"
}
}
]
},
{
"root": "pages_qiun/pages",
"pages": [{
"path": "sport/index",
"style": {
"pageOrientation": "auto"
}
},
{
"path": "school/index",
"style": {
"pageOrientation": "auto"
}
},
{
"path": "finance/index",
"style": {
"pageOrientation": "auto"
}
},
{
"path": "main/index",
"style": {
"pageOrientation": "auto"
}
}
]
},
{
"root": "pages_geek/pages",
"pages": [{
"path": "index/index"
},
{
"path": "code/index"
},
{
"path": "upload/index"
}
]
},
{
"root": "pages_caltools/pages",
"pages": [{
"path": "index"
},
{
"path": "main"
}
]
}
],
"tabBar": {
"color": "#000000",
"selectedColor": "#000000",
"borderStyle": "white",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/index",
"iconPath": "static/images/tabbar/home.png",
"selectedIconPath": "static/images/tabbar/home_.png",
"text": "首页"
},
{
"pagePath": "pages/work",
"iconPath": "static/images/tabbar/work.png",
"selectedIconPath": "static/images/tabbar/work_.png",
"text": "计算"
},
{
"pagePath": "pages/template",
"iconPath": "static/images/tabbar/work.png",
"selectedIconPath": "static/images/tabbar/work_.png",
"text": "资料"
},
{
"pagePath": "pages/mine",
"iconPath": "static/images/tabbar/mine.png",
"selectedIconPath": "static/images/tabbar/mine_.png",
"text": "我的"
}
]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "RuoYi",
"navigationBarBackgroundColor": "#FFFFFF"
}
],
"tabBar": {
"color": "#000000",
"selectedColor": "#000000",
"borderStyle": "white",
"backgroundColor": "#ffffff",
"list": [
{
"pagePath": "pages/index",
"iconPath": "static/images/tabbar/home.png",
"selectedIconPath": "static/images/tabbar/home_.png",
"text": "首页"
},
{
"pagePath": "pages/work",
"iconPath": "static/images/tabbar/work.png",
"selectedIconPath": "static/images/tabbar/work_.png",
"text": "工作台"
},
{
"pagePath": "pages/template",
"iconPath": "static/images/tabbar/work.png",
"selectedIconPath": "static/images/tabbar/work_.png",
"text": "模板"
},
{
"pagePath": "pages/mine",
"iconPath": "static/images/tabbar/mine.png",
"selectedIconPath": "static/images/tabbar/mine_.png",
"text": "我的"
}
]
},
"globalStyle": {
"navigationBarTextStyle": "black",
"navigationBarTitleText": "RuoYi",
"navigationBarBackgroundColor": "#FFFFFF"
}
}
}

View File

@ -1,50 +1,179 @@
<template>
<view class="content">
<image class="logo" src="@/static/logo.png"></image>
<view class="text-area">
<text class="title"> 天然气工具集</text>
</view>
<NG-cal-tools></NG-cal-tools>
</view>
<view class="work-container">
<!-- 轮播图 -->
<uni-swiper-dot class="uni-swiper-dot-box" :info="data" :current="current" field="content">
<swiper class="swiper-box" :current="swiperDotIndex" @change="changeSwiper">
<swiper-item v-for="(item, index) in data" :key="index">
<view class="swiper-item" @click="clickBannerItem(item)">
<image :src="item.image" mode="aspectFill" :draggable="false" />
</view>
</swiper-item>
</swiper>
</uni-swiper-dot>
<!-- 宫格组件 -->
<uni-section title="系统管理" type="line"></uni-section>
<view class="grid-body">
<uni-grid :column="4" :showBorder="false" @change="changeGrid">
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="person-filled" size="30"></uni-icons>
<text class="text">用户管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="staff-filled" size="30"></uni-icons>
<text class="text">角色管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="color" size="30"></uni-icons>
<text class="text">菜单管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="settings-filled" size="30"></uni-icons>
<text class="text">部门管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="heart-filled" size="30"></uni-icons>
<text class="text">岗位管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="bars" size="30"></uni-icons>
<text class="text">字典管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="gear-filled" size="30"></uni-icons>
<text class="text">参数设置</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="chat-filled" size="30"></uni-icons>
<text class="text">通知公告</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="wallet-filled" size="30"></uni-icons>
<text class="text">日志管理</text>
</view>
</uni-grid-item>
</uni-grid>
</view>
</view>
</template>
<script setup>
import {
ref,
onMounted
} from 'vue';
import NGCalTools from '@/pages_caltools/pages/index'
import { ref } from "vue";
import modal from "@/plugins/modal"
const current = ref(0);
const swiperDotIndex = ref(0);
const data = ref([
{ image: '/static/images/banner/banner01.jpg' },
{ image: '/static/images/banner/banner02.jpg' },
{ image: '/static/images/banner/banner03.jpg' }
]);
function clickBannerItem(item) {
console.info(item)
};
function changeSwiper(e) {
current.value = e.detail.current
}
function changeGrid(e) {
modal.showToast({
title: '模块建设中',
mask: false,
icon: 'loading',
duration: 1000
});
}
</script>
<style scoped lang="scss">
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
<style lang="scss">
/* #ifndef APP-NVUE */
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #fff;
min-height: 100%;
height: auto;
}
.text-area {
display: flex;
justify-content: center;
}
view {
font-size: 14px;
line-height: inherit;
}
.title {
font-size: 36rpx;
color: #8f8f94;
}
/* #endif */
.charts-box {
width: 100%;
height: 300px;
}
</style>
.text {
text-align: center;
font-size: 26rpx;
margin-top: 10rpx;
}
.grid-item-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 0;
}
.uni-margin-wrap {
width: 690rpx;
width: 100%;
;
}
.swiper {
height: 300rpx;
}
.swiper-box {
height: 150px;
}
.swiper-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
height: 300rpx;
line-height: 300rpx;
}
@media screen and (min-width: 500px) {
.uni-swiper-dot-box {
width: 400px;
/* #ifndef APP-NVUE */
margin: 0 auto;
/* #endif */
margin-top: 8px;
}
.image {
width: 100%;
}
}
</style>

View File

@ -1,179 +1,50 @@
<template>
<view class="work-container">
<!-- 轮播图 -->
<uni-swiper-dot class="uni-swiper-dot-box" :info="data" :current="current" field="content">
<swiper class="swiper-box" :current="swiperDotIndex" @change="changeSwiper">
<swiper-item v-for="(item, index) in data" :key="index">
<view class="swiper-item" @click="clickBannerItem(item)">
<image :src="item.image" mode="aspectFill" :draggable="false" />
</view>
</swiper-item>
</swiper>
</uni-swiper-dot>
<!-- 宫格组件 -->
<uni-section title="系统管理" type="line"></uni-section>
<view class="grid-body">
<uni-grid :column="4" :showBorder="false" @change="changeGrid">
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="person-filled" size="30"></uni-icons>
<text class="text">用户管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="staff-filled" size="30"></uni-icons>
<text class="text">角色管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="color" size="30"></uni-icons>
<text class="text">菜单管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="settings-filled" size="30"></uni-icons>
<text class="text">部门管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="heart-filled" size="30"></uni-icons>
<text class="text">岗位管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="bars" size="30"></uni-icons>
<text class="text">字典管理</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="gear-filled" size="30"></uni-icons>
<text class="text">参数设置</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="chat-filled" size="30"></uni-icons>
<text class="text">通知公告</text>
</view>
</uni-grid-item>
<uni-grid-item>
<view class="grid-item-box">
<uni-icons type="wallet-filled" size="30"></uni-icons>
<text class="text">日志管理</text>
</view>
</uni-grid-item>
</uni-grid>
</view>
</view>
<view class="content">
<image class="logo" src="@/static/logo.png"></image>
<view class="text-area">
<text class="title"> 天然气工具集</text>
</view>
<NG-cal-tools></NG-cal-tools>
</view>
</template>
<script setup>
import { ref } from "vue";
import modal from "@/plugins/modal"
const current = ref(0);
const swiperDotIndex = ref(0);
const data = ref([
{ image: '/static/images/banner/banner01.jpg' },
{ image: '/static/images/banner/banner02.jpg' },
{ image: '/static/images/banner/banner03.jpg' }
]);
function clickBannerItem(item) {
console.info(item)
};
function changeSwiper(e) {
current.value = e.detail.current
}
function changeGrid(e) {
modal.showToast({
title: '模块建设中',
mask: false,
icon: 'loading',
duration: 1000
});
}
import {
ref,
onMounted
} from 'vue';
import NGCalTools from '@/pages_caltools/pages/index'
</script>
<style scoped lang="scss">
.content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
<style lang="scss">
/* #ifndef APP-NVUE */
page {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #fff;
min-height: 100%;
height: auto;
}
.logo {
height: 200rpx;
width: 200rpx;
margin-top: 200rpx;
margin-left: auto;
margin-right: auto;
margin-bottom: 50rpx;
}
view {
font-size: 14px;
line-height: inherit;
}
.text-area {
display: flex;
justify-content: center;
}
/* #endif */
.title {
font-size: 36rpx;
color: #8f8f94;
}
.text {
text-align: center;
font-size: 26rpx;
margin-top: 10rpx;
}
.grid-item-box {
flex: 1;
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
align-items: center;
justify-content: center;
padding: 15px 0;
}
.uni-margin-wrap {
width: 690rpx;
width: 100%;
;
}
.swiper {
height: 300rpx;
}
.swiper-box {
height: 150px;
}
.swiper-item {
/* #ifndef APP-NVUE */
display: flex;
/* #endif */
flex-direction: column;
justify-content: center;
align-items: center;
color: #fff;
height: 300rpx;
line-height: 300rpx;
}
@media screen and (min-width: 500px) {
.uni-swiper-dot-box {
width: 400px;
/* #ifndef APP-NVUE */
margin: 0 auto;
/* #endif */
margin-top: 8px;
}
.image {
width: 100%;
}
}
</style>
.charts-box {
width: 100%;
height: 300px;
}
</style>

View File

@ -1,23 +1,25 @@
<template>
<view class="container">
<!-- Swiper 组件用于在不同计算分组间滑动 -->
<swiper class="calc-swiper" :current="currentTab" @change="handleSwiperChange" indicator-dots
<swiper class="calc-swiper" :current="currentTab" @change="handleSwiperChange" :indicator-dots="true"
indicator-color="#BBBBBB" indicator-active-color="#007AFF">
<!-- 遍历分组数据动态生成 swiper-item -->
<swiper-item v-for="(group, groupIndex) in calcGroups" :key="groupIndex">
<!-- 3x3 宫格布局 -->
<view class="page-header">{{group.name}}</view>
<uni-grid :column-num="3" :show-border="true" border-color="#EEEEEE">
<!-- 遍历每个分组下的功能项动态生成宫格 -->
<uni-grid-item class="grid-item" v-for="(item, itemIndex) in group.items" :key="itemIndex"
@click="navigateToCalc(item)">
<view class="grid-icon">
<uni-icons :type="item.icon" size="32" :color="group.color"></uni-icons>
</view>
<view class="grid-text">{{ item.name }}</view>
</uni-grid-item>
</uni-grid>
<scroll-view scroll-y="true" class="scroll-content">
<view class="page-header">{{group.name}}</view>
<uni-grid :column="3" :show-border="true" :border="true" border-color="#EEEEEE" class="custom-grid">
<!-- 遍历每个分组下的功能项动态生成宫格 -->
<uni-grid-item v-for="(item, itemIndex) in group.items" :key="itemIndex"
@click="navigateToCalc(item)" class="grid-item">
<view class="grid-content">
<view class="grid-icon">
<uni-icons :type="item.icon" size="32" :color="group.color"></uni-icons>
</view>
<text class="grid-text">{{ item.name }}</text>
</view>
</uni-grid-item>
</uni-grid>
</scroll-view>
</swiper-item>
</swiper>
</view>
@ -27,30 +29,24 @@
import {
ref
} from 'vue';
import {
useRouter
} from 'vue-router'; // Vue 3 使 vue-router
// Swiper
const currentTab = ref(0);
//
const router = useRouter();
//
const calcGroups = [{
name: '流量计算',
color: '#007AFF',
items: [{
name: '差压式流量计算',
icon: 'flow',
dMeterType:0
icon: 'smallcircle',
dMeterType: 0
},
{
name: '速度式流量计算',
icon: 'speedometer',
dMeterType:1
icon: 'paperplane',
dMeterType: 1
},
]
},
{
@ -58,23 +54,23 @@
color: '#5AC8FA',
items: [{
name: '压缩因子',
icon: 'compress',
dMeterType:4
icon: 'pyq',
dMeterType: 4
},
{
name: '声速计算',
icon: 'fire',
dMeterType:5
icon: 'sound',
dMeterType: 5
},
{
name: '发热量',
icon: 'volume-high',
dMeterType:6
icon: 'fire',
dMeterType: 6
},
{
name: '其他参数',
icon: 'density',
dMeterType:7
icon: 'more',
dMeterType: 7
}
]
}
@ -90,70 +86,78 @@
/**
* 导航到具体的计算页面
* @param {Object} group 当前点击的分组对象
* @param {number} itemIndex 点击项在分组内的索引
* @param {Object} item 点击的项
*/
const navigateToCalc = (item) => {
const dMeterType = item.dMeterType;
console.log(`导航到计算页面dMeterType: ${dMeterType}`);
// 使 UniApp API
uni.navigateTo({
// '/' query URL
url: `/pages_caltools/pages/main?dMeterType=${dMeterType}`
});
// 使 UniApp API
uni.navigateTo({
url: `/pages_caltools/pages/main?dMeterType=${dMeterType}`
});
};
</script>
<style scoped>
.container {
padding: 16px;
padding: 16rpx;
background-color: #F5F5F5;
box-sizing: border-box;
min-height: 100vh;
/* 使用 min-height 确保在内容不足时也占满屏幕 */
}
.page-header {
font-size: 18px;
font-size: 36rpx;
font-weight: 500;
color: #333333;
margin-bottom: 16px;
margin: 30rpx 0;
text-align: center;
}
.calc-swiper {
/* 关键:让 swiper 占满剩余空间 */
width: calc(100vw - 100px);
;
height: calc(100vh - 70px);
width: 100vw;
height: 800rpx;
}
/* 确保宫格充满父容器 */
uni-grid {
width: 100%;
.scroll-content {
height: 100%;
width: 100%;
}
::v-deep .custom-grid {
width: 100%;
height: auto;
}
.grid-item {
height: 200rpx;
}
.grid-content {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 10px 0;
height: 100%;
padding: 20rpx;
}
.grid-icon {
margin-bottom: 8px;
margin-bottom: 20rpx;
display: flex;
align-items: center;
justify-content: center;
width: 80rpx;
height: 80rpx;
}
.grid-text {
font-size: 10px;
font-size: 24rpx;
color: #333333;
text-align: center;
width: 100%;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
line-height: 1.4;
/* 允许文字换行 */
word-break: break-all;
}
</style>

View File

@ -0,0 +1,273 @@
<template>
<view class="register-container">
<!-- 背景图建议在 pages.json 中配置这里作为备用 -->
<view class="register-form-wrapper">
<uni-forms ref="registerFormRef" :modelValue="registerForm" :rules="registerRules" label-width="0">
<view class="title">天然气工具平台</view>
<uni-forms-item name="username">
<uni-easyinput v-model="registerForm.username" type="text" placeholder="账号" prefixIcon="person"
@confirm="handleRegister" />
</uni-forms-item>
<uni-forms-item name="password">
<uni-easyinput v-model="registerForm.password" type="password" placeholder="密码" prefixIcon="locked"
@confirm="handleRegister" />
</uni-forms-item>
<uni-forms-item name="confirmPassword">
<uni-easyinput v-model="registerForm.confirmPassword" type="password" placeholder="确认密码"
prefixIcon="locked" @confirm="handleRegister" />
</uni-forms-item>
<uni-forms-item name="code" v-if="captchaEnabled">
<view class="code-input-wrapper">
<uni-easyinput v-model="registerForm.code" type="text" placeholder="验证码" prefixIcon="code"
@confirm="handleRegister" />
<view class="code-img-wrapper">
<image :src="codeUrl" class="code-img" @tap="getCode"></image>
</view>
</view>
</uni-forms-item>
<uni-forms-item>
<uni-button type="primary" size="default" :loading="loading" @click="handleRegister"
class="register-btn">
注册
</uni-button>
<view class="login-link">
<text>已有账号</text>
<navigator url="/pages/login/login" class="link-text">立即登录</navigator>
</view>
</uni-forms-item>
</uni-forms>
</view>
<view class="el-register-footer">
<text>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</text>
</view>
</view>
</template>
<script setup>
import {
ref,
onReady
} from 'vue';
import {
getCodeImg,
register
} from '@/api/login'; // API Uniapp
//
const registerFormRef = ref(null);
//
const registerForm = ref({
username: "",
password: "",
confirmPassword: "",
code: "",
uuid: ""
});
//
const registerRules = {
username: [{
required: true,
errorMessage: '请输入您的账号'
},
{
minLength: 2,
maxLength: 20,
errorMessage: '用户账号长度必须介于 2 和 20 之间'
}
],
password: [{
required: true,
errorMessage: '请输入您的密码'
},
{
minLength: 5,
maxLength: 20,
errorMessage: '用户密码长度必须介于 5 和 20 之间'
},
{
pattern: /^[^<>"'|\\]+$/,
errorMessage: '不能包含非法字符:< > " \' \\ |'
}
],
confirmPassword: [{
required: true,
errorMessage: '请再次输入您的密码'
},
{
validator: (rule, value, callback, source, options) => {
if (value !== registerForm.value.password) {
callback(new Error('两次输入的密码不一致'));
} else {
callback();
}
},
errorMessage: '两次输入的密码不一致'
}
],
code: [{
required: true,
errorMessage: '请输入验证码'
}]
};
//
const codeUrl = ref("");
const loading = ref(false);
const captchaEnabled = ref(true);
//
const getCode = () => {
getCodeImg().then(res => {
// res.data { img: 'base64...', uuid: '...', captchaEnabled: true }
captchaEnabled.value = res.data.captchaEnabled !== false;
if (captchaEnabled.value) {
codeUrl.value = res.data.img; // Uniapp image base64
registerForm.value.uuid = res.data.uuid;
}
}).catch(err => {
console.error("获取验证码失败:", err);
uni.showToast({
title: '获取验证码失败',
icon: 'none'
});
});
};
//
const handleRegister = () => {
// 使 uni-forms validate
registerFormRef.value.validate().then(() => {
loading.value = true;
register(registerForm.value).then(res => {
uni.showModal({
title: '系统提示',
content: `<font color='red'>恭喜你,您的账号 ${registerForm.value.username} 注册成功!</font>`,
showCancel: false,
success: () => {
//
uni.redirectTo({
url: '/pages/login/login'
});
}
});
}).catch(err => {
//
uni.showToast({
title: err.message || '注册失败',
icon: 'none'
});
if (captchaEnabled.value) {
getCode(); //
}
}).finally(() => {
loading.value = false;
});
}).catch(errors => {
// uni-forms
console.log('表单校验失败:', errors);
});
};
//
onReady(() => {
getCode();
});
</script>
<style scoped>
/* 页面整体背景,建议在 pages.json 中配置 "style": { "backgroundImage": "url('/static/login-background.jpg')" } */
.register-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
padding: 20rpx;
box-sizing: border-box;
background-color: #f5f5f5;
/* 备用背景色 */
}
/* 表单外层容器 */
.register-form-wrapper {
width: 100%;
max-width: 400rpx;
padding: 40rpx 30rpx;
background-color: #ffffff;
border-radius: 16rpx;
box-shadow: 0 8rpx 30rpx rgba(0, 0, 0, 0.1);
}
.title {
text-align: center;
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 40rpx;
}
/* 验证码输入框和图片一行显示 */
.code-input-wrapper {
display: flex;
align-items: center;
gap: 16rpx;
}
.code-img-wrapper {
flex-shrink: 0;
width: 140rpx;
height: 72rpx;
/* 与输入框高度对齐 */
}
.code-img {
width: 100%;
height: 100%;
border-radius: 8rpx;
}
/* 注册按钮 */
.register-btn {
width: 100%;
height: 80rpx;
line-height: 80rpx;
font-size: 28rpx;
border-radius: 40rpx;
margin-bottom: 20rpx;
}
/* 登录链接 */
.login-link {
text-align: center;
font-size: 24rpx;
color: #999;
}
.link-text {
color: #007aff;
text-decoration: underline;
}
/* 页脚 */
.el-register-footer {
position: fixed;
bottom: 0;
width: 100%;
height: 80rpx;
line-height: 80rpx;
text-align: center;
font-size: 20rpx;
color: #ccc;
box-sizing: border-box;
}
</style>

View File

@ -1,197 +1,197 @@
<script setup>
import { defineProps } from 'vue';
// import { defineProps } from 'vue';
const props = defineProps({
order: {
type: Object,
required: true
}
});
const props = defineProps({
order: {
type: Object,
required: true
}
});
//
const priceDecimal = (val) => {
if (val !== parseInt(val)) return val.slice(-2);
else return '00';
};
//
const priceDecimal = (val) => {
if (val !== parseInt(val)) return val.slice(-2);
else return '00';
};
//
const priceInt = (val) => {
if (val !== parseInt(val)) return val.split('.')[0];
else return val;
};
//
const priceInt = (val) => {
if (val !== parseInt(val)) return val.split('.')[0];
else return val;
};
//
const totalPrice = (item) => {
let price = 0;
item.forEach(val => {
price += parseFloat(val.price);
});
return price.toFixed(2);
};
//
const totalPrice = (item) => {
let price = 0;
item.forEach(val => {
price += parseFloat(val.price);
});
return price.toFixed(2);
};
//
const totalNum = (item) => {
let num = 0;
item.forEach(val => {
num += val.number;
});
return num;
};
//
const totalNum = (item) => {
let num = 0;
item.forEach(val => {
num += val.number;
});
return num;
};
</script>
<template>
<view class="order">
<view class="top">
<view class="left">
<u-icon name="home" :size="30" color="rgb(94,94,94)"></u-icon>
<view class="store">{{ order.store }}</view>
<u-icon name="arrow-right" color="rgb(203,203,203)" :size="26"></u-icon>
</view>
<view class="right">{{ order.deal }}</view>
</view>
<view class="item" v-for="(item, index) in order.goodsList" :key="index">
<view class="left">
<image :src="item.goodsUrl" mode="aspectFill"></image>
</view>
<view class="content">
<view class="title u-line-2">{{ item.title }}</view>
<view class="type">{{ item.type }}</view>
<view class="delivery-time">发货时间 {{ item.deliveryTime }}</view>
</view>
<view class="right">
<view class="price">
{{ priceInt(item.price) }}
<text class="decimal">.{{ priceDecimal(item.price) }}</text>
</view>
<view class="number">x{{ item.number }}</view>
</view>
</view>
<view class="total">
{{ totalNum(order.goodsList) }}件商品 合计:
<text class="total-price">
{{ priceInt(totalPrice(order.goodsList)) }}.
<text class="decimal">{{ priceDecimal(totalPrice(order.goodsList)) }}</text>
</text>
</view>
<view class="bottom">
<view class="more"><u-icon name="more-dot-fill" color="rgb(203,203,203)"></u-icon></view>
<view class="logistics btn">查看物流</view>
<view class="exchange btn">卖了换钱</view>
<view class="evaluate btn">评价</view>
</view>
</view>
<view class="order">
<view class="top">
<view class="left">
<u-icon name="home" :size="30" color="rgb(94,94,94)"></u-icon>
<view class="store">{{ order.store }}</view>
<u-icon name="arrow-right" color="rgb(203,203,203)" :size="26"></u-icon>
</view>
<view class="right">{{ order.deal }}</view>
</view>
<view class="item" v-for="(item, index) in order.goodsList" :key="index">
<view class="left">
<image :src="item.goodsUrl" mode="aspectFill"></image>
</view>
<view class="content">
<view class="title u-line-2">{{ item.title }}</view>
<view class="type">{{ item.type }}</view>
<view class="delivery-time">发货时间 {{ item.deliveryTime }}</view>
</view>
<view class="right">
<view class="price">
{{ priceInt(item.price) }}
<text class="decimal">.{{ priceDecimal(item.price) }}</text>
</view>
<view class="number">x{{ item.number }}</view>
</view>
</view>
<view class="total">
{{ totalNum(order.goodsList) }}件商品 合计:
<text class="total-price">
{{ priceInt(totalPrice(order.goodsList)) }}.
<text class="decimal">{{ priceDecimal(totalPrice(order.goodsList)) }}</text>
</text>
</view>
<view class="bottom">
<view class="more"><u-icon name="more-dot-fill" color="rgb(203,203,203)"></u-icon></view>
<view class="logistics btn">查看物流</view>
<view class="exchange btn">卖了换钱</view>
<view class="evaluate btn">评价</view>
</view>
</view>
</template>
<style lang="scss" scoped>
.order {
width: 710rpx;
background-color: #ffffff;
margin: 20rpx auto;
border-radius: 20rpx;
box-sizing: border-box;
padding: 20rpx;
font-size: 28rpx;
.order {
width: 710rpx;
background-color: #ffffff;
margin: 20rpx auto;
border-radius: 20rpx;
box-sizing: border-box;
padding: 20rpx;
font-size: 28rpx;
.top {
display: flex;
justify-content: space-between;
.top {
display: flex;
justify-content: space-between;
.left {
display: flex;
align-items: center;
.left {
display: flex;
align-items: center;
.store {
margin: 0 10rpx;
font-size: 32rpx;
font-weight: bold;
}
}
.store {
margin: 0 10rpx;
font-size: 32rpx;
font-weight: bold;
}
}
.right {
color: $u-warning-dark;
}
}
.right {
color: $u-warning-dark;
}
}
.item {
display: flex;
margin: 20rpx 0 0;
.item {
display: flex;
margin: 20rpx 0 0;
.left {
margin-right: 20rpx;
.left {
margin-right: 20rpx;
image {
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
}
}
image {
width: 200rpx;
height: 200rpx;
border-radius: 10rpx;
}
}
.content {
.title {
font-size: 28rpx;
line-height: 50rpx;
}
.content {
.title {
font-size: 28rpx;
line-height: 50rpx;
}
.type {
margin: 10rpx 0;
font-size: 24rpx;
color: $u-tips-color;
}
.type {
margin: 10rpx 0;
font-size: 24rpx;
color: $u-tips-color;
}
.delivery-time {
color: #e5d001;
font-size: 24rpx;
}
}
.delivery-time {
color: #e5d001;
font-size: 24rpx;
}
}
.right {
margin-left: 10rpx;
padding-top: 20rpx;
text-align: right;
.right {
margin-left: 10rpx;
padding-top: 20rpx;
text-align: right;
.decimal {
font-size: 24rpx;
margin-top: 4rpx;
}
.decimal {
font-size: 24rpx;
margin-top: 4rpx;
}
.number {
color: $u-tips-color;
font-size: 24rpx;
}
}
}
.number {
color: $u-tips-color;
font-size: 24rpx;
}
}
}
.total {
margin-top: 20rpx;
text-align: right;
font-size: 24rpx;
.total {
margin-top: 20rpx;
text-align: right;
font-size: 24rpx;
.total-price {
font-size: 32rpx;
}
}
.total-price {
font-size: 32rpx;
}
}
.bottom {
display: flex;
margin-top: 40rpx;
padding: 0 10rpx;
justify-content: space-between;
align-items: center;
.bottom {
display: flex;
margin-top: 40rpx;
padding: 0 10rpx;
justify-content: space-between;
align-items: center;
.btn {
line-height: 52rpx;
width: 160rpx;
border-radius: 26rpx;
border: 2rpx solid $u-border-color;
font-size: 26rpx;
text-align: center;
color: $u-info-dark;
}
.btn {
line-height: 52rpx;
width: 160rpx;
border-radius: 26rpx;
border: 2rpx solid $u-border-color;
font-size: 26rpx;
text-align: center;
color: $u-info-dark;
}
.evaluate {
color: $u-warning-dark;
border-color: $u-warning-dark;
}
}
}
</style>
.evaluate {
color: $u-warning-dark;
border-color: $u-warning-dark;
}
}
}
</style>

View File

@ -195,10 +195,12 @@
var tempData = [];
// #ifdef APP || APP-PLUS
tempData = uni.getStorageSync("unitData");
this.unitData = tempData[unitType];
console.log((tempData));
this.unitData = (tempData[unitType]);
// #endif
// #ifdef H5
tempData = localStorage.getItem("unitData");
console.log((tempData));
var unitDatalist = JSON.parse(tempData);
this.unitData = unitDatalist[unitType];
// #endif