张田田 hai 4 meses
pai
achega
3c4349f9f1

+ 2 - 2
public/editor/preview.html

@@ -41,10 +41,10 @@
           const hashParams = location.hash.split('?')[1];
           const queryString = location.search || (hashParams ? `?${hashParams}` : '');
           const request = await fetch(`${location.origin}/manager/fdhb-mobile/psarticle/getPsarticleDetailById${queryString}`);
-          // const result = await request.json();
+          const result = await request.json();
           alert('request status: ' + request.status + ', ok: ' + request.ok);
           alert('request: ' + request);
-          const result = await JSON.parse(request.text());
+          // const result = await JSON.parse(request.text());
           alert('result: ' + result);
           document.title = result.title || `加载完成`;
           document.querySelector('.w-e-text-container').innerHTML = result.content || `暂无内容`;

+ 20 - 30
src/request/api/account.api.ts

@@ -70,36 +70,26 @@ export function getMenusMethod(account: AccountModel) {
     headers: { Authorization: account.token },
     transform(data) {
       // data.push(
-      // {
-      //   path: '/',
-      //   children: [
-      //     {
-      //       path: 'healthy/education',
-      //       name: 'healthyEducation',
-      //       meta: { title: '健康宣教' },
-      //     },
-      //   ],
-      // },
-      // {
-      //   path: '/',
-      //   children: [
-      //     {
-      //       path: 'notify/manage',
-      //       name: 'notifyManage',
-      //       meta: { title: '通知管理' },
-      //     },
-      //   ],
-      // },
-      // {
-      //   path: '/',
-      //   children: [
-      //     {
-      //       path: 'satisfaction/survey',
-      //       name: 'satisfactionSurvey',
-      //       meta: { title: '满意度调查' },
-      //     },
-      //   ],
-      // }
+      //   {
+      //     path: '/',
+      //     children: [
+      //       {
+      //         path: 'notify/manage',
+      //         name: 'notifyManage',
+      //         meta: { title: '通知管理' },
+      //       },
+      //     ],
+      //   },
+      //   {
+      //     path: '/',
+      //     children: [
+      //       {
+      //         path: 'satisfaction/survey',
+      //         name: 'satisfactionSurvey',
+      //         meta: { title: '满意度调查' },
+      //       },
+      //     ],
+      //   }
       // );
       console.log(data, 'push之后的data', transformMenus(data));
       return { ...account, menus: transformMenus(data) };

+ 128 - 71
src/satisfaction/Statistics.vue

@@ -15,10 +15,16 @@ use([CanvasRenderer, BarChart, GridComponent, TooltipComponent, TitleComponent])
 defineOptions({
   name: 'SatisfactionStatisticsPage',
 });
-
+const questionnaireList = ref<any[]>([
+  { label: '问卷1', value: '1' },
+  { label: '问卷2', value: '2' },
+  { label: '问卷3', value: '3' },
+]);
+const questionnaireId = ref<Array<{ label: string; value: string }>>([]);
 type RangeValue = [Dayjs, Dayjs] | null;
 
 const selectedRange = ref<RangeValue>(null);
+
 const statistics = ref<any[]>([]);
 
 const mockStatistics = [
@@ -37,13 +43,7 @@ const mockStatistics = [
 // });
 
 function normalizeResponse(res: any): any[] {
-  const list = Array.isArray(res?.data)
-    ? res.data
-    : Array.isArray(res)
-      ? res
-      : Array.isArray(res?.records)
-        ? res.records
-        : [];
+  const list = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : Array.isArray(res?.records) ? res.records : [];
   return list.map((item: any & Record<string, any>) => ({
     score: Number(item.score ?? item.rating ?? item.result ?? 0),
     count: Number(item.count ?? item.total ?? item.value ?? 0),
@@ -87,58 +87,105 @@ const aggregatedCounts = computed(() => {
 
 const totalSamples = computed(() => Object.values(aggregatedCounts.value).reduce((sum, val) => sum + val, 0));
 
-const chartOption = computed(() => {
+// 为每个选中的问卷生成图表配置
+const chartOptions = computed(() => {
+  const selected = questionnaireId.value;
+  if (!selected || !Array.isArray(selected) || selected.length === 0) {
+    return [];
+  }
+
+  const counts = aggregatedCounts.value;
   const categories = ['1', '2', '3', '4', '5'];
-  const seriesData = categories.map((score) => aggregatedCounts.value[Number(score)] ?? 0);
-  return {
-    title: {
-      text: '就诊体验满意度',
-      left: 'left',
-      top: 0,
-      textStyle: { fontSize: 16, fontWeight: 600 },
-    },
-    tooltip: { trigger: 'axis' },
-    grid: { left: 60, right: 40, top: 60, bottom: 50 },
-    xAxis: {
-      type: 'category',
-      data: categories,
-      name: '分',
-      nameGap: 25,
-      axisTick: { alignWithLabel: true },
-      axisLabel: { fontSize: 12 },
-    },
-    yAxis: {
-      type: 'value',
-      name: '人',
-      minInterval: 1,
-      splitLine: {
-        lineStyle: { type: 'dashed', color: '#eaeaea' },
-      },
-      axisLine: { lineStyle: { color: '#d9d9d9' } },
-    },
-    series: [
-      {
-        type: 'bar',
-        data: seriesData,
-        barWidth: 40,
-        itemStyle: {
-          color: '#69c0ff',
-          borderRadius: [6, 6, 0, 0],
-        },
-        emphasis: {
-          focus: 'series',
-          itemStyle: {
-            color: '#4096ff',
+  
+  return selected.map((questionnaire) => {
+    // labelInValue 返回的数据结构:{label: string, value: string}
+    let qValue: string;
+    let qLabel: string;
+    
+    if (typeof questionnaire === 'object' && questionnaire !== null) {
+      qValue = String(questionnaire.value || '');
+      
+      // 尝试获取 label,确保是字符串类型
+      let tempLabel: any = questionnaire.label;
+      if (tempLabel && typeof tempLabel === 'string') {
+        qLabel = tempLabel;
+      } else {
+        // 如果 label 不存在或不是字符串,从 questionnaireList 中查找
+        const found = questionnaireList.value.find(item => String(item.value) === qValue);
+        qLabel = found?.label || `问卷 ${qValue}`;
+      }
+    } else {
+      qValue = String(questionnaire);
+      // 从 questionnaireList 中查找对应的 label
+      const found = questionnaireList.value.find(item => String(item.value) === qValue);
+      qLabel = found?.label || `问卷 ${qValue}`;
+    }
+    
+    // 最终确保 qLabel 是有效的字符串(防止任何意外情况)
+    qLabel = String(qLabel || `问卷 ${qValue}`);
+    
+    // 这里可以根据不同的问卷ID加载不同的统计数据
+    // 目前使用相同的统计数据作为示例
+    const seriesData = categories.map((score) => counts[Number(score)] ?? 0);
+    
+    return {
+      questionnaireId: qValue,
+      questionnaireLabel: qLabel,
+      option: {
+        title: {
+          text: String(qLabel), // 确保是字符串
+          left: 'center',
+          top: 0,
+          textStyle: { 
+            fontSize: 16, 
+            fontWeight: 600,
+            color: '#333'
           },
         },
-        label: {
-          show: true,
-          position: 'top',
-          formatter: '{c}',
+        tooltip: { trigger: 'axis' },
+        grid: { left: 60, right: 40, top: 50, bottom: 50 },
+        xAxis: {
+          type: 'category',
+          data: categories,
+          name: '分',
+          nameGap: 25,
+          axisTick: { alignWithLabel: true },
+          axisLabel: { fontSize: 12 },
         },
+        yAxis: {
+          type: 'value',
+          name: '人',
+          minInterval: 1,
+          splitLine: {
+            lineStyle: { type: 'dashed', color: '#eaeaea' },
+          },
+          axisLine: { lineStyle: { color: '#d9d9d9' } },
+        },
+        series: [
+          {
+            type: 'bar',
+            data: seriesData,
+            barWidth: 40,
+            itemStyle: {
+              color: '#69c0ff',
+              borderRadius: [6, 6, 0, 0],
+            },
+            emphasis: {
+              focus: 'series',
+              itemStyle: {
+                color: '#4096ff',
+              },
+            },
+            label: {
+              show: true,
+              position: 'top',
+              formatter: '{c}',
+            },
+          },
+        ],
       },
-    ],
-  };
+    };
+  });
 });
 
 onMounted(() => loadStatistics());
@@ -151,27 +198,27 @@ defineExpose({
 <template>
   <div class="statistics-page">
     <section class="filter-card">
-      <div class="filter-item">
+      <div class="filter-item mr-10">
         <span class="label">发送日期:</span>
-        <a-range-picker
-          v-model:value="selectedRange"
-          allow-clear
-          format="YYYY-MM-DD"
-          :placeholder="['开始日期', '结束日期']"
-          @change="handleRangeChange"
-        />
+        <a-range-picker v-model:value="selectedRange" allow-clear format="YYYY-MM-DD" :placeholder="['开始日期', '结束日期']" @change="handleRangeChange" />
+      </div>
+      <div class="filter-item">
+        <span class="label">选择问卷:</span>
+        <a-select v-model:value="questionnaireId" placeholder="请选择问卷名称" style="width: 300px" mode="multiple" :labelInValue="true" >
+          <a-select-option v-for="item in questionnaireList" :key="item.value" :value="item.value" :label="item.label">{{ item.label }}</a-select-option>
+        </a-select>
       </div>
     </section>
 
     <section class="chart-card">
       <main>
         <!-- <a-spin :spinning="loading"> -->
-          <template v-if="totalSamples">
-            <VChart class="chart" :option="chartOption" autoresize />
-            <!-- <v-chart :option="option" style="width: 350px; height: 200px" /> -->
-            <!-- <VChart class="chart" :option="chartOption" autoresize /> -->
-          </template>
-          <a-empty v-else description="暂无数据" />
+        <template v-if="chartOptions.length > 0">
+          <div v-for="(chartConfig, index) in chartOptions" :key="`chart-${String(chartConfig.questionnaireId)}-${index}`" class="chart-wrapper">
+            <VChart class="chart" :option="chartConfig.option" autoresize />
+          </div>
+        </template>
+        <a-empty v-else description="请选择问卷查看统计" />
         <!-- </a-spin> -->
       </main>
     </section>
@@ -194,7 +241,7 @@ defineExpose({
   border-radius: 8px;
   padding: 16px 24px;
   display: flex;
-  justify-content: space-between;
+  // justify-content: space-between;
   align-items: center;
   // border: 1px solid #f0f0f0;
 }
@@ -233,11 +280,21 @@ defineExpose({
   main {
     flex: 1;
     display: flex;
+    flex-direction: column;
+    gap: 24px;
     // align-items: center;
     // justify-content: center;
   }
 }
 
+.chart-wrapper {
+  width: 100%;
+  background: #fff;
+  border-radius: 8px;
+  padding: 16px;
+  border: 1px solid #f0f0f0;
+}
+
 .chart-title {
   font-size: 16px;
   font-weight: 600;
@@ -264,4 +321,4 @@ defineExpose({
   width: 100%;
   height: 420px;
 }
-</style>
+</style>

+ 1 - 0
src/service/NotifyManageRecord.vue

@@ -111,6 +111,7 @@ const gridOptions = reactive<VxeGridProps<SystemItemModel>>({
     { field: 'cpFixedPricingRule.unitPrice', title: '用户姓名', slots: { default: 'unitPriceCell' } },
     { field: 'cpFixedPricingRule.pricingUnit', title: '手机号码', slots: { default: 'pricingUnitCell' } },
     { field: 'conditioningProgramSupplierName', title: '发送时间' },
+    { field: 'conditioningProgramSupplierName', title: '查看状态' },
   
   ],
   data: [],