2017-03-29 15:44:50 SYIF88 阅读数 5212
  • 深入浅出 Zabbix 4.0(基于 zabbix 4.2)

    课程目标     全面理解和掌握 Zabbix 监控系统的架构及运行原理,搭建和管理各种规模的Zabbix监控系统 课程简介         Zabbix是一个开源的企业级的监控解决方案。通过Zabbix可以监控IT基础设施的方方面面,包括硬件、操作系统、网络、虚拟化层、中间件和各种业务应用系统。用Zabbix几乎可以监控你想监控的任意数据。              本课程从Zabbix的介绍、安装开始,一步步带你深入Zabbix,通过学习你会:         1、掌握Zabbix各个组件的配置和管理。         2、掌握不同监控项的类型和配置方法,根据监控需求灵活配置监控项。         3、掌握网络发现、低级发现和主动式agent自动注册,实现自动化监控。         4、掌握模版、宏变量、触发器和告警通知的配置和高级的应用方法。         5、掌握图形、屏幕、拓扑图和仪表盘等数据可视化的方法,利用大屏可以实时的展示监控数据。         6、掌握Zabbix系统自身的维护、备份、升级、排障以及性能优化。         7、掌握Zabbix内部运行机制和Zabbix使用技巧,让zabbix更好的帮助你实现监控目标。                  本课程中还包含很多操作演示,比如像创建主机,创建监控项、触发器、图形、全局事件关联等,也介绍了微信和钉钉告警的配置方法。当你对Zabbix深入了解之后,面对层出不穷的新业务、新应用,你都能轻松自如的制定和提供相应的监控解决方案。 特别提示:官网的中文文档有些地方翻译的有问题,一定要以英文文档为准。

    999 人正在学习 去看看 程利民

现在基本上很多的企业都会使用钉钉,然后细心地人会看到钉钉组织架构功能。在联系人中放着一个可以展开的公司,下面有组织架构和自己所在的部门。


现在我们产品经理说我们项目中也要加入组织架构功能,而且给个变态的需求就是如果一个人在多家公司呢。那就得有多个组织架构了。

这个需求你可能一下就会想到用ExpandListView能解决所有问题。可以呢,如果他本身就存在在ExpandListView的header或者ListView的header中,你直接放入ExpandListView确定不影响滑动的时候的性能吗,在某些机型上滑动的时候会流畅吗。答案是:不允许这样嵌套

于是我就想到一个办法,就是动态的去生成item,并给每一个item加上点击监听,还有变态需求就是如果存在一个人多家公司,那么就要双层item并进行点击监听。

下面是我做的效果,就是通过动态添加和动态监听。


代码分析:

//点击展开组织架构事件
        RelativeLayout rl__organization_head[] = new RelativeLayout[organizationList.size()];
        //箭头m_
        final ImageView iv_organization_arrow[] = new ImageView[organizationList.size()];
        //组织架构的body
        final LinearLayout ll_organization_body[] = new LinearLayout[organizationList.size()];

        for (int j = 0; j < organizationList.size(); j++) {
            //初始化header(公司)部分
            organization_header_view = LayoutInflater.from(mContext).inflate(R.layout.item_organization_header, null);
            tv_organization_header_text = (TextView) organization_header_view.findViewById(R.id.tv_organizational_organization);
            rl__organization_head[j] = (RelativeLayout) organization_header_view.findViewById(R.id.rl__organization_head);
            iv_organization_arrow[j] = (ImageView) organization_header_view.findViewById(R.id.iv_organization_arrow);
            ll_organization_body[j] = (LinearLayout) organization_header_view.findViewById(R.id.ll_organization_body);

            tv_organization_header_text.setText(organizationList.get(j).getOrganizationName());

            //组织架构body(部门)-name
            TextView tv_organization_body_text[][] = new TextView[organizationList.size()][organizationList.get(j).getOrganizations().size()];

            for (int i = 0; i < organizationList.get(j).getOrganizations().size(); i++) {
                //初始化body(部门)部分
                insitution_body_view = LayoutInflater.from(mContext).inflate(R.layout.item_organization_body, null);
                tv_organization_body_text[j][i] = (TextView) insitution_body_view.findViewById(R.id.tv_organization_body_text);
                view_organization_body_text_line = insitution_body_view.findViewById(R.id.view_organization_body_text_line);

                if (i == 0) {
                    view_organization_body_text_line.setVisibility(View.GONE);
                }
                tv_organization_body_text[j][i].setText(organizationList.get(j).getOrganizations().get(i).getOrganizationName());
                ll_organization_body[j].addView(insitution_body_view);

                final int finalJ1 = j;
                final int finalI = i;
                tv_organization_body_text[j][i].setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        String departmentName = organizationList.get(finalJ1).getOrganizations().get(finalI).getOrganizationName();
                        String departmentId = organizationList.get(finalJ1).getOrganizations().get(finalI).getOrganizationId();
                        Intent intent = new Intent(getActivity(), OrganizationActivity.class);
                        intent.putExtra("organizationId", organizationList.get(finalJ1).getOrganizationId());
                        intent.putExtra("organizationName", organizationList.get(finalJ1).getOrganizationName());
                        if (finalI > 0) {
                            intent.putExtra("nextFlag", "next");
                            intent.putExtra("firstIntent", "first");
                        }
                        intent.putExtra("departmentId", departmentId);
                        intent.putExtra("departmentName", departmentName);
                        startActivity(intent);
                    }
                });
            }

            //默认关闭组织架构
            ll_organization_body[j].setVisibility(View.GONE);
            iv_organization_arrow[j].setBackgroundResource(R.drawable.cell_header_down);

            ll_organization_header.addView(organization_header_view);

            final int finalJ = j;
            rl__organization_head[j].setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (isShowFra) {
                        iv_organization_arrow[finalJ].setBackgroundResource(R.drawable.cell_header_up);
                        isShowFra = false;
                        ll_organization_body[finalJ].setVisibility(View.VISIBLE);
                    } else {
                        iv_organization_arrow[finalJ].setBackgroundResource(R.drawable.cell_header_down);
                        isShowFra = true;
                        ll_organization_body[finalJ].setVisibility(View.GONE);
                    }
                }
            });
        }

    }
