feat:データ集計処理作成

This commit is contained in:
2024-05-24 09:20:19 +09:00
parent 7fb3d08ccb
commit 53aadfcaaa
7 changed files with 212 additions and 165 deletions

View File

@@ -2,7 +2,6 @@
<html lang="ja-jp"> <html lang="ja-jp">
<head> <head>
<title><%= productName %></title> <title><%= productName %></title>
<meta charset="utf-8"> <meta charset="utf-8">
<meta name="description" content="<%= productDescription %>"> <meta name="description" content="<%= productDescription %>">
<meta name="format-detection" content="telephone=no"> <meta name="format-detection" content="telephone=no">

View File

@@ -4,6 +4,7 @@ import { Router } from 'vue-router';
import { App } from 'vue'; import { App } from 'vue';
export default boot(({ app, router }: { app: App<Element>; router: Router }) => { export default boot(({ app, router }: { app: App<Element>; router: Router }) => {
document.documentElement.lang="ja-JP";
app.config.errorHandler = (err: any, instance: any, info: string) => { app.config.errorHandler = (err: any, instance: any, info: string) => {
if (err.response && err.response.status === 401) { if (err.response && err.response.status === 401) {
// 認証エラーの場合再ログインする // 認証エラーの場合再ログインする

View File

@@ -1,5 +1,5 @@
<template> <template>
<show-dialog v-model:visible="showflg" name="条件エディタ" @close="closeDg" min-width="60vw" min-height="60vh"> <show-dialog v-model:visible="showflg" name="条件エディタ" @close="closeDg" min-width="50vw" min-height="60vh">
<template v-slot:toolbar> <template v-slot:toolbar>
<q-btn flat round dense icon="more_vert" > <q-btn flat round dense icon="more_vert" >
<q-menu auto-close anchor="bottom start"> <q-menu auto-close anchor="bottom start">

View File

@@ -13,7 +13,7 @@
<q-icon name="search" class="cursor-pointer" @click="showDg"/> <q-icon name="search" class="cursor-pointer" @click="showDg"/>
</template> </template>
</q-field> </q-field>
<show-dialog v-model:visible="show" name="条件設定項目一覧" @close="closeDg" width="600px"> <show-dialog v-model:visible="show" name="設定項目一覧" @close="closeDg" min-width="400px">
<template v-slot:toolbar> <template v-slot:toolbar>
<q-input dense debounce="200" v-model="filter" placeholder="検索" clearable> <q-input dense debounce="200" v-model="filter" placeholder="検索" clearable>
<template v-slot:before> <template v-slot:before>

View File

@@ -1,7 +1,7 @@
<template> <template>
<!-- <div class="q-pa-md q-gutter-sm" > --> <!-- <div class="q-pa-md q-gutter-sm" > -->
<q-dialog :model-value="visible" persistent bordered > <q-dialog :model-value="visible" persistent bordered >
<q-card :style="cardStyle" style=" min-width: 40vw; max-width: 80vw; max-height: 95vh;"> <q-card style="min-width: 40vw; max-width: 80vw; max-height: 95vh;" :style="cardStyle">
<q-toolbar class="bg-grey-4"> <q-toolbar class="bg-grey-4">
<q-toolbar-title>{{ name }}</q-toolbar-title> <q-toolbar-title>{{ name }}</q-toolbar-title>
<q-space></q-space> <q-space></q-space>

View File

@@ -7,27 +7,30 @@
<q-btn color="grey-3" text-color="black" @click="() => { dgIsShow = true }">クリックで設定</q-btn> <q-btn color="grey-3" text-color="black" @click="() => { dgIsShow = true }">クリックで設定</q-btn>
</q-card-actions> </q-card-actions>
<q-card-section class="text-caption"> <q-card-section class="text-caption">
<div v-if="processingObjectsInputDisplay && processingObjectsInputDisplay.length>0">
<div v-for="(item) in processingObjectsInputDisplay" :key="item">{{ item }}</div> <div v-for="(item) in processingObjectsInputDisplay" :key="item">{{ item }}</div>
</div>
<div v-else>{{ placeholder }}</div>
</q-card-section> </q-card-section>
</q-card> </q-card>
</template> </template>
</q-field> </q-field>
<show-dialog v-model:visible="dgIsShow" name="条件エディタ" @close="closeDg" min-width="60vw" min-height="60vh"> <show-dialog v-model:visible="dgIsShow" name="集計処理" @close="closeDg" min-width="50vw" min-height="60vh">
<div class="q-mx-md q-mb-md"> <div class="q-mx-md q-mb-md">
<q-input v-model="processingProps.name" type="text" label-color="primary" label="変数名を入力してください" <q-input v-model="processingProps.name" type="text" label-color="primary" label="集計結果の変数名"
placeholder="varName" /> placeholder="集計結果を格納する変数名を入力してください" stack-label />
</div> </div>
<div class="q-mx-md"> <div class="q-mx-md">
<div class="row q-col-gutter-x-xs flex-center"> <div class="row q-col-gutter-x-xs flex-center">
<div class="col-5"> <div class="col-5">
<div class="q-mx-xs">数据源</div> <div class="q-mx-xs">データソース</div>
</div> </div>
<div class="col-2"> <div class="col-2">
<div class="q-mx-xs">运算符</div> <div class="q-mx-xs">集計計算</div>
</div> </div>
<div class="col-4"> <div class="col-4">
<div class="q-mx-xs">目标变量</div> <div class="q-mx-xs">集計結果変数名</div>
</div> </div>
<div class="col-1"><q-btn flat round dense icon="add" size="sm" @click="addProcessingObject" /> <div class="col-1"><q-btn flat round dense icon="add" size="sm" @click="addProcessingObject" />
</div> </div>
@@ -38,15 +41,13 @@
<ConditionObject v-model="item.field" /> <ConditionObject v-model="item.field" />
</div> </div>
<div class="col-2"> <div class="col-2">
<q-select v-model="item.logicalOperator" :options="logicalOperators" outlined <q-select v-model="item.logicalOperator" :options="logicalOperators" outlined dense></q-select>
dense></q-select>
</div> </div>
<div class="col-4"> <div class="col-4">
<q-input v-model="item.vName" type="text" label="Label" outlined dense /> <q-input v-model="item.vName" type="text" outlined dense />
</div> </div>
<div class="col-1"> <div class="col-1">
<q-btn flat round dense icon="delete" size="sm" <q-btn flat round dense icon="delete" size="sm" @click="() => deleteProcessingObject(index)" />
@click="() => deleteProcessingObject(index)" />
</div> </div>
</div> </div>
@@ -121,6 +122,10 @@ export default defineComponent({
modelValue: { modelValue: {
type: Object as () => ValueType, type: Object as () => ValueType,
}, },
placeholder: {
type: String,
default: '',
},
}, },
setup(props, { emit }) { setup(props, { emit }) {
@@ -157,6 +162,7 @@ export default defineComponent({
const deleteProcessingObject = (index: number) => processingObjects.length === 1 const deleteProcessingObject = (index: number) => processingObjects.length === 1
? processingObjects.splice(0, processingObjects.length, { id: uuidv4() }) ? processingObjects.splice(0, processingObjects.length, { id: uuidv4() })
: processingObjects.splice(index, 1); : processingObjects.splice(index, 1);
const processingObjectsInputDisplay = computed(() => const processingObjectsInputDisplay = computed(() =>
processingObjects ? processingObjects ?
processingObjects processingObjects
@@ -165,10 +171,43 @@ export default defineComponent({
const name = typeof item.field?.name === 'string' const name = typeof item.field?.name === 'string'
? item.field.name ? item.field.name
: item.field?.name.name; : item.field?.name.name;
return `${processingProps.name}.${item.vName} = ${item.logicalOperator}(${name})` return item.logicalOperator.operator!==''?
`${processingProps.name}.${item.vName} = ${item.logicalOperator.operator}(${name})`
:`${processingProps.name}.${item.vName} = ${name}`
}) })
: '' : []
); );
//集計処理方法
const logicalOperators = ref([
{
"operator": "",
"label": "なし"
},
{
"operator": "SUM",
"label": "合計"
},
{
"operator": "AVG",
"label": "平均"
},
{
"operator": "MAX",
"label": "最大値"
},
{
"operator": "MIN",
"label": "最小値"
},
{
"operator": "COUNT",
"label": "カウント"
},
{
"operator": "FIRST",
"label": "最初の値"
}
]);
watchEffect(() => { watchEffect(() => {
emit('update:modelValue', processingProps); emit('update:modelValue', processingProps);
@@ -181,7 +220,7 @@ export default defineComponent({
processingProps, processingProps,
addProcessingObject: () => processingObjects.push({ id: uuidv4() }), addProcessingObject: () => processingObjects.push({ id: uuidv4() }),
deleteProcessingObject, deleteProcessingObject,
logicalOperators: reactive(['MAX', 'SUM']), logicalOperators,
processingObjectsInputDisplay, processingObjectsInputDisplay,
}; };
}, },

View File

@@ -1,11 +1,12 @@
<template> <template>
<div v-bind="$attrs"> <div v-bind="$attrs">
<q-select v-model="selectedValue" :label="displayName" :options="options"/> <q-select v-model="selectedValue" :use-chips="multiple" :label="displayName" label-color="primary" :options="options" stack-label
:multiple="multiple"/>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent,ref,watchEffect } from 'vue'; import { defineComponent,ref,watchEffect,computed } from 'vue';
export default defineComponent({ export default defineComponent({
name: 'SelectBox', name: 'SelectBox',
@@ -23,20 +24,27 @@ export default defineComponent({
type: Array, type: Array,
required: true, required: true,
}, },
modelValue: { selectType:{
type:String, type:String,
default:'', default:'',
}, },
modelValue: {
type: Object,
default: null,
},
}, },
setup(props, { emit }) { setup(props, { emit }) {
const selectedValue = ref(props.modelValue); const selectedValue = ref(props.modelValue);
const multiple = computed(()=>{
return props.selectType==='multiple'
});
watchEffect(() => { watchEffect(() => {
emit('update:modelValue', selectedValue.value); emit('update:modelValue', selectedValue.value);
}); });
return { return {
selectedValue selectedValue,
multiple
}; };
}, },
}); });