记账本选择标签选择时间,计算器---记录一下

news2024/11/22 21:01:15

*
html部分

<template>
	<view class="pages-main">
		<!-- 标题栏 -->
		<!-- #ifndef MP-TOUTIAO -->
		<view class="" :style="'height:'+barHeight +'px;'"></view>
		<!-- #endif -->
		<!-- #ifdef MP-TOUTIAO -->
		<view class="" :style="'height:'+(barHeight-statusBarHeight) +'px;'"></view>
		<!-- #endif -->
		<view class="nabbar-bar">
			<!-- //手机状态栏 -->
			<!-- #ifndef MP-TOUTIAO -->
			<view class="status-bar" :style="{'height': statusBarHeight + 'px'}"></view>
			<!-- #endif -->
			<!-- //导航栏 -->
			<view class="nabbar-box flex-cent" :style="{'height': (barHeight-statusBarHeight) + 'px', }">
				<!-- #ifdef MP-WEIXIN || MP-KUAISHOU -->
				<image class="left-icon" src="@/static/image/icon-xiangzuo.png" mode="widthFix" @click="onGoBack"></image>
				<!-- #endif -->
				<view class="nav-tabs flex-cent">
					<view v-for="(item, index) in titleList" :key="index" class="nav_item flex-cent"
					 @click="onNavSwitch(item.value)" :id="index==0? 'navTitle': ''" >
						<view class="nav_title">{{ item.title }}</view>
						<view class="task_tabs_line_wrapper">
							<view class="task_tabs_line"
								:style="{width: 100 / titleList.length + '%',transform: `translateX(${isNavActive * 100}%);`}">
								<view class="inside_line"></view>
							</view>
						</view>
					</view>
				</view>
			</view>
		</view>
		
		<view class="body-main">
			<!-- #ifndef MP-TOUTIAO -->
			<swiper class="list_swiper" @change="changeSwiper" :current="isNavActive" :scroll-anchoring="true"
			:style="'height:calc(100vh - '+barHeight+'px)'">
			<!-- #endif -->
			<!-- #ifdef MP-TOUTIAO -->
			<swiper class="list_swiper" @change="changeSwiper" :current="isNavActive" :scroll-anchoring="true"
			:style="'height:calc(100vh - '+(barHeight-statusBarHeight)+'px)'">
			<!-- #endif -->
			
				<swiper-item class="list_swiper_item" :key="0" >
					<scroll-view class="scroll-view" :scroll-y="true" :scroll-with-animation="true" 
					:scroll-top="scrollTop"  :scroll-into-view="isScrollShow? 'book'+selevtType: ''">
					 <!-- :style="{height: conHeight + 'px'}" -->
						<view class="list-box" v-for="(item,index) in expenditureList" :key="index"
						:id="'book'+item._id">
							<view class="title-box">{{item.name}}</view>
							<view class="list-main flex-fs-left">
								<view class="list-item " v-for="(item1,index1) in item.children" :key="index1"
								:class="selectCategory._id==item1._id?'is-acitve': ''" @click="onSelectClass(item1)"
								:id="selectCategory._id==item1._id?'activeItem': ''">
									<view class="head-box flex-cent">
										<image :src="item1.iconUrl | onFiltersImg" mode="widthFix"></image>
									</view>
									<view class="item-title">{{item1.name}}</view>
								</view>
							</view>
						</view>
						<view class="height-foot" v-if="isOpenCalculator"></view>
					</scroll-view>
				</swiper-item>
				<swiper-item class="list_swiper_item" :key="1" >
					<view class="list-box">
						<view class="list-main flex-fs-left">
							<view class="list-item" v-for="(item1,index1) in incomeList" :key="index1"
							:class="selectCategory._id==item1._id?'is-acitve': ''" @click="onSelectClass(item1)">
								<view class="head-box flex-cent">
									<image :src="item1.iconUrl | onFiltersImg" mode="widthFix"></image>
								</view>
								<view class="item-title">{{item1.name}}</view>
							</view>
						</view>
					</view>
					<view class="height-foot" v-if="isOpenCalculator"></view>
				</swiper-item>
			</swiper>
		</view>
		<calculator :isOpen="isOpenCalculator" :selectCategory="selectCategory" :formModel="formModel"></calculator>
		<!-- 新手引导 -->
		<block v-if="showGuide && !functionGuidance">
			<guide :show="showGuide" :width="cWidth" :height="cHeight" :left="cLeft" :right="cRight" :top="cTop"
			:showMessage='cShowMsg' :currentIndex="currentIndex" :noticeArray="noticeArray" pageName="记账本分类页"
			 @onNextBtn="clicktoNext" @operatingButton="onWriteAccount" @closeClick="onCloseClick"></guide>
		</block>
		<block v-if="isFeedbackShow">
			<feedbackPopup :isOpen="isFeedbackShow" @close="onCloseFeedback" pageName="记账本分类页"></feedbackPopup>
		</block>
	</view>
</template>

js部分