有道行的一眼就能看出怎么回事,对我用的数组去处理点击监听问题。类似仿写一个简单的ExpandListView,对绘制和滑动没有任何影响,占用内存也不大。

就是不断的addView动态将item addView到第二层,然后再将第二层动态addView到第一层,以双重for循环处理。organizationList.size()就可以生成多少个公司的组织架构。是不是类似与ExpandListView了,这里为什么不用ExpandListView,是因为这个组件要放在ExpandListView的header里面,至少这样也不会影响ExpandListView的性能。

至于如果只要一个公司呢,organizationList.size() = 1或者拆分出只要一层for循环就行了。精华部分就是怎么去给每一个item添加点击监听事件,这个解决了,多少层都没有问题,一个大树都没有问题。


补充组织架构里面部门的写法,也是简单一级循环监听的方式来处理部门列表的显示,当然也可以用listview也可以做,只是需要对数据处理

/**
     * 处理部门显示的ui
     */
    private void handleDepartmentUi() {
        if (departmentData != null && departmentData.size() > 0) {
            for (int i = 0; i < departmentData.size(); i++) {
                department_item_view = LayoutInflater.from(this).inflate(R.layout.item_organization_department, null);
                rl_department_item = (RelativeLayout) department_item_view.findViewById(R.id.rl_organization_department_item);
                tv_department_name = (TextView) department_item_view.findViewById(R.id.tv_organization_department_name);
                tv_department_count = (TextView) department_item_view.findViewById(R.id.tv_organization_department_count);

                tv_department_name.setText(departmentData.get(i).getOrganizationName());
//                tv_department_count.setText("100");
                //统一监听每个item
                rl_department_item.setOnClickListener(clickListener);
                rl_department_item.setTag(i);

                ll_department_item.addView(department_item_view);
            }
        } else {
            ll_department_item.setVisibility(View.GONE);
            view_department_line_1.setVisibility(View.GONE);
        }
    }

    /**
     * 处理组织架构item的监听
     */
    private View.OnClickListener clickListener = new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            int id = (Integer) v.getTag();
            Intent intent = new Intent(DepartmentActivity.this, OrganizationActivity.class);
            intent.putExtra("departmentName", departmentData.get(id).getOrganizationName());
            intent.putExtra("departmentId", departmentData.get(id).getOrganizationId());
            intent.putExtra("organizationId", organizationId);
            intent.putExtra("organizationName", organizationName);
            intent.putExtra("nextFlag", "next");
            startActivityForResult(intent, CLOSEREQUESTCODE);
        }
    };

这里就是我简单处理部门的方式,其实listview也可以做的,但是要看需求

不知道是否是你们所需要的,还是其他部分,可以提问




2018-08-23 16:45:18 zxc110915017 阅读数 499
  • 深入浅出 Zabbix 4.0(基于 zabbix 4.2)

    课程目标     全面理解和掌握 Zabbix 监控系统的架构及运行原理,搭建和管理各种规模的Zabbix监控系统 课程简介         Zabbix是一个开源的企业级的监控解决方案。通过Zabbix可以监控IT基础设施的方方面面,包括硬件、操作系统、网络、虚拟化层、中间件和各种业务应用系统。用Zabbix几乎可以监控你想监控的任意数据。              本课程从Zabbix的介绍、安装开始,一步步带你深入Zabbix,通过学习你会:         1、掌握Zabbix各个组件的配置和管理。         2、掌握不同监控项的类型和配置方法,根据监控需求灵活配置监控项。         3、掌握网络发现、低级发现和主动式agent自动注册,实现自动化监控。         4、掌握模版、宏变量、触发器和告警通知的配置和高级的应用方法。         5、掌握图形、屏幕、拓扑图和仪表盘等数据可视化的方法,利用大屏可以实时的展示监控数据。         6、掌握Zabbix系统自身的维护、备份、升级、排障以及性能优化。         7、掌握Zabbix内部运行机制和Zabbix使用技巧,让zabbix更好的帮助你实现监控目标。                  本课程中还包含很多操作演示,比如像创建主机,创建监控项、触发器、图形、全局事件关联等,也介绍了微信和钉钉告警的配置方法。当你对Zabbix深入了解之后,面对层出不穷的新业务、新应用,你都能轻松自如的制定和提供相应的监控解决方案。 特别提示:官网的中文文档有些地方翻译的有问题,一定要以英文文档为准。

    999 人正在学习 去看看 程利民

