Kaynağa Gözat

导入导出

zhuangyunsheng 1 yıl önce
ebeveyn
işleme
61867005f6

+ 2 - 1
.eslintrc-auto-import.json

@@ -310,6 +310,7 @@
     "onWatcherCleanup": true,
     "useId": true,
     "useModel": true,
-    "useTemplateRef": true
+    "useTemplateRef": true,
+    "ElLoading": true
   }
 }

+ 2 - 1
package.json

@@ -24,7 +24,8 @@
         "pinia-plugin-persist": "^1.0.0",
         "vue": "^3.3.4",
         "vue-i18n": "^9.5.0",
-        "vue-router": "^4.2.4"
+        "vue-router": "^4.2.4",
+		"xlsx-js-style": "^1.2.0"
     },
     "devDependencies": {
         "@iconify-json/ep": "^1.1.12",

+ 1 - 1
src/api/folder.js

@@ -1,7 +1,7 @@
 import axios from "axios"
 import request from "@/utils/request"
 
-// 登录方法
+// 文件方法
 export default {
     up: function (data, config = {}) {
         return request({ // file: file

+ 9 - 1
src/api/policy/share.js

@@ -81,5 +81,13 @@ export default {
     //         method: "post",
     //         data
     //     })
-    // }
+    // },
+
+    import: function (data) { // 导入
+        return request({
+            url: "qdport-zcgx/import/policyShare",
+            method: "post",
+            data
+        })
+    }
 }

+ 1 - 1
src/components/Upload/index.vue

@@ -31,7 +31,7 @@
 
 <script>
   	import { defineAsyncComponent } from "vue";
-    import Folder from "@/api/folder.js";
+    import Folder from "@/api/folder";
 
 	export default {
 		components: {

+ 42 - 0
src/utils/exportExcel.js

@@ -0,0 +1,42 @@
+import * as XLSX from "xlsx-js-style";
+
+/**
+ * 导出Excel表格
+ * @param header 生成excel的表头 []
+ * @param data 生成excel的内容 []
+ * @param merges 生成excel的合并单元格
+ * @param name 生成excel的文件名,如:abc.xlsx
+ * */
+export const exportExcel = (header, data, merges, name) => {
+    const workbook = XLSX.utils.book_new();  // 创建一个工作表  
+    const worksheet = XLSX.utils.aoa_to_sheet([header, ...data]);// 将工作表添加到工作簿 
+
+    // 设置worksheet每列的最大宽度
+    const colWidth = data.map(d => d.map(val => {
+        let wch = 10;
+        // 是否为中文
+        if (val) wch = val.toString().split("").map(str => str.charCodeAt() > 255 && 2 || 1).reduce((p, v) => p + v);
+        return { wch };
+    }))
+    // 以第一行为初始值
+    let result = colWidth[0];
+    for (let i = 1; i < colWidth.length; i++) {
+        for (let j = 0; j < colWidth[i].length; j++) {
+            if (result[j]["wch"] < colWidth[i][j]["wch"]) result[j]["wch"] = colWidth[i][j]["wch"];
+        }
+    }
+    header.forEach((val, i) => {
+        if (result[i]["wch"] < val.length * 2) result[i]["wch"] = val.length * 2;
+    });
+    worksheet["!cols"] = result;
+
+    // 合并单元格
+    worksheet["!merges"] = merges;
+
+    // 设置居中
+    for (let i in worksheet) {
+        if (worksheet[i].v) worksheet[i].s = { alignment: { horizontal: "center", wrapText: true, vertical: "center" } };
+    }
+    XLSX.utils.book_append_sheet(workbook, worksheet);  // 生成Excel文件 
+    XLSX.writeFile(workbook, name);
+}

+ 2 - 2
src/views/policyShare/approve.vue

@@ -40,14 +40,14 @@
 
 <script>
 import API from "@/api/policy/share";
-import { storageTypeDic, inWHDic } from "./main";
+import { inWHDic, storageTypeDic } from "./main";
 
 export default {
     emits: ["success", "closed"],
 
     data() {
         return {
-            storageTypeDic, inWHDic,
+            inWHDic, storageTypeDic,
 
             visible: false,
             mode: "agree",

+ 2 - 2
src/views/policyShare/dialog.vue

@@ -113,7 +113,7 @@
 <script>
 import API from "@/api/policy/share";
 import { useUserStore } from "@/store/user";
-import { levelDic, typeDic, inWHDic } from "./main";
+import { levelDic, typeDic } from "./main";
 import yhUpload from "@/components/Upload/index.vue";
 import approveDetail from "./approve.vue";
 
@@ -128,7 +128,7 @@ export default {
 
     data() {
         return {
-            levelDic, typeDic, inWHDic,
+            levelDic, typeDic,
             visible: false,
             mode: "add",
             titleMap: {

+ 75 - 28
src/views/policyShare/index.vue

@@ -31,6 +31,9 @@
                         <el-option v-for="item in storageTypeDic" :key="item" :label="item" :value="item"></el-option>
                     </el-select>
                 </el-form-item>
+                <el-form-item label="填报时间">
+                    <el-date-picker v-model="createTime" type="daterange" value-format="YYYY-MM-DD" range-separator="-" start-placeholder="开始时间" end-placeholder="结束时间"></el-date-picker>
+                </el-form-item>
 
                 <el-form-item>
                     <el-button type="primary" icon="search" @click="reloadTable">搜索</el-button>
@@ -43,32 +46,22 @@
         <div class="tjm_card_tools">
             <div class="tjm_card_tools_left">
                 <el-button type="primary" icon="plus" @click="table_add">新增</el-button>
-                <el-button type="primary" icon="upload">导入</el-button>
             </div>
             <div class="tjm_card_tools_right">
-                <el-button icon="upload-filled">导出</el-button>
+                <el-upload class="import-upload" action="" accept=".xlsx, .xls" :limit="1" :show-file-list="false" :http-request="table_import" :on-success="import_success">
+                    <el-button icon="upload-filled">导入</el-button>
+                </el-upload>
+                <el-button icon="download" @click="table_export">导出</el-button>
             </div>
         </div>
         <div class="tjm_card_table">
             <el-table v-loading="loading" row-key="id" header-cell-class-name="tjm_card_table_header" height="400" :data="tableData" border>
                 <el-table-column type="index" width="50"></el-table-column>
-                <el-table-column label="政策编号" prop="businessNo" width="180"></el-table-column>
-                <el-table-column label="状态" width="100">
-                    <template #default="scope">{{ formatStatus(scope.row.status) }}</template>
-                </el-table-column>
-                <el-table-column label="政策名称" prop="name" width="180"></el-table-column>
-                <el-table-column label="政策等级" prop="zcLevel" width="100"></el-table-column>
-                <el-table-column label="政策类别" prop="zcType" width="100"></el-table-column>
-                <el-table-column label="政策文号" prop="docNo" width="180"></el-table-column>
-                <el-table-column label="填报人" prop="createName" width="180"></el-table-column>
-                <el-table-column label="填报单位" prop="companyName" width="180"></el-table-column>
-                <el-table-column label="填报时间" prop="createTime" width="180"></el-table-column>
-                <el-table-column label="联系方式" prop="contactPhone" width="180"></el-table-column>
-                <el-table-column label="考核评分" prop="score" width="100"></el-table-column>
-                <el-table-column label="是否入库" width="100">
-                    <template #default="scope">{{ formatInWh(scope.row.isInWh) }}</template>
-                </el-table-column>
-                <el-table-column label="入库类别" prop="inWhType" width="100"></el-table-column>
+                <template v-for="(item, index) in columns" :key="index">
+                    <el-table-column :label="item.label" :prop="item.props" :width="item.width || 180">
+                        <template #default="scope">{{ columnFormat(scope.row, item.props) }}</template>
+                    </el-table-column>
+                </template>
                 <el-table-column label="操作" fixed="right" width="180">
                     <template #default="scope">
                         <template v-if="scope.row.status == 'active' || scope.row.status == 'inactive'">
@@ -92,7 +85,9 @@
 
 <script>
 import API from "@/api/policy/share"
-import { levelDic, typeDic, statusDic, inWHDic, storageTypeDic } from "./main";
+import Folder from "@/api/folder.js";
+import { exportExcel } from "@/utils/exportExcel";
+import { columns, levelDic, typeDic, storageTypeDic, inWHDic, statusDic } from "./main";
 import yhPagination from "@/components/Pagination/index.vue";
 import policyDetail from "./dialog.vue";
 
@@ -104,9 +99,10 @@ export default {
 
     data() {
         return {
-            levelDic, typeDic, statusDic, inWHDic, storageTypeDic,
+            columns, levelDic, typeDic, storageTypeDic, inWHDic, statusDic,
 
             loading: false,
+            createTime: [],
             params: {
                 page: 1,
                 size: 10
@@ -124,16 +120,16 @@ export default {
     },
 
     methods: {
-        formatStatus(value) {
-            return statusDic[value] || "";
-        },
-
-        formatInWh (value)  {
-            return inWHDic[value] || "";
+        columnFormat(row, props) {
+            if (props == "status") return statusDic[row[props]] || "";
+            if (props == "isInWh") return inWHDic[row[props]] || "";
+            return row[props];
         },
 
         reloadTable(mode = "add") {
             if (mode == "add") this.params.page = 1;
+            this.params.beginCreateTime = this.createTime && this.createTime.length && this.createTime[0] + " 00:00:00" || null;
+            this.params.endCreateTime = this.createTime && this.createTime.length && this.createTime[1] + " 23:59:59" || null;
 
             this.loading = true;
             API.get(this.params).then(res => {
@@ -146,6 +142,7 @@ export default {
         },
 
         reset() {
+            this.createTime = [];
             for (const key in this.params) {
                 if (key == "page") this.params[key] = 1;
                 else if (key == "size") this.params[key] = 10;
@@ -198,7 +195,57 @@ export default {
         closed(e) {
             e && this.reloadTable();
             this.dialog = false;
+        },
+
+        table_export() {
+            const header = columns.map(c => c.label);
+            const data = this.tableData.map(v => columns.map(c => c.props).map(j => this.columnFormat(v, j)));
+
+            exportExcel(header, data, [], `${this.$route.name}.xlsx`);
+        },
+
+        table_import(param) {
+            const importLoading = ElLoading.service({
+                lock: true,
+                text: "上传中请等待…",
+                spinner: "el-icon-loading",
+                background: "rgba(0, 0, 0, 0.7)"
+            });
+            const data = new FormData();
+            data.append(param.filename, param.file);
+
+            Folder.up(data).then(res => {
+                importLoading.close();
+                if (res.code == 200) param.onSuccess(res.data.link);
+                else ElMessage.error(res.msg || "未知错误");
+            }).catch(() => importLoading.close());
+        },
+
+        import_success(excelUrl) {
+            const importLoading = ElLoading.service({
+                lock: true,
+                text: "导入中请等待…",
+                spinner: "el-icon-loading",
+                background: "rgba(0, 0, 0, 0.7)"
+            })
+            API.import({ excelUrl }).then(res => {
+                if (res.code == 200) {
+                    importLoading.close();
+				    ElMessage.success(res.data);
+                    this.reloadTable();
+                } else ElMessage.error(res.msg);
+            }).catch(() => importLoading.close());
         }
     }
 }
-</script>
+</script>
+<style lang="scss" scoped>
+.tjm_card_style_custom .tjm_card_tools .tjm_card_tools_right {
+  display: flex;
+  align-items: center;
+
+  .import-upload {
+    margin-right: 12px;
+  }
+}
+</style>

+ 19 - 3
src/views/policyShare/main.js

@@ -1,10 +1,26 @@
+export const columns = [
+    { label: "政策编号", props: "businessNo" },
+    { label: "状态", props: "status", width: "100" },
+    { label: "政策名称", props: "name" },
+    { label: "政策等级", props: "zcLevel", width: "100" },
+    { label: "政策类别", props: "zcType", width: "100" },
+    { label: "政策文号", props: "docNo" },
+    { label: "填报人", props: "createName" },
+    { label: "填报单位", props: "companyName" },
+    { label: "填报时间", props: "createTime" },
+    { label: "联系方式", props: "contactPhone" },
+    { label: "考核评分", props: "score", width: "100" },
+    { label: "是否入库", props: "isInWh", width: "100" },
+    { label: "入库类别", props: "inWhType", width: "100" },
+];
+
 export const levelDic = ["国家级", "省部级", "市区级"];
 export const typeDic = ["财税政策", "人才支持", "市场开拓", "智慧创新", "招商引资", "技术改造", "法律法规", "营商环境", "企业管理"];
+export const storageTypeDic = ["文件类", "解读类"];
+export const inWHDic = { 0: "否", 1: "是" };
 export const statusDic = {
     active: "保存",
     approve: "审核",
     done: "审核通过",
     inactive: "退回"
-};
-export const storageTypeDic = ["政策类", "解读类"];
-export const inWHDic = { 0: "否", 1: "是" };
+};

+ 3 - 3
src/views/system/role.vue

@@ -78,14 +78,14 @@
                         批量删除
                     </el-button> -->
                 </div>
-                <div class="tjm_card_tools_right">
+                <!-- <div class="tjm_card_tools_right">
                     <el-button>
                         <el-icon class="tjm_btn_icon_right">
-                            <tjm-icon-ep-UploadFilled />
+                            <tjm-icon-ep-Download />
                         </el-icon>
                         导出
                     </el-button>
-                </div>
+                </div> -->
             </div>
             <div class="tjm_cart_table">
                 <el-table

+ 1 - 1
src/views/system/user.vue

@@ -369,7 +369,7 @@ function resetUserPwdBtn(row) {
                 </div>
                 <!-- <div class="tjm_card_tools_right">
                     <el-button>
-                        <el-icon class="tjm_btn_icon_right"><tjm-icon-ep-UploadFilled /></el-icon>
+                        <el-icon class="tjm_btn_icon_right"><tjm-icon-ep-download /></el-icon>
                         excel导出数据
                     </el-button>
                 </div> -->

+ 9 - 0
src/views/toDo/index.vue

@@ -11,6 +11,9 @@
                         <el-option v-for="item in typeDic" :key="item" :label="item" :value="item"></el-option>
                     </el-select>
                 </el-form-item>
+                <el-form-item label="填报时间">
+                    <el-date-picker v-model="createTime" type="daterange" value-format="YYYY-MM-DD" range-separator="-" start-placeholder="开始时间" end-placeholder="结束时间"></el-date-picker>
+                </el-form-item>
 
                 <el-form-item>
                     <el-button type="primary" icon="search" @click="reloadTable">搜索</el-button>
@@ -60,7 +63,9 @@ export default {
     data() {
         return {
             typeDic,
+
             loading: false,
+            createTime: [],
             params: {
                 page: 1,
                 size: 10
@@ -79,6 +84,9 @@ export default {
 
     methods: {
         reloadTable() {
+            this.params.beginCreateTime = this.createTime && this.createTime.length && this.createTime[0] + " 00:00:00" || null;
+            this.params.endCreateTime = this.createTime && this.createTime.length && this.createTime[1] + " 23:59:59" || null;
+            
             this.loading = true;
             API.get(this.params).then(res => {
                 this.loading = false;
@@ -90,6 +98,7 @@ export default {
         },
     
         reset() {
+            this.createTime = [];
             for (const key in this.params) {
                 if (key == "page") this.params[key] = 1;
                 else if (key == "size") this.params[key] = 10;