Browse Source

b端

master
hx 7 days ago
parent
commit
8eeb9f2f8e
  1. 5
      src/api/device/device.js
  2. 1522
      src/components/device/TrajectoryDialog.vue
  3. 78
      src/utils/loadAMap.js
  4. 61
      src/utils/loadGoogleMaps.js
  5. 27
      src/views/device/device/index.vue
  6. 8
      src/views/system/role/index.vue

5
src/api/device/device.js

@ -15,10 +15,11 @@ export function getDevice(id) {
})
}
export function getDeviceTrajectory(id) {
export function getDeviceTrajectory(id, params) {
return request({
url: '/device/device/' + id + '/trajectory',
method: 'get'
method: 'get',
params: params
})
}

1522
src/components/device/TrajectoryDialog.vue

File diff suppressed because it is too large

78
src/utils/loadAMap.js

@ -0,0 +1,78 @@
let amapPromise = null;
export function loadAMap(options = {}) {
const {
key = "",
securityJsCode = "",
version = "2.0",
plugins = [],
} = options;
if (typeof window === "undefined") {
return Promise.reject(new Error("当前环境不支持加载高德地图"));
}
if (window.AMap && typeof window.AMap.Map === "function") {
return Promise.resolve(window.AMap);
}
if (!key) {
return Promise.reject(new Error("未配置高德地图 Web Key"));
}
if (securityJsCode) {
window._AMapSecurityConfig = Object.assign({}, window._AMapSecurityConfig, {
securityJsCode,
});
}
if (amapPromise) {
return amapPromise;
}
amapPromise = new Promise((resolve, reject) => {
const scriptId = "geotag-amap-script";
const existingScript = document.getElementById(scriptId);
const handleResolve = () => {
if (window.AMap && typeof window.AMap.Map === "function") {
resolve(window.AMap);
return;
}
amapPromise = null;
reject(new Error("高德地图脚本加载失败"));
};
const handleError = () => {
amapPromise = null;
reject(new Error("高德地图脚本加载失败"));
};
if (existingScript) {
existingScript.addEventListener("load", handleResolve, { once: true });
existingScript.addEventListener("error", handleError, { once: true });
return;
}
const script = document.createElement("script");
script.id = scriptId;
script.async = true;
script.defer = true;
script.onload = handleResolve;
script.onerror = handleError;
const query = [
"v=" + encodeURIComponent(version),
"key=" + encodeURIComponent(key),
];
if (plugins.length) {
query.push("plugin=" + encodeURIComponent(plugins.join(",")));
}
script.src = "https://webapi.amap.com/maps?" + query.join("&");
document.head.appendChild(script);
});
return amapPromise;
}

61
src/utils/loadGoogleMaps.js

@ -0,0 +1,61 @@
let googleMapsPromise = null;
export function loadGoogleMaps(apiKey) {
if (typeof window === "undefined") {
return Promise.reject(new Error("当前环境不支持加载谷歌地图"));
}
if (window.google && window.google.maps) {
return Promise.resolve(window.google.maps);
}
if (!apiKey) {
return Promise.reject(new Error("未配置谷歌地图 API Key"));
}
if (googleMapsPromise) {
return googleMapsPromise;
}
googleMapsPromise = new Promise((resolve, reject) => {
const callbackName = "__geotagGoogleMapsReady__";
const scriptId = "geotag-google-maps-script";
const existingScript = document.getElementById(scriptId);
const cleanup = () => {
if (window[callbackName]) {
delete window[callbackName];
}
};
window[callbackName] = () => {
cleanup();
resolve(window.google.maps);
};
const handleError = () => {
cleanup();
googleMapsPromise = null;
reject(new Error("谷歌地图脚本加载失败"));
};
if (existingScript) {
existingScript.addEventListener("error", handleError, { once: true });
return;
}
const script = document.createElement("script");
script.id = scriptId;
script.async = true;
script.defer = true;
script.src =
"https://maps.googleapis.com/maps/api/js?key=" +
encodeURIComponent(apiKey) +
"&callback=" +
callbackName;
script.onerror = handleError;
document.head.appendChild(script);
});
return googleMapsPromise;
}

27
src/views/device/device/index.vue

@ -103,29 +103,27 @@
</el-tag>
</template>
</el-table-column>
<el-table-column label="型号" align="center" prop="model" />
<el-table-column label="型号" align="center" prop="model" />
<el-table-column label="序列号" align="center" prop="sn" />
<el-table-column label="名称" align="center" prop="alias" />
<el-table-column label="地址" align="center" prop="lastAddress" />
<el-table-column label="更新时间" align="center" prop="lastLocationTime" width="190">
<el-table-column label="地址" align="center" prop="lastAddress" min-width="220" />
<el-table-column label="更新时间" align="center" prop="lastLocationTime" min-width="115" >
<template slot-scope="scope">
<span>{{ parseTime(scope.row.lastLocationTime, "{y}-{m}-{d} {h}:{i}:{s}") }}</span>
</template>
</el-table-column>
<el-table-column label="经纬度" align="center" min-width="220">
<el-table-column label="经纬度" align="center" >
<template slot-scope="scope">
<span>{{ formatCoordinates(scope.row.lastLat, scope.row.lastLng) }}</span>
</template>
</el-table-column>
<el-table-column label="MAC " align="center" prop="mac" min-width="140" />
<el-table-column label="MAC " align="center" prop="mac" />
<el-table-column label="电量" align="center" prop="battery" />
<el-table-column label="备注" align="center" prop="remark" />
<!-- <el-table-column label="绑定企业id" align="center" prop="bindBusinessId" /> -->
<el-table-column label="操作" align="center" width="220" class-name="small-padding fixed-width">
<template slot-scope="scope">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleEditInfo(scope.row)" v-hasPermi="['device:device:list']">修改</el-button>
@ -253,11 +251,11 @@
<el-descriptions-item label="企业">
{{ detailForm.businessName || detailForm.merchantName || "-" }}
</el-descriptions-item>
<el-descriptions-item label="最后地址名称">
{{ detailForm.lastAddress || "-" }}
</el-descriptions-item>
<el-descriptions-item label="分配员工">
<el-descriptions-item label="分配员工">
{{ formatAssignedUsers(detailForm.assignedUsers) }}
</el-descriptions-item>
<el-descriptions-item label="最后位置更新时间">
@ -669,7 +667,14 @@ export default {
return value === true || value === 1 || value === "1" ? "success" : "info";
},
formatCoordinateValue(value) {
return value === null || value === undefined || value === "" ? "-" : value;
if (value === null || value === undefined || value === "") {
return "-";
}
let strValue = String(value);
const [integerPart, decimalPart] = strValue.split(".");
const fixedDecimal = decimalPart.slice(0, 2).padEnd(2, "0");
return `${integerPart}.${fixedDecimal}`;
},
formatCoordinates(lat, lng) {
return `${this.formatCoordinateValue(lat)} / ${this.formatCoordinateValue(lng)}`;

8
src/views/system/role/index.vue

@ -29,9 +29,9 @@
<el-col :span="1.5">
<el-button type="success" plain icon="el-icon-edit" size="mini" :disabled="single" @click="handleUpdate" v-hasPermi="['system:role:edit']">修改</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:role:remove']">删除</el-button>
</el-col>
<!-- <el-col :span="1.5">-->
<!-- <el-button type="danger" plain icon="el-icon-delete" size="mini" :disabled="multiple" @click="handleDelete" v-hasPermi="['system:role:remove']">删除</el-button>-->
<!-- </el-col>-->
<el-col :span="1.5">
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" v-hasPermi="['system:role:export']">导出</el-button>
</el-col>
@ -57,7 +57,7 @@
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope" v-if="scope.row.roleId !== 1">
<el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)" v-hasPermi="['system:role:edit']">修改</el-button>
<el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:role:remove']">删除</el-button>
<!-- <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)" v-hasPermi="['system:role:remove']">删除</el-button>-->
<el-dropdown size="mini" @command="(command) => handleCommand(command, scope.row)" v-hasPermi="['system:role:edit']">
<!-- <el-button size="mini" type="text" icon="el-icon-d-arrow-right">更多</el-button> -->
<el-dropdown-menu slot="dropdown">

Loading…
Cancel
Save