前言

开发中我们会遇到同一个标题头部,类似注册或重置密码时的分步操作,标题栏都是相同的,只是内容部分的输入框有所不同,可能会想到直接写多个Activity来实现,但是这样的话内存消耗上面就多了,这个时候我们就可以利用Fragment的回退栈来实现这个功能。本文所说的仿钉钉的组织架构功能就是基于这个来实现的,Fragment回退栈具体相关的知识可自行去了解,本文只作简单介绍。

相关方法

  • addToBackStack(String tag);//将Fragment加入回退栈,tag为此Fragment在回退栈中的唯一标识
  • getBackStackEntryCount();//获取回退栈Fragment的总个数
  • getBackStackEntryAt(int index);//获取回退栈中某个Fragment
  • popBackStack();//将回退栈中栈顶的Fragment出栈
  • popBackStackImmediate(String tag, int flags);
    tag为null,flags为0时,弹出回退栈中最上层的那个fragment,flags为1时,弹出回退栈中所有fragment。
    tag不为null,flags为0时,弹出该fragment以上的Fragment,如果是1,弹出该fragment(包括该fragment)以
    上的fragment。
  • fullScroll(HorizontalScrollView.FOCUS_RIGHT);//控制HorizontalScrollView滚动到最右边,延时调用

效果图

效果展示

实现思路

1.可以选择在加入回退栈的时候传入当前部门的名称作为tag

private void initDeptFragment(ArrayList<DeptListBean.DataBean.DepartmentListBean> mDeptList,
                                  ArrayList<String> mDeptUserList, String tag) {
        Fragment mDeptFragment = new DeptFragment();
        FragmentManager manager = getActivity().getSupportFragmentManager();
        Bundle bundle = new Bundle();
        bundle.putParcelableArrayList("deptList", mDeptList);
        bundle.putStringArrayList("deptUserList", mDeptUserList);
        mDeptFragment.setArguments(bundle);
        manager.beginTransaction()
                .replace(R.id.dept_content, mDeptFragment)
                .addToBackStack(tag)
                .commit();
    }

2.点击导航tab时,通过这个tag找到Fragment,然后再进行相关操作

 mNavView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    int currentIndex = 0;

                    if (mNavView.getTag() != null) {
                        currentIndex = (int) mNavView.getTag();
                    }

                    if (currentIndex == 0) {//点击回到一级部门,清除所有回退栈
                        if (mNavNameList.size() > 1) {
                            getActivity().getSupportFragmentManager().popBackStackImmediate(mNavNameList.get(1), FragmentManager.POP_BACK_STACK_INCLUSIVE);
                        }
                    } else {
                        getActivity().getSupportFragmentManager().popBackStackImmediate(mNavNameList.get(currentIndex), 0);
                    }

                }
            });

3.动态添加导航tab后,控制滚动到最右边

mHsvNav.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mHsvNav.fullScroll(HorizontalScrollView.FOCUS_RIGHT); //方法不能直接被调用,可能会不生效,需先加入消息队列等待调用
                }
            }, 100L);

4.返回处理,根据回退栈Fragment数量决定是清除栈顶Fragment还是退出Activity

mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (getActivity().getSupportFragmentManager().getBackStackEntryCount() > 0) {
                    getActivity().getSupportFragmentManager().popBackStack();
                } else {
                    getActivity().finish();
                }
            }
        });

小弟理解可能有所偏差,欢迎各位对之中出现的错误或是代码的质量优化,不吝赐教,谢谢!

Demo下载


2018-05-31 17:41:19 qq_27626333 阅读数 6887
  • 深入浅出 Zabbix 4.0(基于 zabbix 4.2)

    课程目标     全面理解和掌握 Zabbix 监控系统的架构及运行原理,搭建和管理各种规模的Zabbix监控系统 课程简介         Zabbix是一个开源的企业级的监控解决方案。通过Zabbix可以监控IT基础设施的方方面面,包括硬件、操作系统、网络、虚拟化层、中间件和各种业务应用系统。用Zabbix几乎可以监控你想监控的任意数据。              本课程从Zabbix的介绍、安装开始,一步步带你深入Zabbix,通过学习你会:         1、掌握Zabbix各个组件的配置和管理。         2、掌握不同监控项的类型和配置方法,根据监控需求灵活配置监控项。         3、掌握网络发现、低级发现和主动式agent自动注册,实现自动化监控。         4、掌握模版、宏变量、触发器和告警通知的配置和高级的应用方法。         5、掌握图形、屏幕、拓扑图和仪表盘等数据可视化的方法,利用大屏可以实时的展示监控数据。         6、掌握Zabbix系统自身的维护、备份、升级、排障以及性能优化。         7、掌握Zabbix内部运行机制和Zabbix使用技巧,让zabbix更好的帮助你实现监控目标。                  本课程中还包含很多操作演示,比如像创建主机,创建监控项、触发器、图形、全局事件关联等,也介绍了微信和钉钉告警的配置方法。当你对Zabbix深入了解之后,面对层出不穷的新业务、新应用,你都能轻松自如的制定和提供相应的监控解决方案。 特别提示:官网的中文文档有些地方翻译的有问题,一定要以英文文档为准。

    999 人正在学习 去看看 程利民

  不得不吐槽钉钉开发文档过于简单,今天研究了几个小时,踩了各种坑,终于可以调试微应用了,钉钉开发Android调试微应用,这是官网文档,首先下载Android开发包下载地址,开始的时候手机怎么也装不上,总是提示安装失败!后面发现必须先卸载非开发版的钉钉,然后在安装开发版的钉钉。

