npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gsp-fund/ui

v0.0.8

Published

[gitlab](https://git.iec.io/lifeiyue/gsp-fund-common.git) [npm](https://www.npmjs.com/package/@gsp-fund/common) 离线包 `\\10.100.1.163\产品服务器\待测库\TM_Cloud\内部使用\资金内部node_modules\@gsp-fund`

Downloads

14

Readme

@gsp-fund/ui - BatchResultModule 批量结果弹窗模块

项目地址

gitlab npm 离线包 \\10.100.1.163\产品服务器\待测库\TM_Cloud\内部使用\资金内部node_modules\@gsp-fund

使用

  1. 表单设计器引用(打开表单后直接点击代码编辑器,拖到最后添加以下代码) image.png
        "isComposedFrm": true,
        "extraImports": [
            {
                "path": "@gsp-fund/ui",
                "name": "BatchResultModule"
            }
        ]
  1. 注入BatchResultService弹窗服务

BatchResultService弹窗服务

open方法

根据传入的结果及列配置打开弹窗(存在失败)或弹出右下角成功提示(全部为成功),若存在待确认,支持选择,返回选择的数组流

参数 | 类型 | 备注 --- | --- | --- action | string | 操作名称,用于标题 actionResult | ActionResult[] | 动作结果数组 formLoadingService | FormLoadingService | 平台formLoading服务 formNotifyService | FormNotifyService | 平台formNotifyService服务 columns | {field: string,title: string,type?: ColumnType,width?: number}[] | 列配置数组,可选

返回Subject<string[]> 表示待确认列表选择的id数组流 若弹窗正常结束或关闭,返回空数组

ActionResult类结构

属性 | 类型 | 备注 --- | --- | --- id | string | 主键,由于平台farris-grid限制,必填 data | any | 数据,用于open方法中的columnsfield取值 state | ActionState | 动作结果的枚举,也可为对应枚举的number值 message | string | 提示信息

枚举ActionState

枚举 | 值 | 备注 --- | --- | --- Success | 1 | 成功 ToBeConfirmed | 2 | 待确认 Failed | -1 | 失败

columns参数详情

属性 | 类型 | 备注 --- | --- | --- field | string | 字段属性名,若为多级结构用.连接,列表取数时取ActionResultdata属性的对应值 title | string | 列标题 type | ColumnType | 列数据类型枚举,封装了常用类型的平台列配置 width | number | 列宽

ColumnType枚举

枚举 | 值 | 备注 --- | --- | --- String | 0 | 字符串,靠左,无格式特殊处理 AccountNo | 1 | 账号,靠左,四位空格分隔 Amount | 2 | 金额,靠右,数字格式化

默认配置为

  [ 
    {
      field: 'code',
      type: ColumnType.String,
      width: 200,
      title: '单据编号'
    }
  ]

所有配置最后内部添加message的配置,无需手工处理

   {
      field: 'message',
      width: 800,
      title: '原因',
      dataType: 'string',
      align: 'left',
      halign: 'left',
      readonly: true,
      visible: true,
   }

option窗口配置参数详情

枚举 | 默认值 | 备注 --- | --- | --- showButton| true | 显示底部按钮(存在待确认结果时设为false无效) width| 800 | 宽度 height| 600 | 高度 title|参数action的值|标题

用法举例

  1. 后端组装基本的List<ActionResult>响应结构返回给前端

可使用或参考类com.inspur.gs.tm.tmfnd.tmpub.common.pojo.http.ActionResult

import lombok.Getter;
import lombok.Setter;

/**
 * 动作结果
 * @author lifeiyue
 */
@Getter
@Setter
public class ActionResult {
    /**
     * 单据id
     */
    private String id;
   /**
     * 单据数据 (可在前端完成赋值)
     */
    private Object data;
    /**
     * 结果状态
     */
    private ActionState state = ActionState.Success;
    /**
     * 提示信息
     */
    private String message;
}
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

/**
 * 结果状态枚举
 * @author lifeiyue
 */
public enum ActionState {

    /**
     * 成功
     */
    Success(1),
    /**
     * 待确认
     */
    ToBeConfirmed(2),
    /**
     * 失败
     */
    Failed(-1);

    private int value;
    @JsonCreator
    ActionState(int value) {
        this.value = value;
    }
    @JsonValue
    public int getValue() {
        return this.value;
    }

}
  1. 前端配置弹窗的展示列配置
  import {ActionResult, ActionState, BatchResultService, ColumnType} from '@gsp-fund/ui';

 /**
   * 批量结果弹窗列配置
   */
  private readonly dialogConfig: { field: string, title: string, type?: ColumnType, width?: number }[];
  private template: ServiceTemplate;

  constructor(
    private frameContext: FrameContext,
    private loadingService: FormLoadingService,
    private notifyService: FormNotifyService,
    private messageService: FormMessageService,
    private navigationService: NavigationService,
    private navigationMiddlewareService: NavigationMiddlewareService,
    private translateService: TranslateService,
    private batchResultService: BatchResultService,
    private printService: PrintService
  ) {
    this.template = new ServiceTemplate(frameContext, loadingService, notifyService, messageService);
    // 建议在构造器内或调用方法内初始化列配置,而非直接在类级别直接初始化。否则可能导致国际化服务translateService拿不到
    this.dialogConfig = [
      {
        field: 'docNo',
        title: this.translateService.instant('gridField_8debd649-bec7-41e8-a400-61340cc353e8_docNo')
      }
    ];
  }
  1. 组装弹窗需要的结果入参(若后端已赋值data,可跳过)
       // 转换响应结果
      map(response => {
        const responseResult = response as ActionResult[];
        // 赋值请求结果data字段
        responseResult.forEach(r => r.data = this.frameContext.repository.entityCollection.getEntityById(r.id));
        return responseResult;
      }),
  1. 调用弹窗服务并处理弹窗结果
       // 调用弹窗服务
      switchMap((result: ActionResult[]) =>
        this.batchResultService.open(
          this.translateService.instant('withdraw'), result, this.loadingService, this.notifyService, this.dialogConfig)
      ),
      // 重新加载数据
      tap(() => this.frameContext.viewModel['Load1']())

附:前后端代码 后端视图动作

    public void execute() {
        final ArrayList<Object> results = new ArrayList<>();
        if (data != null && data.length > 0) {
            IStandardLcp lcp = getLcp();
            for (EnableUnitStruct item : data) {
                //调用平台原子性动作执行以保证事务
                lcp.atomicallyInvoke(() -> {
                    try {
                        //业务逻辑略...
                        lcp.save();
                        //传回前端的id仍为unitID,因为未启用时,voID就是unitID
                        results.add(new ActionResult() {{
                            setId(item.getUnit());
                        }});
                    } catch (Exception e) {
                        lcp.cleanUp();//清空变更集、锁、缓存
                        String bizErrorInException = ExceptionUtil.getBizErrorInException(e);
                        results.add(new ActionResult() {{
                            setId(item.getUnit());
                            setState(ActionState.Failed);
                            setMessage(bizErrorInException);
                        }});
                    }
                });
            }
        }
        setResult(results);//返回前端的数据
    }
/**
 * 异常工具类
 * @author lifeiyue
 */
public class ExceptionUtil {
    /**
     * 获取捕获异常中的业务信息
     * 在内部存在RPC调用时,扔出的异常会套两层“RPC调用异常”,不可直接拿外层的message。单独的web api请求可能前端处理了此种情况
     * @param e 捕获的异常
     * @return Message
     */
    public static String getBizErrorInException(Exception e){
        String message = e.getMessage();
        Throwable newE = e;
        while(newE.getCause() != null){
            newE = newE.getCause();
            message = newE.getMessage();
        }
        return message;
    }
}

前端调用弹窗方法

        //enableUnit()方法操作的后续操作是,调用平台ListDataService的load动作
	enableUnit() {
		const params: data[] = this['context'].results.getDataToEnable;
		const listData = this.repository.entityCollection;
		this.formLoadingService.show();
                //启用请求
		return this.proxy.EnableUnit(params).pipe(
			concatMap((responseData: ActionResult[]) => {
				if (responseData && responseData.length) {
					const data = responseData.map((item) => {
						item.data = listData.getEntityById(item.id);
						return item;
					});
                                        //调用弹窗
					return this.batchResultService.open(
						this.translate.instant('form_title'),
						data.slice(),
						this.formLoadingService,
						this.formNotifyService,
						this.dialogConfig
					);
				} else {
					this.formLoadingService.clearAll();
					return EMPTY;
				}
			})
		);
    }

附:一种有待确认情况的前端调用

 /**
   * 提交
   */
  submit() {
    const selected = this.template.getFrameContext('data-grid-component').uiState['ids'] as string[];
    if (!selected || !selected.length) {
      this.notifyService.warning(this.translateService.instant('Service_NoSelectData'));
      return EMPTY;
    }
    // 待提交结果
    const submitIds = [];
    // 前端校验结果
    const validResult: ActionResult[] = [];
    // 组装首次提交参数
    selected.forEach(id => {
      const entity = this.frameContext.repository.entityCollection.getEntityById(id) as FundAllocationEntity;
      // 校验单据状态,只有待办理、审批退回、复核退回才能执行
      if (!FundAllocationHandleFrmActionService.canHandleOrSubmit(entity)) {
        validResult.push({
          id,
          data: entity,
          state: ActionState.Failed,
          message: this.translateService.instant('Service_SubmitWithWrongState')
        });
      } else if (!entity.allocationAccount.allocationAccount) { // 下拨账户为空
        validResult.push({
          id,
          data: entity,
          state: ActionState.Failed,
          message: this.translateService.instant('Service_AllocAccountIsNull')
        });
      } else if (!entity.summary) { // 摘要为空
        validResult.push({
          id,
          data: entity,
          state: ActionState.Failed,
          message: this.translateService.instant('Service_SummaryIsNull')
        });
      } else {
        submitIds.push({id, confirmOverBalance: false});
      }
    });
    // 待提交数组流
    const toBeSubmit$ = new Subject<any[]>();
    toBeSubmit$.pipe(
      // 加签
      switchMap(params => this.getMessageAndSign(params)),
      // 若有待提交,执行请求,否则返回空数组
      switchMap(toBeSubmit => {
        if (toBeSubmit.length) {
          this.loadingService.show();
          return this.template.http('/service/submit', 'PUT', {params: toBeSubmit});
        } else {
          return of([]);
        }
      }),
      // 转换响应结果
      map(response => {
        const responseResult = response as ActionResult[];
        // 赋值请求结果data字段
        responseResult.forEach(r => r.data = this.frameContext.repository.entityCollection.getEntityById(r.id));
        // 合并已有的校验结果
        responseResult.push(...validResult);
        return responseResult;
      }),
      // 若有结果,调用弹窗服务,否则抛出空数组
      switchMap((result: ActionResult[]) => {
          if (result.length) {
            return this.batchResultService.open(
              this.translateService.instant('submit'), result, this.loadingService, this.notifyService, this.dialogConfig);
          } else {
            return of([]);
          }
        }
      ),
      // 获取弹窗返回的待确认选择项,若有确认的,进行下一次循环,否则结束
      tap(dialogResult => {
        if (dialogResult.length) {
          // 清空前端的校验结果,不再第二次提示
          validResult.length = 0;
          // 清空提交项,组装下一次提交参数,确认参数改为true
          submitIds.length = 0;
          dialogResult.forEach(result => submitIds.push({id: result, confirmOverBalance: true}));
          // 执行下一次循环
          toBeSubmit$.next(submitIds);
        } else {
          toBeSubmit$.complete();
        }
      })
    ).subscribe({
      // 若有成功提交的,重新加载数据
      complete: () => this.frameContext.viewModel['Load1']()
    });
    // 执行提交
    toBeSubmit$.next(submitIds);
  }

# @gsp-fund/ui - SimpleDialogModule 公共简易表单输入框模块

项目地址

gitlab npm 离线包 \\10.100.1.163\产品服务器\待测库\TM_Cloud\内部使用\资金内部node_modules\@gsp-fund

使用

  1. 表单设计器引用(打开表单后直接点击代码编辑器,拖到最后添加以下代码)
        "isComposedFrm": true,
        "extraImports": [
            {
                "path": "@gsp-fund/ui",
                "name": "SimpleDialogModule"
            }
        ]
  1. 注入SimpleDialogService弹窗服务

SimpleDialogService服务

open方法

根据传入的结果及列配置打开弹窗(存在失败)或弹出右下角成功提示(全部为成功),若存在待确认,支持选择,返回选择的数组流

参数 | 类型 | 备注 --- | --- | --- title| string | 标题 controls| 数组 | 控件及相关配置 option | {width?: number,height?: number,controlInline?:boolean,validateCallback:(value:any)=>boolean} | 窗口相关配置,可选, 返回Subject<any> ,其中key为controls中的key,值为对应数据框的值

控件配置数组结构

属性 | 类型 | 备注 --- | --- | --- key| string | 必传,用于结果key的组装 label| string| 控件label,可选 type| 'string' | 'number'| 'checkbox' | 'date' | 'dateRange' | 'radioGroup' | 'textArea' | 字符串,对应为控件类型,可选,默认为string groupConfig| {value: string, label: strin }[]| 用于radioGroup控件类型的配置,radioGroup类型时必传,label为radio的label,value为对应值

窗口配置参数

属性 | 类型 | 备注 --- | --- | --- width| number| 宽度,默认340 height| number| 高度,默认根据控件数量及类型计算 controlInline| number| label与控件同行,默认为true validateCallback| (value: any) => boolean| 校验函数回调,传入表单的值,返回boolean,必须传入lambda表达式或变量,避免this指向问题 选填

示例

// 组装参数,自行处理国际化
const config: {
      key: string,
      label?: string,
      type?: 'string' | 'number' | 'checkbox' | 'date' | 'dateRange' | 'radioGroup' | 'textArea',
      groupConfig?: {
        value: string,
        label: string
      }[]
    }[] = [
      {
        key: 'text',
        label: '测试文本'
      },
      {
        key: 'number',
        label: '测试数字',
        type: 'number'
      },
      {
        key: 'date',
        type: 'date'
      },
      {
        key: 'check',
        label: '测试check',
        type: 'checkbox'
      },
      {
        key: 'dateRange',
        label: '测试日期范围',
        type: 'dateRange'
      },
      {
        key: 'textArea',
        label: '说明',
        type: 'textArea'
      },
      {
        key: 'radio',
        label: '测试radio',
        type: 'radioGroup',
        groupConfig: [
          {
           value: 'a',
           label: 'AAAAAAAAAAAA'
          },
          {
            value: 'b',
            label: 'BBBBBBBBBB'
          },
          {
            value: 'c',
            label: 'CCCCCCCCCCC'
          }
        ]
      }
    ];
    const validateFun = (value) => {
      if (!value['text']) {
        alert('测试文本为空');
        return false;
      }
      return true;

    }
    this.simpleDialogService.open('测试弹窗', config, {controlInline: false, validateCallback: validateFun}).subscribe(result => {
      console.log(result);
    })