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

fix:同步

上级 059f084e
<template>
<view class="synchronous-dialog">
<view v-if="isOpen" 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">{{ notSynchronizationList.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同步的数据不支持修改。
<text class="title"
>巡检签字 <text class="tip">请在下方虚线框内进行签字</text></text
>
</view>
<view class="operating-instructions"
><!-- 签字区域 -->
<canvas
canvas-id="signatureCanvas"
class="signature-canvas"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
></canvas>
</view>
<view class="row-item bottom-row">
<button class="button" :loading="loading" @click="clickHandle">
数据打包
</button>
<button class="button btn" @click="clearSignature">重新签字</button>
<button class="button" @click="confirmSignature">完成签字</button>
</view>
<!-- 关闭按钮 -->
......@@ -38,265 +31,108 @@
</template>
<script>
import {
SYNCHRONIZE_DATA_PAD,
checkAndCreateDirectory,
createFileWithPlusIO,
setSm2,
USER_FILE_NAME,
getUserList,
} from "@/utils/systemCofig";
import {
writeInspectionData,
copyDirectory,
deleteAllFilesInDirectory,
addLog,
getLogContent,
LOG_TYPE_ENUM,
} from "@/utils/IoReadingAndWriting.js";
import moment from "moment";
import { getAllInspections } from "@/request/index.js";
import { Base64 } from "js-base64";
export default {
props: {
list: {
type: Array,
default: () => {
return [];
},
},
},
components: {},
data() {
return {
loading: false,
notSynchronizationList: [], // 未同步数据
allList: [], // 所有数据
isOpen: false,
points: [], // 存储绘制点
ctx: null, // canvas 上下文
canvasWidth: 761.6,
canvasHeight: 302.4,
isDrawing: false, // 是否正在绘制
};
},
mounted() {
const temp = [];
this.list.forEach((item) => {
temp.push(...(item.list || []));
});
this.notSynchronizationList = temp.filter(
(item) => item.synchronization == 0
);
getAllInspections().then((res) => {
this.allList = res;
});
this.initCanvas();
},
watch: {
list(newData) {
const temp = [];
newData.forEach((item) => {
temp.push(...(item.list || []));
});
this.notSynchronizationList = temp.filter(
(item) => item.synchronization == 0
methods: {
initCanvas() {
this.ctx = uni.createCanvasContext("signatureCanvas", this);
// 设置画布背景为白色
this.ctx.fillStyle = "#ffffff";
this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
this.ctx.setStrokeStyle("#000000"); // 设置线条颜色
this.ctx.setLineWidth(2); // 设置线条宽度
this.ctx.setLineCap("round"); // 设置线条端点样式
this.ctx.setLineJoin("round"); // 设置线条连接样式
this.ctx.draw(true); // 立即绘制背景
this.hasSigned = false; // 初始化时没有签字内容
},
handleTouchStart(e) {
this.isDrawing = true;
this.points = [];
const startX = e.touches[0].x;
const startY = e.touches[0].y;
this.points.push({ x: startX, y: startY });
},
handleTouchMove(e) {
if (!this.isDrawing) return;
const x = e.touches[0].x;
const y = e.touches[0].y;
this.points.push({ x, y });
if (this.points.length >= 2) {
this.ctx.beginPath();
this.ctx.moveTo(
this.points[this.points.length - 2].x,
this.points[this.points.length - 2].y
);
this.ctx.lineTo(x, y);
this.ctx.stroke();
this.ctx.draw(true);
this.hasSigned = true; // 标记有签字内容
}
},
handleTouchEnd() {
this.isDrawing = false;
this.points = [];
},
methods: {
close() {
this.$emit("close");
clearSignature() {
// 清空画布
this.ctx.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
// 重新设置背景为白色
this.ctx.fillStyle = "#ffffff";
this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
this.ctx.draw(true); // 立即更新画布
this.hasSigned = false; // 标记没有签字内容
},
/**
* 1.生成两个文件. 机房文件 和 井道文件
* 2. 更新巡检数据状态 synchronization 置为 1
* 3. 写入数据
* 读取上一次打包的文件, 复制到 [ history ] 文件夹中
*/
clickHandle() {
if(this.loading) return;
const directoryPath = `${SYNCHRONIZE_DATA_PAD}/发送数据`;
const targetDirectoryPath = `${SYNCHRONIZE_DATA_PAD}/history`;
checkAndCreateDirectory(directoryPath).then(() => {
copyDirectory(directoryPath, targetDirectoryPath)
.then(() => {
return deleteAllFilesInDirectory(directoryPath);
})
.then(() => {
this.coverData();
})
.catch((error) => {
async confirmSignature() {
// 如果没有签字内容,直接提示
if (!this.hasSigned) {
uni.showToast({
title: error,
title: "请先签字",
icon: "none",
duration: 1000,
});
});
});
},
// 处理数据
coverData() {
const userName = this.$store.state.now_user.user;
const notSynchronizationList = this.notSynchronizationList;
const allList = this.allList;
let timeStr = moment().format("yyyy_MM_DD_hh_mm_ss");
const JFXJ_DATA = notSynchronizationList
.filter((item) => item.inspectionType == 1)
.map((item) => {
return {
...item,
originData: [],
};
}); // 机房数据类型是 1
const JDXJ_DATA = notSynchronizationList
.filter((item) => item.inspectionType == 2)
.map((item) => {
return item[item.inspectionCode];
}); // 井道数据类型是 2
this.loading = true;
const tmepList = [];
if (JFXJ_DATA.length) {
let JFXJ_DATA_FILE_NAME = `${userName}_JFXJ_${timeStr}.txt`;
tmepList.push(this.packedData(JFXJ_DATA, JFXJ_DATA_FILE_NAME));
}
JDXJ_DATA.forEach((item, index) => {
let JDXJ_DATA_FILE_NAME = `${userName}_JDXJ_${timeStr}_${index}.txt`;
tmepList.push(this.packedData(item, JDXJ_DATA_FILE_NAME));
});
Promise.all(tmepList)
.then(() => {
// 更新巡检数据状态
const synchronizationUids = notSynchronizationList.map((item) => {
item.synchronization = 1;
return item.uid;
});
const userData = {};
allList.forEach((item) => {
if (synchronizationUids.includes(item.uid)) {
item.synchronization = 1;
return;
}
if (userData[item.createByName]) {
userData[item.createByName].push(item);
} else {
userData[item.createByName] = [item];
}
});
this.$store.commit("SET_ALL_DATA", allList);
const keys = Object.keys(userData);
const promiseArr = keys.map((key) => {
const val = userData[key];
return writeInspectionData(val, key);
});
Promise.all(promiseArr)
.then(() => {
setTimeout(() => {
// 生成签字图片
uni.canvasToTempFilePath({
canvasId: "signatureCanvas",
success: (res) => {
const tempFilePath = res.tempFilePath;
// 这里可以将 tempFilePath 上传到服务器或进行其他处理
uni.showToast({
title: "打包成功",
icon: "none",
duration: 2000,
title: "签字已保存",
icon: "success",
});
this.$emit("confirm", tempFilePath);
this.close();
this.loading = false;
// 生成日志
const logContent = getLogContent(
LOG_TYPE_ENUM.sys,
"",
"同步模块"
);
const log_list = this.$store.state.log_list;
log_list.push(logContent);
this.$store.commit("SET_LOG_LIST", log_list);
addLog(log_list).then((res) => {
});
// 更新同步时间
this.updateSysTime();
}, 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);
fail: (err) => {
console.error("生成图片失败", err);
},
});
createFileWithPlusIO(SYNCHRONIZE_DATA_PAD, USER_FILE_NAME, fileContent).then(() => {
console.log("---用户数据更新成功")
}).catch(error => {
console.log("---用户数据更新失败", error)
})
});
},
open() {
this.isOpen = true;
},
// 关闭弹窗
close() {
this.isOpen = false;
},
},
};
......@@ -312,10 +148,28 @@ export default {
display: flex;
align-items: center;
justify-content: center;
.signature-canvas {
width: 761.6px;
height: 302.4px;
background: #ffffff;
border: 1px solid rgba(224, 224, 224, 1);
border-radius: 9.6px;
}
.button-container {
margin-top: 20px;
display: flex;
justify-content: space-between;
button {
flex: 1;
margin: 0 5px;
}
}
.synchronous-content {
padding: 3% 20px 32px 24px;
width: 400px;
height: 60%;
padding: 25.6px 19.2px;
width: 800px;
height: 444.8px;
box-sizing: border-box;
background-image: linear-gradient(
-6deg,
......@@ -336,11 +190,20 @@ export default {
.title {
font-family: PingFangSC-Medium;
font-size: 18px;
font-size: 14.4px;
color: #000000;
text-align: center;
line-height: 26px;
line-height: 20.8px;
font-weight: 500;
margin-bottom: 20.8px;
.tip {
font-size: 12.8px;
color: #4a4a4a;
text-align: center;
line-height: 20.8px;
font-weight: 400;
margin-right: 6.4px;
}
}
.count-num {
margin: 5% 0 5% 0;
......@@ -356,7 +219,6 @@ export default {
}
.operating-instructions {
margin-bottom: 8%;
.title {
font-size: 13px;
color: #4a4a4a;
......@@ -375,7 +237,7 @@ export default {
// 打包按钮
.bottom-row {
position: absolute;
bottom: 24px;
bottom: 25.6px;
left: 50%;
transform: translateX(-50%);
......@@ -386,9 +248,14 @@ export default {
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;
width: 128px;
height: 32px;
color: #fff;
margin: 0 5px;
&.btn {
background: #ffffff;
color: #000000;
}
}
}
......
......@@ -478,7 +478,7 @@ export default {
});
// 清空基础缓存信息
this.$store.commit("SET_TEMP_DATA", {}); // 缓存[巡检信息]
// this.$store.commit("SET_TEMP_DATA", {}); // 缓存[巡检信息]
uni.showToast({
title: isSubmit ? "提交成功" : "保存草稿成功",
icon: "success",
......
......@@ -35,10 +35,10 @@
>
</view>
</view>
<view class="profile-right">
<!-- <button class="record-button" @click="toListingManagement">
<view v-if="isSubmit" class="profile-right">
<button v-if="!isSign" class="record-button" @click="toSign">
巡检人签字
</button> -->
</button>
</view>
</view>
</view>
......@@ -101,15 +101,25 @@
</view>
</view>
</view>
<signDialog ref="signDialog" @confirm="handlePopupConfirm"></signDialog>
</view>
</template>
<script>
import moment from "moment";
import { pad_2_1_inspection_position, pad_2_1_floor } from "@/utils/dict.js";
import {
writeInspectionData,
addLog,
getLogContent,
LOG_TYPE_ENUM,
} from "@/utils/IoReadingAndWriting.js";
import { getInspectionDetails } from "@/request/index.js";
import signDialog from "@/components/signDialog.vue";
export default {
components: {
signDialog,
},
data() {
return {
tabs: ["所有井道"], // 选项卡内容
......@@ -135,6 +145,8 @@ export default {
},
detailsInfo: {}, // 详情
isDisable: false, // 禁用
isSign: false, //签名状态
isSubmit: 0, //提交状态
uid: "",
options: {}, //存储数据
};
......@@ -221,6 +233,8 @@ export default {
this.inspectionNumber = detailsInfo.inspectionNumber;
this.inspectionCode = detailsInfo.inspectionCode;
this.cardsInfo = this.tabList = detailsInfo.originData;
this.isSubmit = this.detailsInfo.isSubmit;
this.isSign = this.detailsInfo.isSign;
console.log("this.cardsInfo", this.cardsInfo);
this.cardsInfo.forEach((item) => {
this.tabs.push(item.name);
......@@ -246,13 +260,54 @@ export default {
deleteClick() {
this.$refs.inputDialog2.open();
},
toSign() {
this.$refs.signDialog.open();
},
// tab选中change 时间
changeTab(index, item) {
this.draft(this.activeTabIndex, false, false).then(() => {
this.activeTabIndex = index;
});
},
// 处理弹窗确认
handlePopupConfirm(summary) {
this.detailsInfo.isSign = this.isSign = true; // 回显到文字显示区域
this.detailsInfo.signImg = summary; // 回显到文字显示区域
this.submit("sign", this.detailsInfo.signImg);
},
// 提交
submit(type = "sign", value = "") {
const all_data = this.$store.state.all_data; //获取全部数据
let params = this.detailsInfo;
params.signImg = value;
console.log("all_data", all_data);
console.log("all_data", all_data);
const index = all_data.findIndex((element) => element.uid == this.uid);
all_data[index] = params;
const logContent = getLogContent(LOG_TYPE_ENUM.sys, "数据同步", "同步");
// 更新巡检list
console.log("all_data存储", all_data);
this.$store.commit("SET_ALL_DATA", all_data);
const inspectList = all_data.filter(
(item) => item.createByName == userInfo.user
);
writeInspectionData(inspectList, userInfo.user);
// 更新日志
const log_list = this.$store.state.log_list;
logContent.inspectionType = params.inspectionType;
log_list.push(logContent);
this.$store.commit("SET_LOG_LIST", log_list);
addLog(log_list).then((res) => {
console.log("日志文件写入成功");
});
uni.showToast({
title: type == "sign" ? "签字成功" : "同步成功",
icon: "success",
});
},
lookTable() {
uni.navigateTo({
url: "/pages/report/sampleTable?isJF=0",
......
......@@ -250,7 +250,8 @@ export default {
inspectionNumber: 0, //巡检数量
floor: this.floor, // 楼层
isSubmit: "", // 0 是草稿态; 1 是正式提交
isSign: "", // 是否签字
isSign: false, // 是否签字
signImg:"",// 签字图片地址
conclusion: "", //摘要
creatTime: `${new Date().getTime()}`,
items: [],
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论