1、远程调试 Android 设备使用入门
  远程调试 Android 设备使用入门的官方文档地址Remote debugging on Android with Chrome DevTools,查看这个文档需要翻墙,可以安装Lantern下载地址,按照步骤一步一步进行调试,最后成功的结果如图所示:
这里写图片描述
此处是在手机chrome APP浏览器中打开微应用。

2、打开钉钉开发版微应用调试

  • 进入“我的”(个人资料页)
  • 选择“设置”
  • 选择“通用”
  • 选择“开发者选项”
  • 打开“微应用调试”

    在chrome控制台可以看到如下:
    这里写图片描述
    在钉钉开发版中打开自己开发的微应用效果如图:
    这里写图片描述
    点击Inspect就可以查看调试信息了如图:
    这里写图片描述

在浏览器中输入chrome://inspect/#devices也可以进行调试如图:
这里写图片描述

接下来就是好好写bug改bug了。

2020-01-08 16:26:40 qq_36907589 阅读数 17
  • 深入浅出 Zabbix 4.0(基于 zabbix 4.2)

    课程目标     全面理解和掌握 Zabbix 监控系统的架构及运行原理,搭建和管理各种规模的Zabbix监控系统 课程简介         Zabbix是一个开源的企业级的监控解决方案。通过Zabbix可以监控IT基础设施的方方面面,包括硬件、操作系统、网络、虚拟化层、中间件和各种业务应用系统。用Zabbix几乎可以监控你想监控的任意数据。              本课程从Zabbix的介绍、安装开始,一步步带你深入Zabbix,通过学习你会:         1、掌握Zabbix各个组件的配置和管理。         2、掌握不同监控项的类型和配置方法,根据监控需求灵活配置监控项。         3、掌握网络发现、低级发现和主动式agent自动注册,实现自动化监控。         4、掌握模版、宏变量、触发器和告警通知的配置和高级的应用方法。         5、掌握图形、屏幕、拓扑图和仪表盘等数据可视化的方法,利用大屏可以实时的展示监控数据。         6、掌握Zabbix系统自身的维护、备份、升级、排障以及性能优化。         7、掌握Zabbix内部运行机制和Zabbix使用技巧,让zabbix更好的帮助你实现监控目标。                  本课程中还包含很多操作演示,比如像创建主机,创建监控项、触发器、图形、全局事件关联等,也介绍了微信和钉钉告警的配置方法。当你对Zabbix深入了解之后,面对层出不穷的新业务、新应用,你都能轻松自如的制定和提供相应的监控解决方案。 特别提示:官网的中文文档有些地方翻译的有问题,一定要以英文文档为准。

    999 人正在学习 去看看 程利民

此功能设计:抓取钉钉组织架构下所有部门 进行统计

1.统计各个部门下所有人员总人数 和当前统计部门ID 和部门名称

2.统计各个部门的主管如果该最底层部门有主管这设置如果没有默认往上在找一级部门 寻求主管信息,如果还没有则放弃寻找

此方法非常耗时,请跟进公司个人组织架构人数在确定使用,本测试数据 7000人 800+部门

 

