Răsfoiți Sursa

feat: 碳排放相关适配

sunxiao 2 săptămâni în urmă
părinte
comite
59b52b3c14

+ 0 - 24
package-lock.json

@@ -8,7 +8,6 @@
       "name": "temp-vue-3",
       "version": "0.0.0",
       "dependencies": {
-        "@vuepic/vue-datepicker": "^9.0.2",
         "@vueuse/core": "^10.9.0",
         "autofit.js": "^3.1.3",
         "axios": "^1.6.8",
@@ -1839,29 +1838,6 @@
       "integrity": "sha512-VcZK7MvpjuTPx2w6blwnwZAu5/LgBUtejFOi3pPGQFXQN5Ela03FUtd2Qtg4yWGGissVL0dr6Ro1LfOFh+PCuQ==",
       "dev": true
     },
-    "node_modules/@vuepic/vue-datepicker": {
-      "version": "9.0.2",
-      "resolved": "https://registry.npmmirror.com/@vuepic/vue-datepicker/-/vue-datepicker-9.0.2.tgz",
-      "integrity": "sha512-VDAexzBJSvpErld1cZdGsBc+W/iU+Z+I98YNtEEboSSHUKHRi1s/h8s5D+wciZHLxgQ6P/tj6loNi4W7DgkYSQ==",
-      "dependencies": {
-        "date-fns": "^3.6.0"
-      },
-      "engines": {
-        "node": ">=18.12.0"
-      },
-      "peerDependencies": {
-        "vue": ">=3.2.0"
-      }
-    },
-    "node_modules/@vuepic/vue-datepicker/node_modules/date-fns": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmmirror.com/date-fns/-/date-fns-3.6.0.tgz",
-      "integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/kossnocorp"
-      }
-    },
     "node_modules/@vueuse/core": {
       "version": "10.9.0",
       "resolved": "https://registry.npmmirror.com/@vueuse/core/-/core-10.9.0.tgz",

+ 0 - 1
package.json

@@ -15,7 +15,6 @@
     "deploy:test": "node deploy/index.js --test"
   },
   "dependencies": {
-    "@vuepic/vue-datepicker": "^9.0.2",
     "@vueuse/core": "^10.9.0",
     "autofit.js": "^3.1.3",
     "axios": "^1.6.8",

+ 5 - 2
src/api/carbon.js

@@ -19,8 +19,11 @@ export const carbonApi = {
   /**
    * 详情数据
    */
-  // /front/bigModel/carbonSmart/getCarbonDetailsByMonth/{id}
-  getDetails: data => http.get(`/front/bigModel/carbonSmart/getCarbonDetailsByMonth/${data}`, ),
+  getDetails: data => http.get(`/front/bigModel/carbonSmart/getCarbonDetailsByMonth/${data}` ),
 
+  /**
+   * 列表数据
+   */
+  getTableList: params => http.get(`/front/bigModel/carbonSmart/pageList`, { params }),
 }
 

BIN
src/assets/images/carbon/bg-large-title2.png


+ 4 - 0
src/assets/svgs/menu/carbon-emission-active.svg

@@ -0,0 +1,4 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1.66675 9.99992L4.80391 6.99992L5.83341 2.78304L10.0001 3.99992L14.1667 2.78304L15.1962 6.99992L18.3334 9.99992L15.1962 12.9999L14.1667 17.2168L10.0001 15.9999L5.83341 17.2168L4.80391 12.9999L1.66675 9.99992Z" stroke="#1A2029" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M4.9646 7.09281L8.22664 6.92839L10 4.18564L11.7734 6.92839L15.0354 7.09281L13.5468 10L15.0354 12.9072L11.7734 13.0716L10 15.8144L8.22664 13.0716L4.9646 12.9072L6.45322 10L4.9646 7.09281Z" fill="#1A2029"/>
+</svg>

+ 4 - 0
src/assets/svgs/menu/carbon-emission.svg

@@ -0,0 +1,4 @@
+<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1.66675 10L4.80391 7.00004L5.83341 2.78317L10.0001 4.00004L14.1667 2.78317L15.1962 7.00004L18.3334 10L15.1962 13L14.1667 17.2169L10.0001 16L5.83341 17.2169L4.80391 13L1.66675 10Z" stroke="#1A2029" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
+<path d="M4.9646 7.09299L8.22664 6.92858L10 4.18583L11.7734 6.92858L15.0354 7.09299L13.5468 10.0002L15.0354 12.9074L11.7734 13.0718L10 15.8146L8.22664 13.0718L4.9646 12.9074L6.45322 10.0002L4.9646 7.09299Z" stroke="#1A2029" stroke-width="1.3" stroke-linecap="round" stroke-linejoin="round"/>
+</svg>

+ 5 - 1
src/components/BaseNumberInput/index.vue

@@ -8,6 +8,10 @@ defineProps({
   placeholder: {
     type: String,
     default: '请输入'
+  },
+  status: {
+    type: String,
+    default: ''
   }
 });
 
@@ -29,7 +33,7 @@ const inputThemeOverrides = {
 
 <template>
   <NInputNumber :placeholder="placeholder" :show-button="false" v-model:value="modelValue"
-    :theme-overrides="inputThemeOverrides" class="custom-input-number">
+    :theme-overrides="inputThemeOverrides" class="custom-input-number" :min="-90000000" :max="90000000">
     <template #suffix>
       <div class="unit" v-if="unit">{{ unit }}</div>
     </template>

+ 5 - 5
src/components/Layout/TheMenu.vue

@@ -88,6 +88,11 @@ const menuOptions = [
         icon: renderChildrenIcon({ name: 'menu-cost-microorganism' }),
         key: 'normal-3',
       },
+      {
+        label: '碳排放智能体',
+        icon: renderChildrenIcon({ name: 'menu-carbon-emission' }),
+        key: '/carbon',
+      },
     ]
   },
   {
@@ -95,11 +100,6 @@ const menuOptions = [
     icon: renderIcon({ name: 'menu-work' }),
     key: '/work'
   },
-  {
-    label: () => renderLabel('碳排放'),
-    icon: renderIcon({ name: 'menu-work' }),
-    key: '/carbon'
-  },
   {
     label: () => renderLabel('用户中心'),
     icon: renderIcon({ name: 'menu-user' }),

+ 0 - 1
src/main.ts

@@ -9,7 +9,6 @@ import 'virtual:svg-icons-register'
 import './assets/styles/tailwind.css'
 import './assets/styles/index.scss'
 // import './utils/resize';
-import '@vuepic/vue-datepicker/dist/main.css'
 
 const app = createApp(App)
 

+ 2 - 3
src/views/carbon/components/BaseDatePicker.vue

@@ -1,7 +1,6 @@
 <script setup>
 import { ref, computed } from 'vue';
 import { c, NPopover } from 'naive-ui';
-import VueDatePicker from '@vuepic/vue-datepicker';
 import dayjs from 'dayjs';
 
 const dateValue = ref(null);
@@ -89,10 +88,10 @@ const disabledDates = computed(() => {
       <slot></slot>
     </template>
     <div>
-      <VueDatePicker month-picker inline locale="zh" v-model="dateValue" 
+      <!-- <VueDatePicker month-picker inline locale="zh" v-model="dateValue" 
         ref="datePickerRef" :dark="dark" :allowed-dates="allowedDates">
         <template #action-row></template>
-      </VueDatePicker>
+      </VueDatePicker> -->
     </div>
   </NPopover>
 </template>

+ 8 - 2
src/views/carbon/components/BasePanel.vue

@@ -1,5 +1,4 @@
 <script setup>
-import { ref } from 'vue';
 import { NScrollbar } from 'naive-ui';
 
 defineProps({
@@ -14,6 +13,10 @@ defineProps({
   isNoPadding: {
     type: Boolean,
     default: false
+  },
+  required: {
+    type: Boolean,
+    default: false
   }
 })
 </script>
@@ -21,7 +24,10 @@ defineProps({
 <template>
   <div :class="['panel-item']" :style="{ paddingBottom: isNoPadding ? 0 : isXScroll ? '0' : '14px' }">
     <div class="sub-title_inner">
-      <h4 class="title">{{ title }}</h4>
+      <h4 class="title">
+        <span>{{ title }}</span>
+        <span class="text-[#d03050] pl-[5px]" v-if="required">*</span>
+      </h4>
       <slot name="side" />
     </div>
 

+ 13 - 5
src/views/carbon/components/BaseTable.vue

@@ -57,15 +57,18 @@ const onRemove = (index) => {
 
 <template>
   <div class="table-wrapper">
-
-    <div class="flex items-center justify-center py-[10px] bg-[#fff] text-[#B0B7C0]" v-if="data.length == 0">
+  
+    <div :class="[{ 'empty-box': data.isEmpty }, 'tip-box','flex', 'items-center', 'justify-center', ' py-[10px]', 'bg-[#fff]', 'text-[#B0B7C0]' ]" v-if="data.length == 0">
       <span>未添加</span>
     </div>
 
     <template v-if="data.length > 0">
       <div :class="['table-box', { 'table-avg-column': avgColumn }]" v-for="item, index in data" :key="index">
         <ul class="header">
-          <li :class="['th', { 'text-center': item.columns.length - 1 === index }]" :key="index" v-for="val, index in item.columns">{{ val }}</li>
+          <li :class="['th', { 'text-center': item.columns.length - 1 === index }]" :key="index" v-for="val, index in item.columns">
+            <span>{{ val }}</span>
+            <span class="text-[#d03050] ml-[5px]" v-show="index != item.columns.length - 1">*</span>
+          </li>
         </ul>
         <div class="body">
           <ul class="t-row_tr">
@@ -75,12 +78,12 @@ const onRemove = (index) => {
               </template>
   
               <template v-if="val.type === 'select'">
-                <NSelect v-model:value="val.value" :options="options" :theme-overrides="selectThemeOverrides" />
+                <NSelect v-model:value="val.value" :options="options" :theme-overrides="selectThemeOverrides" :status="val.isEmpty ? 'error' : ''"/>
               </template>
   
               <template v-if="val.type === 'input'">
                 <NInputNumber v-model:value="val.value" :show-button="false" class="w-full"
-                  :theme-overrides="inputThemeOverrides">
+                  :theme-overrides="inputThemeOverrides" :status="val.isEmpty ? 'error' : ''">
                   <template #suffix>
                     <span>{{ val.unit }}</span>
                   </template>
@@ -159,4 +162,9 @@ const onRemove = (index) => {
     }
   }
 }
+
+.empty-box {
+  border-radius: 8px;
+  border: 1px solid #d03050;
+}
 </style>

+ 138 - 55
src/views/carbon/components/TheDrawerForm.vue

@@ -6,13 +6,13 @@ import { BaseCard, BaseStep, BaseTable, BasePanel, BaseDatePicker } from './inde
 import { useTable } from '@/composables/useTable';
 import { inputConfig } from './config';
 import { inputHasBorderThemeOverrides } from '../tools/resetTheme';
-import VueDatePicker from '@vuepic/vue-datepicker';
-
 
 import { carbonApi } from '@/api/carbon'
 import dayjs from 'dayjs';
 
-const BASE_RULES = { required: true, trigger: ['blur'], type: 'number' };
+const emit = defineEmits(['on-submit']);
+
+const BASE_RULES = { required: true, type: 'number' };
 
 const message = useMessage();
 const { addTable, removeTable, tableData } = useTable();
@@ -21,14 +21,12 @@ const inpConfig = ref(inputConfig);
 
 const spliceInpData = ref([]);
 
-const datePickerRef = ref(null);
 const disabledMonth = ref(null);
 
 const isVisibleDrawer = defineModel();
 const formValue = ref({});
 const selectCodeSet = ref({});
 const selectValue = ref({});
-const checkedTymcValue = ref([]);
 
 const formRef = ref(null);
 const switchCo2State = ref(0);
@@ -36,11 +34,41 @@ const tabCo2Data = ['泵站和沉砂池逸散的CH₄量(实测)', '泵站和沉
 
 const rules = {
   provinceId: [
-    { required: true, trigger: 'blur', type: 'number' }
+    { required: true, type: 'number' }
   ],
-  addYearMonth: [
-    { required: true, trigger: 'blur', type: 'number' }
-  ]
+  wsSjclCh4Clsl: [
+    { required: true, type: 'number' }
+  ],
+  wsSjclCh4JsCod: [{ required: true, type: 'number' }],
+  wsSjclCh4CsCod: [{ required: true, type: 'number' }],
+  wsSjclCh4Tsb: [{ required: true, type: 'number' }],
+  wsSjclCh4Csc: [{ required: true, type: 'number' }],
+
+  wsTdN2oClsl: [{ required: true, type: 'number' }],
+  wsTdN2oJsTn: [{ required: true, type: 'number' }],
+  wsTdN2oCsTn: [{ required: true, type: 'number' }],
+
+  nyyjDlxhZhdl: [{ required: true, type: 'number' }],
+  nyyjDlxhJsbf: [{validator: (_, val) => (( formValue.value.nyyjDlxhZhdl && !val ) ? new Error() : true)}],
+  nyyjDlxhGfjf: [{validator: (_, val) => (( formValue.value.nyyjDlxhZhdl && !val ) ? new Error() : true)}],
+  nyyjDlxhTsjf: [{validator: (_, val) => (( formValue.value.nyyjDlxhZhdl && !val ) ? new Error() : true)}],
+  nyyjDlxhXdj: [{validator: (_, val) => (( formValue.value.nyyjDlxhZhdl && !val ) ? new Error() : true)}],
+  nyyjDlxhSdcl: [{validator: (_, val) => (( formValue.value.nyyjDlxhZhdl && !val ) ? new Error() : true)}],
+  nyyjDlxhWncz: [{validator: (_, val) => (( formValue.value.nyyjDlxhZhdl && !val ) ? new Error() : true)}],
+  nyyjDlxhShq: [{validator: (_, val) => (( formValue.value.nyyjDlxhZhdl && !val ) ? new Error() : true)}],
+  nyyjDlxhQt: [{validator: (_, val) => (( formValue.value.nyyjDlxhZhdl && !val ) ? new Error() : true)}],
+
+  wnclYyzqZqcl: [{validator: (_, val) => (formValue.value.wnclYyzqChZlfs && !val ? new Error() : true)}],
+  wnclYyzqChZlfs: [{validator: (_, val) => (formValue.value.wnclYyzqZqcl && !val ? new Error() : true)}],
+
+  wnclDdclZycll: [{ required: true, type: 'number' }],
+  wnclDdclClqnd: [{ required: true, type: 'number' }],
+  wnclDdclClhnd: [{ required: true, type: 'number' }],
+
+
+  wnclWnrjByhXhl: [{validator: (_, val) => (formValue.value.wnclWnrjByhHtbl && !val ? new Error() : true)}],
+  wnclWnrjByhHtbl: [{validator: (_, val) => (formValue.value.wnclWnrjByhXhl && !val ? new Error() : true)}],
+  
 }
 
 const switchTabs = (index) => {
@@ -63,7 +91,7 @@ const handleAddTableRow = (key) => {
 
   if (key === 'sewageCo2First') {
 
-    const ids = [135]; // 复合碳源
+    const ids = [135];
 
     if (!selectValue.value.tymc) {
       return message.warning("请先选择碳源名称");
@@ -145,7 +173,6 @@ const handleAddTableRow = (key) => {
 
   }
 
-
   if (key === 'carbonFirst') {
 
     if (!selectValue.value.gyittOne) {
@@ -170,7 +197,6 @@ const handleAddTableRow = (key) => {
 
   }
 
-
   if (key === 'carbonThird') {
 
     if (!selectValue.value.gyittTwo) {
@@ -197,7 +223,6 @@ const handleAddTableRow = (key) => {
 
   }
 
-
   if (key === 'carbonFourth') {
 
     if (!selectValue.value.gyittThree) {
@@ -210,7 +235,7 @@ const handleAddTableRow = (key) => {
     });
 
     option = {
-      columns: ['燃料名称', '污泥焚烧或热解电力利用量', '污泥焚烧或热解热能利用量', '沼气提纯并网的天然气量', '操作'],
+      columns: ['燃料名称', '污泥焚烧或热解电力利用量', '污泥焚烧或热解热能利用量', '沼气提纯并网的天然气量', '操作'],
       data: [
         { type: 'name', value: codeSet.dictLabel },
         { type: 'input', value: null, unit: 'kW·h/月' },
@@ -223,7 +248,9 @@ const handleAddTableRow = (key) => {
     }
   }
 
-  addTable(key, option);
+  tableData.value[key].isEmpty = false;
+
+  addTable(key, option); 
 }
 
 // 格式化时间
@@ -267,16 +294,83 @@ const formatData = () => {
   };
 }
 
+const validateTableData = () => {
+  let result = true;
+  const whiteList = ['sewageCo2First', 'energySecond', 'carbonFirst', 'carbonThird', 'carbonFourth'];
+  const otherWhiteList = ['energyFirst', 'energySecond',];
+  const onlyWhiteList = ['mudFirst', 'mudSecond', 'carbonSecond',];
+  const tableInnerInpWhiteList = ['sewageCo2First', 'energyFirst', 'energySecond', 'carbonFirst', 'carbonThird', 'carbonFourth']
+
+  Object.keys(tableData.value).forEach(key => {
+    const item = tableData.value[key];
+    console.log( "上", item );
+    if ( !item.length && whiteList.includes(key)) {
+      console.log(item);
+      item.isEmpty = true;
+      result = false;
+      return
+    }
+
+    if ( item.length && tableInnerInpWhiteList.includes(key) ) {
+
+      item.forEach(item => {
+        item.data.forEach((child) => {
+          if ( (child.type === 'input' || child.type === 'select') && !child.value && child.value !== 0 ) {
+            child.isEmpty = true;
+            result = false
+          } else {
+            child.isEmpty = false;
+          }
+        })
+      })
+    }
+
+    if ( item.length && otherWhiteList.includes(key) ) {
+      item.forEach(item => {
+        item.data.forEach(child => {
+          if ( child.type === 'input' && !child.value && child.value !== 0 ) {
+            child.isEmpty = true;
+            result = false
+          } else {
+            child.isEmpty = false;
+          }
+        })
+      })
+    }
+
+    if ( onlyWhiteList.includes(key) ) {
+      const { data } = tableData.value[key][0];
+      const isExists = data.filter(({ value }) => value || value === 0).length;
+      if ( isExists && isExists < data.length) {
+        data.forEach(child => {
+          if ( (child.type === 'input' || child.type === 'select') && !child.value && child.value !== 0 ) {
+            child.isEmpty = true;
+            result = false
+          } else {
+            child.isEmpty = false;
+          }
+        })
+      } else {
+        data.forEach(child => child.isEmpty = false);
+      }
+    }
+  });
+
+  return result;
+}
+
 const onSubmit = ( e ) => {
   e.preventDefault();
+  const isVerifying  = !validateTableData();
   formRef.value?.validate( async (errors) => {
-    const params = formatData();
-
-    const data = await carbonApi.postCarbonSmart(params);
-    console.log( data );
-    message.success("提交成功");
     if (!errors) {
-      console.log("验证成功");
+      if ( isVerifying ) {
+        return message.error("提交失败, 请检查");
+      }
+      const params = formatData();
+      await carbonApi.postCarbonSmart(params);
+      message.error("提供成功");
+      emit(['on-submit']);
     } else {
       message.error("提交失败, 请检查");
     }
@@ -299,6 +393,7 @@ const getAllCodeSet = async () => {
     yjmcOptions,
     gyittOptions,
     fireOptions: [
+      { label: '选择', value: "" },
       { label: '半连续-加煤机', value: 0 },
       { label: '半连续-流化床', value: 1 },
       { label: '间歇性-加煤机', value: 2 },
@@ -306,11 +401,13 @@ const getAllCodeSet = async () => {
       { label: '连续燃烧', value: 4 }
     ],
     reactOptions: [
+    { label: '选择', value: "" },
       { label: '竖井类型', value: 0 },
       { label: '流化床式', value: 1 },
       { label: '回转窑式', value: 2 }
     ],
     scgmOptions: [
+    { label: '选择', value: "" },
       { label: '小型', value: 0 },
       { label: '中型', value: 1 },
       { label: '大型', value: 2 }
@@ -323,24 +420,10 @@ onMounted(async () => {
   getAllCodeSet();
 })
 
-const closeDatePicker = (test) => {
-  formValue.value.time = test
-  console.log(test);
-  console.log(dayjs(test).format('YYYY-MM'));
-  // console.log( datePickerRef.value, datePickerRef.value.closeMenu );
-  datePickerRef.value.closeMenu();
-}
-
 const dateDisabled = (ts) => {
   return disabledMonth.value.includes(dayjs(ts).format('YYYY-MM'));
 }
 
-const onAfterdEnter = async () => {
-  return
-  const { data: month } = await carbonApi.getAllMonth();
-  disabledMonth.value = month;
-  // disabledMonth.value = month.map(m => dayjs(m, 'YYYY-MM'));
-}
 onMounted(async () => {
   const { data: month } = await carbonApi.getAllMonth();
   disabledMonth.value = month;
@@ -350,7 +433,7 @@ onMounted(async () => {
 
 <template>
   <NDrawer class="drawer-wrapper" placement="right" :width="1220" :close-on-esc="false" v-model:show="isVisibleDrawer"
-    :on-after-enter="onAfterdEnter" :auto-focus="false">
+    :auto-focus="false" :mask-closable="false" :block-scroll="false">
     <n-drawer-content closable title="新建核算" header-class="drawer-header" body-content-class="drawer-body"
       footer-class="drawer-footer">
 
@@ -361,13 +444,13 @@ onMounted(async () => {
             <BaseStep></BaseStep>
           </BaseCard>
 
-          <NForm class="space-y-[12px] from-wrapper" ref="formRef" :model="formValue" :show-feedback="false">
+          <NForm class="space-y-[12px] from-wrapper" ref="formRef" :model="formValue" :show-feedback="false" :rules="rules">
             <BaseCard title="基础信息" sub-title="碳排放管理基础信息填写">
               <div class="flex space-x-[24px]">
 
-                <NFormItem label="省/直辖市" path="provinceId" label-placement="left" class="w-[343px]" :rule="BASE_RULES">
+                <NFormItem label="省/直辖市" path="provinceId" label-placement="left" class="w-[343px]">
                   <NSelect v-model:value="formValue.provinceId" :options="selectCodeSet.areaOptions"
-                    value-field="dictCode" label-field="dictLabel" />
+                    value-field="dictCode" label-field="dictLabel" :rule="BASE_RULES"/>
                 </NFormItem>
 
                 <NFormItem label="核算时间" path="addYearMonth" label-placement="left" class="w-[343px]" :rule="BASE_RULES">
@@ -380,14 +463,14 @@ onMounted(async () => {
             </BaseCard>
 
             <BaseCard title="污水处理" sub-title="生化碳排">
-              <BasePanel isXScroll title="化石源碳矿化产生的碳排放量">
+              <BasePanel isXScroll required title="化石源碳矿化产生的碳排放量">
                 <NFormItem label-placement="top" :label="item.label" :path="item.key"
                   v-for="item, index in inpConfig.sewage.oneBlock" :key="index" :rule="BASE_RULES">
                   <BaseNumberInput :unit="item.unit" v-model:value="formValue[item.key]"></BaseNumberInput>
                 </NFormItem>
               </BasePanel>
 
-              <BasePanel title="外加碳源矿化产生的化石源CO₂碳排放量">
+              <BasePanel required title="外加碳源矿化产生的化石源CO₂碳排放量">
                 <template #side>
                   <div class="flex items-center space-x-[14px]">
                     <NSelect v-model:value="selectValue.tymc" :options="selectCodeSet.tymcOptions" class="w-[200px]"
@@ -403,7 +486,7 @@ onMounted(async () => {
                   @on-remove="(name, index) => removeTable(name, index)"></BaseTable>
               </BasePanel>
 
-              <BasePanel isXScroll title="污水收集提升和处理阶段排放的CH₄的CO₂当量">
+              <BasePanel isXScroll required title="污水收集提升和处理阶段排放的CH₄的CO₂当量">
                 <template #side>
                   <ul class="tabs space-x-[12px]">
                     <li v-for="item, index in tabCo2Data"
@@ -412,28 +495,28 @@ onMounted(async () => {
                   </ul>
                 </template>
                 <NFormItem label-placement="top" :label="item.label" :path="item.key"
-                  v-for="item, index in inpConfig.sewage.twoBlock" :key="index" :rule="BASE_RULES">
+                  v-for="item, index in inpConfig.sewage.twoBlock" :key="index">
                   <BaseNumberInput :unit="item.unit" v-model:value="formValue[item.key]"></BaseNumberInput>
                 </NFormItem>
               </BasePanel>
 
-              <BasePanel isXScroll title="污水生物处理脱氮过程排放的N₂O的CO₂当量">
+              <BasePanel isXScroll required title="污水生物处理脱氮过程排放的N₂O的CO₂当量">
                 <NFormItem label-placement="top" :path="item.key" :label="item.label"
-                  v-for="item, index in inpConfig.sewage.threeBlock" :key="index" :rule="BASE_RULES">
+                  v-for="item, index in inpConfig.sewage.threeBlock" :key="index">
                   <BaseNumberInput :unit="item.unit" v-model:value="formValue[item.key]"></BaseNumberInput>
                 </NFormItem>
               </BasePanel>
             </BaseCard>
 
             <BaseCard title="能源、药剂碳排" sub-title="生化反应碳排">
-              <BasePanel isXScroll title="污水厂电力消耗产生的碳排放量">
+              <BasePanel isXScroll required title="污水厂电力消耗产生的碳排放量">
                 <NFormItem label-placement="top" :path="item.key" :label="item.label"
-                  v-for="item, index in inpConfig.energy.oneBlock" :key="index" :rule="BASE_RULES">
+                  v-for="item, index in inpConfig.energy.oneBlock" :key="index">
                   <BaseNumberInput :unit="item.unit" v-model:value="formValue[item.key]"></BaseNumberInput>
                 </NFormItem>
               </BasePanel>
 
-              <BasePanel isXScroll title="净购入热力消耗产生的碳排放量">
+              <BasePanel isXScroll required title="净购入热力消耗产生的碳排放量">
                 <NFormItem label-placement="top" :path="item.key" :label="item.label"
                   v-for="item, index in inpConfig.energy.twoBlock" :key="index" :rule="BASE_RULES">
                   <BaseNumberInput :unit="item.unit" v-model:value="formValue[item.key]"></BaseNumberInput>
@@ -456,7 +539,7 @@ onMounted(async () => {
                 </BaseTable>
               </BasePanel>
 
-              <BasePanel title="污水处理阶段药剂消耗产生的碳排放量">
+              <BasePanel required title="污水处理阶段药剂消耗产生的碳排放量">
                 <template #side>
                   <div class="flex items-center space-x-[14px]">
                     <NSelect v-model:value="selectValue.yjmc" :options="selectCodeSet.yjmcOptions" class="w-[200px]"
@@ -476,14 +559,14 @@ onMounted(async () => {
             <BaseCard title="污泥处理" sub-title="生化反应碳排">
               <BasePanel isXScroll title="污泥厌氧消化沼气收集管路无意泄露的CH₄或沼气火炬燃烧不充分导致的碳排放">
                 <NFormItem label-placement="top" :path="item.key" :label="item.label"
-                  v-for="item, index in inpConfig.sludge.oneBlock" :key="index" :rule="BASE_RULES">
+                  v-for="item, index in inpConfig.sludge.oneBlock" :key="index" required>
                   <BaseNumberInput :unit="item.unit" v-model:value="formValue[item.key]"></BaseNumberInput>
                 </NFormItem>
               </BasePanel>
 
               <BasePanel isXScroll title="单独处理污泥厌氧消化过程产生的碳排放量">
                 <NFormItem label-placement="top" :path="item.key" :label="item.label"
-                  v-for="item, index in inpConfig.sludge.twoBlock" :key="index" :rule="BASE_RULES">
+                  v-for="item, index in inpConfig.sludge.twoBlock" :key="index">
                   <BaseNumberInput :unit="item.unit" v-model:value="formValue[item.key]"></BaseNumberInput>
                 </NFormItem>
               </BasePanel>
@@ -509,7 +592,7 @@ onMounted(async () => {
 
               <BasePanel isXScroll title="污泥热解碳化或气化过程化石源CO₂碳排放量">
                 <NFormItem label-placement="top" :path="item.key" :label="item.label"
-                  v-for="item, index in inpConfig.sludge.fiveBlock" :key="index" :rule="BASE_RULES">
+                  v-for="item, index in inpConfig.sludge.fiveBlock" :key="index" required>
                   <BaseNumberInput :unit="item.unit" v-model:value="formValue[item.key]"></BaseNumberInput>
                 </NFormItem>
               </BasePanel>
@@ -540,7 +623,7 @@ onMounted(async () => {
 
               <BasePanel isXScroll title="光伏-替碳量">
                 <NFormItem label-placement="top" :path="item.key" :label="item.label"
-                  v-for="item, index in inpConfig.carbon.oneBlock" :key="index" :rule="BASE_RULES">
+                  v-for="item, index in inpConfig.carbon.oneBlock" :key="index" required>
                   <BaseNumberInput :unit="item.unit" v-model:value="formValue[item.key]"></BaseNumberInput>
                 </NFormItem>
               </BasePanel>
@@ -585,7 +668,7 @@ onMounted(async () => {
 
               <BasePanel isXScroll title="污泥经过厌氧、好氧或碳化处理后,产生的替碳量">
                 <NFormItem label-placement="top" :path="item.key" :label="item.label"
-                  v-for="item, index in inpConfig.carbon.twoBlock" :key="index" :rule="BASE_RULES">
+                  v-for="item, index in inpConfig.carbon.twoBlock" :key="index" required>
                   <BaseNumberInput :unit="item.unit" v-model:value="formValue[item.key]"></BaseNumberInput>
                 </NFormItem>
               </BasePanel>
@@ -596,7 +679,7 @@ onMounted(async () => {
       <template #footer>
         <div class="w-full space-x-[8px] flex justify-center">
           <button class="btn btn_primary" @click="onSubmit">提交并核算</button>
-          <button class="btn btn_default">暂存</button>
+          <!-- <button class="btn btn_default">暂存</button> -->
         </div>
       </template>
     </n-drawer-content>

+ 13 - 13
src/views/carbon/components/TheDrawerList.vue

@@ -1,9 +1,14 @@
 <script setup>
-import { ref, onMounted, computed } from 'vue';
+import { ref, computed } from 'vue';
 import { NDrawer, NDrawerContent, NScrollbar } from 'naive-ui';
 import { BaseCard, BasePanel } from './index';
 
-const props = defineProps(['data']);
+const props = defineProps({
+  data: {
+    type: Array,
+    default: () => []
+  },
+});
 
 let cardNodelist = [];
 
@@ -63,6 +68,7 @@ const list = computed(() => {
 
 const handleTabItem = (index) => {
   const top = cardNodelist[index]?.offsetTop;
+  console.log( scrollRef.value );
   scrollRef.value.scrollTo({
     top,
     behavior: 'smooth'
@@ -71,19 +77,13 @@ const handleTabItem = (index) => {
 }
 
 const onAfterdEnter = () => {
-  console.log('onAfterdEnter');
-}
-
-onMounted(() => {
   cardNodelist = document.querySelectorAll(".card-wrapper");
-})
-
+}
 </script>
 
 <template>
-  <NDrawer :width="1220" placement="right" v-model:show="isVisibleDrawer" class="drawer-wrapper" :on-after-enter="onAfterdEnter">
-    <n-drawer-content closable title="历史核算" header-class="drawer-header" body-content-class="drawer-body" footer-class="drawer-footer">
-
+  <NDrawer :width="1220" placement="right" v-model:show="isVisibleDrawer" class="drawer-wrapper" :on-after-enter="onAfterdEnter" :close-on-esc="false" :mask-closable="false">
+    <n-drawer-content closable title="历史核算" header-class="drawer-header" body-content-class="drawer-body" footer-class="drawer-footer" :block-scroll="false">
       <div class="main-container">
         <div class="header">
           <ul class="tab-list space-x-[4px]">
@@ -94,10 +94,10 @@ onMounted(() => {
               @click="handleTabItem(index)"
             >{{ item }}</li>
           </ul>
-          <button class="btn">下载核算结果</button>
+          <!-- <button class="btn">下载核算结果</button> -->
         </div>
         <div class="content">
-          <NScrollbar style="height: 100%" :on-scroll="onScroll" ref="scrollRef">
+          <NScrollbar style="height: 100%" ref="scrollRef">
             <div class="main space-y-[12px]">
               <BaseCard title="基础信息" sub-title="碳排放管理基础信息填写">
                 <ul class="list-info">

+ 0 - 158
src/views/carbon/components/TheModal.vue

@@ -1,158 +0,0 @@
-<script setup>
-import { ref, h } from 'vue';
-import { NModal, NForm, NGrid, NFormItemGi, NInput, NDatePicker, NPagination, NDataTable } from 'naive-ui';
-
-const showModal = ref(true);
-const inputThemeOverrides = {
-  border: '1px solid #d7d9e5',
-  borderRadius: '8px',
-  borderHover: '1px solid #2454FF',
-  borderFocus: '1px solid #2454FF',
-  boxShadowFocus: '0 0 0 2px rgba(36, 84, 255, 0.2)',
-  text: '#333'
-}
-
-const selectThmem = {
-  peers: {
-    Input: {
-      border: '1px solid #d7d9e5',
-      borderRadius: '8px',
-      borderHover: '1px solid #2454FF',
-      borderFocus: '1px solid #2454FF',
-      boxShadowFocus: '0 0 0 2px rgba(36, 84, 255, 0.2)',
-      text: '#333'
-    }
-  }
-}
-
-const range = ref(null);
-
-const columns = [
-  { title: '核算日期', key: 'name1', align: 'center' },
-  { title: '总碳排放量', key: 'name2', align: 'center' },
-  { title: '污水处理碳排放量', key: 'name3', align: 'center' },
-  { title: '能源、药剂碳排量', key: 'name4', align: 'center' },
-  { title: '污泥处理碳排量', key: 'name5', align: 'center' },
-  { title: '替碳、碳汇替碳量', key: 'name6', align: 'center' },
-  { title: '录入人员', key: 'name7', align: 'center' },
-  { title: '填报日期', key: 'name8', align: 'center' },
-  { title: '操作', key: 'name9', align: 'center', render: (row) => {
-    return h('span', {
-      class: 'text-[#2454FF] cursor-pointer',
-      onClick: () => {
-        console.log(row);
-      }
-    }, '下载');
-  }}
-]
-
-const page = ref(1);
-
-const data = ref([
-  { name1: 1, name2: 1 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 },
-  { name2: 2 }
-]);
-
-</script>
-
-<template>
-  <NModal
-    v-model:show="showModal"
-    preset="card"
-    class="custom-card"
-    title="历史核算"
-    header-class="card-preset_header"
-    content-class="card-prset_content"
-    :style="{ width: '1440px' }"
-    :bordered="false"
-  >
-    <div class="main-container space-y-[12px]">
-      <div class="search-inner">
-        <NForm :show-feedback="false">
-          <NGrid :cols="14" :x-gap="24">
-            <NFormItemGi :span="4" label="录入人员:" path="adress" label-placement="top">
-              <NInput :theme-overrides="inputThemeOverrides"/>
-            </NFormItemGi>
-            <NFormItemGi :span="4" label="填报日期:" path="adress" label-placement="top">
-              <n-date-picker v-model:value="range" type="daterange" clearable :theme-overrides="selectThmem"/>
-            </NFormItemGi>
-            <NFormItemGi :span="4" label="核算日期:" path="adress" label-placement="top">
-              <n-date-picker v-model:value="range" type="daterange" clearable :theme-overrides="selectThmem"/>
-            </NFormItemGi>
-            <NFormItemGi :span="2" label="" path="adress" label-placement="top">
-              <div class="space-x-[10px]">
-                <button class="btn">查询</button>
-                <button class="btn default">重置</button>
-              </div>
-            </NFormItemGi>
-          </NGrid>
-        </NForm>
-      </div>
-
-      <div class="table-inner">
-        <NDataTable :columns="columns" :data="data" :bordered="false" :single-line="false" :min-height="400" :max-height="400"></NDataTable>
-        <div class="pt-[20px] flex justify-center">
-          <NPagination v-model:page="page" :page-count="100"></NPagination>
-        </div>
-      </div>
-    </div>
-  </NModal>
-</template>
-
-<style lang="scss" scoped>
-.main-container {
-  padding: 20px;
-  border-radius: 20px;
-  border: 1px solid #FFFFFF;
-  background: linear-gradient(180deg, rgba(238, 253, 255, 0.5) 0%, rgba(231, 243, 252, 0.5) 100%);
-
-  .search-inner, .table-inner {
-    padding: 20px 20px;
-    border-radius: 10px;
-    background: #fff;
-
-    .btn {
-      border-radius: 4px;
-      padding: 5px 16px;
-      background: #2454FF;
-      font-size: 14px;
-      line-height: 22px;
-      text-align: left;
-      color: #fff;
-    }
-
-    .default {
-      border: 1px solid #d7d9e5;
-      color: #2454FF;
-      background: #fff;
-    }
-  }
-
-  .table-inner {
-
-  }
-}
-</style>
-
-<style lang="scss">
-.card-preset_header {
-  padding: 16px !important;
-}
-.card-prset_content {
-  padding: 20px !important;
-  background: linear-gradient(180deg, #F3F7FC 0%, #E4EAF7 100%);
-}
-</style>

+ 193 - 0
src/views/carbon/components/TheModalTable.vue

@@ -0,0 +1,193 @@
+<script setup>
+import { ref, h } from 'vue';
+import { NModal, NForm, NGrid, NFormItemGi, NInput, NDatePicker, NPagination, NDataTable } from 'naive-ui';
+import dayjs from 'dayjs';
+import { carbonApi } from '@/api/carbon';
+
+const modelValue = defineModel();
+
+const timeArr = ref(null);
+const hsTimeArr = ref(null);
+
+const formData = ref({
+  pageNum: 1,
+  pageSize: 10,
+  createBy: '',
+}) 
+
+const inputThemeOverrides = {
+  border: '1px solid #d7d9e5',
+  borderRadius: '8px',
+  borderHover: '1px solid #2454FF',
+  borderFocus: '1px solid #2454FF',
+  boxShadowFocus: '0 0 0 2px rgba(36, 84, 255, 0.2)',
+  text: '#333'
+}
+
+const selectThmem = {
+  peers: {
+    Input: {
+      border: '1px solid #d7d9e5',
+      borderRadius: '8px',
+      borderHover: '1px solid #2454FF',
+      borderFocus: '1px solid #2454FF',
+      boxShadowFocus: '0 0 0 2px rgba(36, 84, 255, 0.2)',
+      text: '#333'
+    }
+  }
+}
+
+const total = ref(0);
+const tableData = ref([]);
+const columns = [
+  { title: '核算日期', key: 'addYearMonth', align: 'center' },
+  { title: '总碳排放量', key: 'ztTotalCo2', align: 'center' },
+  { title: '污水处理碳排放量', key: 'wsclTotalCo2', align: 'center', width: 160 },
+  { title: '能源、药剂碳排量', key: 'nyyjTotalCo2', align: 'center', width: 160 },
+  { title: '污泥处理碳排量', key: 'wnclTotalCo2', align: 'center', width: 160 },
+  { title: '替碳、碳汇替碳量', key: 'ttthTotalCo2', align: 'center', width: 160 },
+  { title: '录入人员', key: 'createBy', align: 'center' },
+  { title: '填报日期', key: 'remark', align: 'center' },
+  // { title: '操作', key: 'name9', align: 'center', render: (row) => {
+  //   return h('span', {
+  //     class: 'text-[#2454FF] cursor-pointer',
+  //     onClick: () => {
+  //       console.log(row);
+  //     }
+  //   }, '下载');
+  // }}
+]
+
+const formatTime = (timestamp) => {
+  let tempTimeList = [];
+
+  if ( timestamp && timestamp.length ) {
+    tempTimeList = timestamp.map(t => dayjs(t).format('YYYY-MM-DD'));
+  }
+
+  return tempTimeList;
+}
+
+const handleQueryList = async() => {
+  const [ timeBegin, timeEnd ] = formatTime(timeArr.value);
+  const [ hsTimeBegin, hsTimeEnd ] = formatTime(timeArr.value);
+
+  const { rows, total: allTotal } = await carbonApi.getTableList({ ...formData.value, timeBegin, timeEnd, hsTimeBegin, hsTimeEnd })
+
+  tableData.value = rows;
+  total.value = allTotal;
+}
+
+const handleResetList = async () => {
+  timeArr.value = null;
+  hsTimeArr.value = null;
+  formData.value = {
+    pageNum: 1,
+    pageSize: 10,
+    createBy: '',
+  };
+  handleQueryList();
+}
+
+const onAfterdEnter = () => {
+  handleQueryList();
+}
+
+const onAfterLeave = () => {
+  handleResetList();
+}
+</script>
+
+<template>
+  <NModal
+    v-model:show="modelValue"
+    preset="card"
+    class="custom-card"
+    title="历史核算"
+    header-class="card-preset_header"
+    content-class="card-prset_content"
+    :style="{ width: '1240px' }"
+    :bordered="false"
+    :close-on-esc="false"
+    :mask-closable="false"
+    :block-scroll="false"
+    :on-after-enter="onAfterdEnter"
+    :on-after-leave="onAfterLeave"
+  >
+    <div class="main-container space-y-[12px]">
+      <div class="search-inner">
+        <NForm :show-feedback="false">
+          <NGrid :cols="14" :x-gap="24">
+            <NFormItemGi :span="4" label="录入人员:" path="adress" label-placement="top">
+              <NInput :theme-overrides="inputThemeOverrides" v-model:value="formData.createBy" />
+            </NFormItemGi>
+            <NFormItemGi :span="4" label="填报日期:" path="adress" label-placement="top">
+              <n-date-picker v-model:value="timeArr" type="daterange" clearable :theme-overrides="selectThmem"/>
+            </NFormItemGi>
+            <NFormItemGi :span="4" label="核算日期:" path="adress" label-placement="top">
+              <n-date-picker v-model:value="hsTimeArr" type="daterange" clearable :theme-overrides="selectThmem"/>
+            </NFormItemGi>
+            <NFormItemGi :span="2" label="" path="adress" label-placement="top">
+              <div class="space-x-[10px]">
+                <button class="btn" @click="handleQueryList">查询</button>
+                <button class="btn default" @click="handleResetList">重置</button>
+              </div>
+            </NFormItemGi>
+          </NGrid>
+        </NForm>
+      </div>
+
+      <div class="table-inner">
+        <NDataTable :columns="columns" :data="tableData" :bordered="false" :single-line="false" :min-height="400" :max-height="400"></NDataTable>
+        <div class="pt-[20px] flex justify-center">
+          <NPagination v-model:page="formData.pageNum" :item-count="total"></NPagination>
+        </div>
+      </div>
+    </div>
+  </NModal>
+</template>
+
+<style lang="scss" scoped>
+.main-container {
+  padding: 20px;
+  border-radius: 20px;
+  border: 1px solid #FFFFFF;
+  background: linear-gradient(180deg, rgba(238, 253, 255, 0.5) 0%, rgba(231, 243, 252, 0.5) 100%);
+
+  .search-inner, .table-inner {
+    padding: 20px 20px;
+    border-radius: 10px;
+    background: #fff;
+
+    .btn {
+      border-radius: 4px;
+      padding: 5px 16px;
+      background: #2454FF;
+      font-size: 14px;
+      line-height: 22px;
+      text-align: left;
+      color: #fff;
+    }
+
+    .default {
+      border: 1px solid #d7d9e5;
+      color: #2454FF;
+      background: #fff;
+    }
+  }
+
+  .table-inner {
+
+  }
+}
+</style>
+
+<style lang="scss">
+.card-preset_header {
+  padding: 16px !important;
+}
+.card-prset_content {
+  padding: 20px !important;
+  background: linear-gradient(180deg, #F3F7FC 0%, #E4EAF7 100%);
+}
+</style>

+ 3 - 3
src/views/carbon/components/config.js

@@ -8,7 +8,7 @@ export const inputConfig = {
     twoBlock: [
       { label: '月处理水量', unit: 'm³/月', key: 'wsSjclCh4Clsl' },
       { label: '进水COD', unit: 'mg/L', key: 'wsSjclCh4JsCod' },
-      { label: '出水COD*', unit: 'mg/L', key: 'wsSjclCh4CsCod' },
+      { label: '出水COD', unit: 'mg/L', key: 'wsSjclCh4CsCod' },
       { label: '污水处理阶段CH₄的排放因子', unit: 'kg CH₄/kg COD', key: 'wsSjclCh4Pfyz' },
       { label: '提升泵逸散的CH₄量', unit: 'kg/月', key: 'wsSjclCh4Tsb' },
       { label: '沉砂池逸散的CH₄量', unit: 'kg/月', key: 'wsSjclCh4Csc' }
@@ -16,7 +16,7 @@ export const inputConfig = {
     threeBlock: [
       { label: '月处理水量', unit: 'm³/月', key: 'wsTdN2oClsl' },
       { label: '进水TN', unit: 'mg/L', key: 'wsTdN2oJsTn' },
-      { label: '出水TN*', unit: 'mg/L', key: 'wsTdN2oCsTn' },
+      { label: '出水TN', unit: 'mg/L', key: 'wsTdN2oCsTn' },
       { label: '污水处理阶段N₂O的排放因子', unit: 'kg CH₄/kg COD', key: 'wsTdN2oPfyz' },
     ]
   },
@@ -35,7 +35,7 @@ export const inputConfig = {
     twoBlock: [
       { label: '蒸汽', unit: 't/月', key: 'nyyjGrrlZq' },
       { label: '对应焓值', unit: 'KJ/Kg', key: 'nyyjGrrlDyhz' },
-      { label: '热力', unit: 'GJ/月', key: 'nyyjGrrlRl' },
+      // { label: '热力', unit: 'GJ/月', key: 'nyyjGrrlRl' },
     ]
   },
   sludge: {

+ 2 - 2
src/views/carbon/components/index.js

@@ -5,7 +5,7 @@ import BasePanel from './BasePanel.vue';
 
 import TheDrawerForm from './TheDrawerForm.vue';
 import TheDrawerList from './TheDrawerList.vue';
-import TheModal from './TheModal.vue';
+import TheModalTable from './TheModalTable.vue';
 
 import BaseDatePicker from './BaseDatePicker.vue';
 
@@ -17,5 +17,5 @@ export {
   BaseDatePicker,
   TheDrawerForm,
   TheDrawerList,
-  TheModal
+  TheModalTable
 }

+ 0 - 21
src/views/carbon/components/screen/DataBorad.vue

@@ -66,26 +66,6 @@ const boardList = ref([
   },
 ]);
 
-const list111 = computed(() => {
-  boardList.value.map(item => {
-
-    Object.entries(props.data).forEach(([k, v]) => {
-     
-      if ( item.key === k ) {
-        item.value = v
-      }
-
-      // if () {
-
-      // }
-
-    })
-    console.log("item", item);
-
-  })
-})
-
-// 总碳排放量
 
 </script>
 
@@ -93,7 +73,6 @@ const list111 = computed(() => {
   <div class="data-board-view">
     <div class="board-item" v-for="item, index in boardList" :key="item.key">
       <p class="title">{{ item.label }}</p>
-      
       <p class="statement">
         <span class="num">{{ data[item.key] }} </span>
         <span class="unit"> {{ item.unit }}</span>

+ 1 - 32
src/views/carbon/components/screen/DataScroll.vue

@@ -3,35 +3,6 @@ import { ref } from 'vue';
 import { Vue3SeamlessScroll } from 'vue3-seamless-scroll'
 import LayoutCard from './LayoutCard.vue'
 
-const listData = ref([{
-  'title': '无缝滚动第一行无缝滚动第一行',
-  'date': '2017-12-16'
-}, {
-  'title': '无缝滚动第二行无缝滚动第二行',
-  'date': '2017-12-16'
-}, {
-  'title': '无缝滚动第三行无缝滚动第三行',
-  'date': '2017-12-16'
-}, {
-  'title': '无缝滚动第四行无缝滚动第四行',
-  'date': '2017-12-16'
-}, {
-  'title': '无缝滚动第五行无缝滚动第五行',
-  'date': '2017-12-16'
-}, {
-  'title': '无缝滚动第六行无缝滚动第六行',
-  'date': '2017-12-16'
-}, {
-  'title': '无缝滚动第七行无缝滚动第七行',
-  'date': '2017-12-16'
-}, {
-  'title': '无缝滚动第八行无缝滚动第八行',
-  'date': '2017-12-16'
-}, {
-  'title': '无缝滚动第九行无缝滚动第九行',
-  'date': '2017-12-16'
-}])
-
 defineProps({
   data: {
     type: Array,
@@ -39,8 +10,6 @@ defineProps({
   }
 })
 
-console.log(listData);
-const start = ref(false)
 </script>
 
 <template>
@@ -65,7 +34,7 @@ const start = ref(false)
 <style lang="scss" scoped>
 .scroll-container {
   height: 100%;
-  padding: 30px 30px;
+  padding: 20px 30px 26px 30px;
   line-height: 40px;
   font-size: 14px;
   color: #fff;

+ 5 - 2
src/views/carbon/components/screen/LayoutCard.vue

@@ -63,8 +63,11 @@ defineProps({
 .layout-card_large {
   .card-header {
     height: 94px;
-    background: url('@/assets/images/carbon/bg-large-title1.png') 0px 0px no-repeat;
-    background-size: 100% 100%;
+    background: url('@/assets/images/carbon/bg-large-title2.png') left 0px no-repeat;
+    background-size: 100% 94%;
+    .title {
+      padding-left: 7%;
+    }
   }
 }
 </style>

+ 13 - 7
src/views/carbon/echartOptions/index.js

@@ -249,7 +249,7 @@ export const echartGraphOptions = (d = []) => {
         }<br/><span style="display:inline-block;margin-right:5px;border-radius:10px;width:10px;height:10px;background-color:${
           params.color.colorStops[0].color
         };"></span>${
-          params.data.value
+          params.data.value || ''
         }`;
       },
     },
@@ -286,7 +286,7 @@ export const echartGraphOptions = (d = []) => {
             color: "#fff",
           },
           formatter: function (params) {
-            return `{a|${params}}`;
+            return `{a|${params || ''}}`;
           },
         },
         data: salvProName,
@@ -320,7 +320,13 @@ export const echartGraphOptions = (d = []) => {
             },
           },
           formatter: function (value) {
-            return `{a|${value}}  {b|tCO₂-eq}`;
+            let val = value;
+            console.log(typeof value);
+            if ( value === 'null' || ( !value && value !== 0 ) ) {
+              val = ''
+            } 
+            console.log("valuevaluevaluevalue", typeof value);
+            return `{a|${val}}  {b|tCO₂-eq}`;
           },
         },
         data: data,
@@ -623,8 +629,8 @@ export const echart3DOptions = () => {
             zIndex: -1,
             background: 'red'
           },
-          left: '8.5%',
-          top: '35%'
+          left: '0%',
+          top: '32%'
         }
       ],
     },
@@ -702,8 +708,8 @@ export const echart3DOptions = () => {
     grid3D: {
       show: false,
       boxHeight: 6,
-      top: "-3%",
-      left: "-16.5%",
+      top: "-6%",
+      left: "-22%",
       width: "100%",
       viewControl: {
         distance: 180,

+ 39 - 45
src/views/carbon/index.vue

@@ -1,24 +1,22 @@
 <script setup>
 import { ref, computed, onMounted, onUnmounted } from 'vue';
 import { useRouter } from 'vue-router';
-import { NPopselect } from 'naive-ui';
+import { NPopselect, useMessage } from 'naive-ui';
 import * as echarts from 'echarts';
 import dayjs from 'dayjs';
 import autofit from 'autofit.js'
 import { carbonApi } from '@/api/carbon'
 import { echartLineOptions, echartGraphOptions, echart3DOptions, echartColumnarOptions } from './echartOptions';
-import VueDatePicker from '@vuepic/vue-datepicker';
 
 import SvgIcon from '@/components/SvgIcon';
-import { TheDrawerForm, TheDrawerList, BaseDatePicker, TheModal } from './components';
+import { TheDrawerForm, TheDrawerList, TheModalTable } from './components';
 
 import DataBorad from './components/screen/DataBorad.vue'
 import DataScroll from './components/screen/DataScroll.vue'
 import LayoutCard from './components/screen/LayoutCard.vue'
-import EchartEnergy from './components/screen/EchartEnergy.vue'
-import EchartColumnar from './components/screen/EchartColumnar.vue'
 
 const router = useRouter();
+const message = useMessage();
 
 let timerId = null;
 let echartMonth = null;
@@ -28,14 +26,17 @@ let echartMdu = null;
 const tDay = dayjs();
 const currentTimer = ref(tDay.format('HH:mm:ss'));
 const currentMonth = tDay.format('YYYY.MM.DD');
-const allMonth = ref([])
-const inpVap = ref('')
+const allMonth = ref([]);
+const inpVal = ref('')
 const historyDetails = ref({});
 
 const echartMonthRef = ref(null);
 const echartSewageRef = ref(null);
 const echartEnergyRef = ref(null);
 const echartMudRef = ref(null);
+const isVisibleDrawerForm = ref(false);
+const isVisibleDrawerList = ref(false);
+const isVisibleDrawerTable = ref(false);
 
 const scrollData = ref([]);
 const scrollMapping = [
@@ -65,25 +66,16 @@ const scrollMapping = [
   { label: '污泥产物土地利用的替碳量', key: 'thWnClhCo2', value: '' },
 ];
 
-const showPopover = ref(false);
-
-const isVisibleDrawerForm = ref(false);
-const isVisibleDrawerList = ref(false);
-
-const allowedMonth = computed(() => {
-  return allMonth.value.map(m => dayjs(m, 'YYYY-MM'));
-})
-
 const selectOptions = computed(() => allMonth.value.map(item => ({ label: item, value: item })));
 
-const handleType = (type) => {
+const handleType = async ( type ) => {
 
   if (type === 'down') {
-
+    return message.warning("该功能暂未开通");
   }
 
   if (type === 'info') {
-
+    isVisibleDrawerTable.value = true;
   }
 
   if (type === 'list') {
@@ -96,25 +88,15 @@ const handleType = (type) => {
 }
 
 const handleBackPage = () => router.back();
-
 const getCurrentTimer = () => dayjs().format('HH:mm:ss');
 
-const dateDisabled = (ts, de) => {
-
-  const m = dayjs(ts).format('YYYY-MM');
-
-  console.log(allMonth.value, m, allMonth.value.includes(m));
-  return m != '2024-06'
-}
-
-const disabledDate = (date) => !allMonth.value.includes(dayjs(date).format('YYYY-MM'));
 const initAllMonth = async () => {
   const { data: month } = await carbonApi.getAllMonth();
-  allMonth.value = month.reverse();
+  allMonth.value = month;
   return month;
 }
 
-const initEchart = (data) => {
+const initEchart = () => {
   const { 
     recent7Datas, extraMap, wsTdN2oCo2, wsSjclCh4Co2, wjtykuCo2, wsHsytkhCo2,
     wnclYyzqCo2,
@@ -123,7 +105,7 @@ const initEchart = (data) => {
     wnclWnfsCo2,
     wnclBwqrsCh4Co2, wnclBwqrsN2oCo2,
     wnclWnrjQtCh4Co2, wnclWnrjQtN2oCo2
-  } = data;
+  } = historyDetails.value;
 
   echartMonth = echarts.init(echartMonthRef.value, 'light');
   echartSewage = echarts.init(echartSewageRef.value, 'light');
@@ -150,7 +132,6 @@ const initEchart = (data) => {
   ]));
 
   const scrollList = Object.entries(extraMap).map(([k, v], i) => {
-    const item = {};
     return v.map((child, index) => {
       return {
         label: child.dictLabel,
@@ -163,7 +144,7 @@ const initEchart = (data) => {
   // 滚动区域
   scrollData.value = [...scrollList, ...scrollMapping].map(item => {
     const temp = { ...item };
-    Object.entries(data).forEach(([k, v]) => {
+    Object.entries(historyDetails.value).forEach(([k, v]) => {
       if ( temp.key === k ) {
         temp.value = v;
       }
@@ -173,9 +154,21 @@ const initEchart = (data) => {
 
 }
 
+const initPageData = async () => {
+  const { data } = await carbonApi.getDetails(inpVal.value);
+
+  historyDetails.value = data;
+
+  initEchart();
+}
+
+// select 的 options选中
+const handleSelectChecked = (time) => {
+  inpVal.value = time;
+  initPageData();
+}
 
 const windowResize = () => {
-  console.log("s???");
   echartMonth.resize();
   echartSewage.resize();
   echartEnergy.resize();
@@ -185,7 +178,6 @@ const windowResize = () => {
 onMounted(async () => {
   const months = await initAllMonth();
   const lastMonth = months[months.length - 1];
-  const { data } = await carbonApi.getDetails(lastMonth);
 
   autofit.init({
     dw: 1920,
@@ -194,16 +186,19 @@ onMounted(async () => {
     resize: true
   })
 
-  inpVap.value = lastMonth;
-  historyDetails.value = data;
+  inpVal.value = lastMonth;
 
-  initEchart(data);
+  initPageData();
 
   window.addEventListener("resize", windowResize);
 
   timerId = setInterval(() => currentTimer.value = getCurrentTimer(), 1000)
 })
 
+const onSubmit = () => {
+  isVisibleDrawerForm.value = false;
+}
+
 onUnmounted(() => {
   window.removeEventListener("resize", windowResize);
   clearInterval(timerId);
@@ -220,9 +215,9 @@ onUnmounted(() => {
   <div class="screen-viewprot" id="test">
     <header class="header">
       <div class="flex items-center">
-        <NPopselect :options="selectOptions" v-model:value="inpVap" scrollable>
+        <NPopselect :options="selectOptions" v-model:value="inpVal" scrollable :on-update:value="handleSelectChecked">
           <div class="calendar space-x-[4px]">
-            <span class="calendar-text">{{ inpVap }}</span>
+            <span class="calendar-text">{{ inpVal }}</span>
           </div>
         </NPopselect>
         <div class="timer-inner">
@@ -259,7 +254,6 @@ onUnmounted(() => {
         <div ref="echartMudRef" class="w-full h-full"></div>
       </LayoutCard>
 
-      <!-- <EchartColumnar></EchartColumnar> -->
     </main>
     <ul class="footer">
       <li><img src="@/assets/images/carbon/bg-btn-1.png" alt="下载报告" class="img" @click="handleType('down')"></li>
@@ -269,9 +263,9 @@ onUnmounted(() => {
     </ul>
   </div>
 
-  <TheDrawerForm v-model="isVisibleDrawerForm" />
+  <TheDrawerForm v-model="isVisibleDrawerForm" @on-submit="onSubmit"/>
   <TheDrawerList v-model="isVisibleDrawerList" :data="historyDetails" />
-  <!-- <TheModal /> -->
+  <TheModalTable v-model="isVisibleDrawerTable"/>
 </template>
 
 <style lang="scss" scoped>
@@ -341,7 +335,7 @@ $text-color_primary: #C2D8EF;
   display: grid;
   grid-gap: 26px 26px;
   padding: 30px 48px 0 48px;
-  grid-template-columns: minmax(490px, 28%) 1fr minmax(490px, 28%);
+  grid-template-columns: 490px 1fr 490px;
   grid-template-rows: minmax(300px, 50%) minmax(300px, 50%);
   color: #fff;