You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
492 lines
14 KiB
TypeScript
492 lines
14 KiB
TypeScript
import Taro from "@tarojs/taro";
|
|
import classnames from "classnames";
|
|
|
|
import { Component, PropsWithChildren, useEffect, useState } from "react";
|
|
import {
|
|
Block,
|
|
View,
|
|
Video,
|
|
Text,
|
|
Image,
|
|
Input,
|
|
Button,
|
|
ScrollView,
|
|
Textarea,
|
|
Canvas,
|
|
} from "@tarojs/components";
|
|
|
|
import Navbar from "@/components/navbar/navbar";
|
|
import PopupInstrumentUploadTips from "@/components/popup/popup-instrument-upload-tips";
|
|
|
|
import { InstrumentInfo } from "@/utils/Interface";
|
|
|
|
import "./index.less";
|
|
import { contraction, getImgInfo } from "@/utils/compressImage";
|
|
import PopupAlert from "@/components/popup/popup-alert";
|
|
import { setStorageSync, getStorageSync, msg } from "@/utils/traoAPI";
|
|
|
|
export default class InstrumentClickInUpload extends Component<any, any> {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
name: "仪器打卡上传",
|
|
year: new Date().getFullYear(),
|
|
month: String(new Date().getMonth() + 1).padStart(2, "0"),
|
|
day: String(new Date().getDate()).padStart(2, "0"),
|
|
zkmoshiindex: 0,
|
|
moshiindex: null,
|
|
buzhouindex: null,
|
|
autoplay: false,
|
|
scrollleft: 0,
|
|
sysinfo: Taro.getSystemInfoSync(),
|
|
showVideoPlayBtn: true,
|
|
duration: 0,
|
|
|
|
videoContext: {}, // 视频播放器
|
|
isTipShow: false,
|
|
clockContent: "", // 默认展示
|
|
instrumentDetail: {},
|
|
punchInInfo: {
|
|
clockImageList: [],
|
|
clockContent: "",
|
|
instrumentId: "84",
|
|
firstClockImg: null,
|
|
secondClockImg: null,
|
|
thirdClockImg: null,
|
|
},
|
|
// 现在选中的数据
|
|
currentInfo: {
|
|
modeVideo: "",
|
|
},
|
|
modeInfo: [],
|
|
nurseInfo: [], // 首次进入介绍弹窗
|
|
isModeLock: false,
|
|
|
|
isSubmit: false, // 已提交则禁用提交按钮
|
|
};
|
|
}
|
|
|
|
async onLoad() {
|
|
this.initData();
|
|
}
|
|
componentDidMount() {}
|
|
|
|
componentWillUnmount() {}
|
|
|
|
componentDidShow() {
|
|
let videoContext = Taro.createVideoContext("myVideo");
|
|
this.setState({ videoContext });
|
|
}
|
|
|
|
componentDidHide() {}
|
|
|
|
async initData() {
|
|
let objStr = getStorageSync("instrument_detail");
|
|
if (objStr) {
|
|
let instrumentDetail = JSON.parse(objStr);
|
|
this.setState({ instrumentDetail });
|
|
}
|
|
|
|
setTimeout(() => {
|
|
this.firstNurseInfo();
|
|
this.getLatestClockRecord();
|
|
this.modeInfoList();
|
|
}, 10);
|
|
}
|
|
|
|
// 打卡介绍
|
|
firstNurseInfo = async () => {
|
|
let { instrumentDetail } = this.state;
|
|
let res = await InstrumentInfo.firstNurseInfo({
|
|
instrumentId: instrumentDetail.id,
|
|
});
|
|
if (res.data.code === 200) {
|
|
let isTipShow = getStorageSync("first_instrument_" + instrumentDetail.id);
|
|
if (!isTipShow) {
|
|
// 首次进入页面:自动打开打卡介绍弹窗
|
|
this.setState({ nurseInfo: res.data.data, isTipShow: true });
|
|
} else {
|
|
this.setState({ nurseInfo: res.data.data });
|
|
}
|
|
}
|
|
};
|
|
// 获取最新一条打卡记录
|
|
getLatestClockRecord = async () => {
|
|
let { punchInInfo } = this.state;
|
|
let res = await InstrumentInfo.apiClock.getLatestClockRecord();
|
|
if (res.data.code === 200) {
|
|
punchInInfo.clockContent = res.data.data.clockContent;
|
|
punchInInfo.clockImageList = res.data.data.clockImg;
|
|
}
|
|
this.setState({ punchInInfo });
|
|
};
|
|
// 获取仪器模式列表
|
|
modeInfoList = async () => {
|
|
let res = await InstrumentInfo.modeInfoList({
|
|
instrumentId: "84",
|
|
});
|
|
if (res.data.code === 200) {
|
|
if (res.data.data.length) {
|
|
this.setState({
|
|
currentInfo: res.data.data[0],
|
|
modeInfo: res.data.data,
|
|
});
|
|
}
|
|
}
|
|
};
|
|
|
|
bindMoshi = async (index) => {
|
|
let { currentInfo, modeInfo, punchInInfo } = this.state;
|
|
currentInfo = modeInfo[index];
|
|
if (currentInfo.lock) {
|
|
this.onModeLockOpen(); // 点击了锁定模式
|
|
return;
|
|
}
|
|
this.setState({ zkmoshiindex: index, currentInfo });
|
|
};
|
|
|
|
// 选择图片上传
|
|
handleChooseImage = async () => {
|
|
let { punchInInfo } = this.state;
|
|
Taro.chooseMedia({
|
|
count: 1,
|
|
mediaType: ["image"],
|
|
sourceType: ["album", "camera"],
|
|
sizeType: ["compressed"],
|
|
camera: "back",
|
|
success: async (res) => {
|
|
const tempFilePath = res.tempFiles[0].tempFilePath;
|
|
let img = await getImgInfo(tempFilePath);
|
|
let compressImage = await contraction(img, "compressImage");
|
|
// 压缩后文件地址
|
|
let compressTempFilePath = compressImage.tempFilePath;
|
|
punchInInfo.clockImageList.push(compressTempFilePath);
|
|
|
|
this.setState({ punchInInfo });
|
|
},
|
|
});
|
|
};
|
|
|
|
// 删除打卡图片
|
|
handleDeleteImage = async (index) => {
|
|
let { punchInInfo } = this.state;
|
|
punchInInfo.clockImageList.splice(index, 1);
|
|
|
|
this.setState({ punchInInfo });
|
|
};
|
|
|
|
// 提交打卡
|
|
handleSubmit = async () => {
|
|
let { punchInInfo } = this.state;
|
|
let obj = punchInInfo;
|
|
if (obj.clockImageList.length === 0) {
|
|
msg("至少上传一张图片");
|
|
return;
|
|
}
|
|
|
|
let promiseTasks: any = [];
|
|
let imgList: any[] = [];
|
|
obj.clockImageList.map((imgUrl: string) => {
|
|
let isTmpFile = imgUrl.indexOf("//tmp") > -1;
|
|
let isWXFile = imgUrl.indexOf("wxfile://") > -1;
|
|
if (isTmpFile || isWXFile) {
|
|
let params = {
|
|
clockImg: imgUrl,
|
|
};
|
|
promiseTasks.push(InstrumentInfo.apiClock.clockFileUpload(params));
|
|
imgList.push("null");
|
|
} else {
|
|
imgList.push(imgUrl);
|
|
}
|
|
});
|
|
|
|
if (promiseTasks.length) {
|
|
let res = await Promise.all(promiseTasks);
|
|
//具体处理写在如下
|
|
if (res.length) {
|
|
res.map((item) => {
|
|
if (item.code === 200) {
|
|
let index = imgList.findIndex((url) => url === "null");
|
|
if (index > -1) {
|
|
imgList[index] = item.data.url;
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
let clockParmas = {
|
|
clockImageList: imgList,
|
|
clockContent: obj.clockContent,
|
|
};
|
|
let res = await InstrumentInfo.apiClock.postInsertClockLog(clockParmas);
|
|
if (res.data.code === 200) {
|
|
msg("打卡成功");
|
|
setTimeout(() => {
|
|
Taro.switchTab({
|
|
url: "/pages/index/index",
|
|
});
|
|
}, 2000);
|
|
}
|
|
};
|
|
|
|
onPlayTap = async () => {
|
|
let { videoContext } = this.state;
|
|
videoContext.play();
|
|
this.setState({
|
|
showVideoPlayBtn: false,
|
|
});
|
|
};
|
|
|
|
videoBindTimeUpdate = async () => {};
|
|
|
|
videoEnded = async () => {};
|
|
|
|
videoPause = async () => {};
|
|
|
|
videoPlay = async () => {};
|
|
|
|
videoLoadedMetaData = async () => {};
|
|
|
|
handleTextareaInput = async (e) => {
|
|
let { punchInInfo } = this.state;
|
|
punchInInfo.clockContent = e.detail.value;
|
|
|
|
this.setState({ punchInInfo });
|
|
};
|
|
|
|
onModeLockOpen = async () => {
|
|
this.setState({ isModeLock: true });
|
|
};
|
|
onModeLockClose = async () => {
|
|
this.setState({ isModeLock: false });
|
|
};
|
|
|
|
onTipShowOpen = async () => {
|
|
this.setState({ isTipShow: true });
|
|
};
|
|
onTipShowClose = async () => {
|
|
setStorageSync(
|
|
"first_instrument_" + this.state.instrumentDetail.id,
|
|
"true"
|
|
);
|
|
this.setState({ isTipShow: false });
|
|
};
|
|
|
|
render() {
|
|
let {
|
|
name,
|
|
duration,
|
|
showVideoPlayBtn,
|
|
scrollleft,
|
|
zkmoshiindex,
|
|
punchInInfo,
|
|
isTipShow,
|
|
currentInfo,
|
|
modeInfo,
|
|
nurseInfo,
|
|
isModeLock,
|
|
isSubmit,
|
|
} = this.state;
|
|
return (
|
|
<Block>
|
|
<Navbar titleSlot="打卡上传" isBack={true} />
|
|
<Canvas
|
|
style="height: 0"
|
|
id="compressImage"
|
|
canvasId="compressImage"
|
|
type="2d"
|
|
></Canvas>
|
|
<PopupAlert
|
|
isShow={isModeLock}
|
|
title="提示"
|
|
content="该模式即将上线,敬请期待"
|
|
confirmButtonText="知道了"
|
|
textAlgin="center"
|
|
isClose={false}
|
|
close={this.onModeLockClose}
|
|
confirm={this.onModeLockClose}
|
|
/>
|
|
<PopupInstrumentUploadTips
|
|
isShow={isTipShow}
|
|
title="打卡介绍"
|
|
data={nurseInfo}
|
|
close={this.onTipShowClose}
|
|
confirm={this.onTipShowClose}
|
|
/>
|
|
|
|
<View className="infobox1 flex aitems jcenter">
|
|
<View className="img">
|
|
<Video
|
|
src={currentInfo.modeVideo}
|
|
id="myVideo"
|
|
enableProgressGesture={false}
|
|
controls={true}
|
|
// autoplay={false}
|
|
direction={0}
|
|
loop={false}
|
|
showMuteBtn={true}
|
|
referrerPolicy="origin"
|
|
onTimeUpdate={this.videoBindTimeUpdate}
|
|
onEnded={this.videoEnded}
|
|
onPause={this.videoPause}
|
|
onPlay={this.videoPlay}
|
|
showCenterPlayBtn={false}
|
|
onLoadedMetaData={this.videoLoadedMetaData}
|
|
style="width: 100%; height: 100%;border-radius: 30rpx;"
|
|
/>
|
|
{showVideoPlayBtn && (
|
|
<View className="video-cover">
|
|
<Image
|
|
className="video-cover-icon"
|
|
src={require("../../img/fr200/play.png")}
|
|
onClick={this.onPlayTap}
|
|
></Image>
|
|
{duration && (
|
|
<View className="video-cover-time">{duration}</View>
|
|
)}
|
|
</View>
|
|
)}
|
|
</View>
|
|
</View>
|
|
|
|
<View className="infobox3">
|
|
<ScrollView
|
|
style="white-space: nowrap; height: 100%;"
|
|
scroll-x={true}
|
|
scroll-left={scrollleft}
|
|
>
|
|
{modeInfo.map((item, index) => {
|
|
return (
|
|
<View
|
|
className="info1"
|
|
onClick={this.bindMoshi.bind(this, index)}
|
|
key={index}
|
|
>
|
|
<View
|
|
className="flex aitems"
|
|
style="height: 100%; {{zkmoshiindex == index ? 'background: linear-gradient(90deg, #EFDCC2, #FFF2DF)': ''}}"
|
|
>
|
|
<View className="block1">
|
|
<View
|
|
className="block1_1 flex aitems "
|
|
style="min-width: 80rpx"
|
|
>
|
|
<View className="tip1">{item.modeName}</View>
|
|
<View className="tip2">{item.modeDesc}</View>
|
|
|
|
{!item.lock && zkmoshiindex !== index && (
|
|
<View className="quan1"></View>
|
|
)}
|
|
{!item.lock && zkmoshiindex == index && (
|
|
<View className="quan1 is-select flex aitems jcenter">
|
|
<View className="quan2"></View>
|
|
</View>
|
|
)}
|
|
|
|
{item.lock && (
|
|
<View className="icon">
|
|
<Image
|
|
src="/img/fr200/suo.png"
|
|
mode="aspectFill"
|
|
></Image>
|
|
</View>
|
|
)}
|
|
</View>
|
|
</View>
|
|
{item.modeBanner && (
|
|
<View className="info1_img">
|
|
<Image src={item.modeBanner} mode="aspectFill" />
|
|
</View>
|
|
)}
|
|
</View>
|
|
</View>
|
|
);
|
|
})}
|
|
</ScrollView>
|
|
</View>
|
|
|
|
<View className="infobox2">
|
|
<View className="infobox2_info">
|
|
<View className="info4">
|
|
<View className="upload_header flex aitems sb">
|
|
<View className="upload_title">打卡上传</View>
|
|
<View className="icon" onClick={this.onTipShowOpen}>
|
|
<Image
|
|
src={require("../../img/clock_in_upload/info.png")}
|
|
mode="aspectFill"
|
|
></Image>
|
|
</View>
|
|
</View>
|
|
<View className="imgbox flex aitems">
|
|
{punchInInfo.clockImageList.length > 0 &&
|
|
punchInInfo.clockImageList.map((item, index) => {
|
|
return (
|
|
<View className="img" key={"clickin_" + index}>
|
|
<Image src={item}></Image>
|
|
<View
|
|
className="close flex aitems jcenter"
|
|
data-index="{{index}}"
|
|
onClick={this.handleDeleteImage}
|
|
>
|
|
<Image
|
|
src={require("../../img/fr200/close_white.png")}
|
|
mode="widthFix"
|
|
></Image>
|
|
</View>
|
|
</View>
|
|
);
|
|
})}
|
|
|
|
{punchInInfo.clockImageList.length < 3 && (
|
|
<View
|
|
className="img2 flex aitems jcenter"
|
|
onClick={this.handleChooseImage}
|
|
>
|
|
<Image
|
|
src={require("../../img/fr200/add-Image.png")}
|
|
mode="aspectFill"
|
|
></Image>
|
|
</View>
|
|
)}
|
|
</View>
|
|
<View className="content">
|
|
<Textarea
|
|
placeholder-className="placeholder"
|
|
maxlength={100}
|
|
onInput={this.handleTextareaInput}
|
|
value={punchInInfo.clockContent}
|
|
placeholder="请记录一下今天打卡的心得吧~"
|
|
></Textarea>
|
|
{/* {tipshow && (
|
|
<View className="Textarea">
|
|
{punchInInfo.clockContent
|
|
? punchInInfo.clockContent
|
|
: "请记录一下今天打卡的心得吧~"}
|
|
</View>
|
|
)} */}
|
|
<View className="tips-num">
|
|
{punchInInfo.clockContent.length}/100
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
</View>
|
|
|
|
<View style="height: 150rpx"></View>
|
|
|
|
{!isSubmit && (
|
|
<View className="confirm_btn flex aitems" onClick={this.handleSubmit}>
|
|
<View className="btn">提交打卡</View>
|
|
</View>
|
|
)}
|
|
{isSubmit && (
|
|
<View className="confirm_btn flex aitems">
|
|
<View className="btn">提交打卡</View>
|
|
</View>
|
|
)}
|
|
</Block>
|
|
);
|
|
}
|
|
}
|