/**
     * 主管测试
     * @throws Exception
     */
    @RequestMapping(params = "getDepChargeTest")
    @ResponseBody
    public void getDepChargeTest() throws Exception {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/list");
        OapiDepartmentListRequest request = new OapiDepartmentListRequest();
        request.setId("1");//118063677 信息技术中心  127041966  运营管理 127041966
        request.setHttpMethod("GET");
        request.setFetchChild(true);//是否递归部门的全部子部门,ISV微应用固定传递false
        OapiDepartmentListResponse response = client.execute(request, NhTokenThread.accessToken);
        List<OapiDepartmentListResponse.Department> department = response.getDepartment();
        int count =0;
        for (OapiDepartmentListResponse.Department department1 : department) {
            String departmentName = department1.getName();//部门名称
            Long departmentId = department1.getId();//部门ID

            //查询是否有子部门
            DingTalkClient clientChild = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/list_ids");
            OapiDepartmentListIdsRequest requestChild = new OapiDepartmentListIdsRequest();
            requestChild.setId(String.valueOf(departmentId));
            requestChild.setHttpMethod("GET");
            OapiDepartmentListIdsResponse responseChild = clientChild.execute(requestChild, NhTokenThread.accessToken);
            List<Long> subDeptChildIdList = responseChild.getSubDeptIdList();
            if(subDeptChildIdList.size()==0){
                //查询最下级子部门所有上级部门
                DingTalkClient clientSupDep = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/list_parent_depts_by_dept");
                OapiDepartmentListParentDeptsByDeptRequest requestSupDep = new OapiDepartmentListParentDeptsByDeptRequest();
                requestSupDep.setId(departmentId.toString());
                requestSupDep.setHttpMethod("GET");
                OapiDepartmentListParentDeptsByDeptResponse responseSupDep = clientSupDep.execute(requestSupDep, NhTokenThread.accessToken);
                List<Long> parentIds = responseSupDep.getParentIds();
                //主管姓名
                String  managePerson ="";
                //主管userID
                String  manageUserId ="";
                if(parentIds!=null){
                    if(parentIds.size()>=0){
                        Long depSupDep = parentIds.get(0);//上级部门ID
                        //通过上级部门id获取上级主管信息
                        DingTalkClient clientDepSum = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/simplelist");
                        OapiUserSimplelistRequest  requestDepSum= new OapiUserSimplelistRequest();
                        requestDepSum.setDepartmentId(depSupDep);
                        requestDepSum.setHttpMethod("GET");
                        try {
                            OapiUserSimplelistResponse responseDepSum = clientDepSum.execute(requestDepSum, NhTokenThread.accessToken);
                            List<OapiUserSimplelistResponse.Userlist> userlist = responseDepSum.getUserlist();
                            for (OapiUserSimplelistResponse.Userlist userlists : userlist) {
                                DingTalkClient clientMag = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get");
                                OapiUserGetRequest requestMag = new OapiUserGetRequest();
                                requestMag.setUserid(userlists.getUserid());
                                requestMag.setHttpMethod("GET");
                                OapiUserGetResponse responseMag = clientMag.execute(requestMag, NhTokenThread.accessToken);
                                String isLeaderInDepts = responseMag.getIsLeaderInDepts();
                                if(StringUtil.isNotEmpty(isLeaderInDepts)){
                                    if(isLeaderInDepts.contains("true")){
                                     //如果是主管
                                        managePerson=responseMag.getName();
                                        manageUserId=responseMag.getUserid();
                                    }
                                }
                            }
                        }catch (ApiException e) {
                            e.printStackTrace();
                        }
                        //如果通过上级部门未查出来主管信息,则再往上级部门查询
                        if(StringUtil.isEmpty(managePerson)&&StringUtil.isEmpty(manageUserId) ){
                                        //如果本部门没有主管再次往上一级部门查找【最高查询2级】
                                        if(parentIds.size()>=1) {
                                            Long depSupDepSuperior = parentIds.get(1);//上级部门ID
                                            //通过上级部门id获取上[上]级主管信息
                                            DingTalkClient clientDepSumUp = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/simplelist");
                                            OapiUserSimplelistRequest  requestDepSumUp= new OapiUserSimplelistRequest();
                                            requestDepSumUp.setDepartmentId(depSupDepSuperior);
                                            requestDepSumUp.setHttpMethod("GET");

                                            try {
                                                OapiUserSimplelistResponse responseDepSumUp = clientDepSumUp.execute(requestDepSumUp, NhTokenThread.accessToken);
                                                List<OapiUserSimplelistResponse.Userlist> userlistUp = responseDepSumUp.getUserlist();
                                                for (OapiUserSimplelistResponse.Userlist userlistUps : userlistUp) {

                                                    DingTalkClient clientMagUp = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/get");
                                                    OapiUserGetRequest requestMagUp = new OapiUserGetRequest();
                                                    requestMagUp.setUserid(userlistUps.getUserid());
                                                    requestMagUp.setHttpMethod("GET");
                                                    OapiUserGetResponse responseMagUp = clientMagUp.execute(requestMagUp, NhTokenThread.accessToken);
                                                    String isLeaderInDeptsUp = responseMagUp.getIsLeaderInDepts();
                                                    if (StringUtil.isNotEmpty(isLeaderInDeptsUp)) {
                                                        if (isLeaderInDeptsUp.contains("true")) {
                                                            //如果是主管
                                                            managePerson = responseMagUp.getName();
                                                            manageUserId = responseMagUp.getUserid();
                                                        }
                                                    }
                                                }
                                            }catch (ApiException e) {
                                                e.printStackTrace();
                                            }

                                        }
                        }
                    }
                }
                //说明没有子部门
                //通过部门名称 和部门ID 查询改部门下有多少人
                DingTalkClient clientDepSum = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/simplelist");
                OapiUserSimplelistRequest  requestDepSum= new OapiUserSimplelistRequest();
                requestDepSum.setDepartmentId(departmentId);
                requestDepSum.setHttpMethod("GET");
                try {
                    OapiUserSimplelistResponse responseDepSum = clientDepSum.execute(requestDepSum, NhTokenThread.accessToken);
                    List<OapiUserSimplelistResponse.Userlist> userlist = responseDepSum.getUserlist();
                    TDingLogDepBaseEntity tDingLogDepBaseEntity = new TDingLogDepBaseEntity();
                    tDingLogDepBaseEntity.setCreateDate(new Date());
                    tDingLogDepBaseEntity.setDepName(departmentName);
                    tDingLogDepBaseEntity.setDepId(departmentId.toString());
                    tDingLogDepBaseEntity.setDepNum(String.valueOf(userlist.size()));
                    tDingLogDepBaseEntity.setDepLeadName(managePerson);
                    tDingLogDepBaseEntity.setDepLeadId(manageUserId);
                    tDingLogDepBaseService.save(tDingLogDepBaseEntity);

                    System.out.println("部门: "+departmentName+"  部门ID=" + departmentId + "  人数  " + userlist.size()+"  部门主管  "+managePerson  +"  部门主管ID "+manageUserId);
                }catch (ApiException e) {
                    e.printStackTrace();
                }
            }else {
                int sumDepAllCount=0;//改部门下人数
                DingTalkClient clientChildAlldep = new DefaultDingTalkClient("https://oapi.dingtalk.com/department/list");
                OapiDepartmentListRequest requestChildAlldep = new OapiDepartmentListRequest();
                requestChildAlldep.setId(department1.getId().toString());
                requestChildAlldep.setHttpMethod("GET");
                requestChildAlldep.setFetchChild(true);//是否递归部门的全部子部门,ISV微应用固定传递false
                OapiDepartmentListResponse responseChildAlldep = clientChildAlldep.execute(requestChildAlldep, NhTokenThread.accessToken);
                List<OapiDepartmentListResponse.Department> departmentChildAlldep = responseChildAlldep.getDepartment();
                if(departmentChildAlldep.size()!=0){
                        for (OapiDepartmentListResponse.Department department2 : departmentChildAlldep) {
                               //通过部门名称 和部门ID 查询改部门下有多少人
                               DingTalkClient clientDepSum = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/simplelist");
                               OapiUserSimplelistRequest  requestDepSum= new OapiUserSimplelistRequest();
                              requestDepSum.setDepartmentId(department2.getId());
                               requestDepSum.setHttpMethod("GET");
                               try {
                                   OapiUserSimplelistResponse responseDepSum = clientDepSum.execute(requestDepSum, NhTokenThread.accessToken);
                                   List<OapiUserSimplelistResponse.Userlist> userlist = responseDepSum.getUserlist();
                                    int sumDepAll= userlist.size();
                                   sumDepAllCount=sumDepAll+sumDepAllCount; //如果多级子部门循环算出改部门下所有人数
                                }catch (ApiException e) {
                                    e.printStackTrace();
                               }
                           }
                    }
                //通过部门名称 和部门ID 查询改部门下主管信息 和 该主管部门下 负责的总人数
                DingTalkClient clientDepSum = new DefaultDingTalkClient("https://oapi.dingtalk.com/user/simplelist");
                OapiUserSimplelistRequest  requestDepSum= new OapiUserSimplelistRequest();
                requestDepSum.setDepartmentId(departmentId);
                requestDepSum.setHttpMethod("GET");
                try {
                    OapiUserSimplelistResponse responseDepSum = clientDepSum.execute(requestDepSum, NhTokenThread.accessToken);
                    List<OapiUserSimplelistResponse.Userlist> userlist = responseDepSum.getUserlist();
                    for (OapiUserSimplelistResponse.Userlist userlists : userlist) {
                        TDingLogDepBaseEntity tDingLogDepBaseEntity = new TDingLogDepBaseEntity();
                        tDingLogDepBaseEntity.setCreateDate(new Date());
                        tDingLogDepBaseEntity.setDepName(departmentName);
                        tDingLogDepBaseEntity.setDepId(departmentId.toString());
                        tDingLogDepBaseEntity.setDepNum(String.valueOf((sumDepAllCount+userlist.size())));
                        tDingLogDepBaseEntity.setDepLeadName(userlists.getName());
                        tDingLogDepBaseEntity.setDepLeadId(userlists.getUserid());
                        tDingLogDepBaseService.save(tDingLogDepBaseEntity);
                        System.out.println("主管部门: "+departmentName+"  主管部门ID=" + departmentId + " 人数 "+(sumDepAllCount+userlist.size())+"  主管名字 " + userlists.getName() +"  主管ID "+userlists.getUserid());
                    }
                }catch (ApiException e) {
                    e.printStackTrace();
                }

            }
        }
        System.out.println("--------------------------------------end-------------------------");
    }

 

