浏览代码

ソース対応

liuxf 4 月之前
父节点
当前提交
b0e12c73a6
共有 3 个文件被更改,包括 145 次插入106 次删除
  1. 7 1
      src/constants/index.js
  2. 137 105
      src/views/fcbi/sales/sumSettings.vue
  3. 1 0
      src/views/monitor/job/log.vue

+ 7 - 1
src/constants/index.js

@@ -1,5 +1,5 @@
 // 集計タイプ
-export const GROUP_TYPE = {
+export const AGGREGATION_TYPE = {
   FC: 1, // FC 別(加盟業者次元で集計)
   AREA: 2, // エリア別(地域次元で集計)
   STORE: 3 // 店舗別(店舗次元で集計)
@@ -10,3 +10,9 @@ export const PUBLIC_MODE = {
   INSTANT: 1, // 即時公開
   PERIOD: 2  // 期間限定公開
 };
+
+// 対象期間
+export const TARGET_PERIOD_TYPE = {
+  ANNUAL: 1, // 年度指定(年度のみ)
+  MONTHLY: 2 // 月指定(年と月)
+};

+ 137 - 105
src/views/fcbi/sales/sumSettings.vue

@@ -3,77 +3,78 @@
   <div class="app-container">
     <div class="form-container">
       <div class="section-container">
-        <div class="form-section">対象 </div>
-      <el-form-item class="radio-group-vertical">
-        <div class="radio-container">
-          <el-radio
-              label="immediate"
-              v-model="queryParams.releaseType"
-              class="vertical-radio"
-          >月指定</el-radio>
-          <div class="scheduled-row">
-            <!-- 期間指定时显示的日期选择(同行) -->
-            <div class="date-group"  >
-              <!-- 日期选择器代码保持不变 -->
-              <el-select v-model="queryParams.monthYear" placeholder="" class="date-select" :disabled="queryParams.releaseType === 'scheduled'">
-                <el-option v-for="year in years" :key="year" :label="year" :value="year"></el-option>
-              </el-select>
-              <span class="date-label">年</span>
-              <el-select
-                  v-model="queryParams.startMonth"
-                  placeholder=""
-                  class="date-select-small"
-                  :disabled="queryParams.releaseType === 'scheduled'"
-              >
-                <el-option
-                    v-for="month in months"
-                    :key="month"
-                    :label="month"
-                    :value="month"
-                ></el-option>
-              </el-select>
-              <span class="date-label">月</span>
-              <el-form-item>
-                <el-button  @click="resetForm"  class="append-button">集計条件リセット</el-button>
-              </el-form-item>
+        <div class="form-section">対象</div>
+        <el-form-item class="radio-group-vertical">
+          <div class="radio-container">
+            <el-radio
+                :label="TARGET_PERIOD_TYPE.MONTHLY"
+                v-model="queryParams.targetPeriodType"
+                class="vertical-radio"
+            >月指定
+            </el-radio>
+            <div class="annual-row">
+              <div class="date-group">
+                <el-select v-model="queryParams.monthYear" placeholder="" class="date-select"
+                           :disabled="queryParams.targetPeriodType !== TARGET_PERIOD_TYPE.MONTHLY">
+                  <el-option v-for="year in years" :key="year" :label="year" :value="year"></el-option>
+                </el-select>
+                <span class="date-label">年</span>
+                <el-select
+                    v-model="queryParams.startMonth"
+                    placeholder=""
+                    class="date-select-small"
+                    :disabled="queryParams.targetPeriodType !== TARGET_PERIOD_TYPE.MONTHLY"
+                >
+                  <el-option
+                      v-for="month in months"
+                      :key="month"
+                      :label="month"
+                      :value="month"
+                  ></el-option>
+                </el-select>
+                <span class="date-label">月</span>
+                <el-form-item>
+                  <el-button @click="resetForm" class="append-button">集計条件リセット</el-button>
+                </el-form-item>
+              </div>
             </div>
-          </div>
-          <el-radio
-              label="scheduled"
-              v-model="queryParams.releaseType"
-              class="scheduled-radio"
-          >年度指定</el-radio>
-          <div class="scheduled-row">
-            <!-- 期間指定时显示的日期选择(同行) -->
-            <div class="date-group"  >
-              <!-- 日期选择器代码保持不变 -->
-              <el-select v-model="queryParams.startYear" placeholder="" class="date-select"  :disabled="queryParams.releaseType === 'immediate'">
-                <el-option v-for="year in years" :key="year" :label="year" :value="year"></el-option>
-              </el-select>
-              <span class="date-label">年度</span>
+            <el-radio
+                :label="TARGET_PERIOD_TYPE.ANNUAL"
+                v-model="queryParams.targetPeriodType"
+                class="annual-radio"
+            >年度指定
+            </el-radio>
+            <div class="annual-row">
+              <div class="date-group">
+                <!-- 日期选择器代码保持不变 -->
+                <el-select v-model="queryParams.startYear" placeholder="" class="date-select"
+                           :disabled="queryParams.targetPeriodType !== TARGET_PERIOD_TYPE.ANNUAL">
+                  <el-option v-for="year in years" :key="year" :label="year" :value="year"></el-option>
+                </el-select>
+                <span class="date-label">年度</span>
+              </div>
             </div>
           </div>
-        </div>
-      </el-form-item>
+        </el-form-item>
       </div>
       <el-form-item label="集計種別" style="margin-left: 50px;margin-top: -15px">
-        <el-radio-group v-model="queryParams.aggregationType"  class="custom-radio-group">
-          <el-radio label="FC_CHECKBOX">FC別集計</el-radio>
-          <el-radio label="TYPE_CHECKBOX">エリア別集計</el-radio>
-          <el-radio label="STORE_CHECKBOX">店舗別集計</el-radio>
+        <el-radio-group v-model="queryParams.aggregationType" class="custom-radio-group">
+          <el-radio :label="AGGREGATION_TYPE.FC">FC別集計</el-radio>
+          <el-radio :label="AGGREGATION_TYPE.AREA">エリア別集計</el-radio>
+          <el-radio :label="AGGREGATION_TYPE.STORE">店舗別集計</el-radio>
         </el-radio-group>
       </el-form-item>
       <div class="divider"></div>
       <PublicRange
           v-model="queryParams"
           :region-tree="regionTree"
-          :yamada-fc-brand="yamadaFcBrand "
+          :yamada-fc-brand="yamadaFcBrand"
           :yamada-business-type="yamadaBusinessType"
           @check-change="handleCheckChange"
           :show-business-type="false"
       />
       <div class="btn-section" style="padding-left: 78px; margin-top: 25px;">
-        <button class="operate-btn" @click="Confirm"  v-hasPermi="['fcbi:sales:sum']">集計</button>
+        <button class="operate-btn" @click="handleConfirm" v-hasPermi="['fcbi:sales:sum']">集計</button>
       </div>
     </div>
   </div>
@@ -81,16 +82,23 @@
 
 <script name="surveySumSettings" setup>
 import { getRegionTree } from "@/api/fcbi/survey.js";
-import {reactive, ref, onMounted, getCurrentInstance, watch, toRefs} from 'vue';
+import { reactive, ref, onMounted, getCurrentInstance, watch, toRefs } from 'vue';
 import PublicRange from '../../../components/PublicRange.vue';
-import { useSurveyStore, useSurveySalesStore } from '@/store/surveyStore';
+import { useSurveyStore, F } from '@/store/surveyStore';
 import { useRouter } from 'vue-router';
+import { AGGREGATION_TYPE, TARGET_PERIOD_TYPE } from '@/constants';
 
 const { proxy } = getCurrentInstance();
 const surveyStore = useSurveyStore();
 const surveySalesStore = useSurveySalesStore();
 const router = useRouter();
 
+// 导出常量以便在模板中使用
+defineExpose({
+  AGGREGATION_TYPE,
+  TARGET_PERIOD_TYPE
+});
+
 /**
  * データ辞書から品牌と業務タイプのデータを取得します
  */
@@ -103,6 +111,9 @@ const { yamada_business_type: yamadaBusinessType } = proxy.useDict('yamada_busin
 const regionTree = ref([]);
 const selectedRegions = ref([]);
 const error = ref('');
+const currentYear = new Date().getFullYear();
+const years = Array.from({ length: 11 }, (_, i) => currentYear + i);
+const months = Array.from({ length: 12 }, (_, i) => i + 1);
 
 /**
  * フォームの入力データを保持するオブジェクトです
@@ -112,8 +123,8 @@ const data = reactive({
   queryParams: {
     brandCode: [],
     businessTypeCode: [],
-    releaseType: 'immediate',
-    aggregationType: 'FC_CHECKBOX',
+    targetPeriodType:  TARGET_PERIOD_TYPE.MONTHLY,
+    aggregationType: AGGREGATION_TYPE.FC,
     monthYear: null,
     startMonth: null,
     startYear: null,
@@ -122,9 +133,6 @@ const data = reactive({
 });
 const { queryParams } = toRefs(data);
 
-const currentYear = new Date().getFullYear();
-const years = Array.from({ length: 11 }, (_, i) => currentYear + i);
-const months = Array.from({ length: 12 }, (_, i) => i + 1);
 /**
  * 地域ツリーのデータが更新されたときに、選択された地域を更新します
  */
@@ -135,9 +143,9 @@ watch(regionTree, () => {
 }, { deep: true });
 
 watch(
-    () => queryParams.value.releaseType,
+    () => queryParams.value.targetPeriodType,
     (newVal) => {
-      if (newVal === 'immediate') {
+      if (newVal === TARGET_PERIOD_TYPE.MONTHLY) {
         queryParams.value.startYear = null;
       } else {
         queryParams.value.monthYear = null;
@@ -151,17 +159,24 @@ watch(
  * コンポーネントのマウント後に地域ツリーデータを初期化します
  */
 onMounted(async () => {
-  const response = await getRegionTree();
-  if (response?.success) {
-    const regions = response.data.regions || [];
-    regionTree.value = regions;
-    surveyStore.setRegionTree(regions)
-    if (regionTree.value.length > 0) {
-      updateSelectedRegions(regionTree.value);
+  try {
+    const response = await getRegionTree();
+    if (response?.success) {
+      const regions = response.data.regions || [];
+      regionTree.value = regions;
+      surveyStore.setRegionTree(regions)
+      if (regionTree.value.length > 0) {
+        updateSelectedRegions(regionTree.value);
+      }
+    } else {
+      error.value = response?.message || '地域データの取得に失敗しました';
+      proxy.$message.error(error.value);
+      console.error('地域データの取得に失敗しました:', response);
     }
-  } else {
-    error.value = response?.message || '地域データの取得に失敗しました';
-    console.error('地域データの取得に失敗しました:', response);
+  } catch (err) {
+    error.value = '地域データの取得中にエラーが発生しました';
+    proxy.$message.error(error.value);
+    console.error('地域データの取得中にエラーが発生しました:', err);
   }
 });
 
@@ -172,15 +187,15 @@ const handleCheckChange = (regionId, isChecked) => {
   const region = findRegionById(regionTree.value, regionId);
   if (region) {
     if (isChecked) {
-      if (!selectedRegions.value.some(r => r.region_code === region.regionCode)) {
+      if (!selectedRegions.value.some(r => r.regionCode === region.regionCode)) {
         selectedRegions.value.push({
-          region_code: region.regionCode
+          regionCode: region.regionCode
         });
       }
     } else {
-      selectedRegions.value = selectedRegions.value.filter(r => r.region_code !== region.regionCode);
+      selectedRegions.value = selectedRegions.value.filter(r => r.regionCode !== region.regionCode);
     }
-    queryParams.value.regions = selectedRegions.value;
+    queryParams.value.regions = [...selectedRegions.value];
   }
 };
 
@@ -188,6 +203,8 @@ const handleCheckChange = (regionId, isChecked) => {
  * 指定されたIDを持つ地域ノードをツリーから再帰的に検索します
  */
 const findRegionById = (nodes, id) => {
+  if (!nodes || !nodes.length) return null;
+
   for (const node of nodes) {
     if (node.id === id) {
       return node;
@@ -206,10 +223,11 @@ const findRegionById = (nodes, id) => {
  * 選択されたすべての地域を再帰的に更新し、サブノードのみを収集します
  */
 const updateSelectedRegions = (nodes) => {
+  if (!nodes || !nodes.length) return;
   selectedRegions.value = [];
   // 最上位ノードは親ノードとしてマークされ、再帰的に子ノードを処理します
   collectSelectedRegions(nodes, true);
-  queryParams.value.regions = selectedRegions.value;
+  queryParams.value.regions = [...selectedRegions.value];
 };
 
 /**
@@ -226,7 +244,7 @@ const collectSelectedRegions = (nodes, isParent = false) => {
     }
     if (node.checked) {
       selectedRegions.value.push({
-        region_code: node.regionCode
+        regionCode: node.regionCode
       });
     }
     if (node.children && node.children.length > 0) {
@@ -235,40 +253,52 @@ const collectSelectedRegions = (nodes, isParent = false) => {
   });
 };
 
-const Confirm = () => {
-
-  let isValid = true;
+/**
+ * 検索条件を検証する関数です
+ */
+const validateForm = () => {
+  const errors = [];
 
-  if (queryParams.value.releaseType === 'immediate') {
+  if (queryParams.value.targetPeriodType === TARGET_PERIOD_TYPE.MONTHLY) {
     if (!queryParams.value.monthYear) {
-      isValid = false;
-      proxy.$message.warning('月指定の年を選択してください');
+      errors.push('「対象 月指定」の年を選択してください');
     }
     if (!queryParams.value.startMonth) {
-      isValid = false;
-      proxy.$message.warning('月指定の月を選択してください');
+      errors.push('「対象 月指定」の月を選択してください');
     }
-  }
-  else if (queryParams.value.releaseType === 'scheduled') {
+  } else if (queryParams.value.targetPeriodType === TARGET_PERIOD_TYPE.ANNUAL) {
     if (!queryParams.value.startYear) {
-      isValid = false;
-      proxy.$message.warning('年度指定の年度を選択してください');
+      errors.push('「対象 年度指定」の年度を選択してください');
     }
   }
 
-  if (!isValid) {
+  return errors;
+};
+
+/**
+ * 確認ボタンをクリックしたときの処理関数です
+ * @constructor
+ */
+const handleConfirm = () => {
+
+  const errors = validateForm();
+
+  if (errors.length > 0) {
+    errors.forEach(error => {
+      proxy.$message.warning(error);
+    });
     return;
   }
 
   let salesFlag = 0;
-  const isMonth = queryParams.value.releaseType === 'immediate';
+  const isMonth = queryParams.value.targetPeriodType === TARGET_PERIOD_TYPE.MONTHLY;
 
   switch (queryParams.value.aggregationType) {
-    case 'FC_CHECKBOX':
+    case AGGREGATION_TYPE.FC:
       const hasArea = queryParams.value.regions && queryParams.value.regions.length > 0;
       salesFlag = isMonth ? (hasArea ? 1 : 2) : (hasArea ? 3 : 4);
       break;
-    case 'STORE_CHECKBOX':
+    case AGGREGATION_TYPE.STORE:
       salesFlag = isMonth ? 5 : 6;
       break;
     default:
@@ -276,30 +306,32 @@ const Confirm = () => {
   }
 
   const transferData = {
-    releaseType: queryParams.value.releaseType,
+    targetPeriodType: queryParams.value.targetPeriodType,
     monthYear: isMonth ? queryParams.value.monthYear : null,
     startMonth: isMonth ? queryParams.value.startMonth : null,
     startYear: !isMonth ? queryParams.value.startYear : null,
     brandCodes: queryParams.value.brandCode,
-    regionCodes: queryParams.value.regions.map(region => region.region_code),
+    regionCodes: queryParams.value.regions.map(region => region.regionCode),
     aggregationType: queryParams.value.aggregationType,
-    salesFlag
+    salesFlag: salesFlag
   };
 
   surveySalesStore.setSalesData(transferData);
   router.push({ name: 'salesSumResult' });
 };
 
+/**
+ * キャンセルボタンをクリックしたときの処理関数です
+ */
 const resetForm = () => {
-  queryParams.value.releaseType = 'immediate';
-  queryParams.value.aggregationType = 'FC_CHECKBOX';
+  queryParams.value.targetPeriodType = TARGET_PERIOD_TYPE.MONTHLY;
+  queryParams.value.aggregationType = AGGREGATION_TYPE.FC;
   queryParams.value.monthYear = null;
   queryParams.value.startMonth = null;
   queryParams.value.startYear = null;
   queryParams.value.brandCode = [];
-
-  selectedRegions.value = [];
   queryParams.value.regions = [];
+  selectedRegions.value = [];
   if (regionTree.value.length > 0) {
     resetRegionTreeCheck(regionTree.value);
   }
@@ -351,14 +383,14 @@ const resetRegionTreeCheck = (nodes) => {
   display: flex;
   align-items: center;
 }
-.scheduled-row {
+.annual-row {
   display: flex;
   align-items: center;
   margin-left: 88px;
   margin-top: -45px;
 }
 @media (max-width:48em) {
-  .scheduled-row  {
+  .annual-row  {
     margin-left: 13%;
     width: 80%;
   }

+ 1 - 0
src/views/monitor/job/log.vue

@@ -178,6 +178,7 @@
 <script name="JobLog" setup>
 import {getJob} from "@/api/monitor/job";
 import {cleanJobLog, delJobLog, listJobLog} from "@/api/monitor/jobLog";
+import {useRoute} from "vue-router";
 
 const {proxy} = getCurrentInstance();
 const {sys_common_status, sys_job_group} = proxy.useDict("sys_common_status", "sys_job_group");