概要
提示:这里可以描述概要
- 前面的输入框是发票金额,
- 后面的输入框是累计发票金额(含本次)--含本次就代表后倾请求的接口的数据(不是保存后返显的-因为保存后返显的是含本次)是不含本次的
- 所以在输入发票金额的时候,累计发票金额(含本次)也会跟着变化
输入框的联动
- 前面本次发票金额的输入框只能输入数值类型的数值,最多生效两位小数,多了会报错
- 后面累计发票金额(含本次)的输入框可以修改值,也是只能输入数值类型的数值,最多生效两位小数,多了会报错
- 输入数值要实时变动,而不是失去焦点后再计算
- 千分位也是实时出现 "," 而不是失去焦点的时候才有千分位
整体思路
提示:这里可以描述思路
后面输入框累计发票金额(含本次)的值虽然可以修改,但是前面的输入框本次发票金额在输入值的时候也要计算,得用后台请求的值加上本次发票金额,而且输入框的值输入错的话不能让其提交,所以得有表单验证,输入框的值是实时变化的,所以可以用监听。
首先,监听本次发票金额,确定实时输入的值是数值,而不是汉字英文字符标点什么的,而且在输入框输入的是 0.(零点几的时候会有 0.)这个时候 累计发票金额(含本次)会自动加上前面本次发票金额的值 不能报错
技术选型
提示:这里可以对技术选项解释
在监听验证数据的时候,验证数据书不是数值,包括在发票金额输入 0. 的时候 累计发票金额(含本次)实时 加上 本次发票金额 不能是 NAN
如果 用 正则验证 不行, 如果用正则 当是 0. 的时候会报错 无论用那种都不识别 但是是 0.3 能识别
因此不能用正则 而且 如果用正则的话 首先要判断输入的值是 数值 还得判定 带小数的和不带小数的
那么用什么呢? Number(val) 可以判定 如果不是数值 就会返回 NAN 如果是 0. 则会返回0
这样就完美的解决了问题
html页面
<el-form
:model="shenPiDialogForm"
ref="shenPiDialogForm"
:rules="shenPiDialogRule"
class="demo-ruleForm"
:label-width="shenPiLabelWidth"
>
<el-row :span="24">
<el-col :span="12">
<el-form-item label="本次发票金额(元):" prop="currentNowMoney">
<el-input v-model.trim="shenPiDialogForm.currentNowMoney">
</el-input>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item
label="累计发票金额(含本次)元:"
prop="cumulativeInvoices"
>
<el-input v-model="shenPiDialogForm.cumulativeInvoices">
</el-input>
</el-form-item>
</el-col>
</el-row>
<el-row :span="24">
<el-col :span="12">
<el-form-item label="缓付金额(人民币小写)元:" prop="">
{{ shenPiDialogForm.deferredAmount }}
</el-form-item>
</el-col>
<el-col :span="12"> </el-col>
</el-row>
<el-form-item>
<el-button
type="primary"
v-loading.fullscreen.lock="loading"
@click="submitForm('shenPiDialogForm')"
>提交</el-button
>
<el-button @click="resetForm('shenPiDialogForm')">取消</el-button>
</el-form-item>
</el-form>
js页面
1:用到的引入
1:本次申请金额 转大写
/*
*@Author: FangbinGuo
*@Date:2023-04-15 12:05:11
*@Description:
*/
// 本次申请金额 转大写
export function ZhuanDaXie(number) {
let newVal="";
if(String(number).indexOf(",")){
//如果是千分位的话 会有 , 去掉 ,
newVal=String(number).replace(/\,/g,"");
}else{
newVal=number;
}
let numberVal=Number(newVal);// 将 传入的值 转换为 数值
let result = "";
if(isNaN(numberVal)||numberVal<0){
// 如果 传入的 值 不是数值 或者 传入的金额 小于零
result=""
}
else {
if (number !== "" && number != null && number !== "0"&& number !== 0) {
// 如果 输入的值 非零 非 空
if(String(number).indexOf(".")){// 如果 含 小数
if(String(newVal).slice(String(newVal).indexOf(".")).length>3){
// 如果 小数部分超过两位
result=""
}else{// 如果 小数部分不超过两位
result=zhuanHanZi(newVal)
}
}else{// 如果不含小数
result=zhuanHanZi(newVal)
}
}else if(number==="0"||number===0){
result="零整"
}else{
result=""
}
}
return result
}
// 将 传入的数值 转为 汉字
export function zhuanHanZi(val){
let hanZi="";
let unit = "仟佰拾亿仟佰拾万仟佰拾元角分";
let str = "";
val += "00";
const point = val.indexOf(".");
if (point >= 0) {
val = val.substring(0, point) + val.substr(point + 1, 2);
}
unit = unit.substr(unit.length - val.length);
for (let i = 0; i < val.length; i++) {
str +=
"零壹贰叁肆伍陆柒捌玖".charAt(val.charAt(i)) + unit.charAt(i);
}
return hanZi =
str
.replace(/零(仟|佰|拾|角)/g, "零")
.replace(/(零)+/g, "零")
.replace(/零(万|亿|元)/g, "$1")
.replace(/(亿)万|(拾)/g, "$1$2")
.replace(/^元零?|零分/g, "")
// .replace(/元$/g, "元");
.replace(/元$/g, "元") + "整";
}
2: 数值转千分位 与 千分位转数值
/*
*@Author: FangbinGuo
*@Date:2023-04-20 09:45:26
*@Description: 数值转千分位 与 千分位转数值
*/
import { MessageBox, Message } from "element-ui";
export function numberToQianFenWei(value) {
let ShuZhireg=/^((0{1}\.\d{1,2})|([1-9]\d*\.{1}\d{1,9})|([1-9]+\d*)|0)$/;
let newValue=""
if(String(value).indexOf(",")){
newValue=String(value).replace(/\,/g,"");
// newValue=String(value).replaceAll(",","");
}else{
newValue=value;
}
if (newValue===0||newValue==="0") return 0;
if (newValue===""||newValue===null||newValue===undefined) return "";
// 获取整数部分
const intPart = Math.trunc(newValue);
// debugger
if(ShuZhireg.test(intPart)){
// 整数部分处理,增加,
const intPartFormat =
intPart.toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,')
// 预定义小数部分
let floatPart = ''
// 将数值截取为小数部分和整数部分
const valueArray = value.toString().split('.')
if (valueArray.length === 2) { // 有小数部分
floatPart = valueArray[1].toString() // 取得小数部分
return intPartFormat + '.' + floatPart
}
return intPartFormat + floatPart
}else{
// Message({
// message: "输入有误,请仔细查看!!!",
// type: "error",
// });
return value;
}
}
// 千分位传到后台 后台不识别 所以 传给后台的金额不能是千分位的数字 要转成正常数值
export function qianFenWeiZhuanToNumber(val){
if(val !== "" && val != null &&val != 0){
let valStr=val+"";
if(valStr.indexOf(",")) {
return valStr.replace(/\,/g,"");
}else{
return valStr
}
}else{
return val
}
}
3:表单的自定义验证方法
// 校验数值 必填 可以为0 但是不能为空 ---必填(最多两位小数)
export function JinEBuNengWeiKong(rule, value, callback) {
let SguZhireg=/^((0{1}\.\d{1,2})|([1-9]\d*\.{1}\d{1,2})|([1-9]+\d*)|0)$/;
if(value===null||value===""){
callback(new Error('请输入数值,不能为空!'));
}
else if(value===0){
callback();
}else{
let newVal="";
if(String(value).indexOf(",")){
//如果是千分位的数值,去掉里面的 , 后再验证
newVal=String(value).replace(/\,/g,"");
}else{
newVal=value;
}
if(!SguZhireg.test(newVal)){
callback(new Error('请输入最多只有两位小数且为正数的数值!'));
}
else if(newVal.toString().indexOf(".")==-1){//如果没有小数点
if(newVal.toString().length>=13){
callback(new Error('输入的数不得超过千亿!'))
}else{
callback()
}
}else if(newVal.toString().indexOf(".")>12){//如果有小数点
callback(new Error('输入的数不得超过千亿!'))
}
else{
callback()
}
}
}
3:方法与监听
import {
numberToQianFenWei,
qianFenWeiZhuanToNumber,
} from "@/utils/qianFenWei.js";//引入方法
import { ZhuanDaXie } from "@/utils/chineseNumber";//引入方法
import {
LJFPJE,//累计发票金额
} from "@/api/noWorkPayment/index.js";//接口
import {
JinEBuNengWeiKong,
} from "@/utils/toolsObj.js";//引入表单验证方法
data() {
return {
loading:false,
contractId:"",//累计发票金额 用到的 参数
lineId:"",//累计发票金额 用到的 参数
shenPiLabelWidth: "210px",
// 审批弹窗
shenPiDialogForm: {
flowEventId:'',//流程id
currentNowMoney:0,//本次发票金额
cumulativeInvoices:"",//累计发票金额
deferredAmount:"",//缓付金额
},
BCSJZF:"",//本次实际支付
NumBCFPJE:0,//本次发票金额 数值形式
NumLJFPJEHBC:0,//累计发票金额含本次 数值形式
NumLJFPJEBHBC:0,//累计发票金额不含本次 数值形式
shenPiDialogRule: {
// 本次发票金额
currentNowMoney: [
{ required: true, validator: JinEBuNengWeiKong, trigger: "blur" },
],
// 累计发票金额
cumulativeInvoices: [
{ required: true, validator: JinEBuNengWeiKong, trigger: "blur" },
],
},
};
},
watch:{
// 本次发票金额
"shenPiDialogForm.currentNowMoney": function (newVAl, oldVal) {
this.NumBCFPJE=qianFenWeiZhuanToNumber(newVAl);
this.shenPiDialogForm.currentNowMoney=numberToQianFenWei(newVAl);
// 首先分为有值和没有值
if(newVAl===""||newVAl===null){//如果输入框没值
this.shenPiDialogForm.currentNowMoney = "";
this.NumBCFPJE=0;
}else {
//如果输入框有值 判断是不是数值类型
if(Number(this.NumBCFPJE)||Number(this.NumBCFPJE)===0){
// 如果this.NumBCFPJE=0.时 Number(0.) 的值是0 0是false 就进入不了里面
if(String(this.NumBCFPJE).indexOf(".")>0){//如果数值中 含小数
// 将不是千分位的数值 转成字符串
let strNewVal=String(this.NumBCFPJE);
// 小数点前的数值
let numDot=strNewVal.slice(
0,(String(this.NumBCFPJE).indexOf(".")-0)+1
);
// 小数点后的数值
let dotNum=strNewVal.slice(
(String(this.NumBCFPJE).indexOf(".")-0)+1,
);
// 小数点后面两位
let baoLiuLiangWei=dotNum.slice(
0,(String(this.NumBCFPJE).indexOf(".")-0)+3
);
let NumValRes="";
if(String(dotNum).length>2 ){
// 小数后超过两位 截取到小数点后两位的值 后拼接
NumValRes=String(numDot).concat(baoLiuLiangWei);
return this.$message.error("最多两位小数!");
}else{
// 如果小数点正好两位 那么直接拼接
NumValRes=String(numDot).concat(dotNum);
}
// 使用 小数点前的(数值/千分位)和小数点后(保留两位)的数值
this.NumBCFPJE=qianFenWeiZhuanToNumber(NumValRes);
this.shenPiDialogForm.currentNowMoney=
numberToQianFenWei(NumValRes);
}else{//如果数值中 不含小数
this.NumBCFPJE=qianFenWeiZhuanToNumber(newVAl);
this.shenPiDialogForm.currentNowMoney=numberToQianFenWei(newVAl);
}
}else{//不是数值 一定是错的,报错
this.$message.error("请输入数值!")
this.shenPiDialogForm.currentNowMoney = "";
this.NumBCFPJE=0;
}
}
this.NumLJFPJEHBC=(this.NumBCFPJE-0)+(this.NumLJFPJEBHBC-0);
this.shenPiDialogForm.cumulativeInvoices=(
(this.NumBCFPJE-0)+(this.NumLJFPJEBHBC-0)
).toFixed(2);
},
// 累计发票金额
"shenPiDialogForm.cumulativeInvoices": function (newVAl, oldVal) {
if (newVAl == 0 || newVAl == null || newVAl == "0") {
this.shenPiDialogForm.cumulativeInvoices = newVAl;
this.NumLJFPJEHBC=0;
this.NumLJFPJEBHBC=0;
} else {
this.NumLJFPJEHBC=qianFenWeiZhuanToNumber(newVAl);
this.NumLJFPJEBHBC=(
(this.NumLJFPJEHBC-0)-(this.NumBCFPJE-0)
).toFixed(2);
this.shenPiDialogForm.cumulativeInvoices = numberToQianFenWei(newVAl);
}
},
},
methods: {
// 累计发票金额 验工与非验工 的参数不一样
getLJFPJE(){
this.loading=true;
this.NumLJFPJEBHBC="";
this.shenPiDialogForm.cumulativeInvoices="";
LJFPJE({
contractId:this.contractId,
segmentId:this.clickData.segmentId,
lineId:this.lineId,
}).then(res=>{
this.loading=false;
if(res.code==0){
this.NumLJFPJEBHBC=(res.data.cumulativeInvoices-0);
this.shenPiDialogForm.cumulativeInvoices=
numberToQianFenWei(res.data.cumulativeInvoices);
}
})
},
}
小结
提示:这里可以添加总结
这里最重要的是对 0. 的验证 如果是用正则验证,大家可以试一下,在输入 0. 时是报错的,但是0.2又不会报错 ,用了 Number(val) 来判断是不是 数值 用 Number(val)===0( 因为 Number(0.)===0 ) 来判定 0. 输入的也是 数值