浏览代码

mod: 油价

weieryang 1 月之前
父节点
当前提交
7213329ac3

+ 20 - 0
apps/web-ele/src/api/task/index.ts

@@ -4,9 +4,11 @@ enum Api {
4 4
   emergencyWySubmit = '/formEmergencyDrill/drill/submit',
5 5
   emergencyWySubmitReport = '/formEmergencyDrill/drill/submitReport',
6 6
   groupLogBase = '/formTeamShiftLog/log/handle',
7
+  marketingSurveyHandle = '/formCompetitorMarketingSurvey/survey/handle',
7 8
   meetingBase = '/formMeetingRecords/records/handle',
8 9
   salesSurveyHandle = '/formCompetitorSalesSurvey/survey/handle',
9 10
   scheduleShiftManagementList = '/scheduleShiftManagement/management/list',
11
+  turnInRateSurveyHandle = '/formTurnInRateSurvey/survey/handle',
10 12
   // childBase = '/taskCheckSubItem/item',
11 13
 }
12 14
 
@@ -63,3 +65,21 @@ export function submitEmergencyWyReport(params: any) {
63 65
 export function handleSalesSurvey(params: any) {
64 66
   return requestClient.put(`${Api.salesSurveyHandle}`, params);
65 67
 }
68
+
69
+/**
70
+ * 入场率调查处理
71
+ * @param params 处理参数
72
+ * @returns
73
+ */
74
+export function handleTurnInRateSurvey(params: any) {
75
+  return requestClient.put(`${Api.turnInRateSurveyHandle}`, params);
76
+}
77
+
78
+/**
79
+ * 营销调查处理
80
+ * @param params 处理参数
81
+ * @returns
82
+ */
83
+export function handleMarketingSurvey(params: any) {
84
+  return requestClient.put(`${Api.marketingSurveyHandle}`, params);
85
+}

+ 162 - 103
apps/web-ele/src/views/schedule/detail/components/competition.vue

@@ -1,11 +1,16 @@
1 1
 <script lang="ts" setup>
2 2
 // @ts-ignore
3
-import { computed, ref } from 'vue';
3
+import { computed, onMounted } from 'vue';
4
+
5
+import { DictEnum } from '@vben/constants';
4 6
 
5 7
 import { ElCard, ElDescriptions, ElDescriptionsItem } from 'element-plus';
8
+import { cloneDeep } from 'lodash-es';
6 9
 
7 10
 // @ts-ignore
8 11
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
12
+// @ts-ignore: 忽略
13
+import { dictDataInfo } from '#/api/system/dict/dict-data';
9 14
 
10 15
 // 定义组件的Props接口
11 16
 interface SalesSurveyProps {
@@ -30,116 +35,88 @@ const formatNumber = (value: number | string) => {
30 35
   return num.toFixed(2);
31 36
 };
32 37
 
33
-// 表格列配置
34
-const tableColumns: any = [
38
+// 第一个表格列配置(油站基本信息)
39
+const stationInfoColumns: any = [
35 40
   {
36 41
     field: 'competitorName',
37
-    title: '站',
38
-    width: 100,
42
+    title: '站',
43
+    width: 120,
39 44
     fixed: 'left',
40 45
     formatter: ({ row }) => {
41 46
       return row.competitorName || row.stationName || '-';
42 47
     },
43 48
   },
44 49
   {
45
-    field: 'gasolineCar',
46
-    title: '汽油车',
47
-    width: 180,
48
-    children: [
49
-      {
50
-        field: 'gasolineVehicleCount',
51
-        title: '进站次数',
52
-        width: 90,
53
-      },
54
-      {
55
-        field: 'gasolineVolumeDiff',
56
-        title: '加油升差数',
57
-        width: 90,
58
-      },
59
-    ],
50
+    field: 'stationNatureName',
51
+    title: '油站性质',
52
+    width: 100,
53
+    formatter: ({ row }) => {
54
+      return row.stationNatureName || '-';
55
+    },
60 56
   },
61 57
   {
62
-    field: 'dieselCar',
63
-    title: '柴油车',
64
-    width: 180,
65
-    children: [
66
-      {
67
-        field: 'dieselVehicleCount',
68
-        title: '进站次数',
69
-        width: 90,
70
-      },
71
-      {
72
-        field: 'dieselVolumeDiff',
73
-        title: '加油升差数',
74
-        width: 90,
75
-      },
76
-    ],
58
+    field: 'isCompetitor',
59
+    title: '竞争关系',
60
+    width: 120,
61
+    formatter: ({ row }) => {
62
+      return row.isCompetitor === 1 ? '是' : '否';
63
+    },
77 64
   },
78 65
   {
79
-    field: 'motorcycle',
80
-    title: '摩托车',
81
-    width: 180,
82
-    children: [
83
-      {
84
-        field: 'motorcycleCount',
85
-        title: '进站次数',
86
-        width: 90,
87
-      },
88
-      {
89
-        field: 'motorcycleVolumeDiff',
90
-        title: '加油升差数',
91
-        width: 90,
92
-      },
93
-    ],
66
+    field: 'distanceKm',
67
+    title: '距离(KM)',
68
+    width: 100,
94 69
   },
95 70
   {
96
-    field: 'gasCar',
97
-    title: '气车',
98
-    width: 180,
99
-    children: [
100
-      {
101
-        field: 'gasVehicleCount',
102
-        title: '进站次数',
103
-        width: 90,
104
-      },
105
-      {
106
-        field: 'gasVolumeDiff',
107
-        title: '加油升差数',
108
-        width: 90,
109
-      },
110
-    ],
71
+    field: 'promotionActivities',
72
+    title: '优惠活动',
73
+    width: 200,
74
+    editRender: { name: 'textarea' },
111 75
   },
112 76
   {
113
-    field: 'periodForecastDiff',
114
-    title: '时段预测销量差(升)',
115
-    width: 150,
77
+    field: 'valueAddedServices',
78
+    title: '增值服务',
79
+    width: 200,
80
+    editRender: { name: 'textarea' },
116 81
   },
117 82
   {
118
-    field: 'dailyForecastDiff',
119
-    title: '全天预测销量差(升)',
120
-    width: 150,
83
+    field: 'equipmentConfigChanges',
84
+    title: '油站设备配置变化',
85
+    width: 200,
86
+    editRender: { name: 'textarea' },
121 87
   },
88
+];
89
+
90
+// 第二个表格列配置(油品价格和销量差)
91
+const oilPriceColumns: any = [
122 92
   {
123
-    field: 'surveySales',
124
-    title: '调查销量(升)',
125
-    width: 180,
126
-    children: [
127
-      {
128
-        field: 'gasolineSurveyVolume',
129
-        title: '汽油',
130
-        width: 90,
131
-      },
132
-      {
133
-        field: 'dieselSurveyVolume',
134
-        title: '柴油',
135
-        width: 90,
136
-      },
137
-    ],
93
+    field: 'oilType',
94
+    title: '油品',
95
+    width: 100,
96
+    fixed: 'left',
97
+  },
98
+  {
99
+    field: 'listingPrice',
100
+    title: '挂牌价',
101
+    width: 100,
102
+    children: [],
103
+  },
104
+  {
105
+    field: 'discountPrice',
106
+    title: '优惠价',
107
+    width: 100,
108
+    children: [],
109
+  },
110
+  {
111
+    field: 'salesDifference',
112
+    title: '销量差',
113
+    width: 120,
114
+    children: [],
138 115
   },
139 116
 ];
140 117
 
141
-// 初始化表格配置
142
-const gridOptions: any = {
118
+// 初始化第一个表格配置(油站基本信息)
119
+const stationInfoGridOptions: any = {
143 120
   size: 'medium',
144 121
   toolbarConfig: {
145 122
     custom: false,
@@ -158,14 +135,90 @@ const gridOptions: any = {
158 135
       },
159 136
     },
160 137
   },
161
-  columns: tableColumns,
138
+  columns: stationInfoColumns,
139
+};
140
+
141
+// 初始化第二个表格配置(油品价格和销量差)
142
+const oilPriceGridOptions: any = {
143
+  size: 'medium',
144
+  toolbarConfig: {
145
+    custom: false,
146
+    refresh: false,
147
+    zoom: false,
148
+  },
149
+  pagerConfig: {
150
+    enabled: false,
151
+  },
152
+  proxyConfig: {
153
+    ajax: {
154
+      query: async () => {
155
+        const oilProducts = await dictDataInfo(DictEnum.OIL_PRODUCT);
156
+        const oilPriceList = oilProducts?.map((item: any) => {
157
+          const info: any = {
158
+            oilType: item.dictLabel,
159
+            oilTypeCode: item.dictValue,
160
+          };
161
+
162
+          props.taskDetail.forEach((item: any, index: number) => {
163
+            item.formOilPriceRecords.forEach((record: any) => {
164
+              if (record.oilTypeCode === item.oilTypeCode) {
165
+                info[`listingPrice_${item.id}_${index}`] =
166
+                  record.listingPrice || '-';
167
+                info[`discountPrice_${item.id}_${index}`] =
168
+                  record.discountPrice || '-';
169
+                info[`salesDifference_${item.id}_${index}`] =
170
+                  record.salesDifference || '-';
171
+              }
172
+            });
173
+          });
174
+          return info;
175
+        });
176
+        console.log(oilPriceList, 'oilPriceList');
177
+        return {
178
+          items: oilPriceList || [], // 初始数据为空
179
+        };
180
+      },
181
+    },
182
+  },
183
+  columns: oilPriceColumns,
162 184
 };
163 185
 
164
-// 表格数据
165
-const tableDatas = ref<any>([]);
166 186
 // 使用BasicTable组件
167
-const [BasicTable, basicTableApi] = useVbenVxeGrid({
168
-  gridOptions,
187
+const [StationInfoTable, stationInfoTableApi] = useVbenVxeGrid({
188
+  gridOptions: stationInfoGridOptions,
189
+});
190
+
191
+const [OilPriceTable, oilPriceTableApi] = useVbenVxeGrid({
192
+  gridOptions: oilPriceGridOptions,
193
+});
194
+
195
+const init = () => {
196
+  const columns: any = [...(cloneDeep(oilPriceColumns) || [])];
197
+  props.taskDetail.forEach((item: any, index: number) => {
198
+    columns[1].children.push({
199
+      field: `listingPrice_${item.id}_${index}`,
200
+      title: `${item.competitorName || item.stationName}`,
201
+      width: 100,
202
+    });
203
+    columns[2].children.push({
204
+      field: `discountPrice_${item.id}_${index}`,
205
+      title: `${item.competitorName || item.stationName}`,
206
+      width: 100,
207
+    });
208
+    columns[3].children.push({
209
+      field: `salesDifference_${item.id}_${index}`,
210
+      title: `${item.competitorName || item.stationName}`,
211
+      width: 100,
212
+    });
213
+  });
214
+
215
+  oilPriceGridOptions.columns = columns;
216
+
217
+  oilPriceTableApi.setGridOptions(oilPriceGridOptions);
218
+};
219
+
220
+onMounted(() => {
221
+  init();
169 222
 });
170 223
 </script>
171 224
 
@@ -178,7 +231,7 @@ const [BasicTable, basicTableApi] = useVbenVxeGrid({
178 231
           class="text-lg font-bold text-gray-800"
179 232
           style="font-size: 14px; font-weight: 600"
180 233
         >
181
-          销售调研详情
234
+          竟对销售调查详情
182 235
         </span>
183 236
       </div>
184 237
     </template>
@@ -187,24 +240,30 @@ const [BasicTable, basicTableApi] = useVbenVxeGrid({
187 240
       <!-- 基本信息 -->
188 241
       <div class="section-title">
189 242
         <div class="section-bar"></div>
190
-        <span class="section-text">基本信息</span>
243
+        <span class="section-text">油站策略</span>
191 244
       </div>
192 245
       <ElDescriptions :column="4" class="mb-6">
193
-        <ElDescriptionsItem label="调查开始时间:">
194
-          {{ taskDetail[0].surveyStartTime || '-' }}
195
-        </ElDescriptionsItem>
196
-        <ElDescriptionsItem label="调查结束时间:">
197
-          {{ taskDetail[0].surveyEndTime || '-' }}
246
+        <ElDescriptionsItem label="调查时间:">
247
+          {{ taskDetail[0]?.surveyDate || '-' }}
198 248
         </ElDescriptionsItem>
199 249
       </ElDescriptions>
200 250
 
201
-      <!-- 销量调查表格 -->
251
+      <!-- 油站基本信息表格 -->
252
+      <!-- <div class="section-title">
253
+        <div class="section-bar"></div>
254
+        <span class="section-text">油站基本信息</span>
255
+      </div> -->
256
+      <div class="mb-6">
257
+        <StationInfoTable table-title="" class="w-full" />
258
+      </div>
259
+
260
+      <!-- 油品价格和销量差表格 -->
202 261
       <div class="section-title">
203 262
         <div class="section-bar"></div>
204
-        <span class="section-text">销量调查数据</span>
263
+        <span class="section-text">价格销售</span>
205 264
       </div>
206 265
       <div class="mb-6">
207
-        <BasicTable table-title="" class="w-full" />
266
+        <OilPriceTable table-title="" class="w-full" />
208 267
       </div>
209 268
     </div>
210 269
   </ElCard>

+ 21 - 65
apps/web-ele/src/views/schedule/detail/components/entrance.vue

@@ -9,7 +9,7 @@ import { useVbenVxeGrid } from '#/adapter/vxe-table';
9 9
 
10 10
 // 定义组件的Props接口
11 11
 interface SalesSurveyProps {
12
-  taskDetail: any;
12
+  taskList: any;
13 13
 }
14 14
 
15 15
 // 接收父组件传递的任务详情数据
@@ -17,7 +17,7 @@ const props = defineProps<SalesSurveyProps>();
17 17
 
18 18
 // 计算属性,获取销售调研数据
19 19
 const salesSurveyData = computed(() => {
20
-  return props.taskDetail || [];
20
+  return props.taskList || [];
21 21
 });
22 22
 
23 23
 // 格式化日期时间
@@ -34,26 +34,26 @@ const formatNumber = (value: number | string) => {
34 34
 const tableColumns: any = [
35 35
   {
36 36
     field: 'competitorName',
37
-    title: '站',
38
-    width: 100,
37
+    title: '站',
38
+    // width: 100,
39 39
     fixed: 'left',
40 40
     formatter: ({ row }) => {
41 41
       return row.competitorName || row.stationName || '-';
42 42
     },
43 43
   },
44 44
   {
45
-    field: 'gasolineCar',
45
+    field: 'gasCar',
46 46
     title: '汽油车',
47 47
     width: 180,
48 48
     children: [
49 49
       {
50
-        field: 'gasolineVehicleCount',
51
-        title: '进站次数',
50
+        field: 'gasRoadFlow',
51
+        title: '路面车流',
52 52
         width: 90,
53 53
       },
54 54
       {
55
-        field: 'gasolineVolumeDiff',
56
-        title: '加油升差数',
55
+        field: 'gasInFlow',
56
+        title: '进站车流',
57 57
         width: 90,
58 58
       },
59 59
     ],
@@ -64,13 +64,13 @@ const tableColumns: any = [
64 64
     width: 180,
65 65
     children: [
66 66
       {
67
-        field: 'dieselVehicleCount',
68
-        title: '进站次数',
67
+        field: 'dieselRoadFlow',
68
+        title: '路面车流',
69 69
         width: 90,
70 70
       },
71 71
       {
72
-        field: 'dieselVolumeDiff',
73
-        title: '加油升差数',
72
+        field: 'dieselInFlow',
73
+        title: '进站车流',
74 74
         width: 90,
75 75
       },
76 76
     ],
@@ -81,57 +81,13 @@ const tableColumns: any = [
81 81
     width: 180,
82 82
     children: [
83 83
       {
84
-        field: 'motorcycleCount',
85
-        title: '进站次数',
86
-        width: 90,
87
-      },
88
-      {
89
-        field: 'motorcycleVolumeDiff',
90
-        title: '加油升差数',
91
-        width: 90,
92
-      },
93
-    ],
94
-  },
95
-  {
96
-    field: 'gasCar',
97
-    title: '气车',
98
-    width: 180,
99
-    children: [
100
-      {
101
-        field: 'gasVehicleCount',
102
-        title: '进站次数',
103
-        width: 90,
104
-      },
105
-      {
106
-        field: 'gasVolumeDiff',
107
-        title: '加油升差数',
108
-        width: 90,
109
-      },
110
-    ],
111
-  },
112
-  {
113
-    field: 'periodForecastDiff',
114
-    title: '时段预测销量差(升)',
115
-    width: 150,
116
-  },
117
-  {
118
-    field: 'dailyForecastDiff',
119
-    title: '全天预测销量差(升)',
120
-    width: 150,
121
-  },
122
-  {
123
-    field: 'surveySales',
124
-    title: '调查销量(升)',
125
-    width: 180,
126
-    children: [
127
-      {
128
-        field: 'gasolineSurveyVolume',
129
-        title: '汽油',
84
+        field: 'motorcycleRoadFlow',
85
+        title: '路面车流',
130 86
         width: 90,
131 87
       },
132 88
       {
133
-        field: 'dieselSurveyVolume',
134
-        title: '柴油',
89
+        field: 'motorcycleInFlow',
90
+        title: '进站车流',
135 91
         width: 90,
136 92
       },
137 93
     ],
@@ -153,7 +109,7 @@ const gridOptions: any = {
153 109
     ajax: {
154 110
       query: async () => {
155 111
         return {
156
-          items: props.taskDetail || [],
112
+          items: props.taskList || [],
157 113
         };
158 114
       },
159 115
     },
@@ -178,7 +134,7 @@ const [BasicTable, basicTableApi] = useVbenVxeGrid({
178 134
           class="text-lg font-bold text-gray-800"
179 135
           style="font-size: 14px; font-weight: 600"
180 136
         >
181
-          销售调研详情
137
+          拐入率调研详情
182 138
         </span>
183 139
       </div>
184 140
     </template>
@@ -191,10 +147,10 @@ const [BasicTable, basicTableApi] = useVbenVxeGrid({
191 147
       </div>
192 148
       <ElDescriptions :column="4" class="mb-6">
193 149
         <ElDescriptionsItem label="调查开始时间:">
194
-          {{ taskDetail[0].surveyStartTime || '-' }}
150
+          {{ taskList[0].surveyStartTime || '-' }}
195 151
         </ElDescriptionsItem>
196 152
         <ElDescriptionsItem label="调查结束时间:">
197
-          {{ taskDetail[0].surveyEndTime || '-' }}
153
+          {{ taskList[0].surveyEndTime || '-' }}
198 154
         </ElDescriptionsItem>
199 155
       </ElDescriptions>
200 156
 

+ 112 - 124
apps/web-ele/src/views/schedule/detail/drawer/competition/config-data.tsx

@@ -8,33 +8,58 @@ export const drawerFormSchema: any | FormSchemaGetter = () => [
8 8
   {
9 9
     component: 'DatePicker',
10 10
     componentProps: {
11
-      placeholder: '请选择调查开始时间',
11
+      placeholder: '请选择调查时间',
12 12
       type: 'datetime',
13 13
       format: 'YYYY-MM-DD HH:mm:ss',
14 14
       valueFormat: 'YYYY-MM-DD HH:mm:ss',
15 15
       width: '100%',
16 16
     },
17
-    fieldName: 'surveyStartTime',
18
-    label: '调查开始时间',
17
+    fieldName: 'surveyDate',
18
+    label: '调查时间',
19 19
     rules: 'required',
20 20
   },
21
+  // {
22
+  //   component: 'DatePicker',
23
+  //   componentProps: {
24
+  //     placeholder: '请选择调查结束时间',
25
+  //     type: 'datetime',
26
+  //     format: 'YYYY-MM-DD HH:mm:ss',
27
+  //     valueFormat: 'YYYY-MM-DD HH:mm:ss',
28
+  //     width: '100%',
29
+  //   },
30
+  //   fieldName: 'surveyEndTime',
31
+  //   label: '调查结束时间',
32
+  //   rules: 'required',
33
+  // },
21 34
   {
22
-    component: 'DatePicker',
35
+    component: 'SectionTitle',
36
+    fieldName: '_section_title',
37
+    hideLabel: true,
23 38
     componentProps: {
24
-      placeholder: '请选择调查结束时间',
25
-      type: 'datetime',
26
-      format: 'YYYY-MM-DD HH:mm:ss',
27
-      valueFormat: 'YYYY-MM-DD HH:mm:ss',
28
-      width: '100%',
39
+      title: '油站策略',
40
+    },
41
+  },
42
+  {
43
+    fieldName: 'stationInfoTable',
44
+    label: '油站基本信息',
45
+    hideLabel: true,
46
+    renderComponentContent: () => {
47
+      return {
48
+        default: () => [],
49
+      };
50
+    },
51
+  },
52
+  {
53
+    component: 'SectionTitle',
54
+    fieldName: '_section_title',
55
+    hideLabel: true,
56
+    componentProps: {
57
+      title: '价格销售',
29 58
     },
30
-    fieldName: 'surveyEndTime',
31
-    label: '调查结束时间',
32
-    rules: 'required',
33 59
   },
34 60
   {
35
-    fieldName: 'salesSurveyTable',
36
-    label: '销量调查表格',
37
-    // component: 'div',
61
+    fieldName: 'oilPriceTable',
62
+    label: '油品价格和销量差',
38 63
     hideLabel: true,
39 64
     renderComponentContent: () => {
40 65
       return {
@@ -44,122 +69,85 @@ export const drawerFormSchema: any | FormSchemaGetter = () => [
44 69
   },
45 70
 ];
46 71
 
47
-// 默认表格列配置
48
-export const defautTableColumns: VxeGridProps['columns'] = [
72
+// 油站基本信息表格列配置
73
+export const stationInfoColumns: VxeGridProps['columns'] = [
49 74
   {
50 75
     field: 'competitorName',
51
-    title: '站',
52
-    width: 100,
76
+    title: '站',
77
+    width: 120,
53 78
     fixed: 'left',
54 79
     formatter: ({ row }) => {
55 80
       return row.competitorName || row.stationName || '-';
56 81
     },
57 82
   },
58 83
   {
59
-    field: 'gasolineCar',
60
-    title: '汽油车',
61
-    width: 180,
62
-    children: [
63
-      {
64
-        field: 'gasolineVehicleCount',
65
-        title: '进站次数',
66
-        editRender: { name: 'input' },
67
-        width: 90,
68
-      },
69
-      {
70
-        field: 'gasolineVolumeDiff',
71
-        title: '加油升差数',
72
-        editRender: { name: 'input' },
73
-        width: 90,
74
-      },
75
-    ],
76
-  },
77
-  {
78
-    field: 'dieselCar',
79
-    title: '柴油车',
80
-    width: 180,
81
-    children: [
82
-      {
83
-        field: 'dieselVehicleCount',
84
-        title: '进站次数',
85
-        width: 90,
86
-        editRender: { name: 'input' },
87
-      },
88
-      {
89
-        field: 'dieselVolumeDiff',
90
-        title: '加油升差数',
91
-        width: 90,
92
-        editRender: { name: 'input' },
93
-      },
94
-    ],
95
-  },
96
-  {
97
-    field: 'motorcycle',
98
-    title: '摩托车',
99
-    width: 180,
100
-    children: [
101
-      {
102
-        field: 'motorcycleCount',
103
-        title: '进站次数',
104
-        width: 90,
105
-        editRender: { name: 'input' },
106
-      },
107
-      {
108
-        field: 'motorcycleVolumeDiff',
109
-        title: '加油升差数',
110
-        width: 90,
111
-        editRender: { name: 'input' },
112
-      },
113
-    ],
114
-  },
115
-  {
116
-    field: 'gasCar',
117
-    title: '气车',
118
-    width: 180,
119
-    children: [
120
-      {
121
-        field: 'gasVehicleCount',
122
-        title: '进站次数',
123
-        width: 90,
124
-        editRender: { name: 'input' },
125
-      },
126
-      {
127
-        field: 'gasVolumeDiff',
128
-        title: '加油升差数',
129
-        width: 90,
130
-        editRender: { name: 'input' },
131
-      },
132
-    ],
133
-  },
134
-  {
135
-    field: 'periodForecastDiff',
136
-    title: '时段预测销量差(升)',
137
-    width: 150,
138
-    editRender: { name: 'input' },
139
-  },
140
-  {
141
-    field: 'dailyForecastDiff',
142
-    title: '全天预测销量差(升)',
143
-    editRender: { name: 'input' },
144
-    width: 150,
145
-  },
146
-  {
147
-    field: 'surveySales',
148
-    title: '调查销量(升)',
149
-    width: 180,
150
-    children: [
151
-      {
152
-        field: 'gasolineSurveyVolume',
153
-        title: '汽油',
154
-        width: 90,
155
-        editRender: { name: 'input' },
156
-      },
157
-      {
158
-        field: 'dieselSurveyVolume',
159
-        title: '柴油',
160
-        width: 90,
161
-        editRender: { name: 'input' },
162
-      },
163
-    ],
84
+    field: 'stationNatureName',
85
+    title: '油站性质',
86
+    width: 100,
87
+    formatter: ({ row }) => {
88
+      return row.stationNatureName || '-';
89
+    },
90
+  },
91
+  {
92
+    field: 'isCompetitor',
93
+    title: '竞争关系',
94
+    width: 120,
95
+    formatter: ({ row }) => {
96
+      return row.isCompetitor === 1 ? '是' : '否';
97
+    },
98
+  },
99
+  {
100
+    field: 'distanceKm',
101
+    title: '距离(KM)',
102
+    width: 100,
103
+  },
104
+  {
105
+    field: 'promotionActivities',
106
+    title: '优惠活动',
107
+    width: 200,
108
+    editRender: { name: 'textarea' },
109
+  },
110
+  {
111
+    field: 'valueAddedServices',
112
+    title: '增值服务',
113
+    width: 200,
114
+    editRender: { name: 'textarea' },
115
+  },
116
+  {
117
+    field: 'equipmentConfigChanges',
118
+    title: '油站设备配置变化',
119
+    width: 200,
120
+    editRender: { name: 'textarea' },
121
+  },
122
+];
123
+
124
+// 油品价格和销量差表格列配置
125
+export const oilPriceColumns: VxeGridProps['columns'] = [
126
+  {
127
+    field: 'oilType',
128
+    title: '油品',
129
+    width: 100,
130
+    fixed: 'left',
131
+  },
132
+  {
133
+    field: 'listingPrice',
134
+    title: '挂牌价',
135
+    width: 100,
136
+    children: [],
137
+  },
138
+  {
139
+    field: 'discountPrice',
140
+    title: '优惠价',
141
+    width: 100,
142
+    children: [],
143
+  },
144
+  {
145
+    field: 'salesDifference',
146
+    title: '销量差',
147
+    width: 120,
148
+    children: [],
164 149
   },
165 150
 ];
151
+
152
+// 默认表格列配置(兼容旧代码,实际使用上面两个表格)
153
+export const defautTableColumns: VxeGridProps['columns'] = stationInfoColumns;

+ 163 - 79
apps/web-ele/src/views/schedule/detail/drawer/competition/index.vue

@@ -6,14 +6,23 @@ import { ref } from 'vue';
6 6
 
7 7
 // @ts-ignore: 忽略
8 8
 import { useVbenDrawer, useVbenForm } from '@vben/common-ui';
9
+import { DictEnum } from '@vben/constants';
10
+
11
+import { cloneDeep } from 'lodash-es';
9 12
 
10 13
 // @ts-ignore: 忽略
11 14
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
12 15
 // @ts-ignore: 忽略
13
-import { handleSalesSurvey } from '#/api/task';
14
-
16
+import { dictDataInfo } from '#/api/system/dict/dict-data';
15 17
 // @ts-ignore: 忽略
16
-import { defautTableColumns, drawerFormSchema } from './config-data.tsx';
18
+import { handleMarketingSurvey } from '#/api/task';
19
+
20
+import {
21
+  drawerFormSchema,
22
+  oilPriceColumns,
23
+  stationInfoColumns,
24
+  // @ts-ignore: 忽略
25
+} from './config-data.tsx';
17 26
 
18 27
 // 定义事件
19 28
 const emit = defineEmits<{ reload: [] }>();
@@ -28,9 +37,122 @@ const [Form, formApi] = useVbenForm({
28 37
 const taskParams = ref({
29 38
   taskId: '',
30 39
   taskName: '',
31
-  taskList: '',
40
+  taskList: [] as any[],
32 41
 });
33 42
 
43
+// 初始化第一个表格配置(油站基本信息)
44
+const stationInfoGridOptions: VxeGridProps = {
45
+  size: 'medium',
46
+  toolbarConfig: {
47
+    custom: false,
48
+    refresh: false,
49
+    zoom: false,
50
+  },
51
+  pagerConfig: {
52
+    enabled: false,
53
+  },
54
+  proxyConfig: {
55
+    ajax: {
56
+      query: async () => {
57
+        // 这里可以调用API获取表格数据
58
+        return {
59
+          items: taskParams.value.taskList || [], // 初始数据为空
60
+        };
61
+      },
62
+    },
63
+  },
64
+  columns: stationInfoColumns,
65
+  editConfig: {
66
+    mode: 'cell',
67
+    trigger: 'click',
68
+  },
69
+};
70
+
71
+// 初始化第二个表格配置(油品价格和销量差)
72
+const oilPriceGridOptions: VxeGridProps = {
73
+  size: 'medium',
74
+  toolbarConfig: {
75
+    custom: false,
76
+    refresh: false,
77
+    zoom: false,
78
+  },
79
+  pagerConfig: {
80
+    enabled: false,
81
+  },
82
+  proxyConfig: {
83
+    ajax: {
84
+      query: async () => {
85
+        // 这里可以调用API获取表格数据
86
+        const oilProducts = await dictDataInfo(DictEnum.OIL_PRODUCT);
87
+        const oilPriceList = oilProducts?.map((item: any) => {
88
+          return {
89
+            oilType: item.dictLabel,
90
+            oilTypeCode: item.dictValue,
91
+          };
92
+        });
93
+        return {
94
+          items: oilPriceList || [], // 初始数据为空
95
+        };
96
+      },
97
+    },
98
+  },
99
+  columns: oilPriceColumns,
100
+  editConfig: {
101
+    mode: 'cell',
102
+    trigger: 'click',
103
+  },
104
+};
105
+
106
+// 初始化第一个表格组件
107
+const [StationInfoTable, stationInfoTableApi] = useVbenVxeGrid({
108
+  gridOptions: stationInfoGridOptions,
109
+});
110
+
111
+// 初始化第二个表格组件
112
+const [OilPriceTable, oilPriceTableApi] = useVbenVxeGrid({
113
+  gridOptions: oilPriceGridOptions,
114
+});
115
+
116
+const initPriceColumnsAndData = () => {
117
+  // 深拷贝oilPriceColumns这个数组,避免直接修改原数组
118
+  const columns: any = [...(cloneDeep(oilPriceColumns) || [])];
119
+  taskParams.value.taskList.forEach((item: any, index: number) => {
120
+    columns[1].children.push({
121
+      field: `listingPrice_${item.id}_${index}`,
122
+      title: `${item.competitorName || item.stationName}`,
123
+      width: 100,
124
+      editRender: { name: 'input' },
125
+    });
126
+    columns[2].children.push({
127
+      field: `discountPrice_${item.id}_${index}`,
128
+      title: `${item.competitorName || item.stationName}`,
129
+      width: 100,
130
+      editRender: { name: 'input' },
131
+    });
132
+    columns[3].children.push({
133
+      field: `salesDifference_${item.id}_${index}`,
134
+      title: `${item.competitorName || item.stationName}`,
135
+      width: 100,
136
+      editRender: { name: 'input' },
137
+    });
138
+  });
139
+
140
+  // 调用油品
141
+  // const oilProducts = getDictOptions(DictEnum.OIL_PRODUCT);
142
+  // oilPrices.value = oilProducts?.map((item: any) => {
143
+  //   return {
144
+  //     oilType: item.dictLabel,
145
+  //     oilTypeCode: item.dictValue,
146
+  //   };
147
+  // });
148
+
149
+  oilPriceGridOptions.columns = columns;
150
+
151
+  oilPriceTableApi.setGridOptions(oilPriceGridOptions);
152
+  // oilPriceTableApi.grid.set();
153
+  // oilPriceTableApi.query();
154
+};
155
+
34 156
 // 初始化抽屉组件
35 157
 const [Drawer, drawerApi] = useVbenDrawer({
36 158
   async onOpenChange(isOpen: boolean) {
@@ -43,6 +165,10 @@ const [Drawer, drawerApi] = useVbenDrawer({
43 165
       taskParams.value.taskId = taskId;
44 166
       taskParams.value.taskName = taskName;
45 167
       taskParams.value.taskList = taskList;
168
+
169
+      // stationInfoTableApi.reload();
170
+
171
+      initPriceColumnsAndData();
46 172
     } catch (error) {
47 173
       console.error(error);
48 174
     } finally {
@@ -61,23 +187,35 @@ const [Drawer, drawerApi] = useVbenDrawer({
61 187
       }
62 188
 
63 189
       const values = await formApi.getValues();
64
-      // const params = {
65
-      //   id: taskParams.value.taskId,
66
-      //   ...values,
67
-      // };
68
-
69
-      const list = basicTableApi.grid.getData();
70
-      const params: any = [];
71
-      list.forEach((item: any) => {
72
-        params.push({
73
-          ...item,
74
-          surveyStartTime: values.surveyStartTime,
75
-          surveyEndTime: values.surveyEndTime,
76
-        });
190
+
191
+      // 收集两个表格的数据
192
+      const stationInfoList = stationInfoTableApi.grid.getData();
193
+      const oilPriceList = oilPriceTableApi.grid.getData();
194
+
195
+      const params = taskParams.value.taskList;
196
+
197
+      stationInfoList.forEach((item: any, index: number) => {
198
+        params[index].promotionActivities = item.promotionActivities || '';
199
+        params[index].valueAddedServices = item.valueAddedServices || '';
200
+        params[index].equipmentConfigChanges =
201
+          item.equipmentConfigChanges || '';
202
+        params[index].surveyDate = values.surveyDate || '';
203
+
204
+        params[index].oilPriceRecords = oilPriceList.map(
205
+          (oilPriceItem: any) => {
206
+            return {
207
+              oilType: oilPriceItem.oilType,
208
+              listingPrice: oilPriceItem[`listingPrice_${item.id}_${index}`],
209
+              discountPrice: oilPriceItem[`discountPrice_${item.id}_${index}`],
210
+              salesDifference:
211
+                oilPriceItem[`salesDifference_${item.id}_${index}`],
212
+            };
213
+          },
214
+        );
77 215
       });
78 216
 
79 217
       // 这里可以调用API提交数据
80
-      await handleSalesSurvey(params);
218
+      await handleMarketingSurvey(params);
81 219
 
82 220
       emit('reload');
83 221
       drawerApi.close();
@@ -88,72 +226,18 @@ const [Drawer, drawerApi] = useVbenDrawer({
88 226
     }
89 227
   },
90 228
 });
91
-
92
-// 初始化表格配置
93
-const gridOptions: VxeGridProps = {
94
-  size: 'medium',
95
-  toolbarConfig: {
96
-    custom: false,
97
-    refresh: false,
98
-    zoom: false,
99
-  },
100
-  pagerConfig: {
101
-    enabled: false,
102
-  },
103
-  proxyConfig: {
104
-    ajax: {
105
-      query: async () => {
106
-        // 这里可以调用API获取表格数据
107
-        return {
108
-          items: taskParams.value.taskList, // 初始数据为空
109
-        };
110
-      },
111
-    },
112
-  },
113
-  columns: defautTableColumns,
114
-  editConfig: {
115
-    mode: 'cell',
116
-    trigger: 'click',
117
-  },
118
-};
119
-
120
-// 初始化表格组件
121
-const [BasicTable, basicTableApi] = useVbenVxeGrid({
122
-  gridOptions,
123
-});
124
-
125
-// 确认事件
126
-const confirmEvent = (row: any) => {
127
-  // 处理确认事件
128
-};
129 229
 </script>
130 230
 
131 231
 <template>
132 232
   <Drawer :title="taskParams.taskName">
133 233
     <Form>
134
-      <!-- 销量调查表格插槽 -->
135
-      <template #salesSurveyTable>
136
-        <BasicTable table-title="" class="w-full">
137
-          <template #action="{ row }">
138
-            <ElSpace>
139
-              <ElPopconfirm
140
-                :title="$t('common.confirm-delete')"
141
-                @confirm="confirmEvent(row)"
142
-              >
143
-                <template #reference>
144
-                  <ElButton
145
-                    size="small"
146
-                    type="danger"
147
-                    plain
148
-                    v-access:code="['system:dict:remove']"
149
-                  >
150
-                    删除
151
-                  </ElButton>
152
-                </template>
153
-              </ElPopconfirm>
154
-            </ElSpace>
155
-          </template>
156
-        </BasicTable>
234
+      <!-- 油站基本信息表格插槽 -->
235
+      <template #stationInfoTable>
236
+        <StationInfoTable table-title="" class="w-full" />
237
+      </template>
238
+      <!-- 油品价格和销量差表格插槽 -->
239
+      <template #oilPriceTable>
240
+        <OilPriceTable table-title="" class="w-full" />
157 241
       </template>
158 242
     </Form>
159 243
   </Drawer>

+ 0 - 1
apps/web-ele/src/views/schedule/detail/drawer/emergency/index.vue

@@ -47,7 +47,6 @@ const [Drawer, drawerApi] = useVbenDrawer({
47 47
       taskParams.value.taskName = taskName;
48 48
       taskParams.value.taskList = taskList;
49 49
       // 填充计划表单
50
-      console.log(taskList, 'taskList');
51 50
       planFormApi.setValues(taskList[0]);
52 51
       // 填充报告表单
53 52
       reportFormApi.setValues(taskList[0]);

+ 18 - 68
apps/web-ele/src/views/schedule/detail/drawer/entrance/config-data.tsx

@@ -32,8 +32,8 @@ export const drawerFormSchema: any | FormSchemaGetter = () => [
32 32
     rules: 'required',
33 33
   },
34 34
   {
35
-    fieldName: 'salesSurveyTable',
36
-    label: '销量调查表格',
35
+    fieldName: 'entranceSurveyTable',
36
+    label: '拐入率调查表格',
37 37
     // component: 'div',
38 38
     hideLabel: true,
39 39
     renderComponentContent: () => {
@@ -48,7 +48,7 @@ export const drawerFormSchema: any | FormSchemaGetter = () => [
48 48
 export const defautTableColumns: VxeGridProps['columns'] = [
49 49
   {
50 50
     field: 'competitorName',
51
-    title: '站',
51
+    title: '站',
52 52
     width: 100,
53 53
     fixed: 'left',
54 54
     formatter: ({ row }) => {
@@ -56,19 +56,19 @@ export const defautTableColumns: VxeGridProps['columns'] = [
56 56
     },
57 57
   },
58 58
   {
59
-    field: 'gasolineCar',
59
+    field: 'gasCar',
60 60
     title: '汽油车',
61 61
     width: 180,
62 62
     children: [
63 63
       {
64
-        field: 'gasolineVehicleCount',
65
-        title: '进站次数',
64
+        field: 'gasRoadFlow',
65
+        title: '路面车流',
66 66
         editRender: { name: 'input' },
67 67
         width: 90,
68 68
       },
69 69
       {
70
-        field: 'gasolineVolumeDiff',
71
-        title: '加油升差数',
70
+        field: 'gasInFlow',
71
+        title: '进站车流',
72 72
         editRender: { name: 'input' },
73 73
         width: 90,
74 74
       },
@@ -80,85 +80,35 @@ export const defautTableColumns: VxeGridProps['columns'] = [
80 80
     width: 180,
81 81
     children: [
82 82
       {
83
-        field: 'dieselVehicleCount',
84
-        title: '进站次数',
85
-        width: 90,
83
+        field: 'dieselRoadFlow',
84
+        title: '路面车流',
86 85
         editRender: { name: 'input' },
87
-      },
88
-      {
89
-        field: 'dieselVolumeDiff',
90
-        title: '加油升差数',
91 86
         width: 90,
92
-        editRender: { name: 'input' },
93 87
       },
94
-    ],
95
-  },
96
-  {
97
-    field: 'motorcycle',
98
-    title: '摩托车',
99
-    width: 180,
100
-    children: [
101 88
       {
102
-        field: 'motorcycleCount',
103
-        title: '进站次数',
104
-        width: 90,
89
+        field: 'dieselInFlow',
90
+        title: '进站车流',
105 91
         editRender: { name: 'input' },
106
-      },
107
-      {
108
-        field: 'motorcycleVolumeDiff',
109
-        title: '加油升差数',
110 92
         width: 90,
111
-        editRender: { name: 'input' },
112 93
       },
113 94
     ],
114 95
   },
115 96
   {
116
-    field: 'gasCar',
117
-    title: '车',
97
+    field: 'motorcycle',
98
+    title: '摩托车',
118 99
     width: 180,
119 100
     children: [
120 101
       {
121
-        field: 'gasVehicleCount',
122
-        title: '进站次数',
123
-        width: 90,
102
+        field: 'motorcycleRoadFlow',
103
+        title: '路面车流',
124 104
         editRender: { name: 'input' },
125
-      },
126
-      {
127
-        field: 'gasVolumeDiff',
128
-        title: '加油升差数',
129 105
         width: 90,
130
-        editRender: { name: 'input' },
131 106
       },
132
-    ],
133
-  },
134
-  {
135
-    field: 'periodForecastDiff',
136
-    title: '时段预测销量差(升)',
137
-    width: 150,
138
-    editRender: { name: 'input' },
139
-  },
140
-  {
141
-    field: 'dailyForecastDiff',
142
-    title: '全天预测销量差(升)',
143
-    editRender: { name: 'input' },
144
-    width: 150,
145
-  },
146
-  {
147
-    field: 'surveySales',
148
-    title: '调查销量(升)',
149
-    width: 180,
150
-    children: [
151 107
       {
152
-        field: 'gasolineSurveyVolume',
153
-        title: '汽油',
154
-        width: 90,
108
+        field: 'motorcycleInFlow',
109
+        title: '进站车流',
155 110
         editRender: { name: 'input' },
156
-      },
157
-      {
158
-        field: 'dieselSurveyVolume',
159
-        title: '柴油',
160 111
         width: 90,
161
-        editRender: { name: 'input' },
162 112
       },
163 113
     ],
164 114
   },

+ 4 - 4
apps/web-ele/src/views/schedule/detail/drawer/entrance/index.vue

@@ -10,7 +10,7 @@ import { useVbenDrawer, useVbenForm } from '@vben/common-ui';
10 10
 // @ts-ignore: 忽略
11 11
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
12 12
 // @ts-ignore: 忽略
13
-import { handleSalesSurvey } from '#/api/task';
13
+import { handleTurnInRateSurvey } from '#/api/task';
14 14
 
15 15
 // @ts-ignore: 忽略
16 16
 import { defautTableColumns, drawerFormSchema } from './config-data.tsx';
@@ -77,7 +77,7 @@ const [Drawer, drawerApi] = useVbenDrawer({
77 77
       });
78 78
 
79 79
       // 这里可以调用API提交数据
80
-      await handleSalesSurvey(params);
80
+      await handleTurnInRateSurvey(params);
81 81
 
82 82
       emit('reload');
83 83
       drawerApi.close();
@@ -131,8 +131,8 @@ const confirmEvent = (row: any) => {
131 131
 <template>
132 132
   <Drawer :title="taskParams.taskName">
133 133
     <Form>
134
-      <!-- 销量调查表格插槽 -->
135
-      <template #salesSurveyTable>
134
+      <!-- 拐入率调查表格插槽 -->
135
+      <template #entranceSurveyTable>
136 136
         <BasicTable table-title="" class="w-full">
137 137
           <template #action="{ row }">
138 138
             <ElSpace>

+ 2 - 2
apps/web-ele/src/views/schedule/detail/index.vue

@@ -687,7 +687,7 @@ onMounted(async () => {
687 687
 
688 688
         <!-- 入场率调查组件 -->
689 689
         <EntranceComponent
690
-          :task-detail="taskInfo.taskList[0]"
690
+          :task-list="taskInfo.taskList"
691 691
           v-if="
692 692
             taskInfo.formType === 'form' &&
693 693
             taskInfo.subFormType === 'entrance_rate_survey'
@@ -696,7 +696,7 @@ onMounted(async () => {
696 696
 
697 697
         <!-- 竞价结果组件 -->
698 698
         <CompetitionComponent
699
-          :task-detail="taskInfo.taskList[0]"
699
+          :task-detail="taskInfo.taskList"
700 700
           v-if="
701 701
             taskInfo.formType === 'form' &&
702 702
             taskInfo.subFormType === 'competition_price_survey'

+ 2 - 1
packages/@core/base/shared/src/constants/dict-enum.ts

@@ -8,6 +8,7 @@ export enum DictEnum {
8 8
   OIL_LOCATION_TYPE = 'oil_location_type', // 油站位置类型
9 9
   OIL_MARKET_TYPE = 'oil_market_type', // 油站市场类型
10 10
   OIL_NETWORK_TYPE = 'oil_network_type', // 油站网络类型
11
+  OIL_PRODUCT = 'oil_product', // 油品类型
11 12
   ROAD_DIRECTION = 'road_direction', // 车道方向
12 13
   ROAD_TYPE = 'road_type', // 道路类型
13 14
   SHIFT_SCHEDULING_TYPE = 'shift_scheduling_type', // 排班方式
@@ -26,12 +27,12 @@ export enum DictEnum {
26 27
   SYS_SHOW_HIDE = 'sys_show_hide', // 显示状态
27 28
   SYS_USER_SEX = 'sys_user_sex', // 性别
28 29
   SYS_YES_NO = 'sys_yes_no', // 是否
30
+  TASK_TYPE = 'task_type', // 任务类型
29 31
   TICKET_STATUS = 'ticket_status', // 工单状态
30 32
   VISIBILITY = 'visibility', // 可视度
31 33
   WEATHER_TYPE = 'weather_type', // 天气类型
32 34
   WF_BUSINESS_STATUS = 'wf_business_status', // 业务状态
33 35
   WF_FORM_TYPE = 'wf_form_type', // 表单类型
34 36
   WF_TASK_STATUS = 'wf_task_status', // 任务状态
35
-  TASK_TYPE = 'task_type', // 任务类型
36 37
   WORK_CONTENT = 'work_content', // 上班内容
37 38
 }