<script>
	import { accAdd, accSub, accMul, accDiv } from '@/utils/calculation.js'
	import calculator from '../components/calculator.vue'
	import guide from '@/components/guide.vue'
	import { mapGetters, mapMutations } from "vuex";
	import { bookkeepingCategoryList } from '@/api/bookApi.js'
	import feedbackPopup from '../components/feedback-popup.vue'
	const globalData = getApp().globalData
	const defaultImageUrl = globalData.defaultImageUrl
	const imageUrlPrefix = globalData.imageUrlPrefix
	export default {
		filters: {
			onFiltersImg(val) {
				if (val) {
					const photoArray = val.split(',')
					if (photoArray[0].indexOf('http') == -1) {
					  return imageUrlPrefix+photoArray[0]
					} else {
						return photoArray[0]
					}
				} else {
					return defaultImageUrl
				}
			},
		},
		data() {
			return {
				statusBarHeight: 20,
				isNavActive: 0,
				barHeight: 44,
				formModel: {},
				bookinclasslist: [],
				bookoutclasslist: [],
				bookclasslist: [],
				currentClass: {},
				// 标题列表
				titleList: [{
					title: '支出', // 标题名
					value: 0, // 标题编号
					count: 0
				}, {
					title: '收入',
					value: 1,
					count: 0
				}],
				isOpenCalculator: false,
				showGuide: false, //引导是否显示
				cShowTitls: '',
				cShowMsg: '', // 展示的解释语
				cWidth: '',
				cHeight: '',
				cLeft: '',
				cTop: '',
				currentIndex: 0,
				noticeArray: [{
					showID: "navTitle", // 对应的id
					showMessage: `选择您要记录的是收入还是收入`, // 对应的解释文本
					type: "bottom", // 解释框的气泡类型
					isbtn: true,
					arrowShow: true,
					seeTop: '200',
				},{
					showID: "activeItem", // 对应的id
					showMessage: `点击您此次支出的分类`, // 对应的解释文本
					type: "bottom", // 解释框的气泡类型
					isbtn: false,
					arrowShow: true,
				}],
				incomeList: [], // 收入类别列表
				expenditureList: [], // 支出类别列表
				selectCategory: {
					_id: '',
					name: '',
					type: 2,
				},
				scrollTop: 0,
				selevtType: '',
				isScrollShow: false,
				isFeedbackShow: false,
			}
		},
		components: {
			calculator,
			guide,
			feedbackPopup,
		},
		
		onLoad(options) {
			//获取手机系统的信息(在这主要是获取状态栏和胶囊的高度)
			let {statusBarHeight,system} = uni.getSystemInfoSync()
			this.statusBarHeight = statusBarHeight
			this.barHeight = statusBarHeight + (system.indexOf('iOS') > -1 ? 44 : 48)
			if (this.bookCategoryList.length>0) {
				this.incomeList = this.bookCategoryList[1].children || []
				this.expenditureList = this.bookCategoryList[0].children || []
				this.guideInit()
			} else {
				this.getCategoryList()
			}
			if (options && options.model) {
				let model = decodeURIComponent(options.model)
				let mode = JSON.parse(model)
				let category = {}
				if (mode.type==2) {
					this.isNavActive = 0
					this.expenditureList.some(e=>{
						category = e.children.find(i=> i._id == mode.categoryId)
						return category
					})
				} else {
					this.isNavActive = 1
					category = this.incomeList.find(i=> i._id == mode.categoryId)
				}
				this.selectCategory = category
				this.formModel={
					Money: mode.amount,
					ConsumptionTime: mode.ytd,
					id: mode._id
				}
				setTimeout(o=> {
					this.onWriteAccount()
				},100)
			}
		},
		computed: {
			...mapGetters(['hasAuth', 'loginUserKey','bookCategoryList','functionGuidance','bookPageEnterNum']),
		},
		methods: {
			getCategoryList() {
				bookkeepingCategoryList({key: this.loginUserKey.key}).then(data=> {
					this.incomeList = data[1].children || []
					this.expenditureList = data[0].children || []
					this.$store.commit('BOOK_CATEGORY_LIST',data||[])
					this.guideInit()
				})
			},
			onGoBack() {
				if (this.bookPageEnterNum==2) {
					this.isFeedbackShow = true
				} else {
					uni.navigateBack()
				}
			},
			onCloseFeedback(val) {
				this.isFeedbackShow = false
				if (val==2) {
					uni.navigateBack()
				}
			},
			onNavSwitch(val) {
				this.isNavActive = val
				if (JSON.stringify(this.formModel) =='{}') {
					this.$set(this,'isOpenCalculator',false)
				}
			},
			// 左右滑动切换标题的回调
			changeSwiper(e) {
				let val = e.target.current
				this.onNavSwitch(val)
			},
			onSelectClass(val) {
				this.selectCategory = val
				this.isScrollShow = true
				this.selevtType = val.parentId
				this.$set(this,'isOpenCalculator',true)
				this.showGuide = false;
				// 埋点
				// this.$uma.trackEvent('BookkeepingCategaryClick',{page_name: '记账本分类页',user_id: this.loginUserKey._id|| '',event_time: Date.parse(new Date())})
			},
			
			guideInit() {
				if(!this.functionGuidance && this.expenditureList.length>0) {
					this.selectCategory = this.expenditureList[0].children[0]
					this.$nextTick(()=> {
						if (this.currentIndex >= this.noticeArray.length) {
							this.showGuide = false;
							return;
						}
						this.showGuide = true;
						this.cShowMsg = this.noticeArray[this.currentIndex].showMessage;
						var idS = '#' + this.noticeArray[this.currentIndex].showID;
						console.log(idS)
						//根据布局信息显示引导框位置
						const query = uni.createSelectorQuery().in(this);
						query.select(idS).boundingClientRect(data => {
							console.log("得到布局位置信息" + JSON.stringify(data));
							this.cWidth = data.width;
							// #ifndef MP-KUAISHOU
							this.cHeight = data.height;
							this.cTop = data.top;
							// #endif
							// #ifdef MP-KUAISHOU
							if (data.height<= 46) {
								this.cHeight = data.height * 2;
								this.cTop = data.top + 20;
							} else {
								this.cHeight = data.height;
								this.cTop = data.top;
							}
							// #endif
							console.log(data)
							console.log('----------------')
							this.cLeft = data.left;
							
						}).exec();
					});
				}
			},
			onWriteAccount() {
				this.onSelectClass(this.selectCategory)
			},
			clicktoNext(val) {
				if (this.currentIndex >= this.noticeArray.length) {
					this.showGuide = false;
					return;
				}
				this.noticeArray[this.currentIndex].zindex = 0;
				this.cShowMsg = '';
				this.currentIndex++;
				if (this.currentIndex >= this.noticeArray.length) {
					this.showGuide = false;
					return;
				}
				this.cShowMsg = this.noticeArray[this.currentIndex].showMessage;
				var idS = '#' + this.noticeArray[this.currentIndex].showID;
				console.log(idS)
				const query = uni.createSelectorQuery().in(this);
				query.select(idS).boundingClientRect(data => {
					console.log("得到布局位置信息" + JSON.stringify(data));
					this.cWidth = data.width;
					this.cHeight = data.height;
					this.cLeft = data.left;
					this.cTop = data.top;
				}).exec();
			},
			onCloseClick() {
				this.showGuide = false;
			},
		},
		onBackPress(e) {
			console.log(e)
			console.log('监听页面的返回事件')
		},
		watch: {
			loginUserKey() {},
			bookCategoryList() {},
			functionGuidance() {},
			bookPageEnterNum() {},
		}
	}
</script>

css部分


<style lang="less" scoped>
.pages-main {
	.nabbar-bar {
		width: 100%;
		z-index: 100;
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		background: #fff;
		z-index: 100;
		.status-bar {
			width: 100%;
			height: var(--status-bar-height);
		}
		.nabbar-box {
			width: 100%;
			padding: 0 25rpx;
			z-index: 996;
			align-items: center;
			padding-right: 90rpx;
			.left-icon {
				font-size: 36rpx;
				color: #000;
				position: absolute;
				left: 16rpx;
				width: 40rpx;
				height: 40rpx;
				z-index: 2;
			}
			
		}
		.nav-tabs {
			position: relative;
			height: 100%;
			width: 100%;
			padding: 0 100rpx;
		}
		
		.nav_item {
			width: 50%;
			font-size: 36rpx;
			font-family: PingFang SC;
			font-weight: 700;
			color: #4F4B4E;
			height: 100%;
			align-items: center;
			flex-direction: column;
			
			.task_tabs_line_wrapper {
				position: absolute;
				bottom: 0rpx;
				left: 0;
				height: 4rpx;
				width: 100%;
				padding: 0 100rpx;
				.task_tabs_line {
					height: 4rpx;
					transition: all 0.2s ease;
			
					.inside_line {
						width: 30rpx;
						margin: 0 auto;
						height: 4rpx;
						background: #F08500;
						border-radius: 2rpx;
					}
				}
			}
		}
	}
	.list_swiper {
		height: calc(100vh - 160rpx);
	}
	.list_swiper_item {
		width: 100%;
		height: 100%;
		padding: 16rpx 0;
		// overflow-y: scroll;
		.scroll-view {
			width: 100%;
			height: 100%;
			overflow-y: scroll;
		}
	}
	.height-foot {
		height: 590rpx;
	}
	.list-box {
		width: 100%;
		background: #FFFFFF;
		border-radius: 18rpx;
		padding: 36rpx 40rpx 0;
		margin-bottom: 12rpx;
	}
	.body-main {
		padding: 0 16rpx;
		.title-box {
			font-size: 30rpx;
			font-family: PingFang SC;
			font-weight: 700;
			color: #4F4B4E;
			line-height: 42rpx;
		}
		.list-main {
			flex-wrap: wrap;
			padding-top: 38rpx;
		}
		.list-item {
			width: 25%;
			margin-bottom: 46rpx;
			.head-box {
				width: 100rpx;
				height: 100rpx;
				background: #F6F6F6;
				margin: 0 auto;
				border-radius: 50%;
				overflow: hidden;
				
				image,img {
					width: 58rpx;
					height: 58rpx;
					background: #F6F6F6;
				}
			}
			&.is-acitve {
				.head-box {
					background: #FDF2E5;
					image,img {
						background-color: #FDF2E5;
					}
				}
			}
		}
		
		.item-title {
			font-size: 28rpx;
			font-family: PingFang SC;
			font-weight: 400;
			color: #4F4B4E;
			text-align: center;
			line-height: 40rpx;
			padding-top: 18rpx;
		}
	}
	
}
	
