123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- <template>
- <div class="log-viewer">
- <s-header :name="$t('device.viewLogs')" :noback="false" />
- <!-- 设备名称标题 -->
- <div class="device-header">
- <div class="vertical-indicator"></div>
- <h3 class="device-name">
- {{ $t("device.equipmentName") }}:{{ deviceName }}
- </h3>
- </div>
- <!-- 操作卡片 -->
- <div class="operation-card">
- <!-- 时间选择 -->
- <div class="time-picker-card">
- <van-field
- v-model="logsTime"
- is-link
- readonly
- label="选择日期"
- placeholder="点击选择时间"
- @click="chooseTime"
- class="time-field"
- />
- <van-popup v-model:show="showPicker" round position="bottom">
- <van-date-picker
- :min-date="minDate"
- :max-date="maxDate"
- @confirm="selectTime"
- @cancel="showPicker = false"
- />
- </van-popup>
- </div>
- <!-- 使用说明 -->
- <div class="tutorial-card">
- <van-field
- v-model="message"
- readonly
- rows="2"
- autosize
- label="使用教程"
- type="textarea"
- class="tutorial-field"
- />
- </div>
- <!-- 新增通道选择 -->
- <div class="channel-selector">
- <van-radio-group v-model="channelType" direction="horizontal">
- <van-radio name="1" icon-size="16px" class="channel-option">
- 默认通道
- </van-radio>
- <van-radio name="2" icon-size="16px" class="channel-option">
- 新通道
- </van-radio>
- </van-radio-group>
- </div>
- <!-- 操作按钮 -->
- <div class="action-buttons">
- <van-button
- round
- type="primary"
- icon="back-top"
- @click="uploadLogBtn"
- class="action-btn"
- >
- 上传日志
- </van-button>
- <van-button
- round
- type="success"
- icon="search"
- @click="queryLogBtn"
- class="action-btn"
- >
- 查询日志
- </van-button>
- </div>
- <!-- 文件下载卡片 -->
- <div v-if="fileName" class="file-card">
- <van-cell
- :title="fileName"
- clickable
- @click="downloadFile"
- class="file-item"
- >
- <template #right-icon>
- <van-icon name="down" class="download-icon" />
- </template>
- </van-cell>
- </div>
- </div>
- </div>
- </template>
- <script>
- import { onMounted, computed, ref } from "vue";
- import sHeader from "@/components/SimpleHeader.vue";
- import {
- downloadLog,
- getDeviceDetal,
- uploadLog,
- newUploadLog,
- queryLog,
- } from "@/service/device";
- import { $M_ExportFile } from "@/common/js/utils";
- import { showFailToast, showToast } from "vant";
- import { useRoute } from "vue-router";
- import dateUtil from "@/utils/dateUtil";
- // import { styleUrl } from "../../../common/js/utils";
- // import {useI18n} from "vue-i18n";
- export default {
- components: {
- sHeader,
- },
- setup() {
- // const { t } = useI18n();
- const route = useRoute();
- const deviceId = route.query.deviceId;
- const deviceDetail = ref(null);
- const showPicker = ref(false);
- const downloading = ref(false);
- const logsTime = ref(null);
- const fileName = ref(""); // 文件名
- const message = ref(
- "选择日期点击上传,等待几秒后点击查询,找到文件点击下载到本地查看。"
- );
- // 计算最小日期为当前日期7天前
- const minDate = computed(() => {
- const minTimestamp = new Date().getTime() - 6 * 24 * 3600 * 1000;
- const minDate = dateUtil.formateDate(
- new Date(minTimestamp),
- "yyyy-MM-dd"
- );
- return new Date(minDate);
- });
- // 计算最大日期为当前日期
- const maxDate = computed(() => {
- return new Date();
- });
- // 上传通道
- const channelType = ref("1");
- // 初始化页面获取列表
- onMounted(async () => {
- // 加载样式
- await getDeviceDetailFun();
- });
- // 选择时间
- const chooseTime = () => {
- showPicker.value = true;
- };
- const selectTime = ({ selectedValues }) => {
- logsTime.value = selectedValues.join("-");
- showPicker.value = false;
- };
- const getDeviceDetailFun = async () => {
- const { data } = await getDeviceDetal({
- id: deviceId,
- });
- if (data.code === "00000") {
- deviceDetail.value = data.data;
- } else {
- showFailToast(data.message);
- }
- };
- const downloadBtn = async () => {
- const pattern = /^\d{4}-\d{2}-\d{2}$/;
- if (logsTime.value == null) {
- showToast("请选择日期");
- return;
- }
- if (!pattern.test(logsTime.value)) {
- showToast("日期格式有误");
- return;
- }
- const formattedDate = logsTime.value.replace(/-/g, "");
- downloading.value = true;
- try {
- const { headers, data } = await downloadLog({
- equipmentId: deviceId,
- day: formattedDate,
- });
- console.log("请求成功", headers, data);
- $M_ExportFile(data, headers);
- } catch (error) {
- if (error.code === "ECONNABORTED") {
- // 处理请求超时的错误
- console.error("请求超时:", error);
- showFailToast("请求超时");
- } else {
- // 处理其他请求错误
- console.error("请求失败:", error);
- showFailToast("请求失败");
- }
- } finally {
- downloading.value = false;
- }
- };
- const uploadLogBtn = async () => {
- const pattern = /^\d{4}-\d{2}-\d{2}$/;
- if (logsTime.value == "") {
- showToast("请选择日期");
- return;
- }
- if (!pattern.test(logsTime.value)) {
- showToast("日期格式有误");
- return;
- }
- const formattedDate = logsTime.value.replace(/-/g, "");
- const { data } = await (channelType.value == "1"
- ? uploadLog
- : newUploadLog)({
- equipmentId: deviceId,
- day: formattedDate,
- });
- if (data.code == "00000") {
- showToast("上传信号发送成功,请等待几秒后查询下载");
- } else {
- showFailToast(data.message);
- }
- };
- // 查询日志是否上传成功
- const queryLogBtn = async () => {
- if (logsTime.value == "") {
- showToast("请选择日期");
- return;
- }
- const pattern = /^\d{4}-\d{2}-\d{2}$/;
- if (!pattern.test(logsTime.value)) {
- showToast("日期格式有误");
- return;
- }
- const formattedDate = logsTime.value.replace(/-/g, "");
- const { data } = await queryLog({
- equipmentId: deviceId,
- day: formattedDate,
- });
- if (data.code == "00000") {
- // console.log(data.data);
- showToast("查询成功,点击下载");
- fileName.value = data.data.substring(4);
- } else {
- fileName.value = "";
- showToast("找不到文件,请重试上传或检查机器网络");
- }
- };
- const downloadFile = async () => {
- // 文件链接
- const fileUrl = "https://qiniuyun.sunzee.com.cn/log/" + fileName.value;
- // 文件名
- const newFileName = fileName.value;
- try {
- const response = await fetch(fileUrl, {
- headers: {
- "Cache-Control": "no-store", // 禁用缓存
- Pragma: "no-cache",
- },
- });
- console.log("response", response);
- // 将文件内容创建为Blob
- const fileBlob = await response.blob();
- // 创建一个下载链接
- const downloadLink = document.createElement("a");
- downloadLink.href = URL.createObjectURL(fileBlob);
- downloadLink.download = newFileName;
- // 模拟点击下载链接
- document.body.appendChild(downloadLink);
- downloadLink.click();
- // 清理添加的链接元素
- document.body.removeChild(downloadLink);
- } catch (error) {
- console.error("请求超时:", error);
- }
- };
- return {
- deviceDetail,
- downloadBtn,
- chooseTime,
- selectTime,
- showPicker,
- logsTime,
- minDate,
- maxDate,
- downloading,
- downloadFile,
- uploadLogBtn,
- queryLogBtn,
- fileName,
- message,
- channelType,
- };
- },
- };
- </script>
- <style lang="less" scoped>
- @import "../../../common/style/common";
- @primary-color: #4dc294;
- @card-bg: #ffffff;
- @text-primary: #2d3436;
- @border-color: #e4e7ec;
- .log-viewer {
- background: #f8fafb;
- min-height: 100vh;
- }
- .device-header {
- display: flex;
- align-items: center;
- padding: 12px 15px;
- background: #fff;
- margin: 10px;
- border-radius: 8px;
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
- .vertical-indicator {
- width: 4px;
- height: 15px;
- background: var(--active-color, #4d6add);
- border-radius: 2px;
- margin-right: 10px;
- }
- .device-name {
- margin: 0;
- font-size: 15px;
- color: #404d74;
- font-weight: 550;
- // 长名称处理
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- max-width: 70vw;
- }
- }
- .operation-card {
- background: @card-bg;
- border-radius: 12px;
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
- padding: 16px;
- margin: 10px;
- .time-picker-card {
- margin-bottom: 16px;
- .time-field {
- :deep(.van-field__label) {
- width: 80px;
- }
- }
- }
- .tutorial-card {
- border: 1px solid @border-color;
- border-radius: 8px;
- margin-bottom: 24px;
- .tutorial-field {
- :deep(.van-field__label) {
- color: @primary-color;
- font-weight: bold;
- }
- :deep(textarea) {
- color: #666;
- font-size: 13px;
- }
- }
- }
- .channel-selector {
- margin: 16px 0;
- padding: 12px 16px;
- background: #f8fafb;
- border-radius: 8px;
- .van-radio-group {
- display: flex;
- gap: 24px;
- justify-content: center;
- }
- .channel-option {
- :deep(.van-radio__label) {
- color: #2d3436;
- font-size: 14px;
- }
- :deep(.van-radio__icon) {
- color: #4dc294;
- }
- }
- }
- .action-buttons {
- display: grid;
- grid-template-columns: repeat(2, 1fr);
- gap: 12px;
- .action-btn {
- height: 44px;
- font-size: 15px;
- box-shadow: 0 4px 12px rgba(77, 194, 148, 0.2);
- &:active {
- transform: scale(0.98);
- }
- }
- }
- }
- .file-card {
- background: #666;
- border-radius: 12px;
- margin: 16px 0;
- box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
- .file-item {
- :deep(.van-cell__title) {
- color: @text-primary;
- font-weight: 500;
- }
- .download-icon {
- color: @primary-color;
- font-size: 18px;
- margin-left: 8px;
- }
- &:active {
- background-color: #f8fafb;
- }
- }
- }
- @media (max-width: 480px) {
- .action-buttons {
- grid-template-columns: 1fr !important;
- .action-btn {
- width: 100%;
- }
- }
- .operation-card {
- padding: 12px;
- }
- }
- </style>
|