2019-11-28 21:24:51 heming9174 阅读数 67
  • 深入浅出 Zabbix 4.0(基于 zabbix 4.2)

    课程目标     全面理解和掌握 Zabbix 监控系统的架构及运行原理,搭建和管理各种规模的Zabbix监控系统 课程简介         Zabbix是一个开源的企业级的监控解决方案。通过Zabbix可以监控IT基础设施的方方面面,包括硬件、操作系统、网络、虚拟化层、中间件和各种业务应用系统。用Zabbix几乎可以监控你想监控的任意数据。              本课程从Zabbix的介绍、安装开始,一步步带你深入Zabbix,通过学习你会:         1、掌握Zabbix各个组件的配置和管理。         2、掌握不同监控项的类型和配置方法,根据监控需求灵活配置监控项。         3、掌握网络发现、低级发现和主动式agent自动注册,实现自动化监控。         4、掌握模版、宏变量、触发器和告警通知的配置和高级的应用方法。         5、掌握图形、屏幕、拓扑图和仪表盘等数据可视化的方法,利用大屏可以实时的展示监控数据。         6、掌握Zabbix系统自身的维护、备份、升级、排障以及性能优化。         7、掌握Zabbix内部运行机制和Zabbix使用技巧,让zabbix更好的帮助你实现监控目标。                  本课程中还包含很多操作演示,比如像创建主机,创建监控项、触发器、图形、全局事件关联等,也介绍了微信和钉钉告警的配置方法。当你对Zabbix深入了解之后,面对层出不穷的新业务、新应用,你都能轻松自如的制定和提供相应的监控解决方案。 特别提示:官网的中文文档有些地方翻译的有问题,一定要以英文文档为准。

    999 人正在学习 去看看 程利民

