Procházet zdrojové kódy

公共组件封装/功能优化

fanghuisheng před 1 rokem
rodič
revize
00f66e79c4

+ 0 - 9
src/api/business/mhxf/xunJian/plan.js

@@ -45,15 +45,6 @@ export function appPlanStatistics(param) {
   });
 }
 
-// 图片上传
-export function uploadAvatar(data) {
-  return uploads({
-    url: "/service-file/upload",
-    name: data.name,
-    filePath: data.filePath,
-  });
-}
-
 /**
  * @站点详情
  * @siteList站点详情信息存储

+ 9 - 0
src/api/common/invoicing/index.js

@@ -8,3 +8,12 @@ export function crmInvoiceInfo(param) {
         data: param,
     });
 }
+
+//客户发票信息表-分页
+export function page(param) {
+    return request({
+        url: "/service-iot/crmInvoiceInfo/page",
+        method: "POST",
+        data: param,
+    });
+}

+ 189 - 0
src/components/oa-upload/index.vue

@@ -0,0 +1,189 @@
+<template>
+  <!-- 图片上传数量等于1显示 -->
+  <view class="oa-upload" v-if="uploadCount == 1">
+    <view v-if="uploadImage" class="uploadView" :style="uploadStyle">
+      <view class="uploadUimage">
+        <u-image width="100%" height="100%" :src="uploadImage"></u-image>
+      </view>
+
+      <view v-if="!uploadCloseStatus" class="uploadViewClose" @click="uploadViewClose()">
+        <u-icon name="close" color="#ffffff" size="12"></u-icon>
+      </view>
+    </view>
+    <view v-if="!uploadImage" :class="uploadCloseStatus ? 'uploadView upload-buttom uploadDisabled' : 'uploadView upload-buttom'" :style="uploadStyle" @click="uploadClick()">
+      <u-icon style="margin: auto" name="plus" color="#909399" :size="uploadIconSize"></u-icon>
+    </view>
+  </view>
+
+  <!-- 图片上传数量大于1显示 -->
+  <view class="oa-upload" v-if="uploadCount > 1">
+    <view class="uploadView" :style="uploadStyle" v-for="up in uploadList" :key="up">
+      <view class="uploadUimage">
+        <u-image width="100%" height="100%" :src="up.url"></u-image>
+      </view>
+
+      <view v-if="!uploadCloseStatus" class="uploadViewClose" @click="uploadViewClose(up)">
+        <u-icon name="close" color="#ffffff" size="12"></u-icon>
+      </view>
+    </view>
+    <view :class="uploadCloseStatus ? 'uploadView upload-buttom uploadDisabled' : 'uploadView upload-buttom'" :style="uploadStyle" @click="uploadClick()">
+      <u-icon style="margin: auto" name="plus" color="#909399" :size="uploadIconSize"></u-icon>
+    </view>
+  </view>
+</template>
+
+<script setup>
+import { uploadAvatar } from "@/api/system/user.js";
+import { ref, toRefs } from "vue";
+
+const emit = defineEmits(["uploadSuccessChange", "uploadDeleteChange"]);
+
+const props = defineProps({
+  //图片路径(uploadCount为1时使用)
+  uploadImage: {
+    type: String,
+    default: "",
+  },
+  //图片集合(uploadCount大于1时使用)
+  uploadList: {
+    type: Object,
+    default: [],
+  },
+  //样式
+  uploadStyle: {
+    type: Object,
+    default: {
+      width: "80px",
+      height: "80px",
+      marginBottom: "0px",
+    },
+  },
+  //icon大小
+  uploadIconSize: {
+    type: String,
+    default: "20px",
+  },
+  //是否禁用
+  uploadCloseStatus: {
+    type: Boolean,
+    default: false,
+  },
+  //上传图片数量
+  uploadCount: {
+    type: Number,
+    default: 1,
+  },
+});
+
+const { uploadImage, uploadList, uploadStyle, uploadIconSize, uploadCloseStatus, uploadCount } = toRefs(props);
+
+/**
+ * @upload图片上传
+ * @点击事件
+ */
+function uploadClick() {
+  uni.chooseImage({
+    count: uploadCount.value, //默认9
+    sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
+    sourceType: ["album", "camera"], //从相册选择、摄像头
+    success: function (res) {
+      uploadApi(res);
+    },
+  });
+}
+
+/**
+ * @upload图片上传
+ * @api接口请求
+ */
+function uploadApi(res) {
+  let data = { name: "file", filePath: res.tempFilePaths[0] };
+
+  uploadAvatar(data).then((response) => {
+    emit("uploadSuccessChange", response.data);
+  });
+}
+
+/**
+ * @upload图片上传
+ * @点击事件
+ * @删除事件
+ */
+function uploadViewClose(el) {
+  if (uploadCount.value > 1) {
+    emit("uploadDeleteChange", uploadList.value.splice(uploadList.value.indexOf(el), 1));
+  } else {
+    emit("uploadDeleteChange", "");
+  }
+}
+</script>
+
+<style scoped>
+.oa-upload {
+  display: flex;
+  flex-wrap: wrap;
+}
+
+.uploadView {
+  position: relative;
+  overflow: hidden;
+  width: calc(33% - 10px);
+  height: 110px;
+  margin: 0 15px 15px 0;
+  border: 1px solid #d9d9d9;
+  border-radius: 6px;
+  cursor: pointer;
+}
+
+.uploadView .uploadUimage {
+  height: 100%;
+}
+
+.uploadView .uploadUimage > uni-view {
+  height: 100%;
+}
+
+.uploadView .uploadViewClose {
+  position: absolute;
+  background-color: #409eff;
+  transform: rotate(45deg);
+  width: 40px;
+  height: 24px;
+  text-align: center;
+  right: -15px;
+  top: -6px;
+  cursor: pointer;
+}
+
+.uploadView .uploadViewClose .u-icon {
+  font-size: 12px;
+  margin-top: 4px;
+  margin-left: 10px;
+  transform: rotate(-45deg);
+  color: #ffffff;
+}
+
+.uploadView img {
+  width: 100%;
+}
+
+.uploadView:nth-child(3n) {
+  margin: 0 !important;
+}
+
+.upload-buttom {
+  display: flex;
+  font-size: 28px;
+  color: #909399;
+  border: 1px dashed #d9d9d9;
+  background-color: #fafafa;
+}
+
+.upload-buttom:hover {
+  border: 1px dashed #409eff;
+}
+
+:deep(.uploadDisabled) {
+  display: none !important;
+}
+</style>

