Browse Source

关联表单数据填充主表填充效果实现

lwx_v8
liwenxuan 1 year ago
parent
commit
01db1b1606
  1. 3
      src/components/DesignForm/assembly/index.ts
  2. 16
      src/components/DesignForm/formControlPropertiNew.vue
  3. 4
      src/components/DesignForm/public/form/form.vue
  4. 128
      src/components/DesignForm/public/form/formGroup.vue
  5. 10
      src/components/DesignForm/public/form/formItem.vue
  6. 2
      src/views/sysworkflow/lowcodepage/runApp/runAppForm.vue
  7. 1
      src/widget/associatedforms/asfTmFillRoleFilterCondi.vue
  8. 26
      src/widget/associatedforms/associatedForms.vue
  9. 5
      src/widget/associatedforms/associatedFormsChildFillRole.vue
  10. 6
      src/widget/associatedforms/index.vue

3
src/components/DesignForm/assembly/index.ts

@ -897,6 +897,7 @@ export default [
mathsString:'', mathsString:'',
}, },
formid: '', formid: '',
glbbddbd:'',//关联本表单的表单
dataRangeConditionHtml: '', dataRangeConditionHtml: '',
dataRangeConditionHtmlCopy: '', dataRangeConditionHtmlCopy: '',
dataRangeGongShi:{ dataRangeGongShi:{
@ -917,7 +918,7 @@ export default [
child: [ child: [
{ {
id: '', id: '',
tableKey: '', asfChildTableKey: '',
filterCondition:{ filterCondition:{
conditionHtml: '', conditionHtml: '',
conditionHtmlCopy: '', conditionHtmlCopy: '',

16
src/components/DesignForm/formControlPropertiNew.vue

@ -1795,7 +1795,7 @@ const showImagePreview = ref(false)
controlData.value.control.fillRoles.child = [ controlData.value.control.fillRoles.child = [
{ {
id: '', id: '',
tableKey: '', asfChildTableKey: '',
filterCondition:{ filterCondition:{
conditionHtml: '', conditionHtml: '',
conditionHtmlCopy: '', conditionHtmlCopy: '',
@ -2116,6 +2116,8 @@ function removeFirstNumElements(arr: string | any[],num:number) {
function formidChanged(){ function formidChanged(){
//
controlData.value.control.glbbddbd=formData.value.name
if(controlData.value.control.formid===''){ if(controlData.value.control.formid===''){
}else{ }else{
@ -2635,7 +2637,7 @@ function selectedOrDelChildRole(){
//console.log(controlData.value.control?.fillRoles?.child) //console.log(controlData.value.control?.fillRoles?.child)
let selectedArr: any[] = [] let selectedArr: any[] = []
controlData.value.control?.fillRoles?.child.forEach(function(item: any) { controlData.value.control?.fillRoles?.child.forEach(function(item: any) {
if(item.tableKey!=""){ if(item.asfChildTableKey!=""){
selectedArr.push(item) selectedArr.push(item)
} }
}); });
@ -2648,7 +2650,7 @@ function selectedOrDelChildRole(){
if(asfasfChildTableList.value){ if(asfasfChildTableList.value){
asfasfChildTableList.value[0].children?.forEach(function(item: any){ asfasfChildTableList.value[0].children?.forEach(function(item: any){
selectedArr.forEach(function(i: any){ selectedArr.forEach(function(i: any){
if(i.tableKey==item.id){ if(i.asfChildTableKey==item.id){
item.disabled=true item.disabled=true
} }
}) })
@ -2804,7 +2806,7 @@ if(controlData.value.control.fillRoles.child.length<currentChildTableCount){
let onlyNumber1 = uuidv4().replaceAll('-','').toString(); // let onlyNumber1 = uuidv4().replaceAll('-','').toString(); //
controlData.value.control.fillRoles.child.push({ controlData.value.control.fillRoles.child.push({
id: onlyNumber, id: onlyNumber,
tableKey: '', asfChildTableKey: '',
filterCondition:{ filterCondition:{
conditionHtml: '', conditionHtml: '',
conditionHtmlCopy: '', conditionHtmlCopy: '',
@ -4702,7 +4704,7 @@ const radioChangeSet = (val:any) => {
<!-- 数据填充规则弹窗 --> <!-- 数据填充规则弹窗 -->
<el-dialog v-model="associatedFormsFillRolesDialogFlag" title="数据填充规则" top="150px" :close-on-click-modal="false" :show-close="false" style="margin-top:70px ;min-height: 300px;max-height:900px" width="50%" > <el-dialog v-model="associatedFormsFillRolesDialogFlag" title="数据填充规则" top="150px" :close-on-click-modal="false" :show-close="false" style="margin-top:70px ;min-height: 300px;max-height:900px" width="80%" >
<template v-if="controlData.type=='associatedForms'"> <template v-if="controlData.type=='associatedForms'">
<el-button style="font-size: large;margin-top: 10px;margin-bottom: 15px;" type="primary" link append-to-body="true" modal="true" @click="addFillRole"> 主表填充规则</el-button> <el-button style="font-size: large;margin-top: 10px;margin-bottom: 15px;" type="primary" link append-to-body="true" modal="true" @click="addFillRole"> 主表填充规则</el-button>
<div style="max-height:230px;border:1px solid white;overflow-y:auto;"> <div style="max-height:230px;border:1px solid white;overflow-y:auto;">
@ -4736,14 +4738,14 @@ const radioChangeSet = (val:any) => {
<div v-if="currentChildTableCount>0" style="max-height: 330px;overflow-y:auto;padding-top: 7px;"> <div v-if="currentChildTableCount>0" style="max-height: 330px;overflow-y:auto;padding-top: 7px;">
<template v-for="(item, index) in controlData.control.fillRoles.child" :key="controlData.control.fillRoles.child[index].id"> <template v-for="(item, index) in controlData.control.fillRoles.child" :key="controlData.control.fillRoles.child[index].id">
<AssociatedFormsChildFillRole <AssociatedFormsChildFillRole
v-model:selected-child-table="controlData.control.fillRoles.child[index].tableKey" v-model:selected-child-table="controlData.control.fillRoles.child[index].asfChildTableKey"
v-model:filter-condition="controlData.control.fillRoles.child[index].filterCondition" v-model:filter-condition="controlData.control.fillRoles.child[index].filterCondition"
v-model:child-roles = "controlData.control.fillRoles.child[index].childRoles" v-model:child-roles = "controlData.control.fillRoles.child[index].childRoles"
:child-table-list="asfasfChildTableList" :child-table-list="asfasfChildTableList"
:asfasf-field-tree="asfasfFieldTree" :asfasf-field-tree="asfasfFieldTree"
:tree-default-props="treeDefaultProps" :tree-default-props="treeDefaultProps"
:filter-node="filterNode" :filter-node="filterNode"
:handle-field-tree-contextmenu-range="handleFieldTreeContextmenuRange"
:org-and-man-tree="orgAndManTree" :org-and-man-tree="orgAndManTree"
:handle-org-tree-contextmenu-range = "handleOrgTreeContextmenuRange" :handle-org-tree-contextmenu-range = "handleOrgTreeContextmenuRange"
:role-tree="roleTree" :role-tree="roleTree"

4
src/components/DesignForm/public/form/form.vue

@ -654,8 +654,8 @@ function showOrHide (data:any){
} }
}else{ }else{
//3 //3
console.log(leftOperatorsAndRight) //console.log(leftOperatorsAndRight)
console.log(data) //console.log(data)
if(data.name==leftArr[2]){ if(data.name==leftArr[2]){
console.log("ghasdhasdfhhsadhasd") console.log("ghasdhasdfhhsadhasd")
console.log(props.formData.list[i].name) console.log(props.formData.list[i].name)

128
src/components/DesignForm/public/form/formGroup.vue

@ -37,7 +37,7 @@ const props = withDefaults(
} }
) )
let emits = defineEmits(['optionsValue3Get2']); let emits = defineEmits(['optionsValue3Get2','asfValueChanged']);
const store = useDesignFormStore() as any // const store = useDesignFormStore() as any //
const formProps = inject(constFormProps, {}) as any const formProps = inject(constFormProps, {}) as any
@ -372,11 +372,132 @@ onUnmounted(() => {
store.setActiveKey('') store.setActiveKey('')
store.setControlAttr({}) store.setControlAttr({})
}) })
const asfs: any[] = []
onMounted(()=>{ onMounted(()=>{
// console.log('',props.nodeKey,"---------------->",props.purview) // console.log('',props.nodeKey,"---------------->",props.purview)
// console.log('formGroup onMounted',props.data,dataList.value,props.tableinfo) // console.log('formGroup onMounted',props.data,dataList.value,props.tableinfo)
setTimeout(()=>{
if(dataList&&Array.isArray(dataList.value)&&dataList.value.length>0){
for(let i = 0;i<dataList.value.length;i++){
if(dataList.value[i].type=="associatedForms"){
asfs.push(dataList.value[i])
}else if(dataList.value[i].type=="card"||dataList.value[i].type=="flex"||dataList.value[i].type=="div"||dataList.value[i].type=="table"){
dataList.value[i].list.forEach((element:any) => {
if(element.type=="associatedForms"){
asfs.push(element)
}
});
}else if(dataList.value[i].type=="grid"){
let columns = JSON.parse(JSON.stringify(dataList.value[i].columns));
//console.log(columns)
if(columns.length>0){
for(let z = 0;z<columns.length;z++){
for(let x = 0; x<columns[z].list.length;x++){
let a = JSON.parse(JSON.stringify(columns[z].list[x]));
//console.log(a)
if(a.type=="associatedForms"){
asfs.push(a)
}
}
}
}
}else if(dataList.value[i].type=="tabs"){//tabsflextable
let columns = JSON.parse(JSON.stringify(dataList.value[i].columns));
if(columns.length>0){
for(let z = 0;z<columns.length;z++){
for(let x = 0; x<columns[z].list.length;x++){
let a = JSON.parse(JSON.stringify(columns[z].list[x]));
//console.log(a)
if(a.type=="associatedForms"){
asfs.push(a)
}else if(a.type=="flex"||a.type=="table"){
if(a.list.length>0){
for(let m = 0;m<a.list.length;m++){
let q = JSON.parse(JSON.stringify(a.list[m]))
//console.log(q)
if(q.type=="associatedForms"){
asfs.push(q)
}
}
}
}
}
}
}
}
}
/* if(asfs.length>0){
//console.log(asfs)
} */
}
},500)
})
function getNewObject(obj:any, arr:any) {
//console.log(obj)
//console.log(arr)
let key = arr[0];
let newKey = arr[1];
if (obj[key]) {
return { [newKey]: obj[key] };
}
return {};
}
function asfValueChanged(val:any){
/* console.log("asfValueChanged",val)
console.log(val.currentVal)
console.log(val.fillFieldsMaster)
console.log(val.fillFieldsChild) */
let fillFieldsMaster = ""
let masterFillRoleFieldsArray1: any[] = [];
if(val.fillFieldsMaster.length>0){
fillFieldsMaster = val.fillFieldsMaster.substring(0, val.fillFieldsMaster.length - 1);
let masterFillRoleFieldsArray = fillFieldsMaster.split(";");
//console.log(masterFillRoleFieldsArray)
masterFillRoleFieldsArray.forEach((item:any)=>{
let itemArray = item.split("_");
itemArray.splice(0, 1);
itemArray = itemArray.map((item1:any) => item1.split(':').pop());
//console.log(itemArray)
masterFillRoleFieldsArray1.push(itemArray)
}) })
}
//emits("asfValueChanged",val)
if(val.options.length>0){
//console.log(val.options)
if(val.options[0].fillRolesFieldsMap){
val.options.forEach((item:any)=>{
if(item.fillRolesFieldsMap.value == val.currentVal){
//console.log(item.fillRolesFieldsMap)
if(masterFillRoleFieldsArray1.length>0){
masterFillRoleFieldsArray1.forEach((item1:any)=>{
let x = convertObjectToArray(getNewObject(item.fillRolesFieldsMap,item1))
formProps.value.model[x[0]] = x[1]
})
}
}
})
}
}
}
function convertObjectToArray(obj:any) {
for (let key in obj) {
return [key, obj[key]];
}
return [];
}
const getFormItemLableStyle = (ele: any) => { const getFormItemLableStyle = (ele: any) => {
if(ele?.labelStyle){ if(ele?.labelStyle){
// console.log("3",AnalysisCss(ele)) // console.log("3",AnalysisCss(ele))
@ -387,10 +508,11 @@ const getFormItemLableStyle = (ele: any) => {
function optionsValue3Get1(data: any,fieldName: string){ function optionsValue3Get1(data: any,fieldName: string){
emits('optionsValue3Get2',data,fieldName) emits('optionsValue3Get2',data,fieldName)
} }
/*
*/
</script> </script>
<template> <template>
<draggable <draggable
itemKey="id" itemKey="id"
:list="dataList" :list="dataList"
@ -591,7 +713,7 @@ function optionsValue3Get1(data: any,fieldName: string){
<UrlLink v-else-if="element.type === 'urllink' && type != 4" :data="element" /> <UrlLink v-else-if="element.type === 'urllink' && type != 4" :data="element" />
<SerialNumber v-else-if="element.type === 'serialNumber' && type != 4" :data="element" :tablekey="props.tableinfo" :numrun="props.numrun" /> --> <SerialNumber v-else-if="element.type === 'serialNumber' && type != 4" :data="element" :tablekey="props.tableinfo" :numrun="props.numrun" /> -->
<!--其他组件--> <!--其他组件-->
<FormItem v-else :data="element" @optionsValue3Get1="optionsValue3Get1" :purview="props.purview" :node-key="props.nodeKey" :tablekey="props.tableinfo" :numrun="props.numrun" /> <FormItem v-else :data="element" @optionsValue3Get1="optionsValue3Get1" :purview="props.purview" :node-key="props.nodeKey" :tablekey="props.tableinfo" :numrun="props.numrun" @asf-value-changed="asfValueChanged" />
<!--组件设计外功能框架--> <!--组件设计外功能框架-->

10
src/components/DesignForm/public/form/formItem.vue

@ -57,6 +57,7 @@ const props = withDefaults(
const emits = defineEmits<{ const emits = defineEmits<{
(e: 'update:modelValue', val: any): void (e: 'update:modelValue', val: any): void
(e: 'optionsValue3Get1', val: any,fieldName: string): void (e: 'optionsValue3Get1', val: any,fieldName: string): void
(e: 'asfValueChanged', val: any): void
}>() }>()
const route = useRoute() const route = useRoute()
const formProps = inject(constFormProps, {}) as any const formProps = inject(constFormProps, {}) as any
@ -840,6 +841,13 @@ const pickUserVal = (val:any) => {
} }
} }
function asfValueChanged(val:any){
//console.log("asfValueChanged",val)
emits("asfValueChanged",val)
}
</script> </script>
<template> <template>
<BaiduMap v-if="judgeIsShow(data.name) &&data.type === 'baidumap' && type != 4" :data="data" /> <BaiduMap v-if="judgeIsShow(data.name) &&data.type === 'baidumap' && type != 4" :data="data" />
@ -856,7 +864,7 @@ const pickUserVal = (val:any) => {
<!--修改时间--> <!--修改时间-->
<EditTime v-else-if="judgeIsShow(data.name) && data.type === 'editTime' " :data="data" :tablekey="props.tablekey" :numrun="props.numrun" /> <EditTime v-else-if="judgeIsShow(data.name) && data.type === 'editTime' " :data="data" :tablekey="props.tablekey" :numrun="props.numrun" />
<!--关联表单--> <!--关联表单-->
<AssociatedForms v-else-if="judgeIsShow(data.name) && data.type === 'associatedForms' && type != 4" :data="data" :form-props="formProps" :tablekey="props.tablekey" /> <AssociatedForms v-else-if="judgeIsShow(data.name) && data.type === 'associatedForms' && type != 4" :data="data" :form-props="formProps" :tablekey="props.tablekey" @asf-value-changed="asfValueChanged"/>
<VideoUpAndPlay v-else-if="judgeIsShow(data.name) && data.type === 'videoUpAndPlay' " :data="data" /> <VideoUpAndPlay v-else-if="judgeIsShow(data.name) && data.type === 'videoUpAndPlay' " :data="data" />

2
src/views/sysworkflow/lowcodepage/runApp/runAppForm.vue

@ -212,7 +212,7 @@ const initLoadData = () => {
/* /*
在这里请求后台获取字段 在这里请求后台获取字段
*/ */
console.log("runAppForm-----214",paramx) //console.log("runAppForm-----214",paramx)
if(paramx && paramx != "" && paramx != null && paramx != "undefined"){ if(paramx && paramx != "" && paramx != null && paramx != "undefined"){
getFieldRecord(paramx).then(({ data }) => { getFieldRecord(paramx).then(({ data }) => {
stateData.tableData.columns[i].options = data stateData.tableData.columns[i].options = data

1
src/widget/associatedforms/asfTmFillRoleFilterCondi.vue

@ -204,6 +204,7 @@ const addIcon = (currentObject:any) =>{
tinymce.activeEditor?.execCommand('mceInsertContent', false, `<span style="margin:3px;background-color: #4189EF;border-radius: 5px; padding:3px" contenteditable="false" data-keyid= "${currentObject.id}" >${currentObject.label}</span>`); tinymce.activeEditor?.execCommand('mceInsertContent', false, `<span style="margin:3px;background-color: #4189EF;border-radius: 5px; padding:3px" contenteditable="false" data-keyid= "${currentObject.id}" >${currentObject.label}</span>`);
} }
const addIcon_field = (currentObject:any) =>{ const addIcon_field = (currentObject:any) =>{
//console.log(currentObject)
tinymce.activeEditor?.execCommand('mceInsertContent', false, `<span style="margin:3px;background-color: #4189EF;border-radius: 5px; padding:3px" contenteditable="false" data-keyid= "${currentObject.id}" >${currentObject.treeAttrs.show}</span>`); tinymce.activeEditor?.execCommand('mceInsertContent', false, `<span style="margin:3px;background-color: #4189EF;border-radius: 5px; padding:3px" contenteditable="false" data-keyid= "${currentObject.id}" >${currentObject.treeAttrs.show}</span>`);
} }
const addIcon_org = (currentObject:any) =>{ const addIcon_org = (currentObject:any) =>{

26
src/widget/associatedforms/associatedForms.vue

@ -44,7 +44,7 @@ onMounted(()=>{
// console.log(props.data.control) // console.log(props.data.control)
if(props.data.control.formid!=null&&props.data.control.formid!=""){ if(props.data.control.formid!=null&&props.data.control.formid!=""){
getAsfDataTitles().then(({ data }) => { getAsfDataTitles().then(({ data }) => {
console.log(data) //console.log(data)
options.value = data options.value = data
value1.value = props.formProps.model[props.data.name] value1.value = props.formProps.model[props.data.name]
}); });
@ -52,9 +52,18 @@ onMounted(()=>{
}) })
let fillFieldsMaster = "";
let fillFieldsChild:any
function asfValueChanged(){ function asfValueChanged(){
emits("valueChanged",value1.value) let val = {
options:options.value,
currentVal:value1.value,
fillFieldsMaster:fillFieldsMaster,
fillFieldsChild:fillFieldsChild
}
emits("valueChanged",val)
} }
function getAsfDataTitles() { function getAsfDataTitles() {
@ -66,7 +75,7 @@ function getAsfDataTitles() {
} }
// //
let fillFieldsMaster = "";
//console.log(props.data.control.fillRoles) //console.log(props.data.control.fillRoles)
//let fillRoles = JSON.parse(JSON.stringify(props.data.control.fillRoles)) //let fillRoles = JSON.parse(JSON.stringify(props.data.control.fillRoles))
for(let i= 0;i<props.data.control.fillRoles.master.length;i++){ for(let i= 0;i<props.data.control.fillRoles.master.length;i++){
@ -74,13 +83,14 @@ function getAsfDataTitles() {
fillFieldsMaster = fillFieldsMaster+props.data.control.fillRoles.master[i].id+"_"+props.data.control.fillRoles.master[i].leftValue+"_"+props.data.control.fillRoles.master[i].rightValue+";" fillFieldsMaster = fillFieldsMaster+props.data.control.fillRoles.master[i].id+"_"+props.data.control.fillRoles.master[i].leftValue+"_"+props.data.control.fillRoles.master[i].rightValue+";"
} }
} }
let fillFieldsChild = JSON.parse(JSON.stringify(props.data.control.fillRoles.child)) fillFieldsChild = JSON.parse(JSON.stringify(props.data.control.fillRoles.child))
fillFieldsChild = fillFieldsChild.filter((item:any)=>{ fillFieldsChild = fillFieldsChild.filter((item:any)=>{
return item.tablekey!="" //console.log(item)
return item.asfChildTableKey!=""
}) })
//console.log(fillFieldsChild) //console.log(fillFieldsChild)
for(let i= 0;i<fillFieldsChild.length;i++){ for(let i= 0;i<fillFieldsChild.length;i++){
if(fillFieldsChild[i].tableKey!=""){ if(fillFieldsChild[i].asfChildTableKey!=""){
if(fillFieldsChild[i].childRoles.length>0){ if(fillFieldsChild[i].childRoles.length>0){
fillFieldsChild[i].childRoles = fillFieldsChild[i].childRoles.filter((element:any) => { fillFieldsChild[i].childRoles = fillFieldsChild[i].childRoles.filter((element:any) => {
if(element.leftValue!=""&&element.rightValue!=""){ if(element.leftValue!=""&&element.rightValue!=""){
@ -93,12 +103,16 @@ function getAsfDataTitles() {
} }
//console.log(fillFieldsMaster) //console.log(fillFieldsMaster)
/*
*/
fillFieldsChild = JSON.stringify(fillFieldsChild) fillFieldsChild = JSON.stringify(fillFieldsChild)
//console.log(fillFieldsChild) //console.log(fillFieldsChild)
return request({ return request({
url: '/javasys/lowCode/AssociatedForms/getAsfDataTitles', url: '/javasys/lowCode/AssociatedForms/getAsfDataTitles',
method: 'post', method: 'post',
data: { data: {
glbbddbd:props.data.control.glbbddbd,
formId:props.data.control.formid, formId:props.data.control.formid,
dataTitle:dataTitle, dataTitle:dataTitle,
rangeFormula:props.data.control.dataRangeGongShi.mathsFormula, rangeFormula:props.data.control.dataRangeGongShi.mathsFormula,

5
src/widget/associatedforms/associatedFormsChildFillRole.vue

@ -73,7 +73,7 @@
<el-main style="border: 1px solid gainsboro; padding: 3px;" class="associatedFormsHideDialogMain"> <el-main style="border: 1px solid gainsboro; padding: 3px;" class="associatedFormsHideDialogMain">
<div <div
style="border: 1px solid gainsboro; height: 7%; border-bottom: 0px; padding-top: 3px; padding-left: 5px; background-color: #E6F3FE;"> style="border: 1px solid gainsboro; height: 7%; border-bottom: 0px; padding-top: 3px; padding-left: 5px; background-color: #E6F3FE;">
可选择符合以下条件的数据</div> 填充符合以下条件的子表数据</div>
<div id="associatedFormsHideEditArea" style="border: 1px solid gainsboro; height: 38%; border-bottom: 0px;"> <div id="associatedFormsHideEditArea" style="border: 1px solid gainsboro; height: 38%; border-bottom: 0px;">
<AsfTmFillRoleFilterCondi <AsfTmFillRoleFilterCondi
ref="tinymceRef" :aft-text="filterCondition1.conditionHtml" ref="tinymceRef" :aft-text="filterCondition1.conditionHtml"
@ -264,7 +264,8 @@ function handleRoleTreeContextmenuRange(MouseEvent: any, object: any, Node: any,
tinymceRef.value.addIcon(object) tinymceRef.value.addIcon(object)
} }
function handleFieldTreeContextmenuRange(MouseEvent: any, object: any, Node: any, element: any) { function handleFieldTreeContextmenuRange(MouseEvent: any, object: any, Node: any, element: any) {
tinymceRef.value.addIcon(object) console.log()
tinymceRef.value.addIcon_field(object)
} }
onMounted(() => { onMounted(() => {
emit('selectedOrDelChildRole') emit('selectedOrDelChildRole')

6
src/widget/associatedforms/index.vue

@ -35,8 +35,10 @@ const props = withDefaults(
}>(), }>(),
{} {}
) )
const emits = defineEmits<{ const emits = defineEmits<{
(e: 'update:modelValue', numVal: any): void (e: 'update:modelValue', numVal: any): void
(e: 'asfValueChanged', val: any): void
}>() }>()
const formProps = inject(constFormProps, {}) as any const formProps = inject(constFormProps, {}) as any
@ -158,8 +160,8 @@ const formatCustomRules = () => {
const valueChanged = (val:any) =>{ const valueChanged = (val:any) =>{
//console.log("--->",val) //console.log("--->",val)
value.value = val value.value = val.currentVal
emits("asfValueChanged",val)
} }

Loading…
Cancel
Save