沈丘营商办后台前端项目
wjt
2024-06-18 033db2186f2fe5589b25ec55e41ddaa4f2f08108
完善
1个文件已添加
7个文件已修改
562 ■■■■ 已修改文件
src/api/system/company/company.ts 45 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/FileUpload/handlerImport.vue 215 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.ts 42 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/infomanger/companymanger/components/export.vue 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/infomanger/companymanger/components/exportRecord.vue 70 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/infomanger/companymanger/index.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/infomanger/policy/components/addNews.vue 90 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/infomanger/policy/index.vue 61 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/system/company/company.ts
@@ -58,7 +58,7 @@
  return request({
    url: '/system/company/import',
    method: 'get',
   })
  })
}
// 导入记录 /system/company/export
@@ -68,7 +68,6 @@
  return request({
    url: '/system/company/export',
    method: 'get',
    responseType: 'blob'
  })
}
// /system/doc/list 慧企政策列表
@@ -76,6 +75,46 @@
  return request({
    url: '/system/doc/list',
    method: 'get',
    responseType: 'blob'
  })
}
// 新增企业信息 /system/doc/add
export function addDoc(data) {
  return request({
    url: '/system/doc/add',
    method: 'post',
    data: data
  })
}
// 修改政策 /system/doc/upd
export function updDoc(data) {
  return request({
    url: '/system/doc/upd',
    method: 'post',
    data: data
  })
}
// system/doc/ 删除政策
export function delDoc(data) {
  return request({
    url: `/system/doc/${data.delId}`,
    method: 'DELETE',
    data: data
  })
}
// 处理导入信息
export function doImport(data) {
  return request({
    url: `/system/company/doImport`,
    method: 'post',
    data: data
  })
}
// 上传文件信息/tool/file/upload
export function uploadFile(data) {
  return request({
    url: `/tool/file/upload`,
    method: 'post',
    data: data
  })
}
src/components/FileUpload/handlerImport.vue
New file
@@ -0,0 +1,215 @@
<template>
  <div class="upload-file">
    <el-upload
      multiple
      :action="uploadFileUrl"
      :before-upload="handleBeforeUpload"
      :file-list="fileList"
      :limit="limit"
      :on-error="handleUploadError"
      :on-exceed="handleExceed"
      :on-success="handleUploadSuccess"
      :show-file-list="false"
      :headers="headers"
      class="upload-file-uploader"
      ref="fileUpload"
    >
      <!-- 上传按钮 -->
      <el-button type="primary">选取文件</el-button>
    </el-upload>
    <!-- 上传提示 -->
    <div class="el-upload__tip" v-if="showTip">
      请上传
      <!-- <template v-if="fileSize">
        大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
      </template> -->
      <template v-if="fileType">
        格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b>
      </template>
      的文件
    </div>
    <!-- 文件列表 -->
    <transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul">
      <li :key="file.uid" class="el-upload-list__item ele-upload-list__item-content" v-for="(file, index) in fileList">
        <el-link :href="`${baseUrl}${file.url}`" :underline="false" target="_blank">
          <span class="el-icon-document"> {{ getFileName(file.name) }} </span>
        </el-link>
        <div class="ele-upload-list__item-content-action">
          <el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link>
        </div>
      </li>
    </transition-group>
  </div>
