001/** 002 * Copyright (c) 2015-2022, Michael Yang 杨福海 (fuhai999@gmail.com). 003 * <p> 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * <p> 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * <p> 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package io.jboot.web.directive.base; 017 018import com.jfinal.plugin.activerecord.Page; 019import com.jfinal.template.Env; 020import com.jfinal.template.io.Writer; 021import com.jfinal.template.stat.Scope; 022import io.jboot.utils.StrUtil; 023 024import java.util.ArrayList; 025import java.util.List; 026 027 028public abstract class PaginateDirectiveBase extends JbootDirectiveBase { 029 030 private static final String PREVIOUS_CLASS_KEY = "previousClass"; 031 private static final String NEXT_CLASS_KEY = "nextClass"; 032 private static final String ACTIVE_CLASS_KEY = "activeClass"; 033 private static final String DISABLED_CLASS_KEY = "disabledClass"; 034 private static final String ONLY_SHOW_PREVIOUS_AND_NEXT_KEY = "onlyShowPreviousAndNext"; 035 036 private static final String PREVIOUS_TEXT_KEY = "previousText"; 037 private static final String NEXT_TEXT_KEY = "nextText"; 038 private static final String PAGE_ITEMS_NAME_KEY = "pageItemsName"; 039 private static final String PAGE_DATA_KEY = "pageData"; 040 private static final String SIBLINGS_ITEM_COUNT_KEY = "siblingsItemCount"; 041 private static final String START_ITEM_COUNT_KEY = "startItemCount"; 042 private static final String END_ITEM_COUNT_KEY = "endItemCount"; 043 044 045 private static final String DEFAULT_PREVIOUS_CLASS = "previous"; 046 private static final String DEFAULT_NEXT_CLASS = "next"; 047 private static final String DEFAULT_ACTIVE_CLASS = "active"; 048 private static final String DEFAULT_DISABLED_CLASS = "disabled"; 049 050 private static final String DEFAULT_PREVIOUS_TEXT = "上一页"; 051 private static final String DEFAULT_NEXT_TEXT = "下一页"; 052 private static final String DEFAULT_PAGE_ITEMS_NAME = "pages"; 053 private static final String DEFAULT_PAGE_DATA_KEY = "pageData"; 054 055 private static final String JAVASCRIPT_TEXT = "javascript:;"; 056 private static final String ELLIPSIS_TEXT = "..."; 057 058 private static final int SIBLINGS_ITEM_COUNT = 2; 059 private static final int START_ITEM_COUNT = 1; 060 private static final int END_ITEM_COUNT = 1; 061 062 063 @Override 064 public void onRender(Env env, Scope scope, Writer writer) { 065 066 String previousClass = getPara(PREVIOUS_CLASS_KEY, scope, DEFAULT_PREVIOUS_CLASS); 067 String nextClass = getPara(NEXT_CLASS_KEY, scope, DEFAULT_NEXT_CLASS); 068 String activeClass = getPara(ACTIVE_CLASS_KEY, scope, DEFAULT_ACTIVE_CLASS); 069 String disabledClass = getPara(DISABLED_CLASS_KEY, scope, DEFAULT_DISABLED_CLASS); 070 boolean onlyShowPreviousAndNext = getParaToBool(ONLY_SHOW_PREVIOUS_AND_NEXT_KEY, scope, false); 071 072 String previousText = getPara(PREVIOUS_TEXT_KEY, scope, DEFAULT_PREVIOUS_TEXT); 073 String nextText = getPara(NEXT_TEXT_KEY, scope, DEFAULT_NEXT_TEXT); 074 String pageItemsName = getPara(PAGE_ITEMS_NAME_KEY, scope, DEFAULT_PAGE_ITEMS_NAME); 075 076 String pageDataKey = getPara(PAGE_DATA_KEY, scope, DEFAULT_PAGE_DATA_KEY); 077 078 int siblingsItemCount = getParaToInt(SIBLINGS_ITEM_COUNT_KEY, scope, SIBLINGS_ITEM_COUNT); 079 if (siblingsItemCount < 1) { 080 siblingsItemCount = SIBLINGS_ITEM_COUNT; 081 } 082 083 084 int startItemCount = getParaToInt(START_ITEM_COUNT_KEY, scope, START_ITEM_COUNT); 085 if (startItemCount < 1) { 086 startItemCount = START_ITEM_COUNT; 087 } 088 089 090 int endItemCount = getParaToInt(END_ITEM_COUNT_KEY, scope, END_ITEM_COUNT); 091 if (endItemCount < 1) { 092 endItemCount = END_ITEM_COUNT; 093 } 094 095 096 Page<?> page = getPage(env, scope, writer); 097 098 int currentPageNumber = page == null ? 1 : page.getPageNumber(); 099 int totalPage = page == null ? 0 : page.getTotalPage(); 100 101 if (totalPage == 0) { 102 return; 103 } 104 105 if (currentPageNumber > totalPage) { 106 currentPageNumber = totalPage; 107 } 108 109 int startPage = currentPageNumber - siblingsItemCount; 110 if (startPage < 1) { 111 startPage = 1; 112 } 113 114 int endPage = currentPageNumber + siblingsItemCount; 115 if (endPage > totalPage) { 116 endPage = totalPage; 117 } 118 119 List<PaginateItem> pages = new ArrayList<PaginateItem>(); 120 if (currentPageNumber == 1) { 121 pages.add(new PaginateDirectiveBase.PaginateItem(previousClass + StrUtil.SPACE + disabledClass, JAVASCRIPT_TEXT, previousText)); 122 } else { 123 pages.add(new PaginateDirectiveBase.PaginateItem(previousClass, getUrl(currentPageNumber - 1, env, scope, writer), previousText)); 124 } 125 126 if (!onlyShowPreviousAndNext) { 127 128 //开始页码 129 for (int i = 1; i <= startItemCount; i++) { 130 if (i < currentPageNumber - siblingsItemCount) { 131 pages.add(new PaginateDirectiveBase.PaginateItem(StrUtil.EMPTY, getUrl(i, env, scope, writer), i)); 132 } 133 } 134 135 //省略号 136 if (currentPageNumber > startItemCount + siblingsItemCount + 1) { 137 pages.add(new PaginateDirectiveBase.PaginateItem(disabledClass, JAVASCRIPT_TEXT, ELLIPSIS_TEXT)); 138 } 139 140 141 //中间页码 142 for (int i = startPage; i <= endPage; i++) { 143 if (currentPageNumber == i) { 144 pages.add(new PaginateDirectiveBase.PaginateItem(activeClass, JAVASCRIPT_TEXT, i)); 145 } else { 146 pages.add(new PaginateDirectiveBase.PaginateItem(StrUtil.EMPTY, getUrl(i, env, scope, writer), i)); 147 } 148 } 149 150 151 //省略号 152 if (currentPageNumber < totalPage - siblingsItemCount - endItemCount) { 153 pages.add(new PaginateDirectiveBase.PaginateItem(disabledClass, JAVASCRIPT_TEXT, ELLIPSIS_TEXT)); 154 } 155 156 //后边页码 157 for (int i = (endItemCount - 1); i >= 0; i--) { 158 if (i < totalPage - (currentPageNumber + siblingsItemCount)) { 159 pages.add(new PaginateDirectiveBase.PaginateItem(StrUtil.EMPTY, getUrl(totalPage - i, env, scope, writer), totalPage - i)); 160 } 161 162 } 163 } 164 165 166 if (currentPageNumber == totalPage) { 167 pages.add(new PaginateDirectiveBase.PaginateItem(nextClass + StrUtil.SPACE + disabledClass, JAVASCRIPT_TEXT, nextText)); 168 } else { 169 pages.add(new PaginateDirectiveBase.PaginateItem(nextClass, getUrl(currentPageNumber + 1, env, scope, writer), nextText)); 170 } 171 172 scope.setLocal(pageItemsName, pages); 173 scope.setLocal(pageDataKey, page); 174 175 renderBody(env, scope, writer); 176 } 177 178 179 protected abstract String getUrl(int pageNumber, Env env, Scope scope, Writer writer); 180 181 protected abstract Page<?> getPage(Env env, Scope scope, Writer writer); 182 183 184 @Override 185 public boolean hasEnd() { 186 return true; 187 } 188 189 190 public static class PaginateItem { 191 private String style; 192 private String url; 193 private String text; 194 195 public PaginateItem(String style, String url, Object text) { 196 this.style = style; 197 this.url = url; 198 this.text = String.valueOf(text); 199 } 200 201 public String getStyle() { 202 return style; 203 } 204 205 public void setStyle(String style) { 206 this.style = style; 207 } 208 209 public String getUrl() { 210 return url; 211 } 212 213 public void setUrl(String url) { 214 this.url = url; 215 } 216 217 public String getText() { 218 return text; 219 } 220 221 public void setText(String text) { 222 this.text = text; 223 } 224 } 225}