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

fix:同步

上级 059f084e
<template> <template>
<view class="synchronous-dialog"> <view v-if="isOpen" class="synchronous-dialog">
<view class="synchronous-content"> <view class="synchronous-content">
<view class="row-item"> <view class="row-item">
<text class="title">待打包数据</text> <text class="title"
</view> >巡检签字 <text class="tip">请在下方虚线框内进行签字</text></text
<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同步的数据不支持修改。
</view> </view>
<view class="operating-instructions"
><!-- 签字区域 -->
<canvas
canvas-id="signatureCanvas"
class="signature-canvas"
@touchstart="handleTouchStart"
@touchmove="handleTouchMove"
@touchend="handleTouchEnd"
></canvas>
</view> </view>
<view class="row-item bottom-row"> <view class="row-item bottom-row">
<button class="button" :loading="loading" @click="clickHandle"> <button class="button btn" @click="clearSignature">重新签字</button>
数据打包 <button class="button" @click="confirmSignature">完成签字</button>
</button>
</view> </view>
<!-- 关闭按钮 --> <!-- 关闭按钮 -->
...@@ -38,265 +31,108 @@ ...@@ -38,265 +31,108 @@
</template> </template>
<script> <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 { export default {
props: {
list: {
type: Array,
default: () => {
return [];
},
},
},
components: {}, components: {},
data() { data() {
return { return {
loading: false, isOpen: false,
notSynchronizationList: [], // 未同步数据 points: [], // 存储绘制点
allList: [], // 所有数据 ctx: null, // canvas 上下文
canvasWidth: 761.6,
canvasHeight: 302.4,
isDrawing: false, // 是否正在绘制
}; };
}, },
mounted() { mounted() {
const temp = []; this.initCanvas();
this.list.forEach((item) => {
temp.push(...(item.list || []));
});
this.notSynchronizationList = temp.filter(
(item) => item.synchronization == 0
);
getAllInspections().then((res) => {
this.allList = res;
});
}, },
watch: { methods: {
list(newData) { initCanvas() {
const temp = []; this.ctx = uni.createCanvasContext("signatureCanvas", this);
newData.forEach((item) => { // 设置画布背景为白色
temp.push(...(item.list || [])); this.ctx.fillStyle = "#ffffff";
}); this.ctx.fillRect(0, 0, this.canvasWidth, this.canvasHeight);
this.notSynchronizationList = temp.filter( this.ctx.setStrokeStyle("#000000"); // 设置线条颜色
(item) => item.synchronization == 0 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: { clearSignature() {
close() { // 清空画布
this.$emit("close"); 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; // 标记没有签字内容
}, },
async confirmSignature() {
/** // 如果没有签字内容,直接提示
* 1.生成两个文件. 机房文件 和 井道文件 if (!this.hasSigned) {
* 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) => {
uni.showToast({ uni.showToast({
title: error, title: "请先签字",
icon: "none", 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;
}); });
return;
const userData = {};
allList.forEach((item) => {
if (synchronizationUids.includes(item.uid)) {
item.synchronization = 1;
} }
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(() => { uni.canvasToTempFilePath({
setTimeout(() => { canvasId: "signatureCanvas",
success: (res) => {
const tempFilePath = res.tempFilePath;
// 这里可以将 tempFilePath 上传到服务器或进行其他处理
uni.showToast({ uni.showToast({
title: "打包成功", title: "签字已保存",
icon: "none", icon: "success",
duration: 2000,
}); });
this.$emit("confirm", tempFilePath);
this.close(); 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);
});
}, },
fail: (err) => {
// 打包文件 console.error("生成图片失败", err);
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("---用户数据更新成功") open() {
}).catch(error => { this.isOpen = true;
console.log("---用户数据更新失败", error) },
// 关闭弹窗
}) close() {
}); this.isOpen = false;
}, },
}, },
}; };
...@@ -312,10 +148,28 @@ export default { ...@@ -312,10 +148,28 @@ export default {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: 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 { .synchronous-content {
padding: 3% 20px 32px 24px; padding: 25.6px 19.2px;
width: 400px; width: 800px;
height: 60%; height: 444.8px;
box-sizing: border-box; box-sizing: border-box;
background-image: linear-gradient( background-image: linear-gradient(
-6deg, -6deg,
...@@ -336,11 +190,20 @@ export default { ...@@ -336,11 +190,20 @@ export default {
.title { .title {
font-family: PingFangSC-Medium; font-family: PingFangSC-Medium;
font-size: 18px; font-size: 14.4px;
color: #000000; color: #000000;
text-align: center; text-align: center;
line-height: 26px; line-height: 20.8px;
font-weight: 500; 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 { .count-num {
margin: 5% 0 5% 0; margin: 5% 0 5% 0;
...@@ -356,7 +219,6 @@ export default { ...@@ -356,7 +219,6 @@ export default {
} }
.operating-instructions { .operating-instructions {
margin-bottom: 8%;
.title { .title {
font-size: 13px; font-size: 13px;
color: #4a4a4a; color: #4a4a4a;
...@@ -375,7 +237,7 @@ export default { ...@@ -375,7 +237,7 @@ export default {
// 打包按钮 // 打包按钮
.bottom-row { .bottom-row {
position: absolute; position: absolute;
bottom: 24px; bottom: 25.6px;
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
...@@ -386,9 +248,14 @@ export default { ...@@ -386,9 +248,14 @@ export default {
background-image: linear-gradient(180deg, #3773f6 0%, #2c57f6 99%); background-image: linear-gradient(180deg, #3773f6 0%, #2c57f6 99%);
box-shadow: 0px 10px 24px 0px rgba(51, 104, 246, 0.24); box-shadow: 0px 10px 24px 0px rgba(51, 104, 246, 0.24);
border-radius: 27px; border-radius: 27px;
width: 160px; width: 128px;
height: 40px; height: 32px;
color: #fff; color: #fff;
margin: 0 5px;
&.btn {
background: #ffffff;
color: #000000;
}
} }
} }
......
...@@ -478,7 +478,7 @@ export default { ...@@ -478,7 +478,7 @@ export default {
}); });
// 清空基础缓存信息 // 清空基础缓存信息
this.$store.commit("SET_TEMP_DATA", {}); // 缓存[巡检信息] // this.$store.commit("SET_TEMP_DATA", {}); // 缓存[巡检信息]
uni.showToast({ uni.showToast({
title: isSubmit ? "提交成功" : "保存草稿成功", title: isSubmit ? "提交成功" : "保存草稿成功",
icon: "success", icon: "success",
......
...@@ -35,10 +35,10 @@ ...@@ -35,10 +35,10 @@
> >
</view> </view>
</view> </view>
<view class="profile-right"> <view v-if="isSubmit" class="profile-right">
<!-- <button class="record-button" @click="toListingManagement"> <button v-if="!isSign" class="record-button" @click="toSign">
巡检人签字 巡检人签字
</button> --> </button>
</view> </view>
</view> </view>
</view> </view>
...@@ -101,15 +101,25 @@ ...@@ -101,15 +101,25 @@
</view> </view>
</view> </view>
</view> </view>
<signDialog ref="signDialog" @confirm="handlePopupConfirm"></signDialog>
</view> </view>
</template> </template>
<script> <script>
import moment from "moment"; import moment from "moment";
import { pad_2_1_inspection_position, pad_2_1_floor } from "@/utils/dict.js"; 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 { getInspectionDetails } from "@/request/index.js";
import signDialog from "@/components/signDialog.vue";
export default { export default {
components: {
signDialog,
},
data() { data() {
return { return {
tabs: ["所有井道"], // 选项卡内容 tabs: ["所有井道"], // 选项卡内容
...@@ -135,6 +145,8 @@ export default { ...@@ -135,6 +145,8 @@ export default {
}, },
detailsInfo: {}, // 详情 detailsInfo: {}, // 详情
isDisable: false, // 禁用 isDisable: false, // 禁用
isSign: false, //签名状态
isSubmit: 0, //提交状态
uid: "", uid: "",
options: {}, //存储数据 options: {}, //存储数据
}; };
...@@ -221,6 +233,8 @@ export default { ...@@ -221,6 +233,8 @@ export default {
this.inspectionNumber = detailsInfo.inspectionNumber; this.inspectionNumber = detailsInfo.inspectionNumber;
this.inspectionCode = detailsInfo.inspectionCode; this.inspectionCode = detailsInfo.inspectionCode;
this.cardsInfo = this.tabList = detailsInfo.originData; this.cardsInfo = this.tabList = detailsInfo.originData;
this.isSubmit = this.detailsInfo.isSubmit;
this.isSign = this.detailsInfo.isSign;
console.log("this.cardsInfo", this.cardsInfo); console.log("this.cardsInfo", this.cardsInfo);
this.cardsInfo.forEach((item) => { this.cardsInfo.forEach((item) => {
this.tabs.push(item.name); this.tabs.push(item.name);
...@@ -246,13 +260,54 @@ export default { ...@@ -246,13 +260,54 @@ export default {
deleteClick() { deleteClick() {
this.$refs.inputDialog2.open(); this.$refs.inputDialog2.open();
}, },
toSign() {
this.$refs.signDialog.open();
},
// tab选中change 时间 // tab选中change 时间
changeTab(index, item) { changeTab(index, item) {
this.draft(this.activeTabIndex, false, false).then(() => { this.draft(this.activeTabIndex, false, false).then(() => {
this.activeTabIndex = index; 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() { lookTable() {
uni.navigateTo({ uni.navigateTo({
url: "/pages/report/sampleTable?isJF=0", url: "/pages/report/sampleTable?isJF=0",
......
...@@ -250,7 +250,8 @@ export default { ...@@ -250,7 +250,8 @@ export default {
inspectionNumber: 0, //巡检数量 inspectionNumber: 0, //巡检数量
floor: this.floor, // 楼层 floor: this.floor, // 楼层
isSubmit: "", // 0 是草稿态; 1 是正式提交 isSubmit: "", // 0 是草稿态; 1 是正式提交
isSign: "", // 是否签字 isSign: false, // 是否签字
signImg:"",// 签字图片地址
conclusion: "", //摘要 conclusion: "", //摘要
creatTime: `${new Date().getTime()}`, creatTime: `${new Date().getTime()}`,
items: [], items: [],
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论