180 lines
3.8 KiB
TypeScript
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(); |