</style>

calculator.vue

<template>
	<view>
		<block v-if="isOpen">
			<view class="input-calculator" >
				<view class="input-box flex-sb-cent">
					<!-- <view class="padding-sm margin-xsradius ">
						<view class="margin-xsradius" :class="selectCategory.IconName" :style="'background-color:'+selectCategory.BgColor"></view>
						<text class="text-grey">{{selectCategory.Name}}</text>
					</view> -->
					<view class="padding-sm ">
						<view class="text-black text-xxl contner">{{model.Money||'0.00'}}</view>
					</view>
				</view>
				<!-- <view class="flex-sb-cent input" :class="InputBottom>0?'foot':''" :style="[{bottom:InputBottom+'px'}]">
					<view class="action">
						<text class="  text-grey">备注</text>
					</view>
					<input class="solid-bottom" :adjust-position="false" :focus="false" maxlength="300" v-model="model.Remark"
					 cursor-spacing="10" @focus="InputFocus" @blur="InputBlur"></input>
				</view> -->
			
				<view class="flex-sb-cent cu-list col-4">
					<view class="cu-item flex-cent border" @click="modifyNum('number','1')">
						<text class="text-black">1</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('number','2')">
						<text class="text-black">2</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('number','3')">
						<text class="text-black">3</text>
					</view>
					<view class="cu-item flex-cent border time" @click="onDateOpen">
						<block v-if="model.ConsumptionTime == today">
							<image class="image-time" src="../static/icon-time.png" mode="widthFix"></image>
							今天
						</block>
						<text class="text-black" v-else>{{model.ConsumptionTime}}</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('number','4')">
						<text class="text-black">4</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('number','5')">
						<text class="text-black">5</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('number','6')">
						<text class="text-black">6</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('operator','+')">	
						<text class="text-black">+</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('number','7')">
						<text class="text-black">7</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('number','8')">
						<text class="text-black">8</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('number','9')">
						<text class="text-black">9</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('operator','-')">
						<text class="text-black">-</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('string','.')">
						<text class="text-black">.</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('number','0')">
						<text class="text-black">0</text>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('cut')">
						<image class="del-img" src="../static/icon-del.png" mode="widthFix"></image>
					</view>
					<view class="cu-item flex-cent border" @click="modifyNum('equal')"
					style="background-color: #FF951A;" v-if="state.currentOperator">
						<text class="text-black">=</text>
					</view>
					<view class="cu-item flex-cent border " style="background-color: #FF951A;"
					id="cuItemSubmit" @click="onSubmit" v-if="!state.currentOperator">
						<text class="text-bold">完成</text>
					</view>
				</view>
			</view>
			<pickerDate :isOpen="isPickerShow" @onDayClick="onDayClick" @close="onClosePick"></pickerDate>
			<!-- 新手引导 -->
			<block v-if="showGuide && !functionGuidance">
				<guide :show="showGuide" :width="cWidth" :height="cHeight" :left="cLeft" :right="cRight" :top="cTop"
				:showMessage='cShowMsg' :currentIndex="currentIndex" :noticeArray="noticeArray" pageName="记账本分类页"
				 @onNextBtn="clicktoNext" @operatingButton="onWriteAccount" @closeClick="onCloseClick"></guide>
			</block>
		</block>
		
	</view>
</template>

