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.

545 lines
16 KiB
TypeScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import Taro from "@tarojs/taro";
import dayjs from "dayjs";
import { Component } from "react";
import {
Block,
View,
Text,
Image,
RichText,
ScrollView,
} from "@tarojs/components";
import { Loading } from "@antmjs/vantui";
import "./integral_list.less";
/*** redux ***/
import { connect } from "react-redux";
import { userRefresh } from "../../store/features/userInfo";
import { otherSettingRefresh } from "../../store/features/otherSetting";
/*** redux end ***/
/** 自定义组件 **/
import Navbar from "../../components/navbar/navbar";
import PopupAlert from "../../components/popup/popup-alert";
/** 自定义组件 **/
import {
GetOtherSetting,
GetIntegralRule,
GetObtainUserIntegral,
GetIsAttentionOfficialAccount,
GetOfficialAccount,
GetCloseOfficialAccount,
RefreshWxUserInfo,
} from "../../utils/Interface";
import { msg } from "../../utils/traoAPI";
class IntegralList extends Component<any, any> {
constructor(props) {
super(props);
this.state = {
name: "我的积分",
userinfo: {
...this.props.userInfo,
},
otherSetting: {
// skipAppid: "",
// skipPath: "",
// envVersion: "",
...this.props.otherSetting,
},
page: 1,
list: [],
isIntegral: false, // 积分规则
isOfficialAccount: false, // 是否关注公众号-一年展示一次
nodes: "",
pageNum: 1,
pageSize: 10,
total: 0,
dargState: 0,
};
}
async onLoad() {
this.initData();
this.GetIntegralRule();
}
componentDidMount() {}
componentWillUnmount() {}
componentDidShow() {}
componentDidHide() {}
async initData() {
this.RefreshWxUserInfo();
this.GetObtainUserIntegral();
this.GetIsAttentionOfficialAccount();
}
// 刷新用户信息
RefreshWxUserInfo = async () => {
let res = await RefreshWxUserInfo();
if (res.data.code === 200) {
this.props.userRefresh(res.data.data);
this.setState({ userInfo: res.data.data });
}
};
openShop = () => {
let { otherSetting } = this.state;
if (otherSetting.skipAppid) {
this.goMiniProgram();
} else {
this.GetOtherSetting(); // 获取小程序设置:商城地址和版本
}
};
// 获取小程序设置
GetOtherSetting = async () => {
let res = await GetOtherSetting();
if (res.data.code === 200) {
let { otherSetting } = this.state;
otherSetting.skipAppid = res.data.data.skipAppid;
otherSetting.skipPath = res.data.data.skipPath;
otherSetting.envVersion = res.data.data.envVersion;
this.setState({ otherSetting });
this.goMiniProgram();
}
};
goMiniProgram = () => {
let { otherSetting } = this.state;
Taro.navigateToMiniProgram({
appId: otherSetting.skipAppid,
path: otherSetting.skipPath,
envVersion: otherSetting.envVersion,
success() {
// 打开成功
// Taro.switchTab({
// url: "/pages/index/index",
// });
},
fail() {
// Taro.switchTab({
// url: "/pages/index/index",
// });
},
});
};
// 检查是否关注公众号只在每年的09-30号前提醒如果没有关注则弹窗提醒
checkOfficialAccount() {
let currentTime = dayjs().valueOf();
let targetTime = dayjs().month(9).day(30).valueOf();
// 仅9月30日前触发提醒过期弹窗
if (currentTime <= targetTime) {
// 检查:今年未提醒,则弹窗
this.setState({ isOfficialAccount: true });
// let isOfficialAccount = Taro.getStorageSync("isOfficialAccount");
// if (isOfficialAccount) {
// let oldYear = isOfficialAccount;
// let currentYear = dayjs().format("YYYY");
// if (currentYear < oldYear) {
// // 检查:今年未提醒,则弹窗
// this.setState({ isOfficialAccount: true });
// }
// } else {
// this.setState({ isOfficialAccount: true });
// }
}
}
// 用户是否已关闭提醒
GetOfficialAccount = async () => {
Taro.showLoading({
title: "请求中...",
mask: true,
});
let res = await GetOfficialAccount();
if (res.data.code === 200) {
if (!res.data.data) {
// 如果false则是未关闭提醒
this.checkOfficialAccount(); // 检测时间,弹窗提示关注公众号
}
}
};
// 用户是否关注公众号
GetIsAttentionOfficialAccount = async () => {
Taro.showLoading({
title: "请求中...",
mask: true,
});
let res = await GetIsAttentionOfficialAccount();
if (res.data.code === 200) {
if (!res.data.data) {
// 如果false则是没关注
this.GetOfficialAccount();
}
}
};
// 用户关闭提醒
GetCloseOfficialAccount = async () => {
let { data } = await GetCloseOfficialAccount();
if (data.code === 200) {
msg("已关闭提醒");
} else {
msg("操作失败");
}
};
GetObtainUserIntegral = async () => {
Taro.showLoading({
title: "请求中...",
mask: true,
});
let { list, pageNum, pageSize } = this.state;
let res = await GetObtainUserIntegral({
pageNum,
pageSize,
});
if (res.data.code === 200) {
if (res.data.rows.length) {
let data = res.data.rows.map((item: any) => {
item.createTime = item.createTime
? dayjs(item.createTime).format("YYYY-MM-DD hh:mm:ss")
: "";
return item;
});
list = [].concat(list, data);
this.setState({ list: list, total: res.data.total, dargState: 0 });
}
}
};
GetIntegralRule = async () => {
Taro.showLoading({
title: "请求中...",
mask: true,
});
let res = await GetIntegralRule();
console.log("GetIntegralRule", res);
if (res.data.code === 200) {
let nodes = decodeURIComponent(res.data.data.value || "");
nodes = nodes.replace(/\<img/gi, '<img style="width:100%;height:auto" ');
nodes = nodes.replace(
/\<table/gi,
'<table style="border-spacing: 0;border-collapse: collapse;border: 1px solid #000" '
);
nodes = nodes.replace(
/\<td/gi,
'<td style="border: 1px solid #000;text-align:center" '
);
this.setState({ nodes: nodes });
}
};
integralPopupShow = () => {
this.setState({ isIntegral: true });
};
integralPopupClose = () => {
this.setState({ isIntegral: false });
};
/** 关注公众号弹窗 */
officialPopupConfirm = () => {
// let currentYear = dayjs().format("YYYY");
// Taro.setStorageSync("isOfficialAccount", currentYear); // 标记:本年度已提醒
this.GetCloseOfficialAccount();
this.officialPopupClose();
};
officialPopupClose = () => {
this.setState({ isOfficialAccount: false });
};
/*** 上拉加载 ***/
reduction = () => {
//还原初始设置
// const time = 0.5;
this.setState({
scrollY: true,
});
};
touchStart = (e) => {
this.setState({
start_p: e.touches[0],
});
};
touchmove = (e) => {
let move_p = e.touches[0], //移动时的位置
deviationX = 0.3, //左右偏移量(超过这个偏移量不执行下拉操做)
deviationY = 70, //拉动长度(低于这个值的时候不执行)
maxY = 100; //拉动的最大高度
let start_x = this.state.start_p.clientX,
start_y = this.state.start_p.clientY,
move_x = move_p.clientX,
move_y = move_p.clientY;
//获得偏移数值
let dev = Math.abs(move_x - start_x) / Math.abs(move_y - start_y);
if (dev < deviationX) {
//当偏移数值大于设置的偏移数值时则不执行操做
let pY = Math.abs(move_y - start_y) / 3.5; //拖动倍率(使拖动的时候有粘滞的感受--试了不少次 这个倍率恰好)
if (move_y - start_y > 0) {
//下拉操做
if (pY >= deviationY) {
// this.setState({ dargState: 1, downText: "释放刷新" });
} else {
// this.setState({ dargState: 0, downText: "下拉刷新" });
}
if (pY >= maxY) {
pY = maxY;
}
this.setState({
scrollY: false, //拖动的时候禁用
});
}
if (start_y - (move_y + 100) > 0) {
//上拉操做
// console.log("上拉操做");
if (pY >= deviationY) {
this.setState({ dargState: -1 });
}
}
}
};
pull = () => {
//上拉
console.log("上拉");
let { list, total, pageNum, dargState } = this.state;
if (dargState === -1) {
if (list.length < total) {
this.setState({ pageNum: pageNum + 1 });
setTimeout(() => {
this.GetObtainUserIntegral();
}, 100);
}
}
};
down = () => {
//下拉
console.log("下拉");
// this.props.onDown()
};
ScrollToUpper = () => {
//滚动到顶部事件
console.log("滚动到顶部事件");
// this.props.Upper()
};
ScrollToLower = () => {
//滚动到底部事件
console.log("滚动到底部事件");
// this.props.Lower()
};
touchEnd = () => {
if (this.state.dargState === 1) {
this.down();
} else if (this.state.dargState === -1) {
this.pull();
}
// this.reduction();
};
/*** 上拉加载 ***/
render() {
let {
list,
userinfo,
isIntegral,
isOfficialAccount,
nodes,
dargState,
total,
} = this.state;
return (
<Block>
<PopupAlert
myClassName="integral"
isLarge={true}
isClose={true}
isShow={isIntegral}
title="积分规则"
content={<RichText nodes={nodes} />}
confirmButtonText="我知道了"
textAlgin="center"
close={this.integralPopupClose}
confirm={this.integralPopupClose}
/>
<PopupAlert
myClassName="officialAccount"
isLarge={true}
isClose={true}
isShow={isOfficialAccount}
title="过期积分提醒"
type="3"
content={
// <View style={{ height: "700rpx" }}> // 删除测试阶段标签后需改回700rpx
<View style={{ height: "750rpx" }}>
<Image
style={{
width: "100%",
height: "600rpx",
// backgroundColor: "#666",
}}
showMenuByLongpress={true} //
src={require("../../img/qrcode-test.jpg")}
mode="aspectFit"
/>
<View style={{ marginTop: "20rpx" }}>
</View>
<View style={{ marginTop: "10rpx", color: "#666" }}>
(广)
</View>
</View>
}
confirmButtonText="我知道了"
textAlgin="center"
close={this.officialPopupClose}
confirm={this.officialPopupConfirm}
/>
<Navbar titleSlot="我的积分" isBack={true} />
<View style="background: #f3f3f3;padding: 33rpx 30rpx 31rpx 30rpx;">
<View className="integral_box1">
<View
className="info1 flex aitems"
onClick={this.integralPopupShow}
>
<View className="tip1"></View>
<View className="icon">
<Image
src={require("../../img/user/right.png")}
mode="aspectFill"
/>
</View>
</View>
<View className="info3"></View>
<View className="info2">{userinfo.credit}</View>
<View className="info4 flex aitems jcenter">
<View className="tip1" onClick={this.openShop}>
</View>
</View>
<Image
className="point_bg"
src={require("../../img/user/point-bg.png")}
mode="aspectFill"
/>
</View>
</View>
<View className="integral_box2">
{/* {list.length === 0 && (
<View className="nodata">
<Image
className="nodata_img"
src={require("../../img/user/points.png")}
mode="aspectFill"
></Image>
<View>暂无数据</View>
</View>
)}
{list.map((item: any, key: number) => {
return (
<View className="list" key={key}>
<View className="list_block flex aitems sb">
<View className="left">
<View className="tip1">{item.remarkContent}</View>
<View className="tip2">{item.createTime}</View>
</View>
<View className="rights" style={item.style}>
{item.source === "1"
? "+" + item.floatScore
: "-" + item.floatScore}
</View>
</View>
</View>
);
})} */}
<ScrollView
onTouchMove={this.touchmove}
onTouchEnd={this.touchEnd}
onTouchStart={this.touchStart}
onScrollToUpper={this.ScrollToUpper}
onScrollToLower={this.ScrollToLower}
className="dragUpdata"
scrollY={this.state.scrollY}
scrollWithAnimation
>
<View>
<View>
{list.length === 0 && (
<View className="nodata">
<Image
className="nodata_img"
src={require("../../img/user/points.png")}
mode="aspectFill"
/>
<View className="nodata_text"></View>
</View>
)}
{list.map((item: any, key: number) => {
return (
<View className="list" key={key}>
<View className="list_block flex aitems sb">
<View className="left">
<View className="tip1">{item.remarkContent}</View>
<View className="tip2">{item.createTime}</View>
</View>
<View className="rights" style={item.style}>
{item.source === "1"
? "+" + item.floatScore
: "-" + item.floatScore}
</View>
</View>
</View>
);
})}
</View>
<View style="height: 20rpx"></View>
</View>
</ScrollView>
{list.length > 0 && list.length < total && (
<View className="upDragBox">
{dargState === 0 ? (
<Text style="color: #666"></Text>
) : (
<Loading size="24px">...</Loading>
)}
</View>
)}
{list.length > 0 && list.length === total && (
<View style="margin: 10rpx 0;text-align: center;">
<Text style="color: #666;"></Text>
</View>
)}
</View>
</Block>
);
}
}
const mapStateToProps = (state) => ({
userInfo: state.userInfo,
otherSetting: state.otherSetting,
});
const mapDispatchToProps = (dispatch) => ({
userRefresh(data) {
dispatch(userRefresh(data));
},
otherSettingRefresh(data) {
dispatch(otherSettingRefresh(data));
},
});
export default connect(mapStateToProps, mapDispatchToProps)(IntegralList);