1.accountgrid.page.html
<ion-content style="overflow: scroll;" (ionScroll)="ionScroll()" scroll-events='true' id='Content'>
<!-- 查询条件 -->
<div id="CONTENT_TOP" style="width: 100%; border: tomato 1px solid;">
<form (submit)='selectData(conditionsInfo)' action="" method="POST">
<ion-row>
<ion-col size="auto" class="ion_col_self_css">
<ion-label> 记账日期: </ion-label>
</ion-col>
<ion-col size="4">
<ion-datetime [(ngModel)]="conditionsInfo.START_TIME" name='START_TIME'
class="el_border_radiusAndbackcolor" display-format='YYYY-MM-DD' placeholder="" cancelText="取消"
doneText="确定"></ion-datetime>
</ion-col>
<ion-col size="auto" class="ion_col_self_css">
<ion-label> - </ion-label>
</ion-col>
<ion-col size="4">
<ion-datetime [(ngModel)]="conditionsInfo.END_TIME" name='END_TIME'
class="el_border_radiusAndbackcolor" display-format='YYYY-MM-DD' placeholder="" cancelText="取消"
doneText="确定"></ion-datetime>
<!-- <app-date-time-picker [(ngModel)]="conditionsInfo.MONEY_USE_TIME" name='MONEY_USE_TIME'></app-date-time-picker> -->
</ion-col>
</ion-row>
<ion-row>
<ion-col size="auto" class="ion_col_self_css">
<ion-label> 收支类型: </ion-label>
</ion-col>
<ion-col size='4'>
<ion-select [(ngModel)]="conditionsInfo.PaymentType" name='PaymentType'
class="el_border_radiusAndbackcolor" placeholder="" interface="popover" cancelText="取消"
okText="确定">
<!-- 动态循环添加选择项 -->
<ion-select-option *ngFor="let item of PaymentType" value="{{item.value}}">
{{item.description}}
</ion-select-option>
</ion-select>
<!-- <ion-input [(ngModel)]="newData.UseType" name='UseType' type="text"> </ion-input> -->
</ion-col>
</ion-row>
<!-- <ion-searchbar placeholder="" animated showCancelButton cancelButtonText=""></ion-searchbar> -->
<ion-row>
<ion-col class="ion_col_self_css">
<ion-button id='selectBtn' expand='full' color="primary" type='submit'> 查询 </ion-button>
</ion-col>
</ion-row>
</form>
</div>
<!-- 查询条件 -->
<!-- slot="fixed":固定在底部,使悬浮按钮不会随着页面滚动 -->
<ion-fab id="addData_FabBtn" vertical="bottom" horizontal="end" slot="fixed">
<!-- 返回顶部功能 -->
<ion-fab-button hidden id='BackTop' (click)="backContentTop()" size='small'>
<ion-icon name="xu-fanhuidingbu1"></ion-icon>
</ion-fab-button>
</ion-fab>
<div id="CONTENT_BOTTOM" style="overflow-x:scroll;position: fixed; border:rgb(0, 60, 255) 1px solid;">
<ion-grid style="overflow-x: scroll;width:215%;">
<!-- <ion-row *ngFor="let row of rowCount">
<ion-col class="grid_col_rgb" *ngFor="let col of colCount">{{col}}</ion-col>
</ion-row> -->
<div id='firstRow' class="firstRow_scroll_Default">
<ion-row>
<ng-container *ngFor="let col of colCount">
<ng-container *ngIf="col==='使用说明'; else elseTemplate">
<ion-col class="grid_col_rgb_header" size='3'> {{col}}</ion-col>
</ng-container>
<ng-template #elseTemplate>
<ion-col class="grid_col_rgb_header" size='1'>{{col}}</ion-col>
</ng-template>
</ng-container>
</ion-row>
</div>
<div style="width: 150%;">
<ng-container *ngFor="let item of QueryData;let i=index">
<ng-container *ngIf="i%2===0; else elseTemplate">
<ion-row>
<ion-col size='1' class="grid_col_rgb_o">{{item.MONEY_USE_TIME}}</ion-col>
<ion-col size='1' class="grid_col_rgb_o">{{item.AMOUNT}}</ion-col>
<ion-col size='3' class="grid_col_rgb_o">{{item.MONEY_USE_DESC}}</ion-col>
<ion-col size='1' class="grid_col_rgb_o">{{item.PaymentWayDesc}}</ion-col>
<ion-col size='1' class="grid_col_rgb_o">{{item.UseTypesDesc}}</ion-col>
<ion-col size='1' class="grid_col_rgb_o">{{item.NAME}}</ion-col>
<ion-col size='1' class="grid_col_rgb_o">{{item.PaymentTypeDesc}}</ion-col>
<ion-col size='1' class="grid_col_rgb_o">{{item.ACCOUNT_DATE}}</ion-col>
</ion-row>
</ng-container>
<ng-template #elseTemplate>
<ion-row >
<ion-col size='1' class="grid_col_rgb_j">{{item.MONEY_USE_TIME}}</ion-col>
<ion-col size='1' class="grid_col_rgb_j">{{item.AMOUNT}}</ion-col>
<ion-col size='3' class="grid_col_rgb_j">{{item.MONEY_USE_DESC}}</ion-col>
<ion-col size='1' class="grid_col_rgb_j">{{item.PaymentWayDesc}}</ion-col>
<ion-col size='1' class="grid_col_rgb_j">{{item.UseTypesDesc}}</ion-col>
<ion-col size='1' class="grid_col_rgb_j">{{item.NAME}}</ion-col>
<ion-col size='1' class="grid_col_rgb_j">{{item.PaymentTypeDesc}}</ion-col>
<ion-col size='1' class="grid_col_rgb_j">{{item.ACCOUNT_DATE}}</ion-col>
</ion-row>
</ng-template>
</ng-container>
</div>
</ion-grid>
</div>
</ion-content>
2.accountgrid.page.ts
import { Component, OnInit ,Renderer2,ElementRef} from '@angular/core';
import { TabsPage } from "../tabs/tabs.page";
import { GlobalVariable } from "../global-variable/global-variable";
import { DBManagerService } from '../dbmanager/dbmanager.service';
import { ToastController } from '@ionic/angular';
@Component({
selector: 'app-accountgrid',
templateUrl: './accountgrid.page.html',
styleUrls: ['./accountgrid.page.scss'],
})
export class AccountgridPage implements OnInit {
//#region 定义全局变量
public rowCount: any[] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30];
public colCount: any[] = ['使用日期', '金额', '使用说明', '支付类型', '使用类型', '姓名', '收支类型', '记账日期'];
private SELECT_CONDITIONS: any; // 查询条件
public QueryData: any[] = []; // 查询结果
public UseTypes: any[] = [];// 使用类型
public PaymentWay: any[] = []; // 付款方式
public PaymentType: any[] = []; // 收支类型
public itemCount: number=1;
private win: any = window;
private elBackTop = null; // 返回顶部按钮
private elContent = null; // 内容标签
private firstRow = null; // Grid第一行对象
private CONTENT_TOP=null;//内容上部分
private CONTENT_BOTTOM=null;//内容下部分
/**
* 查询条件信息
*/
public conditionsInfo = {
START_TIME: new Date().toDateString(),
END_TIME: new Date().toDateString(),
PaymentType: ''
};
//#endregion
constructor(
public tabsPage: TabsPage,
public globalVariable: GlobalVariable,
public dbManagerService: DBManagerService,
public toastController: ToastController,
public renderer2: Renderer2,
public elementRef: ElementRef,
) {
tabsPage.tabTitle = '记账明细'; // 在页面首次加载时默认传值给TabsPage的tabTitle变量用于改变标题栏
this.UseTypes = this.globalVariable.UseTypes; // 使用类型
this.PaymentWay = this.globalVariable.PaymentWay;
this.PaymentType = this.globalVariable.PaymentType;
}
ngAfterViewChecked(): void {
//Called after every check of the component's view. Applies to components only.
//Add 'implements AfterViewChecked' to the class.
this.tabsPage.currentPageInfo = this.globalVariable.pageInfo[0].AccountGrid;
this.tabsPage.SON_TABNAME_NOW = 'AccountGrid';
}
//当页面完全进入并且现在是活动页面时运行。无论是第一次加载还是缓存页面,此事件都会触发。
ionViewDidEnter(){
this.CONTENT_TOP = this.elementRef.nativeElement.querySelector('#CONTENT_TOP');
// console.log("当前CONTENT_TOPDIV标签对象offsetHeight:",this.CONTENT_TOP.offsetHeight);
this.CONTENT_BOTTOM = this.elementRef.nativeElement.querySelector('#CONTENT_BOTTOM');
// console.log("当前CONTENT_BOTTOM_DIV标签对象:",this.CONTENT_BOTTOM);
let height = this.elementRef.nativeElement.clientHeight -this.CONTENT_TOP.offsetHeight + 'px';
// console.log('最终高度height:',height);
this.renderer2.setStyle(this.CONTENT_BOTTOM,'height',height);
}
ngOnInit() {
this.elBackTop = this.elementRef.nativeElement.querySelector('#BackTop');
this.elContent = this.elementRef.nativeElement.querySelector('#Content');
this.firstRow = this.elementRef.nativeElement.querySelector('#firstRow');
// console.log("当前elementRef对象:",this.elementRef);
// console.log("当前elContent标签对象:",this.elContent);
}
// 查询数据
selectData(data: any) {
try {
if (data !== undefined) {
this.SELECT_CONDITIONS = data;
const START_TIME = new Date(data.START_TIME);
const END_TIME = new Date(data.END_TIME);
// console.log('日期:',ACCOUNT_DATE);
data.START_TIME = START_TIME.toLocaleDateString();
data.END_TIME = END_TIME.toLocaleDateString();
// console.log('传入参数data:', data);
// data.ACCOUNT_DATE = data.ACCOUNT_DATE.replace('-','');
// this.globalVariable.sqlParamInfo = []; // 重置
// // console.log('当前表单提交数据:', data);
// // console.log('sql语句拼接参数信息:', this.globalVariable.sqlParamInfo);
// this.globalVariable.sqlParamInfo.push(
// { colName: 'ACCOUNT_DATE', colValue: data.ACCOUNT_DATE },
// { colName: 'PAYMENT_WAY', colValue: data.PaymentWay }
// );
// console.log('sql语句拼接参数信息:', this.globalVariable.sqlParamInfo);
const sql = " SELECT * FROM (" +
" SELECT ACCOUNT_DATE,MONEY_USE_TIME," +
"AMOUNT,PAYMENT_TYPE,PAYMENT_WAY," +
"MONEY_UST_TYPE,MONEY_USE_DESC, '' NAME FROM money_useinfo WHERE 1=1 " +
" UNION ALL " +
" SELECT ACCOUNT_DATE,MONEY_USE_TIME," +
" AMOUNT,PAYMENT_TYPE,PAYMENT_WAY, " +
" MONEY_UST_TYPE,MONEY_USE_DESC,NAME " +
" FROM renqing WHERE 1=1 )";
let sql_where = " WHERE 1=1 AND ACCOUNT_DATE>='" + data.START_TIME + "'" +
" AND ACCOUNT_DATE<='" + data.END_TIME + "'";
if (data.PaymentType !== "") {
sql_where += " AND PAYMENT_TYPE='" + data.PaymentType + "'";
}
const sql2 = " UNION ALL" +
" SELECT" +
" '' ACCOUNT_DATE," +
" '合计:' MONEY_USE_TIME," +
" SUM(AMOUNT) AMOUNT," +
" '' PAYMENT_TYPE," +
" '' PAYMENT_WAY," +
" '' MONEY_UST_TYPE," +
" '' MONEY_USE_DESC," +
" '' NAME" +
" FROM" +
" (" +
" SELECT" +
" ACCOUNT_DATE," +
" MONEY_USE_TIME," +
" AMOUNT," +
" PAYMENT_TYPE," +
" PAYMENT_WAY," +
" MONEY_UST_TYPE," +
" MONEY_USE_DESC," +
" '' NAME" +
" FROM" +
" money_useinfo" +
" WHERE" +
" 1 = 1" +
" UNION ALL" +
" SELECT" +
" ACCOUNT_DATE," +
" MONEY_USE_TIME," +
" AMOUNT," +
" PAYMENT_TYPE," +
" PAYMENT_WAY, " +
" MONEY_UST_TYPE, " +
" MONEY_USE_DESC, " +
" NAME " +
" FROM " +
" renqing " +
" WHERE " +
" 1 = 1 " +
" ) ";
const sql_order = " ORDER BY MONEY_USE_TIME DESC ";
// 调用查询方法
this.dbManagerService.SelectDataBySQL(sql+sql_where +sql2+ sql_where + sql_order)
.then((success) => {
if (this.win.sqlitePlugin) {
this.QueryData = [];
for (let index = 0; index < success.res.rows.length; index++) {
for (const UseTypes of this.UseTypes) {
if (success.res.rows.item(index).MONEY_UST_TYPE === UseTypes.value) {
success.res.rows.item(index).UseTypesDesc = UseTypes.description; // 添加使用类型中文描述
// console.log('row:', row);
}
}
for (const PaymentWay of this.PaymentWay) {
if (success.res.rows.item(index).PAYMENT_WAY === PaymentWay.value) {
success.res.rows.item(index).PaymentWayDesc = PaymentWay.description; // 添加支付方式中文描述
}
}
for (const PaymentType of this.PaymentType) {
if (success.res.rows.item(index).PAYMENT_TYPE === PaymentType.value) {
success.res.rows.item(index).PaymentTypeDesc = PaymentType.description; // 添加收支类型中文描述
}
}
this.QueryData.push(success.res.rows.item(index));
}
} else {
this.QueryData = [];
for (const row of success.res.rows) {
for (const UseTypes of this.UseTypes) {
if (row.MONEY_UST_TYPE === UseTypes.value) {
row.UseTypesDesc = UseTypes.description; // 添加使用类型中文描述
}
}
for (const PaymentWay of this.PaymentWay) {
if (row.PAYMENT_WAY === PaymentWay.value) {
row.PaymentWayDesc = PaymentWay.description; // 添加支付方式中文描述
}
}
for (const PaymentType of this.PaymentType) {
if (row.PAYMENT_TYPE === PaymentType.value) {
row.PaymentTypeDesc = PaymentType.description; // 添加收支类型中文描述
}
}
this.QueryData.push(row); // 将结果中的数据赋值给QueryData对象,在前端可以直接使用ngfor访问QueryData
}
}
}, (error) => {
console.log(error);
const toast = this.toastController.create({
message: error,
duration: 3000, // 3秒后自动消失
position: 'top', // 位置
showCloseButton: true,
closeButtonText: '关闭'
});
toast.then((ok) => {
ok.present(); // 符合触发条件后立即执行显示
});
});
}
} catch (error) {
console.log('错误信息:', error);
}
}
//#region 返回顶部功能
// 返回顶部按钮
backContentTop() {
this.renderer2.setAttribute(this.elBackTop, 'hidden', 'true');
this.elContent.scrollToTop(0); // 返回内容页顶部
}
ionScroll() {
// getScrollElement():获取实际滚动发生的元素
const scrollElement: Promise<HTMLElement> = this.elContent.getScrollElement();
scrollElement.then((Element) => {
// console.log("当前滚动距离:",Element.scrollTop );
if (Element.scrollTop > 110) { // 设置当滚动条距离顶部的距离为110时返回顶部按钮显示
this.renderer2.removeAttribute(this.elBackTop, 'hidden');
this.renderer2.addClass(this.firstRow, 'firstRow_scroll_Top');
} else if (Element.scrollTop === 0) { // 设置当滚动条距离顶部的距离为0时返回顶部按钮隐藏
this.renderer2.setAttribute(this.elBackTop, 'hidden', 'true');
} else if (Element.scrollTop < 110) {
this.renderer2.removeClass(this.firstRow, 'firstRow_scroll_Top');
}
});
}
//#endregion
}
3.accountgrid.page.scss
// 圆角及背景颜色公用
.el_border_radiusAndbackcolor{
border:1px solid gainsboro;
border-radius: 5px;
background-color: rgb(243, 242, 239);
padding: 4%;
height: 35px;
}
// ion-col标签自定义样式
.ion_col_self_css {
align-self: center;
text-align: right;
}
//奇数行样式
.grid_col_rgb_j{
background-color: rgb(211, 242, 247);
border: 1px solid rgb(167, 165, 165);
}
//偶数行样式
.grid_col_rgb_o{
background-color: rgb(233, 230, 230);
border: 1px solid rgb(167, 165, 165);
}
.grid_col_rgb_header{
background-color: #1196EE;
border: 1px solid rgb(165, 166, 167);
text-align: center;
color: white;
}
.grid_col_white{
background-color: white;
border: 1px solid rgb(167, 165, 165);
}
//Gird首行样式
.firstRow_scroll_Default{
z-index: 999;//标签在最顶层
width: 150%;
}
.firstRow_scroll_Top{
position: fixed;//固定
z-index: 999;//标签在最顶层
}
4.效果图