<script>
	import pickerDate from './picker-date.vue'
	import { accAdd,accSub,accDiv,accMul } from '@/utils/calculation.js'
	import guide from '@/components/guide.vue'
	import { saveOrUpdateBookkeeping } from '@/api/bookApi.js'
	import { mapGetters, mapMutations } from "vuex";
	export default {
		props: {
			isOpen: {
				default: false,
				type: Boolean
			},
			selectCategory: {
				default: {},
				type: Object
			},
			formModel: {
				default: {},
				type: Object
			}
		},
		data() {
			return {
				model: {
					Money: '',
					// Remark: '',
					ConsumptionTime: '',
				},
				today: this.getDate(),
				InputBottom: 0,
				isPickerShow: false,
				/*
				*currentNumber: 用于跟踪当前输入的数字或操作数。当用户按下数字按钮时,这个变量将被更新以包含新的数字字符。
				* 例如,当用户按下数字键 "1""2""3" 时,currentNumber 将依次变为 "1""12""123"。
				
				currentOperator: 用于跟踪当前选定的操作符,例如加法 "+"、减法 "-"、乘法 "*"、除法 "/"。
				* 如果用户按下运算符按钮,这个变量将被设置为相应的运算符。
				
				previousValue: 用于存储上一个操作的结果,以便进行下一个操作时使用。
				* 例如,如果用户按下 "1 + 2",previousValue 将存储 "1",然后在按下 "=" 后,将 "previousValue + currentNumber" 计算为最终结果。
				
				isDecimal: 用于跟踪当前数字是否包含小数点。当用户按下小数点按钮时,这个标志将设置为 true,以确保小数点只能出现一次。
				* */
				state: {
					currentNumber: '',
					currentOperator: '',
					previousValue: null,
					isDecimal: false,
				},
				showGuide: false, //引导是否显示
				cShowTitls: '',
				cShowMsg: '', // 展示的解释语
				cWidth: '',
				cHeight: '',
				cLeft: '',
				cTop: '',
				currentIndex: 0,
				noticeArray: [{
					showID: "cuItemSubmit", // 对应的id
					showMessage: `记账可以养成更好地消费习惯,快来开启您的记账生活吧!`, // 对应的解释文本
					type: "top", // 解释框的气泡类型
					isbtn: false,
					arrowShow: true, // 指示箭头是否显示
				}],
			}
		},
		components: {
			pickerDate,
			guide
		},
		created() {
		},
		computed: {
			...mapGetters(['hasAuth', 'loginUserKey','functionGuidance']),
		},
		mounted() {
			if (JSON.stringify(this.formModel) != '{}') {
				this.model = this.formModel
				this.state.currentNumber = this.formModel.Money || ''
			} else {
				this.model.ConsumptionTime = this.getDate()
			}
		},
		methods: {
			onDateOpen() {
				this.$set(this,'isPickerShow',true)
			},
			onDayClick(time) {
				this.model.ConsumptionTime = time
				this.$set(this,'isPickerShow',false)
			},
			onClosePick() {
				this.$set(this,'isPickerShow',false)
			},
			InputFocus(e) {
				this.InputBottom = e.detail.height
			},
			InputBlur(e) {
				this.InputBottom = 0
			},
			bindDateChange(e) {
				this.model.ConsumptionTime = e.target.value
			},
			getDate(type) {
				const date = new Date();
				let year = date.getFullYear();
				let month = date.getMonth() + 1;
				let day = date.getDate();

				if (type === 'start') {
					year = year - 60;
				} else if (type === 'end') {
					year = year + 2;
				}
				month = month > 9 ? month : '0' + month;;
				day = day > 9 ? day : '0' + day;
				return `${year}/${month}/${day}`;
			},
			modifyNum(type, value) {
				if (type === 'number') {
					if (this.model.Money.length>=23) return //
					if (this.state.isDecimal) {
						const decimalCount = this.state.currentNumber.split('.')[1];
						if (decimalCount && decimalCount.length >= 2) {
							return;
						}
						if(this.state.currentNumber.length>=11) return
						this.state.currentNumber += value;
						this.model.Money += value;
					} else {
						if(this.state.currentNumber.length>=8) return
						if (this.state.currentNumber == '0') {
							if (this.state.currentOperator !== '') {
								if (value == '0') {
									this.state.currentNumber = this.state.currentNumber;
									this.model.Money = this.model.Money
								} else {
									this.state.currentNumber += value;
									this.model.Money = this.model.Money.toString().slice(0, -1); // 删除最后一个数
									this.model.Money += value; // 重新添加
								}
							} else {
								this.state.currentNumber = value;
								this.model.Money = value
							}
						} else if (this.state.currentNumber==''&& value=='0'){
							this.state.isDecimal = true
							this.state.currentNumber = '0.';
							this.model.Money += '0.'
						} else {
							this.state.currentNumber += value;
							this.model.Money += value;
						}
					}
					
				} else if (type === 'operator') {
					if (this.state.currentNumber !== '') {
						if (this.state.currentOperator !== '') {
							// 如果之前已经有运算符,先计算上一步的结果
							this.calculate();
						}
						this.state.previousValue = parseFloat(this.state.currentNumber);
						this.state.currentNumber = '';
						this.state.isDecimal = false;
						this.model.Money += `${value}`; // 添加运算符到表达式
						this.state.currentOperator = value;
					} else if (this.model.Money.length>=1){
						this.model.Money = this.model.Money.toString().slice(0, -1); // 删除最后一个数
						this.model.Money += `${value}`; // 添加运算符到表达式
						this.state.currentOperator = value;
					}
				} else if (type === 'equal') {
					if (this.state.currentOperator && this.state.currentNumber !== '') {
						this.model.Money += `${this.state.currentNumber}`; // 显示完整表达式
						this.calculate(); // 计算结果
						this.state.currentOperator = '';
					} else if (this.state.currentOperator && this.state.currentNumber == '' ){
						this.cut();
					}
				} else if (type === 'string') {
					if (this.model.Money.length>=23) return
					if (this.state.currentNumber == '') {
						this.state.currentNumber = '0';
					}
			
					if (value === '.' && this.state.isDecimal) {
						return; // 如果已经输入小数点,不再输入
					}
					this.state.isDecimal = value === '.';
					this.state.currentNumber += value;
					if (this.state.currentOperator !== '') {
						const currentCount = this.model.Money.split(this.state.currentOperator)[1];
						console.log(currentCount)
						console.log('currentCount0000000000000000000')
						if (currentCount) {
							this.model.Money += value
						} else {
							this.model.Money += `${this.state.currentNumber}`; // 显示完整表达式
						}
					} else {
						this.model.Money = this.state.currentNumber; // 更新表达式
					}
				} else if (type === 'clear') {
					this.clear();
				} else if (type === 'cut') {
					this.cut();
				}
			},
			calculate() {
				const num1 = this.state.previousValue;
				const num2 = parseFloat(this.state.currentNumber);
				let result = 0;
				
				switch (this.state.currentOperator) {
					case '+':
					// num1 + num2
						result = accAdd(num1, num2);
						break;
					case '-':
					// num1 - num2
						result = accSub(num1, num2);
						break;
					case '*':
					// num1 * num2
						result = accMul(num1, num2);
						break;
					case '/':
					// num1 / num2
						result = accDiv(num1, num2);
						break;
				}
				this.state.currentNumber = result.toString();
				this.state.isDecimal = this.state.currentNumber.includes('.');
				this.model.Money = result;
			},
			clear() {
				this.state.currentNumber = '';
				this.state.currentOperator = '';
				this.state.previousValue = null;
				this.state.isDecimal = false;
				this.model.Money = this.state.currentNumber;
			},
			
			cut() {
				if (this.state.currentNumber !== '' || this.state.currentOperator !== '') {
					// 删除最后一个字符,无论是数字还是运算符
					const lastChar = this.model.Money.toString().slice(-1);
					this.model.Money = this.model.Money.toString().slice(0, -1);
					//解决输入一个运算符后,删除之后,不能再输入运算符
					if (lastChar === '+' || lastChar === '-' || lastChar === '*') {
						this.state.currentOperator = '';
						this.state.currentNumber = this.model.Money
					} else if (this.state.currentNumber !== '') {
						// 如果最后一个字符是数字,则更新当前数字
						this.state.currentNumber = this.state.currentNumber.slice(0, -1);
					}
				} else if (this.state.previousValue !== null) {
					// 如果以上条件都不满足,则删除前一个值的最后一个字符
					const previousValueString = this.state.previousValue.toString();
					if (previousValueString.length > 1) {
						this.state.previousValue = parseFloat(previousValueString.slice(0, -1));
					} else {
						this.state.previousValue = null;
					}
				}
			
				//解决输入小数点之后,删了小数点,之后不能再输入小数点问题
				this.state.isDecimal = this.state.currentNumber.includes('.')
				//避免当输入的算式清空后,还在以上个运算结果为初始值继续运算
				if (this.model.Money === '') {
					this.state.currentNumber = '';
					this.state.currentOperator = '';
					this.state.previousValue = null;
				}
			},
			
			Deltext(e) { //删除
				if (this.model.Money.length > 1) {
					this.model.Money = this.model.Money.substr(0, this.model.Money.length - 1)
					if (this.model.Money === '-' || this.model.Money === "+") {
						this.model.Money = "0"
					}
				} else {
					this.model.Money = "0"
				}

			},
			onSubmit(e) {
				if (!this.selectCategory._id) return this.$util.Tips({title: '请选择分类!'})
				if (!this.model.Money || this.model.Money == 0) return this.$util.Tips({title: '请输入金额!'})
				if (this.model.Money.length>8) return this.$util.Tips({title: '金额过大!'})
				let parme = {
					amount: Math.abs(this.model.Money),
					date: this.model.ConsumptionTime,
					categoryId: this.selectCategory._id,
					categoryIcon: this.selectCategory.iconUrl,
					categoryName: this.selectCategory.name,
					type: this.selectCategory.type,
					userType: this.loginUserKey.type,
					key: this.loginUserKey.key,
					deviceType: 3,
					remark: '',
					// id: 0, // 存在及更新
				}
				if (this.model.id) {
					parme.id = this.model.id
				}
				saveOrUpdateBookkeeping(parme).then(data=> {
					this.$util.Tips({title: '保存成功!'})
					if (this.functionGuidance) {
						uni.navigateBack()
					} else {
						let pages = getCurrentPages();//获取页面栈
						let prevPage = pages[pages.length - 2]; //上一个页面
						//直接调用上一个页面的setData()方法,把数据存到上一个页面中去
						prevPage.data.source = 2
						uni.navigateBack()
					}
					// 埋点
					// this.$uma.trackEvent('BookkeepingFinishClick',{page_name: '记账本分类页',user_id: this.loginUserKey._id|| '',event_time: Date.parse(new Date())})
				})
			},
			guideInit() {
				if(!this.functionGuidance && this.hasAuth) {
					this.model.Money = 10
					this.$nextTick(()=> {
						if (this.currentIndex >= this.noticeArray.length) {
							this.showGuide = false;
							return;
						}
						this.showGuide = true;
						this.cShowMsg = this.noticeArray[this.currentIndex].showMessage;
						var idS = '#' + this.noticeArray[this.currentIndex].showID;
						console.log(idS)
						//根据布局信息显示引导框位置
						const query = uni.createSelectorQuery().in(this);
						query.select(idS).boundingClientRect(data => {
							console.log("得到布局位置信息" + JSON.stringify(data));
							this.cWidth = data.width;
							this.cHeight = data.height;
							this.cLeft = data.left;
							this.cTop = data.top;
						}).exec();
					});
				}
			},
			onWriteAccount() {
				this.onSubmit()
				this.showGuide = false;
			},
			clicktoNext(val) {
				if (this.currentIndex >= this.noticeArray.length) {
					this.showGuide = false;
					return;
				}
				this.noticeArray[this.currentIndex].zindex = 0;
				this.cShowMsg = '';
				this.currentIndex++;
				if (this.currentIndex >= this.noticeArray.length) {
					this.showGuide = false;
					return;
				}
				this.cShowMsg = this.noticeArray[this.currentIndex].showMessage;
				var idS = '#' + this.noticeArray[this.currentIndex].showID;
				console.log(idS)
				const query = uni.createSelectorQuery().in(this);
				query.select(idS).boundingClientRect(data => {
					console.log("得到布局位置信息" + JSON.stringify(data));
					this.cWidth = data.width;
					this.cHeight = data.height;
					this.cLeft = data.left;
					this.cTop = data.top;
				}).exec();
			},
			onCloseClick() {
				this.showGuide = false;
			},
		},
		
		watch: {
			isOpen() {
				this.guideInit()
			},
			formModel() {
				if (JSON.stringify(this.formModel) != '{}') {
					this.model = this.formModel
				} else {
					this.model.ConsumptionTime = this.getDate()
				}
			},
			functionGuidance(){},
			
		}
		
	}
