Метки услуг

Материал из BiTel WiKi

Перейти к: навигация, поиск

Содержание

Описание

Для отчётов полезно иметь группировку услуг по типам вне зависимости от модуля. Например, группа услуг "Интернет" - туда могут входить как услуги трафиков модулей 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;
    }
}

Клиентские классы

Личные инструменты