博客 / 詳情

返回

金蝶雲蒼穹,新手初學者小白PC端java插件開發教學示例

注:
1.本文章的面向對象為剛剛接觸金蝶雲蒼穹星空旗艦版,具有PC端Java插件開發需求的新手、小白、與初學者
2.本文章中涉及的開發環境包括:金蝶雲蒼穹星空旗艦版開發平台、安裝了金蝶官方插件的IDEA
3.插件的實際開發涉及表單頁面的生命週期,建議對此內容有一定熟悉,頁面的生命週期參考文章:
https://vip.kingdee.com/article/403237280594265344?productLineId=29&lang=zh-CN
4.本文檔涉及一些金蝶官方的插件代碼方法,這些插件代碼方法的使用與介紹可以參考SDK文檔:
https://dev.kingdee.com/sdk/Cosmic%20V5.0.002/index.html?nav=package
5.文章的代碼都是為了方便理解,使用的變量名都儘量簡單,實際的業務開發中需要進行代碼規範化處理,代碼規範參考IDEA中金蝶官方插件的代碼分析功能。
6.文章或許哪裏講的不夠詳細,或者存在疑意,有任何不明白或者不清楚的地方可以在評論區留言,如果我清楚的話會盡量儘快回覆的
7.此文章在金蝶官方的開發者社區也有發佈,本着能對像我一樣熟悉博客園的金蝶開發者起到幫助的想法,所以將文章在園子又發佈了一遍,金蝶開發者社區的此文鏈接:
https://vip.kingdee.com/article/799643532909519872?productLineId=29&lang=zh-CN

一、插件開發思路
對於插件的開發,我們首先要確定的,是插件要實現的功能。
然後根據功能,我們再進一步確定,這個功能包含的事件,事件觸發頁面的頁面類型,事件的觸發時機,事件的邏輯。
等到這些都確定完後,我們就可以進行實際開發了。
比如説,我想要開發一個表單插件,插件的功能是批量修改列表某些分錄(數據行)的數量字段或者狀態字段的值。
那麼這時候我會確定,這個功能的流程是:用户選中數據——>點擊按鈕——>修改選中數據的字段值——>字段列刷新。
這樣一來就可以確定,事件觸發頁面的頁面類型(單據列表類型),觸發時機(用户點擊按鈕之後),事件的邏輯(獲取到用户選擇的數據之後批量修改數據的字段值,最後刷新頁面)。
image

二、新建插件類
在IDEA中新建一個項目,在項目的對應plugin路徑下,新建一個插件類,新建時選擇繼承的插件類名與繼承的插件類型,例如:
1.我的插件類為頁面插件,所以選擇plugin目錄下的form文件夾新建插件類(右鍵點擊form文件夾,點擊新建,選擇金蝶插件的繼承插件)
image
image

2.命名插件類並選擇繼承的插件類類型,這裏我是列表頁面插件,於是我選擇標準單據列表插件類型
image

新建後的插件類內容:

package ***.plugin.other;
import kd.bos.list.plugin.AbstractListPlugin;
import kd.sdk.plugin.Plugin;
/**
 * 標準單據列表插件
 */
public class teacherListPlugin extends AbstractListPlugin implements PLugin {
}

3.編寫代碼實現事件的邏輯
3.1,事件按鈕添加
因為我的插件事件需要用户點擊按鈕來觸發,所以我在頁面上添加了兩個新的按鈕(狀態正常按鈕與數量0按鈕),
並將按鈕的操作代碼選擇為dothing(空操作),操作後刷新字段一個選擇為數量(qty),一個選擇為(status)
image
image

3.2,編寫代碼
因為我的事件在用户點擊對應按鈕後觸發,所以首先註冊兩個按鈕的點擊監聽事件
(添加工具欄按鈕點擊監聽的事件為addItemClickListeners,在生命週期registerListener中添加)

private static final String FID_TOOLBAR = "toolbar";//默認的工具欄標識
    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        this.addItemClickListeners(FID_TOOLBAR);// 添加工具欄按鈕點擊的監聽事件,監聽的工具欄為字段標識對應的工具欄
    }

插件類全代碼:

package ***.plugin.other;
import kd.bos.list.plugin.AbstractListPlugin;
import kd.sdk.plugin.Plugin;
import java.util.EventObject;

/**
 * 標準單據列表插件
 */
public class teacherListPlugin extends AbstractListPlugin implements Plugin {
    private static final String toolbar = "toolbar";//默認的工具欄標識
    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        this.addItemClickListeners(toolbar);// 添加工具欄按鈕點擊的監聽事件,監聽的工具欄為字段標識對應的工具欄
    }
}