感觉都好久没写博客了.
最近这小半年自己都不知道忙啥去了,各种乱七八糟的杂事.
今天刚好将迭代的项目从老的环境迁移到专门的Jenkins服务器里面,就加个班写个这个吧.
当初最早为了弄这个,可是没有少找这方面的资料.

本篇博客背景说明.

说一下正在使用的构建代码环境.
每次版本迭代提测,测试都自己去 Jenkins里面去选 接口环境,选 对应代码分支进行 Jenkins自动构建,构建完成后,自动上传至蒲公英,最后在钉钉群内进行消息推送.


前期准备工作.part1

1.构建一个Jenkins环境,具体怎么弄,自行搜索.
2.注册一个蒲公英,类似于fir,用fir也行,这里我用蒲公英演示.
3.用的是钉钉,创建对应的 智能群助手,后面会说明.

前期准备工作.part2

1.默认你Jenkins环境已经搭建成功,
Manage Jenkins --> Manage Plugins
搜索下载

  • Upload to pgyer(有现成插件,不用其实也可以,有单独的服务器,可以自己用服务器IP去请求上传)(如果是用fir的话,就下载这个fir-plugin,具体应该没有多大差异,原理都一样).
  • Dingding[钉钉] Plugin,看名字就知道了,钉钉进行消息通知,除了 智能群助手外,还需要这个进行搭配.

这是2个相关的插件,至于其他的必备插件,
比如说 gitlab/github branch plugin 自定义分支选择,Gradle gradle编译配置,Groovy Postbuild 支持groovy语法等插件,这些一般会在Jenkins环境搭建相关的技术博客内提及或附带.(在本文最后附带我这项目Jenkins环境的插件列表)

2.蒲公英注册好以后,创建应用,拿到API Key 这个是 基本操作,就不作赘述.

3.钉钉 智能群助手 机器人,没有默认的Jenkins,选择 自定义Webhook机器人.
钉钉-智能群助手-机器人

钉钉Webhook机器人相关文档:
https://ding-doc.dingtalk.com/doc#/serverapi2/qf2nxq

照着文档来,起好名字,消息推送开关打开,保管好Webhook的地址,到时候推送 APP构建完成,推送对应的二维码就靠这个Webhook地址了.


Jenkins新增项目配置说明

新建Item,根据你们自己的项目性质,自己选择,我这肯定就是 Freestyle Project.点击确定后,到了重头戏部分,也就是Jenkins对于你这个项目的配置部分.
窗帘
emmm…这就是你的项目的窗帘了,赶紧把心目中想好的骚话写出来吧,看到&nbsp,各种标签,你懂得,html…

自定义编译配置
添加参数

通用–Choice Parameter

自定义接口环境,这个需要下载对应Jenkins插件,以及APP代码这边build.gradle对应自定义buildTypes配置,这个因人而异,不会的,可以自行搜索关键字[Android,自定义buildTypes].
同时建议在描述里面写上对应接口环境的描述,方便测试同事理解选择(小声BB:只有对测试好一点,才会给你少提点BUG,人天缺陷才没有那么难看).

通用–Git Parameter

自定义代码分支选择,毕竟随着版本迭代,master,各种dev,各种temp分支,各种fix分支,一个比一个多,没有这个怎么行.

记住这个里面2个设置的Name, BUILD_TYPE 和 GIT_BRANCH,后面会用到,(具体名字叫啥随便,后面会引用到这个)

源码管理
这个就是你构建项目的代码来源了,
我这里使用的是Gitlab,所以就填写Git地址了,具体的你们使用SVN还是Github还是码云 还是啥的,都大同小异.

源码管理–Credentials

刚刚搭建好的Jenkins这个可能没有咯,点添加吧.
添加Jenkins凭证
我司使用的是SSH,这个根据你们自己公司的实际环境去自己选择,
以SSH为例,输入对应的Username,Private Key内打开你的C:\Users\你的电脑用户名\.ssh 内的id_rsa文件, 如果没有弄过SSH的,搜索关键字[SSH生成KEY]

注意,复制Private Key 请全部复制,

包括
-----BEGIN RSA PRIVATE KEY-----
-----END RSA PRIVATE KEY-----
这2个部分,别问我是怎么知道的.


关于Credentials的管理

可能又有人会问,诶呀,我手抖之前添加错了,我又重新添加了一个,现在跑出2个一模一样的,这可肿么办啊…
看图,在这里管理.
凭证管理


话题拐回来继续说 源码管理这一个配置,
指定分支(为空时代表any) : ${GIT_BRANCH}
看图我的红框,想起前面我提起过的 BUILD_TYPE 和 GIT_BRANCH 吗?
你起了对应的Name,然后你在构建代码的时候,对 代码分支和APP接口环境进行选择,会将对应的选择结果赋予这里.

构建

构建–Invoke Gradle Script