</script>

<style lang="less" scoped>
	// @import '../css/main.css';
	.input-calculator {
		position: fixed;
		bottom: var(--window-bottom);
		width: 100%;
		background: #fff;
		box-shadow: 0rpx 0rpx 2rpx 3rpx rgba(229,229,229,0.5);
		.input-box {
			height: 118rpx;
			font-size: 32rpx;
			font-family: PingFang SC;
			font-weight: 700;
			color: #4F4B4E;
			line-height: 118rpx;
			padding: 0 46rpx;
		}
		.cu-list {
			flex-wrap: wrap;
		}
		.cu-item {
			width: 25%;
			text-align: center;
			height: 118rpx;
			line-height: 118rpx;
			overflow: hidden;
			font-size: 32rpx;
			font-family: PingFang SC;
			font-weight: 700;
			color: #4F4B4E;
			letter-spacing: 0;
			&.time {
				font-size: 26rpx;
			}
			&:active {
				background: #F6F6F6;
			}
			
		}
		.image-time {
			width: 36rpx;
			height: 36rpx;
			margin-right: 7rpx;
		}
		.del-img {
			width: 46rpx;
			height: 46rpx;
		}
		
		.border {
			border-top: 1rpx solid #E0E0E0;
			border-right: 1rpx solid #E0E0E0;
			&:nth-child(4n) {
				border-right: none;
			}
		}

	}

	.submit:active {
		background-color: #FF951A !important;
	}
</style>

在这里插入图片描述
./picker-date.vue

<template>
	<view class="">
		<view class="batch-num" :class="isOpen ? 'on' : ''">
			<view class="batch-body">
				<view class="title">
					日期选择
					<image class="close-img" @click="onCancel(0)" src="@/static/image/close.png" mode="widthFix"></image>
				</view>
				<!-- 日期选择器 -->
				<view class="calendar-wrapper">
					<!-- 选择月份 -->
					<view class="header" v-if="headerBar">
						<view class="iconfont iconarrow-left-bold pre" @click="changeMonth('pre')">
							<image src="../static/icon-left.png" mode="widthFix"></image>
						</view>
						<view class="">{{y+'年'+formatNum(m)+'月'}}</view>
						<view class="iconfont iconarrow-left-bold-copy next" @click="changeMonth('next')">
							<image src="../static/icon-right.png" mode="widthFix"></image>
						</view>
					</view>
					<!-- 星期栏 -->
					<view class="week">
						<view class="week-day" v-for="(item, index) in weekDay" :key="index">{{ item }}</view>
					</view>
					<!-- 日历数字 -->
					<view class="content" :style="{ height: height }">
						<view :style="{ top: positionTop + 'rpx' }" class="days">
							<view class="item" v-for="(item,index) in dates" :key="index">
								<view class="day" @click="selectOne(item, $event)" :class="{
									choose: getActday(item),//选中的日期
									chooseMarkDay:getChoose(item),
									nolm: !item.isCurM,//不在本月的日
						            today: isToday(item.year, item.month, item.date),//当日日期
						            isWorkDay: isWorkDay(item.year, item.month, item.date)//周一至周五
						          }">
									{{Number(item.date)}}
								</view>
							</view>	
						</view>
					</view>
				</view>
				<view class="slect-time">{{choose}}</view>
				<view class="sub-btn" @click="onSubmitDeta">确定</view>
			</view>
		</view>
		<view class="mask" v-show="isOpen" @click="onCancel(0)"></view>
	</view>
</template>

