浏览代码

代码修正

quyx@nextosd.com 4 月之前
父节点
当前提交
43a0ccb2e7

+ 28 - 0
src/api/fcbi/customer.js

@@ -0,0 +1,28 @@
+import request from '@/utils/request'
+
+//  顧客一覧列表
+export function customerSurvey(query) {
+  return request({
+    url: '/system/customer/customerList',
+    method: 'get',
+    params: query
+  })
+}
+
+//  店舗
+export function fcStoreSurvey(query) {
+  return request({
+    url: '/system/customer/fcStore',
+    method: 'get',
+    params: query
+  })
+}
+
+// 顧客詳細
+export function getcustomerDetail(data) {
+  return request({
+    url: '/system/customer/customerDetail',
+    method: 'post',
+    data: data
+  })
+}

+ 10 - 0
src/api/fcbi/purchaseSale.js

@@ -0,0 +1,10 @@
+import request from '@/utils/request'
+
+// 查询売上集計結果列表
+export function purchaseSaleList(query) {
+  return request({
+    url: '/system/purchase/sale/detail',
+    method: 'get',
+    params: query
+  })
+}

+ 1 - 10
src/api/fcbi/survey.js

@@ -66,13 +66,4 @@ export function listSurveyAnswer(query) {
     method: 'get',
     params: query
   })
-}
-
-// 查询売上集計結果列表
-export function salesSurvey(query) {
-  return request({
-    url: '/system/survey/sales',
-    method: 'get',
-    params: query
-  })
-}
+}

+ 14 - 0
src/router/index.js

@@ -195,6 +195,20 @@ export const constantRoutes = [
             }
         ]
     },
+    {
+        path: '/customerAdmin',
+        component: Layout,
+        hidden: true,
+        redirect: 'noredirect',
+        children: [
+            {
+                path: 'customerDetail/:customerId',
+                component: () => import('@/views/fcbi/customer/detail'),
+                name: 'customerDetail',
+                meta: {title: '顧客詳細', icon: 'user'}
+            }
+        ]
+    },
 ]
 
 // ダイナミックルート、ユーザー権限に基づいて動的に読み込みます

+ 74 - 0
src/views/fcbi/customer/detail.vue

@@ -0,0 +1,74 @@
+<template>
+  <div class="app-container">
+    <el-row :gutter="20">
+      <el-col :span="12" v-for="(item, index) in formItems.slice(0, 4)" :key="index">
+        <el-form-item :label="item.label" label-width="120px">
+          <el-input v-model="data.form[item.prop]" readonly class="small-input" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12">
+        <el-form-item label="郵便番号" label-width="120px">
+          <el-input v-model="data.form.postalCode" readonly class="small-input" />
+        </el-form-item>
+      </el-col>
+      <el-col :span="12">
+        <el-form-item label="お電話番号" label-width="120px">
+          <el-input v-model="data.form.phoneNumber" readonly class="small-input" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="24">
+        <el-form-item label="住所" label-width="120px">
+          <el-input v-model="data.form.address" readonly class="address-input" />
+        </el-form-item>
+      </el-col>
+
+      <el-col :span="12" v-for="(item, index) in formItems.slice(6)" :key="index + 6">
+        <el-form-item :label="item.label" label-width="120px">
+          <el-input v-model="data.form[item.prop]" readonly class="small-input" />
+        </el-form-item>
+      </el-col>
+    </el-row>
+  </div>
+</template>
+
+<script setup>
+import { reactive, toRefs } from 'vue';
+import { useRoute } from 'vue-router';
+const route = useRoute();
+import {getcustomerDetail} from "@/api/fcbi/customer.js"
+const customerId = route.params.customerId;
+
+const data = reactive({
+  form: {},
+  queryParams: {},
+});
+const { queryParams } = toRefs(data);
+
+const formItems = [
+  { label: '顧客名', prop: 'customerName' },
+  { label: '顧客名(カナ)', prop: 'customerNameKana' },
+  { label: '性別', prop: 'gender' },
+  { label: '生年月日', prop: 'birthday' },
+  { label: '郵便番号', prop: 'postalCode' },
+  { label: 'お電話番号', prop: 'phoneNumber' },
+  { label: 'メールアドレス', prop: 'email' },
+  { label: '会員レベル', prop: 'memberLevel' },
+  { label: '直近購入年月', prop: 'recentPurchaseMonth' },
+  { label: '最終購入日', prop: 'lastPurchaseDate' },
+  { label: '購入頻度', prop: 'purchaseFrequency' },
+  { label: '累計有効購入金額', prop: 'totalValidPurchaseAmount' },
+  { label: 'DM対象', prop: 'dmTarget' },
+  { label: 'DM配信', prop: 'dmDelivery' },
+  { label: 'メール配信', prop: 'emailDelivery' },
+  { label: 'SMS配信', prop: 'smsDelivery' },
+];
+</script>
+
+<style>
+.small-input,
+.address-input {
+  width: 100%;
+}
+</style>

+ 2 - 2
src/views/fcbi/customer/export.vue

