Bläddra i källkod

新增表格验证

ymy 1 år sedan
förälder
incheckning
f429b19f08

+ 51 - 9
src/benyun/components/byTable/byTable.vue

@@ -6,6 +6,7 @@
       :size="attrs.size?attrs.size:'small'"
       sync-resize
       auto-resize
+      :edit-rules="attrs.editRules"
       :height="attrs.height"
       :max-height="attrs.maxHeight"
       :stripe="attrs.stripe"
@@ -52,18 +53,19 @@
           :fixed="item.fixed"
           resizable
           :align="item.align"
+          :edit-render="{}"
           :tree-node="item.treeNode"
         >
-          <template #default="{ row }">
-            <slot v-if="item.slot" :name='item.field' :row='row'></slot>
-            <component v-else-if="item.component" :is="item.component" :ref="item.field+'Comp'" :propConfig="item.compConfig" :parentValue="row"
-              :propValue="row[item.field]" @onChange="onChange($event, row,item.field)" />
+          <template #default="scope">
+            <slot v-if="item.slot" :name='item.field' :row='scope.row'></slot>
+            <component v-else-if="item.component" :is="item.component" :ref="item.field+'Comp'" :propConfig="item.compConfig" :parentValue="scope.row"
+              :propValue="scope.row[item.field]" @onChange="onChange($event, scope,item.field)" />
             <template v-else>
-              <div v-if="item.isDetail" :class="{'ellipsis':item.ellipsis}" :title="row[item.field]" :style="{ 'text-align': item.align }" class="tdCol detail" @click="detail(row)">
-                {{ item.formatField ? formatField(item,row) : row[item.field] }}
+              <div v-if="item.isDetail" :class="{'ellipsis':item.ellipsis}" :title="scope.row[item.field]" :style="{ 'text-align': item.align }" class="tdCol detail" @click="detail(scope.row)">
+                {{ item.formatField ? formatField(item,scope.row) : scope.row[item.field] }}
               </div>
-              <div class="tdCol" :class="{'ellipsis':item.ellipsis}" :title="row[item.field]" :style="{ 'text-align': item.align }" v-else>
-                {{ item.formatField ? formatField(item,row) : row[item.field] }}
+              <div class="tdCol" :class="{'ellipsis':item.ellipsis}" :title="scope.row[item.field]" :style="{ 'text-align': item.align }" v-else>
+                {{ item.formatField ? formatField(item,scope.row) : scope.row[item.field] }}
               </div>
             </template>
             
@@ -170,6 +172,43 @@ export default class ByTable extends VueViews {
       }
     })
   }
