完成账单列表,余额页面交互
29
App.vue
|
|
@ -1,22 +1,17 @@
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
onLaunch: function() {
|
onLaunch: function () {
|
||||||
console.log('App Launch')
|
console.log('App Launch')
|
||||||
},
|
},
|
||||||
onShow: function() {
|
onShow: function () {
|
||||||
console.log('App Show')
|
console.log('App Show')
|
||||||
},
|
},
|
||||||
onHide: function() {
|
onHide: function () {
|
||||||
console.log('App Hide')
|
console.log('App Hide')
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="less">
|
<style lang="less">
|
||||||
/*每个页面公共css */
|
@import './common/main.css';
|
||||||
/* #ifdef VUE */
|
// @import './common/layouts.less';</style>
|
||||||
/* 只在vue页面生效的样式,nvue页面不使用 */
|
|
||||||
@import './common/main.css';
|
|
||||||
@import './common/layouts.less';
|
|
||||||
/* #endif */
|
|
||||||
</style>
|
|
||||||
|
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
// layouts.less 使用示例
|
|
||||||
// 这个文件展示了如何在页面中使用 common/layouts.less 中的布局方法
|
|
||||||
|
|
||||||
// 示例1: 使用Flex布局
|
|
||||||
.example-flex {
|
|
||||||
.flex-between; // 使用两端对齐布局
|
|
||||||
padding: 20px;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
.flex-center; // 使用居中布局
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
background-color: #007aff;
|
|
||||||
color: white;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 示例2: 使用Grid布局
|
|
||||||
.example-grid {
|
|
||||||
.grid-responsive(4, 16px); // 使用响应式网格,4列,间距16px
|
|
||||||
padding: 20px;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
height: 120px;
|
|
||||||
background-color: #ff9500;
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
&:nth-child(1) {
|
|
||||||
.grid-col(2); // 占据2列
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 示例3: 使用卡片布局
|
|
||||||
.example-card {
|
|
||||||
max-width: 400px;
|
|
||||||
margin: 20px auto;
|
|
||||||
|
|
||||||
.card(); // 使用基础卡片样式
|
|
||||||
|
|
||||||
.card-header {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-body {
|
|
||||||
.flex-column;
|
|
||||||
gap: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.card-footer {
|
|
||||||
.flex-between;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 示例4: 使用响应式布局
|
|
||||||
.example-responsive {
|
|
||||||
display: flex;
|
|
||||||
gap: 20px;
|
|
||||||
padding: 20px;
|
|
||||||
|
|
||||||
.desktop-only {
|
|
||||||
.hidden-sm; // 在小屏幕上隐藏
|
|
||||||
width: 200px;
|
|
||||||
height: 200px;
|
|
||||||
background-color: #4cd964;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-only {
|
|
||||||
.visible-sm; // 只在小屏幕上显示
|
|
||||||
width: 100%;
|
|
||||||
height: 100px;
|
|
||||||
background-color: #ff3b30;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 示例5: 使用间距工具类
|
|
||||||
.example-spacing {
|
|
||||||
.m-4; // margin: 16px
|
|
||||||
.p-6; // padding: 24px
|
|
||||||
background-color: #e9e9eb;
|
|
||||||
|
|
||||||
.child {
|
|
||||||
.mt-3; // margin-top: 12px
|
|
||||||
.mb-3; // margin-bottom: 12px
|
|
||||||
.px-4; // padding-left: 16px; padding-right: 16px
|
|
||||||
background-color: #ffffff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 示例6: 使用页面布局
|
|
||||||
.example-page {
|
|
||||||
.page-with-header-footer;
|
|
||||||
|
|
||||||
.page-header {
|
|
||||||
.navbar-top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-content {
|
|
||||||
.container-responsive;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-footer {
|
|
||||||
.navbar-bottom;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,446 +0,0 @@
|
||||||
// 布局专用LESS文件
|
|
||||||
// 包含常用的布局混合宏和样式
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// 容器布局
|
|
||||||
// ------------------------------
|
|
||||||
|
|
||||||
// 全屏容器
|
|
||||||
.full-screen {
|
|
||||||
width: 100%;
|
|
||||||
height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 固定宽度容器
|
|
||||||
.container-fixed(@width: 1200px) {
|
|
||||||
width: @width;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 响应式容器
|
|
||||||
.container-responsive {
|
|
||||||
width: 100%;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 20px;
|
|
||||||
max-width: 1200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// Flex布局混合宏
|
|
||||||
// ------------------------------
|
|
||||||
|
|
||||||
// 基础Flex布局
|
|
||||||
.flex(@direction: row; @wrap: nowrap; @justify: flex-start; @align: stretch) {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: @direction;
|
|
||||||
flex-wrap: @wrap;
|
|
||||||
justify-content: @justify;
|
|
||||||
align-items: @align;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 居中布局
|
|
||||||
.flex-center {
|
|
||||||
.flex(row, nowrap, center, center);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 两端对齐
|
|
||||||
.flex-between {
|
|
||||||
.flex(row, nowrap, space-between, center);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 顶部对齐
|
|
||||||
.flex-start {
|
|
||||||
.flex(row, nowrap, flex-start, flex-start);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 底部对齐
|
|
||||||
.flex-end {
|
|
||||||
.flex(row, nowrap, flex-end, flex-end);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 垂直居中
|
|
||||||
.flex-middle {
|
|
||||||
.flex(row, nowrap, flex-start, center);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 垂直布局
|
|
||||||
.flex-column {
|
|
||||||
.flex(column, nowrap, flex-start, stretch);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 垂直居中布局
|
|
||||||
.flex-column-center {
|
|
||||||
.flex(column, nowrap, center, center);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 垂直两端对齐
|
|
||||||
.flex-column-between {
|
|
||||||
.flex(column, nowrap, space-between, stretch);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// 网格布局
|
|
||||||
// ------------------------------
|
|
||||||
|
|
||||||
// 基础网格容器
|
|
||||||
.grid(@columns: 12; @gap: 20px) {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(@columns, 1fr);
|
|
||||||
grid-gap: @gap;
|
|
||||||
gap: @gap;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 响应式网格
|
|
||||||
.grid-responsive(@columns: 12; @gap: 20px) {
|
|
||||||
.grid(@columns, @gap);
|
|
||||||
|
|
||||||
@media (max-width: 768px) {
|
|
||||||
grid-template-columns: repeat(6, 1fr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 480px) {
|
|
||||||
grid-template-columns: repeat(3, 1fr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 网格列宽
|
|
||||||
.grid-col(@span: 1) {
|
|
||||||
grid-column: span @span;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 网格行高
|
|
||||||
.grid-row(@span: 1) {
|
|
||||||
grid-row: span @span;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// 定位布局
|
|
||||||
// ------------------------------
|
|
||||||
|
|
||||||
// 绝对定位
|
|
||||||
.position-absolute(@top: auto; @right: auto; @bottom: auto; @left: auto) {
|
|
||||||
position: absolute;
|
|
||||||
top: @top;
|
|
||||||
right: @right;
|
|
||||||
bottom: @bottom;
|
|
||||||
left: @left;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 固定定位
|
|
||||||
.position-fixed(@top: auto; @right: auto; @bottom: auto; @left: auto) {
|
|
||||||
position: fixed;
|
|
||||||
top: @top;
|
|
||||||
right: @right;
|
|
||||||
bottom: @bottom;
|
|
||||||
left: @left;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 粘性定位
|
|
||||||
.position-sticky(@top: 0; @z-index: 10) {
|
|
||||||
position: sticky;
|
|
||||||
top: @top;
|
|
||||||
z-index: @z-index;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 居中定位(基于父容器)
|
|
||||||
.position-center {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 水平居中定位
|
|
||||||
.position-center-x {
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
transform: translateX(-50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 垂直居中定位
|
|
||||||
.position-center-y {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// 间距布局
|
|
||||||
// ------------------------------
|
|
||||||
|
|
||||||
// 外边距
|
|
||||||
.margin(@top: 0; @right: @top; @bottom: @top; @left: @right) {
|
|
||||||
margin: @top @right @bottom @left;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 内边距
|
|
||||||
.padding(@top: 0; @right: @top; @bottom: @top; @left: @right) {
|
|
||||||
padding: @top @right @bottom @left;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 间距工具类(基于4px网格系统)
|
|
||||||
.spacing-utilities(@prefix: m; @property: margin) {
|
|
||||||
.loop(@i) when (@i <= 12) {
|
|
||||||
.@{prefix}-@{i} {
|
|
||||||
@{property}: @i * 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{prefix}t-@{i} {
|
|
||||||
@{property}-top: @i * 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{prefix}r-@{i} {
|
|
||||||
@{property}-right: @i * 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{prefix}b-@{i} {
|
|
||||||
@{property}-bottom: @i * 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{prefix}l-@{i} {
|
|
||||||
@{property}-left: @i * 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loop(@i + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.loop(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 生成外边距工具类
|
|
||||||
.spacing-utilities(m, margin);
|
|
||||||
|
|
||||||
// 生成内边距工具类
|
|
||||||
.spacing-utilities(p, padding);
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// 卡片布局
|
|
||||||
// ------------------------------
|
|
||||||
|
|
||||||
// 基础卡片
|
|
||||||
.card(@radius: 8px; @shadow: 0 2px 8px rgba(0, 0, 0, 0.1); @bg: #fff) {
|
|
||||||
background-color: @bg;
|
|
||||||
border-radius: @radius;
|
|
||||||
box-shadow: @shadow;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 带边框的卡片
|
|
||||||
.card-bordered(@radius: 8px; @border-color: #e5e5e5; @bg: #fff) {
|
|
||||||
.card(@radius, none, @bg);
|
|
||||||
border: 1px solid @border-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 卡片头部
|
|
||||||
.card-header {
|
|
||||||
padding: 16px 20px;
|
|
||||||
border-bottom: 1px solid #e5e5e5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 卡片主体
|
|
||||||
.card-body {
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 卡片底部
|
|
||||||
.card-footer {
|
|
||||||
padding: 16px 20px;
|
|
||||||
border-top: 1px solid #e5e5e5;
|
|
||||||
background-color: #fafafa;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// 导航栏布局
|
|
||||||
// ------------------------------
|
|
||||||
|
|
||||||
// 基础导航栏
|
|
||||||
.navbar(@height: 60px; @bg-color: #fff; @text-color: #333) {
|
|
||||||
height: @height;
|
|
||||||
background-color: @bg-color;
|
|
||||||
color: @text-color;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding: 0 20px;
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 顶部导航栏
|
|
||||||
.navbar-top {
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
.navbar();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 底部导航栏
|
|
||||||
.navbar-bottom {
|
|
||||||
position: fixed;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
z-index: 1000;
|
|
||||||
.navbar();
|
|
||||||
border-top: 1px solid #e5e5e5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// 页面布局
|
|
||||||
// ------------------------------
|
|
||||||
|
|
||||||
// 基础页面布局
|
|
||||||
.page-layout {
|
|
||||||
min-height: 100vh;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 带头部和底部的页面布局
|
|
||||||
.page-with-header-footer {
|
|
||||||
.page-layout();
|
|
||||||
|
|
||||||
.page-header {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-content {
|
|
||||||
flex: 1;
|
|
||||||
padding: 20px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-footer {
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// 响应式布局
|
|
||||||
// ------------------------------
|
|
||||||
|
|
||||||
// 断点定义
|
|
||||||
@breakpoint-sm: 480px;
|
|
||||||
@breakpoint-md: 768px;
|
|
||||||
@breakpoint-lg: 1024px;
|
|
||||||
@breakpoint-xl: 1200px;
|
|
||||||
|
|
||||||
// 媒体查询混合宏
|
|
||||||
.media-sm(@rules) {
|
|
||||||
@media (max-width: @breakpoint-sm) {
|
|
||||||
@rules();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-md(@rules) {
|
|
||||||
@media (max-width: @breakpoint-md) {
|
|
||||||
@rules();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-lg(@rules) {
|
|
||||||
@media (max-width: @breakpoint-lg) {
|
|
||||||
@rules();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.media-xl(@rules) {
|
|
||||||
@media (max-width: @breakpoint-xl) {
|
|
||||||
@rules();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 响应式显示/隐藏
|
|
||||||
.hidden-sm {
|
|
||||||
.media-sm({
|
|
||||||
display: none;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
.visible-sm {
|
|
||||||
display: none;
|
|
||||||
.media-sm({
|
|
||||||
display: block;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
.hidden-md {
|
|
||||||
.media-md({
|
|
||||||
display: none;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
.visible-md {
|
|
||||||
display: none;
|
|
||||||
.media-md({
|
|
||||||
display: block;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------
|
|
||||||
// 其他布局工具
|
|
||||||
// ------------------------------
|
|
||||||
|
|
||||||
// 清除浮动
|
|
||||||
.clearfix {
|
|
||||||
&::after {
|
|
||||||
content: '';
|
|
||||||
display: table;
|
|
||||||
clear: both;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 相对定位
|
|
||||||
.relative {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 绝对定位
|
|
||||||
.absolute {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 固定定位
|
|
||||||
.fixed {
|
|
||||||
position: fixed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 粘性定位
|
|
||||||
.sticky {
|
|
||||||
position: sticky;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 隐藏溢出
|
|
||||||
.overflow-hidden {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 自动溢出
|
|
||||||
.overflow-auto {
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 水平滚动
|
|
||||||
.overflow-x-auto {
|
|
||||||
overflow-x: auto;
|
|
||||||
overflow-y: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 垂直滚动
|
|
||||||
.overflow-y-auto {
|
|
||||||
overflow-y: auto;
|
|
||||||
overflow-x: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 全屏高度
|
|
||||||
.full-height {
|
|
||||||
height: 100%;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 全屏宽度
|
|
||||||
.full-width {
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
456
common/main.css
|
|
@ -2,276 +2,408 @@
|
||||||
|
|
||||||
/* 重置样式 */
|
/* 重置样式 */
|
||||||
* {
|
* {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
/* color: var(--text-color); */
|
/* color: var(--text-color); */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 基础样式 */
|
/* 基础样式 */
|
||||||
body {
|
body {
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
/* font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||||
font-size: 14px;
|
"Helvetica Neue", Arial, sans-serif; */
|
||||||
line-height: 1.5;
|
font-size: 14px;
|
||||||
color: #333;
|
line-height: 1.5;
|
||||||
background-color: #f5f5f5;
|
color: var(--text-color);
|
||||||
|
background-color: var(--page-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.w100 {
|
||||||
|
width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.h100 {
|
||||||
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 常用颜色变量 */
|
/* 常用颜色变量 */
|
||||||
:root {
|
:root {
|
||||||
--text-color: #1a1a1a;
|
--text-color: #1a1a1a;
|
||||||
--primary-color: #007aff;
|
--primary-color: #007aff;
|
||||||
--success-color: #4cd964;
|
--success-color: #4cd964;
|
||||||
--warning-color: #ff9500;
|
--warning-color: #ff9500;
|
||||||
--error-color: #ff3b30;
|
--error-color: #ff3b30;
|
||||||
--text-primary: #333;
|
--text-primary: #333;
|
||||||
--text-secondary: #666;
|
--text-secondary: #969696;
|
||||||
--text-tertiary: #999;
|
--text-tertiary: #999;
|
||||||
--bg-primary: #fff;
|
--bg-primary: #ffffff;
|
||||||
--bg-secondary: #f5f5f5;
|
--bg-secondary: #f5f5f5;
|
||||||
--border-color: #e5e5e5;
|
--border-color: #D8D8D8;
|
||||||
|
--page-bg-color: #f0f3f8;
|
||||||
|
--footer-text-color: #CBCED3;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 文本样式 */
|
/* 文本样式 */
|
||||||
.text-center {
|
.text-center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-left {
|
.text-left {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-right {
|
.text-right {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-primary {
|
.text-primary {
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-success {
|
.text-success {
|
||||||
color: var(--success-color);
|
color: var(--success-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-warning {
|
.text-warning {
|
||||||
color: var(--warning-color);
|
color: var(--warning-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-error {
|
.text-error {
|
||||||
color: var(--error-color);
|
color: var(--error-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-sm {
|
.text-sm {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-lg {
|
.text-lg {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-xl {
|
.text-xl {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 间距工具类 */
|
/* 间距工具类 */
|
||||||
.m-0 { margin: 0; }
|
.m-0 {
|
||||||
.m-1 { margin: 4px; }
|
margin: 0;
|
||||||
.m-2 { margin: 8px; }
|
}
|
||||||
.m-3 { margin: 16px; }
|
|
||||||
.m-4 { margin: 24px; }
|
|
||||||
|
|
||||||
.mt-0 { margin-top: 0; }
|
.m-1 {
|
||||||
.mt-1 { margin-top: 4px; }
|
margin: 4px;
|
||||||
.mt-2 { margin-top: 8px; }
|
}
|
||||||
.mt-3 { margin-top: 16px; }
|
|
||||||
.mt-4 { margin-top: 24px; }
|
|
||||||
|
|
||||||
.mb-0 { margin-bottom: 0; }
|
.m-2 {
|
||||||
.mb-1 { margin-bottom: 4px; }
|
margin: 8px;
|
||||||
.mb-2 { margin-bottom: 8px; }
|
}
|
||||||
.mb-3 { margin-bottom: 16px; }
|
|
||||||
.mb-4 { margin-bottom: 24px; }
|
|
||||||
|
|
||||||
.ml-0 { margin-left: 0; }
|
.m-3 {
|
||||||
.ml-1 { margin-left: 4px; }
|
margin: 16px;
|
||||||
.ml-2 { margin-left: 8px; }
|
}
|
||||||
.ml-3 { margin-left: 16px; }
|
|
||||||
.ml-4 { margin-left: 24px; }
|
|
||||||
|
|
||||||
.mr-0 { margin-right: 0; }
|
.m-4 {
|
||||||
.mr-1 { margin-right: 4px; }
|
margin: 24px;
|
||||||
.mr-2 { margin-right: 8px; }
|
}
|
||||||
.mr-3 { margin-right: 16px; }
|
|
||||||
.mr-4 { margin-right: 24px; }
|
|
||||||
|
|
||||||
.p-0 { padding: 0; }
|
.mt-0 {
|
||||||
.p-1 { padding: 4px; }
|
margin-top: 0;
|
||||||
.p-2 { padding: 8px; }
|
}
|
||||||
.p-3 { padding: 16px; }
|
|
||||||
.p-4 { padding: 24px; }
|
|
||||||
|
|
||||||
.pt-0 { padding-top: 0; }
|
.mt-1 {
|
||||||
.pt-1 { padding-top: 4px; }
|
margin-top: 4px;
|
||||||
.pt-2 { padding-top: 8px; }
|
}
|
||||||
.pt-3 { padding-top: 16px; }
|
|
||||||
.pt-4 { padding-top: 24px; }
|
|
||||||
|
|
||||||
.pb-0 { padding-bottom: 0; }
|
.mt-2 {
|
||||||
.pb-1 { padding-bottom: 4px; }
|
margin-top: 8px;
|
||||||
.pb-2 { padding-bottom: 8px; }
|
}
|
||||||
.pb-3 { padding-bottom: 16px; }
|
|
||||||
.pb-4 { padding-bottom: 24px; }
|
|
||||||
|
|
||||||
.pl-0 { padding-left: 0; }
|
.mt-3 {
|
||||||
.pl-1 { padding-left: 4px; }
|
margin-top: 16px;
|
||||||
.pl-2 { padding-left: 8px; }
|
}
|
||||||
.pl-3 { padding-left: 16px; }
|
|
||||||
.pl-4 { padding-left: 24px; }
|
|
||||||
|
|
||||||
.pr-0 { padding-right: 0; }
|
.mt-4 {
|
||||||
.pr-1 { padding-right: 4px; }
|
margin-top: 24px;
|
||||||
.pr-2 { padding-right: 8px; }
|
}
|
||||||
.pr-3 { padding-right: 16px; }
|
|
||||||
.pr-4 { padding-right: 24px; }
|
.mb-0 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-1 {
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-2 {
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-3 {
|
||||||
|
margin-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mb-4 {
|
||||||
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-0 {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-1 {
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-2 {
|
||||||
|
margin-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-3 {
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ml-4 {
|
||||||
|
margin-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mr-0 {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mr-1 {
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mr-2 {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mr-3 {
|
||||||
|
margin-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mr-4 {
|
||||||
|
margin-right: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-0 {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-1 {
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-2 {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-3 {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.p-4 {
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pt-0 {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pt-1 {
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pt-2 {
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pt-3 {
|
||||||
|
padding-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pt-4 {
|
||||||
|
padding-top: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pb-0 {
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pb-1 {
|
||||||
|
padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pb-2 {
|
||||||
|
padding-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pb-3 {
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pb-4 {
|
||||||
|
padding-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pl-0 {
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pl-1 {
|
||||||
|
padding-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pl-2 {
|
||||||
|
padding-left: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pl-3 {
|
||||||
|
padding-left: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pl-4 {
|
||||||
|
padding-left: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pr-0 {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pr-1 {
|
||||||
|
padding-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pr-2 {
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pr-3 {
|
||||||
|
padding-right: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pr-4 {
|
||||||
|
padding-right: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
/* 布局工具类 */
|
/* 布局工具类 */
|
||||||
.flex {
|
.flex {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-column {
|
.flex-column {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-center {
|
.flex-center {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-between {
|
.flex-between {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-align-center {
|
.flex-align-center {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-justify-center {
|
.flex-justify-center {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.flex-wrap {
|
.flex-wrap {
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-1 {
|
||||||
|
flex: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 边框样式 */
|
/* 边框样式 */
|
||||||
.border {
|
|
||||||
border: 1px solid var(--border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-top {
|
|
||||||
border-top: 1px solid var(--border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-bottom {
|
|
||||||
border-bottom: 1px solid var(--border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-left {
|
|
||||||
border-left: 1px solid var(--border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.border-right {
|
|
||||||
border-right: 1px solid var(--border-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded {
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.rounded-lg {
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* 圆角 */
|
||||||
.rounded-full {
|
.rounded-full {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 背景色 */
|
/* 背景色 */
|
||||||
.bg-primary {
|
.bg-primary {
|
||||||
background-color: var(--bg-primary);
|
background-color: var(--bg-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-secondary {
|
.bg-secondary {
|
||||||
background-color: var(--bg-secondary);
|
background-color: var(--bg-secondary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-primary-color {
|
.bg-primary-color {
|
||||||
background-color: var(--primary-color);
|
background-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-success-color {
|
.bg-success-color {
|
||||||
background-color: var(--success-color);
|
background-color: var(--success-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-warning-color {
|
.bg-warning-color {
|
||||||
background-color: var(--warning-color);
|
background-color: var(--warning-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.bg-error-color {
|
.bg-error-color {
|
||||||
background-color: var(--error-color);
|
background-color: var(--error-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 尺寸工具类 */
|
|
||||||
.w-full {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-full {
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.w-auto {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-auto {
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 隐藏元素 */
|
/* 隐藏元素 */
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 显示元素 */
|
/* 显示元素 */
|
||||||
.block {
|
.block {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
|
||||||
|
|
||||||
/* 溢出处理 */
|
|
||||||
.overflow-hidden {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.overflow-auto {
|
|
||||||
overflow: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 文本截断 */
|
/* 文本截断 */
|
||||||
.text-ellipsis {
|
.text-ellipsis {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 透明度 */
|
|
||||||
.opacity-100 { opacity: 1; }
|
/* 字体 */
|
||||||
.opacity-75 { opacity: 0.75; }
|
|
||||||
.opacity-50 { opacity: 0.5; }
|
.font-w500 {
|
||||||
.opacity-25 { opacity: 0.25; }
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "alipayNumber";
|
||||||
|
src: url("/static/font/AlipayNumber.ttf") format("truetype");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "wxNumberRegular";
|
||||||
|
src: url("/static/font/WeChatSansStd-Regular.otf");
|
||||||
|
}
|
||||||
|
|
||||||
|
@font-face {
|
||||||
|
font-family: "wxNumberMedium";
|
||||||
|
src: url("/static/font/WeChatSansStd-Medium.otf");
|
||||||
|
}
|
||||||
|
|
||||||
|
.alipay-font {
|
||||||
|
font-family: "alipayNumber";
|
||||||
|
}
|
||||||
|
|
||||||
|
.wx-font-regular {
|
||||||
|
font-family: "wxNumberRegular";
|
||||||
|
}
|
||||||
|
|
||||||
|
.wx-font-medium {
|
||||||
|
font-family: "wxNumberMedium";
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,144 @@
|
||||||
|
<template>
|
||||||
|
<view class="balance-list-container">
|
||||||
|
<view>
|
||||||
|
<view v-for="item in props.list" :key="item.name" class="balance-item"
|
||||||
|
:class="{ 'flex-align-center': isBalance }">
|
||||||
|
<image class="img" :src="item.imgUrl" mode="aspectFill"></image>
|
||||||
|
<view class="balance-item-text-container">
|
||||||
|
<view class="balance-item-text">
|
||||||
|
<view>
|
||||||
|
<text class="name">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
<view v-if="item.classification">
|
||||||
|
<text class="time secondary">{{ item.classification }}</text>
|
||||||
|
</view>
|
||||||
|
<view>
|
||||||
|
<text class="time secondary">{{ item.time }}</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
<view class="balance-item-text text-right" :class="{ 'flex-between': isBalance }">
|
||||||
|
<view class="money alipay-font"
|
||||||
|
:class="item.isAdd ? (isBalance ? 'add-color' : 'red-add-color') : 'minus-color'">
|
||||||
|
{{ item.isAdd ? '+' : '-' }}{{ Number(item.money).toFixed(2) }}
|
||||||
|
</view>
|
||||||
|
<view v-if="item.isRefund" class="refund">已全额退款</view>
|
||||||
|
<view v-if="isBalance" class="balance secondary">余额 <text class="balance-text">{{
|
||||||
|
Number(item.balance).toFixed(2)
|
||||||
|
}}</text>元</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
defineProps,
|
||||||
|
defineEmits,
|
||||||
|
onMounted,
|
||||||
|
reactive
|
||||||
|
} from 'vue'
|
||||||
|
|
||||||
|
// 定义组件属性
|
||||||
|
const props = defineProps({
|
||||||
|
list: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
},
|
||||||
|
isBalance: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 定义事件
|
||||||
|
const emit = defineEmits(['onBill'])
|
||||||
|
|
||||||
|
const data = reactive({})
|
||||||
|
|
||||||
|
onMounted(() => {})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* @import '../../common/main.css'; */
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.balance-list-container {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-item {
|
||||||
|
display: flex;
|
||||||
|
width: 100%;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
.balance-item-text-container {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-left: 12px;
|
||||||
|
box-shadow: 0 0.3px 0 0 #F0F0EE;
|
||||||
|
padding: 12px 12px 12px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.img {
|
||||||
|
margin: 12px 0;
|
||||||
|
width: 30px;
|
||||||
|
height: 30px;
|
||||||
|
border-radius: 50%;
|
||||||
|
margin-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-item-text {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
// justify-content: space-between;
|
||||||
|
|
||||||
|
.name {
|
||||||
|
color: #343434;
|
||||||
|
}
|
||||||
|
|
||||||
|
.secondary {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.money {
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.add-color {
|
||||||
|
color: #F6610F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-add-color {
|
||||||
|
color: #F53646;
|
||||||
|
}
|
||||||
|
|
||||||
|
.minus-color {
|
||||||
|
color: #333333;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.balance-text {
|
||||||
|
margin-right: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.refund {
|
||||||
|
color: #EA6B48;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-right {
|
||||||
|
align-items: flex-end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,71 +1,207 @@
|
||||||
<template>
|
<template>
|
||||||
<view class="nav-bar-container">
|
<view style="width: 100%;" :style="{ height: `${data.statusBarHeight + 44}px` }"></view>
|
||||||
<view class="status-placeholder" :style="{height:`${data.statusBarHeight}px`}"></view>
|
<view class="nav-bar-container" :style="{ backgroundColor: bgColor }">
|
||||||
<uni-nav-bar class="nav-bar" :border="false" :title="title" v-bind="$attrs" v-on="$attrs">
|
<view class="status-placeholder" :style="{ height: `${data.statusBarHeight}px` }"></view>
|
||||||
|
<uni-nav-bar backgroundColor="#00000000" class="nav-bar" :border="false" :title="title" v-bind="$attrs"
|
||||||
|
v-on="$attrs">
|
||||||
<template v-slot:left>
|
<template v-slot:left>
|
||||||
<slot name="left">
|
<view class="nav-bar-left">
|
||||||
|
<slot name="left">
|
||||||
|
<view class="left-icon" @click="onBack">
|
||||||
|
<image class="nav-icon-back" src="/static/image/nav-bar/back-black.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<view class="nav-bar-title w100 h100 flex-1" @click="openPopup">
|
||||||
|
<slot name="center">
|
||||||
|
{{ title }}
|
||||||
</slot>
|
</slot>
|
||||||
|
</view>
|
||||||
|
<template v-slot:right>
|
||||||
|
<view class="nav-bar-right" @click="onRightClick">
|
||||||
|
<slot name="right">
|
||||||
|
<view v-if="isRightIcon" class="right-icon">
|
||||||
|
<image class="nav-icon-more" src="/static/image/nav-bar/more-black.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view v-if="isRightButton" class="right-button">
|
||||||
|
{{ rightButtonText }}
|
||||||
|
</view>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
</template>
|
</template>
|
||||||
</uni-nav-bar>
|
</uni-nav-bar>
|
||||||
|
<popup ref="topPopup">
|
||||||
|
<view class="button-group w100 flex-between flex-wrap">
|
||||||
|
<view class="button-box" v-for="button in buttonGroup" @click="buttonClick(button)">
|
||||||
|
<view class="button">
|
||||||
|
{{ button.name }}
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</popup>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import {
|
import popup from '../popup/popup.vue'
|
||||||
defineProps,
|
import {
|
||||||
defineEmits,
|
defineProps,
|
||||||
onMounted,
|
defineEmits,
|
||||||
reactive
|
onMounted,
|
||||||
} from 'vue'
|
reactive,
|
||||||
|
ref
|
||||||
|
} from 'vue'
|
||||||
|
|
||||||
// 定义组件属性
|
const topPopup = ref()
|
||||||
const props = defineProps({})
|
|
||||||
|
|
||||||
// 定义事件
|
// 定义组件属性
|
||||||
const emit = defineEmits(['back', 'right-click'])
|
const props = defineProps({
|
||||||
|
bgColor: {
|
||||||
const data = reactive({
|
type: String,
|
||||||
statusBarHeight: 0
|
default: '#fff'
|
||||||
})
|
},
|
||||||
|
title: {
|
||||||
onMounted(() => {
|
type: String,
|
||||||
// 同步获取系统信息
|
default: ''
|
||||||
const systemInfo = uni.getSystemInfoSync();
|
},
|
||||||
data.statusBarHeight = systemInfo.statusBarHeight || 0;
|
buttonGroup: {
|
||||||
})
|
type: Array,
|
||||||
|
default: () => []
|
||||||
// 返回按钮点击事件
|
},
|
||||||
const onBack = () => {
|
isRightIcon: {
|
||||||
emit('back')
|
type: Boolean,
|
||||||
// 默认返回上一页
|
default: false
|
||||||
uni.navigateBack()
|
},
|
||||||
|
isRightButton: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
rightButtonText: {
|
||||||
|
type: String,
|
||||||
|
default: '确定'
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
// 右侧按钮点击事件
|
// 定义事件
|
||||||
const onRightClick = () => {
|
const emit = defineEmits(['back', 'right-click', 'button-click'])
|
||||||
emit('right-click')
|
|
||||||
|
const data = reactive({
|
||||||
|
statusBarHeight: 0
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 同步获取系统信息
|
||||||
|
const systemInfo = uni.getSystemInfoSync();
|
||||||
|
data.statusBarHeight = systemInfo.statusBarHeight || 0;
|
||||||
|
})
|
||||||
|
|
||||||
|
const openPopup = () => {
|
||||||
|
if (props.buttonGroup.length > 0) {
|
||||||
|
topPopup.value.open()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 返回按钮点击事件
|
||||||
|
const onBack = () => {
|
||||||
|
emit('back')
|
||||||
|
// 默认返回上一页
|
||||||
|
uni.navigateBack()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 右侧按钮点击事件
|
||||||
|
const onRightClick = () => {
|
||||||
|
emit('right-click')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const buttonClick = (button) => {
|
||||||
|
topPopup.value.close()
|
||||||
|
emit('button-click', button)
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.nav-bar-container{
|
.nav-bar-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
position: fixed !important;
|
||||||
.nav-bar {
|
top: 0;
|
||||||
width: 100%;
|
left: 0;
|
||||||
display: flex;
|
right: 0;
|
||||||
align-items: center;
|
z-index: 999;
|
||||||
justify-content: space-between;
|
}
|
||||||
position: relative;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.status-placeholder {
|
.nav-bar {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
position: relative;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
::v-deep .uni-navbar__content {
|
.status-placeholder {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::v-deep .uni-navbar__content {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-bar-left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-icon-back {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-icon-more {
|
||||||
|
width: 26px;
|
||||||
|
height: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-bar-title {
|
||||||
|
flex: 1;
|
||||||
|
margin: auto;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
font-size: 17px;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-bar-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-button {
|
||||||
|
font-size: 12px;
|
||||||
|
border-radius: 16px;
|
||||||
|
color: #fff;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 30px;
|
||||||
|
height: 30px;
|
||||||
|
min-width: 60px;
|
||||||
|
background: linear-gradient(90deg, #187AFF 0%, #3295FC 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-box {
|
||||||
|
width: calc(50% - 8rpx);
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 16rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
border: 1px solid #E4E4E4;
|
||||||
|
border-radius: 8px;
|
||||||
|
height: 42px;
|
||||||
|
line-height: 42px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -0,0 +1,96 @@
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<!-- 弹窗 -->
|
||||||
|
<uni-popup ref="popup" type="center" border-radius="10px" background-color="rgba(0,0,0,0)">
|
||||||
|
<view class="topBtnBox">
|
||||||
|
<slot></slot>
|
||||||
|
</view>
|
||||||
|
<view class="topBtnBoxbottom" @click="close()">
|
||||||
|
<uni-icons type="clear" color="#AAA" size='40'></uni-icons>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
|
||||||
|
<!-- 底部弹窗 -->
|
||||||
|
<uni-popup class="popup-bottom" ref="popupBottom" type="bottom" border-radius="10px"
|
||||||
|
background-color="rgba(0,0,0,0)">
|
||||||
|
<view class="popup-bottom-box">
|
||||||
|
<slot>
|
||||||
|
</slot>
|
||||||
|
</view>
|
||||||
|
</uni-popup>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
ref
|
||||||
|
} from 'vue';
|
||||||
|
export default {
|
||||||
|
name: "popup",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} e
|
||||||
|
* bottom top lef right
|
||||||
|
* 打开弹窗
|
||||||
|
*/
|
||||||
|
open(e) {
|
||||||
|
switch (e) {
|
||||||
|
case "bottom":
|
||||||
|
this.$refs.popupBottom.open(e)
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
this.$refs.popup.open(e)
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 关闭弹窗
|
||||||
|
*/
|
||||||
|
close() {
|
||||||
|
this.$refs.popup.close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
.popup-box {
|
||||||
|
padding: 32rpx;
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 32rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topBtnBox {
|
||||||
|
background-color: #fff;
|
||||||
|
width: 80vw;
|
||||||
|
padding: 32rpx;
|
||||||
|
border-radius: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.topBtnBoxbottom {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-top: 36rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.popup-bottom {
|
||||||
|
.popup-bottom-box {
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 32rpx 32rpx 0 0;
|
||||||
|
background-color: #EDEDED;
|
||||||
|
height: 100rpx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
67
pages.json
|
|
@ -1,26 +1,45 @@
|
||||||
{
|
{
|
||||||
"pages": [
|
"pages": [
|
||||||
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
|
||||||
{
|
{
|
||||||
"path": "pages/balance/index",
|
"path": "pages/balance/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "余额页面",
|
"navigationBarTitleText": "余额页面",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"path": "pages/index/index",
|
"path": "pages/index/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "uni-app",
|
"navigationBarTitleText": "uni-app",
|
||||||
"navigationStyle": "custom"
|
"navigationStyle": "custom"
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
],
|
{
|
||||||
"globalStyle": {
|
"path": "pages/bill/bill-list/bill-list",
|
||||||
"navigationBarTextStyle": "black",
|
"style": {
|
||||||
"navigationBarTitleText": "uni-app",
|
"navigationBarTitleText": "账单列表页面",
|
||||||
"navigationBarBackgroundColor": "#F8F8F8",
|
"navigationStyle": "custom"
|
||||||
"backgroundColor": "#F8F8F8"
|
}
|
||||||
},
|
},
|
||||||
"uniIdRouter": {}
|
{
|
||||||
|
"path": "pages/bill/add-bill/add-bill",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "新增账单",
|
||||||
|
"navigationStyle": "custom"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"globalStyle": {
|
||||||
|
"navigationBarTextStyle": "black",
|
||||||
|
"navigationBarTitleText": "uni-app",
|
||||||
|
"navigationBarBackgroundColor": "#F8F8F8",
|
||||||
|
"backgroundColor": "#F8F8F8",
|
||||||
|
"androidNavigationBar": {
|
||||||
|
"navigationBarBackgroundColor": "#00000000", // 完全透明
|
||||||
|
"navigationBarTextStyle": "white", // 虚拟按键图标颜色
|
||||||
|
"backgroundColor": "#00000000" // 背景透明
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uniIdRouter": {}
|
||||||
}
|
}
|
||||||
|
|
@ -1,316 +0,0 @@
|
||||||
<template>
|
|
||||||
<view class="container" :style="{ height: data.windowHeight + 'px' }">
|
|
||||||
<NavBar class="nav-bar" title="" :backgroundColor="data.navBar.bgColor">
|
|
||||||
<template v-slot:left>
|
|
||||||
<view class="nav-bar-left">
|
|
||||||
<image class="nav-icon" src="/static/image/nav-bar/back-white.png" mode=""></image>
|
|
||||||
<text class="nav-text">余额</text>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
</NavBar>
|
|
||||||
<view class="background-container" :style="{ 'padding-top': `${data.statusBarHeight * 2 + 124}rpx` }">
|
|
||||||
<view class="balance-box">
|
|
||||||
<view class="top-box">
|
|
||||||
<image class="img" src="/static/image/balance/safe-icon-blue.png" mode=""></image>
|
|
||||||
<text class="text">资金安全有保障</text>
|
|
||||||
<image class="img" src="/static/image/balance/right-blue.png" mode=""></image>
|
|
||||||
</view>
|
|
||||||
<view class="balance-title flex-cneter">
|
|
||||||
<text>可用余额(元)</text>
|
|
||||||
<image class="img" src="/static/image/balance/eye.png" mode=""></image>
|
|
||||||
</view>
|
|
||||||
<view class="balance flex-cneter">
|
|
||||||
<text class="text">{{ Number(balance).toFixed(2) }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="button-group">
|
|
||||||
<view class="flex-1 btn-box">
|
|
||||||
<view class="left btn flex-cneter">
|
|
||||||
<text class="text">提现</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="flex-1 btn-box">
|
|
||||||
<view class="right btn flex-cneter">
|
|
||||||
<text class="text">充值</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
<view class="menu-box">
|
|
||||||
<view class="item" v-for="item in menuList">
|
|
||||||
<image class="menu-icon" :src="`/static/image/balance/menu-icon/${item.imgLabel}.png`" mode=""></image>
|
|
||||||
<text class="icon-name">{{item.name}}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import NavBar from '@/components/nav-bar/nav-bar'
|
|
||||||
|
|
||||||
import {
|
|
||||||
deviceUtil
|
|
||||||
} from '@/utils/common';
|
|
||||||
|
|
||||||
import {
|
|
||||||
reactive,
|
|
||||||
ref,
|
|
||||||
onMounted,
|
|
||||||
watch,
|
|
||||||
toRefs
|
|
||||||
} from 'vue'
|
|
||||||
|
|
||||||
import {
|
|
||||||
onLoad
|
|
||||||
} from '@dcloudio/uni-app'
|
|
||||||
|
|
||||||
// 导入状态管理
|
|
||||||
import {
|
|
||||||
useStore
|
|
||||||
} from '@/store'
|
|
||||||
|
|
||||||
// 获取store
|
|
||||||
const {
|
|
||||||
store
|
|
||||||
} = useStore()
|
|
||||||
|
|
||||||
const menuList = [{
|
|
||||||
imgLabel: "zhuanzhang",
|
|
||||||
name: "转账"
|
|
||||||
}, {
|
|
||||||
imgLabel: "yinhangka",
|
|
||||||
name: "银行卡"
|
|
||||||
}, {
|
|
||||||
imgLabel: "qinqingka",
|
|
||||||
name: "亲情卡"
|
|
||||||
}, {
|
|
||||||
imgLabel: "xiaohebao",
|
|
||||||
name: "小荷包"
|
|
||||||
}, {
|
|
||||||
imgLabel: "zhuanyongjin",
|
|
||||||
name: "专用金"
|
|
||||||
}]
|
|
||||||
|
|
||||||
const data = reactive({
|
|
||||||
navBar: {
|
|
||||||
bgColor: "#00000000"
|
|
||||||
},
|
|
||||||
statusBarHeight: 0,
|
|
||||||
balance: 0,
|
|
||||||
windowHeight: 0
|
|
||||||
})
|
|
||||||
|
|
||||||
let {
|
|
||||||
balance
|
|
||||||
} = toRefs(data)
|
|
||||||
|
|
||||||
onLoad(async () => {
|
|
||||||
// 初始获取状态栏高度和屏幕高度
|
|
||||||
updateStatusBarHeight()
|
|
||||||
data.windowHeight = await deviceUtil.getScreenHeight()
|
|
||||||
})
|
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
// 组件挂载后再次获取,确保信息已更新
|
|
||||||
updateStatusBarHeight()
|
|
||||||
})
|
|
||||||
|
|
||||||
// 更新状态栏高度
|
|
||||||
const updateStatusBarHeight = () => {
|
|
||||||
uni.getSystemInfo({
|
|
||||||
success: (res) => {
|
|
||||||
data.statusBarHeight = res.statusBarHeight || 0
|
|
||||||
console.log('直接获取状态栏高度:', data.statusBarHeight)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 监听store中系统信息的变化
|
|
||||||
watch(() => store.systemInfo, (newVal) => {
|
|
||||||
if (newVal && newVal.statusBarHeight !== undefined) {
|
|
||||||
data.statusBarHeight = newVal.statusBarHeight
|
|
||||||
console.log('监听状态管理变化,更新状态栏高度:', data.statusBarHeight)
|
|
||||||
}
|
|
||||||
}, {
|
|
||||||
deep: true
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.container {
|
|
||||||
background-color: #F0F3F8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-cneter {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-1 {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-bar {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-bar-left {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-icon {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nav-text {
|
|
||||||
font-size: 18px;
|
|
||||||
margin-right: 4px;
|
|
||||||
color: #FFFFFF;
|
|
||||||
height: 24px;
|
|
||||||
line-height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .uni-navbar__header-btns-left {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep .uni-navbar__header-btns-right {
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.background-container {
|
|
||||||
background: linear-gradient(181deg, #1E76FE 0%, rgba(30, 118, 254, 0.74) 39%, rgba(240, 243, 248, 0.84) 90%, #F0F3F8 100%);
|
|
||||||
padding: 12px;
|
|
||||||
padding-bottom: 0;
|
|
||||||
padding-top: 62px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance-box {
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
border-radius: 12px;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-box {
|
|
||||||
background-color: #E3EFFF;
|
|
||||||
border-radius: 12px 12px 0 0;
|
|
||||||
text-align: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
padding: 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-box>.text {
|
|
||||||
color: #2977E6;
|
|
||||||
font-size: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-box>.img {
|
|
||||||
width: 14px;
|
|
||||||
height: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance-title {
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance-title>.img {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
margin-left: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance-title>.text {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #1A1A1A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance {
|
|
||||||
margin-top: 21px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.balance>.text {
|
|
||||||
color: #1A1A1A;
|
|
||||||
font-size: 40px;
|
|
||||||
font-weight: 500;
|
|
||||||
line-height: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-group {
|
|
||||||
margin: 0 12px;
|
|
||||||
margin-top: 60px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
/* box-sizing: border-box; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-box {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn {
|
|
||||||
border-radius: 24px;
|
|
||||||
height: 49px;
|
|
||||||
width: 150px;
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn>.text {
|
|
||||||
color: #1A1A1A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.left {
|
|
||||||
border: 1px solid #E2E2E2;
|
|
||||||
color: #1A1A1A;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right {
|
|
||||||
color: #fff;
|
|
||||||
background-color: #1777FF;
|
|
||||||
}
|
|
||||||
|
|
||||||
.right>.text {
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-box {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
margin-top: 8px;
|
|
||||||
border-radius: 12px;
|
|
||||||
background-color: #FFFFFF;
|
|
||||||
padding: 20px;
|
|
||||||
margin-left: 12px;
|
|
||||||
margin-right: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.item{
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.menu-icon{
|
|
||||||
width: 48rpx;
|
|
||||||
height: 48rpx;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon-name{
|
|
||||||
font-size: 24rpx;
|
|
||||||
color: var(--text-color);
|
|
||||||
margin-top: 8px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
@ -0,0 +1,529 @@
|
||||||
|
<template>
|
||||||
|
<view class="container" :style="{ height: data.windowHeight + 'px' }">
|
||||||
|
<view class="bg-container"></view>
|
||||||
|
<NavBar class="nav-bar" isRightIcon title="" :bgColor="data.navBar.bgColor" :buttonGroup="buttonGroup"
|
||||||
|
@button-click="clickTitlePopupButton">
|
||||||
|
<template v-slot:left>
|
||||||
|
<view class="nav-bar-left">
|
||||||
|
<image class="nav-icon" src="/static/image/nav-bar/back-white.png" mode=""></image>
|
||||||
|
<text class="nav-text">余额</text>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<template v-slot:right>
|
||||||
|
<view class="nav-bar-right mr-1">
|
||||||
|
<image class="nav-icon" src="/static/image/nav-bar/more-white.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</NavBar>
|
||||||
|
<scroll-view class="scroll-view" :style="{ height: (data.windowHeight - 44 - data.statusBarHeight) + 'px' }"
|
||||||
|
scroll-y="true">
|
||||||
|
<view class="h100 w100 flex-between" style="flex-direction: column;">
|
||||||
|
<view class="main-container w100 flex-1">
|
||||||
|
<view class="background-container" :style="{ 'padding-top': '36rpx' }">
|
||||||
|
<view class="balance-box">
|
||||||
|
<view class="top-box">
|
||||||
|
<image class="img" src="/static/image/balance/safe-icon-blue.png" mode=""></image>
|
||||||
|
<text class="text">资金安全有保障</text>
|
||||||
|
<image class="img" src="/static/image/balance/right-blue.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="balance-title flex-cneter">
|
||||||
|
<text>可用余额(元)</text>
|
||||||
|
<image class="img" src="/static/image/balance/eye.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="balance flex-cneter">
|
||||||
|
<text class="text alipay-font">{{ Number(balance).toFixed(2) }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="button-group">
|
||||||
|
<view class="flex-1 btn-box">
|
||||||
|
<view class="left btn flex-cneter">
|
||||||
|
<text class="text">提现</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="flex-1 btn-box">
|
||||||
|
<view class="right btn flex-cneter">
|
||||||
|
<text class="text">充值</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="menu-box">
|
||||||
|
<view class="item" v-for="item in menuList">
|
||||||
|
<image class="menu-icon" :src="`/static/image/balance/menu-icon/${item.imgLabel}.png`"
|
||||||
|
mode="">
|
||||||
|
</image>
|
||||||
|
<text class="icon-name">{{ item.name }}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="balance-change-detail-list">
|
||||||
|
<view class="title-box">
|
||||||
|
<view class="text font-w500" style="font-weight: 500;">余额变动明细</view>
|
||||||
|
<view class="title-right">
|
||||||
|
<text class="text">全部</text>
|
||||||
|
<image class="right-icon" src="/static/image/common/right-grey.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="item">
|
||||||
|
<BalanceList :list="changeDetailList" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="footer-box">
|
||||||
|
<view class="blue-text">我的客服</view>
|
||||||
|
<view class="footer-text">余额升级服务由支付宝和网商银行提供</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
</view>
|
||||||
|
<!-- 输入框示例 -->
|
||||||
|
<uni-popup ref="inputDialog" type="dialog">
|
||||||
|
<uni-popup-dialog before-close mode="input" title="修改余额" @confirm="dialogInputConfirm"
|
||||||
|
@close="dialogInputCancle">
|
||||||
|
<uni-easyinput type="digit" v-model="data.balance" focus placeholder="请输入余额"></uni-easyinput>
|
||||||
|
</uni-popup-dialog>
|
||||||
|
</uni-popup>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import NavBar from '@/components/nav-bar/nav-bar'
|
||||||
|
import BalanceList from '@/components/balance-list/balance-list.vue'
|
||||||
|
|
||||||
|
import {
|
||||||
|
util,
|
||||||
|
deviceUtil
|
||||||
|
} from '@/utils/common';
|
||||||
|
import {
|
||||||
|
storage
|
||||||
|
} from '@/utils/storage';
|
||||||
|
|
||||||
|
import {
|
||||||
|
reactive,
|
||||||
|
ref,
|
||||||
|
onMounted,
|
||||||
|
watch,
|
||||||
|
toRefs
|
||||||
|
} from 'vue'
|
||||||
|
|
||||||
|
import {
|
||||||
|
onLoad,
|
||||||
|
onShow
|
||||||
|
} from '@dcloudio/uni-app'
|
||||||
|
|
||||||
|
// 导入状态管理
|
||||||
|
import {
|
||||||
|
useStore,
|
||||||
|
} from '@/store'
|
||||||
|
|
||||||
|
// 获取store
|
||||||
|
const {
|
||||||
|
store
|
||||||
|
} = useStore()
|
||||||
|
|
||||||
|
const inputDialog = ref(null)
|
||||||
|
|
||||||
|
const menuList = [{
|
||||||
|
imgLabel: "zhuanzhang",
|
||||||
|
name: "转账"
|
||||||
|
}, {
|
||||||
|
imgLabel: "yinhangka",
|
||||||
|
name: "银行卡"
|
||||||
|
}, {
|
||||||
|
imgLabel: "qinqingka",
|
||||||
|
name: "亲情卡"
|
||||||
|
}, {
|
||||||
|
imgLabel: "xiaohebao",
|
||||||
|
name: "小荷包"
|
||||||
|
}, {
|
||||||
|
imgLabel: "zhuanyongjin",
|
||||||
|
name: "专用金"
|
||||||
|
}]
|
||||||
|
|
||||||
|
const buttonGroup = [{
|
||||||
|
name: "编辑模式",
|
||||||
|
click: () => {
|
||||||
|
console.log("编辑模式")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "修改余额",
|
||||||
|
click: () => {
|
||||||
|
console.log("修改余额")
|
||||||
|
data.balance = Number(data.balance).toFixed(2)
|
||||||
|
inputDialog.value.open()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "快捷入口管理",
|
||||||
|
click: () => {
|
||||||
|
console.log("快捷入口管理")
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
name: "账单列表",
|
||||||
|
click: () => {
|
||||||
|
util.goPage("/pages/bill/bill-list/bill-list")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
navBar: {
|
||||||
|
bgColor: "#00000000"
|
||||||
|
},
|
||||||
|
statusBarHeight: 0,
|
||||||
|
balance: 0,
|
||||||
|
windowHeight: 0,
|
||||||
|
changeDetailList: [{
|
||||||
|
time: "2023-08-15 10:00:00",
|
||||||
|
type: "充值",
|
||||||
|
money: "1000.00",
|
||||||
|
isAdd: true,
|
||||||
|
name: "充值",
|
||||||
|
balance: 1000.00,
|
||||||
|
imgUrl: "https://picsum.photos/200/200?random=1"
|
||||||
|
}, {
|
||||||
|
time: "2023-08-15 10:00:00",
|
||||||
|
type: "充值",
|
||||||
|
money: "1000.00",
|
||||||
|
isAdd: false,
|
||||||
|
name: "充值",
|
||||||
|
balance: 1000.00,
|
||||||
|
imgUrl: "https://picsum.photos/200/200?random=1"
|
||||||
|
}, {
|
||||||
|
time: "2023-08-15 10:00:00",
|
||||||
|
type: "充值",
|
||||||
|
money: "1000.00",
|
||||||
|
isAdd: true,
|
||||||
|
name: "充值",
|
||||||
|
balance: 1000.00,
|
||||||
|
imgUrl: "https://picsum.photos/200/200?random=1"
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
let {
|
||||||
|
balance,
|
||||||
|
changeDetailList
|
||||||
|
} = toRefs(data)
|
||||||
|
|
||||||
|
onLoad(async () => {
|
||||||
|
// 初始获取状态栏高度和屏幕高度
|
||||||
|
updateStatusBarHeight()
|
||||||
|
data.windowHeight = await deviceUtil.getWindowHeight()
|
||||||
|
// 从缓存读取余额
|
||||||
|
const cachedBalance = storage.get('balance')
|
||||||
|
if (cachedBalance !== null) {
|
||||||
|
data.balance = cachedBalance
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
util.setAndroidSystemBarColor('#F0F3F8')
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 组件挂载后再次获取,确保信息已更新
|
||||||
|
updateStatusBarHeight()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 更新状态栏高度
|
||||||
|
const updateStatusBarHeight = () => {
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success: (res) => {
|
||||||
|
data.statusBarHeight = res.statusBarHeight || 0
|
||||||
|
console.log('直接获取状态栏高度:', data.statusBarHeight)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听store中系统信息的变化
|
||||||
|
watch(() => store.systemInfo, (newVal) => {
|
||||||
|
if (newVal && newVal.statusBarHeight !== undefined) {
|
||||||
|
data.statusBarHeight = newVal.statusBarHeight
|
||||||
|
console.log('监听状态管理变化,更新状态栏高度:', data.statusBarHeight)
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
deep: true
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 点击标题弹出按钮
|
||||||
|
const clickTitlePopupButton = (button) => {
|
||||||
|
button.click()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 输入框确认事件
|
||||||
|
*/
|
||||||
|
const dialogInputConfirm = () => {
|
||||||
|
if (data.balance > 999999999) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '余额不能超过999999999',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
data.balance = 999999999.00
|
||||||
|
}
|
||||||
|
storage.set('balance', data.balance)
|
||||||
|
inputDialog.value.close()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击关闭输入框弹窗
|
||||||
|
*/
|
||||||
|
const dialogInputCancle = () => {
|
||||||
|
data.balance = storage.get('balance')
|
||||||
|
inputDialog.value.close()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
/* 直接在页面导入公共样式 */
|
||||||
|
@import '../../common/main.css';
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
background-color: #F0F3F8;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll-view {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bg-container {
|
||||||
|
position: absolute;
|
||||||
|
/* z-index: -1; */
|
||||||
|
width: 100%;
|
||||||
|
height: 600rpx;
|
||||||
|
background: linear-gradient(181deg, #1E76FE 0%, rgba(30, 118, 254, 0.74) 39%, rgba(240, 243, 248, 0.84) 90%, #F0F3F8 100%);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-cneter {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.flex-1 {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-bar {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-bar-left {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-icon {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-text {
|
||||||
|
font-size: 18px;
|
||||||
|
margin-right: 4px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
height: 24px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .uni-navbar__header-btns-left {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .uni-navbar__header-btns-right {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.background-container {
|
||||||
|
padding: 12px;
|
||||||
|
padding-bottom: 0;
|
||||||
|
padding-top: 62px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-box {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border-radius: 12px;
|
||||||
|
padding-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-box {
|
||||||
|
background-color: #E3EFFF;
|
||||||
|
border-radius: 12px 12px 0 0;
|
||||||
|
text-align: center;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-box>.text {
|
||||||
|
color: #2977E6;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-box>.img {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-title {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-title>.img {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-title>.text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #1A1A1A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance {
|
||||||
|
margin-top: 21px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance>.text {
|
||||||
|
color: #1A1A1A;
|
||||||
|
font-size: 40px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-group {
|
||||||
|
margin: 0 12px;
|
||||||
|
margin-top: 60px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
/* box-sizing: border-box; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
border-radius: 24px;
|
||||||
|
height: 49px;
|
||||||
|
width: 150px;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn>.text {
|
||||||
|
color: #1A1A1A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
border: 1px solid #E2E2E2;
|
||||||
|
color: #1A1A1A;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right {
|
||||||
|
color: #fff;
|
||||||
|
background-color: #1777FF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right>.text {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-top: 8px;
|
||||||
|
border-radius: 12px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
padding: 20px;
|
||||||
|
margin-left: 12px;
|
||||||
|
margin-right: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-icon {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-name {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: var(--text-color);
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.balance-change-detail-list {
|
||||||
|
border-radius: 12px;
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-left: 12px;
|
||||||
|
margin-right: 12px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
padding: 13px 12px;
|
||||||
|
justify-content: space-between;
|
||||||
|
box-shadow: 0 0.3px 0 0 #F0F0EE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-box>.text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-right {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title-right>.text {
|
||||||
|
font-size: 14px;
|
||||||
|
color: var(--text-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-icon {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-box {
|
||||||
|
margin-top: 18px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 17px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blue-text {
|
||||||
|
color: #507295;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-text {
|
||||||
|
font-size: 13px;
|
||||||
|
color: var(--footer-text-color);
|
||||||
|
margin-top: 18px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,48 @@
|
||||||
|
<template>
|
||||||
|
<view style="overflow: hidden;height: 100vh;">
|
||||||
|
<navBar isRightButton :title="data.navBar.title" :bgColor="data.navBar.bgColor" @right-click="onRightClick">
|
||||||
|
</navBar>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import navBar from '@/components/nav-bar/nav-bar.vue'
|
||||||
|
|
||||||
|
import {
|
||||||
|
reactive,
|
||||||
|
toRefs,
|
||||||
|
ref,
|
||||||
|
onMounted
|
||||||
|
} from 'vue'
|
||||||
|
import {
|
||||||
|
onShow,
|
||||||
|
} from '@dcloudio/uni-app'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
navBar: {
|
||||||
|
title: '新增账单',
|
||||||
|
bgColor: '#F5F5F5',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
let {
|
||||||
|
} = toRefs(data)
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
})
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@import "@/common/main.css";
|
||||||
|
|
||||||
|
page {
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="less" scoped></style>
|
||||||
|
|
@ -0,0 +1,704 @@
|
||||||
|
<template>
|
||||||
|
<view style="overflow: hidden;height: 100vh;;">
|
||||||
|
<navBar isRightIcon :bgColor="data.navBar.bgColor" :buttonGroup="data.navBar.buttonGroup"
|
||||||
|
@button-click="clickTitlePopupButton">
|
||||||
|
<template v-slot:center>
|
||||||
|
<view class="nav-bar-search flex-align-center flex-1">
|
||||||
|
<image class="search-icon" src="/static/image/bill/bill-list/search-black.png" mode=""></image>
|
||||||
|
<input type="text" class="search-input flex-1" placeholder="请输入搜索内容" />
|
||||||
|
<view class="line h100"></view>
|
||||||
|
<view class="search-button">搜索</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</navBar>
|
||||||
|
<view class="filter-box">
|
||||||
|
<view class="filter-line">
|
||||||
|
<view class="filter-item w100" :class="{ 'active-text': item.value == currentFilterType }"
|
||||||
|
v-for="item in filterType" :key="item.value">
|
||||||
|
{{ item.name }}
|
||||||
|
</view>
|
||||||
|
<view style="width: 100rpx; flex-shrink: 0;"></view>
|
||||||
|
</view>
|
||||||
|
<view class="filter-button blur"></view>
|
||||||
|
<view class="filter-button">
|
||||||
|
筛选
|
||||||
|
<image class="filter-icon" src="/static/image/bill/bill-list/down-black.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view style="height: 48px;"></view>
|
||||||
|
<scroll-view :scroll-y="true" class="bill-list-container"
|
||||||
|
:style="{ height: `calc(100vh - ${92 + data.statusBarHeight}px)` }" @scroll="scrollList">
|
||||||
|
<view class="sticky-conatianer" v-if="data.currentScrollTop > 100">
|
||||||
|
<view class="month">
|
||||||
|
<text class="font-w500">{{ currentMonthData.month }}</text>月
|
||||||
|
<image class="down" src="/static/image/bill/bill-list/down-black.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="income-ande-outCome flex-between">
|
||||||
|
<view class="flex">
|
||||||
|
<view class="item"><text>支出¥</text><text class="money wx-font-regular">{{
|
||||||
|
Number(currentMonthData.outCome).toFixed(2) }}</text></view>
|
||||||
|
<view class="item"><text>收入¥</text><text class="money wx-font-regular">{{
|
||||||
|
Number(currentMonthData.inCome).toFixed(2) }}</text></view>
|
||||||
|
</view>
|
||||||
|
<view class="">
|
||||||
|
<text>收支分析</text>
|
||||||
|
<uni-icons type="right" color="#555555" size="14"></uni-icons>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bill-list-card" v-for="(item, index) in billList" :key="index"
|
||||||
|
:ref="el => cardRefs[index] = el">
|
||||||
|
<view class="list-title-card"
|
||||||
|
:class="{ 'current-month': item.month == new Date().getMonth() + 1 && item.year == new Date().getFullYear() }">
|
||||||
|
<view class="list-title">
|
||||||
|
<text class="month alipay-font">{{ item.month }}</text>
|
||||||
|
<text>月</text>
|
||||||
|
<image class="filter-icon down " src="/static/image/bill/bill-list/down-black.png" mode="">
|
||||||
|
</image>
|
||||||
|
</view>
|
||||||
|
<view class="flex-between analysis-box">
|
||||||
|
<view class="income-ande-outCome">
|
||||||
|
<view class="income item">
|
||||||
|
<text class="title">收入</text>
|
||||||
|
<text class="amount alipay-font"><text class="font-11 wx-font-regular">¥</text>{{
|
||||||
|
Number(item.inCome).toFixed(2)
|
||||||
|
}}</text>
|
||||||
|
</view>
|
||||||
|
<view class="outCome item">
|
||||||
|
<text class="title">支出</text>
|
||||||
|
<text class="amount alipay-font"><text class="font-11 wx-font-regular">¥</text>{{
|
||||||
|
Number(item.outCome).toFixed(2)
|
||||||
|
}}</text>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="!(item.month == new Date().getMonth() + 1 && item.year == new Date().getFullYear())"
|
||||||
|
class="analysis-button">
|
||||||
|
收支分析
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view v-if="item.month == new Date().getMonth() + 1 && item.year == new Date().getFullYear()"
|
||||||
|
class="income-ande-outCome-analysis">
|
||||||
|
<view class="left-box">
|
||||||
|
<text class="text">设置支出预算</text>
|
||||||
|
<image class="right-icon" src="/static/image/common/right-black.png" mode=""></image>
|
||||||
|
</view>
|
||||||
|
<view class="analysis-button">
|
||||||
|
收支分析
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="bill-list">
|
||||||
|
<BalanceList :isBalance="false" :list="item.list" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</scroll-view>
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import navBar from '@/components/nav-bar/nav-bar.vue'
|
||||||
|
import BalanceList from '@/components/balance-list/balance-list.vue'
|
||||||
|
|
||||||
|
import {
|
||||||
|
reactive,
|
||||||
|
toRefs,
|
||||||
|
ref,
|
||||||
|
onMounted
|
||||||
|
} from 'vue'
|
||||||
|
import {
|
||||||
|
onShow,
|
||||||
|
} from '@dcloudio/uni-app'
|
||||||
|
|
||||||
|
// 存储卡片的 ref
|
||||||
|
const cardRefs = ref([])
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 筛选类型
|
||||||
|
*/
|
||||||
|
const filterType = [{
|
||||||
|
name: '全部',
|
||||||
|
value: 'all'
|
||||||
|
}, {
|
||||||
|
name: '支出',
|
||||||
|
value: 'income'
|
||||||
|
}, {
|
||||||
|
name: '转账',
|
||||||
|
value: 'transfer'
|
||||||
|
}, {
|
||||||
|
name: '退款',
|
||||||
|
value: 'refund'
|
||||||
|
}, {
|
||||||
|
name: '订单',
|
||||||
|
value: 'order'
|
||||||
|
}, {
|
||||||
|
name: '还款',
|
||||||
|
value: 'repayment'
|
||||||
|
}, {
|
||||||
|
name: '线下消费',
|
||||||
|
value: 'offline-consumption'
|
||||||
|
}, {
|
||||||
|
name: '充值缴费',
|
||||||
|
value: 'recharge'
|
||||||
|
}, {
|
||||||
|
name: '网购',
|
||||||
|
value: 'online-shopping'
|
||||||
|
}, {
|
||||||
|
name: '二维码收款',
|
||||||
|
value: 'qr-code-receiving'
|
||||||
|
}]
|
||||||
|
|
||||||
|
const buttonGroup = [{
|
||||||
|
name: "新增账单",
|
||||||
|
click: () => {
|
||||||
|
uni.navigateTo({
|
||||||
|
url: '/pages/bill/add-bill/add-bill'
|
||||||
|
})
|
||||||
|
console.log("新增账单")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const data = reactive({
|
||||||
|
navBar: {
|
||||||
|
bgColor: '#F5F5F5',
|
||||||
|
buttonGroup: buttonGroup
|
||||||
|
},
|
||||||
|
statusBarHeight: 0,
|
||||||
|
currentScrollTop: 0,
|
||||||
|
currentFilterType: 'all', // 当前筛选类型
|
||||||
|
currentMonthData: {
|
||||||
|
month: '',
|
||||||
|
year: '',
|
||||||
|
inCome: 0,
|
||||||
|
outCome: 0,
|
||||||
|
}, // 当前滚动到的月份
|
||||||
|
cardPositions: [], // 存储每个卡片距离 scroll-view 顶部的距离
|
||||||
|
billList: [{
|
||||||
|
year: '2025',
|
||||||
|
month: '12',
|
||||||
|
inCome: 999999999.00,
|
||||||
|
outCome: 999999999.00,
|
||||||
|
list: [{
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: false,
|
||||||
|
isAdd: false,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}, {
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: true,
|
||||||
|
isAdd: false,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}, {
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: false,
|
||||||
|
isAdd: true,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
year: '2025',
|
||||||
|
month: '11',
|
||||||
|
inCome: 999999999.00,
|
||||||
|
outCome: 999999999.00,
|
||||||
|
list: [{
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: false,
|
||||||
|
isAdd: false,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}, {
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: true,
|
||||||
|
isAdd: false,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}, {
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: false,
|
||||||
|
isAdd: true,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
year: '2025',
|
||||||
|
month: '10',
|
||||||
|
inCome: 999999999.00,
|
||||||
|
outCome: 999999999.00,
|
||||||
|
list: [{
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: false,
|
||||||
|
isAdd: false,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}, {
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: true,
|
||||||
|
isAdd: false,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}, {
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: false,
|
||||||
|
isAdd: true,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
year: '2025',
|
||||||
|
month: '9',
|
||||||
|
inCome: 999999999.00,
|
||||||
|
outCome: 999999999.00,
|
||||||
|
list: [{
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: false,
|
||||||
|
isAdd: false,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}, {
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: true,
|
||||||
|
isAdd: false,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}, {
|
||||||
|
orderId: '1234567890',
|
||||||
|
imgUrl: 'https://picsum.photos/200/200?random=1',
|
||||||
|
name: '测试',
|
||||||
|
amount: 999999999.00,
|
||||||
|
classification: '日荣百货',
|
||||||
|
isRefund: false,
|
||||||
|
isAdd: true,
|
||||||
|
money: "200",
|
||||||
|
time: '2025-12-27 18:18:18'
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
|
let {
|
||||||
|
billList,
|
||||||
|
currentMonthData,
|
||||||
|
currentFilterType
|
||||||
|
} = toRefs(data)
|
||||||
|
|
||||||
|
onShow(() => {
|
||||||
|
// 初始获取状态栏高度和屏幕高度
|
||||||
|
updateStatusBarHeight()
|
||||||
|
})
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
// 在组件挂载后获取卡片位置
|
||||||
|
getCardPositions()
|
||||||
|
})
|
||||||
|
|
||||||
|
// 更新状态栏高度
|
||||||
|
const updateStatusBarHeight = () => {
|
||||||
|
uni.getSystemInfo({
|
||||||
|
success: (res) => {
|
||||||
|
data.statusBarHeight = res.statusBarHeight || 0
|
||||||
|
console.log('直接获取状态栏高度:', data.statusBarHeight)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取所有卡片相对于 scroll-view 顶部的距离
|
||||||
|
*/
|
||||||
|
const getCardPositions = () => {
|
||||||
|
uni.createSelectorQuery().select('.bill-list-container').boundingClientRect(scrollViewRect => {
|
||||||
|
uni.createSelectorQuery().selectAll('.bill-list-card').boundingClientRect(cardRects => {
|
||||||
|
if (cardRects && cardRects.length > 0 && scrollViewRect) {
|
||||||
|
// 计算每个卡片相对于 scroll-view 顶部的距离
|
||||||
|
data.cardPositions = cardRects.map(rect => rect.top - scrollViewRect.top)
|
||||||
|
console.log('卡片位置数据:', data.cardPositions)
|
||||||
|
}
|
||||||
|
}).exec()
|
||||||
|
}).exec()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 滚动列表
|
||||||
|
*/
|
||||||
|
const scrollList = (e) => {
|
||||||
|
data.currentScrollTop = e.detail.scrollTop
|
||||||
|
console.log("滚动高度", data.currentScrollTop)
|
||||||
|
|
||||||
|
// 使用卡片位置数据
|
||||||
|
if (data.cardPositions && data.cardPositions.length > 0) {
|
||||||
|
// 找出当前可见的卡片(示例)
|
||||||
|
const visibleCards = data.cardPositions.map((position, index) => ({
|
||||||
|
index,
|
||||||
|
position,
|
||||||
|
isVisible: position <= data.currentScrollTop + data.statusBarHeight + 100
|
||||||
|
}))
|
||||||
|
|
||||||
|
console.log("可见卡片:", visibleCards)
|
||||||
|
|
||||||
|
// 找出当前最顶部的卡片索引
|
||||||
|
const currentCardIndex = data.cardPositions.findIndex(position =>
|
||||||
|
position > data.currentScrollTop
|
||||||
|
)
|
||||||
|
|
||||||
|
console.log("当前最顶部卡片索引:", currentCardIndex)
|
||||||
|
|
||||||
|
// 获取当前最顶部卡片的月份
|
||||||
|
let currentMonthIndex = currentCardIndex
|
||||||
|
if (currentCardIndex === -1) {
|
||||||
|
// 所有卡片都在视口上方,取最后一个卡片
|
||||||
|
currentMonthIndex = data.billList.length - 1
|
||||||
|
} else if (currentCardIndex > 0) {
|
||||||
|
// 当前视口最顶部的卡片是currentCardIndex - 1
|
||||||
|
currentMonthIndex = currentCardIndex - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置当前滚动到的月份
|
||||||
|
if (currentMonthIndex >= 0 && currentMonthIndex < data.billList.length) {
|
||||||
|
data.currentMonthData.month = parseInt(data.billList[currentMonthIndex].month)
|
||||||
|
data.currentMonthData.year = data.billList[currentMonthIndex].year
|
||||||
|
data.currentMonthData.inCome = data.billList[currentMonthIndex].inCome
|
||||||
|
data.currentMonthData.outCome = data.billList[currentMonthIndex].outCome
|
||||||
|
console.log("当前滚动到的月份:", data.currentMonthData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点击标题弹出按钮
|
||||||
|
* @param e
|
||||||
|
*/
|
||||||
|
const clickTitlePopupButton = (button) => {
|
||||||
|
button.click()
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
@import "@/common/main.css";
|
||||||
|
|
||||||
|
page {
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.nav-bar-search {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 4px;
|
||||||
|
height: 32px;
|
||||||
|
padding: 4px 0;
|
||||||
|
|
||||||
|
.search-icon {
|
||||||
|
width: 32rpx;
|
||||||
|
height: 32rpx;
|
||||||
|
margin-left: 4px;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-input {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .input-placeholder {
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.line {
|
||||||
|
width: 1px;
|
||||||
|
background-color: var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.search-button {
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 0 12px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .uni-navbar__header-btns-right {
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep .uni-navbar__header-btns-left {
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-box {
|
||||||
|
position: fixed;
|
||||||
|
height: 48px;
|
||||||
|
width: 100%;
|
||||||
|
z-index: 1;
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
|
||||||
|
.filter-button {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 120rpx;
|
||||||
|
height: 28px;
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.blur {
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
filter: blur(5px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-icon {
|
||||||
|
width: 24rpx;
|
||||||
|
height: 24rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-line {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
margin: 0 12px;
|
||||||
|
margin-top: 10px;
|
||||||
|
overflow: hidden;
|
||||||
|
overflow-x: scroll;
|
||||||
|
|
||||||
|
.filter-item {
|
||||||
|
background-color: #ffffff;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-size: 14px;
|
||||||
|
padding: 4px 16px;
|
||||||
|
width: auto;
|
||||||
|
border-radius: 14px;
|
||||||
|
margin-right: 8px;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.active-text {
|
||||||
|
color: #1B71F8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bill-list-container {
|
||||||
|
position: relative;
|
||||||
|
// padding: 0 12px;
|
||||||
|
flex: 1;
|
||||||
|
padding-bottom: 12px;
|
||||||
|
|
||||||
|
.sticky-conatianer {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
background-color: #F5F5F5;
|
||||||
|
padding: 12px;
|
||||||
|
z-index: 1;
|
||||||
|
|
||||||
|
.month {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 13px;
|
||||||
|
|
||||||
|
.down {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-ande-outCome {
|
||||||
|
display: flex;
|
||||||
|
font-size: 13px;
|
||||||
|
margin-top: 6px;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
margin-right: 16px;
|
||||||
|
|
||||||
|
.money {
|
||||||
|
font-size: 12px;
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.bill-list-card {
|
||||||
|
border-radius: 8px;
|
||||||
|
margin: 0 12px;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
|
||||||
|
.list-title-card {
|
||||||
|
background-color: #FFFFFF;
|
||||||
|
border-radius: 8px 8px 0 0;
|
||||||
|
padding: 10px 12px;
|
||||||
|
|
||||||
|
.month {
|
||||||
|
font-size: 32px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.down {
|
||||||
|
margin-left: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-ande-outCome {
|
||||||
|
margin-top: 8px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 80px;
|
||||||
|
max-width: 120px;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
.font-11 {
|
||||||
|
font-size: 12px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.amount {
|
||||||
|
font-size: 16px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-box {
|
||||||
|
align-items: flex-end;
|
||||||
|
|
||||||
|
.analysis-button {
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: linear-gradient(90deg, #187AFF 0%, #3295FC 100%);
|
||||||
|
border-radius: 16px 16px 16px 16px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
height: 32px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-month {
|
||||||
|
padding: 10px 12px 18px;
|
||||||
|
background: url('/static/image/bill/bill-list/current-month-bill-bg.png') no-repeat center center;
|
||||||
|
background-size: 100% 100%;
|
||||||
|
|
||||||
|
.income-ande-outCome {
|
||||||
|
margin-top: 8px;
|
||||||
|
display: flex;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-width: 80px;
|
||||||
|
max-width: 120px;
|
||||||
|
margin-right: 10px;
|
||||||
|
|
||||||
|
.font-11 {
|
||||||
|
font-size: 12px;
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 12px;
|
||||||
|
color: var(--text-secondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.amount {
|
||||||
|
font-size: 16px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.income-ande-outCome-analysis {
|
||||||
|
margin-top: 3px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.left-box {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-end;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
|
||||||
|
.text {
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 14px;
|
||||||
|
color: var(--text-primary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-icon {
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.analysis-button {
|
||||||
|
padding: 8px 12px;
|
||||||
|
background: linear-gradient(90deg, #187AFF 0%, #3295FC 100%);
|
||||||
|
border-radius: 16px 16px 16px 16px;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-size: 12px;
|
||||||
|
line-height: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,321 +1,3 @@
|
||||||
<template>
|
<template></template>
|
||||||
<view class="container">
|
<script setup></script>
|
||||||
<view class="header">
|
<style></style>
|
||||||
<text class="title">公共方法使用示例</text>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<view class="content">
|
|
||||||
<!-- 日期处理示例 -->
|
|
||||||
<view class="section">
|
|
||||||
<text class="section-title">日期处理</text>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">当前日期:</text>
|
|
||||||
<text class="value">{{ currentDate }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">格式化日期:</text>
|
|
||||||
<text class="value">{{ formattedDate }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">相对时间:</text>
|
|
||||||
<text class="value">{{ relativeDate }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 数字处理示例 -->
|
|
||||||
<view class="section">
|
|
||||||
<text class="section-title">数字处理</text>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">千分位格式化:</text>
|
|
||||||
<text class="value">{{ formattedNumber }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">金额格式化:</text>
|
|
||||||
<text class="value">{{ formattedMoney }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">随机数:</text>
|
|
||||||
<text class="value">{{ randomNumber }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 字符串处理示例 -->
|
|
||||||
<view class="section">
|
|
||||||
<text class="section-title">字符串处理</text>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">UUID:</text>
|
|
||||||
<text class="value">{{ uuid }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">手机号脱敏:</text>
|
|
||||||
<text class="value">{{ maskedPhone }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">字符串截断:</text>
|
|
||||||
<text class="value">{{ truncatedString }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- UI工具示例 -->
|
|
||||||
<view class="section">
|
|
||||||
<text class="section-title">UI工具</text>
|
|
||||||
<view class="button-group">
|
|
||||||
<button class="button success" @click="showSuccess">成功提示</button>
|
|
||||||
<button class="button error" @click="showError">错误提示</button>
|
|
||||||
<button class="button loading" @click="showLoading">加载提示</button>
|
|
||||||
<button class="button confirm" @click="showConfirm">确认对话框</button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 设备信息示例 -->
|
|
||||||
<view class="section">
|
|
||||||
<text class="section-title">设备信息</text>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">状态栏高度:</text>
|
|
||||||
<text class="value">{{ statusBarHeight }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">设备平台:</text>
|
|
||||||
<text class="value">{{ devicePlatform }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">网络状态:</text>
|
|
||||||
<text class="value">{{ networkStatus }}</text>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
|
|
||||||
<!-- 屏幕尺寸示例 -->
|
|
||||||
<view class="section">
|
|
||||||
<text class="section-title">屏幕尺寸</text>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">屏幕宽度:</text>
|
|
||||||
<text class="value">{{ screenWidth }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">屏幕高度:</text>
|
|
||||||
<text class="value">{{ screenHeight }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">窗口宽度:</text>
|
|
||||||
<text class="value">{{ windowWidth }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="example-item">
|
|
||||||
<text class="label">窗口高度:</text>
|
|
||||||
<text class="value">{{ windowHeight }}</text>
|
|
||||||
</view>
|
|
||||||
<view class="button-group">
|
|
||||||
<button class="button loading" @click="loadScreenSize">获取屏幕尺寸</button>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</view>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script setup>
|
|
||||||
import { ref, onMounted } from 'vue';
|
|
||||||
import { dateUtil, numberUtil, stringUtil, deviceUtil, networkUtil, uiUtil } from '@/utils/common';
|
|
||||||
|
|
||||||
// 日期处理示例数据
|
|
||||||
const currentDate = ref('');
|
|
||||||
const formattedDate = ref('');
|
|
||||||
const relativeDate = ref('');
|
|
||||||
|
|
||||||
// 数字处理示例数据
|
|
||||||
const formattedNumber = ref('');
|
|
||||||
const formattedMoney = ref('');
|
|
||||||
const randomNumber = ref(0);
|
|
||||||
|
|
||||||
// 字符串处理示例数据
|
|
||||||
const uuid = ref('');
|
|
||||||
const maskedPhone = ref('');
|
|
||||||
const truncatedString = ref('');
|
|
||||||
|
|
||||||
// 设备信息示例数据
|
|
||||||
const statusBarHeight = ref(0);
|
|
||||||
const devicePlatform = ref('');
|
|
||||||
const networkStatus = ref('');
|
|
||||||
|
|
||||||
// 屏幕尺寸示例数据
|
|
||||||
const screenWidth = ref(0);
|
|
||||||
const screenHeight = ref(0);
|
|
||||||
const windowWidth = ref(0);
|
|
||||||
const windowHeight = ref(0);
|
|
||||||
|
|
||||||
// 页面加载时初始化示例数据
|
|
||||||
onMounted(async () => {
|
|
||||||
// 日期处理示例
|
|
||||||
currentDate.value = dateUtil.now();
|
|
||||||
const testDate = new Date('2025-12-25 10:30:00');
|
|
||||||
formattedDate.value = dateUtil.format(testDate, 'YYYY年MM月DD日 HH时mm分ss秒');
|
|
||||||
relativeDate.value = dateUtil.relative(testDate);
|
|
||||||
|
|
||||||
// 数字处理示例
|
|
||||||
formattedNumber.value = numberUtil.format(1234567.89);
|
|
||||||
formattedMoney.value = numberUtil.formatMoney(98765.4321);
|
|
||||||
randomNumber.value = numberUtil.random(1, 100);
|
|
||||||
|
|
||||||
// 字符串处理示例
|
|
||||||
uuid.value = stringUtil.uuid();
|
|
||||||
maskedPhone.value = stringUtil.maskPhone('13812345678');
|
|
||||||
truncatedString.value = stringUtil.truncate('这是一个很长的字符串,用于测试字符串截断功能', 20);
|
|
||||||
|
|
||||||
// 设备信息示例
|
|
||||||
await loadDeviceInfo();
|
|
||||||
|
|
||||||
// 网络状态示例
|
|
||||||
await loadNetworkStatus();
|
|
||||||
});
|
|
||||||
|
|
||||||
// 加载设备信息
|
|
||||||
async function loadDeviceInfo() {
|
|
||||||
try {
|
|
||||||
const systemInfo = await deviceUtil.getSystemInfo();
|
|
||||||
statusBarHeight.value = systemInfo.statusBarHeight || 0;
|
|
||||||
devicePlatform.value = systemInfo.platform || '未知';
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取设备信息失败:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载网络状态
|
|
||||||
async function loadNetworkStatus() {
|
|
||||||
try {
|
|
||||||
const isConnected = await networkUtil.isConnected();
|
|
||||||
networkStatus.value = isConnected ? '已连接' : '未连接';
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取网络状态失败:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// UI工具示例方法
|
|
||||||
function showSuccess() {
|
|
||||||
uiUtil.showSuccess('操作成功');
|
|
||||||
}
|
|
||||||
|
|
||||||
function showError() {
|
|
||||||
uiUtil.showError('操作失败,请重试');
|
|
||||||
}
|
|
||||||
|
|
||||||
function showLoading() {
|
|
||||||
uiUtil.showLoading('加载中...');
|
|
||||||
// 模拟加载完成
|
|
||||||
setTimeout(() => {
|
|
||||||
uiUtil.hideLoading();
|
|
||||||
}, 2000);
|
|
||||||
}
|
|
||||||
|
|
||||||
function showConfirm() {
|
|
||||||
uiUtil.showConfirm('确认操作', '您确定要执行此操作吗?', () => {
|
|
||||||
uiUtil.showSuccess('确认成功');
|
|
||||||
}, () => {
|
|
||||||
uiUtil.showError('已取消操作');
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 屏幕尺寸示例方法
|
|
||||||
async function loadScreenSize() {
|
|
||||||
try {
|
|
||||||
const screenSize = await deviceUtil.getScreenSize();
|
|
||||||
screenWidth.value = screenSize.width;
|
|
||||||
screenHeight.value = screenSize.height;
|
|
||||||
windowWidth.value = screenSize.windowWidth;
|
|
||||||
windowHeight.value = screenSize.windowHeight;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取屏幕尺寸失败:', error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="less">
|
|
||||||
.container {
|
|
||||||
min-height: 100vh;
|
|
||||||
background-color: #f5f5f5;
|
|
||||||
padding-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
padding: 20px;
|
|
||||||
background-color: #007aff;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
|
||||||
font-size: 20px;
|
|
||||||
font-weight: bold;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
padding: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section {
|
|
||||||
background-color: #fff;
|
|
||||||
border-radius: 8px;
|
|
||||||
padding: 15px;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-title {
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-bottom: 15px;
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.example-item {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
padding: 8px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value {
|
|
||||||
font-size: 14px;
|
|
||||||
color: #333;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-group {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.button {
|
|
||||||
padding: 12px;
|
|
||||||
border-radius: 6px;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #fff;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: opacity 0.2s;
|
|
||||||
|
|
||||||
&.success {
|
|
||||||
background-color: #4cd964;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.error {
|
|
||||||
background-color: #ff3b30;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.loading {
|
|
||||||
background-color: #007aff;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.confirm {
|
|
||||||
background-color: #5856d6;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
opacity: 0.8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 396 B |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 305 B |
|
After Width: | Height: | Size: 213 B |
|
After Width: | Height: | Size: 805 B |
|
After Width: | Height: | Size: 1.3 KiB |
172
utils/common.js
|
|
@ -136,7 +136,7 @@ export const stringUtil = {
|
||||||
* @returns {string} 唯一ID
|
* @returns {string} 唯一ID
|
||||||
*/
|
*/
|
||||||
uuid() {
|
uuid() {
|
||||||
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
|
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
|
||||||
const r = Math.random() * 16 | 0;
|
const r = Math.random() * 16 | 0;
|
||||||
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
const v = c === 'x' ? r : (r & 0x3 | 0x8);
|
||||||
return v.toString(16);
|
return v.toString(16);
|
||||||
|
|
@ -228,34 +228,6 @@ export const deviceUtil = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取屏幕宽度
|
|
||||||
* @returns {Promise<number>} 屏幕宽度(px)
|
|
||||||
*/
|
|
||||||
async getScreenWidth() {
|
|
||||||
try {
|
|
||||||
const systemInfo = await this.getSystemInfo();
|
|
||||||
return systemInfo.screenWidth || 0;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取屏幕宽度失败:', error);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取屏幕高度
|
|
||||||
* @returns {Promise<number>} 屏幕高度(px)
|
|
||||||
*/
|
|
||||||
async getScreenHeight() {
|
|
||||||
try {
|
|
||||||
const systemInfo = await this.getSystemInfo();
|
|
||||||
return systemInfo.screenHeight || 0;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('获取屏幕高度失败:', error);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取窗口宽度
|
* 获取窗口宽度
|
||||||
* @returns {Promise<number>} 窗口宽度(px)
|
* @returns {Promise<number>} 窗口宽度(px)
|
||||||
|
|
@ -285,37 +257,6 @@ export const deviceUtil = {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* 网络请求相关方法
|
|
||||||
*/
|
|
||||||
export const networkUtil = {
|
|
||||||
/**
|
|
||||||
* 检查网络状态
|
|
||||||
* @returns {Promise<Object>} 网络状态对象
|
|
||||||
*/
|
|
||||||
checkNetwork() {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
uni.getNetworkType({
|
|
||||||
success: resolve,
|
|
||||||
fail: reject
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否有网络连接
|
|
||||||
* @returns {Promise<boolean>} 是否有网络连接
|
|
||||||
*/
|
|
||||||
async isConnected() {
|
|
||||||
try {
|
|
||||||
const networkType = await this.checkNetwork();
|
|
||||||
return networkType.networkType !== 'none';
|
|
||||||
} catch (error) {
|
|
||||||
console.error('检查网络状态失败:', error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* UI相关方法
|
* UI相关方法
|
||||||
|
|
@ -342,20 +283,6 @@ export const uiUtil = {
|
||||||
uni.hideLoading();
|
uni.hideLoading();
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
|
||||||
* 显示成功提示
|
|
||||||
* @param {string} title - 提示文本
|
|
||||||
* @param {number} duration - 显示时长
|
|
||||||
* @returns {void}
|
|
||||||
*/
|
|
||||||
showSuccess(title, duration = 1500) {
|
|
||||||
uni.showToast({
|
|
||||||
title,
|
|
||||||
icon: 'success',
|
|
||||||
duration
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示错误提示
|
* 显示错误提示
|
||||||
* @param {string} title - 提示文本
|
* @param {string} title - 提示文本
|
||||||
|
|
@ -397,65 +324,55 @@ export const uiUtil = {
|
||||||
* 其他工具方法
|
* 其他工具方法
|
||||||
*/
|
*/
|
||||||
export const util = {
|
export const util = {
|
||||||
/**
|
setAndroidSystemBarColor(backgroundColor) {
|
||||||
* 深拷贝对象
|
if (deviceUtil.isAndroid()) {
|
||||||
* @param {Object} obj - 原始对象
|
try {
|
||||||
* @returns {Object} 拷贝后的对象
|
// #ifndef APP-IOS
|
||||||
*/
|
if (plus.os.name === 'Android') {
|
||||||
deepClone(obj) {
|
console.log("1212333");
|
||||||
if (obj === null || typeof obj !== 'object') return obj;
|
let color = plus.android.newObject("android.graphics.Color");
|
||||||
|
let activity = plus.android.runtimeMainActivity();
|
||||||
if (obj instanceof Date) return new Date(obj.getTime());
|
let colorInt = plus.android.invoke(color, "parseColor", backgroundColor);
|
||||||
if (obj instanceof Array) return obj.map(item => this.deepClone(item));
|
let window = plus.android.invoke(activity, "getWindow");
|
||||||
|
plus.android.invoke(window, "setNavigationBarColor", colorInt);
|
||||||
const clonedObj = {};
|
uni.setNavigationBarColor({
|
||||||
for (const key in obj) {
|
animation: { // 动画效果
|
||||||
if (obj.hasOwnProperty(key)) {
|
duration: 100,
|
||||||
clonedObj[key] = this.deepClone(obj[key]);
|
timingFunc: 'easeIn'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.log("状态栏设置完毕!");
|
||||||
|
setTimeout(function () {
|
||||||
|
uni.setNavigationBarColor({
|
||||||
|
backgroundColor: backgroundColor,
|
||||||
|
animation: { // 动画效果
|
||||||
|
duration: 100,
|
||||||
|
timingFunc: 'easeIn'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}, 200);
|
||||||
|
}
|
||||||
|
// #endif
|
||||||
|
} catch (err) {
|
||||||
|
console.log("状态栏修改失败", err);
|
||||||
|
uni.setNavigationBarColor({
|
||||||
|
animation: { // 动画效果
|
||||||
|
duration: 100,
|
||||||
|
timingFunc: 'easeIn'
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return clonedObj;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 防抖函数
|
* 页面跳转
|
||||||
* @param {Function} func - 要执行的函数
|
* @param {*} url
|
||||||
* @param {number} wait - 等待时间
|
|
||||||
* @returns {Function} 防抖后的函数
|
|
||||||
*/
|
*/
|
||||||
debounce(func, wait = 300) {
|
goPage(url) {
|
||||||
let timeout;
|
uni.navigateTo({
|
||||||
return function(...args) {
|
url
|
||||||
clearTimeout(timeout);
|
});
|
||||||
timeout = setTimeout(() => func.apply(this, args), wait);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 节流函数
|
|
||||||
* @param {Function} func - 要执行的函数
|
|
||||||
* @param {number} limit - 限制时间
|
|
||||||
* @returns {Function} 节流后的函数
|
|
||||||
*/
|
|
||||||
throttle(func, limit = 300) {
|
|
||||||
let inThrottle;
|
|
||||||
return function(...args) {
|
|
||||||
if (!inThrottle) {
|
|
||||||
func.apply(this, args);
|
|
||||||
inThrottle = true;
|
|
||||||
setTimeout(() => inThrottle = false, limit);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 延迟执行
|
|
||||||
* @param {number} ms - 延迟时间(毫秒)
|
|
||||||
* @returns {Promise} Promise对象
|
|
||||||
*/
|
|
||||||
delay(ms) {
|
|
||||||
return new Promise(resolve => setTimeout(resolve, ms));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -465,7 +382,6 @@ export default {
|
||||||
...numberUtil,
|
...numberUtil,
|
||||||
...stringUtil,
|
...stringUtil,
|
||||||
...deviceUtil,
|
...deviceUtil,
|
||||||
...networkUtil,
|
|
||||||
...uiUtil,
|
...uiUtil,
|
||||||
...util
|
...util
|
||||||
};
|
};
|
||||||
|
|
|
||||||