现在已经是9012年了,Android已经都是Gradle编译了,Ant对于Android来说已经是 时代的眼泪了, 勾选Invoke Gradle,选择对应的Gradle版本,请和你当前项目gradle/wrapper/gradle-wrapper.properties内distributionUrl的Gradle版本对应.

可能又会有少年问了,这里面没有我想要的Gradle肿么办呢?
保存 – Jenkins回到首页 – Manage Jenkins – Global Tool Configuration – 选择Gradle安装 – 新增Gradle
写好名称,Install from Gradle.org里面选择好对应的版本,再次回来,发现就有了.
至于Task里面写的,按照每个人的项目需求去自定义,

构建–Upload to pyger with apiV2

这个是我前面提及的蒲公英的上传插件.如果安装好了,那就直接把API_KEY填进去,另外2项就用默认就行.

构建后操作–Groovy Postbuild

这里是最重要的地方,前面配置好了,只是可以进行项目的构建和对应的蒲公英上传,
下面这个Groovy语法可以自定义一些拓展的逻辑,比如说将APP上传到蒲公英后的地址和二维码进行保存,然后结合钉钉的智能群助手进行推送,然后展示在群里面.
下面贴出Groovy代码:

import java.util.*;
import java.text.SimpleDateFormat;

//构建结果
def buildResult = manager. getResult()
//构建用户
def buildUser= manager.getEnvVariable("BUILD_USER")
//项目名称
def jobName= manager.getEnvVariable("JOB_NAME")
//构建结果页面
def buildUrl= manager.getEnvVariable("BUILD_URL")
//GIT分支
def gitBranch= manager.getEnvVariable("GIT_BRANCH")


manager.listener.logger.println("构建分支:"+gitBranch)
manager.listener.logger.println("构建结果:"+buildResult)
manager.listener.logger.println("构建用户:"+buildUser)
manager.listener.logger.println("项目名称:"+ jobName)


if(buildResult == "SUCCESS"){
	//解析蒲公英上传返回数据
	//apk下载地址
	apkDownloadUrl = "https://www.pgyer.com/"+ manager.getEnvVariable("buildShortcutUrl")
	//apk二维码
	apkQrCode = manager.getEnvVariable("appQRCodeURL")
	
	manager.listener.logger.println("apk下载地址"+apkDownloadUrl)  
	manager.listener.logger.println("apk二维码地址:"+apkQrCode)  
	
	dingding("标题","### 《"+jobName+"》构建成功\n分支:"+gitBranch+"\n\n[APK下载地址]("+apkDownloadUrl+")\n![]("+apkQrCode+")\n\n"+buildUser+" "+getNowTime()+" 构建\n\n[查看详情]("+buildUrl+")")
}else if(buildResult == "ABORTED"){
    dingding("标题","### 《"+jobName+"》构建被终止\n"+buildUser+" "+getNowTime()+" 终止\n\n[查看详情]("+buildUrl+")")
}else{
	dingding("标题","### 《"+jobName+"》构建失败\n分支:"+gitBranch+"\n\n"+buildUser+" "+getNowTime()+" 构建\n\n[查看详情]("+buildUrl+")")
}


//发送钉钉消息
def dingding(p_title,p_text){
    manager.listener.logger.println("--------------------------"+p_title+p_text)
	def json= new groovy.json.JsonBuilder()
	json {
		msgtype "markdown"
		markdown {
			title p_title
			text p_text
		}
		at {
			atMobiles([])
			isAtAll false
		}
	}
   
	 manager.listener.logger.println("发送钉钉数据:"+json)

	def connection = new URL("你的自定义Webhook机器人的Webhook地址").openConnection()
	connection.setRequestMethod('POST')
	connection.doOutput = true
	connection.setRequestProperty('Content-Type', 'application/json')

	def writer = new OutputStreamWriter(connection.outputStream)
	writer.write(json.toString());
	writer.flush()
	writer.close()
	connection.connect()

	def respText = connection.content.text

	manager.listener.logger.println("钉钉返回结果:"+respText )
}
//获取当前时间
def getNowTime(){
	def str = "";
	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	Calendar lastDate = Calendar.getInstance();
	str = sdf.format(lastDate.getTime());
	return str;
}

注意事项

  1. 获取构建分支等信息获取,
  2. 获取蒲公英上传APP成功后的相关信息
    蒲公英上传成功后,会将返回的参数注入为jenkins的全局变量
    注意使用 manage.getgetEnvVariable(“XXX”)去获取,可获取的具体参数信息见文档

https://www.pgyer.com/doc/api#uploadApp

  1. 推送到钉钉群需要的Webhook地址.

构建后操作–Archive the artifacts

存档!!!

补上最后构建成功推送到钉钉群的效果图
效果图


写在最后.

Jenkins是一个很灵活的工具,本篇介绍的只是我当前使用的很狭小的一个实例.
结合插件支持各种拓展,进行各种自动化处理.

比如说
自己写shell命令,写各种逻辑,
自动检测代码提交,定时触发自动构建,发送邮件通知等等…
这里我就不列举了.


最后附上项目的Jenkins的插件列表:
Jenkins 插件-1
Jenkins 插件-2
Jenkins 插件-3
Jenkins 插件-4
Jenkins 插件-5
Jenkins 插件-6

钉钉E应用架构详解

阅读数 10618

高仿android通讯录

阅读数 181

没有更多推荐了,返回首页