<script>
	export default {
		name: 'pickerDate',
		props: {
			isOpen: {
				type: Boolean,
				default: false
			},
			// 星期几为第一天(0为星期日)
			weekstart: {
				type: Number,
				default: 0
			},
			// 标记的日期
			markDays: {
				type: Array,
				default: () => {
					return [];
				}
			},
			//是否展示月份切换按钮
			headerBar: {
				type: Boolean,
				default: true
			},
			//过去日期是否不可点击
			disabledAfter: {
				type: Boolean,
				default: false
			},
			//接收用户选择的参数
			actDay: {
				type: Array,
				default: [],
			},
			//接受已经被选择的参数
			chooseDay: {
				type: Array,
				default: [],
			}
		},
		data() {
			return {
				weektext: ['日', '一', '二', '三', '四', '五', '六'],
				y: new Date().getFullYear(), // 年
				m: new Date().getMonth() + 1, // 月
				d: new Date().getDate(), //日
				dates: [], // 当前月的日期数据
				positionTop: 0,
				choose: this.getToday().date,
				chooseArr: [],
			}
		},
		created() {
			this.dates = this.monthDay(this.y, this.m);
			console.log('')
		},
		mounted() {
			// this.choose = this.getToday().date;
		},
		computed: {
			// 顶部星期栏
			weekDay() {
				return this.weektext.slice(this.weekstart).concat(this.weektext.slice(0, this.weekstart));
			},
			height() {
				return (this.dates.length / 7) * 80 + 'rpx';
			},
			
		},
		methods: {
			onCancel() {
				this.$emit('close')
				console.log('eeeeeeeeeeeeeeeee')
			},
			//已被投标的日期
			getChoose(val) {
				let day = val.year+'/'+val.month+'/'+val.date 
				for (let i = 0; i < this.chooseDay.length; i++) {
					if (day == this.chooseDay[i]) {
						return true;
					}
				}
			},
			//用户选择的日期
			getActday(val) {
				let day = val.year+'/'+val.month+'/'+val.date
				if (this.choose == day) {
					return true
				} else {
					return false
				}
			},
			formatNum(num) {
				let res = Number(num);
				return res < 10 ? '0' + res : res;
			},
			getToday() {
				let date = new Date();
				let y = date.getFullYear();
				let m = date.getMonth();
				let d = date.getDate();
				let week = new Date().getDay();
				let weekText = ['日', '一', '二', '三', '四', '五', '六'];
				let formatWeek = '星期' + weekText[week];
				let today = {
					date: y + '/' + this.formatNum(m + 1) + '/' + this.formatNum(d),
					week: formatWeek
				};
				return today;
			},
			// 获取当前月份数据
			monthDay(y, month) {
				let dates = [];
				let m = Number(month);
				let firstDayOfMonth = new Date(y, m - 1, 1).getDay(); // 当月第一天星期几
				let lastDateOfMonth = new Date(y, m, 0).getDate(); // 当月最后一天
				let lastDayOfLastMonth = new Date(y, m - 2, 0).getDate(); // 上一月的最后一天
				let weekstart = this.weekstart == 7 ? 0 : this.weekstart;
				let startDay = (() => {
					// 周初有几天是上个月的
					if (firstDayOfMonth == weekstart) {
						return 0;
					} else if (firstDayOfMonth > weekstart) {
						return firstDayOfMonth - weekstart;
					} else {
						return 7 - weekstart + firstDayOfMonth;
					}
				})();
				let endDay = 7 - ((startDay + lastDateOfMonth) % 7); // 结束还有几天是下个月的
				for (let i = 1; i <= startDay; i++) {
					dates.push({
						date: this.formatNum(lastDayOfLastMonth - startDay + i),
						day: weekstart + i - 1 || 7,
						month: m - 1 >= 0 ? this.formatNum(m - 1) : 12,
						year: m - 1 >= 0 ? y : y - 1
					});
				}
				for (let j = 1; j <= lastDateOfMonth; j++) {
					dates.push({
						date: this.formatNum(j),
						day: (j % 7) + firstDayOfMonth - 1 || 7,
						month: this.formatNum(m),
						year: y,
						isCurM: true, //是否当前月份
					});
				}
				for (let k = 1; k <= endDay; k++) {
					dates.push({
						date: this.formatNum(k),
						day: (lastDateOfMonth + startDay + weekstart + k - 1) % 7 || 7,
						month: m + 1 <= 11 ? this.formatNum(m + 1) : 0,
						year: m + 1 <= 11 ? y : y + 1
					});
				}
				// console.log(dates); //日期
				return dates;
			},
			isWorkDay(y, m, d) {
				//是否工作日
				let ymd = y+'/'+m+'/'+d // `${y}/${m}/${d}`;
				let formatDY = new Date(ymd.replace(/-/g, '/'));
				let week = formatDY.getDay();
				if (week == 0 || week == 6) {
					return false;
				} else {
					return true;
				}
			},
			isFutureDay(y, m, d) {
				//是否未来日期
				let ymd = y+'/'+m+'/'+d //`${y}/${m}/${d}`;
				let formatDY = new Date(ymd.replace(/-/g, '/'));
				let showTime = formatDY.getTime();
				let curTime = new Date().getTime();
				if (showTime > curTime) {
					return true;
				} else {
					return false;
				}
			},
			// 标记日期
			isMarkDay(y, m, d) {
				let flag = false;
				for (let i = 0; i < this.markDays.length; i++) {
					let dy = y+'/'+m+'/'+d // `${y}-${m}-${d}`;
					if (this.markDays[i] == dy) {
						flag = true;
						break;
					}
				}
				return flag;
			},
			isToday(y, m, d) {
				let checkD = y + '/' + m + '/' + d;
				let today = this.getToday().date;
				if (checkD == today) {
					return true;
				} else {
					return false;
				}
			},
			// 点击回调
			selectOne(i, event) {
				let date = i.year+'/'+i.month+'/'+i.date 
				let selectD = new Date(date).getTime();
				let curTime = new Date().getTime();
				// let week = new Date(date).getDay();
				// let weekText = ['日', '一', '二', '三', '四', '五', '六'];
				// let formatWeek = '星期' + weekText[week];
				// let response = {
				// 	date: date,
				// 	week: formatWeek
				// };
				if (!i.isCurM) {
					console.log('不在当前月范围内');
					return false;
				}
				if (selectD < curTime) {
					if (this.disabledAfter) {
						console.log('过去日期不可选');
						return false;
					} else {
						this.choose = date;
					}
				} else {
					this.choose = date;
					this.chooseArr.push(date)
					
				}
				// this.response = response
			},
			onSubmitDeta() {
				this.$emit('onDayClick', this.choose);
			},
			//改变年月
			changYearMonth(y, m) {
				this.dates = this.monthDay(y, m);
				this.y = y;
				this.m = m;
			},
			changeMonth(type) {
				if (type == 'pre') {
					if (this.m + 1 == 2) {
						this.m = 12;
						this.y = this.y - 1;
					} else {
						this.m = this.m - 1;
					}
				} else {
					if (this.m + 1 == 13) {
						this.m = 1;
						this.y = this.y + 1;
					} else {
						this.m = this.m + 1;
					}
				}
				this.dates = this.monthDay(this.y, this.m);
			}
		}
	}
</script>