+  validate(){
+    let res = true
+    const $table:any = this.$refs.table
+    const data = $table.getTableData()
+    $table.validate(data.tableData).catch(() => {})
+    if(this.attrs.editRules && data.tableData && data.tableData.length > 0){
+      for(const item of data.tableData) {
+        for(const key in this.attrs.editRules){
+          if(this.attrs.editRules[key] && this.attrs.editRules[key].length > 0) {
+            for(const ruleItem of this.attrs.editRules[key]){
+              if(ruleItem.required) {
+                if(!item[key]){
+                  res = false;
+                  break
+                }
+              }
+              if(ruleItem.validatorHandle && item[key] || item[key] === 0){
+                res = ruleItem.validatorHandle(item[key])
+              }
+              if(!res) break
+            }
+          }
+          if(!res) break
+        }
+      }
+    }else{
+      res = true
+    }
+    return res
+    // console.log(errMap)
+    // if (errMap) {
+    //   this.$message({message:'校验不通过!',type:'warning'})
+    // } else {
+    //   this.$message({message:'校验成功!',type:'warning'})
+    
+    // }
+  }
   recalculate(){
     if(this.$refs.table){
       (this.$refs.table as any).recalculate(true);
@@ -252,7 +291,9 @@ export default class ByTable extends VueViews {
   }
 
   //组件值的变化
-  onChange(val:any,row:any,code:string){
+  onChange(val:any,item:any,code:string){
+    (this.$refs.table as any).updateStatus(item);
+    let row = item.row;
     if(val && (val as any).constructor == Object){
       for (const key in val) {
         if (!row[key]) {
@@ -300,6 +341,7 @@ export default class ByTable extends VueViews {
     // setTimeout(()=>{
       this.value = data ? data : [];
     // },100)
+    (this.$refs.table as any).clearValidate()
     this.$forceUpdate()
   }
 

+ 4 - 2
src/main.ts

@@ -23,7 +23,8 @@ import './assets/styles/element-variables.scss'
 // import VXETable from 'vxe-table'
 import XEUtils from 'xe-utils'
 import 'vxe-table/lib/style.css'
-import { VXETable, Column,Table,Modal,Button,Input } from 'vxe-table'
+// import { VXETable, Column,Table,Modal,Button,Input,Validator,Filter } from 'vxe-table'
+import VXETable from 'vxe-table'
 import zhCN from 'vxe-table/lib/locale/lang/zh-CN'
  // 按需加载的方式默认是不带国际化的,自定义国际化需要自行解析占位符 '{0}',例如:
 VXETable.setup({
@@ -73,7 +74,8 @@ Vue.use(Element, {
   size: Cookies.get('size') || 'medium' // set element-ui default size
 })
 
-Vue.use(Column).use(Table).use(Modal).use(Button).use(Input);
+Vue.use(VXETable)
+// Vue.use(Validator).use(Column).use(Table).use(Modal).use(Button).use(Input);
 Vue.use(gmComponent);
 Vue.use(plugins);
 Vue.use(directive);

+ 59 - 59
src/router/index.ts

@@ -60,66 +60,66 @@ export const constantRoutes: Array<any> = [
     path:'/order',
     name:'Order',
     component:() => import('@/views/demo/order/order.vue')
+  },
+  {
+    path:'/demo',
+    name:'Demo',
+    hidden: true,
+    component:() => import('@/views/demo/index.vue'),
+    // redirect: 'form',
+    children:[
+      {
+        path:'form',
+        component:()=> import('@/views/demo/form.vue'),
+        name:'Form',
+        meta: {
+          title: '表单',
+          activeMenu: '/system/user'
+        }
+      },
+      {
+        path:'table',
+        component:()=> import('@/views/demo/table.vue'),
+        name:'Table',
+        meta: {
+          title: '表格',
+          activeMenu: '/system/user'
+        }
+      },
+      {
+        path:'moduleView',
+        component:()=> import('@/views/demo/moduleView.vue'),
+        name:'ModuleView',
+        meta: {
+          title: 'view封装'
+        }
+      },
+      {
+        path:'bill',
+        component:()=> import('@/views/demo/bill.vue'),
+        name:'Bill',
+        meta: {
+          title: '单据'
+        }
+      },
+      {
+        path:'dialog',
+        component:()=> import('@/views/demo/dialogDemo.vue'),
+        name:'Dialog',
+        meta: {
+          title: '弹窗'
+        }
+      },
+			{
+			  path:'tab',
+			  component:()=> import('@/views/demo/tab.vue'),
+			  name:'Tab',
+			  meta: {
+			    title: '标签'
+			  }
+			}
+    ]
   }
-  // {
-  //   path:'/demo',
-  //   name:'Demo',
-  //   hidden: true,
-  //   component:() => import('@/views/demo/index.vue'),
-  //   // redirect: 'form',
-  //   children:[
-  //     {
-  //       path:'form',
-  //       component:()=> import('@/views/demo/form.vue'),
-  //       name:'Form',
-  //       meta: {
-  //         title: '表单',
-  //         activeMenu: '/system/user'
-  //       }
-  //     },
-  //     {
-  //       path:'table',
-  //       component:()=> import('@/views/demo/table.vue'),
-  //       name:'Table',
-  //       meta: {
-  //         title: '表格',
-  //         activeMenu: '/system/user'
-  //       }
-  //     },
-  //     {
-  //       path:'moduleView',
-  //       component:()=> import('@/views/demo/moduleView.vue'),
-  //       name:'ModuleView',
-  //       meta: {
-  //         title: 'view封装'
-  //       }
-  //     },
-  //     {
-  //       path:'bill',
-  //       component:()=> import('@/views/demo/bill.vue'),
-  //       name:'Bill',
-  //       meta: {
-  //         title: '单据'
-  //       }
-  //     },
-  //     {
-  //       path:'dialog',
-  //       component:()=> import('@/views/demo/dialogDemo.vue'),
-  //       name:'Dialog',
-  //       meta: {
-  //         title: '弹窗'
-  //       }
-  //     },
-	// 		{
-	// 		  path:'tab',
-	// 		  component:()=> import('@/views/demo/tab.vue'),
-	// 		  name:'Tab',
-	// 		  meta: {
-	// 		    title: '标签'
-	// 		  }
-	// 		}
-  //   ]
-  // }
 ]
 
 // 动态路由,基于用户权限动态去加载

+ 18 - 30
src/views/audit/productManagement/index.vue

@@ -113,7 +113,7 @@
 		<!-- 选择物料 -->
 		<productModal ref="product" :mulit="true" @confirm="confirmProduct" />
 		
-		<vxe-modal v-model="vxeValue" width="48%" height="88%" show-zoom resize transfer show-footer :loading="tableloading">
+		<vxe-modal v-model="vxeValue" width="48%" height="88%" show-zoom resize transfer show-footer>
 			<template #title>
 				<span>关联金蝶财务系统物料</span>
 			</template>
@@ -139,6 +139,7 @@
 				<el-table
 				    ref="multipleTable" 
 				    :data="newtableData"
+					v-loading="tableloading"
 					stripe
 					border
 				    style="width: 100%"
@@ -722,9 +723,6 @@
 					name: [{
 						required: true, message: '请输入名称', trigger: 'blur'
 					}],
-					// materialCode: [{
-					// 	required: true, message: '请输入物料编码', trigger: 'blur'
-					// }],
 					basePrice: [{
 						required: true, message: '请输入基本售价', trigger: 'blur'
 					}],
@@ -1088,7 +1086,7 @@
 			},
 		}
 		
-		tableloading = true
+		tableloading = false
 		tableRadio: any = {}
 		tableData: any = []
 		newtableData: any = []
@@ -1113,7 +1111,7 @@
 			this.tableSearchForm.stime = '2020-01-01';
 			this.tableSearchForm.etime = y+'-'+m+'-'+d;
 			this.etime = y+'-'+m+'-'+d;
-			// this.getFinancialCode()
+			this.getFinancialCode()
 			this.getTreeList();
 		}
 		getTreeList(){
@@ -1224,9 +1222,9 @@
 						// if (parseInt(v.height) <= 0) return this.$message.warning('物料属性高度不能小于1');
 						if (!v.skuTitle) return this.$message.warning('物料标题必填');
 						if (!v.skuCode) return this.$message.warning('物料编码必填');
-						// if(v.weight&&v.weight!=0){
-						// 	v.weight = v.weight/1000
-						// }
+						if(v.weight&&v.weight!=0){
+							v.weight = v.weight/1000
+						}
 					};
 					data = { maindataMaterialReceiveParam: query, maindataMaterialSkus: this.tableList }
 					let newArray : any = []
@@ -1268,12 +1266,12 @@
 						// if (parseInt(v.width) <= 0) return this.$message.warning('物料宽不能小于1');
 						// if (!v.height) return this.$message.warning('物料高必填');
 						// if (parseInt(v.height) <= 0) return this.$message.warning('物料高不能小于1');
-						if (!v.skuTitle) return this.$message.warning('物料属性的标题必填');
-						if (!v.skuCode) return this.$message.warning('物料属性的物料编码必填');
+						if (!v.skuTitle) return this.$message.warning('物料标题必填');
+						if (!v.skuCode) return this.$message.warning('物料编码必填');
 						
-						// if(v.weight&&v.weight!=0){
-						// 	v.weight = v.weight/1000
-						// }
+						if(v.weight&&v.weight!=0){
+							v.weight = v.weight/1000
+						}
 					};
 					data.maindataMaterialSkus[0].isDeleted = 0;
 					data.maindataMaterialReceiveParam.attributeList = ""
@@ -1400,13 +1398,10 @@
 									this.towTable = '' // 表格数据
 									this.attributeList = []; // 属性规格
 									this.$nextTick(() => {
-										// console.log(info.data);
+										console.log(info.data);
 										info.data.map((v : any, i : any) => {
-											// if(v.volume&&v.weight!='0.00'&&v.weight!=0&&v.weight!='0'){
-											// 	v.weight = parseFloat(v.weight)*1000
-											// }
-											if(v.volume&&v.volume!='0.00'&&v.volume!=0&&v.volume!='0'){
-												v.volume = parseFloat(v.volume).toFixed(2)
+											if(v.weight!='0.00'&&v.weight!=0&&v.weight!='0'){
+												v.weight = parseFloat(v.weight)*1000
 											}
 										});
 										(this as any).$refs.singeTable.setValue(info.data);
@@ -1419,11 +1414,8 @@
 									info.data.map((v : any, i : any) => {
 										v = Object.assign(v, skuRuleList[i])
 										v.dataIndex = i
-										// if(v.volume&&v.weight!='0.00'&&v.weight!=0&&v.weight!='0'){
-										// 	v.weight = parseFloat(v.weight)*1000
-										// }
-										if(v.volume&&v.volume!='0.00'&&v.volume!=0&&v.volume!='0'){
-											v.volume = parseFloat(v.volume).toFixed(2)
+										if(v.weight!='0.00'&&v.weight!=0&&v.weight!='0'){
+											v.weight = parseFloat(v.weight)*1000
 										}
 									});
 									newColumns.map((v : any) => {
@@ -1667,11 +1659,6 @@
 		// 打开关联金蝶财务系统物料选择
 		openVxeData(){
 			this.vxeValue = true;
-			if(this.tableData.length==0){
-				setTimeout(()=>{
-					this.getFinancialCode();
-				},0)
-			}
 		}
 		// 获取关联金蝶财务系统物料列表
 		getFinancialCode(){
@@ -1735,6 +1722,7 @@
 				val[0].unit = this.tableRadio.fbaseUnitName;
 				val[0].unitCode = this.tableRadio.fbaseUnitCode;
 			}
+			console.log(222,val);
 			(this as any).$refs.singeTable.setValue(val);
 			(this as any).$refs.form.setValue(val2);
 			this.vxeValue = false;

+ 43 - 6
src/views/demo/table.vue

@@ -4,6 +4,7 @@
       <template v-slot:slotField='{ row }'>插槽:{{ row.name }}</template>
     </by-table>
     <el-button type="primary" @click="setData">设置数据</el-button>
+    <el-button type="primary" @click="validate">表格验证</el-button>
     <el-button type="primary" @click="getSelect">获取选中数据</el-button>
     <div>树型表格</div>
     <by-table :propConfig="treeConfig" ref="treeTable"></by-table>
@@ -14,13 +15,36 @@
 import { Component, Prop, Vue, Watch } from "vue-property-decorator";
 @Component
 export default class DemoTable extends Vue {
+
+
   config:any={
     attr:{
       size:'mini',
       height:240,
       seq:true,
       align:'center',
-      checkbox:true
+      checkbox:true,
+      editRules:{
+        name:[
+          //必填
+          { required: true, message: '请输入姓名'}, 
+          //自定义验证
+          { 
+            validator: (parames:any) => {  //表格验证提示信息
+              if (parames.cellValue && !/^\w+$/.test(parames.cellValue)) {
+                return new Error('名称格式不正确,必须字母或数字')
+              } 
+            },
+            validatorHandle:(v:any) => { //判断验证是否通过
+              if (v && !/^\w+$/.test(v)) {
+                return false
+              } else{
+                return true
+              }
+            }
+          }
+        ]
+      }
     },
     columns:[{
       title:'id',
@@ -54,7 +78,7 @@ export default class DemoTable extends Vue {
         event:{
           show:(item:any) => {
             //是否显示该按钮
-            console.log('该行数据:',item);
+            // console.log('该行数据:',item);
             return false
           },
           click:(item:any) => {
@@ -75,15 +99,15 @@ export default class DemoTable extends Vue {
   }
   data:Array<any>=[{
     id:1,
-    name:'张三',
+    name:'',
     time:'2023-04-07'
   },{
     id:2,
-    name:'李四',
+    name:'',
     time:'2023-04-08'
   },{
     id:3,
-    name:'王五',
+    name:'',
     time:'2023-04-09'
   }]
   data2:Array<any>=[{
@@ -111,7 +135,8 @@ export default class DemoTable extends Vue {
       align:'center',
       transform:true,
       rowField:'menuId',
-      parentField:'parentId'
+      parentField:'parentId',
+
     },
     columns:[{
       // treeNode:true,
@@ -133,6 +158,18 @@ export default class DemoTable extends Vue {
     },500)
     this.request();
   }
+  validate() {
+
+    let v = (this.$refs.table as any).validate();
+    if(v){
+      this.$message({message:'成功',type:'success'})
+    }else{
+      this.$message({
+        message:'失败',
+        type:'warning'
+      })
+    }
+  }
   onChange(data:Array<any>){
     console.log('表格数据:',data)
   }

+ 2 - 2
src/views/oms/order/components/sendModeModal.vue

@@ -1,7 +1,7 @@
 <template>
   <vxe-modal v-model="value" id="sendModeModal" :zIndex="9999" width="65%" height="60%" v-loading="load">
     <template #title>
-      <span>订单批量发货模式选择</span>
+      <span>订单发货模式选择</span>
     </template>
     <div class="mode">
       <div class="moda-item" :class="{'onModal': mode==='0'}" @click="modeHandle('0')">
@@ -16,7 +16,7 @@
           <i class="el-icon-success"></i>
           <span>推荐</span>
         </div>
-        <div class="msg">处理后形成一张物流单<br />优惠多多</div>
+        <div class="msg">处理后形成一张物流单<br />优惠多多</div>
         <div class="moda-title">整车发货</div>
       </div>
       <div class="moda-item" :class="{'onModal': mode==='2'}" @click="modeHandle('2')">