然後註冊兩個按鈕的監聽事件:

private static final String statusbtn = "statusbtn";//狀態正常按鈕的對應字段標識
private static final String qtybtn = "qtybtn";//數量0按鈕的對應字段標識
@Override
    public void itemClick(ItemClickEvent evt) {
        if (statusbtn.equals(evt.getItemKey())) {//監聽狀態正常按鈕的點擊事件
            status();//狀態正常事件邏輯處理方法
        } else if (qtybtn.equals(evt.getItemKey())) {//監聽數量0按鈕的點擊事件
            qty();//數量重置為0事件邏輯處理方法
        }
    }
private void status(){//狀態正常事件邏輯

}
private void qty(){//數量0事件邏輯

}

插件類全部代碼:

package ***.plugin.other;
import kd.bos.form.control.events.ItemClickEvent;
import kd.bos.list.plugin.AbstractListPlugin;
import kd.sdk.plugin.Plugin;
import java.util.EventObject;

/**
 * 標準單據列表插件
 */
public class teacherListPlugin extends AbstractListPlugin implements Plugin {
    private static final String toolbar = "toolbar";//默認的工具欄標識
    private static final String statusbtn = "statusbtn";//狀態正常按鈕的對應字段標識
    private static final String qtybtn = "qtybtn";//數量0按鈕的對應字段標識
    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        this.addItemClickListeners(toolbar);// 添加工具欄按鈕點擊的監聽事件,監聽的工具欄為字段標識對應的工具欄
    }
    @Override
    public void itemClick(ItemClickEvent evt) {
        if (statusbtn.equals(evt.getItemKey())) {//監聽狀態正常按鈕的點擊事件
            status();//狀態正常事件邏輯處理方法
        } else if (qtybtn.equals(evt.getItemKey())) {//監聽數量0按鈕的點擊事件
            qty();//數量重置為0事件邏輯處理方法
        }
    }
    private void status(){//狀態正常事件邏輯

    }
    private void qty(){//數量0事件邏輯

    }
}

然後開始編寫事件邏輯方法,(補充:狀態字段的字段標識為status,控件類型為下拉列表,狀態正常的對應值為"0",數量字段的字段標識為qty,控件類型為整數)
狀態正常事件:

private void status(){//狀態正常事件邏輯
        ListSelectedRowCollection selectedRows = this.getSelectedRows();//獲取當前列表選中行的索引
        if (selectedRows == null || selectedRows.isEmpty()) {//校驗選中行數量是否為空,為空則停止事件並提示
            this.getView().showTipNotification("請先選擇要操作的數據");
            return;
        }
        //根據選中行的索引獲取對應數據的主鍵值
        List<Long> ids = new ArrayList<>();
        for(ListSelectedRow row : selectedRows){
            ids.add((Long)row.getPrimaryKeyValue());
        }
        //根據獲取到的對應事件主鍵值批量查詢獲取數據
        DynamicObject[] datas = BusinessDataServiceHelper.load("teacher",//第一個參數:要查詢數據的表單的標識
                "id,number,name,status",//第二個參數:要查詢的數據的屬性名
                new QFilter[]{new QFilter("id", QCP.in,ids)}//第三個參數:要查詢的數據的過濾條件
        );
        //遍歷數據數組,對數據的對應字段的值進行修改
        for (DynamicObject data : datas){
            data.set("status","0");//正常狀態的對應值為"0"
        }
        SaveServiceHelper.save(datas);//保存修改後的結果
        this.getView().invokeOperation("refresh");//刷新頁面
}

數量0事件:

ListSelectedRowCollection selectedRows = this.getSelectedRows();//獲取當前列表選中行的索引
        if (selectedRows == null || selectedRows.isEmpty()) {//校驗選中行數量是否為空,為空則停止事件並提示
            this.getView().showTipNotification("請先選擇要操作的數據");
            return;
        }
        //根據選中行的索引獲取對應數據的主鍵值
        List<Long> ids = new ArrayList<>();
        for(ListSelectedRow row : selectedRows){
            ids.add((Long)row.getPrimaryKeyValue());
        }
        //根據獲取到的對應事件主鍵值批量查詢獲取數據
        DynamicObject[] datas = BusinessDataServiceHelper.load("teacher",//第一個參數:要查詢數據的表單的標識
                "id,number,name,qty",//第二個參數:要查詢的數據的屬性名
                new QFilter[]{new QFilter("id", QCP.in,ids)}//第三個參數:要查詢的數據的過濾條件
        );
        //遍歷數據數組,對數據的對應字段的值進行修改
        for (DynamicObject data : datas){
            data.set("qty",0);//正常狀態的對應值為"0"
        }
        SaveServiceHelper.save(datas);//保存修改後的結果
        this.getView().invokeOperation("refresh");//刷新頁面