@@ -182,7 +182,7 @@ function handleExportCSV() {
   )
       .then(() => {
         // 用户点击"はい"(是)时执行导出
-        download('system/survey/exportCustomerCsv', params, `ymdf_customer${new Date().getTime()}.csv`);
+        download('system/customer/exportCustomerCsv', params, `ymdf_customer${new Date().getTime()}.csv`);
       })
       .catch(() => {
         // 用户点击"いいえ"(否)时不执行操作,自动关闭弹窗
@@ -215,7 +215,7 @@ function handleExportDM() {
   )
       .then(() => {
         // 用户点击"はい"(是)时执行导出
-        download('system/survey/exportCustomerDm', params, `ymdf_customer${new Date().getTime()}.csv`);
+        download('system/customer/exportCustomerDm', params, `ymdf_customer${new Date().getTime()}.csv`);
       })
       .catch(() => {
         // 用户点击"いいえ"(否)时不执行操作,自动关闭弹窗

+ 191 - 0
src/views/fcbi/customer/list.vue

@@ -0,0 +1,191 @@
+<!-- 顧客一覧 -->
+<template>
+  <div class="app-container">
+    <el-form ref="queryRef" :inline="true" :model="queryParams">
+      <el-form-item label="顧客名" prop="customerName">
+        <el-input v-model="queryParams.customerName"
+                  clearable maxlength="255" @keyup.enter="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="顧客名(カナ)" prop="customerNameKana">
+        <el-input v-model="queryParams.customerNameKana"
+                  clearable
+                  maxlength="255" @keyup.enter="handleQuery"/>
+      </el-form-item>
+      <el-row v-show="initLoadingCompleted" :gutter="10" class="mb8">
+        <el-col :span="1.5">
+          <el-form-item label="店舗" prop="storeCode">
+            <el-select v-model="queryParams.storeCode" filterable style="width: 600px;margin-left: 13px;">
+              <el-option
+                  v-for="dict in fcStoreOptions"
+                  :key="dict.key"
+                  :label="dict.value"
+                  :value="dict.key"
+              />
+            </el-select>
+          </el-form-item>
+        </el-col>
+        <el-form-item label="FC" prop="brandCode" >
+          <el-checkbox-group v-model="queryParams.brandNames ">
+            <el-checkbox v-for="dict in yamada_fc_brand" :key="dict.label" :label="dict.label">{{ dict.label }}</el-checkbox>
+          </el-checkbox-group>
+        </el-form-item>
+        <el-form-item>
+          <el-button icon="Search" type="primary" @click="handleQuery">検索</el-button>
+          <el-button icon="Refresh" type="primary" @click="resetQuery">クリア</el-button>
+        </el-form-item>
+      </el-row>
+    </el-form>
+
+    <el-table v-show="initLoadingCompleted" v-loading="listLoading" :border="true" :data="CustomerList">
+      <el-table-column :show-overflow-tooltip="true" align="center" header-align="left" label="顧客" min-width="60"
+                       prop="customerName"
+      >
+      </el-table-column>
+      <el-table-column :show-overflow-tooltip="true" align="left" header-align="left" label="顧客名(カナ)" min-width="70"
+                       prop="customerNameKana"
+      >
+      </el-table-column>
+      <el-table-column :show-overflow-tooltip="true" align="center" header-align="center" label="FC" min-width="80"
+                       prop="brandName"
+                       width=""/>
+      <el-table-column :show-overflow-tooltip="true" align="center" header-align="center" label="店舗名" min-width="60"
+                       prop="storeName"
+                       width=""/>
+      <el-table-column :show-overflow-tooltip="true" align="center" header-align="center" label="住所" min-width="90"
+                       prop="address1"
+                       width=""/>
+      <el-table-column :show-overflow-tooltip="true" align="left" header-align="center" label="郵便番号" min-width="70"
+                       prop="postalCode"
+                       width=""/>
+      <el-table-column :show-overflow-tooltip="true" align="center" header-align="center" label="お電話番号" min-width="60"
+                       prop="mobilePhone"
+                       width=""/>
+      <el-table-column :show-overflow-tooltip="true" align="center" header-align="left" label="生年月日" min-width="70"
+                       prop="birthDate"
+                       width=""/>
+      <el-table-column :show-overflow-tooltip="true" align="right" header-align="left" label="直近購入年月" min-width="70"
+                       prop="lastPurchaseMonth"
+                       width=""/>
+      <el-table-column align="center" class-name="small-padding fixed-width" label="操作" min-width="180" width="300">
+        <template #default="scope">
+          <el-button @click="CustomerDetail(scope.row)"  v-hasPermi="['fcbi:customer:detail']"  icon="Edit" link type="primary" >顧客詳細</el-button>
+          <el-button @click="Confirm(scope.row)"  v-hasPermi="['fcbi:customer:history']"  icon="Edit" link type="primary" >顧客購入履歴</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination v-show="listTotalCnt>0"
+                v-model:limit="queryParams.pageSize"
+                v-model:page="queryParams.pageNum"
+                :total="listTotalCnt"
+                @pagination="getSearchList"/>
+  </div>
+</template>
+
+<script name="CustomerList" setup>
+
+import {customerSurvey, fcStoreSurvey} from "@/api/fcbi/customer.js"
+import {useRouter} from 'vue-router';
+
+// 認証項目のテーブルデータを格納するリアクティブ
+const CustomerList = ref([]);
+// データ読み込み中のローディング状態を管理するリアクティブ
+const listLoading = ref(false);
+// 検索結果の総件数を格納するリアクティブ
+const listTotalCnt = ref(0);
+// 初期ロードが完了したかどうかを示すリアクティブ
+const initLoadingCompleted = ref(false);
+const {proxy} = getCurrentInstance();
+const router = useRouter();
+// アップロード対象を取得
+const { yamada_fc_brand } = proxy.useDict('yamada_fc_brand');
+const fcStoreOptions = ref([]);
+
+/**
+ * コンポーネントの状態を管理するリアクティブオブジェクト
+ */
+const data = reactive({
+  form: {},
+  // 検索条件を格納するオブジェクト
+  queryParams: {
+    pageNum: 1,
+    pageSize: 10,
+    customerName: '',
+    customerNameKana: '',
+    storeCode: '',
+    brandNames : [],
+  },
+});
+
+// リアクティブオブジェクトからプロパティを参照可能なオブジェクトに変換
+const {queryParams} = toRefs(data);
+
+/**
+ * 検索ボタンのクリックイベントハンドラー
+ * 検索条件を初期ページに設定して検索を実行する
+ */
+function handleQuery() {
+  queryParams.value.pageNum = 1;
+  getSearchList();
+}
+
+/**
+ * 店舗の情報を取得する
+ */
+function getFcStoreOptions() {
+  fcStoreSurvey().then(response => {
+    fcStoreOptions.value = response.rows.map(store => {
+      return {
+        key: store.storeCode,
+        value: `${store.fcBrandName} ${store.storeName}`,
+      };
+    });
+  });
+}
+
+/**
+ * 発注リストを検索する関数
+ * APIを呼び出して検索条件に一致する発注データを取得する
+ */
+function getSearchList() {
+  listLoading.value = true;
+  let params = {
+    pageNum: queryParams.value.pageNum,
+    pageSize: queryParams.value.pageSize,
+    customerName: queryParams.value.customerName,
+    customerNameKana: queryParams.value.customerNameKana,
+    storeCode: queryParams.value.storeCode,
+    brandNames : queryParams.value.brandNames ,
+  };
+  customerSurvey(params).then(response => {
+    CustomerList.value = response.rows;
+    listTotalCnt.value = response.total;
+    listLoading.value = false;
+    initLoadingCompleted.value = true;
+  });
+}
+
+const CustomerDetail = (row) => {
+  router.push({
+    name: 'customerDetail',
+    params: {
+      customerId: row.customerId
+    }
+  });
+};
+/**
+ * リセット ボタンアクション
+ */
+function resetQuery() {
+  proxy.resetForm("queryRef");
+  queryParams.value.brandNames = [];
+  handleQuery();
+}
+// コンポーネント初期化時に検索を実行
+getFcStoreOptions();
+getSearchList();
+</script>
+
+<style>
+
+</style>

+ 4 - 4
src/views/fcbi/sales/sumResult.vue

@@ -44,7 +44,7 @@
                        prop="storeName"
                        width=""/>
       <el-table-column :show-overflow-tooltip="true" align="left" header-align="center" label="平均取引額" min-width="60"
-                       prop="avgTransation"
+                       prop="avgTransaction"
                        width=""/>
       <el-table-column :show-overflow-tooltip="true" align="left" header-align="center" :label="ratioLabel" min-width="40"
                        prop="prevRatio"
@@ -64,7 +64,7 @@
 
 <script name="SurveySumResults" setup>
 
-import { salesSurvey} from "@/api/fcbi/survey.js"
+import { purchaseSaleList} from "@/api/fcbi/purchaseSale.js"
 import { useSurveySalesStore } from '@/store/surveyStore';
 import {download} from "@/utils/request.js";
 import { AGGREGATION_TYPE, TARGET_PERIOD_TYPE } from '@/constants';
@@ -156,7 +156,7 @@ function getSearchList() {
     // 标志位(用于后端判断逻辑)
     salesFlag: queryParams.value.salesFlag
   };
-  salesSurvey(params).then(response => {
+  purchaseSaleList(params).then(response => {
     fcItemList.value = response.rows;
     storeItemList.value = response.rows;
     listTotalCnt.value = response.total;
@@ -205,7 +205,7 @@ function handleExportCSV() {
     // 标志位(用于后端判断逻辑)
     salesFlag: queryParams.value.salesFlag
   };
-  download('system/survey/exportResultsCsv', exportParams, fileName);
+  download('system/purchase/sale/exportResultsCsv', exportParams, fileName);
 }
 </script>