Files
KintoneAppBuilder/plugin/kintone-addins/src/actions/data-processing.ts
2024-07-31 18:28:25 +09:00

180 lines
3.8 KiB
TypeScript

import {
IAction,
IActionResult,
IActionNode,
IActionProperty,
IContext,
} from "../types/ActionTypes";
import { actionAddins } from ".";
import {KintoneRestAPIClient} from '@kintone/rest-api-client';
import { Aggregator,Operator} from '../util/aggregates';
import { FieldForm } from "../types/FieldLayout";
interface IDataProcessingProps {
displayName: string;
sources: Sources;
condition: string;
verName?: VerName;
}
interface Condition {
queryString: string;
}
interface VerName {
name: string;
actionName: string;
displayName: string;
vars: Var[];
}
interface Var {
id: string;
field: FieldForm;
logicalOperator: CalcOperator;
vName: string;
}
interface CalcOperator {
operator: Operator;
label: string;
}
interface Sources {
app: App;
fields: FieldForm[];
}
interface App {
id: string;
name?: string;
}
type Result = {
[key: string]: {
type: string;
value: any[];
};
};
type AnyObject = {
[key: string]: any;
};
export class DataProcessingAction implements IAction {
name: string;
actionProps: IActionProperty[];
props: IDataProcessingProps ;
constructor() {
this.name = "データ処理";
this.actionProps = [];
this.props = {
displayName:'',
condition:'',
sources:{
app:{
id:""
},
fields:[]
},
};
this.register();
}
async process(
actionNode: IActionNode,
event: any,
context: IContext
): Promise<IActionResult> {
this.actionProps = actionNode.actionProps;
this.props = actionNode.ActionValue as IDataProcessingProps;
const condition = JSON.parse(this.props.condition) as Condition;
let result = {
canNext: true,
result: "",
} as IActionResult;
try {
if (!this.props) {
return result;
}
const query = this.getQuery(condition.queryString,context.variables);
const data = await this.selectData(query);
console.log("data ", data);
if(this.props.verName){
const varValues= this.props.verName.vars.reduce((acc, f) => {
const datas=data[f.field.code].value;
const agg = new Aggregator(datas,f.field);
const result = agg.calculate(f.logicalOperator.operator)
acc[f.vName]=result;
return acc;
}, {} as AnyObject);
context.variables[this.props.verName.name]=varValues;
console.log("context ", context);
}
return result;
} catch (error) {
context.errors.handleError(error,actionNode);
result.canNext = false;
return result;
}
}
/**
*
* @param str
* @param vars
* @returns
*/
getQuery = (str: string, vars: any) => {
console.log(str);
const regex = /var\((.*?)\)/g;
let match;
while ((match = regex.exec(str)) !== null) {
const varName = match[1];
if (varName in vars) {
str = str.replace(match[0], vars[varName]);
} else {
throw new Error(`変数${varName}が見つかりません`);
}
}
console.log(str);
return str;
};
/**
* データを取得する
* @param query
* @returns
*/
selectData = async ( query?: string) => {
const api = new KintoneRestAPIClient();
const fields = this.props.sources.fields.map((field)=>field.code);
const resp = await api.record.getAllRecords({
app: this.props.sources.app.id,
fields:fields,
condition:query
});
const result: Result = {};
resp.forEach((element) => {
for (const [key, value] of Object.entries(element)) {
if (!result[key]) {
result[key] = { type: value.type, value: [] };
}
result[key].value.push(value.value);
}
});
return result;
};
register(): void {
actionAddins[this.name] = this;
}
}
new DataProcessingAction();