提交 c3cdfd16 authored 作者: caodi\cd's avatar caodi\cd

fix:保存

上级 07767b16
...@@ -20,7 +20,9 @@ ...@@ -20,7 +20,9 @@
"delay" : 0 "delay" : 0
}, },
/* 模块配置 */ /* 模块配置 */
"modules" : {}, "modules" : {
"Camera" : {}
},
/* 应用发布信息 */ /* 应用发布信息 */
"distribute" : { "distribute" : {
/* android打包配置 */ /* android打包配置 */
......
{ {
"pages": [ "pages": [ //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
//pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages {
{ "path": "pages/login/login"
"path": "pages/login/login" },
}, {
{ "path": "pages/home/home",
"path": "pages/home/home", "style": {
"style": { "navigationBarTitleText": ""
"navigationBarTitleText": "" }
} },
}, { //操作日志
{ "path": "pages/index/operLog"
//操作日志 },
"path": "pages/index/operLog"
},
//杭州内网机房巡检 //杭州内网机房巡检
{ {
"path": "pages/inspection/inspFirst" "path": "pages/inspection/inspFirst"
}, },
{ {
"path": "pages/report/sampleTable" "path": "pages/report/sampleTable"
}, },
{
//修改密码
"path": "pages/index/editPd"
},
{
"path": "pages/home/home",
"style": {
"navigationBarTitleText": ""
}
},
// 机房巡检列表页 { //修改密码
{ "path": "pages/index/editPd"
"path": "pages/inspectionContent/inspectionContent", },
"style": { {
"navigationBarTitleText": "" "path": "pages/home/home",
} "style": {
}, "navigationBarTitleText": ""
// 井道巡检 }
{ },
"path": "pages/shaftInspection/shaftInspection",
"style": {
"navigationBarTitleText": ""
}
},
// 新增配置--------- // 机房巡检
{
"path": "pages/inspectionContent/inspectionContent",
"style": {
"navigationBarTitleText": ""
}
},
// 井道巡检
{
"path": "pages/shaftInspection/shaftInspection",
"style": {
"navigationBarTitleText": ""
}
},
// 机房巡检 // 新增配置---------
{ // 巡检管理
"path": "pages/inspectionContent/inspectionContentList" {
}, "path": "pages/inspectionManagement/index"
// 井道巡检新页面 },
{ // 设备上架管理
"path": "pages/shaftInspection/shaftInspectionNew", {
"style": { "path": "pages/listingManagement/index"
"navigationBarTitleText": "" },
} // 井道巡检新页面
}, {
// 设备上架管理 "path": "pages/shaftInspection/shaftInspectionNew",
{ "style": {
"path": "pages/listingManagement/index" "navigationBarTitleText": ""
} }
], }
"globalStyle": { ],
"pageOrientation": "landscape", "globalStyle": {
"navigationStyle": "custom", "pageOrientation": "landscape",
"rpxCalcMaxDeviceWidth": 2000, "navigationStyle": "custom",
"rpxCalcIncludeWidth": 750 "rpxCalcBaseDeviceWidth": 1280, // 设计稿基准宽度
}, "rpxCalcMaxDeviceWidth": 2560, // 设备最大宽度
"uniIdRouter": {}, "rpxCalcIncludeWidth": 1024 // 包含宽度
"condition": { },
//模式配置,仅开发期间生效 "uniIdRouter": {},
"current": 0, //当前激活的模式(list 的索引项) "condition": { //模式配置,仅开发期间生效
"list": [ "current": 0, //当前激活的模式(list 的索引项)
{ "list": [{
"name": "", //模式名称 "name": "", //模式名称
"path": "", //启动页面,必选 "path": "", //启动页面,必选
"query": "" //启动参数,在页面的onLoad函数里面得到 "query": "" //启动参数,在页面的onLoad函数里面得到
} }]
] }
} }
} \ No newline at end of file
<template>
<view class="synchronous-dialog">
<view class="synchronous-content">
<view class="row-item">
<text class="title">待打包数据</text>
</view>
<view class="row-item count-num">
<text class="num">{{ list.length }}</text>
<text></text>
</view>
<view class="operating-instructions">
<view class="title">操作说明:</view>
<view class="instructions-item">
1、在PAD端,点击“数据打包”,做好同步准备。
</view>
<view class="instructions-item">
2、完成打包后,将PAD直联PC机,等待PC机自动导入需同步记录。
</view>
<view class="instructions-item">
3、PC端自动导入完成后,请点击“同步数据”,同步成功后,列表自动刷新展示同步数据;且PAD同步的数据不支持修改。
</view>
</view>
<view class="row-item bottom-row">
<button class="button" :loading="loading" @click="clickHandle">
数据打包
</button>
</view>
<!-- 关闭按钮 -->
<div class="close-button">
<text class="iconfont icon-a-bianzu16beifen" @click="close"></text>
</div>
</view>
</view>
</template>
<script>
import {
SYNCHRONIZE_DATA_PAD,
checkAndCreateDirectory,
createFileWithPlusIO,
setSm2,
USER_FILE_NAME,
getUserList,
} from "@/utils/systemCofig";
import {
copyDirectory,
deleteAllFilesInDirectory,
addLog,
getLogContent,
LOG_TYPE_ENUM,
writeDeviceData,
} from "@/utils/IoReadingAndWriting.js";
import moment from "moment";
import { Base64 } from "js-base64";
export default {
props: {
list: {
type: Array,
default: () => {
return [];
},
},
photos: {
type: Array,
default: () => {
return [];
},
},
},
components: {},
data() {
return {
loading: false,
};
},
mounted() {},
watch: {
list(newData) {
const temp = [];
newData.forEach((item) => {
temp.push(...(item.list || []));
});
},
},
methods: {
close() {
this.$emit("close");
},
getDetails() {
this.$emit("getDetails");
},
/**
* 1.生成两个文件. 机房文件 和 井道文件
* 2. 更新巡检数据状态 synchronization 置为 1
* 3. 写入数据
* 读取上一次打包的文件, 复制到 [ history ] 文件夹中
*/
clickHandle() {
if (this.loading) return;
const directoryPath = `${SYNCHRONIZE_DATA_PAD}/发送数据`;
const targetDirectoryPath = `${SYNCHRONIZE_DATA_PAD}/history/listingManagement`;
checkAndCreateDirectory(directoryPath).then(() => {
copyDirectory(directoryPath, targetDirectoryPath)
.then(() => {
return deleteAllFilesInDirectory(directoryPath);
})
.then(() => {
this.coverData();
})
.catch((error) => {
uni.showToast({
title: error,
icon: "none",
duration: 1000,
});
});
});
},
// 处理数据
coverData() {
const userName = this.$store.state.now_user.user;
let syncedData = this.list;
let timeStr = moment().format("yyyy_MM_DD_hh_mm_ss");
syncedData.forEach((item) => {
item.synchronization = true;
item.selected = false;
item.status = "已同步";
});
console.log("syncedData", syncedData);
this.loading = true;
let SBSJ_DATA_FILE_NAME = `${userName}_SBSJ_${timeStr}.txt`;
const tmepList = this.packedData(syncedData, SBSJ_DATA_FILE_NAME);
let arr = this.photos.map((item) => {
// 查找 B 数组中是否有对应的对象
const updatedItem = syncedData.find((bItem) => bItem.id === item.id);
// 如果有,则返回 B 数组中的对象,否则返回原对象
return updatedItem ? updatedItem : item;
});
writeDeviceData(tmepList, userName)
.then((res) => {
console.log("tmepList", tmepList);
this.$store.commit("SET_DEVICEDATA", arr);
console.log("arr",arr)
setTimeout(() => {
uni.showToast({
title: "打包成功",
icon: "none",
duration: 2000,
});
this.close();
this.loading = false;
let length = tmepList.length;
// 生成日志
const logContent = getLogContent(
LOG_TYPE_ENUM.sys,
`${length}张照同步`,
"同步"
);
const log_list = this.$store.state.log_list;
log_list.push(logContent);
this.$store.commit("SET_LOG_LIST", log_list);
addLog(log_list).then(() => {});
// 更新同步时间
this.updateSysTime();
this.getDetails();
}, 2 * 1000);
})
.catch((error) => {
this.loading = false;
uni.showToast({
title: error,
icon: "none",
duration: 2000,
});
})
.catch(() => {
setTimeout(() => {
uni.showToast({
title: "打包失败",
icon: "none",
duration: 2000,
});
this.loading = false;
}, 2 * 1000);
});
},
// 打包文件
packedData(content, fileName) {
const fileContent = setSm2(content);
return createFileWithPlusIO(
`${SYNCHRONIZE_DATA_PAD}/发送数据`,
fileName,
fileContent
);
},
// 更新最近一次同步时间
updateSysTime() {
getUserList().then((personList) => {
const now_user = this.$store.state.now_user;
const key = personList.findIndex(
(item) => item.userId == now_user.userId
);
// 更新用户同步时间
const userInfo = personList[key];
const LastSynchronizationTime = moment().format("yyyy-MM-DD HH:mm");
personList[key].LastSynchronizationTime = LastSynchronizationTime;
userInfo.LastSynchronizationTime = LastSynchronizationTime;
this.$store.commit("SET_USER", userInfo);
uni.setStorageSync("last_time", userInfo.LastSynchronizationTime || "");
// 更新用户数据
const fileContent = JSON.stringify(
Base64.encode(JSON.stringify(personList))
);
uni.setStorage({
key: "user_data",
data: JSON.stringify(personList),
fail: (error) => {
console.log("APP.vue 存储数据失败", error);
},
});
createFileWithPlusIO(SYNCHRONIZE_DATA_PAD, USER_FILE_NAME, fileContent)
.then(() => {
console.log("---用户数据更新成功");
})
.catch((error) => {
console.log("---用户数据更新失败", error);
});
});
},
},
};
</script>
<style scoped lang="less">
.synchronous-dialog {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
.synchronous-content {
padding: 3% 20px 32px 24px;
width: 400px;
height: 60%;
box-sizing: border-box;
background-image: linear-gradient(
-6deg,
#f9ffe7 0%,
#ffffff 12%,
#fcfeff 73%,
#ccf1ff 100%
);
border: 0.4px solid rgba(224, 224, 224, 1);
border-radius: 12px;
position: relative;
.row-item {
display: flex;
align-items: center;
justify-content: center;
}
.title {
font-family: PingFangSC-Medium;
font-size: 18px;
color: #000000;
text-align: center;
line-height: 26px;
font-weight: 500;
}
.count-num {
margin: 5% 0 5% 0;
align-items: flex-end;
.num {
display: inline-block;
font-family: AlibabaPuHuiTi_2_65_Medium;
font-size: 50px;
color: #3774f6;
line-height: 44px;
font-weight: 500;
}
}
.operating-instructions {
margin-bottom: 8%;
.title {
font-size: 13px;
color: #4a4a4a;
line-height: 24px;
font-weight: 600;
text-align: left;
}
.instructions-item {
font-size: 12px;
color: #7c7c7c;
line-height: 22px;
font-weight: 400;
}
}
// 打包按钮
.bottom-row {
position: absolute;
bottom: 24px;
left: 50%;
transform: translateX(-50%);
.button {
display: flex;
align-items: center;
justify-content: center;
background-image: linear-gradient(180deg, #3773f6 0%, #2c57f6 99%);
box-shadow: 0px 10px 24px 0px rgba(51, 104, 246, 0.24);
border-radius: 27px;
width: 160px;
height: 40px;
color: #fff;
}
}
// 关闭按钮
.close-button {
position: absolute;
bottom: -40px;
left: 50%;
transform: translateX(-50%);
.iconfont {
color: #fff;
font-size: 24px;
}
}
}
}
</style>
<template> <template>
<view class="container"> <view class="container">
<uni-nav-bar :fixed="true" background-color="rgba(214, 240, 255, 0.0)" status-bar rightWidth="300"> <uni-nav-bar
<block slot="left"> :fixed="true"
<view class="uni-nav-bar-text" @click="back"> background-color="rgba(214, 240, 255, 0.0)"
<text class="iconfont icon-Arrow-Left"></text> status-bar
</view> rightWidth="300"
</block> >
<block slot="right" class="nav-right"> <block slot="left">
<view class="header-buttons"> <view class="uni-nav-bar-text" @click="back">
<button class="button" @click="lookLog">机房巡检</button> <text class="iconfont icon-Arrow-Left"></text>
</view> </view>
</block> </block>
</uni-nav-bar> <block slot="right" class="nav-right">
<!-- 第一个模块:标题和按钮 --> <view class="header-buttons">
<view class="header"> <button class="button">机房</button>
<view class="title"> </view>
<view class="blue-line"></view> </block>
<text>设备上架管理</text> </uni-nav-bar>
</view>
<view class="buttons">
<button class="btn" @click="syncData">数据同步</button>
<button class="btn" @click="takePhoto">设备上架拍照</button>
</view>
</view>
<!-- 第二个模块:选中条数显示 --> <!-- 第二个模块:选中条数显示 -->
<view class="selected-count"> <view class="selected-count"> 已选择{{ selectedCount }}张图片</view>
选中:{{ selectedCount }}
</view>
<!-- 第三个模块:照片显示模块 --> <!-- 第三个模块:照片显示模块 -->
<view class="photo-list"> <view class="photo-list">
<view v-for="(group, date) in photoGroups" :key="date" class="photo-group"> <view
<view class="group-header"> v-for="(group, date) in photoGroups"
<text>{{ date }}</text> :key="date"
<button class="select-all" @click="toggleSelectAll(date)">全选</button> class="photo-group"
</view> >
<view class="card-list"> <view class="group-header">
<view v-for="photo in group" :key="photo.id" class="card" @click="previewPhoto(photo)"> <view
<image :src="photo.url" mode="widthFix" class="photo"></image> class="circle-button"
<view class="check-icon" @click.stop="toggleSelect(photo)"> :class="{ active: filteredData(selectedPhotos, group, date) }"
<text v-if="photo.selected"></text> @click.stop="toggleSelectAll(date)"
</view> >
<view class="delete-icon" @click.stop="deletePhoto(photo)">×</view> <text
<view class="photo-info"> class="inner-circle"
<text>编号:{{ photo.id }}</text> v-if="filteredData(selectedPhotos, group, date)"
<text>时间:{{ photo.time }}</text> ></text>
<text>状态:{{ photo.synced ? '已同步' : '待同步' }}</text> </view>
</view> <text class="date">{{ date }}</text>
</view> </view>
</view> <view class="card-list">
</view> <view
</view> v-for="photo in group"
</view> :key="photo.id"
class="card"
@click="previewPhoto(photo)"
>
<image :src="photo.url" mode="scaleToFill" class="photo"></image>
<view class="check-icon" @click.stop="toggleSelect(photo)">
<text v-if="photo.selected"></text>
</view>
<view class="delete-icon" @click.stop="deletePhoto(photo)">×</view>
<view class="type">{{
photo.synchronization ? "已同步" : "待同步"
}}</view>
<view class="photo-info">
<text class="no">照片编号:{{ photo.id }}</text>
</view>
<view v-if="false" class="photo-info">
<text>编号:{{ photo.id }}</text>
<text>时间:{{ photo.time }}</text>
<text
>状态:{{ photo.synchronization ? "已同步" : "待同步" }}</text
>
</view>
</view>
</view>
</view>
</view>
<view
v-if="selectedPhotos && selectedPhotos.length"
class="inspection-button"
@click="openDialog(true)"
>数据同步</view
>
<view v-else class="inspection-button" @click="takePhoto">设备拍照</view>
<!-- 打包弹窗 -->
<Dialog
v-show="isDialog && selectedPhotos.length"
ref="Dialog"
:list="selectedPhotos"
:photos="photos"
@close="openDialog(false)"
@getDetails="getDetails"
></Dialog>
</view>
</template> </template>
<script> <script>
import moment from "moment"; import moment from "moment";
export default { import Dialog from "./dialog.vue";
data() { import {
return { addLog,
photos: [], // 所有照片 getLogContent,
selectedPhotos: [], // 选中的照片 LOG_TYPE_ENUM,
syncedPhotos: [] // 已同步的照片 writeDeviceData,
}; } from "@/utils/IoReadingAndWriting.js";
}, import { getDeviceDataDetails } from "@/request/index.js";
computed: { export default {
// 按日期分组照片 components: {
photoGroups() { Dialog,
const groups = {}; },
this.photos.forEach(photo => { data() {
const date = photo.time.split(' ')[0]; return {
if (!groups[date]) { isDialog: false, //
groups[date] = []; photos: [], // 所有照片
} selectedPhotos: [], // 选中的照片
groups[date].push(photo); syncedPhotos: [], // 已同步的照片
}); };
return groups; },
}, computed: {
// 选中的照片数量 // 按日期分组照片
selectedCount() { photoGroups() {
return this.selectedPhotos.length; const groups = {};
} this.photos.forEach((photo) => {
}, const date = photo.date;
methods: { if (!groups[date]) {
back() { groups[date] = [];
uni.navigateBack(); }
}, groups[date].push(photo);
// 拍照 });
takePhoto() { return groups;
uni.chooseImage({ },
count: 1, // 选中的照片数量
success: (res) => { selectedCount() {
console.log(111, res) return this.selectedPhotos.length;
const tempFilePaths = res.tempFilePaths; },
const newPhoto = { userInfo() {
id: this.getFileName(tempFilePaths[0]), return this.$store.state.now_user || {};
url: tempFilePaths[0], },
time: moment(new Date()).format("yyyy-MM-DD HH:mm"), },
selected: false, onLoad(options) {
synced: false this.getDetails();
}; },
this.photos.unshift(newPhoto); mounted() {
}
}); const systemInfo = uni.getSystemInfoSync();
}, console.log("设备逻辑宽度",systemInfo.windowWidth); // 设备逻辑宽度
// 从路径中提取文件名(去掉路径和扩展名) console.log("设备像素比",systemInfo.pixelRatio); // 设备像素比
getFileName(filePath) { },
// 获取路径中的文件名部分(包括扩展名) methods: {
const fileNameWithExt = filePath.split('/').pop(); back() {
// 去掉扩展名 uni.navigateBack();
const fileName = fileNameWithExt.split('.').shift(); }, // 回显数据
return fileName; getDetails() {
}, uni.showLoading();
// 切换选中状态 getDeviceDataDetails()
toggleSelect(photo) { .then((res) => {
photo.selected = !photo.selected; this.photos = res;
if (photo.selected) { console.log("this.photos", this.photos);
this.selectedPhotos.push(photo);
} else { uni.hideLoading();
this.selectedPhotos = this.selectedPhotos.filter(p => p.id !== photo.id); })
} .catch((error) => {
}, uni.showToast({
// 全选/取消全选 title: error.msg,
toggleSelectAll(date) { icon: "none",
const group = this.photoGroups[date]; duration: 1000,
const allSelected = group.every(photo => photo.selected); });
group.forEach(photo => { uni.hideLoading();
photo.selected = !allSelected; });
if (photo.selected) { },
this.selectedPhotos.push(photo); // 拍照
} else { takePhoto() {
this.selectedPhotos = this.selectedPhotos.filter(p => p.id !== photo.id); uni.chooseImage({
} count: 1,
}); sourceType: ["camera"], // 可以从相机拍摄
}, success: async (res) => {
// 删除照片 console.log(111, res);
deletePhoto(photo) { const tempFilePath = res.tempFilePaths[0];
this.photos = this.photos.filter(p => p.id !== photo.id); // 存储照片到本地
this.selectedPhotos = this.selectedPhotos.filter(p => p.id !== photo.id); uni.saveImageToPhotosAlbum({
}, filePath: tempFilePath,
// 预览照片 success: function () {
previewPhoto(photo) { console.log("图片已成功保存到相册");
uni.previewImage({ },
urls: this.photos.map(p => p.url), fail: function (err) {
current: photo.url console.error("保存图片到相册失败:", err);
}); },
}, });
// 数据同步 const base64 = await this.convertFileToBase64(tempFilePath);
syncData() { // 数据合成
const syncedData = this.selectedPhotos.map(photo => ({ const newPhoto = {
id: photo.id, id: this.getFileName(tempFilePath),
time: photo.time, url: base64,
status: photo.synced ? '已同步' : '待同步' date: moment(new Date()).format("yyyy-MM-DD"),
})); time: moment(new Date()).format("yyyy-MM-DD HH:mm"),
// 存储到本地 selected: false,
uni.setStorageSync('syncedPhotos', syncedData); synchronization: false,
// 更新同步状态 };
this.selectedPhotos.forEach(photo => { console.log("newPhoto", newPhoto);
photo.synced = true; this.photos.unshift(newPhoto);
}); this.addPhotos(this.photos, `照片编号(${newPhoto.id})`, "设备上架");
this.selectedPhotos = []; },
} });
}, },
mounted() { // 转化为base64
// 从本地存储加载已同步的照片 convertFileToBase64(filePath) {
const syncedPhotos = uni.getStorageSync('syncedPhotos') || []; return new Promise((resolve, reject) => {
this.syncedPhotos = syncedPhotos; plus.io.resolveLocalFileSystemURL(
// 更新照片的同步状态 filePath,
this.photos.forEach(photo => { function (entry) {
if (this.syncedPhotos.some(p => p.id === photo.id)) { entry.file(
photo.synced = true; function (file) {
} const reader = new plus.io.FileReader();
}); reader.onloadend = function (evt) {
} const base64 = evt.target.result; // 获取 Base64 数据
}; resolve(base64); // 返回 Base64 数据
};
reader.readAsDataURL(file); // 读取文件并转换为 Base64
},
function (error) {
reject("获取文件对象失败:" + error.message);
}
);
},
function (error) {
reject("解析文件路径失败:" + error.message);
}
);
});
},
// 照片数据处理
addPhotos(photos, title, type) {
// 传入数据 文案 操作类型
// let deviceData = this.$store.state.deviceData; //获取全部数据
// deviceData = photos;
// 写入设备上架文件
this.$store.commit("SET_DEVICEDATA", photos);
writeDeviceData(photos, this.userInfo.user);
// 日志
let logContent = getLogContent(LOG_TYPE_ENUM.edit, title, type);
const log_list = this.$store.state.log_list;
logContent.inspectionType = "3";
log_list.push(logContent);
this.$store.commit("SET_LOG_LIST", log_list);
addLog(log_list).then((res) => {
console.log("日志文件写入成功");
});
// 日志
console.log("photos", photos, logContent);
},
// 从路径中提取文件名(去掉路径和扩展名)
getFileName(filePath) {
// 获取路径中的文件名部分(包括扩展名)
const fileNameWithExt = filePath.split("/").pop();
// 去掉扩展名
const fileName = fileNameWithExt.split(".").shift();
return fileName;
},
// 根据当前行的日期获取照片集合
filteredData(data, group, targetDate) {
let filteredData =
data && data.filter((item) => item.date === targetDate);
return filteredData.length == group.length;
},
// 切换选中状态
toggleSelect(photo) {
photo.selected = !photo.selected;
if (photo.selected) {
this.selectedPhotos.push(photo);
} else {
this.selectedPhotos = this.selectedPhotos.filter(
(p) => p.id !== photo.id
);
}
},
// 全选/取消全选
toggleSelectAll(date) {
const group = this.photoGroups[date];
const allSelected = group.every((photo) => photo.selected);
group.forEach((photo) => {
photo.selected = !allSelected;
if (photo.selected) {
this.selectedPhotos.push(photo);
} else {
this.selectedPhotos = this.selectedPhotos.filter(
(p) => p.id !== photo.id
);
}
});
console.log(this.selectedPhotos);
},
// 删除照片
deletePhoto(photo) {
this.photos = this.photos.filter((p) => p.id !== photo.id);
this.selectedPhotos = this.selectedPhotos.filter(
(p) => p.id !== photo.id
);
this.addPhotos(this.photos, "删除照片", "删除");
},
// 预览照片
previewPhoto(photo) {
uni.previewImage({
urls: this.photos.map((p) => p.url),
current: photo.url,
});
},
openDialog(show) {
this.isDialog = show;
if (!show) {
this.getDetails();
}
},
// 数据同步
syncData() {
const syncedData = this.selectedPhotos.map((photo) => ({
id: photo.id,
time: photo.time,
synchronization: true,
status: photo.synchronization ? "已同步" : "待同步",
}));
// 存储到本地
uni.setStorageSync("syncedPhotos", syncedData);
// 更新同步状态
this.selectedPhotos.forEach((photo) => {
photo.synchronization = true;
});
this.selectedPhotos = [];
},
},
};
</script> </script>
<style lang="less" scoped> <style lang="less" scoped>
/* 导航栏样式--- */ /* 导航栏样式--- */
.uni-nav-bar-text { .uni-nav-bar-text {
height: 36px; height: 36px;
width: 36px; width: 36px;
background: #ffffff; background: #ffffff;
border: 0.4px solid rgba(224, 224, 224, 1); border: 0.4px solid rgba(224, 224, 224, 1);
border-radius: 18px; border-radius: 18px;
border-radius: 50%; border-radius: 50%;
color: #333; color: #333;
text-align: center; text-align: center;
.iconfont {
font-size: 20px;
line-height: 36px;
}
}
.nav-right {
width: 240px;
}
.header-buttons { .iconfont {
display: flex; font-size: 20px;
align-items: center; line-height: 36px;
margin-left: auto; // 将按钮组推到最右侧 }
}
.button { .nav-right {
width: 112px; width: 240px;
height: 36px; }
background: #FFFFFF;
border-radius: 18px;
margin-left: 16px;
font-family: PingFangSC-Regular;
font-size: 16px;
color: #000000;
line-height: 36px;
font-weight: 400;
}
}
/* 导航栏样式--- */ .header-buttons {
display: flex;
align-items: center;
margin-left: auto; // 将按钮组推到最右侧
.container { .button {
background-image: linear-gradient(115deg, #E8F0FB 0%, #E1EBFA 100%); width: 112px;
padding: 0 32px; height: 36px;
height: 100vh; background: #ffffff;
border-radius: 18px;
margin-left: 16px;
font-family: PingFangSC-Regular;
font-size: 16px;
color: #000000;
line-height: 36px;
font-weight: 400;
}
}
} /* 导航栏样式--- */
.header { .container {
display: flex; background-image: linear-gradient(115deg, #e8f0fb 0%, #e1ebfa 100%);
justify-content: space-between; // padding: 0 32px;
align-items: center; height: 100vh;
margin-bottom: 16px; }
.title { .header {
display: flex; display: flex;
align-items: center; justify-content: space-between;
align-items: center;
margin-bottom: 16px;
.blue-line { .title {
width: 4px; display: flex;
height: 20px; align-items: center;
background-color: blue;
margin-right: 8px;
}
}
.buttons { .blue-line {
display: flex; width: 4px;
height: 20px;
background-color: blue;
margin-right: 8px;
}
}
.btn { .buttons {
width: 112px; display: flex;
height: 36px;
border-radius: 18px;
margin-left: 8px;
}
}
}
.selected-count { .btn {
background-color: #f0f0f0; width: 112px;
padding: 8px; height: 36px;
border-radius: 8px; border-radius: 18px;
margin-bottom: 16px; margin-left: 8px;
} }
}
}
.photo-list { .selected-count {
.photo-group { background-color: #f0f0f0;
margin-bottom: 16px; padding: 8px;
border-radius: 8px;
margin-bottom: 16px;
}
.group-header { .photo-list {
display: flex; padding: 24px 0;
justify-content: space-between; .photo-group {
align-items: center; margin-bottom: 16px;
margin-bottom: 8px;
.select-all { .group-header {
font-size: 14px; display: flex;
color: blue; justify-content: flex-start;
} align-items: center;
} margin-bottom: 8px;
padding: 0 32px;
.date {
font-size: 26px;
color: #000000;
line-height: 18px;
font-weight: 500;
margin-left: 8px;
}
}
.card-list { .card-list {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 16px; gap: 8px;
.card { .card {
width: calc(20% - 13px); width: 210px;
position: relative; height: 236px;
margin-bottom: 22px;
position: relative;
.photo { .photo {
width: 100%; width: 210px;
height: auto; height: 210px;
border-radius: 8px; }
}
.check-icon { .check-icon {
position: absolute; position: absolute;
top: 8px; top: 8px;
right: 8px; left: 8px;
background-color: rgba(255, 255, 255, 0.8); background-color: rgba(255, 255, 255, 0.8);
border-radius: 50%; border-radius: 50%;
width: 24px; width: 24px;
height: 24px; height: 24px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
} }
.delete-icon { .delete-icon {
position: absolute; position: absolute;
bottom: 8px; bottom: 8px;
left: 8px; left: 8px;
background-color: rgba(255, 0, 0, 0.8); background-color: rgba(255, 0, 0, 0.8);
border-radius: 50%; border-radius: 50%;
width: 24px; width: 24px;
height: 24px; height: 24px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
color: white; color: white;
} }
.type {
width: 52px;
padding: 0 8px;
text-align: center;
background: rgba(0, 0, 0, 0.5);
border-radius: 11px;
font-size: 12px;
color: #ffffff;
text-align: left;
line-height: 20px;
font-weight: 400;
position: absolute;
right: 13.5px;
top: 8px;
}
.photo-info {
text-align: center;
.photo-info { text {
margin-top: 8px; font-family: PingFangSC-Regular;
text-align: center; font-size: 14px;
color: #000000;
line-height: 22px;
font-weight: 400;
}
}
}
}
}
}
// 按钮
.inspection-button {
display: flex;
align-items: center;
justify-content: center;
position: fixed;
bottom: 60px;
width: 280px;
height: 48px;
left: 50%;
transform: translateX(-50%);
background-image: linear-gradient(180deg, #3773f6 0%, #2c57f6 99%);
box-shadow: 0px 10px 24px 0px rgba(51, 104, 246, 0.24);
border-radius: 27px;
font-family: PingFangSC-Regular;
font-size: 20px;
line-height: 48px;
color: #ffffff;
text-align: center;
font-weight: 400;
}
text { /* 圆形按钮样式 */
display: blo980782ck; .circle-button {
font-size: 12px; width: 18px;
} height: 18px;
} border-radius: 50%;
} border: 1.14px solid rgba(199, 199, 199, 1);
} display: flex;
} align-items: center;
} justify-content: center;
</style> cursor: pointer;
\ No newline at end of file transition: all 0.3s ease;
/* 选中状态样式 */
&.active {
border-color: #007aff;
background-color: #3774f6;
}
/* 内部小圆点 */
.inner-circle {
width: 18px;
height: 18px;
border-radius: 50%;
margin-right: 8px;
}
}
</style>
...@@ -2,7 +2,8 @@ import store from "../store/index"; ...@@ -2,7 +2,8 @@ import store from "../store/index";
import { import {
readLogData, readLogData,
readInspectionData, readInspectionData,
readDarfData readDarfData,
readDeviceData
} from "@/utils/IoReadingAndWriting.js"; } from "@/utils/IoReadingAndWriting.js";
import lodash from "lodash"; import lodash from "lodash";
...@@ -98,4 +99,47 @@ export const getDarft = () => { ...@@ -98,4 +99,47 @@ export const getDarft = () => {
reject(error) reject(error)
}) })
}) })
}
// 获取设备上架所有图片信息
export const getAllDeviceData = () => {
return new Promise((resolve, reject) => {
console.log(store.state.deviceData.length)
if(store.state.deviceData.length){
const tempRes = lodash.orderBy(store.state.deviceData, "creatTime", ['desc']);
const result = lodash.orderBy(tempRes, "synchronization", ['asc']);
resolve(result)
return;
}
readDeviceData()
.then((res) => {
const tempRes = lodash.orderBy(res, "creatTime", ['desc']);
const result = lodash.orderBy(tempRes, "synchronization", ['asc']);
store.commit("SET_DEVICEDATA", result);
resolve(result)
})
.catch((error) => {
reject(error)
})
})
}
/**
*
* 获取设备上架数据详情
* @returns
*/
export const getDeviceDataDetails = () => {
return new Promise((resolve, reject) => {
getAllDeviceData()
.then((res) => {
const detailsInfo = res
resolve(detailsInfo)
})
.catch((error) => {
reject(error)
})
})
} }
\ No newline at end of file
...@@ -72,7 +72,8 @@ const store = new Vuex.Store({ ...@@ -72,7 +72,8 @@ const store = new Vuex.Store({
// 保存 日志文件 // 保存 日志文件
state.log_list = payload; state.log_list = payload;
}, },
SET_DEVICEDATA(state, payload) { //保存上次上报时间 SET_DEVICEDATA(state, payload) {
//保存设备上架数据
state.deviceData = payload state.deviceData = payload
}, },
DEL_DEVICEDATA(state, index) { DEL_DEVICEDATA(state, index) {
......
...@@ -23,10 +23,11 @@ import { Base64 } from "js-base64"; ...@@ -23,10 +23,11 @@ import { Base64 } from "js-base64";
export const LOG_TYPE_ENUM = { export const LOG_TYPE_ENUM = {
login: "登录", login: "登录",
add: "新增成功", add: "新增成功",
photo: "拍照",
edit: "编辑成功", edit: "编辑成功",
darf: "草稿", darf: "草稿",
delete: "删除", delete: "删除",
sys: "同步数据", sys: "同步",
updatePassword: "修改密码", updatePassword: "修改密码",
}; };
...@@ -192,6 +193,58 @@ export const readInspectionData = () => { ...@@ -192,6 +193,58 @@ export const readInspectionData = () => {
.catch((error) => reject(error)); .catch((error) => reject(error));
}); });
}; };
/**
* // 写入【设备上架】文件
* @param {*} content 写入内容
* @param {*} isEncryption 是否加密
* @returns
*/
export const writeDeviceData= (content, userName) => {
return new Promise((resolve, reject) => {
let fileName = `list.txt`;
const fileContent = Base64.encode(JSON.stringify(content));
createFileWithPlusIO(
`${SYNCHRONIZE_DATA_PAD}/设备上架/${userName}`,
fileName,
fileContent
).then((res) => {
// store 更新 设备上架. 缓存数据置为空,让接口重新读取文件数据
store.commit("SET_DEVICEDATA", []);
resolve();
});
});
};
// 读取【设备上架】文件
export const readDeviceData= () => {
const now_user = store.state.now_user;
console.log("now_user",now_user)
const isAdmin = now_user.isAdmin;
// const directoryPath = isAdmin
// ? `${SYNCHRONIZE_DATA_PAD}/设备上架`
// : `${SYNCHRONIZE_DATA_PAD}/设备上架/${now_user.user}`;
const directoryPath = `${SYNCHRONIZE_DATA_PAD}/设备上架/${now_user.user}`;
console.log("directoryPath",directoryPath)
return new Promise((resolve, reject) => {
readFilesInDirectory(directoryPath)
.then((res) => {
console.log("directoryPathres",res)
const temp = res.map((element) => {
return JSON.parse(Base64.decode(element));
});
resolve(lodash.flattenDeep(temp));
})
.catch((error) => reject(error));
});
};
// 复制文件夹中的所有数据到另一个文件夹 // 复制文件夹中的所有数据到另一个文件夹
/** /**
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论