<style lang="less" scoped>
	.batch-num {
		width: 100%;
		// height: 624rpx;
		// background-color: #fff;
		position: fixed;
		left: 0;
		bottom: 0;
		z-index: 1000;
		transform: translate3d(0, 100%, 0);
		transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
		border-top-left-radius: 32rpx;
		border-top-right-radius: 32rpx;
		overflow: hidden;

		&.on {
			transform: translate3d(0, 0, 0);
		}

		.batch-body {
			// padding: 20rpx;
			padding: 35rpx 0 30rpx;
			background: #fff;
			border-radius: 18rpx 18rpx 0 0;

			.title {
				font-size: 30rpx;
				font-family: PingFang SC;
				color: #858585;
				line-height: 42rpx;
				font-weight: 700;
				text-align: center;
				padding-bottom: 35rpx;
				position: relative;
			}
			.close-img {
				position: absolute;
				right: 20rpx;
				width: 58rpx;
				height: 58rpx;
			}
		}

		.calendar-wrapper {
			color: #6f6d6d;
			font-size: 28rpx;
			text-align: center;
			background-color: #fff;
			padding-bottom: 10rpx;
			border-radius: 20rpx;
			.header {
				display: flex;
				align-items: center;
				justify-content: center;
				height: 88rpx;
				font-weight: bold;
				font-size: 28rpx;
				font-family: PingFang SC;
				color: #4F4B4E;
				
				.pre,
				.next {
					image,img {
						width: 24rpx;
						height: 24rpx;
					}
				}

				.pre {
					margin-right: 30rpx;
				}

				.next {
					margin-left: 30rpx;
				}
			}

			.week {
				display: flex;
				align-items: center;
				height: 80rpx;
				line-height: 80rpx;
				background: #FFFFFF;
				box-shadow: 0rpx 4rpx 6rpx 0rpx rgba(201,201,201,0.5);
				border-radius: 18rpx 18rpx 0rpx 0rpx;
				view {
					flex: 1;
				}
			}

			.content {
				position: relative;
				overflow: hidden;
				transition: height 0.4s ease;

				.days {
					transition: top 0.3s;
					display: flex;
					align-items: center;
					flex-wrap: wrap;
					position: relative;

					.item {
						position: relative;
						display: block;
						height: 80rpx;
						line-height: 80rpx;
						width: calc(100% / 7);

						.day {
							display: inline-block;
							vertical-align: middle;
							font-size: 26rpx;
							font-family: PingFang SC;
							font-weight: 400;
							color: #4F4B4E;
							width: 60rpx;
							height: 60rpx;
							line-height: 60rpx;
							overflow: hidden;
							border-radius: 50%;
							&.choose {
								background-color: #FF951A;
								color: #fff;
							}

							&.chooseMarkDay {
								//已被投标的日期
								color: #FF951A;
							}

							&.nolm {
								color: #fff;
								opacity: 0;
							}
						}

						.isWorkDay {
							color: #25272a;
						}

						.notSigned {
							font-style: normal;
							width: 8rpx;
							height: 8rpx;
							background: #fa7268;
							border-radius: 10rpx;
							position: absolute;
							left: 50%;
							bottom: 0;
							pointer-events: none;
						}

						.today {
							color: #FF951A;
						}
						
						.workDay {
							font-style: normal;
							width: 8rpx;
							height: 8rpx;
							background: #4d7df9;
							border-radius: 10rpx;
							position: absolute;
							left: 50%;
							bottom: 0;
							pointer-events: none;
						}

						.markDays {
							font-style: normal;
							position: absolute;
							top: 2rpx;
							right: 11rpx;
							pointer-events: none;
							font-size: 80rpx;
							color: rgba(160, 234, 193, 0.5);
						}
					}
				}
			}
		}

		.cancle-btn {
			width: 100%;
			height: 97rpx;
			background: #FFFFFF;
			text-align: center;
			line-height: 97rpx;
			font-family: PingFang SC;
			font-size: 34rpx;
			font-weight: 500;
			color: #858585;
		}
		.slect-time {
			text-align: center;
			font-size: 26rpx;
			font-family: PingFang SC;
			font-weight: 400;
			color: #858585;
			line-height: 37rpx;
		}
		
		.sub-btn {
			width: 560rpx;
			height: 96rpx;
			background: #FF951A;
			border-radius: 14rpx;
			font-size: 34rpx;
			font-family: PingFang SC;
			font-weight: 700;
			color: #FFFFFF;
			text-align: center;
			line-height: 96rpx;
			margin: 0 auto;
			margin-top: 10rpx;
		}
	}

	// 分享
	.mask {
		position: fixed;
		top: 0;
		left: 0;
		right: 0;
		bottom: 0;
		opacity: 0.7;
		background-color: rgba(0, 0, 0, 0.7);
		z-index: 999 !important;
	}
</style>

calculation.js

export function accAdd(arg1, arg2) {
    var r1, r2, m, c;
    try {
        r1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
        r2 = 0;
    }
    c = Math.abs(r1 - r2);
    m = Math.pow(10, Math.max(r1, r2));
    if (c > 0) {
        var cm = Math.pow(10, c);
        if (r1 > r2) {
            arg1 = Number(arg1.toString().replace(".", ""));
            arg2 = Number(arg2.toString().replace(".", "")) * cm;
        } else {
            arg1 = Number(arg1.toString().replace(".", "")) * cm;
            arg2 = Number(arg2.toString().replace(".", ""));
        }
    } else {
        arg1 = Number(arg1.toString().replace(".", ""));
        arg2 = Number(arg2.toString().replace(".", ""));
    }
    return (arg1 + arg2) / m;
}

export function accSub(arg1, arg2) {
    var r1, r2, m, n;
    try {
        r1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
        r1 = 0;
    }
    try {
        r2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
        r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2)); //last modify by deeka //动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    return ((arg1 * m - arg2 * m) / m).toFixed(n);
}

export function accMul(arg1, arg2) {
    var m = 0, s1 = arg1.toString(), s2 = arg2.toString();
    try {
        m += s1.split(".")[1].length;
    }
    catch (e) {
    }
    try {
        m += s2.split(".")[1].length;
    }
    catch (e) {
    }

    return Number(s1.replace(".", "")) * Number(s2.replace(".", "")) / Math.pow(10, m);
}