插件類全代碼:

package ***.plugin.other;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.entity.datamodel.ListSelectedRow;
import kd.bos.entity.datamodel.ListSelectedRowCollection;
import kd.bos.form.control.events.ItemClickEvent;
import kd.bos.list.plugin.AbstractListPlugin;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.operation.SaveServiceHelper;
import kd.sdk.plugin.Plugin;

import java.util.ArrayList;
import java.util.EventObject;
import java.util.List;

/**
 * 標準單據列表插件
 */
public class teacherListPlugin extends AbstractListPlugin implements Plugin {
    private static final String toolbar = "toolbar";//默認的工具欄標識
    private static final String statusbtn = "statusbtn";//狀態正常按鈕的對應字段標識
    private static final String qtybtn = "qtybtn";//數量0按鈕的對應字段標識
    @Override
    public void registerListener(EventObject e) {
        super.registerListener(e);
        this.addItemClickListeners(toolbar);// 添加工具欄按鈕點擊的監聽事件,監聽的工具欄為字段標識對應的工具欄
    }
    @Override
    public void itemClick(ItemClickEvent evt) {
        if (statusbtn.equals(evt.getItemKey())) {//監聽狀態正常按鈕的點擊事件
            status();//狀態正常事件邏輯處理方法
        } else if (qtybtn.equals(evt.getItemKey())) {//監聽數量0按鈕的點擊事件
            qty();//數量重置為0事件邏輯處理方法
        }
    }
    private void status(){//狀態正常事件邏輯
        ListSelectedRowCollection selectedRows = this.getSelectedRows();//獲取當前列表選中行的索引
        if (selectedRows == null || selectedRows.isEmpty()) {//校驗選中行數量是否為空,為空則停止事件並提示
            this.getView().showTipNotification("請先選擇要操作的數據");
            return;
        }
        //根據選中行的索引獲取對應數據的主鍵值
        List<Long> ids = new ArrayList<>();
        for(ListSelectedRow row : selectedRows){
            ids.add((Long)row.getPrimaryKeyValue());
        }
        //根據獲取到的對應事件主鍵值批量查詢獲取數據
        DynamicObject[] datas = BusinessDataServiceHelper.load("teacher",//第一個參數:要查詢數據的表單的標識
                "id,number,name,status",//第二個參數:要查詢的數據的屬性名
                new QFilter[]{new QFilter("id", QCP.in,ids)}//第三個參數:要查詢的數據的過濾條件
        );
        //遍歷數據數組,對數據的對應字段的值進行修改
        for (DynamicObject data : datas){
            data.set("status","0");//正常狀態的對應值為"0"
        }
        SaveServiceHelper.save(datas);//保存修改後的結果
        this.getView().invokeOperation("refresh");//刷新頁面
    }
    private void qty(){//數量0事件邏輯
        ListSelectedRowCollection selectedRows = this.getSelectedRows();//獲取當前列表選中行的索引
        if (selectedRows == null || selectedRows.isEmpty()) {//校驗選中行數量是否為空,為空則停止事件並提示
            this.getView().showTipNotification("請先選擇要操作的數據");
            return;
        }
        //根據選中行的索引獲取對應數據的主鍵值
        List<Long> ids = new ArrayList<>();
        for(ListSelectedRow row : selectedRows){
            ids.add((Long)row.getPrimaryKeyValue());
        }
        //根據獲取到的對應事件主鍵值批量查詢獲取數據
        DynamicObject[] datas = BusinessDataServiceHelper.load("teacher",//第一個參數:要查詢數據的表單的標識
                "id,number,name,qty",//第二個參數:要查詢的數據的屬性名
                new QFilter[]{new QFilter("id", QCP.in,ids)}//第三個參數:要查詢的數據的過濾條件
        );
        //遍歷數據數組,對數據的對應字段的值進行修改
        for (DynamicObject data : datas){
            data.set("qty",0);//正常狀態的對應值為"0"
        }
        SaveServiceHelper.save(datas);//保存修改後的結果
        this.getView().invokeOperation("refresh");//刷新頁面
    }
}

3.3,註冊插件
插件類編寫完成後,需要將代碼綁定到對應頁面上才能生效:
image
image

示例:
image

然後點擊保存頁面
image

三、頁面運行測試插件
點擊頁面預覽按鈕進入預覽模式,然後測試對應功能
image

我的:
點擊狀態正常按鈕前與點擊正常狀態按鈕後:
image
image

點擊數量0前與點擊數量0按鈕後:
image
image

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.