Метки услуг
Материал из BiTel WiKi
(Отмена правки 3309 участника Cromeshnic (обсуждение)) |
(→Клиентские классы) |
||
Строка 610: | Строка 610: | ||
= Клиентские классы = | = Клиентские классы = | ||
+ | |||
+ | В файл '''/bitel/billing/module/services/npay/setup_user.properties''' пропишем нашу панель как вкладку модуля абонплат с названием «Группы услуг» | ||
+ | <source lang=ini> | ||
+ | module.tab.3.class=bitel.billing.module.services.npay.ServiceLabelModulePanel | ||
+ | module.tab.3.title=\u0413\u0440\u0443\u043F\u043F\u044B \u0443\u0441\u043B\u0443\u0433 | ||
+ | </source> |
Версия 08:02, 21 апреля 2013
Содержание |
Описание
Для отчётов полезно иметь группировку услуг по типам вне зависимости от модуля. Например, группа услуг "Интернет" - туда могут входить как услуги трафиков модулей Inet, Dialup, IPN, так и абонплаты за интернет. Аналогично, "VPN"
Было решено сделать группировку аналогично меткам тарифов - в виде дерева меток.
Решение состоит из серверного API и клиентского интерфейса. Решение является упрощённой копипастой работы с метками тарифов.
Общие классы
Классы, которые должны быть как в серверных библиотеках, так и в клиентских
Во-первых, нам понадобится веб-сервис для работы с метками тарифов:
package ru.bitel.bgbilling.kernel.module.common.service; import ru.bitel.bgbilling.common.BGException; import ru.dsi.bgbilling.kernel.module.common.bean.ServiceItem; import ru.dsi.bgbilling.kernel.module.common.bean.ServiceLabelItem; import javax.jws.WebMethod; import javax.jws.WebParam; import javax.jws.WebService; import java.util.List; import java.util.Set; @WebService public abstract interface ServiceLabelService { @WebMethod public abstract List<ServiceLabelItem> getServiceLabelTreeItemList(@WebParam(name="serviceId") int serviceId) throws BGException; @WebMethod public abstract void setServiceLabelTreeItemList(@WebParam(name="serviceId") int serviceId, @WebParam(name="items") List<ServiceLabelItem> items) throws BGException; @WebMethod public abstract int updateServiceLabelTreeItem(@WebParam(name="serviceLabelItem") ServiceLabelItem serviceLabelItem) throws BGException; @WebMethod public abstract void removeServiceLabelTreeItem(@WebParam(name="serviceLabelItemId") int serviceLabelItemId) throws BGException; @WebMethod public abstract List<ServiceItem> getServiceList(@WebParam(name="moduleIds") Set<Integer> moduleIds, @WebParam(name="serviceLabelIds") List<Integer> serviceLabelIds) throws BGException; }
Элемент списка услуг для отображения:
package ru.dsi.bgbilling.kernel.module.common.bean; import ru.bitel.common.model.IdTitle; import javax.xml.bind.annotation.XmlAttribute; /** * Услуга, расширенная доп информацией */ public class ServiceItem extends IdTitle{ private int labelCount; private String moduleTitle; private int moduleId; private boolean using; @XmlAttribute public int getLabelCount() { return labelCount; } public void setLabelCount(int labelCount) { this.labelCount = labelCount; } @XmlAttribute public String getModuleTitle() { return moduleTitle; } public void setModuleTitle(String moduleTitle) { this.moduleTitle = moduleTitle; } @XmlAttribute public int getModuleId() { return this.moduleId; } public void setModuleId(int moduleId) { this.moduleId = moduleId; } @XmlAttribute public boolean isUsing() { return this.using; } public void setUsing(boolean used) { this.using = used; } }
Элемент дерева меток:
package ru.dsi.bgbilling.kernel.module.common.bean; import ru.bitel.common.model.IdTitle; import javax.xml.bind.annotation.XmlAttribute; public class ServiceLabelItem extends IdTitle { private int parentId = -1; private int serviceLinkCount = 0; private boolean selected = false; @XmlAttribute public int getParentId() { return this.parentId; } public void setParentId(int parentId) { this.parentId = parentId; } @XmlAttribute public int getServiceLinkCount() { return this.serviceLinkCount; } public void setServiceLinkCount(int serviceLinkCount) { this.serviceLinkCount = serviceLinkCount; } @XmlAttribute public boolean isSelected() { return this.selected; } public void setSelected(boolean selected) { this.selected = selected; } }
Renderer дерева меток:
package ru.dsi.bgbilling.kernel.module.common.bean; import ru.bitel.bgbilling.client.util.ClientUtils; import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.TreeCellRenderer; import java.awt.*; public class ServiceLabelTreeCellRenderer extends JPanel implements TreeCellRenderer { private JCheckBox check; private DefaultTreeCellRenderer label; public ServiceLabelTreeCellRenderer() { setLayout(new GridBagLayout()); add(this.check = new JCheckBox(), new GridBagConstraints(0, 0, 1, 1, 0.0D, 0.0D, 17, 0, new Insets(0, 0, 0, 0), 0, 0)); add(this.label = new DefaultTreeCellRenderer(), new GridBagConstraints(1, 0, 1, 1, 0.0D, 0.0D, 17, 0, new Insets(0, 0, 0, 0), 0, 0)); prepare(); setOpaque(false); this.label.setOpenIcon(ClientUtils.getIcon("node.png")); this.label.setClosedIcon(ClientUtils.getIcon("node.png")); this.label.setLeafIcon(ClientUtils.getIcon("leaf.png")); } public void setEnabled(boolean enabled) { super.setEnabled(enabled); this.check.setEnabled(enabled); } public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { prepare(); this.label.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); if ((value instanceof DefaultMutableTreeNode)) { setEnabled(tree.isEnabled()); this.check.setEnabled(true); DefaultMutableTreeNode serviceLabelTreeNode = (DefaultMutableTreeNode)value; Object userObject = serviceLabelTreeNode.getUserObject(); if ((userObject instanceof ServiceLabelItem)) { this.check.setSelected(((ServiceLabelItem)userObject).isSelected()); } this.check.setVisible(!serviceLabelTreeNode.isRoot()); } invalidate(); return this; } public final DefaultTreeCellRenderer getTreeCellRenderer() { return this.label; } private void prepare() { Color bColor = UIManager.getColor("Tree.textBackground"); setBackground(bColor); this.check.setBackground(bColor); this.label.setBackgroundNonSelectionColor(bColor); this.label.setBackgroundSelectionColor(bColor); this.label.setBackground(bColor); } }
Сервер
Таблицы mysql
Таблицы аналогичны таблицам меток тарифов tariff_label и tariff_label_link
CREATE TABLE `custom_service_label` ( `id` int(11) NOT NULL AUTO_INCREMENT, `parent_id` int(11) NOT NULL DEFAULT '0', `title` varchar(255) NOT NULL DEFAULT '', PRIMARY KEY (`id`) ) CREATE TABLE `custom_service_label_link` ( `sid` int(11) NOT NULL DEFAULT '0', `label_id` int(11) NOT NULL DEFAULT '0', KEY `sid` (`sid`,`label_id`) )
Классы java
Реализация веб-сервиса меток услуг
package ru.bitel.bgbilling.kernel.module.server.service; import ru.bitel.bgbilling.common.BGException; import ru.bitel.bgbilling.kernel.container.service.server.AbstractService; import ru.bitel.bgbilling.kernel.module.common.bean.BGModule; import ru.bitel.bgbilling.kernel.module.common.bean.Service; import ru.bitel.bgbilling.kernel.module.common.service.ServiceLabelService; import ru.bitel.bgbilling.kernel.module.server.bean.ModuleManager; import ru.bitel.bgbilling.kernel.module.server.bean.ServiceManager; import ru.dsi.bgbilling.kernel.module.common.bean.ServiceItem; import ru.dsi.bgbilling.kernel.module.common.bean.ServiceLabelItem; import ru.dsi.bgbilling.kernel.module.server.bean.ServiceLabelDao; import javax.jws.WebParam; import javax.jws.WebService; import java.sql.Connection; import java.util.*; /** * Вебсервис для работы с метками (группами) услуг */ @WebService(endpointInterface="ru.bitel.bgbilling.kernel.module.common.service.ServiceLabelService") public class ServiceLabelServiceImpl extends AbstractService implements ServiceLabelService { @Override public List<ServiceLabelItem> getServiceLabelTreeItemList(@WebParam(name="serviceId") int serviceId) throws BGException { ServiceLabelDao serviceLabelManager = new ServiceLabelDao(getConnection()); List<ServiceLabelItem> serviceLabelItems = serviceLabelManager.getServiceLabelItemList(); if (serviceId > 0) { Set<Integer> serviceLabelSet = serviceLabelManager.getServiceLabelIds(serviceId); for (ServiceLabelItem serviceLabelItem : serviceLabelItems) { serviceLabelItem.setSelected(serviceLabelSet.contains(Integer.valueOf(serviceLabelItem.getId()))); } } return serviceLabelItems; } @Override public void setServiceLabelTreeItemList(@WebParam(name="serviceId") int serviceId, @WebParam(name="items") List<ServiceLabelItem> items) throws BGException { Set<Integer> labelIds = new HashSet<Integer>(); if (items != null) { for (ServiceLabelItem tariffLabelItem : items) { labelIds.add(tariffLabelItem.getId()); } } new ServiceLabelDao(getConnection()).setServiceLabelIds(serviceId, labelIds); } @Override public int updateServiceLabelTreeItem(@WebParam(name = "serviceLabelItem") ServiceLabelItem serviceLabelItem) throws BGException { new ServiceLabelDao(getConnection()).updateServiceLabelTreeItem(serviceLabelItem); return serviceLabelItem != null ? serviceLabelItem.getId() : -1; } @Override public void removeServiceLabelTreeItem(@WebParam(name = "serviceLabelItemId") int serviceLabelItemId) throws BGException { new ServiceLabelDao(getConnection()).removeServiceLabelItem(serviceLabelItemId); } @Override public List<ServiceItem> getServiceList(@WebParam(name = "moduleIds") Set<Integer> moduleIds, @WebParam(name = "serviceLabelIds") List<Integer> serviceLabelIds) throws BGException { List<ServiceItem> result = new ArrayList<ServiceItem>(); Connection con = getConnection(); ServiceManager sm = new ServiceManager(con); ModuleManager mm = new ModuleManager(con); ServiceLabelDao slDao = new ServiceLabelDao(con); Map<Integer,BGModule> modulesMap = mm.getModulesMap(); List<Service> services = sm.list(); ServiceItem serviceItem; BGModule module; boolean found; for(Service service : services){ if(moduleIds!=null && moduleIds.size()>0){ if(!moduleIds.contains(service.getModuleId())){ continue; } } Set<Integer> labelIds = slDao.getServiceLabelIds(service.getId()); if(serviceLabelIds!=null && serviceLabelIds.size()>0){ found = false;//Ищем, есть ли у услуги хотя бы одна метка из фильтра serviceLabelIds for(Integer label_id : serviceLabelIds){ if(labelIds.contains(label_id)){ found = true; break; } } if(!found){ continue; } } //всё ок - добавляем услугу в список serviceItem = new ServiceItem(); serviceItem.setId(service.getId()); serviceItem.setTitle(service.getTitle()); serviceItem.setModuleId(service.getModuleId()); serviceItem.setUsing(service.isUsing()); serviceItem.setLabelCount(labelIds.size()); module = modulesMap.get(service.getModuleId()); serviceItem.setModuleTitle(module == null ? "???" : module.getTitle()); result.add(serviceItem); } sm.recycle(); return result; } }
Dao для работы с метками (группами) услуг:
package ru.dsi.bgbilling.kernel.module.server.bean; import ru.bitel.bgbilling.common.BGException; import ru.bitel.bgbilling.server.util.ServerUtils; import ru.dsi.bgbilling.kernel.module.common.bean.ServiceLabelItem; import java.sql.*; import java.util.*; /** * Dao для работы с метками (группами) услуг */ public class ServiceLabelDao { protected static final String TABLE_SERVICE_LABEL = "custom_service_label"; protected static final String TABLE_SERVICE_LABEL_LINK = "custom_service_label_link"; private Connection con; public ServiceLabelDao(Connection con) { this.con = con; } public List<ServiceLabelItem> getServiceLabelItemList() throws BGException { List<ServiceLabelItem> result = new ArrayList<ServiceLabelItem>(); try { Map<Integer, ServiceLabelItem> map = new HashMap<Integer, ServiceLabelItem>(); Statement st = this.con.createStatement(); StringBuilder query = new StringBuilder("SELECT * FROM ") .append(TABLE_SERVICE_LABEL) .append(" ORDER BY title"); ResultSet rs = st.executeQuery(query.toString()); while (rs.next()) { ServiceLabelItem serviceLabelItem = getServiceLabelItemFromRS(rs); map.put(serviceLabelItem.getId(), serviceLabelItem); result.add(serviceLabelItem); } rs.close(); query.setLength(0); query.append("SELECT label_id, count(*) FROM ").append(TABLE_SERVICE_LABEL_LINK).append(" GROUP BY label_id"); rs = st.executeQuery(query.toString()); while (rs.next()) { ServiceLabelItem serviceLabelItem = map.get(rs.getInt(1)); if (serviceLabelItem != null) { serviceLabelItem.setServiceLinkCount(rs.getInt(2)); } } rs.close(); st.close(); } catch (Exception ex) { throw new BGException(ex); } return result; } public Set<Integer> getServiceLabelIds(int serviceId) throws BGException { Set<Integer> result = new HashSet<Integer>(); try { String query = "SELECT label_id FROM " + TABLE_SERVICE_LABEL_LINK + " WHERE sid=" + serviceId; Statement st = this.con.createStatement(); ResultSet rs = st.executeQuery(query); while (rs.next()) { result.add(rs.getInt(1)); } rs.close(); st.close(); } catch (Exception ex) { throw new BGException(ex); } return result; } public void setServiceLabelIds(int serviceId, Set<Integer> labelIds) throws BGException { try { StringBuilder query = new StringBuilder("DELETE FROM ").append(TABLE_SERVICE_LABEL_LINK) .append(" WHERE sid=").append(serviceId); Statement st = this.con.createStatement(); st.executeUpdate(query.toString()); st.close(); query.setLength(0); query.append("INSERT INTO ").append(TABLE_SERVICE_LABEL_LINK).append(" SET sid=").append(serviceId).append(", label_id=?"); PreparedStatement ps = this.con.prepareStatement(query.toString()); for (Integer id : labelIds) { ps.setInt(1, id); ps.executeUpdate(); } ps.close(); } catch (Exception ex) { throw new BGException(ex); } } public void updateServiceLabelTreeItem(ServiceLabelItem serviceLabelItem) throws BGException { try { if (serviceLabelItem == null) { throw new NullPointerException("serviceLabelItem is null!"); } StringBuilder query = new StringBuilder(); if (serviceLabelItem.getId() > 0) { query.append("UPDATE "); query.append(TABLE_SERVICE_LABEL); query.append(" SET parent_id=?, title=? WHERE id=?"); } else { query.append("INSERT INTO "); query.append(TABLE_SERVICE_LABEL); query.append(" SET parent_id=?, title=?"); } PreparedStatement ps = this.con.prepareStatement(query.toString()); ps.setInt(1, serviceLabelItem.getParentId()); ps.setString(2, serviceLabelItem.getTitle()); if (serviceLabelItem.getId() > 0) { ps.setInt(3, serviceLabelItem.getId()); } ps.executeUpdate(); if (serviceLabelItem.getId() < 0) { serviceLabelItem.setId(ServerUtils.lastInsertId(this.con)); } ps.close(); } catch (Exception ex) { throw new BGException(ex); } } public void removeServiceLabelItem(int serviceLabelItemId) throws BGException { try { Statement st = this.con.createStatement(); StringBuilder query = new StringBuilder("DELETE FROM ").append(TABLE_SERVICE_LABEL_LINK) .append(" WHERE label_id=").append(serviceLabelItemId); st.executeUpdate(query.toString()); query.setLength(0); query.append("DELETE FROM ").append(TABLE_SERVICE_LABEL).append(" WHERE id=").append(serviceLabelItemId); st.executeUpdate(query.toString()); st.close(); } catch (Exception ex) { throw new BGException(ex); } } /*public List<ServiceItem> getServices(int moduleId, List<Integer> serviceLabelIds) throws BGException { try { StringBuilder sb = new StringBuilder("SELECT * FROM service s "). append("left join module m on s.mid=m.id "). append("left join " + TABLE_SERVICE_LABEL_LINK + " sll on s.id=sll.sid "). append("WHERE 1 "); if(moduleId>0){ sb.append("AND s.mid=").append(moduleId).append(" "); } if(serviceLabelIds!=null && serviceLabelIds.size()>0){ sb.append("AND sll.label_id in (") .append(Utils.toString(serviceLabelIds)) .append(") "); } sb.append("GROUP BY ") PreparedStatement ps = this.con.prepareStatement(); } catch (SQLException e) { throw new BGException(e); } ServiceManager sm = new ServiceManager(this.con); List<Service> serviceList = sm.list(moduleId); for(Service service: serviceList){ service. } sm.recycle(); }*/ private ServiceLabelItem getServiceLabelItemFromRS(ResultSet rs) throws SQLException { ServiceLabelItem serviceLabelItem = new ServiceLabelItem(); serviceLabelItem.setId(rs.getInt("id")); serviceLabelItem.setParentId(rs.getInt("parent_id")); serviceLabelItem.setTitle(rs.getString("title")); return serviceLabelItem; } }
Клиентские классы
В файл /bitel/billing/module/services/npay/setup_user.properties пропишем нашу панель как вкладку модуля абонплат с названием «Группы услуг»
module.tab.3.class=bitel.billing.module.services.npay.ServiceLabelModulePanel module.tab.3.title=\u0413\u0440\u0443\u043F\u043F\u044B \u0443\u0441\u043B\u0443\u0433