export function accDiv(arg1, arg2) {
    var t1 = 0, t2 = 0, r1, r2;
    try {
        t1 = arg1.toString().split(".")[1].length;
    }
    catch (e) {
    }
    try {
        t2 = arg2.toString().split(".")[1].length;
    }
    catch (e) {
    }

    r1 = Number(arg1.toString().replace(".", ""));
    r2 = Number(arg2.toString().replace(".", ""));

    return (r1 / r2) * Math.pow(10, t2 - t1);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1307167.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

zookeeper1==zookeeper源码阅读,源码启动ZK集群

下载源码 Tags apache/zookeeper GitHub https://codeload.github.com/apache/zookeeper/zip/refs/tags/release-3.9.1 JDK8 MAVEN3.8.6 mvn -DskipTeststrue package 配置ZK1 zkServer.cmd中指出了启动类是 QuorumPeerMain QuorumPeer翻译成集群成员比较合理&#xf…

Nacos配置Mysql数据库

目录 前言1. 配置2. 测试前言 关于Nacos的基本知识可看我之前的文章: Nacos基础版 从入门到精通云服务器 通过docker安装配置Nacos 图文操作以下Nacos的版本为1.1.3 1. 配置 对应的配置文件路径如下: 对应的application.properties为配置文件 需配置端口号 以及 mysql中的…

Mysql的事务日志

Mysql的事务具有四个特性&#xff1a;原子性、一致性、隔离性、持久性。那么事务的四种特性分别是靠什么机制实现的呢&#xff1f; 事务的隔离性由锁机制来保证 事务的原子性、一致性、持久性则由redo log和Undo log来保证。 - redo log是重做日志&#xff0c;提供再写入操作&…

docker-compose安装nacos和msql

docker-compose安装nacos和msql 前言前提已经安装docker-compose&#xff0c;如果没有安装&#xff0c;则可以查看上面系列文章中的安装教程。并且文章中使用的是mobaxterm连接虚拟机。 1、下载2、创建并运行 前言 前提已经安装docker-compose&#xff0c;如果没有安装&#x…

BugKu-Web-Flask_FileUpload(模板注入与文件上传)

Flask Flask是一个使用Python编写的轻量级Web应用框架。它是一个微型框架&#xff0c;因为它的核心非常简单&#xff0c;但可以通过扩展来增加其他功能。Flask的核心组件包括Werkzeug&#xff0c;一个WSGI工具箱&#xff0c;以及Jinja2&#xff0c;一个模板引擎。 Flask使用BSD…

Windows提权方法

简介 内网提权&#xff0c;本意为通过某些服务的漏洞&#xff0c;从而获取到该服务器的shell&#xff0c;进而内网渗透&#xff0c;最终从普通用户变成超级管理员的一个过程 以下是一些常见的内网提权原理和方法&#xff1a; 横向移动&#xff1a;攻击者通过在内网中的一台受感…

fuxploide,一款针对文件上传的Fuzz检测工具

fuxploide,一款针对文件上传的Fuzz检测工具 1.工具概述2.安装3.参数解析4.使用案例1.工具概述 Fuxploider 是一种开源渗透测试工具,可自动检测和利用文件上传表单缺陷。该工具能够检测允许上传的文件类型,并能够检测哪种技术最适合在所需的 Web 服务器上上传 Web Shell 或任…

【同步FIFO_2023.12.13】

同步fifo&#xff0c;写时钟和读时钟为同一个时钟&#xff0c;用于交互数据缓冲 fifo的深度&#xff1a;同一块数据内存的大小 reg [2:0] Mem [8];//宽度3&#xff0c;深度8典型同步fifo的三部分 fifo写控制逻辑&#xff1a;写地址、写有效信号&#xff0c;fifo写满、写错等状…

Linux中的权限问题【详解】

shell命令以及运行原理 Windows以图形化界面为主要交互方式&#xff0c;简单高效&#xff0c;易于日常使用。Linux以命令行界面为主要交互方式&#xff0c;操作相较windows&#xff0c;mac来说比较困难一些&#xff0c;但linux也有向着图形化界面努力的桌面系统&#xff0c;例…

遥感深度学习:如何读取TIFF文件和切片成256*256?

博客已同步微信公众号&#xff1a;GIS不要炒茄子 01 前言 最近打算认真从头开始学习深度学习和遥感结合的相关内容&#xff0c;主要通过Python进行处理。此前用深度学习进行遥感相关的学习一直都是用 tensorflow3.0 框架&#xff0c;但是考虑很多因素我后面打算换用 Pytorch…

JetBrains2023年度报告,编程领域的风向标

前言 JetBrains是一家位于捷克的软件开发公司&#xff0c;有很多知名的开发IDE都是他们家的&#xff0c;比如IntelliJ IDEA、CLion、PyCharm、WebStorm等等&#xff0c;还有Kotlin编程语言也是JetBrains开发的&#xff0c;后来成为Android官方开发语言。 自2017年JetBrains发…

HNU-算法设计与分析-讨论课2

第二次小班讨论 &#xff08;以组为单位&#xff0c;每组一题&#xff0c;每组人人参与、合理分工&#xff0c;ppt中标记分工&#xff0c;尽量都有代码演示&#xff09; 算法分析题 3-4、4-1(要求:有 ppt和代码演示讲解 算法实现题 3-23、4-1(要求:有ppt 和代码演示讲解 数学之…

使用HTTP协议在Linux上进行API调用

在Linux系统上使用HTTP协议进行API调用是一种常见的操作&#xff0c;有时候我们需要调用一些外部API来获取数据或者进行自动化操作。下面是一个使用HTTP协议在Linux上进行API调用的代码示例&#xff0c;希望能够帮助你更好地理解这个过程。 首先&#xff0c;我们需要使用curl命…

【Docker】swarm stack部署多service应用

前面我们已经学习过了Docker Compose&#xff0c;它可以用来进行一个完整的应用程序相互依赖的多个容器的编排的&#xff0c;但是缺点是只能在单机模式使用&#xff0c;不能在分布式多机器上使用&#xff1b;前面我们也学习了Docker swarm&#xff0c;它可以将单个服务部署为多…

SOLIDWORKS CSWE认证考试报名

​ SOLIDWORKS CSWE是高级别的SOLIDWORKS认证&#xff0c;是一项充满挑战性的艰巨任务。CSWE测试不是简单注册就可以的&#xff0c;是要有一定资格才能参加考试&#xff0c;您首先需要获得CSWP证书&#xff0c;然后还得通过5个CSWPA系列主题考试中的至少4个主题&#xff08;钣金…

基于UDP的套接字通信

基于UDP的套接字通信 1、通信流程1.1 服务端1.2 客户端 2、通信函数3、通信代码3.1 服务端代码3.2 客户端代码 原文链接 udp是一个面向无连接的&#xff0c;不安全的&#xff0c;报式传输层协议&#xff0c;udp的通信过程默认也是阻塞的。 UDP通信不需要建立连接 &#xff0c;…

【ZYNQ】AXI4总线接口协议学习

建议翻看着底部的参考文档资料和本文一起辅助阅读 本文带你详细的了解AXI总线协议&#xff0c;并且基于官方手册&#xff0c;能够提高你的手册阅读能力。 什么是AXI AXI 的英文全称是 Advanced eXtensible Interface&#xff0c;即高级可扩展接口&#xff0c;它是 ARM 公司所提…

数据探索和模型建构

数据探索&#xff1a;观察数据之间的关系 分别判断 性别(sex)、船舱等级(Pclass)、年龄(Age)、有无父母子女(Parch)、有无兄弟姐妹(SibSp)、票价(Fare) 和 港口(Embarked)等因素和 存活(Survived)之间的关系 In [27]: sex_survived_cor train_data[[Sex,Survived]] sex_sur…

安科瑞出席宁波市建筑电气2023年年会-安科瑞 蒋静

12月1日&#xff0c;宁波市建筑电气2023年年会在宁波市海曙天港禧悦酒店成功举办。作为推动宁波市建筑电气行业技术发展的专业交流会&#xff0c;吸引了建筑电气行业领导、专家、设计师、厂家等300多名代表参会。期间&#xff0c;安科瑞电气股份有限公司携智能楼宇、智慧校园、…