</template>
<script setup>
import { getToken } from "@/utils/auth";
const props = defineProps({
  modelValue: [String, Object, Array],
  // 数量限制
  limit: {
    type: Number,
    default: 5,
  },
  // 大小限制(MB)
  fileSize: {
    type: Number,
    default: 5,
  },
  // 文件类型, 例如['png', 'jpg', 'jpeg']
  fileType: {
    type: Array,
    default: () => ["doc", "xls", "ppt", "txt", "pdf"],
  },
  // 是否显示提示
  isShowTip: {
    type: Boolean,
    default: true,
  },
});
const { proxy } = getCurrentInstance();
const emit = defineEmits();
const number = ref(0);
const uploadList = ref([]);
const baseUrl = import.meta.env.VITE_APP_BASE_API;
const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/system/company/doImport"); // 上传文件服务器地址
const headers = ref({ Authorization: "Bearer " + getToken() });
const fileList = ref([]);
const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize));
watch(
  () => props.modelValue,
  (val) => {
    if (val) {
      let temp = 1;
      // 首先将值转为数组
      const list = Array.isArray(val) ? val : props.modelValue.split(",");
      // 然后将数组转为对象数组
      fileList.value = list.map((item) => {
        if (typeof item === "string") {
          item = { name: item, url: item };
        }
        item.uid = item.uid || new Date().getTime() + temp++;
        return item;
      });
    } else {
      fileList.value = [];
      return [];
    }
  },
  { deep: true, immediate: true }
);
// 上传前校检格式和大小
function handleBeforeUpload(file) {
  // 校检文件类型
  if (props.fileType.length) {
    const fileName = file.name.split(".");
    const fileExt = fileName[fileName.length - 1];
    const isTypeOk = props.fileType.indexOf(fileExt) >= 0;
    if (!isTypeOk) {
      proxy.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join("/")}格式文件!`);
      return false;
    }
  }
  // 校检文件大小
  if (props.fileSize) {
    const isLt = file.size / 1024 / 1024 < props.fileSize;
    if (!isLt) {
      proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);
      return false;
    }
  }
  proxy.$modal.loading("正在上传文件,请稍候...");
  number.value++;
  return true;
}
// 文件个数超出
function handleExceed() {
  proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
}
// 上传失败
function handleUploadError(err) {
  proxy.$modal.msgError("上传文件失败");
}
// 上传成功回调
function handleUploadSuccess(res, file) {
  if (res.code === 200) {
    uploadList.value.push({ name: res.fileName, url: res.fileName });
    uploadedSuccessfully(res.data.voList);
  } else {
    number.value--;
    proxy.$modal.closeLoading();
    proxy.$modal.msgError(res.msg);
    proxy.$refs.fileUpload.handleRemove(file);
    uploadedSuccessfully();
  }
}
// 删除文件
function handleDelete(index) {
  fileList.value.splice(index, 1);
  emit("update:modelValue", listToString(fileList.value));
}
// 上传结束处理
function uploadedSuccessfully(item) {
  if (number.value > 0 && uploadList.value.length === number.value) {
    fileList.value = fileList.value.filter((f) => f.url !== undefined).concat(uploadList.value);
    uploadList.value = [];
    number.value = 0;
    emit("update:modelValue", listToString(fileList.value));
    proxy.$modal.closeLoading();
    if(item) {
      emit('resList', item)
    }
  }
}
// 获取文件名称
function getFileName(name) {
  if (name.lastIndexOf("/") > -1) {
    return name.slice(name.lastIndexOf("/") + 1);
  } else {
    return "";
  }
}
// 对象转成指定字符串分隔
function listToString(list, separator) {
  let strs = "";
  separator = separator || ",";
  for (let i in list) {
    if (list[i].url) {
      strs += list[i].url + separator;
    }
  }
  return strs != "" ? strs.substr(0, strs.length - 1) : "";
}
</script>
<style scoped lang="scss">
.upload-file-uploader {
  margin-bottom: 5px;
}
.upload-file-list .el-upload-list__item {
  border: 1px solid #e4e7ed;
  line-height: 2;
  margin-bottom: 10px;
  position: relative;
}
.upload-file-list .ele-upload-list__item-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  color: inherit;
}
.ele-upload-list__item-content-action .el-link {
  margin-right: 10px;
}
</style>
src/utils/request.ts
@@ -136,7 +136,10 @@
export function download(url: string, params: any, filename: string, config: any) {
  downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)" });
  return service
    .post(url, params, {
    .get(url, {
      params,
      responseType: "blob",
    }, {
      transformRequest: [
        (params) => {
          return tansParams(params);
@@ -165,42 +168,7 @@
      downloadLoadingInstance.close();
    });
}
// 通用下载方法
export function downloadGet(url: string, params: any, filename: string, config: any, isSaveFile = false) {
  downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)" });
  return service
    .get(url, { params }, {
      transformRequest: [
        (params) => {
          return tansParams(params);
        },
      ],
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      responseType: "blob",
      ...config,
    })
    .then(async (data) => {
      const isBlob = blobValidate(data);
      if (isBlob && isSaveFile) {
        const blob = new Blob([data]);
        saveAs(blob, filename);
      } else {
        if(!isSaveFile) {
        } else {
          const resText = await data.text();
          const rspObj = JSON.parse(resText);
          const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode["default"];
          ElMessage.error(errMsg);
        }
      }
      downloadLoadingInstance.close();
    })
    .catch((r) => {
      console.error(r);
      ElMessage.error("下载文件出现错误,请联系管理员!");
      downloadLoadingInstance.close();
    });
}
const request = <T = any>(_config: AxiosRequestConfig<any>): Promise<T> => {
  return service(_config) as Promise<T>;
};
src/views/infomanger/companymanger/components/export.vue
@@ -1,28 +1,31 @@
<template>
  <el-dialog title="用户导入" v-model="dialogVisible" width="600px" append-to-body @close="closeDialog"
  <el-dialog title="用户导入" v-model="dialogVisible" width="900px" append-to-body @close="cloaseDialog"
  >
    <el-form label-width="80px">
      <el-form-item label="下载模板">
        <el-link type="primary" @click="downLoad">企业信息导入模板.xlsx</el-link>
      </el-form-item>
      <el-form-item label="选取文件">
        <FileUpload :limit="1" :fileType="['cvs', 'xlsx']" v-model="form.exportNews.file"></FileUpload>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" plain @click="startExport">开始导入</el-button>
        <FileUpload :limit="1" :fileType="['cvs', 'xlsx']" v-model="form.exportNews.file" @resList="resList"></FileUpload>
      </el-form-item>
    </el-form>
    <template #footer>
      <div style="text-align: center;">
        <el-button @click="cloaseDialog" >关闭</el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { ElMessageBox } from 'element-plus'
import FileUpload from '@/components/FileUpload/index'
import { downloadGet  as downloadHttp} from '@/utils/request'
import { downTemplate, importTemplate } from '@/api/system/company/company'
import FileUpload from '@/components/FileUpload/handlerImport.vue'
import { download  as downloadHttp} from '@/utils/request'
import { downTemplate, importTemplate, doImport } from '@/api/system/company/company'
const { proxy } = getCurrentInstance();
const dialogVisible = ref(false)
const emit = defineEmits()
const form = reactive({
  exportNews: {}
})
@@ -42,7 +45,11 @@
  })
}
function startExport() {
  uploadFile()
}
function resList(row) {
  cloaseDialog()
  emit('resList', row)
}
defineExpose({
  openDialog,
src/views/infomanger/companymanger/components/exportRecord.vue
@@ -1,32 +1,70 @@
<template>
   <el-dialog title="导入记录" v-model="dialogVisible" width="1200px" append-to-body @close="closeDialog"
  >
    <el-table>
      <el-table-column label="序号"></el-table-column>
      <el-table-column label="导入文件"></el-table-column>
      <el-table-column label="导入人"></el-table-column>
      <el-table-column label="导入时间"></el-table-column>
      <el-table-column label="进度"></el-table-column>
      <el-table-column label="导入结果"></el-table-column>
      <el-table-column label="导入结果文件"></el-table-column>
    <el-table :data="recordValue" border>
      <el-table-column label="企业名(企业全称)" prop="companyName">
        <template #default="scope">
          <el-input v-model="scope.row.companyName"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="统一社会信用代码" prop="companyCode">
        <template #default="scope">
          <el-input v-model="scope.row.companyCode"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="企业联系人" prop="companyUser">
        <template #default="scope">
          <el-input v-model="scope.row.companyUser"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="联系人电话" prop="companyPhone">
        <template #default="scope">
          <el-input v-model="scope.row.companyPhone"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="企业地址" prop="companyAddress">
        <template #default="scope">
          <el-input v-model="scope.row.companyAddress"></el-input>
        </template>
      </el-table-column>
      <el-table-column label="备注" prop="mark">
        <template #default="scope">
          <el-input v-model="scope.row.mark"></el-input>
        </template>
      </el-table-column>
    </el-table>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="closeDialog">取 消</el-button>
        <el-button type="primary" @click="addCompany">确 定</el-button>
      </div>
    </template>
  </el-dialog>
</template>
<script setup lang="ts">
import { importTemplateRecord } from '@/api/system/company/company'
const dialogVisible = ref(false)
const closeDialog = () => {
  dialogVisible.value = false
}
const openDialog = () => {
const props = defineProps({
  recordRow: { type: Array, default: () => [] },
})
const recordValue = ref([])
watch(() => props.recordRow, (newValue) => {
  // console.log(props.recordRow)
  recordValue.value = newValue
})
function openDialog() {
  dialogVisible.value = true
}
function importTemplateRecord() {
  console.log('获取导入记录')
function closeDialog() {
  dialogVisible.value = false
}
defineExpose({
  openDialog,
  closeDialog
})
</script>
</script>
<style>
.dialog-footer{
  text-align: center;
}
</style>
src/views/infomanger/companymanger/index.vue
@@ -41,9 +41,9 @@
      <el-col :span="1.5">
        <el-button type="primary" plain icon="Plus" @click="exportExcel" v-hasPermi="['system:dept:add']">导入</el-button>
      </el-col>
      <el-col :span="1.5">
      <!-- <el-col :span="1.5">
        <el-button type="primary" plain icon="Plus" @click="exportRecordComOpen" v-hasPermi="['system:dept:add']">导入记录</el-button>
      </el-col>
      </el-col> -->
      <!-- <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> -->
    </el-row>
@@ -127,8 +127,8 @@
        </div>
      </template>
    </el-dialog>
    <exportExcelCom ref="exporttem"></exportExcelCom>
    <exportRecord ref="exportRecordCom"></exportRecord>
    <exportExcelCom ref="exporttem" @resList="resList"></exportExcelCom>
    <exportRecord ref="exportRecordCom" :recordRow="recordRow"></exportRecord>
  </div>
</template>
@@ -223,7 +223,7 @@
// const dispDeptType = computed(() => (e) => {
//   return dept_type.value.find((f) => f.value == e).label;
// });
const recordRow = ref([])
/** 查询企业列表 */
function getList() {
  loading.value = true;
@@ -326,5 +326,9 @@
function exportRecordComOpen() {
  exportRecordCom.value.openDialog()
}
function resList(row) {
  recordRow.value = row
  exportRecordCom.value.openDialog()
}
getList();
</script>
src/views/infomanger/policy/components/addNews.vue
@@ -1,32 +1,72 @@
<!-- 新增政策 -->
<template>
  <el-dialog title="用户导入" v-model="dialogVisible" width="600px" append-to-body @close="closeDialog">
    <el-form>
      <el-form-item>
        <el-select>
          <el-option></el-option>
  <el-dialog title="惠企政策" v-model="dialogVisible" width="900px" append-to-body @close="closeDialog">
    <div style="padding: 0 20px;">
      <el-form :mode="form" :rules="rules">
      <el-form-item label="政策类型" prop="docType">
        <el-select v-model="form.docType" placeholder="请选择" style="width: 200px">
          <el-option v-for="(item,index) in policyList" :label="item.label" :value="item.value"></el-option>
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-input></el-input>
      <el-form-item label="政策名称" prop="docName">
        <el-input v-model="form.docTitle" placeholder="请输入政策名称"></el-input>
      </el-form-item>
      <el-form-item>
        <div>内容</div>
      <el-form-item label="政策内容" prop="docContent">
        <div><editPolicy v-model="form.docContent"></editPolicy></div>
      </el-form-item>
      <el-form-item label="状态" prop="docStatus">
        <el-switch v-model="form.docStatus"></el-switch>
      <el-form-item label="状态" >
        <el-switch v-model="form.docStatus" :active-value="0" :inactive-value="1"></el-switch>
      </el-form-item>
    </el-form>
    </div>
    <template v-slot:footer>
      <el-button type="primary" @click="addDoc">确认</el-button>
      <el-button @click="closeDialog">取消</el-button>
    </template>
</el-dialog>
</template>
<script>
import editPolicy from '@/components/Editor/index'
import { addDoc, updDoc } from '@/api/system/company/company'
export default {
  components: {
    editPolicy
  },
  props: {
    policyList: {
      type: Array,
      default: () => {
        return []
      }
    }
  },
  data() {
    return {
      dialogVisible: false,
      form: {
        docStatus: 0
      },
      rules: {
        docType:[{
          required: true,
          message: '请输入政策名称',
          trigger: 'blur'
        }],
        docName: [
          {
            required: true,
            message: '请输入政策名称',
            trigger: 'blur'
          }
        ],
        docContent: [
          {
            required: true,
            message: '请输入政策内容',
            trigger: 'blur'
          }
        ]
      }
    }
  },
@@ -34,8 +74,32 @@
    closeDialog() {
      this.dialogVisible = false
    },
    openDialog() {
    openDialog(row) {
      if(row) {
        this.form = row
        this.form.docContent = decodeURIComponent(row.docContent)
      } else {
        this.form = {
          docStatus: 0
        }
      }
      this.dialogVisible = true
    },
    addDoc() {
      this.form.docContent = encodeURIComponent(this.form.docContent)
      if(this.form.docId) {
        updDoc(this.form).then(val => {
        this.$message.success('添加成功')
        this.closeDialog()
        this.$emit('upload')
      })
      } else {
        addDoc(this.form).then(val => {
        this.$message.success('添加成功')
        this.closeDialog()
        this.$emit('upload')
      })
      }
    }
  }
}
src/views/infomanger/policy/index.vue
@@ -24,22 +24,33 @@
        <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['system:dept:add']">新增</el-button>
      </el-col>
    </el-row>
    <el-table :data="deptList">
      <el-table-column label="政策名称"></el-table-column>
      <el-table-column label="政策类型"></el-table-column>
      <el-table-column label="创建时间"></el-table-column>
    <el-table :data="tableData" v-loading="loading" border>
      <el-table-column label="政策名称" prop="docTitle"></el-table-column>
      <el-table-column label="政策类型" prop="docType"></el-table-column>
      <el-table-column label="创建时间" ></el-table-column>
      <el-table-column label="创建人" width="200"></el-table-column>
      <el-table-column label="状态" width="200"></el-table-column>
      <el-table-column label="操作"></el-table-column>
      <el-table-column label="状态" width="200" prop="docStatus">
        <template #default="scope">
          <el-switch v-if="scope.row.docId" v-model="scope.row.docStatus" :active-value="0" :inactive-value="1" @change="changeStatus(scope.row)"></el-switch>
        </template>
      </el-table-column>
      <el-table-column label="操作">
        <template #default="scope">
          <el-link type="primary" @click="handleAdd(scope.row)">编辑</el-link>
          <el-divider direction="vertical" />
          <el-link type="primary" @click="delData(scope.row)">删除</el-link>
        </template>
      </el-table-column>
    </el-table>
    <pagination v-show="queryParams.total > 0" :total="queryParams.total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
      <addNews ref="addnews"></addNews>
      <addNews ref="addnews" :policyList="policyList" @upload="getList"></addNews>
   </div>
</template>
<script>
import { docList } from '@/api/system/company/company'
import { docList,updDoc, delDoc } from '@/api/system/company/company'
import addNews from './components/addNews'
import { ElMessageBox } from 'element-plus'
export default {
  components: {
    addNews
@@ -67,10 +78,12 @@
        pageNum: 1,
        pageSize: 10
      },
      tableData: []
      tableData: [],
      loading: false
    }
  },
  mounted() {
  created() {
    this.loading = true
    this.getList()
  },
  methods: {
@@ -79,6 +92,7 @@
      docList(this.queryParams).then(res => {
        this.tableData = res.rows
        this.queryParams.total = res.total
        this.loading = false
      })
    },
    // 搜索
@@ -86,8 +100,31 @@
      this.queryParams.pageNum = 1
      this.getList()
   },
   handleAdd() {
    this.$refs.addnews.openDialog()
   handleAdd(row) {
    this.$refs.addnews.openDialog(row)
   },
   changeStatus(row) {
    if(this.loading){
      return
    }
    updDoc(row).then(val => {
      this.$message.success('修改成功')
      this.getList()
    })
   },
   delData(row) {
    ElMessageBox({
      type: 'warning',
      message: '确认删除该政策?',
      title: '提示',
      cancelButtonText: '取消',
    }).then(val => {
      delDoc({delId: row.docId}).then(val => {
        this.$message.success('删除成功')
        this.getList()
      })
    })
   }
  }
}