| | |
| | | # 页面标题
|
| | | VITE_APP_TITLE = 入企扫码
|
| | | VITE_APP_TITLE = 惠企执法
|
| | |
|
| | | # 开发环境配置
|
| | | VITE_APP_ENV = 'development'
|
| | |
|
| | | VITE_APP_BASE = 'http://172.16.61.34:8089'
|
| | | # VITE_APP_BASE = 'http://172.16.61.31:8089'
|
| | | VITE_APP_BASE = 'http://172.16.60.184:8089'
|
| | | # VITE_APP_BASE = 'http://172.16.61.34:8089'
|
| | | #VITE_APP_BASE = 'http://localhost:8089'
|
| | |
|
| | |
| | | <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" />
|
| | | <!-- <link rel="icon" href="/logo.ico" /> -->
|
| | | <title>惠企执法</title>
|
| | | <script src='//webapi.amap.com/maps?v=2.0&key=a3472b04ae282cabb61670b13c7b90ab' type="text/javascript"></script>
|
| | | <script src="//webapi.amap.com/ui/1.1/main.js"></script>
|
| | | <!--[if lt IE 11
|
| | | ]><script>
|
| | | window.location.href = "/html/ie.html";
|
| | |
| | | method: 'get', |
| | | params: data |
| | | }) |
| | | } |
| | | // /enforce/company/log/list |
| | | export function listCompanyLog(data) { |
| | | return request({ |
| | | url: `/enforce/company/log/list`, |
| | | method: 'get', |
| | | params: data |
| | | }) |
| | | } |
| | | // /enforce/company/log/upd |
| | | export function updCompanyLog(data) { |
| | | return request({ |
| | | url: `/enforce/company/log/upd`, |
| | | method: 'post', |
| | | data: data |
| | | }) |
| | | } |
| | | // /enforce/company/log/{ids} |
| | | export function delCompanyLog(data) { |
| | | return request({ |
| | | url: `/enforce/company/log/${data.delId}`, |
| | | method: 'DELETE', |
| | | }) |
| | | } |
| | |
| | |
|
| | | NProgress.configure({ showSpinner: false });
|
| | |
|
| | | const whiteList = ["/login", "/register"];
|
| | | const whiteList = ["/login", "/register", "/main"];
|
| | |
|
| | | router.beforeEach((to, from, next) => {
|
| | | NProgress.start();
|
| | |
| | | import { createWebHistory, createRouter, RouteRecordRaw } from "vue-router";
|
| | | /* Layout */
|
| | | import Layout from "@/layout/index.vue";
|
| | | import path from "path";
|
| | |
|
| | | /**
|
| | | * Note: 路由配置项
|
| | |
| | | hidden: true,
|
| | | },
|
| | | {
|
| | | path: '/main',
|
| | | component: () => import("@/views/main/indexMarge.vue"),
|
| | | },
|
| | | {
|
| | | path: "",
|
| | | component: Layout,
|
| | | redirect: "/home",
|
New file |
| | |
| | | <template> |
| | | <el-dialog title="二维码" v-model="dialogVisible" width="300px" @close="closeDialog"> |
| | | <div class="text-center"> |
| | | <vueQr ref="query" background="#fff" :text="info.companyCode"></vueQr> |
| | | <div style="font-weight: bold;margin-bottom: 10px;">沈丘惠企执法</div> |
| | | |
| | | <div>{{ info.companyName }}</div> |
| | | <div style="margin-top: 10px;"> |
| | | <el-link @click="downImage" type="primary">下载企业码</el-link> |
| | | </div> |
| | | </div> |
| | | <canvas ref="canvasRef" style="position: absolute; left: 0; top: 2210px;background-color: white; display: none;"></canvas> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import vueQr from 'vue-qr/src/packages/vue-qr.vue' |
| | | let dialogVisible = ref(false) |
| | | const canvasRef = ref() |
| | | const info = ref({}) |
| | | const query = ref() |
| | | function openDialog(row) { |
| | | // console.log(row) |
| | | info.value = row |
| | | dialogVisible.value = true |
| | | } |
| | | function closeDialog() { |
| | | dialogVisible.value = false |
| | | } |
| | | function downImage() { |
| | | drawText() |
| | | const imageUrl = canvasRef.value.toDataURL('image/png') |
| | | // console.log(query.value.imgUrl) |
| | | let aLink = document.createElement('a') |
| | | let blob = base64ToBlob(imageUrl) |
| | | let evt = document.createEvent("HTMLEvents") |
| | | evt.initEvent("click", true, true) // initEvent 不加后两个参数在FF下会报错 事件类型,是否冒泡,是否阻止浏览器的默认行为 |
| | | aLink.download = "二维码.png" |
| | | aLink.href = URL.createObjectURL(blob); |
| | | // aLink.dispatchEvent(evt); |
| | | aLink.click() |
| | | } |
| | | function drawText() { |
| | | const canvas = canvasRef.value; |
| | | canvas.width = 350; |
| | | canvas.height = 380; |
| | | canvas.style.width = '350px'; |
| | | canvas.style.height = '380px'; |
| | | const ctx = canvas.getContext('2d'); |
| | | ctx.fillStyle = "#fff" |
| | | ctx.fillRect(0, 0, canvas.width, canvas.height); |
| | | let img = new Image(); |
| | | img.src = query.value.imgUrl; |
| | | const text = info.value.companyName; |
| | | |
| | | ctx.drawImage(img, 10, 0, 320, 320); |
| | | // ctx.font = '20px Arial'; |
| | | ctx.textAlign = 'center'; |
| | | ctx.fillStyle = '#000'; |
| | | // ctx.setFontWeight('bold') |
| | | ctx.font ='bold 20px Arial' |
| | | wrapText(ctx, "沈丘惠企执法", 180, 320, 350, 40) |
| | | // ctx.setFontWeight('normal') |
| | | ctx.font ="20px Arial" |
| | | wrapText(ctx, text, 180, 350, 350, 20) |
| | | } |
| | | function wrapText(context, text, x, y, maxWidth, lineHeight) { |
| | | var words = text.split(''); |
| | | var line = ''; |
| | | for(var n = 0; n < words.length; n++) { |
| | | var testLine = line + words[n] + ' '; |
| | | var metrics = context.measureText(testLine); |
| | | var testWidth = metrics.width; |
| | | if (testWidth > maxWidth && n > 0) { |
| | | context.fillText(line, x, y); |
| | | line = words[n] + ' '; |
| | | y += lineHeight; |
| | | } |
| | | else { |
| | | line = testLine; |
| | | } |
| | | } |
| | | if(line) { |
| | | context.fillText(line, x, y); |
| | | } |
| | | } |
| | | function base64ToBlob(code) { |
| | | let parts = code.split(';base64,') |
| | | let contentType = parts[0].split(':')[1] |
| | | let raw = window.atob(parts[1]) |
| | | let rawLength = raw.length |
| | | let uInt8Array = new Uint8Array(rawLength) |
| | | for (let i = 0; i < rawLength; ++i) { |
| | | uInt8Array[i] = raw.charCodeAt(i) |
| | | } |
| | | return new Blob([uInt8Array], {type: contentType}) |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | closeDialog |
| | | }) |
| | | </script> |
| | | |
| | | <style> |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <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" @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/handlerImport.vue' |
| | | import { download as downloadHttp} from '@/utils/request' |
| | | import { downTemplate, importTemplate, doImport, exportTemplate } from '@/api/system/company/company' |
| | | const { proxy } = getCurrentInstance(); |
| | | const dialogVisible = ref(false) |
| | | const emit = defineEmits() |
| | | const form = reactive({ |
| | | exportNews: {} |
| | | }) |
| | | function openDialog() { |
| | | dialogVisible.value = true |
| | | } |
| | | |
| | | function cloaseDialog() { |
| | | dialogVisible.value = false |
| | | } |
| | | function downLoad() { |
| | | exportTemplate().then(val => { |
| | | downloadHttp('/tool/file/download', { |
| | | fileName: val.msg, |
| | | delete: true |
| | | }, "企业信息模板.xlsx") |
| | | }) |
| | | } |
| | | function startExport() { |
| | | uploadFile() |
| | | } |
| | | function resList(row) { |
| | | cloaseDialog() |
| | | emit('resList', row) |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | cloaseDialog |
| | | }) |
| | | </script> |
| | | <style scoped> |
| | | .dialog-footer button:first-child { |
| | | margin-right: 10px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-dialog title="导入记录" v-model="dialogVisible" width="1200px" append-to-body @close="closeDialog" |
| | | > |
| | | <el-table :data="recordValue" border> |
| | | <el-table-column label="企业名(企业全称)" prop="companyName"> |
| | | <template #default="scope"> |
| | | <div class="flex-box-per"> |
| | | <el-input v-model="scope.row.companyName" @blur="checkImport(scope.row, scope.$index)"></el-input> |
| | | <el-tooltip v-if="scope.row.errorList.length && scope.row.errorList.find(item => item.index == 0)" :content="scope.row.errorList.find(item => item.index == 0).msg"> |
| | | <div class="ml5"> |
| | | <el-icon size="large" color="red" class="ml5"><CircleCloseFilled /></el-icon> |
| | | </div> |
| | | </el-tooltip> |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="统一社会信用代码" prop="companyCode"> |
| | | <template #default="scope"> |
| | | <div class="flex-box-per"> |
| | | <el-input v-model="scope.row.companyCode" @blur="checkImport(scope.row, scope.$index)"></el-input> |
| | | <el-tooltip v-if="scope.row.errorList.length && scope.row.errorList.find(item => item.index == 1)" :content="scope.row.errorList.find(item => item.index == 1).msg"> |
| | | <div class="ml5"> |
| | | <el-icon size="large" color="red" class="ml5"><CircleCloseFilled /></el-icon> |
| | | </div> |
| | | </el-tooltip> |
| | | |
| | | </div> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="企业联系人" prop="companyUser"> |
| | | <template #default="scope"> |
| | | <div class="flex-box-per"> |
| | | <el-input v-model="scope.row.companyUser" @blur="checkImport(scope.row, scope.$index)"></el-input> |
| | | <el-tooltip v-if="scope.row.errorList.length && scope.row.errorList.find(item => item.index == 2)" :content="scope.row.errorList.find(item => item.index == 2).msg"> |
| | | <div class="ml5" v-if="scope.row.errorList.length &&scope.row.errorList.find(item => item.index == 2)"> |
| | | <el-icon size="large" color="red" class="ml5"><CircleCloseFilled /></el-icon> |
| | | </div> |
| | | </el-tooltip> |
| | | |
| | | </div> |
| | | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="联系人电话" prop="companyPhone"> |
| | | <template #default="scope"> |
| | | <div class="flex-box-per"> |
| | | <el-input type="numer" :maxlength="11" v-model="scope.row.companyPhone" @blur="checkImport(scope.row, scope.$index, 'companyPhone')"></el-input> |
| | | <el-tooltip v-if="scope.row.errorList.length && scope.row.errorList.find(item => item.index == 3)" :content="scope.row.errorList.find(item => item.index == 3).msg"> |
| | | <div class="ml5"> |
| | | <el-icon size="large" color="red" class="ml5"><CircleCloseFilled /></el-icon> |
| | | </div> |
| | | </el-tooltip> |
| | | |
| | | </div> |
| | | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="企业地址" prop="companyAddress"> |
| | | <template #default="scope"> |
| | | <div class="flex-box-per"> |
| | | <el-input v-model="scope.row.companyAddress" @blur="checkImport(scope.row, scope.$index)"></el-input> |
| | | <el-tooltip v-if="scope.row.errorList.length && scope.row.errorList.find(item => item.index == 4)" :content="scope.row.errorList.find(item => item.index == 4).msg"> |
| | | <div class="ml5" v-if="scope.row.errorList.length && scope.row.errorList.find(item => item.index == 4)"> |
| | | <el-icon size="large" color="red" class="ml5"><CircleCloseFilled /></el-icon> |
| | | </div> |
| | | </el-tooltip> |
| | | </div> |
| | | |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="备注" prop="mark"> |
| | | <template #default="scope"> |
| | | <div class="flex-box-per"> |
| | | <el-input v-model="scope.row.mark" @blur="checkImport(scope.row, scope.$index)"></el-input> |
| | | <el-tooltip v-if="scope.row.errorList.length && scope.row.errorList.find(item => item.index == 5)" :content="scope.row.errorList.find(item => item.index == 5).msg"> |
| | | <div class="ml5"> |
| | | <el-icon size="large" color="red" class="ml5"><CircleCloseFilled /></el-icon> |
| | | </div> |
| | | </el-tooltip> |
| | | |
| | | </div> |
| | | |
| | | </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 { checkImport as checkImportHttp, saveImport } from '@/api/system/company/company' |
| | | import { ElMessage} from 'element-plus' |
| | | const dialogVisible = ref(false) |
| | | const emits = defineEmits() |
| | | 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 closeDialog() { |
| | | dialogVisible.value = false |
| | | } |
| | | function checkImport(row, index, item) { |
| | | // row.companyPhone |
| | | if(item && item == 'companyPhone') { |
| | | if(row.companyPhone) { |
| | | const reg = /^1[3|4|5|6|7|8|9][0-9]\d{8}$/ |
| | | if(!reg.test(row.companyPhone)){ |
| | | ElMessage.error('请输入正确的手机号') |
| | | } |
| | | } |
| | | } |
| | | checkImportHttp({voList: [row]}).then(val => { |
| | | // recordValue.value.splice(index, 1, val.data.voList[0]) |
| | | recordValue.value[index] = val.data.voList[0] |
| | | // ElMessage.success('修改成功') |
| | | }) |
| | | } |
| | | function addCompany() { |
| | | saveImport({voList: recordValue.value}).then(val =>{ |
| | | ElMessage.success('导入成功') |
| | | closeDialog() |
| | | emits('uploadList') |
| | | }) |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | closeDialog |
| | | }) |
| | | </script> |
| | | <style > |
| | | .dialog-footer{ |
| | | text-align: center; |
| | | } |
| | | .flex-box-per{ |
| | | display: flex; |
| | | justify-content: flex-start; |
| | | align-items: center; |
| | | } |
| | | .ml5{ |
| | | /* margin-left: 5px; */ |
| | | line-height: 15px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-dialog title="审核" v-model="dialogVisible" width="900px" append-to-body @close="cloaseDialog" |
| | | > |
| | | <el-form> |
| | | <!-- <el-form-item label="审核类型"> |
| | | <el-select style="width: 200px;" v-model="form.checkType"> |
| | | <el-option label="企业审批" value="1"></el-option> |
| | | <el-option label="企业审批" value="2"></el-option> |
| | | </el-select> |
| | | </el-form-item> --> |
| | | <el-form-item label="审核状态"> |
| | | <el-radio-group v-model="form.checkStatus" class="ml-4"> |
| | | <el-radio value="1" size="large">通过</el-radio> |
| | | <el-radio value="-1" size="large">拒绝</el-radio> |
| | | </el-radio-group> |
| | | </el-form-item> |
| | | <el-form-item label="审核说明"> |
| | | <el-input type="textarea" v-model="form.checkReason" ></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div style="text-align: center;"> |
| | | <el-button @click="cloaseDialog" >关闭</el-button> |
| | | <el-button @click="checkOrder" type="primary">确认</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { checkOrder as httpCheck } from '@/api/system/company/company' |
| | | import { ElMessage } from 'element-plus' |
| | | const dialogVisible = ref(false) |
| | | const info = ref({}) |
| | | const emit:any = defineEmits() |
| | | const form: any = reactive({ |
| | | checkStatus: '1' |
| | | }) |
| | | const cloaseDialog = () => { |
| | | dialogVisible.value = false |
| | | } |
| | | const openDialog = (row: { companyId?: any }) => { |
| | | info.value = row |
| | | form['ids'] = [row.companyId] |
| | | form['checkType'] = 1 |
| | | form['checkReason'] = '' |
| | | dialogVisible.value = true |
| | | } |
| | | function checkOrder() { |
| | | if(!form['checkStatus']) { |
| | | ElMessage.error('请填写审核状态') |
| | | return |
| | | } |
| | | if(form['checkStatus'] == -1 && !form.checkReason) { |
| | | ElMessage.error('请填写审核说明') |
| | | return |
| | | } |
| | | httpCheck(form).then(res => { |
| | | cloaseDialog() |
| | | emit('upload') |
| | | }) |
| | | } |
| | | defineExpose({ |
| | | openDialog, |
| | | cloaseDialog |
| | | }) |
| | | </script> |
New file |
| | |
| | | <template> |
| | | <div class="app-container"> |
| | | <el-form :model="queryParams" ref="queryRef" class="evenly-distributed-labels" :inline="true" v-show="showSearch" label-width="80px" label-position="left"> |
| | | <el-form-item label="企业名称" prop="companyName"> |
| | | <el-input v-model="queryParams.companyName" placeholder="请输入企业名称" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="联系人" prop="companyUser"> |
| | | <el-input v-model="queryParams.companyUser" placeholder="请输入联系人" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item label="手机号" prop="companyPhone"> |
| | | <el-input v-model="queryParams.companyPhone" type="number" placeholder="请输入手机号" clearable style="width: 200px" @keyup.enter="handleQuery" /> |
| | | </el-form-item> |
| | | <el-form-item> |
| | | <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> |
| | | <el-button icon="Refresh" @click="resetQuery">重置</el-button> |
| | | </el-form-item> |
| | | </el-form> |
| | | <el-table |
| | | v-if="refreshTable" |
| | | v-loading="loading" |
| | | :data="deptList" |
| | | row-key="deptId" |
| | | :default-expand-all="isExpandAll" |
| | | :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" |
| | | > |
| | | <el-table-column prop="companyName" label="企业名称" minWidth="300"></el-table-column> |
| | | <!-- <el-table-column prop="companyName" label="企业类型" width="200"></el-table-column> --> |
| | | <el-table-column prop="companyUser" label="联系人" width="180"></el-table-column> |
| | | <el-table-column prop="companyPhone" label="手机号码" width="120"></el-table-column> |
| | | <el-table-column prop="comeTime" label="创建时间" width="200"></el-table-column> |
| | | <el-table-column prop="comeContent" label="来访事项" width="200"></el-table-column> |
| | | <el-table-column prop="userNum" label="随行人数" width="200"></el-table-column> |
| | | <el-table-column prop="remark" label="备注" ></el-table-column> |
| | | <el-table-column label="操作" align="center" fixed="right" class-name="small-padding fixed-width" width="240"> |
| | | <template #default="scope"> |
| | | <el-link type="success" v-if="scope.row.checkStatus < 2" v-hasPermi="['sys:company:check']" @click="checkJudge(scope.row)">审核</el-link> |
| | | <el-divider direction="vertical" v-hasPermi="['sys:company:check']" v-if="scope.row.checkStatus < 2"/> |
| | | <el-link type="info" v-if="scope.row.checkStatus == 2" @click="createQrcodeHandler(scope.row)">二维码</el-link> |
| | | <el-divider direction="vertical" v-if="scope.row.checkStatus == 2"/> |
| | | <el-link type="primary" @click="handleAdd(scope.row)">编辑</el-link> |
| | | <el-divider direction="vertical" /> |
| | | <el-link type="error" @click="handleDelete(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" /> |
| | | |
| | | <!-- 添加或修改对话框 --> |
| | | <el-dialog :title="title" v-model="open" width="600px" append-to-body> |
| | | <el-form ref="deptRef" :model="form" :rules="rules" label-width="140px"> |
| | | <el-form-item label="企业名称" prop="companyName"> |
| | | <el-input placeholder="请输入企业名称" v-model="form.companyName"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="联系人" prop="companyUser"> |
| | | <el-input placeholder="请输入联系人" v-model="form.companyUser"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="手机号码" prop="companyPhone"> |
| | | <el-input placeholder="请输入手机号码" v-model="form.companyPhone"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="来访人员" prop="comeUser"> |
| | | <el-input placeholder="请输入" v-model="form.comeUser"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="来访事项" prop="comeContent"> |
| | | <el-input placeholder="请输入" v-model="form.comeContent"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="随行人数" prop="userNum"> |
| | | <el-input placeholder="请输入" v-model="form.userNum"></el-input> |
| | | </el-form-item> |
| | | <el-form-item label="备注"> |
| | | <el-input placeholder="请输入备注" v-model="form.remark"></el-input> |
| | | </el-form-item> |
| | | </el-form> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="submitForm">确 定</el-button> |
| | | <el-button @click="cancel">取 消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | <exportExcelCom ref="exporttem" @resList="resList"></exportExcelCom> |
| | | <exportRecord ref="exportRecordCom" :recordRow="recordRow" @uploadList="getList"></exportRecord> |
| | | <judgeCom ref="judgeComRef" @upload="getList"></judgeCom> |
| | | <createQrcode ref="createQrcodeRef"></createQrcode> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup name="Dept"> |
| | | import FileUpload from '@/components/ImageUpload/index' |
| | | import exportRecord from './components/exportRecord' |
| | | import createQrcode from './components/createQrcode' |
| | | import judgeCom from './components/judge' |
| | | import { listCompanyLog,addCompany, updStatus, delCompanyLog, updCompanyLog } from "@/api/system/company/company"; |
| | | import exportExcelCom from './components/export' |
| | | import { computed } from "vue"; |
| | | import { judgeStatus, companyStatus, scopeList } from '@/utils/mapList/index.ts' |
| | | import useSettingsStore from "@/store/modules/settings"; |
| | | const thcolor = computed(() => useSettingsStore().theme); |
| | | const { proxy } = getCurrentInstance(); |
| | | const { sys_normal_disable } = proxy.useDict("sys_normal_disable"); |
| | | const deptList = ref([]); |
| | | const open = ref(false); |
| | | const loading = ref(true); |
| | | const showSearch = ref(true); |
| | | const title = ref(""); |
| | | const deptOptions = ref([]); |
| | | const isExpandAll = ref(false); |
| | | const refreshTable = ref(true); |
| | | const exporttem = ref() |
| | | const exportRecordCom = ref() |
| | | const judgeComRef = ref() |
| | | const createQrcodeRef = ref() |
| | | const options = reactive({ |
| | | // -1拒绝,0待审批,1审批中,2通过 |
| | | checkOptions: [ |
| | | { |
| | | label: '拒绝', |
| | | value: -1 |
| | | }, |
| | | { |
| | | label: '待审批', |
| | | value: 0 |
| | | }, |
| | | { |
| | | label: '审批中', |
| | | value: 1 |
| | | }, |
| | | { |
| | | label: '通过', |
| | | value: 2 |
| | | } |
| | | ], |
| | | companyStatus: [ |
| | | { |
| | | label: '正常', |
| | | value: 0 |
| | | }, |
| | | { |
| | | label: '禁用', |
| | | value: 1 |
| | | }, |
| | | ], |
| | | socreList: [ |
| | | { |
| | | label: '导入', |
| | | value: 1 |
| | | }, |
| | | { |
| | | label: '注册', |
| | | value: 0 |
| | | }, |
| | | ] |
| | | }) |
| | | const data = reactive({ |
| | | form: {}, |
| | | queryParams: { |
| | | deptName: undefined, |
| | | status: undefined, |
| | | deptType: undefined, |
| | | pageNum: 1, |
| | | pageSize: 10, |
| | | total: 1 |
| | | }, |
| | | rules: { |
| | | companyName: [{ required: true, message: "企业名称不能为空", trigger: "blur" }], |
| | | companyUser: [{ required: true, message: "联系人不能为空", trigger: "blur" }], |
| | | companyPhone: [{ required: true, message: "手机号码不能为空", trigger: "blur" }, { |
| | | pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" |
| | | }], |
| | | companyCode: [{ required: true, message: "统一社会信用代码不能为空", trigger: "blur" }], |
| | | companyImg: [{ required: true, message: "营业执照不能为空", trigger: "blur" }], |
| | | companyAddress: [{ required: true, message: "企业地址不能为空", trigger: "blur" }], |
| | | |
| | | // email: [{ type: "email", message: "请输入正确的邮箱地址", trigger: ["blur", "change"] }], |
| | | // phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "请输入正确的手机号码", trigger: "blur" }], |
| | | }, |
| | | }); |
| | | |
| | | const { queryParams, form, rules } = toRefs(data); |
| | | // const dispDeptType = computed(() => (e) => { |
| | | // return dept_type.value.find((f) => f.value == e).label; |
| | | // }); |
| | | const recordRow = ref([]) |
| | | /** 查询企业列表 */ |
| | | function getList() { |
| | | loading.value = true; |
| | | listCompanyLog(queryParams.value).then((response) => { |
| | | deptList.value = response.rows |
| | | data.queryParams.total = response.total |
| | | loading.value = false; |
| | | }); |
| | | } |
| | | /** 取消按钮 */ |
| | | function cancel() { |
| | | open.value = false; |
| | | reset(); |
| | | getList(); |
| | | } |
| | | /** 表单重置 */ |
| | | function reset() { |
| | | form.value = { |
| | | deptId: undefined, |
| | | parentId: undefined, |
| | | deptName: undefined, |
| | | orderNum: 0, |
| | | leader: undefined, |
| | | phone: undefined, |
| | | email: undefined, |
| | | status: "0", |
| | | deptType: undefined, |
| | | }; |
| | | proxy.resetForm("deptRef"); |
| | | } |
| | | const queryRef = ref() |
| | | /** 搜索按钮操作 */ |
| | | function handleQuery() { |
| | | getList(); |
| | | } |
| | | /** 重置按钮操作 */ |
| | | function resetQuery() { |
| | | queryRef.value.resetFields(); |
| | | handleQuery(); |
| | | } |
| | | /** 新增按钮操作 */ |
| | | function handleAdd(row) { |
| | | if(row) { |
| | | form.value = row |
| | | title.value = "编辑企业"; |
| | | } else { |
| | | form.value = { |
| | | companyStatus: 0 |
| | | } |
| | | title.value = "添加企业"; |
| | | } |
| | | open.value = true; |
| | | } |
| | | |
| | | /** 提交按钮 */ |
| | | function submitForm() { |
| | | proxy.$refs["deptRef"].validate((valid) => { |
| | | if (valid) { |
| | | if (form.value.companyId != undefined) { |
| | | updCompanyLog(form.value).then((response) => { |
| | | proxy.$modal.msgSuccess("修改成功"); |
| | | open.value = false; |
| | | getList(); |
| | | }); |
| | | } else { |
| | | addCompany(form.value).then((response) => { |
| | | proxy.$modal.msgSuccess("新增成功"); |
| | | open.value = false; |
| | | getList(); |
| | | }); |
| | | } |
| | | } |
| | | }); |
| | | } |
| | | /** 删除按钮操作 */ |
| | | function handleDelete(row) { |
| | | proxy.$modal |
| | | .confirm('是否确认删除该数据?') |
| | | .then(function () { |
| | | return delCompanyLog({delId: row.id}); |
| | | }) |
| | | .then(() => { |
| | | getList(); |
| | | proxy.$modal.msgSuccess("删除成功"); |
| | | }) |
| | | .catch(() => {}); |
| | | } |
| | | // 修改企业信息 |
| | | function changeCompanyNews(row, event) { |
| | | if(loading.value){ |
| | | return |
| | | } |
| | | updStatus(row).then(val => { |
| | | proxy.$modal.msgSuccess("修改成功"); |
| | | getList(); |
| | | }) |
| | | } |
| | | // 导入模板 |
| | | function exportExcel() { |
| | | exporttem.value.openDialog() |
| | | } |
| | | // 导入记录 |
| | | function exportRecordComOpen() { |
| | | exportRecordCom.value.openDialog() |
| | | } |
| | | function resList(row) { |
| | | recordRow.value = row |
| | | exportRecordCom.value.openDialog() |
| | | } |
| | | function checkJudge(row) { |
| | | judgeComRef.value.openDialog(row) |
| | | } |
| | | function createQrcodeHandler(row) { |
| | | createQrcodeRef.value.openDialog(row) |
| | | } |
| | | getList(); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .evenly-distributed-labels { |
| | | :deep(){ |
| | | .el-form-item__label { |
| | | position: relative; /* 设置相对定位作为星号的定位基准 */ |
| | | text-align: justify; |
| | | text-align-last: justify; /* 确保最后一行也两端对齐 */ |
| | | padding-left: 10px; /* 为星号预留空间 */ |
| | | display: inline-block; |
| | | } |
| | | } |
| | | } |
| | | |
| | | |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="select-color"> |
| | | <div class="color red" :class="[selectColor === '#FF0000' ? 'active' : '']" @click="selectColorClick('#FF0000')" /> |
| | | <div |
| | | class="color green" |
| | | :class="[selectColor === '#008000' ? 'active' : '']" |
| | | @click="selectColorClick('#008000')" |
| | | /> |
| | | <div |
| | | class="color yellow" |
| | | :class="[selectColor === '#0000FF' ? 'active' : '']" |
| | | @click="selectColorClick('#0000FF')" |
| | | /> |
| | | <div |
| | | class="gradit-color" |
| | | :style="{ 'background': `linear-gradient(${selectColor}, ${adjustColor(selectColor, 200)})` }" |
| | | /> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | export default { |
| | | props: { |
| | | selectColor: { |
| | | type: String, |
| | | default: '#FF0000' |
| | | } |
| | | }, |
| | | methods: { |
| | | selectColorClick(item) { |
| | | this.$emit('update:selectColor', item) |
| | | this.$emit('changeRender') |
| | | }, |
| | | adjustColor(color, range) { |
| | | let newColor = '#' |
| | | for (let i = 0; i < 3; i++) { |
| | | const hxStr = color.substr(i * 2 + 1, 2) |
| | | let val = parseInt(hxStr, 16) |
| | | val += range |
| | | if (val < 0) val = 0 |
| | | else if (val > 255) val = 255 |
| | | newColor += val.toString(16).padStart(2, '0') |
| | | } |
| | | this.$emit('minColor', newColor) |
| | | return newColor |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style scoped> |
| | | .select-color { |
| | | position: fixed; |
| | | top: 0; |
| | | z-index: 100000; |
| | | padding: 20px; |
| | | } |
| | | |
| | | .title { |
| | | font-size: 26px; |
| | | font-weight: 700; |
| | | margin-bottom: 10px; |
| | | } |
| | | |
| | | .color { |
| | | width: 100px; |
| | | height: 100px; |
| | | margin-bottom: 20px; |
| | | } |
| | | |
| | | .red { |
| | | background-color: red; |
| | | } |
| | | |
| | | .green { |
| | | background-color: green; |
| | | } |
| | | |
| | | .yellow { |
| | | background-color: #0000FF; |
| | | } |
| | | |
| | | .active { |
| | | border: 2px solid #a0a0a0; |
| | | box-shadow: 0 0 10px #232323; |
| | | } |
| | | |
| | | .gradit-color { |
| | | width: 10px; |
| | | height: 200px; |
| | | border-radius: 10px; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <div class="theme-box"> |
| | | <el-select v-model="style" @change="styleChange" size="large"> |
| | | <el-option v-for="(item, index) in styleOptions" :key="index" :label="item.label" :value="item.value" /> |
| | | </el-select> |
| | | </div> |
| | | </template> |
| | | <script> |
| | | export default { |
| | | data() { |
| | | return { |
| | | style: 'dark', |
| | | styleOptions: [ |
| | | { label: '标准', value: 'normal' }, |
| | | { label: '幻影黑', value: 'dark' }, |
| | | { label: '月光银', value: 'light' }, |
| | | { label: '远山黛', value: 'whitesmoke' }, |
| | | { label: '草色青', value: 'fresh' }, |
| | | { label: '雅士灰', value: 'grey' }, |
| | | { label: '涂鸦', value: 'graffiti' }, |
| | | { label: '马卡龙', value: 'macaron' }, |
| | | { label: '靛青蓝', value: 'blue' }, |
| | | { label: '极夜蓝', value: 'darkblue' }, |
| | | { label: '酱籽', value: 'wine' } |
| | | ] |
| | | } |
| | | }, |
| | | methods: { |
| | | styleChange(e) { |
| | | this.$emit('styleChange', e) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | <style> |
| | | .theme-box{ |
| | | position: fixed; |
| | | top: 20px; |
| | | right: 20px; |
| | | z-index: 1000; |
| | | } |
| | | </style> |
New file |
| | |
| | | <template> |
| | | <el-container> |
| | | <selectColor :select-color.sync="selectColor" :min-color="minColor" @changeRender="changeRender" /> |
| | | <themeCom @styleChange="changeStyle" /> |
| | | <el-main style="margin: 0px; padding: 0px"> |
| | | <div id="aMap" :style="{ height: windowHeight - 50 + 'px' }" /> |
| | | </el-main> |
| | | </el-container> |
| | | </template> |
| | | <script> |
| | | const markerContent = ` |
| | | |
| | | <div class="custom-content-marker" onclick="showContent()"> |
| | | <img src="//a.amap.com/jsapi_demos/static/demo-center/icons/dir-via-marker.png"> |
| | | </div>` |
| | | import selectColor from './components/selectColor.vue' |
| | | import themeCom from './components/theme.vue' |
| | | export default { |
| | | name: 'AMap', |
| | | components: { |
| | | selectColor, |
| | | themeCom |
| | | }, |
| | | data() { |
| | | return { |
| | | circleMarker: [], |
| | | recordValue: [], // 记录绘制过的文字 |
| | | adcode: 410000, // 中心行政code |
| | | currentCodeObj: '', // 中心行政code |
| | | map: null, // 地图实例化 |
| | | districtExplorer: null, // 渲染行政区域实例化 |
| | | windowHeight: document.documentElement.clientHeight, |
| | | selectColor: '#FF0000', |
| | | minColor: '', |
| | | provinceData: [ |
| | | { |
| | | 'name': '郑州市', |
| | | 'value': '8.99' |
| | | }, |
| | | { |
| | | 'name': '开封市', |
| | | 'value': '22.84' |
| | | }, |
| | | { |
| | | 'name': '洛阳市', |
| | | 'value': '48.96' |
| | | }, |
| | | { |
| | | 'name': '平顶山市', |
| | | 'value': '79.49' |
| | | }, |
| | | { |
| | | 'name': '安阳市', |
| | | 'value': '37.82' |
| | | }, |
| | | { |
| | | 'name': '鹤壁市', |
| | | 'value': '27.55' |
| | | }, |
| | | { |
| | | 'name': '新乡市', |
| | | 'value': '90.76' |
| | | }, |
| | | { |
| | | 'name': '焦作市', |
| | | 'value': '72.26' |
| | | }, |
| | | { |
| | | 'name': '濮阳市', |
| | | 'value': '14.03' |
| | | }, |
| | | { |
| | | 'name': '许昌市', |
| | | 'value': '32.93' |
| | | }, |
| | | { |
| | | 'name': '漯河市', |
| | | 'value': '57.85' |
| | | }, |
| | | { |
| | | 'name': '三门峡市', |
| | | 'value': '85.35' |
| | | }, |
| | | { |
| | | 'name': '南阳市', |
| | | 'value': '99.59' |
| | | }, |
| | | { |
| | | 'name': '商丘市', |
| | | 'value': '45.33' |
| | | }, |
| | | { |
| | | 'name': '信阳市', |
| | | 'value': '69.38' |
| | | }, |
| | | { |
| | | 'name': '周口市', |
| | | 'value': '65.45' |
| | | }, |
| | | { |
| | | 'name': '驻马店市', |
| | | 'value': '90.25' |
| | | }, |
| | | { |
| | | 'name': '济源市', |
| | | 'value': '88.85' |
| | | } |
| | | ], |
| | | style: 'dark', |
| | | marker: [], |
| | | infoWindow: [], |
| | | // marker: [], |
| | | regionData: { |
| | | type: 'FeatureCollection', |
| | | features: [ |
| | | { |
| | | type: 'Feature', |
| | | geometry: { |
| | | type: 'Polygon', |
| | | coordinates: [ |
| | | [ |
| | | [113.576491, 34.744435], |
| | | [113.605331, 34.768129], |
| | | [113.712447, 34.74782], |
| | | [113.673995, 34.66823], |
| | | [113.601211, 34.687994], |
| | | [113.573745, 34.705495], |
| | | [113.570998, 34.725249] |
| | | ] |
| | | ] |
| | | }, |
| | | properties: {} |
| | | } |
| | | ] |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | | const vm = this |
| | | vm.loadMap() |
| | | }, |
| | | methods: { |
| | | changeStyle(e) { |
| | | this.style = e |
| | | this.loadMap() |
| | | }, |
| | | changeRender() { |
| | | this.loadMap() |
| | | }, |
| | | loadMap() { |
| | | const vm = this |
| | | vm.map = new AMap.Map('aMap', { |
| | | viewMode: '2D', // 默认使用 2D 模式,如果希望使用带有俯仰角的 3D 模式,请设置 viewMode: '3D' |
| | | zoom: 11, // 初始化地图层级 |
| | | center: [113.681999, 34.762029], // 初始化地图中心点 |
| | | mapStyle: 'amap://styles/' + this.style |
| | | }) |
| | | vm.fillCityOrTown() |
| | | }, |
| | | // 加载河南省市县 |
| | | fillCityOrTown() { |
| | | const vm = this |
| | | AMapUI.loadUI(['geo/DistrictExplorer'], function(DistrictExplorer) { |
| | | // 启动页面 |
| | | vm.initPage(DistrictExplorer) |
| | | }) |
| | | }, |
| | | initPage(DistrictExplorer) { |
| | | const vm = this |
| | | // 创建一个实例 |
| | | vm.districtExplorer = new DistrictExplorer({ |
| | | eventSupport: true, // 打开事件支持 |
| | | map: vm.map // 关联的地图实例 |
| | | }) |
| | | // 配置点击事件 |
| | | vm.districtExplorer.on('featureClick', function(e, feature) { |
| | | var props = feature.properties |
| | | // 如果存在子节点 |
| | | vm.recordValue.map(item => { |
| | | item.setMap(null) |
| | | }) |
| | | |
| | | vm.recordValue = [] |
| | | vm.circleMarker.map(item => { |
| | | // item.setMap(null) |
| | | vm.map.remove(item) |
| | | }) |
| | | vm.circleMarker = [] |
| | | if (feature.properties.level === 'district') { |
| | | setTimeout(() => { |
| | | vm.drawMarker(feature.properties.center) |
| | | }, 500) |
| | | vm.initData() |
| | | } |
| | | // if (props.childrenNum > 0) { |
| | | // 切换聚焦区域 |
| | | vm.switch2AreaNode(props.adcode) |
| | | // } |
| | | }) |
| | | // 外部区域被点击 |
| | | vm.districtExplorer.on('outsideClick', function(e) { |
| | | vm.districtExplorer.locatePosition(e.originalEvent.lnglat, function(_error, routeFeatures) { |
| | | vm.recordValue.map(item => { |
| | | item.setMap(null) |
| | | }) |
| | | vm.recordValue = [] |
| | | vm.infoWindow.forEach(element => { |
| | | element.close(vm.map) |
| | | }) |
| | | vm.marker.forEach(element => { |
| | | element.setMap(null) |
| | | }) |
| | | vm.circleMarker.map(item => { |
| | | // item.setMap(null) |
| | | vm.map.remove(item) |
| | | }) |
| | | vm.circleMarker = [] |
| | | if (routeFeatures && routeFeatures.length > 1) { |
| | | // 切换到省级区域 |
| | | vm.switch2AreaNode(routeFeatures[1].properties.adcode) |
| | | } else { |
| | | // 切换到全国 |
| | | vm.switch2AreaNode(100000) |
| | | } |
| | | }, { |
| | | levelLimit: 2 |
| | | }) |
| | | }) |
| | | var adcode = vm.adcode // 全国的区划编码 |
| | | vm.districtExplorer.loadAreaNode(adcode, function(error, areaNode) { |
| | | if (error) { |
| | | console.error(error) |
| | | return |
| | | } |
| | | // 绘制载入的区划节点 |
| | | vm.renderAreaNode(areaNode) |
| | | }) |
| | | }, |
| | | initData(){ |
| | | for (let i = 0; i < this.regionData.features.length; i++) { |
| | | let item = this.regionData.features[i]; |
| | | if(item.geometry.type=='Polygon'){ |
| | | let arr = item.geometry.coordinates |
| | | let polygon = new AMap.Polygon({ |
| | | path: arr, |
| | | fillColor: '#ccebc5', |
| | | strokeOpacity: 1, |
| | | fillOpacity: 0.2,//背景透明度 |
| | | strokeColor: '#2b8cbe', |
| | | strokeWeight: 2, |
| | | strokeStyle: 'dashed', |
| | | strokeDasharray: [5, 5], |
| | | }); |
| | | this.map.add(polygon); |
| | | } |
| | | } |
| | | }, |
| | | getMathRandom() { |
| | | return (Math.random() * 101).toFixed(2) |
| | | }, |
| | | adjustColor(color, range) { |
| | | let newColor = '#' |
| | | for (let i = 0; i < 3; i++) { |
| | | const hxStr = color.substr(i * 2 + 1, 2) |
| | | let val = parseInt(hxStr, 16) |
| | | val += range |
| | | if (val < 0) val = 0 |
| | | else if (val > 255) val = 255 |
| | | newColor += val.toString(16).padStart(2, '0') |
| | | } |
| | | this.$emit('minColor', newColor) |
| | | return newColor |
| | | }, |
| | | renderAreaNode(areaNode) { |
| | | const vm = this |
| | | vm.map.setBounds(areaNode.getBounds(), null, null, true) |
| | | // 清除已有的绘制内容 |
| | | vm.districtExplorer.clearFeaturePolygons() |
| | | var colors = ['#3366cc', '#dc3912', '#ff9900', '#109618', '#990099', '#0099c6', '#dd4477', '#66aa00'] |
| | | // 绘制子区域 |
| | | // const arr = [] |
| | | vm.districtExplorer.renderSubFeatures(areaNode, function(feature, i) { |
| | | // arr.push({ |
| | | // name: feature.properties.name, value: vm.getMathRandom() |
| | | // }) |
| | | // console.log(feature.adcode) // 行政区的areacode |
| | | var fillColor = colors[i % colors.length] |
| | | var strokeColor = colors[colors.length - 1 - i % colors.length] |
| | | const value = vm.provinceData.find(item => item.name === feature.properties.name) |
| | | const color = vm.adjustColor(vm.selectColor, 200) |
| | | const colorValue = vm.getColorBetween(value.value, 0, 100, color, vm.selectColor) |
| | | const fontStyle = { |
| | | 'background-color': 'rgba(0,0,0,0)', |
| | | 'border-width': 0, |
| | | 'font-size': '10px', |
| | | color: '#fff', |
| | | 'text-align': 'center' |
| | | } |
| | | // 定义Text类 |
| | | const text1 = new AMap.Text({ |
| | | text: feature.properties.name, |
| | | position: new AMap.LngLat(feature.properties.center[0], feature.properties.center[1]), |
| | | style: fontStyle |
| | | }) |
| | | // 创建圆形点标记 CircleMarker 实例 |
| | | const circleMarker = new AMap.CircleMarker({ |
| | | center: new AMap.LngLat(feature.properties.center[0], feature.properties.center[1]), |
| | | radius: 4, // 3D视图下,CircleMarker半径不要超过64px |
| | | strokeColor: 'white', |
| | | strokeWeight: 2, |
| | | strokeOpacity: 1, |
| | | fillColor: 'green', |
| | | fillOpacity: 1, |
| | | zIndex: 100000, |
| | | bubble: true, |
| | | cursor: 'pointer', |
| | | clickable: true |
| | | }) |
| | | vm.recordValue.push(text1) |
| | | vm.circleMarker.push(circleMarker) |
| | | vm.map.add(text1) |
| | | vm.map.add(circleMarker) |
| | | return { |
| | | cursor: 'default', |
| | | bubble: true, |
| | | strokeColor: strokeColor, // 线颜色 |
| | | strokeOpacity: 1, // 线透明度 |
| | | strokeWeight: 1, // 线宽 |
| | | fillColor: colorValue, // 填充色 |
| | | fillOpacity: 1 // 填充透明度 |
| | | } |
| | | }) |
| | | // 绘制父区域 |
| | | vm.districtExplorer.renderParentFeature(areaNode, { |
| | | cursor: 'default', |
| | | bubble: true, |
| | | strokeColor: 'black', // 线颜色 |
| | | strokeOpacity: 1, // 线透明度 |
| | | strokeWeight: 1, // 线宽 |
| | | fillColor: areaNode.getSubFeatures().length ? null : colors[0], // 填充色 |
| | | fillOpacity: 0.35 // 填充透明度 |
| | | }) |
| | | // vm. |
| | | |
| | | vm.map.setFitView(vm.districtExplorer.getAllFeaturePolygons()) |
| | | }, |
| | | // 刷新页面 |
| | | switch2AreaNode(adcode, callback) { |
| | | const vm = this |
| | | if (vm.currentCodeObj && ('' + vm.currentCodeObj.getAdcode() === '' + adcode)) { |
| | | return |
| | | } |
| | | vm.loadAreaNode(adcode, function(error, areaNode) { |
| | | if (error) { |
| | | if (callback) { |
| | | callback(error) |
| | | } |
| | | return |
| | | } |
| | | vm.adcode = window.currentAreaNode = areaNode.adcode |
| | | vm.currentCodeObj = window.currentAreaNode = areaNode |
| | | // 设置当前使用的定位用节点 |
| | | vm.districtExplorer.setAreaNodesForLocating([vm.currentCodeObj]) |
| | | vm.refreshAreaNode(areaNode) |
| | | if (callback) { |
| | | callback(null, areaNode) |
| | | } |
| | | }) |
| | | }, |
| | | // 刷新区域边界 |
| | | loadAreaNode(adcode, callback) { |
| | | const vm = this |
| | | vm.districtExplorer.loadAreaNode(adcode, function(error, areaNode) { |
| | | if (error) { |
| | | if (callback) { |
| | | callback(error) |
| | | } |
| | | return |
| | | } |
| | | if (callback) { |
| | | callback(null, areaNode) |
| | | } |
| | | }) |
| | | }, |
| | | refreshAreaNode(areaNode) { |
| | | this.districtExplorer.setHoverFeature(null) |
| | | this.renderAreaPolygons(areaNode) |
| | | }, |
| | | // 绘制某个区域的边界 |
| | | renderAreaPolygons(areaNode) { |
| | | const vm = this |
| | | // 更新地图视野 |
| | | vm.map.setBounds(areaNode.getBounds(), null, null, true) |
| | | // 清除已有的绘制内容 |
| | | vm.districtExplorer.clearFeaturePolygons() |
| | | var colors = ['#3366cc', '#dc3912', '#ff9900', '#109618', '#990099', '#0099c6', '#dd4477', '#66aa00'] |
| | | // 绘制子区域 |
| | | vm.districtExplorer.renderSubFeatures(areaNode, function(feature, i) { |
| | | var fillColor = colors[i % colors.length] |
| | | var strokeColor = colors[colors.length - 1 - i % colors.length] |
| | | const fontStyle = { |
| | | 'background-color': 'rgba(0,0,0,0)', |
| | | 'border-width': 0, |
| | | 'text-align': 'center', |
| | | 'font-size': '14px', |
| | | color: '#fff' |
| | | } |
| | | const text1 = new AMap.Text({ |
| | | text: feature.properties.name, |
| | | position: new AMap.LngLat(feature.properties.center[0], feature.properties.center[1]), |
| | | style: fontStyle |
| | | }) |
| | | vm.recordValue.push(text1) |
| | | |
| | | vm.map.add(text1) |
| | | |
| | | const value = vm.provinceData.find(item => item.name === feature.properties.name) |
| | | if (value && value.value) { |
| | | const color = vm.adjustColor(vm.selectColor, 200) |
| | | fillColor = vm.getColorBetween(value.value, 0, 100, color, vm.selectColor) |
| | | } |
| | | // 创建圆形点标记 CircleMarker 实例 |
| | | const circleMarker = new AMap.CircleMarker({ |
| | | center: new AMap.LngLat(feature.properties.center[0], feature.properties.center[1]), |
| | | radius: 4, // 3D视图下,CircleMarker半径不要超过64px |
| | | strokeColor: 'white', |
| | | strokeWeight: 2, |
| | | strokeOpacity: 1, |
| | | fillColor: 'green', |
| | | fillOpacity: 1, |
| | | zIndex: 100000, |
| | | bubble: true, |
| | | cursor: 'pointer', |
| | | clickable: true |
| | | }) |
| | | vm.circleMarker.push(circleMarker) |
| | | vm.map.add(circleMarker) |
| | | return { |
| | | cursor: 'default', |
| | | bubble: true, |
| | | strokeColor: strokeColor, // 线颜色 |
| | | strokeOpacity: 1, // 线透明度 |
| | | strokeWeight: 1, // 线宽 |
| | | fillColor: fillColor, // 填充色 |
| | | fillOpacity: 1 // 填充透明度 |
| | | } |
| | | }) |
| | | |
| | | // 绘制父区域 |
| | | vm.districtExplorer.renderParentFeature(areaNode, { |
| | | cursor: 'default', |
| | | bubble: true, |
| | | strokeColor: 'black', // 线颜色 |
| | | strokeOpacity: 1, // 线透明度 |
| | | strokeWeight: 1, // 线宽 |
| | | fillColor: areaNode.getSubFeatures().length ? null : colors[0], // 填充色 |
| | | fillOpacity: 0.35 // 填充透明度 |
| | | }) |
| | | }, |
| | | // 根据值返回颜色 |
| | | getColorBetween(value, minValue, maxValue, minColor, maxColor) { |
| | | // 将颜色转换为RGB |
| | | function hexToRgb(hex) { |
| | | const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) |
| | | return result ? { |
| | | r: parseInt(result[1], 16), |
| | | g: parseInt(result[2], 16), |
| | | b: parseInt(result[3], 16) |
| | | } : null |
| | | } |
| | | |
| | | // 将RGB转换为十六进制颜色 |
| | | function rgbToHex(r, g, b) { |
| | | return '#' + ((1 << 24) + (r << 16) + (g << 8) + b).toString(16).slice(1) |
| | | } |
| | | |
| | | // 将颜色的每个分量进行插值 |
| | | function interpolateColor(start, end, factor) { |
| | | return Math.round(start + (end - start) * factor) |
| | | } |
| | | |
| | | // 确保值在最小值和最大值之间 |
| | | value = Math.max(minValue, Math.min(value, maxValue)) |
| | | |
| | | // 计算因子,将值范围映射到0到1之间 |
| | | const factor = (value - minValue) / (maxValue - minValue) |
| | | |
| | | // 获取两种颜色的RGB值 |
| | | const minRgb = hexToRgb(minColor) |
| | | const maxRgb = hexToRgb(maxColor) |
| | | // 根据因子插值RGB分量 |
| | | const r = interpolateColor(minRgb.r, maxRgb.r, factor) |
| | | const g = interpolateColor(minRgb.g, maxRgb.g, factor) |
| | | const b = interpolateColor(minRgb.b, maxRgb.b, factor) |
| | | |
| | | // 将RGB转换为十六进制颜色并返回 |
| | | return rgbToHex(r, g, b) |
| | | }, |
| | | // 绘制标点 |
| | | // 绘制标点 |
| | | drawMarker(positionArg) { |
| | | var content = [ |
| | | '<div><b>这是个提示文字</b>', |
| | | '地址:郑州市金水区花园路</div>' |
| | | ] |
| | | const position = new AMap.LngLat(positionArg[0], positionArg[1]) // Marker 经纬度 |
| | | // 创建 infoWindow 实例 |
| | | |
| | | function getImageUrl(url) { |
| | | console.log(`../../assets/icon/${url}.png`) |
| | | const path = new URL(`../../assets/icon/${url}.png`, import.meta.url) |
| | | return path.href |
| | | } |
| | | |
| | | for (let a = 0; a < 4; a++) { |
| | | const icon = new AMap.Icon({ |
| | | size: new AMap.Size(20, 20), // 图标尺寸 |
| | | image: getImageUrl(`icon${a + 1}`), // 图标的URL |
| | | imageSize: new AMap.Size(20, 20) // 图标所用图片的大小 |
| | | }) |
| | | const position = new AMap.LngLat(positionArg[0] - 0.02 * a, positionArg[1]) // Marker 经纬度 |
| | | const infoWindow = new AMap.InfoWindow({ |
| | | content: content.join('<br>'), // 传入字符串拼接的 DOM 元素 |
| | | anchor: 'top-center', |
| | | position: position |
| | | // offset: [10, 40] |
| | | }) |
| | | this.infoWindow.push(infoWindow) |
| | | const marker = new AMap.Marker({ |
| | | position: position, |
| | | // content: markerContent, // 将 html 传给 content |
| | | // icon: '', |
| | | icon: icon, |
| | | offset: new AMap.Pixel(-10, -30) // 以 icon 的 [center bottom] 为原点 |
| | | }) |
| | | this.map.add(marker) |
| | | this.marker.push(marker) |
| | | marker.on('click', () => { |
| | | infoWindow.open(this.map) |
| | | }) |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | .aMap { |
| | | width: 100vw; |
| | | height: 100vh; |
| | | } |
| | | </style> |