+ 2 - 2
src/main.js

@@ -17,8 +17,7 @@ import oaCalendar from "@/components/oa-calendar/uni-calendar";
 import oaTabbar from "@/components/oa-tabbar/index";
 import oaTimeLine from "@/components/oa-timeLine/index"
 import oaTimeLineItem from "@/components/oa-timeLine-item/index"
-
-
+import oaUpload from "@/components/oa-upload/index"
 
 export function createApp() {
   const app = createSSRApp(App);
@@ -28,6 +27,7 @@ export function createApp() {
   app.component('oa-tabbar', oaTabbar)
   app.component('oa-timeLine', oaTimeLine)
   app.component('oa-timeLine-item', oaTimeLineItem)
+  app.component('oa-upload', oaUpload)
 
   // 挂载全局json导出
   app.component("downloadExcel", JsonExcel);

+ 6 - 41
src/pages/business/fireIot/facilitiesGather/index.vue

@@ -48,20 +48,7 @@
                   <u-input v-model="form.contactPhone" placeholder="请输入联系电话" border="none" maxlength="11" />
                 </u-form-item>
                 <u-form-item label="设备图片" prop="imagesUrl" :borderBottom="true">
-                  <view class="flex flex-wrap">
-                    <view class="uploadView" style="width: 80px; height: 80px; margin-bottom: 0px" v-if="form.imagesUrl">
-                      <view class="uploadUimage">
-                        <u-image width="100%" height="100%" :src="form.imagesUrl"></u-image>
-                      </view>
-
-                      <view class="uploadViewClose" @click="uploadViewClose()">
-                        <u-icon name="close" color="#ffffff" size="12"></u-icon>
-                      </view>
-                    </view>
-                    <view :class="'uploadView upload-buttom'" style="width: 80px; height: 80px; margin-bottom: 0px" v-if="!form.imagesUrl" @click="uploadClick">
-                      <u-icon style="margin: auto" name="plus" color="#909399" size="20"></u-icon>
-                    </view>
-                  </view>
+                  <oa-upload :uploadCount="1" :uploadImage="form.imagesUrl" @uploadSuccessChange="uploadSuccessChange" @uploadDeleteChange="uploadDeleteChange"></oa-upload>
                 </u-form-item>
                 <u-form-item label="备注" prop="facilityDesc" :borderBottom="true">
                   <u-textarea v-model="form.facilityDesc" placeholder="请输入" border="none" maxlength="30" style="padding: 0px"></u-textarea>
@@ -545,38 +532,16 @@ function changeHandler(e) {
 }
 
 /**
- * @upload图片上传
- * @点击事件
+ * @图片上传成功回调
  */
-function uploadClick() {
-  uni.chooseImage({
-    count: 1, //默认9
-    sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
-    sourceType: ["album", "camera"], //从相册选择、摄像头
-    success: function (res) {
-      uploadApi(res);
-    },
-  });
-}
-
-/**
- * @upload图片上传
- * @api接口请求
- */
-function uploadApi(res) {
-  let data = { name: "file", filePath: res.tempFilePaths[0] };
-
-  uploadAvatar(data).then((response) => {
-    form.value.imagesUrl = response.data.url;
-  });
+function uploadSuccessChange(e) {
+  form.value.imagesUrl = e.url;
 }
 
 /**
- * @upload图片上传
- * @点击事件
- * @删除事件
+ * @图片删除回调
  */
-function uploadViewClose(el) {
+function uploadDeleteChange(e) {
   form.value.imagesUrl = "";
 }
 

+ 21 - 45
src/pages/business/mhxf/xunJian/plan/components/siteDetails.vue

@@ -20,20 +20,17 @@
       <view class="bg-white padding-15 margin-b-15">
         <uni-section class="block margin-b-10" title="上报现场" type="line"></uni-section>
 
-        <view class="flex flex-wrap">
-          <view class="uploadView" v-for="record in siteList.recordPictureList" :key="record">
-            <view class="uploadUimage">
-              <u-image width="100%" height="100%" :src="record.pictureUrl"></u-image>
-            </view>
-
-            <view v-if="siteList.inspectionStatus == 1" class="uploadViewClose" @click="uploadViewClose(record)">
-              <u-icon name="close" color="#ffffff" size="12"></u-icon>
-            </view>
-          </view>
-          <view :class="siteList.inspectionStatus == 2 ? 'uploadView upload-buttom uploadDisabled' : 'uploadView upload-buttom'" @click="uploadClick">
-            <u-icon style="margin: auto" name="plus" color="#909399" size="28"></u-icon>
-          </view>
-        </view>
+        <oa-upload
+          :uploadCount="9"
+          :uploadList="siteList.recordPictureList"
+          :uploadStyle="{
+            width: 'calc(33% - 10px)',
+            height: '110px',
+          }"
+          :uploadCloseStatus="siteList.inspectionStatus == 2"
+          @uploadSuccessChange="uploadSuccessChange"
+          @uploadDeleteChange="uploadDeleteChange"
+        ></oa-upload>
       </view>
 
       <view class="bg-white padding-15 margin-b-15" style="height: 170px; max-height: 170px">
@@ -67,7 +64,7 @@ import { onLoad, onShow } from "@dcloudio/uni-app";
 import { ref, onMounted, reactive, computed, getCurrentInstance, toRefs, inject, shallowRef } from "vue";
 import { publicStores, xunJianStores } from "@/store/modules/index";
 
-import { uploadAvatar, siteDetails } from "@/api/business/mhxf/xunJian/plan.js";
+import { siteDetails } from "@/api/business/mhxf/xunJian/plan.js";
 
 const xunJianStore = xunJianStores(); //全局变量值Store
 
@@ -118,42 +115,21 @@ function buttonClick() {
 }
 
 /**
- * @upload图片上传
- * @点击事件
- */
-function uploadClick() {
-  uni.chooseImage({
-    count: 1, //默认9
-    sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
-    sourceType: ["album", "camera"], //从相册选择、摄像头
-    success: function (res) {
-      uploadApi(res);
-    },
-  });
-}
-
-/**
- * @upload图片上传
- * @api接口请求
+ * @图片上传成功回调
  */
-function uploadApi(res) {
-  let data = { name: "file", filePath: res.tempFilePaths[0] };
-
-  uploadAvatar(data).then((response) => {
-    siteList.value.recordPictureList.push({
-      name: response.data.name,
-      pictureUrl: response.data.url,
-    });
+function uploadSuccessChange(e) {
+  siteList.value.recordPictureList.push({
+    name: e.name,
+    url: e.url,
+    pictureUrl: e.url,
   });
 }
 
 /**
- * @upload图片上传
- * @点击事件
- * @删除事件
+ * @图片删除回调
  */
-function uploadViewClose(el) {
-  siteList.value.recordPictureList.splice(siteList.value.recordPictureList.indexOf(el), 1);
+function uploadDeleteChange(e) {
+  siteList.value.recordPictureList = e;
 }
 
 onLoad((options) => {

+ 52 - 71
src/pages/common/invoicing/index.vue

@@ -5,7 +5,7 @@
 
   <scroll-view class="invoicing-container scroll-height" :scroll-y="true" :data-theme="'theme-' + proxy.$settingStore.themeColor.name">
     <view v-show="tabsCurrent == 0">
-      <u-notice-bar text="注:查询到您近期有开票记录,请勿重复开票" :duration="9000" color="#FF0000" bgColor="#FFFFFF"></u-notice-bar>
+      <u-notice-bar v-if="promptStatus" text="注:查询到您近期有开票记录,请勿重复开票" :duration="9000" color="#FF0000" bgColor="#FFFFFF"></u-notice-bar>
 
       <view class="menu-list" style="font-size: 15px; line-height: 30px">
         <view class="list-cell">
@@ -81,20 +81,7 @@
                   <u-input v-model="form.sendAddress" placeholder="请填写邮寄地址" border="none" />
                 </u-form-item>
                 <u-form-item label="付款回执" prop="paymentReceipt" :borderBottom="true">
-                  <view class="flex flex-wrap">
-                    <view class="uploadView" style="width: 80px; height: 80px; margin-bottom: 0px" v-if="form.paymentReceipt">
-                      <view class="uploadUimage">
-                        <u-image width="100%" height="100%" :src="form.paymentReceipt"></u-image>
-                      </view>
-
-                      <view class="uploadViewClose" @click="uploadViewClose()">
-                        <u-icon name="close" color="#ffffff" size="12"></u-icon>
-                      </view>
-                    </view>
-                    <view :class="'uploadView upload-buttom'" style="width: 80px; height: 80px; margin-bottom: 0px" v-if="!form.paymentReceipt" @click="uploadClick">
-                      <u-icon style="margin: auto" name="plus" color="#909399" size="20"></u-icon>
-                    </view>
-                  </view>
+                  <oa-upload :uploadCount="1" :uploadImage="form.paymentReceipt" @uploadSuccessChange="uploadSuccessChange" @uploadDeleteChange="uploadDeleteChange"></oa-upload>
                   <view style="color: #666666">图片支持png、jpg</view>
 
                   <!-- <view>
@@ -174,9 +161,10 @@ import { onLoad, onShow, onReady, onHide, onLaunch, onNavigationBarButtonTap, on
 import { ref, reactive, computed, getCurrentInstance, toRefs, inject } from "vue";
 import { publicStores, useStores } from "@/store/modules/index";
 
-import { crmInvoiceInfo } from "@/api/common/invoicing/index";
+import { crmInvoiceInfo, page } from "@/api/common/invoicing/index";
 
 const { proxy } = getCurrentInstance();
+const publicStore = publicStores();
 
 const uForm = ref(null);
 const data = reactive({
@@ -292,74 +280,67 @@ const data = reactive({
       },
     ],
   },
-});
 
-const { tabsList, tabsCurrent, form, rules } = toRefs(data);
-
-function handleSubmit(value) {
-  if (value === "提交") {
-    uForm.value
-      .validate()
-      .then((res) => {
-        uni.$u.toast("校验通过");
+  promptStatus: false,
+});
 
-        var param = {
-          customId: parseInt(form.value.customId), //客户管理id
-          invoiceTitle: form.value.invoiceTitle, //发票抬头
-          dutyId: form.value.dutyId, //税号
-          email: form.value.email, //电子邮箱
-          applicant: form.value.applicant, //申请人
-          phone: form.value.phone, //手机号码
-          amount: parseFloat(form.value.amount), //金额
-          invoiceType: parseInt(form.value.invoiceType), //发票类型;1:普票,2:专票
-          invoiceAttribute: parseInt(form.value.invoiceAttribute), //发票性质;1:电子发票,2:纸质发票
-          sendAddress: form.value.sendAddress, //邮寄地址
-          paymentReceipt: form.value.paymentReceipt, //付款回执
-        };
-
-        crmInvoiceInfo(param).then((requset) => {});
-      })
-      .catch((errors) => {
-        uni.$u.toast("校验失败");
-      });
-  } else if (value === "复制汇款信息") {
-  }
-}
+const { tabsList, tabsCurrent, form, rules, promptStatus } = toRefs(data);
 
 /**
- * @upload图片上传
- * @点击事件
+ * @提交
  */
-function uploadClick() {
-  uni.chooseImage({
-    count: 1, //默认9
-    sizeType: ["original", "compressed"], //可以指定是原图还是压缩图,默认二者都有
-    sourceType: ["album", "camera"], //从相册选择、摄像头
-    success: function (res) {
-      uploadApi(res);
-    },
-  });
+function handleSubmit(value) {
+  uForm.value
+    .validate()
+    .then((res) => {
+      uni.$u.toast("校验通过");
+
+      crmInvoiceInfo({
+        current: 1,
+        size: 10,
+        invoiceTitle: form.value.invoiceTitle,
+        startTime: publicStore.formatterDateTime(new Date()),
+        endTime: publicStore.getYearLast(new Date()),
+      }).then((requset) => {
+        if (requset.status === "SUCCESS") {
+          if (requset.data.records.length > 0) {
+            promptStatus.value = true;
+          } else {
+            var param = {
+              customId: parseInt(form.value.customId), //客户管理id
+              invoiceTitle: form.value.invoiceTitle, //发票抬头
+              dutyId: form.value.dutyId, //税号
+              email: form.value.email, //电子邮箱
+              applicant: form.value.applicant, //申请人
+              phone: form.value.phone, //手机号码
+              amount: parseFloat(form.value.amount), //金额
+              invoiceType: parseInt(form.value.invoiceType), //发票类型;1:普票,2:专票
+              invoiceAttribute: parseInt(form.value.invoiceAttribute), //发票性质;1:电子发票,2:纸质发票
+              sendAddress: form.value.sendAddress, //邮寄地址
+              paymentReceipt: form.value.paymentReceipt, //付款回执
+            };
+            crmInvoiceInfo(param).then((requset) => {});
+          }
+        }
+      });
+    })
+    .catch((errors) => {
+      uni.$u.toast("校验失败");
+    });
 }
 
 /**
- * @upload图片上传
- * @api接口请求
+ * @图片上传成功回调
  */
-function uploadApi(res) {
-  let data = { name: "file", filePath: res.tempFilePaths[0] };
-
-  uploadAvatar(data).then((response) => {
-    form.value.paymentReceipt = response.data.url;
-  });
+function uploadSuccessChange(e) {
+  form.value.paymentReceipt = e.url;
 }
 
 /**
- * @upload图片上传
- * @点击事件
- * @删除事件
+ * @图片删除回调
  */
-function uploadViewClose(el) {
-  form.value.paymentReceipt = "";
+function uploadDeleteChange(e) {
+  form.value.paymentReceipt = e;
 }
 
 /**

+ 57 - 0
src/store/modules/public.js

@@ -124,6 +124,30 @@ const publicStore = defineStore("public", {
 
     deviceDetailsArray: {},//设备详情页面-数据存储
 
+    facilitiesGatherType: "",//设施采集类型-数据存储
+    facilitiesGatherArray: {
+      department: "", //所属部门
+      facilityType: "", //设施类型
+      facilityTypeName: "", //设施类型名称
+      facilityName: "", //设施名称
+      status: "0", //设施状态
+      address: "", //设施地址
+      longitude: "", //经度
+      latitude: "", //纬度
+      province: "", //省
+      city: "", //市
+      area: "", //区(县)
+      facilityAddress: "", //详细地址
+      streetTown: null, //所属街镇
+      gpsAreas: [], //经纬度集合
+      contact: "", //联系人
+      contactPhone: "", //联系方式
+      imagesUrl: "", //图⽚地址URL
+      facilityDesc: "", //备注
+      extendData: [], //扩展属性
+      recordPictureList: [],
+      typeGuise: "", //点线面类型
+    },//设施采集页面-数据存储
   }),
   persist: {
     // 自定义数据持久化方式
@@ -161,6 +185,7 @@ const publicStore = defineStore("public", {
         arr,
       };
     },
+
     /**
      * @处理公共日期格式
      */
@@ -183,6 +208,38 @@ const publicStore = defineStore("public", {
       }
       return fmt;
     },
+
+    /**
+   * @获取当前日期前一年的日期
+   */
+    getYearLast(dateStr) {
+      // 假设要获取的日期为dateStr,格式为"YYYY-MM-DD"
+      let date = new Date(dateStr);
+      let Y = date.getFullYear() - 1; // 获取前一年的年份
+      let M = date.getMonth() + 1 < 10 ? "0" + (date.getMonth() + 1) : date.getMonth() + 1; // 月
+      let D; // 日
+
+      var h = (date.getHours() < 10 ? "0" + date.getHours() : date.getHours()) + ":";
+      var m = (date.getMinutes() < 10 ? "0" + date.getMinutes() : date.getMinutes()) + ":";
+      var s = date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();
+
+      // 判断原日期的月份是否为2月份
+      if (date.getMonth() === 1) { // 2月份
+        // 判断前一年是否为闰年
+        if (Y % 4 === 0 && Y % 100 !== 0 || Y % 400 === 0) { // 闰年
+          D = Math.min(date.getDate(), 29); // 新日期的日期最大为29
+        } else { // 平年
+          D = Math.min(date.getDate(), 28); // 新日期的日期最大为28
+        }
+      } else { // 非2月份
+        D = date.getDate(); // 新日期的日期为原日期的日期
+      }
+
+      let newDateStr = Y + "-" + M + "-" + (D < 10 ? "0" + D : D) + " " + h + m + s; // 格式化日期字符串
+
+      return newDateStr
+    },
+
     /**
      * @获取年月日时分秒
      * @returns